diff --git a/[refs] b/[refs] index 56ef85bcc7c7..397f0b6eae24 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0c23664ee8c42f247dba7ceb620baabd892cef88 +refs/heads/master: 1605b8471d64c855bc2493abf3adf6a1ebc3e645 diff --git a/trunk/CREDITS b/trunk/CREDITS index 80e241304b8e..d7140309e06d 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -661,7 +661,7 @@ N: Kees Cook E: kees@outflux.net W: http://outflux.net/ P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30 1975 1FFF 4BA9 1706 3E6D -D: Minor updates to SCSI types, added /proc/pid/maps protection +D: Minor updates to SCSI code for the Communications type S: (ask for current address) S: USA @@ -1745,9 +1745,8 @@ S: D-64295 S: Germany N: Andi Kleen -E: andi@firstfloor.org -U: http://www.halobates.de -D: network, x86, NUMA, various hacks +E: ak@muc.de +D: network hacker, syncookies S: Schwalbenstr. 96 S: 85551 Ottobrunn S: Germany @@ -2580,9 +2579,10 @@ S: Australia N: Miguel Ojeda Sandonis E: maxextreme@gmail.com -W: http://maxextreme.googlepages.com/ -D: Author of the ks0108, cfag12864b and cfag12864bfb auxiliary display drivers. -D: Maintainer of the auxiliary display drivers tree (drivers/auxdisplay/*) +D: Author: Auxiliary LCD Controller driver (ks0108) +D: Author: Auxiliary LCD driver (cfag12864b) +D: Author: Auxiliary LCD framebuffer driver (cfag12864bfb) +D: Maintainer: Auxiliary display drivers tree (drivers/auxdisplay/*) S: C/ Mieses 20, 9-B S: Valladolid 47009 S: Spain diff --git a/trunk/Documentation/CodingStyle b/trunk/Documentation/CodingStyle index afc286775891..9069189e78ef 100644 --- a/trunk/Documentation/CodingStyle +++ b/trunk/Documentation/CodingStyle @@ -160,21 +160,6 @@ supply of new-lines on your screen is not a renewable resource (think 25-line terminal screens here), you have more empty lines to put comments on. -Do not unnecessarily use braces where a single statement will do. - -if (condition) - action(); - -This does not apply if one branch of a conditional statement is a single -statement. Use braces in both branches. - -if (condition) { - do_this(); - do_that(); -} else { - otherwise(); -} - 3.1: Spaces Linux kernel style for use of spaces depends (mostly) on @@ -640,7 +625,7 @@ language. There appears to be a common misperception that gcc has a magic "make me faster" speedup option called "inline". While the use of inlines can be -appropriate (for example as a means of replacing macros, see Chapter 12), it +appropriate (for example as a means of replacing macros, see Chapter 11), it very often is not. Abundant use of the inline keyword leads to a much bigger kernel, which in turn slows the system as a whole down, due to a bigger icache footprint for the CPU and simply because there is less memory diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index 6fd1646d3204..867608ab3ca0 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -41,9 +41,8 @@ psdocs: $(PS) PDF := $(patsubst %.xml, %.pdf, $(BOOKS)) pdfdocs: $(PDF) -HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS))) +HTML := $(patsubst %.xml, %.html, $(BOOKS)) htmldocs: $(HTML) - $(call build_main_index) MAN := $(patsubst %.xml, %.9, $(BOOKS)) mandocs: $(MAN) @@ -133,17 +132,10 @@ quiet_cmd_db2pdf = PDF $@ %.pdf : %.xml $(call cmd,db2pdf) - -main_idx = Documentation/DocBook/index.html -build_main_index = rm -rf $(main_idx) && \ - echo '

Linux Kernel HTML Documentation

' >> $(main_idx) && \ - echo '

Kernel Version: $(KERNELVERSION)

' >> $(main_idx) && \ - cat $(HTML) >> $(main_idx) - quiet_cmd_db2html = HTML $@ cmd_db2html = xmlto xhtml $(XMLTOFLAGS) -o $(patsubst %.html,%,$@) $< && \ echo ' \ - $(patsubst %.html,%,$(notdir $@))

' > $@ + Goto $(patsubst %.html,%,$(notdir $@))

' > $@ %.html: %.xml @(which xmlto > /dev/null 2>&1) || \ @@ -160,7 +152,6 @@ quiet_cmd_db2man = MAN $@ @(which xmlto > /dev/null 2>&1) || \ (echo "*** You need to install xmlto ***"; \ exit 1) - $(Q)mkdir -p $(obj)/man $(call cmd,db2man) @touch $@ @@ -221,7 +212,11 @@ clean-files := $(DOCBOOKS) \ $(patsubst %.xml, %.9, $(DOCBOOKS)) \ $(C-procfs-example) -clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) man +clean-dirs := $(patsubst %.xml,%,$(DOCBOOKS)) + +#man put files in man subdir - traverse down +subdir- := man/ + # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable se we can use it in if_changed and friends. diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index a2b2b4d187c5..b61dfc79e1b8 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -576,67 +576,4 @@ X!Idrivers/video/console/fonts.c !Edrivers/input/ff-core.c !Edrivers/input/ff-memless.c - - - Serial Peripheral Interface (SPI) - - SPI is the "Serial Peripheral Interface", widely used with - embedded systems because it is a simple and efficient - interface: basically a multiplexed shift register. - Its three signal wires hold a clock (SCK, often in the range - of 1-20 MHz), a "Master Out, Slave In" (MOSI) data line, and - a "Master In, Slave Out" (MISO) data line. - SPI is a full duplex protocol; for each bit shifted out the - MOSI line (one per clock) another is shifted in on the MISO line. - Those bits are assembled into words of various sizes on the - way to and from system memory. - An additional chipselect line is usually active-low (nCS); - four signals are normally used for each peripheral, plus - sometimes an interrupt. - - - The SPI bus facilities listed here provide a generalized - interface to declare SPI busses and devices, manage them - according to the standard Linux driver model, and perform - input/output operations. - At this time, only "master" side interfaces are supported, - where Linux talks to SPI peripherals and does not implement - such a peripheral itself. - (Interfaces to support implementing SPI slaves would - necessarily look different.) - - - The programming interface is structured around two kinds of driver, - and two kinds of device. - A "Controller Driver" abstracts the controller hardware, which may - be as simple as a set of GPIO pins or as complex as a pair of FIFOs - connected to dual DMA engines on the other side of the SPI shift - register (maximizing throughput). Such drivers bridge between - whatever bus they sit on (often the platform bus) and SPI, and - expose the SPI side of their device as a - struct spi_master. - SPI devices are children of that master, represented as a - struct spi_device and manufactured from - struct spi_board_info descriptors which - are usually provided by board-specific initialization code. - A struct spi_driver is called a - "Protocol Driver", and is bound to a spi_device using normal - driver model calls. - - - The I/O model is a set of queued messages. Protocol drivers - submit one or more struct spi_message - objects, which are processed and completed asynchronously. - (There are synchronous wrappers, however.) Messages are - built from one or more struct spi_transfer - objects, each of which wraps a full duplex SPI transfer. - A variety of protocol tweaking options are needed, because - different chips adopt very different policies for how they - use the bits transferred with SPI. - -!Iinclude/linux/spi/spi.h -!Fdrivers/spi/spi.c spi_register_board_info -!Edrivers/spi/spi.c - - diff --git a/trunk/Documentation/DocBook/librs.tmpl b/trunk/Documentation/DocBook/librs.tmpl index 94f21361e0ed..3ff39bafc00e 100644 --- a/trunk/Documentation/DocBook/librs.tmpl +++ b/trunk/Documentation/DocBook/librs.tmpl @@ -79,12 +79,12 @@ Usage - This chapter provides examples of how to use the library. + This chapter provides examples how to use the library. Initializing - The init function init_rs returns a pointer to an + The init function init_rs returns a pointer to a rs decoder structure, which holds the necessary information for encoding, decoding and error correction with the given polynomial. It either uses an existing @@ -98,10 +98,10 @@ static struct rs_control *rs_decoder; /* Symbolsize is 10 (bits) - * Primitive polynomial is x^10+x^3+1 + * Primitve polynomial is x^10+x^3+1 * first consecutive root is 0 - * primitive element to generate roots = 1 - * generator polynomial degree (number of roots) = 6 + * primitve element to generate roots = 1 + * generator polinomial degree (number of roots) = 6 */ rs_decoder = init_rs (10, 0x409, 0, 1, 6); @@ -116,12 +116,12 @@ rs_decoder = init_rs (10, 0x409, 0, 1, 6); The expanded data can be inverted on the fly by - providing a non-zero inversion mask. The expanded data is + providing a non zero inversion mask. The expanded data is XOR'ed with the mask. This is used e.g. for FLASH ECC, where the all 0xFF is inverted to an all 0x00. The Reed-Solomon code for all 0x00 is all 0x00. The code is inverted before storing to FLASH so it is 0xFF - too. This prevents that reading from an erased FLASH + too. This prevent's that reading from an erased FLASH results in ECC errors. @@ -273,7 +273,7 @@ free_rs(rs_decoder); May be used under the terms of the GNU General Public License (GPL) - The wrapper functions and interfaces are written by Thomas Gleixner. + The wrapper functions and interfaces are written by Thomas Gleixner Many users have provided bugfixes, improvements and helping hands for testing. diff --git a/trunk/Documentation/DocBook/man/Makefile b/trunk/Documentation/DocBook/man/Makefile new file mode 100644 index 000000000000..4fb7ea0f7ac8 --- /dev/null +++ b/trunk/Documentation/DocBook/man/Makefile @@ -0,0 +1,3 @@ +# Rules are put in Documentation/DocBook + +clean-files := *.9.gz *.sgml manpage.links manpage.refs diff --git a/trunk/Documentation/SubmittingDrivers b/trunk/Documentation/SubmittingDrivers index d7e26427e426..58bead05eabb 100644 --- a/trunk/Documentation/SubmittingDrivers +++ b/trunk/Documentation/SubmittingDrivers @@ -87,21 +87,6 @@ Clarity: It helps if anyone can see how to fix the driver. It helps driver that intentionally obfuscates how the hardware works it will go in the bitbucket. -PM support: Since Linux is used on many portable and desktop systems, your - driver is likely to be used on such a system and therefore it - should support basic power management by implementing, if - necessary, the .suspend and .resume methods used during the - system-wide suspend and resume transitions. You should verify - that your driver correctly handles the suspend and resume, but - if you are unable to ensure that, please at least define the - .suspend method returning the -ENOSYS ("Function not - implemented") error. You should also try to make sure that your - driver uses as little power as possible when it's not doing - anything. For the driver testing instructions see - Documentation/power/drivers-testing.txt and for a relatively - complete overview of the power management issues related to - drivers see Documentation/power/devices.txt . - Control: In general if there is active maintainance of a driver by the author then patches will be redirected to them unless they are totally obvious and without need of checking. diff --git a/trunk/Documentation/accounting/getdelays.c b/trunk/Documentation/accounting/getdelays.c index 71acc28ed0d1..e9126e794ed7 100644 --- a/trunk/Documentation/accounting/getdelays.c +++ b/trunk/Documentation/accounting/getdelays.c @@ -61,6 +61,8 @@ __u64 stime, utime; #define MAX_MSG_SIZE 1024 /* Maximum number of cpus expected to be specified in a cpumask */ #define MAX_CPUS 32 +/* Maximum length of pathname to log file */ +#define MAX_FILENAME 256 struct msgtemplate { struct nlmsghdr n; @@ -70,16 +72,6 @@ struct msgtemplate { char cpumask[100+6*MAX_CPUS]; -static void usage(void) -{ - fprintf(stderr, "getdelays [-dilv] [-w logfile] [-r bufsize] " - "[-m cpumask] [-t tgid] [-p pid]\n"); - fprintf(stderr, " -d: print delayacct stats\n"); - fprintf(stderr, " -i: print IO accounting (works only with -p)\n"); - fprintf(stderr, " -l: listen forever\n"); - fprintf(stderr, " -v: debug on\n"); -} - /* * Create a raw netlink socket and bind */ @@ -229,13 +221,13 @@ int main(int argc, char *argv[]) int count = 0; int write_file = 0; int maskset = 0; - char *logfile = NULL; + char logfile[128]; int loop = 0; struct msgtemplate msg; while (1) { - c = getopt(argc, argv, "diw:r:m:t:p:vl"); + c = getopt(argc, argv, "diw:r:m:t:p:v:l"); if (c < 0) break; @@ -249,7 +241,7 @@ int main(int argc, char *argv[]) print_io_accounting = 1; break; case 'w': - logfile = strdup(optarg); + strncpy(logfile, optarg, MAX_FILENAME); printf("write to file %s\n", logfile); write_file = 1; break; @@ -285,7 +277,7 @@ int main(int argc, char *argv[]) loop = 1; break; default: - usage(); + printf("Unknown option %d\n", c); exit(-1); } } diff --git a/trunk/Documentation/blackfin/00-INDEX b/trunk/Documentation/blackfin/00-INDEX deleted file mode 100644 index 7cb3b356b249..000000000000 --- a/trunk/Documentation/blackfin/00-INDEX +++ /dev/null @@ -1,11 +0,0 @@ -00-INDEX - - This file - -cache-lock.txt - - HOWTO for blackfin cache locking. - -cachefeatures.txt - - Supported cache features. - -Filesystems - - Requirements for mounting the root file system. diff --git a/trunk/Documentation/blackfin/Filesystems b/trunk/Documentation/blackfin/Filesystems deleted file mode 100644 index 51260a1b8032..000000000000 --- a/trunk/Documentation/blackfin/Filesystems +++ /dev/null @@ -1,169 +0,0 @@ -/* - * File: Documentation/blackfin/Filesystems - * Based on: - * Author: - * - * Created: - * Description: This file contains the simple DMA Implementation for Blackfin - * - * Rev: $Id: Filesystems 2384 2006-11-01 04:12:43Z magicyang $ - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - */ - - How to mount the root file system in uClinux/Blackfin - ----------------------------------------------------- - -1 Mounting EXT3 File system. - ------------------------ - - Creating an EXT3 File system for uClinux/Blackfin: - - -Please follow the steps to form the EXT3 File system and mount the same as root -file system. - -a Make an ext3 file system as large as you want the final root file - system. - - mkfs.ext3 /dev/ram0 - -b Mount this Empty file system on a free directory as: - - mount -t ext3 /dev/ram0 ./test - where ./test is the empty directory. - -c Copy your root fs directory that you have so carefully made over. - - cp -af /tmp/my_final_rootfs_files/* ./test - - (For ex: cp -af uClinux-dist/romfs/* ./test) - -d If you have done everything right till now you should be able to see - the required "root" dir's (that's etc, root, bin, lib, sbin...) - -e Now unmount the file system - - umount ./test - -f Create the root file system image. - - dd if=/dev/ram0 bs=1k count= \ - > ext3fs.img - - -Now you have to tell the kernel that will be mounting this file system as -rootfs. -So do a make menuconfig under kernel and select the Ext3 journaling file system -support under File system --> submenu. - - -2. Mounting EXT2 File system. - ------------------------- - -By default the ext2 file system image will be created if you invoke make from -the top uClinux-dist directory. - - -3. Mounting CRAMFS File System - ---------------------------- - -To create a CRAMFS file system image execute the command - - mkfs.cramfs ./test cramfs.img - - where ./test is the target directory. - - -4. Mounting ROMFS File System - -------------------------- - -To create a ROMFS file system image execute the command - - genromfs -v -V "ROMdisk" -f romfs.img -d ./test - - where ./test is the target directory - - -5. Mounting the JFFS2 Filesystem - ----------------------------- - -To create a compressed JFFS filesystem (JFFS2), please execute the command - - mkfs.jffs2 -d ./test -o jffs2.img - - where ./test is the target directory. - -However, please make sure the following is in your kernel config. - -/* - * RAM/ROM/Flash chip drivers - */ -#define CONFIG_MTD_CFI 1 -#define CONFIG_MTD_ROM 1 -/* - * Mapping drivers for chip access - */ -#define CONFIG_MTD_COMPLEX_MAPPINGS 1 -#define CONFIG_MTD_BF533 1 -#undef CONFIG_MTD_UCLINUX - -Through the u-boot boot loader, use the jffs2.img in the corresponding -partition made in linux-2.6.x/drivers/mtd/maps/bf533_flash.c. - -NOTE - Currently the Flash driver is available only for EZKIT. Watch out for a - STAMP driver soon. - - -6. Mounting the NFS File system - ----------------------------- - - For mounting the NFS please do the following in the kernel config. - - In Networking Support --> Networking options --> TCP/IP networking --> - IP: kernel level autoconfiguration - - Enable BOOTP Support. - - In Kernel hacking --> Compiled-in kernel boot parameter add the following - - root=/dev/nfs rw ip=bootp - - In File system --> Network File system, Enable - - NFS file system support --> NFSv3 client support - Root File system on NFS - - in uClibc menuconfig, do the following - In Networking Support - enable Remote Procedure Call (RPC) support - Full RPC Support - - On the Host side, ensure that /etc/dhcpd.conf looks something like this - - ddns-update-style ad-hoc; - allow bootp; - subnet 10.100.4.0 netmask 255.255.255.0 { - default-lease-time 122209600; - max-lease-time 31557600; - group { - host bf533 { - hardware ethernet 00:CF:52:49:C3:01; - fixed-address 10.100.4.50; - option root-path "/home/nfsmount"; - } - } - - ensure that /etc/exports looks something like this - /home/nfsmount *(rw,no_root_squash,no_all_squash) - - run the following commands as root (may differ depending on your - distribution) : - - service nfs start - - service portmap start - - service dhcpd start - - /usr/sbin/exportfs diff --git a/trunk/Documentation/blackfin/cache-lock.txt b/trunk/Documentation/blackfin/cache-lock.txt deleted file mode 100644 index 88ba1e6c31c3..000000000000 --- a/trunk/Documentation/blackfin/cache-lock.txt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * File: Documentation/blackfin/cache-lock.txt - * Based on: - * Author: - * - * Created: - * Description: This file contains the simple DMA Implementation for Blackfin - * - * Rev: $Id: cache-lock.txt 2384 2006-11-01 04:12:43Z magicyang $ - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - */ - -How to lock your code in cache in uClinux/blackfin --------------------------------------------------- - -There are only a few steps required to lock your code into the cache. -Currently you can lock the code by Way. - -Below are the interface provided for locking the cache. - - -1. cache_grab_lock(int Ways); - -This function grab the lock for locking your code into the cache specified -by Ways. - - -2. cache_lock(int Ways); - -This function should be called after your critical code has been executed. -Once the critical code exits, the code is now loaded into the cache. This -function locks the code into the cache. - - -So, the example sequence will be: - - cache_grab_lock(WAY0_L); /* Grab the lock */ - - critical_code(); /* Execute the code of interest */ - - cache_lock(WAY0_L); /* Lock the cache */ - -Where WAY0_L signifies WAY0 locking. diff --git a/trunk/Documentation/blackfin/cachefeatures.txt b/trunk/Documentation/blackfin/cachefeatures.txt deleted file mode 100644 index 0fbec23becb5..000000000000 --- a/trunk/Documentation/blackfin/cachefeatures.txt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * File: Documentation/blackfin/cachefeatures.txt - * Based on: - * Author: - * - * Created: - * Description: This file contains the simple DMA Implementation for Blackfin - * - * Rev: $Id: cachefeatures.txt 2384 2006-11-01 04:12:43Z magicyang $ - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - */ - - - Instruction and Data cache initialization. - icache_init(); - dcache_init(); - - - Instruction and Data cache Invalidation Routines, when flushing the - same is not required. - _icache_invalidate(); - _dcache_invalidate(); - - Also, for invalidating the entire instruction and data cache, the below - routines are provided (another method for invalidation, refer page no 267 and 287 of - ADSP-BF533 Hardware Reference manual) - - invalidate_entire_dcache(); - invalidate_entire_icache(); - - -External Flushing of Instruction and data cache routines. - - flush_instruction_cache(); - flush_data_cache(); - - - Internal Flushing of Instruction and Data Cache. - - icplb_flush(); - dcplb_flush(); - - - Locking the cache. - - cache_grab_lock(); - cache_lock(); - - Please refer linux-2.6.x/Documentation/blackfin/cache-lock.txt for how to - lock the cache. - - Locking the cache is optional feature. - - - Miscellaneous cache functions. - - flush_cache_all(); - flush_cache_mm(); - invalidate_dcache_range(); - flush_dcache_range(); - flush_dcache_page(); - flush_cache_range(); - flush_cache_page(); - invalidate_dcache_range(); - flush_page_to_ram(); - diff --git a/trunk/Documentation/cciss.txt b/trunk/Documentation/cciss.txt index e65736c6b8bc..f74affe5c829 100644 --- a/trunk/Documentation/cciss.txt +++ b/trunk/Documentation/cciss.txt @@ -22,21 +22,14 @@ This driver is known to work with the following cards: * SA E200i * SA E500 -Detecting drive failures: -------------------------- - -To get the status of logical volumes and to detect physical drive -failures, you can use the cciss_vol_status program found here: -http://cciss.sourceforge.net/#cciss_utils - -Device Naming: --------------- - If nodes are not already created in the /dev/cciss directory, run as root: # cd /dev # ./MAKEDEV cciss +Device Naming: +-------------- + You need some entries in /dev for the cciss device. The MAKEDEV script can make device nodes for you automatically. Currently the device setup is as follows: diff --git a/trunk/Documentation/dontdiff b/trunk/Documentation/dontdiff index 64e9f6c4826b..63c2d0c55aa2 100644 --- a/trunk/Documentation/dontdiff +++ b/trunk/Documentation/dontdiff @@ -55,8 +55,8 @@ aic7*seq.h* aicasm aicdb.h* asm -asm-offsets.h -asm_offsets.h +asm-offsets.* +asm_offsets.* autoconf.h* bbootsect bin2c diff --git a/trunk/Documentation/driver-model/devres.txt b/trunk/Documentation/driver-model/devres.txt index 6c8d8f27db34..5163b85308f5 100644 --- a/trunk/Documentation/driver-model/devres.txt +++ b/trunk/Documentation/driver-model/devres.txt @@ -182,7 +182,7 @@ For example, you can do something like the following. ... - devres_close_group(dev, my_midlayer_create_something); + devres_close_group(dev, my_midlayer_something); return 0; } diff --git a/trunk/Documentation/fb/deferred_io.txt b/trunk/Documentation/fb/deferred_io.txt deleted file mode 100644 index 73cf9fb7cf60..000000000000 --- a/trunk/Documentation/fb/deferred_io.txt +++ /dev/null @@ -1,75 +0,0 @@ -Deferred IO ------------ - -Deferred IO is a way to delay and repurpose IO. It uses host memory as a -buffer and the MMU pagefault as a pretrigger for when to perform the device -IO. The following example may be a useful explaination of how one such setup -works: - -- userspace app like Xfbdev mmaps framebuffer -- deferred IO and driver sets up nopage and page_mkwrite handlers -- userspace app tries to write to mmaped vaddress -- we get pagefault and reach nopage handler -- nopage handler finds and returns physical page -- we get page_mkwrite where we add this page to a list -- schedule a workqueue task to be run after a delay -- app continues writing to that page with no additional cost. this is - the key benefit. -- the workqueue task comes in and mkcleans the pages on the list, then - completes the work associated with updating the framebuffer. this is - the real work talking to the device. -- app tries to write to the address (that has now been mkcleaned) -- get pagefault and the above sequence occurs again - -As can be seen from above, one benefit is roughly to allow bursty framebuffer -writes to occur at minimum cost. Then after some time when hopefully things -have gone quiet, we go and really update the framebuffer which would be -a relatively more expensive operation. - -For some types of nonvolatile high latency displays, the desired image is -the final image rather than the intermediate stages which is why it's okay -to not update for each write that is occuring. - -It may be the case that this is useful in other scenarios as well. Paul Mundt -has mentioned a case where it is beneficial to use the page count to decide -whether to coalesce and issue SG DMA or to do memory bursts. - -Another one may be if one has a device framebuffer that is in an usual format, -say diagonally shifting RGB, this may then be a mechanism for you to allow -apps to pretend to have a normal framebuffer but reswizzle for the device -framebuffer at vsync time based on the touched pagelist. - -How to use it: (for applications) ---------------------------------- -No changes needed. mmap the framebuffer like normal and just use it. - -How to use it: (for fbdev drivers) ----------------------------------- -The following example may be helpful. - -1. Setup your structure. Eg: - -static struct fb_deferred_io hecubafb_defio = { - .delay = HZ, - .deferred_io = hecubafb_dpy_deferred_io, -}; - -The delay is the minimum delay between when the page_mkwrite trigger occurs -and when the deferred_io callback is called. The deferred_io callback is -explained below. - -2. Setup your deferred IO callback. Eg: -static void hecubafb_dpy_deferred_io(struct fb_info *info, - struct list_head *pagelist) - -The deferred_io callback is where you would perform all your IO to the display -device. You receive the pagelist which is the list of pages that were written -to during the delay. You must not modify this list. This callback is called -from a workqueue. - -3. Call init - info->fbdefio = &hecubafb_defio; - fb_deferred_io_init(info); - -4. Call cleanup - fb_deferred_io_cleanup(info); diff --git a/trunk/Documentation/fb/s3fb.txt b/trunk/Documentation/fb/s3fb.txt index 2c97770bdbaa..8a04c0da0c91 100644 --- a/trunk/Documentation/fb/s3fb.txt +++ b/trunk/Documentation/fb/s3fb.txt @@ -35,12 +35,10 @@ Supported Features * suspend/resume support * DPMS support -Text mode is supported even in higher resolutions, but there is limitation to -lower pixclocks (maximum usually between 50-60 MHz, depending on specific -hardware, i get best results from plain S3 Trio32 card - about 75 MHz). This -limitation is not enforced by driver. Text mode supports 8bit wide fonts only -(hardware limitation) and 16bit tall fonts (driver limitation). Text mode -support is broken on S3 Trio64 V2/DX. +Text mode is supported even in higher resolutions, but there is limitation +to lower pixclocks (maximum between 50-60 MHz, depending on specific hardware). +This limitation is not enforced by driver. Text mode supports 8bit wide fonts +only (hardware limitation) and 16bit tall fonts (driver limitation). There are two 4 bpp modes. First mode (selected if nonstd == 0) is mode with packed pixels, high nibble first. Second mode (selected if nonstd == 1) is mode @@ -75,8 +73,6 @@ Known bugs ========== * cursor disable in text mode doesn't work - * text mode broken on S3 Trio64 V2/DX - -- Ondrej Zajicek diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 676b7981adb7..5c88ba1ea262 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -6,14 +6,6 @@ be removed from this file. --------------------------- -What: MXSER -When: December 2007 -Why: Old mxser driver is obsoleted by the mxser_new. Give it some time yet - and remove it. -Who: Jiri Slaby - ---------------------------- - What: V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP When: October 2007 Why: Broken attempt to set MPEG compression parameters. These ioctls are @@ -59,15 +51,6 @@ Who: Dan Dennedy , Stefan Richter --------------------------- -What: old NCR53C9x driver -When: October 2007 -Why: Replaced by the much better esp_scsi driver. Actual low-level - driver can ported over almost trivially. -Who: David Miller - Christoph Hellwig - ---------------------------- - What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. When: December 2006 Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6 @@ -134,6 +117,25 @@ Who: Adrian Bunk --------------------------- +What: pci_module_init(driver) +When: January 2007 +Why: Is replaced by pci_register_driver(pci_driver). +Who: Richard Knutsson and Greg Kroah-Hartman + +--------------------------- + +What: Usage of invalid timevals in setitimer +When: March 2007 +Why: POSIX requires to validate timevals in the setitimer call. This + was never done by Linux. The invalid (e.g. negative timevals) were + silently converted to more or less random timeouts and intervals. + Until the removal a per boot limited number of warnings is printed + and the timevals are sanitized. + +Who: Thomas Gleixner + +--------------------------- + What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports (temporary transition config option provided until then) The transition config option will also be removed at the same time. @@ -161,7 +163,7 @@ Who: Greg Kroah-Hartman --------------------------- What: Interrupt only SA_* flags -When: September 2007 +When: Januar 2007 Why: The interrupt related SA_* flags are replaced by IRQF_* to move them out of the signal namespace. @@ -188,10 +190,18 @@ Who: Jean Delvare --------------------------- -What: i2c_adapter.list +What: i2c_adapter.dev + i2c_adapter.list When: July 2007 -Why: Superfluous, this list duplicates the one maintained by the driver - core. +Why: Superfluous, given i2c_adapter.class_dev: + * The "dev" was a stand-in for the physical device node that legacy + drivers would not have; but now it's almost always present. Any + remaining legacy drivers must upgrade (they now trigger warnings). + * The "list" duplicates class device children. + The delay in removing this is so upgraded lm_sensors and libsensors + can get deployed. (Removal causes minor changes in the sysfs layout, + notably the location of the adapter type name and parenting the i2c + client hardware directly from their controller.) Who: Jean Delvare , David Brownell @@ -304,35 +314,3 @@ Why: Code was merged, then submitter immediately disappeared leaving Who: David S. Miller --------------------------- - -What: read_dev_chars(), read_conf_data{,_lpm}() (s390 common I/O layer) -When: December 2007 -Why: These functions are a leftover from 2.4 times. They have several - problems: - - Duplication of checks that are done in the device driver's - interrupt handler - - common I/O layer can't do device specific error recovery - - device driver can't be notified for conditions happening during - execution of the function - Device drivers should issue the read device characteristics and read - configuration data ccws and do the appropriate error handling - themselves. -Who: Cornelia Huck - ---------------------------- - -What: i2c-ixp2000, i2c-ixp4xx and scx200_i2c drivers -When: September 2007 -Why: Obsolete. The new i2c-gpio driver replaces all hardware-specific - I2C-over-GPIO drivers. -Who: Jean Delvare - ---------------------------- - -What: drivers depending on OSS_OBSOLETE -When: options in 2.6.23, code in 2.6.25 -Why: obsolete OSS drivers -Who: Adrian Bunk - ---------------------------- - diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index 59c14159cc47..28bfea75bcf2 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -15,7 +15,6 @@ prototypes: int (*d_delete)(struct dentry *); void (*d_release)(struct dentry *); void (*d_iput)(struct dentry *, struct inode *); - char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); locking rules: none have BKL @@ -26,7 +25,6 @@ d_compare: no yes no no d_delete: yes no yes no d_release: no no no yes d_iput: no no no yes -d_dname: no no no no --------------------------- inode_operations --------------------------- prototypes: diff --git a/trunk/Documentation/filesystems/jfs.txt b/trunk/Documentation/filesystems/jfs.txt index 26ebde77e821..bae128663748 100644 --- a/trunk/Documentation/filesystems/jfs.txt +++ b/trunk/Documentation/filesystems/jfs.txt @@ -29,13 +29,7 @@ errors=continue Keep going on a filesystem error. errors=remount-ro Default. Remount the filesystem read-only on an error. errors=panic Panic and halt the machine if an error occurs. -uid=value Override on-disk uid with specified value -gid=value Override on-disk gid with specified value -umask=value Override on-disk umask with specified octal value. For - directories, the execute bit will be set if the corresponding - read bit is set. - -Please send bugs, comments, cards and letters to shaggy@linux.vnet.ibm.com. +Please send bugs, comments, cards and letters to shaggy@austin.ibm.com. The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe" at our web page http://jfs.sourceforge.net/ diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index 4f3e84c520a5..7aaf09b86a55 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -122,22 +122,21 @@ subdirectory has the entries listed in Table 1-1. Table 1-1: Process specific entries in /proc .............................................................................. - File Content - clear_refs Clears page referenced bits shown in smaps output - cmdline Command line arguments - cpu Current and last cpu in which it was executed (2.4)(smp) - cwd Link to the current working directory - environ Values of environment variables - exe Link to the executable of this process - fd Directory, which contains all file descriptors - maps Memory maps to executables and library files (2.4) - mem Memory held by this process - root Link to the root directory of this process - stat Process status - statm Process memory status information - status Process status in human readable form - wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan - smaps Extension based on maps, the rss size for each mapped file + File Content + cmdline Command line arguments + cpu Current and last cpu in which it was executed (2.4)(smp) + cwd Link to the current working directory + environ Values of environment variables + exe Link to the executable of this process + fd Directory, which contains all file descriptors + maps Memory maps to executables and library files (2.4) + mem Memory held by this process + root Link to the root directory of this process + stat Process status + statm Process memory status information + status Process status in human readable form + wchan If CONFIG_KALLSYMS is set, a pre-decoded wchan + smaps Extension based on maps, presenting the rss size for each mapped file .............................................................................. For example, to get the status information of a process, all you have to do is @@ -1138,13 +1137,6 @@ determine whether or not they are still functioning properly. Because the NMI watchdog shares registers with oprofile, by disabling the NMI watchdog, oprofile may have more registers to utilize. -maps_protect ------------- - -Enables/Disables the protection of the per-process proc entries "maps" and -"smaps". When enabled, the contents of these files are visible only to -readers that are allowed to ptrace() the given process. - 2.4 /proc/sys/vm - The virtual memory subsystem ----------------------------------------------- diff --git a/trunk/Documentation/filesystems/vfat.txt b/trunk/Documentation/filesystems/vfat.txt index fcc123ffa252..069cb1094300 100644 --- a/trunk/Documentation/filesystems/vfat.txt +++ b/trunk/Documentation/filesystems/vfat.txt @@ -57,13 +57,6 @@ nonumtail= -- When creating 8.3 aliases, normally the alias will currently exist in the directory, 'longfile.txt' will be the short alias instead of 'longfi~1.txt'. -usefree -- Use the "free clusters" value stored on FSINFO. It'll - be used to determine number of free clusters without - scanning disk. But it's not used by default, because - recent Windows don't update it correctly in some - case. If you are sure the "free clusters" on FSINFO is - correct, by this option you can avoid scanning disk. - quiet -- Stops printing certain warning messages. check=s|r|n -- Case sensitivity checking setting. diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index a47cc819f37b..ea271f2d3954 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -827,7 +827,7 @@ This describes how a filesystem can overload the standard dentry operations. Dentries and the dcache are the domain of the VFS and the individual filesystem implementations. Device drivers have no business here. These methods may be set to NULL, as they are either optional or -the VFS uses a default. As of kernel 2.6.22, the following members are +the VFS uses a default. As of kernel 2.6.13, the following members are defined: struct dentry_operations { @@ -837,7 +837,6 @@ struct dentry_operations { int (*d_delete)(struct dentry *); void (*d_release)(struct dentry *); void (*d_iput)(struct dentry *, struct inode *); - char *(*d_dname)(struct dentry *, char *, int); }; d_revalidate: called when the VFS needs to revalidate a dentry. This @@ -860,26 +859,6 @@ struct dentry_operations { VFS calls iput(). If you define this method, you must call iput() yourself - d_dname: called when the pathname of a dentry should be generated. - Usefull for some pseudo filesystems (sockfs, pipefs, ...) to delay - pathname generation. (Instead of doing it when dentry is created, - its done only when the path is needed.). Real filesystems probably - dont want to use it, because their dentries are present in global - dcache hash, so their hash should be an invariant. As no lock is - held, d_dname() should not try to modify the dentry itself, unless - appropriate SMP safety is used. CAUTION : d_path() logic is quite - tricky. The correct way to return for example "Hello" is to put it - at the end of the buffer, and returns a pointer to the first char. - dynamic_dname() helper function is provided to take care of this. - -Example : - -static char *pipefs_dname(struct dentry *dent, char *buffer, int buflen) -{ - return dynamic_dname(dentry, buffer, buflen, "pipe:[%lu]", - dentry->d_inode->i_ino); -} - Each dentry has a pointer to its parent dentry, as well as a hash list of child dentries. Child dentries are basically like files in a directory. diff --git a/trunk/Documentation/hwmon/coretemp b/trunk/Documentation/hwmon/coretemp deleted file mode 100644 index 870cda9416e9..000000000000 --- a/trunk/Documentation/hwmon/coretemp +++ /dev/null @@ -1,36 +0,0 @@ -Kernel driver coretemp -====================== - -Supported chips: - * All Intel Core family - Prefix: 'coretemp' - CPUID: family 0x6, models 0xe, 0xf - Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 3A: System Programming Guide - -Author: Rudolf Marek - -Description ------------ - -This driver permits reading temperature sensor embedded inside Intel Core CPU. -Temperature is measured in degrees Celsius and measurement resolution is -1 degree C. Valid temperatures are from 0 to TjMax degrees C, because -the actual value of temperature register is in fact a delta from TjMax. - -Temperature known as TjMax is the maximum junction temperature of processor. -Intel defines this temperature as 85C or 100C. At this temperature, protection -mechanism will perform actions to forcibly cool down the processor. Alarm -may be raised, if the temperature grows enough (more than TjMax) to trigger -the Out-Of-Spec bit. Following table summarizes the exported sysfs files: - -temp1_input - Core temperature (in millidegrees Celsius). -temp1_crit - Maximum junction temperature (in millidegrees Celsius). -temp1_crit_alarm - Set when Out-of-spec bit is set, never clears. - Correct CPU operation is no longer guaranteed. -temp1_label - Contains string "Core X", where X is processor - number. - -The TjMax temperature is set to 85 degrees C if undocumented model specific -register (UMSR) 0xee has bit 30 set. If not the TjMax is 100 degrees C as -(sometimes) documented in processor datasheet. diff --git a/trunk/Documentation/hwmon/max6650 b/trunk/Documentation/hwmon/max6650 deleted file mode 100644 index 8be7beb9e3e8..000000000000 --- a/trunk/Documentation/hwmon/max6650 +++ /dev/null @@ -1,53 +0,0 @@ -Kernel driver max6650 -===================== - -Supported chips: - * Maxim 6650 / 6651 - Prefix: 'max6650' - Addresses scanned: I2C 0x1b, 0x1f, 0x48, 0x4b - Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf - -Authors: - Hans J. Koch - John Morris - Claus Gindhart - -Description ------------ - -This driver implements support for the Maxim 6650/6651 - -The 2 devices are very similar, but the Maxim 6550 has a reduced feature -set, e.g. only one fan-input, instead of 4 for the 6651. - -The driver is not able to distinguish between the 2 devices. - -The driver provides the following sensor accesses in sysfs: - -fan1_input ro fan tachometer speed in RPM -fan2_input ro " -fan3_input ro " -fan4_input ro " -fan1_target rw desired fan speed in RPM (closed loop mode only) -pwm1_enable rw regulator mode, 0=full on, 1=open loop, 2=closed loop -pwm1 rw relative speed (0-255), 255=max. speed. - Used in open loop mode only. -fan1_div rw sets the speed range the inputs can handle. Legal - values are 1, 2, 4, and 8. Use lower values for - faster fans. - -Module parameters ------------------ - -If your board has a BIOS that initializes the MAX6650/6651 correctly, you can -simply load your module without parameters. It won't touch the configuration -registers then. If your board BIOS doesn't initialize the chip, or you want -different settings, you can set the following parameters: - -voltage_12V: 5=5V fan, 12=12V fan, 0=don't change -prescaler: Possible values are 1,2,4,8,16, or 0 for don't change -clock: The clock frequency in Hz of the chip the driver should assume [254000] - -Please have a look at the MAX6650/6651 data sheet and make sure that you fully -understand the meaning of these parameters before you attempt to change them. - diff --git a/trunk/Documentation/hwmon/smsc47m1 b/trunk/Documentation/hwmon/smsc47m1 index 42c8431b3c9d..04a11124f667 100644 --- a/trunk/Documentation/hwmon/smsc47m1 +++ b/trunk/Documentation/hwmon/smsc47m1 @@ -14,10 +14,6 @@ Supported chips: http://www.smsc.com/main/datasheets/47m14x.pdf http://www.smsc.com/main/tools/discontinued/47m15x.pdf http://www.smsc.com/main/datasheets/47m192.pdf - * SMSC LPC47M292 - Addresses scanned: none, address read from Super I/O config space - Prefix: 'smsc47m2' - Datasheet: Not public * SMSC LPC47M997 Addresses scanned: none, address read from Super I/O config space Prefix: 'smsc47m1' @@ -36,10 +32,9 @@ Description The Standard Microsystems Corporation (SMSC) 47M1xx Super I/O chips contain monitoring and PWM control circuitry for two fans. -The LPC47M15x, LPC47M192 and LPC47M292 chips contain a full 'hardware -monitoring block' in addition to the fan monitoring and control. The -hardware monitoring block is not supported by this driver, use the -smsc47m192 driver for that. +The 47M15x and 47M192 chips contain a full 'hardware monitoring block' +in addition to the fan monitoring and control. The hardware monitoring +block is not supported by the driver. No documentation is available for the 47M997, but it has the same device ID as the 47M15x and 47M192 chips and seems to be compatible. diff --git a/trunk/Documentation/hwmon/smsc47m192 b/trunk/Documentation/hwmon/smsc47m192 index 6d54ecb7b3f8..45d6453cd435 100644 --- a/trunk/Documentation/hwmon/smsc47m192 +++ b/trunk/Documentation/hwmon/smsc47m192 @@ -2,13 +2,12 @@ Kernel driver smsc47m192 ======================== Supported chips: - * SMSC LPC47M192, LPC47M15x, LPC47M292 and LPC47M997 + * SMSC LPC47M192 and LPC47M997 Prefix: 'smsc47m192' Addresses scanned: I2C 0x2c - 0x2d Datasheet: The datasheet for LPC47M192 is publicly available from http://www.smsc.com/ - The LPC47M15x, LPC47M292 and LPC47M997 are compatible for - hardware monitoring. + The LPC47M997 is compatible for hardware monitoring. Author: Hartmut Rick Special thanks to Jean Delvare for careful checking @@ -19,7 +18,7 @@ Description ----------- This driver implements support for the hardware sensor capabilities -of the SMSC LPC47M192 and compatible Super-I/O chips. +of the SMSC LPC47M192 and LPC47M997 Super-I/O chips. These chips support 3 temperature channels and 8 voltage inputs as well as CPU voltage VID input. diff --git a/trunk/Documentation/hwmon/sysfs-interface b/trunk/Documentation/hwmon/sysfs-interface index a9a18ad0d17a..d73d2e8c7534 100644 --- a/trunk/Documentation/hwmon/sysfs-interface +++ b/trunk/Documentation/hwmon/sysfs-interface @@ -152,13 +152,6 @@ fan[1-*]_div Fan divisor. Note that this is actually an internal clock divisor, which affects the measurable speed range, not the read value. -fan[1-*]_target - Desired fan speed - Unit: revolution/min (RPM) - RW - Only makes sense if the chip supports closed-loop fan speed - control based on the measured fan speed. - Also see the Alarms section for status flags associated with fans. diff --git a/trunk/Documentation/i2c/busses/i2c-nforce2 b/trunk/Documentation/i2c/busses/i2c-nforce2 index fae3495bcbaf..7f61fbc03f7f 100644 --- a/trunk/Documentation/i2c/busses/i2c-nforce2 +++ b/trunk/Documentation/i2c/busses/i2c-nforce2 @@ -9,8 +9,6 @@ Supported adapters: * nForce4 MCP-04 10de:0034 * nForce4 MCP51 10de:0264 * nForce4 MCP55 10de:0368 - * nForce4 MCP61 10de:03EB - * nForce4 MCP65 10de:0446 Datasheet: not publicly available, but seems to be similar to the AMD-8111 SMBus 2.0 adapter. diff --git a/trunk/Documentation/i2c/porting-clients b/trunk/Documentation/i2c/porting-clients index 7bf82c08f6ca..ca272b263a92 100644 --- a/trunk/Documentation/i2c/porting-clients +++ b/trunk/Documentation/i2c/porting-clients @@ -1,4 +1,4 @@ -Revision 7, 2007-04-19 +Revision 6, 2005-11-20 Jean Delvare Greg KH @@ -20,10 +20,6 @@ yours for best results. Technical changes: -* [Driver type] Any driver that was relying on i2c-isa has to be - converted to a proper isa, platform or pci driver. This is not - covered by this guide. - * [Includes] Get rid of "version.h" and . Includes typically look like that: #include @@ -31,10 +27,12 @@ Technical changes: #include #include #include + #include /* for ISA drivers */ #include /* for hardware monitoring drivers */ #include #include /* if you need VRM support */ #include /* for class registration */ + #include /* if you have I/O operations */ Please respect this inclusion order. Some extra headers may be required for a given driver (e.g. "lm75.h"). @@ -71,16 +69,20 @@ Technical changes: sensors mailing list by providing a patch to the Documentation/hwmon/sysfs-interface file. -* [Attach] The attach function should make sure that the adapter's - class has I2C_CLASS_HWMON (or whatever class is suitable for your - driver), using the following construct: +* [Attach] For I2C drivers, the attach function should make sure + that the adapter's class has I2C_CLASS_HWMON (or whatever class is + suitable for your driver), using the following construct: if (!(adapter->class & I2C_CLASS_HWMON)) return 0; + ISA-only drivers of course don't need this. Call i2c_probe() instead of i2c_detect(). * [Detect] As mentioned earlier, the flags parameter is gone. The type_name and client_name strings are replaced by a single name string, which will be filled with a lowercase, short string. + In i2c-only drivers, drop the i2c_is_isa_adapter check, it's + useless. Same for isa-only drivers, as the test would always be + true. Only hybrid drivers (which are quite rare) still need it. The labels used for error paths are reduced to the number needed. It is advised that the labels are given descriptive names such as exit and exit_free. Don't forget to properly set err before diff --git a/trunk/Documentation/i2c/summary b/trunk/Documentation/i2c/summary index aea60bf7e8f0..41dde8776791 100644 --- a/trunk/Documentation/i2c/summary +++ b/trunk/Documentation/i2c/summary @@ -4,23 +4,17 @@ I2C and SMBus ============= I2C (pronounce: I squared C) is a protocol developed by Philips. It is a -slow two-wire protocol (variable speed, up to 400 kHz), with a high speed -extension (3.4 MHz). It provides an inexpensive bus for connecting many -types of devices with infrequent or low bandwidth communications needs. -I2C is widely used with embedded systems. Some systems use variants that -don't meet branding requirements, and so are not advertised as being I2C. +slow two-wire protocol (10-400 kHz), but it suffices for many types of +devices. -SMBus (System Management Bus) is based on the I2C protocol, and is mostly -a subset of I2C protocols and signaling. Many I2C devices will work on an -SMBus, but some SMBus protocols add semantics beyond what is required to -achieve I2C branding. Modern PC mainboards rely on SMBus. The most common -devices connected through SMBus are RAM modules configured using I2C EEPROMs, -and hardware monitoring chips. +SMBus (System Management Bus) is a subset of the I2C protocol. Many +modern mainboards have a System Management Bus. There are a lot of +devices which can be connected to a SMBus; the most notable are modern +memory chips with EEPROM memories and chips for hardware monitoring. -Because the SMBus is mostly a subset of the generalized I2C bus, we can -use its protocols on many I2C systems. However, there are systems that don't -meet both SMBus and I2C electrical constraints; and others which can't -implement all the common SMBus protocol semantics or messages. +Because the SMBus is just a special case of the generalized I2C bus, we +can simulate the SMBus protocol on plain I2C busses. The reverse is +regretfully impossible. Terminology @@ -35,7 +29,6 @@ When we talk about I2C, we use the following terms: An Algorithm driver contains general code that can be used for a whole class of I2C adapters. Each specific adapter driver depends on one algorithm driver. - A Driver driver (yes, this sounds ridiculous, sorry) contains the general code to access some type of device. Each detected device gets its own data in the Client structure. Usually, Driver and Client are more closely @@ -47,10 +40,6 @@ a separate Adapter and Algorithm driver), and drivers for your I2C devices in this package. See the lm_sensors project http://www.lm-sensors.nu for device drivers. -At this time, Linux only operates I2C (or SMBus) in master mode; you can't -use these APIs to make a Linux system behave as a slave/device, either to -speak a custom protocol or to emulate some other device. - Included Bus Drivers ==================== diff --git a/trunk/Documentation/i2c/writing-clients b/trunk/Documentation/i2c/writing-clients index 3d8d36b0ad12..fbcff96f4ca1 100644 --- a/trunk/Documentation/i2c/writing-clients +++ b/trunk/Documentation/i2c/writing-clients @@ -1,5 +1,5 @@ This is a small guide for those who want to write kernel drivers for I2C -or SMBus devices, using Linux as the protocol host/master (not slave). +or SMBus devices. To set up a driver, you need to do several things. Some are optional, and some things can be done slightly or completely different. Use this as a @@ -29,16 +29,8 @@ static struct i2c_driver foo_driver = { .driver = { .name = "foo", }, - - /* iff driver uses driver model ("new style") binding model: */ - .probe = foo_probe, - .remove = foo_remove, - - /* else, driver uses "legacy" binding model: */ .attach_adapter = foo_attach_adapter, .detach_client = foo_detach_client, - - /* these may be used regardless of the driver binding model */ .shutdown = foo_shutdown, /* optional */ .suspend = foo_suspend, /* optional */ .resume = foo_resume, /* optional */ @@ -48,8 +40,7 @@ static struct i2c_driver foo_driver = { The name field is the driver name, and must not contain spaces. It should match the module name (if the driver can be compiled as a module), although you can use MODULE_ALIAS (passing "foo" in this example) to add -another name for the module. If the driver name doesn't match the module -name, the module won't be automatically loaded (hotplug/coldplug). +another name for the module. All other fields are for call-back functions which will be explained below. @@ -74,13 +65,16 @@ An example structure is below. struct foo_data { struct i2c_client client; + struct semaphore lock; /* For ISA access in `sensors' drivers. */ + int sysctl_id; /* To keep the /proc directory entry for + `sensors' drivers. */ enum chips type; /* To keep the chips type for `sensors' drivers. */ /* Because the i2c bus is slow, it is often useful to cache the read information of a chip for some time (for example, 1 or 2 seconds). It depends of course on the device whether this is really worthwhile or even sensible. */ - struct mutex update_lock; /* When we are reading lots of information, + struct semaphore update_lock; /* When we are reading lots of information, another process should not update the below information */ char valid; /* != 0 if the following fields are valid. */ @@ -101,7 +95,8 @@ some obscure clients). But we need generic reading and writing routines. I have found it useful to define foo_read and foo_write function for this. For some cases, it will be easier to call the i2c functions directly, but many chips have some kind of register-value idea that can easily -be encapsulated. +be encapsulated. Also, some chips have both ISA and I2C interfaces, and +it useful to abstract from this (only for `sensors' drivers). The below functions are simple examples, and should not be copied literally. @@ -124,101 +119,28 @@ literally. return i2c_smbus_write_word_data(client,reg,value); } +For sensors code, you may have to cope with ISA registers too. Something +like the below often works. Note the locking! + + int foo_read_value(struct i2c_client *client, u8 reg) + { + int res; + if (i2c_is_isa_client(client)) { + down(&(((struct foo_data *) (client->data)) -> lock)); + outb_p(reg,client->addr + FOO_ADDR_REG_OFFSET); + res = inb_p(client->addr + FOO_DATA_REG_OFFSET); + up(&(((struct foo_data *) (client->data)) -> lock)); + return res; + } else + return i2c_smbus_read_byte_data(client,reg); + } + +Writing is done the same way. + Probing and attaching ===================== -The Linux I2C stack was originally written to support access to hardware -monitoring chips on PC motherboards, and thus it embeds some assumptions -that are more appropriate to SMBus (and PCs) than to I2C. One of these -assumptions is that most adapters and devices drivers support the SMBUS_QUICK -protocol to probe device presence. Another is that devices and their drivers -can be sufficiently configured using only such probe primitives. - -As Linux and its I2C stack became more widely used in embedded systems -and complex components such as DVB adapters, those assumptions became more -problematic. Drivers for I2C devices that issue interrupts need more (and -different) configuration information, as do drivers handling chip variants -that can't be distinguished by protocol probing, or which need some board -specific information to operate correctly. - -Accordingly, the I2C stack now has two models for associating I2C devices -with their drivers: the original "legacy" model, and a newer one that's -fully compatible with the Linux 2.6 driver model. These models do not mix, -since the "legacy" model requires drivers to create "i2c_client" device -objects after SMBus style probing, while the Linux driver model expects -drivers to be given such device objects in their probe() routines. - - -Standard Driver Model Binding ("New Style") -------------------------------------------- - -System infrastructure, typically board-specific initialization code or -boot firmware, reports what I2C devices exist. For example, there may be -a table, in the kernel or from the boot loader, identifying I2C devices -and linking them to board-specific configuration information about IRQs -and other wiring artifacts, chip type, and so on. That could be used to -create i2c_client objects for each I2C device. - -I2C device drivers using this binding model work just like any other -kind of driver in Linux: they provide a probe() method to bind to -those devices, and a remove() method to unbind. - - static int foo_probe(struct i2c_client *client); - static int foo_remove(struct i2c_client *client); - -Remember that the i2c_driver does not create those client handles. The -handle may be used during foo_probe(). If foo_probe() reports success -(zero not a negative status code) it may save the handle and use it until -foo_remove() returns. That binding model is used by most Linux drivers. - -Drivers match devices when i2c_client.driver_name and the driver name are -the same; this approach is used in several other busses that don't have -device typing support in the hardware. The driver and module name should -match, so hotplug/coldplug mechanisms will modprobe the driver. - - -Device Creation (Standard driver model) ---------------------------------------- - -If you know for a fact that an I2C device is connected to a given I2C bus, -you can instantiate that device by simply filling an i2c_board_info -structure with the device address and driver name, and calling -i2c_new_device(). This will create the device, then the driver core will -take care of finding the right driver and will call its probe() method. -If a driver supports different device types, you can specify the type you -want using the type field. You can also specify an IRQ and platform data -if needed. - -Sometimes you know that a device is connected to a given I2C bus, but you -don't know the exact address it uses. This happens on TV adapters for -example, where the same driver supports dozens of slightly different -models, and I2C device addresses change from one model to the next. In -that case, you can use the i2c_new_probed_device() variant, which is -similar to i2c_new_device(), except that it takes an additional list of -possible I2C addresses to probe. A device is created for the first -responsive address in the list. If you expect more than one device to be -present in the address range, simply call i2c_new_probed_device() that -many times. - -The call to i2c_new_device() or i2c_new_probed_device() typically happens -in the I2C bus driver. You may want to save the returned i2c_client -reference for later use. - - -Device Deletion (Standard driver model) ---------------------------------------- - -Each I2C device which has been created using i2c_new_device() or -i2c_new_probed_device() can be unregistered by calling -i2c_unregister_device(). If you don't call it explicitly, it will be -called automatically before the underlying I2C bus itself is removed, as a -device can't survive its parent in the device driver model. - - -Legacy Driver Binding Model ---------------------------- - Most i2c devices can be present on several i2c addresses; for some this is determined in hardware (by soldering some chip pins to Vcc or Ground), for others this can be changed in software (by writing to specific client @@ -235,9 +157,13 @@ detection algorithm. You do not have to use this parameter interface; but don't try to use function i2c_probe() if you don't. +NOTE: If you want to write a `sensors' driver, the interface is slightly + different! See below. + -Probing classes (Legacy model) ------------------------------- + +Probing classes +--------------- All parameters are given as lists of unsigned 16-bit integers. Lists are terminated by I2C_CLIENT_END. @@ -284,8 +210,8 @@ Note that you *have* to call the defined variable `normal_i2c', without any prefix! -Attaching to an adapter (Legacy model) --------------------------------------- +Attaching to an adapter +----------------------- Whenever a new adapter is inserted, or for all adapters if the driver is being registered, the callback attach_adapter() is called. Now is the @@ -311,13 +237,17 @@ them (unless a `force' parameter was used). In addition, addresses that are already in use (by some other registered client) are skipped. -The detect client function (Legacy model) ------------------------------------------ +The detect client function +-------------------------- The detect client function is called by i2c_probe. The `kind' parameter contains -1 for a probed detection, 0 for a forced detection, or a positive number for a forced detection with a chip type forced. +Below, some things are only needed if this is a `sensors' driver. Those +parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */ +markers. + Returning an error different from -ENODEV in a detect function will cause the detection to stop: other addresses and adapters won't be scanned. This should only be done on fatal or internal errors, such as a memory @@ -326,20 +256,64 @@ shortage or i2c_attach_client failing. For now, you can ignore the `flags' parameter. It is there for future use. int foo_detect_client(struct i2c_adapter *adapter, int address, - int kind) + unsigned short flags, int kind) { int err = 0; int i; - struct i2c_client *client; + struct i2c_client *new_client; struct foo_data *data; - const char *name = ""; + const char *client_name = ""; /* For non-`sensors' drivers, put the real + name here! */ /* Let's see whether this adapter can support what we need. - Please substitute the things you need here! */ + Please substitute the things you need here! + For `sensors' drivers, add `! is_isa &&' to the if statement */ if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_WRITE_BYTE)) goto ERROR0; + /* SENSORS ONLY START */ + const char *type_name = ""; + int is_isa = i2c_is_isa_adapter(adapter); + + /* Do this only if the chip can additionally be found on the ISA bus + (hybrid chip). */ + + if (is_isa) { + + /* Discard immediately if this ISA range is already used */ + /* FIXME: never use check_region(), only request_region() */ + if (check_region(address,FOO_EXTENT)) + goto ERROR0; + + /* Probe whether there is anything on this address. + Some example code is below, but you will have to adapt this + for your own driver */ + + if (kind < 0) /* Only if no force parameter was used */ { + /* We may need long timeouts at least for some chips. */ + #define REALLY_SLOW_IO + i = inb_p(address + 1); + if (inb_p(address + 2) != i) + goto ERROR0; + if (inb_p(address + 3) != i) + goto ERROR0; + if (inb_p(address + 7) != i) + goto ERROR0; + #undef REALLY_SLOW_IO + + /* Let's just hope nothing breaks here */ + i = inb_p(address + 5) & 0x7f; + outb_p(~i & 0x7f,address+5); + if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { + outb_p(i,address+5); + return 0; + } + } + } + + /* SENSORS ONLY END */ + /* OK. For now, we presume we have a valid client. We now create the client structure, even though we cannot fill it completely yet. But it allows us to access several i2c functions safely */ @@ -349,12 +323,13 @@ For now, you can ignore the `flags' parameter. It is there for future use. goto ERROR0; } - client = &data->client; - i2c_set_clientdata(client, data); + new_client = &data->client; + i2c_set_clientdata(new_client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &foo_driver; + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &foo_driver; + new_client->flags = 0; /* Now, we do the remaining detection. If no `force' parameter is used. */ @@ -362,17 +337,19 @@ For now, you can ignore the `flags' parameter. It is there for future use. parameter was used. */ if (kind < 0) { /* The below is of course bogus */ - if (foo_read(client, FOO_REG_GENERIC) != FOO_GENERIC_VALUE) + if (foo_read(new_client,FOO_REG_GENERIC) != FOO_GENERIC_VALUE) goto ERROR1; } + /* SENSORS ONLY START */ + /* Next, specific detection. This is especially important for `sensors' devices. */ /* Determine the chip type. Not needed if a `force_CHIPTYPE' parameter was used. */ if (kind <= 0) { - i = foo_read(client, FOO_REG_CHIPTYPE); + i = foo_read(new_client,FOO_REG_CHIPTYPE); if (i == FOO_TYPE_1) kind = chip1; /* As defined in the enum */ else if (i == FOO_TYPE_2) @@ -386,31 +363,63 @@ For now, you can ignore the `flags' parameter. It is there for future use. /* Now set the type and chip names */ if (kind == chip1) { - name = "chip1"; + type_name = "chip1"; /* For /proc entry */ + client_name = "CHIP 1"; } else if (kind == chip2) { - name = "chip2"; + type_name = "chip2"; /* For /proc entry */ + client_name = "CHIP 2"; } + /* Reserve the ISA region */ + if (is_isa) + request_region(address,FOO_EXTENT,type_name); + + /* SENSORS ONLY END */ + /* Fill in the remaining client fields. */ - strlcpy(client->name, name, I2C_NAME_SIZE); + strcpy(new_client->name,client_name); + + /* SENSORS ONLY BEGIN */ data->type = kind; - mutex_init(&data->update_lock); /* Only if you use this field */ + /* SENSORS ONLY END */ - /* Any other initializations in data must be done here too. */ + data->valid = 0; /* Only if you use this field */ + init_MUTEX(&data->update_lock); /* Only if you use this field */ - /* This function can write default values to the client registers, if - needed. */ - foo_init_client(client); + /* Any other initializations in data must be done here too. */ /* Tell the i2c layer a new client has arrived */ - if ((err = i2c_attach_client(client))) - goto ERROR1; + if ((err = i2c_attach_client(new_client))) + goto ERROR3; + + /* SENSORS ONLY BEGIN */ + /* Register a new directory entry with module sensors. See below for + the `template' structure. */ + if ((i = i2c_register_entry(new_client, type_name, + foo_dir_table_template,THIS_MODULE)) < 0) { + err = i; + goto ERROR4; + } + data->sysctl_id = i; + + /* SENSORS ONLY END */ + /* This function can write default values to the client registers, if + needed. */ + foo_init_client(new_client); return 0; /* OK, this is not exactly good programming practice, usually. But it is very code-efficient in this case. */ + ERROR4: + i2c_detach_client(new_client); + ERROR3: + ERROR2: + /* SENSORS ONLY START */ + if (is_isa) + release_region(address,FOO_EXTENT); + /* SENSORS ONLY END */ ERROR1: kfree(data); ERROR0: @@ -418,8 +427,8 @@ For now, you can ignore the `flags' parameter. It is there for future use. } -Removing the client (Legacy model) -================================== +Removing the client +=================== The detach_client call back function is called when a client should be removed. It may actually fail, but only when panicking. This code is @@ -427,12 +436,22 @@ much simpler than the attachment code, fortunately! int foo_detach_client(struct i2c_client *client) { - int err; + int err,i; + + /* SENSORS ONLY START */ + /* Deregister with the `i2c-proc' module. */ + i2c_deregister_entry(((struct lm78_data *)(client->data))->sysctl_id); + /* SENSORS ONLY END */ /* Try to detach the client from i2c space */ if ((err = i2c_detach_client(client))) return err; + /* HYBRID SENSORS CHIP ONLY START */ + if i2c_is_isa_client(client) + release_region(client->addr,LM78_EXTENT); + /* HYBRID SENSORS CHIP ONLY END */ + kfree(i2c_get_clientdata(client)); return 0; } @@ -445,34 +464,45 @@ When the kernel is booted, or when your foo driver module is inserted, you have to do some initializing. Fortunately, just attaching (registering) the driver module is usually enough. + /* Keep track of how far we got in the initialization process. If several + things have to initialized, and we fail halfway, only those things + have to be cleaned up! */ + static int __initdata foo_initialized = 0; + static int __init foo_init(void) { int res; + printk("foo version %s (%s)\n",FOO_VERSION,FOO_DATE); if ((res = i2c_add_driver(&foo_driver))) { printk("foo: Driver registration failed, module not inserted.\n"); + foo_cleanup(); return res; } + foo_initialized ++; return 0; } - static void __exit foo_cleanup(void) + void foo_cleanup(void) { - i2c_del_driver(&foo_driver); + if (foo_initialized == 1) { + if ((res = i2c_del_driver(&foo_driver))) { + printk("foo: Driver registration failed, module not removed.\n"); + return; + } + foo_initialized --; + } } /* Substitute your own name and email address */ MODULE_AUTHOR("Frodo Looijaard " MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices"); - /* a few non-GPL license types are also allowed */ - MODULE_LICENSE("GPL"); - module_init(foo_init); module_exit(foo_cleanup); Note that some functions are marked by `__init', and some data structures -by `__initdata'. These functions and structures can be removed after +by `__init_data'. Hose functions and structures can be removed after kernel booting (or module loading) is completed. @@ -602,7 +632,110 @@ General purpose routines Below all general purpose routines are listed, that were not mentioned before. - /* This call returns a unique low identifier for each registered adapter. + /* This call returns a unique low identifier for each registered adapter, + * or -1 if the adapter was not registered. */ extern int i2c_adapter_id(struct i2c_adapter *adap); + +The sensors sysctl/proc interface +================================= + +This section only applies if you write `sensors' drivers. + +Each sensors driver creates a directory in /proc/sys/dev/sensors for each +registered client. The directory is called something like foo-i2c-4-65. +The sensors module helps you to do this as easily as possible. + +The template +------------ + +You will need to define a ctl_table template. This template will automatically +be copied to a newly allocated structure and filled in where necessary when +you call sensors_register_entry. + +First, I will give an example definition. + static ctl_table foo_dir_table_template[] = { + { FOO_SYSCTL_FUNC1, "func1", NULL, 0, 0644, NULL, &i2c_proc_real, + &i2c_sysctl_real,NULL,&foo_func }, + { FOO_SYSCTL_FUNC2, "func2", NULL, 0, 0644, NULL, &i2c_proc_real, + &i2c_sysctl_real,NULL,&foo_func }, + { FOO_SYSCTL_DATA, "data", NULL, 0, 0644, NULL, &i2c_proc_real, + &i2c_sysctl_real,NULL,&foo_data }, + { 0 } + }; + +In the above example, three entries are defined. They can either be +accessed through the /proc interface, in the /proc/sys/dev/sensors/* +directories, as files named func1, func2 and data, or alternatively +through the sysctl interface, in the appropriate table, with identifiers +FOO_SYSCTL_FUNC1, FOO_SYSCTL_FUNC2 and FOO_SYSCTL_DATA. + +The third, sixth and ninth parameters should always be NULL, and the +fourth should always be 0. The fifth is the mode of the /proc file; +0644 is safe, as the file will be owned by root:root. + +The seventh and eighth parameters should be &i2c_proc_real and +&i2c_sysctl_real if you want to export lists of reals (scaled +integers). You can also use your own function for them, as usual. +Finally, the last parameter is the call-back to gather the data +(see below) if you use the *_proc_real functions. + + +Gathering the data +------------------ + +The call back functions (foo_func and foo_data in the above example) +can be called in several ways; the operation parameter determines +what should be done: + + * If operation == SENSORS_PROC_REAL_INFO, you must return the + magnitude (scaling) in nrels_mag; + * If operation == SENSORS_PROC_REAL_READ, you must read information + from the chip and return it in results. The number of integers + to display should be put in nrels_mag; + * If operation == SENSORS_PROC_REAL_WRITE, you must write the + supplied information to the chip. nrels_mag will contain the number + of integers, results the integers themselves. + +The *_proc_real functions will display the elements as reals for the +/proc interface. If you set the magnitude to 2, and supply 345 for +SENSORS_PROC_REAL_READ, it would display 3.45; and if the user would +write 45.6 to the /proc file, it would be returned as 4560 for +SENSORS_PROC_REAL_WRITE. A magnitude may even be negative! + +An example function: + + /* FOO_FROM_REG and FOO_TO_REG translate between scaled values and + register values. Note the use of the read cache. */ + void foo_in(struct i2c_client *client, int operation, int ctl_name, + int *nrels_mag, long *results) + { + struct foo_data *data = client->data; + int nr = ctl_name - FOO_SYSCTL_FUNC1; /* reduce to 0 upwards */ + + if (operation == SENSORS_PROC_REAL_INFO) + *nrels_mag = 2; + else if (operation == SENSORS_PROC_REAL_READ) { + /* Update the readings cache (if necessary) */ + foo_update_client(client); + /* Get the readings from the cache */ + results[0] = FOO_FROM_REG(data->foo_func_base[nr]); + results[1] = FOO_FROM_REG(data->foo_func_more[nr]); + results[2] = FOO_FROM_REG(data->foo_func_readonly[nr]); + *nrels_mag = 2; + } else if (operation == SENSORS_PROC_REAL_WRITE) { + if (*nrels_mag >= 1) { + /* Update the cache */ + data->foo_base[nr] = FOO_TO_REG(results[0]); + /* Update the chip */ + foo_write_value(client,FOO_REG_FUNC_BASE(nr),data->foo_base[nr]); + } + if (*nrels_mag >= 2) { + /* Update the cache */ + data->foo_more[nr] = FOO_TO_REG(results[1]); + /* Update the chip */ + foo_write_value(client,FOO_REG_FUNC_MORE(nr),data->foo_more[nr]); + } + } + } diff --git a/trunk/Documentation/i386/boot.txt b/trunk/Documentation/i386/boot.txt index 6498666ea330..38fe1f03fb14 100644 --- a/trunk/Documentation/i386/boot.txt +++ b/trunk/Documentation/i386/boot.txt @@ -2,7 +2,7 @@ ---------------------------- H. Peter Anvin - Last update 2007-03-06 + Last update 2007-01-26 On the i386 platform, the Linux kernel uses a rather complicated boot convention. This has evolved partially due to historical aspects, as @@ -35,13 +35,9 @@ Protocol 2.03: (Kernel 2.4.18-pre1) Explicitly makes the highest possible initrd address available to the bootloader. Protocol 2.04: (Kernel 2.6.14) Extend the syssize field to four bytes. - Protocol 2.05: (Kernel 2.6.20) Make protected mode kernel relocatable. Introduce relocatable_kernel and kernel_alignment fields. -Protocol 2.06: (Kernel 2.6.22) Added a field that contains the size of - the boot command line - **** MEMORY LAYOUT @@ -137,8 +133,6 @@ Offset Proto Name Meaning 022C/4 2.03+ initrd_addr_max Highest legal initrd address 0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel 0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not -0235/3 N/A pad2 Unused -0238/4 2.06+ cmdline_size Maximum size of the kernel command line (1) For backwards compatibility, if the setup_sects field contains 0, the real value is 4. @@ -239,12 +233,6 @@ filled out, however: if your ramdisk is exactly 131072 bytes long and this field is 0x37FFFFFF, you can start your ramdisk at 0x37FE0000.) - cmdline_size: - The maximum size of the command line without the terminating - zero. This means that the command line can contain at most - cmdline_size characters. With protocol version 2.05 and - earlier, the maximum size was 255. - **** THE KERNEL COMMAND LINE @@ -253,10 +241,11 @@ loader to communicate with the kernel. Some of its options are also relevant to the boot loader itself, see "special command line options" below. -The kernel command line is a null-terminated string. The maximum -length can be retrieved from the field cmdline_size. Before protocol -version 2.06, the maximum was 255 characters. A string that is too -long will be automatically truncated by the kernel. +The kernel command line is a null-terminated string currently up to +255 characters long, plus the final null. A string that is too long +will be automatically truncated by the kernel, a boot loader may allow +a longer command line to be passed to permit future kernels to extend +this limit. If the boot protocol version is 2.02 or later, the address of the kernel command line is given by the header field cmd_line_ptr (see diff --git a/trunk/Documentation/ia64/aliasing-test.c b/trunk/Documentation/ia64/aliasing-test.c deleted file mode 100644 index 3153167b41c3..000000000000 --- a/trunk/Documentation/ia64/aliasing-test.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Exercise /dev/mem mmap cases that have been troublesome in the past - * - * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. - * Bjorn Helgaas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int sum; - -int map_mem(char *path, off_t offset, size_t length, int touch) -{ - int fd, rc; - void *addr; - int *c; - - fd = open(path, O_RDWR); - if (fd == -1) { - perror(path); - return -1; - } - - addr = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset); - if (addr == MAP_FAILED) - return 1; - - if (touch) { - c = (int *) addr; - while (c < (int *) (offset + length)) - sum += *c++; - } - - rc = munmap(addr, length); - if (rc == -1) { - perror("munmap"); - return -1; - } - - close(fd); - return 0; -} - -int scan_sysfs(char *path, char *file, off_t offset, size_t length, int touch) -{ - struct dirent **namelist; - char *name, *path2; - int i, n, r, rc, result = 0; - struct stat buf; - - n = scandir(path, &namelist, 0, alphasort); - if (n < 0) { - perror("scandir"); - return -1; - } - - for (i = 0; i < n; i++) { - name = namelist[i]->d_name; - - if (fnmatch(".", name, 0) == 0) - goto skip; - if (fnmatch("..", name, 0) == 0) - goto skip; - - path2 = malloc(strlen(path) + strlen(name) + 3); - strcpy(path2, path); - strcat(path2, "/"); - strcat(path2, name); - - if (fnmatch(file, name, 0) == 0) { - rc = map_mem(path2, offset, length, touch); - if (rc == 0) - fprintf(stderr, "PASS: %s 0x%lx-0x%lx is %s\n", path2, offset, offset + length, touch ? "readable" : "mappable"); - else if (rc > 0) - fprintf(stderr, "PASS: %s 0x%lx-0x%lx not mappable\n", path2, offset, offset + length); - else { - fprintf(stderr, "FAIL: %s 0x%lx-0x%lx not accessible\n", path2, offset, offset + length); - return rc; - } - } else { - r = lstat(path2, &buf); - if (r == 0 && S_ISDIR(buf.st_mode)) { - rc = scan_sysfs(path2, file, offset, length, touch); - if (rc < 0) - return rc; - } - } - - result |= rc; - free(path2); - -skip: - free(namelist[i]); - } - free(namelist); - return rc; -} - -char buf[1024]; - -int read_rom(char *path) -{ - int fd, rc; - size_t size = 0; - - fd = open(path, O_RDWR); - if (fd == -1) { - perror(path); - return -1; - } - - rc = write(fd, "1", 2); - if (rc <= 0) { - perror("write"); - return -1; - } - - do { - rc = read(fd, buf, sizeof(buf)); - if (rc > 0) - size += rc; - } while (rc > 0); - - close(fd); - return size; -} - -int scan_rom(char *path, char *file) -{ - struct dirent **namelist; - char *name, *path2; - int i, n, r, rc, result = 0; - struct stat buf; - - n = scandir(path, &namelist, 0, alphasort); - if (n < 0) { - perror("scandir"); - return -1; - } - - for (i = 0; i < n; i++) { - name = namelist[i]->d_name; - - if (fnmatch(".", name, 0) == 0) - goto skip; - if (fnmatch("..", name, 0) == 0) - goto skip; - - path2 = malloc(strlen(path) + strlen(name) + 3); - strcpy(path2, path); - strcat(path2, "/"); - strcat(path2, name); - - if (fnmatch(file, name, 0) == 0) { - rc = read_rom(path2); - - /* - * It's OK if the ROM is unreadable. Maybe there - * is no ROM, or some other error ocurred. The - * important thing is that no MCA happened. - */ - if (rc > 0) - fprintf(stderr, "PASS: %s read %ld bytes\n", path2, rc); - else { - fprintf(stderr, "PASS: %s not readable\n", path2); - return rc; - } - } else { - r = lstat(path2, &buf); - if (r == 0 && S_ISDIR(buf.st_mode)) { - rc = scan_rom(path2, file); - if (rc < 0) - return rc; - } - } - - result |= rc; - free(path2); - -skip: - free(namelist[i]); - } - free(namelist); - return rc; -} - -main() -{ - int rc; - - if (map_mem("/dev/mem", 0, 0xA0000, 1) == 0) - fprintf(stderr, "PASS: /dev/mem 0x0-0xa0000 is readable\n"); - else - fprintf(stderr, "FAIL: /dev/mem 0x0-0xa0000 not accessible\n"); - - /* - * It's not safe to blindly read the VGA frame buffer. If you know - * how to poke the card the right way, it should respond, but it's - * not safe in general. Many machines, e.g., Intel chipsets, cover - * up a non-responding card by just returning -1, but others will - * report the failure as a machine check. - */ - if (map_mem("/dev/mem", 0xA0000, 0x20000, 0) == 0) - fprintf(stderr, "PASS: /dev/mem 0xa0000-0xc0000 is mappable\n"); - else - fprintf(stderr, "FAIL: /dev/mem 0xa0000-0xc0000 not accessible\n"); - - if (map_mem("/dev/mem", 0xC0000, 0x40000, 1) == 0) - fprintf(stderr, "PASS: /dev/mem 0xc0000-0x100000 is readable\n"); - else - fprintf(stderr, "FAIL: /dev/mem 0xc0000-0x100000 not accessible\n"); - - /* - * Often you can map all the individual pieces above (0-0xA0000, - * 0xA0000-0xC0000, and 0xC0000-0x100000), but can't map the whole - * thing at once. This is because the individual pieces use different - * attributes, and there's no single attribute supported over the - * whole region. - */ - rc = map_mem("/dev/mem", 0, 1024*1024, 0); - if (rc == 0) - fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 is mappable\n"); - else if (rc > 0) - fprintf(stderr, "PASS: /dev/mem 0x0-0x100000 not mappable\n"); - else - fprintf(stderr, "FAIL: /dev/mem 0x0-0x100000 not accessible\n"); - - scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 0xA0000, 1); - scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xA0000, 0x20000, 0); - scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0xC0000, 0x40000, 1); - scan_sysfs("/sys/class/pci_bus", "legacy_mem", 0, 1024*1024, 0); - - scan_rom("/sys/devices", "rom"); -} diff --git a/trunk/Documentation/ia64/aliasing.txt b/trunk/Documentation/ia64/aliasing.txt index 9a431a7d0f5d..38f9a52d1820 100644 --- a/trunk/Documentation/ia64/aliasing.txt +++ b/trunk/Documentation/ia64/aliasing.txt @@ -112,6 +112,16 @@ POTENTIAL ATTRIBUTE ALIASING CASES The /dev/mem mmap constraints apply. + However, since this is for mapping legacy MMIO space, WB access + does not make sense. This matters on machines without legacy + VGA support: these machines may have WB memory for the entire + first megabyte (or even the entire first granule). + + On these machines, we could mmap legacy_mem as WB, which would + be safe in terms of attribute aliasing, but X has no way of + knowing that it is accessing regular memory, not a frame buffer, + so the kernel should fail the mmap rather than doing it with WB. + read/write of /dev/mem This uses copy_from_user(), which implicitly uses a kernel @@ -128,20 +138,14 @@ POTENTIAL ATTRIBUTE ALIASING CASES ioremap() - This returns a mapping for use inside the kernel. + This returns a kernel identity mapping for use inside the + kernel. If the region is in kern_memmap, we should use the attribute - specified there. - - If the EFI memory map reports that the entire granule supports - WB, we should use that (granules that are partially reserved - or occupied by firmware do not appear in kern_memmap). - - If the granule contains non-WB memory, but we can cover the - region safely with kernel page table mappings, we can use - ioremap_page_range() as most other architectures do. - - Failing all of the above, we have to fall back to a UC mapping. + specified there. Otherwise, if the EFI memory map reports that + the entire granule supports WB, we should use that (granules + that are partially reserved or occupied by firmware do not appear + in kern_memmap). Otherwise, we should use a UC mapping. PAST PROBLEM CASES @@ -154,7 +158,7 @@ PAST PROBLEM CASES succeed. It may create either WB or UC user mappings, depending on whether the region is in kern_memmap or the EFI memory map. - mmap of 0x0-0x9FFFF /dev/mem by "hwinfo" on HP sx1000 with VGA enabled + mmap of 0x0-0xA0000 /dev/mem by "hwinfo" on HP sx1000 with VGA enabled See https://bugzilla.novell.com/show_bug.cgi?id=140858. @@ -167,25 +171,28 @@ PAST PROBLEM CASES so it is safe to use WB mappings. The kernel VGA driver may ioremap the VGA frame buffer at 0xA0000, - which uses a granule-sized UC mapping. This granule will cover some - WB-only memory, but since UC is non-speculative, the processor will - never generate an uncacheable reference to the WB-only areas unless - the driver explicitly touches them. + which will use a granule-sized UC mapping covering 0-0xFFFFF. This + granule covers some WB-only memory, but since UC is non-speculative, + the processor will never generate an uncacheable reference to the + WB-only areas unless the driver explicitly touches them. mmap of 0x0-0xFFFFF legacy_mem by "X" - If the EFI memory map reports that the entire range supports the - same attributes, we can allow the mmap (and we will prefer WB if - supported, as is the case with HP sx[12]000 machines with VGA - disabled). + If the EFI memory map reports this entire range as WB, there + is no VGA MMIO hole, and the mmap should fail or be done with + a WB mapping. - If EFI reports the range as partly WB and partly UC (as on sx[12]000 - machines with VGA enabled), we must fail the mmap because there's no - safe attribute to use. + There's no easy way for X to determine whether the 0xA0000-0xBFFFF + region is a frame buffer or just memory, so I think it's best to + just fail this mmap request rather than using a WB mapping. As + far as I know, there's no need to map legacy_mem with WB + mappings. - If EFI reports some of the range but not all (as on Intel firmware - that doesn't report the VGA frame buffer at all), we should fail the - mmap and force the user to map just the specific region of interest. + Otherwise, a UC mapping of the entire region is probably safe. + The VGA hole means the region will not be in kern_memmap. The + HP sx1000 chipset doesn't support UC access to the memory surrounding + the VGA hole, but X doesn't need that area anyway and should not + reference it. mmap of 0xA0000-0xBFFFF legacy_mem by "X" on HP sx1000 with VGA disabled @@ -195,16 +202,6 @@ PAST PROBLEM CASES This is a special case of the previous case, and the mmap should fail for the same reason as above. - read of /sys/devices/.../rom - - For VGA devices, this may cause an ioremap() of 0xC0000. This - used to be done with a UC mapping, because the VGA frame buffer - at 0xA0000 prevents use of a WB granule. The UC mapping causes - an MCA on HP sx[12]000 chipsets. - - We should use WB page table mappings to avoid covering the VGA - frame buffer. - NOTES [1] SDM rev 2.2, vol 2, sec 4.4.1. diff --git a/trunk/Documentation/ia64/err_inject.txt b/trunk/Documentation/ia64/err_inject.txt deleted file mode 100644 index 6449a7090dbb..000000000000 --- a/trunk/Documentation/ia64/err_inject.txt +++ /dev/null @@ -1,1068 +0,0 @@ - -IPF Machine Check (MC) error inject tool -======================================== - -IPF Machine Check (MC) error inject tool is used to inject MC -errors from Linux. The tool is a test bed for IPF MC work flow including -hardware correctable error handling, OS recoverable error handling, MC -event logging, etc. - -The tool includes two parts: a kernel driver and a user application -sample. The driver provides interface to PAL to inject error -and query error injection capabilities. The driver code is in -arch/ia64/kernel/err_inject.c. The application sample (shown below) -provides a combination of various errors and calls the driver's interface -(sysfs interface) to inject errors or query error injection capabilities. - -The tool can be used to test Intel IPF machine MC handling capabilities. -It's especially useful for people who can not access hardware MC injection -tool to inject error. It's also very useful to integrate with other -software test suits to do stressful testing on IPF. - -Below is a sample application as part of the whole tool. The sample -can be used as a working test tool. Or it can be expanded to include -more features. It also can be a integrated into a libary or other user -application to have more thorough test. - -The sample application takes err.conf as error configuation input. Gcc -compiles the code. After you install err_inject driver, you can run -this sample application to inject errors. - -Errata: Itanium 2 Processors Specification Update lists some errata against -the pal_mc_error_inject PAL procedure. The following err.conf has been tested -on latest Montecito PAL. - -err.conf: - -#This is configuration file for err_inject_tool. -#The format of the each line is: -#cpu, loop, interval, err_type_info, err_struct_info, err_data_buffer -#where -# cpu: logical cpu number the error will be inject in. -# loop: times the error will be injected. -# interval: In second. every so often one error is injected. -# err_type_info, err_struct_info: PAL parameters. -# -#Note: All values are hex w/o or w/ 0x prefix. - - -#On cpu2, inject only total 0x10 errors, interval 5 seconds -#corrected, data cache, hier-2, physical addr(assigned by tool code). -#working on Montecito latest PAL. -2, 10, 5, 4101, 95 - -#On cpu4, inject and consume total 0x10 errors, interval 5 seconds -#corrected, data cache, hier-2, physical addr(assigned by tool code). -#working on Montecito latest PAL. -4, 10, 5, 4109, 95 - -#On cpu15, inject and consume total 0x10 errors, interval 5 seconds -#recoverable, DTR0, hier-2. -#working on Montecito latest PAL. -0xf, 0x10, 5, 4249, 15 - -The sample application source code: - -err_injection_tool.c: - -/* - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Copyright (C) 2006 Intel Co - * Fenghua Yu - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_FN_SIZE 256 -#define MAX_BUF_SIZE 256 -#define DATA_BUF_SIZE 256 -#define NR_CPUS 512 -#define MAX_TASK_NUM 2048 -#define MIN_INTERVAL 5 // seconds -#define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte. -#define PARA_FIELD_NUM 5 -#define MASK_SIZE (NR_CPUS/64) -#define PATH_FORMAT "/sys/devices/system/cpu/cpu%d/err_inject/" - -int sched_setaffinity(pid_t pid, unsigned int len, unsigned long *mask); - -int verbose; -#define vbprintf if (verbose) printf - -int log_info(int cpu, const char *fmt, ...) -{ - FILE *log; - char fn[MAX_FN_SIZE]; - char buf[MAX_BUF_SIZE]; - va_list args; - - sprintf(fn, "%d.log", cpu); - log=fopen(fn, "a+"); - if (log==NULL) { - perror("Error open:"); - return -1; - } - - va_start(args, fmt); - vprintf(fmt, args); - memset(buf, 0, MAX_BUF_SIZE); - vsprintf(buf, fmt, args); - va_end(args); - - fwrite(buf, sizeof(buf), 1, log); - fclose(log); - - return 0; -} - -typedef unsigned long u64; -typedef unsigned int u32; - -typedef union err_type_info_u { - struct { - u64 mode : 3, /* 0-2 */ - err_inj : 3, /* 3-5 */ - err_sev : 2, /* 6-7 */ - err_struct : 5, /* 8-12 */ - struct_hier : 3, /* 13-15 */ - reserved : 48; /* 16-63 */ - } err_type_info_u; - u64 err_type_info; -} err_type_info_t; - -typedef union err_struct_info_u { - struct { - u64 siv : 1, /* 0 */ - c_t : 2, /* 1-2 */ - cl_p : 3, /* 3-5 */ - cl_id : 3, /* 6-8 */ - cl_dp : 1, /* 9 */ - reserved1 : 22, /* 10-31 */ - tiv : 1, /* 32 */ - trigger : 4, /* 33-36 */ - trigger_pl : 3, /* 37-39 */ - reserved2 : 24; /* 40-63 */ - } err_struct_info_cache; - struct { - u64 siv : 1, /* 0 */ - tt : 2, /* 1-2 */ - tc_tr : 2, /* 3-4 */ - tr_slot : 8, /* 5-12 */ - reserved1 : 19, /* 13-31 */ - tiv : 1, /* 32 */ - trigger : 4, /* 33-36 */ - trigger_pl : 3, /* 37-39 */ - reserved2 : 24; /* 40-63 */ - } err_struct_info_tlb; - struct { - u64 siv : 1, /* 0 */ - regfile_id : 4, /* 1-4 */ - reg_num : 7, /* 5-11 */ - reserved1 : 20, /* 12-31 */ - tiv : 1, /* 32 */ - trigger : 4, /* 33-36 */ - trigger_pl : 3, /* 37-39 */ - reserved2 : 24; /* 40-63 */ - } err_struct_info_register; - struct { - u64 reserved; - } err_struct_info_bus_processor_interconnect; - u64 err_struct_info; -} err_struct_info_t; - -typedef union err_data_buffer_u { - struct { - u64 trigger_addr; /* 0-63 */ - u64 inj_addr; /* 64-127 */ - u64 way : 5, /* 128-132 */ - index : 20, /* 133-152 */ - : 39; /* 153-191 */ - } err_data_buffer_cache; - struct { - u64 trigger_addr; /* 0-63 */ - u64 inj_addr; /* 64-127 */ - u64 way : 5, /* 128-132 */ - index : 20, /* 133-152 */ - reserved : 39; /* 153-191 */ - } err_data_buffer_tlb; - struct { - u64 trigger_addr; /* 0-63 */ - } err_data_buffer_register; - struct { - u64 reserved; /* 0-63 */ - } err_data_buffer_bus_processor_interconnect; - u64 err_data_buffer[ERR_DATA_BUFFER_SIZE]; -} err_data_buffer_t; - -typedef union capabilities_u { - struct { - u64 i : 1, - d : 1, - rv : 1, - tag : 1, - data : 1, - mesi : 1, - dp : 1, - reserved1 : 3, - pa : 1, - va : 1, - wi : 1, - reserved2 : 20, - trigger : 1, - trigger_pl : 1, - reserved3 : 30; - } capabilities_cache; - struct { - u64 d : 1, - i : 1, - rv : 1, - tc : 1, - tr : 1, - reserved1 : 27, - trigger : 1, - trigger_pl : 1, - reserved2 : 30; - } capabilities_tlb; - struct { - u64 gr_b0 : 1, - gr_b1 : 1, - fr : 1, - br : 1, - pr : 1, - ar : 1, - cr : 1, - rr : 1, - pkr : 1, - dbr : 1, - ibr : 1, - pmc : 1, - pmd : 1, - reserved1 : 3, - regnum : 1, - reserved2 : 15, - trigger : 1, - trigger_pl : 1, - reserved3 : 30; - } capabilities_register; - struct { - u64 reserved; - } capabilities_bus_processor_interconnect; -} capabilities_t; - -typedef struct resources_s { - u64 ibr0 : 1, - ibr2 : 1, - ibr4 : 1, - ibr6 : 1, - dbr0 : 1, - dbr2 : 1, - dbr4 : 1, - dbr6 : 1, - reserved : 48; -} resources_t; - - -long get_page_size(void) -{ - long page_size=sysconf(_SC_PAGESIZE); - return page_size; -} - -#define PAGE_SIZE (get_page_size()==-1?0x4000:get_page_size()) -#define SHM_SIZE (2*PAGE_SIZE*NR_CPUS) -#define SHM_VA 0x2000000100000000 - -int shmid; -void *shmaddr; - -int create_shm(void) -{ - key_t key; - char fn[MAX_FN_SIZE]; - - /* cpu0 is always existing */ - sprintf(fn, PATH_FORMAT, 0); - if ((key = ftok(fn, 's')) == -1) { - perror("ftok"); - return -1; - } - - shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT); - if (shmid == -1) { - if (errno==EEXIST) { - shmid = shmget(key, SHM_SIZE, 0); - if (shmid == -1) { - perror("shmget"); - return -1; - } - } - else { - perror("shmget"); - return -1; - } - } - vbprintf("shmid=%d", shmid); - - /* connect to the segment: */ - shmaddr = shmat(shmid, (void *)SHM_VA, 0); - if (shmaddr == (void*)-1) { - perror("shmat"); - return -1; - } - - memset(shmaddr, 0, SHM_SIZE); - mlock(shmaddr, SHM_SIZE); - - return 0; -} - -int free_shm() -{ - munlock(shmaddr, SHM_SIZE); - shmdt(shmaddr); - semctl(shmid, 0, IPC_RMID); - - return 0; -} - -#ifdef _SEM_SEMUN_UNDEFINED -union semun -{ - int val; - struct semid_ds *buf; - unsigned short int *array; - struct seminfo *__buf; -}; -#endif - -u32 mode=1; /* 1: physical mode; 2: virtual mode. */ -int one_lock=1; -key_t key[NR_CPUS]; -int semid[NR_CPUS]; - -int create_sem(int cpu) -{ - union semun arg; - char fn[MAX_FN_SIZE]; - int sid; - - sprintf(fn, PATH_FORMAT, cpu); - sprintf(fn, "%s/%s", fn, "err_type_info"); - if ((key[cpu] = ftok(fn, 'e')) == -1) { - perror("ftok"); - return -1; - } - - if (semid[cpu]!=0) - return 0; - - /* clear old semaphore */ - if ((sid = semget(key[cpu], 1, 0)) != -1) - semctl(sid, 0, IPC_RMID); - - /* get one semaphore */ - if ((semid[cpu] = semget(key[cpu], 1, IPC_CREAT | IPC_EXCL)) == -1) { - perror("semget"); - printf("Please remove semaphore with key=0x%lx, then run the tool.\n", - (u64)key[cpu]); - return -1; - } - - vbprintf("semid[%d]=0x%lx, key[%d]=%lx\n",cpu,(u64)semid[cpu],cpu, - (u64)key[cpu]); - /* initialize the semaphore to 1: */ - arg.val = 1; - if (semctl(semid[cpu], 0, SETVAL, arg) == -1) { - perror("semctl"); - return -1; - } - - return 0; -} - -static int lock(int cpu) -{ - struct sembuf lock; - - lock.sem_num = cpu; - lock.sem_op = 1; - semop(semid[cpu], &lock, 1); - - return 0; -} - -static int unlock(int cpu) -{ - struct sembuf unlock; - - unlock.sem_num = cpu; - unlock.sem_op = -1; - semop(semid[cpu], &unlock, 1); - - return 0; -} - -void free_sem(int cpu) -{ - semctl(semid[cpu], 0, IPC_RMID); -} - -int wr_multi(char *fn, unsigned long *data, int size) -{ - int fd; - char buf[MAX_BUF_SIZE]; - int ret; - - if (size==1) - sprintf(buf, "%lx", *data); - else if (size==3) - sprintf(buf, "%lx,%lx,%lx", data[0], data[1], data[2]); - else { - fprintf(stderr,"write to file with wrong size!\n"); - return -1; - } - - fd=open(fn, O_RDWR); - if (!fd) { - perror("Error:"); - return -1; - } - ret=write(fd, buf, sizeof(buf)); - close(fd); - return ret; -} - -int wr(char *fn, unsigned long data) -{ - return wr_multi(fn, &data, 1); -} - -int rd(char *fn, unsigned long *data) -{ - int fd; - char buf[MAX_BUF_SIZE]; - - fd=open(fn, O_RDONLY); - if (fd<0) { - perror("Error:"); - return -1; - } - read(fd, buf, MAX_BUF_SIZE); - *data=strtoul(buf, NULL, 16); - close(fd); - return 0; -} - -int rd_status(char *path, int *status) -{ - char fn[MAX_FN_SIZE]; - sprintf(fn, "%s/status", path); - if (rd(fn, (u64*)status)<0) { - perror("status reading error.\n"); - return -1; - } - - return 0; -} - -int rd_capabilities(char *path, u64 *capabilities) -{ - char fn[MAX_FN_SIZE]; - sprintf(fn, "%s/capabilities", path); - if (rd(fn, capabilities)<0) { - perror("capabilities reading error.\n"); - return -1; - } - - return 0; -} - -int rd_all(char *path) -{ - unsigned long err_type_info, err_struct_info, err_data_buffer; - int status; - unsigned long capabilities, resources; - char fn[MAX_FN_SIZE]; - - sprintf(fn, "%s/err_type_info", path); - if (rd(fn, &err_type_info)<0) { - perror("err_type_info reading error.\n"); - return -1; - } - printf("err_type_info=%lx\n", err_type_info); - - sprintf(fn, "%s/err_struct_info", path); - if (rd(fn, &err_struct_info)<0) { - perror("err_struct_info reading error.\n"); - return -1; - } - printf("err_struct_info=%lx\n", err_struct_info); - - sprintf(fn, "%s/err_data_buffer", path); - if (rd(fn, &err_data_buffer)<0) { - perror("err_data_buffer reading error.\n"); - return -1; - } - printf("err_data_buffer=%lx\n", err_data_buffer); - - sprintf(fn, "%s/status", path); - if (rd("status", (u64*)&status)<0) { - perror("status reading error.\n"); - return -1; - } - printf("status=%d\n", status); - - sprintf(fn, "%s/capabilities", path); - if (rd(fn,&capabilities)<0) { - perror("capabilities reading error.\n"); - return -1; - } - printf("capabilities=%lx\n", capabilities); - - sprintf(fn, "%s/resources", path); - if (rd(fn, &resources)<0) { - perror("resources reading error.\n"); - return -1; - } - printf("resources=%lx\n", resources); - - return 0; -} - -int query_capabilities(char *path, err_type_info_t err_type_info, - u64 *capabilities) -{ - char fn[MAX_FN_SIZE]; - err_struct_info_t err_struct_info; - err_data_buffer_t err_data_buffer; - - err_struct_info.err_struct_info=0; - memset(err_data_buffer.err_data_buffer, -1, ERR_DATA_BUFFER_SIZE*8); - - sprintf(fn, "%s/err_type_info", path); - wr(fn, err_type_info.err_type_info); - sprintf(fn, "%s/err_struct_info", path); - wr(fn, 0x0); - sprintf(fn, "%s/err_data_buffer", path); - wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE); - - // Fire pal_mc_error_inject procedure. - sprintf(fn, "%s/call_start", path); - wr(fn, mode); - - if (rd_capabilities(path, capabilities)<0) - return -1; - - return 0; -} - -int query_all_capabilities() -{ - int status; - err_type_info_t err_type_info; - int err_sev, err_struct, struct_hier; - int cap=0; - u64 capabilities; - char path[MAX_FN_SIZE]; - - err_type_info.err_type_info=0; // Initial - err_type_info.err_type_info_u.mode=0; // Query mode; - err_type_info.err_type_info_u.err_inj=0; - - printf("All capabilities implemented in pal_mc_error_inject:\n"); - sprintf(path, PATH_FORMAT ,0); - for (err_sev=0;err_sev<3;err_sev++) - for (err_struct=0;err_struct<5;err_struct++) - for (struct_hier=0;struct_hier<5;struct_hier++) - { - status=-1; - capabilities=0; - err_type_info.err_type_info_u.err_sev=err_sev; - err_type_info.err_type_info_u.err_struct=err_struct; - err_type_info.err_type_info_u.struct_hier=struct_hier; - - if (query_capabilities(path, err_type_info, &capabilities)<0) - continue; - - if (rd_status(path, &status)<0) - continue; - - if (status==0) { - cap=1; - printf("For err_sev=%d, err_struct=%d, struct_hier=%d: ", - err_sev, err_struct, struct_hier); - printf("capabilities 0x%lx\n", capabilities); - } - } - if (!cap) { - printf("No capabilities supported.\n"); - return 0; - } - - return 0; -} - -int err_inject(int cpu, char *path, err_type_info_t err_type_info, - err_struct_info_t err_struct_info, - err_data_buffer_t err_data_buffer) -{ - int status; - char fn[MAX_FN_SIZE]; - - log_info(cpu, "err_type_info=%lx, err_struct_info=%lx, ", - err_type_info.err_type_info, - err_struct_info.err_struct_info); - log_info(cpu,"err_data_buffer=[%lx,%lx,%lx]\n", - err_data_buffer.err_data_buffer[0], - err_data_buffer.err_data_buffer[1], - err_data_buffer.err_data_buffer[2]); - sprintf(fn, "%s/err_type_info", path); - wr(fn, err_type_info.err_type_info); - sprintf(fn, "%s/err_struct_info", path); - wr(fn, err_struct_info.err_struct_info); - sprintf(fn, "%s/err_data_buffer", path); - wr_multi(fn, err_data_buffer.err_data_buffer, ERR_DATA_BUFFER_SIZE); - - // Fire pal_mc_error_inject procedure. - sprintf(fn, "%s/call_start", path); - wr(fn,mode); - - if (rd_status(path, &status)<0) { - vbprintf("fail: read status\n"); - return -100; - } - - if (status!=0) { - log_info(cpu, "fail: status=%d\n", status); - return status; - } - - return status; -} - -static int construct_data_buf(char *path, err_type_info_t err_type_info, - err_struct_info_t err_struct_info, - err_data_buffer_t *err_data_buffer, - void *va1) -{ - char fn[MAX_FN_SIZE]; - u64 virt_addr=0, phys_addr=0; - - vbprintf("va1=%lx\n", (u64)va1); - memset(&err_data_buffer->err_data_buffer_cache, 0, ERR_DATA_BUFFER_SIZE*8); - - switch (err_type_info.err_type_info_u.err_struct) { - case 1: // Cache - switch (err_struct_info.err_struct_info_cache.cl_id) { - case 1: //Virtual addr - err_data_buffer->err_data_buffer_cache.inj_addr=(u64)va1; - break; - case 2: //Phys addr - sprintf(fn, "%s/virtual_to_phys", path); - virt_addr=(u64)va1; - if (wr(fn,virt_addr)<0) - return -1; - rd(fn, &phys_addr); - err_data_buffer->err_data_buffer_cache.inj_addr=phys_addr; - break; - default: - printf("Not supported cl_id\n"); - break; - } - break; - case 2: // TLB - break; - case 3: // Register file - break; - case 4: // Bus/system interconnect - default: - printf("Not supported err_struct\n"); - break; - } - - return 0; -} - -typedef struct { - u64 cpu; - u64 loop; - u64 interval; - u64 err_type_info; - u64 err_struct_info; - u64 err_data_buffer[ERR_DATA_BUFFER_SIZE]; -} parameters_t; - -parameters_t line_para; -int para; - -static int empty_data_buffer(u64 *err_data_buffer) -{ - int empty=1; - int i; - - for (i=0;iMIN_INTERVAL - ?interval:MIN_INTERVAL; - parameters[num].err_type_info=err_type_info_conf; - parameters[num].err_struct_info=err_struct_info_conf; - memcpy(parameters[num++].err_data_buffer, - err_data_buffer_conf,ERR_DATA_BUFFER_SIZE*8) ; - - if (num>=MAX_TASK_NUM) - break; - } - } - else { - parameters[0].cpu=line_para.cpu; - parameters[0].loop=line_para.loop; - parameters[0].interval= line_para.interval>MIN_INTERVAL - ?line_para.interval:MIN_INTERVAL; - parameters[0].err_type_info=line_para.err_type_info; - parameters[0].err_struct_info=line_para.err_struct_info; - memcpy(parameters[0].err_data_buffer, - line_para.err_data_buffer,ERR_DATA_BUFFER_SIZE*8) ; - - num=1; - } - - /* Create semaphore: If one_lock, one semaphore for all processors. - Otherwise, one sempaphore for each processor. */ - if (one_lock) { - if (create_sem(0)) { - printf("Can not create semaphore...exit\n"); - free_sem(0); - return -1; - } - } - else { - for (i=0;i #include -static struct input_dev *button_dev; - static void button_interrupt(int irq, void *dummy, struct pt_regs *fp) { - input_report_key(button_dev, BTN_1, inb(BUTTON_PORT) & 1); - input_sync(button_dev); + input_report_key(&button_dev, BTN_1, inb(BUTTON_PORT) & 1); + input_sync(&button_dev); } static int __init button_init(void) { - int error; - if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) { printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq); return -EBUSY; } - - button_dev = input_allocate_device(); - if (!button_dev) { - printk(KERN_ERR "button.c: Not enough memory\n"); - error = -ENOMEM; - goto err_free_irq; - } - - button_dev->evbit[0] = BIT(EV_KEY); - button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); - - error = input_register_device(button_dev); - if (error) { - printk(KERN_ERR "button.c: Failed to register device\n"); - goto err_free_dev; - } - - return 0; - - err_free_dev: - input_free_device(button_dev); - err_free_irq: - free_irq(BUTTON_IRQ, button_interrupt); - return error; + + button_dev.evbit[0] = BIT(EV_KEY); + button_dev.keybit[LONG(BTN_0)] = BIT(BTN_0); + + input_register_device(&button_dev); } static void __exit button_exit(void) { - input_unregister_device(button_dev); + input_unregister_device(&button_dev); free_irq(BUTTON_IRQ, button_interrupt); } @@ -79,18 +58,17 @@ In the _init function, which is called either upon module load or when booting the kernel, it grabs the required resources (it should also check for the presence of the device). -Then it allocates a new input device structure with input_aloocate_device() -and sets up input bitfields. This way the device driver tells the other +Then it sets the input bitfields. This way the device driver tells the other parts of the input systems what it is - what events can be generated or -accepted by this input device. Our example device can only generate EV_KEY -type events, and from those only BTN_0 event code. Thus we only set these -two bits. We could have used +accepted by this input device. Our example device can only generate EV_KEY type +events, and from those only BTN_0 event code. Thus we only set these two +bits. We could have used set_bit(EV_KEY, button_dev.evbit); set_bit(BTN_0, button_dev.keybit); as well, but with more than single bits the first approach tends to be -shorter. +shorter. Then the example driver registers the input device structure by calling @@ -98,15 +76,16 @@ Then the example driver registers the input device structure by calling This adds the button_dev structure to linked lists of the input driver and calls device handler modules _connect functions to tell them a new input -device has appeared. input_register_device() may sleep and therefore must -not be called from an interrupt or with a spinlock held. +device has appeared. Because the _connect functions may call kmalloc(, +GFP_KERNEL), which can sleep, input_register_device() must not be called +from an interrupt or with a spinlock held. While in use, the only used function of the driver is button_interrupt() which upon every interrupt from the button checks its state and reports it -via the +via the input_report_key() @@ -134,10 +113,16 @@ can use the open and close callback to know when it can stop polling or release the interrupt and when it must resume polling or grab the interrupt again. To do that, we would add this to our example driver: +int button_used = 0; + static int button_open(struct input_dev *dev) { + if (button_used++) + return 0; + if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) { printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_irq); + button_used--; return -EBUSY; } @@ -146,21 +131,20 @@ static int button_open(struct input_dev *dev) static void button_close(struct input_dev *dev) { - free_irq(IRQ_AMIGA_VERTB, button_interrupt); + if (!--button_used) + free_irq(IRQ_AMIGA_VERTB, button_interrupt); } static int __init button_init(void) { ... - button_dev->open = button_open; - button_dev->close = button_close; + button_dev.open = button_open; + button_dev.close = button_close; ... } -Note that input core keeps track of number of users for the device and -makes sure that dev->open() is called only when the first user connects -to the device and that dev->close() is called when the very last user -disconnects. Calls to both callbacks are serialized. +Note the button_used variable - we have to track how many times the open +function was called to know when exactly our device stops being used. The open() callback should return a 0 in case of success or any nonzero value in case of failure. The close() callback (which is void) must always succeed. @@ -191,7 +175,7 @@ set the corresponding bits and call the input_report_rel(struct input_dev *dev, int code, int value) -function. Events are generated only for nonzero value. +function. Events are generated only for nonzero value. However EV_ABS requires a little special care. Before calling input_register_device, you have to fill additional fields in the input_dev @@ -203,10 +187,6 @@ the ABS_X axis: button_dev.absfuzz[ABS_X] = 4; button_dev.absflat[ABS_X] = 8; -Or, you can just say: - - input_set_abs_params(button_dev, ABS_X, 0, 255, 4, 8); - This setting would be appropriate for a joystick X axis, with the minimum of 0, maximum of 255 (which the joystick *must* be able to reach, no problem if it sometimes reports more, but it must be able to always reach the min and @@ -217,7 +197,14 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean that the thing is precise and always returns to exactly the center position (if it has any). -1.4 NBITS(), LONG(), BIT() +1.4 The void *private field +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This field in the input structure can be used to point to any private data +structures in the input device driver, in case the driver handles more than +one device. You'll need it in the open and close callbacks. + +1.5 NBITS(), LONG(), BIT() ~~~~~~~~~~~~~~~~~~~~~~~~~~ These three macros from input.h help some bitfield computations: @@ -226,9 +213,13 @@ These three macros from input.h help some bitfield computations: LONG(x) - returns the index in the array in longs for bit x BIT(x) - returns the index in a long for bit x -1.5 The id* and name fields +1.6 The number, id* and name fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The dev->number is assigned by the input system to the input device when it +is registered. It has no use except for identifying the device to the user +in system messages. + The dev->name should be set before registering the input device by the input device driver. It's a string like 'Generic button device' containing a user friendly name of the device. @@ -243,25 +234,15 @@ driver. The id and name fields can be passed to userland via the evdev interface. -1.6 The keycode, keycodemax, keycodesize fields +1.7 The keycode, keycodemax, keycodesize fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -These three fields should be used by input devices that have dense keymaps. -The keycode is an array used to map from scancodes to input system keycodes. -The keycode max should contain the size of the array and keycodesize the -size of each entry in it (in bytes). - -Userspace can query and alter current scancode to keycode mappings using -EVIOCGKEYCODE and EVIOCSKEYCODE ioctls on corresponding evdev interface. -When a device has all 3 aforementioned fields filled in, the driver may -rely on kernel's default implementation of setting and querying keycode -mappings. - -1.7 dev->getkeycode() and dev->setkeycode() -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -getkeycode() and setkeycode() callbacks allow drivers to override default -keycode/keycodesize/keycodemax mapping mechanism provided by input core -and implement sparse keycode maps. +These two fields will be used for any input devices that report their data +as scancodes. If not all scancodes can be known by autodetection, they may +need to be set by userland utilities. The keycode array then is an array +used to map from scancodes to input system keycodes. The keycode max will +contain the size of the array and keycodesize the size of each entry in it +(in bytes). 1.8 Key autorepeat ~~~~~~~~~~~~~~~~~~ @@ -285,7 +266,7 @@ direction - from the system to the input device driver. If your input device driver can handle these events, it has to set the respective bits in evbit, *and* also the callback routine: - button_dev->event = button_event; + button_dev.event = button_event; int button_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); { diff --git a/trunk/Documentation/ioctl-number.txt b/trunk/Documentation/ioctl-number.txt index 3de7d379cf07..8f750c0efed5 100644 --- a/trunk/Documentation/ioctl-number.txt +++ b/trunk/Documentation/ioctl-number.txt @@ -138,8 +138,7 @@ Code Seq# Include File Comments 'm' 00-1F net/irda/irmod.h conflict! 'n' 00-7F linux/ncp_fs.h 'n' E0-FF video/matrox.h matroxfb -'p' 00-0F linux/phantom.h conflict! (OpenHaptics needs this) -'p' 00-3F linux/mc146818rtc.h conflict! +'p' 00-3F linux/mc146818rtc.h 'p' 40-7F linux/nvram.h 'p' 80-9F user-space parport diff --git a/trunk/Documentation/kbuild/modules.txt b/trunk/Documentation/kbuild/modules.txt index 1d247d59ad56..769ee05ee4d1 100644 --- a/trunk/Documentation/kbuild/modules.txt +++ b/trunk/Documentation/kbuild/modules.txt @@ -249,7 +249,7 @@ following files: --> filename: Makefile KERNELDIR := /lib/modules/`uname -r`/build all:: - $(MAKE) -C $(KERNELDIR) M=`pwd` $@ + $(MAKE) -C $KERNELDIR M=`pwd` $@ # Module specific targets genbin: diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 6b8ad06846c4..84c3bd05c639 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -64,7 +64,6 @@ parameter is applicable: GENERIC_TIME The generic timeofday code is enabled. NFS Appropriate NFS support is enabled. OSS OSS sound support is enabled. - PV_OPS A paravirtualized kernel PARIDE The ParIDE subsystem is enabled. PARISC The PA-RISC architecture is enabled. PCI PCI bus support is enabled. @@ -496,30 +495,6 @@ and is between 256 and 4096 characters. It is defined in the file Format: [,] See also Documentation/networking/decnet.txt. - default_blu= [VT] - Format: ,,,..., - Change the default blue palette of the console. - This is a 16-member array composed of values - ranging from 0-255. - - default_grn= [VT] - Format: ,,,..., - Change the default green palette of the console. - This is a 16-member array composed of values - ranging from 0-255. - - default_red= [VT] - Format: ,,,..., - Change the default red palette of the console. - This is a 16-member array composed of values - ranging from 0-255. - - default_utf8= [VT] - Format=<0|1> - Set system-wide default UTF-8 mode for all tty's. - Default is 0 and by setting to 1, it enables UTF-8 - mode for all newly opened or allocated terminals. - dhash_entries= [KNL] Set number of hash buckets for dentry cache. @@ -720,15 +695,8 @@ and is between 256 and 4096 characters. It is defined in the file idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed See Documentation/ide.txt. - idle= [X86] - Format: idle=poll or idle=mwait - Poll forces a polling idle loop that can slightly improves the performance - of waking up a idle CPU, but will use a lot of power and make the system - run hot. Not recommended. - idle=mwait. On systems which support MONITOR/MWAIT but the kernel chose - to not use it because it doesn't save as much power as a normal idle - loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same - as idle=poll. + idle= [HW] + Format: idle=poll or idle=halt ignore_loglevel [KNL] Ignore loglevel setting - this will print /all/ @@ -840,11 +808,6 @@ and is between 256 and 4096 characters. It is defined in the file lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip Format: addr:,irq: - legacy_serial.force [HW,IA-32,X86-64] - Probe for COM ports at legacy addresses even - if PNPBIOS or ACPI should describe them. This - is for working around firmware defects. - llsc*= [IA64] See function print_params() in arch/ia64/sn/kernel/llsc4.c. @@ -1194,11 +1157,6 @@ and is between 256 and 4096 characters. It is defined in the file nomce [IA-32] Machine Check Exception - noreplace-paravirt [IA-32,PV_OPS] Don't patch paravirt_ops - - noreplace-smp [IA-32,SMP] Don't replace SMP instructions - with UP alternatives - noresidual [PPC] Don't use residual data on PReP machines. noresume [SWSUSP] Disables resume and restores original swap @@ -1604,20 +1562,6 @@ and is between 256 and 4096 characters. It is defined in the file smart2= [HW] Format: [,[,...,]] - smp-alt-once [IA-32,SMP] On a hotplug CPU system, only - attempt to substitute SMP alternatives once at boot. - - smsc-ircc2.nopnp [HW] Don't use PNP to discover SMC devices - smsc-ircc2.ircc_cfg= [HW] Device configuration I/O port - smsc-ircc2.ircc_sir= [HW] SIR base I/O port - smsc-ircc2.ircc_fir= [HW] FIR base I/O port - smsc-ircc2.ircc_irq= [HW] IRQ line - smsc-ircc2.ircc_dma= [HW] DMA channel - smsc-ircc2.ircc_transceiver= [HW] Transceiver type: - 0: Toshiba Satellite 1800 (GP data pin select) - 1: Fast pin select (default) - 2: ATC IRMode - snd-ad1816a= [HW,ALSA] snd-ad1848= [HW,ALSA] @@ -1876,7 +1820,6 @@ and is between 256 and 4096 characters. It is defined in the file [USBHID] The interval which mice are to be polled at. vdso= [IA-32,SH] - vdso=2: enable compat VDSO (default with COMPAT_VDSO) vdso=1: enable VDSO (default) vdso=0: disable VDSO mapping diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt index da5404ab7569..d71fafffce90 100644 --- a/trunk/Documentation/kprobes.txt +++ b/trunk/Documentation/kprobes.txt @@ -14,7 +14,6 @@ CONTENTS 8. Kprobes Example 9. Jprobes Example 10. Kretprobes Example -Appendix A: The kprobes debugfs interface 1. Concepts: Kprobes, Jprobes, Return Probes @@ -350,12 +349,9 @@ for instrumentation and error reporting.) If the number of times a function is called does not match the number of times it returns, registering a return probe on that function may -produce undesirable results. In such a case, a line: -kretprobe BUG!: Processing kretprobe d000000000041aa8 @ c00000000004f48c -gets printed. With this information, one will be able to correlate the -exact instance of the kretprobe that caused the problem. We have the -do_exit() case covered. do_execve() and do_fork() are not an issue. -We're unaware of other specific cases where this could be a problem. +produce undesirable results. We have the do_exit() case covered. +do_execve() and do_fork() are not an issue. We're unaware of other +specific cases where this could be a problem. If, upon entry to or exit from a function, the CPU is running on a stack other than that of the current task, registering a return @@ -618,27 +614,3 @@ http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe http://www.redhat.com/magazine/005mar05/features/kprobes/ http://www-users.cs.umn.edu/~boutcher/kprobes/ http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115) - - -Appendix A: The kprobes debugfs interface - -With recent kernels (> 2.6.20) the list of registered kprobes is visible -under the /debug/kprobes/ directory (assuming debugfs is mounted at /debug). - -/debug/kprobes/list: Lists all registered probes on the system - -c015d71a k vfs_read+0x0 -c011a316 j do_fork+0x0 -c03dedc5 r tcp_v4_rcv+0x0 - -The first column provides the kernel address where the probe is inserted. -The second column identifies the type of probe (k - kprobe, r - kretprobe -and j - jprobe), while the third column specifies the symbol+offset of -the probe. If the probed function belongs to a module, the module name -is also specified. - -/debug/kprobes/enabled: Turn kprobes ON/OFF - -Provides a knob to globally turn registered kprobes ON or OFF. By default, -all kprobes are enabled. By echoing "0" to this file, all registered probes -will be disarmed, till such time a "1" is echoed to this file. diff --git a/trunk/Documentation/laptop-mode.txt b/trunk/Documentation/laptop-mode.txt index eeedee11c8c2..6f639e3473af 100644 --- a/trunk/Documentation/laptop-mode.txt +++ b/trunk/Documentation/laptop-mode.txt @@ -33,7 +33,7 @@ or anything. Simply install all the files included in this document, and laptop mode will automatically be started when you're on battery. For your convenience, a tarball containing an installer can be downloaded at: -http://www.samwel.tk/laptop_mode/laptop_mode/ +http://www.xs4all.nl/~bsamwel/laptop_mode/tools/ To configure laptop mode, you need to edit the configuration file, which is located in /etc/default/laptop-mode on Debian-based systems, or in diff --git a/trunk/Documentation/oops-tracing.txt b/trunk/Documentation/oops-tracing.txt index 7d5b60dea551..ea55ea8bc8ef 100644 --- a/trunk/Documentation/oops-tracing.txt +++ b/trunk/Documentation/oops-tracing.txt @@ -234,6 +234,9 @@ characters, each representing a particular tainted value. 6: 'B' if a page-release function has found a bad page reference or some unexpected page flags. + 7: 'U' if a user specifically requested that the Tainted flag be set, + ' ' otherwise. + 7: 'U' if a user or user application specifically requested that the Tainted flag be set, ' ' otherwise. diff --git a/trunk/Documentation/pci.txt b/trunk/Documentation/pci.txt index e2c9d0a0c43d..cdf2f3c0ab14 100644 --- a/trunk/Documentation/pci.txt +++ b/trunk/Documentation/pci.txt @@ -124,6 +124,10 @@ initialization with a pointer to a structure describing the driver err_handler See Documentation/pci-error-recovery.txt + multithread_probe Enable multi-threaded probe/scan. Driver must + provide its own locking/syncronization for init + operations if this is enabled. + The ID table is an array of struct pci_device_id entries ending with an all-zero entry. Each entry consists of: @@ -159,9 +163,9 @@ echo "vendor device subvendor subdevice class class_mask driver_data" > \ /sys/bus/pci/drivers/{driver}/new_id All fields are passed in as hexadecimal values (no leading 0x). -The vendor and device fields are mandatory, the others are optional. Users -need pass only as many optional fields as necessary: - o subvendor and subdevice fields default to PCI_ANY_ID (FFFFFFFF) +Users need pass only as many fields as necessary: + o vendor, device, subvendor, and subdevice fields default + to PCI_ANY_ID (FFFFFFFF), o class and classmask fields default to 0 o driver_data defaults to 0UL. @@ -545,6 +549,8 @@ pci_find_slot() Find pci_dev corresponding to given bus and pci_set_power_state() Set PCI Power Management state (0=D0 ... 3=D3) pci_find_capability() Find specified capability in device's capability list. +pci_module_init() Inline helper function for ensuring correct + pci_driver initialization and error handling. pci_resource_start() Returns bus start address for a given PCI region pci_resource_end() Returns bus end address for a given PCI region pci_resource_len() Returns the byte length of a PCI region diff --git a/trunk/Documentation/pcmcia/driver.txt b/trunk/Documentation/pcmcia/driver.txt deleted file mode 100644 index 0ac167920778..000000000000 --- a/trunk/Documentation/pcmcia/driver.txt +++ /dev/null @@ -1,30 +0,0 @@ -PCMCIA Driver -------------- - - -sysfs ------ - -New PCMCIA IDs may be added to a device driver pcmcia_device_id table at -runtime as shown below: - -echo "match_flags manf_id card_id func_id function device_no \ -prod_id_hash[0] prod_id_hash[1] prod_id_hash[2] prod_id_hash[3]" > \ -/sys/bus/pcmcia/drivers/{driver}/new_id - -All fields are passed in as hexadecimal values (no leading 0x). -The meaning is described in the PCMCIA specification, the match_flags is -a bitwise or-ed combination from PCMCIA_DEV_ID_MATCH_* constants -defined in include/linux/mod_devicetable.h. - -Once added, the driver probe routine will be invoked for any unclaimed -PCMCIA device listed in its (newly updated) pcmcia_device_id list. - -A common use-case is to add a new device according to the manufacturer ID -and the card ID (form the manf_id and card_id file in the device tree). -For this, just use: - -echo "0x3 manf_id card_id 0 0 0 0 0 0 0" > \ - /sys/bus/pcmcia/drivers/{driver}/new_id - -after loading the driver. diff --git a/trunk/Documentation/power/basic-pm-debugging.txt b/trunk/Documentation/power/basic-pm-debugging.txt deleted file mode 100644 index 1a85e2b964dc..000000000000 --- a/trunk/Documentation/power/basic-pm-debugging.txt +++ /dev/null @@ -1,106 +0,0 @@ -Debugging suspend and resume - (C) 2007 Rafael J. Wysocki , GPL - -1. Testing suspend to disk (STD) - -To verify that the STD works, you can try to suspend in the "reboot" mode: - -# echo reboot > /sys/power/disk -# echo disk > /sys/power/state - -and the system should suspend, reboot, resume and get back to the command prompt -where you have started the transition. If that happens, the STD is most likely -to work correctly, but you need to repeat the test at least a couple of times in -a row for confidence. This is necessary, because some problems only show up on -a second attempt at suspending and resuming the system. You should also test -the "platform" and "shutdown" modes of suspend: - -# echo platform > /sys/power/disk -# echo disk > /sys/power/state - -or - -# echo shutdown > /sys/power/disk -# echo disk > /sys/power/state - -in which cases you will have to press the power button to make the system -resume. If that does not work, you will need to identify what goes wrong. - -a) Test mode of STD - -To verify if there are any drivers that cause problems you can run the STD -in the test mode: - -# echo test > /sys/power/disk -# echo disk > /sys/power/state - -in which case the system should freeze tasks, suspend devices, disable nonboot -CPUs (if any), wait for 5 seconds, enable nonboot CPUs, resume devices, thaw -tasks and return to your command prompt. If that fails, most likely there is -a driver that fails to either suspend or resume (in the latter case the system -may hang or be unstable after the test, so please take that into consideration). -To find this driver, you can carry out a binary search according to the rules: -- if the test fails, unload a half of the drivers currently loaded and repeat -(that would probably involve rebooting the system, so always note what drivers -have been loaded before the test), -- if the test succeeds, load a half of the drivers you have unloaded most -recently and repeat. - -Once you have found the failing driver (there can be more than just one of -them), you have to unload it every time before the STD transition. In that case -please make sure to report the problem with the driver. - -It is also possible that a cycle can still fail after you have unloaded -all modules. In that case, you would want to look in your kernel configuration -for the drivers that can be compiled as modules (testing again with them as -modules), and possibly also try boot time options such as "noapic" or "noacpi". - -b) Testing minimal configuration - -If the test mode of STD works, you can boot the system with "init=/bin/bash" -and attempt to suspend in the "reboot", "shutdown" and "platform" modes. If -that does not work, there probably is a problem with a driver statically -compiled into the kernel and you can try to compile more drivers as modules, -so that they can be tested individually. Otherwise, there is a problem with a -modular driver and you can find it by loading a half of the modules you normally -use and binary searching in accordance with the algorithm: -- if there are n modules loaded and the attempt to suspend and resume fails, -unload n/2 of the modules and try again (that would probably involve rebooting -the system), -- if there are n modules loaded and the attempt to suspend and resume succeeds, -load n/2 modules more and try again. - -Again, if you find the offending module(s), it(they) must be unloaded every time -before the STD transition, and please report the problem with it(them). - -c) Advanced debugging - -In case the STD does not work on your system even in the minimal configuration -and compiling more drivers as modules is not practical or some modules cannot -be unloaded, you can use one of the more advanced debugging techniques to find -the problem. First, if there is a serial port in your box, you can set the -CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel -messages using the serial console. This may provide you with some information -about the reasons of the suspend (resume) failure. Alternatively, it may be -possible to use a FireWire port for debugging with firescope -(ftp://ftp.firstfloor.org/pub/ak/firescope/). On i386 it is also possible to -use the PM_TRACE mechanism documented in Documentation/s2ram.txt . - -2. Testing suspend to RAM (STR) - -To verify that the STR works, it is generally more convenient to use the s2ram -tool available from http://suspend.sf.net and documented at -http://en.opensuse.org/s2ram . However, before doing that it is recommended to -carry out the procedure described in section 1. - -Assume you have resolved the problems with the STD and you have found some -failing drivers. These drivers are also likely to fail during the STR or -during the resume, so it is better to unload them every time before the STR -transition. Now, you can follow the instructions at -http://en.opensuse.org/s2ram to test the system, but if it does not work -"out of the box", you may need to boot it with "init=/bin/bash" and test -s2ram in the minimal configuration. In that case, you may be able to search -for failing drivers by following the procedure analogous to the one described in -1b). If you find some failing drivers, you will have to unload them every time -before the STR transition (ie. before you run s2ram), and please report the -problems with them. diff --git a/trunk/Documentation/power/drivers-testing.txt b/trunk/Documentation/power/drivers-testing.txt deleted file mode 100644 index 33016c2f18dd..000000000000 --- a/trunk/Documentation/power/drivers-testing.txt +++ /dev/null @@ -1,42 +0,0 @@ -Testing suspend and resume support in device drivers - (C) 2007 Rafael J. Wysocki , GPL - -1. Preparing the test system - -Unfortunately, to effectively test the support for the system-wide suspend and -resume transitions in a driver, it is necessary to suspend and resume a fully -functional system with this driver loaded. Moreover, that should be done -several times, preferably several times in a row, and separately for the suspend -to disk (STD) and the suspend to RAM (STR) transitions, because each of these -cases involves different ordering of operations and different interactions with -the machine's BIOS. - -Of course, for this purpose the test system has to be known to suspend and -resume without the driver being tested. Thus, if possible, you should first -resolve all suspend/resume-related problems in the test system before you start -testing the new driver. Please see Documents/power/basic-pm-debugging.txt for -more information about the debugging of suspend/resume functionality. - -2. Testing the driver - -Once you have resolved the suspend/resume-related problems with your test system -without the new driver, you are ready to test it: - -a) Build the driver as a module, load it and try the STD in the test mode (see: -Documents/power/basic-pm-debugging.txt, 1a)). - -b) Load the driver and attempt to suspend to disk in the "reboot", "shutdown" -and "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1). - -c) Compile the driver directly into the kernel and try the STD in the test mode. - -d) Attempt to suspend to disk with the driver compiled directly into the kernel -in the "reboot", "shutdown" and "platform" modes. - -e) Attempt to suspend to RAM using the s2ram tool with the driver loaded (see: -Documents/power/basic-pm-debugging.txt, 2). As far as the STR tests are -concerned, it should not matter whether or not the driver is built as a module. - -Each of the above tests should be repeated several times and the STD tests -should be mixed with the STR tests. If any of them fails, the driver cannot be -regarded as suspend/resume-safe. diff --git a/trunk/Documentation/power/interface.txt b/trunk/Documentation/power/interface.txt index fd5192a8fa8a..8c5b41bf3f36 100644 --- a/trunk/Documentation/power/interface.txt +++ b/trunk/Documentation/power/interface.txt @@ -34,12 +34,8 @@ for 5 seconds, resume devices, unfreeze tasks and enable nonboot CPUs. Then, we are able to look in the log messages and work out, for example, which code is being slow and which device drivers are misbehaving. -Reading from this file will display all supported modes and the currently -selected one in brackets, for example - - [shutdown] reboot test testproc - -Writing to this file will accept one of +Reading from this file will display what the mode is currently set +to. Writing to this file will accept one of 'platform' (only if the platform supports it) 'shutdown' diff --git a/trunk/Documentation/power/pci.txt b/trunk/Documentation/power/pci.txt index e00b099a4b86..b6a3cbf7e846 100644 --- a/trunk/Documentation/power/pci.txt +++ b/trunk/Documentation/power/pci.txt @@ -203,7 +203,7 @@ resume Usage: -if (dev->driver && dev->driver->resume) +if (dev->driver && dev->driver->suspend) dev->driver->resume(dev) The resume callback may be called from any power state, and is always meant to diff --git a/trunk/Documentation/powerpc/booting-without-of.txt b/trunk/Documentation/powerpc/booting-without-of.txt index d4bfae75c946..033a3f3b3ab7 100644 --- a/trunk/Documentation/powerpc/booting-without-of.txt +++ b/trunk/Documentation/powerpc/booting-without-of.txt @@ -1560,9 +1560,6 @@ platforms are moved over to use the flattened-device-tree model. network device. This is used by the bootwrapper to interpret MAC addresses passed by the firmware when no information other than indices is available to associate an address with a device. - - phy-connection-type : a string naming the controller/PHY interface type, - i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "tbi", - or "rtbi". Example: ucc@2000 { @@ -1577,7 +1574,6 @@ platforms are moved over to use the flattened-device-tree model. rx-clock = "none"; tx-clock = "clk9"; phy-handle = <212000>; - phy-connection-type = "gmii"; pio-handle = <140001>; }; diff --git a/trunk/Documentation/rtc.txt b/trunk/Documentation/rtc.txt index 7c701b88d6d5..1ef6bb88cd00 100644 --- a/trunk/Documentation/rtc.txt +++ b/trunk/Documentation/rtc.txt @@ -147,7 +147,7 @@ RTC class framework, but can't be supported by the older driver. * RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC is connected to an IRQ line, it can often issue an alarm IRQ up to - 24 hours in the future. (Use RTC_WKALM_* by preference.) + 24 hours in the future. * RTC_WKALM_SET, RTC_WKALM_RD ... RTCs that can issue alarms beyond the next 24 hours use a slightly more powerful API, which supports @@ -175,7 +175,10 @@ driver returns ENOIOCTLCMD. Some common examples: called with appropriate values. * RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: the - set_alarm/read_alarm functions will be called. + set_alarm/read_alarm functions will be called. To differentiate + between the ALM and WKALM, check the larger fields of the rtc_wkalrm + struct (like tm_year). These will be set to -1 when using ALM and + will be set to proper values when using WKALM. * RTC_IRQP_SET, RTC_IRQP_READ: the irq_set_freq function will be called to set the frequency while the framework will handle the read for you diff --git a/trunk/Documentation/scsi/aacraid.txt b/trunk/Documentation/scsi/aacraid.txt index ce3cb42507bd..dc8e44fc650f 100644 --- a/trunk/Documentation/scsi/aacraid.txt +++ b/trunk/Documentation/scsi/aacraid.txt @@ -37,11 +37,7 @@ Supported Cards/Chipsets 9005:0286:9005:029d Adaptec 2420SA (Intruder HP release) 9005:0286:9005:02ac Adaptec 1800 (Typhoon44) 9005:0285:9005:02b5 Adaptec 5445 (Voodoo44) - 9005:0285:15d9:02b5 SMC AOC-USAS-S4i - 9005:0285:15d9:02c9 SMC AOC-USAS-S4iR 9005:0285:9005:02b6 Adaptec 5805 (Voodoo80) - 9005:0285:15d9:02b6 SMC AOC-USAS-S8i - 9005:0285:15d9:02ca SMC AOC-USAS-S8iR 9005:0285:9005:02b7 Adaptec 5085 (Voodoo08) 9005:0285:9005:02bb Adaptec 3405 (Marauder40LP) 9005:0285:9005:02bc Adaptec 3805 (Marauder80LP) @@ -97,9 +93,6 @@ Supported Cards/Chipsets 9005:0286:9005:02ae (Aurora Lite ARK) 9005:0285:9005:02b0 (Sunrise Lake ARK) 9005:0285:9005:02b1 Adaptec (Voodoo 8 internal 8 external) - 9005:0285:108e:7aac SUN STK RAID REM (Voodoo44 Coyote) - 9005:0285:108e:0286 SUN STK RAID INT (Cougar) - 9005:0285:108e:0287 SUN STK RAID EXT (Prometheus) People ------------------------- diff --git a/trunk/Documentation/scsi/ncr53c8xx.txt b/trunk/Documentation/scsi/ncr53c8xx.txt index 88ef88b949f7..caf10b155185 100644 --- a/trunk/Documentation/scsi/ncr53c8xx.txt +++ b/trunk/Documentation/scsi/ncr53c8xx.txt @@ -562,6 +562,11 @@ if only one has a flaw for some SCSI feature, you can disable the support by the driver of this feature at linux start-up and enable this feature after boot-up only for devices that support it safely. +CONFIG_SCSI_NCR53C8XX_PROFILE_SUPPORT (default answer: n) + This option must be set for profiling information to be gathered + and printed out through the proc file system. This features may + impact performances. + CONFIG_SCSI_NCR53C8XX_IOMAPPED (default answer: n) Answer "y" if you suspect your mother board to not allow memory mapped I/O. May slow down performance a little. This option is required by diff --git a/trunk/Documentation/sh/clk.txt b/trunk/Documentation/sh/clk.txt deleted file mode 100644 index 9aef710e9a4b..000000000000 --- a/trunk/Documentation/sh/clk.txt +++ /dev/null @@ -1,32 +0,0 @@ -Clock framework on SuperH architecture - -The framework on SH extends existing API by the function clk_set_rate_ex, -which prototype is as follows: - - clk_set_rate_ex (struct clk *clk, unsigned long rate, int algo_id) - -The algo_id parameter is used to specify algorithm used to recalculate clocks, -adjanced to clock, specified as first argument. It is assumed that algo_id==0 -means no changes to adjanced clock - -Internally, the clk_set_rate_ex forwards request to clk->ops->set_rate method, -if it is present in ops structure. The method should set the clock rate and adjust -all needed clocks according to the passed algo_id. -Exact values for algo_id are machine-dependend. For the sh7722, the following -values are defined: - - NO_CHANGE = 0, - IUS_N1_N1, /* I:U = N:1, U:Sh = N:1 */ - IUS_322, /* I:U:Sh = 3:2:2 */ - IUS_522, /* I:U:Sh = 5:2:2 */ - IUS_N11, /* I:U:Sh = N:1:1 */ - SB_N1, /* Sh:B = N:1 */ - SB3_N1, /* Sh:B3 = N:1 */ - SB3_32, /* Sh:B3 = 3:2 */ - SB3_43, /* Sh:B3 = 4:3 */ - SB3_54, /* Sh:B3 = 5:4 */ - BP_N1, /* B:P = N:1 */ - IP_N1 /* I:P = N:1 */ - -Each of these constants means relation between clocks that can be set via the FRQCR -register diff --git a/trunk/Documentation/spi/pxa2xx b/trunk/Documentation/spi/pxa2xx index 215e3b8e7266..f9717fe9bd85 100644 --- a/trunk/Documentation/spi/pxa2xx +++ b/trunk/Documentation/spi/pxa2xx @@ -62,7 +62,7 @@ static struct resource pxa_spi_nssp_resources[] = { static struct pxa2xx_spi_master pxa_nssp_master_info = { .ssp_type = PXA25x_NSSP, /* Type of SSP */ - .clock_enable = CKEN_NSSP, /* NSSP Peripheral clock */ + .clock_enable = CKEN9_NSSP, /* NSSP Peripheral clock */ .num_chipselect = 1, /* Matches the number of chips attached to NSSP */ .enable_dma = 1, /* Enables NSSP DMA */ }; diff --git a/trunk/Documentation/spi/spi-summary b/trunk/Documentation/spi/spi-summary index 795fbb48ffa7..ecc7c9eb9f29 100644 --- a/trunk/Documentation/spi/spi-summary +++ b/trunk/Documentation/spi/spi-summary @@ -8,7 +8,7 @@ What is SPI? The "Serial Peripheral Interface" (SPI) is a synchronous four wire serial link used to connect microcontrollers to sensors, memory, and peripherals. -The three signal wires hold a clock (SCK, often on the order of 10 MHz), +The three signal wires hold a clock (SCLK, often on the order of 10 MHz), and parallel data lines with "Master Out, Slave In" (MOSI) or "Master In, Slave Out" (MISO) signals. (Other names are also used.) There are four clocking modes through which data is exchanged; mode-0 and mode-3 are most @@ -22,7 +22,7 @@ other signals, often including an interrupt to the master. Unlike serial busses like USB or SMBUS, even low level protocols for SPI slave functions are usually not interoperable between vendors -(except for commodities like SPI memory chips). +(except for cases like SPI memory chips). - SPI may be used for request/response style device protocols, as with touchscreen sensors and memory chips. @@ -77,9 +77,8 @@ cards without needing a special purpose MMC/SD/SDIO controller. How do these driver programming interfaces work? ------------------------------------------------ The header file includes kerneldoc, as does the -main source code, and you should certainly read that chapter of the -kernel API document. This is just an overview, so you get the big -picture before those details. +main source code, and you should certainly read that. This is just +an overview, so you get the big picture before the details. SPI requests always go into I/O queues. Requests for a given SPI device are always executed in FIFO order, and complete asynchronously through @@ -89,7 +88,7 @@ a command and then reading its response. There are two types of SPI driver, here called: - Controller drivers ... controllers may be built in to System-On-Chip + Controller drivers ... these are often built in to System-On-Chip processors, and often support both Master and Slave roles. These drivers touch hardware registers and may use DMA. Or they can be PIO bitbangers, needing just GPIO pins. @@ -109,18 +108,18 @@ those two types of driver. At this writing, Linux has no slave side programming interface. There is a minimal core of SPI programming interfaces, focussing on -using the driver model to connect controller and protocol drivers using +using driver model to connect controller and protocol drivers using device tables provided by board specific initialization code. SPI shows up in sysfs in several locations: - /sys/devices/.../CTLR/spiB.C ... spi_device on bus "B", + /sys/devices/.../CTLR/spiB.C ... spi_device for on bus "B", chipselect C, accessed through CTLR. /sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver that should be used with this device (for hotplug/coldplug) /sys/bus/spi/devices/spiB.C ... symlink to the physical - spiB.C device + spiB-C device /sys/bus/spi/drivers/D ... driver for one or more spi*.* devices @@ -241,7 +240,7 @@ The board_info should provide enough information to let the system work without the chip's driver being loaded. The most troublesome aspect of that is likely the SPI_CS_HIGH bit in the spi_device.mode field, since sharing a bus with a device that interprets chipselect "backwards" is -not possible until the infrastructure knows how to deselect it. +not possible. Then your board initialization code would register that table with the SPI infrastructure, so that it's available later when the SPI master controller @@ -269,14 +268,16 @@ board info based on the board that was hotplugged. Of course, you'd later call at least spi_unregister_device() when that board is removed. When Linux includes support for MMC/SD/SDIO/DataFlash cards through SPI, those -configurations will also be dynamic. Fortunately, such devices all support -basic device identification probes, so they should hotplug normally. +configurations will also be dynamic. Fortunately, those devices all support +basic device identification probes, so that support should hotplug normally. How do I write an "SPI Protocol Driver"? ---------------------------------------- -Most SPI drivers are currently kernel drivers, but there's also support -for userspace drivers. Here we talk only about kernel drivers. +All SPI drivers are currently kernel drivers. A userspace driver API +would just be another kernel driver, probably offering some lowlevel +access through aio_read(), aio_write(), and ioctl() calls and using the +standard userspace sysfs mechanisms to bind to a given SPI device. SPI protocol drivers somewhat resemble platform device drivers: @@ -318,8 +319,7 @@ might look like this unless you're creating a class_device: As soon as it enters probe(), the driver may issue I/O requests to the SPI device using "struct spi_message". When remove() returns, -or after probe() fails, the driver guarantees that it won't submit -any more such messages. +the driver guarantees that it won't submit any more such messages. - An spi_message is a sequence of protocol operations, executed as one atomic sequence. SPI driver controls include: @@ -368,8 +368,7 @@ any more such messages. Some drivers may need to modify spi_device characteristics like the transfer mode, wordsize, or clock rate. This is done with spi_setup(), which would normally be called from probe() before the first I/O is -done to the device. However, that can also be called at any time -that no message is pending for that device. +done to the device. While "spi_device" would be the bottom boundary of the driver, the upper boundaries might include sysfs (especially for sensor readings), @@ -446,15 +445,11 @@ SPI MASTER METHODS This sets up the device clock rate, SPI mode, and word sizes. Drivers may change the defaults provided by board_info, and then call spi_setup(spi) to invoke this routine. It may sleep. - Unless each SPI slave has its own configuration registers, don't - change them right away ... otherwise drivers could corrupt I/O - that's in progress for other SPI devices. master->transfer(struct spi_device *spi, struct spi_message *message) This must not sleep. Its responsibility is arrange that the - transfer happens and its complete() callback is issued. The two - will normally happen later, after other transfers complete, and - if the controller is idle it will need to be kickstarted. + transfer happens and its complete() callback is issued; the two + will normally happen later, after other transfers complete. master->cleanup(struct spi_device *spi) Your controller driver may use spi_device.controller_state to hold diff --git a/trunk/Documentation/spi/spidev b/trunk/Documentation/spi/spidev deleted file mode 100644 index 5c8e1b988a08..000000000000 --- a/trunk/Documentation/spi/spidev +++ /dev/null @@ -1,307 +0,0 @@ -SPI devices have a limited userspace API, supporting basic half-duplex -read() and write() access to SPI slave devices. Using ioctl() requests, -full duplex transfers and device I/O configuration are also available. - - #include - #include - #include - #include - #include - -Some reasons you might want to use this programming interface include: - - * Prototyping in an environment that's not crash-prone; stray pointers - in userspace won't normally bring down any Linux system. - - * Developing simple protocols used to talk to microcontrollers acting - as SPI slaves, which you may need to change quite often. - -Of course there are drivers that can never be written in userspace, because -they need to access kernel interfaces (such as IRQ handlers or other layers -of the driver stack) that are not accessible to userspace. - - -DEVICE CREATION, DRIVER BINDING -=============================== -The simplest way to arrange to use this driver is to just list it in the -spi_board_info for a device as the driver it should use: the "modalias" -entry is "spidev", matching the name of the driver exposing this API. -Set up the other device characteristics (bits per word, SPI clocking, -chipselect polarity, etc) as usual, so you won't always need to override -them later. - -(Sysfs also supports userspace driven binding/unbinding of drivers to -devices. That mechanism might be supported here in the future.) - -When you do that, the sysfs node for the SPI device will include a child -device node with a "dev" attribute that will be understood by udev or mdev. -(Larger systems will have "udev". Smaller ones may configure "mdev" into -busybox; it's less featureful, but often enough.) For a SPI device with -chipselect C on bus B, you should see: - - /dev/spidevB.C ... character special device, major number 153 with - a dynamically chosen minor device number. This is the node - that userspace programs will open, created by "udev" or "mdev". - - /sys/devices/.../spiB.C ... as usual, the SPI device node will - be a child of its SPI master controller. - - /sys/class/spidev/spidevB.C ... created when the "spidev" driver - binds to that device. (Directory or symlink, based on whether - or not you enabled the "deprecated sysfs files" Kconfig option.) - -Do not try to manage the /dev character device special file nodes by hand. -That's error prone, and you'd need to pay careful attention to system -security issues; udev/mdev should already be configured securely. - -If you unbind the "spidev" driver from that device, those two "spidev" nodes -(in sysfs and in /dev) should automatically be removed (respectively by the -kernel and by udev/mdev). You can unbind by removing the "spidev" driver -module, which will affect all devices using this driver. You can also unbind -by having kernel code remove the SPI device, probably by removing the driver -for its SPI controller (so its spi_master vanishes). - -Since this is a standard Linux device driver -- even though it just happens -to expose a low level API to userspace -- it can be associated with any number -of devices at a time. Just provide one spi_board_info record for each such -SPI device, and you'll get a /dev device node for each device. - - -BASIC CHARACTER DEVICE API -========================== -Normal open() and close() operations on /dev/spidevB.D files work as you -would expect. - -Standard read() and write() operations are obviously only half-duplex, and -the chipselect is deactivated between those operations. Full-duplex access, -and composite operation without chipselect de-activation, is available using -the SPI_IOC_MESSAGE(N) request. - -Several ioctl() requests let your driver read or override the device's current -settings for data transfer parameters: - - SPI_IOC_RD_MODE, SPI_IOC_WR_MODE ... pass a pointer to a byte which will - return (RD) or assign (WR) the SPI transfer mode. Use the constants - SPI_MODE_0..SPI_MODE_3; or if you prefer you can combine SPI_CPOL - (clock polarity, idle high iff this is set) or SPI_CPHA (clock phase, - sample on trailing edge iff this is set) flags. - - SPI_IOC_RD_LSB_FIRST, SPI_IOC_WR_LSB_FIRST ... pass a pointer to a byte - which will return (RD) or assign (WR) the bit justification used to - transfer SPI words. Zero indicates MSB-first; other values indicate - the less common LSB-first encoding. In both cases the specified value - is right-justified in each word, so that unused (TX) or undefined (RX) - bits are in the MSBs. - - SPI_IOC_RD_BITS_PER_WORD, SPI_IOC_WR_BITS_PER_WORD ... pass a pointer to - a byte which will return (RD) or assign (WR) the number of bits in - each SPI transfer word. The value zero signifies eight bits. - - SPI_IOC_RD_MAX_SPEED_HZ, SPI_IOC_WR_MAX_SPEED_HZ ... pass a pointer to a - u32 which will return (RD) or assign (WR) the maximum SPI transfer - speed, in Hz. The controller can't necessarily assign that specific - clock speed. - -NOTES: - - - At this time there is no async I/O support; everything is purely - synchronous. - - - There's currently no way to report the actual bit rate used to - shift data to/from a given device. - - - From userspace, you can't currently change the chip select polarity; - that could corrupt transfers to other devices sharing the SPI bus. - Each SPI device is deselected when it's not in active use, allowing - other drivers to talk to other devices. - - - There's a limit on the number of bytes each I/O request can transfer - to the SPI device. It defaults to one page, but that can be changed - using a module parameter. - - - Because SPI has no low-level transfer acknowledgement, you usually - won't see any I/O errors when talking to a non-existent device. - - -FULL DUPLEX CHARACTER DEVICE API -================================ - -See the sample program below for one example showing the use of the full -duplex programming interface. (Although it doesn't perform a full duplex -transfer.) The model is the same as that used in the kernel spi_sync() -request; the individual transfers offer the same capabilities as are -available to kernel drivers (except that it's not asynchronous). - -The example shows one half-duplex RPC-style request and response message. -These requests commonly require that the chip not be deselected between -the request and response. Several such requests could be chained into -a single kernel request, even allowing the chip to be deselected after -each response. (Other protocol options include changing the word size -and bitrate for each transfer segment.) - -To make a full duplex request, provide both rx_buf and tx_buf for the -same transfer. It's even OK if those are the same buffer. - - -SAMPLE PROGRAM -============== - --------------------------------- CUT HERE -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - - -static int verbose; - -static void do_read(int fd, int len) -{ - unsigned char buf[32], *bp; - int status; - - /* read at least 2 bytes, no more than 32 */ - if (len < 2) - len = 2; - else if (len > sizeof(buf)) - len = sizeof(buf); - memset(buf, 0, sizeof buf); - - status = read(fd, buf, len); - if (status < 0) { - perror("read"); - return; - } - if (status != len) { - fprintf(stderr, "short read\n"); - return; - } - - printf("read(%2d, %2d): %02x %02x,", len, status, - buf[0], buf[1]); - status -= 2; - bp = buf + 2; - while (status-- > 0) - printf(" %02x", *bp++); - printf("\n"); -} - -static void do_msg(int fd, int len) -{ - struct spi_ioc_transfer xfer[2]; - unsigned char buf[32], *bp; - int status; - - memset(xfer, 0, sizeof xfer); - memset(buf, 0, sizeof buf); - - if (len > sizeof buf) - len = sizeof buf; - - buf[0] = 0xaa; - xfer[0].tx_buf = (__u64) buf; - xfer[0].len = 1; - - xfer[1].rx_buf = (__u64) buf; - xfer[1].len = len; - - status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer); - if (status < 0) { - perror("SPI_IOC_MESSAGE"); - return; - } - - printf("response(%2d, %2d): ", len, status); - for (bp = buf; len; len--) - printf(" %02x", *bp++); - printf("\n"); -} - -static void dumpstat(const char *name, int fd) -{ - __u8 mode, lsb, bits; - __u32 speed; - - if (ioctl(fd, SPI_IOC_RD_MODE, &mode) < 0) { - perror("SPI rd_mode"); - return; - } - if (ioctl(fd, SPI_IOC_RD_LSB_FIRST, &lsb) < 0) { - perror("SPI rd_lsb_fist"); - return; - } - if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0) { - perror("SPI bits_per_word"); - return; - } - if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) { - perror("SPI max_speed_hz"); - return; - } - - printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n", - name, mode, bits, lsb ? "(lsb first) " : "", speed); -} - -int main(int argc, char **argv) -{ - int c; - int readcount = 0; - int msglen = 0; - int fd; - const char *name; - - while ((c = getopt(argc, argv, "hm:r:v")) != EOF) { - switch (c) { - case 'm': - msglen = atoi(optarg); - if (msglen < 0) - goto usage; - continue; - case 'r': - readcount = atoi(optarg); - if (readcount < 0) - goto usage; - continue; - case 'v': - verbose++; - continue; - case 'h': - case '?': -usage: - fprintf(stderr, - "usage: %s [-h] [-m N] [-r N] /dev/spidevB.D\n", - argv[0]); - return 1; - } - } - - if ((optind + 1) != argc) - goto usage; - name = argv[optind]; - - fd = open(name, O_RDWR); - if (fd < 0) { - perror("open"); - return 1; - } - - dumpstat(name, fd); - - if (msglen) - do_msg(fd, msglen); - - if (readcount) - do_read(fd, readcount); - - close(fd); - return 0; -} diff --git a/trunk/Documentation/sysctl/vm.txt b/trunk/Documentation/sysctl/vm.txt index 1d192565e182..e96a341eb7e4 100644 --- a/trunk/Documentation/sysctl/vm.txt +++ b/trunk/Documentation/sysctl/vm.txt @@ -197,22 +197,11 @@ and may not be fast. panic_on_oom -This enables or disables panic on out-of-memory feature. - -If this is set to 0, the kernel will kill some rogue process, -called oom_killer. Usually, oom_killer can kill rogue processes and -system will survive. - -If this is set to 1, the kernel panics when out-of-memory happens. -However, if a process limits using nodes by mempolicy/cpusets, -and those nodes become memory exhaustion status, one process -may be killed by oom-killer. No panic occurs in this case. -Because other nodes' memory may be free. This means system total status -may be not fatal yet. - -If this is set to 2, the kernel panics compulsorily even on the -above-mentioned. +This enables or disables panic on out-of-memory feature. If this is set to 1, +the kernel panics when out-of-memory happens. If this is set to 0, the kernel +will kill some rogue process, called oom_killer. Usually, oom_killer can kill +rogue processes and system will survive. If you want to panic the system +rather than killing rogue processes, set this to 1. The default value is 0. -1 and 2 are for failover of clustering. Please select either -according to your policy of failover. + diff --git a/trunk/Documentation/sysrq.txt b/trunk/Documentation/sysrq.txt index ba328f255417..d43aa9d3c105 100644 --- a/trunk/Documentation/sysrq.txt +++ b/trunk/Documentation/sysrq.txt @@ -1,6 +1,6 @@ Linux Magic System Request Key Hacks Documentation for sysrq.c -Last update: 2007-MAR-14 +Last update: 2007-JAN-06 * What is the magic SysRq key? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -75,7 +75,7 @@ On all - write a character to /proc/sysrq-trigger. e.g.: 'f' - Will call oom_kill to kill a memory hog process. -'g' - Used by kgdb on ppc and sh platforms. +'g' - Used by kgdb on ppc platforms. 'h' - Will display help (actually any other key than those listed above will display help. but 'h' is easy to remember :-) diff --git a/trunk/Documentation/tty.txt b/trunk/Documentation/tty.txt index 048a8762cfb5..5f799e612e03 100644 --- a/trunk/Documentation/tty.txt +++ b/trunk/Documentation/tty.txt @@ -108,9 +108,7 @@ hardware driver through the function pointers within the tty->driver structure: write() Write a block of characters to the tty device. - Returns the number of characters accepted. The - character buffer passed to this method is already - in kernel space. + Returns the number of characters accepted. put_char() Queues a character for writing to the tty device. If there is no room in the queue, the character is diff --git a/trunk/Documentation/usb/usb-serial.txt b/trunk/Documentation/usb/usb-serial.txt index b18e86a22506..d61f6e7865de 100644 --- a/trunk/Documentation/usb/usb-serial.txt +++ b/trunk/Documentation/usb/usb-serial.txt @@ -42,7 +42,7 @@ ConnectTech WhiteHEAT 4 port converter http://www.connecttech.com For any questions or problems with this driver, please contact - Connect Tech's Support Department at support@connecttech.com + Stuart MacDonald at stuartm@connecttech.com HandSpring Visor, Palm USB, and Clié USB driver diff --git a/trunk/Documentation/vm/slabinfo.c b/trunk/Documentation/vm/slabinfo.c deleted file mode 100644 index 41710ccf3a29..000000000000 --- a/trunk/Documentation/vm/slabinfo.c +++ /dev/null @@ -1,943 +0,0 @@ -/* - * Slabinfo: Tool to get reports about slabs - * - * (C) 2007 sgi, Christoph Lameter - * - * Compile by: - * - * gcc -o slabinfo slabinfo.c - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_SLABS 500 -#define MAX_ALIASES 500 -#define MAX_NODES 1024 - -struct slabinfo { - char *name; - int alias; - int refs; - int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu; - int hwcache_align, object_size, objs_per_slab; - int sanity_checks, slab_size, store_user, trace; - int order, poison, reclaim_account, red_zone; - unsigned long partial, objects, slabs; - int numa[MAX_NODES]; - int numa_partial[MAX_NODES]; -} slabinfo[MAX_SLABS]; - -struct aliasinfo { - char *name; - char *ref; - struct slabinfo *slab; -} aliasinfo[MAX_ALIASES]; - -int slabs = 0; -int aliases = 0; -int alias_targets = 0; -int highest_node = 0; - -char buffer[4096]; - -int show_alias = 0; -int show_slab = 0; -int skip_zero = 1; -int show_numa = 0; -int show_track = 0; -int show_first_alias = 0; -int validate = 0; -int shrink = 0; -int show_inverted = 0; -int show_single_ref = 0; -int show_totals = 0; -int sort_size = 0; - -int page_size; - -regex_t pattern; - -void fatal(const char *x, ...) -{ - va_list ap; - - va_start(ap, x); - vfprintf(stderr, x, ap); - va_end(ap); - exit(1); -} - -void usage(void) -{ - printf("slabinfo [-ahnpvtsz] [slab-regexp]\n" - "-a|--aliases Show aliases\n" - "-h|--help Show usage information\n" - "-n|--numa Show NUMA information\n" - "-s|--shrink Shrink slabs\n" - "-v|--validate Validate slabs\n" - "-t|--tracking Show alloc/free information\n" - "-T|--Totals Show summary information\n" - "-l|--slabs Show slabs\n" - "-S|--Size Sort by size\n" - "-z|--zero Include empty slabs\n" - "-f|--first-alias Show first alias\n" - "-i|--inverted Inverted list\n" - "-1|--1ref Single reference\n" - ); -} - -unsigned long read_obj(char *name) -{ - FILE *f = fopen(name, "r"); - - if (!f) - buffer[0] = 0; - else { - if (!fgets(buffer,sizeof(buffer), f)) - buffer[0] = 0; - fclose(f); - if (buffer[strlen(buffer)] == '\n') - buffer[strlen(buffer)] = 0; - } - return strlen(buffer); -} - - -/* - * Get the contents of an attribute - */ -unsigned long get_obj(char *name) -{ - if (!read_obj(name)) - return 0; - - return atol(buffer); -} - -unsigned long get_obj_and_str(char *name, char **x) -{ - unsigned long result = 0; - char *p; - - *x = NULL; - - if (!read_obj(name)) { - x = NULL; - return 0; - } - result = strtoul(buffer, &p, 10); - while (*p == ' ') - p++; - if (*p) - *x = strdup(p); - return result; -} - -void set_obj(struct slabinfo *s, char *name, int n) -{ - char x[100]; - - sprintf(x, "%s/%s", s->name, name); - - FILE *f = fopen(x, "w"); - - if (!f) - fatal("Cannot write to %s\n", x); - - fprintf(f, "%d\n", n); - fclose(f); -} - -/* - * Put a size string together - */ -int store_size(char *buffer, unsigned long value) -{ - unsigned long divisor = 1; - char trailer = 0; - int n; - - if (value > 1000000000UL) { - divisor = 100000000UL; - trailer = 'G'; - } else if (value > 1000000UL) { - divisor = 100000UL; - trailer = 'M'; - } else if (value > 1000UL) { - divisor = 100; - trailer = 'K'; - } - - value /= divisor; - n = sprintf(buffer, "%ld",value); - if (trailer) { - buffer[n] = trailer; - n++; - buffer[n] = 0; - } - if (divisor != 1) { - memmove(buffer + n - 2, buffer + n - 3, 4); - buffer[n-2] = '.'; - n++; - } - return n; -} - -void decode_numa_list(int *numa, char *t) -{ - int node; - int nr; - - memset(numa, 0, MAX_NODES * sizeof(int)); - - while (*t == 'N') { - t++; - node = strtoul(t, &t, 10); - if (*t == '=') { - t++; - nr = strtoul(t, &t, 10); - numa[node] = nr; - if (node > highest_node) - highest_node = node; - } - while (*t == ' ') - t++; - } -} - -void slab_validate(struct slabinfo *s) -{ - set_obj(s, "validate", 1); -} - -void slab_shrink(struct slabinfo *s) -{ - set_obj(s, "shrink", 1); -} - -int line = 0; - -void first_line(void) -{ - printf("Name Objects Objsize Space " - "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n"); -} - -/* - * Find the shortest alias of a slab - */ -struct aliasinfo *find_one_alias(struct slabinfo *find) -{ - struct aliasinfo *a; - struct aliasinfo *best = NULL; - - for(a = aliasinfo;a < aliasinfo + aliases; a++) { - if (a->slab == find && - (!best || strlen(best->name) < strlen(a->name))) { - best = a; - if (strncmp(a->name,"kmall", 5) == 0) - return best; - } - } - if (best) - return best; - fatal("Cannot find alias for %s\n", find->name); - return NULL; -} - -unsigned long slab_size(struct slabinfo *s) -{ - return s->slabs * (page_size << s->order); -} - - -void slabcache(struct slabinfo *s) -{ - char size_str[20]; - char dist_str[40]; - char flags[20]; - char *p = flags; - - if (skip_zero && !s->slabs) - return; - - store_size(size_str, slab_size(s)); - sprintf(dist_str,"%lu/%lu/%d", s->slabs, s->partial, s->cpu_slabs); - - if (!line++) - first_line(); - - if (s->aliases) - *p++ = '*'; - if (s->cache_dma) - *p++ = 'd'; - if (s->hwcache_align) - *p++ = 'A'; - if (s->poison) - *p++ = 'P'; - if (s->reclaim_account) - *p++ = 'a'; - if (s->red_zone) - *p++ = 'Z'; - if (s->sanity_checks) - *p++ = 'F'; - if (s->store_user) - *p++ = 'U'; - if (s->trace) - *p++ = 'T'; - - *p = 0; - printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n", - s->name, s->objects, s->object_size, size_str, dist_str, - s->objs_per_slab, s->order, - s->slabs ? (s->partial * 100) / s->slabs : 100, - s->slabs ? (s->objects * s->object_size * 100) / - (s->slabs * (page_size << s->order)) : 100, - flags); -} - -void slab_numa(struct slabinfo *s) -{ - int node; - - if (!highest_node) - fatal("No NUMA information available.\n"); - - if (skip_zero && !s->slabs) - return; - - if (!line) { - printf("\nSlab Node "); - for(node = 0; node <= highest_node; node++) - printf(" %4d", node); - printf("\n----------------------"); - for(node = 0; node <= highest_node; node++) - printf("-----"); - printf("\n"); - } - printf("%-21s ", s->name); - for(node = 0; node <= highest_node; node++) { - char b[20]; - - store_size(b, s->numa[node]); - printf(" %4s", b); - } - printf("\n"); - line++; -} - -void show_tracking(struct slabinfo *s) -{ - printf("\n%s: Calls to allocate a slab object\n", s->name); - printf("---------------------------------------------------\n"); - if (read_obj("alloc_calls")) - printf(buffer); - - printf("%s: Calls to free a slab object\n", s->name); - printf("-----------------------------------------------\n"); - if (read_obj("free_calls")) - printf(buffer); - -} - -void totals(void) -{ - struct slabinfo *s; - - int used_slabs = 0; - char b1[20], b2[20], b3[20], b4[20]; - unsigned long long max = 1ULL << 63; - - /* Object size */ - unsigned long long min_objsize = max, max_objsize = 0, avg_objsize; - - /* Number of partial slabs in a slabcache */ - unsigned long long min_partial = max, max_partial = 0, - avg_partial, total_partial = 0; - - /* Number of slabs in a slab cache */ - unsigned long long min_slabs = max, max_slabs = 0, - avg_slabs, total_slabs = 0; - - /* Size of the whole slab */ - unsigned long long min_size = max, max_size = 0, - avg_size, total_size = 0; - - /* Bytes used for object storage in a slab */ - unsigned long long min_used = max, max_used = 0, - avg_used, total_used = 0; - - /* Waste: Bytes used for alignment and padding */ - unsigned long long min_waste = max, max_waste = 0, - avg_waste, total_waste = 0; - /* Number of objects in a slab */ - unsigned long long min_objects = max, max_objects = 0, - avg_objects, total_objects = 0; - /* Waste per object */ - unsigned long long min_objwaste = max, - max_objwaste = 0, avg_objwaste, - total_objwaste = 0; - - /* Memory per object */ - unsigned long long min_memobj = max, - max_memobj = 0, avg_memobj, - total_objsize = 0; - - /* Percentage of partial slabs per slab */ - unsigned long min_ppart = 100, max_ppart = 0, - avg_ppart, total_ppart = 0; - - /* Number of objects in partial slabs */ - unsigned long min_partobj = max, max_partobj = 0, - avg_partobj, total_partobj = 0; - - /* Percentage of partial objects of all objects in a slab */ - unsigned long min_ppartobj = 100, max_ppartobj = 0, - avg_ppartobj, total_ppartobj = 0; - - - for (s = slabinfo; s < slabinfo + slabs; s++) { - unsigned long long size; - unsigned long used; - unsigned long long wasted; - unsigned long long objwaste; - long long objects_in_partial_slabs; - unsigned long percentage_partial_slabs; - unsigned long percentage_partial_objs; - - if (!s->slabs || !s->objects) - continue; - - used_slabs++; - - size = slab_size(s); - used = s->objects * s->object_size; - wasted = size - used; - objwaste = s->slab_size - s->object_size; - - objects_in_partial_slabs = s->objects - - (s->slabs - s->partial - s ->cpu_slabs) * - s->objs_per_slab; - - if (objects_in_partial_slabs < 0) - objects_in_partial_slabs = 0; - - percentage_partial_slabs = s->partial * 100 / s->slabs; - if (percentage_partial_slabs > 100) - percentage_partial_slabs = 100; - - percentage_partial_objs = objects_in_partial_slabs * 100 - / s->objects; - - if (percentage_partial_objs > 100) - percentage_partial_objs = 100; - - if (s->object_size < min_objsize) - min_objsize = s->object_size; - if (s->partial < min_partial) - min_partial = s->partial; - if (s->slabs < min_slabs) - min_slabs = s->slabs; - if (size < min_size) - min_size = size; - if (wasted < min_waste) - min_waste = wasted; - if (objwaste < min_objwaste) - min_objwaste = objwaste; - if (s->objects < min_objects) - min_objects = s->objects; - if (used < min_used) - min_used = used; - if (objects_in_partial_slabs < min_partobj) - min_partobj = objects_in_partial_slabs; - if (percentage_partial_slabs < min_ppart) - min_ppart = percentage_partial_slabs; - if (percentage_partial_objs < min_ppartobj) - min_ppartobj = percentage_partial_objs; - if (s->slab_size < min_memobj) - min_memobj = s->slab_size; - - if (s->object_size > max_objsize) - max_objsize = s->object_size; - if (s->partial > max_partial) - max_partial = s->partial; - if (s->slabs > max_slabs) - max_slabs = s->slabs; - if (size > max_size) - max_size = size; - if (wasted > max_waste) - max_waste = wasted; - if (objwaste > max_objwaste) - max_objwaste = objwaste; - if (s->objects > max_objects) - max_objects = s->objects; - if (used > max_used) - max_used = used; - if (objects_in_partial_slabs > max_partobj) - max_partobj = objects_in_partial_slabs; - if (percentage_partial_slabs > max_ppart) - max_ppart = percentage_partial_slabs; - if (percentage_partial_objs > max_ppartobj) - max_ppartobj = percentage_partial_objs; - if (s->slab_size > max_memobj) - max_memobj = s->slab_size; - - total_partial += s->partial; - total_slabs += s->slabs; - total_size += size; - total_waste += wasted; - - total_objects += s->objects; - total_used += used; - total_partobj += objects_in_partial_slabs; - total_ppart += percentage_partial_slabs; - total_ppartobj += percentage_partial_objs; - - total_objwaste += s->objects * objwaste; - total_objsize += s->objects * s->slab_size; - } - - if (!total_objects) { - printf("No objects\n"); - return; - } - if (!used_slabs) { - printf("No slabs\n"); - return; - } - - /* Per slab averages */ - avg_partial = total_partial / used_slabs; - avg_slabs = total_slabs / used_slabs; - avg_size = total_size / used_slabs; - avg_waste = total_waste / used_slabs; - - avg_objects = total_objects / used_slabs; - avg_used = total_used / used_slabs; - avg_partobj = total_partobj / used_slabs; - avg_ppart = total_ppart / used_slabs; - avg_ppartobj = total_ppartobj / used_slabs; - - /* Per object object sizes */ - avg_objsize = total_used / total_objects; - avg_objwaste = total_objwaste / total_objects; - avg_partobj = total_partobj * 100 / total_objects; - avg_memobj = total_objsize / total_objects; - - printf("Slabcache Totals\n"); - printf("----------------\n"); - printf("Slabcaches : %3d Aliases : %3d->%-3d Active: %3d\n", - slabs, aliases, alias_targets, used_slabs); - - store_size(b1, total_size);store_size(b2, total_waste); - store_size(b3, total_waste * 100 / total_used); - printf("Memory used: %6s # Loss : %6s MRatio: %6s%%\n", b1, b2, b3); - - store_size(b1, total_objects);store_size(b2, total_partobj); - store_size(b3, total_partobj * 100 / total_objects); - printf("# Objects : %6s # PartObj: %6s ORatio: %6s%%\n", b1, b2, b3); - - printf("\n"); - printf("Per Cache Average Min Max Total\n"); - printf("---------------------------------------------------------\n"); - - store_size(b1, avg_objects);store_size(b2, min_objects); - store_size(b3, max_objects);store_size(b4, total_objects); - printf("#Objects %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_slabs);store_size(b2, min_slabs); - store_size(b3, max_slabs);store_size(b4, total_slabs); - printf("#Slabs %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_partial);store_size(b2, min_partial); - store_size(b3, max_partial);store_size(b4, total_partial); - printf("#PartSlab %10s %10s %10s %10s\n", - b1, b2, b3, b4); - store_size(b1, avg_ppart);store_size(b2, min_ppart); - store_size(b3, max_ppart); - store_size(b4, total_partial * 100 / total_slabs); - printf("%%PartSlab %10s%% %10s%% %10s%% %10s%%\n", - b1, b2, b3, b4); - - store_size(b1, avg_partobj);store_size(b2, min_partobj); - store_size(b3, max_partobj); - store_size(b4, total_partobj); - printf("PartObjs %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj); - store_size(b3, max_ppartobj); - store_size(b4, total_partobj * 100 / total_objects); - printf("%% PartObj %10s%% %10s%% %10s%% %10s%%\n", - b1, b2, b3, b4); - - store_size(b1, avg_size);store_size(b2, min_size); - store_size(b3, max_size);store_size(b4, total_size); - printf("Memory %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_used);store_size(b2, min_used); - store_size(b3, max_used);store_size(b4, total_used); - printf("Used %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_waste);store_size(b2, min_waste); - store_size(b3, max_waste);store_size(b4, total_waste); - printf("Loss %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - printf("\n"); - printf("Per Object Average Min Max\n"); - printf("---------------------------------------------\n"); - - store_size(b1, avg_memobj);store_size(b2, min_memobj); - store_size(b3, max_memobj); - printf("Memory %10s %10s %10s\n", - b1, b2, b3); - store_size(b1, avg_objsize);store_size(b2, min_objsize); - store_size(b3, max_objsize); - printf("User %10s %10s %10s\n", - b1, b2, b3); - - store_size(b1, avg_objwaste);store_size(b2, min_objwaste); - store_size(b3, max_objwaste); - printf("Loss %10s %10s %10s\n", - b1, b2, b3); -} - -void sort_slabs(void) -{ - struct slabinfo *s1,*s2; - - for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) { - for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) { - int result; - - if (sort_size) - result = slab_size(s1) < slab_size(s2); - else - result = strcasecmp(s1->name, s2->name); - - if (show_inverted) - result = -result; - - if (result > 0) { - struct slabinfo t; - - memcpy(&t, s1, sizeof(struct slabinfo)); - memcpy(s1, s2, sizeof(struct slabinfo)); - memcpy(s2, &t, sizeof(struct slabinfo)); - } - } - } -} - -void sort_aliases(void) -{ - struct aliasinfo *a1,*a2; - - for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) { - for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) { - char *n1, *n2; - - n1 = a1->name; - n2 = a2->name; - if (show_alias && !show_inverted) { - n1 = a1->ref; - n2 = a2->ref; - } - if (strcasecmp(n1, n2) > 0) { - struct aliasinfo t; - - memcpy(&t, a1, sizeof(struct aliasinfo)); - memcpy(a1, a2, sizeof(struct aliasinfo)); - memcpy(a2, &t, sizeof(struct aliasinfo)); - } - } - } -} - -void link_slabs(void) -{ - struct aliasinfo *a; - struct slabinfo *s; - - for (a = aliasinfo; a < aliasinfo + aliases; a++) { - - for(s = slabinfo; s < slabinfo + slabs; s++) - if (strcmp(a->ref, s->name) == 0) { - a->slab = s; - s->refs++; - break; - } - if (s == slabinfo + slabs) - fatal("Unresolved alias %s\n", a->ref); - } -} - -void alias(void) -{ - struct aliasinfo *a; - char *active = NULL; - - sort_aliases(); - link_slabs(); - - for(a = aliasinfo; a < aliasinfo + aliases; a++) { - - if (!show_single_ref && a->slab->refs == 1) - continue; - - if (!show_inverted) { - if (active) { - if (strcmp(a->slab->name, active) == 0) { - printf(" %s", a->name); - continue; - } - } - printf("\n%-20s <- %s", a->slab->name, a->name); - active = a->slab->name; - } - else - printf("%-20s -> %s\n", a->name, a->slab->name); - } - if (active) - printf("\n"); -} - - -void rename_slabs(void) -{ - struct slabinfo *s; - struct aliasinfo *a; - - for (s = slabinfo; s < slabinfo + slabs; s++) { - if (*s->name != ':') - continue; - - if (s->refs > 1 && !show_first_alias) - continue; - - a = find_one_alias(s); - - s->name = a->name; - } -} - -int slab_mismatch(char *slab) -{ - return regexec(&pattern, slab, 0, NULL, 0); -} - -void read_slab_dir(void) -{ - DIR *dir; - struct dirent *de; - struct slabinfo *slab = slabinfo; - struct aliasinfo *alias = aliasinfo; - char *p; - char *t; - int count; - - dir = opendir("."); - while ((de = readdir(dir))) { - if (de->d_name[0] == '.' || - slab_mismatch(de->d_name)) - continue; - switch (de->d_type) { - case DT_LNK: - alias->name = strdup(de->d_name); - count = readlink(de->d_name, buffer, sizeof(buffer)); - - if (count < 0) - fatal("Cannot read symlink %s\n", de->d_name); - - buffer[count] = 0; - p = buffer + count; - while (p > buffer && p[-1] != '/') - p--; - alias->ref = strdup(p); - alias++; - break; - case DT_DIR: - if (chdir(de->d_name)) - fatal("Unable to access slab %s\n", slab->name); - slab->name = strdup(de->d_name); - slab->alias = 0; - slab->refs = 0; - slab->aliases = get_obj("aliases"); - slab->align = get_obj("align"); - slab->cache_dma = get_obj("cache_dma"); - slab->cpu_slabs = get_obj("cpu_slabs"); - slab->destroy_by_rcu = get_obj("destroy_by_rcu"); - slab->hwcache_align = get_obj("hwcache_align"); - slab->object_size = get_obj("object_size"); - slab->objects = get_obj("objects"); - slab->objs_per_slab = get_obj("objs_per_slab"); - slab->order = get_obj("order"); - slab->partial = get_obj("partial"); - slab->partial = get_obj_and_str("partial", &t); - decode_numa_list(slab->numa_partial, t); - slab->poison = get_obj("poison"); - slab->reclaim_account = get_obj("reclaim_account"); - slab->red_zone = get_obj("red_zone"); - slab->sanity_checks = get_obj("sanity_checks"); - slab->slab_size = get_obj("slab_size"); - slab->slabs = get_obj_and_str("slabs", &t); - decode_numa_list(slab->numa, t); - slab->store_user = get_obj("store_user"); - slab->trace = get_obj("trace"); - chdir(".."); - if (slab->name[0] == ':') - alias_targets++; - slab++; - break; - default : - fatal("Unknown file type %lx\n", de->d_type); - } - } - closedir(dir); - slabs = slab - slabinfo; - aliases = alias - aliasinfo; - if (slabs > MAX_SLABS) - fatal("Too many slabs\n"); - if (aliases > MAX_ALIASES) - fatal("Too many aliases\n"); -} - -void output_slabs(void) -{ - struct slabinfo *slab; - - for (slab = slabinfo; slab < slabinfo + slabs; slab++) { - - if (slab->alias) - continue; - - - if (show_numa) - slab_numa(slab); - else - if (show_track) - show_tracking(slab); - else - if (validate) - slab_validate(slab); - else - if (shrink) - slab_shrink(slab); - else { - if (show_slab) - slabcache(slab); - } - } -} - -struct option opts[] = { - { "aliases", 0, NULL, 'a' }, - { "slabs", 0, NULL, 'l' }, - { "numa", 0, NULL, 'n' }, - { "zero", 0, NULL, 'z' }, - { "help", 0, NULL, 'h' }, - { "validate", 0, NULL, 'v' }, - { "first-alias", 0, NULL, 'f' }, - { "shrink", 0, NULL, 's' }, - { "track", 0, NULL, 't'}, - { "inverted", 0, NULL, 'i'}, - { "1ref", 0, NULL, '1'}, - { NULL, 0, NULL, 0 } -}; - -int main(int argc, char *argv[]) -{ - int c; - int err; - char *pattern_source; - - page_size = getpagesize(); - if (chdir("/sys/slab")) - fatal("This kernel does not have SLUB support.\n"); - - while ((c = getopt_long(argc, argv, "afhil1npstvzTS", opts, NULL)) != -1) - switch(c) { - case '1': - show_single_ref = 1; - break; - case 'a': - show_alias = 1; - break; - case 'f': - show_first_alias = 1; - break; - case 'h': - usage(); - return 0; - case 'i': - show_inverted = 1; - break; - case 'n': - show_numa = 1; - break; - case 's': - shrink = 1; - break; - case 'l': - show_slab = 1; - break; - case 't': - show_track = 1; - break; - case 'v': - validate = 1; - break; - case 'z': - skip_zero = 0; - break; - case 'T': - show_totals = 1; - break; - case 'S': - sort_size = 1; - break; - - default: - fatal("%s: Invalid option '%c'\n", argv[0], optopt); - - } - - if (!show_slab && !show_alias && !show_track - && !validate && !shrink) - show_slab = 1; - - if (argc > optind) - pattern_source = argv[optind]; - else - pattern_source = ".*"; - - err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB); - if (err) - fatal("%s: Invalid pattern '%s' code %d\n", - argv[0], pattern_source, err); - read_slab_dir(); - if (show_alias) - alias(); - else - if (show_totals) - totals(); - else { - link_slabs(); - rename_slabs(); - sort_slabs(); - output_slabs(); - } - return 0; -} diff --git a/trunk/Documentation/vm/slub.txt b/trunk/Documentation/vm/slub.txt deleted file mode 100644 index 727c8d81aeaf..000000000000 --- a/trunk/Documentation/vm/slub.txt +++ /dev/null @@ -1,113 +0,0 @@ -Short users guide for SLUB --------------------------- - -First of all slub should transparently replace SLAB. If you enable -SLUB then everything should work the same (Note the word "should". -There is likely not much value in that word at this point). - -The basic philosophy of SLUB is very different from SLAB. SLAB -requires rebuilding the kernel to activate debug options for all -SLABS. SLUB always includes full debugging but its off by default. -SLUB can enable debugging only for selected slabs in order to avoid -an impact on overall system performance which may make a bug more -difficult to find. - -In order to switch debugging on one can add a option "slub_debug" -to the kernel command line. That will enable full debugging for -all slabs. - -Typically one would then use the "slabinfo" command to get statistical -data and perform operation on the slabs. By default slabinfo only lists -slabs that have data in them. See "slabinfo -h" for more options when -running the command. slabinfo can be compiled with - -gcc -o slabinfo Documentation/vm/slabinfo.c - -Some of the modes of operation of slabinfo require that slub debugging -be enabled on the command line. F.e. no tracking information will be -available without debugging on and validation can only partially -be performed if debugging was not switched on. - -Some more sophisticated uses of slub_debug: -------------------------------------------- - -Parameters may be given to slub_debug. If none is specified then full -debugging is enabled. Format: - -slub_debug= Enable options for all slabs -slub_debug=, - Enable options only for select slabs - -Possible debug options are - F Sanity checks on (enables SLAB_DEBUG_FREE. Sorry - SLAB legacy issues) - Z Red zoning - P Poisoning (object and padding) - U User tracking (free and alloc) - T Trace (please only use on single slabs) - -F.e. in order to boot just with sanity checks and red zoning one would specify: - - slub_debug=FZ - -Trying to find an issue in the dentry cache? Try - - slub_debug=,dentry_cache - -to only enable debugging on the dentry cache. - -Red zoning and tracking may realign the slab. We can just apply sanity checks -to the dentry cache with - - slub_debug=F,dentry_cache - -In case you forgot to enable debugging on the kernel command line: It is -possible to enable debugging manually when the kernel is up. Look at the -contents of: - -/sys/slab// - -Look at the writable files. Writing 1 to them will enable the -corresponding debug option. All options can be set on a slab that does -not contain objects. If the slab already contains objects then sanity checks -and tracing may only be enabled. The other options may cause the realignment -of objects. - -Careful with tracing: It may spew out lots of information and never stop if -used on the wrong slab. - -SLAB Merging ------------- - -If no debugging is specified then SLUB may merge similar slabs together -in order to reduce overhead and increase cache hotness of objects. -slabinfo -a displays which slabs were merged together. - -Getting more performance ------------------------- - -To some degree SLUB's performance is limited by the need to take the -list_lock once in a while to deal with partial slabs. That overhead is -governed by the order of the allocation for each slab. The allocations -can be influenced by kernel parameters: - -slub_min_objects=x (default 8) -slub_min_order=x (default 0) -slub_max_order=x (default 4) - -slub_min_objects allows to specify how many objects must at least fit -into one slab in order for the allocation order to be acceptable. -In general slub will be able to perform this number of allocations -on a slab without consulting centralized resources (list_lock) where -contention may occur. - -slub_min_order specifies a minim order of slabs. A similar effect like -slub_min_objects. - -slub_max_order specified the order at which slub_min_objects should no -longer be checked. This is useful to avoid SLUB trying to generate -super large order pages to fit slub_min_objects of a slab cache with -large object sizes into one high order page. - - -Christoph Lameter, , April 10, 2007 diff --git a/trunk/Documentation/x86_64/boot-options.txt b/trunk/Documentation/x86_64/boot-options.txt index 6177d881983f..85f51e5a749f 100644 --- a/trunk/Documentation/x86_64/boot-options.txt +++ b/trunk/Documentation/x86_64/boot-options.txt @@ -149,19 +149,7 @@ NUMA numa=noacpi Don't parse the SRAT table for NUMA setup - numa=fake=CMDLINE - If a number, fakes CMDLINE nodes and ignores NUMA setup of the - actual machine. Otherwise, system memory is configured - depending on the sizes and coefficients listed. For example: - numa=fake=2*512,1024,4*256,*128 - gives two 512M nodes, a 1024M node, four 256M nodes, and the - rest split into 128M chunks. If the last character of CMDLINE - is a *, the remaining memory is divided up equally among its - coefficient: - numa=fake=2*512,2* - gives two 512M nodes and the rest split into two nodes. - Otherwise, the remaining system RAM is allocated to an - additional node. + numa=fake=X Fake X nodes and ignore NUMA setup of the actual machine. numa=hotadd=percent Only allow hotadd memory to preallocate page structures upto diff --git a/trunk/Documentation/x86_64/fake-numa-for-cpusets b/trunk/Documentation/x86_64/fake-numa-for-cpusets deleted file mode 100644 index d1a985c5b00a..000000000000 --- a/trunk/Documentation/x86_64/fake-numa-for-cpusets +++ /dev/null @@ -1,66 +0,0 @@ -Using numa=fake and CPUSets for Resource Management -Written by David Rientjes - -This document describes how the numa=fake x86_64 command-line option can be used -in conjunction with cpusets for coarse memory management. Using this feature, -you can create fake NUMA nodes that represent contiguous chunks of memory and -assign them to cpusets and their attached tasks. This is a way of limiting the -amount of system memory that are available to a certain class of tasks. - -For more information on the features of cpusets, see Documentation/cpusets.txt. -There are a number of different configurations you can use for your needs. For -more information on the numa=fake command line option and its various ways of -configuring fake nodes, see Documentation/x86_64/boot-options.txt. - -For the purposes of this introduction, we'll assume a very primitive NUMA -emulation setup of "numa=fake=4*512,". This will split our system memory into -four equal chunks of 512M each that we can now use to assign to cpusets. As -you become more familiar with using this combination for resource control, -you'll determine a better setup to minimize the number of nodes you have to deal -with. - -A machine may be split as follows with "numa=fake=4*512," as reported by dmesg: - - Faking node 0 at 0000000000000000-0000000020000000 (512MB) - Faking node 1 at 0000000020000000-0000000040000000 (512MB) - Faking node 2 at 0000000040000000-0000000060000000 (512MB) - Faking node 3 at 0000000060000000-0000000080000000 (512MB) - ... - On node 0 totalpages: 130975 - On node 1 totalpages: 131072 - On node 2 totalpages: 131072 - On node 3 totalpages: 131072 - -Now following the instructions for mounting the cpusets filesystem from -Documentation/cpusets.txt, you can assign fake nodes (i.e. contiguous memory -address spaces) to individual cpusets: - - [root@xroads /]# mkdir exampleset - [root@xroads /]# mount -t cpuset none exampleset - [root@xroads /]# mkdir exampleset/ddset - [root@xroads /]# cd exampleset/ddset - [root@xroads /exampleset/ddset]# echo 0-1 > cpus - [root@xroads /exampleset/ddset]# echo 0-1 > mems - -Now this cpuset, 'ddset', will only allowed access to fake nodes 0 and 1 for -memory allocations (1G). - -You can now assign tasks to these cpusets to limit the memory resources -available to them according to the fake nodes assigned as mems: - - [root@xroads /exampleset/ddset]# echo $$ > tasks - [root@xroads /exampleset/ddset]# dd if=/dev/zero of=tmp bs=1024 count=1G - [1] 13425 - -Notice the difference between the system memory usage as reported by -/proc/meminfo between the restricted cpuset case above and the unrestricted -case (i.e. running the same 'dd' command without assigning it to a fake NUMA -cpuset): - Unrestricted Restricted - MemTotal: 3091900 kB 3091900 kB - MemFree: 42113 kB 1513236 kB - -This allows for coarse memory management for the tasks you assign to particular -cpusets. Since cpusets can form a hierarchy, you can create some pretty -interesting combinations of use-cases for various classes of tasks for your -memory management needs. diff --git a/trunk/Documentation/x86_64/machinecheck b/trunk/Documentation/x86_64/machinecheck index feaeaf6f6e4d..068a6d9904b9 100644 --- a/trunk/Documentation/x86_64/machinecheck +++ b/trunk/Documentation/x86_64/machinecheck @@ -36,12 +36,7 @@ between all CPUs. check_interval How often to poll for corrected machine check errors, in seconds - (Note output is hexademical). Default 5 minutes. When the poller - finds MCEs it triggers an exponential speedup (poll more often) on - the polling interval. When the poller stops finding MCEs, it - triggers an exponential backoff (poll less often) on the polling - interval. The check_interval variable is both the initial and - maximum polling interval. + (Note output is hexademical). Default 5 minutes. tolerant Tolerance level. When a machine check exception occurs for a non diff --git a/trunk/Kbuild b/trunk/Kbuild index 163f8cb020a4..0451f69353ba 100644 --- a/trunk/Kbuild +++ b/trunk/Kbuild @@ -2,7 +2,6 @@ # Kbuild for top-level directory of the kernel # This file takes care of the following: # 1) Generate asm-offsets.h -# 2) Check for missing system calls ##### # 1) Generate asm-offsets.h @@ -47,13 +46,3 @@ $(obj)/$(offsets-file): arch/$(ARCH)/kernel/asm-offsets.s Kbuild $(Q)mkdir -p $(dir $@) $(call cmd,offsets) -##### -# 2) Check for missing system calls -# - -quiet_cmd_syscalls = CALL $< - cmd_syscalls = $(CONFIG_SHELL) $< $(CC) $(c_flags) - -PHONY += missing-syscalls -missing-syscalls: scripts/checksyscalls.sh FORCE - $(call cmd,syscalls) diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 41a4b477c576..af1c7926c153 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -382,12 +382,6 @@ L: linux-laptop@vger.kernel.org W: http://www.canb.auug.org.au/~sfr/ S: Supported -APPLE SMC DRIVER -P: Nicolas Boichat -M: nicolas@boichat.ch -L: mactel-linux-devel@lists.sourceforge.net -S: Maintained - APPLETALK NETWORK LAYER P: Arnaldo Carvalho de Melo M: acme@ghostprotocols.net @@ -679,7 +673,6 @@ AUXILIARY DISPLAY DRIVERS P: Miguel Ojeda Sandonis M: maxextreme@gmail.com L: linux-kernel@vger.kernel.org -W: http://auxdisplay.googlepages.com/ S: Maintained AVR32 ARCHITECTURE @@ -707,44 +700,6 @@ P: Richard Purdie M: rpurdie@rpsys.net S: Maintained -BLACKFIN ARCHITECTURE -P: Aubrey Li -M: aubrey.li@analog.com -P: Bernd Schmidt -M: bernd.schmidt@analog.com -P: Bryan Wu -M: bryan.wu@analog.com -P: Grace Pan -M: grace.pan@analog.com -P: Michael Hennerich -M: michael.hennerich@analog.com -P: Mike Frysinger -M: michael.frysinger@analog.com -P: Jane Lv -M: jane.lv@analog.com -P: Jerry Zeng -M: jerry.zeng@analog.com -P: Jie Zhang -M: jie.zhang@analog.com -P: Robin Getz -M: robin.getz@analog.com -P: Roy Huang -M: roy.huang@analog.com -P: Sonic Zhang -M: sonic.zhang@analog.com -P: Yi Li -M: yi.li@analog.com -L: uclinux-dist-devel@blackfin.uclinux.org -W: http://blackfin.uclinux.org -S: Supported - -BLACKFIN SERIAL DRIVER -P: Aubrey Li -M: aubrey.li@analog.com -L: uclinux-dist-devel@blackfin.uclinux.org -W: http://blackfin.uclinux.org -S: Supported - BAYCOM/HDLCDRV DRIVERS FOR AX.25 P: Thomas Sailer M: t.sailer@alumni.ethz.ch @@ -778,13 +733,6 @@ M: tigran@aivazian.fsnet.co.uk L: linux-kernel@vger.kernel.org S: Maintained -BLACKFIN I2C TWI DRIVER -P: Sonic Zhang -M: sonic.zhang@analog.com -L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) -W: http://blackfin.uclinux.org/ -S: Supported - BLOCK LAYER P: Jens Axboe M: axboe@kernel.dk @@ -944,14 +892,12 @@ CFAG12864B LCD DRIVER P: Miguel Ojeda Sandonis M: maxextreme@gmail.com L: linux-kernel@vger.kernel.org -W: http://auxdisplay.googlepages.com/ S: Maintained CFAG12864BFB LCD FRAMEBUFFER DRIVER P: Miguel Ojeda Sandonis M: maxextreme@gmail.com L: linux-kernel@vger.kernel.org -W: http://auxdisplay.googlepages.com/ S: Maintained CFG80211 and NL80211 @@ -1040,12 +986,6 @@ P: Simon Arlott M: cxacru@fire.lp0.eu S: Maintained -CORETEMP HARDWARE MONITORING DRIVER -P: Rudolf Marek -M: r.marek@assembler.cz -L: lm-sensors@lm-sensors.org -S: Maintained - COSA/SRP SYNC SERIAL DRIVER P: Jan "Yenya" Kasprzak M: kas@fi.muni.cz @@ -1519,11 +1459,6 @@ L: linux-scsi@vger.kernel.org W: http://www.icp-vortex.com/ S: Supported -GENERIC GPIO I2C DRIVER -P: Haavard Skinnemoen -M: hskinnemoen@atmel.com -S: Supported - GENERIC HDLC DRIVER, N2, C101, PCI200SYN and WANXL DRIVERS P: Krzysztof Halasa M: khc@pm.waw.pl @@ -1670,7 +1605,7 @@ S: Maintained HPET: x86_64 P: Andi Kleen and Vojtech Pavlik -M: andi@firstfloor.org and vojtech@suse.cz +M: ak@muc.de and vojtech@suse.cz S: Maintained HPET: ACPI hpet.c @@ -1696,13 +1631,6 @@ L: i2c@lm-sensors.org T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/ S: Maintained -I2C-TINY-USB DRIVER -P: Till Harbaum -M: till@harbaum.org -L: i2c@lm-sensors.org -T: http://www.harbaum.org/till/i2c_tiny_usb -S: Maintained - i386 BOOT CODE P: Riley H. Williams M: Riley@Williams.Name @@ -2036,7 +1964,7 @@ P: Vivek Goyal M: vgoyal@in.ibm.com P: Haren Myneni M: hbabu@us.ibm.com -L: kexec@lists.infradead.org +L: fastboot@lists.linux-foundation.org L: linux-kernel@vger.kernel.org W: http://lse.sourceforge.net/kdump/ S: Maintained @@ -2086,7 +2014,7 @@ P: Eric Biederman M: ebiederm@xmission.com W: http://www.xmission.com/~ebiederm/files/kexec/ L: linux-kernel@vger.kernel.org -L: kexec@lists.infradead.org +L: fastboot@lists.linux-foundation.org S: Maintained KPROBES @@ -2105,7 +2033,6 @@ KS0108 LCD CONTROLLER DRIVER P: Miguel Ojeda Sandonis M: maxextreme@gmail.com L: linux-kernel@vger.kernel.org -W: http://auxdisplay.googlepages.com/ S: Maintained LAPB module @@ -2282,16 +2209,6 @@ M: philb@gnu.org W: http://www.tazenda.demon.co.uk/phil/linux-hp S: Maintained -MAC80211 -P: Jiri Benc -M: jbenc@suse.cz -P: Michael Wu -M: flamingice@sourmilk.net -L: linux-wireless@vger.kernel.org -W: http://linuxwireless.org/ -T: git kernel.org:/pub/scm/linux/kernel/git/jbenc/mac80211.git -S: Maintained - MARVELL YUKON / SYSKONNECT DRIVER P: Mirko Lindner M: mlindner@syskonnect.de @@ -2320,12 +2237,6 @@ M: vandrove@vc.cvut.cz L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only) S: Maintained -MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER -P: Hans J. Koch -M: hjk@linutronix.de -L: lm-sensors@lm-sensors.org -S: Maintained - MEGARAID SCSI DRIVERS P: Neela Syam Kolli M: Neela.Kolli@engenio.com @@ -2712,19 +2623,6 @@ T: git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git T: cvs cvs.parisc-linux.org:/var/cvs/linux-2.6 S: Maintained -PARAVIRT_OPS INTERFACE -P: Jeremy Fitzhardinge -M: jeremy@xensource.com -P: Chris Wright -M: chrisw@sous-sol.org -P: Zachary Amsden -M: zach@vmware.com -P: Rusty Russell -M: rusty@rustcorp.com.au -L: virtualization@lists.osdl.org -L: linux-kernel@vger.kernel.org -S: Supported - PC87360 HARDWARE MONITORING DRIVER P: Jim Cromie M: jim.cromie@gmail.com @@ -3120,11 +3018,6 @@ L: selinux@tycho.nsa.gov (subscribers-only, general discussion) W: http://www.nsa.gov/selinux S: Supported -SENSABLE PHANTOM -P: Jiri Slaby -M: jirislaby@gmail.com -S: Maintained - SERIAL ATA (SATA) SUBSYSTEM: P: Jeff Garzik M: jgarzik@pobox.com @@ -3734,8 +3627,8 @@ W: http://www.kroah.com/linux/ S: Maintained USB SERIAL WHITEHEAT DRIVER -P: Support Department -M: support@connecttech.com +P: Stuart MacDonald +M: stuartm@connecttech.com L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net W: http://www.connecttech.com @@ -3954,15 +3847,6 @@ M: eis@baty.hanse.de L: linux-x25@vger.kernel.org S: Maintained -XEN HYPERVISOR INTERFACE -P: Jeremy Fitzhardinge -M: jeremy@xensource.com -P: Chris Wright -M: chrisw@sous-sol.org -L: virtualization@lists.osdl.org -L: xen-devel@lists.xensource.com -S: Supported - XFS FILESYSTEM P: Silicon Graphics Inc P: Tim Shimmin, David Chatterton diff --git a/trunk/Makefile b/trunk/Makefile index dfe559c89fe6..d970cb16545a 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -491,7 +491,7 @@ endif include $(srctree)/arch/$(ARCH)/Makefile ifdef CONFIG_FRAME_POINTER -CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls +CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) else CFLAGS += -fomit-frame-pointer endif @@ -576,7 +576,7 @@ libs-y := $(libs-y1) $(libs-y2) # --------------------------------------------------------------------------- # vmlinux is built from the objects selected by $(vmlinux-init) and # $(vmlinux-main). Most are built-in.o files from top-level directories -# in the kernel tree, others are specified in arch/$(ARCH)/Makefile. +# in the kernel tree, others are specified in arch/$(ARCH)Makefile. # Ordering when linking is important, and $(vmlinux-init) must be first. # # vmlinux @@ -603,7 +603,6 @@ vmlinux-init := $(head-y) $(init-y) vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y) vmlinux-all := $(vmlinux-init) $(vmlinux-main) vmlinux-lds := arch/$(ARCH)/kernel/vmlinux.lds -export KBUILD_VMLINUX_OBJS := $(vmlinux-all) # Rule to link vmlinux - also used during CONFIG_KALLSYMS # May be overridden by arch/$(ARCH)/Makefile @@ -856,7 +855,6 @@ archprepare: prepare1 scripts_basic prepare0: archprepare FORCE $(Q)$(MAKE) $(build)=. - $(Q)$(MAKE) $(build)=. missing-syscalls # All the preparing.. prepare: prepare0 @@ -1279,7 +1277,10 @@ endif ALLSOURCE_ARCHS := $(ARCH) define find-sources - ( for ARCH in $(ALLSOURCE_ARCHS) ; do \ + ( find $(__srctree) $(RCS_FIND_IGNORE) \ + \( -name include -o -name arch \) -prune -o \ + -name $1 -print; \ + for ARCH in $(ALLSOURCE_ARCHS) ; do \ find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \ -name $1 -print; \ done ; \ @@ -1293,11 +1294,7 @@ define find-sources -name $1 -print; \ done ; \ find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ - -name $1 -print; \ - find $(__srctree) $(RCS_FIND_IGNORE) \ - \( -name include -o -name arch \) -prune -o \ - -name $1 -print; \ - ) + -name $1 -print ) endef define all-sources diff --git a/trunk/arch/alpha/Kconfig.debug b/trunk/arch/alpha/Kconfig.debug index f45f28cc10da..36d0106c32eb 100644 --- a/trunk/arch/alpha/Kconfig.debug +++ b/trunk/arch/alpha/Kconfig.debug @@ -16,6 +16,14 @@ config DEBUG_RWLOCK too many attempts. If you suspect a rwlock problem or a kernel hacker asks for this option then say Y. Otherwise say N. +config DEBUG_SEMAPHORE + bool "Semaphore debugging" + depends on DEBUG_KERNEL + help + If you say Y here then semaphore processing will issue lots of + verbose debugging messages. If you suspect a semaphore problem or a + kernel hacker asks for this option then say Y. Otherwise say N. + config ALPHA_LEGACY_START_ADDRESS bool "Legacy kernel start address" depends on ALPHA_GENERIC diff --git a/trunk/arch/alpha/boot/bootpz.c b/trunk/arch/alpha/boot/bootpz.c index 1036b515e20c..4307bde80a35 100644 --- a/trunk/arch/alpha/boot/bootpz.c +++ b/trunk/arch/alpha/boot/bootpz.c @@ -467,9 +467,3 @@ start_kernel(void) #endif runkernel(); } - - /* dummy function, should never be called. */ -void *__kmalloc(size_t size, gfp_t flags) -{ - return (void *)NULL; -} diff --git a/trunk/arch/alpha/boot/misc.c b/trunk/arch/alpha/boot/misc.c index c00646b25f6e..1d65adf5691e 100644 --- a/trunk/arch/alpha/boot/misc.c +++ b/trunk/arch/alpha/boot/misc.c @@ -98,7 +98,7 @@ extern int end; static ulg free_mem_ptr; static ulg free_mem_ptr_end; -#define HEAP_SIZE 0x3000 +#define HEAP_SIZE 0x2000 #include "../../../lib/inflate.c" diff --git a/trunk/arch/alpha/boot/tools/objstrip.c b/trunk/arch/alpha/boot/tools/objstrip.c index 96154e768a20..67beb1b45e4f 100644 --- a/trunk/arch/alpha/boot/tools/objstrip.c +++ b/trunk/arch/alpha/boot/tools/objstrip.c @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef __ELF__ # include #endif diff --git a/trunk/arch/alpha/kernel/err_common.c b/trunk/arch/alpha/kernel/err_common.c index 13d53b1c9657..687580b16b41 100644 --- a/trunk/arch/alpha/kernel/err_common.c +++ b/trunk/arch/alpha/kernel/err_common.c @@ -7,6 +7,7 @@ */ #include +#include #include #include diff --git a/trunk/arch/alpha/kernel/err_ev6.c b/trunk/arch/alpha/kernel/err_ev6.c index 11aee012a8ae..69b5f4ea7355 100644 --- a/trunk/arch/alpha/kernel/err_ev6.c +++ b/trunk/arch/alpha/kernel/err_ev6.c @@ -7,6 +7,7 @@ */ #include +#include #include #include diff --git a/trunk/arch/alpha/kernel/err_ev7.c b/trunk/arch/alpha/kernel/err_ev7.c index bc799f72d8c1..95463ab1cf35 100644 --- a/trunk/arch/alpha/kernel/err_ev7.c +++ b/trunk/arch/alpha/kernel/err_ev7.c @@ -7,6 +7,7 @@ */ #include +#include #include #include diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index ce857158c1ea..be133f1f75a4 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -93,6 +93,7 @@ osf_set_program_attributes(unsigned long text_start, unsigned long text_len, * offset differences aren't the same as "d_reclen"). */ #define NAME_OFFSET offsetof (struct osf_dirent, d_name) +#define ROUND_UP(x) (((x)+3) & ~3) struct osf_dirent { unsigned int d_ino; @@ -114,7 +115,7 @@ osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, { struct osf_dirent __user *dirent; struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; - unsigned int reclen = ALIGN(NAME_OFFSET + namlen + 1, sizeof(u32)); + unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1); unsigned int d_ino; buf->error = -EINVAL; /* only used if we fail */ @@ -173,6 +174,7 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent, return error; } +#undef ROUND_UP #undef NAME_OFFSET asmlinkage unsigned long @@ -953,25 +955,15 @@ osf_setitimer(int which, struct itimerval32 __user *in, struct itimerval32 __use asmlinkage int osf_utimes(char __user *filename, struct timeval32 __user *tvs) { - struct timespec tv[2]; + struct timeval ktvs[2]; if (tvs) { - struct timeval ktvs[2]; if (get_tv32(&ktvs[0], &tvs[0]) || get_tv32(&ktvs[1], &tvs[1])) return -EFAULT; - - if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 || - ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000) - return -EINVAL; - - tv[0].tv_sec = ktvs[0].tv_sec; - tv[0].tv_nsec = 1000 * ktvs[0].tv_usec; - tv[1].tv_sec = ktvs[1].tv_sec; - tv[1].tv_nsec = 1000 * ktvs[1].tv_usec; } - return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0); + return do_utimes(AT_FDCWD, filename, tvs ? ktvs : NULL); } #define MAX_SELECT_SECONDS \ @@ -1275,9 +1267,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, if (len > limit) return -ENOMEM; - if (flags & MAP_FIXED) - return addr; - /* First, see if the given suggestion fits. The OSF/1 loader (/sbin/loader) relies on us returning an diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c index 92b61629fe3f..c15186390693 100644 --- a/trunk/arch/alpha/kernel/process.c +++ b/trunk/arch/alpha/kernel/process.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/alpha/kernel/setup.c b/trunk/arch/alpha/kernel/setup.c index 915f26345c45..d352c2b05f1a 100644 --- a/trunk/arch/alpha/kernel/setup.c +++ b/trunk/arch/alpha/kernel/setup.c @@ -744,6 +744,15 @@ setup_arch(char **cmdline_p) paging_init(); } +void __init +disable_early_printk(void) +{ + if (alpha_using_srm && srmcons_output) { + unregister_srm_console(); + srmcons_output = 0; + } +} + static char sys_unknown[] = "Unknown"; static char systype_names[][16] = { "0", diff --git a/trunk/arch/alpha/kernel/signal.c b/trunk/arch/alpha/kernel/signal.c index 7f64aa767d5a..741da0945dc4 100644 --- a/trunk/arch/alpha/kernel/signal.c +++ b/trunk/arch/alpha/kernel/signal.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/alpha/kernel/smp.c b/trunk/arch/alpha/kernel/smp.c index 80cfb758ee2b..d1ec4f51df1a 100644 --- a/trunk/arch/alpha/kernel/smp.c +++ b/trunk/arch/alpha/kernel/smp.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/alpha/kernel/srmcons.c b/trunk/arch/alpha/kernel/srmcons.c index 930cedc8be24..756923203860 100644 --- a/trunk/arch/alpha/kernel/srmcons.c +++ b/trunk/arch/alpha/kernel/srmcons.c @@ -164,9 +164,9 @@ srmcons_get_private_struct(struct srmcons_private **ps) int retval = 0; if (srmconsp == NULL) { - srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL); spin_lock_irqsave(&srmconsp_lock, flags); + srmconsp = kmalloc(sizeof(*srmconsp), GFP_KERNEL); if (srmconsp == NULL) retval = -ENOMEM; else { @@ -300,7 +300,7 @@ static struct console srmcons = { .write = srm_console_write, .device = srm_console_device, .setup = srm_console_setup, - .flags = CON_PRINTBUFFER | CON_BOOT, + .flags = CON_PRINTBUFFER, .index = -1, }; diff --git a/trunk/arch/alpha/kernel/vmlinux.lds.S b/trunk/arch/alpha/kernel/vmlinux.lds.S index cf1e6fc6c686..4cc44bd33d33 100644 --- a/trunk/arch/alpha/kernel/vmlinux.lds.S +++ b/trunk/arch/alpha/kernel/vmlinux.lds.S @@ -69,7 +69,7 @@ SECTIONS . = ALIGN(8); SECURITY_INIT - . = ALIGN(8192); + . = ALIGN(64); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/alpha/mm/fault.c b/trunk/arch/alpha/mm/fault.c index f5862792a167..8aa9db834c11 100644 --- a/trunk/arch/alpha/mm/fault.c +++ b/trunk/arch/alpha/mm/fault.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 0d8fac3b0371..e7baca29f3fb 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -29,10 +29,6 @@ config GENERIC_TIME bool default n -config GENERIC_CLOCKEVENTS - bool - default n - config MMU bool default y @@ -71,14 +67,6 @@ config GENERIC_HARDIRQS bool default y -config STACKTRACE_SUPPORT - bool - default y - -config LOCKDEP_SUPPORT - bool - default y - config TRACE_IRQFLAGS_SUPPORT bool default y @@ -174,8 +162,6 @@ config ARCH_VERSATILE select ARM_AMBA select ARM_VIC select ICST307 - select GENERIC_TIME - select GENERIC_CLOCKEVENTS help This enables support for ARM Ltd Versatile board. @@ -269,7 +255,6 @@ config ARCH_IOP13XX depends on MMU select PLAT_IOP select PCI - select ARCH_SUPPORTS_MSI help Support for Intel's IOP13XX (XScale) family of processors. @@ -277,7 +262,6 @@ config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU select GENERIC_TIME - select GENERIC_CLOCKEVENTS help Support for Intel's IXP4XX (XScale) family of processors. @@ -379,7 +363,6 @@ config ARCH_LH7A40X config ARCH_OMAP bool "TI OMAP" select GENERIC_GPIO - select GENERIC_TIME help Support for TI's OMAP platform (OMAP1 and OMAP2). @@ -530,8 +513,6 @@ endmenu menu "Kernel Features" -source "kernel/time/Kconfig" - config SMP bool "Symmetric Multi-Processing (EXPERIMENTAL)" depends on EXPERIMENTAL && REALVIEW_MPCORE @@ -591,7 +572,6 @@ config PREEMPT config NO_IDLE_HZ bool "Dynamic tick timer" - depends on !GENERIC_CLOCKEVENTS help Select this option if you want to disable continuous timer ticks and have them programmed to occur as required. This option saves @@ -689,7 +669,6 @@ config LEDS_TIMER bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \ MACH_OMAP_H2 || MACH_OMAP_PERSEUS2 depends on LEDS - depends on !GENERIC_CLOCKEVENTS default y if ARCH_EBSA110 help If you say Y here, one of the system LEDs (the green one on the diff --git a/trunk/arch/arm/boot/compressed/head-at91rm9200.S b/trunk/arch/arm/boot/compressed/head-at91rm9200.S index 11782ccd93a1..d68b9acd826e 100644 --- a/trunk/arch/arm/boot/compressed/head-at91rm9200.S +++ b/trunk/arch/arm/boot/compressed/head-at91rm9200.S @@ -61,12 +61,6 @@ cmp r7, r3 beq 99f - @ picotux 200 : 963 - mov r3, #(MACH_TYPE_PICOTUX2XX & 0xff) - orr r3, r3, #(MACH_TYPE_PICOTUX2XX & 0xff00) - cmp r7, r3 - beq 99f - @ Ajeco 1ARM : 1075 mov r3, #(MACH_TYPE_ONEARM & 0xff) orr r3, r3, #(MACH_TYPE_ONEARM & 0xff00) diff --git a/trunk/arch/arm/boot/compressed/misc.c b/trunk/arch/arm/boot/compressed/misc.c index 9b444022cb9b..283891c736c4 100644 --- a/trunk/arch/arm/boot/compressed/misc.c +++ b/trunk/arch/arm/boot/compressed/misc.c @@ -239,7 +239,7 @@ extern int end; static ulg free_mem_ptr; static ulg free_mem_ptr_end; -#define HEAP_SIZE 0x3000 +#define HEAP_SIZE 0x2000 #include "../../../../lib/inflate.c" diff --git a/trunk/arch/arm/common/sa1111.c b/trunk/arch/arm/common/sa1111.c index 798bbfccafb7..fe3f05901a23 100644 --- a/trunk/arch/arm/common/sa1111.c +++ b/trunk/arch/arm/common/sa1111.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/arm/common/via82c505.c b/trunk/arch/arm/common/via82c505.c index 79a8206e62ac..ba2e62986a57 100644 --- a/trunk/arch/arm/common/via82c505.c +++ b/trunk/arch/arm/common/via82c505.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include diff --git a/trunk/arch/arm/configs/ixp4xx_defconfig b/trunk/arch/arm/configs/ixp4xx_defconfig index db850a5689eb..fabf74c51a88 100644 --- a/trunk/arch/arm/configs/ixp4xx_defconfig +++ b/trunk/arch/arm/configs/ixp4xx_defconfig @@ -117,13 +117,11 @@ CONFIG_ARCH_ADI_COYOTE=y CONFIG_ARCH_IXDP425=y CONFIG_MACH_IXDPG425=y CONFIG_MACH_IXDP465=y -CONFIG_MACH_KIXRP435=y CONFIG_ARCH_IXCDP1100=y CONFIG_ARCH_PRPMC1100=y CONFIG_MACH_NAS100D=y CONFIG_ARCH_IXDP4XX=y CONFIG_CPU_IXP46X=y -CONFIG_CPU_IXP43X=y # CONFIG_MACH_GTWX5715 is not set # diff --git a/trunk/arch/arm/configs/picotux200_defconfig b/trunk/arch/arm/configs/picotux200_defconfig deleted file mode 100644 index 339c48953a62..000000000000 --- a/trunk/arch/arm/configs/picotux200_defconfig +++ /dev/null @@ -1,1386 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc4 -# Wed Mar 28 16:19:50 2007 -# -CONFIG_ARM=y -CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_GENERIC_GPIO=y -# CONFIG_GENERIC_TIME is not set -CONFIG_MMU=y -# CONFIG_NO_IOPORT is not set -CONFIG_GENERIC_HARDIRQS=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_ZONE_DMA=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=m -CONFIG_IKCONFIG_PROC=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -# CONFIG_KALLSYMS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# System Type -# -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -CONFIG_ARCH_AT91=y -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set -# CONFIG_ARCH_IOP13XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_NS9XXX is not set -# CONFIG_ARCH_PNX4008 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set - -# -# Atmel AT91 System-on-Chip -# -CONFIG_ARCH_AT91RM9200=y -# CONFIG_ARCH_AT91SAM9260 is not set -# CONFIG_ARCH_AT91SAM9261 is not set -# CONFIG_ARCH_AT91SAM9263 is not set - -# -# AT91RM9200 Board Type -# -# CONFIG_MACH_ONEARM is not set -# CONFIG_ARCH_AT91RM9200DK is not set -# CONFIG_MACH_AT91RM9200EK is not set -# CONFIG_MACH_CSB337 is not set -# CONFIG_MACH_CSB637 is not set -# CONFIG_MACH_CARMEVA is not set -# CONFIG_MACH_ATEB9200 is not set -# CONFIG_MACH_KB9200 is not set -CONFIG_MACH_PICOTUX2XX=y -# CONFIG_MACH_KAFA is not set - -# -# AT91 Board Options -# - -# -# AT91 Feature Selections -# -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_ARM920T=y -CONFIG_CPU_32v4T=y -CONFIG_CPU_ABRT_EV4T=y -CONFIG_CPU_CACHE_V4WT=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_V4WB=y -CONFIG_CPU_TLB_V4WBI=y -CONFIG_CPU_CP15=y -CONFIG_CPU_CP15_MMU=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_WRITETHROUGH is not set -# CONFIG_OUTER_CACHE is not set - -# -# Bus support -# - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_NO_IDLE_HZ=y -CONFIG_HZ=100 -CONFIG_AEABI=y -CONFIG_OABI_COMPAT=y -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -# CONFIG_LEDS is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="" -# CONFIG_XIP_KERNEL is not set -CONFIG_KEXEC=y - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_MISC=m - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=m -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=m -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_XFRM_TUNNEL=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m -CONFIG_INET_XFRM_MODE_BEET=m -CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=m -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_IPV6_MIP6=y -CONFIG_INET6_XFRM_TUNNEL=m -CONFIG_INET6_TUNNEL=m -CONFIG_INET6_XFRM_MODE_TRANSPORT=m -CONFIG_INET6_XFRM_MODE_TUNNEL=m -CONFIG_INET6_XFRM_MODE_BEET=m -CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m -CONFIG_IPV6_SIT=m -CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -CONFIG_BT=m -CONFIG_BT_L2CAP=m -CONFIG_BT_SCO=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y -# CONFIG_BT_HCIUART is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIVHCI is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x8000000 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=m -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=m -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_ARM_AT91_ETHER=y -# CONFIG_SMC91X is not set -# CONFIG_DM9000 is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -# CONFIG_PPP_SYNC_TTY is not set -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_MPPE=m -CONFIG_PPPOE=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLHC=m -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -# CONFIG_SERIAL_ATMEL_TTYAT is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91RM9200_WATCHDOG=m - -# -# USB-based Watchdog Cards -# -# CONFIG_USBPCWATCHDOG is not set -CONFIG_HW_RANDOM=m -# CONFIG_NVRAM is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -CONFIG_I2C_AT91=m -CONFIG_I2C_ISA=m -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -CONFIG_SENSORS_DS1337=m -CONFIG_SENSORS_DS1374=m -CONFIG_SENSORS_EEPROM=m -CONFIG_SENSORS_PCF8574=m -CONFIG_SENSORS_PCA9539=m -CONFIG_SENSORS_PCF8591=m -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=m -CONFIG_HWMON_VID=m -# CONFIG_SENSORS_ABITUGURU is not set -CONFIG_SENSORS_ADM1021=m -CONFIG_SENSORS_ADM1025=m -CONFIG_SENSORS_ADM1026=m -CONFIG_SENSORS_ADM1029=m -CONFIG_SENSORS_ADM1031=m -CONFIG_SENSORS_ADM9240=m -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -CONFIG_SENSORS_DS1621=m -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_GL520SM=m -CONFIG_SENSORS_IT87=m -CONFIG_SENSORS_LM63=m -CONFIG_SENSORS_LM75=m -CONFIG_SENSORS_LM77=m -CONFIG_SENSORS_LM78=m -CONFIG_SENSORS_LM80=m -CONFIG_SENSORS_LM83=m -CONFIG_SENSORS_LM85=m -CONFIG_SENSORS_LM87=m -CONFIG_SENSORS_LM90=m -CONFIG_SENSORS_LM92=m -CONFIG_SENSORS_MAX1619=m -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -CONFIG_SENSORS_SMSC47B397=m -# CONFIG_SENSORS_VT1211 is not set -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_W83791D=m -CONFIG_SENSORS_W83792D=m -CONFIG_SENSORS_W83793=m -CONFIG_SENSORS_W83L785TS=m -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=m -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB_ARCH_HAS_EHCI is not set -CONFIG_USB=m -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=m -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=m -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -CONFIG_USB_CATC=m -CONFIG_USB_KAWETH=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_USBNET_MII=m -CONFIG_USB_USBNET=m -CONFIG_USB_NET_AX8817X=m -CONFIG_USB_NET_CDCETHER=m -CONFIG_USB_NET_DM9601=m -CONFIG_USB_NET_GL620A=m -CONFIG_USB_NET_NET1080=m -CONFIG_USB_NET_PLUSB=m -CONFIG_USB_NET_MCS7830=m -CONFIG_USB_NET_RNDIS_HOST=m -CONFIG_USB_NET_CDC_SUBSET=m -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -CONFIG_USB_BELKIN=y -CONFIG_USB_ARMLINUX=y -CONFIG_USB_EPSON2888=y -CONFIG_USB_KC2190=y -CONFIG_USB_NET_ZAURUS=m -# CONFIG_USB_MON is not set - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=m -CONFIG_USB_SERIAL_GENERIC=y -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP2101 is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_FUNSOFT is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -CONFIG_USB_SERIAL_PL2303=m -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_DEBUG is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -CONFIG_MMC=m -# CONFIG_MMC_DEBUG is not set -CONFIG_MMC_BLOCK=m -CONFIG_MMC_AT91=m - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=m - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=m -CONFIG_RTC_INTF_PROC=m -CONFIG_RTC_INTF_DEV=m -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_CMOS is not set -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_M48T86 is not set -CONFIG_RTC_DRV_AT91RM9200=m -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# File systems -# -CONFIG_EXT2_FS=m -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=m -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=m -# CONFIG_JBD_DEBUG is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=m -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -CONFIG_JFFS2_SUMMARY=y -# CONFIG_JFFS2_FS_XATTR is not set -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_JFFS2_CMODE_NONE is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=m -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -CONFIG_AMIGA_PARTITION=y -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=m -CONFIG_NLS_DEFAULT="utf-8" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set -CONFIG_FRAME_POINTER=y -# CONFIG_FORCED_INLINING is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_ERRORS is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=m -CONFIG_CRYPTO_BLKCIPHER=m -CONFIG_CRYPTO_HASH=m -CONFIG_CRYPTO_MANAGER=m -CONFIG_CRYPTO_HMAC=m -CONFIG_CRYPTO_XCBC=m -CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=m -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_GF128MUL=m -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m -CONFIG_CRYPTO_PCBC=m -CONFIG_CRYPTO_LRW=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_FCRYPT=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_TWOFISH_COMMON=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -CONFIG_CRYPTO_CAMELLIA=m -CONFIG_CRYPTO_TEST=m - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=m -CONFIG_CRC16=m -CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/trunk/arch/arm/kernel/Makefile b/trunk/arch/arm/kernel/Makefile index 593b56509f4f..bb28087bf818 100644 --- a/trunk/arch/arm/kernel/Makefile +++ b/trunk/arch/arm/kernel/Makefile @@ -7,8 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) # Object file lists. obj-y := compat.o entry-armv.o entry-common.o irq.o \ - process.o ptrace.o semaphore.o setup.o signal.o \ - sys_arm.o stacktrace.o time.o traps.o + process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \ + time.o traps.o obj-$(CONFIG_ISA_DMA_API) += dma.o obj-$(CONFIG_ARCH_ACORN) += ecard.o diff --git a/trunk/arch/arm/kernel/ecard.c b/trunk/arch/arm/kernel/ecard.c index bdbd7da99286..f1c0fb974177 100644 --- a/trunk/arch/arm/kernel/ecard.c +++ b/trunk/arch/arm/kernel/ecard.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -51,8 +50,6 @@ #include #include -#include "ecard.h" - #ifndef CONFIG_ARCH_RPC #define HAVE_EXPMASK #endif @@ -126,7 +123,7 @@ static void ecard_task_reset(struct ecard_request *req) res = ec->slot_no == 8 ? &ec->resource[ECARD_RES_MEMC] - : ec->easi + : ec->type == ECARD_EASI ? &ec->resource[ECARD_RES_EASI] : &ec->resource[ECARD_RES_IOCSYNC]; @@ -181,7 +178,7 @@ static void ecard_task_readbytes(struct ecard_request *req) index += 1; } } else { - unsigned long base = (ec->easi + unsigned long base = (ec->type == ECARD_EASI ? &ec->resource[ECARD_RES_EASI] : &ec->resource[ECARD_RES_IOCSYNC])->start; void __iomem *pbase = (void __iomem *)base; @@ -266,6 +263,8 @@ static int ecard_init_mm(void) static int ecard_task(void * unused) { + daemonize("kecardd"); + /* * Allocate a mm. We're not a lazy-TLB kernel task since we need * to set page table entries where the user space would be. Note @@ -728,7 +727,7 @@ static int ecard_prints(char *buffer, ecard_t *ec) char *start = buffer; buffer += sprintf(buffer, " %d: %s ", ec->slot_no, - ec->easi ? "EASI" : " "); + ec->type == ECARD_EASI ? "EASI" : " "); if (ec->cid.id == 0) { struct in_chunk_dir incd; @@ -815,7 +814,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot) } ec->slot_no = slot; - ec->easi = type == ECARD_EASI; + ec->type = type; ec->irq = NO_IRQ; ec->fiq = NO_IRQ; ec->dma = NO_DMA; @@ -826,7 +825,6 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot) ec->dev.bus = &ecard_bus_type; ec->dev.dma_mask = &ec->dma_mask; ec->dma_mask = (u64)0xffffffff; - ec->dev.coherent_dma_mask = ec->dma_mask; if (slot < 4) { ec_set_resource(ec, ECARD_RES_MEMC, @@ -909,7 +907,7 @@ static ssize_t ecard_show_device(struct device *dev, struct device_attribute *at static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf) { struct expansion_card *ec = ECARD_DEV(dev); - return sprintf(buf, "%s\n", ec->easi ? "EASI" : "IOC"); + return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC"); } static struct device_attribute ecard_dev_attrs[] = { @@ -1060,14 +1058,13 @@ ecard_probe(int slot, card_type_t type) */ static int __init ecard_init(void) { - struct task_struct *task; - int slot, irqhw; - - task = kthread_run(ecard_task, NULL, "kecardd"); - if (IS_ERR(task)) { - printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n", - PTR_ERR(task)); - return PTR_ERR(task); + int slot, irqhw, ret; + + ret = kernel_thread(ecard_task, NULL, CLONE_KERNEL); + if (ret < 0) { + printk(KERN_ERR "Ecard: unable to create kernel thread: %d\n", + ret); + return ret; } printk("Probing expansion cards\n"); diff --git a/trunk/arch/arm/kernel/ecard.h b/trunk/arch/arm/kernel/ecard.h deleted file mode 100644 index d7c2dacf935d..000000000000 --- a/trunk/arch/arm/kernel/ecard.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * ecard.h - * - * Copyright 2007 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* Definitions internal to ecard.c - for it's use only!! - * - * External expansion card header as read from the card - */ -struct ex_ecid { - unsigned char r_irq:1; - unsigned char r_zero:1; - unsigned char r_fiq:1; - unsigned char r_id:4; - unsigned char r_a:1; - - unsigned char r_cd:1; - unsigned char r_is:1; - unsigned char r_w:2; - unsigned char r_r1:4; - - unsigned char r_r2:8; - - unsigned char r_prod[2]; - - unsigned char r_manu[2]; - - unsigned char r_country; - - unsigned char r_fiqmask; - unsigned char r_fiqoff[3]; - - unsigned char r_irqmask; - unsigned char r_irqoff[3]; -}; - -/* - * Chunk directory entry as read from the card - */ -struct ex_chunk_dir { - unsigned char r_id; - unsigned char r_len[3]; - unsigned long r_start; - union { - char string[256]; - char data[1]; - } d; -#define c_id(x) ((x)->r_id) -#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16)) -#define c_start(x) ((x)->r_start) -}; diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index 1d35edacc011..66db0a9bf0bc 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -257,9 +257,7 @@ __create_page_tables: * Map some ram to cover our .data and .bss areas. */ orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000) - .if (KERNEL_RAM_PADDR & 0x00f00000) orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000) - .endif add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]! ldr r6, =(_end - 1) @@ -276,9 +274,7 @@ __create_page_tables: */ add r0, r4, #PAGE_OFFSET >> 18 orr r6, r7, #(PHYS_OFFSET & 0xff000000) - .if (PHYS_OFFSET & 0x00f00000) - orr r6, r6, #(PHYS_OFFSET & 0x00f00000) - .endif + orr r6, r6, #(PHYS_OFFSET & 0x00e00000) str r6, [r0] #ifdef CONFIG_DEBUG_LL diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index 11dcd52e51be..e101846ab7dd 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -108,7 +109,7 @@ static struct irq_desc bad_irq_desc = { * come via this function. Instead, they should provide their * own 'handler' */ -asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); struct irq_desc *desc = irq_desc + irq; diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 5d6e6523598b..782af3cb213f 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,6 @@ #include #include #include -#include #include #include @@ -160,11 +160,9 @@ void cpu_idle(void) if (!idle) idle = default_idle; leds_event(led_idle_start); - tick_nohz_stop_sched_tick(); while (!need_resched()) idle(); leds_event(led_idle_end); - tick_nohz_restart_sched_tick(); preempt_enable_no_resched(); schedule(); preempt_disable(); diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index 6f2f46c2e406..9254ba2f46fc 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -456,10 +457,13 @@ void ptrace_cancel_bpt(struct task_struct *child) /* * Called by kernel/ptrace.c when detaching.. + * + * Make sure the single step bit is not set. */ void ptrace_disable(struct task_struct *child) { - single_step_disable(child); + child->ptrace &= ~PT_SINGLESTEP; + ptrace_cancel_bpt(child); } /* @@ -708,7 +712,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; - single_step_disable(child); + /* make sure single-step breakpoint is gone. */ + child->ptrace &= ~PT_SINGLESTEP; + ptrace_cancel_bpt(child); wake_up_process(child); ret = 0; break; @@ -719,7 +725,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) * exit. */ case PTRACE_KILL: - single_step_disable(child); + /* make sure single-step breakpoint is gone. */ + child->ptrace &= ~PT_SINGLESTEP; + ptrace_cancel_bpt(child); if (child->exit_state != EXIT_ZOMBIE) { child->exit_code = SIGKILL; wake_up_process(child); @@ -734,7 +742,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ret = -EIO; if (!valid_signal(data)) break; - single_step_enable(child); + child->ptrace |= PT_SINGLESTEP; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->exit_code = data; /* give it a chance to run. */ @@ -778,8 +786,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) break; case PTRACE_SET_SYSCALL: - task_thread_info(child)->syscall = data; ret = 0; + child->ptrace_message = data; break; #ifdef CONFIG_CRUNCH @@ -816,7 +824,7 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) ip = regs->ARM_ip; regs->ARM_ip = why; - current_thread_info()->syscall = scno; + current->ptrace_message = scno; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ @@ -833,5 +841,5 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) } regs->ARM_ip = ip; - return current_thread_info()->syscall; + return current->ptrace_message; } diff --git a/trunk/arch/arm/kernel/ptrace.h b/trunk/arch/arm/kernel/ptrace.h index def3b6184a79..f7cad13a22e9 100644 --- a/trunk/arch/arm/kernel/ptrace.h +++ b/trunk/arch/arm/kernel/ptrace.h @@ -7,45 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include - extern void ptrace_cancel_bpt(struct task_struct *); extern void ptrace_set_bpt(struct task_struct *); extern void ptrace_break(struct task_struct *, struct pt_regs *); - -/* - * make sure single-step breakpoint is gone. - */ -static inline void single_step_disable(struct task_struct *task) -{ - task->ptrace &= ~PT_SINGLESTEP; - ptrace_cancel_bpt(task); -} - -static inline void single_step_enable(struct task_struct *task) -{ - task->ptrace |= PT_SINGLESTEP; -} - -/* - * Send SIGTRAP if we're single-stepping - */ -static inline void single_step_trap(struct task_struct *task) -{ - if (task->ptrace & PT_SINGLESTEP) { - ptrace_cancel_bpt(task); - send_sig(SIGTRAP, task, 1); - } -} - -static inline void single_step_clear(struct task_struct *task) -{ - if (task->ptrace & PT_SINGLESTEP) - ptrace_cancel_bpt(task); -} - -static inline void single_step_set(struct task_struct *task) -{ - if (task->ptrace & PT_SINGLESTEP) - ptrace_set_bpt(task); -} diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 54cdf1aeefc3..3843d3bab2dd 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include @@ -284,7 +285,11 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) if (restore_sigframe(regs, frame)) goto badframe; - single_step_trap(current); + /* Send SIGTRAP if we're single-stepping */ + if (current->ptrace & PT_SINGLESTEP) { + ptrace_cancel_bpt(current); + send_sig(SIGTRAP, current, 1); + } return regs->ARM_r0; @@ -319,7 +324,11 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) goto badframe; - single_step_trap(current); + /* Send SIGTRAP if we're single-stepping */ + if (current->ptrace & PT_SINGLESTEP) { + ptrace_cancel_bpt(current); + send_sig(SIGTRAP, current, 1); + } return regs->ARM_r0; @@ -635,12 +644,14 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) if (try_to_freeze()) goto no_signal; - single_step_clear(current); + if (current->ptrace & PT_SINGLESTEP) + ptrace_cancel_bpt(current); signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { handle_signal(signr, &ka, &info, oldset, regs, syscall); - single_step_set(current); + if (current->ptrace & PT_SINGLESTEP) + ptrace_set_bpt(current); return 1; } @@ -694,7 +705,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) restart_syscall(regs); } } - single_step_set(current); + if (current->ptrace & PT_SINGLESTEP) + ptrace_set_bpt(current); return 0; } diff --git a/trunk/arch/arm/kernel/stacktrace.c b/trunk/arch/arm/kernel/stacktrace.c deleted file mode 100644 index 77ef35efaa8d..000000000000 --- a/trunk/arch/arm/kernel/stacktrace.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include - -#include "stacktrace.h" - -int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, - int (*fn)(struct stackframe *, void *), void *data) -{ - struct stackframe *frame; - - do { - /* - * Check current frame pointer is within bounds - */ - if ((fp - 12) < low || fp + 4 >= high) - break; - - frame = (struct stackframe *)(fp - 12); - - if (fn(frame, data)) - break; - - /* - * Update the low bound - the next frame must always - * be at a higher address than the current frame. - */ - low = fp + 4; - fp = frame->fp; - } while (fp); - - return 0; -} - -#ifdef CONFIG_STACKTRACE -struct stack_trace_data { - struct stack_trace *trace; - unsigned int skip; -}; - -static int save_trace(struct stackframe *frame, void *d) -{ - struct stack_trace_data *data = d; - struct stack_trace *trace = data->trace; - - if (data->skip) { - data->skip--; - return 0; - } - - trace->entries[trace->nr_entries++] = frame->lr; - - return trace->nr_entries >= trace->max_entries; -} - -void save_stack_trace(struct stack_trace *trace, struct task_struct *task) -{ - struct stack_trace_data data; - unsigned long fp, base; - - data.trace = trace; - data.skip = trace->skip; - - if (task) { - base = (unsigned long)task_stack_page(task); - fp = 0; /* FIXME */ - } else { - base = (unsigned long)task_stack_page(current); - asm("mov %0, fp" : "=r" (fp)); - } - - walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data); -} -#endif diff --git a/trunk/arch/arm/kernel/stacktrace.h b/trunk/arch/arm/kernel/stacktrace.h deleted file mode 100644 index e9fd20cb5662..000000000000 --- a/trunk/arch/arm/kernel/stacktrace.h +++ /dev/null @@ -1,9 +0,0 @@ -struct stackframe { - unsigned long fp; - unsigned long sp; - unsigned long lr; - unsigned long pc; -}; - -int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, - int (*fn)(struct stackframe *, void *), void *data); diff --git a/trunk/arch/arm/kernel/time.c b/trunk/arch/arm/kernel/time.c index d0540e4eaf5b..f61decb89ba2 100644 --- a/trunk/arch/arm/kernel/time.c +++ b/trunk/arch/arm/kernel/time.c @@ -327,7 +327,6 @@ void restore_time_delta(struct timespec *delta, struct timespec *rtc) } EXPORT_SYMBOL(restore_time_delta); -#ifndef CONFIG_GENERIC_CLOCKEVENTS /* * Kernel system timer support. */ @@ -341,9 +340,8 @@ void timer_tick(void) update_process_times(user_mode(get_irq_regs())); #endif } -#endif -#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) +#ifdef CONFIG_PM static int timer_suspend(struct sys_device *dev, pm_message_t state) { struct sys_timer *timer = container_of(dev, struct sys_timer, dev); diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 10ff36e4e414..24095601359b 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -44,18 +45,7 @@ static int __init user_debug_setup(char *str) __setup("user_debug=", user_debug_setup); #endif -static void dump_mem(const char *str, unsigned long bottom, unsigned long top); - -static inline int in_exception_text(unsigned long ptr) -{ - extern char __exception_text_start[]; - extern char __exception_text_end[]; - - return ptr >= (unsigned long)&__exception_text_start && - ptr < (unsigned long)&__exception_text_end; -} - -void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) +void dump_backtrace_entry(unsigned long where, unsigned long from) { #ifdef CONFIG_KALLSYMS printk("[<%08lx>] ", where); @@ -65,9 +55,6 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long #else printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); #endif - - if (in_exception_text(where)) - dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); } /* @@ -245,8 +232,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) do_exit(SIGSEGV); } -void arm_notify_die(const char *str, struct pt_regs *regs, - struct siginfo *info, unsigned long err, unsigned long trap) +void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, + unsigned long err, unsigned long trap) { if (user_mode(regs)) { current->thread.error_code = err; @@ -279,14 +266,13 @@ void unregister_undef_hook(struct undef_hook *hook) spin_unlock_irqrestore(&undef_lock, flags); } -asmlinkage void __exception do_undefinstr(struct pt_regs *regs) +asmlinkage void do_undefinstr(struct pt_regs *regs) { unsigned int correction = thumb_mode(regs) ? 2 : 4; unsigned int instr; struct undef_hook *hook; siginfo_t info; void __user *pc; - unsigned long flags; /* * According to the ARM ARM, PC is 2 or 4 bytes ahead, @@ -305,7 +291,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) get_user(instr, (u32 __user *)pc); } - spin_lock_irqsave(&undef_lock, flags); + spin_lock_irq(&undef_lock); list_for_each_entry(hook, &undef_hook, node) { if ((instr & hook->instr_mask) == hook->instr_val && (regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) { @@ -315,7 +301,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) } } } - spin_unlock_irqrestore(&undef_lock, flags); + spin_unlock_irq(&undef_lock); #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) { @@ -330,7 +316,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) info.si_code = ILL_ILLOPC; info.si_addr = pc; - arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); + notify_die("Oops - undefined instruction", regs, &info, 0, 6); } asmlinkage void do_unexp_fiq (struct pt_regs *regs) @@ -384,7 +370,7 @@ static int bad_syscall(int n, struct pt_regs *regs) info.si_addr = (void __user *)instruction_pointer(regs) - (thumb_mode(regs) ? 2 : 4); - arm_notify_die("Oops - bad syscall", regs, &info, n, 0); + notify_die("Oops - bad syscall", regs, &info, n, 0); return regs->ARM_r0; } @@ -428,7 +414,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) info.si_code = SEGV_MAPERR; info.si_addr = NULL; - arm_notify_die("branch through zero", regs, &info, 0, 0); + notify_die("branch through zero", regs, &info, 0, 0); return 0; case NR(breakpoint): /* SWI BREAK_POINT */ @@ -564,7 +550,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) info.si_addr = (void __user *)instruction_pointer(regs) - (thumb_mode(regs) ? 2 : 4); - arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0); + notify_die("Oops - bad syscall(2)", regs, &info, no, 0); return 0; } @@ -638,7 +624,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) info.si_code = ILL_ILLOPC; info.si_addr = (void __user *)addr; - arm_notify_die("unknown data abort code", regs, &info, instr, 0); + notify_die("unknown data abort code", regs, &info, instr, 0); } void __attribute__((noreturn)) __bug(const char *file, int line) diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 6be67296f333..ddbdad48f5b2 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -59,7 +59,7 @@ SECTIONS usr/built-in.o(.init.ramfs) __initramfs_end = .; #endif - . = ALIGN(4096); + . = ALIGN(64); __per_cpu_start = .; *(.data.percpu) __per_cpu_end = .; @@ -83,9 +83,6 @@ SECTIONS .text : { /* Real text segment */ _text = .; /* Text and read-only data */ - __exception_text_start = .; - *(.exception.text) - __exception_text_end = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/arm/lib/backtrace.S b/trunk/arch/arm/lib/backtrace.S index 84dc890d2bf3..74230083cbf4 100644 --- a/trunk/arch/arm/lib/backtrace.S +++ b/trunk/arch/arm/lib/backtrace.S @@ -17,8 +17,8 @@ @ fp is 0 or stack frame #define frame r4 -#define sv_fp r5 -#define sv_pc r6 +#define next r5 +#define save r6 #define mask r7 #define offset r8 @@ -31,106 +31,108 @@ ENTRY(c_backtrace) #if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK) mov pc, lr #else - stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... - movs frame, r0 @ if frame pointer is zero - beq no_frame @ we have no stack frames - - tst r1, #0x10 @ 26 or 32-bit mode? - moveq mask, #0xfc000003 @ mask for 26-bit - movne mask, #0 @ mask for 32-bit -1: stmfd sp!, {pc} @ calculate offset of PC stored - ldr r0, [sp], #4 @ by stmfd for this CPU - adr r1, 1b + stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location... + tst r1, #0x10 @ 26 or 32-bit? + moveq mask, #0xfc000003 + movne mask, #0 + tst mask, r0 + movne r0, #0 + movs frame, r0 +1: moveq r0, #-2 + ldmeqfd sp!, {r4 - r8, pc} + +2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction + ldr r0, [sp], #4 + adr r1, 2b - 4 sub offset, r0, r1 -/* - * Stack frame layout: - * optionally saved caller registers (r4 - r10) - * saved fp - * saved sp - * saved lr - * frame => saved pc - * optionally saved arguments (r0 - r3) - * saved sp => - * - * Functions start with the following code sequence: - * mov ip, sp - * stmfd sp!, {r0 - r3} (optional) - * corrected pc => stmfd sp!, {..., fp, ip, lr, pc} - */ -for_each_frame: tst frame, mask @ Check for address exceptions - bne no_frame - -1001: ldr sv_pc, [frame, #0] @ get saved pc -1002: ldr sv_fp, [frame, #-12] @ get saved fp - - sub sv_pc, sv_pc, offset @ Correct PC for prefetching - bic sv_pc, sv_pc, mask @ mask PC/LR for the mode +3: tst frame, mask @ Check for address exceptions... + bne 1b -1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists, - ldr r3, .Ldsi+4 @ adjust saved 'pc' back one - teq r3, r2, lsr #10 @ instruction - subne r0, sv_pc, #4 @ allow for mov - subeq r0, sv_pc, #8 @ allow for mov + stmia - - ldr r1, [frame, #-4] @ get saved lr - mov r2, frame - bic r1, r1, mask @ mask PC/LR for the mode - bl dump_backtrace_entry - - ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists, +1001: ldr next, [frame, #-12] @ get fp +1002: ldr r2, [frame, #-4] @ get lr +1003: ldr r3, [frame, #0] @ get pc + sub save, r3, offset @ Correct PC for prefetching + bic save, save, mask +1004: ldr r1, [save, #0] @ get instruction at function + mov r1, r1, lsr #10 ldr r3, .Ldsi+4 - teq r3, r1, lsr #10 - ldreq r0, [frame, #-8] @ get sp - subeq r0, r0, #4 @ point at the last arg - bleq .Ldumpstm @ dump saved registers - -1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc} - ldr r3, .Ldsi @ instruction exists, - teq r3, r1, lsr #10 - subeq r0, frame, #16 - bleq .Ldumpstm @ dump saved registers - - teq sv_fp, #0 @ zero saved fp means - beq no_frame @ no further frames + teq r1, r3 + subeq save, save, #4 + mov r0, save + bic r1, r2, mask + bl dump_backtrace_entry - cmp sv_fp, frame @ next frame must be - mov frame, sv_fp @ above the current frame - bhi for_each_frame + ldr r0, [frame, #-8] @ get sp + sub r0, r0, #4 +1005: ldr r1, [save, #4] @ get instruction at function+4 + mov r3, r1, lsr #10 + ldr r2, .Ldsi+4 + teq r3, r2 @ Check for stmia sp!, {args} + addeq save, save, #4 @ next instruction + bleq .Ldumpstm + + sub r0, frame, #16 +1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction + mov r3, r1, lsr #10 + ldr r2, .Ldsi + teq r3, r2 + bleq .Ldumpstm + + /* + * A zero next framepointer means we're done. + */ + teq next, #0 + ldmeqfd sp!, {r4 - r8, pc} + + /* + * The next framepointer must be above the + * current framepointer. + */ + cmp next, frame + mov frame, next + bhi 3b + b 1007f -1006: adr r0, .Lbad +/* + * Fixup for LDMDB. Note that this must not be in the fixup section. + */ +1007: ldr r0, =.Lbad mov r1, frame bl printk -no_frame: ldmfd sp!, {r4 - r8, pc} + ldmfd sp!, {r4 - r8, pc} + .ltorg .section __ex_table,"a" .align 3 - .long 1001b, 1006b - .long 1002b, 1006b - .long 1003b, 1006b - .long 1004b, 1006b + .long 1001b, 1007b + .long 1002b, 1007b + .long 1003b, 1007b + .long 1004b, 1007b + .long 1005b, 1007b + .long 1006b, 1007b .previous #define instr r4 #define reg r5 #define stack r6 -.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} +.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr} mov stack, r0 mov instr, r1 - mov reg, #10 + mov reg, #9 mov r7, #0 1: mov r3, #1 tst instr, r3, lsl reg beq 2f add r7, r7, #1 - teq r7, #6 - moveq r7, #1 - moveq r1, #'\n' - movne r1, #' ' - ldr r3, [stack], #-4 - mov r2, reg + teq r7, #4 + moveq r7, #0 + moveq r3, #'\n' + movne r3, #' ' + ldr r2, [stack], #-4 + mov r1, reg adr r0, .Lfp bl printk 2: subs reg, reg, #1 @@ -138,13 +140,14 @@ no_frame: ldmfd sp!, {r4 - r8, pc} teq r7, #0 adrne r0, .Lcr blne printk - ldmfd sp!, {instr, reg, stack, r7, pc} + mov r0, stack + ldmfd sp!, {instr, reg, stack, r7, r8, pc} -.Lfp: .asciz "%cr%d:%08x" +.Lfp: .asciz " r%d = %08X%c" .Lcr: .asciz "\n" .Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n" .align -.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc} - .word 0xe92d0000 >> 10 @ stmfd sp!, {} +.Ldsi: .word 0x00e92dd8 >> 2 + .word 0x00e92d00 >> 2 #endif diff --git a/trunk/arch/arm/lib/getuser.S b/trunk/arch/arm/lib/getuser.S index 1dd8ea4f9a9c..c03ea8e666ba 100644 --- a/trunk/arch/arm/lib/getuser.S +++ b/trunk/arch/arm/lib/getuser.S @@ -26,6 +26,8 @@ * Note that ADDR_LIMIT is either 0 or 0xc0000000. * Note also that it is intended that __get_user_bad is not global. */ +#include +#include #include .global __get_user_1 diff --git a/trunk/arch/arm/lib/putuser.S b/trunk/arch/arm/lib/putuser.S index 8620afe54f72..4593e9c07f05 100644 --- a/trunk/arch/arm/lib/putuser.S +++ b/trunk/arch/arm/lib/putuser.S @@ -26,6 +26,8 @@ * Note that ADDR_LIMIT is either 0 or 0xc0000000 * Note also that it is intended that __put_user_bad is not global. */ +#include +#include #include .global __put_user_1 diff --git a/trunk/arch/arm/mach-aaec2000/core.c b/trunk/arch/arm/mach-aaec2000/core.c index 0446ef2f5bd6..a950160fcfb6 100644 --- a/trunk/arch/arm/mach-aaec2000/core.c +++ b/trunk/arch/arm/mach-aaec2000/core.c @@ -142,7 +142,7 @@ aaec2000_timer_interrupt(int irq, void *dev_id) static struct irqaction aaec2000_timer_irq = { .name = "AAEC-2000 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = aaec2000_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-at91/Kconfig b/trunk/arch/arm/mach-at91/Kconfig index e238ad8cfd8f..bf0d96272e3a 100644 --- a/trunk/arch/arm/mach-at91/Kconfig +++ b/trunk/arch/arm/mach-at91/Kconfig @@ -81,13 +81,6 @@ config MACH_KB9200 Select this if you are using KwikByte's KB920x board. -config MACH_PICOTUX2XX - bool "picotux 200" - depends on ARCH_AT91RM9200 - help - Select this if you are using a picotux 200. - - config MACH_KAFA bool "Sperry-Sun KAFA board" depends on ARCH_AT91RM9200 diff --git a/trunk/arch/arm/mach-at91/Makefile b/trunk/arch/arm/mach-at91/Makefile index a412ae18a421..05de6cdc88f1 100644 --- a/trunk/arch/arm/mach-at91/Makefile +++ b/trunk/arch/arm/mach-at91/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o obj-$(CONFIG_MACH_KB9200) += board-kb9202.o obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o obj-$(CONFIG_MACH_KAFA) += board-kafa.o -obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o # AT91SAM9260 board-specific support obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o diff --git a/trunk/arch/arm/mach-at91/at91rm9200.c b/trunk/arch/arm/mach-at91/at91rm9200.c index 2cad2bf864be..2ddcdd69df7d 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200.c +++ b/trunk/arch/arm/mach-at91/at91rm9200.c @@ -117,21 +117,6 @@ static struct clk pioD_clk = { .pmc_mask = 1 << AT91RM9200_ID_PIOD, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91RM9200_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91RM9200_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc2_clk = { - .name = "ssc2_clk", - .pmc_mask = 1 << AT91RM9200_ID_SSC2, - .type = CLK_TYPE_PERIPHERAL, -}; static struct clk tc0_clk = { .name = "tc0_clk", .pmc_mask = 1 << AT91RM9200_ID_TC0, @@ -176,9 +161,7 @@ static struct clk *periph_clocks[] __initdata = { &udc_clk, &twi_clk, &spi_clk, - &ssc0_clk, - &ssc1_clk, - &ssc2_clk, + // ssc 0 .. ssc2 &tc0_clk, &tc1_clk, &tc2_clk, diff --git a/trunk/arch/arm/mach-at91/at91rm9200_time.c b/trunk/arch/arm/mach-at91/at91rm9200_time.c index a6340357585d..949199a244c7 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_time.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_time.c @@ -87,7 +87,7 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) static struct irqaction at91rm9200_timer_irq = { .name = "at91_tick", - .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER, .handler = at91rm9200_timer_interrupt }; diff --git a/trunk/arch/arm/mach-at91/at91sam9260.c b/trunk/arch/arm/mach-at91/at91sam9260.c index e47381e8aaba..6ea41d8266cb 100644 --- a/trunk/arch/arm/mach-at91/at91sam9260.c +++ b/trunk/arch/arm/mach-at91/at91sam9260.c @@ -119,11 +119,6 @@ static struct clk spi1_clk = { .pmc_mask = 1 << AT91SAM9260_ID_SPI1, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk ssc_clk = { - .name = "ssc_clk", - .pmc_mask = 1 << AT91SAM9260_ID_SSC, - .type = CLK_TYPE_PERIPHERAL, -}; static struct clk tc0_clk = { .name = "tc0_clk", .pmc_mask = 1 << AT91SAM9260_ID_TC0, @@ -198,7 +193,7 @@ static struct clk *periph_clocks[] __initdata = { &twi_clk, &spi0_clk, &spi1_clk, - &ssc_clk, + // ssc &tc0_clk, &tc1_clk, &tc2_clk, diff --git a/trunk/arch/arm/mach-at91/at91sam9261.c b/trunk/arch/arm/mach-at91/at91sam9261.c index dfe8c39c9fb9..784d1e682d6d 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261.c +++ b/trunk/arch/arm/mach-at91/at91sam9261.c @@ -97,21 +97,6 @@ static struct clk spi1_clk = { .pmc_mask = 1 << AT91SAM9261_ID_SPI1, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91SAM9261_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91SAM9261_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc2_clk = { - .name = "ssc2_clk", - .pmc_mask = 1 << AT91SAM9261_ID_SSC2, - .type = CLK_TYPE_PERIPHERAL, -}; static struct clk tc0_clk = { .name = "tc0_clk", .pmc_mask = 1 << AT91SAM9261_ID_TC0, @@ -150,9 +135,7 @@ static struct clk *periph_clocks[] __initdata = { &twi_clk, &spi0_clk, &spi1_clk, - &ssc0_clk, - &ssc1_clk, - &ssc2_clk, + // ssc 0 .. ssc2 &tc0_clk, &tc1_clk, &tc2_clk, diff --git a/trunk/arch/arm/mach-at91/at91sam9261_devices.c b/trunk/arch/arm/mach-at91/at91sam9261_devices.c index 8e781997716a..e1504766fd64 100644 --- a/trunk/arch/arm/mach-at91/at91sam9261_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9261_devices.c @@ -430,9 +430,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) * LCD Controller * -------------------------------------------------------------------- */ -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) +#if defined(CONFIG_FB_AT91) || defined(CONFIG_FB_AT91_MODULE) static u64 lcdc_dmamask = 0xffffffffUL; -static struct atmel_lcdfb_info lcdc_data; +static struct at91fb_info lcdc_data; static struct resource lcdc_resources[] = { [0] = { @@ -455,7 +455,7 @@ static struct resource lcdc_resources[] = { }; static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", + .name = "at91-fb", .id = 0, .dev = { .dma_mask = &lcdc_dmamask, @@ -466,7 +466,7 @@ static struct platform_device at91_lcdc_device = { .num_resources = ARRAY_SIZE(lcdc_resources), }; -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) +void __init at91_add_device_lcdc(struct at91fb_info *data) { if (!data) { return; @@ -499,7 +499,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) platform_device_register(&at91_lcdc_device); } #else -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} +void __init at91_add_device_lcdc(struct at91fb_info *data) {} #endif diff --git a/trunk/arch/arm/mach-at91/at91sam9263.c b/trunk/arch/arm/mach-at91/at91sam9263.c index 00e27b177857..0e89a7fca3fa 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263.c +++ b/trunk/arch/arm/mach-at91/at91sam9263.c @@ -87,11 +87,6 @@ static struct clk mmc1_clk = { .pmc_mask = 1 << AT91SAM9263_ID_MCI1, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk can_clk = { - .name = "can_clk", - .pmc_mask = 1 << AT91SAM9263_ID_CAN, - .type = CLK_TYPE_PERIPHERAL, -}; static struct clk twi_clk = { .name = "twi_clk", .pmc_mask = 1 << AT91SAM9263_ID_TWI, @@ -107,46 +102,16 @@ static struct clk spi1_clk = { .pmc_mask = 1 << AT91SAM9263_ID_SPI1, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91SAM9263_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91SAM9263_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ac97_clk = { - .name = "ac97_clk", - .pmc_mask = 1 << AT91SAM9263_ID_AC97C, - .type = CLK_TYPE_PERIPHERAL, -}; static struct clk tcb_clk = { .name = "tcb_clk", .pmc_mask = 1 << AT91SAM9263_ID_TCB, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk pwmc_clk = { - .name = "pwmc_clk", - .pmc_mask = 1 << AT91SAM9263_ID_PWMC, - .type = CLK_TYPE_PERIPHERAL, -}; static struct clk macb_clk = { .name = "macb_clk", .pmc_mask = 1 << AT91SAM9263_ID_EMAC, .type = CLK_TYPE_PERIPHERAL, }; -static struct clk dma_clk = { - .name = "dma_clk", - .pmc_mask = 1 << AT91SAM9263_ID_DMA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twodge_clk = { - .name = "2dge_clk", - .pmc_mask = 1 << AT91SAM9263_ID_2DGE, - .type = CLK_TYPE_PERIPHERAL, -}; static struct clk udc_clk = { .name = "udc_clk", .pmc_mask = 1 << AT91SAM9263_ID_UDP, @@ -177,21 +142,20 @@ static struct clk *periph_clocks[] __initdata = { &usart2_clk, &mmc0_clk, &mmc1_clk, - &can_clk, + // can &twi_clk, &spi0_clk, &spi1_clk, - &ssc0_clk, - &ssc1_clk, - &ac97_clk, + // ssc0 .. ssc1 + // ac97 &tcb_clk, - &pwmc_clk, + // pwmc &macb_clk, - &twodge_clk, + // 2dge &udc_clk, &isi_clk, &lcdc_clk, - &dma_clk, + // dma &ohci_clk, // irq0 .. irq1 }; diff --git a/trunk/arch/arm/mach-at91/at91sam9263_devices.c b/trunk/arch/arm/mach-at91/at91sam9263_devices.c index 2b2e18a67128..b77121f27f34 100644 --- a/trunk/arch/arm/mach-at91/at91sam9263_devices.c +++ b/trunk/arch/arm/mach-at91/at91sam9263_devices.c @@ -572,130 +572,6 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) #endif -/* -------------------------------------------------------------------- - * AC97 - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE) -static u64 ac97_dmamask = 0xffffffffUL; -static struct atmel_ac97_data ac97_data; - -static struct resource ac97_resources[] = { - [0] = { - .start = AT91SAM9263_BASE_AC97C, - .end = AT91SAM9263_BASE_AC97C + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9263_ID_AC97C, - .end = AT91SAM9263_ID_AC97C, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91sam9263_ac97_device = { - .name = "ac97c", - .id = 1, - .dev = { - .dma_mask = &ac97_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &ac97_data, - }, - .resource = ac97_resources, - .num_resources = ARRAY_SIZE(ac97_resources), -}; - -void __init at91_add_device_ac97(struct atmel_ac97_data *data) -{ - if (!data) - return; - - at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */ - at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */ - at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */ - at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */ - - /* reset */ - if (data->reset_pin) - at91_set_gpio_output(data->reset_pin, 0); - - ac97_data = *ek_data; - platform_device_register(&at91sam9263_ac97_device); -} -#else -void __init at91_add_device_ac97(struct atmel_ac97_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * LCD Controller - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE) -static u64 lcdc_dmamask = 0xffffffffUL; -static struct atmel_lcdfb_info lcdc_data; - -static struct resource lcdc_resources[] = { - [0] = { - .start = AT91SAM9263_LCDC_BASE, - .end = AT91SAM9263_LCDC_BASE + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91SAM9263_ID_LCDC, - .end = AT91SAM9263_ID_LCDC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91_lcdc_device = { - .name = "atmel_lcdfb", - .id = 0, - .dev = { - .dma_mask = &lcdc_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &lcdc_data, - }, - .resource = lcdc_resources, - .num_resources = ARRAY_SIZE(lcdc_resources), -}; - -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) -{ - if (!data) - return; - - at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */ - at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */ - at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */ - at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */ - at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */ - at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */ - at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */ - at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */ - at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */ - at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */ - at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */ - at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */ - at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */ - at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */ - at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */ - at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */ - at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */ - at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */ - at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */ - at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */ - - lcdc_data = *data; - platform_device_register(&at91_lcdc_device); -} -#else -void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {} -#endif - - /* -------------------------------------------------------------------- * LEDs * -------------------------------------------------------------------- */ diff --git a/trunk/arch/arm/mach-at91/at91sam926x_time.c b/trunk/arch/arm/mach-at91/at91sam926x_time.c index 5c090c9442f5..a4dded27fa16 100644 --- a/trunk/arch/arm/mach-at91/at91sam926x_time.c +++ b/trunk/arch/arm/mach-at91/at91sam926x_time.c @@ -66,7 +66,7 @@ static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id) static struct irqaction at91sam926x_timer_irq = { .name = "at91_tick", - .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER, .handler = at91sam926x_timer_interrupt }; diff --git a/trunk/arch/arm/mach-at91/board-picotux200.c b/trunk/arch/arm/mach-at91/board-picotux200.c deleted file mode 100644 index 49cfe7ab4a85..000000000000 --- a/trunk/arch/arm/mach-at91/board-picotux200.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * linux/arch/arm/mach-at91/board-picotux200.c - * - * Copyright (C) 2005 SAN People - * Copyright (C) 2007 Kleinhenz Elektronik GmbH - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "generic.h" - - -/* - * Serial port configuration. - * 0 .. 3 = USART0 .. USART3 - * 4 = DBGU - */ -static struct at91_uart_config __initdata picotux200_uart_config = { - .console_tty = 0, /* ttyS0 */ - .nr_tty = 2, - .tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */ -}; - -static void __init picotux200_map_io(void) -{ - /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000, AT91RM9200_BGA); - - /* Setup the serial ports and console */ - at91_init_serial(&picotux200_uart_config); -} - -static void __init picotux200_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - -static struct at91_eth_data __initdata picotux200_eth_data = { - .phy_irq_pin = AT91_PIN_PC4, - .is_rmii = 1, -}; - -static struct at91_usbh_data __initdata picotux200_usbh_data = { - .ports = 1, -}; - -// static struct at91_udc_data __initdata picotux200_udc_data = { -// .vbus_pin = AT91_PIN_PD4, -// .pullup_pin = AT91_PIN_PD5, -// }; - -static struct at91_mmc_data __initdata picotux200_mmc_data = { - .det_pin = AT91_PIN_PB27, - .slot_b = 0, - .wire4 = 1, - .wp_pin = AT91_PIN_PA17, -}; - -// static struct spi_board_info picotux200_spi_devices[] = { -// { /* DataFlash chip */ -// .modalias = "mtd_dataflash", -// .chip_select = 0, -// .max_speed_hz = 15 * 1000 * 1000, -// }, -// #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD -// { /* DataFlash card */ -// .modalias = "mtd_dataflash", -// .chip_select = 3, -// .max_speed_hz = 15 * 1000 * 1000, -// }, -// #endif -// }; - -#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0 -#define PICOTUX200_FLASH_SIZE 0x400000 - -static struct physmap_flash_data picotux200_flash_data = { - .width = 2, -}; - -static struct resource picotux200_flash_resource = { - .start = PICOTUX200_FLASH_BASE, - .end = PICOTUX200_FLASH_BASE + PICOTUX200_FLASH_SIZE - 1, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device picotux200_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &picotux200_flash_data, - }, - .resource = &picotux200_flash_resource, - .num_resources = 1, -}; - -static void __init picotux200_board_init(void) -{ - /* Serial */ - at91_add_device_serial(); - /* Ethernet */ - at91_add_device_eth(&picotux200_eth_data); - /* USB Host */ - at91_add_device_usbh(&picotux200_usbh_data); - /* USB Device */ - // at91_add_device_udc(&picotux200_udc_data); - // at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */ - /* I2C */ - at91_add_device_i2c(); - /* SPI */ - // at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices)); -#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD - /* DataFlash card */ - at91_set_gpio_output(AT91_PIN_PB22, 0); -#else - /* MMC */ - at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ - at91_add_device_mmc(0, &picotux200_mmc_data); -#endif - /* NOR Flash */ - platform_device_register(&picotux200_flash); -} - -MACHINE_START(PICOTUX2XX, "picotux 200") - /* Maintainer: Kleinhenz Elektronik GmbH */ - .phys_io = AT91_BASE_SYS, - .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, - .boot_params = AT91_SDRAM_BASE + 0x100, - .timer = &at91rm9200_timer, - .map_io = picotux200_map_io, - .init_irq = picotux200_init_irq, - .init_machine = picotux200_board_init, -MACHINE_END diff --git a/trunk/arch/arm/mach-at91/board-sam9260ek.c b/trunk/arch/arm/mach-at91/board-sam9260ek.c index 65fa532bb4ac..57fb4499d969 100644 --- a/trunk/arch/arm/mach-at91/board-sam9260ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9260ek.c @@ -104,9 +104,9 @@ static struct spi_board_info ek_spi_devices[] = { }, #endif #endif -#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) +#if defined(CONFIG_SND_AT73C213) { /* AT73C213 DAC */ - .modalias = "at73c213", + .modalias = "snd_at73c213", .chip_select = 0, .max_speed_hz = 10 * 1000 * 1000, .bus_num = 1, @@ -118,7 +118,7 @@ static struct spi_board_info ek_spi_devices[] = { /* * MACB Ethernet device */ -static struct at91_eth_data __initdata ek_macb_data = { +static struct __initdata at91_eth_data ek_macb_data = { .phy_irq_pin = AT91_PIN_PA7, .is_rmii = 1, }; @@ -140,7 +140,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { }, }; -static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) +static struct mtd_partition *nand_partitions(int size, int *num_partitions) { *num_partitions = ARRAY_SIZE(ek_nand_partition); return ek_nand_partition; @@ -188,8 +188,6 @@ static void __init ek_board_init(void) at91_add_device_eth(&ek_macb_data); /* MMC */ at91_add_device_mmc(0, &ek_mmc_data); - /* I2C */ - at91_add_device_i2c(); } MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") diff --git a/trunk/arch/arm/mach-at91/board-sam9261ek.c b/trunk/arch/arm/mach-at91/board-sam9261ek.c index bcf71536cc6d..b7e772467cf6 100644 --- a/trunk/arch/arm/mach-at91/board-sam9261ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9261ek.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -195,41 +194,6 @@ static struct at91_nand_data __initdata ek_nand_data = { #endif }; -/* - * ADS7846 Touchscreen - */ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - -static int ads7843_pendown_state(void) -{ - return !at91_get_gpio_value(AT91_PIN_PC2); /* Touchscreen PENIRQ */ -} - -static struct ads7846_platform_data ads_info = { - .model = 7843, - .x_min = 150, - .x_max = 3830, - .y_min = 190, - .y_max = 3830, - .vref_delay_usecs = 100, - .x_plate_ohms = 450, - .y_plate_ohms = 250, - .pressure_max = 15000, - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7843_pendown_state, -}; - -static void __init ek_add_device_ts(void) -{ - at91_set_B_periph(AT91_PIN_PC2, 1); /* External IRQ0, with pullup */ - at91_set_gpio_input(AT91_PIN_PA11, 1); /* Touchscreen BUSY signal */ -} -#else -static void __init ek_add_device_ts(void) {} -#endif - /* * SPI devices */ @@ -240,16 +204,6 @@ static struct spi_board_info ek_spi_devices[] = { .max_speed_hz = 15 * 1000 * 1000, .bus_num = 0, }, -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - { - .modalias = "ads7846", - .chip_select = 2, - .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, - .irq = AT91SAM9261_ID_IRQ0, - }, -#endif #if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */ .modalias = "mtd_dataflash", @@ -257,9 +211,9 @@ static struct spi_board_info ek_spi_devices[] = { .max_speed_hz = 15 * 1000 * 1000, .bus_num = 0, }, -#elif defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE) +#elif defined(CONFIG_SND_AT73C213) { /* AT73C213 DAC */ - .modalias = "at73c213", + .modalias = "snd_at73c213", .chip_select = 3, .max_speed_hz = 10 * 1000 * 1000, .bus_num = 0, @@ -287,8 +241,6 @@ static void __init ek_board_init(void) #if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) /* SPI */ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* Touchscreen */ - ek_add_device_ts(); #else /* MMC */ at91_add_device_mmc(0, &ek_mmc_data); diff --git a/trunk/arch/arm/mach-at91/board-sam9263ek.c b/trunk/arch/arm/mach-at91/board-sam9263ek.c index f57458559fb6..8fdce11a880c 100644 --- a/trunk/arch/arm/mach-at91/board-sam9263ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9263ek.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -86,40 +85,6 @@ static struct at91_udc_data __initdata ek_udc_data = { }; -/* - * ADS7846 Touchscreen - */ -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -static int ads7843_pendown_state(void) -{ - return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */ -} - -static struct ads7846_platform_data ads_info = { - .model = 7843, - .x_min = 150, - .x_max = 3830, - .y_min = 190, - .y_max = 3830, - .vref_delay_usecs = 100, - .x_plate_ohms = 450, - .y_plate_ohms = 250, - .pressure_max = 15000, - .debounce_max = 1, - .debounce_rep = 0, - .debounce_tol = (~0), - .get_pendown_state = ads7843_pendown_state, -}; - -static void __init ek_add_device_ts(void) -{ - at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */ - at91_set_gpio_input(AT91_PIN_PA31, 1); /* Touchscreen BUSY signal */ -} -#else -static void __init ek_add_device_ts(void) {} -#endif - /* * SPI devices. */ @@ -132,16 +97,6 @@ static struct spi_board_info ek_spi_devices[] = { .bus_num = 0, }, #endif -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) - { - .modalias = "ads7846", - .chip_select = 3, - .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */ - .bus_num = 0, - .platform_data = &ads_info, - .irq = AT91SAM9263_ID_IRQ1, - }, -#endif }; @@ -156,14 +111,6 @@ static struct at91_mmc_data __initdata ek_mmc_data = { }; -/* - * MACB Ethernet device - */ -static struct at91_eth_data __initdata ek_macb_data = { - .is_rmii = 1, -}; - - /* * NAND flash */ @@ -201,14 +148,6 @@ static struct at91_nand_data __initdata ek_nand_data = { }; -/* - * AC97 - */ -static struct atmel_ac97_data ek_ac97_data = { - .reset_pin = AT91_PIN_PA13, -}; - - static void __init ek_board_init(void) { /* Serial */ @@ -218,20 +157,11 @@ static void __init ek_board_init(void) /* USB Device */ at91_add_device_udc(&ek_udc_data); /* SPI */ - at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */ at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); - /* Touchscreen */ - ek_add_device_ts(); /* MMC */ at91_add_device_mmc(1, &ek_mmc_data); - /* Ethernet */ - at91_add_device_eth(&ek_macb_data); /* NAND */ at91_add_device_nand(&ek_nand_data); - /* I2C */ - at91_add_device_i2c(); - /* AC97 */ - at91_add_device_ac97(&ek_ac97_data); } MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK") diff --git a/trunk/arch/arm/mach-clps711x/time.c b/trunk/arch/arm/mach-clps711x/time.c index f428af7545b4..428493dd4687 100644 --- a/trunk/arch/arm/mach-clps711x/time.c +++ b/trunk/arch/arm/mach-clps711x/time.c @@ -58,7 +58,7 @@ p720t_timer_interrupt(int irq, void *dev_id) static struct irqaction clps711x_timer_irq = { .name = "CLPS711x Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = p720t_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-clps7500/core.c b/trunk/arch/arm/mach-clps7500/core.c index 4dde34f25e63..231b90004736 100644 --- a/trunk/arch/arm/mach-clps7500/core.c +++ b/trunk/arch/arm/mach-clps7500/core.c @@ -316,7 +316,7 @@ clps7500_timer_interrupt(int irq, void *dev_id) static struct irqaction clps7500_timer_irq = { .name = "CLPS7500 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = clps7500_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-ebsa110/core.c b/trunk/arch/arm/mach-ebsa110/core.c index 8c1b5690dfe8..8459431cfd71 100644 --- a/trunk/arch/arm/mach-ebsa110/core.c +++ b/trunk/arch/arm/mach-ebsa110/core.c @@ -199,7 +199,7 @@ ebsa110_timer_interrupt(int irq, void *dev_id) static struct irqaction ebsa110_timer_irq = { .name = "EBSA110 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = ebsa110_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-ebsa110/io.c b/trunk/arch/arm/mach-ebsa110/io.c index bbf0d332407e..db38afb2aa88 100644 --- a/trunk/arch/arm/mach-ebsa110/io.c +++ b/trunk/arch/arm/mach-ebsa110/io.c @@ -102,26 +102,6 @@ EXPORT_SYMBOL(__readb); EXPORT_SYMBOL(__readw); EXPORT_SYMBOL(__readl); -void readsw(void __iomem *addr, void *data, int len) -{ - void __iomem *a = __isamem_convert_addr(addr); - - BUG_ON((unsigned long)addr & 1); - - __raw_readsw(a, data, len); -} -EXPORT_SYMBOL(readsw); - -void readsl(void __iomem *addr, void *data, int len) -{ - void __iomem *a = __isamem_convert_addr(addr); - - BUG_ON((unsigned long)addr & 3); - - __raw_readsl(a, data, len); -} -EXPORT_SYMBOL(readsl); - void __writeb(u8 val, void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); @@ -157,26 +137,6 @@ EXPORT_SYMBOL(__writeb); EXPORT_SYMBOL(__writew); EXPORT_SYMBOL(__writel); -void writesw(void __iomem *addr, void *data, int len) -{ - void __iomem *a = __isamem_convert_addr(addr); - - BUG_ON((unsigned long)addr & 1); - - __raw_writesw(a, data, len); -} -EXPORT_SYMBOL(writesw); - -void writesl(void __iomem *addr, void *data, int len) -{ - void __iomem *a = __isamem_convert_addr(addr); - - BUG_ON((unsigned long)addr & 3); - - __raw_writesl(a, data, len); -} -EXPORT_SYMBOL(writesl); - #define SUPERIO_PORT(p) \ (((p) >> 3) == (0x3f8 >> 3) || \ ((p) >> 3) == (0x2f8 >> 3) || \ diff --git a/trunk/arch/arm/mach-ep93xx/clock.c b/trunk/arch/arm/mach-ep93xx/clock.c index 9d7515c36bff..f174d1a3b11c 100644 --- a/trunk/arch/arm/mach-ep93xx/clock.c +++ b/trunk/arch/arm/mach-ep93xx/clock.c @@ -27,10 +27,6 @@ struct clk { u32 enable_mask; }; -static struct clk clk_uart = { - .name = "UARTCLK", - .rate = 14745600, -}; static struct clk clk_pll1 = { .name = "pll1", }; @@ -54,7 +50,6 @@ static struct clk clk_usb_host = { static struct clk *clocks[] = { - &clk_uart, &clk_pll1, &clk_f, &clk_h, diff --git a/trunk/arch/arm/mach-ep93xx/core.c b/trunk/arch/arm/mach-ep93xx/core.c index 851cc7158ca3..829aed696d98 100644 --- a/trunk/arch/arm/mach-ep93xx/core.c +++ b/trunk/arch/arm/mach-ep93xx/core.c @@ -116,7 +116,7 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id) static struct irqaction ep93xx_timer_irq = { .name = "ep93xx timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = ep93xx_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-footbridge/dc21285-timer.c b/trunk/arch/arm/mach-footbridge/dc21285-timer.c index 3a63941d43be..fa6be870c6c2 100644 --- a/trunk/arch/arm/mach-footbridge/dc21285-timer.c +++ b/trunk/arch/arm/mach-footbridge/dc21285-timer.c @@ -44,7 +44,7 @@ timer1_interrupt(int irq, void *dev_id) static struct irqaction footbridge_timer_irq = { .name = "Timer1 timer tick", .handler = timer1_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, }; /* diff --git a/trunk/arch/arm/mach-footbridge/dc21285.c b/trunk/arch/arm/mach-footbridge/dc21285.c index d0dc51e81338..1463330ed8ee 100644 --- a/trunk/arch/arm/mach-footbridge/dc21285.c +++ b/trunk/arch/arm/mach-footbridge/dc21285.c @@ -10,6 +10,7 @@ */ #include #include +#include #include #include #include diff --git a/trunk/arch/arm/mach-footbridge/isa-timer.c b/trunk/arch/arm/mach-footbridge/isa-timer.c index d08d64139d00..d884a3954fb4 100644 --- a/trunk/arch/arm/mach-footbridge/isa-timer.c +++ b/trunk/arch/arm/mach-footbridge/isa-timer.c @@ -73,7 +73,7 @@ isa_timer_interrupt(int irq, void *dev_id) static struct irqaction isa_timer_irq = { .name = "ISA timer tick", .handler = isa_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, }; static void __init isa_timer_init(void) diff --git a/trunk/arch/arm/mach-h720x/cpu-h7201.c b/trunk/arch/arm/mach-h720x/cpu-h7201.c index 9107b8e2ad6e..13f76bdb3d9d 100644 --- a/trunk/arch/arm/mach-h720x/cpu-h7201.c +++ b/trunk/arch/arm/mach-h720x/cpu-h7201.c @@ -41,7 +41,7 @@ h7201_timer_interrupt(int irq, void *dev_id) static struct irqaction h7201_timer_irq = { .name = "h7201 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = h7201_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-h720x/cpu-h7202.c b/trunk/arch/arm/mach-h720x/cpu-h7202.c index 82e420d6fd19..703870f30adf 100644 --- a/trunk/arch/arm/mach-h720x/cpu-h7202.c +++ b/trunk/arch/arm/mach-h720x/cpu-h7202.c @@ -170,7 +170,7 @@ static struct irq_chip h7202_timerx_chip = { static struct irqaction h7202_timer_irq = { .name = "h7202 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = h7202_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-imx/time.c b/trunk/arch/arm/mach-imx/time.c index 6960a9d04217..2703a730baf7 100644 --- a/trunk/arch/arm/mach-imx/time.c +++ b/trunk/arch/arm/mach-imx/time.c @@ -56,7 +56,7 @@ imx_timer_interrupt(int irq, void *dev_id) static struct irqaction imx_timer_irq = { .name = "i.MX Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = imx_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-integrator/core.c b/trunk/arch/arm/mach-integrator/core.c index 897c21c2fb5b..8d880cb9ba39 100644 --- a/trunk/arch/arm/mach-integrator/core.c +++ b/trunk/arch/arm/mach-integrator/core.c @@ -282,7 +282,7 @@ integrator_timer_interrupt(int irq, void *dev_id) static struct irqaction integrator_timer_irq = { .name = "Integrator Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = integrator_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-integrator/pci.c b/trunk/arch/arm/mach-integrator/pci.c index af7d3ff013ec..394ec9261c4e 100644 --- a/trunk/arch/arm/mach-integrator/pci.c +++ b/trunk/arch/arm/mach-integrator/pci.c @@ -23,6 +23,7 @@ */ #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-integrator/pci_v3.c b/trunk/arch/arm/mach-integrator/pci_v3.c index af9ebccac7c1..fb8c6d97b22b 100644 --- a/trunk/arch/arm/mach-integrator/pci_v3.c +++ b/trunk/arch/arm/mach-integrator/pci_v3.c @@ -22,6 +22,7 @@ */ #include #include +#include #include #include #include diff --git a/trunk/arch/arm/mach-iop13xx/Makefile b/trunk/arch/arm/mach-iop13xx/Makefile index da1609dc0dee..4185e0586c33 100644 --- a/trunk/arch/arm/mach-iop13xx/Makefile +++ b/trunk/arch/arm/mach-iop13xx/Makefile @@ -7,6 +7,5 @@ obj-$(CONFIG_ARCH_IOP13XX) += setup.o obj-$(CONFIG_ARCH_IOP13XX) += irq.o obj-$(CONFIG_ARCH_IOP13XX) += pci.o obj-$(CONFIG_ARCH_IOP13XX) += io.o -obj-$(CONFIG_ARCH_IOP13XX) += tpmi.o obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o diff --git a/trunk/arch/arm/mach-iop13xx/io.c b/trunk/arch/arm/mach-iop13xx/io.c index 5b22fdeca52c..e79a1b62600f 100644 --- a/trunk/arch/arm/mach-iop13xx/io.c +++ b/trunk/arch/arm/mach-iop13xx/io.c @@ -41,7 +41,7 @@ void * __iomem __iop13xx_io(unsigned long io_addr) EXPORT_SYMBOL(__iop13xx_io); void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, - unsigned int mtype) + unsigned long flags) { void __iomem * retval; @@ -61,9 +61,9 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, (cookie - IOP13XX_PCIE_LOWER_MEM_RA)); break; case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA: - retval = __arm_ioremap(IOP13XX_PBI_LOWER_MEM_PA + - (cookie - IOP13XX_PBI_LOWER_MEM_RA), - size, mtype); + retval = __ioremap(IOP13XX_PBI_LOWER_MEM_PA + + (cookie - IOP13XX_PBI_LOWER_MEM_RA), + size, flags); break; case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA: retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie); @@ -75,7 +75,7 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie); break; default: - retval = __arm_ioremap(cookie, size, mtype); + retval = __ioremap(cookie, size, flags); } return retval; diff --git a/trunk/arch/arm/mach-iop13xx/iq81340mc.c b/trunk/arch/arm/mach-iop13xx/iq81340mc.c index 268a8d84999c..a519d707571c 100644 --- a/trunk/arch/arm/mach-iop13xx/iq81340mc.c +++ b/trunk/arch/arm/mach-iop13xx/iq81340mc.c @@ -75,14 +75,11 @@ static void __init iq81340mc_init(void) { iop13xx_platform_init(); iq81340mc_pci_init(); - iop13xx_add_tpmi_devices(); } static void __init iq81340mc_timer_init(void) { - unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio(); - printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq); - iop_init_time(bus_freq); + iop_init_time(400000000); } static struct sys_timer iq81340mc_timer = { diff --git a/trunk/arch/arm/mach-iop13xx/iq81340sc.c b/trunk/arch/arm/mach-iop13xx/iq81340sc.c index a51ffd2683e5..0e71fbcabe00 100644 --- a/trunk/arch/arm/mach-iop13xx/iq81340sc.c +++ b/trunk/arch/arm/mach-iop13xx/iq81340sc.c @@ -77,14 +77,11 @@ static void __init iq81340sc_init(void) { iop13xx_platform_init(); iq81340sc_pci_init(); - iop13xx_add_tpmi_devices(); } static void __init iq81340sc_timer_init(void) { - unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio(); - printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq); - iop_init_time(bus_freq); + iop_init_time(400000000); } static struct sys_timer iq81340sc_timer = { diff --git a/trunk/arch/arm/mach-iop13xx/pci.c b/trunk/arch/arm/mach-iop13xx/pci.c index d1d0d32ca77c..89ec70ea3187 100644 --- a/trunk/arch/arm/mach-iop13xx/pci.c +++ b/trunk/arch/arm/mach-iop13xx/pci.c @@ -88,9 +88,9 @@ void iop13xx_map_pci_memory(void) if (end) { iop13xx_atux_mem_base = - (u32) __arm_ioremap_pfn( + (u32) __ioremap_pfn( __phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA) - , 0, iop13xx_atux_mem_size, MT_DEVICE); + , 0, iop13xx_atux_mem_size, 0); if (!iop13xx_atux_mem_base) { printk("%s: atux allocation " "failed\n", __FUNCTION__); @@ -114,9 +114,9 @@ void iop13xx_map_pci_memory(void) if (end) { iop13xx_atue_mem_base = - (u32) __arm_ioremap_pfn( + (u32) __ioremap_pfn( __phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA) - , 0, iop13xx_atue_mem_size, MT_DEVICE); + , 0, iop13xx_atue_mem_size, 0); if (!iop13xx_atue_mem_base) { printk("%s: atue allocation " "failed\n", __FUNCTION__); @@ -1023,7 +1023,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) << IOP13XX_ATUX_PCIXSR_FUNC_NUM; __raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR); - res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET; + res[0].start = IOP13XX_PCIX_LOWER_IO_PA; res[0].end = IOP13XX_PCIX_UPPER_IO_PA; res[0].name = "IQ81340 ATUX PCI I/O Space"; res[0].flags = IORESOURCE_IO; @@ -1033,7 +1033,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) res[1].name = "IQ81340 ATUX PCI Memory Space"; res[1].flags = IORESOURCE_MEM; sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET; - sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA; + sys->io_offset = IOP13XX_PCIX_IO_OFFSET; break; case IOP13XX_INIT_ATU_ATUE: /* Note: the function number field in the PCSR is ro */ @@ -1044,7 +1044,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) __raw_writel(pcsr, IOP13XX_ATUE_PCSR); - res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET; + res[0].start = IOP13XX_PCIE_LOWER_IO_PA; res[0].end = IOP13XX_PCIE_UPPER_IO_PA; res[0].name = "IQ81340 ATUE PCI I/O Space"; res[0].flags = IORESOURCE_IO; @@ -1054,7 +1054,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) res[1].name = "IQ81340 ATUE PCI Memory Space"; res[1].flags = IORESOURCE_MEM; sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET; - sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA; + sys->io_offset = IOP13XX_PCIE_IO_OFFSET; sys->map_irq = iop13xx_pcie_map_irq; break; default: diff --git a/trunk/arch/arm/mach-iop13xx/setup.c b/trunk/arch/arm/mach-iop13xx/setup.c index bc4871553f6a..9a46bcd5f18e 100644 --- a/trunk/arch/arm/mach-iop13xx/setup.c +++ b/trunk/arch/arm/mach-iop13xx/setup.c @@ -258,11 +258,15 @@ void __init iop13xx_platform_init(void) if (init_uart == IOP13XX_INIT_UART_DEFAULT) { switch (iop13xx_dev_id()) { - /* enable both uarts on iop341 */ + /* enable both uarts on iop341 and iop342 */ case 0x3380: case 0x3384: case 0x3388: case 0x338c: + case 0x3382: + case 0x3386: + case 0x338a: + case 0x338e: init_uart |= IOP13XX_INIT_UART_0; init_uart |= IOP13XX_INIT_UART_1; break; diff --git a/trunk/arch/arm/mach-iop13xx/tpmi.c b/trunk/arch/arm/mach-iop13xx/tpmi.c deleted file mode 100644 index d3dc278213da..000000000000 --- a/trunk/arch/arm/mach-iop13xx/tpmi.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * iop13xx tpmi device resources - * Copyright (c) 2005-2006, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */ -#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12)) -#define IOP13XX_TPMI_MEM(dev) IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13)) -#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10)) -#define IOP13XX_TPMI_MMR_SIZE (SZ_4K - 1) -#define IOP13XX_TPMI_MEM_SIZE (255) -#define IOP13XX_TPMI_MEM_CTRL (SZ_1K - 1) -#define IOP13XX_TPMI_RESOURCE_MMR 0 -#define IOP13XX_TPMI_RESOURCE_MEM 1 -#define IOP13XX_TPMI_RESOURCE_CTRL 2 -#define IOP13XX_TPMI_RESOURCE_IRQ 3 - -static struct resource iop13xx_tpmi_0_resources[] = { - [IOP13XX_TPMI_RESOURCE_MMR] = { - .start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */ - .end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_MEM] = { - .start = IOP13XX_TPMI_MEM(0), - .end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_CTRL] = { - .start = IOP13XX_TPMI_CTRL(0), - .end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_IRQ] = { - .start = IRQ_IOP13XX_TPMI0_OUT, - .end = IRQ_IOP13XX_TPMI0_OUT, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop13xx_tpmi_1_resources[] = { - [IOP13XX_TPMI_RESOURCE_MMR] = { - .start = IOP13XX_TPMI_MMR(1), - .end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_MEM] = { - .start = IOP13XX_TPMI_MEM(1), - .end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_CTRL] = { - .start = IOP13XX_TPMI_CTRL(1), - .end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_IRQ] = { - .start = IRQ_IOP13XX_TPMI1_OUT, - .end = IRQ_IOP13XX_TPMI1_OUT, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop13xx_tpmi_2_resources[] = { - [IOP13XX_TPMI_RESOURCE_MMR] = { - .start = IOP13XX_TPMI_MMR(2), - .end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_MEM] = { - .start = IOP13XX_TPMI_MEM(2), - .end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_CTRL] = { - .start = IOP13XX_TPMI_CTRL(2), - .end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_IRQ] = { - .start = IRQ_IOP13XX_TPMI2_OUT, - .end = IRQ_IOP13XX_TPMI2_OUT, - .flags = IORESOURCE_IRQ - } -}; - -static struct resource iop13xx_tpmi_3_resources[] = { - [IOP13XX_TPMI_RESOURCE_MMR] = { - .start = IOP13XX_TPMI_MMR(3), - .end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_MEM] = { - .start = IOP13XX_TPMI_MEM(3), - .end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_CTRL] = { - .start = IOP13XX_TPMI_CTRL(3), - .end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL, - .flags = IORESOURCE_MEM, - }, - [IOP13XX_TPMI_RESOURCE_IRQ] = { - .start = IRQ_IOP13XX_TPMI3_OUT, - .end = IRQ_IOP13XX_TPMI3_OUT, - .flags = IORESOURCE_IRQ - } -}; - -u64 iop13xx_tpmi_mask = DMA_64BIT_MASK; -static struct platform_device iop13xx_tpmi_0_device = { - .name = "iop-tpmi", - .id = 0, - .num_resources = 4, - .resource = iop13xx_tpmi_0_resources, - .dev = { - .dma_mask = &iop13xx_tpmi_mask, - .coherent_dma_mask = DMA_64BIT_MASK, - }, -}; - -static struct platform_device iop13xx_tpmi_1_device = { - .name = "iop-tpmi", - .id = 1, - .num_resources = 4, - .resource = iop13xx_tpmi_1_resources, - .dev = { - .dma_mask = &iop13xx_tpmi_mask, - .coherent_dma_mask = DMA_64BIT_MASK, - }, -}; - -static struct platform_device iop13xx_tpmi_2_device = { - .name = "iop-tpmi", - .id = 2, - .num_resources = 4, - .resource = iop13xx_tpmi_2_resources, - .dev = { - .dma_mask = &iop13xx_tpmi_mask, - .coherent_dma_mask = DMA_64BIT_MASK, - }, -}; - -static struct platform_device iop13xx_tpmi_3_device = { - .name = "iop-tpmi", - .id = 3, - .num_resources = 4, - .resource = iop13xx_tpmi_3_resources, - .dev = { - .dma_mask = &iop13xx_tpmi_mask, - .coherent_dma_mask = DMA_64BIT_MASK, - }, -}; - -__init void iop13xx_add_tpmi_devices(void) -{ - unsigned short device_id; - - /* tpmi's not present on iop341 or iop342 */ - if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) - /* ATUE must be present */ - device_id = __raw_readw(IOP13XX_ATUE_DID); - else - /* ATUX must be present */ - device_id = __raw_readw(IOP13XX_ATUX_DID); - - switch (device_id) { - /* iop34[1|2] 0-tpmi */ - case 0x3380: - case 0x3384: - case 0x3388: - case 0x338c: - case 0x3382: - case 0x3386: - case 0x338a: - case 0x338e: - return; - /* iop348 1-tpmi */ - case 0x3310: - case 0x3312: - case 0x3314: - case 0x3318: - case 0x331a: - case 0x331c: - case 0x33c0: - case 0x33c2: - case 0x33c4: - case 0x33c8: - case 0x33ca: - case 0x33cc: - case 0x33b0: - case 0x33b2: - case 0x33b4: - case 0x33b8: - case 0x33ba: - case 0x33bc: - case 0x3320: - case 0x3322: - case 0x3324: - case 0x3328: - case 0x332a: - case 0x332c: - platform_device_register(&iop13xx_tpmi_0_device); - return; - default: - platform_device_register(&iop13xx_tpmi_0_device); - platform_device_register(&iop13xx_tpmi_1_device); - platform_device_register(&iop13xx_tpmi_2_device); - platform_device_register(&iop13xx_tpmi_3_device); - return; - } -} diff --git a/trunk/arch/arm/mach-iop32x/Kconfig b/trunk/arch/arm/mach-iop32x/Kconfig index 9bb02b6d7ae1..9dd49cff21ff 100644 --- a/trunk/arch/arm/mach-iop32x/Kconfig +++ b/trunk/arch/arm/mach-iop32x/Kconfig @@ -34,14 +34,6 @@ config MACH_N2100 Say Y here if you want to run your kernel on the Thecus n2100 NAS appliance. -config IOP3XX_ATU - bool "Enable the PCI Controller" - default y - help - Say Y here if you want the IOP to initialize its PCI Controller. - Say N if the IOP is an add in card, the host system owns the PCI - bus in this case. - endmenu endif diff --git a/trunk/arch/arm/mach-iop32x/iq31244.c b/trunk/arch/arm/mach-iop32x/iq31244.c index 7b21c6e13e59..60e74309a458 100644 --- a/trunk/arch/arm/mach-iop32x/iq31244.c +++ b/trunk/arch/arm/mach-iop32x/iq31244.c @@ -178,10 +178,9 @@ static struct hw_pci iq31244_pci __initdata = { static int __init iq31244_pci_init(void) { - if (is_ep80219()) { - if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) - pci_common_init(&ep80219_pci); - } else if (machine_is_iq31244()) { + if (is_ep80219()) + pci_common_init(&ep80219_pci); + else if (machine_is_iq31244()) { if (is_80219()) { printk("note: iq31244 board type has been selected\n"); printk("note: to select ep80219 operation:\n"); @@ -190,9 +189,7 @@ static int __init iq31244_pci_init(void) printk("\t2/ update boot loader to pass" " the ep80219 id: %d\n", MACH_TYPE_EP80219); } - - if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) - pci_common_init(&iq31244_pci); + pci_common_init(&iq31244_pci); } return 0; diff --git a/trunk/arch/arm/mach-iop32x/iq80321.c b/trunk/arch/arm/mach-iop32x/iq80321.c index bc25fb91e7b9..361c70c0f64c 100644 --- a/trunk/arch/arm/mach-iop32x/iq80321.c +++ b/trunk/arch/arm/mach-iop32x/iq80321.c @@ -113,8 +113,7 @@ static struct hw_pci iq80321_pci __initdata = { static int __init iq80321_pci_init(void) { - if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) && - machine_is_iq80321()) + if (machine_is_iq80321()) pci_common_init(&iq80321_pci); return 0; diff --git a/trunk/arch/arm/mach-iop33x/Kconfig b/trunk/arch/arm/mach-iop33x/Kconfig index 45598e096898..9aa016bb18f9 100644 --- a/trunk/arch/arm/mach-iop33x/Kconfig +++ b/trunk/arch/arm/mach-iop33x/Kconfig @@ -16,14 +16,6 @@ config MACH_IQ80332 Say Y here if you want to run your kernel on the Intel IQ80332 evaluation kit for the IOP332 chipset. -config IOP3XX_ATU - bool "Enable the PCI Controller" - default y - help - Say Y here if you want the IOP to initialize its PCI Controller. - Say N if the IOP is an add in card, the host system owns the PCI - bus in this case. - endmenu endif diff --git a/trunk/arch/arm/mach-iop33x/iq80331.c b/trunk/arch/arm/mach-iop33x/iq80331.c index 376c932830be..1a9e36138d80 100644 --- a/trunk/arch/arm/mach-iop33x/iq80331.c +++ b/trunk/arch/arm/mach-iop33x/iq80331.c @@ -96,8 +96,7 @@ static struct hw_pci iq80331_pci __initdata = { static int __init iq80331_pci_init(void) { - if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) && - machine_is_iq80331()) + if (machine_is_iq80331()) pci_common_init(&iq80331_pci); return 0; diff --git a/trunk/arch/arm/mach-iop33x/iq80332.c b/trunk/arch/arm/mach-iop33x/iq80332.c index 58c81496c6f6..96d6f0f3cd21 100644 --- a/trunk/arch/arm/mach-iop33x/iq80332.c +++ b/trunk/arch/arm/mach-iop33x/iq80332.c @@ -96,8 +96,7 @@ static struct hw_pci iq80332_pci __initdata = { static int __init iq80332_pci_init(void) { - if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) && - machine_is_iq80332()) + if (machine_is_iq80332()) pci_common_init(&iq80332_pci); return 0; diff --git a/trunk/arch/arm/mach-ixp2000/core.c b/trunk/arch/arm/mach-ixp2000/core.c index cb6ad211887a..27b7480f4afe 100644 --- a/trunk/arch/arm/mach-ixp2000/core.c +++ b/trunk/arch/arm/mach-ixp2000/core.c @@ -84,59 +84,59 @@ static struct map_desc ixp2000_io_desc[] __initdata = { .virtual = IXP2000_CAP_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), .length = IXP2000_CAP_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_INTCTL_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), .length = IXP2000_INTCTL_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_PCI_CREG_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), .length = IXP2000_PCI_CREG_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_PCI_CSR_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), .length = IXP2000_PCI_CSR_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_MSF_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), .length = IXP2000_MSF_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_SCRATCH_RING_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE), .length = IXP2000_SCRATCH_RING_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_SRAM0_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE), .length = IXP2000_SRAM0_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_PCI_IO_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), .length = IXP2000_PCI_IO_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_PCI_CFG0_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), .length = IXP2000_PCI_CFG0_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = IXP2000_PCI_CFG1_VIRT_BASE, .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), .length = IXP2000_PCI_CFG1_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, } }; void __init ixp2000_map_io(void) { /* - * On IXP2400 CPUs we need to use MT_DEVICE_IXP2000 so that + * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that * XCB=101 (to avoid triggering erratum #66), and given that * this mode speeds up I/O accesses and we have write buffer * flushes in the right places anyway, it doesn't hurt to use @@ -224,7 +224,7 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id) static struct irqaction ixp2000_timer_irq = { .name = "IXP2000 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = ixp2000_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-ixp2000/enp2611.c b/trunk/arch/arm/mach-ixp2000/enp2611.c index 500e997ba7a4..ac29298c5d3f 100644 --- a/trunk/arch/arm/mach-ixp2000/enp2611.c +++ b/trunk/arch/arm/mach-ixp2000/enp2611.c @@ -70,17 +70,17 @@ static struct map_desc enp2611_io_desc[] __initdata = { .virtual = ENP2611_CALEB_VIRT_BASE, .pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE), .length = ENP2611_CALEB_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = ENP2611_PM3386_0_VIRT_BASE, .pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE), .length = ENP2611_PM3386_0_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, }, { .virtual = ENP2611_PM3386_1_VIRT_BASE, .pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE), .length = ENP2611_PM3386_1_SIZE, - .type = MT_DEVICE_IXP2000, + .type = MT_IXP2000_DEVICE, } }; diff --git a/trunk/arch/arm/mach-ixp23xx/core.c b/trunk/arch/arm/mach-ixp23xx/core.c index b644bbab7d0a..ce6ad635a00c 100644 --- a/trunk/arch/arm/mach-ixp23xx/core.c +++ b/trunk/arch/arm/mach-ixp23xx/core.c @@ -363,7 +363,7 @@ ixp23xx_timer_interrupt(int irq, void *dev_id) static struct irqaction ixp23xx_timer_irq = { .name = "IXP23xx Timer Tick", .handler = ixp23xx_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, }; void __init ixp23xx_init_timer(void) diff --git a/trunk/arch/arm/mach-ixp4xx/Kconfig b/trunk/arch/arm/mach-ixp4xx/Kconfig index 9715ef506c24..8a339cdfe222 100644 --- a/trunk/arch/arm/mach-ixp4xx/Kconfig +++ b/trunk/arch/arm/mach-ixp4xx/Kconfig @@ -62,12 +62,6 @@ config MACH_IXDP465 IXDP465 Development Platform (Also known as BMP). For more information on this platform, see . -config MACH_KIXRP435 - bool "KIXRP435" - help - Say 'Y' here if you want your kernel to support Intel's - KIXRP435 Reference Platform. - For more information on this platform, see . # # IXCDP1100 is the exact same HW as IXDP425, but with a different machine @@ -95,21 +89,12 @@ config MACH_NAS100D NAS 100d device. For more information on this platform, see http://www.nslu2-linux.org/wiki/NAS100d/HomePage -config MACH_DSMG600 - bool - prompt "D-Link DSM-G600 RevA" - select PCI - help - Say 'Y' here if you want your kernel to support D-Link's - DSM-G600 RevA device. For more information on this platform, - see http://www.nslu2-linux.org/wiki/DSMG600/HomePage - # # Avila and IXDP share the same source for now. Will change in future # config ARCH_IXDP4XX bool - depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435 + depends on ARCH_IXDP425 || MACH_IXDP465 default y # @@ -120,11 +105,6 @@ config CPU_IXP46X depends on MACH_IXDP465 default y -config CPU_IXP43X - bool - depends on MACH_KIXRP435 - default y - config MACH_GTWX5715 bool "Gemtek WX5715 (Linksys WRV54G)" depends on ARCH_IXP4XX diff --git a/trunk/arch/arm/mach-ixp4xx/Makefile b/trunk/arch/arm/mach-ixp4xx/Makefile index 3b87c47e06cf..746e297284ed 100644 --- a/trunk/arch/arm/mach-ixp4xx/Makefile +++ b/trunk/arch/arm/mach-ixp4xx/Makefile @@ -12,7 +12,6 @@ obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o -obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o obj-y += common.o @@ -23,6 +22,5 @@ obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o -obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o diff --git a/trunk/arch/arm/mach-ixp4xx/common-pci.c b/trunk/arch/arm/mach-ixp4xx/common-pci.c index bf04121d1a31..9562177b5fe1 100644 --- a/trunk/arch/arm/mach-ixp4xx/common-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/common-pci.c @@ -374,7 +374,7 @@ void __init ixp4xx_pci_preinit(void) * Determine which PCI read method to use. * Rev 0 IXP425 requires workaround. */ - if (!(processor_id & 0xf) && cpu_is_ixp42x()) { + if (!(processor_id & 0xf) && !cpu_is_ixp46x()) { printk("PCI: IXP42x A0 silicon detected - " "PCI Non-Prefetch Workaround Enabled\n"); ixp4xx_pci_read = ixp4xx_pci_read_errata; @@ -480,7 +480,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) res[0].flags = IORESOURCE_IO; res[1].name = "PCI Memory Space"; - res[1].start = PCIBIOS_MIN_MEM; + res[1].start = 0x48000000; #ifndef CONFIG_IXP4XX_INDIRECT_PCI res[1].end = 0x4bffffff; #else diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index 64685da1462d..45068c3d8dcc 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -42,8 +41,6 @@ #include static int __init ixp4xx_clocksource_init(void); -static int __init ixp4xx_clockevent_init(void); -static struct clock_event_device clockevent_ixp4xx; /************************************************************************* * IXP4xx chipset I/O mapping @@ -105,29 +102,6 @@ static signed char irq2gpio[32] = { 7, 8, 9, 10, 11, 12, -1, -1, }; -int gpio_to_irq(int gpio) -{ - int irq; - - for (irq = 0; irq < 32; irq++) { - if (irq2gpio[irq] == gpio) - return irq; - } - return -EINVAL; -} -EXPORT_SYMBOL(gpio_to_irq); - -int irq_to_gpio(int irq) -{ - int gpio = (irq < 32) ? irq2gpio[irq] : -EINVAL; - - if (gpio == -1) - return -EINVAL; - - return gpio; -} -EXPORT_SYMBOL(irq_to_gpio); - static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) { int line = irq2gpio[irq]; @@ -195,7 +169,7 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) static void ixp4xx_irq_mask(unsigned int irq) { - if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32) + if (cpu_is_ixp46x() && irq >= 32) *IXP4XX_ICMR2 &= ~(1 << (irq - 32)); else *IXP4XX_ICMR &= ~(1 << irq); @@ -218,7 +192,7 @@ static void ixp4xx_irq_unmask(unsigned int irq) if (!(ixp4xx_irq_edge & (1 << irq))) ixp4xx_irq_ack(irq); - if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32) + if (cpu_is_ixp46x() && irq >= 32) *IXP4XX_ICMR2 |= (1 << (irq - 32)); else *IXP4XX_ICMR |= (1 << irq); @@ -242,7 +216,7 @@ void __init ixp4xx_init_irq(void) /* Disable all interrupt */ *IXP4XX_ICMR = 0x0; - if (cpu_is_ixp46x() || cpu_is_ixp43x()) { + if (cpu_is_ixp46x()) { /* Route upper 32 sources to IRQ instead of FIQ */ *IXP4XX_ICLR2 = 0x00; @@ -265,40 +239,52 @@ void __init ixp4xx_init_irq(void) * counter as a source of real clock ticks to account for missed jiffies. *************************************************************************/ +static unsigned volatile last_jiffy_time; + +#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) + static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id) { - struct clock_event_device *evt = &clockevent_ixp4xx; + write_seqlock(&xtime_lock); /* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; - evt->event_handler(evt); + /* + * Catch up with the real idea of time + */ + while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) { + timer_tick(); + last_jiffy_time += LATCH; + } + + write_sequnlock(&xtime_lock); return IRQ_HANDLED; } static struct irqaction ixp4xx_timer_irq = { - .name = "timer1", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .name = "IXP4xx Timer Tick", + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = ixp4xx_timer_interrupt, }; static void __init ixp4xx_timer_init(void) { - /* Reset/disable counter */ - *IXP4XX_OSRT1 = 0; - /* Clear Pending Interrupt by writing '1' to it */ *IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND; + /* Setup the Timer counter value */ + *IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE; + /* Reset time-stamp counter */ *IXP4XX_OSTS = 0; + last_jiffy_time = 0; /* Connect the interrupt handler and enable the interrupt */ setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); ixp4xx_clocksource_init(); - ixp4xx_clockevent_init(); } struct sys_timer ixp4xx_timer = { @@ -398,9 +384,6 @@ void __init ixp4xx_sys_init(void) ixp4xx_exp_bus_size >> 20); } -/* - * clocksource - */ cycle_t ixp4xx_get_cycles(void) { return *IXP4XX_OSTS; @@ -425,64 +408,3 @@ static int __init ixp4xx_clocksource_init(void) return 0; } - -/* - * clockevents - */ -static int ixp4xx_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK; - - *IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts; - - return 0; -} - -static void ixp4xx_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - unsigned long opts, osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK; - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - osrt = LATCH & ~IXP4XX_OST_RELOAD_MASK; - opts = IXP4XX_OST_ENABLE; - break; - case CLOCK_EVT_MODE_ONESHOT: - /* period set by 'set next_event' */ - osrt = 0; - opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT; - break; - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - default: - osrt = opts = 0; - break; - } - - *IXP4XX_OSRT1 = osrt | opts; -} - -static struct clock_event_device clockevent_ixp4xx = { - .name = "ixp4xx timer1", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .rating = 200, - .shift = 24, - .set_mode = ixp4xx_set_mode, - .set_next_event = ixp4xx_set_next_event, -}; - -static int __init ixp4xx_clockevent_init(void) -{ - clockevent_ixp4xx.mult = div_sc(FREQ, NSEC_PER_SEC, - clockevent_ixp4xx.shift); - clockevent_ixp4xx.max_delta_ns = - clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx); - clockevent_ixp4xx.min_delta_ns = - clockevent_delta2ns(0xf, &clockevent_ixp4xx); - clockevent_ixp4xx.cpumask = cpumask_of_cpu(0); - - clockevents_register_device(&clockevent_ixp4xx); - return 0; -} diff --git a/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c b/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c deleted file mode 100644 index 9db7e1f42011..000000000000 --- a/trunk/arch/arm/mach-ixp4xx/dsmg600-pci.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * DSM-G600 board-level PCI initialization - * - * Copyright (C) 2006 Tower Technologies - * Author: Alessandro Zummo - * - * based on ixdp425-pci.c: - * Copyright (C) 2002 Intel Corporation. - * Copyright (C) 2003-2004 MontaVista Software, Inc. - * - * Maintainer: http://www.nslu2-linux.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include - -#include -#include - -void __init dsmg600_pci_preinit(void) -{ - set_irq_type(IRQ_DSMG600_PCI_INTA, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTB, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTC, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTD, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTE, IRQT_LOW); - set_irq_type(IRQ_DSMG600_PCI_INTF, IRQT_LOW); - - ixp4xx_pci_preinit(); -} - -static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - static int pci_irq_table[DSMG600_PCI_MAX_DEV][DSMG600_PCI_IRQ_LINES] = - { - { IRQ_DSMG600_PCI_INTE, -1, -1 }, - { IRQ_DSMG600_PCI_INTA, -1, -1 }, - { IRQ_DSMG600_PCI_INTB, IRQ_DSMG600_PCI_INTC, IRQ_DSMG600_PCI_INTD }, - { IRQ_DSMG600_PCI_INTF, -1, -1 }, - }; - - int irq = -1; - - if (slot >= 1 && slot <= DSMG600_PCI_MAX_DEV && - pin >= 1 && pin <= DSMG600_PCI_IRQ_LINES) - irq = pci_irq_table[slot-1][pin-1]; - - return irq; -} - -struct hw_pci __initdata dsmg600_pci = { - .nr_controllers = 1, - .preinit = dsmg600_pci_preinit, - .swizzle = pci_std_swizzle, - .setup = ixp4xx_setup, - .scan = ixp4xx_scan_bus, - .map_irq = dsmg600_map_irq, -}; - -int __init dsmg600_pci_init(void) -{ - if (machine_is_dsmg600()) - pci_common_init(&dsmg600_pci); - - return 0; -} - -subsys_initcall(dsmg600_pci_init); diff --git a/trunk/arch/arm/mach-ixp4xx/dsmg600-power.c b/trunk/arch/arm/mach-ixp4xx/dsmg600-power.c deleted file mode 100644 index 34717872d076..000000000000 --- a/trunk/arch/arm/mach-ixp4xx/dsmg600-power.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * arch/arm/mach-ixp4xx/dsmg600-power.c - * - * DSM-G600 Power/Reset driver - * Author: Michael Westerhof - * - * Based on nslu2-power.c - * Copyright (C) 2005 Tower Technologies - * Author: Alessandro Zummo - * - * which was based on nslu2-io.c - * Copyright (C) 2004 Karen Spearel - * - * Maintainers: http://www.nslu2-linux.org/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include - -#include - -extern void ctrl_alt_del(void); - -/* This is used to make sure the power-button pusher is serious. The button - * must be held until the value of this counter reaches zero. - */ -static volatile int power_button_countdown; - -/* Must hold the button down for at least this many counts to be processed */ -#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */ - -static void dsmg600_power_handler(unsigned long data); -static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0); - -static void dsmg600_power_handler(unsigned long data) -{ - /* This routine is called twice per second to check the - * state of the power button. - */ - - if (*IXP4XX_GPIO_GPINR & DSMG600_PB_BM) { - - /* IO Pin is 1 (button pushed) */ - if (power_button_countdown == 0) { - /* Signal init to do the ctrlaltdel action, this will bypass - * init if it hasn't started and do a kernel_restart. - */ - ctrl_alt_del(); - - /* Change the state of the power LED to "blink" */ - gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW); - } - power_button_countdown--; - - } else { - power_button_countdown = PBUTTON_HOLDDOWN_COUNT; - } - - mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500)); -} - -static irqreturn_t dsmg600_reset_handler(int irq, void *dev_id) -{ - /* This is the paper-clip reset, it shuts the machine down directly. */ - machine_power_off(); - - return IRQ_HANDLED; -} - -static int __init dsmg600_power_init(void) -{ - if (!(machine_is_dsmg600())) - return 0; - - if (request_irq(DSMG600_RB_IRQ, &dsmg600_reset_handler, - IRQF_DISABLED | IRQF_TRIGGER_LOW, "DSM-G600 reset button", - NULL) < 0) { - - printk(KERN_DEBUG "Reset Button IRQ %d not available\n", - DSMG600_RB_IRQ); - - return -EIO; - } - - /* The power button on the D-Link DSM-G600 is on GPIO 15, but - * it cannot handle interrupts on that GPIO line. So we'll - * have to poll it with a kernel timer. - */ - - /* Make sure that the power button GPIO is set up as an input */ - gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN); - - /* Set the initial value for the power button IRQ handler */ - power_button_countdown = PBUTTON_HOLDDOWN_COUNT; - - mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500)); - - return 0; -} - -static void __exit dsmg600_power_exit(void) -{ - if (!(machine_is_dsmg600())) - return; - - del_timer_sync(&dsmg600_power_timer); - - free_irq(DSMG600_RB_IRQ, NULL); -} - -module_init(dsmg600_power_init); -module_exit(dsmg600_power_exit); - -MODULE_AUTHOR("Michael Westerhof "); -MODULE_DESCRIPTION("DSM-G600 Power/Reset driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/arch/arm/mach-ixp4xx/dsmg600-setup.c b/trunk/arch/arm/mach-ixp4xx/dsmg600-setup.c deleted file mode 100644 index 1caff65e22cc..000000000000 --- a/trunk/arch/arm/mach-ixp4xx/dsmg600-setup.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * DSM-G600 board-setup - * - * Copyright (C) 2006 Tower Technologies - * Author: Alessandro Zummo - * - * based ixdp425-setup.c: - * Copyright (C) 2003-2004 MontaVista Software, Inc. - * - * Author: Alessandro Zummo - * Maintainers: http://www.nslu2-linux.org/ - */ - -#include -#include -#include - -#include -#include -#include - -static struct flash_platform_data dsmg600_flash_data = { - .map_name = "cfi_probe", - .width = 2, -}; - -static struct resource dsmg600_flash_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device dsmg600_flash = { - .name = "IXP4XX-Flash", - .id = 0, - .dev.platform_data = &dsmg600_flash_data, - .num_resources = 1, - .resource = &dsmg600_flash_resource, -}; - -static struct ixp4xx_i2c_pins dsmg600_i2c_gpio_pins = { - .sda_pin = DSMG600_SDA_PIN, - .scl_pin = DSMG600_SCL_PIN, -}; - -static struct platform_device dsmg600_i2c_controller = { - .name = "IXP4XX-I2C", - .id = 0, - .dev.platform_data = &dsmg600_i2c_gpio_pins, -}; - -#ifdef CONFIG_LEDS_CLASS -static struct resource dsmg600_led_resources[] = { - { - .name = "power", - .start = DSMG600_LED_PWR_GPIO, - .end = DSMG600_LED_PWR_GPIO, - .flags = IXP4XX_GPIO_HIGH, - }, - { - .name = "wlan", - .start = DSMG600_LED_WLAN_GPIO, - .end = DSMG600_LED_WLAN_GPIO, - .flags = IXP4XX_GPIO_LOW, - }, -}; - -static struct platform_device dsmg600_leds = { - .name = "IXP4XX-GPIO-LED", - .id = -1, - .num_resources = ARRAY_SIZE(dsmg600_led_resources), - .resource = dsmg600_led_resources, -}; -#endif - -static struct resource dsmg600_uart_resources[] = { - { - .start = IXP4XX_UART1_BASE_PHYS, - .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, - .flags = IORESOURCE_MEM, - }, - { - .start = IXP4XX_UART2_BASE_PHYS, - .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, - .flags = IORESOURCE_MEM, - } -}; - -static struct plat_serial8250_port dsmg600_uart_data[] = { - { - .mapbase = IXP4XX_UART1_BASE_PHYS, - .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, - .irq = IRQ_IXP4XX_UART1, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IXP4XX_UART_XTAL, - }, - { - .mapbase = IXP4XX_UART2_BASE_PHYS, - .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, - .irq = IRQ_IXP4XX_UART2, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IXP4XX_UART_XTAL, - }, - { } -}; - -static struct platform_device dsmg600_uart = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev.platform_data = dsmg600_uart_data, - .num_resources = ARRAY_SIZE(dsmg600_uart_resources), - .resource = dsmg600_uart_resources, -}; - -static struct platform_device *dsmg600_devices[] __initdata = { - &dsmg600_i2c_controller, - &dsmg600_flash, -}; - -static void dsmg600_power_off(void) -{ - /* enable the pwr cntl gpio */ - gpio_line_config(DSMG600_PO_GPIO, IXP4XX_GPIO_OUT); - - /* poweroff */ - gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH); -} - -static void __init dsmg600_init(void) -{ - ixp4xx_sys_init(); - - /* Make sure that GPIO14 and GPIO15 are not used as clocks */ - *IXP4XX_GPIO_GPCLKR = 0; - - dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); - dsmg600_flash_resource.end = - IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; - - pm_power_off = dsmg600_power_off; - - /* The UART is required on the DSM-G600 (Redboot cannot use the - * NIC) -- do it here so that it does *not* get removed if - * platform_add_devices fails! - */ - (void)platform_device_register(&dsmg600_uart); - - platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices)); - -#ifdef CONFIG_LEDS_CLASS - /* We don't care whether or not this works. */ - (void)platform_device_register(&dsmg600_leds); -#endif -} - -static void __init dsmg600_fixup(struct machine_desc *desc, - struct tag *tags, char **cmdline, struct meminfo *mi) -{ - /* The xtal on this machine is non-standard. */ - ixp4xx_timer_freq = DSMG600_FREQ; -} - -MACHINE_START(DSMG600, "D-Link DSM-G600 RevA") - /* Maintainer: www.nslu2-linux.org */ - .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, - .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, - .boot_params = 0x00000100, - .fixup = dsmg600_fixup, - .map_io = ixp4xx_map_io, - .init_irq = ixp4xx_init_irq, - .timer = &ixp4xx_timer, - .init_machine = dsmg600_init, -MACHINE_END diff --git a/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c b/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c index 408796004812..99c1dc8033c8 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c +++ b/trunk/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -66,7 +66,7 @@ struct hw_pci ixdp425_pci __initdata = { int __init ixdp425_pci_init(void) { if (machine_is_ixdp425() || machine_is_ixcdp1100() || - machine_is_ixdp465() || machine_is_kixrp435()) + machine_is_ixdp465()) pci_common_init(&ixdp425_pci); return 0; } diff --git a/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c b/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c index ec4f07950ec6..04b1d56396a0 100644 --- a/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/trunk/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -115,11 +115,6 @@ static void __init ixdp425_init(void) ixdp425_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; - if (cpu_is_ixp43x()) { - ixdp425_uart.num_resources = 1; - ixdp425_uart_data[1].flags = 0; - } - platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices)); } @@ -161,16 +156,3 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") .init_machine = ixdp425_init, MACHINE_END #endif - -#ifdef CONFIG_MACH_KIXRP435 -MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform") - /* Maintainer: MontaVista Software, Inc. */ - .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, - .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, - .map_io = ixp4xx_map_io, - .init_irq = ixp4xx_init_irq, - .timer = &ixp4xx_timer, - .boot_params = 0x0100, - .init_machine = ixdp425_init, -MACHINE_END -#endif diff --git a/trunk/arch/arm/mach-lh7a40x/irq-lh7a400.c b/trunk/arch/arm/mach-lh7a40x/irq-lh7a400.c index 9472bbebd8ab..0b938e8b4d98 100644 --- a/trunk/arch/arm/mach-lh7a40x/irq-lh7a400.c +++ b/trunk/arch/arm/mach-lh7a40x/irq-lh7a400.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-lh7a40x/irq-lh7a404.c b/trunk/arch/arm/mach-lh7a40x/irq-lh7a404.c index 9b28389035e6..5760f8c53e89 100644 --- a/trunk/arch/arm/mach-lh7a40x/irq-lh7a404.c +++ b/trunk/arch/arm/mach-lh7a40x/irq-lh7a404.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/trunk/arch/arm/mach-lh7a40x/irq-lpd7a40x.c index 66e1ed3961ea..15b9577023c9 100644 --- a/trunk/arch/arm/mach-lh7a40x/irq-lpd7a40x.c +++ b/trunk/arch/arm/mach-lh7a40x/irq-lpd7a40x.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-lh7a40x/time.c b/trunk/arch/arm/mach-lh7a40x/time.c index c25316d02537..bef3c4b68d3b 100644 --- a/trunk/arch/arm/mach-lh7a40x/time.c +++ b/trunk/arch/arm/mach-lh7a40x/time.c @@ -53,7 +53,7 @@ lh7a40x_timer_interrupt(int irq, void *dev_id) static struct irqaction lh7a40x_timer_irq = { .name = "LHA740x Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = lh7a40x_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-netx/time.c b/trunk/arch/arm/mach-netx/time.c index 4762e207b0bf..7e132fcccd47 100644 --- a/trunk/arch/arm/mach-netx/time.c +++ b/trunk/arch/arm/mach-netx/time.c @@ -47,7 +47,7 @@ netx_timer_interrupt(int irq, void *dev_id) static struct irqaction netx_timer_irq = { .name = "NetX Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = netx_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-ns9xxx/Kconfig b/trunk/arch/arm/mach-ns9xxx/Kconfig index 8584ed107991..8175ba92a2fa 100644 --- a/trunk/arch/arm/mach-ns9xxx/Kconfig +++ b/trunk/arch/arm/mach-ns9xxx/Kconfig @@ -3,30 +3,19 @@ if ARCH_NS9XXX menu "NS9xxx Implementations" config MACH_CC9P9360DEV - bool "ConnectCore 9P 9360 on an A9M9750 Devboard" + bool "Connect Core 9P 9360 on an A9M9750 Devboard" select PROCESSOR_NS9360 select BOARD_A9M9750DEV help - Say Y here if you are using the Digi ConnectCore 9P 9360 + Say Y here if you are using the Digi Connect Core 9P 9360 on an A9M9750 Development Board. -config MACH_CC9P9360JS - bool "ConnectCore 9P 9360 on a JSCC9P9360 Devboard" - select PROCESSOR_NS9360 - select BOARD_JSCC9P9360 - help - Say Y here if you are using the Digi ConnectCore 9P 9360 - on an JSCC9P9360 Development Board. - config PROCESSOR_NS9360 bool config BOARD_A9M9750DEV bool -config BOARD_JSCC9P9360 - bool - endmenu endif diff --git a/trunk/arch/arm/mach-ns9xxx/Makefile b/trunk/arch/arm/mach-ns9xxx/Makefile index 53213a69f601..91e945f5e16d 100644 --- a/trunk/arch/arm/mach-ns9xxx/Makefile +++ b/trunk/arch/arm/mach-ns9xxx/Makefile @@ -3,4 +3,3 @@ obj-y := irq.o time.o generic.o obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o -obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o diff --git a/trunk/arch/arm/mach-ns9xxx/board-jscc9p9360.c b/trunk/arch/arm/mach-ns9xxx/board-jscc9p9360.c deleted file mode 100644 index 4bd3eec04bfe..000000000000 --- a/trunk/arch/arm/mach-ns9xxx/board-jscc9p9360.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/arm/mach-ns9xxx/board-jscc9p9360.c - * - * Copyright (C) 2006,2007 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include "board-jscc9p9360.h" - -void __init board_jscc9p9360_init_machine(void) -{ - /* TODO: reserve GPIOs for push buttons, etc pp */ -} - diff --git a/trunk/arch/arm/mach-ns9xxx/board-jscc9p9360.h b/trunk/arch/arm/mach-ns9xxx/board-jscc9p9360.h deleted file mode 100644 index 1a81a074df45..000000000000 --- a/trunk/arch/arm/mach-ns9xxx/board-jscc9p9360.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/mach-ns9xxx/board-jscc9p9360.h - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include - -void __init board_jscc9p9360_init_machine(void); diff --git a/trunk/arch/arm/mach-ns9xxx/mach-cc9p9360js.c b/trunk/arch/arm/mach-ns9xxx/mach-cc9p9360js.c deleted file mode 100644 index d09d5fa5620a..000000000000 --- a/trunk/arch/arm/mach-ns9xxx/mach-cc9p9360js.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/arm/mach-ns9xxx/mach-cc9p9360js.c - * - * Copyright (C) 2006 by Digi International Inc. - * All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ -#include -#include - -#include "board-jscc9p9360.h" -#include "generic.h" - -static void __init mach_cc9p9360js_init_machine(void) -{ - ns9xxx_init_machine(); - board_jscc9p9360_init_machine(); -} - -MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard") - .map_io = ns9xxx_map_io, - .init_irq = ns9xxx_init_irq, - .init_machine = mach_cc9p9360js_init_machine, - .timer = &ns9xxx_timer, - .boot_params = 0x100, -MACHINE_END diff --git a/trunk/arch/arm/mach-ns9xxx/time.c b/trunk/arch/arm/mach-ns9xxx/time.c index dd257084441c..eec05f18714a 100644 --- a/trunk/arch/arm/mach-ns9xxx/time.c +++ b/trunk/arch/arm/mach-ns9xxx/time.c @@ -53,7 +53,7 @@ static unsigned long ns9xxx_timer_gettimeoffset(void) static struct irqaction ns9xxx_timer_irq = { .name = "NS9xxx Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = ns9xxx_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-omap1/irq.c b/trunk/arch/arm/mach-omap1/irq.c index 0733078940fa..410d3e78dd0f 100644 --- a/trunk/arch/arm/mach-omap1/irq.c +++ b/trunk/arch/arm/mach-omap1/irq.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-omap1/pm.c b/trunk/arch/arm/mach-omap1/pm.c index 6f4ea4bda5e0..0383ab334270 100644 --- a/trunk/arch/arm/mach-omap1/pm.c +++ b/trunk/arch/arm/mach-omap1/pm.c @@ -72,12 +72,12 @@ static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; static unsigned short enable_dyn_sleep = 1; -static ssize_t omap_pm_sleep_while_idle_show(struct kset *kset, char *buf) +static ssize_t omap_pm_sleep_while_idle_show(struct subsystem * subsys, char *buf) { return sprintf(buf, "%hu\n", enable_dyn_sleep); } -static ssize_t omap_pm_sleep_while_idle_store(struct kset *kset, +static ssize_t omap_pm_sleep_while_idle_store(struct subsystem * subsys, const char * buf, size_t n) { @@ -100,7 +100,7 @@ static struct subsys_attribute sleep_while_idle_attr = { .store = omap_pm_sleep_while_idle_store, }; -extern struct kset power_subsys; +extern struct subsystem power_subsys; static void (*omap_sram_idle)(void) = NULL; static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; diff --git a/trunk/arch/arm/mach-omap1/time.c b/trunk/arch/arm/mach-omap1/time.c index 3705d20c4e5c..1b7e4a506c26 100644 --- a/trunk/arch/arm/mach-omap1/time.c +++ b/trunk/arch/arm/mach-omap1/time.c @@ -39,10 +39,6 @@ #include #include #include -#include -#include -#include -#include #include #include @@ -52,7 +48,13 @@ #include #include +struct sys_timer omap_timer; +/* + * --------------------------------------------------------------------------- + * MPU timer + * --------------------------------------------------------------------------- + */ #define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE #define OMAP_MPU_TIMER_OFFSET 0x100 @@ -86,6 +88,21 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc) return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; } +/* + * MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs + * will break. On P2, the timer count rate is 6.5 MHz after programming PTV + * with 0. This divides the 13MHz input by 2, and is undocumented. + */ +#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE) +/* REVISIT: This ifdef construct should be replaced by a query to clock + * framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz. + */ +#define MPU_TICKS_PER_SEC (13000000 / 2) +#else +#define MPU_TICKS_PER_SEC (12000000 / 2) +#endif + +#define MPU_TIMER_TICK_PERIOD ((MPU_TICKS_PER_SEC / HZ) - 1) typedef struct { u32 cntl; /* CNTL_TIMER, R/W */ @@ -103,164 +120,98 @@ static inline unsigned long omap_mpu_timer_read(int nr) return timer->read_tim; } -static inline void omap_mpu_set_autoreset(int nr) -{ - volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr); - - timer->cntl = timer->cntl | MPU_TIMER_AR; -} - -static inline void omap_mpu_remove_autoreset(int nr) -{ - volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr); - - timer->cntl = timer->cntl & ~MPU_TIMER_AR; -} - -static inline void omap_mpu_timer_start(int nr, unsigned long load_val, - int autoreset) +static inline void omap_mpu_timer_start(int nr, unsigned long load_val) { volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr); - unsigned int timerflags = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_ST); - - if (autoreset) timerflags |= MPU_TIMER_AR; timer->cntl = MPU_TIMER_CLOCK_ENABLE; udelay(1); timer->load_tim = load_val; udelay(1); - timer->cntl = timerflags; -} - -/* - * --------------------------------------------------------------------------- - * MPU timer 1 ... count down to zero, interrupt, reload - * --------------------------------------------------------------------------- - */ -static int omap_mpu_set_next_event(unsigned long cycles, - struct clock_event_device *evt) -{ - omap_mpu_timer_start(0, cycles, 0); - return 0; -} - -static void omap_mpu_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - omap_mpu_set_autoreset(0); - break; - case CLOCK_EVT_MODE_ONESHOT: - omap_mpu_remove_autoreset(0); - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - break; - } + timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST); } -static struct clock_event_device clockevent_mpu_timer1 = { - .name = "mpu_timer1", - .features = CLOCK_EVT_FEAT_PERIODIC, CLOCK_EVT_FEAT_ONESHOT, - .shift = 32, - .set_next_event = omap_mpu_set_next_event, - .set_mode = omap_mpu_set_mode, -}; - -static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id) +unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks) { - struct clock_event_device *evt = &clockevent_mpu_timer1; + unsigned long long nsec; - evt->event_handler(evt); - - return IRQ_HANDLED; + nsec = cycles_2_ns((unsigned long long)nr_ticks); + return (unsigned long)nsec / 1000; } -static struct irqaction omap_mpu_timer1_irq = { - .name = "mpu_timer1", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, - .handler = omap_mpu_timer1_interrupt, -}; +/* + * Last processed system timer interrupt + */ +static unsigned long omap_mpu_timer_last = 0; -static __init void omap_init_mpu_timer(unsigned long rate) +/* + * Returns elapsed usecs since last system timer interrupt + */ +static unsigned long omap_mpu_timer_gettimeoffset(void) { - set_cyc2ns_scale(rate / 1000); - - setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); - omap_mpu_timer_start(0, (rate / HZ) - 1, 1); - - clockevent_mpu_timer1.mult = div_sc(rate, NSEC_PER_SEC, - clockevent_mpu_timer1.shift); - clockevent_mpu_timer1.max_delta_ns = - clockevent_delta2ns(-1, &clockevent_mpu_timer1); - clockevent_mpu_timer1.min_delta_ns = - clockevent_delta2ns(1, &clockevent_mpu_timer1); + unsigned long now = 0 - omap_mpu_timer_read(0); + unsigned long elapsed = now - omap_mpu_timer_last; - clockevent_mpu_timer1.cpumask = cpumask_of_cpu(0); - clockevents_register_device(&clockevent_mpu_timer1); + return omap_mpu_timer_ticks_to_usecs(elapsed); } - /* - * --------------------------------------------------------------------------- - * MPU timer 2 ... free running 32-bit clock source and scheduler clock - * --------------------------------------------------------------------------- + * Elapsed time between interrupts is calculated using timer0. + * Latency during the interrupt is calculated using timer1. + * Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz). */ +static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id) +{ + unsigned long now, latency; -static unsigned long omap_mpu_timer2_overflows; + write_seqlock(&xtime_lock); + now = 0 - omap_mpu_timer_read(0); + latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1); + omap_mpu_timer_last = now - latency; + timer_tick(); + write_sequnlock(&xtime_lock); -static irqreturn_t omap_mpu_timer2_interrupt(int irq, void *dev_id) -{ - omap_mpu_timer2_overflows++; return IRQ_HANDLED; } -static struct irqaction omap_mpu_timer2_irq = { - .name = "mpu_timer2", - .flags = IRQF_DISABLED, - .handler = omap_mpu_timer2_interrupt, +static struct irqaction omap_mpu_timer_irq = { + .name = "mpu timer", + .flags = IRQF_DISABLED | IRQF_TIMER, + .handler = omap_mpu_timer_interrupt, }; -static cycle_t mpu_read(void) +static unsigned long omap_mpu_timer1_overflows; +static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id) { - return ~omap_mpu_timer_read(1); + omap_mpu_timer1_overflows++; + return IRQ_HANDLED; } -static struct clocksource clocksource_mpu = { - .name = "mpu_timer2", - .rating = 300, - .read = mpu_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 24, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, +static struct irqaction omap_mpu_timer1_irq = { + .name = "mpu timer1 overflow", + .flags = IRQF_DISABLED, + .handler = omap_mpu_timer1_interrupt, }; -static void __init omap_init_clocksource(unsigned long rate) +static __init void omap_init_mpu_timer(void) { - static char err[] __initdata = KERN_ERR - "%s: can't register clocksource!\n"; - - clocksource_mpu.mult - = clocksource_khz2mult(rate/1000, clocksource_mpu.shift); - - setup_irq(INT_TIMER2, &omap_mpu_timer2_irq); - omap_mpu_timer_start(1, ~0, 1); - - if (clocksource_register(&clocksource_mpu)) - printk(err, clocksource_mpu.name); + set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000); + omap_timer.offset = omap_mpu_timer_gettimeoffset; + setup_irq(INT_TIMER1, &omap_mpu_timer1_irq); + setup_irq(INT_TIMER2, &omap_mpu_timer_irq); + omap_mpu_timer_start(0, 0xffffffff); + omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD); } - /* * Scheduler clock - returns current time in nanosec units. */ unsigned long long sched_clock(void) { - unsigned long ticks = 0 - omap_mpu_timer_read(1); + unsigned long ticks = 0 - omap_mpu_timer_read(0); unsigned long long ticks64; - ticks64 = omap_mpu_timer2_overflows; + ticks64 = omap_mpu_timer1_overflows; ticks64 <<= 32; ticks64 |= ticks; @@ -274,21 +225,10 @@ unsigned long long sched_clock(void) */ static void __init omap_timer_init(void) { - struct clk *ck_ref = clk_get(NULL, "ck_ref"); - unsigned long rate; - - BUG_ON(IS_ERR(ck_ref)); - - rate = clk_get_rate(ck_ref); - clk_put(ck_ref); - - /* PTV = 0 */ - rate /= 2; - - omap_init_mpu_timer(rate); - omap_init_clocksource(rate); + omap_init_mpu_timer(); } struct sys_timer omap_timer = { .init = omap_timer_init, + .offset = NULL, /* Initialized later */ }; diff --git a/trunk/arch/arm/mach-omap2/timer-gp.c b/trunk/arch/arm/mach-omap2/timer-gp.c index 62e801ef9ad9..45d1aaa51b57 100644 --- a/trunk/arch/arm/mach-omap2/timer-gp.c +++ b/trunk/arch/arm/mach-omap2/timer-gp.c @@ -52,7 +52,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) static struct irqaction omap2_gp_timer_irq = { .name = "gp timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = omap2_gp_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-pnx4008/time.c b/trunk/arch/arm/mach-pnx4008/time.c index 67e05f005a6b..8621c206ac84 100644 --- a/trunk/arch/arm/mach-pnx4008/time.c +++ b/trunk/arch/arm/mach-pnx4008/time.c @@ -82,7 +82,7 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id) static struct irqaction pnx4008_timer_irq = { .name = "PNX4008 Tick Timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = pnx4008_timer_interrupt }; diff --git a/trunk/arch/arm/mach-pxa/generic.c b/trunk/arch/arm/mach-pxa/generic.c index 64b08b744f9f..b8cb79f899d5 100644 --- a/trunk/arch/arm/mach-pxa/generic.c +++ b/trunk/arch/arm/mach-pxa/generic.c @@ -164,9 +164,9 @@ void pxa_set_cken(int clock, int enable) local_irq_save(flags); if (enable) - CKEN |= (1 << clock); + CKEN |= clock; else - CKEN &= ~(1 << clock); + CKEN &= ~clock; local_irq_restore(flags); } diff --git a/trunk/arch/arm/mach-pxa/irq.c b/trunk/arch/arm/mach-pxa/irq.c index 4619d5fe606c..f815678a9d63 100644 --- a/trunk/arch/arm/mach-pxa/irq.c +++ b/trunk/arch/arm/mach-pxa/irq.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -38,33 +39,11 @@ static void pxa_unmask_low_irq(unsigned int irq) ICMR |= (1 << (irq + PXA_IRQ_SKIP)); } -static int pxa_set_wake(unsigned int irq, unsigned int on) -{ - u32 mask; - - switch (irq) { - case IRQ_RTCAlrm: - mask = PWER_RTC; - break; -#ifdef CONFIG_PXA27x - /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */ -#endif - default: - return -EINVAL; - } - if (on) - PWER |= mask; - else - PWER &= ~mask; - return 0; -} - static struct irq_chip pxa_internal_chip_low = { .name = "SC", .ack = pxa_mask_low_irq, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, - .set_wake = pxa_set_wake, }; #if PXA_INTERNAL_IRQS > 32 @@ -92,26 +71,6 @@ static struct irq_chip pxa_internal_chip_high = { #endif -/* Note that if an input/irq line ever gets changed to an output during - * suspend, the relevant PWER, PRER, and PFER bits should be cleared. - */ -#ifdef CONFIG_PXA27x - -/* PXA27x: Various gpios can issue wakeup events. This logic only - * handles the simple cases, not the WEMUX2 and WEMUX3 options - */ -#define PXA27x_GPIO_NOWAKE_MASK \ - ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)) -#define WAKEMASK(gpio) \ - (((gpio) <= 15) \ - ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \ - : ((gpio == 35) ? (1 << 24) : 0)) -#else - -/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */ -#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0) -#endif - /* * PXA GPIO edge detection for IRQs: * IRQs are generated on Falling-Edge, Rising-Edge, or both. @@ -125,11 +84,9 @@ static long GPIO_IRQ_mask[4]; static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) { int gpio, idx; - u32 mask; gpio = IRQ_TO_GPIO(irq); idx = gpio >> 5; - mask = WAKEMASK(gpio); if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or @@ -149,20 +106,14 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) if (type & __IRQT_RISEDGE) { /* printk("rising "); */ __set_bit (gpio, GPIO_IRQ_rising_edge); - PRER |= mask; - } else { + } else __clear_bit (gpio, GPIO_IRQ_rising_edge); - PRER &= ~mask; - } if (type & __IRQT_FALEDGE) { /* printk("falling "); */ __set_bit (gpio, GPIO_IRQ_falling_edge); - PFER |= mask; - } else { + } else __clear_bit (gpio, GPIO_IRQ_falling_edge); - PFER &= ~mask; - } /* printk("edges\n"); */ @@ -180,29 +131,12 @@ static void pxa_ack_low_gpio(unsigned int irq) GEDR0 = (1 << (irq - IRQ_GPIO0)); } -static int pxa_set_gpio_wake(unsigned int irq, unsigned int on) -{ - int gpio = IRQ_TO_GPIO(irq); - u32 mask = WAKEMASK(gpio); - - if (!mask) - return -EINVAL; - - if (on) - PWER |= mask; - else - PWER &= ~mask; - return 0; -} - - static struct irq_chip pxa_low_gpio_chip = { .name = "GPIO-l", .ack = pxa_ack_low_gpio, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, .set_type = pxa_gpio_irq_type, - .set_wake = pxa_set_gpio_wake, }; /* @@ -311,7 +245,6 @@ static struct irq_chip pxa_muxed_gpio_chip = { .mask = pxa_mask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio, .set_type = pxa_gpio_irq_type, - .set_wake = pxa_set_gpio_wake, }; diff --git a/trunk/arch/arm/mach-pxa/lpd270.c b/trunk/arch/arm/mach-pxa/lpd270.c index e3097664ffe1..8e27a64fa9f4 100644 --- a/trunk/arch/arm/mach-pxa/lpd270.c +++ b/trunk/arch/arm/mach-pxa/lpd270.c @@ -234,7 +234,7 @@ static void lpd270_backlight_power(int on) { if (on) { pxa_gpio_mode(GPIO16_PWM0_MD); - pxa_set_cken(CKEN_PWM0, 1); + pxa_set_cken(CKEN0_PWM0, 1); PWM_CTRL0 = 0; PWM_PWDUTY0 = 0x3ff; PWM_PERVAL0 = 0x3ff; @@ -242,7 +242,7 @@ static void lpd270_backlight_power(int on) PWM_CTRL0 = 0; PWM_PWDUTY0 = 0x0; PWM_PERVAL0 = 0x3FF; - pxa_set_cken(CKEN_PWM0, 0); + pxa_set_cken(CKEN0_PWM0, 0); } } diff --git a/trunk/arch/arm/mach-pxa/lubbock.c b/trunk/arch/arm/mach-pxa/lubbock.c index 6377b2e29ff0..055de7f4f00a 100644 --- a/trunk/arch/arm/mach-pxa/lubbock.c +++ b/trunk/arch/arm/mach-pxa/lubbock.c @@ -220,7 +220,7 @@ static struct resource pxa_ssp_resources[] = { static struct pxa2xx_spi_master pxa_ssp_master_info = { .ssp_type = PXA25x_SSP, - .clock_enable = CKEN_SSP, + .clock_enable = CKEN3_SSP, .num_chipselect = 0, }; diff --git a/trunk/arch/arm/mach-pxa/mainstone.c b/trunk/arch/arm/mach-pxa/mainstone.c index ed99a81b98f3..56d94d88d5ca 100644 --- a/trunk/arch/arm/mach-pxa/mainstone.c +++ b/trunk/arch/arm/mach-pxa/mainstone.c @@ -266,7 +266,7 @@ static void mainstone_backlight_power(int on) { if (on) { pxa_gpio_mode(GPIO16_PWM0_MD); - pxa_set_cken(CKEN_PWM0, 1); + pxa_set_cken(CKEN0_PWM0, 1); PWM_CTRL0 = 0; PWM_PWDUTY0 = 0x3ff; PWM_PERVAL0 = 0x3ff; @@ -274,7 +274,7 @@ static void mainstone_backlight_power(int on) PWM_CTRL0 = 0; PWM_PWDUTY0 = 0x0; PWM_PERVAL0 = 0x3FF; - pxa_set_cken(CKEN_PWM0, 0); + pxa_set_cken(CKEN0_PWM0, 0); } } diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c index c64bab49efc4..74eeada1e2fc 100644 --- a/trunk/arch/arm/mach-pxa/pxa27x.c +++ b/trunk/arch/arm/mach-pxa/pxa27x.c @@ -140,9 +140,9 @@ void pxa_cpu_pm_enter(suspend_state_t state) extern void pxa_cpu_resume(void); if (state == PM_SUSPEND_STANDBY) - CKEN = CKEN_MEMC | CKEN_OSTIMER | CKEN_LCD | CKEN_PWM0; + CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0; else - CKEN = CKEN_MEMC | CKEN_OSTIMER; + CKEN = CKEN22_MEMC | CKEN9_OSTIMER; /* ensure voltage-change sequencer not initiated, which hangs */ PCFR &= ~PCFR_FVC; diff --git a/trunk/arch/arm/mach-pxa/ssp.c b/trunk/arch/arm/mach-pxa/ssp.c index 71766ac0328b..6cc202755fb4 100644 --- a/trunk/arch/arm/mach-pxa/ssp.c +++ b/trunk/arch/arm/mach-pxa/ssp.c @@ -52,13 +52,13 @@ struct ssp_info_ { */ static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = { #if defined (CONFIG_PXA27x) - {IRQ_SSP, CKEN_SSP1}, - {IRQ_SSP2, CKEN_SSP2}, - {IRQ_SSP3, CKEN_SSP3}, + {IRQ_SSP, CKEN23_SSP1}, + {IRQ_SSP2, CKEN3_SSP2}, + {IRQ_SSP3, CKEN4_SSP3}, #else - {IRQ_SSP, CKEN_SSP}, - {IRQ_NSSP, CKEN_NSSP}, - {IRQ_ASSP, CKEN_ASSP}, + {IRQ_SSP, CKEN3_SSP}, + {IRQ_NSSP, CKEN9_NSSP}, + {IRQ_ASSP, CKEN10_ASSP}, #endif }; diff --git a/trunk/arch/arm/mach-pxa/time.c b/trunk/arch/arm/mach-pxa/time.c index 5248abe334d2..fc3b82a740a0 100644 --- a/trunk/arch/arm/mach-pxa/time.c +++ b/trunk/arch/arm/mach-pxa/time.c @@ -97,7 +97,7 @@ pxa_timer_interrupt(int irq, void *dev_id) static struct irqaction pxa_timer_irq = { .name = "PXA Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = pxa_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-realview/core.c b/trunk/arch/arm/mach-realview/core.c index c7f1b44da40d..84d3fe76e94e 100644 --- a/trunk/arch/arm/mach-realview/core.c +++ b/trunk/arch/arm/mach-realview/core.c @@ -549,7 +549,7 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) static struct irqaction realview_timer_irq = { .name = "RealView Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = realview_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-rpc/riscpc.c b/trunk/arch/arm/mach-rpc/riscpc.c index 570cf937e73b..208a2b5dba1b 100644 --- a/trunk/arch/arm/mach-rpc/riscpc.c +++ b/trunk/arch/arm/mach-rpc/riscpc.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -160,45 +159,11 @@ static struct platform_device serial_device = { }, }; -static struct pata_platform_info pata_platform_data = { - .ioport_shift = 2, -}; - -static struct resource pata_resources[] = { - [0] = { - .start = 0x030107c0, - .end = 0x030107df, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 0x03010fd8, - .end = 0x03010fdb, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = IRQ_HARDDISK, - .end = IRQ_HARDDISK, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device pata_device = { - .name = "pata_platform", - .id = -1, - .num_resources = ARRAY_SIZE(pata_resources), - .resource = pata_resources, - .dev = { - .platform_data = &pata_platform_data, - .coherent_dma_mask = ~0, /* grumble */ - }, -}; - static struct platform_device *devs[] __initdata = { &iomd_device, &kbd_device, &serial_device, &acornfb_device, - &pata_device, }; static int __init rpc_init(void) diff --git a/trunk/arch/arm/mach-s3c2410/bast-irq.c b/trunk/arch/arm/mach-s3c2410/bast-irq.c index 76a7cb15f3be..daeba427d781 100644 --- a/trunk/arch/arm/mach-s3c2410/bast-irq.c +++ b/trunk/arch/arm/mach-s3c2410/bast-irq.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-s3c2410/irq.c b/trunk/arch/arm/mach-s3c2410/irq.c index f5c5c53e1cc1..53cbdaa43ac6 100644 --- a/trunk/arch/arm/mach-s3c2410/irq.c +++ b/trunk/arch/arm/mach-s3c2410/irq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c b/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c index bc308ceb91c3..72f2cc4fcd03 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/trunk/arch/arm/mach-s3c2410/mach-amlm5900.c @@ -160,11 +160,17 @@ static struct platform_device *amlm5900_devices[] __initdata = { #endif }; +static struct s3c24xx_board amlm5900_board __initdata = { + .devices = amlm5900_devices, + .devices_count = ARRAY_SIZE(amlm5900_devices) +}; + void __init amlm5900_map_io(void) { s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs)); + s3c24xx_set_board(&amlm5900_board); } #ifdef CONFIG_FB_S3C2410 @@ -241,7 +247,6 @@ static void __init amlm5900_init(void) #ifdef CONFIG_FB_S3C2410 s3c24xx_fb_set_platdata(&amlm5900_lcd_info); #endif - platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); } MACHINE_START(AML_M5900, "AML_M5900") diff --git a/trunk/arch/arm/mach-s3c2410/mach-bast.c b/trunk/arch/arm/mach-s3c2410/mach-bast.c index f01de807b72f..7b81296427eb 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-bast.c +++ b/trunk/arch/arm/mach-s3c2410/mach-bast.c @@ -464,6 +464,13 @@ static struct clk *bast_clocks[] = { &s3c24xx_uclk, }; +static struct s3c24xx_board bast_board __initdata = { + .devices = bast_devices, + .devices_count = ARRAY_SIZE(bast_devices), + .clocks = bast_clocks, + .clocks_count = ARRAY_SIZE(bast_clocks), +}; + static void __init bast_map_io(void) { /* initialise the clocks */ @@ -479,22 +486,19 @@ static void __init bast_map_io(void) s3c24xx_uclk.parent = &s3c24xx_clkout1; - s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks)); - s3c_device_nand.dev.platform_data = &bast_nand_info; s3c_device_i2c.dev.platform_data = &bast_i2c_info; s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs)); - + s3c24xx_set_board(&bast_board); usb_simtec_init(); } static void __init bast_init(void) { s3c24xx_fb_set_platdata(&bast_lcd_info); - platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); } MACHINE_START(BAST, "Simtec-BAST") diff --git a/trunk/arch/arm/mach-s3c2410/mach-h1940.c b/trunk/arch/arm/mach-s3c2410/mach-h1940.c index 5d5f00e9c462..d052ab2d9377 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-h1940.c +++ b/trunk/arch/arm/mach-s3c2410/mach-h1940.c @@ -129,6 +129,7 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = { }; + /** * Set lcd on or off **/ @@ -187,11 +188,17 @@ static struct platform_device *h1940_devices[] __initdata = { &s3c_device_leds, }; +static struct s3c24xx_board h1940_board __initdata = { + .devices = h1940_devices, + .devices_count = ARRAY_SIZE(h1940_devices) +}; + static void __init h1940_map_io(void) { s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs)); + s3c24xx_set_board(&h1940_board); /* setup PM */ @@ -225,8 +232,6 @@ static void __init h1940_init(void) | (0x02 << S3C2410_PLLCON_PDIVSHIFT) | (0x03 << S3C2410_PLLCON_SDIVSHIFT); writel(tmp, S3C2410_UPLLCON); - - platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices)); } MACHINE_START(H1940, "IPAQ-H1940") diff --git a/trunk/arch/arm/mach-s3c2410/mach-n30.c b/trunk/arch/arm/mach-s3c2410/mach-n30.c index 412e50c3d28a..261aa4cc0770 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-n30.c +++ b/trunk/arch/arm/mach-s3c2410/mach-n30.c @@ -90,11 +90,17 @@ static struct s3c2410_platform_i2c n30_i2ccfg = { .max_freq = 10*1000, }; +static struct s3c24xx_board n30_board __initdata = { + .devices = n30_devices, + .devices_count = ARRAY_SIZE(n30_devices) +}; + static void __init n30_map_io(void) { s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs)); + s3c24xx_set_board(&n30_board); } static void __init n30_init_irq(void) @@ -114,8 +120,6 @@ static void __init n30_init(void) s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST | S3C2410_MISCCR_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1, 0x0); - - platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices)); } MACHINE_START(N30, "Acer-N30") diff --git a/trunk/arch/arm/mach-s3c2410/mach-otom.c b/trunk/arch/arm/mach-s3c2410/mach-otom.c index 1f899fa588df..c78ab75b44f3 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-otom.c +++ b/trunk/arch/arm/mach-s3c2410/mach-otom.c @@ -100,17 +100,20 @@ static struct platform_device *otom11_devices[] __initdata = { &otom_device_nor, }; +static struct s3c24xx_board otom11_board __initdata = { + .devices = otom11_devices, + .devices_count = ARRAY_SIZE(otom11_devices) +}; + + static void __init otom11_map_io(void) { s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs)); + s3c24xx_set_board(&otom11_board); } -static void __init otom11_init(void) -{ - platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices)); -} MACHINE_START(OTOM, "Nex Vision - Otom 1.1") /* Maintainer: Guillaume GOURAT */ @@ -118,7 +121,6 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1") .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = otom11_map_io, - .init_machine = otom11_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2410/mach-qt2410.c b/trunk/arch/arm/mach-s3c2410/mach-qt2410.c index 9cc4253d7bbc..c6a41593de21 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-qt2410.c +++ b/trunk/arch/arm/mach-s3c2410/mach-qt2410.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -330,6 +331,11 @@ static struct platform_device *qt2410_devices[] __initdata = { &qt2410_led, }; +static struct s3c24xx_board qt2410_board __initdata = { + .devices = qt2410_devices, + .devices_count = ARRAY_SIZE(qt2410_devices) +}; + static struct mtd_partition qt2410_nand_part[] = { [0] = { .name = "U-Boot", @@ -399,6 +405,7 @@ static void __init qt2410_map_io(void) s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc)); s3c24xx_init_clocks(12*1000*1000); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); + s3c24xx_set_board(&qt2410_board); } static void __init qt2410_machine_init(void) @@ -425,7 +432,6 @@ static void __init qt2410_machine_init(void) s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT); - platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices)); s3c2410_pm_init(); } diff --git a/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c index 5852d300d52f..57b8a80f33d0 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -94,17 +94,17 @@ static struct platform_device *smdk2410_devices[] __initdata = { &s3c_device_iis, }; +static struct s3c24xx_board smdk2410_board __initdata = { + .devices = smdk2410_devices, + .devices_count = ARRAY_SIZE(smdk2410_devices) +}; + static void __init smdk2410_map_io(void) { s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs)); -} - -static void __init smdk2410_init(void) -{ - platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices)); - smdk_machine_init(); + s3c24xx_set_board(&smdk2410_board); } MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch @@ -115,7 +115,7 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = smdk2410_map_io, .init_irq = s3c24xx_init_irq, - .init_machine = smdk2410_init, + .init_machine = smdk_machine_init, .timer = &s3c24xx_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c index 7b624bb00490..c947c75bcbf0 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/trunk/arch/arm/mach-s3c2410/mach-vr1000.c @@ -384,6 +384,13 @@ static struct clk *vr1000_clocks[] = { &s3c24xx_uclk, }; +static struct s3c24xx_board vr1000_board __initdata = { + .devices = vr1000_devices, + .devices_count = ARRAY_SIZE(vr1000_devices), + .clocks = vr1000_clocks, + .clocks_count = ARRAY_SIZE(vr1000_clocks), +}; + static void vr1000_power_off(void) { s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_OUTP); @@ -405,19 +412,15 @@ static void __init vr1000_map_io(void) s3c24xx_uclk.parent = &s3c24xx_clkout1; - s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks)); - pm_power_off = vr1000_power_off; s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs)); + s3c24xx_set_board(&vr1000_board); + usb_simtec_init(); } -static void __init vr1000_init(void) -{ - platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices)); -} MACHINE_START(VR1000, "Thorcom-VR1000") /* Maintainer: Ben Dooks */ @@ -425,7 +428,6 @@ MACHINE_START(VR1000, "Thorcom-VR1000") .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = vr1000_map_io, - .init_machine = vr1000_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2412/Kconfig b/trunk/arch/arm/mach-s3c2412/Kconfig index d5be5d053264..befc5fdbb613 100644 --- a/trunk/arch/arm/mach-s3c2412/Kconfig +++ b/trunk/arch/arm/mach-s3c2412/Kconfig @@ -47,15 +47,6 @@ config MACH_S3C2413 machine_is_s3c2413() will work when MACH_SMDK2413 is selected -config MACH_SMDK2412 - bool "SMDK2412" - select MACH_SMDK2413 - help - Say Y here if you are using an SMDK2412 - - Note, this shares support with SMDK2413, so will automatically - select MACH_SMDK2413. - config MACH_VSTMS bool "VMSTMS" select CPU_S3C2412 diff --git a/trunk/arch/arm/mach-s3c2412/irq.c b/trunk/arch/arm/mach-s3c2412/irq.c index f0d66828f965..e89dbdcb1b7b 100644 --- a/trunk/arch/arm/mach-s3c2412/irq.c +++ b/trunk/arch/arm/mach-s3c2412/irq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c b/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c index 063af09f899d..b5befce6c8d3 100644 --- a/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c +++ b/trunk/arch/arm/mach-s3c2412/mach-smdk2413.c @@ -110,6 +110,11 @@ static struct platform_device *smdk2413_devices[] __initdata = { &s3c_device_usbgadget, }; +static struct s3c24xx_board smdk2413_board __initdata = { + .devices = smdk2413_devices, + .devices_count = ARRAY_SIZE(smdk2413_devices) +}; + static void __init smdk2413_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) @@ -127,6 +132,7 @@ static void __init smdk2413_map_io(void) s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs)); + s3c24xx_set_board(&smdk2413_board); } static void __init smdk2413_machine_init(void) @@ -143,7 +149,6 @@ static void __init smdk2413_machine_init(void) s3c24xx_udc_set_platdata(&smdk2413_udc_cfg); - platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices)); smdk_machine_init(); } diff --git a/trunk/arch/arm/mach-s3c2412/mach-vstms.c b/trunk/arch/arm/mach-s3c2412/mach-vstms.c index f2fbd65956ac..4231b549d797 100644 --- a/trunk/arch/arm/mach-s3c2412/mach-vstms.c +++ b/trunk/arch/arm/mach-s3c2412/mach-vstms.c @@ -129,6 +129,11 @@ static struct platform_device *vstms_devices[] __initdata = { &s3c_device_nand, }; +static struct s3c24xx_board vstms_board __initdata = { + .devices = vstms_devices, + .devices_count = ARRAY_SIZE(vstms_devices) +}; + static void __init vstms_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) @@ -148,11 +153,7 @@ static void __init vstms_map_io(void) s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs)); -} - -static void __init vstms_init(void) -{ - platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices)); + s3c24xx_set_board(&vstms_board); } MACHINE_START(VSTMS, "VSTMS") @@ -162,7 +163,6 @@ MACHINE_START(VSTMS, "VSTMS") .fixup = vstms_fixup, .init_irq = s3c24xx_init_irq, - .init_machine = vstms_init, .map_io = vstms_map_io, .timer = &s3c24xx_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2440/irq.c b/trunk/arch/arm/mach-s3c2440/irq.c index a87608bc1a03..1069d13d8c57 100644 --- a/trunk/arch/arm/mach-s3c2440/irq.c +++ b/trunk/arch/arm/mach-s3c2440/irq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-s3c2440/mach-anubis.c b/trunk/arch/arm/mach-s3c2440/mach-anubis.c index b5d387ef37e1..3f0288eb1ed5 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-anubis.c +++ b/trunk/arch/arm/mach-s3c2440/mach-anubis.c @@ -281,6 +281,13 @@ static struct clk *anubis_clocks[] = { &s3c24xx_uclk, }; +static struct s3c24xx_board anubis_board __initdata = { + .devices = anubis_devices, + .devices_count = ARRAY_SIZE(anubis_devices), + .clocks = anubis_clocks, + .clocks_count = ARRAY_SIZE(anubis_clocks), +}; + static void __init anubis_map_io(void) { /* initialise the clocks */ @@ -296,31 +303,23 @@ static void __init anubis_map_io(void) s3c24xx_uclk.parent = &s3c24xx_clkout1; - s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks)); - s3c_device_nand.dev.platform_data = &anubis_nand_info; s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs)); + s3c24xx_set_board(&anubis_board); /* ensure that the GPIO is setup */ s3c2410_gpio_setpin(S3C2410_GPA0, 1); } -static void __init anubis_init(void) -{ - platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices)); -} - - MACHINE_START(ANUBIS, "Simtec-Anubis") /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = anubis_map_io, - .init_machine = anubis_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c b/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c index 5e61f2166c76..6d551d88330b 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c +++ b/trunk/arch/arm/mach-s3c2440/mach-nexcoder.c @@ -116,6 +116,12 @@ static struct platform_device *nexcoder_devices[] __initdata = { &nexcoder_device_nor, }; +static struct s3c24xx_board nexcoder_board __initdata = { + .devices = nexcoder_devices, + .devices_count = ARRAY_SIZE(nexcoder_devices), +}; + + static void __init nexcoder_sensorboard_init(void) { // Initialize SCCB bus @@ -136,14 +142,10 @@ static void __init nexcoder_map_io(void) s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs)); - + s3c24xx_set_board(&nexcoder_board); nexcoder_sensorboard_init(); } -static void __init nexcoder_init(void) -{ - platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices)); -}; MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") /* Maintainer: Guillaume GOURAT */ @@ -151,7 +153,6 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = nexcoder_map_io, - .init_machine = nexcoder_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2440/mach-osiris.c b/trunk/arch/arm/mach-s3c2440/mach-osiris.c index 324f5a237921..2ed8e51f20c8 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-osiris.c +++ b/trunk/arch/arm/mach-s3c2440/mach-osiris.c @@ -251,6 +251,13 @@ static struct clk *osiris_clocks[] = { &s3c24xx_uclk, }; +static struct s3c24xx_board osiris_board __initdata = { + .devices = osiris_devices, + .devices_count = ARRAY_SIZE(osiris_devices), + .clocks = osiris_clocks, + .clocks_count = ARRAY_SIZE(osiris_clocks), +}; + static void __init osiris_map_io(void) { unsigned long flags; @@ -268,13 +275,12 @@ static void __init osiris_map_io(void) s3c24xx_uclk.parent = &s3c24xx_clkout1; - s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks)); - s3c_device_nand.dev.platform_data = &osiris_nand_info; s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc)); s3c24xx_init_clocks(0); s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs)); + s3c24xx_set_board(&osiris_board); /* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */ @@ -286,18 +292,12 @@ static void __init osiris_map_io(void) s3c2410_gpio_setpin(S3C2410_GPA0, 1); } -static void __init osiris_init(void) -{ - platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices)); -}; - MACHINE_START(OSIRIS, "Simtec-OSIRIS") /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = osiris_map_io, - .init_machine = osiris_init, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2440/mach-rx3715.c b/trunk/arch/arm/mach-s3c2440/mach-rx3715.c index c3cc4bf158f6..ae1d0a81fd6a 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-rx3715.c +++ b/trunk/arch/arm/mach-s3c2440/mach-rx3715.c @@ -202,6 +202,11 @@ static struct platform_device *rx3715_devices[] __initdata = { &s3c_device_nand, }; +static struct s3c24xx_board rx3715_board __initdata = { + .devices = rx3715_devices, + .devices_count = ARRAY_SIZE(rx3715_devices) +}; + static void __init rx3715_map_io(void) { s3c_device_nand.dev.platform_data = &rx3715_nand_info; @@ -209,6 +214,7 @@ static void __init rx3715_map_io(void) s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc)); s3c24xx_init_clocks(16934000); s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs)); + s3c24xx_set_board(&rx3715_board); } static void __init rx3715_init_irq(void) @@ -224,9 +230,9 @@ static void __init rx3715_init_machine(void) s3c2410_pm_init(); s3c24xx_fb_set_platdata(&rx3715_lcdcfg); - platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices)); } + MACHINE_START(RX3715, "IPAQ-RX3715") /* Maintainer: Ben Dooks */ .phys_io = S3C2410_PA_UART, diff --git a/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c b/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c index e167254e232e..c17eb5b1f6b4 100644 --- a/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c +++ b/trunk/arch/arm/mach-s3c2440/mach-smdk2440.c @@ -174,18 +174,23 @@ static struct platform_device *smdk2440_devices[] __initdata = { &s3c_device_iis, }; +static struct s3c24xx_board smdk2440_board __initdata = { + .devices = smdk2440_devices, + .devices_count = ARRAY_SIZE(smdk2440_devices) +}; + static void __init smdk2440_map_io(void) { s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc)); s3c24xx_init_clocks(16934400); s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs)); + s3c24xx_set_board(&smdk2440_board); } static void __init smdk2440_machine_init(void) { s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); - platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); smdk_machine_init(); } diff --git a/trunk/arch/arm/mach-s3c2443/irq.c b/trunk/arch/arm/mach-s3c2443/irq.c index 6cd4818f3f0d..756573595b88 100644 --- a/trunk/arch/arm/mach-s3c2443/irq.c +++ b/trunk/arch/arm/mach-s3c2443/irq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c b/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c index b71ee53c2865..e82aaff7dee4 100644 --- a/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c +++ b/trunk/arch/arm/mach-s3c2443/mach-smdk2443.c @@ -106,16 +106,21 @@ static struct platform_device *smdk2443_devices[] __initdata = { &s3c_device_i2c, }; +static struct s3c24xx_board smdk2443_board __initdata = { + .devices = smdk2443_devices, + .devices_count = ARRAY_SIZE(smdk2443_devices) +}; + static void __init smdk2443_map_io(void) { s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc)); s3c24xx_init_clocks(12000000); s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs)); + s3c24xx_set_board(&smdk2443_board); } static void __init smdk2443_machine_init(void) { - platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices)); smdk_machine_init(); } diff --git a/trunk/arch/arm/mach-sa1100/clock.c b/trunk/arch/arm/mach-sa1100/clock.c index fc97fe57ee6f..b1e8fd766c1a 100644 --- a/trunk/arch/arm/mach-sa1100/clock.c +++ b/trunk/arch/arm/mach-sa1100/clock.c @@ -9,17 +9,14 @@ #include #include #include -#include #include +#include -/* - * Very simple clock implementation - we only have one clock to - * deal with at the moment, so we only match using the "name". - */ struct clk { struct list_head node; unsigned long rate; + struct module *owner; const char *name; unsigned int enabled; void (*enable)(void); @@ -27,21 +24,21 @@ struct clk { }; static LIST_HEAD(clocks); -static DEFINE_MUTEX(clocks_mutex); +static DECLARE_MUTEX(clocks_sem); static DEFINE_SPINLOCK(clocks_lock); struct clk *clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); - mutex_lock(&clocks_mutex); + down(&clocks_sem); list_for_each_entry(p, &clocks, node) { - if (strcmp(id, p->name) == 0) { + if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; break; } } - mutex_unlock(&clocks_mutex); + up(&clocks_sem); return clk; } @@ -49,6 +46,7 @@ EXPORT_SYMBOL(clk_get); void clk_put(struct clk *clk) { + module_put(clk->owner); } EXPORT_SYMBOL(clk_put); @@ -111,18 +109,18 @@ static struct clk clk_gpio27 = { int clk_register(struct clk *clk) { - mutex_lock(&clocks_mutex); + down(&clocks_sem); list_add(&clk->node, &clocks); - mutex_unlock(&clocks_mutex); + up(&clocks_sem); return 0; } EXPORT_SYMBOL(clk_register); void clk_unregister(struct clk *clk) { - mutex_lock(&clocks_mutex); + down(&clocks_sem); list_del(&clk->node); - mutex_unlock(&clocks_mutex); + up(&clocks_sem); } EXPORT_SYMBOL(clk_unregister); diff --git a/trunk/arch/arm/mach-sa1100/h3600.c b/trunk/arch/arm/mach-sa1100/h3600.c index b72fee0f2538..b034ad69a324 100644 --- a/trunk/arch/arm/mach-sa1100/h3600.c +++ b/trunk/arch/arm/mach-sa1100/h3600.c @@ -740,7 +740,7 @@ static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc) static struct irqaction h3800_irq = { .name = "h3800_asic", .handler = h3800_IRQ_demux, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, }; u32 kpio_int_shadow = 0; diff --git a/trunk/arch/arm/mach-sa1100/irq.c b/trunk/arch/arm/mach-sa1100/irq.c index edf3347d9c5b..5642aeca079e 100644 --- a/trunk/arch/arm/mach-sa1100/irq.c +++ b/trunk/arch/arm/mach-sa1100/irq.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-sa1100/neponset.c b/trunk/arch/arm/mach-sa1100/neponset.c index d7c038a0256b..075d4d1d63be 100644 --- a/trunk/arch/arm/mach-sa1100/neponset.c +++ b/trunk/arch/arm/mach-sa1100/neponset.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #include diff --git a/trunk/arch/arm/mach-sa1100/time.c b/trunk/arch/arm/mach-sa1100/time.c index 416e277054c2..29c89f9eb2ce 100644 --- a/trunk/arch/arm/mach-sa1100/time.c +++ b/trunk/arch/arm/mach-sa1100/time.c @@ -111,7 +111,7 @@ sa1100_timer_interrupt(int irq, void *dev_id) static struct irqaction sa1100_timer_irq = { .name = "SA11xx Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = sa1100_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-shark/core.c b/trunk/arch/arm/mach-shark/core.c index a0545db2a34f..0e480fae8ec5 100644 --- a/trunk/arch/arm/mach-shark/core.c +++ b/trunk/arch/arm/mach-shark/core.c @@ -90,7 +90,7 @@ shark_timer_interrupt(int irq, void *dev_id) static struct irqaction shark_timer_irq = { .name = "Shark Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = shark_timer_interrupt, }; diff --git a/trunk/arch/arm/mach-shark/irq.c b/trunk/arch/arm/mach-shark/irq.c index 5b0c6af44ec6..00a6c1466867 100644 --- a/trunk/arch/arm/mach-shark/irq.c +++ b/trunk/arch/arm/mach-shark/irq.c @@ -10,6 +10,7 @@ #include #include +#include #include #include diff --git a/trunk/arch/arm/mach-versatile/core.c b/trunk/arch/arm/mach-versatile/core.c index a7dd09436cbc..bf71507c76fd 100644 --- a/trunk/arch/arm/mach-versatile/core.c +++ b/trunk/arch/arm/mach-versatile/core.c @@ -26,8 +26,6 @@ #include #include #include -#include -#include #include #include @@ -830,101 +828,69 @@ void __init versatile_init(void) #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -static void timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk) +/* + * Returns number of ms since last clock interrupt. Note that interrupts + * will have been disabled by do_gettimeoffset() + */ +static unsigned long versatile_gettimeoffset(void) { - unsigned long ctrl; - - switch(mode) { - case CLOCK_EVT_MODE_PERIODIC: - writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); - - ctrl = TIMER_CTRL_PERIODIC; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE; - break; - case CLOCK_EVT_MODE_ONESHOT: - /* period set, and timer enabled in 'next_event' hook */ - ctrl = TIMER_CTRL_ONESHOT; - ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE; - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - default: - ctrl = 0; - } + unsigned long ticks1, ticks2, status; - writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL); -} + /* + * Get the current number of ticks. Note that there is a race + * condition between us reading the timer and checking for + * an interrupt. We get around this by ensuring that the + * counter has not reloaded between our two reads. + */ + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; + do { + ticks1 = ticks2; + status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS); + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; + } while (ticks2 > ticks1); -static int timer_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL); + /* + * Number of ticks since last interrupt. + */ + ticks1 = TIMER_RELOAD - ticks2; - writel(evt, TIMER0_VA_BASE + TIMER_LOAD); - writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL); + /* + * Interrupt pending? If so, we've reloaded once already. + * + * FIXME: Need to check this is effectively timer 0 that expires + */ + if (status & IRQMASK_TIMERINT0_1) + ticks1 += TIMER_RELOAD; - return 0; + /* + * Convert the ticks to usecs + */ + return TICKS2USECS(ticks1); } -static struct clock_event_device timer0_clockevent = { - .name = "timer0", - .shift = 32, - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_mode = timer_set_mode, - .set_next_event = timer_set_next_event, -}; - /* * IRQ handler for the timer */ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id) { - struct clock_event_device *evt = &timer0_clockevent; + write_seqlock(&xtime_lock); + // ...clear the interrupt writel(1, TIMER0_VA_BASE + TIMER_INTCLR); - evt->event_handler(evt); + timer_tick(); + + write_sequnlock(&xtime_lock); return IRQ_HANDLED; } static struct irqaction versatile_timer_irq = { .name = "Versatile Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = versatile_timer_interrupt, }; -static cycle_t versatile_get_cycles(void) -{ - return ~readl(TIMER3_VA_BASE + TIMER_VALUE); -} - -static struct clocksource clocksource_versatile = { - .name = "timer3", - .rating = 200, - .read = versatile_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init versatile_clocksource_init(void) -{ - /* setup timer3 as free-running clocksource */ - writel(0, TIMER3_VA_BASE + TIMER_CTRL); - writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD); - writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE); - writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC, - TIMER3_VA_BASE + TIMER_CTRL); - - clocksource_versatile.mult = - clocksource_khz2mult(1000, clocksource_versatile.shift); - clocksource_register(&clocksource_versatile); - - return 0; -} - /* * Set up timer interrupt, and return the current time in seconds. */ @@ -952,25 +918,18 @@ static void __init versatile_timer_init(void) writel(0, TIMER2_VA_BASE + TIMER_CTRL); writel(0, TIMER3_VA_BASE + TIMER_CTRL); + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE); + writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC | + TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL); + /* * Make irqs happen for the system timer */ setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq); - - versatile_clocksource_init(); - - timer0_clockevent.mult = - div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift); - timer0_clockevent.max_delta_ns = - clockevent_delta2ns(0xffffffff, &timer0_clockevent); - timer0_clockevent.min_delta_ns = - clockevent_delta2ns(0xf, &timer0_clockevent); - - timer0_clockevent.cpumask = cpumask_of_cpu(0); - clockevents_register_device(&timer0_clockevent); } struct sys_timer versatile_timer = { .init = versatile_timer_init, + .offset = versatile_gettimeoffset, }; - diff --git a/trunk/arch/arm/mach-versatile/pci.c b/trunk/arch/arm/mach-versatile/pci.c index ba58223f12be..5cd0b5d9e7eb 100644 --- a/trunk/arch/arm/mach-versatile/pci.c +++ b/trunk/arch/arm/mach-versatile/pci.c @@ -16,6 +16,7 @@ */ #include #include +#include #include #include #include diff --git a/trunk/arch/arm/mm/alignment.c b/trunk/arch/arm/mm/alignment.c index 19ca333240ec..aa109f074dd9 100644 --- a/trunk/arch/arm/mm/alignment.c +++ b/trunk/arch/arm/mm/alignment.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index 75d491448e45..9fd6d2eafb40 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -10,6 +10,7 @@ */ #include #include +#include #include #include @@ -437,7 +438,7 @@ hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *) /* * Dispatch a data abort to the relevant handler. */ -asmlinkage void __exception +asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); @@ -453,10 +454,10 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) info.si_errno = 0; info.si_code = inf->code; info.si_addr = (void __user *)addr; - arm_notify_die("", regs, &info, fsr, 0); + notify_die("", regs, &info, fsr, 0); } -asmlinkage void __exception +asmlinkage void do_PrefetchAbort(unsigned long addr, struct pt_regs *regs) { do_translation_fault(addr, 0, regs); diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index c0ad7c0fbae0..7760193e74cc 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -9,6 +9,7 @@ */ #include #include +#include #include #include #include diff --git a/trunk/arch/arm/mm/ioremap.c b/trunk/arch/arm/mm/ioremap.c index d6167ad4e011..0ac615c0f798 100644 --- a/trunk/arch/arm/mm/ioremap.c +++ b/trunk/arch/arm/mm/ioremap.c @@ -32,9 +32,6 @@ #include #include -#include -#include "mm.h" - /* * Used by ioremap() and iounmap() code to mark (super)section-mapped * I/O regions in vm_struct->flags field. @@ -42,9 +39,8 @@ #define VM_ARM_SECTION_MAPPING 0x80000000 static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end, - unsigned long phys_addr, const struct mem_type *type) + unsigned long phys_addr, pgprot_t prot) { - pgprot_t prot = __pgprot(type->prot_pte); pte_t *pte; pte = pte_alloc_kernel(pmd, addr); @@ -55,8 +51,7 @@ static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end, if (!pte_none(*pte)) goto bad; - set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), - type->prot_pte_ext); + set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0); phys_addr += PAGE_SIZE; } while (pte++, addr += PAGE_SIZE, addr != end); return 0; @@ -68,7 +63,7 @@ static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end, static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr, unsigned long end, unsigned long phys_addr, - const struct mem_type *type) + pgprot_t prot) { unsigned long next; pmd_t *pmd; @@ -80,7 +75,7 @@ static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr, do { next = pmd_addr_end(addr, end); - ret = remap_area_pte(pmd, addr, next, phys_addr, type); + ret = remap_area_pte(pmd, addr, next, phys_addr, prot); if (ret) return ret; phys_addr += next - addr; @@ -89,11 +84,13 @@ static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr, } static int remap_area_pages(unsigned long start, unsigned long pfn, - size_t size, const struct mem_type *type) + unsigned long size, unsigned long flags) { unsigned long addr = start; unsigned long next, end = start + size; unsigned long phys_addr = __pfn_to_phys(pfn); + pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | + L_PTE_DIRTY | L_PTE_WRITE | flags); pgd_t *pgd; int err = 0; @@ -101,7 +98,7 @@ static int remap_area_pages(unsigned long start, unsigned long pfn, pgd = pgd_offset_k(addr); do { next = pgd_addr_end(addr, end); - err = remap_area_pmd(pgd, addr, next, phys_addr, type); + err = remap_area_pmd(pgd, addr, next, phys_addr, prot); if (err) break; phys_addr += next - addr; @@ -181,9 +178,9 @@ static void unmap_area_sections(unsigned long virt, unsigned long size) static int remap_area_sections(unsigned long virt, unsigned long pfn, - size_t size, const struct mem_type *type) + unsigned long size, unsigned long flags) { - unsigned long addr = virt, end = virt + size; + unsigned long prot, addr = virt, end = virt + size; pgd_t *pgd; /* @@ -192,13 +189,23 @@ remap_area_sections(unsigned long virt, unsigned long pfn, */ unmap_area_sections(virt, size); + prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO) | + (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE)); + + /* + * ARMv6 and above need XN set to prevent speculative prefetches + * hitting IO. + */ + if (cpu_architecture() >= CPU_ARCH_ARMv6) + prot |= PMD_SECT_XN; + pgd = pgd_offset_k(addr); do { pmd_t *pmd = pmd_offset(pgd, addr); - pmd[0] = __pmd(__pfn_to_phys(pfn) | type->prot_sect); + pmd[0] = __pmd(__pfn_to_phys(pfn) | prot); pfn += SZ_1M >> PAGE_SHIFT; - pmd[1] = __pmd(__pfn_to_phys(pfn) | type->prot_sect); + pmd[1] = __pmd(__pfn_to_phys(pfn) | prot); pfn += SZ_1M >> PAGE_SHIFT; flush_pmd_entry(pmd); @@ -211,9 +218,9 @@ remap_area_sections(unsigned long virt, unsigned long pfn, static int remap_area_supersections(unsigned long virt, unsigned long pfn, - size_t size, const struct mem_type *type) + unsigned long size, unsigned long flags) { - unsigned long addr = virt, end = virt + size; + unsigned long prot, addr = virt, end = virt + size; pgd_t *pgd; /* @@ -222,12 +229,22 @@ remap_area_supersections(unsigned long virt, unsigned long pfn, */ unmap_area_sections(virt, size); + prot = PMD_TYPE_SECT | PMD_SECT_SUPER | PMD_SECT_AP_WRITE | + PMD_DOMAIN(DOMAIN_IO) | + (flags & (L_PTE_CACHEABLE | L_PTE_BUFFERABLE)); + + /* + * ARMv6 and above need XN set to prevent speculative prefetches + * hitting IO. + */ + if (cpu_architecture() >= CPU_ARCH_ARMv6) + prot |= PMD_SECT_XN; + pgd = pgd_offset_k(virt); do { unsigned long super_pmd_val, i; - super_pmd_val = __pfn_to_phys(pfn) | type->prot_sect | - PMD_SECT_SUPER; + super_pmd_val = __pfn_to_phys(pfn) | prot; super_pmd_val |= ((pfn >> (32 - PAGE_SHIFT)) & 0xf) << 20; for (i = 0; i < 8; i++) { @@ -262,10 +279,9 @@ remap_area_supersections(unsigned long virt, unsigned long pfn, * mapping. See include/asm-arm/proc-armv/pgtable.h for more information. */ void __iomem * -__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, - unsigned int mtype) +__ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, + unsigned long flags) { - const struct mem_type *type; int err; unsigned long addr; struct vm_struct * area; @@ -276,10 +292,6 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK)) return NULL; - type = get_mem_type(mtype); - if (!type) - return NULL; - size = PAGE_ALIGN(size); area = get_vm_area(size, VM_IOREMAP); @@ -290,16 +302,16 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, #ifndef CONFIG_SMP if (DOMAIN_IO == 0 && (((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) || - cpu_is_xsc3()) && pfn >= 0x100000 && + cpu_is_xsc3()) && !((__pfn_to_phys(pfn) | size | addr) & ~SUPERSECTION_MASK)) { area->flags |= VM_ARM_SECTION_MAPPING; - err = remap_area_supersections(addr, pfn, size, type); + err = remap_area_supersections(addr, pfn, size, flags); } else if (!((__pfn_to_phys(pfn) | size | addr) & ~PMD_MASK)) { area->flags |= VM_ARM_SECTION_MAPPING; - err = remap_area_sections(addr, pfn, size, type); + err = remap_area_sections(addr, pfn, size, flags); } else #endif - err = remap_area_pages(addr, pfn, size, type); + err = remap_area_pages(addr, pfn, size, flags); if (err) { vunmap((void *)addr); @@ -309,10 +321,10 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, flush_cache_vmap(addr, addr + size); return (void __iomem *) (offset + addr); } -EXPORT_SYMBOL(__arm_ioremap_pfn); +EXPORT_SYMBOL(__ioremap_pfn); void __iomem * -__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) +__ioremap(unsigned long phys_addr, size_t size, unsigned long flags) { unsigned long last_addr; unsigned long offset = phys_addr & ~PAGE_MASK; @@ -330,9 +342,9 @@ __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) */ size = PAGE_ALIGN(last_addr + 1) - phys_addr; - return __arm_ioremap_pfn(pfn, offset, size, mtype); + return __ioremap_pfn(pfn, offset, size, flags); } -EXPORT_SYMBOL(__arm_ioremap); +EXPORT_SYMBOL(__ioremap); void __iounmap(volatile void __iomem *addr) { diff --git a/trunk/arch/arm/mm/mm.h b/trunk/arch/arm/mm/mm.h index 7647c597fc59..a44e30970635 100644 --- a/trunk/arch/arm/mm/mm.h +++ b/trunk/arch/arm/mm/mm.h @@ -16,16 +16,6 @@ static inline pmd_t *pmd_off_k(unsigned long virt) return pmd_off(pgd_offset_k(virt), virt); } -struct mem_type { - unsigned int prot_pte; - unsigned int prot_pte_ext; - unsigned int prot_l1; - unsigned int prot_sect; - unsigned int domain; -}; - -const struct mem_type *get_mem_type(unsigned int type); - #endif struct map_desc; diff --git a/trunk/arch/arm/mm/mmap.c b/trunk/arch/arm/mm/mmap.c index 2c4c2422cd1e..b0b5f4694070 100644 --- a/trunk/arch/arm/mm/mmap.c +++ b/trunk/arch/arm/mm/mmap.c @@ -49,7 +49,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, #endif /* - * We enforce the MAP_FIXED case. + * We should enforce the MAP_FIXED case. However, currently + * the generic kernel code doesn't allow us to handle this. */ if (flags & MAP_FIXED) { if (aliasing && flags & MAP_SHARED && addr & (SHMLBA - 1)) diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index 2ba1530d1ce1..94fd4bf5cb9e 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -176,42 +176,28 @@ void adjust_cr(unsigned long mask, unsigned long set) } #endif -#define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_WRITE -#define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_XN|PMD_SECT_AP_WRITE - -static struct mem_type mem_types[] = { - [MT_DEVICE] = { /* Strongly ordered / ARMv6 shared device */ - .prot_pte = PROT_PTE_DEVICE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PROT_SECT_DEVICE | PMD_SECT_UNCACHED, - .domain = DOMAIN_IO, - }, - [MT_DEVICE_NONSHARED] = { /* ARMv6 non-shared device */ - .prot_pte = PROT_PTE_DEVICE, - .prot_pte_ext = PTE_EXT_TEX(2), - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PROT_SECT_DEVICE | PMD_SECT_TEX(2), - .domain = DOMAIN_IO, - }, - [MT_DEVICE_CACHED] = { /* ioremap_cached */ - .prot_pte = PROT_PTE_DEVICE | L_PTE_CACHEABLE | L_PTE_BUFFERABLE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PROT_SECT_DEVICE | PMD_SECT_WB, - .domain = DOMAIN_IO, - }, - [MT_DEVICE_IXP2000] = { /* IXP2400 requires XCB=101 for on-chip I/O */ - .prot_pte = PROT_PTE_DEVICE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PROT_SECT_DEVICE | PMD_SECT_BUFFERABLE | - PMD_SECT_TEX(1), - .domain = DOMAIN_IO, +struct mem_types { + unsigned int prot_pte; + unsigned int prot_l1; + unsigned int prot_sect; + unsigned int domain; +}; + +static struct mem_types mem_types[] __initdata = { + [MT_DEVICE] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, }, [MT_CACHECLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4, .domain = DOMAIN_KERNEL, }, [MT_MINICLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE, .domain = DOMAIN_KERNEL, }, [MT_LOW_VECTORS] = { @@ -227,20 +213,30 @@ static struct mem_type mem_types[] = { .domain = DOMAIN_USER, }, [MT_MEMORY] = { - .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE, .domain = DOMAIN_KERNEL, }, [MT_ROM] = { - .prot_sect = PMD_TYPE_SECT, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4, .domain = DOMAIN_KERNEL, }, + [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | + PMD_SECT_TEX(1), + .domain = DOMAIN_IO, + }, + [MT_NONSHARED_DEVICE] = { + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, + } }; -const struct mem_type *get_mem_type(unsigned int type) -{ - return type < ARRAY_SIZE(mem_types) ? &mem_types[type] : NULL; -} - /* * Adjust the PMD section entries according to the CPU in use. */ @@ -266,23 +262,20 @@ static void __init build_mem_type_table(void) } /* - * ARMv5 and lower, bit 4 must be set for page tables. - * (was: cache "update-able on write" bit on ARM610) - * However, Xscale cores require this bit to be cleared. + * Xscale must not have PMD bit 4 set for section mappings. */ - if (cpu_is_xscale()) { - for (i = 0; i < ARRAY_SIZE(mem_types); i++) { + if (cpu_is_xscale()) + for (i = 0; i < ARRAY_SIZE(mem_types); i++) mem_types[i].prot_sect &= ~PMD_BIT4; - mem_types[i].prot_l1 &= ~PMD_BIT4; - } - } else if (cpu_arch < CPU_ARCH_ARMv6) { - for (i = 0; i < ARRAY_SIZE(mem_types); i++) { + + /* + * ARMv5 and lower, excluding Xscale, bit 4 must be set for + * page tables. + */ + if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale()) + for (i = 0; i < ARRAY_SIZE(mem_types); i++) if (mem_types[i].prot_l1) mem_types[i].prot_l1 |= PMD_BIT4; - if (mem_types[i].prot_sect) - mem_types[i].prot_sect |= PMD_BIT4; - } - } cp = &cache_policies[cachepolicy]; kern_pgprot = user_pgprot = cp->pte; @@ -302,6 +295,13 @@ static void __init build_mem_type_table(void) * ARMv6 and above have extended page tables. */ if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { + /* + * bit 4 becomes XN which we must clear for the + * kernel memory mapping. + */ + mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN; + mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN; + /* * Mark cache clean areas and XIP ROM read only * from SVC mode and no access from userspace. @@ -368,126 +368,64 @@ static void __init build_mem_type_table(void) } printk("Memory policy: ECC %sabled, Data cache %s\n", ecc_mask ? "en" : "dis", cp->policy); - - for (i = 0; i < ARRAY_SIZE(mem_types); i++) { - struct mem_type *t = &mem_types[i]; - if (t->prot_l1) - t->prot_l1 |= PMD_DOMAIN(t->domain); - if (t->prot_sect) - t->prot_sect |= PMD_DOMAIN(t->domain); - } } #define vectors_base() (vectors_high() ? 0xffff0000 : 0) -static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, - unsigned long end, unsigned long pfn, - const struct mem_type *type) +/* + * Create a SECTION PGD between VIRT and PHYS in domain + * DOMAIN with protection PROT. This operates on half- + * pgdir entry increments. + */ +static inline void +alloc_init_section(unsigned long virt, unsigned long phys, int prot) { - pte_t *pte; + pmd_t *pmdp = pmd_off_k(virt); - if (pmd_none(*pmd)) { - pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t)); - __pmd_populate(pmd, __pa(pte) | type->prot_l1); - } + if (virt & (1 << 20)) + pmdp++; - pte = pte_offset_kernel(pmd, addr); - do { - set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), - type->prot_pte_ext); - pfn++; - } while (pte++, addr += PAGE_SIZE, addr != end); + *pmdp = __pmd(phys | prot); + flush_pmd_entry(pmdp); } -static void __init alloc_init_section(pgd_t *pgd, unsigned long addr, - unsigned long end, unsigned long phys, - const struct mem_type *type) +/* + * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT + */ +static inline void +alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) { - pmd_t *pmd = pmd_offset(pgd, addr); - - /* - * Try a section mapping - end, addr and phys must all be aligned - * to a section boundary. Note that PMDs refer to the individual - * L1 entries, whereas PGDs refer to a group of L1 entries making - * up one logical pointer to an L2 table. - */ - if (((addr | end | phys) & ~SECTION_MASK) == 0) { - pmd_t *p = pmd; - - if (addr & SECTION_SIZE) - pmd++; + int i; - do { - *pmd = __pmd(phys | type->prot_sect); - phys += SECTION_SIZE; - } while (pmd++, addr += SECTION_SIZE, addr != end); + for (i = 0; i < 16; i += 1) { + alloc_init_section(virt, phys, prot | PMD_SECT_SUPER); - flush_pmd_entry(p); - } else { - /* - * No need to loop; pte's aren't interested in the - * individual L1 entries. - */ - alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type); + virt += (PGDIR_SIZE / 2); } } -static void __init create_36bit_mapping(struct map_desc *md, - const struct mem_type *type) +/* + * Add a PAGE mapping between VIRT and PHYS in domain + * DOMAIN with protection PROT. Note that due to the + * way we map the PTEs, we must allocate two PTE_SIZE'd + * blocks - one for the Linux pte table, and one for + * the hardware pte table. + */ +static inline void +alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) { - unsigned long phys, addr, length, end; - pgd_t *pgd; - - addr = md->virtual; - phys = (unsigned long)__pfn_to_phys(md->pfn); - length = PAGE_ALIGN(md->length); - - if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) { - printk(KERN_ERR "MM: CPU does not support supersection " - "mapping for 0x%08llx at 0x%08lx\n", - __pfn_to_phys((u64)md->pfn), addr); - return; - } + pmd_t *pmdp = pmd_off_k(virt); + pte_t *ptep; - /* N.B. ARMv6 supersections are only defined to work with domain 0. - * Since domain assignments can in fact be arbitrary, the - * 'domain == 0' check below is required to insure that ARMv6 - * supersections are only allocated for domain 0 regardless - * of the actual domain assignments in use. - */ - if (type->domain) { - printk(KERN_ERR "MM: invalid domain in supersection " - "mapping for 0x%08llx at 0x%08lx\n", - __pfn_to_phys((u64)md->pfn), addr); - return; - } + if (pmd_none(*pmdp)) { + ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * + sizeof(pte_t)); - if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) { - printk(KERN_ERR "MM: cannot create mapping for " - "0x%08llx at 0x%08lx invalid alignment\n", - __pfn_to_phys((u64)md->pfn), addr); - return; + __pmd_populate(pmdp, __pa(ptep) | prot_l1); } + ptep = pte_offset_kernel(pmdp, virt); - /* - * Shift bits [35:32] of address into bits [23:20] of PMD - * (See ARMv6 spec). - */ - phys |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); - - pgd = pgd_offset_k(addr); - end = addr + length; - do { - pmd_t *pmd = pmd_offset(pgd, addr); - int i; - - for (i = 0; i < 16; i++) - *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER); - - addr += SUPERSECTION_SIZE; - phys += SUPERSECTION_SIZE; - pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT; - } while (addr != end); + set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, prot), 0); } /* @@ -499,9 +437,10 @@ static void __init create_36bit_mapping(struct map_desc *md, */ void __init create_mapping(struct map_desc *md) { - unsigned long phys, addr, length, end; - const struct mem_type *type; - pgd_t *pgd; + unsigned long virt, length; + int prot_sect, prot_l1, domain; + pgprot_t prot_pte; + unsigned long off = (u32)__pfn_to_phys(md->pfn); if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { printk(KERN_WARNING "BUG: not creating mapping for " @@ -517,37 +456,105 @@ void __init create_mapping(struct map_desc *md) __pfn_to_phys((u64)md->pfn), md->virtual); } - type = &mem_types[md->type]; + domain = mem_types[md->type].domain; + prot_pte = __pgprot(mem_types[md->type].prot_pte); + prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); + prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); /* * Catch 36-bit addresses */ - if (md->pfn >= 0x100000) { - create_36bit_mapping(md, type); - return; + if(md->pfn >= 0x100000) { + if(domain) { + printk(KERN_ERR "MM: invalid domain in supersection " + "mapping for 0x%08llx at 0x%08lx\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + if((md->virtual | md->length | __pfn_to_phys(md->pfn)) + & ~SUPERSECTION_MASK) { + printk(KERN_ERR "MM: cannot create mapping for " + "0x%08llx at 0x%08lx invalid alignment\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + + /* + * Shift bits [35:32] of address into bits [23:20] of PMD + * (See ARMv6 spec). + */ + off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); } - addr = md->virtual; - phys = (unsigned long)__pfn_to_phys(md->pfn); - length = PAGE_ALIGN(md->length); + virt = md->virtual; + off -= virt; + length = md->length; - if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { + if (mem_types[md->type].prot_l1 == 0 && + (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " "be mapped using pages, ignoring.\n", - __pfn_to_phys(md->pfn), addr); + __pfn_to_phys(md->pfn), md->virtual); return; } - pgd = pgd_offset_k(addr); - end = addr + length; - do { - unsigned long next = pgd_addr_end(addr, end); + while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); - alloc_init_section(pgd, addr, next, phys, type); + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } + + /* N.B. ARMv6 supersections are only defined to work with domain 0. + * Since domain assignments can in fact be arbitrary, the + * 'domain == 0' check below is required to insure that ARMv6 + * supersections are only allocated for domain 0 regardless + * of the actual domain assignments in use. + */ + if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) + && domain == 0) { + /* + * Align to supersection boundary if !high pages. + * High pages have already been checked for proper + * alignment above and they will fail the SUPSERSECTION_MASK + * check because of the way the address is encoded into + * offset. + */ + if (md->pfn <= 0x100000) { + while ((virt & ~SUPERSECTION_MASK || + (virt + off) & ~SUPERSECTION_MASK) && + length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + } - phys += next - addr; - addr = next; - } while (pgd++, addr != end); + while (length >= SUPERSECTION_SIZE) { + alloc_init_supersection(virt, virt + off, prot_sect); + + virt += SUPERSECTION_SIZE; + length -= SUPERSECTION_SIZE; + } + } + + /* + * A section mapping covers half a "pgdir" entry. + */ + while (length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + + while (length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } } /* diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c index 8cd3a60954f0..05818fc0c705 100644 --- a/trunk/arch/arm/mm/nommu.c +++ b/trunk/arch/arm/mm/nommu.c @@ -62,21 +62,21 @@ void flush_dcache_page(struct page *page) } EXPORT_SYMBOL(flush_dcache_page); -void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, - size_t size, unsigned int mtype) +void __iomem *__ioremap_pfn(unsigned long pfn, unsigned long offset, + size_t size, unsigned long flags) { if (pfn >= (0x100000000ULL >> PAGE_SHIFT)) return NULL; return (void __iomem *) (offset + (pfn << PAGE_SHIFT)); } -EXPORT_SYMBOL(__arm_ioremap_pfn); +EXPORT_SYMBOL(__ioremap_pfn); -void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size, - unsigned int mtype) +void __iomem *__ioremap(unsigned long phys_addr, size_t size, + unsigned long flags) { return (void __iomem *)phys_addr; } -EXPORT_SYMBOL(__arm_ioremap); +EXPORT_SYMBOL(__ioremap); void __iounmap(volatile void __iomem *addr) { diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S index c156ddab9a2d..d29fe927ee9e 100644 --- a/trunk/arch/arm/mm/proc-xscale.S +++ b/trunk/arch/arm/mm/proc-xscale.S @@ -584,11 +584,6 @@ cpu_ixp42x_name: .asciz "XScale-IXP42x Family" .size cpu_ixp42x_name, . - cpu_ixp42x_name - .type cpu_ixp43x_name, #object -cpu_ixp43x_name: - .asciz "XScale-IXP43x Family" - .size cpu_ixp43x_name, . - cpu_ixp43x_name - .type cpu_ixp46x_name, #object cpu_ixp46x_name: .asciz "XScale-IXP46x Family" @@ -848,29 +843,6 @@ __ixp42x_proc_info: .long xscale_cache_fns .size __ixp42x_proc_info, . - __ixp42x_proc_info - .type __ixp43x_proc_info, #object -__ixp43x_proc_info: - .long 0x69054040 - .long 0xfffffff0 - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_ixp43x_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_cache_fns - .size __ixp43x_proc_info, . - __ixp43x_proc_info - .type __ixp46x_proc_info, #object __ixp46x_proc_info: .long 0x69054200 diff --git a/trunk/arch/arm/oprofile/backtrace.c b/trunk/arch/arm/oprofile/backtrace.c index f5ebf30151fa..7c22c12618cc 100644 --- a/trunk/arch/arm/oprofile/backtrace.c +++ b/trunk/arch/arm/oprofile/backtrace.c @@ -19,19 +19,6 @@ #include #include -#include "../kernel/stacktrace.h" - -static int report_trace(struct stackframe *frame, void *d) -{ - unsigned int *depth = d; - - if (*depth) { - oprofile_add_trace(frame->lr); - (*depth)--; - } - - return *depth == 0; -} /* * The registers we're interested in are at the end of the variable @@ -45,6 +32,21 @@ struct frame_tail { unsigned long lr; } __attribute__((packed)); + +#ifdef CONFIG_FRAME_POINTER +static struct frame_tail* kernel_backtrace(struct frame_tail *tail) +{ + oprofile_add_trace(tail->lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= tail->fp) + return NULL; + + return tail->fp-1; +} +#endif + static struct frame_tail* user_backtrace(struct frame_tail *tail) { struct frame_tail buftail[2]; @@ -65,14 +67,47 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail) return buftail[0].fp-1; } +/* + * | | /\ Higher addresses + * | | + * --------------- stack base (address of current_thread_info) + * | thread info | + * . . + * | stack | + * --------------- saved regs->ARM_fp value if valid (frame_tail address) + * . . + * --------------- struct pt_regs stored on stack (struct pt_regs *) + * | | + * . . + * | | + * --------------- %esp + * | | + * | | \/ Lower addresses + * + * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values + */ +static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) +{ + unsigned long tailaddr = (unsigned long)tail; + unsigned long stack = (unsigned long)regs; + unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; + + return (tailaddr > stack) && (tailaddr < stack_base); +} + void arm_backtrace(struct pt_regs * const regs, unsigned int depth) { - struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1; + struct frame_tail *tail; + + tail = ((struct frame_tail *) regs->ARM_fp) - 1; if (!user_mode(regs)) { - unsigned long base = ((unsigned long)regs) & ~(THREAD_SIZE - 1); - walk_stackframe(regs->ARM_fp, base, base + THREAD_SIZE, - report_trace, &depth); + +#ifdef CONFIG_FRAME_POINTER + while (depth-- && tail && valid_kernel_stack(tail, regs)) { + tail = kernel_backtrace(tail); + } +#endif return; } diff --git a/trunk/arch/arm/plat-iop/io.c b/trunk/arch/arm/plat-iop/io.c index 498675d028d0..f7eccecf2e47 100644 --- a/trunk/arch/arm/plat-iop/io.c +++ b/trunk/arch/arm/plat-iop/io.c @@ -22,7 +22,7 @@ #include void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size, - unsigned int mtype) + unsigned long flags) { void __iomem * retval; @@ -34,7 +34,7 @@ void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size, retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie); break; default: - retval = __arm_ioremap(cookie, size, mtype); + retval = __ioremap(cookie, size, flags); } return retval; diff --git a/trunk/arch/arm/plat-iop/pci.c b/trunk/arch/arm/plat-iop/pci.c index e2744b7227c5..b5f6ec35aafb 100644 --- a/trunk/arch/arm/plat-iop/pci.c +++ b/trunk/arch/arm/plat-iop/pci.c @@ -55,7 +55,7 @@ static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where) * This routine checks the status of the last configuration cycle. If an error * was detected it returns a 1, else it returns a 0. The errors being checked * are parity, master abort, target abort (master and target). These types of - * errors occur during a config cycle where there is no device, like during + * errors occure during a config cycle where there is no device, like during * the discovery stage. */ static int iop3xx_pci_status(void) @@ -223,111 +223,8 @@ struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys) return pci_scan_bus(sys->busnr, &iop3xx_ops, sys); } -void __init iop3xx_atu_setup(void) -{ - /* BAR 0 ( Disabled ) */ - *IOP3XX_IAUBAR0 = 0x0; - *IOP3XX_IABAR0 = 0x0; - *IOP3XX_IATVR0 = 0x0; - *IOP3XX_IALR0 = 0x0; - - /* BAR 1 ( Disabled ) */ - *IOP3XX_IAUBAR1 = 0x0; - *IOP3XX_IABAR1 = 0x0; - *IOP3XX_IALR1 = 0x0; - - /* BAR 2 (1:1 mapping with Physical RAM) */ - /* Set limit and enable */ - *IOP3XX_IALR2 = ~((u32)IOP3XX_MAX_RAM_SIZE - 1) & ~0x1; - *IOP3XX_IAUBAR2 = 0x0; - - /* Align the inbound bar with the base of memory */ - *IOP3XX_IABAR2 = PHYS_OFFSET | - PCI_BASE_ADDRESS_MEM_TYPE_64 | - PCI_BASE_ADDRESS_MEM_PREFETCH; - - *IOP3XX_IATVR2 = PHYS_OFFSET; - - /* Outbound window 0 */ - *IOP3XX_OMWTVR0 = IOP3XX_PCI_LOWER_MEM_PA; - *IOP3XX_OUMWTVR0 = 0; - - /* Outbound window 1 */ - *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE; - *IOP3XX_OUMWTVR1 = 0; - - /* BAR 3 ( Disabled ) */ - *IOP3XX_IAUBAR3 = 0x0; - *IOP3XX_IABAR3 = 0x0; - *IOP3XX_IATVR3 = 0x0; - *IOP3XX_IALR3 = 0x0; - - /* Setup the I/O Bar - */ - *IOP3XX_OIOWTVR = IOP3XX_PCI_LOWER_IO_PA;; - - /* Enable inbound and outbound cycles - */ - *IOP3XX_ATUCMD |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | - PCI_COMMAND_PARITY | PCI_COMMAND_SERR; - *IOP3XX_ATUCR |= IOP3XX_ATUCR_OUT_EN; -} - -void __init iop3xx_atu_disable(void) -{ - *IOP3XX_ATUCMD = 0; - *IOP3XX_ATUCR = 0; - - /* wait for cycles to quiesce */ - while (*IOP3XX_PCSR & (IOP3XX_PCSR_OUT_Q_BUSY | - IOP3XX_PCSR_IN_Q_BUSY)) - cpu_relax(); - - /* BAR 0 ( Disabled ) */ - *IOP3XX_IAUBAR0 = 0x0; - *IOP3XX_IABAR0 = 0x0; - *IOP3XX_IATVR0 = 0x0; - *IOP3XX_IALR0 = 0x0; - - /* BAR 1 ( Disabled ) */ - *IOP3XX_IAUBAR1 = 0x0; - *IOP3XX_IABAR1 = 0x0; - *IOP3XX_IALR1 = 0x0; - - /* BAR 2 ( Disabled ) */ - *IOP3XX_IAUBAR2 = 0x0; - *IOP3XX_IABAR2 = 0x0; - *IOP3XX_IATVR2 = 0x0; - *IOP3XX_IALR2 = 0x0; - - /* BAR 3 ( Disabled ) */ - *IOP3XX_IAUBAR3 = 0x0; - *IOP3XX_IABAR3 = 0x0; - *IOP3XX_IATVR3 = 0x0; - *IOP3XX_IALR3 = 0x0; - - /* Clear the outbound windows */ - *IOP3XX_OIOWTVR = 0; - - /* Outbound window 0 */ - *IOP3XX_OMWTVR0 = 0; - *IOP3XX_OUMWTVR0 = 0; - - /* Outbound window 1 */ - *IOP3XX_OMWTVR1 = 0; - *IOP3XX_OUMWTVR1 = 0; -} - -/* Flag to determine whether the ATU is initialized and the PCI bus scanned */ -int init_atu; - void iop3xx_pci_preinit(void) { - if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) { - iop3xx_atu_disable(); - iop3xx_atu_setup(); - } - DBG("PCI: Intel 803xx PCI init code.\n"); DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD); DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n", @@ -348,38 +245,3 @@ void iop3xx_pci_preinit(void) hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort"); } - -/* allow init_atu to be user overridden */ -static int __init iop3xx_init_atu_setup(char *str) -{ - init_atu = IOP3XX_INIT_ATU_DEFAULT; - if (str) { - while (*str != '\0') { - switch (*str) { - case 'y': - case 'Y': - init_atu = IOP3XX_INIT_ATU_ENABLE; - break; - case 'n': - case 'N': - init_atu = IOP3XX_INIT_ATU_DISABLE; - break; - case ',': - case '=': - break; - default: - printk(KERN_DEBUG "\"%s\" malformed at " - "character: \'%c\'", - __FUNCTION__, - *str); - *(str + 1) = '\0'; - } - str++; - } - } - - return 1; -} - -__setup("iop3xx_init_atu", iop3xx_init_atu_setup); - diff --git a/trunk/arch/arm/plat-iop/time.c b/trunk/arch/arm/plat-iop/time.c index 100d57ad98ed..16300adfb4de 100644 --- a/trunk/arch/arm/plat-iop/time.c +++ b/trunk/arch/arm/plat-iop/time.c @@ -32,22 +32,22 @@ static unsigned long next_jiffy_time; unsigned long iop_gettimeoffset(void) { - unsigned long offset, temp; + unsigned long offset, temp1, temp2; /* enable cp6, if necessary, to avoid taking the overhead of an * undefined instruction trap */ asm volatile ( "mrc p15, 0, %0, c15, c1, 0\n\t" - "tst %0, #(1 << 6)\n\t" + "ands %1, %0, #(1 << 6)\n\t" "orreq %0, %0, #(1 << 6)\n\t" "mcreq p15, 0, %0, c15, c1, 0\n\t" -#ifdef CONFIG_CPU_XSCALE +#ifdef CONFIG_XSCALE "mrceq p15, 0, %0, c15, c1, 0\n\t" "moveq %0, %0\n\t" "subeq pc, pc, #4\n\t" #endif - : "=r"(temp) : : "cc"); + : "=r"(temp1), "=r"(temp2) : : "cc"); offset = next_jiffy_time - read_tcr1(); @@ -75,7 +75,7 @@ iop_timer_interrupt(int irq, void *dev_id) static struct irqaction iop_timer_irq = { .name = "IOP Timer Tick", .handler = iop_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, }; void __init iop_init_time(unsigned long tick_rate) diff --git a/trunk/arch/arm/plat-omap/Kconfig b/trunk/arch/arm/plat-omap/Kconfig index 9e8d21eca4ec..f2dc363de66b 100644 --- a/trunk/arch/arm/plat-omap/Kconfig +++ b/trunk/arch/arm/plat-omap/Kconfig @@ -11,7 +11,6 @@ choice config ARCH_OMAP1 bool "TI OMAP1" - select GENERIC_CLOCKEVENTS config ARCH_OMAP2 bool "TI OMAP2" diff --git a/trunk/arch/arm/plat-omap/common.c b/trunk/arch/arm/plat-omap/common.c index fecd3d625995..57b7b93674a4 100644 --- a/trunk/arch/arm/plat-omap/common.c +++ b/trunk/arch/arm/plat-omap/common.c @@ -156,53 +156,3 @@ static int __init omap_add_serial_console(void) return add_preferred_console("ttyS", line, opt); } console_initcall(omap_add_serial_console); - - -/* - * 32KHz clocksource ... always available, on pretty most chips except - * OMAP 730 and 1510. Other timers could be used as clocksources, with - * higher resolution in free-running counter modes (e.g. 12 MHz xtal), - * but systems won't necessarily want to spend resources that way. - */ - -#if defined(CONFIG_ARCH_OMAP16XX) -#define TIMER_32K_SYNCHRONIZED 0xfffbc410 -#elif defined(CONFIG_ARCH_OMAP24XX) -#define TIMER_32K_SYNCHRONIZED 0x48004010 -#endif - -#ifdef TIMER_32K_SYNCHRONIZED - -#include - -static cycle_t omap_32k_read(void) -{ - return omap_readl(TIMER_32K_SYNCHRONIZED); -} - -static struct clocksource clocksource_32k = { - .name = "32k_counter", - .rating = 250, - .read = omap_32k_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 10, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init omap_init_clocksource_32k(void) -{ - static char err[] __initdata = KERN_ERR - "%s: can't register clocksource!\n"; - - if (cpu_is_omap16xx() || cpu_is_omap24xx()) { - clocksource_32k.mult = clocksource_hz2mult(32768, - clocksource_32k.shift); - - if (clocksource_register(&clocksource_32k)) - printk(err, clocksource_32k.name); - } - return 0; -} -arch_initcall(omap_init_clocksource_32k); - -#endif /* TIMER_32K_SYNCHRONIZED */ diff --git a/trunk/arch/arm/plat-omap/devices.c b/trunk/arch/arm/plat-omap/devices.c index eeb33fed6f7c..dbc3f44e07a6 100644 --- a/trunk/arch/arm/plat-omap/devices.c +++ b/trunk/arch/arm/plat-omap/devices.c @@ -429,10 +429,6 @@ static inline void omap_init_rng(void) {} */ static int __init omap_init_devices(void) { -/* - * Need to enable relevant once for 2430 SDP - */ -#ifndef CONFIG_MACH_OMAP_2430SDP /* please keep these calls, and their implementations above, * in alphabetical order so they're easier to sort through. */ @@ -442,7 +438,7 @@ static int __init omap_init_devices(void) omap_init_uwire(); omap_init_wdt(); omap_init_rng(); -#endif + return 0; } arch_initcall(omap_init_devices); diff --git a/trunk/arch/arm/plat-omap/dmtimer.c b/trunk/arch/arm/plat-omap/dmtimer.c index 659619f235ca..45f0439bffba 100644 --- a/trunk/arch/arm/plat-omap/dmtimer.c +++ b/trunk/arch/arm/plat-omap/dmtimer.c @@ -506,8 +506,6 @@ int omap_dm_timer_init(void) BUG_ON(dm_source_clocks[i] == NULL); } #endif - if (cpu_is_omap243x()) - dm_timers[0].phys_base = 0x49018000; for (i = 0; i < dm_timer_count; i++) { #ifdef CONFIG_ARCH_OMAP2 diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index 9dc6d3617bdb..b8c01de208b4 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -85,17 +86,10 @@ /* * omap24xx specific GPIO registers */ -#define OMAP242X_GPIO1_BASE (void __iomem *)0x48018000 -#define OMAP242X_GPIO2_BASE (void __iomem *)0x4801a000 -#define OMAP242X_GPIO3_BASE (void __iomem *)0x4801c000 -#define OMAP242X_GPIO4_BASE (void __iomem *)0x4801e000 - -#define OMAP243X_GPIO1_BASE (void __iomem *)0x4900C000 -#define OMAP243X_GPIO2_BASE (void __iomem *)0x4900E000 -#define OMAP243X_GPIO3_BASE (void __iomem *)0x49010000 -#define OMAP243X_GPIO4_BASE (void __iomem *)0x49012000 -#define OMAP243X_GPIO5_BASE (void __iomem *)0x480B6000 - +#define OMAP24XX_GPIO1_BASE (void __iomem *)0x48018000 +#define OMAP24XX_GPIO2_BASE (void __iomem *)0x4801a000 +#define OMAP24XX_GPIO3_BASE (void __iomem *)0x4801c000 +#define OMAP24XX_GPIO4_BASE (void __iomem *)0x4801e000 #define OMAP24XX_GPIO_REVISION 0x0000 #define OMAP24XX_GPIO_SYSCONFIG 0x0010 #define OMAP24XX_GPIO_SYSSTATUS 0x0014 @@ -124,18 +118,8 @@ struct gpio_bank { u16 virtual_irq_start; int method; u32 reserved_map; -#if defined (CONFIG_ARCH_OMAP16XX) || defined (CONFIG_ARCH_OMAP24XX) u32 suspend_wakeup; u32 saved_wakeup; -#endif -#ifdef CONFIG_ARCH_OMAP24XX - u32 non_wakeup_gpios; - u32 enabled_non_wakeup_gpios; - - u32 saved_datain; - u32 saved_fallingdetect; - u32 saved_risingdetect; -#endif spinlock_t lock; }; @@ -175,22 +159,12 @@ static struct gpio_bank gpio_bank_730[7] = { #endif #ifdef CONFIG_ARCH_OMAP24XX - -static struct gpio_bank gpio_bank_242x[4] = { - { OMAP242X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX }, - { OMAP242X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX }, - { OMAP242X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX }, - { OMAP242X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX }, -}; - -static struct gpio_bank gpio_bank_243x[5] = { - { OMAP243X_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX }, - { OMAP243X_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX }, - { OMAP243X_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX }, - { OMAP243X_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX }, - { OMAP243X_GPIO5_BASE, INT_24XX_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_24XX }, +static struct gpio_bank gpio_bank_24xx[4] = { + { OMAP24XX_GPIO1_BASE, INT_24XX_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_24XX }, + { OMAP24XX_GPIO2_BASE, INT_24XX_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_24XX }, + { OMAP24XX_GPIO3_BASE, INT_24XX_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_24XX }, + { OMAP24XX_GPIO4_BASE, INT_24XX_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_24XX }, }; - #endif static struct gpio_bank *gpio_bank; @@ -284,34 +258,21 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) u32 l; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_IO_CNTL; break; -#endif -#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_DIR_CONTROL; break; -#endif -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: reg += OMAP1610_GPIO_DIRECTION; break; -#endif -#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_DIR_CONTROL; break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_OE; break; -#endif - default: - WARN_ON(1); - return; } l = __raw_readl(reg); if (is_input) @@ -339,7 +300,6 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) u32 l = 0; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_OUTPUT; l = __raw_readl(reg); @@ -348,8 +308,6 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio); break; -#endif -#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_DATA_OUTPUT; l = __raw_readl(reg); @@ -358,8 +316,6 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio); break; -#endif -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: if (enable) reg += OMAP1610_GPIO_SET_DATAOUT; @@ -367,8 +323,6 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) reg += OMAP1610_GPIO_CLEAR_DATAOUT; l = 1 << gpio; break; -#endif -#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_DATA_OUTPUT; l = __raw_readl(reg); @@ -377,8 +331,6 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) else l &= ~(1 << gpio); break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: if (enable) reg += OMAP24XX_GPIO_SETDATAOUT; @@ -386,9 +338,8 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) reg += OMAP24XX_GPIO_CLEARDATAOUT; l = 1 << gpio; break; -#endif default: - WARN_ON(1); + BUG(); return; } __raw_writel(l, reg); @@ -412,37 +363,28 @@ int omap_get_gpio_datain(int gpio) void __iomem *reg; if (check_gpio(gpio) < 0) - return -EINVAL; + return -1; bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_INPUT_LATCH; break; -#endif -#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_DATA_INPUT; break; -#endif -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: reg += OMAP1610_GPIO_DATAIN; break; -#endif -#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_DATA_INPUT; break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_DATAIN; break; -#endif default: - return -EINVAL; + BUG(); + return -1; } return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; @@ -456,10 +398,8 @@ do { \ __raw_writel(l, base + reg); \ } while(0) -#ifdef CONFIG_ARCH_OMAP24XX -static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) +static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int trigger) { - void __iomem *base = bank->base; u32 gpio_bit = 1 << gpio; MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit, @@ -470,21 +410,9 @@ static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio, in trigger & __IRQT_RISEDGE); MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, trigger & __IRQT_FALEDGE); - if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { - if (trigger != 0) - __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_SETWKUENA); - else - __raw_writel(1 << gpio, bank->base + OMAP24XX_GPIO_CLEARWKUENA); - } else { - if (trigger != 0) - bank->enabled_non_wakeup_gpios |= gpio_bit; - else - bank->enabled_non_wakeup_gpios &= ~gpio_bit; - } /* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level * triggering requested. */ } -#endif static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) { @@ -492,7 +420,6 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) u32 l = 0; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_INT_EDGE; l = __raw_readl(reg); @@ -503,8 +430,6 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad; break; -#endif -#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_CONTROL; l = __raw_readl(reg); @@ -515,28 +440,22 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad; break; -#endif -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: if (gpio & 0x08) reg += OMAP1610_GPIO_EDGE_CTRL2; else reg += OMAP1610_GPIO_EDGE_CTRL1; gpio &= 0x07; + /* We allow only edge triggering, i.e. two lowest bits */ + if (trigger & (__IRQT_LOWLVL | __IRQT_HIGHLVL)) + BUG(); l = __raw_readl(reg); l &= ~(3 << (gpio << 1)); if (trigger & __IRQT_RISEDGE) l |= 2 << (gpio << 1); if (trigger & __IRQT_FALEDGE) l |= 1 << (gpio << 1); - if (trigger) - /* Enable wake-up during idle for dynamic tick */ - __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA); - else - __raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA); break; -#endif -#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_CONTROL; l = __raw_readl(reg); @@ -547,13 +466,11 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger) else goto bad; break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: - set_24xx_gpio_triggering(bank, gpio, trigger); + set_24xx_gpio_triggering(reg, gpio, trigger); break; -#endif default: + BUG(); goto bad; } __raw_writel(l, reg); @@ -568,7 +485,7 @@ static int gpio_irq_type(unsigned irq, unsigned type) unsigned gpio; int retval; - if (!cpu_is_omap24xx() && irq > IH_MPUIO_BASE) + if (irq > IH_MPUIO_BASE) gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); else gpio = irq - IH_GPIO_BASE; @@ -576,21 +493,14 @@ static int gpio_irq_type(unsigned irq, unsigned type) if (check_gpio(gpio) < 0) return -EINVAL; - if (type & ~IRQ_TYPE_SENSE_MASK) + if (type & IRQT_PROBE) return -EINVAL; - - /* OMAP1 allows only only edge triggering */ - if (!cpu_is_omap24xx() - && (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH))) + if (!cpu_is_omap24xx() && (type & (__IRQT_LOWLVL|__IRQT_HIGHLVL))) return -EINVAL; - bank = get_irq_chip_data(irq); + bank = get_gpio_bank(gpio); spin_lock(&bank->lock); retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type); - if (retval == 0) { - irq_desc[irq].status &= ~IRQ_TYPE_SENSE_MASK; - irq_desc[irq].status |= type; - } spin_unlock(&bank->lock); return retval; } @@ -600,34 +510,24 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) void __iomem *reg = bank->base; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: /* MPUIO irqstatus is reset by reading the status register, * so do nothing here */ return; -#endif -#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_STATUS; break; -#endif -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: reg += OMAP1610_GPIO_IRQSTATUS1; break; -#endif -#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_STATUS; break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_IRQSTATUS1; break; -#endif default: - WARN_ON(1); + BUG(); return; } __raw_writel(gpio_mask, reg); @@ -650,41 +550,31 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) u32 mask; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_MASKIT; mask = 0xffff; inv = 1; break; -#endif -#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_MASK; mask = 0xffff; inv = 1; break; -#endif -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: reg += OMAP1610_GPIO_IRQENABLE1; mask = 0xffff; break; -#endif -#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_MASK; mask = 0xffffffff; inv = 1; break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: reg += OMAP24XX_GPIO_IRQENABLE1; mask = 0xffffffff; break; -#endif default: - WARN_ON(1); + BUG(); return 0; } @@ -701,7 +591,6 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab u32 l; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP1 case METHOD_MPUIO: reg += OMAP_MPUIO_GPIO_MASKIT; l = __raw_readl(reg); @@ -710,8 +599,6 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask; break; -#endif -#ifdef CONFIG_ARCH_OMAP15XX case METHOD_GPIO_1510: reg += OMAP1510_GPIO_INT_MASK; l = __raw_readl(reg); @@ -720,8 +607,6 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask; break; -#endif -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: if (enable) reg += OMAP1610_GPIO_SET_IRQENABLE1; @@ -729,8 +614,6 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab reg += OMAP1610_GPIO_CLEAR_IRQENABLE1; l = gpio_mask; break; -#endif -#ifdef CONFIG_ARCH_OMAP730 case METHOD_GPIO_730: reg += OMAP730_GPIO_INT_MASK; l = __raw_readl(reg); @@ -739,8 +622,6 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab else l |= gpio_mask; break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: if (enable) reg += OMAP24XX_GPIO_SETIRQENABLE1; @@ -748,9 +629,8 @@ static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enab reg += OMAP24XX_GPIO_CLEARIRQENABLE1; l = gpio_mask; break; -#endif default: - WARN_ON(1); + BUG(); return; } __raw_writel(l, reg); @@ -772,39 +652,15 @@ static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int ena static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) { switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP16XX - case METHOD_MPUIO: case METHOD_GPIO_1610: - spin_lock(&bank->lock); - if (enable) { - bank->suspend_wakeup |= (1 << gpio); - enable_irq_wake(bank->irq); - } else { - disable_irq_wake(bank->irq); - bank->suspend_wakeup &= ~(1 << gpio); - } - spin_unlock(&bank->lock); - return 0; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: - if (bank->non_wakeup_gpios & (1 << gpio)) { - printk(KERN_ERR "Unable to modify wakeup on " - "non-wakeup GPIO%d\n", - (bank - gpio_bank) * 32 + gpio); - return -EINVAL; - } spin_lock(&bank->lock); - if (enable) { + if (enable) bank->suspend_wakeup |= (1 << gpio); - enable_irq_wake(bank->irq); - } else { - disable_irq_wake(bank->irq); + else bank->suspend_wakeup &= ~(1 << gpio); - } spin_unlock(&bank->lock); return 0; -#endif default: printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n", bank->method); @@ -829,7 +685,7 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) if (check_gpio(gpio) < 0) return -ENODEV; - bank = get_irq_chip_data(irq); + bank = get_gpio_bank(gpio); retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); return retval; @@ -865,6 +721,20 @@ int omap_request_gpio(int gpio) reg = bank->base + OMAP1510_GPIO_PIN_CONTROL; __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg); } +#endif +#ifdef CONFIG_ARCH_OMAP16XX + if (bank->method == METHOD_GPIO_1610) { + /* Enable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; + __raw_writel(1 << get_gpio_index(gpio), reg); + } +#endif +#ifdef CONFIG_ARCH_OMAP24XX + if (bank->method == METHOD_GPIO_24XX) { + /* Enable wake-up during idle for dynamic tick */ + void __iomem *reg = bank->base + OMAP24XX_GPIO_SETWKUENA; + __raw_writel(1 << get_gpio_index(gpio), reg); + } #endif spin_unlock(&bank->lock); @@ -925,10 +795,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) desc->chip->ack(irq); bank = get_irq_data(irq); -#ifdef CONFIG_ARCH_OMAP1 if (bank->method == METHOD_MPUIO) isr_reg = bank->base + OMAP_MPUIO_GPIO_INT; -#endif #ifdef CONFIG_ARCH_OMAP15XX if (bank->method == METHOD_GPIO_1510) isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS; @@ -1044,7 +912,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) static void gpio_irq_shutdown(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; - struct gpio_bank *bank = get_irq_chip_data(irq); + struct gpio_bank *bank = get_gpio_bank(gpio); _reset_gpio(bank, gpio); } @@ -1052,7 +920,7 @@ static void gpio_irq_shutdown(unsigned int irq) static void gpio_ack_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; - struct gpio_bank *bank = get_irq_chip_data(irq); + struct gpio_bank *bank = get_gpio_bank(gpio); _clear_gpio_irqstatus(bank, gpio); } @@ -1060,7 +928,7 @@ static void gpio_ack_irq(unsigned int irq) static void gpio_mask_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; - struct gpio_bank *bank = get_irq_chip_data(irq); + struct gpio_bank *bank = get_gpio_bank(gpio); _set_gpio_irqenable(bank, gpio, 0); } @@ -1069,27 +937,11 @@ static void gpio_unmask_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; unsigned int gpio_idx = get_gpio_index(gpio); - struct gpio_bank *bank = get_irq_chip_data(irq); + struct gpio_bank *bank = get_gpio_bank(gpio); _set_gpio_irqenable(bank, gpio_idx, 1); } -static struct irq_chip gpio_irq_chip = { - .name = "GPIO", - .shutdown = gpio_irq_shutdown, - .ack = gpio_ack_irq, - .mask = gpio_mask_irq, - .unmask = gpio_unmask_irq, - .set_type = gpio_irq_type, - .set_wake = gpio_wake_enable, -}; - -/*---------------------------------------------------------------------*/ - -#ifdef CONFIG_ARCH_OMAP1 - -/* MPUIO uses the always-on 32k clock */ - static void mpuio_ack_irq(unsigned int irq) { /* The ISR is reset automatically, so do nothing here. */ @@ -1098,7 +950,7 @@ static void mpuio_ack_irq(unsigned int irq) static void mpuio_mask_irq(unsigned int irq) { unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); - struct gpio_bank *bank = get_irq_chip_data(irq); + struct gpio_bank *bank = get_gpio_bank(gpio); _set_gpio_irqenable(bank, gpio, 0); } @@ -1106,108 +958,33 @@ static void mpuio_mask_irq(unsigned int irq) static void mpuio_unmask_irq(unsigned int irq) { unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE); - struct gpio_bank *bank = get_irq_chip_data(irq); + struct gpio_bank *bank = get_gpio_bank(gpio); _set_gpio_irqenable(bank, gpio, 1); } -static struct irq_chip mpuio_irq_chip = { - .name = "MPUIO", - .ack = mpuio_ack_irq, - .mask = mpuio_mask_irq, - .unmask = mpuio_unmask_irq, +static struct irq_chip gpio_irq_chip = { + .name = "GPIO", + .shutdown = gpio_irq_shutdown, + .ack = gpio_ack_irq, + .mask = gpio_mask_irq, + .unmask = gpio_unmask_irq, .set_type = gpio_irq_type, -#ifdef CONFIG_ARCH_OMAP16XX - /* REVISIT: assuming only 16xx supports MPUIO wake events */ .set_wake = gpio_wake_enable, -#endif -}; - - -#define bank_is_mpuio(bank) ((bank)->method == METHOD_MPUIO) - - -#ifdef CONFIG_ARCH_OMAP16XX - -#include - -static int omap_mpuio_suspend_late(struct platform_device *pdev, pm_message_t mesg) -{ - struct gpio_bank *bank = platform_get_drvdata(pdev); - void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; - - spin_lock(&bank->lock); - bank->saved_wakeup = __raw_readl(mask_reg); - __raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg); - spin_unlock(&bank->lock); - - return 0; -} - -static int omap_mpuio_resume_early(struct platform_device *pdev) -{ - struct gpio_bank *bank = platform_get_drvdata(pdev); - void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT; - - spin_lock(&bank->lock); - __raw_writel(bank->saved_wakeup, mask_reg); - spin_unlock(&bank->lock); - - return 0; -} - -/* use platform_driver for this, now that there's no longer any - * point to sys_device (other than not disturbing old code). - */ -static struct platform_driver omap_mpuio_driver = { - .suspend_late = omap_mpuio_suspend_late, - .resume_early = omap_mpuio_resume_early, - .driver = { - .name = "mpuio", - }, }; -static struct platform_device omap_mpuio_device = { - .name = "mpuio", - .id = -1, - .dev = { - .driver = &omap_mpuio_driver.driver, - } - /* could list the /proc/iomem resources */ +static struct irq_chip mpuio_irq_chip = { + .name = "MPUIO", + .ack = mpuio_ack_irq, + .mask = mpuio_mask_irq, + .unmask = mpuio_unmask_irq, + .set_type = gpio_irq_type, }; -static inline void mpuio_init(void) -{ - platform_set_drvdata(&omap_mpuio_device, &gpio_bank_1610[0]); - - if (platform_driver_register(&omap_mpuio_driver) == 0) - (void) platform_device_register(&omap_mpuio_device); -} - -#else -static inline void mpuio_init(void) {} -#endif /* 16xx */ - -#else - -extern struct irq_chip mpuio_irq_chip; - -#define bank_is_mpuio(bank) 0 -static inline void mpuio_init(void) {} - -#endif - -/*---------------------------------------------------------------------*/ - static int initialized; static struct clk * gpio_ick; static struct clk * gpio_fck; -#ifdef CONFIG_ARCH_OMAP2430 -static struct clk * gpio5_ick; -static struct clk * gpio5_fck; -#endif - static int __init _omap_gpio_init(void) { int i; @@ -1233,25 +1010,7 @@ static int __init _omap_gpio_init(void) printk("Could not get gpios_fck\n"); else clk_enable(gpio_fck); - - /* - * On 2430 GPIO 5 uses CORE L4 ICLK - */ -#ifdef CONFIG_ARCH_OMAP2430 - if (cpu_is_omap2430()) { - gpio5_ick = clk_get(NULL, "gpio5_ick"); - if (IS_ERR(gpio5_ick)) - printk("Could not get gpio5_ick\n"); - else - clk_enable(gpio5_ick); - gpio5_fck = clk_get(NULL, "gpio5_fck"); - if (IS_ERR(gpio5_fck)) - printk("Could not get gpio5_fck\n"); - else - clk_enable(gpio5_fck); - } -#endif -} + } #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap15xx()) { @@ -1278,24 +1037,14 @@ static int __init _omap_gpio_init(void) gpio_bank = gpio_bank_730; } #endif - #ifdef CONFIG_ARCH_OMAP24XX - if (cpu_is_omap242x()) { + if (cpu_is_omap24xx()) { int rev; gpio_bank_count = 4; - gpio_bank = gpio_bank_242x; - rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); - printk(KERN_INFO "OMAP242x GPIO hardware version %d.%d\n", - (rev >> 4) & 0x0f, rev & 0x0f); - } - if (cpu_is_omap243x()) { - int rev; - - gpio_bank_count = 5; - gpio_bank = gpio_bank_243x; + gpio_bank = gpio_bank_24xx; rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION); - printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n", + printk(KERN_INFO "OMAP24xx GPIO hardware version %d.%d\n", (rev >> 4) & 0x0f, rev & 0x0f); } #endif @@ -1306,8 +1055,9 @@ static int __init _omap_gpio_init(void) bank->reserved_map = 0; bank->base = IO_ADDRESS(bank->base); spin_lock_init(&bank->lock); - if (bank_is_mpuio(bank)) + if (bank->method == METHOD_MPUIO) { omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT); + } #ifdef CONFIG_ARCH_OMAP15XX if (bank->method == METHOD_GPIO_1510) { __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK); @@ -1331,25 +1081,15 @@ static int __init _omap_gpio_init(void) #endif #ifdef CONFIG_ARCH_OMAP24XX if (bank->method == METHOD_GPIO_24XX) { - static const u32 non_wakeup_gpios[] = { - 0xe203ffc0, 0x08700040 - }; - __raw_writel(0x00000000, bank->base + OMAP24XX_GPIO_IRQENABLE1); __raw_writel(0xffffffff, bank->base + OMAP24XX_GPIO_IRQSTATUS1); - __raw_writew(0x0015, bank->base + OMAP24XX_GPIO_SYSCONFIG); - /* Initialize interface clock ungated, module enabled */ - __raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL); - if (i < ARRAY_SIZE(non_wakeup_gpios)) - bank->non_wakeup_gpios = non_wakeup_gpios[i]; gpio_count = 32; } #endif for (j = bank->virtual_irq_start; j < bank->virtual_irq_start + gpio_count; j++) { - set_irq_chip_data(j, bank); - if (bank_is_mpuio(bank)) + if (bank->method == METHOD_MPUIO) set_irq_chip(j, &mpuio_irq_chip); else set_irq_chip(j, &gpio_irq_chip); @@ -1365,12 +1105,6 @@ static int __init _omap_gpio_init(void) if (cpu_is_omap16xx()) omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL); -#ifdef CONFIG_ARCH_OMAP24XX - /* Enable autoidle for the OCP interface */ - if (cpu_is_omap24xx()) - omap_writel(1 << 0, 0x48019010); -#endif - return 0; } @@ -1389,20 +1123,16 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg) void __iomem *wake_set; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE; wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA; wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; break; -#endif default: continue; } @@ -1430,18 +1160,14 @@ static int omap_gpio_resume(struct sys_device *dev) void __iomem *wake_set; switch (bank->method) { -#ifdef CONFIG_ARCH_OMAP16XX case METHOD_GPIO_1610: wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; break; -#endif -#ifdef CONFIG_ARCH_OMAP24XX case METHOD_GPIO_24XX: wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; break; -#endif default: continue; } @@ -1465,80 +1191,6 @@ static struct sys_device omap_gpio_device = { .id = 0, .cls = &omap_gpio_sysclass, }; - -#endif - -#ifdef CONFIG_ARCH_OMAP24XX - -static int workaround_enabled; - -void omap2_gpio_prepare_for_retention(void) -{ - int i, c = 0; - - /* Remove triggering for all non-wakeup GPIOs. Otherwise spurious - * IRQs will be generated. See OMAP2420 Errata item 1.101. */ - for (i = 0; i < gpio_bank_count; i++) { - struct gpio_bank *bank = &gpio_bank[i]; - u32 l1, l2; - - if (!(bank->enabled_non_wakeup_gpios)) - continue; - bank->saved_datain = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); - l1 = __raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT); - l2 = __raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT); - bank->saved_fallingdetect = l1; - bank->saved_risingdetect = l2; - l1 &= ~bank->enabled_non_wakeup_gpios; - l2 &= ~bank->enabled_non_wakeup_gpios; - __raw_writel(l1, bank->base + OMAP24XX_GPIO_FALLINGDETECT); - __raw_writel(l2, bank->base + OMAP24XX_GPIO_RISINGDETECT); - c++; - } - if (!c) { - workaround_enabled = 0; - return; - } - workaround_enabled = 1; -} - -void omap2_gpio_resume_after_retention(void) -{ - int i; - - if (!workaround_enabled) - return; - for (i = 0; i < gpio_bank_count; i++) { - struct gpio_bank *bank = &gpio_bank[i]; - u32 l; - - if (!(bank->enabled_non_wakeup_gpios)) - continue; - __raw_writel(bank->saved_fallingdetect, - bank->base + OMAP24XX_GPIO_FALLINGDETECT); - __raw_writel(bank->saved_risingdetect, - bank->base + OMAP24XX_GPIO_RISINGDETECT); - /* Check if any of the non-wakeup interrupt GPIOs have changed - * state. If so, generate an IRQ by software. This is - * horribly racy, but it's the best we can do to work around - * this silicon bug. */ - l = __raw_readl(bank->base + OMAP24XX_GPIO_DATAIN); - l ^= bank->saved_datain; - l &= bank->non_wakeup_gpios; - if (l) { - u32 old0, old1; - - old0 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0); - old1 = __raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1); - __raw_writel(old0 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT0); - __raw_writel(old1 | l, bank->base + OMAP24XX_GPIO_LEVELDETECT1); - __raw_writel(old0, bank->base + OMAP24XX_GPIO_LEVELDETECT0); - __raw_writel(old1, bank->base + OMAP24XX_GPIO_LEVELDETECT1); - } - } - -} - #endif /* @@ -1560,8 +1212,6 @@ static int __init omap_gpio_sysinit(void) if (!initialized) ret = _omap_gpio_init(); - mpuio_init(); - #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP24XX) if (cpu_is_omap16xx() || cpu_is_omap24xx()) { if (ret == 0) { @@ -1582,128 +1232,3 @@ EXPORT_SYMBOL(omap_set_gpio_dataout); EXPORT_SYMBOL(omap_get_gpio_datain); arch_initcall(omap_gpio_sysinit); - - -#ifdef CONFIG_DEBUG_FS - -#include -#include - -static int gpio_is_input(struct gpio_bank *bank, int mask) -{ - void __iomem *reg = bank->base; - - switch (bank->method) { - case METHOD_MPUIO: - reg += OMAP_MPUIO_IO_CNTL; - break; - case METHOD_GPIO_1510: - reg += OMAP1510_GPIO_DIR_CONTROL; - break; - case METHOD_GPIO_1610: - reg += OMAP1610_GPIO_DIRECTION; - break; - case METHOD_GPIO_730: - reg += OMAP730_GPIO_DIR_CONTROL; - break; - case METHOD_GPIO_24XX: - reg += OMAP24XX_GPIO_OE; - break; - } - return __raw_readl(reg) & mask; -} - - -static int dbg_gpio_show(struct seq_file *s, void *unused) -{ - unsigned i, j, gpio; - - for (i = 0, gpio = 0; i < gpio_bank_count; i++) { - struct gpio_bank *bank = gpio_bank + i; - unsigned bankwidth = 16; - u32 mask = 1; - - if (bank_is_mpuio(bank)) - gpio = OMAP_MPUIO(0); - else if (cpu_is_omap24xx() || cpu_is_omap730()) - bankwidth = 32; - - for (j = 0; j < bankwidth; j++, gpio++, mask <<= 1) { - unsigned irq, value, is_in, irqstat; - - if (!(bank->reserved_map & mask)) - continue; - - irq = bank->virtual_irq_start + j; - value = omap_get_gpio_datain(gpio); - is_in = gpio_is_input(bank, mask); - - if (bank_is_mpuio(bank)) - seq_printf(s, "MPUIO %2d: ", j); - else - seq_printf(s, "GPIO %3d: ", gpio); - seq_printf(s, "%s %s", - is_in ? "in " : "out", - value ? "hi" : "lo"); - - irqstat = irq_desc[irq].status; - if (is_in && ((bank->suspend_wakeup & mask) - || irqstat & IRQ_TYPE_SENSE_MASK)) { - char *trigger = NULL; - - switch (irqstat & IRQ_TYPE_SENSE_MASK) { - case IRQ_TYPE_EDGE_FALLING: - trigger = "falling"; - break; - case IRQ_TYPE_EDGE_RISING: - trigger = "rising"; - break; - case IRQ_TYPE_EDGE_BOTH: - trigger = "bothedge"; - break; - case IRQ_TYPE_LEVEL_LOW: - trigger = "low"; - break; - case IRQ_TYPE_LEVEL_HIGH: - trigger = "high"; - break; - case IRQ_TYPE_NONE: - trigger = "(unspecified)"; - break; - } - seq_printf(s, ", irq-%d %s%s", - irq, trigger, - (bank->suspend_wakeup & mask) - ? " wakeup" : ""); - } - seq_printf(s, "\n"); - } - - if (bank_is_mpuio(bank)) { - seq_printf(s, "\n"); - gpio = 0; - } - } - return 0; -} - -static int dbg_gpio_open(struct inode *inode, struct file *file) -{ - return single_open(file, dbg_gpio_show, &inode->i_private); -} - -static const struct file_operations debug_fops = { - .open = dbg_gpio_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int __init omap_gpio_debuginit(void) -{ - (void) debugfs_create_file("omap_gpio", S_IRUGO, - NULL, NULL, &debug_fops); - return 0; -} -late_initcall(omap_gpio_debuginit); -#endif diff --git a/trunk/arch/arm/plat-omap/mcbsp.c b/trunk/arch/arm/plat-omap/mcbsp.c index f7b9ccdaacbc..b8d6f17ff58f 100644 --- a/trunk/arch/arm/plat-omap/mcbsp.c +++ b/trunk/arch/arm/plat-omap/mcbsp.c @@ -225,16 +225,11 @@ static void omap_mcbsp_dsp_free(void) #ifdef CONFIG_ARCH_OMAP2 static void omap2_mcbsp2_mux_setup(void) { - if (cpu_is_omap2420()) { - omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); - omap_cfg_reg(R14_24XX_MCBSP2_FSX); - omap_cfg_reg(W15_24XX_MCBSP2_DR); - omap_cfg_reg(V15_24XX_MCBSP2_DX); - omap_cfg_reg(V14_24XX_GPIO117); - } - /* - * Need to add MUX settings for OMAP 2430 SDP - */ + omap_cfg_reg(Y15_24XX_MCBSP2_CLKX); + omap_cfg_reg(R14_24XX_MCBSP2_FSX); + omap_cfg_reg(W15_24XX_MCBSP2_DR); + omap_cfg_reg(V15_24XX_MCBSP2_DX); + omap_cfg_reg(V14_24XX_GPIO117); } #endif diff --git a/trunk/arch/arm/plat-omap/timer32k.c b/trunk/arch/arm/plat-omap/timer32k.c index 2feceec8eccd..265310601161 100644 --- a/trunk/arch/arm/plat-omap/timer32k.c +++ b/trunk/arch/arm/plat-omap/timer32k.c @@ -42,8 +42,6 @@ #include #include #include -#include -#include #include #include @@ -82,13 +80,13 @@ struct sys_timer omap_timer; #define OMAP1_32K_TIMER_TVR 0x00 #define OMAP1_32K_TIMER_TCR 0x04 -#define OMAP_32K_TICKS_PER_SEC (32768) +#define OMAP_32K_TICKS_PER_HZ (32768 / HZ) /* * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 * so with HZ = 128, TVR = 255. */ -#define OMAP_32K_TIMER_TICK_PERIOD ((OMAP_32K_TICKS_PER_SEC / HZ) - 1) +#define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ (((nr_jiffies) * (clock_rate)) / HZ) @@ -144,28 +142,6 @@ static inline void omap_32k_timer_ack_irq(void) #endif -static void omap_32k_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - switch (mode) { - case CLOCK_EVT_MODE_ONESHOT: - case CLOCK_EVT_MODE_PERIODIC: - omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - omap_32k_timer_stop(); - break; - } -} - -static struct clock_event_device clockevent_32k_timer = { - .name = "32k-timer", - .features = CLOCK_EVT_FEAT_PERIODIC, - .shift = 32, - .set_mode = omap_32k_timer_set_mode, -}; - /* * The 32KHz synchronized timer is an additional timer on 16xx. * It is always running. @@ -194,6 +170,15 @@ omap_32k_ticks_to_nsecs(unsigned long ticks_32k) static unsigned long omap_32k_last_tick = 0; +/* + * Returns elapsed usecs since last 32k timer interrupt + */ +static unsigned long omap_32k_timer_gettimeoffset(void) +{ + unsigned long now = omap_32k_sync_timer_read(); + return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); +} + /* * Returns current time from boot in nsecs. It's OK for this to wrap * around for now, as it's just a relative time stamp. @@ -203,26 +188,110 @@ unsigned long long sched_clock(void) return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); } -static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) +/* + * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this + * function is also called from other interrupts to remove latency + * issues with dynamic tick. In the dynamic tick case, we need to lock + * with irqsave. + */ +static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id) { - struct clock_event_device *evt = &clockevent_32k_timer; + unsigned long now; + omap_32k_timer_ack_irq(); + now = omap_32k_sync_timer_read(); + + while ((signed long)(now - omap_32k_last_tick) + >= OMAP_32K_TICKS_PER_HZ) { + omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; + timer_tick(); + } + + /* Restart timer so we don't drift off due to modulo or dynamic tick. + * By default we program the next timer to be continuous to avoid + * latencies during high system load. During dynamic tick operation the + * continuous timer can be overridden from pm_idle to be longer. + */ + omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); + + return IRQ_HANDLED; +} + +static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id) +{ + return _omap_32k_timer_interrupt(irq, dev_id); +} + +static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id) +{ + unsigned long flags; - evt->event_handler(evt); + write_seqlock_irqsave(&xtime_lock, flags); + _omap_32k_timer_interrupt(irq, dev_id); + write_sequnlock_irqrestore(&xtime_lock, flags); return IRQ_HANDLED; } +#ifdef CONFIG_NO_IDLE_HZ +/* + * Programs the next timer interrupt needed. Called when dynamic tick is + * enabled, and to reprogram the ticks to skip from pm_idle. Note that + * we can keep the timer continuous, and don't need to set it to run in + * one-shot mode. This is because the timer will get reprogrammed again + * after next interrupt. + */ +void omap_32k_timer_reprogram(unsigned long next_tick) +{ + unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1; + unsigned long now = omap_32k_sync_timer_read(); + unsigned long idled = now - omap_32k_last_tick; + + if (idled + 1 < ticks) + ticks -= idled; + else + ticks = 1; + omap_32k_timer_start(ticks); +} + +static struct irqaction omap_32k_timer_irq; +extern struct timer_update_handler timer_update; + +static int omap_32k_timer_enable_dyn_tick(void) +{ + /* No need to reprogram timer, just use the next interrupt */ + return 0; +} + +static int omap_32k_timer_disable_dyn_tick(void) +{ + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); + return 0; +} + +static struct dyn_tick_timer omap_dyn_tick_timer = { + .enable = omap_32k_timer_enable_dyn_tick, + .disable = omap_32k_timer_disable_dyn_tick, + .reprogram = omap_32k_timer_reprogram, + .handler = omap_32k_timer_handler, +}; +#endif /* CONFIG_NO_IDLE_HZ */ + static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = omap_32k_timer_interrupt, }; static __init void omap_init_32k_timer(void) { +#ifdef CONFIG_NO_IDLE_HZ + omap_timer.dyn_tick = &omap_dyn_tick_timer; +#endif + if (cpu_class_is_omap1()) setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); + omap_timer.offset = omap_32k_timer_gettimeoffset; omap_32k_last_tick = omap_32k_sync_timer_read(); #ifdef CONFIG_ARCH_OMAP2 @@ -239,16 +308,7 @@ static __init void omap_init_32k_timer(void) } #endif - clockevent_32k_timer.mult = div_sc(OMAP_32K_TICKS_PER_SEC, - NSEC_PER_SEC, - clockevent_32k_timer.shift); - clockevent_32k_timer.max_delta_ns = - clockevent_delta2ns(0xfffffffe, &clockevent_32k_timer); - clockevent_32k_timer.min_delta_ns = - clockevent_delta2ns(1, &clockevent_32k_timer); - - clockevent_32k_timer.cpumask = cpumask_of_cpu(0); - clockevents_register_device(&clockevent_32k_timer); + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); } /* @@ -266,4 +326,5 @@ static void __init omap_timer_init(void) struct sys_timer omap_timer = { .init = omap_timer_init, + .offset = NULL, /* Initialized later */ }; diff --git a/trunk/arch/arm/plat-s3c24xx/clock.c b/trunk/arch/arm/plat-s3c24xx/clock.c index 79cda0faec86..d3dc03a7383a 100644 --- a/trunk/arch/arm/plat-s3c24xx/clock.c +++ b/trunk/arch/arm/plat-s3c24xx/clock.c @@ -404,18 +404,6 @@ int s3c24xx_register_clock(struct clk *clk) return 0; } -int s3c24xx_register_clocks(struct clk **clks, int nr_clks) -{ - int fails = 0; - - for (; nr_clks > 0; nr_clks--, clks++) { - if (s3c24xx_register_clock(*clks) < 0) - fails++; - } - - return fails; -} - /* initalise all the clocks */ int __init s3c24xx_setup_clocks(unsigned long xtal, diff --git a/trunk/arch/arm/plat-s3c24xx/cpu.c b/trunk/arch/arm/plat-s3c24xx/cpu.c index 8ce4904d3131..6a2d1070e5a0 100644 --- a/trunk/arch/arm/plat-s3c24xx/cpu.c +++ b/trunk/arch/arm/plat-s3c24xx/cpu.c @@ -181,6 +181,24 @@ s3c_lookup_cpu(unsigned long idcode) return NULL; } +/* board information */ + +static struct s3c24xx_board *board; + +void s3c24xx_set_board(struct s3c24xx_board *b) +{ + int i; + + board = b; + + if (b->clocks_count != 0) { + struct clk **ptr = b->clocks; + + for (i = b->clocks_count; i > 0; i--, ptr++) + s3c24xx_register_clock(*ptr); + } +} + /* cpu information */ static struct cpu_table *cpu; @@ -324,6 +342,26 @@ static int __init s3c_arch_init(void) return ret; ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts); + if (ret != 0) + return ret; + + if (board != NULL) { + struct platform_device **ptr = board->devices; + int i; + + for (i = 0; i < board->devices_count; i++, ptr++) { + ret = platform_device_register(*ptr); + + if (ret) { + printk(KERN_ERR "s3c24xx: failed to add board device %s (%d) @%p\n", (*ptr)->name, ret, *ptr); + } + } + + /* mask any error, we may not need all these board + * devices */ + ret = 0; + } + return ret; } diff --git a/trunk/arch/arm/plat-s3c24xx/dma.c b/trunk/arch/arm/plat-s3c24xx/dma.c index 6f03c9370979..4540a806f522 100644 --- a/trunk/arch/arm/plat-s3c24xx/dma.c +++ b/trunk/arch/arm/plat-s3c24xx/dma.c @@ -44,7 +44,7 @@ static struct kmem_cache *dma_kmem; static int dma_channels; -static struct s3c24xx_dma_selection dma_sel; +struct s3c24xx_dma_selection dma_sel; /* dma channel state information */ struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; @@ -880,7 +880,7 @@ static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) return 0; } -static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan) +void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan) { unsigned long tmp; unsigned int timeout = 0x10000; @@ -957,7 +957,8 @@ static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan) return 0; } -static int s3c2410_dma_started(struct s3c2410_dma_chan *chan) +int +s3c2410_dma_started(struct s3c2410_dma_chan *chan) { unsigned long flags; @@ -1279,7 +1280,7 @@ static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long /* initialisation code */ -static int __init s3c24xx_dma_sysclass_init(void) +int __init s3c24xx_dma_sysclass_init(void) { int ret = sysdev_class_register(&dma_sysclass); @@ -1291,7 +1292,7 @@ static int __init s3c24xx_dma_sysclass_init(void) core_initcall(s3c24xx_dma_sysclass_init); -static int __init s3c24xx_dma_sysdev_register(void) +int __init s3c24xx_dma_sysdev_register(void) { struct s3c2410_dma_chan *cp = s3c2410_chans; int channel, ret; @@ -1395,7 +1396,7 @@ static struct s3c24xx_dma_order *dma_order; * channel */ -static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) +struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) { struct s3c24xx_dma_order_ch *ord = NULL; struct s3c24xx_dma_map *ch_map; diff --git a/trunk/arch/arm/plat-s3c24xx/irq.c b/trunk/arch/arm/plat-s3c24xx/irq.c index 8fbc88470261..ce186398e3fd 100644 --- a/trunk/arch/arm/plat-s3c24xx/irq.c +++ b/trunk/arch/arm/plat-s3c24xx/irq.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c b/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c index 2dbb2606d448..a0e39d894014 100644 --- a/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c +++ b/trunk/arch/arm/plat-s3c24xx/s3c244x-irq.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm/plat-s3c24xx/time.c b/trunk/arch/arm/plat-s3c24xx/time.c index b7667375bcec..c523d1c9cce5 100644 --- a/trunk/arch/arm/plat-s3c24xx/time.c +++ b/trunk/arch/arm/plat-s3c24xx/time.c @@ -138,7 +138,7 @@ s3c2410_timer_interrupt(int irq, void *dev_id) static struct irqaction s3c2410_timer_irq = { .name = "S3C2410 Timer Tick", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .handler = s3c2410_timer_interrupt, }; diff --git a/trunk/arch/arm/vfp/vfpdouble.c b/trunk/arch/arm/vfp/vfpdouble.c index 74e89f8fb3ab..e44b9ed0f81f 100644 --- a/trunk/arch/arm/vfp/vfpdouble.c +++ b/trunk/arch/arm/vfp/vfpdouble.c @@ -34,6 +34,7 @@ #include #include +#include #include #include "vfpinstr.h" diff --git a/trunk/arch/arm/vfp/vfpsingle.c b/trunk/arch/arm/vfp/vfpsingle.c index b252631b406b..0221ba3bc799 100644 --- a/trunk/arch/arm/vfp/vfpsingle.c +++ b/trunk/arch/arm/vfp/vfpsingle.c @@ -34,6 +34,7 @@ #include #include +#include #include #include "vfpinstr.h" diff --git a/trunk/arch/arm26/Kconfig b/trunk/arch/arm26/Kconfig index 20688bc13e9b..989113dce415 100644 --- a/trunk/arch/arm26/Kconfig +++ b/trunk/arch/arm26/Kconfig @@ -57,6 +57,9 @@ config GENERIC_CALIBRATE_DELAY bool default y +config GENERIC_BUST_SPINLOCK + bool + config ZONE_DMA bool default y diff --git a/trunk/arch/arm26/boot/compressed/misc.c b/trunk/arch/arm26/boot/compressed/misc.c index 0714d19c5776..f17f50e5516f 100644 --- a/trunk/arch/arm26/boot/compressed/misc.c +++ b/trunk/arch/arm26/boot/compressed/misc.c @@ -182,7 +182,7 @@ extern int end; static ulg free_mem_ptr; static ulg free_mem_ptr_end; -#define HEAP_SIZE 0x3000 +#define HEAP_SIZE 0x2000 #include "../../../../lib/inflate.c" diff --git a/trunk/arch/arm26/kernel/armksyms.c b/trunk/arch/arm26/kernel/armksyms.c index f735d7e018e4..93293d04b303 100644 --- a/trunk/arch/arm26/kernel/armksyms.c +++ b/trunk/arch/arm26/kernel/armksyms.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/arm26/kernel/ptrace.c b/trunk/arch/arm26/kernel/ptrace.c index 416927956721..9343889b27fe 100644 --- a/trunk/arch/arm26/kernel/ptrace.c +++ b/trunk/arch/arm26/kernel/ptrace.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/arm26/kernel/signal.c b/trunk/arch/arm26/kernel/signal.c index 379b82dc645f..6a8ef8da6dab 100644 --- a/trunk/arch/arm26/kernel/signal.c +++ b/trunk/arch/arm26/kernel/signal.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/arm26/mm/memc.c b/trunk/arch/arm26/mm/memc.c index 42505541a9b1..f2901581d4da 100644 --- a/trunk/arch/arm26/mm/memc.c +++ b/trunk/arch/arm26/mm/memc.c @@ -176,9 +176,13 @@ void __init pgtable_cache_init(void) { pte_cache = kmem_cache_create("pte-cache", sizeof(pte_t) * PTRS_PER_PTE, - 0, SLAB_PANIC, pte_cache_ctor, NULL); + 0, 0, pte_cache_ctor, NULL); + if (!pte_cache) + BUG(); pgd_cache = kmem_cache_create("pgd-cache", MEMC_TABLE_SIZE + sizeof(pgd_t) * PTRS_PER_PGD, - 0, SLAB_PANIC, pgd_cache_ctor, NULL); + 0, 0, pgd_cache_ctor, NULL); + if (!pgd_cache) + BUG(); } diff --git a/trunk/arch/avr32/kernel/kprobes.c b/trunk/arch/avr32/kernel/kprobes.c index 004c94b6fc1d..d0abbcaf1c1e 100644 --- a/trunk/arch/avr32/kernel/kprobes.c +++ b/trunk/arch/avr32/kernel/kprobes.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include DEFINE_PER_CPU(struct kprobe *, current_kprobe); diff --git a/trunk/arch/avr32/kernel/ptrace.c b/trunk/arch/avr32/kernel/ptrace.c index 8ac74dddbbde..6f4388f7c20b 100644 --- a/trunk/arch/avr32/kernel/ptrace.c +++ b/trunk/arch/avr32/kernel/ptrace.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -20,7 +21,7 @@ #include #include #include -#include +#include static struct pt_regs *get_user_regs(struct task_struct *tsk) { @@ -299,7 +300,7 @@ asmlinkage void do_debug_priv(struct pt_regs *regs) else die_val = DIE_BREAKPOINT; - if (notify_die(die_val, "ptrace", regs, 0, 0, SIGTRAP) == NOTIFY_STOP) + if (notify_die(die_val, regs, 0, SIGTRAP) == NOTIFY_STOP) return; if (likely(ds & DS_SSS)) { diff --git a/trunk/arch/avr32/kernel/traps.c b/trunk/arch/avr32/kernel/traps.c index 4de9edf96ed2..4f0382d8483f 100644 --- a/trunk/arch/avr32/kernel/traps.c +++ b/trunk/arch/avr32/kernel/traps.c @@ -20,6 +20,20 @@ #include #include +ATOMIC_NOTIFIER_HEAD(avr32_die_chain); + +int register_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&avr32_die_chain, nb); +} +EXPORT_SYMBOL(register_die_notifier); + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&avr32_die_chain, nb); +} +EXPORT_SYMBOL(unregister_die_notifier); + static DEFINE_SPINLOCK(die_lock); void NORET_TYPE die(const char *str, struct pt_regs *regs, long err) diff --git a/trunk/arch/avr32/mm/fault.c b/trunk/arch/avr32/mm/fault.c index 88b00b15970f..146ebdbdc302 100644 --- a/trunk/arch/avr32/mm/fault.c +++ b/trunk/arch/avr32/mm/fault.c @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig deleted file mode 100644 index 1a4930509325..000000000000 --- a/trunk/arch/blackfin/Kconfig +++ /dev/null @@ -1,989 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see Documentation/kbuild/kconfig-language.txt. -# - -mainmenu "uClinux/Blackfin (w/o MMU) Kernel Configuration" - -config MMU - bool - default n - -config FPU - bool - default n - -config RWSEM_GENERIC_SPINLOCK - bool - default y - -config RWSEM_XCHGADD_ALGORITHM - bool - default n - -config BLACKFIN - bool - default y - -config BFIN - bool - default y - -config SEMAPHORE_SLEEPERS - bool - default y - -config GENERIC_FIND_NEXT_BIT - bool - default y - -config GENERIC_HWEIGHT - bool - default y - -config GENERIC_HARDIRQS - bool - default y - -config GENERIC_IRQ_PROBE - bool - default y - -config GENERIC_TIME - bool - default n - -config GENERIC_CALIBRATE_DELAY - bool - default y - -config FORCE_MAX_ZONEORDER - int - default "14" - -config GENERIC_CALIBRATE_DELAY - bool - default y - -config IRQCHIP_DEMUX_GPIO - bool - default y - -source "init/Kconfig" -source "kernel/Kconfig.preempt" - -menu "Blackfin Processor Options" - -comment "Processor and Board Settings" - -choice - prompt "CPU" - default BF533 - -config BF531 - bool "BF531" - help - BF531 Processor Support. - -config BF532 - bool "BF532" - help - BF532 Processor Support. - -config BF533 - bool "BF533" - help - BF533 Processor Support. - -config BF534 - bool "BF534" - help - BF534 Processor Support. - -config BF536 - bool "BF536" - help - BF536 Processor Support. - -config BF537 - bool "BF537" - help - BF537 Processor Support. - -config BF561 - bool "BF561" - help - Not Supported Yet - Work in progress - BF561 Processor Support. - -endchoice - -choice - prompt "Silicon Rev" - default BF_REV_0_2 if BF537 - default BF_REV_0_3 if BF533 - -config BF_REV_0_2 - bool "0.2" - depends on (BF537 || BF536 || BF534) - -config BF_REV_0_3 - bool "0.3" - depends on (BF561 || BF537 || BF536 || BF534 || BF533 || BF532 || BF531) - -config BF_REV_0_4 - bool "0.4" - depends on (BF561 || BF533 || BF532 || BF531) - -config BF_REV_0_5 - bool "0.5" - depends on (BF561 || BF533 || BF532 || BF531) - -endchoice - -config BFIN_DUAL_CORE - bool - depends on (BF561) - default y - -config BFIN_SINGLE_CORE - bool - depends on !BFIN_DUAL_CORE - default y - -choice - prompt "System type" - default BFIN533_STAMP - help - Do NOT change the board here. Please use the top level - configuration to ensure that all the other settings are - correct. - -config BFIN533_EZKIT - bool "BF533-EZKIT" - depends on (BF533 || BF532 || BF531) - help - BF533-EZKIT-LITE board Support. - -config BFIN533_STAMP - bool "BF533-STAMP" - depends on (BF533 || BF532 || BF531) - help - BF533-STAMP board Support. - -config BFIN537_STAMP - bool "BF537-STAMP" - depends on (BF537 || BF536 || BF534) - help - BF537-STAMP board Support. - -config BFIN533_BLUETECHNIX_CM - bool "Bluetechnix CM-BF533" - depends on (BF533) - help - CM-BF533 support for EVAL- and DEV-Board. - -config BFIN537_BLUETECHNIX_CM - bool "Bluetechnix CM-BF537" - depends on (BF537) - help - CM-BF537 support for EVAL- and DEV-Board. - -config BFIN561_BLUETECHNIX_CM - bool "BF561-CM" - depends on (BF561) - help - CM-BF561 support for EVAL- and DEV-Board. - -config BFIN561_EZKIT - bool "BF561-EZKIT" - depends on (BF561) - help - BF561-EZKIT-LITE board Support. - -config PNAV10 - bool "PNAV 1.0 board" - depends on (BF537) - help - PNAV 1.0 board Support. - -config GENERIC_BOARD - bool "Custom" - depends on (BF537 || BF536 \ - || BF534 || BF561 || BF535 || BF533 || BF532 || BF531) - help - GENERIC or Custom board Support. - -endchoice - -config MEM_GENERIC_BOARD - bool - depends on GENERIC_BOARD - default y - -config MEM_MT48LC64M4A2FB_7E - bool - depends on (BFIN533_STAMP) - default y - -config MEM_MT48LC16M16A2TG_75 - bool - depends on (BFIN533_EZKIT || BFIN561_EZKIT \ - || BFIN533_BLUETECHNIX_CM || BFIN537_BLUETECHNIX_CM) - default y - -config MEM_MT48LC32M8A2_75 - bool - depends on (BFIN537_STAMP || PNAV10) - default y - -config MEM_MT48LC8M32B2B5_7 - bool - depends on (BFIN561_BLUETECHNIX_CM) - default y - -config BFIN_SHARED_FLASH_ENET - bool - depends on (BFIN533_STAMP) - default y - -source "arch/blackfin/mach-bf533/Kconfig" -source "arch/blackfin/mach-bf561/Kconfig" -source "arch/blackfin/mach-bf537/Kconfig" - -menu "Board customizations" - -config CMDLINE_BOOL - bool "Default bootloader kernel arguments" - -config CMDLINE - string "Initial kernel command string" - depends on CMDLINE_BOOL - default "console=ttyBF0,57600" - help - If you don't have a boot loader capable of passing a command line string - to the kernel, you may specify one here. As a minimum, you should specify - the memory size and the root device (e.g., mem=8M, root=/dev/nfs). - -comment "Board Setup" - -config CLKIN_HZ - int "Crystal Frequency in Hz" - default "11059200" if BFIN533_STAMP - default "27000000" if BFIN533_EZKIT - default "25000000" if BFIN537_STAMP - default "30000000" if BFIN561_EZKIT - default "24576000" if PNAV10 - help - The frequency of CLKIN crystal oscillator on the board in Hz. - -config MEM_SIZE - int "SDRAM Memory Size in MBytes" - default 32 if BFIN533_EZKIT - default 64 if BFIN537_STAMP - default 64 if BFIN561_EZKIT - default 128 if BFIN533_STAMP - default 64 if PNAV10 - -config MEM_ADD_WIDTH - int "SDRAM Memory Address Width" - default 9 if BFIN533_EZKIT - default 9 if BFIN561_EZKIT - default 10 if BFIN537_STAMP - default 11 if BFIN533_STAMP - default 10 if PNAV10 - -config ENET_FLASH_PIN - int "PF port/pin used for flash and ethernet sharing" - depends on (BFIN533_STAMP) - default 0 - help - PF port/pin used for flash and ethernet sharing to allow other PF - pins to be used on other platforms without having to touch common - code. - For example: PF0 --> 0,PF1 --> 1,PF2 --> 2, etc. - -config BOOT_LOAD - hex "Kernel load address for booting" - default "0x1000" - help - This option allows you to set the load address of the kernel. - This can be useful if you are on a board which has a small amount - of memory or you wish to reserve some memory at the beginning of - the address space. - - Note that you generally want to keep this value at or above 4k - (0x1000) as this will allow the kernel to capture NULL pointer - references. - -comment "LED Status Indicators" - depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) - -config BFIN_ALIVE_LED - bool "Enable Board Alive" - depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) - default n - help - Blink the LEDs you select when the kernel is running. Helps detect - a hung kernel. - -config BFIN_ALIVE_LED_NUM - int "LED" - depends on BFIN_ALIVE_LED - range 1 3 if BFIN533_STAMP - default "3" if BFIN533_STAMP - help - Select the LED (marked on the board) for you to blink. - -config BFIN_IDLE_LED - bool "Enable System Load/Idle LED" - depends on (BFIN533_STAMP || BFIN533_BLUETECHNIX_CM) - default n - help - Blinks the LED you select when to determine kernel load. - -config BFIN_IDLE_LED_NUM - int "LED" - depends on BFIN_IDLE_LED - range 1 3 if BFIN533_STAMP - default "2" if BFIN533_STAMP - help - Select the LED (marked on the board) for you to blink. - -# -# Sorry - but you need to put the hex address here - -# - -# Flag Data register -config BFIN_ALIVE_LED_PORT - hex - default 0xFFC00700 if (BFIN533_STAMP) - -# Peripheral Flag Direction Register -config BFIN_ALIVE_LED_DPORT - hex - default 0xFFC00730 if (BFIN533_STAMP) - -config BFIN_ALIVE_LED_PIN - hex - default 0x04 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 1) - default 0x08 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 2) - default 0x10 if (BFIN533_STAMP && BFIN_ALIVE_LED_NUM = 3) - -config BFIN_IDLE_LED_PORT - hex - default 0xFFC00700 if (BFIN533_STAMP) - -# Peripheral Flag Direction Register -config BFIN_IDLE_LED_DPORT - hex - default 0xFFC00730 if (BFIN533_STAMP) - -config BFIN_IDLE_LED_PIN - hex - default 0x04 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 1) - default 0x08 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 2) - default 0x10 if (BFIN533_STAMP && BFIN_IDLE_LED_NUM = 3) - -comment "Console UART Setup" - -choice - prompt "Baud Rate" - default BAUD_57600 -config BAUD_9600 - bool "9600" -config BAUD_19200 - bool "19200" -config BAUD_38400 - bool "38400" -config BAUD_57600 - bool "57600" -config BAUD_115200 - bool "115200" -endchoice - -choice - prompt "Parity" - default BAUD_NO_PARITY -config BAUD_NO_PARITY - bool "No Parity" -config BAUD_PARITY - bool "Parity" -endchoice - -choice - prompt "Stop Bits" - default BAUD_1_STOPBIT -config BAUD_1_STOPBIT - bool "1" -config BAUD_2_STOPBIT - bool "2" -endchoice - -endmenu - - -menu "Blackfin Kernel Optimizations" - -comment "Timer Tick" - -source kernel/Kconfig.hz - -comment "Memory Optimizations" - -config I_ENTRY_L1 - bool "Locate interrupt entry code in L1 Memory" - default y - help - If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked - into L1 instruction memory.(less latency) - -config EXCPT_IRQ_SYSC_L1 - bool "Locate entire ASM lowlevel excepetion / interrupt - Syscall and CPLB handler code in L1 Memory" - default y - help - If enabled entire ASM lowlevel exception and interrupt entry code (STORE/RESTORE CONTEXT) is linked - into L1 instruction memory.(less latency) - -config DO_IRQ_L1 - bool "Locate frequently called do_irq dispatcher function in L1 Memory" - default y - help - If enabled frequently called do_irq dispatcher function is linked - into L1 instruction memory.(less latency) - -config CORE_TIMER_IRQ_L1 - bool "Locate frequently called timer_interrupt() function in L1 Memory" - default y - help - If enabled frequently called timer_interrupt() function is linked - into L1 instruction memory.(less latency) - -config IDLE_L1 - bool "Locate frequently idle function in L1 Memory" - default y - help - If enabled frequently called idle function is linked - into L1 instruction memory.(less latency) - -config SCHEDULE_L1 - bool "Locate kernel schedule function in L1 Memory" - default y - help - If enabled frequently called kernel schedule is linked - into L1 instruction memory.(less latency) - -config ARITHMETIC_OPS_L1 - bool "Locate kernel owned arithmetic functions in L1 Memory" - default y - help - If enabled arithmetic functions are linked - into L1 instruction memory.(less latency) - -config ACCESS_OK_L1 - bool "Locate access_ok function in L1 Memory" - default y - help - If enabled access_ok function is linked - into L1 instruction memory.(less latency) - -config MEMSET_L1 - bool "Locate memset function in L1 Memory" - default y - help - If enabled memset function is linked - into L1 instruction memory.(less latency) - -config MEMCPY_L1 - bool "Locate memcpy function in L1 Memory" - default y - help - If enabled memcpy function is linked - into L1 instruction memory.(less latency) - -config SYS_BFIN_SPINLOCK_L1 - bool "Locate sys_bfin_spinlock function in L1 Memory" - default y - help - If enabled sys_bfin_spinlock function is linked - into L1 instruction memory.(less latency) - -config IP_CHECKSUM_L1 - bool "Locate IP Checksum function in L1 Memory" - default n - help - If enabled IP Checksum function is linked - into L1 instruction memory.(less latency) - -config CACHELINE_ALIGNED_L1 - bool "Locate cacheline_aligned data to L1 Data Memory" - default y - depends on !BF531 - help - If enabled cacheline_anligned data is linked - into L1 data memory.(less latency) - -config SYSCALL_TAB_L1 - bool "Locate Syscall Table L1 Data Memory" - default n - depends on !BF531 - help - If enabled the Syscall LUT is linked - into L1 data memory.(less latency) - -config CPLB_SWITCH_TAB_L1 - bool "Locate CPLB Switch Tables L1 Data Memory" - default n - depends on !BF531 - help - If enabled the CPLB Switch Tables are linked - into L1 data memory.(less latency) - -endmenu - - -choice - prompt "Kernel executes from" - help - Choose the memory type that the kernel will be running in. - -config RAMKERNEL - bool "RAM" - help - The kernel will be resident in RAM when running. - -config ROMKERNEL - bool "ROM" - help - The kernel will be resident in FLASH/ROM when running. - -endchoice - -source "mm/Kconfig" - -config LARGE_ALLOCS - bool "Allow allocating large blocks (> 1MB) of memory" - help - Allow the slab memory allocator to keep chains for very large - memory sizes - upto 32MB. You may need this if your system has - a lot of RAM, and you need to able to allocate very large - contiguous chunks. If unsure, say N. - -config BFIN_DMA_5XX - bool "Enable DMA Support" - depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561) - default y - help - DMA driver for BF5xx. - -choice - prompt "Uncached SDRAM region" - default DMA_UNCACHED_1M - depends BFIN_DMA_5XX -config DMA_UNCACHED_2M - bool "Enable 2M DMA region" -config DMA_UNCACHED_1M - bool "Enable 1M DMA region" -config DMA_UNCACHED_NONE - bool "Disable DMA region" -endchoice - - -comment "Cache Support" -config BLKFIN_CACHE - bool "Enable ICACHE" -config BLKFIN_DCACHE - bool "Enable DCACHE" -config BLKFIN_DCACHE_BANKA - bool "Enable only 16k BankA DCACHE - BankB is SRAM" - depends on BLKFIN_DCACHE && !BF531 - default n -config BLKFIN_CACHE_LOCK - bool "Enable Cache Locking" - -choice - prompt "Policy" - depends on BLKFIN_DCACHE - default BLKFIN_WB -config BLKFIN_WB - bool "Write back" - help - Write Back Policy: - Cached data will be written back to SDRAM only when needed. - This can give a nice increase in performance, but beware of - broken drivers that do not properly invalidate/flush their - cache. - - Write Through Policy: - Cached data will always be written back to SDRAM when the - cache is updated. This is a completely safe setting, but - performance is worse than Write Back. - - If you are unsure of the options and you want to be safe, - then go with Write Through. - -config BLKFIN_WT - bool "Write through" - help - Write Back Policy: - Cached data will be written back to SDRAM only when needed. - This can give a nice increase in performance, but beware of - broken drivers that do not properly invalidate/flush their - cache. - - Write Through Policy: - Cached data will always be written back to SDRAM when the - cache is updated. This is a completely safe setting, but - performance is worse than Write Back. - - If you are unsure of the options and you want to be safe, - then go with Write Through. - -endchoice - -config L1_MAX_PIECE - int "Set the max L1 SRAM pieces" - default 16 - help - Set the max memory pieces for the L1 SRAM allocation algorithm. - Min value is 16. Max value is 1024. - -menu "Clock Settings" - - -config BFIN_KERNEL_CLOCK - bool "Re-program Clocks while Kernel boots?" - default n - help - This option decides if kernel clocks are re-programed from the - bootloader settings. If the clocks are not set, the SDRAM settings - are also not changed, and the Bootloader does 100% of the hardware - configuration. - -config VCO_MULT - int "VCO Multiplier" - depends on BFIN_KERNEL_CLOCK - default "22" if BFIN533_EZKIT - default "45" if BFIN533_STAMP - default "20" if BFIN537_STAMP - default "22" if BFIN533_BLUETECHNIX_CM - default "20" if BFIN537_BLUETECHNIX_CM - default "20" if BFIN561_BLUETECHNIX_CM - default "20" if BFIN561_EZKIT - -config CCLK_DIV - int "Core Clock Divider" - depends on BFIN_KERNEL_CLOCK - default 1 if BFIN533_EZKIT - default 1 if BFIN533_STAMP - default 1 if BFIN537_STAMP - default 1 if BFIN533_BLUETECHNIX_CM - default 1 if BFIN537_BLUETECHNIX_CM - default 1 if BFIN561_BLUETECHNIX_CM - default 1 if BFIN561_EZKIT - -config SCLK_DIV - int "System Clock Divider" - depends on BFIN_KERNEL_CLOCK - default 5 if BFIN533_EZKIT - default 5 if BFIN533_STAMP - default 4 if BFIN537_STAMP - default 5 if BFIN533_BLUETECHNIX_CM - default 4 if BFIN537_BLUETECHNIX_CM - default 4 if BFIN561_BLUETECHNIX_CM - default 5 if BFIN561_EZKIT - -config CLKIN_HALF - bool "Half ClockIn" - depends on BFIN_KERNEL_CLOCK - default n - -config PLL_BYPASS - bool "Bypass PLL" - depends on BFIN_KERNEL_CLOCK - default n - -endmenu - -comment "Asynchonous Memory Configuration" - -menu "EBIU_AMBCTL Global Control" -config C_AMCKEN - bool "Enable CLKOUT" - default y - -config C_CDPRIO - bool "DMA has priority over core for ext. accesses" - default n - -config C_B0PEN - depends on BF561 - bool "Bank 0 16 bit packing enable" - default y - -config C_B1PEN - depends on BF561 - bool "Bank 1 16 bit packing enable" - default y - -config C_B2PEN - depends on BF561 - bool "Bank 2 16 bit packing enable" - default y - -config C_B3PEN - depends on BF561 - bool "Bank 3 16 bit packing enable" - default n - -choice - prompt"Enable Asynchonous Memory Banks" - default C_AMBEN_ALL - -config C_AMBEN - bool "Disable All Banks" - -config C_AMBEN_B0 - bool "Enable Bank 0" - -config C_AMBEN_B0_B1 - bool "Enable Bank 0 & 1" - -config C_AMBEN_B0_B1_B2 - bool "Enable Bank 0 & 1 & 2" - -config C_AMBEN_ALL - bool "Enable All Banks" -endchoice -endmenu - -menu "EBIU_AMBCTL Control" -config BANK_0 - hex "Bank 0" - default 0x7BB0 - -config BANK_1 - hex "Bank 1" - default 0x7BB0 - -config BANK_2 - hex "Bank 2" - default 0x7BB0 - -config BANK_3 - hex "Bank 3" - default 0x99B3 -endmenu - -endmenu - -############################################################################# -menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" - -config PCI - bool "PCI support" - help - Support for PCI bus. - -source "drivers/pci/Kconfig" - -config HOTPLUG - bool "Support for hot-pluggable device" - help - Say Y here if you want to plug devices into your computer while - the system is running, and be able to use them quickly. In many - cases, the devices can likewise be unplugged at any time too. - - One well known example of this is PCMCIA- or PC-cards, credit-card - size devices such as network cards, modems or hard drives which are - plugged into slots found on all modern laptop computers. Another - example, used on modern desktops as well as laptops, is USB. - - Enable HOTPLUG and KMOD, and build a modular kernel. Get agent - software (at ) and install it. - Then your kernel will automatically call out to a user mode "policy - agent" (/sbin/hotplug) to load modules and set up software needed - to use devices as you hotplug them. - -source "drivers/pcmcia/Kconfig" - -source "drivers/pci/hotplug/Kconfig" - -endmenu - -menu "Executable file formats" - -source "fs/Kconfig.binfmt" - -endmenu - -menu "Power management options" -source "kernel/power/Kconfig" - -choice - prompt "Select PM Wakeup Event Source" - default PM_WAKEUP_GPIO_BY_SIC_IWR - depends on PM - help - If you have a GPIO already configured as input with the corresponding PORTx_MASK - bit set - "Specify Wakeup Event by SIC_IWR value" - -config PM_WAKEUP_GPIO_BY_SIC_IWR - bool "Specify Wakeup Event by SIC_IWR value" -config PM_WAKEUP_BY_GPIO - bool "Cause Wakeup Event by GPIO" -config PM_WAKEUP_GPIO_API - bool "Configure Wakeup Event by PM GPIO API" - -endchoice - -config PM_WAKEUP_SIC_IWR - hex "Wakeup Events (SIC_IWR)" - depends on PM_WAKEUP_GPIO_BY_SIC_IWR - default 0x80000000 if (BF537 || BF536 || BF534) - default 0x100000 if (BF533 || BF532 || BF531) - -config PM_WAKEUP_GPIO_NUMBER - int "Wakeup GPIO number" - range 0 47 - depends on PM_WAKEUP_BY_GPIO - default 2 if BFIN537_STAMP - -choice - prompt "GPIO Polarity" - depends on PM_WAKEUP_BY_GPIO - default PM_WAKEUP_GPIO_POLAR_H -config PM_WAKEUP_GPIO_POLAR_H - bool "Active High" -config PM_WAKEUP_GPIO_POLAR_L - bool "Active Low" -config PM_WAKEUP_GPIO_POLAR_EDGE_F - bool "Falling EDGE" -config PM_WAKEUP_GPIO_POLAR_EDGE_R - bool "Rising EDGE" -config PM_WAKEUP_GPIO_POLAR_EDGE_B - bool "Both EDGE" -endchoice - -endmenu - -if (BF537 || BF533) - -menu "CPU Frequency scaling" - -source "drivers/cpufreq/Kconfig" - -config CPU_FREQ - bool - default n - help - If you want to enable this option, you should select the - DPMC driver from Character Devices. -endmenu - -endif - -source "net/Kconfig" - -source "drivers/Kconfig" - -source "fs/Kconfig" - -source "arch/blackfin/oprofile/Kconfig" - -menu "Kernel hacking" - -source "lib/Kconfig.debug" - -config DEBUG_HWERR - bool "Hardware error interrupt debugging" - depends on DEBUG_KERNEL - help - When enabled, the hardware error interrupt is never disabled, and - will happen immediately when an error condition occurs. This comes - at a slight cost in code size, but is necessary if you are getting - hardware error interrupts and need to know where they are coming - from. - -config DEBUG_ICACHE_CHECK - bool "Check Instruction cache coherancy" - depends on DEBUG_KERNEL - depends on DEBUG_HWERR - help - Say Y here if you are getting wierd unexplained errors. This will - ensure that icache is what SDRAM says it should be, by doing a - byte wise comparision between SDRAM and instruction cache. This - also relocates the irq_panic() function to L1 memory, (which is - un-cached). - -config DEBUG_KERNEL_START - bool "Debug Kernel Startup" - depends on DEBUG_KERNEL - help - Say Y here to put in an mini-execption handler before the kernel - replaces the bootloader exception handler. This will stop kernels - from dieing at startup with no visible error messages. - -config DEBUG_SERIAL_EARLY_INIT - bool "Initialize serial driver early" - default n - depends on SERIAL_BFIN - help - Say Y here if you want to get kernel output early when kernel - crashes before the normal console initialization. If this option - is enable, console output will always go to the ttyBF0, no matter - what kernel boot paramters you set. - -config DEBUG_HUNT_FOR_ZERO - bool "Catch NULL pointer reads/writes" - default y - help - Say Y here to catch reads/writes to anywhere in the memory range - from 0x0000 - 0x0FFF (the first 4k) of memory. This is useful in - catching common programming errors such as NULL pointer dereferences. - - Misbehaving applications will be killed (generate a SEGV) while the - kernel will trigger a panic. - - Enabling this option will take up an extra entry in CPLB table. - Otherwise, there is no extra overhead. - -config DEBUG_BFIN_NO_KERN_HWTRACE - bool "Trace user apps (turn off hwtrace in kernel)" - default n - help - Some pieces of the kernel contain a lot of flow changes which can - quickly fill up the hardware trace buffer. When debugging crashes, - the hardware trace may indicate that the problem lies in kernel - space when in reality an application is buggy. - - Say Y here to disable hardware tracing in some known "jumpy" pieces - of code so that the trace buffer will extend further back. - -config DUAL_CORE_TEST_MODULE - tristate "Dual Core Test Module" - depends on (BF561) - default n - help - Say Y here to build-in dual core test module for dual core test. - -config CPLB_INFO - bool "Display the CPLB information" - help - Display the CPLB information. - -config ACCESS_CHECK - bool "Check the user pointer address" - default y - help - Usually the pointer transfer from user space is checked to see if its - address is in the kernel space. - - Say N here to disable that check to improve the performance. - -endmenu - -source "security/Kconfig" - -source "crypto/Kconfig" - -source "lib/Kconfig" diff --git a/trunk/arch/blackfin/Makefile b/trunk/arch/blackfin/Makefile deleted file mode 100644 index 52d4dbdb2b1a..000000000000 --- a/trunk/arch/blackfin/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -# -# arch/blackfin/Makefile -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# - - -CROSS_COMPILE ?= bfin-uclinux- -LDFLAGS_vmlinux := -X -OBJCOPYFLAGS := -O binary -R .note -R .comment -S -GZFLAGS := -9 - -CFLAGS_MODULE += -mlong-calls -KALLSYMS += --symbol-prefix=_ - - -# setup the machine name and the machine dependent settings -machine-$(CONFIG_BF531) := bf533 -machine-$(CONFIG_BF532) := bf533 -machine-$(CONFIG_BF533) := bf533 -machine-$(CONFIG_BF534) := bf537 -machine-$(CONFIG_BF536) := bf537 -machine-$(CONFIG_BF537) := bf537 -machine-$(CONFIG_BF561) := bf561 -MACHINE := $(machine-y) -export MACHINE - - -head-y := arch/$(ARCH)/mach-$(MACHINE)/head.o arch/$(ARCH)/kernel/init_task.o - -core-y += arch/$(ARCH)/kernel/ arch/$(ARCH)/mm/ arch/$(ARCH)/mach-common/ - -# If we have a machine-specific directory, then include it in the build. -ifneq ($(machine-y),) -core-y += arch/$(ARCH)/mach-$(MACHINE)/ -core-y += arch/$(ARCH)/mach-$(MACHINE)/boards/ -endif - -libs-y += arch/$(ARCH)/lib/ - -drivers-$(CONFIG_OPROFILE) += arch/$(ARCH)/oprofile/ - - - -# Update machine arch symlinks if something which affects -# them changed. We use .mach to indicate when they were updated -# last, otherwise make uses the target directory mtime. - -include/asm-blackfin/.mach: $(wildcard include/config/arch/*.h) include/config/auto.conf - @echo ' SYMLINK include/asm-$(ARCH)/mach-$(MACHINE) -> include/asm-$(ARCH)/mach' -ifneq ($(KBUILD_SRC),) - $(Q)mkdir -p include/asm-$(ARCH) - $(Q)ln -fsn $(srctree)/include/asm-$(ARCH)/mach-$(MACHINE) include/asm-$(ARCH)/mach -else - $(Q)ln -fsn mach-$(MACHINE) include/asm-$(ARCH)/mach -endif - @touch $@ - -CLEAN_FILES += \ - include/asm-$(ARCH)/asm-offsets.h \ - arch/$(ARCH)/kernel/asm-offsets.s \ - include/asm-$(ARCH)/mach \ - include/asm-$(ARCH)/.mach - -archprepare: include/asm-blackfin/.mach -archclean: - $(Q)$(MAKE) $(clean)=$(boot) - - -all: vmImage -boot := arch/$(ARCH)/boot -BOOT_TARGETS = vmImage -.PHONY: $(BOOT_TARGETS) -$(BOOT_TARGETS): vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -define archhelp - echo '* vmImage - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)' -endef diff --git a/trunk/arch/blackfin/boot/Makefile b/trunk/arch/blackfin/boot/Makefile deleted file mode 100644 index 49e8098d4c21..000000000000 --- a/trunk/arch/blackfin/boot/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# arch/blackfin/boot/Makefile -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# - -MKIMAGE := $(srctree)/scripts/mkuboot.sh - -targets := vmImage -extra-y += vmlinux.bin vmlinux.gz - -quiet_cmd_uimage = UIMAGE $@ - cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \ - -C gzip -a $(CONFIG_BOOT_LOAD) -e $(CONFIG_BOOT_LOAD) -n 'Linux-$(KERNELRELEASE)' \ - -d $< $@ - -$(obj)/vmlinux.bin: vmlinux FORCE - $(call if_changed,objcopy) - -$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE - $(call if_changed,gzip) - -$(obj)/vmImage: $(obj)/vmlinux.gz - $(call if_changed,uimage) - @echo 'Kernel: $@ is ready' diff --git a/trunk/arch/blackfin/defconfig b/trunk/arch/blackfin/defconfig deleted file mode 100644 index d5904ca994cf..000000000000 --- a/trunk/arch/blackfin/defconfig +++ /dev/null @@ -1,1314 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.20 -# -# CONFIG_MMU is not set -# CONFIG_FPU is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_BFIN=y -CONFIG_SEMAPHORE_SLEEPERS=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_UCLINUX=y -CONFIG_FORCE_MAX_ZONEORDER=14 -CONFIG_IRQCHIP_DEMUX_GPIO=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -# CONFIG_LIMIT_PAGECACHE is not set -CONFIG_BUDDY=y -# CONFIG_NP2 is not set -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -# CONFIG_IOSCHED_DEADLINE is not set -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Blackfin Processor Options -# - -# -# Processor and Board Settings -# -# CONFIG_BF531 is not set -# CONFIG_BF532 is not set -# CONFIG_BF533 is not set -# CONFIG_BF534 is not set -# CONFIG_BF535 is not set -# CONFIG_BF536 is not set -CONFIG_BF537=y -# CONFIG_BF561 is not set -CONFIG_BF_REV_0_2=y -# CONFIG_BF_REV_0_3 is not set -# CONFIG_BF_REV_0_4 is not set -# CONFIG_BF_REV_0_5 is not set -CONFIG_BLACKFIN=y -CONFIG_BFIN_SINGLE_CORE=y -# CONFIG_BFIN533_EZKIT is not set -# CONFIG_BFIN533_STAMP is not set -CONFIG_BFIN537_STAMP=y -# CONFIG_BFIN533_BLUETECHNIX_CM is not set -# CONFIG_BFIN537_BLUETECHNIX_CM is not set -# CONFIG_BFIN561_BLUETECHNIX_CM is not set -# CONFIG_BFIN561_EZKIT is not set -# CONFIG_PNAV10 is not set -# CONFIG_GENERIC_BOARD is not set -CONFIG_MEM_MT48LC32M8A2_75=y -CONFIG_IRQ_PLL_WAKEUP=7 - -# -# BF537 Specific Configuration -# - -# -# PORT F/G Selection -# -CONFIG_BF537_PORT_F=y -# CONFIG_BF537_PORT_G is not set -# CONFIG_BF537_PORT_H is not set - -# -# Interrupt Priority Assignment -# - -# -# Priority -# -CONFIG_IRQ_DMA_ERROR=7 -CONFIG_IRQ_ERROR=7 -CONFIG_IRQ_RTC=8 -CONFIG_IRQ_PPI=8 -CONFIG_IRQ_SPORT0_RX=9 -CONFIG_IRQ_SPORT0_TX=9 -CONFIG_IRQ_SPORT1_RX=9 -CONFIG_IRQ_SPORT1_TX=9 -CONFIG_IRQ_TWI=10 -CONFIG_IRQ_SPI=10 -CONFIG_IRQ_UART0_RX=10 -CONFIG_IRQ_UART0_TX=10 -CONFIG_IRQ_UART1_RX=10 -CONFIG_IRQ_UART1_TX=10 -CONFIG_IRQ_CAN_RX=11 -CONFIG_IRQ_CAN_TX=11 -CONFIG_IRQ_MAC_RX=11 -CONFIG_IRQ_MAC_TX=11 -CONFIG_IRQ_TMR0=12 -CONFIG_IRQ_TMR1=12 -CONFIG_IRQ_TMR2=12 -CONFIG_IRQ_TMR3=12 -CONFIG_IRQ_TMR4=12 -CONFIG_IRQ_TMR5=12 -CONFIG_IRQ_TMR6=12 -CONFIG_IRQ_TMR7=12 -CONFIG_IRQ_PROG_INTA=12 -CONFIG_IRQ_PORTG_INTB=12 -CONFIG_IRQ_MEM_DMA0=13 -CONFIG_IRQ_MEM_DMA1=13 -CONFIG_IRQ_WATCH=13 - -# -# Board customizations -# - -# -# Board Setup -# -CONFIG_CLKIN_HZ=25000000 -CONFIG_MEM_SIZE=64 -CONFIG_MEM_ADD_WIDTH=10 -CONFIG_BOOT_LOAD=0x1000 - -# -# Console UART Setup -# -# CONFIG_BAUD_9600 is not set -# CONFIG_BAUD_19200 is not set -# CONFIG_BAUD_38400 is not set -CONFIG_BAUD_57600=y -# CONFIG_BAUD_115200 is not set -CONFIG_BAUD_NO_PARITY=y -# CONFIG_BAUD_PARITY is not set -CONFIG_BAUD_1_STOPBIT=y -# CONFIG_BAUD_2_STOPBIT is not set - -# -# Blackfin Kernel Optimizations -# - -# -# Timer Tick -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 - -# -# Memory Optimizations -# -CONFIG_I_ENTRY_L1=y -CONFIG_RAMKERNEL=y -# CONFIG_ROMKERNEL is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_LARGE_ALLOCS=y -CONFIG_BFIN_DMA_5XX=y -# CONFIG_DMA_UNCACHED_2M is not set -CONFIG_DMA_UNCACHED_1M=y -# CONFIG_DMA_UNCACHED_NONE is not set - -# -# Cache Support -# -CONFIG_BLKFIN_CACHE=y -CONFIG_BLKFIN_DCACHE=y -# CONFIG_BLKFIN_CACHE_LOCK is not set -# CONFIG_BLKFIN_WB is not set -CONFIG_BLKFIN_WT=y -CONFIG_L1_MAX_PIECE=16 - -# -# Clock Settings -# -# CONFIG_BFIN_KERNEL_CLOCK is not set - -# -# Asynchonous Memory Configuration -# - -# -# EBIU_AMBCTL Global Control -# -CONFIG_C_AMCKEN=y -CONFIG_C_CDPRIO=y -# CONFIG_C_AMBEN is not set -# CONFIG_C_AMBEN_B0 is not set -# CONFIG_C_AMBEN_B0_B1 is not set -# CONFIG_C_AMBEN_B0_B1_B2 is not set -CONFIG_C_AMBEN_ALL=y - -# -# EBIU_AMBCTL Control -# -CONFIG_BANK_0=0x7BB0 -CONFIG_BANK_1=0x7BB0 -CONFIG_BANK_2=0x7BB0 -CONFIG_BANK_3=0x99B3 - -# -# Bus options (PCI, PCMCIA, EISA, MCA, ISA) -# -# CONFIG_PCI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF_FDPIC=y -CONFIG_BINFMT_FLAT=y -CONFIG_BINFMT_ZFLAT=y -# CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options -# -CONFIG_PM=y -CONFIG_PM_LEGACY=y -# CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set -CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR=y -# CONFIG_PM_WAKEUP_BY_GPIO is not set -# CONFIG_PM_WAKEUP_GPIO_API is not set -CONFIG_PM_WAKEUP_SIC_IWR=0x80000000 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETLABEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -CONFIG_IRDA=m - -# -# IrDA protocols -# -CONFIG_IRLAN=m -CONFIG_IRCOMM=m -# CONFIG_IRDA_ULTRA is not set - -# -# IrDA options -# -CONFIG_IRDA_CACHE_LAST_LSAP=y -# CONFIG_IRDA_FAST_RR is not set -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# - -# -# SIR device drivers -# -CONFIG_IRTTY_SIR=m - -# -# Dongle support -# -# CONFIG_DONGLE is not set - -# -# Old SIR device drivers -# -# CONFIG_IRPORT_SIR is not set - -# -# Old Serial dongle support -# - -# -# FIR device drivers -# -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=m -CONFIG_MTD_GEN_PROBE=m -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_MW320D=m -CONFIG_MTD_RAM=y -CONFIG_MTD_ROM=m -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -CONFIG_MTD_COMPLEX_MAPPINGS=y -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_BF5xx=m -CONFIG_BFIN_FLASH_SIZE=0x400000 -CONFIG_EBIU_FLASH_BASE=0x20000000 - -# -# FLASH_EBIU_AMBCTL Control -# -CONFIG_BFIN_FLASH_BANK_0=0x7BB0 -CONFIG_BFIN_FLASH_BANK_1=0x7BB0 -CONFIG_BFIN_FLASH_BANK_2=0x7BB0 -CONFIG_BFIN_FLASH_BANK_3=0x7BB0 -CONFIG_MTD_UCLINUX=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_M25P80 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -CONFIG_MTD_NAND=m -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -# CONFIG_MTD_NAND_ECC_SMC is not set -CONFIG_MTD_NAND_BFIN=m -CONFIG_BFIN_NAND_BASE=0x20212000 -CONFIG_BFIN_NAND_CLE=2 -CONFIG_BFIN_NAND_ALE=1 -CONFIG_BFIN_NAND_READY=3 -CONFIG_MTD_NAND_IDS=m -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_SMC91X is not set -CONFIG_BFIN_MAC=y -CONFIG_BFIN_MAC_USE_L1=y -CONFIG_BFIN_TX_DESC_NUM=10 -CONFIG_BFIN_RX_DESC_NUM=20 -# CONFIG_BFIN_MAC_RMII is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=m -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -CONFIG_INPUT_MISC=y -# CONFIG_INPUT_UINPUT is not set -# CONFIG_BF53X_PFBUTTONS is not set -CONFIG_TWI_KEYPAD=m -CONFIG_BFIN_TWIKEYPAD_IRQ_PFX=72 - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_AD9960 is not set -# CONFIG_SPI_ADC_BF533 is not set -# CONFIG_BF533_PFLAGS is not set -# CONFIG_BF5xx_PPIFCD is not set -# CONFIG_BF5xx_TIMERS is not set -# CONFIG_BF5xx_PPI is not set -CONFIG_BFIN_SPORT=y -# CONFIG_BFIN_TIMER_LATENCY is not set -CONFIG_TWI_LCD=m -CONFIG_TWI_LCD_SLAVE_ADDR=34 -# CONFIG_AD5304 is not set -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_BFIN=y -CONFIG_SERIAL_BFIN_CONSOLE=y -CONFIG_SERIAL_BFIN_DMA=y -# CONFIG_SERIAL_BFIN_PIO is not set -CONFIG_SERIAL_BFIN_UART0=y -# CONFIG_BFIN_UART0_CTSRTS is not set -# CONFIG_SERIAL_BFIN_UART1 is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_BFIN_SPORT is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# CAN, the car bus and industrial fieldbus -# -CONFIG_CAN4LINUX=y - -# -# linux embedded drivers -# -# CONFIG_CAN_MCF5282 is not set -# CONFIG_CAN_UNCTWINCAN is not set -CONFIG_CAN_BLACKFIN=m - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -CONFIG_BLACKFIN_DPMC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_CHARDEV=m - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_BFIN_GPIO is not set -CONFIG_I2C_BFIN_TWI=m -CONFIG_TWICLK_KHZ=50 -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -CONFIG_SENSORS_AD5252=m -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8575 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -CONFIG_SPI=y -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -# CONFIG_SPI_BITBANG is not set -CONFIG_SPI_BFIN=y - -# -# SPI Protocol Masters -# - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FIRMWARE_EDID=y -CONFIG_FB=m -CONFIG_FB_CFB_FILLRECT=m -CONFIG_FB_CFB_COPYAREA=m -CONFIG_FB_CFB_IMAGEBLIT=m -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_BFIN_7171=m -CONFIG_FB_BFIN_7393=m -CONFIG_NTSC=y -# CONFIG_PAL is not set -# CONFIG_NTSC_640x480 is not set -# CONFIG_PAL_640x480 is not set -# CONFIG_NTSC_YCBCR is not set -# CONFIG_PAL_YCBCR is not set -CONFIG_ADV7393_1XMEM=y -# CONFIG_ADV7393_2XMEM is not set -CONFIG_FB_BF537_LQ035=m -CONFIG_LQ035_SLAVE_ADDR=0x58 -# CONFIG_FB_BFIN_LANDSCAPE is not set -# CONFIG_FB_BFIN_BGR is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_BACKLIGHT_CLASS_DEVICE=m -CONFIG_BACKLIGHT_DEVICE=y -CONFIG_LCD_CLASS_DEVICE=m -CONFIG_LCD_DEVICE=y - -# -# Sound -# -CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m -# CONFIG_SND_SEQUENCER is not set -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set - -# -# HID Devices -# -CONFIG_HID=y - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_SPI_MMC is not set -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_X1205 is not set -# CONFIG_RTC_DRV_DS1307 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_ISL1208 is not set -# CONFIG_RTC_DRV_DS1672 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_PCF8563 is not set -# CONFIG_RTC_DRV_PCF8583 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTC_DRV_RS5C372 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_V3020 is not set -CONFIG_RTC_DRV_BFIN=y - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Virtualization -# - -# -# PBX support -# -# CONFIG_PBX is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -# CONFIG_EXT2_FS_POSIX_ACL is not set -# CONFIG_EXT2_FS_SECURITY is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_YAFFS_FS=m -CONFIG_YAFFS_YAFFS1=y -# CONFIG_YAFFS_DOES_ECC is not set -CONFIG_YAFFS_YAFFS2=y -CONFIG_YAFFS_AUTO_YAFFS2=y -# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set -CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10 -# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set -# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set -CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y -CONFIG_JFFS2_FS=m -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=m -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_DEBUG_HUNT_FOR_ZERO=y -# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set -# CONFIG_BOOTPARAM is not set -# CONFIG_NO_KERNEL_MSG is not set -CONFIG_CPLB_INFO=y -# CONFIG_NO_ACCESS_CHECK is not set - -# -# Security options -# -# CONFIG_KEYS is not set -CONFIG_SECURITY=y -# CONFIG_SECURITY_NETWORK is not set -CONFIG_SECURITY_CAPABILITIES=y - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y diff --git a/trunk/arch/blackfin/kernel/Makefile b/trunk/arch/blackfin/kernel/Makefile deleted file mode 100644 index f3b7d2f9d49c..000000000000 --- a/trunk/arch/blackfin/kernel/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# arch/blackfin/kernel/Makefile -# - -extra-y := init_task.o vmlinux.lds - -obj-y := \ - entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ - sys_bfin.o time.o traps.o irqchip.o dma-mapping.o bfin_gpio.o \ - flat.o - -obj-$(CONFIG_MODULES) += module.o -obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o -obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o diff --git a/trunk/arch/blackfin/kernel/asm-offsets.c b/trunk/arch/blackfin/kernel/asm-offsets.c deleted file mode 100644 index 41d9a9f89700..000000000000 --- a/trunk/arch/blackfin/kernel/asm-offsets.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * File: arch/blackfin/kernel/asm-offsets.c - * Based on: - * Author: - * - * Created: - * Description: generate definitions needed by assembly language modules. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DEFINE(sym, val) \ - asm volatile("\n->" #sym " %0 " #val : : "i" (val)) - -int main(void) -{ - /* offsets into the task struct */ - DEFINE(TASK_STATE, offsetof(struct task_struct, state)); - DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); - DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); - DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked)); - DEFINE(TASK_THREAD, offsetof(struct task_struct, thread)); - DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info)); - DEFINE(TASK_MM, offsetof(struct task_struct, mm)); - DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); - DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending)); - - /* offsets into the irq_cpustat_t struct */ - DEFINE(CPUSTAT_SOFTIRQ_PENDING, - offsetof(irq_cpustat_t, __softirq_pending)); - - /* offsets into the thread struct */ - DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp)); - DEFINE(THREAD_USP, offsetof(struct thread_struct, usp)); - DEFINE(THREAD_SR, offsetof(struct thread_struct, seqstat)); - DEFINE(PT_SR, offsetof(struct thread_struct, seqstat)); - DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); - DEFINE(THREAD_PC, offsetof(struct thread_struct, pc)); - DEFINE(KERNEL_STACK_SIZE, THREAD_SIZE); - - /* offsets into the pt_regs */ - DEFINE(PT_ORIG_P0, offsetof(struct pt_regs, orig_p0)); - DEFINE(PT_ORIG_PC, offsetof(struct pt_regs, orig_pc)); - DEFINE(PT_R0, offsetof(struct pt_regs, r0)); - DEFINE(PT_R1, offsetof(struct pt_regs, r1)); - DEFINE(PT_R2, offsetof(struct pt_regs, r2)); - DEFINE(PT_R3, offsetof(struct pt_regs, r3)); - DEFINE(PT_R4, offsetof(struct pt_regs, r4)); - DEFINE(PT_R5, offsetof(struct pt_regs, r5)); - DEFINE(PT_R6, offsetof(struct pt_regs, r6)); - DEFINE(PT_R7, offsetof(struct pt_regs, r7)); - - DEFINE(PT_P0, offsetof(struct pt_regs, p0)); - DEFINE(PT_P1, offsetof(struct pt_regs, p1)); - DEFINE(PT_P2, offsetof(struct pt_regs, p2)); - DEFINE(PT_P3, offsetof(struct pt_regs, p3)); - DEFINE(PT_P4, offsetof(struct pt_regs, p4)); - DEFINE(PT_P5, offsetof(struct pt_regs, p5)); - - DEFINE(PT_FP, offsetof(struct pt_regs, fp)); - DEFINE(PT_USP, offsetof(struct pt_regs, usp)); - DEFINE(PT_I0, offsetof(struct pt_regs, i0)); - DEFINE(PT_I1, offsetof(struct pt_regs, i1)); - DEFINE(PT_I2, offsetof(struct pt_regs, i2)); - DEFINE(PT_I3, offsetof(struct pt_regs, i3)); - DEFINE(PT_M0, offsetof(struct pt_regs, m0)); - DEFINE(PT_M1, offsetof(struct pt_regs, m1)); - DEFINE(PT_M2, offsetof(struct pt_regs, m2)); - DEFINE(PT_M3, offsetof(struct pt_regs, m3)); - DEFINE(PT_L0, offsetof(struct pt_regs, l0)); - DEFINE(PT_L1, offsetof(struct pt_regs, l1)); - DEFINE(PT_L2, offsetof(struct pt_regs, l2)); - DEFINE(PT_L3, offsetof(struct pt_regs, l3)); - DEFINE(PT_B0, offsetof(struct pt_regs, b0)); - DEFINE(PT_B1, offsetof(struct pt_regs, b1)); - DEFINE(PT_B2, offsetof(struct pt_regs, b2)); - DEFINE(PT_B3, offsetof(struct pt_regs, b3)); - DEFINE(PT_A0X, offsetof(struct pt_regs, a0x)); - DEFINE(PT_A0W, offsetof(struct pt_regs, a0w)); - DEFINE(PT_A1X, offsetof(struct pt_regs, a1x)); - DEFINE(PT_A1W, offsetof(struct pt_regs, a1w)); - DEFINE(PT_LC0, offsetof(struct pt_regs, lc0)); - DEFINE(PT_LC1, offsetof(struct pt_regs, lc1)); - DEFINE(PT_LT0, offsetof(struct pt_regs, lt0)); - DEFINE(PT_LT1, offsetof(struct pt_regs, lt1)); - DEFINE(PT_LB0, offsetof(struct pt_regs, lb0)); - DEFINE(PT_LB1, offsetof(struct pt_regs, lb1)); - DEFINE(PT_ASTAT, offsetof(struct pt_regs, astat)); - DEFINE(PT_RESERVED, offsetof(struct pt_regs, reserved)); - DEFINE(PT_RETS, offsetof(struct pt_regs, rets)); - DEFINE(PT_PC, offsetof(struct pt_regs, pc)); - DEFINE(PT_RETX, offsetof(struct pt_regs, retx)); - DEFINE(PT_RETN, offsetof(struct pt_regs, retn)); - DEFINE(PT_RETE, offsetof(struct pt_regs, rete)); - DEFINE(PT_SEQSTAT, offsetof(struct pt_regs, seqstat)); - DEFINE(PT_SYSCFG, offsetof(struct pt_regs, syscfg)); - DEFINE(PT_IPEND, offsetof(struct pt_regs, ipend)); - DEFINE(SIZEOF_PTREGS, sizeof(struct pt_regs)); - DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs)); /* Needed by gdb */ - DEFINE(PT_TEXT_END_ADDR, 4 + sizeof(struct pt_regs));/* Needed by gdb */ - DEFINE(PT_DATA_ADDR, 8 + sizeof(struct pt_regs)); /* Needed by gdb */ - DEFINE(PT_FDPIC_EXEC, 12 + sizeof(struct pt_regs)); /* Needed by gdb */ - DEFINE(PT_FDPIC_INTERP, 16 + sizeof(struct pt_regs));/* Needed by gdb */ - - /* signal defines */ - DEFINE(SIGSEGV, SIGSEGV); - DEFINE(SIGTRAP, SIGTRAP); - - return 0; -} diff --git a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c b/trunk/arch/blackfin/kernel/bfin_dma_5xx.c deleted file mode 100644 index 8ea079ebecb5..000000000000 --- a/trunk/arch/blackfin/kernel/bfin_dma_5xx.c +++ /dev/null @@ -1,742 +0,0 @@ -/* - * File: arch/blackfin/kernel/bfin_dma_5xx.c - * Based on: - * Author: - * - * Created: - * Description: This file contains the simple DMA Implementation for Blackfin - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* Remove unused code not exported by symbol or internally called */ -#define REMOVE_DEAD_CODE - -/************************************************************************** - * Global Variables -***************************************************************************/ - -static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL]; -#if defined (CONFIG_BF561) -static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { - (struct dma_register *) DMA1_0_NEXT_DESC_PTR, - (struct dma_register *) DMA1_1_NEXT_DESC_PTR, - (struct dma_register *) DMA1_2_NEXT_DESC_PTR, - (struct dma_register *) DMA1_3_NEXT_DESC_PTR, - (struct dma_register *) DMA1_4_NEXT_DESC_PTR, - (struct dma_register *) DMA1_5_NEXT_DESC_PTR, - (struct dma_register *) DMA1_6_NEXT_DESC_PTR, - (struct dma_register *) DMA1_7_NEXT_DESC_PTR, - (struct dma_register *) DMA1_8_NEXT_DESC_PTR, - (struct dma_register *) DMA1_9_NEXT_DESC_PTR, - (struct dma_register *) DMA1_10_NEXT_DESC_PTR, - (struct dma_register *) DMA1_11_NEXT_DESC_PTR, - (struct dma_register *) DMA2_0_NEXT_DESC_PTR, - (struct dma_register *) DMA2_1_NEXT_DESC_PTR, - (struct dma_register *) DMA2_2_NEXT_DESC_PTR, - (struct dma_register *) DMA2_3_NEXT_DESC_PTR, - (struct dma_register *) DMA2_4_NEXT_DESC_PTR, - (struct dma_register *) DMA2_5_NEXT_DESC_PTR, - (struct dma_register *) DMA2_6_NEXT_DESC_PTR, - (struct dma_register *) DMA2_7_NEXT_DESC_PTR, - (struct dma_register *) DMA2_8_NEXT_DESC_PTR, - (struct dma_register *) DMA2_9_NEXT_DESC_PTR, - (struct dma_register *) DMA2_10_NEXT_DESC_PTR, - (struct dma_register *) DMA2_11_NEXT_DESC_PTR, - (struct dma_register *) MDMA1_D0_NEXT_DESC_PTR, - (struct dma_register *) MDMA1_S0_NEXT_DESC_PTR, - (struct dma_register *) MDMA1_D1_NEXT_DESC_PTR, - (struct dma_register *) MDMA1_S1_NEXT_DESC_PTR, - (struct dma_register *) MDMA2_D0_NEXT_DESC_PTR, - (struct dma_register *) MDMA2_S0_NEXT_DESC_PTR, - (struct dma_register *) MDMA2_D1_NEXT_DESC_PTR, - (struct dma_register *) MDMA2_S1_NEXT_DESC_PTR, - (struct dma_register *) IMDMA_D0_NEXT_DESC_PTR, - (struct dma_register *) IMDMA_S0_NEXT_DESC_PTR, - (struct dma_register *) IMDMA_D1_NEXT_DESC_PTR, - (struct dma_register *) IMDMA_S1_NEXT_DESC_PTR, -}; -#else -static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = { - (struct dma_register *) DMA0_NEXT_DESC_PTR, - (struct dma_register *) DMA1_NEXT_DESC_PTR, - (struct dma_register *) DMA2_NEXT_DESC_PTR, - (struct dma_register *) DMA3_NEXT_DESC_PTR, - (struct dma_register *) DMA4_NEXT_DESC_PTR, - (struct dma_register *) DMA5_NEXT_DESC_PTR, - (struct dma_register *) DMA6_NEXT_DESC_PTR, - (struct dma_register *) DMA7_NEXT_DESC_PTR, -#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536)) - (struct dma_register *) DMA8_NEXT_DESC_PTR, - (struct dma_register *) DMA9_NEXT_DESC_PTR, - (struct dma_register *) DMA10_NEXT_DESC_PTR, - (struct dma_register *) DMA11_NEXT_DESC_PTR, -#endif - (struct dma_register *) MDMA_D0_NEXT_DESC_PTR, - (struct dma_register *) MDMA_S0_NEXT_DESC_PTR, - (struct dma_register *) MDMA_D1_NEXT_DESC_PTR, - (struct dma_register *) MDMA_S1_NEXT_DESC_PTR, -}; -#endif - -/*------------------------------------------------------------------------------ - * Set the Buffer Clear bit in the Configuration register of specific DMA - * channel. This will stop the descriptor based DMA operation. - *-----------------------------------------------------------------------------*/ -static void clear_dma_buffer(unsigned int channel) -{ - dma_ch[channel].regs->cfg |= RESTART; - SSYNC(); - dma_ch[channel].regs->cfg &= ~RESTART; - SSYNC(); -} - -int __init blackfin_dma_init(void) -{ - int i; - - printk(KERN_INFO "Blackfin DMA Controller\n"); - - for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { - dma_ch[i].chan_status = DMA_CHANNEL_FREE; - dma_ch[i].regs = base_addr[i]; - mutex_init(&(dma_ch[i].dmalock)); - } - - return 0; -} - -arch_initcall(blackfin_dma_init); - -/* - * Form the channel find the irq number for that channel. - */ -#if !defined(CONFIG_BF561) - -static int bf533_channel2irq(unsigned int channel) -{ - int ret_irq = -1; - - switch (channel) { - case CH_PPI: - ret_irq = IRQ_PPI; - break; - -#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536)) - case CH_EMAC_RX: - ret_irq = IRQ_MAC_RX; - break; - - case CH_EMAC_TX: - ret_irq = IRQ_MAC_TX; - break; - - case CH_UART1_RX: - ret_irq = IRQ_UART1_RX; - break; - - case CH_UART1_TX: - ret_irq = IRQ_UART1_TX; - break; -#endif - - case CH_SPORT0_RX: - ret_irq = IRQ_SPORT0_RX; - break; - - case CH_SPORT0_TX: - ret_irq = IRQ_SPORT0_TX; - break; - - case CH_SPORT1_RX: - ret_irq = IRQ_SPORT1_RX; - break; - - case CH_SPORT1_TX: - ret_irq = IRQ_SPORT1_TX; - break; - - case CH_SPI: - ret_irq = IRQ_SPI; - break; - - case CH_UART_RX: - ret_irq = IRQ_UART_RX; - break; - - case CH_UART_TX: - ret_irq = IRQ_UART_TX; - break; - - case CH_MEM_STREAM0_SRC: - case CH_MEM_STREAM0_DEST: - ret_irq = IRQ_MEM_DMA0; - break; - - case CH_MEM_STREAM1_SRC: - case CH_MEM_STREAM1_DEST: - ret_irq = IRQ_MEM_DMA1; - break; - } - return ret_irq; -} - -# define channel2irq(channel) bf533_channel2irq(channel) - -#else - -static int bf561_channel2irq(unsigned int channel) -{ - int ret_irq = -1; - - switch (channel) { - case CH_PPI0: - ret_irq = IRQ_PPI0; - break; - case CH_PPI1: - ret_irq = IRQ_PPI1; - break; - case CH_SPORT0_RX: - ret_irq = IRQ_SPORT0_RX; - break; - case CH_SPORT0_TX: - ret_irq = IRQ_SPORT0_TX; - break; - case CH_SPORT1_RX: - ret_irq = IRQ_SPORT1_RX; - break; - case CH_SPORT1_TX: - ret_irq = IRQ_SPORT1_TX; - break; - case CH_SPI: - ret_irq = IRQ_SPI; - break; - case CH_UART_RX: - ret_irq = IRQ_UART_RX; - break; - case CH_UART_TX: - ret_irq = IRQ_UART_TX; - break; - - case CH_MEM_STREAM0_SRC: - case CH_MEM_STREAM0_DEST: - ret_irq = IRQ_MEM_DMA0; - break; - case CH_MEM_STREAM1_SRC: - case CH_MEM_STREAM1_DEST: - ret_irq = IRQ_MEM_DMA1; - break; - case CH_MEM_STREAM2_SRC: - case CH_MEM_STREAM2_DEST: - ret_irq = IRQ_MEM_DMA2; - break; - case CH_MEM_STREAM3_SRC: - case CH_MEM_STREAM3_DEST: - ret_irq = IRQ_MEM_DMA3; - break; - - case CH_IMEM_STREAM0_SRC: - case CH_IMEM_STREAM0_DEST: - ret_irq = IRQ_IMEM_DMA0; - break; - case CH_IMEM_STREAM1_SRC: - case CH_IMEM_STREAM1_DEST: - ret_irq = IRQ_IMEM_DMA1; - break; - } - return ret_irq; -} - -# define channel2irq(channel) bf561_channel2irq(channel) - -#endif - -/*------------------------------------------------------------------------------ - * Request the specific DMA channel from the system. - *-----------------------------------------------------------------------------*/ -int request_dma(unsigned int channel, char *device_id) -{ - - pr_debug("request_dma() : BEGIN \n"); - mutex_lock(&(dma_ch[channel].dmalock)); - - if ((dma_ch[channel].chan_status == DMA_CHANNEL_REQUESTED) - || (dma_ch[channel].chan_status == DMA_CHANNEL_ENABLED)) { - mutex_unlock(&(dma_ch[channel].dmalock)); - pr_debug("DMA CHANNEL IN USE \n"); - return -EBUSY; - } else { - dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; - pr_debug("DMA CHANNEL IS ALLOCATED \n"); - } - - mutex_unlock(&(dma_ch[channel].dmalock)); - - dma_ch[channel].device_id = device_id; - dma_ch[channel].irq_callback = NULL; - - /* This is to be enabled by putting a restriction - - * you have to request DMA, before doing any operations on - * descriptor/channel - */ - pr_debug("request_dma() : END \n"); - return channel; -} -EXPORT_SYMBOL(request_dma); - -int set_dma_callback(unsigned int channel, dma_interrupt_t callback, void *data) -{ - int ret_irq = 0; - - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - if (callback != NULL) { - int ret_val; - ret_irq = channel2irq(channel); - - dma_ch[channel].data = data; - - ret_val = - request_irq(ret_irq, (void *)callback, IRQF_DISABLED, - dma_ch[channel].device_id, data); - if (ret_val) { - printk(KERN_NOTICE - "Request irq in DMA engine failed.\n"); - return -EPERM; - } - dma_ch[channel].irq_callback = callback; - } - return 0; -} -EXPORT_SYMBOL(set_dma_callback); - -void free_dma(unsigned int channel) -{ - int ret_irq; - - pr_debug("freedma() : BEGIN \n"); - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - /* Halt the DMA */ - disable_dma(channel); - clear_dma_buffer(channel); - - if (dma_ch[channel].irq_callback != NULL) { - ret_irq = channel2irq(channel); - free_irq(ret_irq, dma_ch[channel].data); - } - - /* Clear the DMA Variable in the Channel */ - mutex_lock(&(dma_ch[channel].dmalock)); - dma_ch[channel].chan_status = DMA_CHANNEL_FREE; - mutex_unlock(&(dma_ch[channel].dmalock)); - - pr_debug("freedma() : END \n"); -} -EXPORT_SYMBOL(free_dma); - -void dma_enable_irq(unsigned int channel) -{ - int ret_irq; - - pr_debug("dma_enable_irq() : BEGIN \n"); - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - ret_irq = channel2irq(channel); - enable_irq(ret_irq); -} -EXPORT_SYMBOL(dma_enable_irq); - -void dma_disable_irq(unsigned int channel) -{ - int ret_irq; - - pr_debug("dma_disable_irq() : BEGIN \n"); - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - ret_irq = channel2irq(channel); - disable_irq(ret_irq); -} -EXPORT_SYMBOL(dma_disable_irq); - -int dma_channel_active(unsigned int channel) -{ - if (dma_ch[channel].chan_status == DMA_CHANNEL_FREE) { - return 0; - } else { - return 1; - } -} -EXPORT_SYMBOL(dma_channel_active); - -/*------------------------------------------------------------------------------ -* stop the specific DMA channel. -*-----------------------------------------------------------------------------*/ -void disable_dma(unsigned int channel) -{ - pr_debug("stop_dma() : BEGIN \n"); - - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->cfg &= ~DMAEN; /* Clean the enable bit */ - SSYNC(); - dma_ch[channel].chan_status = DMA_CHANNEL_REQUESTED; - /* Needs to be enabled Later */ - pr_debug("stop_dma() : END \n"); - return; -} -EXPORT_SYMBOL(disable_dma); - -void enable_dma(unsigned int channel) -{ - pr_debug("enable_dma() : BEGIN \n"); - - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].chan_status = DMA_CHANNEL_ENABLED; - dma_ch[channel].regs->curr_x_count = 0; - dma_ch[channel].regs->curr_y_count = 0; - - dma_ch[channel].regs->cfg |= DMAEN; /* Set the enable bit */ - SSYNC(); - pr_debug("enable_dma() : END \n"); - return; -} -EXPORT_SYMBOL(enable_dma); - -/*------------------------------------------------------------------------------ -* Set the Start Address register for the specific DMA channel -* This function can be used for register based DMA, -* to setup the start address -* addr: Starting address of the DMA Data to be transferred. -*-----------------------------------------------------------------------------*/ -void set_dma_start_addr(unsigned int channel, unsigned long addr) -{ - pr_debug("set_dma_start_addr() : BEGIN \n"); - - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->start_addr = addr; - SSYNC(); - pr_debug("set_dma_start_addr() : END\n"); -} -EXPORT_SYMBOL(set_dma_start_addr); - -void set_dma_next_desc_addr(unsigned int channel, unsigned long addr) -{ - pr_debug("set_dma_next_desc_addr() : BEGIN \n"); - - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->next_desc_ptr = addr; - SSYNC(); - pr_debug("set_dma_start_addr() : END\n"); -} -EXPORT_SYMBOL(set_dma_next_desc_addr); - -void set_dma_x_count(unsigned int channel, unsigned short x_count) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->x_count = x_count; - SSYNC(); -} -EXPORT_SYMBOL(set_dma_x_count); - -void set_dma_y_count(unsigned int channel, unsigned short y_count) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->y_count = y_count; - SSYNC(); -} -EXPORT_SYMBOL(set_dma_y_count); - -void set_dma_x_modify(unsigned int channel, short x_modify) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->x_modify = x_modify; - SSYNC(); -} -EXPORT_SYMBOL(set_dma_x_modify); - -void set_dma_y_modify(unsigned int channel, short y_modify) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->y_modify = y_modify; - SSYNC(); -} -EXPORT_SYMBOL(set_dma_y_modify); - -void set_dma_config(unsigned int channel, unsigned short config) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->cfg = config; - SSYNC(); -} -EXPORT_SYMBOL(set_dma_config); - -unsigned short -set_bfin_dma_config(char direction, char flow_mode, - char intr_mode, char dma_mode, char width) -{ - unsigned short config; - - config = - ((direction << 1) | (width << 2) | (dma_mode << 4) | - (intr_mode << 6) | (flow_mode << 12) | RESTART); - return config; -} -EXPORT_SYMBOL(set_bfin_dma_config); - -void set_dma_sg(unsigned int channel, struct dmasg * sg, int nr_sg) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - dma_ch[channel].regs->cfg |= ((nr_sg & 0x0F) << 8); - - dma_ch[channel].regs->next_desc_ptr = (unsigned int)sg; - - SSYNC(); -} -EXPORT_SYMBOL(set_dma_sg); - -/*------------------------------------------------------------------------------ - * Get the DMA status of a specific DMA channel from the system. - *-----------------------------------------------------------------------------*/ -unsigned short get_dma_curr_irqstat(unsigned int channel) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - return dma_ch[channel].regs->irq_status; -} -EXPORT_SYMBOL(get_dma_curr_irqstat); - -/*------------------------------------------------------------------------------ - * Clear the DMA_DONE bit in DMA status. Stop the DMA completion interrupt. - *-----------------------------------------------------------------------------*/ -void clear_dma_irqstat(unsigned int channel) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - dma_ch[channel].regs->irq_status |= 3; -} -EXPORT_SYMBOL(clear_dma_irqstat); - -/*------------------------------------------------------------------------------ - * Get current DMA xcount of a specific DMA channel from the system. - *-----------------------------------------------------------------------------*/ -unsigned short get_dma_curr_xcount(unsigned int channel) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - return dma_ch[channel].regs->curr_x_count; -} -EXPORT_SYMBOL(get_dma_curr_xcount); - -/*------------------------------------------------------------------------------ - * Get current DMA ycount of a specific DMA channel from the system. - *-----------------------------------------------------------------------------*/ -unsigned short get_dma_curr_ycount(unsigned int channel) -{ - BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE - && channel < MAX_BLACKFIN_DMA_CHANNEL)); - - return dma_ch[channel].regs->curr_y_count; -} -EXPORT_SYMBOL(get_dma_curr_ycount); - -void *dma_memcpy(void *dest, const void *src, size_t size) -{ - int direction; /* 1 - address decrease, 0 - address increase */ - int flag_align; /* 1 - address aligned, 0 - address unaligned */ - int flag_2D; /* 1 - 2D DMA needed, 0 - 1D DMA needed */ - - if (size <= 0) - return NULL; - - if ((unsigned long)src < memory_end) - blackfin_dcache_flush_range((unsigned int)src, - (unsigned int)(src + size)); - - bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); - - if ((unsigned long)src < (unsigned long)dest) - direction = 1; - else - direction = 0; - - if ((((unsigned long)dest % 2) == 0) && (((unsigned long)src % 2) == 0) - && ((size % 2) == 0)) - flag_align = 1; - else - flag_align = 0; - - if (size > 0x10000) /* size > 64K */ - flag_2D = 1; - else - flag_2D = 0; - - /* Setup destination and source start address */ - if (direction) { - if (flag_align) { - bfin_write_MDMA_D0_START_ADDR(dest + size - 2); - bfin_write_MDMA_S0_START_ADDR(src + size - 2); - } else { - bfin_write_MDMA_D0_START_ADDR(dest + size - 1); - bfin_write_MDMA_S0_START_ADDR(src + size - 1); - } - } else { - bfin_write_MDMA_D0_START_ADDR(dest); - bfin_write_MDMA_S0_START_ADDR(src); - } - - /* Setup destination and source xcount */ - if (flag_2D) { - if (flag_align) { - bfin_write_MDMA_D0_X_COUNT(1024 / 2); - bfin_write_MDMA_S0_X_COUNT(1024 / 2); - } else { - bfin_write_MDMA_D0_X_COUNT(1024); - bfin_write_MDMA_S0_X_COUNT(1024); - } - bfin_write_MDMA_D0_Y_COUNT(size >> 10); - bfin_write_MDMA_S0_Y_COUNT(size >> 10); - } else { - if (flag_align) { - bfin_write_MDMA_D0_X_COUNT(size / 2); - bfin_write_MDMA_S0_X_COUNT(size / 2); - } else { - bfin_write_MDMA_D0_X_COUNT(size); - bfin_write_MDMA_S0_X_COUNT(size); - } - } - - /* Setup destination and source xmodify and ymodify */ - if (direction) { - if (flag_align) { - bfin_write_MDMA_D0_X_MODIFY(-2); - bfin_write_MDMA_S0_X_MODIFY(-2); - if (flag_2D) { - bfin_write_MDMA_D0_Y_MODIFY(-2); - bfin_write_MDMA_S0_Y_MODIFY(-2); - } - } else { - bfin_write_MDMA_D0_X_MODIFY(-1); - bfin_write_MDMA_S0_X_MODIFY(-1); - if (flag_2D) { - bfin_write_MDMA_D0_Y_MODIFY(-1); - bfin_write_MDMA_S0_Y_MODIFY(-1); - } - } - } else { - if (flag_align) { - bfin_write_MDMA_D0_X_MODIFY(2); - bfin_write_MDMA_S0_X_MODIFY(2); - if (flag_2D) { - bfin_write_MDMA_D0_Y_MODIFY(2); - bfin_write_MDMA_S0_Y_MODIFY(2); - } - } else { - bfin_write_MDMA_D0_X_MODIFY(1); - bfin_write_MDMA_S0_X_MODIFY(1); - if (flag_2D) { - bfin_write_MDMA_D0_Y_MODIFY(1); - bfin_write_MDMA_S0_Y_MODIFY(1); - } - } - } - - /* Enable source DMA */ - if (flag_2D) { - if (flag_align) { - bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D | WDSIZE_16); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D | WDSIZE_16); - } else { - bfin_write_MDMA_S0_CONFIG(DMAEN | DMA2D); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | DMA2D); - } - } else { - if (flag_align) { - bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); - } else { - bfin_write_MDMA_S0_CONFIG(DMAEN); - bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN); - } - } - - while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) - ; - - bfin_write_MDMA_D0_IRQ_STATUS(bfin_read_MDMA_D0_IRQ_STATUS() | - (DMA_DONE | DMA_ERR)); - - bfin_write_MDMA_S0_CONFIG(0); - bfin_write_MDMA_D0_CONFIG(0); - - if ((unsigned long)dest < memory_end) - blackfin_dcache_invalidate_range((unsigned int)dest, - (unsigned int)(dest + size)); - - return dest; -} -EXPORT_SYMBOL(dma_memcpy); - -void *safe_dma_memcpy(void *dest, const void *src, size_t size) -{ - int flags = 0; - void *addr; - local_irq_save(flags); - addr = dma_memcpy(dest, src, size); - local_irq_restore(flags); - return addr; -} -EXPORT_SYMBOL(safe_dma_memcpy); diff --git a/trunk/arch/blackfin/kernel/bfin_gpio.c b/trunk/arch/blackfin/kernel/bfin_gpio.c deleted file mode 100644 index e9f24a9a46ba..000000000000 --- a/trunk/arch/blackfin/kernel/bfin_gpio.c +++ /dev/null @@ -1,637 +0,0 @@ -/* - * File: arch/blackfin/kernel/bfin_gpio.c - * Based on: - * Author: Michael Hennerich (hennerich@blackfin.uclinux.org) - * - * Created: - * Description: GPIO Abstraction Layer - * - * Modified: - * Copyright 2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* -* Number BF537/6/4 BF561 BF533/2/1 -* -* GPIO_0 PF0 PF0 PF0 -* GPIO_1 PF1 PF1 PF1 -* GPIO_2 PF2 PF2 PF2 -* GPIO_3 PF3 PF3 PF3 -* GPIO_4 PF4 PF4 PF4 -* GPIO_5 PF5 PF5 PF5 -* GPIO_6 PF6 PF6 PF6 -* GPIO_7 PF7 PF7 PF7 -* GPIO_8 PF8 PF8 PF8 -* GPIO_9 PF9 PF9 PF9 -* GPIO_10 PF10 PF10 PF10 -* GPIO_11 PF11 PF11 PF11 -* GPIO_12 PF12 PF12 PF12 -* GPIO_13 PF13 PF13 PF13 -* GPIO_14 PF14 PF14 PF14 -* GPIO_15 PF15 PF15 PF15 -* GPIO_16 PG0 PF16 -* GPIO_17 PG1 PF17 -* GPIO_18 PG2 PF18 -* GPIO_19 PG3 PF19 -* GPIO_20 PG4 PF20 -* GPIO_21 PG5 PF21 -* GPIO_22 PG6 PF22 -* GPIO_23 PG7 PF23 -* GPIO_24 PG8 PF24 -* GPIO_25 PG9 PF25 -* GPIO_26 PG10 PF26 -* GPIO_27 PG11 PF27 -* GPIO_28 PG12 PF28 -* GPIO_29 PG13 PF29 -* GPIO_30 PG14 PF30 -* GPIO_31 PG15 PF31 -* GPIO_32 PH0 PF32 -* GPIO_33 PH1 PF33 -* GPIO_34 PH2 PF34 -* GPIO_35 PH3 PF35 -* GPIO_36 PH4 PF36 -* GPIO_37 PH5 PF37 -* GPIO_38 PH6 PF38 -* GPIO_39 PH7 PF39 -* GPIO_40 PH8 PF40 -* GPIO_41 PH9 PF41 -* GPIO_42 PH10 PF42 -* GPIO_43 PH11 PF43 -* GPIO_44 PH12 PF44 -* GPIO_45 PH13 PF45 -* GPIO_46 PH14 PF46 -* GPIO_47 PH15 PF47 -*/ - -#include -#include -#include -#include -#include - -#ifdef BF533_FAMILY -static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { - (struct gpio_port_t *) FIO_FLAG_D, -}; -#endif - -#ifdef BF537_FAMILY -static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { - (struct gpio_port_t *) PORTFIO, - (struct gpio_port_t *) PORTGIO, - (struct gpio_port_t *) PORTHIO, -}; - -static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = { - (unsigned short *) PORTF_FER, - (unsigned short *) PORTG_FER, - (unsigned short *) PORTH_FER, -}; - -#endif - -#ifdef BF561_FAMILY -static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { - (struct gpio_port_t *) FIO0_FLAG_D, - (struct gpio_port_t *) FIO1_FLAG_D, - (struct gpio_port_t *) FIO2_FLAG_D, -}; -#endif - -static unsigned short reserved_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; - -#ifdef CONFIG_PM -static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; -static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; -static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; - -#ifdef BF533_FAMILY -static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB}; -#endif - -#ifdef BF537_FAMILY -static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX}; -#endif - -#ifdef BF561_FAMILY -static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; -#endif - -#endif /* CONFIG_PM */ - -inline int check_gpio(unsigned short gpio) -{ - if (gpio > MAX_BLACKFIN_GPIOS) - return -EINVAL; - return 0; -} - -#ifdef BF537_FAMILY -void port_setup(unsigned short gpio, unsigned short usage) -{ - if (usage == GPIO_USAGE) { - if (*port_fer[gpio_bank(gpio)] & gpio_bit(gpio)) - printk(KERN_WARNING "bfin-gpio: Possible Conflict with Peripheral " - "usage and GPIO %d detected!\n", gpio); - *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); - } else - *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); - SSYNC(); -} -#else -# define port_setup(...) do { } while (0) -#endif - - -void default_gpio(unsigned short gpio) -{ - unsigned short bank,bitmask; - - bank = gpio_bank(gpio); - bitmask = gpio_bit(gpio); - - gpio_bankb[bank]->maska_clear = bitmask; - gpio_bankb[bank]->maskb_clear = bitmask; - SSYNC(); - gpio_bankb[bank]->inen &= ~bitmask; - gpio_bankb[bank]->dir &= ~bitmask; - gpio_bankb[bank]->polar &= ~bitmask; - gpio_bankb[bank]->both &= ~bitmask; - gpio_bankb[bank]->edge &= ~bitmask; -} - - -int __init bfin_gpio_init(void) -{ - int i; - - printk(KERN_INFO "Blackfin GPIO Controller\n"); - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) - reserved_map[gpio_bank(i)] = 0; - -#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) -# if defined(CONFIG_BFIN_MAC_RMII) - reserved_map[PORT_H] = 0xC373; -# else - reserved_map[PORT_H] = 0xFFFF; -# endif -#endif - - return 0; -} - -arch_initcall(bfin_gpio_init); - - -/*********************************************************** -* -* FUNCTIONS: Blackfin General Purpose Ports Access Functions -* -* INPUTS/OUTPUTS: -* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS -* -* -* DESCRIPTION: These functions abstract direct register access -* to Blackfin processor General Purpose -* Ports Regsiters -* -* CAUTION: These functions do not belong to the GPIO Driver API -************************************************************* -* MODIFICATION HISTORY : -**************************************************************/ - -/* Set a specific bit */ - -#define SET_GPIO(name) \ -void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ -{ \ - unsigned long flags; \ - BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ - local_irq_save(flags); \ - if (arg) \ - gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ - else \ - gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ - local_irq_restore(flags); \ -} \ -EXPORT_SYMBOL(set_gpio_ ## name); - -SET_GPIO(dir) -SET_GPIO(inen) -SET_GPIO(polar) -SET_GPIO(edge) -SET_GPIO(both) - - -#define SET_GPIO_SC(name) \ -void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ -{ \ - BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); \ - if (arg) \ - gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ - else \ - gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ -} \ -EXPORT_SYMBOL(set_gpio_ ## name); - -SET_GPIO_SC(maska) -SET_GPIO_SC(maskb) - -#if defined(ANOMALY_05000311) -void set_gpio_data(unsigned short gpio, unsigned short arg) -{ - unsigned long flags; - BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); - local_irq_save(flags); - if (arg) - gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); - else - gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); - bfin_read_CHIPID(); - local_irq_restore(flags); -} -EXPORT_SYMBOL(set_gpio_data); -#else -SET_GPIO_SC(data) -#endif - - -#if defined(ANOMALY_05000311) -void set_gpio_toggle(unsigned short gpio) -{ - unsigned long flags; - BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); - local_irq_save(flags); - gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); - bfin_read_CHIPID(); - local_irq_restore(flags); -} -#else -void set_gpio_toggle(unsigned short gpio) -{ - BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); - gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); -} -#endif -EXPORT_SYMBOL(set_gpio_toggle); - - -/*Set current PORT date (16-bit word)*/ - -#define SET_GPIO_P(name) \ -void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ -{ \ - gpio_bankb[gpio_bank(gpio)]->name = arg; \ -} \ -EXPORT_SYMBOL(set_gpiop_ ## name); - -SET_GPIO_P(dir) -SET_GPIO_P(inen) -SET_GPIO_P(polar) -SET_GPIO_P(edge) -SET_GPIO_P(both) -SET_GPIO_P(maska) -SET_GPIO_P(maskb) - - -#if defined(ANOMALY_05000311) -void set_gpiop_data(unsigned short gpio, unsigned short arg) -{ - unsigned long flags; - local_irq_save(flags); - gpio_bankb[gpio_bank(gpio)]->data = arg; - bfin_read_CHIPID(); - local_irq_restore(flags); -} -EXPORT_SYMBOL(set_gpiop_data); -#else -SET_GPIO_P(data) -#endif - - - -/* Get a specific bit */ - -#define GET_GPIO(name) \ -unsigned short get_gpio_ ## name(unsigned short gpio) \ -{ \ - return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ -} \ -EXPORT_SYMBOL(get_gpio_ ## name); - -GET_GPIO(dir) -GET_GPIO(inen) -GET_GPIO(polar) -GET_GPIO(edge) -GET_GPIO(both) -GET_GPIO(maska) -GET_GPIO(maskb) - - -#if defined(ANOMALY_05000311) -unsigned short get_gpio_data(unsigned short gpio) -{ - unsigned long flags; - unsigned short ret; - BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); - local_irq_save(flags); - ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)); - bfin_read_CHIPID(); - local_irq_restore(flags); - return ret; -} -EXPORT_SYMBOL(get_gpio_data); -#else -GET_GPIO(data) -#endif - -/*Get current PORT date (16-bit word)*/ - -#define GET_GPIO_P(name) \ -unsigned short get_gpiop_ ## name(unsigned short gpio) \ -{ \ - return (gpio_bankb[gpio_bank(gpio)]->name);\ -} \ -EXPORT_SYMBOL(get_gpiop_ ## name); - -GET_GPIO_P(dir) -GET_GPIO_P(inen) -GET_GPIO_P(polar) -GET_GPIO_P(edge) -GET_GPIO_P(both) -GET_GPIO_P(maska) -GET_GPIO_P(maskb) - -#if defined(ANOMALY_05000311) -unsigned short get_gpiop_data(unsigned short gpio) -{ - unsigned long flags; - unsigned short ret; - local_irq_save(flags); - ret = gpio_bankb[gpio_bank(gpio)]->data; - bfin_read_CHIPID(); - local_irq_restore(flags); - return ret; -} -EXPORT_SYMBOL(get_gpiop_data); -#else -GET_GPIO_P(data) -#endif - -#ifdef CONFIG_PM -/*********************************************************** -* -* FUNCTIONS: Blackfin PM Setup API -* -* INPUTS/OUTPUTS: -* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS -* type - -* PM_WAKE_RISING -* PM_WAKE_FALLING -* PM_WAKE_HIGH -* PM_WAKE_LOW -* PM_WAKE_BOTH_EDGES -* -* DESCRIPTION: Blackfin PM Driver API -* -* CAUTION: -************************************************************* -* MODIFICATION HISTORY : -**************************************************************/ -int gpio_pm_wakeup_request(unsigned short gpio, unsigned char type) -{ - unsigned long flags; - - if ((check_gpio(gpio) < 0) || !type) - return -EINVAL; - - local_irq_save(flags); - - wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio); - wakeup_flags_map[gpio] = type; - local_irq_restore(flags); - - return 0; -} -EXPORT_SYMBOL(gpio_pm_wakeup_request); - -void gpio_pm_wakeup_free(unsigned short gpio) -{ - unsigned long flags; - - if (check_gpio(gpio) < 0) - return; - - local_irq_save(flags); - - wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); - - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_pm_wakeup_free); - -static int bfin_gpio_wakeup_type(unsigned short gpio, unsigned char type) -{ - port_setup(gpio, GPIO_USAGE); - set_gpio_dir(gpio, 0); - set_gpio_inen(gpio, 1); - - if (type & (PM_WAKE_RISING | PM_WAKE_FALLING)) - set_gpio_edge(gpio, 1); - else - set_gpio_edge(gpio, 0); - - if ((type & (PM_WAKE_BOTH_EDGES)) == (PM_WAKE_BOTH_EDGES)) - set_gpio_both(gpio, 1); - else - set_gpio_both(gpio, 0); - - if ((type & (PM_WAKE_FALLING | PM_WAKE_LOW))) - set_gpio_polar(gpio, 1); - else - set_gpio_polar(gpio, 0); - - SSYNC(); - - return 0; -} - -u32 gpio_pm_setup(void) -{ - u32 sic_iwr = 0; - u16 bank, mask, i, gpio; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) { - mask = wakeup_map[gpio_bank(i)]; - bank = gpio_bank(i); - - gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb; - gpio_bankb[bank]->maskb = 0; - - if (mask) { -#ifdef BF537_FAMILY - gpio_bank_saved[bank].fer = *port_fer[bank]; -#endif - gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; - gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; - gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; - gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; - gpio_bank_saved[bank].both = gpio_bankb[bank]->both; - - gpio = i; - - while (mask) { - if (mask & 1) { - bfin_gpio_wakeup_type(gpio, wakeup_flags_map[gpio]); - set_gpio_data(gpio, 0); /*Clear*/ - } - gpio++; - mask >>= 1; - } - - sic_iwr |= 1 << (sic_iwr_irqs[bank] - (IRQ_CORETMR + 1)); - gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; - } - } - - if (sic_iwr) - return sic_iwr; - else - return IWR_ENABLE_ALL; -} - - -void gpio_pm_restore(void) -{ - u16 bank, mask, i; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) { - mask = wakeup_map[gpio_bank(i)]; - bank = gpio_bank(i); - - if (mask) { -#ifdef BF537_FAMILY - *port_fer[bank] = gpio_bank_saved[bank].fer; -#endif - gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; - gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; - gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; - gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; - gpio_bankb[bank]->both = gpio_bank_saved[bank].both; - } - - gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; - } -} - -#endif - -/*********************************************************** -* -* FUNCTIONS: Blackfin GPIO Driver -* -* INPUTS/OUTPUTS: -* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS -* -* -* DESCRIPTION: Blackfin GPIO Driver API -* -* CAUTION: -************************************************************* -* MODIFICATION HISTORY : -**************************************************************/ - -int gpio_request(unsigned short gpio, const char *label) -{ - unsigned long flags; - - if (check_gpio(gpio) < 0) - return -EINVAL; - - local_irq_save(flags); - - if (unlikely(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))) { - printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio); - dump_stack(); - local_irq_restore(flags); - return -EBUSY; - } - reserved_map[gpio_bank(gpio)] |= gpio_bit(gpio); - - local_irq_restore(flags); - - port_setup(gpio, GPIO_USAGE); - - return 0; -} -EXPORT_SYMBOL(gpio_request); - - -void gpio_free(unsigned short gpio) -{ - unsigned long flags; - - if (check_gpio(gpio) < 0) - return; - - local_irq_save(flags); - - if (unlikely(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { - printk(KERN_ERR "bfin-gpio: GPIO %d wasn't reserved!\n", gpio); - dump_stack(); - local_irq_restore(flags); - return; - } - - default_gpio(gpio); - - reserved_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); - - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_free); - - -void gpio_direction_input(unsigned short gpio) -{ - unsigned long flags; - - BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); - - local_irq_save(flags); - gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); - gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_direction_input); - -void gpio_direction_output(unsigned short gpio) -{ - unsigned long flags; - - BUG_ON(!(reserved_map[gpio_bank(gpio)] & gpio_bit(gpio))); - - local_irq_save(flags); - gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); - gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_direction_output); diff --git a/trunk/arch/blackfin/kernel/bfin_ksyms.c b/trunk/arch/blackfin/kernel/bfin_ksyms.c deleted file mode 100644 index f64ecb638fab..000000000000 --- a/trunk/arch/blackfin/kernel/bfin_ksyms.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * File: arch/blackfin/kernel/bfin_ksyms.c - * Based on: none - original work - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -/* platform dependent support */ - -EXPORT_SYMBOL(__ioremap); -EXPORT_SYMBOL(strcmp); -EXPORT_SYMBOL(strncmp); -EXPORT_SYMBOL(dump_thread); - -EXPORT_SYMBOL(ip_fast_csum); - -EXPORT_SYMBOL(kernel_thread); - -EXPORT_SYMBOL(__up); -EXPORT_SYMBOL(__down); -EXPORT_SYMBOL(__down_trylock); -EXPORT_SYMBOL(__down_interruptible); - -EXPORT_SYMBOL(is_in_rom); - -/* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial_copy); - -/* The following are special because they're not called - * explicitly (the C compiler generates them). Fortunately, - * their interface isn't gonna change any time soon now, so - * it's OK to leave it out of version control. - */ -EXPORT_SYMBOL(memcpy); -EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memcmp); -EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(memchr); -EXPORT_SYMBOL(get_wchan); - -/* - * libgcc functions - functions that are used internally by the - * compiler... (prototypes are not correct though, but that - * doesn't really matter since they're not versioned). - */ -extern void __ashldi3(void); -extern void __ashrdi3(void); -extern void __smulsi3_highpart(void); -extern void __umulsi3_highpart(void); -extern void __divsi3(void); -extern void __lshrdi3(void); -extern void __modsi3(void); -extern void __muldi3(void); -extern void __udivsi3(void); -extern void __umodsi3(void); - -/* gcc lib functions */ -EXPORT_SYMBOL(__ashldi3); -EXPORT_SYMBOL(__ashrdi3); -EXPORT_SYMBOL(__umulsi3_highpart); -EXPORT_SYMBOL(__smulsi3_highpart); -EXPORT_SYMBOL(__divsi3); -EXPORT_SYMBOL(__lshrdi3); -EXPORT_SYMBOL(__modsi3); -EXPORT_SYMBOL(__muldi3); -EXPORT_SYMBOL(__udivsi3); -EXPORT_SYMBOL(__umodsi3); - -EXPORT_SYMBOL(outsb); -EXPORT_SYMBOL(insb); -EXPORT_SYMBOL(outsw); -EXPORT_SYMBOL(insw); -EXPORT_SYMBOL(outsl); -EXPORT_SYMBOL(insl); -EXPORT_SYMBOL(irq_flags); -EXPORT_SYMBOL(iounmap); -EXPORT_SYMBOL(blackfin_dcache_invalidate_range); -EXPORT_SYMBOL(blackfin_icache_dcache_flush_range); -EXPORT_SYMBOL(blackfin_icache_flush_range); -EXPORT_SYMBOL(blackfin_dcache_flush_range); -EXPORT_SYMBOL(blackfin_dflush_page); - -EXPORT_SYMBOL(csum_partial); -EXPORT_SYMBOL(__init_begin); -EXPORT_SYMBOL(__init_end); -EXPORT_SYMBOL(_ebss_l1); -EXPORT_SYMBOL(_stext_l1); -EXPORT_SYMBOL(_etext_l1); -EXPORT_SYMBOL(_sdata_l1); -EXPORT_SYMBOL(_ebss_b_l1); -EXPORT_SYMBOL(_sdata_b_l1); diff --git a/trunk/arch/blackfin/kernel/dma-mapping.c b/trunk/arch/blackfin/kernel/dma-mapping.c deleted file mode 100644 index 539eb24e062f..000000000000 --- a/trunk/arch/blackfin/kernel/dma-mapping.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * File: arch/blackfin/kernel/dma-mapping.c - * Based on: - * Author: - * - * Created: - * Description: Dynamic DMA mapping support. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static spinlock_t dma_page_lock; -static unsigned int *dma_page; -static unsigned int dma_pages; -static unsigned long dma_base; -static unsigned long dma_size; -static unsigned int dma_initialized; - -void dma_alloc_init(unsigned long start, unsigned long end) -{ - spin_lock_init(&dma_page_lock); - dma_initialized = 0; - - dma_page = (unsigned int *)__get_free_page(GFP_KERNEL); - memset(dma_page, 0, PAGE_SIZE); - dma_base = PAGE_ALIGN(start); - dma_size = PAGE_ALIGN(end) - PAGE_ALIGN(start); - dma_pages = dma_size >> PAGE_SHIFT; - memset((void *)dma_base, 0, DMA_UNCACHED_REGION); - dma_initialized = 1; - - printk(KERN_INFO "%s: dma_page @ 0x%p - %d pages at 0x%08lx\n", __FUNCTION__, - dma_page, dma_pages, dma_base); -} - -static inline unsigned int get_pages(size_t size) -{ - return ((size - 1) >> PAGE_SHIFT) + 1; -} - -static unsigned long __alloc_dma_pages(unsigned int pages) -{ - unsigned long ret = 0, flags; - int i, count = 0; - - if (dma_initialized == 0) - dma_alloc_init(_ramend - DMA_UNCACHED_REGION, _ramend); - - spin_lock_irqsave(&dma_page_lock, flags); - - for (i = 0; i < dma_pages;) { - if (dma_page[i++] == 0) { - if (++count == pages) { - while (count--) - dma_page[--i] = 1; - ret = dma_base + (i << PAGE_SHIFT); - break; - } - } else - count = 0; - } - spin_unlock_irqrestore(&dma_page_lock, flags); - return ret; -} - -static void __free_dma_pages(unsigned long addr, unsigned int pages) -{ - unsigned long page = (addr - dma_base) >> PAGE_SHIFT; - unsigned long flags; - int i; - - if ((page + pages) > dma_pages) { - printk(KERN_ERR "%s: freeing outside range.\n", __FUNCTION__); - BUG(); - } - - spin_lock_irqsave(&dma_page_lock, flags); - for (i = page; i < page + pages; i++) { - dma_page[i] = 0; - } - spin_unlock_irqrestore(&dma_page_lock, flags); -} - -void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t * dma_handle, gfp_t gfp) -{ - void *ret; - - ret = (void *)__alloc_dma_pages(get_pages(size)); - - if (ret) { - memset(ret, 0, size); - *dma_handle = virt_to_phys(ret); - } - - return ret; -} -EXPORT_SYMBOL(dma_alloc_coherent); - -void -dma_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle) -{ - __free_dma_pages((unsigned long)vaddr, get_pages(size)); -} -EXPORT_SYMBOL(dma_free_coherent); - -/* - * Dummy functions defined for some existing drivers - */ - -dma_addr_t -dma_map_single(struct device *dev, void *ptr, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(direction == DMA_NONE); - - invalidate_dcache_range((unsigned long)ptr, - (unsigned long)ptr + size); - - return (dma_addr_t) ptr; -} -EXPORT_SYMBOL(dma_map_single); - -int -dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) -{ - int i; - - BUG_ON(direction == DMA_NONE); - - for (i = 0; i < nents; i++) - invalidate_dcache_range(sg_dma_address(&sg[i]), - sg_dma_address(&sg[i]) + - sg_dma_len(&sg[i])); - - return nents; -} -EXPORT_SYMBOL(dma_map_sg); - -void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) -{ - BUG_ON(direction == DMA_NONE); -} -EXPORT_SYMBOL(dma_unmap_single); - -void dma_unmap_sg(struct device *dev, struct scatterlist *sg, - int nhwentries, enum dma_data_direction direction) -{ - BUG_ON(direction == DMA_NONE); -} -EXPORT_SYMBOL(dma_unmap_sg); diff --git a/trunk/arch/blackfin/kernel/dualcore_test.c b/trunk/arch/blackfin/kernel/dualcore_test.c deleted file mode 100644 index 8b89c99f9dfa..000000000000 --- a/trunk/arch/blackfin/kernel/dualcore_test.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * File: arch/blackfin/kernel/dualcore_test.c - * Based on: - * Author: - * - * Created: - * Description: Small test code for CoreB on a BF561 - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -static int *testarg = (int*)0xfeb00000; - -static int test_init(void) -{ - *testarg = 1; - printk("Dual core test module inserted: set testarg = [%d]\n @ [%p]\n", - *testarg, testarg); - return 0; -} - -static void test_exit(void) -{ - printk("Dual core test module removed: testarg = [%d]\n", *testarg); -} - -module_init(test_init); -module_exit(test_exit); diff --git a/trunk/arch/blackfin/kernel/entry.S b/trunk/arch/blackfin/kernel/entry.S deleted file mode 100644 index 5880b270bd50..000000000000 --- a/trunk/arch/blackfin/kernel/entry.S +++ /dev/null @@ -1,94 +0,0 @@ -/* - * File: arch/blackfin/kernel/entry.S - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -#include - -#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 -.section .l1.text -#else -.text -#endif - -ENTRY(_ret_from_fork) - SP += -12; - call _schedule_tail; - SP += 12; - r0 = [sp + PT_IPEND]; - cc = bittst(r0,1); - if cc jump .Lin_kernel; - RESTORE_CONTEXT - rti; -.Lin_kernel: - bitclr(r0,1); - [sp + PT_IPEND] = r0; - /* do a 'fake' RTI by jumping to [RETI] - * to avoid clearing supervisor mode in child - */ - RESTORE_ALL_SYS - p0 = reti; - jump (p0); - -ENTRY(_sys_fork) - r0 = -EINVAL; - rts; - -ENTRY(_sys_vfork) - r0 = sp; - r0 += 24; - [--sp] = rets; - SP += -12; - call _bfin_vfork; - SP += 12; - rets = [sp++]; - rts; - -ENTRY(_sys_clone) - r0 = sp; - r0 += 24; - [--sp] = rets; - SP += -12; - call _bfin_clone; - SP += 12; - rets = [sp++]; - rts; - -ENTRY(_sys_rt_sigreturn) - r0 = sp; - r0 += 24; - [--sp] = rets; - SP += -12; - call _do_rt_sigreturn; - SP += 12; - rets = [sp++]; - rts; diff --git a/trunk/arch/blackfin/kernel/flat.c b/trunk/arch/blackfin/kernel/flat.c deleted file mode 100644 index a92587b628b5..000000000000 --- a/trunk/arch/blackfin/kernel/flat.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * arch/blackfin/kernel/flat.c - * - * Copyright (C) 2007 Analog Devices, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#define FLAT_BFIN_RELOC_TYPE_16_BIT 0 -#define FLAT_BFIN_RELOC_TYPE_16H_BIT 1 -#define FLAT_BFIN_RELOC_TYPE_32_BIT 2 - -unsigned long bfin_get_addr_from_rp(unsigned long *ptr, - unsigned long relval, - unsigned long flags, - unsigned long *persistent) -{ - unsigned short *usptr = (unsigned short *)ptr; - int type = (relval >> 26) & 7; - unsigned long val; - - switch (type) { - case FLAT_BFIN_RELOC_TYPE_16_BIT: - case FLAT_BFIN_RELOC_TYPE_16H_BIT: - usptr = (unsigned short *)ptr; - pr_debug("*usptr = %x", get_unaligned(usptr)); - val = get_unaligned(usptr); - val += *persistent; - break; - - case FLAT_BFIN_RELOC_TYPE_32_BIT: - pr_debug("*ptr = %lx", get_unaligned(ptr)); - val = get_unaligned(ptr); - break; - - default: - pr_debug("BINFMT_FLAT: Unknown relocation type %x\n", - type); - - return 0; - } - - /* - * Stack-relative relocs contain the offset into the stack, we - * have to add the stack's start address here and return 1 from - * flat_addr_absolute to prevent the normal address calculations - */ - if (relval & (1 << 29)) - return val + current->mm->context.end_brk; - - if ((flags & FLAT_FLAG_GOTPIC) == 0) - val = htonl(val); - return val; -} -EXPORT_SYMBOL(bfin_get_addr_from_rp); - -/* - * Insert the address ADDR into the symbol reference at RP; - * RELVAL is the raw relocation-table entry from which RP is derived - */ -void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr, - unsigned long relval) -{ - unsigned short *usptr = (unsigned short *)ptr; - int type = (relval >> 26) & 7; - - switch (type) { - case FLAT_BFIN_RELOC_TYPE_16_BIT: - put_unaligned(addr, usptr); - pr_debug("new value %x at %p", get_unaligned(usptr), - usptr); - break; - - case FLAT_BFIN_RELOC_TYPE_16H_BIT: - put_unaligned(addr >> 16, usptr); - pr_debug("new value %x", get_unaligned(usptr)); - break; - - case FLAT_BFIN_RELOC_TYPE_32_BIT: - put_unaligned(addr, ptr); - pr_debug("new ptr =%lx", get_unaligned(ptr)); - break; - } -} -EXPORT_SYMBOL(bfin_put_addr_at_rp); diff --git a/trunk/arch/blackfin/kernel/init_task.c b/trunk/arch/blackfin/kernel/init_task.c deleted file mode 100644 index b45188f8512e..000000000000 --- a/trunk/arch/blackfin/kernel/init_task.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * File: arch/blackfin/kernel/init_task.c - * Based on: - * Author: - * - * Created: - * Description: This file contains the simple DMA Implementation for Blackfin - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -static struct fs_struct init_fs = INIT_FS; -static struct files_struct init_files = INIT_FILES; -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); - -struct mm_struct init_mm = INIT_MM(init_mm); -EXPORT_SYMBOL(init_mm); - -/* - * Initial task structure. - * - * All other task structs will be allocated on slabs in fork.c - */ -struct task_struct init_task = INIT_TASK(init_task); -EXPORT_SYMBOL(init_task); - -/* - * Initial thread structure. - * - * We need to make sure that this is 8192-byte aligned due to the - * way process stacks are handled. This is done by having a special - * "init_task" linker map entry. - */ -union thread_union init_thread_union - __attribute__ ((__section__(".data.init_task"))) = { -INIT_THREAD_INFO(init_task)}; diff --git a/trunk/arch/blackfin/kernel/irqchip.c b/trunk/arch/blackfin/kernel/irqchip.c deleted file mode 100644 index df5bf022cf79..000000000000 --- a/trunk/arch/blackfin/kernel/irqchip.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * File: arch/blackfin/kernel/irqchip.c - * Based on: - * Author: - * - * Created: - * Description: This file contains the simple DMA Implementation for Blackfin - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -static unsigned long irq_err_count; -static spinlock_t irq_controller_lock; - -/* - * Dummy mask/unmask handler - */ -void dummy_mask_unmask_irq(unsigned int irq) -{ -} - -void ack_bad_irq(unsigned int irq) -{ - irq_err_count += 1; - printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq); -} -EXPORT_SYMBOL(ack_bad_irq); - -static struct irq_chip bad_chip = { - .ack = dummy_mask_unmask_irq, - .mask = dummy_mask_unmask_irq, - .unmask = dummy_mask_unmask_irq, -}; - -static struct irq_desc bad_irq_desc = { - .chip = &bad_chip, - .handle_irq = handle_bad_irq, - .depth = 1, -}; - -int show_interrupts(struct seq_file *p, void *v) -{ - int i = *(loff_t *) v; - struct irqaction *action; - unsigned long flags; - - if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; - if (!action) - goto unlock; - - seq_printf(p, "%3d: %10u ", i, kstat_irqs(i)); - seq_printf(p, " %s", action->name); - for (action = action->next; action; action = action->next) - seq_printf(p, ", %s", action->name); - - seq_putc(p, '\n'); - unlock: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) { - seq_printf(p, "Err: %10lu\n", irq_err_count); - } - return 0; -} - -/* - * do_IRQ handles all hardware IRQ's. Decoded IRQs should not - * come via this function. Instead, they should provide their - * own 'handler' - */ - -#ifdef CONFIG_DO_IRQ_L1 -asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text)); -#endif - -asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) -{ - struct pt_regs *old_regs; - struct irq_desc *desc = irq_desc + irq; - unsigned short pending, other_ints; - - old_regs = set_irq_regs(regs); - - /* - * Some hardware gives randomly wrong interrupts. Rather - * than crashing, do something sensible. - */ - if (irq >= NR_IRQS) - desc = &bad_irq_desc; - - irq_enter(); - - generic_handle_irq(irq); - - /* If we're the only interrupt running (ignoring IRQ15 which is for - syscalls), lower our priority to IRQ14 so that softirqs run at - that level. If there's another, lower-level interrupt, irq_exit - will defer softirqs to that. */ - CSYNC(); - pending = bfin_read_IPEND() & ~0x8000; - other_ints = pending & (pending - 1); - if (other_ints == 0) - lower_to_irq14(); - irq_exit(); - - set_irq_regs(old_regs); -} - -void __init init_IRQ(void) -{ - struct irq_desc *desc; - int irq; - - spin_lock_init(&irq_controller_lock); - for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) { - *desc = bad_irq_desc; - } - - init_arch_irq(); -} diff --git a/trunk/arch/blackfin/kernel/module.c b/trunk/arch/blackfin/kernel/module.c deleted file mode 100644 index 372f756f1ad9..000000000000 --- a/trunk/arch/blackfin/kernel/module.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * File: arch/blackfin/kernel/module.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * handle arithmetic relocations. - * See binutils/bfd/elf32-bfin.c for more details - */ -#define RELOC_STACK_SIZE 100 -static uint32_t reloc_stack[RELOC_STACK_SIZE]; -static unsigned int reloc_stack_tos; - -#define is_reloc_stack_empty() ((reloc_stack_tos > 0)?0:1) - -static void reloc_stack_push(uint32_t value) -{ - reloc_stack[reloc_stack_tos++] = value; -} - -static uint32_t reloc_stack_pop(void) -{ - return reloc_stack[--reloc_stack_tos]; -} - -static uint32_t reloc_stack_operate(unsigned int oper, struct module *mod) -{ - uint32_t value; - - switch (oper) { - case R_add: - value = reloc_stack[reloc_stack_tos - 2] + - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_sub: - value = reloc_stack[reloc_stack_tos - 2] - - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_mult: - value = reloc_stack[reloc_stack_tos - 2] * - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_div: - value = reloc_stack[reloc_stack_tos - 2] / - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_mod: - value = reloc_stack[reloc_stack_tos - 2] % - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_lshift: - value = reloc_stack[reloc_stack_tos - 2] << - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_rshift: - value = reloc_stack[reloc_stack_tos - 2] >> - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_and: - value = reloc_stack[reloc_stack_tos - 2] & - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_or: - value = reloc_stack[reloc_stack_tos - 2] | - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_xor: - value = reloc_stack[reloc_stack_tos - 2] ^ - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_land: - value = reloc_stack[reloc_stack_tos - 2] && - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_lor: - value = reloc_stack[reloc_stack_tos - 2] || - reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 2; - break; - case R_neg: - value = -reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos--; - break; - case R_comp: - value = ~reloc_stack[reloc_stack_tos - 1]; - reloc_stack_tos -= 1; - break; - default: - printk(KERN_WARNING "module %s: unhandled reloction\n", - mod->name); - return 0; - } - - /* now push the new value back on stack */ - reloc_stack_push(value); - - return value; -} - -void *module_alloc(unsigned long size) -{ - if (size == 0) - return NULL; - return vmalloc(size); -} - -/* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) -{ - vfree(module_region); -} - -/* Transfer the section to the L1 memory */ -int -module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, - char *secstrings, struct module *mod) -{ - Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; - void *dest = NULL; - - for (s = sechdrs; s < sechdrs_end; ++s) { - if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || - ((strcmp(".text", secstrings + s->sh_name)==0) && - (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { - mod->arch.text_l1 = s; - dest = l1_inst_sram_alloc(s->sh_size); - if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 instruction memory allocation failed\n", - mod->name); - return -1; - } - dma_memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if ((strcmp(".l1.data", secstrings + s->sh_name) == 0)|| - ((strcmp(".data", secstrings + s->sh_name)==0) && - (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { - mod->arch.data_a_l1 = s; - dest = l1_data_sram_alloc(s->sh_size); - if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 data memory allocation failed\n", - mod->name); - return -1; - } - memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || - ((strcmp(".bss", secstrings + s->sh_name)==0) && - (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { - mod->arch.bss_a_l1 = s; - dest = l1_data_sram_alloc(s->sh_size); - if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 data memory allocation failed\n", - mod->name); - return -1; - } - memset(dest, 0, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) { - mod->arch.data_b_l1 = s; - dest = l1_data_B_sram_alloc(s->sh_size); - if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 data memory allocation failed\n", - mod->name); - return -1; - } - memcpy(dest, (void *)s->sh_addr, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) { - mod->arch.bss_b_l1 = s; - dest = l1_data_B_sram_alloc(s->sh_size); - if (dest == NULL) { - printk(KERN_ERR - "module %s: L1 data memory allocation failed\n", - mod->name); - return -1; - } - memset(dest, 0, s->sh_size); - s->sh_flags &= ~SHF_ALLOC; - s->sh_addr = (unsigned long)dest; - } - } - return 0; -} - -int -apply_relocate(Elf_Shdr * sechdrs, const char *strtab, - unsigned int symindex, unsigned int relsec, struct module *me) -{ - printk(KERN_ERR "module %s: .rel unsupported\n", me->name); - return -ENOEXEC; -} - -/*************************************************************************/ -/* FUNCTION : apply_relocate_add */ -/* ABSTRACT : Blackfin specific relocation handling for the loadable */ -/* modules. Modules are expected to be .o files. */ -/* Arithmetic relocations are handled. */ -/* We do not expect LSETUP to be split and hence is not */ -/* handled. */ -/* R_byte and R_byte2 are also not handled as the gas */ -/* does not generate it. */ -/*************************************************************************/ -int -apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, - unsigned int symindex, unsigned int relsec, - struct module *mod) -{ - unsigned int i; - unsigned short tmp; - Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr; - Elf32_Sym *sym; - uint32_t *location32; - uint16_t *location16; - uint32_t value; - - pr_debug("Applying relocate section %u to %u\n", relsec, - sechdrs[relsec].sh_info); - for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { - /* This is where to make the change */ - location16 = - (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr + - rel[i].r_offset); - location32 = (uint32_t *) location16; - /* This is the symbol it is referring to. Note that all - undefined symbols have been resolved. */ - sym = (Elf32_Sym *) sechdrs[symindex].sh_addr - + ELF32_R_SYM(rel[i].r_info); - if (is_reloc_stack_empty()) { - value = sym->st_value; - } else { - value = reloc_stack_pop(); - } - value += rel[i].r_addend; - pr_debug("location is %x, value is %x type is %d \n", - (unsigned int) location32, value, - ELF32_R_TYPE(rel[i].r_info)); - - switch (ELF32_R_TYPE(rel[i].r_info)) { - - case R_pcrel24: - case R_pcrel24_jump_l: - /* Add the value, subtract its postition */ - location16 = - (uint16_t *) (sechdrs[sechdrs[relsec].sh_info]. - sh_addr + rel[i].r_offset - 2); - location32 = (uint32_t *) location16; - value -= (uint32_t) location32; - value >>= 1; - pr_debug("value is %x, before %x-%x after %x-%x\n", value, - *location16, *(location16 + 1), - (*location16 & 0xff00) | (value >> 16 & 0x00ff), - value & 0xffff); - *location16 = - (*location16 & 0xff00) | (value >> 16 & 0x00ff); - *(location16 + 1) = value & 0xffff; - break; - case R_pcrel12_jump: - case R_pcrel12_jump_s: - value -= (uint32_t) location32; - value >>= 1; - *location16 = (value & 0xfff); - break; - case R_pcrel10: - value -= (uint32_t) location32; - value >>= 1; - *location16 = (value & 0x3ff); - break; - case R_luimm16: - pr_debug("before %x after %x\n", *location16, - (value & 0xffff)); - tmp = (value & 0xffff); - if((unsigned long)location16 >= L1_CODE_START) { - dma_memcpy(location16, &tmp, 2); - } else - *location16 = tmp; - break; - case R_huimm16: - pr_debug("before %x after %x\n", *location16, - ((value >> 16) & 0xffff)); - tmp = ((value >> 16) & 0xffff); - if((unsigned long)location16 >= L1_CODE_START) { - dma_memcpy(location16, &tmp, 2); - } else - *location16 = tmp; - break; - case R_rimm16: - *location16 = (value & 0xffff); - break; - case R_byte4_data: - pr_debug("before %x after %x\n", *location32, value); - *location32 = value; - break; - case R_push: - reloc_stack_push(value); - break; - case R_const: - reloc_stack_push(rel[i].r_addend); - break; - case R_add: - case R_sub: - case R_mult: - case R_div: - case R_mod: - case R_lshift: - case R_rshift: - case R_and: - case R_or: - case R_xor: - case R_land: - case R_lor: - case R_neg: - case R_comp: - reloc_stack_operate(ELF32_R_TYPE(rel[i].r_info), mod); - break; - default: - printk(KERN_ERR "module %s: Unknown relocation: %u\n", - mod->name, ELF32_R_TYPE(rel[i].r_info)); - return -ENOEXEC; - } - } - return 0; -} - -int -module_finalize(const Elf_Ehdr * hdr, - const Elf_Shdr * sechdrs, struct module *mod) -{ - unsigned int i, strindex = 0, symindex = 0; - char *secstrings; - - secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - - for (i = 1; i < hdr->e_shnum; i++) { - /* Internal symbols and strings. */ - if (sechdrs[i].sh_type == SHT_SYMTAB) { - symindex = i; - strindex = sechdrs[i].sh_link; - } - } - - for (i = 1; i < hdr->e_shnum; i++) { - const char *strtab = (char *)sechdrs[strindex].sh_addr; - unsigned int info = sechdrs[i].sh_info; - - /* Not a valid relocation section? */ - if (info >= hdr->e_shnum) - continue; - - if ((sechdrs[i].sh_type == SHT_RELA) && - ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0)|| - ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && - (hdr->e_flags & FLG_CODE_IN_L1)))) { - apply_relocate_add((Elf_Shdr *) sechdrs, strtab, - symindex, i, mod); - } - } - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ - if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr)) - l1_inst_sram_free((void*)mod->arch.text_l1->sh_addr); - if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr)) - l1_data_sram_free((void*)mod->arch.data_a_l1->sh_addr); - if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr)) - l1_data_sram_free((void*)mod->arch.bss_a_l1->sh_addr); - if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr)) - l1_data_B_sram_free((void*)mod->arch.data_b_l1->sh_addr); - if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr)) - l1_data_B_sram_free((void*)mod->arch.bss_b_l1->sh_addr); -} diff --git a/trunk/arch/blackfin/kernel/process.c b/trunk/arch/blackfin/kernel/process.c deleted file mode 100644 index 3eff7439d8d3..000000000000 --- a/trunk/arch/blackfin/kernel/process.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * File: arch/blackfin/kernel/process.c - * Based on: - * Author: - * - * Created: - * Description: Blackfin architecture-dependent process handling. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define LED_ON 0 -#define LED_OFF 1 - -asmlinkage void ret_from_fork(void); - -/* Points to the SDRAM backup memory for the stack that is currently in - * L1 scratchpad memory. - */ -void *current_l1_stack_save; - -/* The number of tasks currently using a L1 stack area. The SRAM is - * allocated/deallocated whenever this changes from/to zero. - */ -int nr_l1stack_tasks; - -/* Start and length of the area in L1 scratchpad memory which we've allocated - * for process stacks. - */ -void *l1_stack_base; -unsigned long l1_stack_len; - -/* - * Powermanagement idle function, if any.. - */ -void (*pm_idle)(void) = NULL; -EXPORT_SYMBOL(pm_idle); - -void (*pm_power_off)(void) = NULL; -EXPORT_SYMBOL(pm_power_off); - -/* - * We are using a different LED from the one used to indicate timer interrupt. - */ -#if defined(CONFIG_BFIN_IDLE_LED) -static inline void leds_switch(int flag) -{ - unsigned short tmp = 0; - - tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT(); - SSYNC(); - - if (flag == LED_ON) - tmp &= ~CONFIG_BFIN_IDLE_LED_PIN; /* light on */ - else - tmp |= CONFIG_BFIN_IDLE_LED_PIN; /* light off */ - - bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp); - SSYNC(); - -} -#else -static inline void leds_switch(int flag) -{ -} -#endif - -/* - * The idle loop on BFIN - */ -#ifdef CONFIG_IDLE_L1 -void default_idle(void)__attribute__((l1_text)); -void cpu_idle(void)__attribute__((l1_text)); -#endif - -void default_idle(void) -{ - while (!need_resched()) { - leds_switch(LED_OFF); - local_irq_disable(); - if (likely(!need_resched())) - idle_with_irq_disabled(); - local_irq_enable(); - leds_switch(LED_ON); - } -} - -void (*idle)(void) = default_idle; - -/* - * The idle thread. There's no useful work to be - * done, so just try to conserve power and have a - * low exit latency (ie sit in a loop waiting for - * somebody to say that they'd like to reschedule) - */ -void cpu_idle(void) -{ - /* endless idle loop with no priority at all */ - while (1) { - idle(); - preempt_enable_no_resched(); - schedule(); - preempt_disable(); - } -} - -void machine_restart(char *__unused) -{ -#if defined(CONFIG_BLKFIN_CACHE) - bfin_write_IMEM_CONTROL(0x01); - SSYNC(); -#endif - bfin_reset(); - /* Dont do anything till the reset occurs */ - while (1) { - SSYNC(); - } -} - -void machine_halt(void) -{ - for (;;) - asm volatile ("idle"); -} - -void machine_power_off(void) -{ - for (;;) - asm volatile ("idle"); -} - -void show_regs(struct pt_regs *regs) -{ - printk(KERN_NOTICE "\n"); - printk(KERN_NOTICE - "PC: %08lu Status: %04lu SysStatus: %04lu RETS: %08lu\n", - regs->pc, regs->astat, regs->seqstat, regs->rets); - printk(KERN_NOTICE - "A0.x: %08lx A0.w: %08lx A1.x: %08lx A1.w: %08lx\n", - regs->a0x, regs->a0w, regs->a1x, regs->a1w); - printk(KERN_NOTICE "P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n", - regs->p0, regs->p1, regs->p2, regs->p3); - printk(KERN_NOTICE "P4: %08lx P5: %08lx\n", regs->p4, regs->p5); - printk(KERN_NOTICE "R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n", - regs->r0, regs->r1, regs->r2, regs->r3); - printk(KERN_NOTICE "R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n", - regs->r4, regs->r5, regs->r6, regs->r7); - - if (!(regs->ipend)) - printk("USP: %08lx\n", rdusp()); -} - -/* Fill in the fpu structure for a core dump. */ - -int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpregs) -{ - return 1; -} - -/* - * This gets run with P1 containing the - * function to call, and R1 containing - * the "args". Note P0 is clobbered on the way here. - */ -void kernel_thread_helper(void); -__asm__(".section .text\n" - ".align 4\n" - "_kernel_thread_helper:\n\t" - "\tsp += -12;\n\t" - "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous"); - -/* - * Create a kernel thread. - */ -pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - regs.r1 = (unsigned long)arg; - regs.p1 = (unsigned long)fn; - regs.pc = (unsigned long)kernel_thread_helper; - regs.orig_p0 = -1; - /* Set bit 2 to tell ret_from_fork we should be returning to kernel - mode. */ - regs.ipend = 0x8002; - __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):); - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, - NULL); -} - -void flush_thread(void) -{ -} - -asmlinkage int bfin_vfork(struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, - NULL); -} - -asmlinkage int bfin_clone(struct pt_regs *regs) -{ - unsigned long clone_flags; - unsigned long newsp; - - /* syscall2 puts clone_flags in r0 and usp in r1 */ - clone_flags = regs->r0; - newsp = regs->r1; - if (!newsp) - newsp = rdusp(); - else - newsp -= 12; - return do_fork(clone_flags, newsp, regs, 0, NULL, NULL); -} - -int -copy_thread(int nr, unsigned long clone_flags, - unsigned long usp, unsigned long topstk, - struct task_struct *p, struct pt_regs *regs) -{ - struct pt_regs *childregs; - - childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; - *childregs = *regs; - childregs->r0 = 0; - - p->thread.usp = usp; - p->thread.ksp = (unsigned long)childregs; - p->thread.pc = (unsigned long)ret_from_fork; - - return 0; -} - -/* - * fill in the user structure for a core dump.. - */ -void dump_thread(struct pt_regs *regs, struct user *dump) -{ - dump->magic = CMAGIC; - dump->start_code = 0; - dump->start_stack = rdusp() & ~(PAGE_SIZE - 1); - dump->u_tsize = ((unsigned long)current->mm->end_code) >> PAGE_SHIFT; - dump->u_dsize = ((unsigned long)(current->mm->brk + - (PAGE_SIZE - 1))) >> PAGE_SHIFT; - dump->u_dsize -= dump->u_tsize; - dump->u_ssize = 0; - - if (dump->start_stack < TASK_SIZE) - dump->u_ssize = - ((unsigned long)(TASK_SIZE - - dump->start_stack)) >> PAGE_SHIFT; - - dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump); - - dump->regs.r0 = regs->r0; - dump->regs.r1 = regs->r1; - dump->regs.r2 = regs->r2; - dump->regs.r3 = regs->r3; - dump->regs.r4 = regs->r4; - dump->regs.r5 = regs->r5; - dump->regs.r6 = regs->r6; - dump->regs.r7 = regs->r7; - dump->regs.p0 = regs->p0; - dump->regs.p1 = regs->p1; - dump->regs.p2 = regs->p2; - dump->regs.p3 = regs->p3; - dump->regs.p4 = regs->p4; - dump->regs.p5 = regs->p5; - dump->regs.orig_p0 = regs->orig_p0; - dump->regs.a0w = regs->a0w; - dump->regs.a1w = regs->a1w; - dump->regs.a0x = regs->a0x; - dump->regs.a1x = regs->a1x; - dump->regs.rets = regs->rets; - dump->regs.astat = regs->astat; - dump->regs.pc = regs->pc; -} - -/* - * sys_execve() executes a new program. - */ - -asmlinkage int sys_execve(char *name, char **argv, char **envp) -{ - int error; - char *filename; - struct pt_regs *regs = (struct pt_regs *)((&name) + 6); - - lock_kernel(); - filename = getname(name); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, argv, envp, regs); - putname(filename); - out: - unlock_kernel(); - return error; -} - -unsigned long get_wchan(struct task_struct *p) -{ - unsigned long fp, pc; - unsigned long stack_page; - int count = 0; - if (!p || p == current || p->state == TASK_RUNNING) - return 0; - - stack_page = (unsigned long)p; - fp = p->thread.usp; - do { - if (fp < stack_page + sizeof(struct thread_info) || - fp >= 8184 + stack_page) - return 0; - pc = ((unsigned long *)fp)[1]; - if (!in_sched_functions(pc)) - return pc; - fp = *(unsigned long *)fp; - } - while (count++ < 16); - return 0; -} - -#if defined(CONFIG_ACCESS_CHECK) -int _access_ok(unsigned long addr, unsigned long size) -{ - - if (addr > (addr + size)) - return 0; - if (segment_eq(get_fs(),KERNEL_DS)) - return 1; -#ifdef CONFIG_MTD_UCLINUX - if (addr >= memory_start && (addr + size) <= memory_end) - return 1; - if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end) - return 1; -#else - if (addr >= memory_start && (addr + size) <= physical_mem_end) - return 1; -#endif - if (addr >= (unsigned long)__init_begin && - addr + size <= (unsigned long)__init_end) - return 1; - if (addr >= L1_SCRATCH_START - && addr + size <= L1_SCRATCH_START + L1_SCRATCH_LENGTH) - return 1; -#if L1_CODE_LENGTH != 0 - if (addr >= L1_CODE_START + (_etext_l1 - _stext_l1) - && addr + size <= L1_CODE_START + L1_CODE_LENGTH) - return 1; -#endif -#if L1_DATA_A_LENGTH != 0 - if (addr >= L1_DATA_A_START + (_ebss_l1 - _sdata_l1) - && addr + size <= L1_DATA_A_START + L1_DATA_A_LENGTH) - return 1; -#endif -#if L1_DATA_B_LENGTH != 0 - if (addr >= L1_DATA_B_START - && addr + size <= L1_DATA_B_START + L1_DATA_B_LENGTH) - return 1; -#endif - return 0; -} -EXPORT_SYMBOL(_access_ok); -#endif /* CONFIG_ACCESS_CHECK */ diff --git a/trunk/arch/blackfin/kernel/ptrace.c b/trunk/arch/blackfin/kernel/ptrace.c deleted file mode 100644 index d7c8e514cb92..000000000000 --- a/trunk/arch/blackfin/kernel/ptrace.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * File: arch/blackfin/kernel/ptrace.c - * Based on: Taken from linux/kernel/ptrace.c - * Author: linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds - * - * Created: 1/23/92 - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#define MAX_SHARED_LIBS 3 -#define TEXT_OFFSET 0 -/* - * does not yet catch signals sent when the child dies. - * in exit.c or in signal.c. - */ - -/* determines which bits in the SYSCFG reg the user has access to. */ -/* 1 = access 0 = no access */ -#define SYSCFG_MASK 0x0007 /* SYSCFG reg */ -/* sets the trace bits. */ -#define TRACE_BITS 0x0001 - -/* Find the stack offset for a register, relative to thread.esp0. */ -#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) - -/* - * Get the address of the live pt_regs for the specified task. - * These are saved onto the top kernel stack when the process - * is not running. - * - * Note: if a user thread is execve'd from kernel space, the - * kernel stack will not be empty on entry to the kernel, so - * ptracing these tasks will fail. - */ -static inline struct pt_regs *get_user_regs(struct task_struct *task) -{ - return (struct pt_regs *) - ((unsigned long)task->thread_info + - (THREAD_SIZE - sizeof(struct pt_regs))); -} - -/* - * Get all user integer registers. - */ -static inline int ptrace_getregs(struct task_struct *tsk, void __user * uregs) -{ - struct pt_regs *regs = get_user_regs(tsk); - return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; -} - -/* Mapping from PT_xxx to the stack offset at which the register is - * saved. Notice that usp has no stack-slot and needs to be treated - * specially (see get_reg/put_reg below). - */ - -/* - * Get contents of register REGNO in task TASK. - */ -static inline long get_reg(struct task_struct *task, int regno) -{ - unsigned char *reg_ptr; - - struct pt_regs *regs = - (struct pt_regs *)((unsigned long)task->thread_info + - (THREAD_SIZE - sizeof(struct pt_regs))); - reg_ptr = (char *)regs; - - switch (regno) { - case PT_USP: - return task->thread.usp; - default: - if (regno <= 216) - return *(long *)(reg_ptr + regno); - } - /* slight mystery ... never seems to come here but kernel misbehaves without this code! */ - - printk(KERN_WARNING "Request to get for unknown register %d\n", regno); - return 0; -} - -/* - * Write contents of register REGNO in task TASK. - */ -static inline int -put_reg(struct task_struct *task, int regno, unsigned long data) -{ - char * reg_ptr; - - struct pt_regs *regs = - (struct pt_regs *)((unsigned long)task->thread_info + - (THREAD_SIZE - sizeof(struct pt_regs))); - reg_ptr = (char *)regs; - - switch (regno) { - case PT_PC: - /*********************************************************************/ - /* At this point the kernel is most likely in exception. */ - /* The RETX register will be used to populate the pc of the process. */ - /*********************************************************************/ - regs->retx = data; - regs->pc = data; - break; - case PT_RETX: - break; /* regs->retx = data; break; */ - case PT_USP: - regs->usp = data; - task->thread.usp = data; - break; - default: - if (regno <= 216) - *(long *)(reg_ptr + regno) = data; - } - return 0; -} - -/* - * check that an address falls within the bounds of the target process's memory mappings - */ -static inline int is_user_addr_valid(struct task_struct *child, - unsigned long start, unsigned long len) -{ - struct vm_list_struct *vml; - struct sram_list_struct *sraml; - - for (vml = child->mm->context.vmlist; vml; vml = vml->next) - if (start >= vml->vma->vm_start && start + len <= vml->vma->vm_end) - return 0; - - for (sraml = child->mm->context.sram_list; sraml; sraml = sraml->next) - if (start >= (unsigned long)sraml->addr - && start + len <= (unsigned long)sraml->addr + sraml->length) - return 0; - - return -EIO; -} - -/* - * Called by kernel/ptrace.c when detaching.. - * - * Make sure the single step bit is not set. - */ -void ptrace_disable(struct task_struct *child) -{ - unsigned long tmp; - /* make sure the single step bit is not set. */ - tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); - put_reg(child, PT_SR, tmp); -} - -long arch_ptrace(struct task_struct *child, long request, long addr, long data) -{ - int ret; - int add = 0; - - switch (request) { - /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKDATA: - pr_debug("ptrace: PEEKDATA\n"); - add = MAX_SHARED_LIBS * 4; /* space between text and data */ - /* fall through */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ - { - unsigned long tmp = 0; - int copied; - - ret = -EIO; - pr_debug("ptrace: PEEKTEXT at addr 0x%08lx + add %d %ld\n", addr, add, - sizeof(data)); - if (is_user_addr_valid(child, addr + add, sizeof(tmp)) < 0) - break; - pr_debug("ptrace: user address is valid\n"); - -#if L1_CODE_LENGTH != 0 - if (addr + add >= L1_CODE_START - && addr + add + sizeof(tmp) <= L1_CODE_START + L1_CODE_LENGTH) { - safe_dma_memcpy (&tmp, (const void *)(addr + add), sizeof(tmp)); - copied = sizeof(tmp); - } else -#endif - copied = - access_process_vm(child, addr + add, &tmp, - sizeof(tmp), 0); - pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); - if (copied != sizeof(tmp)) - break; - ret = put_user(tmp, (unsigned long *)data); - break; - } - - /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: - { - unsigned long tmp; - ret = -EIO; - tmp = 0; - if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) { - printk(KERN_WARNING "ptrace error : PEEKUSR : temporarily returning " - "0 - %x sizeof(pt_regs) is %lx\n", - (int)addr, sizeof(struct pt_regs)); - break; - } - if (addr == sizeof(struct pt_regs)) { - /* PT_TEXT_ADDR */ - tmp = child->mm->start_code + TEXT_OFFSET; - } else if (addr == (sizeof(struct pt_regs) + 4)) { - /* PT_TEXT_END_ADDR */ - tmp = child->mm->end_code; - } else if (addr == (sizeof(struct pt_regs) + 8)) { - /* PT_DATA_ADDR */ - tmp = child->mm->start_data; -#ifdef CONFIG_BINFMT_ELF_FDPIC - } else if (addr == (sizeof(struct pt_regs) + 12)) { - tmp = child->mm->context.exec_fdpic_loadmap; - } else if (addr == (sizeof(struct pt_regs) + 16)) { - tmp = child->mm->context.interp_fdpic_loadmap; -#endif - } else { - tmp = get_reg(child, addr); - } - ret = put_user(tmp, (unsigned long *)data); - break; - } - - /* when I and D space are separate, this will have to be fixed. */ - case PTRACE_POKEDATA: - printk(KERN_NOTICE "ptrace: PTRACE_PEEKDATA\n"); - /* fall through */ - case PTRACE_POKETEXT: /* write the word at location addr. */ - { - int copied; - - ret = -EIO; - pr_debug("ptrace: POKETEXT at addr 0x%08lx + add %d %ld bytes %lx\n", - addr, add, sizeof(data), data); - if (is_user_addr_valid(child, addr + add, sizeof(data)) < 0) - break; - pr_debug("ptrace: user address is valid\n"); - -#if L1_CODE_LENGTH != 0 - if (addr + add >= L1_CODE_START - && addr + add + sizeof(data) <= L1_CODE_START + L1_CODE_LENGTH) { - safe_dma_memcpy ((void *)(addr + add), &data, sizeof(data)); - copied = sizeof(data); - } else -#endif - copied = - access_process_vm(child, addr + add, &data, - sizeof(data), 1); - pr_debug("ptrace: copied size %d\n", copied); - if (copied != sizeof(data)) - break; - ret = 0; - break; - } - - case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ - ret = -EIO; - if ((addr & 3) || (addr > (sizeof(struct pt_regs) + 16))) { - printk(KERN_WARNING "ptrace error : POKEUSR: temporarily returning 0\n"); - break; - } - - if (addr >= (sizeof(struct pt_regs))) { - ret = 0; - break; - } - if (addr == PT_SYSCFG) { - data &= SYSCFG_MASK; - data |= get_reg(child, PT_SYSCFG); - } - ret = put_reg(child, addr, data); - break; - - case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ - case PTRACE_CONT: - { /* restart after signal. */ - long tmp; - - pr_debug("ptrace_cont\n"); - - ret = -EIO; - if (!valid_signal(data)) - break; - if (request == PTRACE_SYSCALL) - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - else - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - - child->exit_code = data; - /* make sure the single step bit is not set. */ - tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS); - put_reg(child, PT_SYSCFG, tmp); - pr_debug("before wake_up_process\n"); - wake_up_process(child); - ret = 0; - break; - } - - /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to - * exit. - */ - case PTRACE_KILL: - { - long tmp; - ret = 0; - if (child->exit_state == EXIT_ZOMBIE) /* already dead */ - break; - child->exit_code = SIGKILL; - /* make sure the single step bit is not set. */ - tmp = get_reg(child, PT_SYSCFG) & ~(TRACE_BITS); - put_reg(child, PT_SYSCFG, tmp); - wake_up_process(child); - break; - } - - case PTRACE_SINGLESTEP: - { /* set the trap flag. */ - long tmp; - - pr_debug("single step\n"); - ret = -EIO; - if (!valid_signal(data)) - break; - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - - tmp = get_reg(child, PT_SYSCFG) | (TRACE_BITS); - put_reg(child, PT_SYSCFG, tmp); - - child->exit_code = data; - /* give it a chance to run. */ - wake_up_process(child); - ret = 0; - break; - } - - case PTRACE_DETACH: - { /* detach a process that was attached. */ - ret = ptrace_detach(child, data); - break; - } - - case PTRACE_GETREGS: - { - - /* Get all gp regs from the child. */ - ret = ptrace_getregs(child, (void __user *)data); - break; - } - - case PTRACE_SETREGS: - { - printk(KERN_NOTICE - "ptrace: SETREGS: **** NOT IMPLEMENTED ***\n"); - /* Set all gp regs in the child. */ - ret = 0; - break; - } - default: - ret = ptrace_request(child, request, addr, data); - break; - } - - return ret; -} - -asmlinkage void syscall_trace(void) -{ - - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - - if (!(current->ptrace & PT_PTRACED)) - return; - - /* the 0x80 provides a way for the tracing parent to distinguish - * between a syscall stop and SIGTRAP delivery - */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} diff --git a/trunk/arch/blackfin/kernel/setup.c b/trunk/arch/blackfin/kernel/setup.c deleted file mode 100644 index 342bb8dd56ac..000000000000 --- a/trunk/arch/blackfin/kernel/setup.c +++ /dev/null @@ -1,902 +0,0 @@ -/* - * File: arch/blackfin/kernel/setup.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -unsigned long memory_start, memory_end, physical_mem_end; -unsigned long reserved_mem_dcache_on; -unsigned long reserved_mem_icache_on; -EXPORT_SYMBOL(memory_start); -EXPORT_SYMBOL(memory_end); -EXPORT_SYMBOL(physical_mem_end); -EXPORT_SYMBOL(_ramend); - -#ifdef CONFIG_MTD_UCLINUX -unsigned long memory_mtd_end, memory_mtd_start, mtd_size; -unsigned long _ebss; -EXPORT_SYMBOL(memory_mtd_end); -EXPORT_SYMBOL(memory_mtd_start); -EXPORT_SYMBOL(mtd_size); -#endif - -char command_line[COMMAND_LINE_SIZE]; - -#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) -static void generate_cpl_tables(void); -#endif - -void __init bf53x_cache_init(void) -{ -#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) - generate_cpl_tables(); -#endif - -#ifdef CONFIG_BLKFIN_CACHE - bfin_icache_init(); - printk(KERN_INFO "Instruction Cache Enabled\n"); -#endif - -#ifdef CONFIG_BLKFIN_DCACHE - bfin_dcache_init(); - printk(KERN_INFO "Data Cache Enabled" -# if defined CONFIG_BLKFIN_WB - " (write-back)" -# elif defined CONFIG_BLKFIN_WT - " (write-through)" -# endif - "\n"); -#endif -} - -void bf53x_relocate_l1_mem(void) -{ - unsigned long l1_code_length; - unsigned long l1_data_a_length; - unsigned long l1_data_b_length; - - l1_code_length = _etext_l1 - _stext_l1; - if (l1_code_length > L1_CODE_LENGTH) - l1_code_length = L1_CODE_LENGTH; - /* cannot complain as printk is not available as yet. - * But we can continue booting and complain later! - */ - - /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ - dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); - - l1_data_a_length = _ebss_l1 - _sdata_l1; - if (l1_data_a_length > L1_DATA_A_LENGTH) - l1_data_a_length = L1_DATA_A_LENGTH; - - /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */ - dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); - - l1_data_b_length = _ebss_b_l1 - _sdata_b_l1; - if (l1_data_b_length > L1_DATA_B_LENGTH) - l1_data_b_length = L1_DATA_B_LENGTH; - - /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ - dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + - l1_data_a_length, l1_data_b_length); - -} - -/* - * Initial parsing of the command line. Currently, we support: - * - Controlling the linux memory size: mem=xxx[KMG] - * - Controlling the physical memory size: max_mem=xxx[KMG][$][#] - * $ -> reserved memory is dcacheable - * # -> reserved memory is icacheable - */ -static __init void parse_cmdline_early(char *cmdline_p) -{ - char c = ' ', *to = cmdline_p; - unsigned int memsize; - for (;;) { - if (c == ' ') { - - if (!memcmp(to, "mem=", 4)) { - to += 4; - memsize = memparse(to, &to); - if (memsize) - _ramend = memsize; - - } else if (!memcmp(to, "max_mem=", 8)) { - to += 8; - memsize = memparse(to, &to); - if (memsize) { - physical_mem_end = memsize; - if (*to != ' ') { - if (*to == '$' - || *(to + 1) == '$') - reserved_mem_dcache_on = - 1; - if (*to == '#' - || *(to + 1) == '#') - reserved_mem_icache_on = - 1; - } - } - } - - } - c = *(to++); - if (!c) - break; - } -} - -void __init setup_arch(char **cmdline_p) -{ - int bootmap_size; - unsigned long l1_length, sclk, cclk; -#ifdef CONFIG_MTD_UCLINUX - unsigned long mtd_phys = 0; -#endif - - cclk = get_cclk(); - sclk = get_sclk(); - -#if !defined(CONFIG_BFIN_KERNEL_CLOCK) && defined(ANOMALY_05000273) - if (cclk == sclk) - panic("ANOMALY 05000273, SCLK can not be same as CCLK"); -#endif - -#if defined(ANOMALY_05000266) - bfin_read_IMDMA_D0_IRQ_STATUS(); - bfin_read_IMDMA_D1_IRQ_STATUS(); -#endif - -#ifdef DEBUG_SERIAL_EARLY_INIT - bfin_console_init(); /* early console registration */ - /* this give a chance to get printk() working before crash. */ -#endif - -#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) - /* we need to initialize the Flashrom device here since we might - * do things with flash early on in the boot - */ - flash_probe(); -#endif - -#if defined(CONFIG_CMDLINE_BOOL) - memset(command_line, 0, sizeof(command_line)); - strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line)); - command_line[sizeof(command_line) - 1] = 0; -#endif - - /* Keep a copy of command line */ - *cmdline_p = &command_line[0]; - memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE - 1] = 0; - - /* setup memory defaults from the user config */ - physical_mem_end = 0; - _ramend = CONFIG_MEM_SIZE * 1024 * 1024; - - parse_cmdline_early(&command_line[0]); - - if (physical_mem_end == 0) - physical_mem_end = _ramend; - - /* by now the stack is part of the init task */ - memory_end = _ramend - DMA_UNCACHED_REGION; - - _ramstart = (unsigned long)__bss_stop; - memory_start = PAGE_ALIGN(_ramstart); - -#if defined(CONFIG_MTD_UCLINUX) - /* generic memory mapped MTD driver */ - memory_mtd_end = memory_end; - - mtd_phys = _ramstart; - mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); - -# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) - if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) - mtd_size = - PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); -# endif - -# if defined(CONFIG_CRAMFS) - if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC) - mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4))); -# endif - -# if defined(CONFIG_ROMFS_FS) - if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0 - && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) - mtd_size = - PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2])); -# if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) - /* Due to a Hardware Anomaly we need to limit the size of usable - * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on - * 05000263 - Hardware loop corrupted when taking an ICPLB exception - */ -# if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) - if (memory_end >= 56 * 1024 * 1024) - memory_end = 56 * 1024 * 1024; -# else - if (memory_end >= 60 * 1024 * 1024) - memory_end = 60 * 1024 * 1024; -# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ -# endif /* ANOMALY_05000263 */ -# endif /* CONFIG_ROMFS_FS */ - - memory_end -= mtd_size; - - if (mtd_size == 0) { - console_init(); - panic("Don't boot kernel without rootfs attached.\n"); - } - - /* Relocate MTD image to the top of memory after the uncached memory area */ - dma_memcpy((char *)memory_end, __bss_stop, mtd_size); - - memory_mtd_start = memory_end; - _ebss = memory_mtd_start; /* define _ebss for compatible */ -#endif /* CONFIG_MTD_UCLINUX */ - -#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) - /* Due to a Hardware Anomaly we need to limit the size of usable - * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on - * 05000263 - Hardware loop corrupted when taking an ICPLB exception - */ -#if (defined(CONFIG_DEBUG_HUNT_FOR_ZERO)) - if (memory_end >= 56 * 1024 * 1024) - memory_end = 56 * 1024 * 1024; -#else - if (memory_end >= 60 * 1024 * 1024) - memory_end = 60 * 1024 * 1024; -#endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ - printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20); -#endif /* ANOMALY_05000263 */ - -#if !defined(CONFIG_MTD_UCLINUX) - memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ -#endif - init_mm.start_code = (unsigned long)_stext; - init_mm.end_code = (unsigned long)_etext; - init_mm.end_data = (unsigned long)_edata; - init_mm.brk = (unsigned long)0; - - init_leds(); - - printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n"); - printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid()); - if (bfin_revid() != bfin_compiled_revid()) - printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", - bfin_compiled_revid(), bfin_revid()); - if (bfin_revid() < SUPPORTED_REVID) - printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", - CPU, bfin_revid()); - printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); - - printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu Mhz System Clock\n", - cclk / 1000000, sclk / 1000000); - -#if defined(ANOMALY_05000273) - if ((cclk >> 1) <= sclk) - printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n"); -#endif - - printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); - printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); - - printk(KERN_INFO "Memory map:\n" - KERN_INFO " text = 0x%p-0x%p\n" - KERN_INFO " init = 0x%p-0x%p\n" - KERN_INFO " data = 0x%p-0x%p\n" - KERN_INFO " stack = 0x%p-0x%p\n" - KERN_INFO " bss = 0x%p-0x%p\n" - KERN_INFO " available = 0x%p-0x%p\n" -#ifdef CONFIG_MTD_UCLINUX - KERN_INFO " rootfs = 0x%p-0x%p\n" -#endif -#if DMA_UNCACHED_REGION > 0 - KERN_INFO " DMA Zone = 0x%p-0x%p\n" -#endif - , _stext, _etext, - __init_begin, __init_end, - _sdata, _edata, - (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000), - __bss_start, __bss_stop, - (void*)_ramstart, (void*)memory_end -#ifdef CONFIG_MTD_UCLINUX - , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size) -#endif -#if DMA_UNCACHED_REGION > 0 - , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend) -#endif - ); - - /* - * give all the memory to the bootmap allocator, tell it to put the - * boot mem_map at the start of memory - */ - bootmap_size = init_bootmem_node(NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */ - PAGE_OFFSET >> PAGE_SHIFT, - memory_end >> PAGE_SHIFT); - /* - * free the usable memory, we have to make sure we do not free - * the bootmem bitmap so we then reserve it after freeing it :-) - */ - free_bootmem(memory_start, memory_end - memory_start); - - reserve_bootmem(memory_start, bootmap_size); - /* - * get kmalloc into gear - */ - paging_init(); - - /* check the size of the l1 area */ - l1_length = _etext_l1 - _stext_l1; - if (l1_length > L1_CODE_LENGTH) - panic("L1 memory overflow\n"); - - l1_length = _ebss_l1 - _sdata_l1; - if (l1_length > L1_DATA_A_LENGTH) - panic("L1 memory overflow\n"); - - bf53x_cache_init(); - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -# if defined(CONFIG_BFIN_SHARED_FLASH_ENET) && defined(CONFIG_BFIN533_STAMP) - /* setup BF533_STAMP CPLD to route AMS3 to Ethernet MAC */ - bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1 << CONFIG_ENET_FLASH_PIN)); - bfin_write_FIO_FLAG_S(1 << CONFIG_ENET_FLASH_PIN); - SSYNC(); -# endif -# if defined (CONFIG_BFIN561_EZKIT) - bfin_write_FIO0_DIR(bfin_read_FIO0_DIR() | (1 << 12)); - SSYNC(); -# endif /* defined (CONFIG_BFIN561_EZKIT) */ -#endif - - printk(KERN_INFO "Hardware Trace Enabled\n"); - bfin_write_TBUFCTL(0x03); -} - -#if defined(CONFIG_BF561) -static struct cpu cpu[2]; -#else -static struct cpu cpu[1]; -#endif -static int __init topology_init(void) -{ -#if defined (CONFIG_BF561) - register_cpu(&cpu[0], 0); - register_cpu(&cpu[1], 1); - return 0; -#else - return register_cpu(cpu, 0); -#endif -} - -subsys_initcall(topology_init); - -#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) -u16 lock_kernel_check(u32 start, u32 end) -{ - if ((start <= (u32) _stext && end >= (u32) _end) - || (start >= (u32) _stext && end <= (u32) _end)) - return IN_KERNEL; - return 0; -} - -static unsigned short __init -fill_cplbtab(struct cplb_tab *table, - unsigned long start, unsigned long end, - unsigned long block_size, unsigned long cplb_data) -{ - int i; - - switch (block_size) { - case SIZE_4M: - i = 3; - break; - case SIZE_1M: - i = 2; - break; - case SIZE_4K: - i = 1; - break; - case SIZE_1K: - default: - i = 0; - break; - } - - cplb_data = (cplb_data & ~(3 << 16)) | (i << 16); - - while ((start < end) && (table->pos < table->size)) { - - table->tab[table->pos++] = start; - - if (lock_kernel_check(start, start + block_size) == IN_KERNEL) - table->tab[table->pos++] = - cplb_data | CPLB_LOCK | CPLB_DIRTY; - else - table->tab[table->pos++] = cplb_data; - - start += block_size; - } - return 0; -} - -static unsigned short __init -close_cplbtab(struct cplb_tab *table) -{ - - while (table->pos < table->size) { - - table->tab[table->pos++] = 0; - table->tab[table->pos++] = 0; /* !CPLB_VALID */ - } - return 0; -} - -static void __init generate_cpl_tables(void) -{ - - u16 i, j, process; - u32 a_start, a_end, as, ae, as_1m; - - struct cplb_tab *t_i = NULL; - struct cplb_tab *t_d = NULL; - struct s_cplb cplb; - - cplb.init_i.size = MAX_CPLBS; - cplb.init_d.size = MAX_CPLBS; - cplb.switch_i.size = MAX_SWITCH_I_CPLBS; - cplb.switch_d.size = MAX_SWITCH_D_CPLBS; - - cplb.init_i.pos = 0; - cplb.init_d.pos = 0; - cplb.switch_i.pos = 0; - cplb.switch_d.pos = 0; - - cplb.init_i.tab = icplb_table; - cplb.init_d.tab = dcplb_table; - cplb.switch_i.tab = ipdt_table; - cplb.switch_d.tab = dpdt_table; - - cplb_data[SDRAM_KERN].end = memory_end; - -#ifdef CONFIG_MTD_UCLINUX - cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start; - cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size; - cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0; -# if defined(CONFIG_ROMFS_FS) - cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB; - - /* - * The ROMFS_FS size is often not multiple of 1MB. - * This can cause multiple CPLB sets covering the same memory area. - * This will then cause multiple CPLB hit exceptions. - * Workaround: We ensure a contiguous memory area by extending the kernel - * memory section over the mtd section. - * For ROMFS_FS memory must be covered with ICPLBs anyways. - * So there is no difference between kernel and mtd memory setup. - */ - - cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;; - cplb_data[SDRAM_RAM_MTD].valid = 0; - -# endif -#else - cplb_data[SDRAM_RAM_MTD].valid = 0; -#endif - - cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION; - cplb_data[SDRAM_DMAZ].end = _ramend; - - cplb_data[RES_MEM].start = _ramend; - cplb_data[RES_MEM].end = physical_mem_end; - - if (reserved_mem_dcache_on) - cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC; - else - cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL; - - if (reserved_mem_icache_on) - cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC; - else - cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL; - - for (i = ZERO_P; i <= L2_MEM; i++) { - - if (cplb_data[i].valid) { - - as_1m = cplb_data[i].start % SIZE_1M; - - /* We need to make sure all sections are properly 1M aligned - * However between Kernel Memory and the Kernel mtd section, depending on the - * rootfs size, there can be overlapping memory areas. - */ - - if (as_1m && i!=L1I_MEM && i!=L1D_MEM) { -#ifdef CONFIG_MTD_UCLINUX - if (i == SDRAM_RAM_MTD) { - if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start) - cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)) + SIZE_1M; - else - cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M)); - } else -#endif - printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n", - cplb_data[i].name, cplb_data[i].start); - } - - as = cplb_data[i].start % SIZE_4M; - ae = cplb_data[i].end % SIZE_4M; - - if (as) - a_start = cplb_data[i].start + (SIZE_4M - (as)); - else - a_start = cplb_data[i].start; - - a_end = cplb_data[i].end - ae; - - for (j = INITIAL_T; j <= SWITCH_T; j++) { - - switch (j) { - case INITIAL_T: - if (cplb_data[i].attr & INITIAL_T) { - t_i = &cplb.init_i; - t_d = &cplb.init_d; - process = 1; - } else - process = 0; - break; - case SWITCH_T: - if (cplb_data[i].attr & SWITCH_T) { - t_i = &cplb.switch_i; - t_d = &cplb.switch_d; - process = 1; - } else - process = 0; - break; - default: - process = 0; - break; - } - - if (process) { - if (cplb_data[i].attr & I_CPLB) { - - if (cplb_data[i].psize) { - fill_cplbtab(t_i, - cplb_data[i].start, - cplb_data[i].end, - cplb_data[i].psize, - cplb_data[i].i_conf); - } else { - /*icplb_table */ -#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) - if (i == SDRAM_KERN) { - fill_cplbtab(t_i, - cplb_data[i].start, - cplb_data[i].end, - SIZE_4M, - cplb_data[i].i_conf); - } else -#endif - { - fill_cplbtab(t_i, - cplb_data[i].start, - a_start, - SIZE_1M, - cplb_data[i].i_conf); - fill_cplbtab(t_i, - a_start, - a_end, - SIZE_4M, - cplb_data[i].i_conf); - fill_cplbtab(t_i, a_end, - cplb_data[i].end, - SIZE_1M, - cplb_data[i].i_conf); - } - } - - } - if (cplb_data[i].attr & D_CPLB) { - - if (cplb_data[i].psize) { - fill_cplbtab(t_d, - cplb_data[i].start, - cplb_data[i].end, - cplb_data[i].psize, - cplb_data[i].d_conf); - } else { -/*dcplb_table*/ - fill_cplbtab(t_d, - cplb_data[i].start, - a_start, SIZE_1M, - cplb_data[i].d_conf); - fill_cplbtab(t_d, a_start, - a_end, SIZE_4M, - cplb_data[i].d_conf); - fill_cplbtab(t_d, a_end, - cplb_data[i].end, - SIZE_1M, - cplb_data[i].d_conf); - - } - - } - } - } - - } - } - -/* close tables */ - - close_cplbtab(&cplb.init_i); - close_cplbtab(&cplb.init_d); - - cplb.init_i.tab[cplb.init_i.pos] = -1; - cplb.init_d.tab[cplb.init_d.pos] = -1; - cplb.switch_i.tab[cplb.switch_i.pos] = -1; - cplb.switch_d.tab[cplb.switch_d.pos] = -1; - -} - -#endif - -static inline u_long get_vco(void) -{ - u_long msel; - u_long vco; - - msel = (bfin_read_PLL_CTL() >> 9) & 0x3F; - if (0 == msel) - msel = 64; - - vco = CONFIG_CLKIN_HZ; - vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */ - vco = msel * vco; - return vco; -} - -/*Get the Core clock*/ -u_long get_cclk(void) -{ - u_long csel, ssel; - if (bfin_read_PLL_STAT() & 0x1) - return CONFIG_CLKIN_HZ; - - ssel = bfin_read_PLL_DIV(); - csel = ((ssel >> 4) & 0x03); - ssel &= 0xf; - if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ - return get_vco() / ssel; - return get_vco() >> csel; -} - -EXPORT_SYMBOL(get_cclk); - -/* Get the System clock */ -u_long get_sclk(void) -{ - u_long ssel; - - if (bfin_read_PLL_STAT() & 0x1) - return CONFIG_CLKIN_HZ; - - ssel = (bfin_read_PLL_DIV() & 0xf); - if (0 == ssel) { - printk(KERN_WARNING "Invalid System Clock\n"); - ssel = 1; - } - - return get_vco() / ssel; -} - -EXPORT_SYMBOL(get_sclk); - -/* - * Get CPU information for use by the procfs. - */ -static int show_cpuinfo(struct seq_file *m, void *v) -{ - char *cpu, *mmu, *fpu, *name; - uint32_t revid; - - u_long cclk = 0, sclk = 0; - u_int dcache_size = 0, dsup_banks = 0; - - cpu = CPU; - mmu = "none"; - fpu = "none"; - revid = bfin_revid(); - name = bfin_board_name; - - cclk = get_cclk(); - sclk = get_sclk(); - - seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n" - "MMU:\t\t%s\n" - "FPU:\t\t%s\n" - "Core Clock:\t%9lu Hz\n" - "System Clock:\t%9lu Hz\n" - "BogoMips:\t%lu.%02lu\n" - "Calibration:\t%lu loops\n", - cpu, revid, mmu, fpu, - cclk, - sclk, - (loops_per_jiffy * HZ) / 500000, - ((loops_per_jiffy * HZ) / 5000) % 100, - (loops_per_jiffy * HZ)); - seq_printf(m, "Board Name:\t%s\n", name); - seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20); - seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20); - if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC)) - seq_printf(m, "I-CACHE:\tON\n"); - else - seq_printf(m, "I-CACHE:\tOFF\n"); - if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE)) - seq_printf(m, "D-CACHE:\tON" -#if defined CONFIG_BLKFIN_WB - " (write-back)" -#elif defined CONFIG_BLKFIN_WT - " (write-through)" -#endif - "\n"); - else - seq_printf(m, "D-CACHE:\tOFF\n"); - - - switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) { - case ACACHE_BSRAM: - seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n"); - dcache_size = 16; - dsup_banks = 1; - break; - case ACACHE_BCACHE: - seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n"); - dcache_size = 32; - dsup_banks = 2; - break; - case ASRAM_BSRAM: - seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n"); - dcache_size = 0; - dsup_banks = 0; - break; - default: - break; - } - - - seq_printf(m, "I-CACHE Size:\t%dKB\n", BLKFIN_ICACHESIZE / 1024); - seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size); - seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n", - BLKFIN_ISUBBANKS, BLKFIN_IWAYS, BLKFIN_ILINES); - seq_printf(m, - "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", - dsup_banks, BLKFIN_DSUBBANKS, BLKFIN_DWAYS, - BLKFIN_DLINES); -#ifdef CONFIG_BLKFIN_CACHE_LOCK - switch (read_iloc()) { - case WAY0_L: - seq_printf(m, "Way0 Locked-Down\n"); - break; - case WAY1_L: - seq_printf(m, "Way1 Locked-Down\n"); - break; - case WAY01_L: - seq_printf(m, "Way0,Way1 Locked-Down\n"); - break; - case WAY2_L: - seq_printf(m, "Way2 Locked-Down\n"); - break; - case WAY02_L: - seq_printf(m, "Way0,Way2 Locked-Down\n"); - break; - case WAY12_L: - seq_printf(m, "Way1,Way2 Locked-Down\n"); - break; - case WAY012_L: - seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n"); - break; - case WAY3_L: - seq_printf(m, "Way3 Locked-Down\n"); - break; - case WAY03_L: - seq_printf(m, "Way0,Way3 Locked-Down\n"); - break; - case WAY13_L: - seq_printf(m, "Way1,Way3 Locked-Down\n"); - break; - case WAY013_L: - seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n"); - break; - case WAY32_L: - seq_printf(m, "Way3,Way2 Locked-Down\n"); - break; - case WAY320_L: - seq_printf(m, "Way3,Way2,Way0 Locked-Down\n"); - break; - case WAY321_L: - seq_printf(m, "Way3,Way2,Way1 Locked-Down\n"); - break; - case WAYALL_L: - seq_printf(m, "All Ways are locked\n"); - break; - default: - seq_printf(m, "No Ways are locked\n"); - } -#endif - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - return *pos < NR_CPUS ? ((void *)0x12345678) : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return c_start(m, pos); -} - -static void c_stop(struct seq_file *m, void *v) -{ -} - -struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, -}; - -void cmdline_init(unsigned long r0) -{ - if (r0) - strncpy(command_line, (char *)r0, COMMAND_LINE_SIZE); -} diff --git a/trunk/arch/blackfin/kernel/signal.c b/trunk/arch/blackfin/kernel/signal.c deleted file mode 100644 index 316e65c3439d..000000000000 --- a/trunk/arch/blackfin/kernel/signal.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - * File: arch/blackfin/kernel/signal.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - -struct fdpic_func_descriptor { - unsigned long text; - unsigned long GOT; -}; - -struct rt_sigframe { - int sig; - struct siginfo *pinfo; - void *puc; - char retcode[8]; - struct siginfo info; - struct ucontext uc; -}; - -asmlinkage int sys_sigaltstack(const stack_t * uss, stack_t * uoss) -{ - return do_sigaltstack(uss, uoss, rdusp()); -} - -static inline int -rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc, int *pr0) -{ - unsigned long usp = 0; - int err = 0; - -#define RESTORE(x) err |= __get_user(regs->x, &sc->sc_##x) - - /* restore passed registers */ - RESTORE(r0); RESTORE(r1); RESTORE(r2); RESTORE(r3); - RESTORE(r4); RESTORE(r5); RESTORE(r6); RESTORE(r7); - RESTORE(p0); RESTORE(p1); RESTORE(p2); RESTORE(p3); - RESTORE(p4); RESTORE(p5); - err |= __get_user(usp, &sc->sc_usp); - wrusp(usp); - RESTORE(a0w); RESTORE(a1w); - RESTORE(a0x); RESTORE(a1x); - RESTORE(astat); - RESTORE(rets); - RESTORE(pc); - RESTORE(retx); - RESTORE(fp); - RESTORE(i0); RESTORE(i1); RESTORE(i2); RESTORE(i3); - RESTORE(m0); RESTORE(m1); RESTORE(m2); RESTORE(m3); - RESTORE(l0); RESTORE(l1); RESTORE(l2); RESTORE(l3); - RESTORE(b0); RESTORE(b1); RESTORE(b2); RESTORE(b3); - RESTORE(lc0); RESTORE(lc1); - RESTORE(lt0); RESTORE(lt1); - RESTORE(lb0); RESTORE(lb1); - RESTORE(seqstat); - - regs->orig_p0 = -1; /* disable syscall checks */ - - *pr0 = regs->r0; - return err; -} - -asmlinkage int do_rt_sigreturn(unsigned long __unused) -{ - struct pt_regs *regs = (struct pt_regs *)__unused; - unsigned long usp = rdusp(); - struct rt_sigframe *frame = (struct rt_sigframe *)(usp); - sigset_t set; - int r0; - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) - goto badframe; - - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - - if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) - goto badframe; - - if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->usp) == -EFAULT) - goto badframe; - - return r0; - - badframe: - force_sig(SIGSEGV, current); - return 0; -} - -static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs) -{ - int err = 0; - -#define SETUP(x) err |= __put_user(regs->x, &sc->sc_##x) - - SETUP(r0); SETUP(r1); SETUP(r2); SETUP(r3); - SETUP(r4); SETUP(r5); SETUP(r6); SETUP(r7); - SETUP(p0); SETUP(p1); SETUP(p2); SETUP(p3); - SETUP(p4); SETUP(p5); - err |= __put_user(rdusp(), &sc->sc_usp); - SETUP(a0w); SETUP(a1w); - SETUP(a0x); SETUP(a1x); - SETUP(astat); - SETUP(rets); - SETUP(pc); - SETUP(retx); - SETUP(fp); - SETUP(i0); SETUP(i1); SETUP(i2); SETUP(i3); - SETUP(m0); SETUP(m1); SETUP(m2); SETUP(m3); - SETUP(l0); SETUP(l1); SETUP(l2); SETUP(l3); - SETUP(b0); SETUP(b1); SETUP(b2); SETUP(b3); - SETUP(lc0); SETUP(lc1); - SETUP(lt0); SETUP(lt1); - SETUP(lb0); SETUP(lb1); - SETUP(seqstat); - - return err; -} - -static inline void push_cache(unsigned long vaddr, unsigned int len) -{ - flush_icache_range(vaddr, vaddr + len); -} - -static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, - size_t frame_size) -{ - unsigned long usp; - - /* Default to using normal stack. */ - usp = rdusp(); - - /* This is the X/Open sanctioned signal stack switching. */ - if (ka->sa.sa_flags & SA_ONSTACK) { - if (!on_sig_stack(usp)) - usp = current->sas_ss_sp + current->sas_ss_size; - } - return (void *)((usp - frame_size) & -8UL); -} - -static int -setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info, - sigset_t * set, struct pt_regs *regs) -{ - struct rt_sigframe *frame; - int err = 0; - - frame = get_sigframe(ka, regs, sizeof(*frame)); - - err |= __put_user((current_thread_info()->exec_domain - && current_thread_info()->exec_domain->signal_invmap - && sig < 32 - ? current_thread_info()->exec_domain-> - signal_invmap[sig] : sig), &frame->sig); - - err |= __put_user(&frame->info, &frame->pinfo); - err |= __put_user(&frame->uc, &frame->puc); - err |= copy_siginfo_to_user(&frame->info, info); - - /* Create the ucontext. */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= - __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); - err |= __put_user(sas_ss_flags(rdusp()), &frame->uc.uc_stack.ss_flags); - err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); - err |= rt_setup_sigcontext(&frame->uc.uc_mcontext, regs); - err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - - /* Set up to return from userspace. */ - err |= __put_user(0x28, &(frame->retcode[0])); - err |= __put_user(0xe1, &(frame->retcode[1])); - err |= __put_user(0xad, &(frame->retcode[2])); - err |= __put_user(0x00, &(frame->retcode[3])); - err |= __put_user(0xa0, &(frame->retcode[4])); - err |= __put_user(0x00, &(frame->retcode[5])); - - if (err) - goto give_sigsegv; - - push_cache((unsigned long)&frame->retcode, sizeof(frame->retcode)); - - /* Set up registers for signal handler */ - wrusp((unsigned long)frame); - if (get_personality & FDPIC_FUNCPTRS) { - struct fdpic_func_descriptor __user *funcptr = - (struct fdpic_func_descriptor *) ka->sa.sa_handler; - __get_user(regs->pc, &funcptr->text); - __get_user(regs->p3, &funcptr->GOT); - } else - regs->pc = (unsigned long)ka->sa.sa_handler; - regs->rets = (unsigned long)(frame->retcode); - - regs->r0 = frame->sig; - regs->r1 = (unsigned long)(&frame->info); - regs->r2 = (unsigned long)(&frame->uc); - - return 0; - - give_sigsegv: - if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - force_sig(SIGSEGV, current); - return -EFAULT; -} - -static inline void -handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) -{ - switch (regs->r0) { - case -ERESTARTNOHAND: - if (!has_handler) - goto do_restart; - regs->r0 = -EINTR; - break; - - case -ERESTARTSYS: - if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { - regs->r0 = -EINTR; - break; - } - /* fallthrough */ - case -ERESTARTNOINTR: - do_restart: - regs->p0 = regs->orig_p0; - regs->r0 = regs->orig_r0; - regs->pc -= 2; - break; - } -} - -/* - * OK, we're invoking a handler - */ -static int -handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, - sigset_t *oldset, struct pt_regs *regs) -{ - int ret; - - /* are we from a system call? to see pt_regs->orig_p0 */ - if (regs->orig_p0 >= 0) - /* If so, check system call restarting.. */ - handle_restart(regs, ka, 1); - - /* set up the stack frame */ - ret = setup_rt_frame(sig, ka, info, oldset, regs); - - if (ret == 0) { - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, - &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } - return ret; -} - -/* - * Note that 'init' is a special process: it doesn't get signals it doesn't - * want to handle. Thus you cannot kill init even with a SIGKILL even by - * mistake. - * - * Note that we go through the signals twice: once to check the signals - * that the kernel can handle, and then we build all the user-level signal - * handling stack-frames in one go after that. - */ -asmlinkage void do_signal(struct pt_regs *regs) -{ - siginfo_t info; - int signr; - struct k_sigaction ka; - sigset_t *oldset; - - current->thread.esp0 = (unsigned long)regs; - - if (try_to_freeze()) - goto no_signal; - - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - - signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { - /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } - - return; - } - -no_signal: - /* Did we come from a system call? */ - if (regs->orig_p0 >= 0) - /* Restart the system call - no handlers present */ - handle_restart(regs, NULL, 0); - - /* if there's no signal to deliver, we just put the saved sigmask - * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } -} diff --git a/trunk/arch/blackfin/kernel/sys_bfin.c b/trunk/arch/blackfin/kernel/sys_bfin.c deleted file mode 100644 index f436e6743f5a..000000000000 --- a/trunk/arch/blackfin/kernel/sys_bfin.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * File: arch/blackfin/kernel/sys_bfin.c - * Based on: - * Author: - * - * Created: - * Description: This file contains various random system calls that - * have a non-standard calling sequence on the Linux/bfin - * platform. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * sys_pipe() is the normal C calling standard for creating - * a pipe. It's not the way unix traditionally does this, though. - */ -asmlinkage int sys_pipe(unsigned long *fildes) -{ - int fd[2]; - int error; - - error = do_pipe(fd); - if (!error) { - if (copy_to_user(fildes, fd, 2 * sizeof(int))) - error = -EFAULT; - } - return error; -} - -/* common code for old and new mmaps */ -static inline long -do_mmap2(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff) -{ - int error = -EBADF; - struct file *file = NULL; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - file = fget(fd); - if (!file) - goto out; - } - - down_write(¤t->mm->mmap_sem); - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - - if (file) - fput(file); - out: - return error; -} - -asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff) -{ - return do_mmap2(addr, len, prot, flags, fd, pgoff); -} - -asmlinkage int sys_getpagesize(void) -{ - return PAGE_SIZE; -} - -asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) -{ - return sram_alloc_with_lsl(size, flags); -} - -asmlinkage int sys_sram_free(const void *addr) -{ - return sram_free_with_lsl(addr); -} - -asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len) -{ - return safe_dma_memcpy(dest, src, len); -} diff --git a/trunk/arch/blackfin/kernel/time.c b/trunk/arch/blackfin/kernel/time.c deleted file mode 100644 index f578176b6d92..000000000000 --- a/trunk/arch/blackfin/kernel/time.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * File: arch/blackfin/kernel/time.c - * Based on: none - original work - * Author: - * - * Created: - * Description: This file contains the bfin-specific time handling details. - * Most of the stuff is located in the machine specific files. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include - -/* This is an NTP setting */ -#define TICK_SIZE (tick_nsec / 1000) - -static void time_sched_init(irqreturn_t(*timer_routine) - (int, void *)); -static unsigned long gettimeoffset(void); -static inline void do_leds(void); - -#if (defined(CONFIG_BFIN_ALIVE_LED) || defined(CONFIG_BFIN_IDLE_LED)) -void __init init_leds(void) -{ - unsigned int tmp = 0; - -#if defined(CONFIG_BFIN_ALIVE_LED) - /* config pins as output. */ - tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_DPORT(); - SSYNC(); - bfin_write_CONFIG_BFIN_ALIVE_LED_DPORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); - SSYNC(); - - /* First set led be off */ - tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT(); - SSYNC(); - bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp | CONFIG_BFIN_ALIVE_LED_PIN); /* light off */ - SSYNC(); -#endif - -#if defined(CONFIG_BFIN_IDLE_LED) - /* config pins as output. */ - tmp = bfin_read_CONFIG_BFIN_IDLE_LED_DPORT(); - SSYNC(); - bfin_write_CONFIG_BFIN_IDLE_LED_DPORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); - SSYNC(); - - /* First set led be off */ - tmp = bfin_read_CONFIG_BFIN_IDLE_LED_PORT(); - SSYNC(); - bfin_write_CONFIG_BFIN_IDLE_LED_PORT(tmp | CONFIG_BFIN_IDLE_LED_PIN); /* light off */ - SSYNC(); -#endif -} -#else -void __init init_leds(void) -{ -} -#endif - -#if defined(CONFIG_BFIN_ALIVE_LED) -static inline void do_leds(void) -{ - static unsigned int count = 50; - static int flag = 0; - unsigned short tmp = 0; - - if (--count == 0) { - count = 50; - flag = ~flag; - } - tmp = bfin_read_CONFIG_BFIN_ALIVE_LED_PORT(); - SSYNC(); - - if (flag) - tmp &= ~CONFIG_BFIN_ALIVE_LED_PIN; /* light on */ - else - tmp |= CONFIG_BFIN_ALIVE_LED_PIN; /* light off */ - - bfin_write_CONFIG_BFIN_ALIVE_LED_PORT(tmp); - SSYNC(); - -} -#else -static inline void do_leds(void) -{ -} -#endif - -static struct irqaction bfin_timer_irq = { - .name = "BFIN Timer Tick", - .flags = IRQF_DISABLED -}; - -/* - * The way that the Blackfin core timer works is: - * - CCLK is divided by a programmable 8-bit pre-scaler (TSCALE) - * - Every time TSCALE ticks, a 32bit is counted down (TCOUNT) - * - * If you take the fastest clock (1ns, or 1GHz to make the math work easier) - * 10ms is 10,000,000 clock ticks, which fits easy into a 32-bit counter - * (32 bit counter is 4,294,967,296ns or 4.2 seconds) so, we don't need - * to use TSCALE, and program it to zero (which is pass CCLK through). - * If you feel like using it, try to keep HZ * TIMESCALE to some - * value that divides easy (like power of 2). - */ - -#define TIME_SCALE 1 - -static void -time_sched_init(irqreturn_t(*timer_routine) (int, void *)) -{ - u32 tcount; - - /* power up the timer, but don't enable it just yet */ - bfin_write_TCNTL(1); - CSYNC(); - - /* - * the TSCALE prescaler counter. - */ - bfin_write_TSCALE((TIME_SCALE - 1)); - - tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1); - bfin_write_TPERIOD(tcount); - bfin_write_TCOUNT(tcount); - - /* now enable the timer */ - CSYNC(); - - bfin_write_TCNTL(7); - - bfin_timer_irq.handler = (irq_handler_t)timer_routine; - /* call setup_irq instead of request_irq because request_irq calls - * kmalloc which has not been initialized yet - */ - setup_irq(IRQ_CORETMR, &bfin_timer_irq); -} - -/* - * Should return useconds since last timer tick - */ -static unsigned long gettimeoffset(void) -{ - unsigned long offset; - unsigned long clocks_per_jiffy; - - clocks_per_jiffy = bfin_read_TPERIOD(); - offset = - (clocks_per_jiffy - - bfin_read_TCOUNT()) / (((clocks_per_jiffy + 1) * HZ) / - USEC_PER_SEC); - - /* Check if we just wrapped the counters and maybe missed a tick */ - if ((bfin_read_ILAT() & (1 << IRQ_CORETMR)) - && (offset < (100000 / HZ / 2))) - offset += (USEC_PER_SEC / HZ); - - return offset; -} - -static inline int set_rtc_mmss(unsigned long nowtime) -{ - return 0; -} - -/* - * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick - */ -#ifdef CONFIG_CORE_TIMER_IRQ_L1 -irqreturn_t timer_interrupt(int irq, void *dummy)__attribute__((l1_text)); -#endif - -irqreturn_t timer_interrupt(int irq, void *dummy) -{ - /* last time the cmos clock got updated */ - static long last_rtc_update = 0; - - write_seqlock(&xtime_lock); - - do_timer(1); - do_leds(); - -#ifndef CONFIG_SMP - update_process_times(user_mode(get_irq_regs())); -#endif - profile_tick(CPU_PROFILING); - - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - - if (ntp_synced() && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / NSEC_PER_USEC) >= - 500000 - ((unsigned)TICK_SIZE) / 2 - && (xtime.tv_nsec / NSEC_PER_USEC) <= - 500000 + ((unsigned)TICK_SIZE) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* Do it again in 60s. */ - last_rtc_update = xtime.tv_sec - 600; - } - write_sequnlock(&xtime_lock); - return IRQ_HANDLED; -} - -void __init time_init(void) -{ - time_t secs_since_1970 = (365 * 37 + 9) * 24 * 60 * 60; /* 1 Jan 2007 */ - -#ifdef CONFIG_RTC_DRV_BFIN - /* [#2663] hack to filter junk RTC values that would cause - * userspace to have to deal with time values greater than - * 2^31 seconds (which uClibc cannot cope with yet) - */ - if ((bfin_read_RTC_STAT() & 0xC0000000) == 0xC0000000) { - printk(KERN_NOTICE "bfin-rtc: invalid date; resetting\n"); - bfin_write_RTC_STAT(0); - } -#endif - - /* Initialize xtime. From now on, xtime is updated with timer interrupts */ - xtime.tv_sec = secs_since_1970; - xtime.tv_nsec = 0; - - wall_to_monotonic.tv_sec = -xtime.tv_sec; - - time_sched_init(timer_interrupt); -} - -#ifndef CONFIG_GENERIC_TIME -void do_gettimeofday(struct timeval *tv) -{ - unsigned long flags; - unsigned long seq; - unsigned long usec, sec; - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - usec = gettimeoffset(); - sec = xtime.tv_sec; - usec += (xtime.tv_nsec / NSEC_PER_USEC); - } - while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - while (usec >= USEC_PER_SEC) { - usec -= USEC_PER_SEC; - sec++; - } - - tv->tv_sec = sec; - tv->tv_usec = usec; -} -EXPORT_SYMBOL(do_gettimeofday); - -int do_settimeofday(struct timespec *tv) -{ - time_t wtm_sec, sec = tv->tv_sec; - long wtm_nsec, nsec = tv->tv_nsec; - - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) - return -EINVAL; - - write_seqlock_irq(&xtime_lock); - /* - * This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! - */ - nsec -= (gettimeoffset() * NSEC_PER_USEC); - - wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); - wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); - - set_normalized_timespec(&xtime, sec, nsec); - set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); - - ntp_clear(); - - write_sequnlock_irq(&xtime_lock); - clock_was_set(); - - return 0; -} -EXPORT_SYMBOL(do_settimeofday); -#endif /* !CONFIG_GENERIC_TIME */ - -/* - * Scheduler clock - returns current time in nanosec units. - */ -unsigned long long sched_clock(void) -{ - return (unsigned long long)jiffies *(NSEC_PER_SEC / HZ); -} diff --git a/trunk/arch/blackfin/kernel/traps.c b/trunk/arch/blackfin/kernel/traps.c deleted file mode 100644 index 9556b73de808..000000000000 --- a/trunk/arch/blackfin/kernel/traps.c +++ /dev/null @@ -1,649 +0,0 @@ -/* - * File: arch/blackfin/kernel/traps.c - * Based on: - * Author: Hamish Macdonald - * - * Created: - * Description: uses S/W interrupt 15 for the system calls - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_KGDB -# include -# include -#endif - -/* Initiate the event table handler */ -void __init trap_init(void) -{ - CSYNC(); - bfin_write_EVT3(trap); - CSYNC(); -} - -asmlinkage void trap_c(struct pt_regs *fp); - -int kstack_depth_to_print = 48; - -static int printk_address(unsigned long address) -{ - struct vm_list_struct *vml; - struct task_struct *p; - struct mm_struct *mm; - -#ifdef CONFIG_KALLSYMS - unsigned long offset = 0, symsize; - const char *symname; - char *modname; - char *delim = ":"; - char namebuf[128]; - - /* look up the address and see if we are in kernel space */ - symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); - - if (symname) { - /* yeah! kernel space! */ - if (!modname) - modname = delim = ""; - return printk("<0x%p> { %s%s%s%s + 0x%lx }", - (void*)address, delim, modname, delim, symname, - (unsigned long)offset); - - } -#endif - - /* looks like we're off in user-land, so let's walk all the - * mappings of all our processes and see if we can't be a whee - * bit more specific - */ - write_lock_irq(&tasklist_lock); - for_each_process(p) { - mm = get_task_mm(p); - if (!mm) - continue; - - vml = mm->context.vmlist; - while (vml) { - struct vm_area_struct *vma = vml->vma; - - if (address >= vma->vm_start && address < vma->vm_end) { - char *name = p->comm; - struct file *file = vma->vm_file; - if (file) { - char _tmpbuf[256]; - name = d_path(file->f_dentry, - file->f_vfsmnt, - _tmpbuf, - sizeof(_tmpbuf)); - } - - write_unlock_irq(&tasklist_lock); - return printk("<0x%p> [ %s + 0x%lx ]", - (void*)address, name, - (unsigned long) - ((address - vma->vm_start) + - (vma->vm_pgoff << PAGE_SHIFT))); - } - - vml = vml->next; - } - } - write_unlock_irq(&tasklist_lock); - - /* we were unable to find this address anywhere */ - return printk("[<0x%p>]", (void*)address); -} - -#define trace_buffer_save(x) \ - do { \ - (x) = bfin_read_TBUFCTL(); \ - bfin_write_TBUFCTL((x) & ~TBUFEN); \ - } while (0) -#define trace_buffer_restore(x) \ - do { \ - bfin_write_TBUFCTL((x)); \ - } while (0) - -asmlinkage void trap_c(struct pt_regs *fp) -{ - int j, sig = 0; - siginfo_t info; - unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; - -#ifdef CONFIG_KGDB -# define CHK_DEBUGGER_TRAP() do { CHK_DEBUGGER(trapnr, sig, info.si_code, fp,); } while (0) -# define CHK_DEBUGGER_TRAP_MAYBE() do { if (kgdb_connected) CHK_DEBUGGER_TRAP(); } while (0) -#else -# define CHK_DEBUGGER_TRAP() do { } while (0) -# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) -#endif - - trace_buffer_save(j); - - /* trap_c() will be called for exceptions. During exceptions - * processing, the pc value should be set with retx value. - * With this change we can cleanup some code in signal.c- TODO - */ - fp->orig_pc = fp->retx; - /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n", - trapnr, fp->ipend, fp->pc, fp->retx); */ - - /* send the appropriate signal to the user program */ - switch (trapnr) { - - /* This table works in conjuction with the one in ./mach-common/entry.S - * Some exceptions are handled there (in assembly, in exception space) - * Some are handled here, (in C, in interrupt space) - * Some, like CPLB, are handled in both, where the normal path is - * handled in assembly/exception space, and the error path is handled - * here - */ - - /* 0x00 - Linux Syscall, getting here is an error */ - /* 0x01 - userspace gdb breakpoint, handled here */ - case VEC_EXCPT01: - info.si_code = TRAP_ILLTRAP; - sig = SIGTRAP; - CHK_DEBUGGER_TRAP_MAYBE(); - /* Check if this is a breakpoint in kernel space */ - if (fp->ipend & 0xffc0) - return; - else - break; -#ifdef CONFIG_KGDB - case VEC_EXCPT02 : /* gdb connection */ - info.si_code = TRAP_ILLTRAP; - sig = SIGTRAP; - CHK_DEBUGGER_TRAP(); - return; -#else - /* 0x02 - User Defined, Caught by default */ -#endif - /* 0x03 - Atomic test and set */ - case VEC_EXCPT03: - info.si_code = SEGV_STACKFLOW; - sig = SIGSEGV; - printk(KERN_EMERG EXC_0x03); - CHK_DEBUGGER_TRAP(); - break; - /* 0x04 - spinlock - handled by _ex_spinlock, - getting here is an error */ - /* 0x05 - User Defined, Caught by default */ - /* 0x06 - User Defined, Caught by default */ - /* 0x07 - User Defined, Caught by default */ - /* 0x08 - User Defined, Caught by default */ - /* 0x09 - User Defined, Caught by default */ - /* 0x0A - User Defined, Caught by default */ - /* 0x0B - User Defined, Caught by default */ - /* 0x0C - User Defined, Caught by default */ - /* 0x0D - User Defined, Caught by default */ - /* 0x0E - User Defined, Caught by default */ - /* 0x0F - User Defined, Caught by default */ - /* 0x10 HW Single step, handled here */ - case VEC_STEP: - info.si_code = TRAP_STEP; - sig = SIGTRAP; - CHK_DEBUGGER_TRAP_MAYBE(); - /* Check if this is a single step in kernel space */ - if (fp->ipend & 0xffc0) - return; - else - break; - /* 0x11 - Trace Buffer Full, handled here */ - case VEC_OVFLOW: - info.si_code = TRAP_TRACEFLOW; - sig = SIGTRAP; - printk(KERN_EMERG EXC_0x11); - CHK_DEBUGGER_TRAP(); - break; - /* 0x12 - Reserved, Caught by default */ - /* 0x13 - Reserved, Caught by default */ - /* 0x14 - Reserved, Caught by default */ - /* 0x15 - Reserved, Caught by default */ - /* 0x16 - Reserved, Caught by default */ - /* 0x17 - Reserved, Caught by default */ - /* 0x18 - Reserved, Caught by default */ - /* 0x19 - Reserved, Caught by default */ - /* 0x1A - Reserved, Caught by default */ - /* 0x1B - Reserved, Caught by default */ - /* 0x1C - Reserved, Caught by default */ - /* 0x1D - Reserved, Caught by default */ - /* 0x1E - Reserved, Caught by default */ - /* 0x1F - Reserved, Caught by default */ - /* 0x20 - Reserved, Caught by default */ - /* 0x21 - Undefined Instruction, handled here */ - case VEC_UNDEF_I: - info.si_code = ILL_ILLOPC; - sig = SIGILL; - printk(KERN_EMERG EXC_0x21); - CHK_DEBUGGER_TRAP(); - break; - /* 0x22 - Illegal Instruction Combination, handled here */ - case VEC_ILGAL_I: - info.si_code = ILL_ILLPARAOP; - sig = SIGILL; - printk(KERN_EMERG EXC_0x22); - CHK_DEBUGGER_TRAP(); - break; - /* 0x23 - Data CPLB Protection Violation, - normal case is handled in _cplb_hdr */ - case VEC_CPLB_VL: - info.si_code = ILL_CPLB_VI; - sig = SIGILL; - printk(KERN_EMERG EXC_0x23); - CHK_DEBUGGER_TRAP(); - break; - /* 0x24 - Data access misaligned, handled here */ - case VEC_MISALI_D: - info.si_code = BUS_ADRALN; - sig = SIGBUS; - printk(KERN_EMERG EXC_0x24); - CHK_DEBUGGER_TRAP(); - break; - /* 0x25 - Unrecoverable Event, handled here */ - case VEC_UNCOV: - info.si_code = ILL_ILLEXCPT; - sig = SIGILL; - printk(KERN_EMERG EXC_0x25); - CHK_DEBUGGER_TRAP(); - break; - /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr, - error case is handled here */ - case VEC_CPLB_M: - info.si_code = BUS_ADRALN; - sig = SIGBUS; - printk(KERN_EMERG EXC_0x26); - CHK_DEBUGGER_TRAP(); - break; - /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ - case VEC_CPLB_MHIT: - info.si_code = ILL_CPLB_MULHIT; -#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO - sig = SIGSEGV; - printk(KERN_EMERG "\n\nNULL pointer access (probably)\n"); -#else - sig = SIGILL; - printk(KERN_EMERG EXC_0x27); -#endif - CHK_DEBUGGER_TRAP(); - break; - /* 0x28 - Emulation Watchpoint, handled here */ - case VEC_WATCH: - info.si_code = TRAP_WATCHPT; - sig = SIGTRAP; - pr_debug(EXC_0x28); - CHK_DEBUGGER_TRAP_MAYBE(); - /* Check if this is a watchpoint in kernel space */ - if (fp->ipend & 0xffc0) - return; - else - break; -#ifdef CONFIG_BF535 - /* 0x29 - Instruction fetch access error (535 only) */ - case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */ - info.si_code = BUS_OPFETCH; - sig = SIGBUS; - printk(KERN_EMERG "BF535: VEC_ISTRU_VL\n"); - CHK_DEBUGGER_TRAP(); - break; -#else - /* 0x29 - Reserved, Caught by default */ -#endif - /* 0x2A - Instruction fetch misaligned, handled here */ - case VEC_MISALI_I: - info.si_code = BUS_ADRALN; - sig = SIGBUS; - printk(KERN_EMERG EXC_0x2A); - CHK_DEBUGGER_TRAP(); - break; - /* 0x2B - Instruction CPLB protection Violation, - handled in _cplb_hdr */ - case VEC_CPLB_I_VL: - info.si_code = ILL_CPLB_VI; - sig = SIGILL; - printk(KERN_EMERG EXC_0x2B); - CHK_DEBUGGER_TRAP(); - break; - /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */ - case VEC_CPLB_I_M: - info.si_code = ILL_CPLB_MISS; - sig = SIGBUS; - printk(KERN_EMERG EXC_0x2C); - CHK_DEBUGGER_TRAP(); - break; - /* 0x2D - Instruction CPLB Multiple Hits, handled here */ - case VEC_CPLB_I_MHIT: - info.si_code = ILL_CPLB_MULHIT; -#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO - sig = SIGSEGV; - printk(KERN_EMERG "\n\nJump to address 0 - 0x0fff\n"); -#else - sig = SIGILL; - printk(KERN_EMERG EXC_0x2D); -#endif - CHK_DEBUGGER_TRAP(); - break; - /* 0x2E - Illegal use of Supervisor Resource, handled here */ - case VEC_ILL_RES: - info.si_code = ILL_PRVOPC; - sig = SIGILL; - printk(KERN_EMERG EXC_0x2E); - CHK_DEBUGGER_TRAP(); - break; - /* 0x2F - Reserved, Caught by default */ - /* 0x30 - Reserved, Caught by default */ - /* 0x31 - Reserved, Caught by default */ - /* 0x32 - Reserved, Caught by default */ - /* 0x33 - Reserved, Caught by default */ - /* 0x34 - Reserved, Caught by default */ - /* 0x35 - Reserved, Caught by default */ - /* 0x36 - Reserved, Caught by default */ - /* 0x37 - Reserved, Caught by default */ - /* 0x38 - Reserved, Caught by default */ - /* 0x39 - Reserved, Caught by default */ - /* 0x3A - Reserved, Caught by default */ - /* 0x3B - Reserved, Caught by default */ - /* 0x3C - Reserved, Caught by default */ - /* 0x3D - Reserved, Caught by default */ - /* 0x3E - Reserved, Caught by default */ - /* 0x3F - Reserved, Caught by default */ - default: - info.si_code = TRAP_ILLTRAP; - sig = SIGTRAP; - printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", - (fp->seqstat & SEQSTAT_EXCAUSE)); - CHK_DEBUGGER_TRAP(); - break; - } - - info.si_signo = sig; - info.si_errno = 0; - info.si_addr = (void *)fp->pc; - force_sig_info(sig, &info, current); - if (sig != 0 && sig != SIGTRAP) { - unsigned long stack; - dump_bfin_regs(fp, (void *)fp->retx); - dump_bfin_trace_buffer(); - show_stack(current, &stack); - if (current->mm == NULL) - panic("Kernel exception"); - } - - /* if the address that we are about to return to is not valid, set it - * to a valid address, if we have a current application or panic - */ - if (!(fp->pc <= physical_mem_end -#if L1_CODE_LENGTH != 0 - || (fp->pc >= L1_CODE_START && - fp->pc <= (L1_CODE_START + L1_CODE_LENGTH)) -#endif - )) { - if (current->mm) { - fp->pc = current->mm->start_code; - } else { - printk(KERN_EMERG "I can't return to memory that doesn't exist - bad things happen\n"); - panic("Help - I've fallen and can't get up\n"); - } - } - - trace_buffer_restore(j); - return; -} - -/* Typical exception handling routines */ - -void dump_bfin_trace_buffer(void) -{ - int tflags; - trace_buffer_save(tflags); - - if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { - int i; - printk(KERN_EMERG "Hardware Trace:\n"); - for (i = 0; bfin_read_TBUFSTAT() & TBUFCNT; i++) { - printk(KERN_EMERG "%2i Target : ", i); - printk_address((unsigned long)bfin_read_TBUF()); - printk("\n" KERN_EMERG " Source : "); - printk_address((unsigned long)bfin_read_TBUF()); - printk("\n"); - } - } - - trace_buffer_restore(tflags); -} -EXPORT_SYMBOL(dump_bfin_trace_buffer); - -static void show_trace(struct task_struct *tsk, unsigned long *sp) -{ - unsigned long addr; - - printk("\nCall Trace:"); -#ifdef CONFIG_KALLSYMS - printk("\n"); -#endif - - while (!kstack_end(sp)) { - addr = *sp++; - /* - * If the address is either in the text segment of the - * kernel, or in the region which contains vmalloc'ed - * memory, it *may* be the address of a calling - * routine; if so, print it so that someone tracing - * down the cause of the crash will be able to figure - * out the call path that was taken. - */ - if (kernel_text_address(addr)) - print_ip_sym(addr); - } - - printk("\n"); -} - -void show_stack(struct task_struct *task, unsigned long *stack) -{ - unsigned long *endstack, addr; - int i; - - /* Cannot call dump_bfin_trace_buffer() here as show_stack() is - * called externally in some places in the kernel. - */ - - if (!stack) { - if (task) - stack = (unsigned long *)task->thread.ksp; - else - stack = (unsigned long *)&stack; - } - - addr = (unsigned long)stack; - endstack = (unsigned long *)PAGE_ALIGN(addr); - - printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack); - for (i = 0; i < kstack_depth_to_print; i++) { - if (stack + 1 > endstack) - break; - if (i % 8 == 0) - printk("\n" KERN_EMERG " "); - printk(" %08lx", *stack++); - } - - show_trace(task, stack); -} - -void dump_stack(void) -{ - unsigned long stack; - int tflags; - trace_buffer_save(tflags); - dump_bfin_trace_buffer(); - show_stack(current, &stack); - trace_buffer_restore(tflags); -} - -EXPORT_SYMBOL(dump_stack); - -void dump_bfin_regs(struct pt_regs *fp, void *retaddr) -{ - if (current->pid) { - printk("\nCURRENT PROCESS:\n\n"); - printk("COMM=%s PID=%d\n", current->comm, current->pid); - } else { - printk - ("\nNo Valid pid - Either things are really messed up, or you are in the kernel\n"); - } - - if (current->mm) { - printk("TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" - "BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", - (void*)current->mm->start_code, - (void*)current->mm->end_code, - (void*)current->mm->start_data, - (void*)current->mm->end_data, - (void*)current->mm->end_data, - (void*)current->mm->brk, - (void*)current->mm->start_stack); - } - - printk("return address: 0x%p; contents of [PC-16...PC+8]:\n", retaddr); - if (retaddr != 0 && retaddr <= (void*)physical_mem_end -#if L1_CODE_LENGTH != 0 - /* FIXME: Copy the code out of L1 Instruction SRAM through dma - memcpy. */ - && !(retaddr >= (void*)L1_CODE_START - && retaddr < (void*)(L1_CODE_START + L1_CODE_LENGTH)) -#endif - ) { - int i = 0; - unsigned short x = 0; - for (i = -16; i < 8; i++) { - if (get_user(x, (unsigned short *)retaddr + i)) - break; -#ifndef CONFIG_DEBUG_HWERR - /* If one of the last few instructions was a STI - * it is likily that the error occured awhile ago - * and we just noticed - */ - if (x >= 0x0040 && x <= 0x0047 && i <= 0) - panic("\n\nWARNING : You should reconfigure the kernel to turn on\n" - " 'Hardware error interrupt debugging'\n" - " The rest of this error is meanless\n"); -#endif - - if (i == -8) - printk("\n"); - if (i == 0) - printk("X\n"); - printk("%04x ", x); - } - } else - printk("Cannot look at the [PC] for it is in unreadable L1 SRAM - sorry\n"); - - printk("\n\n"); - - printk("RETE: %08lx RETN: %08lx RETX: %08lx RETS: %08lx\n", - fp->rete, fp->retn, fp->retx, fp->rets); - printk("IPEND: %04lx SYSCFG: %04lx\n", fp->ipend, fp->syscfg); - printk("SEQSTAT: %08lx SP: %08lx\n", (long)fp->seqstat, (long)fp); - printk("R0: %08lx R1: %08lx R2: %08lx R3: %08lx\n", - fp->r0, fp->r1, fp->r2, fp->r3); - printk("R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n", - fp->r4, fp->r5, fp->r6, fp->r7); - printk("P0: %08lx P1: %08lx P2: %08lx P3: %08lx\n", - fp->p0, fp->p1, fp->p2, fp->p3); - printk("P4: %08lx P5: %08lx FP: %08lx\n", fp->p4, fp->p5, fp->fp); - printk("A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", - fp->a0w, fp->a0x, fp->a1w, fp->a1x); - - printk("LB0: %08lx LT0: %08lx LC0: %08lx\n", fp->lb0, fp->lt0, - fp->lc0); - printk("LB1: %08lx LT1: %08lx LC1: %08lx\n", fp->lb1, fp->lt1, - fp->lc1); - printk("B0: %08lx L0: %08lx M0: %08lx I0: %08lx\n", fp->b0, fp->l0, - fp->m0, fp->i0); - printk("B1: %08lx L1: %08lx M1: %08lx I1: %08lx\n", fp->b1, fp->l1, - fp->m1, fp->i1); - printk("B2: %08lx L2: %08lx M2: %08lx I2: %08lx\n", fp->b2, fp->l2, - fp->m2, fp->i2); - printk("B3: %08lx L3: %08lx M3: %08lx I3: %08lx\n", fp->b3, fp->l3, - fp->m3, fp->i3); - - printk("\nUSP: %08lx ASTAT: %08lx\n", rdusp(), fp->astat); - if ((long)fp->seqstat & SEQSTAT_EXCAUSE) { - printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR()); - printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR()); - } - - printk("\n\n"); -} - -#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 -asmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); -#endif - -asmlinkage int sys_bfin_spinlock(int *spinlock) -{ - int ret = 0; - int tmp = 0; - - local_irq_disable(); - ret = get_user(tmp, spinlock); - if (ret == 0) { - if (tmp) - ret = 1; - tmp = 1; - put_user(tmp, spinlock); - } - local_irq_enable(); - return ret; -} - -void panic_cplb_error(int cplb_panic, struct pt_regs *fp) -{ - switch (cplb_panic) { - case CPLB_NO_UNLOCKED: - printk(KERN_EMERG "All CPLBs are locked\n"); - break; - case CPLB_PROT_VIOL: - return; - case CPLB_NO_ADDR_MATCH: - return; - case CPLB_UNKNOWN_ERR: - printk(KERN_EMERG "Unknown CPLB Exception\n"); - break; - } - - printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void*)bfin_read_DCPLB_FAULT_ADDR()); - printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void*)bfin_read_ICPLB_FAULT_ADDR()); - dump_bfin_regs(fp, (void *)fp->retx); - dump_stack(); - panic("Unrecoverable event\n"); -} diff --git a/trunk/arch/blackfin/kernel/vmlinux.lds.S b/trunk/arch/blackfin/kernel/vmlinux.lds.S deleted file mode 100644 index 6ae9ebbd8e58..000000000000 --- a/trunk/arch/blackfin/kernel/vmlinux.lds.S +++ /dev/null @@ -1,228 +0,0 @@ -/* - * File: arch/blackfin/kernel/vmlinux.lds.S - * Based on: none - original work - * Author: - * - * Created: Tue Sep 21 2004 - * Description: Master linker script for blackfin architecture - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define VMLINUX_SYMBOL(_sym_) _##_sym_ - -#include -#include - - -OUTPUT_FORMAT("elf32-bfin") -ENTRY(__start) -_jiffies = _jiffies_64; - -MEMORY -{ - ram : ORIGIN = CONFIG_BOOT_LOAD, LENGTH = (CONFIG_MEM_SIZE * 1024 * 1024) - (CONFIG_BOOT_LOAD) - l1_data_a : ORIGIN = L1_DATA_A_START, LENGTH = L1_DATA_A_LENGTH - l1_data_b : ORIGIN = L1_DATA_B_START, LENGTH = L1_DATA_B_LENGTH - l1_code : ORIGIN = L1_CODE_START, LENGTH = L1_CODE_LENGTH - l1_scratch : ORIGIN = L1_SCRATCH_START, LENGTH = L1_SCRATCH_LENGTH -} - -SECTIONS -{ - . = CONFIG_BOOT_LOAD; - - .text : - { - _text = .; - __stext = .; - *(.text) - SCHED_TEXT - *(.text.lock) - . = ALIGN(16); - ___start___ex_table = .; - *(__ex_table) - ___stop___ex_table = .; - - *($code) - *(.rodata) - *(.rodata.*) - *(__vermagic) /* Kernel version magic */ - *(.rodata1) - *(.fixup) - *(.spinlock.text) - - /* Kernel symbol table: Normal symbols */ - . = ALIGN(4); - ___start___ksymtab = .; - *(__ksymtab) - ___stop___ksymtab = .; - - /* Kernel symbol table: GPL-only symbols */ - ___start___ksymtab_gpl = .; - *(__ksymtab_gpl) - ___stop___ksymtab_gpl = .; - - /* Kernel symbol table: Normal unused symbols */ \ - ___start___ksymtab_unused = .; - *(__ksymtab_unused) - ___stop___ksymtab_unused = .; - - /* Kernel symbol table: GPL-only unused symbols */ - ___start___ksymtab_unused_gpl = .; - *(__ksymtab_unused_gpl) - ___stop___ksymtab_unused_gpl = .; - - - /* Kernel symbol table: GPL-future symbols */ - ___start___ksymtab_gpl_future = .; - *(__ksymtab_gpl_future) - ___stop___ksymtab_gpl_future = .; - - /* Kernel symbol table: Normal symbols */ - ___start___kcrctab = .; - *(__kcrctab) - ___stop___kcrctab = .; - - /* Kernel symbol table: GPL-only symbols */ - ___start___kcrctab_gpl = .; - *(__kcrctab_gpl) - ___stop___kcrctab_gpl = .; - - /* Kernel symbol table: GPL-future symbols */ - ___start___kcrctab_gpl_future = .; - *(__kcrctab_gpl_future) - ___stop___kcrctab_gpl_future = .; - - /* Kernel symbol table: strings */ - *(__ksymtab_strings) - - . = ALIGN(4); - __etext = .; - } > ram - - .init : - { - . = ALIGN(4096); - ___init_begin = .; - __sinittext = .; - *(.init.text) - __einittext = .; - *(.init.data) - . = ALIGN(16); - ___setup_start = .; - *(.init.setup) - ___setup_end = .; - ___start___param = .; - *(__param) - ___stop___param = .; - ___initcall_start = .; - INITCALLS - ___initcall_end = .; - ___con_initcall_start = .; - *(.con_initcall.init) - ___con_initcall_end = .; - ___security_initcall_start = .; - *(.security_initcall.init) - ___security_initcall_end = .; - . = ALIGN(4); - ___initramfs_start = .; - *(.init.ramfs) - ___initramfs_end = .; - . = ALIGN(4); - ___init_end = .; - } > ram - - __l1_lma_start = .; - - .text_l1 : - { - . = ALIGN(4); - __stext_l1 = .; - *(.l1.text) - - . = ALIGN(4); - __etext_l1 = .; - } > l1_code AT > ram - - .data_l1 : - { - . = ALIGN(4); - __sdata_l1 = .; - *(.l1.data) - __edata_l1 = .; - - . = ALIGN(4); - __sbss_l1 = .; - *(.l1.bss) - - . = ALIGN(32); - *(.data_l1.cacheline_aligned) - - . = ALIGN(4); - __ebss_l1 = .; - } > l1_data_a AT > ram - .data_b_l1 : - { - . = ALIGN(4); - __sdata_b_l1 = .; - *(.l1.data.B) - __edata_b_l1 = .; - - . = ALIGN(4); - __sbss_b_l1 = .; - *(.l1.bss.B) - - . = ALIGN(4); - __ebss_b_l1 = .; - } > l1_data_b AT > ram - - .data : - { - __sdata = .; - . = ALIGN(0x2000); - *(.data.init_task) - *(.data) - - . = ALIGN(32); - *(.data.cacheline_aligned) - - . = ALIGN(0x2000); - __edata = .; - } > ram - - /DISCARD/ : { /* Exit code and data*/ - *(.exit.text) - *(.exit.data) - *(.exitcall.exit) - } > ram - - .bss : - { - . = ALIGN(4); - ___bss_start = .; - *(.bss) - *(COMMON) - . = ALIGN(4); - ___bss_stop = .; - __end = . ; - } > ram -} diff --git a/trunk/arch/blackfin/lib/Makefile b/trunk/arch/blackfin/lib/Makefile deleted file mode 100644 index 635288fc5f54..000000000000 --- a/trunk/arch/blackfin/lib/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# arch/blackfin/lib/Makefile -# - -lib-y := \ - ashldi3.o ashrdi3.o lshrdi3.o \ - muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \ - checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \ - strcmp.o strcpy.o strncmp.o strncpy.o \ - umulsi3_highpart.o smulsi3_highpart.o \ - ins.o outs.o diff --git a/trunk/arch/blackfin/lib/ashldi3.c b/trunk/arch/blackfin/lib/ashldi3.c deleted file mode 100644 index a8c279e9b192..000000000000 --- a/trunk/arch/blackfin/lib/ashldi3.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * File: arch/blackfin/lib/ashldi3.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "gcclib.h" - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -DItype __ashldi3(DItype u, word_type b)__attribute__((l1_text)); -#endif - -DItype __ashldi3(DItype u, word_type b) -{ - DIunion w; - word_type bm; - DIunion uu; - - if (b == 0) - return u; - - uu.ll = u; - - bm = (sizeof(SItype) * BITS_PER_UNIT) - b; - if (bm <= 0) { - w.s.low = 0; - w.s.high = (USItype) uu.s.low << -bm; - } else { - USItype carries = (USItype) uu.s.low >> bm; - w.s.low = (USItype) uu.s.low << b; - w.s.high = ((USItype) uu.s.high << b) | carries; - } - - return w.ll; -} diff --git a/trunk/arch/blackfin/lib/ashrdi3.c b/trunk/arch/blackfin/lib/ashrdi3.c deleted file mode 100644 index a0d3419329ca..000000000000 --- a/trunk/arch/blackfin/lib/ashrdi3.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * File: arch/blackfin/lib/ashrdi3.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "gcclib.h" - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -DItype __ashrdi3(DItype u, word_type b)__attribute__((l1_text)); -#endif - -DItype __ashrdi3(DItype u, word_type b) -{ - DIunion w; - word_type bm; - DIunion uu; - - if (b == 0) - return u; - - uu.ll = u; - - bm = (sizeof(SItype) * BITS_PER_UNIT) - b; - if (bm <= 0) { - /* w.s.high = 1..1 or 0..0 */ - w.s.high = uu.s.high >> (sizeof(SItype) * BITS_PER_UNIT - 1); - w.s.low = uu.s.high >> -bm; - } else { - USItype carries = (USItype) uu.s.high << bm; - w.s.high = uu.s.high >> b; - w.s.low = ((USItype) uu.s.low >> b) | carries; - } - - return w.ll; -} diff --git a/trunk/arch/blackfin/lib/checksum.c b/trunk/arch/blackfin/lib/checksum.c deleted file mode 100644 index 42768e0c80ca..000000000000 --- a/trunk/arch/blackfin/lib/checksum.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * File: arch/blackfin/lib/checksum.c - * Based on: none - original work - * Author: - * - * Created: - * Description: An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#ifdef CONFIG_IP_CHECKSUM_L1 -static unsigned short do_csum(const unsigned char *buff, int len)__attribute__((l1_text)); -#endif - -static unsigned short do_csum(const unsigned char *buff, int len) -{ - register unsigned long sum = 0; - int swappem = 0; - - if (1 & (unsigned long)buff) { - sum = *buff << 8; - buff++; - len--; - ++swappem; - } - - while (len > 1) { - sum += *(unsigned short *)buff; - buff += 2; - len -= 2; - } - - if (len > 0) - sum += *buff; - - /* Fold 32-bit sum to 16 bits */ - while (sum >> 16) - sum = (sum & 0xffff) + (sum >> 16); - - if (swappem) - sum = ((sum & 0xff00) >> 8) + ((sum & 0x00ff) << 8); - - return sum; - -} - -/* - * This is a version of ip_compute_csum() optimized for IP headers, - * which always checksum on 4 octet boundaries. - */ -unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) -{ - return ~do_csum(iph, ihl * 4); -} - -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum) -{ - /* - * Just in case we get nasty checksum data... - * Like 0xffff6ec3 in the case of our IPv6 multicast header. - * We fold to begin with, as well as at the end. - */ - sum = (sum & 0xffff) + (sum >> 16); - - sum += do_csum(buff, len); - - sum = (sum & 0xffff) + (sum >> 16); - - return sum; -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -unsigned short ip_compute_csum(const unsigned char *buff, int len) -{ - return ~do_csum(buff, len); -} - -/* - * copy from fs while checksumming, otherwise like csum_partial - */ - -unsigned int -csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, - int len, int sum, int *csum_err) -{ - if (csum_err) - *csum_err = 0; - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} - -/* - * copy from ds while checksumming, otherwise like csum_partial - */ - -unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, - int len, int sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} diff --git a/trunk/arch/blackfin/lib/divsi3.S b/trunk/arch/blackfin/lib/divsi3.S deleted file mode 100644 index 3e29861852b2..000000000000 --- a/trunk/arch/blackfin/lib/divsi3.S +++ /dev/null @@ -1,216 +0,0 @@ -/* - * File: arch/blackfin/lib/divsi3.S - * Based on: - * Author: - * - * Created: - * Description: 16 / 32 bit signed division. - * Special cases : - * 1) If(numerator == 0) - * return 0 - * 2) If(denominator ==0) - * return positive max = 0x7fffffff - * 3) If(numerator == denominator) - * return 1 - * 4) If(denominator ==1) - * return numerator - * 5) If(denominator == -1) - * return -numerator - * - * Operand : R0 - Numerator (i) - * R1 - Denominator (i) - * R0 - Quotient (o) - * Registers Used : R2-R7,P0-P2 - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -.global ___divsi3; - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -.section .l1.text -#else -.text -#endif - -.align 2; -___divsi3 : - - - R3 = R0 ^ R1; - R0 = ABS R0; - - CC = V; - - r3 = rot r3 by -1; - r1 = abs r1; /* now both positive, r3.30 means "negate result", - ** r3.31 means overflow, add one to result - */ - cc = r0 < r1; - if cc jump .Lret_zero; - r2 = r1 >> 15; - cc = r2; - if cc jump .Lidents; - r2 = r1 << 16; - cc = r2 <= r0; - if cc jump .Lidents; - - DIVS(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - DIVQ(R0, R1); - - R0 = R0.L (Z); - r1 = r3 >> 31; /* add overflow issue back in */ - r0 = r0 + r1; - r1 = -r0; - cc = bittst(r3, 30); - if cc r0 = r1; - RTS; - -/* Can't use the primitives. Test common identities. -** If the identity is true, return the value in R2. -*/ - -.Lidents: - CC = R1 == 0; /* check for divide by zero */ - IF CC JUMP .Lident_return; - - CC = R0 == 0; /* check for division of zero */ - IF CC JUMP .Lzero_return; - - CC = R0 == R1; /* check for identical operands */ - IF CC JUMP .Lident_return; - - CC = R1 == 1; /* check for divide by 1 */ - IF CC JUMP .Lident_return; - - R2.L = ONES R1; - R2 = R2.L (Z); - CC = R2 == 1; - IF CC JUMP .Lpower_of_two; - - /* Identities haven't helped either. - ** Perform the full division process. - */ - - P1 = 31; /* Set loop counter */ - - [--SP] = (R7:5); /* Push registers R5-R7 */ - R2 = -R1; - [--SP] = R2; - R2 = R0 << 1; /* R2 lsw of dividend */ - R6 = R0 ^ R1; /* Get sign */ - R5 = R6 >> 31; /* Shift sign to LSB */ - - R0 = 0 ; /* Clear msw partial remainder */ - R2 = R2 | R5; /* Shift quotient bit */ - R6 = R0 ^ R1; /* Get new quotient bit */ - - LSETUP(.Llst,.Llend) LC0 = P1; /* Setup loop */ -.Llst: R7 = R2 >> 31; /* record copy of carry from R2 */ - R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */ - R0 = R0 << 1 || R5 = [SP]; - R0 = R0 | R7; /* and add carry */ - CC = R6 < 0; /* Check quotient(AQ) */ - /* we might be subtracting divisor (AQ==0) */ - IF CC R5 = R1; /* or we might be adding divisor (AQ==1)*/ - R0 = R0 + R5; /* do add or subtract, as indicated by AQ */ - R6 = R0 ^ R1; /* Generate next quotient bit */ - R5 = R6 >> 31; - /* Assume AQ==1, shift in zero */ - BITTGL(R5,0); /* tweak AQ to be what we want to shift in */ -.Llend: R2 = R2 + R5; /* and then set shifted-in value to - ** tweaked AQ. - */ - r1 = r3 >> 31; - r2 = r2 + r1; - cc = bittst(r3,30); - r0 = -r2; - if !cc r0 = r2; - SP += 4; - (R7:5)= [SP++]; /* Pop registers R6-R7 */ - RTS; - -.Lident_return: - CC = R1 == 0; /* check for divide by zero => 0x7fffffff */ - R2 = -1 (X); - R2 >>= 1; - IF CC JUMP .Ltrue_ident_return; - - CC = R0 == R1; /* check for identical operands => 1 */ - R2 = 1 (Z); - IF CC JUMP .Ltrue_ident_return; - - R2 = R0; /* assume divide by 1 => numerator */ - /*FALLTHRU*/ - -.Ltrue_ident_return: - R0 = R2; /* Return an identity value */ - R2 = -R2; - CC = bittst(R3,30); - IF CC R0 = R2; -.Lzero_return: - RTS; /* ...including zero */ - -.Lpower_of_two: - /* Y has a single bit set, which means it's a power of two. - ** That means we can perform the division just by shifting - ** X to the right the appropriate number of bits - */ - - /* signbits returns the number of sign bits, minus one. - ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need - ** to shift right n-signbits spaces. It also means 0x80000000 - ** is a special case, because that *also* gives a signbits of 0 - */ - - R2 = R0 >> 31; - CC = R1 < 0; - IF CC JUMP .Ltrue_ident_return; - - R1.l = SIGNBITS R1; - R1 = R1.L (Z); - R1 += -30; - R0 = LSHIFT R0 by R1.L; - r1 = r3 >> 31; - r0 = r0 + r1; - R2 = -R0; // negate result if necessary - CC = bittst(R3,30); - IF CC R0 = R2; - RTS; - -.Lret_zero: - R0 = 0; - RTS; diff --git a/trunk/arch/blackfin/lib/gcclib.h b/trunk/arch/blackfin/lib/gcclib.h deleted file mode 100644 index 9ccd39a135ee..000000000000 --- a/trunk/arch/blackfin/lib/gcclib.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * File: arch/blackfin/lib/gcclib.h - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define BITS_PER_UNIT 8 -#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT) - -typedef unsigned int UQItype __attribute__ ((mode(QI))); -typedef int SItype __attribute__ ((mode(SI))); -typedef unsigned int USItype __attribute__ ((mode(SI))); -typedef int DItype __attribute__ ((mode(DI))); -typedef int word_type __attribute__ ((mode(__word__))); -typedef unsigned int UDItype __attribute__ ((mode(DI))); - -struct DIstruct { - SItype low, high; -}; - -typedef union { - struct DIstruct s; - DItype ll; -} DIunion; diff --git a/trunk/arch/blackfin/lib/ins.S b/trunk/arch/blackfin/lib/ins.S deleted file mode 100644 index 730d2b427538..000000000000 --- a/trunk/arch/blackfin/lib/ins.S +++ /dev/null @@ -1,69 +0,0 @@ -/* - * File: arch/blackfin/lib/ins.S - * Based on: - * Author: Bas Vermeulen - * - * Created: Tue Mar 22 15:27:24 CEST 2005 - * Description: Implementation of ins{bwl} for BlackFin processors using zero overhead loops. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * Copyright (C) 2005 Bas Vermeulen, BuyWays BV - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -.align 2 - -ENTRY(_insl) - P0 = R0; /* P0 = port */ - cli R3; - P1 = R1; /* P1 = address */ - P2 = R2; /* P2 = count */ - SSYNC; - LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2; -.Llong_loop_s: R0 = [P0]; -.Llong_loop_e: [P1++] = R0; - sti R3; - RTS; - -ENTRY(_insw) - P0 = R0; /* P0 = port */ - cli R3; - P1 = R1; /* P1 = address */ - P2 = R2; /* P2 = count */ - SSYNC; - LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2; -.Lword_loop_s: R0 = W[P0]; -.Lword_loop_e: W[P1++] = R0; - sti R3; - RTS; - -ENTRY(_insb) - P0 = R0; /* P0 = port */ - cli R3; - P1 = R1; /* P1 = address */ - P2 = R2; /* P2 = count */ - SSYNC; - LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2; -.Lbyte_loop_s: R0 = B[P0]; -.Lbyte_loop_e: B[P1++] = R0; - sti R3; - RTS; diff --git a/trunk/arch/blackfin/lib/lshrdi3.c b/trunk/arch/blackfin/lib/lshrdi3.c deleted file mode 100644 index 84b9c5592220..000000000000 --- a/trunk/arch/blackfin/lib/lshrdi3.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * File: arch/blackfin/lib/lshrdi3.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define BITS_PER_UNIT 8 - -typedef int SItype __attribute__ ((mode(SI))); -typedef unsigned int USItype __attribute__ ((mode(SI))); -typedef int DItype __attribute__ ((mode(DI))); -typedef int word_type __attribute__ ((mode(__word__))); - -struct DIstruct { - SItype high, low; -}; - -typedef union { - struct DIstruct s; - DItype ll; -} DIunion; - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -DItype __lshrdi3(DItype u, word_type b)__attribute__((l1_text)); -#endif - -DItype __lshrdi3(DItype u, word_type b) -{ - DIunion w; - word_type bm; - DIunion uu; - - if (b == 0) - return u; - - uu.ll = u; - - bm = (sizeof(SItype) * BITS_PER_UNIT) - b; - if (bm <= 0) { - w.s.high = 0; - w.s.low = (USItype) uu.s.high >> -bm; - } else { - USItype carries = (USItype) uu.s.high << bm; - w.s.high = (USItype) uu.s.high >> b; - w.s.low = ((USItype) uu.s.low >> b) | carries; - } - - return w.ll; -} diff --git a/trunk/arch/blackfin/lib/memchr.S b/trunk/arch/blackfin/lib/memchr.S deleted file mode 100644 index 498122250d07..000000000000 --- a/trunk/arch/blackfin/lib/memchr.S +++ /dev/null @@ -1,70 +0,0 @@ -/* - * File: arch/blackfin/lib/memchr.S - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -/* void *memchr(const void *s, int c, size_t n); - * R0 = address (s) - * R1 = sought byte (c) - * R2 = count (n) - * - * Returns pointer to located character. - */ - -.text - -.align 2 - -ENTRY(_memchr) - P0 = R0; /* P0 = address */ - P2 = R2; /* P2 = count */ - R1 = R1.B(Z); - CC = R2 == 0; - IF CC JUMP .Lfailed; - -.Lbytes: - LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2; - -.Lbyte_loop_s: - R3 = B[P0++](Z); - CC = R3 == R1; - IF CC JUMP .Lfound; -.Lbyte_loop_e: - NOP; - -.Lfailed: - R0=0; - RTS; - -.Lfound: - R0 = P0; - R0 += -1; - RTS; - -.size _memchr,.-_memchr diff --git a/trunk/arch/blackfin/lib/memcmp.S b/trunk/arch/blackfin/lib/memcmp.S deleted file mode 100644 index 5b9502368fc6..000000000000 --- a/trunk/arch/blackfin/lib/memcmp.S +++ /dev/null @@ -1,110 +0,0 @@ -/* - * File: arch/blackfin/lib/memcmp.S - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -/* int memcmp(const void *s1, const void *s2, size_t n); - * R0 = First Address (s1) - * R1 = Second Address (s2) - * R2 = count (n) - * - * Favours word aligned data. - */ - -.text - -.align 2 - -ENTRY(_memcmp) - I1 = P3; - P0 = R0; /* P0 = s1 address */ - P3 = R1; /* P3 = s2 Address */ - P2 = R2 ; /* P2 = count */ - CC = R2 <= 7(IU); - IF CC JUMP .Ltoo_small; - I0 = R1; /* s2 */ - R1 = R1 | R0; /* OR addresses together */ - R1 <<= 30; /* check bottom two bits */ - CC = AZ; /* AZ set if zero. */ - IF !CC JUMP .Lbytes ; /* Jump if addrs not aligned. */ - - P1 = P2 >> 2; /* count = n/4 */ - R3 = 3; - R2 = R2 & R3; /* remainder */ - P2 = R2; /* set remainder */ - - LSETUP (.Lquad_loop_s, .Lquad_loop_e) LC0=P1; -.Lquad_loop_s: - MNOP || R0 = [P0++] || R1 = [I0++]; - CC = R0 == R1; - IF !CC JUMP .Lquad_different; -.Lquad_loop_e: - NOP; - - P3 = I0; /* s2 */ -.Ltoo_small: - CC = P2 == 0; /* Check zero count*/ - IF CC JUMP .Lfinished; /* very unlikely*/ - -.Lbytes: - LSETUP (.Lbyte_loop_s, .Lbyte_loop_e) LC0=P2; -.Lbyte_loop_s: - R1 = B[P3++](Z); /* *s2 */ - R0 = B[P0++](Z); /* *s1 */ - CC = R0 == R1; - IF !CC JUMP .Ldifferent; -.Lbyte_loop_e: - NOP; - -.Ldifferent: - R0 = R0 - R1; - P3 = I1; - RTS; - -.Lquad_different: - /* We've read two quads which don't match. - * Can't just compare them, because we're - * a little-endian machine, so the MSBs of - * the regs occur at later addresses in the - * string. - * Arrange to re-read those two quads again, - * byte-by-byte. - */ - P0 += -4; /* back up to the start of the */ - P3 = I0; /* quads, and increase the*/ - P2 += 4; /* remainder count*/ - P3 += -4; - JUMP .Lbytes; - -.Lfinished: - R0 = 0; - P3 = I1; - RTS; - -.size _memcmp,.-_memcmp diff --git a/trunk/arch/blackfin/lib/memcpy.S b/trunk/arch/blackfin/lib/memcpy.S deleted file mode 100644 index c1e00eff541c..000000000000 --- a/trunk/arch/blackfin/lib/memcpy.S +++ /dev/null @@ -1,142 +0,0 @@ -/* - * File: arch/blackfin/lib/memcpy.S - * Based on: - * Author: - * - * Created: - * Description: internal version of memcpy(), issued by the compiler - * to copy blocks of data around. - * This is really memmove() - it has to be able to deal with - * possible overlaps, because that ambiguity is when the compiler - * gives up and calls a function. We have our own, internal version - * so that we get something we trust, even if the user has redefined - * the normal symbol. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -/* void *memcpy(void *dest, const void *src, size_t n); - * R0 = To Address (dest) (leave unchanged to form result) - * R1 = From Address (src) - * R2 = count - * - * Note: Favours word alignment - */ - -#ifdef CONFIG_MEMCPY_L1 -.section .l1.text -#else -.text -#endif - -.align 2 - -ENTRY(_memcpy) - CC = R2 <= 0; /* length not positive? */ - IF CC JUMP .L_P1L2147483647; /* Nothing to do */ - - P0 = R0 ; /* dst*/ - P1 = R1 ; /* src*/ - P2 = R2 ; /* length */ - - /* check for overlapping data */ - CC = R1 < R0; /* src < dst */ - IF !CC JUMP .Lno_overlap; - R3 = R1 + R2; - CC = R0 < R3; /* and dst < src+len */ - IF CC JUMP .Lhas_overlap; - -.Lno_overlap: - /* Check for aligned data.*/ - - R3 = R1 | R0; - R0 = 0x3; - R3 = R3 & R0; - CC = R3; /* low bits set on either address? */ - IF CC JUMP .Lnot_aligned; - - /* Both addresses are word-aligned, so we can copy - at least part of the data using word copies.*/ - P2 = P2 >> 2; - CC = P2 <= 2; - IF !CC JUMP .Lmore_than_seven; - /* less than eight bytes... */ - P2 = R2; - LSETUP(.Lthree_start, .Lthree_end) LC0=P2; - R0 = R1; /* setup src address for return */ -.Lthree_start: - R3 = B[P1++] (X); -.Lthree_end: - B[P0++] = R3; - - RTS; - -.Lmore_than_seven: - /* There's at least eight bytes to copy. */ - P2 += -1; /* because we unroll one iteration */ - LSETUP(.Lword_loop, .Lword_loop) LC0=P2; - R0 = R1; - I1 = P1; - R3 = [I1++]; -.Lword_loop: - MNOP || [P0++] = R3 || R3 = [I1++]; - - [P0++] = R3; - /* Any remaining bytes to copy? */ - R3 = 0x3; - R3 = R2 & R3; - CC = R3 == 0; - P1 = I1; /* in case there's something left, */ - IF !CC JUMP .Lbytes_left; - RTS; -.Lbytes_left: P2 = R3; -.Lnot_aligned: - /* From here, we're copying byte-by-byte. */ - LSETUP (.Lbyte_start, .Lbyte_end) LC0=P2; - R0 = R1; /* Save src address for return */ -.Lbyte_start: - R1 = B[P1++] (X); -.Lbyte_end: - B[P0++] = R1; - -.L_P1L2147483647: - RTS; - -.Lhas_overlap: - /* Need to reverse the copying, because the - * dst would clobber the src. - * Don't bother to work out alignment for - * the reverse case. - */ - R0 = R1; /* save src for later. */ - P0 = P0 + P2; - P0 += -1; - P1 = P1 + P2; - P1 += -1; - LSETUP(.Lover_start, .Lover_end) LC0=P2; -.Lover_start: - R1 = B[P1--] (X); -.Lover_end: - B[P0--] = R1; - - RTS; diff --git a/trunk/arch/blackfin/lib/memmove.S b/trunk/arch/blackfin/lib/memmove.S deleted file mode 100644 index 2e5fb7f8df13..000000000000 --- a/trunk/arch/blackfin/lib/memmove.S +++ /dev/null @@ -1,103 +0,0 @@ -/* - * File: arch/blackfin/lib/memmove.S - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -.align 2 - -/* - * C Library function MEMMOVE - * R0 = To Address (leave unchanged to form result) - * R1 = From Address - * R2 = count - * Data may overlap - */ - -ENTRY(_memmove) - I1 = P3; - P0 = R0; /* P0 = To address */ - P3 = R1; /* P3 = From Address */ - P2 = R2; /* P2 = count */ - CC = P2 == 0; /* Check zero count*/ - IF CC JUMP .Lfinished; /* very unlikely */ - - CC = R1 < R0 (IU); /* From < To */ - IF !CC JUMP .Lno_overlap; - R3 = R1 + R2; - CC = R0 <= R3 (IU); /* (From+len) >= To */ - IF CC JUMP .Loverlap; -.Lno_overlap: - R3 = 11; - CC = R2 <= R3; - IF CC JUMP .Lbytes; - R3 = R1 | R0; /* OR addresses together */ - R3 <<= 30; /* check bottom two bits */ - CC = AZ; /* AZ set if zero.*/ - IF !CC JUMP .Lbytes; /* Jump if addrs not aligned.*/ - - I0 = P3; - P1 = P2 >> 2; /* count = n/4 */ - P1 += -1; - R3 = 3; - R2 = R2 & R3; /* remainder */ - P2 = R2; /* set remainder */ - R1 = [I0++]; - - LSETUP (.Lquad_loop, .Lquad_loop) LC0=P1; -.Lquad_loop: MNOP || [P0++] = R1 || R1 = [I0++]; - [P0++] = R1; - - CC = P2 == 0; /* any remaining bytes? */ - P3 = I0; /* Ammend P3 to updated ptr. */ - IF !CC JUMP .Lbytes; - P3 = I1; - RTS; - -.Lbytes: LSETUP (.Lbyte2_s, .Lbyte2_e) LC0=P2; -.Lbyte2_s: R1 = B[P3++](Z); -.Lbyte2_e: B[P0++] = R1; - -.Lfinished: P3 = I1; - RTS; - -.Loverlap: - P2 += -1; - P0 = P0 + P2; - P3 = P3 + P2; - R1 = B[P3--] (Z); - CC = P2 == 0; - IF CC JUMP .Lno_loop; - LSETUP (.Lol_s, .Lol_e) LC0 = P2; -.Lol_s: B[P0--] = R1; -.Lol_e: R1 = B[P3--] (Z); -.Lno_loop: B[P0] = R1; - P3 = I1; - RTS; - -.size _memmove,.-_memmove diff --git a/trunk/arch/blackfin/lib/memset.S b/trunk/arch/blackfin/lib/memset.S deleted file mode 100644 index ba6d047568dd..000000000000 --- a/trunk/arch/blackfin/lib/memset.S +++ /dev/null @@ -1,109 +0,0 @@ -/* - * File: arch/blackfin/lib/memset.S - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -.align 2 - -#ifdef CONFIG_MEMSET_L1 -.section .l1.text -#else -.text -#endif - -/* - * C Library function MEMSET - * R0 = address (leave unchanged to form result) - * R1 = filler byte - * R2 = count - * Favours word aligned data. - */ - -ENTRY(_memset) - P0 = R0 ; /* P0 = address */ - P2 = R2 ; /* P2 = count */ - R3 = R0 + R2; /* end */ - CC = R2 <= 7(IU); - IF CC JUMP .Ltoo_small; - R1 = R1.B (Z); /* R1 = fill char */ - R2 = 3; - R2 = R0 & R2; /* addr bottom two bits */ - CC = R2 == 0; /* AZ set if zero. */ - IF !CC JUMP .Lforce_align ; /* Jump if addr not aligned. */ - -.Laligned: - P1 = P2 >> 2; /* count = n/4 */ - R2 = R1 << 8; /* create quad filler */ - R2.L = R2.L + R1.L(NS); - R2.H = R2.L + R1.H(NS); - P2 = R3; - - LSETUP (.Lquad_loop , .Lquad_loop) LC0=P1; -.Lquad_loop: - [P0++] = R2; - - CC = P0 == P2; - IF !CC JUMP .Lbytes_left; - RTS; - -.Lbytes_left: - R2 = R3; /* end point */ - R3 = P0; /* current position */ - R2 = R2 - R3; /* bytes left */ - P2 = R2; - -.Ltoo_small: - CC = P2 == 0; /* Check zero count */ - IF CC JUMP .Lfinished; /* Unusual */ - -.Lbytes: - LSETUP (.Lbyte_loop , .Lbyte_loop) LC0=P2; -.Lbyte_loop: - B[P0++] = R1; - -.Lfinished: - RTS; - -.Lforce_align: - CC = BITTST (R0, 0); /* odd byte */ - R0 = 4; - R0 = R0 - R2; - P1 = R0; - R0 = P0; /* Recover return address */ - IF !CC JUMP .Lskip1; - B[P0++] = R1; -.Lskip1: - CC = R2 <= 2; /* 2 bytes */ - P2 -= P1; /* reduce count */ - IF !CC JUMP .Laligned; - B[P0++] = R1; - B[P0++] = R1; - JUMP .Laligned; - -.size _memset,.-_memset diff --git a/trunk/arch/blackfin/lib/modsi3.S b/trunk/arch/blackfin/lib/modsi3.S deleted file mode 100644 index 528b8b1ccb34..000000000000 --- a/trunk/arch/blackfin/lib/modsi3.S +++ /dev/null @@ -1,79 +0,0 @@ -/* - * File: arch/blackfin/lib/modsi3.S - * Based on: - * Author: - * - * Created: - * Description: This program computes 32 bit signed remainder. It calls div32 function - * for quotient estimation. - * - * Registers used : - * Numerator/ Denominator in R0, R1 - * R0 - returns remainder. - * R2-R7 - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -.global ___modsi3; -.type ___modsi3, STT_FUNC; -.extern ___divsi3; -.type ___divsi3, STT_FUNC; - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -.section .l1.text -#else -.text -#endif - -___modsi3: - - CC=R0==0; - IF CC JUMP .LRETURN_R0; /* Return 0, if numerator == 0 */ - CC=R1==0; - IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 0 */ - CC=R0==R1; - IF CC JUMP .LRETURN_ZERO; /* Return 0, if numerator == denominator */ - CC = R1 == 1; - IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == 1 */ - CC = R1 == -1; - IF CC JUMP .LRETURN_ZERO; /* Return 0, if denominator == -1 */ - - /* Valid input. Use __divsi3() to compute the quotient, and then - * derive the remainder from that. */ - - [--SP] = (R7:6); /* Push R7 and R6 */ - [--SP] = RETS; /* and return address */ - R7 = R0; /* Copy of R0 */ - R6 = R1; /* Save for later */ - SP += -12; /* Should always provide this space */ - CALL ___divsi3; /* Compute signed quotient using ___divsi3()*/ - SP += 12; - R0 *= R6; /* Quotient * divisor */ - R0 = R7 - R0; /* Dividend - (quotient * divisor) */ - RETS = [SP++]; /* Get back return address */ - (R7:6) = [SP++]; /* Pop registers R7 and R4 */ - RTS; /* Store remainder */ - -.LRETURN_ZERO: - R0 = 0; -.LRETURN_R0: - RTS; diff --git a/trunk/arch/blackfin/lib/muldi3.c b/trunk/arch/blackfin/lib/muldi3.c deleted file mode 100644 index 303d0c6a6dba..000000000000 --- a/trunk/arch/blackfin/lib/muldi3.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * File: arch/blackfin/lib/muldi3.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef SI_TYPE_SIZE -#define SI_TYPE_SIZE 32 -#endif -#define __ll_b (1L << (SI_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((usitype) (t) % __ll_b) -#define __ll_highpart(t) ((usitype) (t) / __ll_b) -#define BITS_PER_UNIT 8 - -#if !defined(umul_ppmm) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - usitype __x0, __x1, __x2, __x3; \ - usitype __ul, __vl, __uh, __vh; \ - \ - __ul = __ll_lowpart (u); \ - __uh = __ll_highpart (u); \ - __vl = __ll_lowpart (v); \ - __vh = __ll_highpart (v); \ - \ - __x0 = (usitype) __ul * __vl; \ - __x1 = (usitype) __ul * __vh; \ - __x2 = (usitype) __uh * __vl; \ - __x3 = (usitype) __uh * __vh; \ - \ - __x1 += __ll_highpart (__x0);/* this can't give carry */ \ - __x1 += __x2; /* but this indeed can */ \ - if (__x1 < __x2) /* did we get it? */ \ - __x3 += __ll_b; /* yes, add it in the proper pos. */ \ - \ - (w1) = __x3 + __ll_highpart (__x1); \ - (w0) = __ll_lowpart (__x1) * __ll_b + __ll_lowpart (__x0); \ - } while (0) -#endif - -#if !defined(__umulsidi3) -#define __umulsidi3(u, v) \ - ({diunion __w; \ - umul_ppmm (__w.s.high, __w.s.low, u, v); \ - __w.ll; }) -#endif - -typedef unsigned int usitype __attribute__ ((mode(SI))); -typedef int sitype __attribute__ ((mode(SI))); -typedef int ditype __attribute__ ((mode(DI))); -typedef int word_type __attribute__ ((mode(__word__))); - -struct distruct { - sitype low, high; -}; -typedef union { - struct distruct s; - ditype ll; -} diunion; - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -ditype __muldi3(ditype u, ditype v)__attribute__((l1_text)); -#endif - -ditype __muldi3(ditype u, ditype v) -{ - diunion w; - diunion uu, vv; - - uu.ll = u, vv.ll = v; - w.ll = __umulsidi3(uu.s.low, vv.s.low); - w.s.high += ((usitype) uu.s.low * (usitype) vv.s.high - + (usitype) uu.s.high * (usitype) vv.s.low); - - return w.ll; -} diff --git a/trunk/arch/blackfin/lib/outs.S b/trunk/arch/blackfin/lib/outs.S deleted file mode 100644 index f8c876fe8930..000000000000 --- a/trunk/arch/blackfin/lib/outs.S +++ /dev/null @@ -1,62 +0,0 @@ -/* - * File: arch/blackfin/lib/outs.S - * Based on: - * Author: Bas Vermeulen - * - * Created: Tue Mar 22 15:27:24 CEST 2005 - * Description: Implementation of outs{bwl} for BlackFin processors using zero overhead loops. - * - * Modified: Copyright (C) 2005 Bas Vermeulen, BuyWays BV - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -.align 2 - -ENTRY(_outsl) - P0 = R0; /* P0 = port */ - P1 = R1; /* P1 = address */ - P2 = R2; /* P2 = count */ - - LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2; -.Llong_loop_s: R0 = [P1++]; -.Llong_loop_e: [P0] = R0; - RTS; - -ENTRY(_outsw) - P0 = R0; /* P0 = port */ - P1 = R1; /* P1 = address */ - P2 = R2; /* P2 = count */ - - LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2; -.Lword_loop_s: R0 = W[P1++]; -.Lword_loop_e: W[P0] = R0; - RTS; - -ENTRY(_outsb) - P0 = R0; /* P0 = port */ - P1 = R1; /* P1 = address */ - P2 = R2; /* P2 = count */ - - LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2; -.Lbyte_loop_s: R0 = B[P1++]; -.Lbyte_loop_e: B[P0] = R0; - RTS; diff --git a/trunk/arch/blackfin/lib/smulsi3_highpart.S b/trunk/arch/blackfin/lib/smulsi3_highpart.S deleted file mode 100644 index 10b8f8da576f..000000000000 --- a/trunk/arch/blackfin/lib/smulsi3_highpart.S +++ /dev/null @@ -1,30 +0,0 @@ -.align 2 -.global ___smulsi3_highpart; -.type ___smulsi3_highpart, STT_FUNC; - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -.section .l1.text -#else -.text -#endif - -___smulsi3_highpart: - R2 = R1.L * R0.L (FU); - R3 = R1.H * R0.L (IS,M); - R0 = R0.H * R1.H, R1 = R0.H * R1.L (IS,M); - - R1.L = R2.H + R1.L; - cc = ac0; - R2 = cc; - - R1.L = R1.L + R3.L; - cc = ac0; - R1 >>>= 16; - R3 >>>= 16; - R1 = R1 + R3; - R1 = R1 + R2; - R2 = cc; - R1 = R1 + R2; - - R0 = R0 + R1; - RTS; diff --git a/trunk/arch/blackfin/lib/strcmp.c b/trunk/arch/blackfin/lib/strcmp.c deleted file mode 100644 index 2ad47c4254ba..000000000000 --- a/trunk/arch/blackfin/lib/strcmp.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -#define strcmp __inline_strcmp -#include -#undef strcmp - -int strcmp(const char *dest, const char *src) -{ - return __inline_strcmp(dest, src); -} - diff --git a/trunk/arch/blackfin/lib/strcpy.c b/trunk/arch/blackfin/lib/strcpy.c deleted file mode 100644 index 4dc835a8a19b..000000000000 --- a/trunk/arch/blackfin/lib/strcpy.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -#define strcpy __inline_strcpy -#include -#undef strcpy - -char *strcpy(char *dest, const char *src) -{ - return __inline_strcpy(dest, src); -} - diff --git a/trunk/arch/blackfin/lib/strncmp.c b/trunk/arch/blackfin/lib/strncmp.c deleted file mode 100644 index 947bcfe3f3bb..000000000000 --- a/trunk/arch/blackfin/lib/strncmp.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -#define strncmp __inline_strncmp -#include -#undef strncmp - -int strncmp(const char *cs, const char *ct, size_t count) -{ - return __inline_strncmp(cs, ct, count); -} - diff --git a/trunk/arch/blackfin/lib/strncpy.c b/trunk/arch/blackfin/lib/strncpy.c deleted file mode 100644 index 77a9b2e95097..000000000000 --- a/trunk/arch/blackfin/lib/strncpy.c +++ /dev/null @@ -1,11 +0,0 @@ -#include - -#define strncpy __inline_strncpy -#include -#undef strncpy - -char *strncpy(char *dest, const char *src, size_t n) -{ - return __inline_strncpy(dest, src, n); -} - diff --git a/trunk/arch/blackfin/lib/udivsi3.S b/trunk/arch/blackfin/lib/udivsi3.S deleted file mode 100644 index d39a12916259..000000000000 --- a/trunk/arch/blackfin/lib/udivsi3.S +++ /dev/null @@ -1,298 +0,0 @@ -/* - * File: arch/blackfin/lib/udivsi3.S - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#define CARRY AC0 - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -.section .l1.text -#else -.text -#endif - - -ENTRY(___udivsi3) - - CC = R0 < R1 (IU); /* If X < Y, always return 0 */ - IF CC JUMP .Lreturn_ident; - - R2 = R1 << 16; - CC = R2 <= R0 (IU); - IF CC JUMP .Lidents; - - R2 = R0 >> 31; /* if X is a 31-bit number */ - R3 = R1 >> 15; /* and Y is a 15-bit number */ - R2 = R2 | R3; /* then it's okay to use the DIVQ builtins (fallthrough to fast)*/ - CC = R2; - IF CC JUMP .Ly_16bit; - -/* METHOD 1: FAST DIVQ - We know we have a 31-bit dividend, and 15-bit divisor so we can use the - simple divq approach (first setting AQ to 0 - implying unsigned division, - then 16 DIVQ's). -*/ - - AQ = CC; /* Clear AQ (CC==0) */ - -/* ISR States: When dividing two integers (32.0/16.0) using divide primitives, - we need to shift the dividend one bit to the left. - We have already checked that we have a 31-bit number so we are safe to do - that. -*/ - R0 <<= 1; - DIVQ(R0, R1); // 1 - DIVQ(R0, R1); // 2 - DIVQ(R0, R1); // 3 - DIVQ(R0, R1); // 4 - DIVQ(R0, R1); // 5 - DIVQ(R0, R1); // 6 - DIVQ(R0, R1); // 7 - DIVQ(R0, R1); // 8 - DIVQ(R0, R1); // 9 - DIVQ(R0, R1); // 10 - DIVQ(R0, R1); // 11 - DIVQ(R0, R1); // 12 - DIVQ(R0, R1); // 13 - DIVQ(R0, R1); // 14 - DIVQ(R0, R1); // 15 - DIVQ(R0, R1); // 16 - R0 = R0.L (Z); - RTS; - -.Ly_16bit: - /* We know that the upper 17 bits of Y might have bits set, - ** or that the sign bit of X might have a bit. If Y is a - ** 16-bit number, but not bigger, then we can use the builtins - ** with a post-divide correction. - ** R3 currently holds Y>>15, which means R3's LSB is the - ** bit we're interested in. - */ - - /* According to the ISR, to use the Divide primitives for - ** unsigned integer divide, the useable range is 31 bits - */ - CC = ! BITTST(R0, 31); - - /* IF condition is true we can scale our inputs and use the divide primitives, - ** with some post-adjustment - */ - R3 += -1; /* if so, Y is 0x00008nnn */ - CC &= AZ; - - /* If condition is true we can scale our inputs and use the divide primitives, - ** with some post-adjustment - */ - R3 = R1 >> 1; /* Pre-scaled divisor for primitive case */ - R2 = R0 >> 16; - - R2 = R3 - R2; /* shifted divisor < upper 16 bits of dividend */ - CC &= CARRY; - IF CC JUMP .Lshift_and_correct; - - /* Fall through to the identities */ - -/* METHOD 2: identities and manual calculation - We are not able to use the divide primites, but may still catch some special - cases. -*/ -.Lidents: - /* Test for common identities. Value to be returned is placed in R2. */ - CC = R0 == 0; /* 0/Y => 0 */ - IF CC JUMP .Lreturn_r0; - CC = R0 == R1; /* X==Y => 1 */ - IF CC JUMP .Lreturn_ident; - CC = R1 == 1; /* X/1 => X */ - IF CC JUMP .Lreturn_ident; - - R2.L = ONES R1; - R2 = R2.L (Z); - CC = R2 == 1; - IF CC JUMP .Lpower_of_two; - - [--SP] = (R7:5); /* Push registers R5-R7 */ - - /* Idents don't match. Go for the full operation. */ - - - R6 = 2; /* assume we'll shift two */ - R3 = 1; - - P2 = R1; - /* If either R0 or R1 have sign set, */ - /* divide them by two, and note it's */ - /* been done. */ - CC = R1 < 0; - R2 = R1 >> 1; - IF CC R1 = R2; /* Possibly-shifted R1 */ - IF !CC R6 = R3; /* R1 doesn't, so at most 1 shifted */ - - P0 = 0; - R3 = -R1; - [--SP] = R3; - R2 = R0 >> 1; - R2 = R0 >> 1; - CC = R0 < 0; - IF CC P0 = R6; /* Number of values divided */ - IF !CC R2 = R0; /* Shifted R0 */ - - /* P0 is 0, 1 (NR/=2) or 2 (NR/=2, DR/=2) */ - - /* r2 holds Copy dividend */ - R3 = 0; /* Clear partial remainder */ - R7 = 0; /* Initialise quotient bit */ - - P1 = 32; /* Set loop counter */ - LSETUP(.Lulst, .Lulend) LC0 = P1; /* Set loop counter */ -.Lulst: R6 = R2 >> 31; /* R6 = sign bit of R2, for carry */ - R2 = R2 << 1; /* Shift 64 bit dividend up by 1 bit */ - R3 = R3 << 1 || R5 = [SP]; - R3 = R3 | R6; /* Include any carry */ - CC = R7 < 0; /* Check quotient(AQ) */ - /* If AQ==0, we'll sub divisor */ - IF CC R5 = R1; /* and if AQ==1, we'll add it. */ - R3 = R3 + R5; /* Add/sub divsor to partial remainder */ - R7 = R3 ^ R1; /* Generate next quotient bit */ - - R5 = R7 >> 31; /* Get AQ */ - BITTGL(R5, 0); /* Invert it, to get what we'll shift */ -.Lulend: R2 = R2 + R5; /* and "shift" it in. */ - - CC = P0 == 0; /* Check how many inputs we shifted */ - IF CC JUMP .Lno_mult; /* if none... */ - R6 = R2 << 1; - CC = P0 == 1; - IF CC R2 = R6; /* if 1, Q = Q*2 */ - IF !CC R1 = P2; /* if 2, restore stored divisor */ - - R3 = R2; /* Copy of R2 */ - R3 *= R1; /* Q * divisor */ - R5 = R0 - R3; /* Z = (dividend - Q * divisor) */ - CC = R1 <= R5 (IU); /* Check if divisor <= Z? */ - R6 = CC; /* if yes, R6 = 1 */ - R2 = R2 + R6; /* if yes, add one to quotient(Q) */ -.Lno_mult: - SP += 4; - (R7:5) = [SP++]; /* Pop registers R5-R7 */ - R0 = R2; /* Store quotient */ - RTS; - -.Lreturn_ident: - CC = R0 < R1 (IU); /* If X < Y, always return 0 */ - R2 = 0; - IF CC JUMP .Ltrue_return_ident; - R2 = -1 (X); /* X/0 => 0xFFFFFFFF */ - CC = R1 == 0; - IF CC JUMP .Ltrue_return_ident; - R2 = -R2; /* R2 now 1 */ - CC = R0 == R1; /* X==Y => 1 */ - IF CC JUMP .Ltrue_return_ident; - R2 = R0; /* X/1 => X */ - /*FALLTHRU*/ - -.Ltrue_return_ident: - R0 = R2; -.Lreturn_r0: - RTS; - -.Lpower_of_two: - /* Y has a single bit set, which means it's a power of two. - ** That means we can perform the division just by shifting - ** X to the right the appropriate number of bits - */ - - /* signbits returns the number of sign bits, minus one. - ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need - ** to shift right n-signbits spaces. It also means 0x80000000 - ** is a special case, because that *also* gives a signbits of 0 - */ - - R2 = R0 >> 31; - CC = R1 < 0; - IF CC JUMP .Ltrue_return_ident; - - R1.l = SIGNBITS R1; - R1 = R1.L (Z); - R1 += -30; - R0 = LSHIFT R0 by R1.L; - RTS; - -/* METHOD 3: PRESCALE AND USE THE DIVIDE PRIMITIVES WITH SOME POST-CORRECTION - Two scaling operations are required to use the divide primitives with a - divisor > 0x7FFFF. - Firstly (as in method 1) we need to shift the dividend 1 to the left for - integer division. - Secondly we need to shift both the divisor and dividend 1 to the right so - both are in range for the primitives. - The left/right shift of the dividend does nothing so we can skip it. -*/ -.Lshift_and_correct: - R2 = R0; - // R3 is already R1 >> 1 - CC=!CC; - AQ = CC; /* Clear AQ, got here with CC = 0 */ - DIVQ(R2, R3); // 1 - DIVQ(R2, R3); // 2 - DIVQ(R2, R3); // 3 - DIVQ(R2, R3); // 4 - DIVQ(R2, R3); // 5 - DIVQ(R2, R3); // 6 - DIVQ(R2, R3); // 7 - DIVQ(R2, R3); // 8 - DIVQ(R2, R3); // 9 - DIVQ(R2, R3); // 10 - DIVQ(R2, R3); // 11 - DIVQ(R2, R3); // 12 - DIVQ(R2, R3); // 13 - DIVQ(R2, R3); // 14 - DIVQ(R2, R3); // 15 - DIVQ(R2, R3); // 16 - - /* According to the Instruction Set Reference: - To divide by a divisor > 0x7FFF, - 1. prescale and perform divide to obtain quotient (Q) (done above), - 2. multiply quotient by unscaled divisor (result M) - 3. subtract the product from the divident to get an error (E = X - M) - 4. if E < divisor (Y) subtract 1, if E > divisor (Y) add 1, else return quotient (Q) - */ - R3 = R2.L (Z); /* Q = X' / Y' */ - R2 = R3; /* Preserve Q */ - R2 *= R1; /* M = Q * Y */ - R2 = R0 - R2; /* E = X - M */ - R0 = R3; /* Copy Q into result reg */ - -/* Correction: If result of the multiply is negative, we overflowed - and need to correct the result by subtracting 1 from the result.*/ - R3 = 0xFFFF (Z); - R2 = R2 >> 16; /* E >> 16 */ - CC = R2 == R3; - R3 = 1 ; - R1 = R0 - R3; - IF CC R0 = R1; - RTS; diff --git a/trunk/arch/blackfin/lib/umodsi3.S b/trunk/arch/blackfin/lib/umodsi3.S deleted file mode 100644 index b55ce96ab89f..000000000000 --- a/trunk/arch/blackfin/lib/umodsi3.S +++ /dev/null @@ -1,66 +0,0 @@ -/* - * File: arch/blackfin/lib/umodsi3.S - * Based on: - * Author: - * - * Created: - * Description: libgcc1 routines for Blackfin 5xx - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifdef CONFIG_ARITHMETIC_OPS_L1 -.section .l1.text -#else -.text -#endif - -.extern ___udivsi3; -.globl ___umodsi3 -___umodsi3: - - CC=R0==0; - IF CC JUMP .LRETURN_R0; /* Return 0, if NR == 0 */ - CC= R1==0; - IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 0 */ - CC=R0==R1; - IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if NR == DR */ - CC = R1 == 1; - IF CC JUMP .LRETURN_ZERO_VAL; /* Return 0, if DR == 1 */ - CC = R0>= 16; - /* Unsigned multiplication has the nice property that we can - ignore carry on this first addition. */ - R0 = R0 + R3; - R0 = R0 + R1; - cc = ac0; - R1 = cc; - R1 = PACK(R1.l,R0.h); - R0 = R1 + R2; - RTS; diff --git a/trunk/arch/blackfin/mach-bf533/Kconfig b/trunk/arch/blackfin/mach-bf533/Kconfig deleted file mode 100644 index 14297b3ed5c3..000000000000 --- a/trunk/arch/blackfin/mach-bf533/Kconfig +++ /dev/null @@ -1,92 +0,0 @@ -if (BF533 || BF532 || BF531) - -menu "BF533/2/1 Specific Configuration" - -comment "Interrupt Priority Assignment" -menu "Priority" - -config UART_ERROR - int "UART ERROR" - default 7 -config SPORT0_ERROR - int "SPORT0 ERROR" - default 7 -config SPI_ERROR - int "SPI ERROR" - default 7 -config SPORT1_ERROR - int "SPORT1 ERROR" - default 7 -config PPI_ERROR - int "PPI ERROR" - default 7 -config DMA_ERROR - int "DMA ERROR" - default 7 -config PLLWAKE_ERROR - int "PLL WAKEUP ERROR" - default 7 - -config RTC_ERROR - int "RTC ERROR" - default 8 -config DMA0_PPI - int "DMA0 PPI" - default 8 - -config DMA1_SPORT0RX - int "DMA1 (SPORT0 RX)" - default 9 -config DMA2_SPORT0TX - int "DMA2 (SPORT0 TX)" - default 9 -config DMA3_SPORT1RX - int "DMA3 (SPORT1 RX)" - default 9 -config DMA4_SPORT1TX - int "DMA4 (SPORT1 TX)" - default 9 -config DMA5_SPI - int "DMA5 (SPI)" - default 10 -config DMA6_UARTRX - int "DMA6 (UART0 RX)" - default 10 -config DMA7_UARTTX - int "DMA7 (UART0 TX)" - default 10 -config TIMER0 - int "TIMER0" - default 11 -config TIMER1 - int "TIMER1" - default 11 -config TIMER2 - int "TIMER2" - default 11 -config PFA - int "PF Interrupt A" - default 12 -config PFB - int "PF Interrupt B" - default 12 -config MEMDMA0 - int "MEMORY DMA0" - default 13 -config MEMDMA1 - int "MEMORY DMA1" - default 13 -config WDTIMER - int "WATCH DOG TIMER" - default 13 - - help - Enter the priority numbers between 7-13 ONLY. Others are Reserved. - This applies to all the above. It is not recommended to assign the - highest priority number 7 to UART or any other device. - -endmenu - -endmenu - -endif diff --git a/trunk/arch/blackfin/mach-bf533/Makefile b/trunk/arch/blackfin/mach-bf533/Makefile deleted file mode 100644 index 76d2c2b8579a..000000000000 --- a/trunk/arch/blackfin/mach-bf533/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# arch/blackfin/mach-bf533/Makefile -# - -extra-y := head.o - -obj-y := ints-priority.o - -obj-$(CONFIG_CPU_FREQ_BF533) += cpu.o diff --git a/trunk/arch/blackfin/mach-bf533/boards/Makefile b/trunk/arch/blackfin/mach-bf533/boards/Makefile deleted file mode 100644 index 12a631ab389d..000000000000 --- a/trunk/arch/blackfin/mach-bf533/boards/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# arch/blackfin/mach-bf533/boards/Makefile -# - -obj-$(CONFIG_GENERIC_BOARD) += generic_board.o -obj-$(CONFIG_BFIN533_STAMP) += stamp.o -obj-$(CONFIG_BFIN533_EZKIT) += ezkit.o -obj-$(CONFIG_BFIN533_BLUETECHNIX_CM) += cm_bf533.o diff --git a/trunk/arch/blackfin/mach-bf533/boards/cm_bf533.c b/trunk/arch/blackfin/mach-bf533/boards/cm_bf533.c deleted file mode 100644 index 23a7f607df3f..000000000000 --- a/trunk/arch/blackfin/mach-bf533/boards/cm_bf533.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * File: arch/blackfin/mach-bf533/boards/cm_bf533.c - * Based on: arch/blackfin/mach-bf533/boards/ezkit.c - * Author: Aidan Williams Copright 2005 - * - * Created: 2005 - * Description: Board description file - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "Bluetechnix CM BF533"; - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* all SPI peripherals info goes here */ - -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader", - .size = 0x00020000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - },{ - .name = "kernel", - .size = 0xe0000, - .offset = 0x20000 - },{ - .name = "file system", - .size = 0x700000, - .offset = 0x00100000, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p64", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; - -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - },{ - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 2, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif -}; - -/* SPI controller data */ -static struct bfin5xx_spi_master spi_bfin_master_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ -}; - -static struct platform_device spi_bfin_master_device = { - .name = "bfin-spi-master", - .id = 1, /* Bus number */ - .dev = { - .platform_data = &spi_bfin_master_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .start = 0x20200300, - .end = 0x20200300 + 16, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF0, - .end = IRQ_PF0, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -static struct platform_device bfin_sport0_uart_device = { - .name = "bfin-sport-uart", - .id = 0, -}; - -static struct platform_device bfin_sport1_uart_device = { - .name = "bfin-sport-uart", - .id = 1, -}; -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x20308000, - .end = 0x20308000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20308004, - .end = 0x20308004, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF4, - .end = IRQ_PF4, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - -static struct platform_device *cm_bf533_devices[] __initdata = { -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) - &bfin_sport0_uart_device, - &bfin_sport1_uart_device, -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &spi_bfin_master_device, -#endif -}; - -static int __init cm_bf533_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - platform_add_devices(cm_bf533_devices, ARRAY_SIZE(cm_bf533_devices)); -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); -#endif - return 0; -} - -arch_initcall(cm_bf533_init); diff --git a/trunk/arch/blackfin/mach-bf533/boards/ezkit.c b/trunk/arch/blackfin/mach-bf533/boards/ezkit.c deleted file mode 100644 index 747298ea907b..000000000000 --- a/trunk/arch/blackfin/mach-bf533/boards/ezkit.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * File: arch/blackfin/mach-bf533/ezkit.c - * Based on: Orginal Work - * Author: Aidan Williams - * - * Created: 2005 - * Description: - * - * Modified: Robin Getz - Named the boards - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "ADDS-BF533-EZKIT"; - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -/* - * USB-LAN EzExtender board - * Driver needs to know address, irq and flag pin. - */ -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .name = "smc91x-regs", - .start = 0x20310300, - .end = 0x20310300 + 16, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF9, - .end = IRQ_PF9, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* all SPI peripherals info goes here */ - -#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader", - .size = 0x00020000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - },{ - .name = "kernel", - .size = 0xe0000, - .offset = 0x20000 - },{ - .name = "file system", - .size = 0x700000, - .offset = 0x00100000, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p64", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) - { - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif -}; - -/* SPI controller data */ -static struct bfin5xx_spi_master spi_bfin_master_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ -}; - -static struct platform_device spi_bfin_master_device = { - .name = "bfin-spi-master", - .id = 1, /* Bus number */ - .dev = { - .platform_data = &spi_bfin_master_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -static struct platform_device *ezkit_devices[] __initdata = { -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &spi_bfin_master_device, -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif -}; - -static int __init ezkit_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); -#endif - return 0; -} - -arch_initcall(ezkit_init); diff --git a/trunk/arch/blackfin/mach-bf533/boards/generic_board.c b/trunk/arch/blackfin/mach-bf533/boards/generic_board.c deleted file mode 100644 index c0f43ccfbfb5..000000000000 --- a/trunk/arch/blackfin/mach-bf533/boards/generic_board.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * File: arch/blackfin/mach-bf533/generic_board.c - * Based on: arch/blackfin/mach-bf533/ezkit.c - * Author: Aidan Williams - * - * Created: 2005 - * Description: - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "UNKNOWN BOARD"; - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -/* - * Driver needs to know address, irq and flag pin. - */ -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .start = 0x20300300, - .end = 0x20300300 + 16, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PROG_INTB, - .end = IRQ_PROG_INTB, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - },{ - /* - * denotes the flag pin and is used directly if - * CONFIG_IRQCHIP_DEMUX_GPIO is defined. - */ - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -static struct platform_device *generic_board_devices[] __initdata = { -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif -}; - -static int __init generic_board_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - return platform_add_devices(generic_board_devices, ARRAY_SIZE(generic_board_devices)); -} - -arch_initcall(generic_board_init); diff --git a/trunk/arch/blackfin/mach-bf533/boards/stamp.c b/trunk/arch/blackfin/mach-bf533/boards/stamp.c deleted file mode 100644 index d7b3a5d74e8c..000000000000 --- a/trunk/arch/blackfin/mach-bf533/boards/stamp.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * File: arch/blackfin/mach-bf533/stamp.c - * Based on: arch/blackfin/mach-bf533/ezkit.c - * Author: Aidan Williams - * - * Created: 2005 - * Description: Board Info File for the BF533-STAMP - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -#include -#endif -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "ADDS-BF533-STAMP"; - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -/* - * Driver needs to know address, irq and flag pin. - */ -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .name = "smc91x-regs", - .start = 0x20300300, - .end = 0x20300300 + 16, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) -static struct resource net2272_bfin_resources[] = { - { - .start = 0x20300000, - .end = 0x20300000 + 0x100, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF10, - .end = IRQ_PF10, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device net2272_bfin_device = { - .name = "net2272", - .id = -1, - .num_resources = ARRAY_SIZE(net2272_bfin_resources), - .resource = net2272_bfin_resources, -}; -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* all SPI peripherals info goes here */ - -#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader", - .size = 0x00020000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - },{ - .name = "kernel", - .size = 0xe0000, - .offset = 0x20000 - },{ - .name = "file system", - .size = 0x700000, - .offset = 0x00100000, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p64", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 2, /* Framework chip select. On STAMP537 it is SPISSEL2*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) - { - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 31250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif - -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 3, - .controller_data= &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 2, - .controller_data= &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif -}; - -/* SPI controller data */ -static struct bfin5xx_spi_master spi_bfin_master_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ -}; - -static struct platform_device spi_bfin_master_device = { - .name = "bfin-spi-master", - .id = 1, /* Bus number */ - .dev = { - .platform_data = &spi_bfin_master_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) -static struct platform_device bfin_fb_device = { - .name = "bf537-fb", -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -static struct platform_device bfin_sport0_uart_device = { - .name = "bfin-sport-uart", - .id = 0, -}; - -static struct platform_device bfin_sport1_uart_device = { - .name = "bfin-sport-uart", - .id = 1, -}; -#endif - -static struct platform_device *stamp_devices[] __initdata = { -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) - &net2272_bfin_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &spi_bfin_master_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) - &bfin_sport0_uart_device, - &bfin_sport1_uart_device, -#endif -}; - -static int __init stamp_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); -#endif - return 0; -} - -arch_initcall(stamp_init); diff --git a/trunk/arch/blackfin/mach-bf533/cpu.c b/trunk/arch/blackfin/mach-bf533/cpu.c deleted file mode 100644 index 99547c4c290e..000000000000 --- a/trunk/arch/blackfin/mach-bf533/cpu.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * File: arch/blackfin/mach-bf533/cpu.c - * Based on: - * Author: michael.kang@analog.com - * - * Created: - * Description: clock scaling for the bf533 - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -/* CONFIG_CLKIN_HZ=11059200 */ -#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */ -#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */ -#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */ -#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */ -#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */ -#define VCO(x) VCO##x - -#define FREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)} -/* frequency */ -static struct cpufreq_frequency_table bf533_freq_table[] = { - FREQ(1), - FREQ(3), - {VCO4, VCO4 / 2}, {VCO4, VCO4}, - FREQ(5), - {0, CPUFREQ_TABLE_END}, -}; - -/* - * dpmc_fops->ioctl() - * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) - */ -static int bf533_getfreq(unsigned int cpu) -{ - unsigned long cclk_mhz, vco_mhz; - - /* The driver only support single cpu */ - if (cpu == 0) - dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz); - else - cclk_mhz = -1; - return cclk_mhz; -} - -static int bf533_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - unsigned long cclk_mhz; - unsigned long vco_mhz; - unsigned long flags; - unsigned int index, vco_index; - int i; - - struct cpufreq_freqs freqs; - if (cpufreq_frequency_table_target - (policy, bf533_freq_table, target_freq, relation, &index)) - return -EINVAL; - cclk_mhz = bf533_freq_table[index].frequency; - vco_mhz = bf533_freq_table[index].index; - - dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz); - freqs.old = bf533_getfreq(0); - freqs.new = cclk_mhz; - freqs.cpu = 0; - - pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n", - cclk_mhz, vco_mhz, index, target_freq, freqs.old); - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - local_irq_save(flags); - dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz); - local_irq_restore(flags); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - vco_mhz = get_vco(); - cclk_mhz = get_cclk(); - return 0; -} - -/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on - * this platform, anyway. - */ -static int bf533_verify_speed(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, &bf533_freq_table); -} - -static int __init __bf533_cpu_init(struct cpufreq_policy *policy) -{ - int result; - - if (policy->cpu != 0) - return -EINVAL; - - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - /*Now ,only support one cpu */ - policy->cur = bf533_getfreq(0); - cpufreq_frequency_table_get_attr(bf533_freq_table, policy->cpu); - return cpufreq_frequency_table_cpuinfo(policy, bf533_freq_table); -} - -static struct freq_attr *bf533_freq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver bf533_driver = { - .verify = bf533_verify_speed, - .target = bf533_target, - .get = bf533_getfreq, - .init = __bf533_cpu_init, - .name = "bf533", - .owner = THIS_MODULE, - .attr = bf533_freq_attr, -}; - -static int __init bf533_cpu_init(void) -{ - return cpufreq_register_driver(&bf533_driver); -} - -static void __exit bf533_cpu_exit(void) -{ - cpufreq_unregister_driver(&bf533_driver); -} - -MODULE_AUTHOR("Mickael Kang"); -MODULE_DESCRIPTION("cpufreq driver for BF533 CPU"); -MODULE_LICENSE("GPL"); - -module_init(bf533_cpu_init); -module_exit(bf533_cpu_exit); diff --git a/trunk/arch/blackfin/mach-bf533/head.S b/trunk/arch/blackfin/mach-bf533/head.S deleted file mode 100644 index 4808edb0680f..000000000000 --- a/trunk/arch/blackfin/mach-bf533/head.S +++ /dev/null @@ -1,774 +0,0 @@ -/* - * File: arch/blackfin/mach-bf533/head.S - * Based on: - * Author: Jeff Dionne COPYRIGHT 1998 D. Jeff Dionne - * - * Created: 1998 - * Description: bf533 startup file - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#if CONFIG_BFIN_KERNEL_CLOCK -#include -#endif -#if CONFIG_DEBUG_KERNEL_START -#include -#endif - -.global __rambase -.global __ramstart -.global __ramend -.extern ___bss_stop -.extern ___bss_start -.extern _bf53x_relocate_l1_mem - -#define INITIAL_STACK 0xFFB01000 - -.text - -ENTRY(__start) -ENTRY(__stext) - /* R0: argument of command line string, passed from uboot, save it */ - R7 = R0; - /* Set the SYSCFG register */ - R0 = 0x36; - /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ - SYSCFG = R0; - R0 = 0; - - /*Clear Out All the data and pointer Registers*/ - R1 = R0; - R2 = R0; - R3 = R0; - R4 = R0; - R5 = R0; - R6 = R0; - - P0 = R0; - P1 = R0; - P2 = R0; - P3 = R0; - P4 = R0; - P5 = R0; - - LC0 = r0; - LC1 = r0; - L0 = r0; - L1 = r0; - L2 = r0; - L3 = r0; - - /* Clear Out All the DAG Registers*/ - B0 = r0; - B1 = r0; - B2 = r0; - B3 = r0; - - I0 = r0; - I1 = r0; - I2 = r0; - I3 = r0; - - M0 = r0; - M1 = r0; - M2 = r0; - M3 = r0; - -#if CONFIG_DEBUG_KERNEL_START - -/* - * Set up a temporary Event Vector Table, so if something bad happens before - * the kernel is fully started, it doesn't vector off into the bootloaders - * table - */ - P0.l = lo(EVT2); - P0.h = hi(EVT2); - P1.l = lo(EVT15); - P1.h = hi(EVT15); - P2.l = debug_kernel_start_trap; - P2.h = debug_kernel_start_trap; - - RTS = P2; - RTI = P2; - RTX = P2; - RTN = P2; - RTE = P2; - -.Lfill_temp_vector_table: - [P0++] = P2; /* Core Event Vector Table */ - CC = P0 == P1; - if !CC JUMP .Lfill_temp_vector_table - P0 = r0; - P1 = r0; - P2 = r0; - -#endif - - p0.h = hi(FIO_MASKA_C); - p0.l = lo(FIO_MASKA_C); - r0 = 0xFFFF(Z); - w[p0] = r0.L; /* Disable all interrupts */ - ssync; - - p0.h = hi(FIO_MASKB_C); - p0.l = lo(FIO_MASKB_C); - r0 = 0xFFFF(Z); - w[p0] = r0.L; /* Disable all interrupts */ - ssync; - - /* Turn off the icache */ - p0.l = (IMEM_CONTROL & 0xFFFF); - p0.h = (IMEM_CONTROL >> 16); - R1 = [p0]; - R0 = ~ENICPLB; - R0 = R0 & R1; - - /* Anomaly 05000125 */ -#ifdef ANOMALY_05000125 - CLI R2; - SSYNC; -#endif - [p0] = R0; - SSYNC; -#ifdef ANOMALY_05000125 - STI R2; -#endif - - /* Turn off the dcache */ - p0.l = (DMEM_CONTROL & 0xFFFF); - p0.h = (DMEM_CONTROL >> 16); - R1 = [p0]; - R0 = ~ENDCPLB; - R0 = R0 & R1; - - /* Anomaly 05000125 */ -#ifdef ANOMALY_05000125 - CLI R2; - SSYNC; -#endif - [p0] = R0; - SSYNC; -#ifdef ANOMALY_05000125 - STI R2; -#endif - - /* Initialise UART */ - p0.h = hi(UART_LCR); - p0.l = lo(UART_LCR); - r0 = 0x0(Z); - w[p0] = r0.L; /* To enable DLL writes */ - ssync; - - p0.h = hi(UART_DLL); - p0.l = lo(UART_DLL); - r0 = 0x0(Z); - w[p0] = r0.L; - ssync; - - p0.h = hi(UART_DLH); - p0.l = lo(UART_DLH); - r0 = 0x00(Z); - w[p0] = r0.L; - ssync; - - p0.h = hi(UART_GCTL); - p0.l = lo(UART_GCTL); - r0 = 0x0(Z); - w[p0] = r0.L; /* To enable UART clock */ - ssync; - - /* Initialize stack pointer */ - sp.l = lo(INITIAL_STACK); - sp.h = hi(INITIAL_STACK); - fp = sp; - usp = sp; - - /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ - call _bf53x_relocate_l1_mem; -#if CONFIG_BFIN_KERNEL_CLOCK - call _start_dma_code; -#endif - - /* Code for initializing Async memory banks */ - - p2.h = hi(EBIU_AMBCTL1); - p2.l = lo(EBIU_AMBCTL1); - r0.h = hi(AMBCTL1VAL); - r0.l = lo(AMBCTL1VAL); - [p2] = r0; - ssync; - - p2.h = hi(EBIU_AMBCTL0); - p2.l = lo(EBIU_AMBCTL0); - r0.h = hi(AMBCTL0VAL); - r0.l = lo(AMBCTL0VAL); - [p2] = r0; - ssync; - - p2.h = hi(EBIU_AMGCTL); - p2.l = lo(EBIU_AMGCTL); - r0 = AMGCTLVAL; - w[p2] = r0; - ssync; - - /* This section keeps the processor in supervisor mode - * during kernel boot. Switches to user mode at end of boot. - * See page 3-9 of Hardware Reference manual for documentation. - */ - - /* EVT15 = _real_start */ - - p0.l = lo(EVT15); - p0.h = hi(EVT15); - p1.l = _real_start; - p1.h = _real_start; - [p0] = p1; - csync; - - p0.l = lo(IMASK); - p0.h = hi(IMASK); - p1.l = IMASK_IVG15; - p1.h = 0x0; - [p0] = p1; - csync; - - raise 15; - p0.l = .LWAIT_HERE; - p0.h = .LWAIT_HERE; - reti = p0; -#if defined(ANOMALY_05000281) - nop; nop; nop; -#endif - rti; - -.LWAIT_HERE: - jump .LWAIT_HERE; - -ENTRY(_real_start) - [ -- sp ] = reti; - p0.l = lo(WDOG_CTL); - p0.h = hi(WDOG_CTL); - r0 = 0xAD6(z); - w[p0] = r0; /* watchdog off for now */ - ssync; - - /* Code update for BSS size == 0 - * Zero out the bss region. - */ - - p1.l = ___bss_start; - p1.h = ___bss_start; - p2.l = ___bss_stop; - p2.h = ___bss_stop; - r0 = 0; - p2 -= p1; - lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2; -.L_clear_bss: - B[p1++] = r0; - - /* In case there is a NULL pointer reference - * Zero out region before stext - */ - - p1.l = 0x0; - p1.h = 0x0; - r0.l = __stext; - r0.h = __stext; - r0 = r0 >> 1; - p2 = r0; - r0 = 0; - lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2; -.L_clear_zero: - W[p1++] = r0; - -/* pass the uboot arguments to the global value command line */ - R0 = R7; - call _cmdline_init; - - p1.l = __rambase; - p1.h = __rambase; - r0.l = __sdata; - r0.h = __sdata; - [p1] = r0; - - p1.l = __ramstart; - p1.h = __ramstart; - p3.l = ___bss_stop; - p3.h = ___bss_stop; - - r1 = p3; - [p1] = r1; - - /* - * load the current thread pointer and stack - */ - r1.l = _init_thread_union; - r1.h = _init_thread_union; - - r2.l = 0x2000; - r2.h = 0x0000; - r1 = r1 + r2; - sp = r1; - usp = sp; - fp = sp; - call _start_kernel; -.L_exit: - jump.s .L_exit; - -.section .l1.text -#if CONFIG_BFIN_KERNEL_CLOCK -ENTRY(_start_dma_code) - p0.h = hi(SIC_IWR); - p0.l = lo(SIC_IWR); - r0.l = 0x1; - r0.h = 0x0; - [p0] = r0; - SSYNC; - - /* - * Set PLL_CTL - * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors - * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK - * - [7] = output delay (add 200ps of delay to mem signals) - * - [6] = input delay (add 200ps of input delay to mem signals) - * - [5] = PDWN : 1=All Clocks off - * - [3] = STOPCK : 1=Core Clock off - * - [1] = PLL_OFF : 1=Disable Power to PLL - * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL - * all other bits set to zero - */ - - p0.h = hi(PLL_LOCKCNT); - p0.l = lo(PLL_LOCKCNT); - r0 = 0x300(Z); - w[p0] = r0.l; - ssync; - - P2.H = hi(EBIU_SDGCTL); - P2.L = lo(EBIU_SDGCTL); - R0 = [P2]; - BITSET (R0, 24); - [P2] = R0; - SSYNC; - - r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ - r0 = r0 << 9; /* Shift it over, */ - r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ - r0 = r1 | r0; - r1 = PLL_BYPASS; /* Bypass the PLL? */ - r1 = r1 << 8; /* Shift it over */ - r0 = r1 | r0; /* add them all together */ - - p0.h = hi(PLL_CTL); - p0.l = lo(PLL_CTL); /* Load the address */ - cli r2; /* Disable interrupts */ - ssync; - w[p0] = r0.l; /* Set the value */ - idle; /* Wait for the PLL to stablize */ - sti r2; /* Enable interrupts */ - -.Lcheck_again: - p0.h = hi(PLL_STAT); - p0.l = lo(PLL_STAT); - R0 = W[P0](Z); - CC = BITTST(R0,5); - if ! CC jump .Lcheck_again; - - /* Configure SCLK & CCLK Dividers */ - r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); - p0.h = hi(PLL_DIV); - p0.l = lo(PLL_DIV); - w[p0] = r0.l; - ssync; - - p0.l = lo(EBIU_SDRRC); - p0.h = hi(EBIU_SDRRC); - r0 = mem_SDRRC; - w[p0] = r0.l; - ssync; - - p0.l = (EBIU_SDBCTL & 0xFFFF); - p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */ - r0 = mem_SDBCTL; - w[p0] = r0.l; - ssync; - - P2.H = hi(EBIU_SDGCTL); - P2.L = lo(EBIU_SDGCTL); - R0 = [P2]; - BITCLR (R0, 24); - p0.h = hi(EBIU_SDSTAT); - p0.l = lo(EBIU_SDSTAT); - r2.l = w[p0]; - cc = bittst(r2,3); - if !cc jump .Lskip; - NOP; - BITSET (R0, 23); -.Lskip: - [P2] = R0; - SSYNC; - - R0.L = lo(mem_SDGCTL); - R0.H = hi(mem_SDGCTL); - R1 = [p2]; - R1 = R1 | R0; - [P2] = R1; - SSYNC; - - p0.h = hi(SIC_IWR); - p0.l = lo(SIC_IWR); - r0.l = lo(IWR_ENABLE_ALL) - r0.h = hi(IWR_ENABLE_ALL) - [p0] = r0; - SSYNC; - - RTS; -#endif /* CONFIG_BFIN_KERNEL_CLOCK */ - -ENTRY(_bfin_reset) - /* No more interrupts to be handled*/ - CLI R6; - SSYNC; - -#if defined(CONFIG_BFIN_SHARED_FLASH_ENET) - p0.h = hi(FIO_INEN); - p0.l = lo(FIO_INEN); - r0.l = ~(1 << CONFIG_ENET_FLASH_PIN); - w[p0] = r0.l; - - p0.h = hi(FIO_DIR); - p0.l = lo(FIO_DIR); - r0.l = (1 << CONFIG_ENET_FLASH_PIN); - w[p0] = r0.l; - - p0.h = hi(FIO_FLAG_C); - p0.l = lo(FIO_FLAG_C); - r0.l = (1 << CONFIG_ENET_FLASH_PIN); - w[p0] = r0.l; -#endif - - /* Clear the bits 13-15 in SWRST if they werent cleared */ - p0.h = hi(SWRST); - p0.l = lo(SWRST); - csync; - r0.l = w[p0]; - - /* Clear the IMASK register */ - p0.h = hi(IMASK); - p0.l = lo(IMASK); - r0 = 0x0; - [p0] = r0; - - /* Clear the ILAT register */ - p0.h = hi(ILAT); - p0.l = lo(ILAT); - r0 = [p0]; - [p0] = r0; - SSYNC; - - /* Disable the WDOG TIMER */ - p0.h = hi(WDOG_CTL); - p0.l = lo(WDOG_CTL); - r0.l = 0xAD6; - w[p0] = r0.l; - SSYNC; - - /* Clear the sticky bit incase it is already set */ - p0.h = hi(WDOG_CTL); - p0.l = lo(WDOG_CTL); - r0.l = 0x8AD6; - w[p0] = r0.l; - SSYNC; - - /* Program the count value */ - R0.l = 0x100; - R0.h = 0x0; - P0.h = hi(WDOG_CNT); - P0.l = lo(WDOG_CNT); - [P0] = R0; - SSYNC; - - /* Program WDOG_STAT if necessary */ - P0.h = hi(WDOG_CTL); - P0.l = lo(WDOG_CTL); - R0 = W[P0](Z); - CC = BITTST(R0,1); - if !CC JUMP .LWRITESTAT; - CC = BITTST(R0,2); - if !CC JUMP .LWRITESTAT; - JUMP .LSKIP_WRITE; - -.LWRITESTAT: - /* When watch dog timer is enabled, a write to STAT will load the contents of CNT to STAT */ - R0 = 0x0000(z); - P0.h = hi(WDOG_STAT); - P0.l = lo(WDOG_STAT) - [P0] = R0; - SSYNC; - -.LSKIP_WRITE: - /* Enable the reset event */ - P0.h = hi(WDOG_CTL); - P0.l = lo(WDOG_CTL); - R0 = W[P0](Z); - BITCLR(R0,1); - BITCLR(R0,2); - W[P0] = R0.L; - SSYNC; - NOP; - - /* Enable the wdog counter */ - R0 = W[P0](Z); - BITCLR(R0,4); - W[P0] = R0.L; - SSYNC; - - IDLE; - - RTS; - -#if CONFIG_DEBUG_KERNEL_START -debug_kernel_start_trap: - /* Set up a temp stack in L1 - SDRAM might not be working */ - P0.L = lo(L1_DATA_A_START + 0x100); - P0.H = hi(L1_DATA_A_START + 0x100); - SP = P0; - - /* Make sure the Clocks are the way I think they should be */ - r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ - r0 = r0 << 9; /* Shift it over, */ - r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ - r0 = r1 | r0; - r1 = PLL_BYPASS; /* Bypass the PLL? */ - r1 = r1 << 8; /* Shift it over */ - r0 = r1 | r0; /* add them all together */ - - p0.h = hi(PLL_CTL); - p0.l = lo(PLL_CTL); /* Load the address */ - cli r2; /* Disable interrupts */ - ssync; - w[p0] = r0.l; /* Set the value */ - idle; /* Wait for the PLL to stablize */ - sti r2; /* Enable interrupts */ - -.Lcheck_again1: - p0.h = hi(PLL_STAT); - p0.l = lo(PLL_STAT); - R0 = W[P0](Z); - CC = BITTST(R0,5); - if ! CC jump .Lcheck_again1; - - /* Configure SCLK & CCLK Dividers */ - r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); - p0.h = hi(PLL_DIV); - p0.l = lo(PLL_DIV); - w[p0] = r0.l; - ssync; - - /* Make sure UART is enabled - you can never be sure */ - -/* - * Setup for console. Argument comes from the menuconfig - */ - -#ifdef CONFIG_BAUD_9600 -#define CONSOLE_BAUD_RATE 9600 -#elif CONFIG_BAUD_19200 -#define CONSOLE_BAUD_RATE 19200 -#elif CONFIG_BAUD_38400 -#define CONSOLE_BAUD_RATE 38400 -#elif CONFIG_BAUD_57600 -#define CONSOLE_BAUD_RATE 57600 -#elif CONFIG_BAUD_115200 -#define CONSOLE_BAUD_RATE 115200 -#endif - - p0.h = hi(UART_GCTL); - p0.l = lo(UART_GCTL); - r0 = 0x00(Z); - w[p0] = r0.L; /* To Turn off UART clocks */ - ssync; - - p0.h = hi(UART_LCR); - p0.l = lo(UART_LCR); - r0 = 0x83(Z); - w[p0] = r0.L; /* To enable DLL writes */ - ssync; - - R1 = (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_SCLK_DIV) / (CONSOLE_BAUD_RATE * 16)); - - p0.h = hi(UART_DLL); - p0.l = lo(UART_DLL); - r0 = 0xFF(Z); - r0 = R1 & R0; - w[p0] = r0.L; - ssync; - - p0.h = hi(UART_DLH); - p0.l = lo(UART_DLH); - r1 >>= 8 ; - w[p0] = r1.L; - ssync; - - p0.h = hi(UART_GCTL); - p0.l = lo(UART_GCTL); - r0 = 0x0(Z); - w[p0] = r0.L; /* To enable UART clock */ - ssync; - - p0.h = hi(UART_LCR); - p0.l = lo(UART_LCR); - r0 = 0x03(Z); - w[p0] = r0.L; /* To Turn on UART */ - ssync; - - p0.h = hi(UART_GCTL); - p0.l = lo(UART_GCTL); - r0 = 0x01(Z); - w[p0] = r0.L; /* To Turn on UART Clocks */ - ssync; - - P0.h = hi(UART_THR); - P0.l = lo(UART_THR); - P1.h = hi(UART_LSR); - P1.l = lo(UART_LSR); - - R0.L = 'K'; - call .Lwait_char; - R0.L='e'; - call .Lwait_char; - R0.L='r'; - call .Lwait_char; - R0.L='n' - call .Lwait_char; - R0.L='e' - call .Lwait_char; - R0.L='l'; - call .Lwait_char; - R0.L=' '; - call .Lwait_char; - R0.L='c'; - call .Lwait_char; - R0.L='r'; - call .Lwait_char; - R0.L='a'; - call .Lwait_char; - R0.L='s'; - call .Lwait_char; - R0.L='h'; - call .Lwait_char; - R0.L='\r'; - call .Lwait_char; - R0.L='\n'; - call .Lwait_char; - - R0.L='S'; - call .Lwait_char; - R0.L='E'; - call .Lwait_char; - R0.L='Q' - call .Lwait_char; - R0.L='S' - call .Lwait_char; - R0.L='T'; - call .Lwait_char; - R0.L='A'; - call .Lwait_char; - R0.L='T'; - call .Lwait_char; - R0.L='='; - call .Lwait_char; - R2 = SEQSTAT; - call .Ldump_reg; - - R0.L=' '; - call .Lwait_char; - R0.L='R'; - call .Lwait_char; - R0.L='E' - call .Lwait_char; - R0.L='T' - call .Lwait_char; - R0.L='X'; - call .Lwait_char; - R0.L='='; - call .Lwait_char; - R2 = RETX; - call .Ldump_reg; - - R0.L='\r'; - call .Lwait_char; - R0.L='\n'; - call .Lwait_char; - -.Ldebug_kernel_start_trap_done: - JUMP .Ldebug_kernel_start_trap_done; -.Ldump_reg: - R3 = 32; - R4 = 0x0F; - R5 = ':'; /* one past 9 */ - -.Ldump_reg2: - R0 = R2; - R3 += -4; - R0 >>>= R3; - R0 = R0 & R4; - R0 += 0x30; - CC = R0 <= R5; - if CC JUMP .Ldump_reg1; - R0 += 7; - -.Ldump_reg1: - R1.l = W[P1]; - CC = BITTST(R1, 5); - if !CC JUMP .Ldump_reg1; - W[P0] = r0; - - CC = R3 == 0; - if !CC JUMP .Ldump_reg2 - RTS; - -.Lwait_char: - R1.l = W[P1]; - CC = BITTST(R1, 5); - if !CC JUMP .Lwait_char; - W[P0] = r0; - RTS; - -#endif /* CONFIG_DEBUG_KERNEL_START */ - -.data - -/* - * Set up the usable of RAM stuff. Size of RAM is determined then - * an initial stack set up at the end. - */ - -.align 4 -__rambase: -.long 0 -__ramstart: -.long 0 -__ramend: -.long 0 diff --git a/trunk/arch/blackfin/mach-bf533/ints-priority.c b/trunk/arch/blackfin/mach-bf533/ints-priority.c deleted file mode 100644 index 36a693345204..000000000000 --- a/trunk/arch/blackfin/mach-bf533/ints-priority.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * File: arch/blackfin/mach-bf533/ints-priority.c - * Based on: - * Author: Michael Hennerich - * - * Created: ? - * Description: Set up the interupt priorities - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -void program_IAR(void) -{ - /* Program the IAR0 Register with the configured priority */ - bfin_write_SIC_IAR0(((CONFIG_PLLWAKE_ERROR - 7) << PLLWAKE_ERROR_POS) | - ((CONFIG_DMA_ERROR - 7) << DMA_ERROR_POS) | - ((CONFIG_PPI_ERROR - 7) << PPI_ERROR_POS) | - ((CONFIG_SPORT0_ERROR - 7) << SPORT0_ERROR_POS) | - ((CONFIG_SPI_ERROR - 7) << SPI_ERROR_POS) | - ((CONFIG_SPORT1_ERROR - 7) << SPORT1_ERROR_POS) | - ((CONFIG_UART_ERROR - 7) << UART_ERROR_POS) | - ((CONFIG_RTC_ERROR - 7) << RTC_ERROR_POS)); - - bfin_write_SIC_IAR1(((CONFIG_DMA0_PPI - 7) << DMA0_PPI_POS) | - ((CONFIG_DMA1_SPORT0RX - 7) << DMA1_SPORT0RX_POS) | - ((CONFIG_DMA2_SPORT0TX - 7) << DMA2_SPORT0TX_POS) | - ((CONFIG_DMA3_SPORT1RX - 7) << DMA3_SPORT1RX_POS) | - ((CONFIG_DMA4_SPORT1TX - 7) << DMA4_SPORT1TX_POS) | - ((CONFIG_DMA5_SPI - 7) << DMA5_SPI_POS) | - ((CONFIG_DMA6_UARTRX - 7) << DMA6_UARTRX_POS) | - ((CONFIG_DMA7_UARTTX - 7) << DMA7_UARTTX_POS)); - - bfin_write_SIC_IAR2(((CONFIG_TIMER0 - 7) << TIMER0_POS) | - ((CONFIG_TIMER1 - 7) << TIMER1_POS) | - ((CONFIG_TIMER2 - 7) << TIMER2_POS) | - ((CONFIG_PFA - 7) << PFA_POS) | - ((CONFIG_PFB - 7) << PFB_POS) | - ((CONFIG_MEMDMA0 - 7) << MEMDMA0_POS) | - ((CONFIG_MEMDMA1 - 7) << MEMDMA1_POS) | - ((CONFIG_WDTIMER - 7) << WDTIMER_POS)); - - SSYNC(); -} diff --git a/trunk/arch/blackfin/mach-bf537/Kconfig b/trunk/arch/blackfin/mach-bf537/Kconfig deleted file mode 100644 index cc9ae38a4dda..000000000000 --- a/trunk/arch/blackfin/mach-bf537/Kconfig +++ /dev/null @@ -1,141 +0,0 @@ -if (BF537 || BF534 || BF536) - -menu "BF537 Specific Configuration" - -comment "PORT F/G Selection" -choice - prompt "Select BF537/6/4 default GPIO PFx PORTx" - help - Quick Hack for BF537/6/4 default GPIO PFx PORTF. - -config BF537_PORT_F - bool "Select BF537/6/4 default GPIO PFx PORTF" - depends on (BF537 || BF536 || BF534) - help - Quick Hack for BF537/6/4 default GPIO PFx PORTF. - -config BF537_PORT_G - bool "Select BF537/6/4 default GPIO PFx PORTG" - depends on (BF537 || BF536 || BF534) - help - Quick Hack for BF537/6/4 default GPIO PFx PORTG. - -config BF537_PORT_H - bool "Select BF537/6/4 default GPIO PFx PORTH" - depends on (BF537 || BF536 || BF534) - help - Quick Hack for BF537/6/4 default GPIO PFx PORTH - Use only when Blackfin EMAC support is not required. - -endchoice - -comment "Interrupt Priority Assignment" -menu "Priority" - -config IRQ_PLL_WAKEUP - int "IRQ_PLL_WAKEUP" - default 7 -config IRQ_DMA_ERROR - int "IRQ_DMA_ERROR Generic" - default 7 -config IRQ_ERROR - int "IRQ_ERROR: CAN MAC SPORT0 SPORT1 SPI UART0 UART1" - default 7 -config IRQ_RTC - int "IRQ_RTC" - default 8 -config IRQ_PPI - int "IRQ_PPI" - default 8 -config IRQ_SPORT0_RX - int "IRQ_SPORT0_RX" - default 9 -config IRQ_SPORT0_TX - int "IRQ_SPORT0_TX" - default 9 -config IRQ_SPORT1_RX - int "IRQ_SPORT1_RX" - default 9 -config IRQ_SPORT1_TX - int "IRQ_SPORT1_TX" - default 9 -config IRQ_TWI - int "IRQ_TWI" - default 10 -config IRQ_SPI - int "IRQ_SPI" - default 10 -config IRQ_UART0_RX - int "IRQ_UART0_RX" - default 10 -config IRQ_UART0_TX - int "IRQ_UART0_TX" - default 10 -config IRQ_UART1_RX - int "IRQ_UART1_RX" - default 10 -config IRQ_UART1_TX - int "IRQ_UART1_TX" - default 10 -config IRQ_CAN_RX - int "IRQ_CAN_RX" - default 11 -config IRQ_CAN_TX - int "IRQ_CAN_TX" - default 11 -config IRQ_MAC_RX - int "IRQ_MAC_RX" - default 11 -config IRQ_MAC_TX - int "IRQ_MAC_TX" - default 11 -config IRQ_TMR0 - int "IRQ_TMR0" - default 12 -config IRQ_TMR1 - int "IRQ_TMR1" - default 12 -config IRQ_TMR2 - int "IRQ_TMR2" - default 12 -config IRQ_TMR3 - int "IRQ_TMR3" - default 12 -config IRQ_TMR4 - int "IRQ_TMR4" - default 12 -config IRQ_TMR5 - int "IRQ_TMR5" - default 12 -config IRQ_TMR6 - int "IRQ_TMR6" - default 12 -config IRQ_TMR7 - int "IRQ_TMR7" - default 12 -config IRQ_PROG_INTA - int "IRQ_PROG_INTA" - default 12 -config IRQ_PORTG_INTB - int "IRQ_PORTG_INTB" - default 12 -config IRQ_MEM_DMA0 - int "IRQ_MEM_DMA0" - default 13 -config IRQ_MEM_DMA1 - int "IRQ_MEM_DMA1" - default 13 -config IRQ_WATCH - int "IRQ_WATCH" - default 13 - - help - Enter the priority numbers between 7-13 ONLY. Others are Reserved. - This applies to all the above. It is not recommended to assign the - highest priority number 7 to UART or any other device. - -endmenu - -endmenu - -endif diff --git a/trunk/arch/blackfin/mach-bf537/Makefile b/trunk/arch/blackfin/mach-bf537/Makefile deleted file mode 100644 index f32d44215bb7..000000000000 --- a/trunk/arch/blackfin/mach-bf537/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# arch/blackfin/mach-bf537/Makefile -# - -extra-y := head.o - -obj-y := ints-priority.o - -obj-$(CONFIG_CPU_FREQ) += cpu.o diff --git a/trunk/arch/blackfin/mach-bf537/boards/Makefile b/trunk/arch/blackfin/mach-bf537/boards/Makefile deleted file mode 100644 index 23323cacc3aa..000000000000 --- a/trunk/arch/blackfin/mach-bf537/boards/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# arch/blackfin/mach-bf537/boards/Makefile -# - -obj-y += eth_mac.o -obj-$(CONFIG_GENERIC_BOARD) += generic_board.o -obj-$(CONFIG_BFIN537_STAMP) += stamp.o led.o -obj-$(CONFIG_BFIN537_BLUETECHNIX_CM) += cm_bf537.o -obj-$(CONFIG_PNAV10) += pnav10.o diff --git a/trunk/arch/blackfin/mach-bf537/boards/cm_bf537.c b/trunk/arch/blackfin/mach-bf537/boards/cm_bf537.c deleted file mode 100644 index 6a60618a78ec..000000000000 --- a/trunk/arch/blackfin/mach-bf537/boards/cm_bf537.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * File: arch/blackfin/mach-bf537/boards/cm_bf537.c - * Based on: arch/blackfin/mach-bf533/boards/ezkit.c - * Author: Aidan Williams - * - * Created: 2005 - * Description: Board description file - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "Bluetechnix CM BF537"; - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* all SPI peripherals info goes here */ - -#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader", - .size = 0x00020000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - },{ - .name = "kernel", - .size = 0xe0000, - .offset = 0x20000 - },{ - .name = "file system", - .size = 0x700000, - .offset = 0x00100000, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p64", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) -static struct bfin5xx_spi_chip spi_mmc_chip_info = { - .enable_dma = 1, - .bits_per_word = 8, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) - { - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif - -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif - -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) - { - .modalias = "spi_mmc_dummy", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 7, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "spi_mmc", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SPI_MMC_CS_CHAN, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, -#endif -}; - -/* SPI controller data */ -static struct bfin5xx_spi_master spi_bfin_master_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ -}; - -static struct platform_device spi_bfin_master_device = { - .name = "bfin-spi-master", - .id = 1, /* Bus number */ - .dev = { - .platform_data = &spi_bfin_master_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .start = 0x20200300, - .end = 0x20200300 + 16, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF14, - .end = IRQ_PF14, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x20308000, - .end = 0x20308000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20308004, - .end = 0x20308004, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PG15, - .end = IRQ_PG15, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) -static struct resource net2272_bfin_resources[] = { - { - .start = 0x20200000, - .end = 0x20200000 + 0x100, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device net2272_bfin_device = { - .name = "net2272", - .id = -1, - .num_resources = ARRAY_SIZE(net2272_bfin_resources), - .resource = net2272_bfin_resources, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - },{ - .start = 0xFFC02000, - .end = 0xFFC020FF, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -static struct platform_device bfin_sport0_uart_device = { - .name = "bfin-sport-uart", - .id = 0, -}; - -static struct platform_device bfin_sport1_uart_device = { - .name = "bfin-sport-uart", - .id = 1, -}; -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mac_device = { - .name = "bfin_mac", -}; -#endif - -static struct platform_device *cm_bf537_devices[] __initdata = { -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) - &bfin_sport0_uart_device, - &bfin_sport1_uart_device, -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mac_device, -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) - &net2272_bfin_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &spi_bfin_master_device, -#endif -}; - -static int __init cm_bf537_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - platform_add_devices(cm_bf537_devices, ARRAY_SIZE(cm_bf537_devices)); -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); -#endif - return 0; -} - -arch_initcall(cm_bf537_init); diff --git a/trunk/arch/blackfin/mach-bf537/boards/eth_mac.c b/trunk/arch/blackfin/mach-bf537/boards/eth_mac.c deleted file mode 100644 index e129a08d63de..000000000000 --- a/trunk/arch/blackfin/mach-bf537/boards/eth_mac.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * arch/blackfin/mach-bf537/board/eth_mac.c - * - * Copyright (C) 2007 Analog Devices, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include - -#if defined(CONFIG_GENERIC_BOARD) \ - || defined(CONFIG_BFIN537_STAMP) - -/* - * Currently the MAC address is saved in Flash by U-Boot - */ -#define FLASH_MAC 0x203f0000 - -void get_bf537_ether_addr(char *addr) -{ - unsigned int flash_mac = (unsigned int) FLASH_MAC; - *(u32 *)(&(addr[0])) = bfin_read32(flash_mac); - flash_mac += 4; - *(u16 *)(&(addr[4])) = bfin_read16(flash_mac); -} - -#else - -/* - * Provide MAC address function for other specific board setting - */ -void get_bf537_ether_addr(char *addr) -{ - printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n",__FILE__); -} - -#endif - -EXPORT_SYMBOL(get_bf537_ether_addr); diff --git a/trunk/arch/blackfin/mach-bf537/boards/generic_board.c b/trunk/arch/blackfin/mach-bf537/boards/generic_board.c deleted file mode 100644 index 9019c0edbe7c..000000000000 --- a/trunk/arch/blackfin/mach-bf537/boards/generic_board.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * File: arch/blackfin/mach-bf537/boards/generic_board.c - * Based on: arch/blackfin/mach-bf533/boards/ezkit.c - * Author: Aidan Williams - * - * Created: - * Description: - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "UNKNOWN BOARD"; - -/* - * Driver needs to know address, irq and flag pin. - */ - -#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) -static struct resource bfin_pcmcia_cf_resources[] = { - { - .start = 0x20310000, /* IO PORT */ - .end = 0x20312000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20311000, /* Attribute Memeory */ - .end = 0x20311FFF, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PROG_INTA, - .end = IRQ_PROG_INTA, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, - },{ - .start = IRQ_PF4, - .end = IRQ_PF4, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, - },{ - .start = 6, /* Card Detect PF6 */ - .end = 6, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_pcmcia_cf_device = { - .name = "bfin_cf_pcmcia", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), - .resource = bfin_pcmcia_cf_resources, -}; -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .name = "smc91x-regs", - .start = 0x20300300, - .end = 0x20300300 + 16, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PROG_INTB, - .end = IRQ_PROG_INTB, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - },{ - /* - * denotes the flag pin and is used directly if - * CONFIG_IRQCHIP_DEMUX_GPIO is defined. - */ - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) -static struct resource sl811_hcd_resources[] = { - { - .start = 0x20340000, - .end = 0x20340000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20340004, - .end = 0x20340004, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PROG_INTA, - .end = IRQ_PROG_INTA, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - },{ - .start = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO, - .end = IRQ_PF0 + CONFIG_USB_SL811_BFIN_GPIO, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) -void sl811_port_power(struct device *dev, int is_on) -{ - unsigned short mask = (1< -#include - -/* All functions in this file save the registers they uses. - So there is no need to save any registers before calling them. */ - - .text; - -/* Initialize LEDs. */ - -ENTRY(_led_init) - LINK 12; - [--SP] = P0; - [--SP] = R0; - [--SP] = R1; - [--SP] = R2; - R1 = PF6|PF7|PF8|PF9|PF10|PF11 (Z); - R2 = ~R1; - - P0.H = hi(PORTF_FER); - P0.L = lo(PORTF_FER); - R0 = W[P0](Z); - SSYNC; - R0 = R0 & R2; - W[P0] = R0.L; - SSYNC; - - P0.H = hi(PORTFIO_DIR); - P0.L = lo(PORTFIO_DIR); - R0 = W[P0](Z); - SSYNC; - R0 = R0 | R1; - W[P0] = R0.L; - SSYNC; - - P0.H = hi(PORTFIO_INEN); - P0.L = lo(PORTFIO_INEN); - R0 = W[P0](Z); - SSYNC; - R0 = R0 & R2; - W[P0] = R0.L; - SSYNC; - - R2 = [SP++]; - R1 = [SP++]; - R0 = [SP++]; - P0 = [SP++]; - UNLINK; - RTS; - .size _led_init, .-_led_init - -/* Set one LED on. Leave other LEDs unchanged. - It expects the LED number passed through R0. */ - -ENTRY(_led_on) - LINK 12; - [--SP] = P0; - [--SP] = R1; - CALL _led_init; - R1 = 1; - R0 += 5; - R1 <<= R0; - P0.H = hi(PORTFIO); - P0.L = lo(PORTFIO); - R0 = W[P0](Z); - SSYNC; - R0 = R0 | R1; - W[P0] = R0.L; - SSYNC; - R1 = [SP++]; - P0 = [SP++]; - UNLINK; - RTS; - .size _led_on, .-_led_on - -/* Set one LED off. Leave other LEDs unchanged. */ - -ENTRY(_led_off) - LINK 12; - [--SP] = P0; - [--SP] = R1; - CALL _led_init; - R1 = 1; - R0 += 5; - R1 <<= R0; - R1 = ~R1; - P0.H = hi(PORTFIO); - P0.L = lo(PORTFIO); - R0 = W[P0](Z); - SSYNC; - R0 = R0 & R1; - W[P0] = R0.L; - SSYNC; - R1 = [SP++]; - P0 = [SP++]; - UNLINK; - RTS; - .size _led_off, .-_led_off - -/* Toggle one LED. Leave other LEDs unchanged. */ - -ENTRY(_led_toggle) - LINK 12; - [--SP] = P0; - [--SP] = R1; - CALL _led_init; - R1 = 1; - R0 += 5; - R1 <<= R0; - P0.H = hi(PORTFIO); - P0.L = lo(PORTFIO); - R0 = W[P0](Z); - SSYNC; - R0 = R0 ^ R1; - W[P0] = R0.L; - SSYNC; - R1 = [SP++]; - P0 = [SP++]; - UNLINK; - RTS; - .size _led_toggle, .-_led_toggle - -/* Display the number using LEDs in binary format. */ - -ENTRY(_led_disp_num) - LINK 12; - [--SP] = P0; - [--SP] = R1; - [--SP] = R2; - CALL _led_init; - R1 = 0x3f(X); - R0 = R0 & R1; - R2 = 6(X); - R0 <<= R2; - R1 <<= R2; - P0.H = hi(PORTFIO); - P0.L = lo(PORTFIO); - R2 = W[P0](Z); - SSYNC; - R1 = ~R1; - R2 = R2 & R1; - R2 = R2 | R0; - W[P0] = R2.L; - SSYNC; - R2 = [SP++]; - R1 = [SP++]; - P0 = [SP++]; - UNLINK; - RTS; - .size _led_disp_num, .-_led_disp_num - -/* Toggle the number using LEDs in binary format. */ - -ENTRY(_led_toggle_num) - LINK 12; - [--SP] = P0; - [--SP] = R1; - [--SP] = R2; - CALL _led_init; - R1 = 0x3f(X); - R0 = R0 & R1; - R1 = 6(X); - R0 <<= R1; - P0.H = hi(PORTFIO); - P0.L = lo(PORTFIO); - R1 = W[P0](Z); - SSYNC; - R1 = R1 ^ R0; - W[P0] = R1.L; - SSYNC; - R2 = [SP++]; - R1 = [SP++]; - P0 = [SP++]; - UNLINK; - RTS; - .size _led_toggle_num, .-_led_toggle_num - diff --git a/trunk/arch/blackfin/mach-bf537/boards/pnav10.c b/trunk/arch/blackfin/mach-bf537/boards/pnav10.c deleted file mode 100644 index 40d3a1b70ee7..000000000000 --- a/trunk/arch/blackfin/mach-bf537/boards/pnav10.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * File: arch/blackfin/mach-bf537/boards/stamp.c - * Based on: arch/blackfin/mach-bf533/boards/ezkit.c - * Author: Aidan Williams - * - * Created: - * Description: - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -#include -#endif -#include -#include -#include - -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "PNAV-1.0"; - -/* - * Driver needs to know address, irq and flag pin. - */ - -#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) -static struct resource bfin_pcmcia_cf_resources[] = { - { - .start = 0x20310000, /* IO PORT */ - .end = 0x20312000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20311000, /* Attribute Memeory */ - .end = 0x20311FFF, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF4, - .end = IRQ_PF4, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, - },{ - .start = 6, /* Card Detect PF6 */ - .end = 6, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_pcmcia_cf_device = { - .name = "bfin_cf_pcmcia", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), - .resource = bfin_pcmcia_cf_resources, -}; -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .name = "smc91x-regs", - .start = 0x20300300, - .end = 0x20300300 + 16, - .flags = IORESOURCE_MEM, - },{ - - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) -static struct resource sl811_hcd_resources[] = { - { - .start = 0x20340000, - .end = 0x20340000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20340004, - .end = 0x20340004, - .flags = IORESOURCE_MEM, - },{ - .start = CONFIG_USB_SL811_BFIN_IRQ, - .end = CONFIG_USB_SL811_BFIN_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) -void sl811_port_power(struct device *dev, int is_on) -{ - unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS); - - bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask); - bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask); - - if (is_on) - bfin_write_FIO_FLAG_S(mask); - else - bfin_write_FIO_FLAG_C(mask); -} -#endif - -static struct sl811_platform_data sl811_priv = { - .potpg = 10, - .power = 250, /* == 500mA */ -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) - .port_power = &sl811_port_power, -#endif -}; - -static struct platform_device sl811_hcd_device = { - .name = "sl811-hcd", - .id = 0, - .dev = { - .platform_data = &sl811_priv, - }, - .num_resources = ARRAY_SIZE(sl811_hcd_resources), - .resource = sl811_hcd_resources, -}; -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x20360000, - .end = 0x20360000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20360004, - .end = 0x20360004, - .flags = IORESOURCE_MEM, - },{ - .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mac_device = { - .name = "bfin_mac", -}; -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) -static struct resource net2272_bfin_resources[] = { - { - .start = 0x20300000, - .end = 0x20300000 + 0x100, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device net2272_bfin_device = { - .name = "net2272", - .id = -1, - .num_resources = ARRAY_SIZE(net2272_bfin_resources), - .resource = net2272_bfin_resources, -}; -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* all SPI peripherals info goes here */ - -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader", - .size = 0x00020000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - },{ - .name = "kernel", - .size = 0xe0000, - .offset = 0x20000 - },{ - .name = "file system", - .size = 0x700000, - .offset = 0x00100000, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p64", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_SPI_ADC_BF533) \ - || defined(CONFIG_SPI_ADC_BF533_MODULE) -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) -static struct bfin5xx_spi_chip spi_mmc_chip_info = { - .enable_dma = 1, - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - - -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) -static struct bfin5xx_spi_chip spi_ad7877_chip_info = { - .cs_change_per_word = 1, - .enable_dma = 0, - .bits_per_word = 16, -}; - -static const struct ad7877_platform_data bfin_ad7877_ts_info = { - .model = 7877, - .vref_delay_usecs = 50, /* internal, no capacitor */ - .x_plate_ohms = 419, - .y_plate_ohms = 486, - .pressure_max = 1000, - .pressure_min = 0, - .stopacq_polarity = 1, - .first_conversion_delay = 3, - .acquisition_time = 1, - .averaging = 1, - .pen_down_acc_interval = 1, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_SPI_ADC_BF533) \ - || defined(CONFIG_SPI_ADC_BF533_MODULE) - { - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) - { - .modalias = "spi_mmc_dummy", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 7, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "spi_mmc", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SPI_MMC_CS_CHAN, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 3, - .controller_data= &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 2, - .controller_data= &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) -{ - .modalias = "ad7877", - .platform_data = &bfin_ad7877_ts_info, - .irq = IRQ_PF2, - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 5, - .controller_data = &spi_ad7877_chip_info, -}, -#endif - -}; - -/* SPI controller data */ -static struct bfin5xx_spi_master spi_bfin_master_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ -}; - -static struct platform_device spi_bfin_master_device = { - .name = "bfin-spi-master", - .id = 1, /* Bus number */ - .dev = { - .platform_data = &spi_bfin_master_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) -static struct platform_device bfin_fb_device = { - .name = "bf537-fb", -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - },{ - .start = 0xFFC02000, - .end = 0xFFC020FF, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - - -static struct platform_device *stamp_devices[] __initdata = { -#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) - &bfin_pcmcia_cf_device, -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) - &sl811_hcd_device, -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mac_device, -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) - &net2272_bfin_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &spi_bfin_master_device, -#endif - -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) - &bfin_fb_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif -}; - -static int __init stamp_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - spi_register_board_info(bfin_spi_board_info, - ARRAY_SIZE(bfin_spi_board_info)); -#endif - return 0; -} - -arch_initcall(stamp_init); diff --git a/trunk/arch/blackfin/mach-bf537/boards/stamp.c b/trunk/arch/blackfin/mach-bf537/boards/stamp.c deleted file mode 100644 index ba2f875a7f7d..000000000000 --- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c +++ /dev/null @@ -1,615 +0,0 @@ -/* - * File: arch/blackfin/mach-bf537/boards/stamp.c - * Based on: arch/blackfin/mach-bf533/boards/ezkit.c - * Author: Aidan Williams - * - * Created: - * Description: - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -#include -#endif -#include -#include -#include -#include -#include - -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "ADDS-BF537-STAMP"; - -/* - * Driver needs to know address, irq and flag pin. - */ - -#define ISP1761_BASE 0x203C0000 -#define ISP1761_IRQ IRQ_PF7 - -#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE) -static struct resource bfin_isp1761_resources[] = { - [0] = { - .name = "isp1761-regs", - .start = ISP1761_BASE + 0x00000000, - .end = ISP1761_BASE + 0x000fffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = ISP1761_IRQ, - .end = ISP1761_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_isp1761_device = { - .name = "isp1761", - .id = 0, - .num_resources = ARRAY_SIZE(bfin_isp1761_resources), - .resource = bfin_isp1761_resources, -}; - -static struct platform_device *bfin_isp1761_devices[] = { - &bfin_isp1761_device, -}; - -int __init bfin_isp1761_init(void) -{ - unsigned int num_devices=ARRAY_SIZE(bfin_isp1761_devices); - - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING); - - return platform_add_devices(bfin_isp1761_devices, num_devices); -} - -void __exit bfin_isp1761_exit(void) -{ - platform_device_unregister(&bfin_isp1761_device); -} - -arch_initcall(bfin_isp1761_init); -#endif - -#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) -static struct resource bfin_pcmcia_cf_resources[] = { - { - .start = 0x20310000, /* IO PORT */ - .end = 0x20312000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20311000, /* Attribute Memeory */ - .end = 0x20311FFF, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF4, - .end = IRQ_PF4, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, - },{ - .start = 6, /* Card Detect PF6 */ - .end = 6, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device bfin_pcmcia_cf_device = { - .name = "bfin_cf_pcmcia", - .id = -1, - .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources), - .resource = bfin_pcmcia_cf_resources, -}; -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) -static struct platform_device rtc_device = { - .name = "rtc-bfin", - .id = -1, -}; -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .name = "smc91x-regs", - .start = 0x20300300, - .end = 0x20300300 + 16, - .flags = IORESOURCE_MEM, - },{ - - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) -static struct resource sl811_hcd_resources[] = { - { - .start = 0x20340000, - .end = 0x20340000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20340004, - .end = 0x20340004, - .flags = IORESOURCE_MEM, - },{ - .start = CONFIG_USB_SL811_BFIN_IRQ, - .end = CONFIG_USB_SL811_BFIN_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) -void sl811_port_power(struct device *dev, int is_on) -{ - unsigned short mask = (1 << CONFIG_USB_SL811_BFIN_GPIO_VBUS); - - bfin_write_PORT_FER(bfin_read_PORT_FER() & ~mask); - bfin_write_FIO_DIR(bfin_read_FIO_DIR() | mask); - - if (is_on) - bfin_write_FIO_FLAG_S(mask); - else - bfin_write_FIO_FLAG_C(mask); -} -#endif - -static struct sl811_platform_data sl811_priv = { - .potpg = 10, - .power = 250, /* == 500mA */ -#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS) - .port_power = &sl811_port_power, -#endif -}; - -static struct platform_device sl811_hcd_device = { - .name = "sl811-hcd", - .id = 0, - .dev = { - .platform_data = &sl811_priv, - }, - .num_resources = ARRAY_SIZE(sl811_hcd_resources), - .resource = sl811_hcd_resources, -}; -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x20360000, - .end = 0x20360000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x20360004, - .end = 0x20360004, - .flags = IORESOURCE_MEM, - },{ - .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) -static struct platform_device bfin_mac_device = { - .name = "bfin_mac", -}; -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) -static struct resource net2272_bfin_resources[] = { - { - .start = 0x20300000, - .end = 0x20300000 + 0x100, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF7, - .end = IRQ_PF7, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device net2272_bfin_device = { - .name = "net2272", - .id = -1, - .num_resources = ARRAY_SIZE(net2272_bfin_resources), - .resource = net2272_bfin_resources, -}; -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* all SPI peripherals info goes here */ - -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader", - .size = 0x00020000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - },{ - .name = "kernel", - .size = 0xe0000, - .offset = 0x20000 - },{ - .name = "file system", - .size = 0x700000, - .offset = 0x00100000, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p64", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_SPI_ADC_BF533) \ - || defined(CONFIG_SPI_ADC_BF533_MODULE) -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) -static struct bfin5xx_spi_chip spi_mmc_chip_info = { - .enable_dma = 1, - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_PBX) -static struct bfin5xx_spi_chip spi_si3xxx_chip_info = { - .ctl_reg = 0x4, /* send zero */ - .enable_dma = 0, - .bits_per_word = 8, - .cs_change_per_word = 1, -}; -#endif - -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) -static struct bfin5xx_spi_chip ad5304_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) -static struct bfin5xx_spi_chip spi_ad7877_chip_info = { -// .cs_change_per_word = 1, - .enable_dma = 0, - .bits_per_word = 16, -}; - -static const struct ad7877_platform_data bfin_ad7877_ts_info = { - .model = 7877, - .vref_delay_usecs = 50, /* internal, no capacitor */ - .x_plate_ohms = 419, - .y_plate_ohms = 486, - .pressure_max = 1000, - .pressure_min = 0, - .stopacq_polarity = 1, - .first_conversion_delay = 3, - .acquisition_time = 1, - .averaging = 1, - .pen_down_acc_interval = 1, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) \ - || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_SPI_ADC_BF533) \ - || defined(CONFIG_SPI_ADC_BF533_MODULE) - { - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) - { - .modalias = "spi_mmc_dummy", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 0, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "spi_mmc", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SPI_MMC_CS_CHAN, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_PBX) - { - .modalias = "fxs-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 3, - .controller_data= &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, - { - .modalias = "fxo-spi", - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 2, - .controller_data= &spi_si3xxx_chip_info, - .mode = SPI_MODE_3, - }, -#endif -#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE) - { - .modalias = "ad5304_spi", - .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 2, - .platform_data = NULL, - .controller_data = &ad5304_chip_info, - .mode = SPI_MODE_2, - }, -#endif -#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) - { - .modalias = "ad7877", - .platform_data = &bfin_ad7877_ts_info, - .irq = IRQ_PF6, - .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 1, - .controller_data = &spi_ad7877_chip_info, - }, -#endif -}; - -/* SPI controller data */ -static struct bfin5xx_spi_master spi_bfin_master_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ -}; - -static struct platform_device spi_bfin_master_device = { - .name = "bfin-spi-master", - .id = 1, /* Bus number */ - .dev = { - .platform_data = &spi_bfin_master_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) -static struct platform_device bfin_fb_device = { - .name = "bf537-fb", -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - },{ - .start = 0xFFC02000, - .end = 0xFFC020FF, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) -static struct platform_device i2c_bfin_twi_device = { - .name = "i2c-bfin-twi", - .id = 0, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) -static struct platform_device bfin_sport0_uart_device = { - .name = "bfin-sport-uart", - .id = 0, -}; - -static struct platform_device bfin_sport1_uart_device = { - .name = "bfin-sport-uart", - .id = 1, -}; -#endif - -static struct platform_device *stamp_devices[] __initdata = { -#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) - &bfin_pcmcia_cf_device, -#endif - -#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) - &rtc_device, -#endif - -#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) - &sl811_hcd_device, -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif - -#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE) - &bfin_mac_device, -#endif - -#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) - &net2272_bfin_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &spi_bfin_master_device, -#endif - -#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE) - &bfin_fb_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif - -#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) - &i2c_bfin_twi_device, -#endif - -#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) - &bfin_sport0_uart_device, - &bfin_sport1_uart_device, -#endif -}; - -static int __init stamp_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - spi_register_board_info(bfin_spi_board_info, - ARRAY_SIZE(bfin_spi_board_info)); -#endif - return 0; -} - -arch_initcall(stamp_init); diff --git a/trunk/arch/blackfin/mach-bf537/cpu.c b/trunk/arch/blackfin/mach-bf537/cpu.c deleted file mode 100644 index 2d83b7e35469..000000000000 --- a/trunk/arch/blackfin/mach-bf537/cpu.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * File: arch/blackfin/mach-bf537/cpu.c - * Based on: - * Author: michael.kang@analog.com - * - * Created: - * Description: clock scaling for the bf537 - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -/* CONFIG_CLKIN_HZ=11059200 */ -#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */ -#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */ -#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */ -#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */ -#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */ -#define VCO(x) VCO##x - -#define FREQ(x) {VCO(x),VCO(x)/4},{VCO(x),VCO(x)/2},{VCO(x),VCO(x)} -/* frequency */ -static struct cpufreq_frequency_table bf537_freq_table[] = { - FREQ(1), - FREQ(3), - {VCO4, VCO4 / 2}, {VCO4, VCO4}, - FREQ(5), - {0, CPUFREQ_TABLE_END}, -}; - -/* - * dpmc_fops->ioctl() - * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) - */ -static int bf537_getfreq(unsigned int cpu) -{ - unsigned long cclk_mhz, vco_mhz; - - /* The driver only support single cpu */ - if (cpu == 0) - dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz); - else - cclk_mhz = -1; - return cclk_mhz; -} - -static int bf537_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - unsigned long cclk_mhz; - unsigned long vco_mhz; - unsigned long flags; - unsigned int index, vco_index; - int i; - - struct cpufreq_freqs freqs; - if (cpufreq_frequency_table_target - (policy, bf537_freq_table, target_freq, relation, &index)) - return -EINVAL; - cclk_mhz = bf537_freq_table[index].frequency; - vco_mhz = bf537_freq_table[index].index; - - dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz); - freqs.old = bf537_getfreq(0); - freqs.new = cclk_mhz; - freqs.cpu = 0; - - pr_debug("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n", - cclk_mhz, vco_mhz, index, target_freq, freqs.old); - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - local_irq_save(flags); - dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz); - local_irq_restore(flags); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - vco_mhz = get_vco(); - cclk_mhz = get_cclk(); - return 0; -} - -/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on - * this platform, anyway. - */ -static int bf537_verify_speed(struct cpufreq_policy *policy) -{ - return cpufreq_frequency_table_verify(policy, &bf537_freq_table); -} - -static int __init __bf537_cpu_init(struct cpufreq_policy *policy) -{ - int result; - - if (policy->cpu != 0) - return -EINVAL; - - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; - - policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; - /*Now ,only support one cpu */ - policy->cur = bf537_getfreq(0); - cpufreq_frequency_table_get_attr(bf537_freq_table, policy->cpu); - return cpufreq_frequency_table_cpuinfo(policy, bf537_freq_table); -} - -static struct freq_attr *bf537_freq_attr[] = { - &cpufreq_freq_attr_scaling_available_freqs, - NULL, -}; - -static struct cpufreq_driver bf537_driver = { - .verify = bf537_verify_speed, - .target = bf537_target, - .get = bf537_getfreq, - .init = __bf537_cpu_init, - .name = "bf537", - .owner = THIS_MODULE, - .attr = bf537_freq_attr, -}; - -static int __init bf537_cpu_init(void) -{ - return cpufreq_register_driver(&bf537_driver); -} - -static void __exit bf537_cpu_exit(void) -{ - cpufreq_unregister_driver(&bf537_driver); -} - -MODULE_AUTHOR("Mickael Kang"); -MODULE_DESCRIPTION("cpufreq driver for BF537 CPU"); -MODULE_LICENSE("GPL"); - -module_init(bf537_cpu_init); -module_exit(bf537_cpu_exit); diff --git a/trunk/arch/blackfin/mach-bf537/head.S b/trunk/arch/blackfin/mach-bf537/head.S deleted file mode 100644 index d104e1d8e07a..000000000000 --- a/trunk/arch/blackfin/mach-bf537/head.S +++ /dev/null @@ -1,602 +0,0 @@ -/* - * File: arch/blackfin/mach-bf537/head.S - * Based on: arch/blackfin/mach-bf533/head.S - * Author: Jeff Dionne COPYRIGHT 1998 D. Jeff Dionne - * - * Created: 1998 - * Description: Startup code for Blackfin BF537 - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#if CONFIG_BFIN_KERNEL_CLOCK -#include -#endif - -.global __rambase -.global __ramstart -.global __ramend -.extern ___bss_stop -.extern ___bss_start -.extern _bf53x_relocate_l1_mem - -#define INITIAL_STACK 0xFFB01000 - -.text - -ENTRY(__start) -ENTRY(__stext) - /* R0: argument of command line string, passed from uboot, save it */ - R7 = R0; - /* Set the SYSCFG register */ - R0 = 0x36; - SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ - R0 = 0; - - /* Clear Out All the data and pointer Registers*/ - R1 = R0; - R2 = R0; - R3 = R0; - R4 = R0; - R5 = R0; - R6 = R0; - - P0 = R0; - P1 = R0; - P2 = R0; - P3 = R0; - P4 = R0; - P5 = R0; - - LC0 = r0; - LC1 = r0; - L0 = r0; - L1 = r0; - L2 = r0; - L3 = r0; - - /* Clear Out All the DAG Registers*/ - B0 = r0; - B1 = r0; - B2 = r0; - B3 = r0; - - I0 = r0; - I1 = r0; - I2 = r0; - I3 = r0; - - M0 = r0; - M1 = r0; - M2 = r0; - M3 = r0; - - /* Turn off the icache */ - p0.l = (IMEM_CONTROL & 0xFFFF); - p0.h = (IMEM_CONTROL >> 16); - R1 = [p0]; - R0 = ~ENICPLB; - R0 = R0 & R1; - - /* Anomaly 05000125 */ -#ifdef ANOMALY_05000125 - CLI R2; - SSYNC; -#endif - [p0] = R0; - SSYNC; -#ifdef ANOMALY_05000125 - STI R2; -#endif - - /* Turn off the dcache */ - p0.l = (DMEM_CONTROL & 0xFFFF); - p0.h = (DMEM_CONTROL >> 16); - R1 = [p0]; - R0 = ~ENDCPLB; - R0 = R0 & R1; - - /* Anomaly 05000125 */ -#ifdef ANOMALY_05000125 - CLI R2; - SSYNC; -#endif - [p0] = R0; - SSYNC; -#ifdef ANOMALY_05000125 - STI R2; -#endif - - /* Initialise General-Purpose I/O Modules on BF537 */ - /* Rev 0.0 Anomaly 05000212 - PORTx_FER, - * PORT_MUX Registers Do Not accept "writes" correctly: - */ - p0.h = hi(BFIN_PORT_MUX); - p0.l = lo(BFIN_PORT_MUX); -#ifdef ANOMALY_05000212 - R0.L = W[P0]; /* Read */ - SSYNC; -#endif - R0 = (PGDE_UART | PFTE_UART)(Z); -#ifdef ANOMALY_05000212 - W[P0] = R0.L; /* Write */ - SSYNC; -#endif - W[P0] = R0.L; /* Enable both UARTS */ - SSYNC; - - p0.h = hi(PORTF_FER); - p0.l = lo(PORTF_FER); -#ifdef ANOMALY_05000212 - R0.L = W[P0]; /* Read */ - SSYNC; -#endif - R0 = 0x000F(Z); -#ifdef ANOMALY_05000212 - W[P0] = R0.L; /* Write */ - SSYNC; -#endif - /* Enable peripheral function of PORTF for UART0 and UART1 */ - W[P0] = R0.L; - SSYNC; - -#if !defined(CONFIG_BF534) - p0.h = hi(EMAC_SYSTAT); - p0.l = lo(EMAC_SYSTAT); - R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */ - R0.l = 0xFFFF; - [P0] = R0; - SSYNC; -#endif - -#ifdef CONFIG_BF537_PORT_H - p0.h = hi(PORTH_FER); - p0.l = lo(PORTH_FER); - R0.L = W[P0]; /* Read */ - SSYNC; - R0 = 0x0000; - W[P0] = R0.L; /* Write */ - SSYNC; - W[P0] = R0.L; /* Disable peripheral function of PORTH */ - SSYNC; -#endif - - /*Initialise UART*/ - p0.h = hi(UART_LCR); - p0.l = lo(UART_LCR); - r0 = 0x0(Z); - w[p0] = r0.L; /* To enable DLL writes */ - ssync; - - p0.h = hi(UART_DLL); - p0.l = lo(UART_DLL); - r0 = 0x00(Z); - w[p0] = r0.L; - ssync; - - p0.h = hi(UART_DLH); - p0.l = lo(UART_DLH); - r0 = 0x00(Z); - w[p0] = r0.L; - ssync; - - p0.h = hi(UART_GCTL); - p0.l = lo(UART_GCTL); - r0 = 0x0(Z); - w[p0] = r0.L; /* To enable UART clock */ - ssync; - - /* Initialize stack pointer */ - sp.l = lo(INITIAL_STACK); - sp.h = hi(INITIAL_STACK); - fp = sp; - usp = sp; - - /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ - call _bf53x_relocate_l1_mem; -#if CONFIG_BFIN_KERNEL_CLOCK - call _start_dma_code; -#endif - /* Code for initializing Async memory banks */ - - p2.h = hi(EBIU_AMBCTL1); - p2.l = lo(EBIU_AMBCTL1); - r0.h = hi(AMBCTL1VAL); - r0.l = lo(AMBCTL1VAL); - [p2] = r0; - ssync; - - p2.h = hi(EBIU_AMBCTL0); - p2.l = lo(EBIU_AMBCTL0); - r0.h = hi(AMBCTL0VAL); - r0.l = lo(AMBCTL0VAL); - [p2] = r0; - ssync; - - p2.h = hi(EBIU_AMGCTL); - p2.l = lo(EBIU_AMGCTL); - r0 = AMGCTLVAL; - w[p2] = r0; - ssync; - - /* This section keeps the processor in supervisor mode - * during kernel boot. Switches to user mode at end of boot. - * See page 3-9 of Hardware Reference manual for documentation. - */ - - /* EVT15 = _real_start */ - - p0.l = lo(EVT15); - p0.h = hi(EVT15); - p1.l = _real_start; - p1.h = _real_start; - [p0] = p1; - csync; - - p0.l = lo(IMASK); - p0.h = hi(IMASK); - p1.l = IMASK_IVG15; - p1.h = 0x0; - [p0] = p1; - csync; - - raise 15; - p0.l = .LWAIT_HERE; - p0.h = .LWAIT_HERE; - reti = p0; -#if defined(ANOMALY_05000281) - nop; nop; nop; -#endif - rti; - -.LWAIT_HERE: - jump .LWAIT_HERE; - -ENTRY(_real_start) - [ -- sp ] = reti; - p0.l = lo(WDOG_CTL); - p0.h = hi(WDOG_CTL); - r0 = 0xAD6(z); - w[p0] = r0; /* watchdog off for now */ - ssync; - - /* Code update for BSS size == 0 - * Zero out the bss region. - */ - - p1.l = ___bss_start; - p1.h = ___bss_start; - p2.l = ___bss_stop; - p2.h = ___bss_stop; - r0 = 0; - p2 -= p1; - lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2; -.L_clear_bss: - B[p1++] = r0; - - /* In case there is a NULL pointer reference - * Zero out region before stext - */ - - p1.l = 0x0; - p1.h = 0x0; - r0.l = __stext; - r0.h = __stext; - r0 = r0 >> 1; - p2 = r0; - r0 = 0; - lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2; -.L_clear_zero: - W[p1++] = r0; - - /* pass the uboot arguments to the global value command line */ - R0 = R7; - call _cmdline_init; - - p1.l = __rambase; - p1.h = __rambase; - r0.l = __sdata; - r0.h = __sdata; - [p1] = r0; - - p1.l = __ramstart; - p1.h = __ramstart; - p3.l = ___bss_stop; - p3.h = ___bss_stop; - - r1 = p3; - [p1] = r1; - - - /* - * load the current thread pointer and stack - */ - r1.l = _init_thread_union; - r1.h = _init_thread_union; - - r2.l = 0x2000; - r2.h = 0x0000; - r1 = r1 + r2; - sp = r1; - usp = sp; - fp = sp; - call _start_kernel; -.L_exit: - jump.s .L_exit; - -.section .l1.text -#if CONFIG_BFIN_KERNEL_CLOCK -ENTRY(_start_dma_code) - - /* Enable PHY CLK buffer output */ - p0.h = hi(VR_CTL); - p0.l = lo(VR_CTL); - r0.l = w[p0]; - bitset(r0, 14); - w[p0] = r0.l; - ssync; - - p0.h = hi(SIC_IWR); - p0.l = lo(SIC_IWR); - r0.l = 0x1; - r0.h = 0x0; - [p0] = r0; - SSYNC; - - /* - * Set PLL_CTL - * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors - * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK - * - [7] = output delay (add 200ps of delay to mem signals) - * - [6] = input delay (add 200ps of input delay to mem signals) - * - [5] = PDWN : 1=All Clocks off - * - [3] = STOPCK : 1=Core Clock off - * - [1] = PLL_OFF : 1=Disable Power to PLL - * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL - * all other bits set to zero - */ - - p0.h = hi(PLL_LOCKCNT); - p0.l = lo(PLL_LOCKCNT); - r0 = 0x300(Z); - w[p0] = r0.l; - ssync; - - P2.H = hi(EBIU_SDGCTL); - P2.L = lo(EBIU_SDGCTL); - R0 = [P2]; - BITSET (R0, 24); - [P2] = R0; - SSYNC; - - r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ - r0 = r0 << 9; /* Shift it over, */ - r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ - r0 = r1 | r0; - r1 = PLL_BYPASS; /* Bypass the PLL? */ - r1 = r1 << 8; /* Shift it over */ - r0 = r1 | r0; /* add them all together */ - - p0.h = hi(PLL_CTL); - p0.l = lo(PLL_CTL); /* Load the address */ - cli r2; /* Disable interrupts */ - ssync; - w[p0] = r0.l; /* Set the value */ - idle; /* Wait for the PLL to stablize */ - sti r2; /* Enable interrupts */ - -.Lcheck_again: - p0.h = hi(PLL_STAT); - p0.l = lo(PLL_STAT); - R0 = W[P0](Z); - CC = BITTST(R0,5); - if ! CC jump .Lcheck_again; - - /* Configure SCLK & CCLK Dividers */ - r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); - p0.h = hi(PLL_DIV); - p0.l = lo(PLL_DIV); - w[p0] = r0.l; - ssync; - - p0.l = lo(EBIU_SDRRC); - p0.h = hi(EBIU_SDRRC); - r0 = mem_SDRRC; - w[p0] = r0.l; - ssync; - - p0.l = (EBIU_SDBCTL & 0xFFFF); - p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */ - r0 = mem_SDBCTL; - w[p0] = r0.l; - ssync; - - P2.H = hi(EBIU_SDGCTL); - P2.L = lo(EBIU_SDGCTL); - R0 = [P2]; - BITCLR (R0, 24); - p0.h = hi(EBIU_SDSTAT); - p0.l = lo(EBIU_SDSTAT); - r2.l = w[p0]; - cc = bittst(r2,3); - if !cc jump .Lskip; - NOP; - BITSET (R0, 23); -.Lskip: - [P2] = R0; - SSYNC; - - R0.L = lo(mem_SDGCTL); - R0.H = hi(mem_SDGCTL); - R1 = [p2]; - R1 = R1 | R0; - [P2] = R1; - SSYNC; - - p0.h = hi(SIC_IWR); - p0.l = lo(SIC_IWR); - r0.l = lo(IWR_ENABLE_ALL); - r0.h = hi(IWR_ENABLE_ALL); - [p0] = r0; - SSYNC; - - RTS; -#endif /* CONFIG_BFIN_KERNEL_CLOCK */ - -ENTRY(_bfin_reset) - /* No more interrupts to be handled*/ - CLI R6; - SSYNC; - -#if defined(CONFIG_MTD_M25P80) -/* - * The following code fix the SPI flash reboot issue, - * /CS signal of the chip which is using PF10 return to GPIO mode - */ - p0.h = hi(PORTF_FER); - p0.l = lo(PORTF_FER); - r0.l = 0x0000; - w[p0] = r0.l; - SSYNC; - -/* /CS return to high */ - p0.h = hi(PORTFIO); - p0.l = lo(PORTFIO); - r0.l = 0xFFFF; - w[p0] = r0.l; - SSYNC; - -/* Delay some time, This is necessary */ - r1.h = 0; - r1.l = 0x400; - p1 = r1; - lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1; -_delay_lab1: - r0.h = 0; - r0.l = 0x8000; - p0 = r0; - lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0; -_delay_lab0: - nop; -_delay_lab0_end: - nop; -_delay_lab1_end: - nop; -#endif - - /* Clear the bits 13-15 in SWRST if they werent cleared */ - p0.h = hi(SWRST); - p0.l = lo(SWRST); - csync; - r0.l = w[p0]; - - /* Clear the IMASK register */ - p0.h = hi(IMASK); - p0.l = lo(IMASK); - r0 = 0x0; - [p0] = r0; - - /* Clear the ILAT register */ - p0.h = hi(ILAT); - p0.l = lo(ILAT); - r0 = [p0]; - [p0] = r0; - SSYNC; - - /* Disable the WDOG TIMER */ - p0.h = hi(WDOG_CTL); - p0.l = lo(WDOG_CTL); - r0.l = 0xAD6; - w[p0] = r0.l; - SSYNC; - - /* Clear the sticky bit incase it is already set */ - p0.h = hi(WDOG_CTL); - p0.l = lo(WDOG_CTL); - r0.l = 0x8AD6; - w[p0] = r0.l; - SSYNC; - - /* Program the count value */ - R0.l = 0x100; - R0.h = 0x0; - P0.h = hi(WDOG_CNT); - P0.l = lo(WDOG_CNT); - [P0] = R0; - SSYNC; - - /* Program WDOG_STAT if necessary */ - P0.h = hi(WDOG_CTL); - P0.l = lo(WDOG_CTL); - R0 = W[P0](Z); - CC = BITTST(R0,1); - if !CC JUMP .LWRITESTAT; - CC = BITTST(R0,2); - if !CC JUMP .LWRITESTAT; - JUMP .LSKIP_WRITE; - -.LWRITESTAT: - /* When watch dog timer is enabled, - * a write to STAT will load the contents of CNT to STAT - */ - R0 = 0x0000(z); - P0.h = hi(WDOG_STAT); - P0.l = lo(WDOG_STAT) - [P0] = R0; - SSYNC; - -.LSKIP_WRITE: - /* Enable the reset event */ - P0.h = hi(WDOG_CTL); - P0.l = lo(WDOG_CTL); - R0 = W[P0](Z); - BITCLR(R0,1); - BITCLR(R0,2); - W[P0] = R0.L; - SSYNC; - NOP; - - /* Enable the wdog counter */ - R0 = W[P0](Z); - BITCLR(R0,4); - W[P0] = R0.L; - SSYNC; - - IDLE; - - RTS; - -.data - -/* - * Set up the usable of RAM stuff. Size of RAM is determined then - * an initial stack set up at the end. - */ - -.align 4 -__rambase: -.long 0 -__ramstart: -.long 0 -__ramend: -.long 0 diff --git a/trunk/arch/blackfin/mach-bf537/ints-priority.c b/trunk/arch/blackfin/mach-bf537/ints-priority.c deleted file mode 100644 index fd6308eccbe6..000000000000 --- a/trunk/arch/blackfin/mach-bf537/ints-priority.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * File: arch/blackfin/mach-bf537/ints-priority.c - * Based on: arch/blackfin/mach-bf533/ints-priority.c - * Author: Michael Hennerich - * - * Created: - * Description: Set up the interupt priorities - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -void program_IAR(void) -{ - /* Program the IAR0 Register with the configured priority */ - bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) | - ((CONFIG_IRQ_DMA_ERROR - 7) << IRQ_DMA_ERROR_POS) | - ((CONFIG_IRQ_ERROR - 7) << IRQ_ERROR_POS) | - ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS) | - ((CONFIG_IRQ_PPI - 7) << IRQ_PPI_POS) | - ((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) | - ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) | - ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS)); - - bfin_write_SIC_IAR1(((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) | - ((CONFIG_IRQ_TWI - 7) << IRQ_TWI_POS) | - ((CONFIG_IRQ_SPI - 7) << IRQ_SPI_POS) | - ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) | - ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS) | - ((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) | - ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) | - ((CONFIG_IRQ_CAN_RX - 7) << IRQ_CAN_RX_POS)); - - bfin_write_SIC_IAR2(((CONFIG_IRQ_CAN_TX - 7) << IRQ_CAN_TX_POS) | - ((CONFIG_IRQ_MAC_RX - 7) << IRQ_MAC_RX_POS) | - ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) | - ((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) | - ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) | - ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) | - ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) | - ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS)); - - bfin_write_SIC_IAR3(((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) | - ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) | - ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS) | - ((CONFIG_IRQ_PROG_INTA - 7) << IRQ_PROG_INTA_POS) | - ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) | - ((CONFIG_IRQ_MEM_DMA0 - 7) << IRQ_MEM_DMA0_POS) | - ((CONFIG_IRQ_MEM_DMA1 - 7) << IRQ_MEM_DMA1_POS) | - ((CONFIG_IRQ_WATCH - 7) << IRQ_WATCH_POS)); - - SSYNC(); -} diff --git a/trunk/arch/blackfin/mach-bf561/Kconfig b/trunk/arch/blackfin/mach-bf561/Kconfig deleted file mode 100644 index 0a17c4cf0059..000000000000 --- a/trunk/arch/blackfin/mach-bf561/Kconfig +++ /dev/null @@ -1,222 +0,0 @@ -if BF561 - -menu "BF561 Specific Configuration" - -comment "Core B Support" - -menu "Core B Support" - -config BF561_COREB - bool "Enable Core B support" - default y - -config BF561_COREB_RESET - bool "Enable Core B reset support" - default n - help - This requires code in the application that is loaded - into Core B. In order to reset, the application needs - to install an interrupt handler for Supplemental - Interrupt 0, that sets RETI to 0xff600000 and writes - bit 11 of SICB_SYSCR when bit 5 of SICA_SYSCR is 0. - This causes Core B to stall when Supplemental Interrupt - 0 is set, and will reset PC to 0xff600000 when - COREB_SRAM_INIT is cleared. - -endmenu - -comment "Interrupt Priority Assignment" - -menu "Priority" - -config IRQ_PLL_WAKEUP - int "PLL Wakeup Interrupt" - default 7 -config IRQ_DMA1_ERROR - int "DMA1 Error (generic)" - default 7 -config IRQ_DMA2_ERROR - int "DMA2 Error (generic)" - default 7 -config IRQ_IMDMA_ERROR - int "IMDMA Error (generic)" - default 7 -config IRQ_PPI0_ERROR - int "PPI0 Error Interrupt" - default 7 -config IRQ_PPI1_ERROR - int "PPI1 Error Interrupt" - default 7 -config IRQ_SPORT0_ERROR - int "SPORT0 Error Interrupt" - default 7 -config IRQ_SPORT1_ERROR - int "SPORT1 Error Interrupt" - default 7 -config IRQ_SPI_ERROR - int "SPI Error Interrupt" - default 7 -config IRQ_UART_ERROR - int "UART Error Interrupt" - default 7 -config IRQ_RESERVED_ERROR - int "Reserved Interrupt" - default 7 -config IRQ_DMA1_0 - int "DMA1 0 Interrupt(PPI1)" - default 8 -config IRQ_DMA1_1 - int "DMA1 1 Interrupt(PPI2)" - default 8 -config IRQ_DMA1_2 - int "DMA1 2 Interrupt" - default 8 -config IRQ_DMA1_3 - int "DMA1 3 Interrupt" - default 8 -config IRQ_DMA1_4 - int "DMA1 4 Interrupt" - default 8 -config IRQ_DMA1_5 - int "DMA1 5 Interrupt" - default 8 -config IRQ_DMA1_6 - int "DMA1 6 Interrupt" - default 8 -config IRQ_DMA1_7 - int "DMA1 7 Interrupt" - default 8 -config IRQ_DMA1_8 - int "DMA1 8 Interrupt" - default 8 -config IRQ_DMA1_9 - int "DMA1 9 Interrupt" - default 8 -config IRQ_DMA1_10 - int "DMA1 10 Interrupt" - default 8 -config IRQ_DMA1_11 - int "DMA1 11 Interrupt" - default 8 -config IRQ_DMA2_0 - int "DMA2 0 (SPORT0 RX)" - default 9 -config IRQ_DMA2_1 - int "DMA2 1 (SPORT0 TX)" - default 9 -config IRQ_DMA2_2 - int "DMA2 2 (SPORT1 RX)" - default 9 -config IRQ_DMA2_3 - int "DMA2 3 (SPORT2 TX)" - default 9 -config IRQ_DMA2_4 - int "DMA2 4 (SPI)" - default 9 -config IRQ_DMA2_5 - int "DMA2 5 (UART RX)" - default 9 -config IRQ_DMA2_6 - int "DMA2 6 (UART TX)" - default 9 -config IRQ_DMA2_7 - int "DMA2 7 Interrupt" - default 9 -config IRQ_DMA2_8 - int "DMA2 8 Interrupt" - default 9 -config IRQ_DMA2_9 - int "DMA2 9 Interrupt" - default 9 -config IRQ_DMA2_10 - int "DMA2 10 Interrupt" - default 9 -config IRQ_DMA2_11 - int "DMA2 11 Interrupt" - default 9 -config IRQ_TIMER0 - int "TIMER 0 Interrupt" - default 10 -config IRQ_TIMER1 - int "TIMER 1 Interrupt" - default 10 -config IRQ_TIMER2 - int "TIMER 2 Interrupt" - default 10 -config IRQ_TIMER3 - int "TIMER 3 Interrupt" - default 10 -config IRQ_TIMER4 - int "TIMER 4 Interrupt" - default 10 -config IRQ_TIMER5 - int "TIMER 5 Interrupt" - default 10 -config IRQ_TIMER6 - int "TIMER 6 Interrupt" - default 10 -config IRQ_TIMER7 - int "TIMER 7 Interrupt" - default 10 -config IRQ_TIMER8 - int "TIMER 8 Interrupt" - default 10 -config IRQ_TIMER9 - int "TIMER 9 Interrupt" - default 10 -config IRQ_TIMER10 - int "TIMER 10 Interrupt" - default 10 -config IRQ_TIMER11 - int "TIMER 11 Interrupt" - default 10 -config IRQ_PROG0_INTA - int "Programmable Flags0 A (8)" - default 11 -config IRQ_PROG0_INTB - int "Programmable Flags0 B (8)" - default 11 -config IRQ_PROG1_INTA - int "Programmable Flags1 A (8)" - default 11 -config IRQ_PROG1_INTB - int "Programmable Flags1 B (8)" - default 11 -config IRQ_PROG2_INTA - int "Programmable Flags2 A (8)" - default 11 -config IRQ_PROG2_INTB - int "Programmable Flags2 B (8)" - default 11 -config IRQ_DMA1_WRRD0 - int "MDMA1 0 write/read INT" - default 8 -config IRQ_DMA1_WRRD1 - int "MDMA1 1 write/read INT" - default 8 -config IRQ_DMA2_WRRD0 - int "MDMA2 0 write/read INT" - default 9 -config IRQ_DMA2_WRRD1 - int "MDMA2 1 write/read INT" - default 9 -config IRQ_IMDMA_WRRD0 - int "IMDMA 0 write/read INT" - default 12 -config IRQ_IMDMA_WRRD1 - int "IMDMA 1 write/read INT" - default 12 -config IRQ_WDTIMER - int "Watch Dog Timer" - default 13 - - help - Enter the priority numbers between 7-13 ONLY. Others are Reserved. - This applies to all the above. It is not recommended to assign the - highest priority number 7 to UART or any other device. - -endmenu - -endmenu - -endif diff --git a/trunk/arch/blackfin/mach-bf561/Makefile b/trunk/arch/blackfin/mach-bf561/Makefile deleted file mode 100644 index 57f475a55161..000000000000 --- a/trunk/arch/blackfin/mach-bf561/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# arch/blackfin/mach-bf561/Makefile -# - -extra-y := head.o - -obj-y := ints-priority.o - -obj-$(CONFIG_BF561_COREB) += coreb.o diff --git a/trunk/arch/blackfin/mach-bf561/boards/Makefile b/trunk/arch/blackfin/mach-bf561/boards/Makefile deleted file mode 100644 index 886edc739ab4..000000000000 --- a/trunk/arch/blackfin/mach-bf561/boards/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# arch/blackfin/mach-bf561/boards/Makefile -# - -obj-$(CONFIG_GENERIC_BOARD) += generic_board.o -obj-$(CONFIG_BFIN561_EZKIT) += ezkit.o -obj-$(CONFIG_BFIN561_BLUETECHNIX_CM) += cm_bf561.o diff --git a/trunk/arch/blackfin/mach-bf561/boards/cm_bf561.c b/trunk/arch/blackfin/mach-bf561/boards/cm_bf561.c deleted file mode 100644 index 6824e956d153..000000000000 --- a/trunk/arch/blackfin/mach-bf561/boards/cm_bf561.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * File: arch/blackfin/mach-bf533/boards/cm_bf561.c - * Based on: arch/blackfin/mach-bf533/boards/ezkit.c - * Author: Aidan Williams Copright 2005 - * - * Created: 2006 - * Description: Board description file - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "Bluetechnix CM BF561"; - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) -/* all SPI perpherals info goes here */ - -#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) -static struct mtd_partition bfin_spi_flash_partitions[] = { - { - .name = "bootloader", - .size = 0x00020000, - .offset = 0, - .mask_flags = MTD_CAP_ROM - },{ - .name = "kernel", - .size = 0xe0000, - .offset = 0x20000 - },{ - .name = "file system", - .size = 0x700000, - .offset = 0x00100000, - } -}; - -static struct flash_platform_data bfin_spi_flash_data = { - .name = "m25p80", - .parts = bfin_spi_flash_partitions, - .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions), - .type = "m25p64", -}; - -/* SPI flash chip (m25p64) */ -static struct bfin5xx_spi_chip spi_flash_chip_info = { - .enable_dma = 0, /* use dma transfer with this chip*/ - .bits_per_word = 8, -}; -#endif - -#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) -/* SPI ADC chip */ -static struct bfin5xx_spi_chip spi_adc_chip_info = { - .enable_dma = 1, /* use dma transfer with this chip*/ - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) -static struct bfin5xx_spi_chip ad9960_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif - -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) -static struct bfin5xx_spi_chip spi_mmc_chip_info = { - .enable_dma = 1, - .bits_per_word = 8, -}; -#endif - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) - { - /* the modalias must be the same as spi device driver name */ - .modalias = "m25p80", /* Name of spi_driver for this device */ - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/ - .platform_data = &bfin_spi_flash_data, - .controller_data = &spi_flash_chip_info, - .mode = SPI_MODE_3, - }, -#endif - -#if defined(CONFIG_SPI_ADC_BF533) || defined(CONFIG_SPI_ADC_BF533_MODULE) - { - .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */ - .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, /* Framework bus number */ - .chip_select = 1, /* Framework chip select. */ - .platform_data = NULL, /* No spi_driver specific config */ - .controller_data = &spi_adc_chip_info, - }, -#endif - -#if defined(CONFIG_SND_BLACKFIN_AD1836) || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif -#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE) - { - .modalias = "ad9960-spi", - .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = 1, - .controller_data = &ad9960_spi_chip_info, - }, -#endif -#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE) - { - .modalias = "spi_mmc", - .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SPI_MMC_CS_CHAN, - .platform_data = NULL, - .controller_data = &spi_mmc_chip_info, - .mode = SPI_MODE_3, - }, -#endif -}; - -/* SPI controller data */ -static struct bfin5xx_spi_master spi_bfin_master_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ -}; - -static struct platform_device spi_bfin_master_device = { - .name = "bfin-spi-master", - .id = 1, /* Bus number */ - .dev = { - .platform_data = &spi_bfin_master_info, /* Passed to driver */ - }, -}; -#endif /* spi master and devices */ - - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - -static struct resource smc91x_resources[] = { - { - .name = "smc91x-regs", - .start = 0x28000300, - .end = 0x28000300 + 16, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF0, - .end = IRQ_PF0, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) -static struct resource isp1362_hcd_resources[] = { - { - .start = 0x24008000, - .end = 0x24008000, - .flags = IORESOURCE_MEM, - },{ - .start = 0x24008004, - .end = 0x24008004, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PF47, - .end = IRQ_PF47, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct isp1362_platform_data isp1362_priv = { - .sel15Kres = 1, - .clknotstop = 0, - .oc_enable = 0, - .int_act_high = 0, - .int_edge_triggered = 0, - .remote_wakeup_connected = 0, - .no_power_switching = 1, - .power_switching_mode = 0, -}; - -static struct platform_device isp1362_hcd_device = { - .name = "isp1362-hcd", - .id = 0, - .dev = { - .platform_data = &isp1362_priv, - }, - .num_resources = ARRAY_SIZE(isp1362_hcd_resources), - .resource = isp1362_hcd_resources, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -static struct platform_device *cm_bf561_devices[] __initdata = { - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif - -#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) - &isp1362_hcd_device, -#endif - -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif - -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &spi_bfin_master_device, -#endif - -}; - -static int __init cm_bf561_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - platform_add_devices(cm_bf561_devices, ARRAY_SIZE(cm_bf561_devices)); -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); -#endif - return 0; -} - -arch_initcall(cm_bf561_init); diff --git a/trunk/arch/blackfin/mach-bf561/boards/ezkit.c b/trunk/arch/blackfin/mach-bf561/boards/ezkit.c deleted file mode 100644 index 14eb4f9a68ea..000000000000 --- a/trunk/arch/blackfin/mach-bf561/boards/ezkit.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * File: arch/blackfin/mach-bf561/ezkit.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -/* - * Name the Board for the /proc/cpuinfo - */ -char *bfin_board_name = "ADDS-BF561-EZKIT"; - -/* - * USB-LAN EzExtender board - * Driver needs to know address, irq and flag pin. - */ -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .name = "smc91x-regs", - .start = 0x2C010300, - .end = 0x2C010300 + 16, - .flags = IORESOURCE_MEM, - },{ - - .start = IRQ_PF9, - .end = IRQ_PF9, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) -static struct resource bfin_uart_resources[] = { - { - .start = 0xFFC00400, - .end = 0xFFC004FF, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device bfin_uart_device = { - .name = "bfin-uart", - .id = 1, - .num_resources = ARRAY_SIZE(bfin_uart_resources), - .resource = bfin_uart_resources, -}; -#endif - -#ifdef CONFIG_SPI_BFIN -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) -static struct bfin5xx_spi_chip ad1836_spi_chip_info = { - .enable_dma = 0, - .bits_per_word = 16, -}; -#endif -#endif - -/* SPI controller data */ -static struct bfin5xx_spi_master spi_bfin_master_info = { - .num_chipselect = 8, - .enable_dma = 1, /* master has the ability to do dma transfer */ -}; - -static struct platform_device spi_bfin_master_device = { - .name = "bfin-spi-master", - .id = 1, /* Bus number */ - .dev = { - .platform_data = &spi_bfin_master_info, /* Passed to driver */ - }, -}; - -static struct spi_board_info bfin_spi_board_info[] __initdata = { -#if defined(CONFIG_SND_BLACKFIN_AD1836) \ - || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) - { - .modalias = "ad1836-spi", - .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ - .bus_num = 1, - .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT, - .controller_data = &ad1836_spi_chip_info, - }, -#endif -}; - -static struct platform_device *ezkit_devices[] __initdata = { -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) - &spi_bfin_master_device, -#endif -#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) - &bfin_uart_device, -#endif -}; - -static int __init ezkit_init(void) -{ - int ret; - - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - ret = platform_add_devices(ezkit_devices, - ARRAY_SIZE(ezkit_devices)); - if (ret < 0) - return ret; - return spi_register_board_info(bfin_spi_board_info, - ARRAY_SIZE(bfin_spi_board_info)); -} - -arch_initcall(ezkit_init); diff --git a/trunk/arch/blackfin/mach-bf561/boards/generic_board.c b/trunk/arch/blackfin/mach-bf561/boards/generic_board.c deleted file mode 100644 index 585ecdd2f6a5..000000000000 --- a/trunk/arch/blackfin/mach-bf561/boards/generic_board.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * File: arch/blackfin/mach-bf561/generic_board.c - * Based on: arch/blackfin/mach-bf533/ezkit.c - * Author: Aidan Williams - * - * Created: - * Description: - * - * Modified: - * Copyright 2005 National ICT Australia (NICTA) - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -char *bfin_board_name = "UNKNOWN BOARD"; - -/* - * Driver needs to know address, irq and flag pin. - */ -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) -static struct resource smc91x_resources[] = { - { - .start = 0x2C010300, - .end = 0x2C010300 + 16, - .flags = IORESOURCE_MEM, - },{ - .start = IRQ_PROG_INTB, - .end = IRQ_PROG_INTB, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - },{ - /* - * denotes the flag pin and is used directly if - * CONFIG_IRQCHIP_DEMUX_GPIO is defined. - */ - .start = IRQ_PF9, - .end = IRQ_PF9, - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; -#endif - -static struct platform_device *generic_board_devices[] __initdata = { -#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE) - &smc91x_device, -#endif -}; - -static int __init generic_board_init(void) -{ - printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__); - return platform_add_devices(generic_board_devices, - ARRAY_SIZE(generic_board_devices)); -} - -arch_initcall(generic_board_init); diff --git a/trunk/arch/blackfin/mach-bf561/coreb.c b/trunk/arch/blackfin/mach-bf561/coreb.c deleted file mode 100644 index b28582fe083c..000000000000 --- a/trunk/arch/blackfin/mach-bf561/coreb.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * File: arch/blackfin/mach-bf561/coreb.c - * Based on: - * Author: - * - * Created: - * Description: Handle CoreB on a BF561 - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include - -#define MODULE_VER "v0.1" - -static spinlock_t coreb_lock; -static wait_queue_head_t coreb_dma_wait; - -#define COREB_IS_OPEN 0x00000001 -#define COREB_IS_RUNNING 0x00000010 - -#define CMD_COREB_INDEX 1 -#define CMD_COREB_START 2 -#define CMD_COREB_STOP 3 -#define CMD_COREB_RESET 4 - -#define COREB_MINOR 229 - -static unsigned long coreb_status = 0; -static unsigned long coreb_base = 0xff600000; -static unsigned long coreb_size = 0x4000; -int coreb_dma_done; - -static loff_t coreb_lseek(struct file *file, loff_t offset, int origin); -static ssize_t coreb_read(struct file *file, char *buf, size_t count, - loff_t * ppos); -static ssize_t coreb_write(struct file *file, const char *buf, size_t count, - loff_t * ppos); -static int coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long arg); -static int coreb_open(struct inode *inode, struct file *file); -static int coreb_release(struct inode *inode, struct file *file); - -static irqreturn_t coreb_dma_interrupt(int irq, void *dev_id) -{ - clear_dma_irqstat(CH_MEM_STREAM2_DEST); - coreb_dma_done = 1; - wake_up_interruptible(&coreb_dma_wait); - return IRQ_HANDLED; -} - -static ssize_t coreb_write(struct file *file, const char *buf, size_t count, - loff_t * ppos) -{ - unsigned long p = *ppos; - ssize_t wrote = 0; - - if (p + count > coreb_size) - return -EFAULT; - - while (count > 0) { - int len = count; - - if (len > PAGE_SIZE) - len = PAGE_SIZE; - - coreb_dma_done = 0; - - /* Source Channel */ - set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf); - set_dma_x_count(CH_MEM_STREAM2_SRC, len); - set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); - set_dma_config(CH_MEM_STREAM2_SRC, RESTART); - /* Destination Channel */ - set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p); - set_dma_x_count(CH_MEM_STREAM2_DEST, len); - set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char)); - set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN); - - enable_dma(CH_MEM_STREAM2_SRC); - enable_dma(CH_MEM_STREAM2_DEST); - - wait_event_interruptible(coreb_dma_wait, coreb_dma_done); - - disable_dma(CH_MEM_STREAM2_SRC); - disable_dma(CH_MEM_STREAM2_DEST); - - count -= len; - wrote += len; - buf += len; - p += len; - } - *ppos = p; - return wrote; -} - -static ssize_t coreb_read(struct file *file, char *buf, size_t count, - loff_t * ppos) -{ - unsigned long p = *ppos; - ssize_t read = 0; - - if ((p + count) > coreb_size) - return -EFAULT; - - while (count > 0) { - int len = count; - - if (len > PAGE_SIZE) - len = PAGE_SIZE; - - coreb_dma_done = 0; - - /* Source Channel */ - set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p); - set_dma_x_count(CH_MEM_STREAM2_SRC, len); - set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); - set_dma_config(CH_MEM_STREAM2_SRC, RESTART); - /* Destination Channel */ - set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf); - set_dma_x_count(CH_MEM_STREAM2_DEST, len); - set_dma_x_modify(CH_MEM_STREAM2_DEST, sizeof(char)); - set_dma_config(CH_MEM_STREAM2_DEST, WNR | RESTART | DI_EN); - - enable_dma(CH_MEM_STREAM2_SRC); - enable_dma(CH_MEM_STREAM2_DEST); - - wait_event_interruptible(coreb_dma_wait, coreb_dma_done); - - disable_dma(CH_MEM_STREAM2_SRC); - disable_dma(CH_MEM_STREAM2_DEST); - - count -= len; - read += len; - buf += len; - p += len; - } - - return read; -} - -static loff_t coreb_lseek(struct file *file, loff_t offset, int origin) -{ - loff_t ret; - - mutex_lock(&file->f_dentry->d_inode->i_mutex); - - switch (origin) { - case 0 /* SEEK_SET */ : - if (offset < coreb_size) { - file->f_pos = offset; - ret = file->f_pos; - } else - ret = -EINVAL; - break; - case 1 /* SEEK_CUR */ : - if ((offset + file->f_pos) < coreb_size) { - file->f_pos += offset; - ret = file->f_pos; - } else - ret = -EINVAL; - default: - ret = -EINVAL; - } - mutex_unlock(&file->f_dentry->d_inode->i_mutex); - return ret; -} - -static int coreb_open(struct inode *inode, struct file *file) -{ - spin_lock_irq(&coreb_lock); - - if (coreb_status & COREB_IS_OPEN) - goto out_busy; - - coreb_status |= COREB_IS_OPEN; - - spin_unlock_irq(&coreb_lock); - return 0; - - out_busy: - spin_unlock_irq(&coreb_lock); - return -EBUSY; -} - -static int coreb_release(struct inode *inode, struct file *file) -{ - spin_lock_irq(&coreb_lock); - coreb_status &= ~COREB_IS_OPEN; - spin_unlock_irq(&coreb_lock); - return 0; -} - -static int coreb_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - int retval = 0; - int coreb_index = 0; - - switch (cmd) { - case CMD_COREB_INDEX: - if (copy_from_user(&coreb_index, (int *)arg, sizeof(int))) { - retval = -EFAULT; - break; - } - - spin_lock_irq(&coreb_lock); - switch (coreb_index) { - case 0: - coreb_base = 0xff600000; - coreb_size = 0x4000; - break; - case 1: - coreb_base = 0xff610000; - coreb_size = 0x4000; - break; - case 2: - coreb_base = 0xff500000; - coreb_size = 0x8000; - break; - case 3: - coreb_base = 0xff400000; - coreb_size = 0x8000; - break; - default: - retval = -EINVAL; - break; - } - spin_unlock_irq(&coreb_lock); - - mutex_lock(&file->f_dentry->d_inode->i_mutex); - file->f_pos = 0; - mutex_unlock(&file->f_dentry->d_inode->i_mutex); - break; - case CMD_COREB_START: - spin_lock_irq(&coreb_lock); - if (coreb_status & COREB_IS_RUNNING) { - retval = -EBUSY; - break; - } - printk(KERN_INFO "Starting Core B\n"); - coreb_status |= COREB_IS_RUNNING; - bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020); - SSYNC(); - spin_lock_irq(&coreb_lock); - break; -#if defined(CONFIG_BF561_COREB_RESET) - case CMD_COREB_STOP: - spin_lock_irq(&coreb_lock); - printk(KERN_INFO "Stopping Core B\n"); - bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020); - bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); - coreb_status &= ~COREB_IS_RUNNING; - spin_lock_irq(&coreb_lock); - break; - case CMD_COREB_RESET: - printk(KERN_INFO "Resetting Core B\n"); - bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); - break; -#endif - } - - return retval; -} - -static struct file_operations coreb_fops = { - .owner = THIS_MODULE, - .llseek = coreb_lseek, - .read = coreb_read, - .write = coreb_write, - .ioctl = coreb_ioctl, - .open = coreb_open, - .release = coreb_release -}; - -static struct miscdevice coreb_dev = { - COREB_MINOR, - "coreb", - &coreb_fops -}; - -static ssize_t coreb_show_status(struct device *dev, struct device_attribute *attr, char *buf) -{ - return sprintf(buf, - "Base Address:\t0x%08lx\n" - "Core B is %s\n" - "SICA_SYSCR:\t%04x\n" - "SICB_SYSCR:\t%04x\n" - "\n" - "IRQ Status:\tCore A\t\tCore B\n" - "ISR0:\t\t%08x\t\t%08x\n" - "ISR1:\t\t%08x\t\t%08x\n" - "IMASK0:\t\t%08x\t\t%08x\n" - "IMASK1:\t\t%08x\t\t%08x\n", - coreb_base, - coreb_status & COREB_IS_RUNNING ? "running" : "stalled", - bfin_read_SICA_SYSCR(), bfin_read_SICB_SYSCR(), - bfin_read_SICA_ISR0(), bfin_read_SICB_ISR0(), - bfin_read_SICA_ISR1(), bfin_read_SICB_ISR0(), - bfin_read_SICA_IMASK0(), bfin_read_SICB_IMASK0(), - bfin_read_SICA_IMASK1(), bfin_read_SICB_IMASK1()); -} - -static DEVICE_ATTR(coreb_status, S_IRUGO, coreb_show_status, NULL); - -int __init bf561_coreb_init(void) -{ - init_waitqueue_head(&coreb_dma_wait); - - spin_lock_init(&coreb_lock); - /* Request the core memory regions for Core B */ - if (request_mem_region(0xff600000, 0x4000, - "Core B - Instruction SRAM") == NULL) - goto exit; - - if (request_mem_region(0xFF610000, 0x4000, - "Core B - Instruction SRAM") == NULL) - goto release_instruction_a_sram; - - if (request_mem_region(0xFF500000, 0x8000, - "Core B - Data Bank B SRAM") == NULL) - goto release_instruction_b_sram; - - if (request_mem_region(0xff400000, 0x8000, - "Core B - Data Bank A SRAM") == NULL) - goto release_data_b_sram; - - if (request_dma(CH_MEM_STREAM2_DEST, "Core B - DMA Destination") < 0) - goto release_data_a_sram; - - if (request_dma(CH_MEM_STREAM2_SRC, "Core B - DMA Source") < 0) - goto release_dma_dest; - - set_dma_callback(CH_MEM_STREAM2_DEST, coreb_dma_interrupt, NULL); - - misc_register(&coreb_dev); - - if (device_create_file(coreb_dev.this_device, &dev_attr_coreb_status)) - goto release_dma_src; - - printk(KERN_INFO "BF561 Core B driver %s initialized.\n", MODULE_VER); - return 0; - - release_dma_src: - free_dma(CH_MEM_STREAM2_SRC); - release_dma_dest: - free_dma(CH_MEM_STREAM2_DEST); - release_data_a_sram: - release_mem_region(0xff400000, 0x8000); - release_data_b_sram: - release_mem_region(0xff500000, 0x8000); - release_instruction_b_sram: - release_mem_region(0xff610000, 0x4000); - release_instruction_a_sram: - release_mem_region(0xff600000, 0x4000); - exit: - return -ENOMEM; -} - -void __exit bf561_coreb_exit(void) -{ - device_remove_file(coreb_dev.this_device, &dev_attr_coreb_status); - misc_deregister(&coreb_dev); - - release_mem_region(0xff610000, 0x4000); - release_mem_region(0xff600000, 0x4000); - release_mem_region(0xff500000, 0x8000); - release_mem_region(0xff400000, 0x8000); - - free_dma(CH_MEM_STREAM2_DEST); - free_dma(CH_MEM_STREAM2_SRC); -} - -module_init(bf561_coreb_init); -module_exit(bf561_coreb_exit); - -MODULE_AUTHOR("Bas Vermeulen "); -MODULE_DESCRIPTION("BF561 Core B Support"); diff --git a/trunk/arch/blackfin/mach-bf561/head.S b/trunk/arch/blackfin/mach-bf561/head.S deleted file mode 100644 index 7bca478526b9..000000000000 --- a/trunk/arch/blackfin/mach-bf561/head.S +++ /dev/null @@ -1,512 +0,0 @@ -/* - * File: arch/blackfin/mach-bf561/head.S - * Based on: arch/blackfin/mach-bf533/head.S - * Author: - * - * Created: - * Description: BF561 startup file - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#if CONFIG_BFIN_KERNEL_CLOCK -#include -#endif - -.global __rambase -.global __ramstart -.global __ramend -.extern ___bss_stop -.extern ___bss_start -.extern _bf53x_relocate_l1_mem - -#define INITIAL_STACK 0xFFB01000 - -.text - -ENTRY(__start) -ENTRY(__stext) - /* R0: argument of command line string, passed from uboot, save it */ - R7 = R0; - /* Set the SYSCFG register */ - R0 = 0x36; - SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ - R0 = 0; - - /*Clear Out All the data and pointer Registers*/ - R1 = R0; - R2 = R0; - R3 = R0; - R4 = R0; - R5 = R0; - R6 = R0; - - P0 = R0; - P1 = R0; - P2 = R0; - P3 = R0; - P4 = R0; - P5 = R0; - - LC0 = r0; - LC1 = r0; - L0 = r0; - L1 = r0; - L2 = r0; - L3 = r0; - - /* Clear Out All the DAG Registers*/ - B0 = r0; - B1 = r0; - B2 = r0; - B3 = r0; - - I0 = r0; - I1 = r0; - I2 = r0; - I3 = r0; - - M0 = r0; - M1 = r0; - M2 = r0; - M3 = r0; - - /* Turn off the icache */ - p0.l = (IMEM_CONTROL & 0xFFFF); - p0.h = (IMEM_CONTROL >> 16); - R1 = [p0]; - R0 = ~ENICPLB; - R0 = R0 & R1; - - /* Anomaly 05000125 */ -#ifdef ANOMALY_05000125 - CLI R2; - SSYNC; -#endif - [p0] = R0; - SSYNC; -#ifdef ANOMALY_05000125 - STI R2; -#endif - - /* Turn off the dcache */ - p0.l = (DMEM_CONTROL & 0xFFFF); - p0.h = (DMEM_CONTROL >> 16); - R1 = [p0]; - R0 = ~ENDCPLB; - R0 = R0 & R1; - - /* Anomaly 05000125 */ -#ifdef ANOMALY_05000125 - CLI R2; - SSYNC; -#endif - [p0] = R0; - SSYNC; -#ifdef ANOMALY_05000125 - STI R2; -#endif - - /* Initialise UART*/ - p0.h = hi(UART_LCR); - p0.l = lo(UART_LCR); - r0 = 0x0(Z); - w[p0] = r0.L; /* To enable DLL writes */ - ssync; - - p0.h = hi(UART_DLL); - p0.l = lo(UART_DLL); - r0 = 0x0(Z); - w[p0] = r0.L; - ssync; - - p0.h = hi(UART_DLH); - p0.l = lo(UART_DLH); - r0 = 0x00(Z); - w[p0] = r0.L; - ssync; - - p0.h = hi(UART_GCTL); - p0.l = lo(UART_GCTL); - r0 = 0x0(Z); - w[p0] = r0.L; /* To enable UART clock */ - ssync; - - /* Initialize stack pointer */ - sp.l = lo(INITIAL_STACK); - sp.h = hi(INITIAL_STACK); - fp = sp; - usp = sp; - - /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ - call _bf53x_relocate_l1_mem; -#if CONFIG_BFIN_KERNEL_CLOCK - call _start_dma_code; -#endif - - /* Code for initializing Async memory banks */ - - p2.h = hi(EBIU_AMBCTL1); - p2.l = lo(EBIU_AMBCTL1); - r0.h = hi(AMBCTL1VAL); - r0.l = lo(AMBCTL1VAL); - [p2] = r0; - ssync; - - p2.h = hi(EBIU_AMBCTL0); - p2.l = lo(EBIU_AMBCTL0); - r0.h = hi(AMBCTL0VAL); - r0.l = lo(AMBCTL0VAL); - [p2] = r0; - ssync; - - p2.h = hi(EBIU_AMGCTL); - p2.l = lo(EBIU_AMGCTL); - r0 = AMGCTLVAL; - w[p2] = r0; - ssync; - - /* This section keeps the processor in supervisor mode - * during kernel boot. Switches to user mode at end of boot. - * See page 3-9 of Hardware Reference manual for documentation. - */ - - /* EVT15 = _real_start */ - - p0.l = lo(EVT15); - p0.h = hi(EVT15); - p1.l = _real_start; - p1.h = _real_start; - [p0] = p1; - csync; - - p0.l = lo(IMASK); - p0.h = hi(IMASK); - p1.l = IMASK_IVG15; - p1.h = 0x0; - [p0] = p1; - csync; - - raise 15; - p0.l = .LWAIT_HERE; - p0.h = .LWAIT_HERE; - reti = p0; -#if defined(ANOMALY_05000281) - nop; nop; nop; -#endif - rti; - -.LWAIT_HERE: - jump .LWAIT_HERE; - -ENTRY(_real_start) - [ -- sp ] = reti; - p0.l = lo(WDOGA_CTL); - p0.h = hi(WDOGA_CTL); - r0 = 0xAD6(z); - w[p0] = r0; /* watchdog off for now */ - ssync; - - /* Code update for BSS size == 0 - * Zero out the bss region. - */ - - p1.l = ___bss_start; - p1.h = ___bss_start; - p2.l = ___bss_stop; - p2.h = ___bss_stop; - r0 = 0; - p2 -= p1; - lsetup (.L_clear_bss, .L_clear_bss ) lc0 = p2; -.L_clear_bss: - B[p1++] = r0; - - /* In case there is a NULL pointer reference - * Zero out region before stext - */ - - p1.l = 0x0; - p1.h = 0x0; - r0.l = __stext; - r0.h = __stext; - r0 = r0 >> 1; - p2 = r0; - r0 = 0; - lsetup (.L_clear_zero, .L_clear_zero ) lc0 = p2; -.L_clear_zero: - W[p1++] = r0; - -/* pass the uboot arguments to the global value command line */ - R0 = R7; - call _cmdline_init; - - p1.l = __rambase; - p1.h = __rambase; - r0.l = __sdata; - r0.h = __sdata; - [p1] = r0; - - p1.l = __ramstart; - p1.h = __ramstart; - p3.l = ___bss_stop; - p3.h = ___bss_stop; - - r1 = p3; - [p1] = r1; - - /* - * load the current thread pointer and stack - */ - r1.l = _init_thread_union; - r1.h = _init_thread_union; - - r2.l = 0x2000; - r2.h = 0x0000; - r1 = r1 + r2; - sp = r1; - usp = sp; - fp = sp; - call _start_kernel; -.L_exit: - jump.s .L_exit; - -.section .l1.text -#if CONFIG_BFIN_KERNEL_CLOCK -ENTRY(_start_dma_code) - p0.h = hi(SICA_IWR0); - p0.l = lo(SICA_IWR0); - r0.l = 0x1; - [p0] = r0; - SSYNC; - - /* - * Set PLL_CTL - * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors - * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK - * - [7] = output delay (add 200ps of delay to mem signals) - * - [6] = input delay (add 200ps of input delay to mem signals) - * - [5] = PDWN : 1=All Clocks off - * - [3] = STOPCK : 1=Core Clock off - * - [1] = PLL_OFF : 1=Disable Power to PLL - * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL - * all other bits set to zero - */ - - p0.h = hi(PLL_LOCKCNT); - p0.l = lo(PLL_LOCKCNT); - r0 = 0x300(Z); - w[p0] = r0.l; - ssync; - - P2.H = hi(EBIU_SDGCTL); - P2.L = lo(EBIU_SDGCTL); - R0 = [P2]; - BITSET (R0, 24); - [P2] = R0; - SSYNC; - - r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */ - r0 = r0 << 9; /* Shift it over, */ - r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/ - r0 = r1 | r0; - r1 = PLL_BYPASS; /* Bypass the PLL? */ - r1 = r1 << 8; /* Shift it over */ - r0 = r1 | r0; /* add them all together */ - - p0.h = hi(PLL_CTL); - p0.l = lo(PLL_CTL); /* Load the address */ - cli r2; /* Disable interrupts */ - ssync; - w[p0] = r0.l; /* Set the value */ - idle; /* Wait for the PLL to stablize */ - sti r2; /* Enable interrupts */ - -.Lcheck_again: - p0.h = hi(PLL_STAT); - p0.l = lo(PLL_STAT); - R0 = W[P0](Z); - CC = BITTST(R0,5); - if ! CC jump .Lcheck_again; - - /* Configure SCLK & CCLK Dividers */ - r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV); - p0.h = hi(PLL_DIV); - p0.l = lo(PLL_DIV); - w[p0] = r0.l; - ssync; - - p0.l = lo(EBIU_SDRRC); - p0.h = hi(EBIU_SDRRC); - r0 = mem_SDRRC; - w[p0] = r0.l; - ssync; - - p0.l = (EBIU_SDBCTL & 0xFFFF); - p0.h = (EBIU_SDBCTL >> 16); /* SDRAM Memory Bank Control Register */ - r0 = mem_SDBCTL; - w[p0] = r0.l; - ssync; - - P2.H = hi(EBIU_SDGCTL); - P2.L = lo(EBIU_SDGCTL); - R0 = [P2]; - BITCLR (R0, 24); - p0.h = hi(EBIU_SDSTAT); - p0.l = lo(EBIU_SDSTAT); - r2.l = w[p0]; - cc = bittst(r2,3); - if !cc jump .Lskip; - NOP; - BITSET (R0, 23); -.Lskip: - [P2] = R0; - SSYNC; - - R0.L = lo(mem_SDGCTL); - R0.H = hi(mem_SDGCTL); - R1 = [p2]; - R1 = R1 | R0; - [P2] = R1; - SSYNC; - - RTS; -#endif /* CONFIG_BFIN_KERNEL_CLOCK */ - -ENTRY(_bfin_reset) - /* No more interrupts to be handled*/ - CLI R6; - SSYNC; - -#if defined(CONFIG_BFIN_SHARED_FLASH_ENET) - p0.h = hi(FIO_INEN); - p0.l = lo(FIO_INEN); - r0.l = ~(PF1 | PF0); - w[p0] = r0.l; - - p0.h = hi(FIO_DIR); - p0.l = lo(FIO_DIR); - r0.l = (PF1 | PF0); - w[p0] = r0.l; - - p0.h = hi(FIO_FLAG_C); - p0.l = lo(FIO_FLAG_C); - r0.l = (PF1 | PF0); - w[p0] = r0.l; -#endif - - /* Clear the bits 13-15 in SWRST if they werent cleared */ - p0.h = hi(SICA_SWRST); - p0.l = lo(SICA_SWRST); - csync; - r0.l = w[p0]; - - /* Clear the IMASK register */ - p0.h = hi(IMASK); - p0.l = lo(IMASK); - r0 = 0x0; - [p0] = r0; - - /* Clear the ILAT register */ - p0.h = hi(ILAT); - p0.l = lo(ILAT); - r0 = [p0]; - [p0] = r0; - SSYNC; - - /* Disable the WDOG TIMER */ - p0.h = hi(WDOGA_CTL); - p0.l = lo(WDOGA_CTL); - r0.l = 0xAD6; - w[p0] = r0.l; - SSYNC; - - /* Clear the sticky bit incase it is already set */ - p0.h = hi(WDOGA_CTL); - p0.l = lo(WDOGA_CTL); - r0.l = 0x8AD6; - w[p0] = r0.l; - SSYNC; - - /* Program the count value */ - R0.l = 0x100; - R0.h = 0x0; - P0.h = hi(WDOGA_CNT); - P0.l = lo(WDOGA_CNT); - [P0] = R0; - SSYNC; - - /* Program WDOG_STAT if necessary */ - P0.h = hi(WDOGA_CTL); - P0.l = lo(WDOGA_CTL); - R0 = W[P0](Z); - CC = BITTST(R0,1); - if !CC JUMP .LWRITESTAT; - CC = BITTST(R0,2); - if !CC JUMP .LWRITESTAT; - JUMP .LSKIP_WRITE; - -.LWRITESTAT: - /* When watch dog timer is enabled, - * a write to STAT will load the contents of CNT to STAT - */ - R0 = 0x0000(z); - P0.h = hi(WDOGA_STAT); - P0.l = lo(WDOGA_STAT) - [P0] = R0; - SSYNC; - -.LSKIP_WRITE: - /* Enable the reset event */ - P0.h = hi(WDOGA_CTL); - P0.l = lo(WDOGA_CTL); - R0 = W[P0](Z); - BITCLR(R0,1); - BITCLR(R0,2); - W[P0] = R0.L; - SSYNC; - NOP; - - /* Enable the wdog counter */ - R0 = W[P0](Z); - BITCLR(R0,4); - W[P0] = R0.L; - SSYNC; - - IDLE; - - RTS; - -.data - -/* - * Set up the usable of RAM stuff. Size of RAM is determined then - * an initial stack set up at the end. - */ - -.align 4 -__rambase: -.long 0 -__ramstart: -.long 0 -__ramend: -.long 0 diff --git a/trunk/arch/blackfin/mach-bf561/ints-priority.c b/trunk/arch/blackfin/mach-bf561/ints-priority.c deleted file mode 100644 index 89c52ff95b27..000000000000 --- a/trunk/arch/blackfin/mach-bf561/ints-priority.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * File: arch/blackfin/mach-bf561/ints-priority.c - * Based on: arch/blackfin/mach-bf537/ints-priority.c - * Author: Michael Hennerich - * - * Created: - * Description: Set up the interupt priorities - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -void program_IAR(void) -{ - /* Program the IAR0 Register with the configured priority */ - bfin_write_SICA_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) | - ((CONFIG_IRQ_DMA1_ERROR - 7) << IRQ_DMA1_ERROR_POS) | - ((CONFIG_IRQ_DMA2_ERROR - 7) << IRQ_DMA2_ERROR_POS) | - ((CONFIG_IRQ_IMDMA_ERROR - 7) << IRQ_IMDMA_ERROR_POS) | - ((CONFIG_IRQ_PPI0_ERROR - 7) << IRQ_PPI0_ERROR_POS) | - ((CONFIG_IRQ_PPI1_ERROR - 7) << IRQ_PPI1_ERROR_POS) | - ((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) | - ((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS)); - - bfin_write_SICA_IAR1(((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS) | - ((CONFIG_IRQ_UART_ERROR - 7) << IRQ_UART_ERROR_POS) | - ((CONFIG_IRQ_RESERVED_ERROR - 7) << IRQ_RESERVED_ERROR_POS) | - ((CONFIG_IRQ_DMA1_0 - 7) << IRQ_DMA1_0_POS) | - ((CONFIG_IRQ_DMA1_1 - 7) << IRQ_DMA1_1_POS) | - ((CONFIG_IRQ_DMA1_2 - 7) << IRQ_DMA1_2_POS) | - ((CONFIG_IRQ_DMA1_3 - 7) << IRQ_DMA1_3_POS) | - ((CONFIG_IRQ_DMA1_4 - 7) << IRQ_DMA1_4_POS)); - - bfin_write_SICA_IAR2(((CONFIG_IRQ_DMA1_5 - 7) << IRQ_DMA1_5_POS) | - ((CONFIG_IRQ_DMA1_6 - 7) << IRQ_DMA1_6_POS) | - ((CONFIG_IRQ_DMA1_7 - 7) << IRQ_DMA1_7_POS) | - ((CONFIG_IRQ_DMA1_8 - 7) << IRQ_DMA1_8_POS) | - ((CONFIG_IRQ_DMA1_9 - 7) << IRQ_DMA1_9_POS) | - ((CONFIG_IRQ_DMA1_10 - 7) << IRQ_DMA1_10_POS) | - ((CONFIG_IRQ_DMA1_11 - 7) << IRQ_DMA1_11_POS) | - ((CONFIG_IRQ_DMA2_0 - 7) << IRQ_DMA2_0_POS)); - - bfin_write_SICA_IAR3(((CONFIG_IRQ_DMA2_1 - 7) << IRQ_DMA2_1_POS) | - ((CONFIG_IRQ_DMA2_2 - 7) << IRQ_DMA2_2_POS) | - ((CONFIG_IRQ_DMA2_3 - 7) << IRQ_DMA2_3_POS) | - ((CONFIG_IRQ_DMA2_4 - 7) << IRQ_DMA2_4_POS) | - ((CONFIG_IRQ_DMA2_5 - 7) << IRQ_DMA2_5_POS) | - ((CONFIG_IRQ_DMA2_6 - 7) << IRQ_DMA2_6_POS) | - ((CONFIG_IRQ_DMA2_7 - 7) << IRQ_DMA2_7_POS) | - ((CONFIG_IRQ_DMA2_8 - 7) << IRQ_DMA2_8_POS)); - - bfin_write_SICA_IAR4(((CONFIG_IRQ_DMA2_9 - 7) << IRQ_DMA2_9_POS) | - ((CONFIG_IRQ_DMA2_10 - 7) << IRQ_DMA2_10_POS) | - ((CONFIG_IRQ_DMA2_11 - 7) << IRQ_DMA2_11_POS) | - ((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) | - ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) | - ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) | - ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) | - ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS)); - - bfin_write_SICA_IAR5(((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) | - ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) | - ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) | - ((CONFIG_IRQ_TIMER8 - 7) << IRQ_TIMER8_POS) | - ((CONFIG_IRQ_TIMER9 - 7) << IRQ_TIMER9_POS) | - ((CONFIG_IRQ_TIMER10 - 7) << IRQ_TIMER10_POS) | - ((CONFIG_IRQ_TIMER11 - 7) << IRQ_TIMER11_POS) | - ((CONFIG_IRQ_PROG0_INTA - 7) << IRQ_PROG0_INTA_POS)); - - bfin_write_SICA_IAR6(((CONFIG_IRQ_PROG0_INTB - 7) << IRQ_PROG0_INTB_POS) | - ((CONFIG_IRQ_PROG1_INTA - 7) << IRQ_PROG1_INTA_POS) | - ((CONFIG_IRQ_PROG1_INTB - 7) << IRQ_PROG1_INTB_POS) | - ((CONFIG_IRQ_PROG2_INTA - 7) << IRQ_PROG2_INTA_POS) | - ((CONFIG_IRQ_PROG2_INTB - 7) << IRQ_PROG2_INTB_POS) | - ((CONFIG_IRQ_DMA1_WRRD0 - 7) << IRQ_DMA1_WRRD0_POS) | - ((CONFIG_IRQ_DMA1_WRRD1 - 7) << IRQ_DMA1_WRRD1_POS) | - ((CONFIG_IRQ_DMA2_WRRD0 - 7) << IRQ_DMA2_WRRD0_POS)); - - bfin_write_SICA_IAR7(((CONFIG_IRQ_DMA2_WRRD1 - 7) << IRQ_DMA2_WRRD1_POS) | - ((CONFIG_IRQ_IMDMA_WRRD0 - 7) << IRQ_IMDMA_WRRD0_POS) | - ((CONFIG_IRQ_IMDMA_WRRD1 - 7) << IRQ_IMDMA_WRRD1_POS) | - ((CONFIG_IRQ_WDTIMER - 7) << IRQ_WDTIMER_POS) | - (0 << IRQ_RESERVED_1_POS) | (0 << IRQ_RESERVED_2_POS) | - (0 << IRQ_SUPPLE_0_POS) | (0 << IRQ_SUPPLE_1_POS)); - - SSYNC(); -} diff --git a/trunk/arch/blackfin/mach-common/Makefile b/trunk/arch/blackfin/mach-common/Makefile deleted file mode 100644 index d3a49073d196..000000000000 --- a/trunk/arch/blackfin/mach-common/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# arch/blackfin/mach-common/Makefile -# - -obj-y := \ - cache.o cacheinit.o cplbhdlr.o cplbmgr.o entry.o \ - interrupt.o lock.o dpmc.o irqpanic.o - -obj-$(CONFIG_CPLB_INFO) += cplbinfo.o -obj-$(CONFIG_BFIN_SINGLE_CORE) += ints-priority-sc.o -obj-$(CONFIG_BFIN_DUAL_CORE) += ints-priority-dc.o -obj-$(CONFIG_PM) += pm.o diff --git a/trunk/arch/blackfin/mach-common/cache.S b/trunk/arch/blackfin/mach-common/cache.S deleted file mode 100644 index bb9446ef66ef..000000000000 --- a/trunk/arch/blackfin/mach-common/cache.S +++ /dev/null @@ -1,253 +0,0 @@ -/* - * File: arch/blackfin/mach-common/cache.S - * Based on: - * Author: LG Soft India - * - * Created: - * Description: cache control support - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -.text -.align 2 -ENTRY(_cache_invalidate) - - /* - * Icache or DcacheA or DcacheB Invalidation - * or any combination thereof - * R0 has bits - * CPLB_ENABLE_ICACHE_P,CPLB_ENABLE_DCACHE_P,CPLB_ENABLE_DCACHE2_P - * set as required - */ - [--SP] = R7; - - R7 = R0; - CC = BITTST(R7,CPLB_ENABLE_ICACHE_P); - IF !CC JUMP .Lno_icache; - [--SP] = RETS; - CALL _icache_invalidate; - RETS = [SP++]; -.Lno_icache: - CC = BITTST(R7,CPLB_ENABLE_DCACHE_P); - IF !CC JUMP .Lno_dcache_a; - R0 = 0; /* specifies bank A */ - [--SP] = RETS; - CALL _dcache_invalidate; - RETS = [SP++]; -.Lno_dcache_a: - CC = BITTST(R7,CPLB_ENABLE_DCACHE2_P); - IF !CC JUMP .Lno_dcache_b; - R0 = 0; - BITSET(R0, 23); /* specifies bank B */ - [--SP] = RETS; - CALL _dcache_invalidate; - RETS = [SP++]; -.Lno_dcache_b: - R7 = [SP++]; - RTS; - -/* Invalidate the Entire Instruction cache by - * disabling IMC bit - */ -ENTRY(_icache_invalidate) -ENTRY(_invalidate_entire_icache) - [--SP] = ( R7:5); - - P0.L = (IMEM_CONTROL & 0xFFFF); - P0.H = (IMEM_CONTROL >> 16); - R7 = [P0]; - - /* Clear the IMC bit , All valid bits in the instruction - * cache are set to the invalid state - */ - BITCLR(R7,IMC_P); - CLI R6; - SSYNC; /* SSYNC required before invalidating cache. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - /* Configures the instruction cache agian */ - R6 = (IMC | ENICPLB); - R7 = R7 | R6; - - CLI R6; - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - ( R7:5) = [SP++]; - RTS; - -/* - * blackfin_cache_flush_range(start, end) - * Invalidate all cache lines assocoiated with this - * area of memory. - * - * start: Start address - * end: End address - */ -ENTRY(_blackfin_icache_flush_range) - R2 = -L1_CACHE_BYTES; - R2 = R0 & R2; - P0 = R2; - P1 = R1; - CSYNC; - IFLUSH [P0]; -1: - IFLUSH [P0++]; - CC = P0 < P1 (iu); - IF CC JUMP 1b (bp); - IFLUSH [P0]; - SSYNC; - RTS; - -/* - * blackfin_icache_dcache_flush_range(start, end) - * FLUSH all cache lines assocoiated with this - * area of memory. - * - * start: Start address - * end: End address - */ - -ENTRY(_blackfin_icache_dcache_flush_range) - R2 = -L1_CACHE_BYTES; - R2 = R0 & R2; - P0 = R2; - P1 = R1; - CSYNC; - IFLUSH [P0]; -1: - FLUSH [P0]; - IFLUSH [P0++]; - CC = P0 < P1 (iu); - IF CC JUMP 1b (bp); - IFLUSH [P0]; - FLUSH [P0]; - SSYNC; - RTS; - -/* Throw away all D-cached data in specified region without any obligation to - * write them back. However, we must clean the D-cached entries around the - * boundaries of the start and/or end address is not cache aligned. - * - * Start: start address, - * end : end address. - */ - -ENTRY(_blackfin_dcache_invalidate_range) - R2 = -L1_CACHE_BYTES; - R2 = R0 & R2; - P0 = R2; - P1 = R1; - CSYNC; - FLUSHINV[P0]; -1: - FLUSHINV[P0++]; - CC = P0 < P1 (iu); - IF CC JUMP 1b (bp); - - /* If the data crosses a cache line, then we'll be pointing to - * the last cache line, but won't have flushed/invalidated it yet, - * so do one more. - */ - FLUSHINV[P0]; - SSYNC; - RTS; - -/* Invalidate the Entire Data cache by - * clearing DMC[1:0] bits - */ -ENTRY(_invalidate_entire_dcache) -ENTRY(_dcache_invalidate) - [--SP] = ( R7:6); - - P0.L = (DMEM_CONTROL & 0xFFFF); - P0.H = (DMEM_CONTROL >> 16); - R7 = [P0]; - - /* Clear the DMC[1:0] bits, All valid bits in the data - * cache are set to the invalid state - */ - BITCLR(R7,DMC0_P); - BITCLR(R7,DMC1_P); - CLI R6; - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - /* Configures the data cache again */ - - R6 = DMEM_CNTR; - R7 = R7 | R6; - - CLI R6; - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; - [P0] = R7; - SSYNC; - STI R6; - - ( R7:6) = [SP++]; - RTS; - -ENTRY(_blackfin_dcache_flush_range) - R2 = -L1_CACHE_BYTES; - R2 = R0 & R2; - P0 = R2; - P1 = R1; - CSYNC; - FLUSH[P0]; -1: - FLUSH[P0++]; - CC = P0 < P1 (iu); - IF CC JUMP 1b (bp); - - /* If the data crosses a cache line, then we'll be pointing to - * the last cache line, but won't have flushed it yet, so do - * one more. - */ - FLUSH[P0]; - SSYNC; - RTS; - -ENTRY(_blackfin_dflush_page) - P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT); - P0 = R0; - CSYNC; - FLUSH[P0]; - LSETUP (.Lfl1, .Lfl1) LC0 = P1; -.Lfl1: FLUSH [P0++]; - SSYNC; - RTS; diff --git a/trunk/arch/blackfin/mach-common/cacheinit.S b/trunk/arch/blackfin/mach-common/cacheinit.S deleted file mode 100644 index 8c17f099e5eb..000000000000 --- a/trunk/arch/blackfin/mach-common/cacheinit.S +++ /dev/null @@ -1,137 +0,0 @@ -/* - * File: arch/blackfin/mach-common/cacheinit.S - * Based on: - * Author: LG Soft India - * - * Created: ? - * Description: cache initialization - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* This function sets up the data and instruction cache. The - * tables like icplb table, dcplb table and Page Descriptor table - * are defined in cplbtab.h. You can configure those tables for - * your suitable requirements - */ - -#include -#include - -.text - -#if defined(CONFIG_BLKFIN_CACHE) -ENTRY(_bfin_icache_init) - - /* Initialize Instruction CPLBS */ - - I0.L = (ICPLB_ADDR0 & 0xFFFF); - I0.H = (ICPLB_ADDR0 >> 16); - - I1.L = (ICPLB_DATA0 & 0xFFFF); - I1.H = (ICPLB_DATA0 >> 16); - - I2.L = _icplb_table; - I2.H = _icplb_table; - - r1 = -1; /* end point comparison */ - r3 = 15; /* max counter */ - -/* read entries from table */ - -.Lread_iaddr: - R0 = [I2++]; - CC = R0 == R1; - IF CC JUMP .Lidone; - [I0++] = R0; - -.Lread_idata: - R2 = [I2++]; - [I1++] = R2; - R3 = R3 + R1; - CC = R3 == R1; - IF !CC JUMP .Lread_iaddr; - -.Lidone: - /* Enable Instruction Cache */ - P0.l = (IMEM_CONTROL & 0xFFFF); - P0.h = (IMEM_CONTROL >> 16); - R1 = [P0]; - R0 = (IMC | ENICPLB); - R0 = R0 | R1; - - /* Anomaly 05000125 */ - CLI R2; - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; - [P0] = R0; - SSYNC; - STI R2; - RTS; -#endif - -#if defined(CONFIG_BLKFIN_DCACHE) -ENTRY(_bfin_dcache_init) - - /* Initialize Data CPLBS */ - - I0.L = (DCPLB_ADDR0 & 0xFFFF); - I0.H = (DCPLB_ADDR0 >> 16); - - I1.L = (DCPLB_DATA0 & 0xFFFF); - I1.H = (DCPLB_DATA0 >> 16); - - I2.L = _dcplb_table; - I2.H = _dcplb_table; - - R1 = -1; /* end point comparison */ - R3 = 15; /* max counter */ - - /* read entries from table */ -.Lread_daddr: - R0 = [I2++]; - cc = R0 == R1; - IF CC JUMP .Lddone; - [I0++] = R0; - -.Lread_ddata: - R2 = [I2++]; - [I1++] = R2; - R3 = R3 + R1; - CC = R3 == R1; - IF !CC JUMP .Lread_daddr; -.Lddone: - P0.L = (DMEM_CONTROL & 0xFFFF); - P0.H = (DMEM_CONTROL >> 16); - R1 = [P0]; - - R0 = DMEM_CNTR; - - R0 = R0 | R1; - /* Anomaly 05000125 */ - CLI R2; - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; - [P0] = R0; - SSYNC; - STI R2; - RTS; -#endif diff --git a/trunk/arch/blackfin/mach-common/cplbhdlr.S b/trunk/arch/blackfin/mach-common/cplbhdlr.S deleted file mode 100644 index b979067c49ef..000000000000 --- a/trunk/arch/blackfin/mach-common/cplbhdlr.S +++ /dev/null @@ -1,130 +0,0 @@ -/* - * File: arch/blackfin/mach-common/cplbhdlr.S - * Based on: - * Author: LG Soft India - * - * Created: ? - * Description: CPLB exception handler - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 -.section .l1.text -#else -.text -#endif - -.type _cplb_mgr, STT_FUNC; -.type _panic_cplb_error, STT_FUNC; - -.align 2 - -.global __cplb_hdr; -.type __cplb_hdr, STT_FUNC; -ENTRY(__cplb_hdr) - R2 = SEQSTAT; - - /* Mask the contents of SEQSTAT and leave only EXCAUSE in R2 */ - R2 <<= 26; - R2 >>= 26; - - R1 = 0x23; /* Data access CPLB protection violation */ - CC = R2 == R1; - IF !CC JUMP .Lnot_data_write; - R0 = 2; /* is a write to data space*/ - JUMP .Lis_icplb_miss; - -.Lnot_data_write: - R1 = 0x2C; /* CPLB miss on an instruction fetch */ - CC = R2 == R1; - R0 = 0; /* is_data_miss == False*/ - IF CC JUMP .Lis_icplb_miss; - - R1 = 0x26; - CC = R2 == R1; - IF !CC JUMP .Lunknown; - - R0 = 1; /* is_data_miss == True*/ - -.Lis_icplb_miss: - -#if defined(CONFIG_BLKFIN_CACHE) || defined(CONFIG_BLKFIN_DCACHE) -# if defined(CONFIG_BLKFIN_CACHE) && !defined(CONFIG_BLKFIN_DCACHE) - R1 = CPLB_ENABLE_ICACHE; -# endif -# if !defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE) - R1 = CPLB_ENABLE_DCACHE; -# endif -# if defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE) - R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE; -# endif -#else - R1 = 0; -#endif - - [--SP] = RETS; - CALL _cplb_mgr; - RETS = [SP++]; - CC = R0 == 0; - IF !CC JUMP .Lnot_replaced; - RTS; - -/* - * Diagnostic exception handlers - */ -.Lunknown: - R0 = CPLB_UNKNOWN_ERR; - JUMP .Lcplb_error; - -.Lnot_replaced: - CC = R0 == CPLB_NO_UNLOCKED; - IF !CC JUMP .Lnext_check; - R0 = CPLB_NO_UNLOCKED; - JUMP .Lcplb_error; - -.Lnext_check: - CC = R0 == CPLB_NO_ADDR_MATCH; - IF !CC JUMP .Lnext_check2; - R0 = CPLB_NO_ADDR_MATCH; - JUMP .Lcplb_error; - -.Lnext_check2: - CC = R0 == CPLB_PROT_VIOL; - IF !CC JUMP .Lstrange_return_from_cplb_mgr; - R0 = CPLB_PROT_VIOL; - JUMP .Lcplb_error; - -.Lstrange_return_from_cplb_mgr: - IDLE; - CSYNC; - JUMP .Lstrange_return_from_cplb_mgr; - -.Lcplb_error: - R1 = sp; - SP += -12; - call _panic_cplb_error; - SP += 12; - JUMP _handle_bad_cplb; diff --git a/trunk/arch/blackfin/mach-common/cplbinfo.c b/trunk/arch/blackfin/mach-common/cplbinfo.c deleted file mode 100644 index d65fac39d1bf..000000000000 --- a/trunk/arch/blackfin/mach-common/cplbinfo.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * File: arch/blackfin/mach-common/cplbinfo.c - * Based on: - * Author: Sonic Zhang - * - * Created: Jan. 2005 - * Description: Display CPLB status - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#define CPLB_I 1 -#define CPLB_D 2 - -#define SYNC_SYS SSYNC() -#define SYNC_CORE CSYNC() - -#define CPLB_BIT_PAGESIZE 0x30000 - -static int page_size_table[4] = { - 0x00000400, /* 1K */ - 0x00001000, /* 4K */ - 0x00100000, /* 1M */ - 0x00400000 /* 4M */ -}; - -static char page_size_string_table[][4] = { "1K", "4K", "1M", "4M" }; - -static int cplb_find_entry(unsigned long *cplb_addr, - unsigned long *cplb_data, unsigned long addr, - unsigned long data) -{ - int ii; - - for (ii = 0; ii < 16; ii++) - if (addr >= cplb_addr[ii] && addr < cplb_addr[ii] + - page_size_table[(cplb_data[ii] & CPLB_BIT_PAGESIZE) >> 16] - && (cplb_data[ii] == data)) - return ii; - - return -1; -} - -static char *cplb_print_entry(char *buf, int type) -{ - unsigned long *p_addr = dpdt_table; - unsigned long *p_data = dpdt_table + 1; - unsigned long *p_icount = dpdt_swapcount_table; - unsigned long *p_ocount = dpdt_swapcount_table + 1; - unsigned long *cplb_addr = (unsigned long *)DCPLB_ADDR0; - unsigned long *cplb_data = (unsigned long *)DCPLB_DATA0; - int entry = 0, used_cplb = 0; - - if (type == CPLB_I) { - buf += sprintf(buf, "Instrction CPLB entry:\n"); - p_addr = ipdt_table; - p_data = ipdt_table + 1; - p_icount = ipdt_swapcount_table; - p_ocount = ipdt_swapcount_table + 1; - cplb_addr = (unsigned long *)ICPLB_ADDR0; - cplb_data = (unsigned long *)ICPLB_DATA0; - } else - buf += sprintf(buf, "Data CPLB entry:\n"); - - buf += sprintf(buf, "Address\t\tData\tSize\tValid\tLocked\tSwapin\ -\tiCount\toCount\n"); - - while (*p_addr != 0xffffffff) { - entry = cplb_find_entry(cplb_addr, cplb_data, *p_addr, *p_data); - if (entry >= 0) - used_cplb |= 1 << entry; - - buf += - sprintf(buf, - "0x%08lx\t0x%05lx\t%s\t%c\t%c\t%2d\t%ld\t%ld\n", - *p_addr, *p_data, - page_size_string_table[(*p_data & 0x30000) >> 16], - (*p_data & CPLB_VALID) ? 'Y' : 'N', - (*p_data & CPLB_LOCK) ? 'Y' : 'N', entry, *p_icount, - *p_ocount); - - p_addr += 2; - p_data += 2; - p_icount += 2; - p_ocount += 2; - } - - if (used_cplb != 0xffff) { - buf += sprintf(buf, "Unused/mismatched CPLBs:\n"); - - for (entry = 0; entry < 16; entry++) - if (0 == ((1 << entry) & used_cplb)) { - int flags = cplb_data[entry]; - buf += - sprintf(buf, - "%2d: 0x%08lx\t0x%05x\t%s\t%c\t%c\n", - entry, cplb_addr[entry], flags, - page_size_string_table[(flags & - 0x30000) >> - 16], - (flags & CPLB_VALID) ? 'Y' : 'N', - (flags & CPLB_LOCK) ? 'Y' : 'N'); - } - } - - buf += sprintf(buf, "\n"); - - return buf; -} - -static int cplbinfo_proc_output(char *buf) -{ - char *p; - - p = buf; - - p += sprintf(p, - "------------------ CPLB Information ------------------\n\n"); - - if (bfin_read_IMEM_CONTROL() & ENICPLB) - p = cplb_print_entry(p, CPLB_I); - else - p += sprintf(p, "Instruction CPLB is disabled.\n\n"); - - if (bfin_read_DMEM_CONTROL() & ENDCPLB) - p = cplb_print_entry(p, CPLB_D); - else - p += sprintf(p, "Data CPLB is disabled.\n"); - - return p - buf; -} - -static int cplbinfo_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len; - - len = cplbinfo_proc_output(page); - if (len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; -} - -static int cplbinfo_write_proc(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - printk(KERN_INFO "Reset the CPLB swap in/out counts.\n"); - memset(ipdt_swapcount_table, 0, MAX_SWITCH_I_CPLBS * sizeof(unsigned long)); - memset(dpdt_swapcount_table, 0, MAX_SWITCH_D_CPLBS * sizeof(unsigned long)); - - return count; -} - -static int __init cplbinfo_init(void) -{ - struct proc_dir_entry *entry; - - if ((entry = create_proc_entry("cplbinfo", 0, NULL)) == NULL) { - return -ENOMEM; - } - - entry->read_proc = cplbinfo_read_proc; - entry->write_proc = cplbinfo_write_proc; - entry->data = NULL; - - return 0; -} - -static void __exit cplbinfo_exit(void) -{ - remove_proc_entry("cplbinfo", NULL); -} - -module_init(cplbinfo_init); -module_exit(cplbinfo_exit); diff --git a/trunk/arch/blackfin/mach-common/cplbmgr.S b/trunk/arch/blackfin/mach-common/cplbmgr.S deleted file mode 100644 index f5efc4bc65e6..000000000000 --- a/trunk/arch/blackfin/mach-common/cplbmgr.S +++ /dev/null @@ -1,607 +0,0 @@ -/* - * File: arch/blackfin/mach-common/cplbmgtr.S - * Based on: - * Author: LG Soft India - * - * Created: ? - * Description: CPLB replacement routine for CPLB mismatch - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* Usage: int _cplb_mgr(is_data_miss,int enable_cache) - * is_data_miss==2 => Mark as Dirty, write to the clean data page - * is_data_miss==1 => Replace a data CPLB. - * is_data_miss==0 => Replace an instruction CPLB. - * - * Returns: - * CPLB_RELOADED => Successfully updated CPLB table. - * CPLB_NO_UNLOCKED => All CPLBs are locked, so cannot be evicted. - * This indicates that the CPLBs in the configuration - * tablei are badly configured, as this should never - * occur. - * CPLB_NO_ADDR_MATCH => The address being accessed, that triggered the - * exception, is not covered by any of the CPLBs in - * the configuration table. The application is - * presumably misbehaving. - * CPLB_PROT_VIOL => The address being accessed, that triggered the - * exception, was not a first-write to a clean Write - * Back Data page, and so presumably is a genuine - * violation of the page's protection attributes. - * The application is misbehaving. - */ - -#include -#include -#include - -#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 -.section .l1.text -#else -.text -#endif - -.align 2; -ENTRY(_cplb_mgr) - - [--SP]=( R7:4,P5:3 ); - - CC = R0 == 2; - IF CC JUMP .Ldcplb_write; - - CC = R0 == 0; - IF !CC JUMP .Ldcplb_miss_compare; - - /* ICPLB Miss Exception. We need to choose one of the - * currently-installed CPLBs, and replace it with one - * from the configuration table. - */ - - P4.L = (ICPLB_FAULT_ADDR & 0xFFFF); - P4.H = (ICPLB_FAULT_ADDR >> 16); - - P1 = 16; - P5.L = _page_size_table; - P5.H = _page_size_table; - - P0.L = (ICPLB_DATA0 & 0xFFFF); - P0.H = (ICPLB_DATA0 >> 16); - R4 = [P4]; /* Get faulting address*/ - R6 = 64; /* Advance past the fault address, which*/ - R6 = R6 + R4; /* we'll use if we find a match*/ - R3 = ((16 << 8) | 2); /* Extract mask, bits 16 and 17.*/ - - R5 = 0; -.Lisearch: - - R1 = [P0-0x100]; /* Address for this CPLB */ - - R0 = [P0++]; /* Info for this CPLB*/ - CC = BITTST(R0,0); /* Is the CPLB valid?*/ - IF !CC JUMP .Lnomatch; /* Skip it, if not.*/ - CC = R4 < R1(IU); /* If fault address less than page start*/ - IF CC JUMP .Lnomatch; /* then skip this one.*/ - R2 = EXTRACT(R0,R3.L) (Z); /* Get page size*/ - P1 = R2; - P1 = P5 + (P1<<2); /* index into page-size table*/ - R2 = [P1]; /* Get the page size*/ - R1 = R1 + R2; /* and add to page start, to get page end*/ - CC = R4 < R1(IU); /* and see whether fault addr is in page.*/ - IF !CC R4 = R6; /* If so, advance the address and finish loop.*/ - IF !CC JUMP .Lisearch_done; -.Lnomatch: - /* Go around again*/ - R5 += 1; - CC = BITTST(R5, 4); /* i.e CC = R5 >= 16*/ - IF !CC JUMP .Lisearch; - -.Lisearch_done: - I0 = R4; /* Fault address we'll search for*/ - - /* set up pointers */ - P0.L = (ICPLB_DATA0 & 0xFFFF); - P0.H = (ICPLB_DATA0 >> 16); - - /* The replacement procedure for ICPLBs */ - - P4.L = (IMEM_CONTROL & 0xFFFF); - P4.H = (IMEM_CONTROL >> 16); - - /* disable cplbs */ - R5 = [P4]; /* Control Register*/ - BITCLR(R5,ENICPLB_P); - CLI R1; - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; - [P4] = R5; - SSYNC; - STI R1; - - R1 = -1; /* end point comparison */ - R3 = 16; /* counter */ - - /* Search through CPLBs for first non-locked entry */ - /* Overwrite it by moving everyone else up by 1 */ -.Licheck_lock: - R0 = [P0++]; - R3 = R3 + R1; - CC = R3 == R1; - IF CC JUMP .Lall_locked; - CC = BITTST(R0, 0); /* an invalid entry is good */ - IF !CC JUMP .Lifound_victim; - CC = BITTST(R0,1); /* but a locked entry isn't */ - IF CC JUMP .Licheck_lock; - -.Lifound_victim: -#ifdef CONFIG_CPLB_INFO - R7 = [P0 - 0x104]; - P2.L = _ipdt_table; - P2.H = _ipdt_table; - P3.L = _ipdt_swapcount_table; - P3.H = _ipdt_swapcount_table; - P3 += -4; -.Licount: - R2 = [P2]; /* address from config table */ - P2 += 8; - P3 += 8; - CC = R2==-1; - IF CC JUMP .Licount_done; - CC = R7==R2; - IF !CC JUMP .Licount; - R7 = [P3]; - R7 += 1; - [P3] = R7; - CSYNC; -.Licount_done: -#endif - LC0=R3; - LSETUP(.Lis_move,.Lie_move) LC0; -.Lis_move: - R0 = [P0]; - [P0 - 4] = R0; - R0 = [P0 - 0x100]; - [P0-0x104] = R0; -.Lie_move:P0+=4; - - /* We've made space in the ICPLB table, so that ICPLB15 - * is now free to be overwritten. Next, we have to determine - * which CPLB we need to install, from the configuration - * table. This is a matter of getting the start-of-page - * addresses and page-lengths from the config table, and - * determining whether the fault address falls within that - * range. - */ - - P2.L = _ipdt_table; - P2.H = _ipdt_table; -#ifdef CONFIG_CPLB_INFO - P3.L = _ipdt_swapcount_table; - P3.H = _ipdt_swapcount_table; - P3 += -8; -#endif - P0.L = _page_size_table; - P0.H = _page_size_table; - - /* Retrieve our fault address (which may have been advanced - * because the faulting instruction crossed a page boundary). - */ - - R0 = I0; - - /* An extraction pattern, to get the page-size bits from - * the CPLB data entry. Bits 16-17, so two bits at posn 16. - */ - - R1 = ((16<<8)|2); -.Linext: R4 = [P2++]; /* address from config table */ - R2 = [P2++]; /* data from config table */ -#ifdef CONFIG_CPLB_INFO - P3 += 8; -#endif - - CC = R4 == -1; /* End of config table*/ - IF CC JUMP .Lno_page_in_table; - - /* See if failed address > start address */ - CC = R4 <= R0(IU); - IF !CC JUMP .Linext; - - /* extract page size (17:16)*/ - R3 = EXTRACT(R2, R1.L) (Z); - - /* add page size to addr to get range */ - - P5 = R3; - P5 = P0 + (P5 << 2); /* scaled, for int access*/ - R3 = [P5]; - R3 = R3 + R4; - - /* See if failed address < (start address + page size) */ - CC = R0 < R3(IU); - IF !CC JUMP .Linext; - - /* We've found a CPLB in the config table that covers - * the faulting address, so install this CPLB into the - * last entry of the table. - */ - - P1.L = (ICPLB_DATA15 & 0xFFFF); /* ICPLB_DATA15 */ - P1.H = (ICPLB_DATA15 >> 16); - [P1] = R2; - [P1-0x100] = R4; -#ifdef CONFIG_CPLB_INFO - R3 = [P3]; - R3 += 1; - [P3] = R3; -#endif - - /* P4 points to IMEM_CONTROL, and R5 contains its old - * value, after we disabled ICPLBS. Re-enable them. - */ - - BITSET(R5,ENICPLB_P); - CLI R2; - SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ - .align 8; - [P4] = R5; - SSYNC; - STI R2; - - ( R7:4,P5:3 ) = [SP++]; - R0 = CPLB_RELOADED; - RTS; - -/* FAILED CASES*/ -.Lno_page_in_table: - ( R7:4,P5:3 ) = [SP++]; - R0 = CPLB_NO_ADDR_MATCH; - RTS; -.Lall_locked: - ( R7:4,P5:3 ) = [SP++]; - R0 = CPLB_NO_UNLOCKED; - RTS; -.Lprot_violation: - ( R7:4,P5:3 ) = [SP++]; - R0 = CPLB_PROT_VIOL; - RTS; - -.Ldcplb_write: - - /* if a DCPLB is marked as write-back (CPLB_WT==0), and - * it is clean (CPLB_DIRTY==0), then a write to the - * CPLB's page triggers a protection violation. We have to - * mark the CPLB as dirty, to indicate that there are - * pending writes associated with the CPLB. - */ - - P4.L = (DCPLB_STATUS & 0xFFFF); - P4.H = (DCPLB_STATUS >> 16); - P3.L = (DCPLB_DATA0 & 0xFFFF); - P3.H = (DCPLB_DATA0 >> 16); - R5 = [P4]; - - /* A protection violation can be caused by more than just writes - * to a clean WB page, so we have to ensure that: - * - It's a write - * - to a clean WB page - * - and is allowed in the mode the access occurred. - */ - - CC = BITTST(R5, 16); /* ensure it was a write*/ - IF !CC JUMP .Lprot_violation; - - /* to check the rest, we have to retrieve the DCPLB.*/ - - /* The low half of DCPLB_STATUS is a bit mask*/ - - R2 = R5.L (Z); /* indicating which CPLB triggered the event.*/ - R3 = 30; /* so we can use this to determine the offset*/ - R2.L = SIGNBITS R2; - R2 = R2.L (Z); /* into the DCPLB table.*/ - R3 = R3 - R2; - P4 = R3; - P3 = P3 + (P4<<2); - R3 = [P3]; /* Retrieve the CPLB*/ - - /* Now we can check whether it's a clean WB page*/ - - CC = BITTST(R3, 14); /* 0==WB, 1==WT*/ - IF CC JUMP .Lprot_violation; - CC = BITTST(R3, 7); /* 0 == clean, 1 == dirty*/ - IF CC JUMP .Lprot_violation; - - /* Check whether the write is allowed in the mode that was active.*/ - - R2 = 1<<3; /* checking write in user mode*/ - CC = BITTST(R5, 17); /* 0==was user, 1==was super*/ - R5 = CC; - R2 <<= R5; /* if was super, check write in super mode*/ - R2 = R3 & R2; - CC = R2 == 0; - IF CC JUMP .Lprot_violation; - - /* It's a genuine write-to-clean-page.*/ - - BITSET(R3, 7); /* mark as dirty*/ - [P3] = R3; /* and write back.*/ - NOP; - CSYNC; - ( R7:4,P5:3 ) = [SP++]; - R0 = CPLB_RELOADED; - RTS; - -.Ldcplb_miss_compare: - - /* Data CPLB Miss event. We need to choose a CPLB to - * evict, and then locate a new CPLB to install from the - * config table, that covers the faulting address. - */ - - P1.L = (DCPLB_DATA15 & 0xFFFF); - P1.H = (DCPLB_DATA15 >> 16); - - P4.L = (DCPLB_FAULT_ADDR & 0xFFFF); - P4.H = (DCPLB_FAULT_ADDR >> 16); - R4 = [P4]; - I0 = R4; - - /* The replacement procedure for DCPLBs*/ - - R6 = R1; /* Save for later*/ - - /* Turn off CPLBs while we work.*/ - P4.L = (DMEM_CONTROL & 0xFFFF); - P4.H = (DMEM_CONTROL >> 16); - R5 = [P4]; - BITCLR(R5,ENDCPLB_P); - CLI R0; - SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ - .align 8; - [P4] = R5; - SSYNC; - STI R0; - - /* Start looking for a CPLB to evict. Our order of preference - * is: invalid CPLBs, clean CPLBs, dirty CPLBs. Locked CPLBs - * are no good. - */ - - I1.L = (DCPLB_DATA0 & 0xFFFF); - I1.H = (DCPLB_DATA0 >> 16); - P1 = 2; - P2 = 16; - I2.L = _dcplb_preference; - I2.H = _dcplb_preference; - LSETUP(.Lsdsearch1, .Ledsearch1) LC0 = P1; -.Lsdsearch1: - R0 = [I2++]; /* Get the bits we're interested in*/ - P0 = I1; /* Go back to start of table*/ - LSETUP (.Lsdsearch2, .Ledsearch2) LC1 = P2; -.Lsdsearch2: - R1 = [P0++]; /* Fetch each installed CPLB in turn*/ - R2 = R1 & R0; /* and test for interesting bits.*/ - CC = R2 == 0; /* If none are set, it'll do.*/ - IF !CC JUMP .Lskip_stack_check; - - R2 = [P0 - 0x104]; /* R2 - PageStart */ - P3.L = _page_size_table; /* retrieve end address */ - P3.H = _page_size_table; /* retrieve end address */ - R3 = 0x1002; /* 16th - position, 2 bits -length */ -#ifdef ANOMALY_05000209 - nop; /* Anomaly 05000209 */ -#endif - R7 = EXTRACT(R1,R3.l); - R7 = R7 << 2; /* Page size index offset */ - P5 = R7; - P3 = P3 + P5; - R7 = [P3]; /* page size in bytes */ - - R7 = R2 + R7; /* R7 - PageEnd */ - R4 = SP; /* Test SP is in range */ - - CC = R7 < R4; /* if PageEnd < SP */ - IF CC JUMP .Ldfound_victim; - R3 = 0x284; /* stack length from start of trap till - * the point. - * 20 stack locations for future modifications - */ - R4 = R4 + R3; - CC = R4 < R2; /* if SP + stacklen < PageStart */ - IF CC JUMP .Ldfound_victim; -.Lskip_stack_check: - -.Ledsearch2: NOP; -.Ledsearch1: NOP; - - /* If we got here, we didn't find a DCPLB we considered - * replacable, which means all of them were locked. - */ - - JUMP .Lall_locked; -.Ldfound_victim: - -#ifdef CONFIG_CPLB_INFO - R7 = [P0 - 0x104]; - P2.L = _dpdt_table; - P2.H = _dpdt_table; - P3.L = _dpdt_swapcount_table; - P3.H = _dpdt_swapcount_table; - P3 += -4; -.Ldicount: - R2 = [P2]; - P2 += 8; - P3 += 8; - CC = R2==-1; - IF CC JUMP .Ldicount_done; - CC = R7==R2; - IF !CC JUMP .Ldicount; - R7 = [P3]; - R7 += 1; - [P3] = R7; -.Ldicount_done: -#endif - - /* Clean down the hardware loops*/ - R2 = 0; - LC1 = R2; - LC0 = R2; - - /* There's a suitable victim in [P0-4] (because we've - * advanced already). - */ - -.LDdoverwrite: - - /* [P0-4] is a suitable victim CPLB, so we want to - * overwrite it by moving all the following CPLBs - * one space closer to the start. - */ - - R1.L = (DCPLB_DATA16 & 0xFFFF); /* DCPLB_DATA15 + 4 */ - R1.H = (DCPLB_DATA16 >> 16); - R0 = P0; - - /* If the victim happens to be in DCPLB15, - * we don't need to move anything. - */ - - CC = R1 == R0; - IF CC JUMP .Lde_moved; - R1 = R1 - R0; - R1 >>= 2; - P1 = R1; - LSETUP(.Lds_move, .Lde_move) LC0=P1; -.Lds_move: - R0 = [P0++]; /* move data */ - [P0 - 8] = R0; - R0 = [P0-0x104] /* move address */ -.Lde_move: [P0-0x108] = R0; - - /* We've now made space in DCPLB15 for the new CPLB to be - * installed. The next stage is to locate a CPLB in the - * config table that covers the faulting address. - */ - -.Lde_moved:NOP; - R0 = I0; /* Our faulting address */ - - P2.L = _dpdt_table; - P2.H = _dpdt_table; -#ifdef CONFIG_CPLB_INFO - P3.L = _dpdt_swapcount_table; - P3.H = _dpdt_swapcount_table; - P3 += -8; -#endif - - P1.L = _page_size_table; - P1.H = _page_size_table; - - /* An extraction pattern, to retrieve bits 17:16.*/ - - R1 = (16<<8)|2; -.Ldnext: R4 = [P2++]; /* address */ - R2 = [P2++]; /* data */ -#ifdef CONFIG_CPLB_INFO - P3 += 8; -#endif - - CC = R4 == -1; - IF CC JUMP .Lno_page_in_table; - - /* See if failed address > start address */ - CC = R4 <= R0(IU); - IF !CC JUMP .Ldnext; - - /* extract page size (17:16)*/ - R3 = EXTRACT(R2, R1.L) (Z); - - /* add page size to addr to get range */ - - P5 = R3; - P5 = P1 + (P5 << 2); - R3 = [P5]; - R3 = R3 + R4; - - /* See if failed address < (start address + page size) */ - CC = R0 < R3(IU); - IF !CC JUMP .Ldnext; - - /* We've found the CPLB that should be installed, so - * write it into CPLB15, masking off any caching bits - * if necessary. - */ - - P1.L = (DCPLB_DATA15 & 0xFFFF); - P1.H = (DCPLB_DATA15 >> 16); - - /* If the DCPLB has cache bits set, but caching hasn't - * been enabled, then we want to mask off the cache-in-L1 - * bit before installing. Moreover, if caching is off, we - * also want to ensure that the DCPLB has WT mode set, rather - * than WB, since WB pages still trigger first-write exceptions - * even when not caching is off, and the page isn't marked as - * cachable. Finally, we could mark the page as clean, not dirty, - * but we choose to leave that decision to the user; if the user - * chooses to have a CPLB pre-defined as dirty, then they always - * pay the cost of flushing during eviction, but don't pay the - * cost of first-write exceptions to mark the page as dirty. - */ - -#ifdef CONFIG_BLKFIN_WT - BITSET(R6, 14); /* Set WT*/ -#endif - - [P1] = R2; - [P1-0x100] = R4; -#ifdef CONFIG_CPLB_INFO - R3 = [P3]; - R3 += 1; - [P3] = R3; -#endif - - /* We've installed the CPLB, so re-enable CPLBs. P4 - * points to DMEM_CONTROL, and R5 is the value we - * last wrote to it, when we were disabling CPLBs. - */ - - BITSET(R5,ENDCPLB_P); - CLI R2; - .align 8; - [P4] = R5; - SSYNC; - STI R2; - - ( R7:4,P5:3 ) = [SP++]; - R0 = CPLB_RELOADED; - RTS; - -.data -.align 4; -_page_size_table: -.byte4 0x00000400; /* 1K */ -.byte4 0x00001000; /* 4K */ -.byte4 0x00100000; /* 1M */ -.byte4 0x00400000; /* 4M */ - -.align 4; -_dcplb_preference: -.byte4 0x00000001; /* valid bit */ -.byte4 0x00000002; /* lock bit */ diff --git a/trunk/arch/blackfin/mach-common/dpmc.S b/trunk/arch/blackfin/mach-common/dpmc.S deleted file mode 100644 index 97cdcd6a00d4..000000000000 --- a/trunk/arch/blackfin/mach-common/dpmc.S +++ /dev/null @@ -1,418 +0,0 @@ -/* - * File: arch/blackfin/mach-common/dpmc.S - * Based on: - * Author: LG Soft India - * - * Created: ? - * Description: Watchdog Timer APIs - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -.text - -ENTRY(_unmask_wdog_wakeup_evt) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.H = hi(SICA_IWR1); - P0.L = lo(SICA_IWR1); -#else - P0.h = (SIC_IWR >> 16); - P0.l = (SIC_IWR & 0xFFFF); -#endif - R7 = [P0]; -#if defined(CONFIG_BF561) - BITSET(R7, 27); -#else - BITSET(R7,(IRQ_WATCH - IVG7)); -#endif - [P0] = R7; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -.LWRITE_TO_STAT: - /* When watch dog timer is enabled, a write to STAT will load the - * contents of CNT to STAT - */ - R7 = 0x0000(z); -#if defined(CONFIG_BF561) - P0.h = (WDOGA_STAT >> 16); - P0.l = (WDOGA_STAT & 0xFFFF); -#else - P0.h = (WDOG_STAT >> 16); - P0.l = (WDOG_STAT & 0xFFFF); -#endif - [P0] = R7; - SSYNC; - JUMP .LSKIP_WRITE_TO_STAT; - -ENTRY(_program_wdog_timer) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.h = (WDOGA_CNT >> 16); - P0.l = (WDOGA_CNT & 0xFFFF); -#else - P0.h = (WDOG_CNT >> 16); - P0.l = (WDOG_CNT & 0xFFFF); -#endif - [P0] = R0; - SSYNC; - -#if defined(CONFIG_BF561) - P0.h = (WDOGA_CTL >> 16); - P0.l = (WDOGA_CTL & 0xFFFF); -#else - P0.h = (WDOG_CTL >> 16); - P0.l = (WDOG_CTL & 0xFFFF); -#endif - R7 = W[P0](Z); - CC = BITTST(R7,1); - if !CC JUMP .LWRITE_TO_STAT; - CC = BITTST(R7,2); - if !CC JUMP .LWRITE_TO_STAT; - -.LSKIP_WRITE_TO_STAT: -#if defined(CONFIG_BF561) - P0.h = (WDOGA_CTL >> 16); - P0.l = (WDOGA_CTL & 0xFFFF); -#else - P0.h = (WDOG_CTL >> 16); - P0.l = (WDOG_CTL & 0xFFFF); -#endif - R7 = W[P0](Z); - BITCLR(R7,1); /* Enable GP event */ - BITSET(R7,2); - W[P0] = R7.L; - SSYNC; - NOP; - - R7 = W[P0](Z); - BITCLR(R7,4); /* Enable the wdog counter */ - W[P0] = R7.L; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_clear_wdog_wakeup_evt) - [--SP] = ( R7:0, P5:0 ); - -#if defined(CONFIG_BF561) - P0.h = (WDOGA_CTL >> 16); - P0.l = (WDOGA_CTL & 0xFFFF); -#else - P0.h = (WDOG_CTL >> 16); - P0.l = (WDOG_CTL & 0xFFFF); -#endif - R7 = 0x0AD6(Z); - W[P0] = R7.L; - SSYNC; - - R7 = W[P0](Z); - BITSET(R7,15); - W[P0] = R7.L; - SSYNC; - - R7 = W[P0](Z); - BITSET(R7,1); - BITSET(R7,2); - W[P0] = R7.L; - SSYNC; - - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_disable_wdog_timer) - [--SP] = ( R7:0, P5:0 ); -#if defined(CONFIG_BF561) - P0.h = (WDOGA_CTL >> 16); - P0.l = (WDOGA_CTL & 0xFFFF); -#else - P0.h = (WDOG_CTL >> 16); - P0.l = (WDOG_CTL & 0xFFFF); -#endif - R7 = 0xAD6(Z); - W[P0] = R7.L; - SSYNC; - ( R7:0, P5:0 ) = [SP++]; - RTS; - -#if !defined(CONFIG_BF561) - -.section .l1.text - -ENTRY(_sleep_mode) - [--SP] = ( R7:0, P5:0 ); - [--SP] = RETS; - - call _set_sic_iwr; - - R0 = 0xFFFF (Z); - call _set_rtc_istat - - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - R1 = W[P0](z); - BITSET (R1, 3); - W[P0] = R1.L; - - CLI R2; - SSYNC; - IDLE; - STI R2; - - call _test_pll_locked; - - R0 = IWR_ENABLE(0); - call _set_sic_iwr; - - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - R7 = w[p0](z); - BITCLR (R7, 3); - BITCLR (R7, 5); - w[p0] = R7.L; - IDLE; - call _test_pll_locked; - - RETS = [SP++]; - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_hibernate_mode) - [--SP] = ( R7:0, P5:0 ); - [--SP] = RETS; - - call _set_sic_iwr; - - R0 = 0xFFFF (Z); - call _set_rtc_istat - - P0.H = hi(VR_CTL); - P0.L = lo(VR_CTL); - R1 = W[P0](z); - BITSET (R1, 8); - BITCLR (R1, 0); - BITCLR (R1, 1); - W[P0] = R1.L; - SSYNC; - - CLI R2; - IDLE; - - /* Actually, adding anything may not be necessary...SDRAM contents - * are lost - */ - -ENTRY(_deep_sleep) - [--SP] = ( R7:0, P5:0 ); - [--SP] = RETS; - - CLI R4; - - call _set_sic_iwr; - - call _set_sdram_srfs; - - /* Clear all the interrupts,bits sticky */ - R0 = 0xFFFF (Z); - call _set_rtc_istat - - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - R0 = W[P0](z); - BITSET (R0, 5); - W[P0] = R0.L; - - call _test_pll_locked; - - SSYNC; - IDLE; - - call _unset_sdram_srfs; - - call _test_pll_locked; - - R0 = IWR_ENABLE(0); - call _set_sic_iwr; - - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - R0 = w[p0](z); - BITCLR (R0, 3); - BITCLR (R0, 5); - BITCLR (R0, 8); - w[p0] = R0; - IDLE; - call _test_pll_locked; - - STI R4; - - RETS = [SP++]; - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_sleep_deeper) - [--SP] = ( R7:0, P5:0 ); - [--SP] = RETS; - - CLI R4; - - P3 = R0; - R0 = IWR_ENABLE(0); - call _set_sic_iwr; - call _set_sdram_srfs; - - /* Clear all the interrupts,bits sticky */ - R0 = 0xFFFF (Z); - call _set_rtc_istat - - P0.H = hi(PLL_DIV); - P0.L = lo(PLL_DIV); - R6 = W[P0](z); - R0.L = 0xF; - W[P0] = R0.l; - - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - R5 = W[P0](z); - R0.L = (MIN_VC/CONFIG_CLKIN_HZ) << 9; - W[P0] = R0.l; - - SSYNC; - IDLE; - - call _test_pll_locked; - - P0.H = hi(VR_CTL); - P0.L = lo(VR_CTL); - R7 = W[P0](z); - R1 = 0x6; - R1 <<= 16; - R2 = 0x0404(Z); - R1 = R1|R2; - - R2 = DEPOSIT(R7, R1); - W[P0] = R2; - - SSYNC; - IDLE; - - call _test_pll_locked; - - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - R0 = W[P0](z); - BITSET (R0, 3); - W[P0] = R0.L; - - R0 = P3; - call _set_sic_iwr; - - SSYNC; - IDLE; - - call _test_pll_locked; - - R0 = IWR_ENABLE(0); - call _set_sic_iwr; - - P0.H = hi(VR_CTL); - P0.L = lo(VR_CTL); - W[P0]= R7; - - SSYNC; - IDLE; - - call _test_pll_locked; - - P0.H = hi(PLL_DIV); - P0.L = lo(PLL_DIV); - W[P0]= R6; - - P0.H = hi(PLL_CTL); - P0.L = lo(PLL_CTL); - w[p0] = R5; - IDLE; - call _test_pll_locked; - - call _unset_sdram_srfs; - - STI R4; - - RETS = [SP++]; - ( R7:0, P5:0 ) = [SP++]; - RTS; - -ENTRY(_set_sdram_srfs) - /* set the sdram to self refresh mode */ - P0.H = hi(EBIU_SDGCTL); - P0.L = lo(EBIU_SDGCTL); - R2 = [P0]; - R3.H = hi(SRFS); - R3.L = lo(SRFS); - R2 = R2|R3; - [P0] = R2; - ssync; - RTS; - -ENTRY(_unset_sdram_srfs) - /* set the sdram out of self refresh mode */ - P0.H = hi(EBIU_SDGCTL); - P0.L = lo(EBIU_SDGCTL); - R2 = [P0]; - R3.H = hi(SRFS); - R3.L = lo(SRFS); - R3 = ~R3; - R2 = R2&R3; - [P0] = R2; - ssync; - RTS; - -ENTRY(_set_sic_iwr) - P0.H = hi(SIC_IWR); - P0.L = lo(SIC_IWR); - [P0] = R0; - SSYNC; - RTS; - -ENTRY(_set_rtc_istat) - P0.H = hi(RTC_ISTAT); - P0.L = lo(RTC_ISTAT); - w[P0] = R0.L; - SSYNC; - RTS; - -ENTRY(_test_pll_locked) - P0.H = hi(PLL_STAT); - P0.L = lo(PLL_STAT); -1: - R0 = W[P0] (Z); - CC = BITTST(R0,5); - IF !CC JUMP 1b; - RTS; -#endif diff --git a/trunk/arch/blackfin/mach-common/entry.S b/trunk/arch/blackfin/mach-common/entry.S deleted file mode 100644 index 8eb0a9023482..000000000000 --- a/trunk/arch/blackfin/mach-common/entry.S +++ /dev/null @@ -1,1207 +0,0 @@ -/* - * File: arch/blackfin/mach-common/entry.S - * Based on: - * Author: Linus Torvalds - * - * Created: ? - * Description: contains the system-call and fault low-level handling routines. - * This also contains the timer-interrupt handler, as well as all - * interrupts and faults that can result in a task-switch. - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * 25-Dec-2004 - LG Soft India - * 1. Fix in return_from_int, to make sure any pending - * system call in ILAT for this process to get - * executed, otherwise in case context switch happens, - * system call of first process (i.e in ILAT) will be - * carried forward to the switched process. - * 2. Removed Constant references for the following - * a. IPEND - * b. EXCAUSE mask - * c. PAGE Mask - */ - -/* - * NOTE: This code handles signal-recognition, which happens every time - * after a timer-interrupt and after each system call. - */ - - -#include -#include -#include -#include -#include /* TIF_NEED_RESCHED */ -#include - -#include - -#ifdef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE - /* - * TODO: this should be proper save/restore, but for now - * we'll just cheat and use 0x1/0x13 - */ -# define DEBUG_START_HWTRACE \ - P5.l = LO(TBUFCTL); \ - P5.h = HI(TBUFCTL); \ - R7 = 0x13; \ - [P5] = R7; -# define DEBUG_STOP_HWTRACE \ - P5.l = LO(TBUFCTL); \ - P5.h = HI(TBUFCTL); \ - R7 = 0x01; \ - [P5] = R7; -#else -# define DEBUG_START_HWTRACE -# define DEBUG_STOP_HWTRACE -#endif - -#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 -.section .l1.text -#else -.text -#endif - -/* Slightly simplified and streamlined entry point for CPLB misses. - * This one does not lower the level to IRQ5, and thus can be used to - * patch up CPLB misses on the kernel stack. - */ -ENTRY(_ex_dcplb) -#if defined(ANOMALY_05000261) - /* - * Work around an anomaly: if we see a new DCPLB fault, return - * without doing anything. Then, if we get the same fault again, - * handle it. - */ - p5.l = _last_cplb_fault_retx; - p5.h = _last_cplb_fault_retx; - r7 = [p5]; - r6 = retx; - [p5] = r6; - cc = r6 == r7; - if !cc jump _return_from_exception; - /* fall through */ -#endif - -ENTRY(_ex_icplb) - (R7:6,P5:4) = [sp++]; - ASTAT = [sp++]; - SAVE_ALL_SYS - call __cplb_hdr; - DEBUG_START_HWTRACE - RESTORE_ALL_SYS - SP = RETN; - rtx; - -ENTRY(_ex_spinlock) - /* Transform this into a syscall - twiddle the syscall vector. */ - p5.l = lo(EVT15); - p5.h = hi(EVT15); - r7.l = _spinlock_bh; - r7.h = _spinlock_bh; - [p5] = r7; - csync; - /* Fall through. */ - -ENTRY(_ex_syscall) - DEBUG_START_HWTRACE - (R7:6,P5:4) = [sp++]; - ASTAT = [sp++]; - raise 15; /* invoked by TRAP #0, for sys call */ - sp = retn; - rtx - -ENTRY(_spinlock_bh) - SAVE_ALL_SYS - /* To end up here, vector 15 was changed - so we have to change it - * back. - */ - p0.l = lo(EVT15); - p0.h = hi(EVT15); - p1.l = _evt_system_call; - p1.h = _evt_system_call; - [p0] = p1; - csync; - r0 = [sp + PT_R0]; - sp += -12; - call _sys_bfin_spinlock; - sp += 12; - [SP + PT_R0] = R0; - RESTORE_ALL_SYS - rti; - -ENTRY(_ex_soft_bp) - r7 = retx; - r7 += -2; - retx = r7; - jump.s _ex_trap_c; - -ENTRY(_ex_single_step) - r7 = retx; - r6 = reti; - cc = r7 == r6; - if cc jump _return_from_exception - r7 = syscfg; - bitclr (r7, 0); - syscfg = R7; - - p5.l = lo(IPEND); - p5.h = hi(IPEND); - r6 = [p5]; - cc = bittst(r6, 5); - if !cc jump _ex_trap_c; - p4.l = lo(EVT5); - p4.h = hi(EVT5); - r6.h = _exception_to_level5; - r6.l = _exception_to_level5; - r7 = [p4]; - cc = r6 == r7; - if !cc jump _ex_trap_c; - -_return_from_exception: - DEBUG_START_HWTRACE - (R7:6,P5:4) = [sp++]; - ASTAT = [sp++]; - sp = retn; - rtx; - -ENTRY(_handle_bad_cplb) - /* To get here, we just tried and failed to change a CPLB - * so, handle things in trap_c (C code), by lowering to - * IRQ5, just like we normally do. Since this is not a - * "normal" return path, we have a do alot of stuff to - * the stack to get ready so, we can fall through - we - * need to make a CPLB exception look like a normal exception - */ - - DEBUG_START_HWTRACE - RESTORE_ALL_SYS - [--sp] = ASTAT; - [--sp] = (R7:6, P5:4); - -ENTRY(_ex_trap_c) - /* Call C code (trap_c) to handle the exception, which most - * likely involves sending a signal to the current process. - * To avoid double faults, lower our priority to IRQ5 first. - */ - P5.h = _exception_to_level5; - P5.l = _exception_to_level5; - p4.l = lo(EVT5); - p4.h = hi(EVT5); - [p4] = p5; - csync; - - /* Disable all interrupts, but make sure level 5 is enabled so - * we can switch to that level. Save the old mask. */ - cli r6; - p4.l = _excpt_saved_imask; - p4.h = _excpt_saved_imask; - [p4] = r6; - r6 = 0x3f; - sti r6; - - /* Save the excause into a circular buffer, in case the instruction - * which caused this excecptions causes others. - */ - P5.l = _in_ptr_excause; - P5.h = _in_ptr_excause; - R7 = [P5]; - R7 += 4; - R6 = 0xF; - R7 = R7 & R6; - [P5] = R7; - R6.l = _excause_circ_buf; - R6.h = _excause_circ_buf; - R7 = R7 + R6; - p5 = R7; - R6 = SEQSTAT; - [P5] = R6; - - DEBUG_START_HWTRACE - (R7:6,P5:4) = [sp++]; - ASTAT = [sp++]; - SP = RETN; - raise 5; - rtx; - -ENTRY(_exception_to_level5) - SAVE_ALL_SYS - - /* Restore interrupt mask. We haven't pushed RETI, so this - * doesn't enable interrupts until we return from this handler. */ - p4.l = _excpt_saved_imask; - p4.h = _excpt_saved_imask; - r6 = [p4]; - sti r6; - - /* Restore the hardware error vector. */ - P5.h = _evt_ivhw; - P5.l = _evt_ivhw; - p4.l = lo(EVT5); - p4.h = hi(EVT5); - [p4] = p5; - csync; - - p2.l = lo(IPEND); - p2.h = hi(IPEND); - csync; - r0 = [p2]; /* Read current IPEND */ - [sp + PT_IPEND] = r0; /* Store IPEND */ - - /* Pop the excause from the circular buffer and push it on the stack - * (in the right place - if you change the location of SEQSTAT, you - * must change this offset. - */ -.L_excep_to_5_again: - P5.l = _out_ptr_excause; - P5.h = _out_ptr_excause; - R7 = [P5]; - R7 += 4; - R6 = 0xF; - R7 = R7 & R6; - [P5] = R7; - R6.l = _excause_circ_buf; - R6.h = _excause_circ_buf; - R7 = R7 + R6; - P5 = R7; - R1 = [P5]; - [SP + 8] = r1; - - r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ - SP += -12; - call _trap_c; - SP += 12; - - /* See if anything else is in the exception buffer - * if there is, process it - */ - P5.l = _out_ptr_excause; - P5.h = _out_ptr_excause; - P4.l = _in_ptr_excause; - P4.h = _in_ptr_excause; - R6 = [P5]; - R7 = [P4]; - CC = R6 == R7; - if ! CC JUMP .L_excep_to_5_again - - call _ret_from_exception; - RESTORE_ALL_SYS - rti; - -ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ - /* Since the kernel stack can be anywhere, it's not guaranteed to be - * covered by a CPLB. Switch to an exception stack; use RETN as a - * scratch register (for want of a better option). - */ - retn = sp; - sp.l = _exception_stack_top; - sp.h = _exception_stack_top; - /* Try to deal with syscalls quickly. */ - [--sp] = ASTAT; - [--sp] = (R7:6, P5:4); - DEBUG_STOP_HWTRACE - r7 = SEQSTAT; /* reason code is in bit 5:0 */ - r6.l = lo(SEQSTAT_EXCAUSE); - r6.h = hi(SEQSTAT_EXCAUSE); - r7 = r7 & r6; - p5.h = _extable; - p5.l = _extable; - p4 = r7; - p5 = p5 + (p4 << 2); - p4 = [p5]; - jump (p4); - -.Lbadsys: - r7 = -ENOSYS; /* signextending enough */ - [sp + PT_R0] = r7; /* return value from system call */ - jump .Lsyscall_really_exit; - -ENTRY(_kernel_execve) - link SIZEOF_PTREGS; - p0 = sp; - r3 = SIZEOF_PTREGS / 4; - r4 = 0(x); -0: - [p0++] = r4; - r3 += -1; - cc = r3 == 0; - if !cc jump 0b (bp); - - p0 = sp; - sp += -16; - [sp + 12] = p0; - call _do_execve; - SP += 16; - cc = r0 == 0; - if ! cc jump 1f; - /* Success. Copy our temporary pt_regs to the top of the kernel - * stack and do a normal exception return. - */ - r1 = sp; - r0 = (-KERNEL_STACK_SIZE) (x); - r1 = r1 & r0; - p2 = r1; - p3 = [p2]; - r0 = KERNEL_STACK_SIZE - 4 (z); - p1 = r0; - p1 = p1 + p2; - - p0 = fp; - r4 = [p0--]; - r3 = SIZEOF_PTREGS / 4; -0: - r4 = [p0--]; - [p1--] = r4; - r3 += -1; - cc = r3 == 0; - if ! cc jump 0b (bp); - - r0 = (KERNEL_STACK_SIZE - SIZEOF_PTREGS) (z); - p1 = r0; - p1 = p1 + p2; - sp = p1; - r0 = syscfg; - [SP + PT_SYSCFG] = r0; - [p3 + (TASK_THREAD + THREAD_KSP)] = sp; - - RESTORE_CONTEXT; - rti; -1: - unlink; - rts; - -ENTRY(_system_call) - /* Store IPEND */ - p2.l = lo(IPEND); - p2.h = hi(IPEND); - csync; - r0 = [p2]; - [sp + PT_IPEND] = r0; - - /* Store RETS for now */ - r0 = rets; - [sp + PT_RESERVED] = r0; - /* Set the stack for the current process */ - r7 = sp; - r6.l = lo(ALIGN_PAGE_MASK); - r6.h = hi(ALIGN_PAGE_MASK); - r7 = r7 & r6; /* thread_info */ - p2 = r7; - p2 = [p2]; - - [p2+(TASK_THREAD+THREAD_KSP)] = sp; - - /* Check the System Call */ - r7 = __NR_syscall; - /* System call number is passed in P0 */ - r6 = p0; - cc = r6 < r7; - if ! cc jump .Lbadsys; - - /* are we tracing syscalls?*/ - r7 = sp; - r6.l = lo(ALIGN_PAGE_MASK); - r6.h = hi(ALIGN_PAGE_MASK); - r7 = r7 & r6; - p2 = r7; - r7 = [p2+TI_FLAGS]; - CC = BITTST(r7,TIF_SYSCALL_TRACE); - if CC JUMP _sys_trace; - - /* Execute the appropriate system call */ - - p4 = p0; - p5.l = _sys_call_table; - p5.h = _sys_call_table; - p5 = p5 + (p4 << 2); - r0 = [sp + PT_R0]; - r1 = [sp + PT_R1]; - r2 = [sp + PT_R2]; - p5 = [p5]; - - [--sp] = r5; - [--sp] = r4; - [--sp] = r3; - SP += -12; - call (p5); - SP += 24; - [sp + PT_R0] = r0; - -.Lresume_userspace: - r7 = sp; - r4.l = lo(ALIGN_PAGE_MASK); - r4.h = hi(ALIGN_PAGE_MASK); - r7 = r7 & r4; /* thread_info->flags */ - p5 = r7; -.Lresume_userspace_1: - /* Disable interrupts. */ - [--sp] = reti; - reti = [sp++]; - - r7 = [p5 + TI_FLAGS]; - r4.l = lo(_TIF_WORK_MASK); - r4.h = hi(_TIF_WORK_MASK); - r7 = r7 & r4; - -.Lsyscall_resched: - cc = BITTST(r7, TIF_NEED_RESCHED); - if !cc jump .Lsyscall_sigpending; - - /* Reenable interrupts. */ - [--sp] = reti; - r0 = [sp++]; - - SP += -12; - call _schedule; - SP += 12; - - jump .Lresume_userspace_1; - -.Lsyscall_sigpending: - cc = BITTST(r7, TIF_RESTORE_SIGMASK); - if cc jump .Lsyscall_do_signals; - cc = BITTST(r7, TIF_SIGPENDING); - if !cc jump .Lsyscall_really_exit; -.Lsyscall_do_signals: - /* Reenable interrupts. */ - [--sp] = reti; - r0 = [sp++]; - - r0 = sp; - SP += -12; - call _do_signal; - SP += 12; - -.Lsyscall_really_exit: - r5 = [sp + PT_RESERVED]; - rets = r5; - rts; - -_sys_trace: - call _syscall_trace; - - /* Execute the appropriate system call */ - - p4 = [SP + PT_P0]; - p5.l = _sys_call_table; - p5.h = _sys_call_table; - p5 = p5 + (p4 << 2); - r0 = [sp + PT_R0]; - r1 = [sp + PT_R1]; - r2 = [sp + PT_R2]; - r3 = [sp + PT_R3]; - r4 = [sp + PT_R4]; - r5 = [sp + PT_R5]; - p5 = [p5]; - - [--sp] = r5; - [--sp] = r4; - [--sp] = r3; - SP += -12; - call (p5); - SP += 24; - [sp + PT_R0] = r0; - - call _syscall_trace; - jump .Lresume_userspace; - -ENTRY(_resume) - /* - * Beware - when entering resume, prev (the current task) is - * in r0, next (the new task) is in r1. - */ - p0 = r0; - p1 = r1; - [--sp] = rets; - [--sp] = fp; - [--sp] = (r7:4, p5:3); - - /* save usp */ - p2 = usp; - [p0+(TASK_THREAD+THREAD_USP)] = p2; - - /* save current kernel stack pointer */ - [p0+(TASK_THREAD+THREAD_KSP)] = sp; - - /* save program counter */ - r1.l = _new_old_task; - r1.h = _new_old_task; - [p0+(TASK_THREAD+THREAD_PC)] = r1; - - /* restore the kernel stack pointer */ - sp = [p1+(TASK_THREAD+THREAD_KSP)]; - - /* restore user stack pointer */ - p0 = [p1+(TASK_THREAD+THREAD_USP)]; - usp = p0; - - /* restore pc */ - p0 = [p1+(TASK_THREAD+THREAD_PC)]; - jump (p0); - - /* - * Following code actually lands up in a new (old) task. - */ - -_new_old_task: - (r7:4, p5:3) = [sp++]; - fp = [sp++]; - rets = [sp++]; - - /* - * When we come out of resume, r0 carries "old" task, becuase we are - * in "new" task. - */ - rts; - -ENTRY(_ret_from_exception) - p2.l = lo(IPEND); - p2.h = hi(IPEND); - - csync; - r0 = [p2]; - [sp + PT_IPEND] = r0; - -1: - r1 = 0x37(Z); - r2 = ~r1; - r2.h = 0; - r0 = r2 & r0; - cc = r0 == 0; - if !cc jump 4f; /* if not return to user mode, get out */ - - /* Make sure any pending system call or deferred exception - * return in ILAT for this process to get executed, otherwise - * in case context switch happens, system call of - * first process (i.e in ILAT) will be carried - * forward to the switched process - */ - - p2.l = lo(ILAT); - p2.h = hi(ILAT); - r0 = [p2]; - r1 = (EVT_IVG14 | EVT_IVG15) (z); - r0 = r0 & r1; - cc = r0 == 0; - if !cc jump 5f; - - /* Set the stack for the current process */ - r7 = sp; - r4.l = lo(ALIGN_PAGE_MASK); - r4.h = hi(ALIGN_PAGE_MASK); - r7 = r7 & r4; /* thread_info->flags */ - p5 = r7; - r7 = [p5 + TI_FLAGS]; - r4.l = lo(_TIF_WORK_MASK); - r4.h = hi(_TIF_WORK_MASK); - r7 = r7 & r4; - cc = r7 == 0; - if cc jump 4f; - - p0.l = lo(EVT15); - p0.h = hi(EVT15); - p1.l = _schedule_and_signal; - p1.h = _schedule_and_signal; - [p0] = p1; - csync; - raise 15; /* raise evt14 to do signal or reschedule */ -4: - r0 = syscfg; - bitclr(r0, 0); - syscfg = r0; -5: - rts; - -ENTRY(_return_from_int) - /* If someone else already raised IRQ 15, do nothing. */ - csync; - p2.l = lo(ILAT); - p2.h = hi(ILAT); - r0 = [p2]; - cc = bittst (r0, EVT_IVG15_P); - if cc jump 2f; - - /* if not return to user mode, get out */ - p2.l = lo(IPEND); - p2.h = hi(IPEND); - r0 = [p2]; - r1 = 0x17(Z); - r2 = ~r1; - r2.h = 0; - r0 = r2 & r0; - r1 = 1; - r1 = r0 - r1; - r2 = r0 & r1; - cc = r2 == 0; - if !cc jump 2f; - - /* Lower the interrupt level to 15. */ - p0.l = lo(EVT15); - p0.h = hi(EVT15); - p1.l = _schedule_and_signal_from_int; - p1.h = _schedule_and_signal_from_int; - [p0] = p1; - csync; -#if defined(ANOMALY_05000281) - r0.l = lo(CONFIG_BOOT_LOAD); - r0.h = hi(CONFIG_BOOT_LOAD); - reti = r0; -#endif - r0 = 0x801f (z); - STI r0; - raise 15; /* raise evt15 to do signal or reschedule */ - rti; -2: - rts; - -ENTRY(_lower_to_irq14) -#if defined(ANOMALY_05000281) - r0.l = lo(CONFIG_BOOT_LOAD); - r0.h = hi(CONFIG_BOOT_LOAD); - reti = r0; -#endif - r0 = 0x401f; - sti r0; - raise 14; - rti; -ENTRY(_evt14_softirq) -#ifdef CONFIG_DEBUG_HWERR - r0 = 0x3f; - sti r0; -#else - cli r0; -#endif - [--sp] = RETI; - SP += 4; - rts; - -_schedule_and_signal_from_int: - /* To end up here, vector 15 was changed - so we have to change it - * back. - */ - p0.l = lo(EVT15); - p0.h = hi(EVT15); - p1.l = _evt_system_call; - p1.h = _evt_system_call; - [p0] = p1; - csync; - p1 = rets; - [sp + PT_RESERVED] = p1; - - p0.l = _irq_flags; - p0.h = _irq_flags; - r0 = [p0]; - sti r0; - - jump.s .Lresume_userspace; - -_schedule_and_signal: - SAVE_CONTEXT_SYSCALL - /* To end up here, vector 15 was changed - so we have to change it - * back. - */ - p0.l = lo(EVT15); - p0.h = hi(EVT15); - p1.l = _evt_system_call; - p1.h = _evt_system_call; - [p0] = p1; - csync; - p0.l = 1f; - p0.h = 1f; - [sp + PT_RESERVED] = P0; - call .Lresume_userspace; -1: - RESTORE_CONTEXT - rti; - -/* Make sure when we start, that the circular buffer is initialized properly - * R0 and P0 are call clobbered, so we can use them here. - */ -ENTRY(_init_exception_buff) - r0 = 0; - p0.h = _in_ptr_excause; - p0.l = _in_ptr_excause; - [p0] = r0; - p0.h = _out_ptr_excause; - p0.l = _out_ptr_excause; - [p0] = r0; - rts; - -/* - * Put these in the kernel data section - that should always be covered by - * a CPLB. This is needed to ensure we don't get double fault conditions - */ - -#ifdef CONFIG_SYSCALL_TAB_L1 -.section .l1.data -#else -.data -#endif -ALIGN -_extable: - /* entry for each EXCAUSE[5:0] - * This table bmust be in sync with the table in ./kernel/traps.c - * EXCPT instruction can provide 4 bits of EXCAUSE, allowing 16 to be user defined - */ - .long _ex_syscall; /* 0x00 - User Defined - Linux Syscall */ - .long _ex_soft_bp /* 0x01 - User Defined - Software breakpoint */ - .long _ex_trap_c /* 0x02 - User Defined */ - .long _ex_trap_c /* 0x03 - User Defined - Atomic test and set service */ - .long _ex_spinlock /* 0x04 - User Defined */ - .long _ex_trap_c /* 0x05 - User Defined */ - .long _ex_trap_c /* 0x06 - User Defined */ - .long _ex_trap_c /* 0x07 - User Defined */ - .long _ex_trap_c /* 0x08 - User Defined */ - .long _ex_trap_c /* 0x09 - User Defined */ - .long _ex_trap_c /* 0x0A - User Defined */ - .long _ex_trap_c /* 0x0B - User Defined */ - .long _ex_trap_c /* 0x0C - User Defined */ - .long _ex_trap_c /* 0x0D - User Defined */ - .long _ex_trap_c /* 0x0E - User Defined */ - .long _ex_trap_c /* 0x0F - User Defined */ - .long _ex_single_step /* 0x10 - HW Single step */ - .long _ex_trap_c /* 0x11 - Trace Buffer Full */ - .long _ex_trap_c /* 0x12 - Reserved */ - .long _ex_trap_c /* 0x13 - Reserved */ - .long _ex_trap_c /* 0x14 - Reserved */ - .long _ex_trap_c /* 0x15 - Reserved */ - .long _ex_trap_c /* 0x16 - Reserved */ - .long _ex_trap_c /* 0x17 - Reserved */ - .long _ex_trap_c /* 0x18 - Reserved */ - .long _ex_trap_c /* 0x19 - Reserved */ - .long _ex_trap_c /* 0x1A - Reserved */ - .long _ex_trap_c /* 0x1B - Reserved */ - .long _ex_trap_c /* 0x1C - Reserved */ - .long _ex_trap_c /* 0x1D - Reserved */ - .long _ex_trap_c /* 0x1E - Reserved */ - .long _ex_trap_c /* 0x1F - Reserved */ - .long _ex_trap_c /* 0x20 - Reserved */ - .long _ex_trap_c /* 0x21 - Undefined Instruction */ - .long _ex_trap_c /* 0x22 - Illegal Instruction Combination */ - .long _ex_dcplb /* 0x23 - Data CPLB Protection Violation */ - .long _ex_trap_c /* 0x24 - Data access misaligned */ - .long _ex_trap_c /* 0x25 - Unrecoverable Event */ - .long _ex_dcplb /* 0x26 - Data CPLB Miss */ - .long _ex_trap_c /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero */ - .long _ex_trap_c /* 0x28 - Emulation Watchpoint */ - .long _ex_trap_c /* 0x29 - Instruction fetch access error (535 only) */ - .long _ex_trap_c /* 0x2A - Instruction fetch misaligned */ - .long _ex_icplb /* 0x2B - Instruction CPLB protection Violation */ - .long _ex_icplb /* 0x2C - Instruction CPLB miss */ - .long _ex_trap_c /* 0x2D - Instruction CPLB Multiple Hits */ - .long _ex_trap_c /* 0x2E - Illegal use of Supervisor Resource */ - .long _ex_trap_c /* 0x2E - Illegal use of Supervisor Resource */ - .long _ex_trap_c /* 0x2F - Reserved */ - .long _ex_trap_c /* 0x30 - Reserved */ - .long _ex_trap_c /* 0x31 - Reserved */ - .long _ex_trap_c /* 0x32 - Reserved */ - .long _ex_trap_c /* 0x33 - Reserved */ - .long _ex_trap_c /* 0x34 - Reserved */ - .long _ex_trap_c /* 0x35 - Reserved */ - .long _ex_trap_c /* 0x36 - Reserved */ - .long _ex_trap_c /* 0x37 - Reserved */ - .long _ex_trap_c /* 0x38 - Reserved */ - .long _ex_trap_c /* 0x39 - Reserved */ - .long _ex_trap_c /* 0x3A - Reserved */ - .long _ex_trap_c /* 0x3B - Reserved */ - .long _ex_trap_c /* 0x3C - Reserved */ - .long _ex_trap_c /* 0x3D - Reserved */ - .long _ex_trap_c /* 0x3E - Reserved */ - .long _ex_trap_c /* 0x3F - Reserved */ - -ALIGN -ENTRY(_sys_call_table) - .long _sys_ni_syscall /* 0 - old "setup()" system call*/ - .long _sys_exit - .long _sys_fork - .long _sys_read - .long _sys_write - .long _sys_open /* 5 */ - .long _sys_close - .long _sys_ni_syscall /* old waitpid */ - .long _sys_creat - .long _sys_link - .long _sys_unlink /* 10 */ - .long _sys_execve - .long _sys_chdir - .long _sys_time - .long _sys_mknod - .long _sys_chmod /* 15 */ - .long _sys_chown /* chown16 */ - .long _sys_ni_syscall /* old break syscall holder */ - .long _sys_ni_syscall /* old stat */ - .long _sys_lseek - .long _sys_getpid /* 20 */ - .long _sys_mount - .long _sys_ni_syscall /* old umount */ - .long _sys_setuid - .long _sys_getuid - .long _sys_stime /* 25 */ - .long _sys_ptrace - .long _sys_alarm - .long _sys_ni_syscall /* old fstat */ - .long _sys_pause - .long _sys_ni_syscall /* old utime */ /* 30 */ - .long _sys_ni_syscall /* old stty syscall holder */ - .long _sys_ni_syscall /* old gtty syscall holder */ - .long _sys_access - .long _sys_nice - .long _sys_ni_syscall /* 35 */ /* old ftime syscall holder */ - .long _sys_sync - .long _sys_kill - .long _sys_rename - .long _sys_mkdir - .long _sys_rmdir /* 40 */ - .long _sys_dup - .long _sys_pipe - .long _sys_times - .long _sys_ni_syscall /* old prof syscall holder */ - .long _sys_brk /* 45 */ - .long _sys_setgid - .long _sys_getgid - .long _sys_ni_syscall /* old sys_signal */ - .long _sys_geteuid /* geteuid16 */ - .long _sys_getegid /* getegid16 */ /* 50 */ - .long _sys_acct - .long _sys_umount /* recycled never used phys() */ - .long _sys_ni_syscall /* old lock syscall holder */ - .long _sys_ioctl - .long _sys_fcntl /* 55 */ - .long _sys_ni_syscall /* old mpx syscall holder */ - .long _sys_setpgid - .long _sys_ni_syscall /* old ulimit syscall holder */ - .long _sys_ni_syscall /* old old uname */ - .long _sys_umask /* 60 */ - .long _sys_chroot - .long _sys_ustat - .long _sys_dup2 - .long _sys_getppid - .long _sys_getpgrp /* 65 */ - .long _sys_setsid - .long _sys_ni_syscall /* old sys_sigaction */ - .long _sys_sgetmask - .long _sys_ssetmask - .long _sys_setreuid /* setreuid16 */ /* 70 */ - .long _sys_setregid /* setregid16 */ - .long _sys_ni_syscall /* old sys_sigsuspend */ - .long _sys_ni_syscall /* old sys_sigpending */ - .long _sys_sethostname - .long _sys_setrlimit /* 75 */ - .long _sys_ni_syscall /* old getrlimit */ - .long _sys_getrusage - .long _sys_gettimeofday - .long _sys_settimeofday - .long _sys_getgroups /* getgroups16 */ /* 80 */ - .long _sys_setgroups /* setgroups16 */ - .long _sys_ni_syscall /* old_select */ - .long _sys_symlink - .long _sys_ni_syscall /* old lstat */ - .long _sys_readlink /* 85 */ - .long _sys_uselib - .long _sys_ni_syscall /* sys_swapon */ - .long _sys_reboot - .long _sys_ni_syscall /* old_readdir */ - .long _sys_ni_syscall /* sys_mmap */ /* 90 */ - .long _sys_munmap - .long _sys_truncate - .long _sys_ftruncate - .long _sys_fchmod - .long _sys_fchown /* fchown16 */ /* 95 */ - .long _sys_getpriority - .long _sys_setpriority - .long _sys_ni_syscall /* old profil syscall holder */ - .long _sys_statfs - .long _sys_fstatfs /* 100 */ - .long _sys_ni_syscall - .long _sys_ni_syscall /* old sys_socketcall */ - .long _sys_syslog - .long _sys_setitimer - .long _sys_getitimer /* 105 */ - .long _sys_newstat - .long _sys_newlstat - .long _sys_newfstat - .long _sys_ni_syscall /* old uname */ - .long _sys_ni_syscall /* iopl for i386 */ /* 110 */ - .long _sys_vhangup - .long _sys_ni_syscall /* obsolete idle() syscall */ - .long _sys_ni_syscall /* vm86old for i386 */ - .long _sys_wait4 - .long _sys_ni_syscall /* 115 */ /* sys_swapoff */ - .long _sys_sysinfo - .long _sys_ni_syscall /* old sys_ipc */ - .long _sys_fsync - .long _sys_ni_syscall /* old sys_sigreturn */ - .long _sys_clone /* 120 */ - .long _sys_setdomainname - .long _sys_newuname - .long _sys_ni_syscall /* old sys_modify_ldt */ - .long _sys_adjtimex - .long _sys_ni_syscall /* 125 */ /* sys_mprotect */ - .long _sys_ni_syscall /* old sys_sigprocmask */ - .long _sys_ni_syscall /* old "creat_module" */ - .long _sys_init_module - .long _sys_delete_module - .long _sys_ni_syscall /* 130: old "get_kernel_syms" */ - .long _sys_quotactl - .long _sys_getpgid - .long _sys_fchdir - .long _sys_bdflush - .long _sys_ni_syscall /* 135 */ /* sys_sysfs */ - .long _sys_personality - .long _sys_ni_syscall /* for afs_syscall */ - .long _sys_setfsuid /* setfsuid16 */ - .long _sys_setfsgid /* setfsgid16 */ - .long _sys_llseek /* 140 */ - .long _sys_getdents - .long _sys_ni_syscall /* sys_select */ - .long _sys_flock - .long _sys_ni_syscall /* sys_msync */ - .long _sys_readv /* 145 */ - .long _sys_writev - .long _sys_getsid - .long _sys_fdatasync - .long _sys_sysctl - .long _sys_ni_syscall /* 150 */ /* sys_mlock */ - .long _sys_ni_syscall /* sys_munlock */ - .long _sys_ni_syscall /* sys_mlockall */ - .long _sys_ni_syscall /* sys_munlockall */ - .long _sys_sched_setparam - .long _sys_sched_getparam /* 155 */ - .long _sys_sched_setscheduler - .long _sys_sched_getscheduler - .long _sys_sched_yield - .long _sys_sched_get_priority_max - .long _sys_sched_get_priority_min /* 160 */ - .long _sys_sched_rr_get_interval - .long _sys_nanosleep - .long _sys_ni_syscall /* sys_mremap */ - .long _sys_setresuid /* setresuid16 */ - .long _sys_getresuid /* getresuid16 */ /* 165 */ - .long _sys_ni_syscall /* for vm86 */ - .long _sys_ni_syscall /* old "query_module" */ - .long _sys_ni_syscall /* sys_poll */ - .long _sys_ni_syscall /* sys_nfsservctl */ - .long _sys_setresgid /* setresgid16 */ /* 170 */ - .long _sys_getresgid /* getresgid16 */ - .long _sys_prctl - .long _sys_rt_sigreturn - .long _sys_rt_sigaction - .long _sys_rt_sigprocmask /* 175 */ - .long _sys_rt_sigpending - .long _sys_rt_sigtimedwait - .long _sys_rt_sigqueueinfo - .long _sys_rt_sigsuspend - .long _sys_pread64 /* 180 */ - .long _sys_pwrite64 - .long _sys_lchown /* lchown16 */ - .long _sys_getcwd - .long _sys_capget - .long _sys_capset /* 185 */ - .long _sys_sigaltstack - .long _sys_sendfile - .long _sys_ni_syscall /* streams1 */ - .long _sys_ni_syscall /* streams2 */ - .long _sys_vfork /* 190 */ - .long _sys_getrlimit - .long _sys_mmap2 - .long _sys_truncate64 - .long _sys_ftruncate64 - .long _sys_stat64 /* 195 */ - .long _sys_lstat64 - .long _sys_fstat64 - .long _sys_chown - .long _sys_getuid - .long _sys_getgid /* 200 */ - .long _sys_geteuid - .long _sys_getegid - .long _sys_setreuid - .long _sys_setregid - .long _sys_getgroups /* 205 */ - .long _sys_setgroups - .long _sys_fchown - .long _sys_setresuid - .long _sys_getresuid - .long _sys_setresgid /* 210 */ - .long _sys_getresgid - .long _sys_lchown - .long _sys_setuid - .long _sys_setgid - .long _sys_setfsuid /* 215 */ - .long _sys_setfsgid - .long _sys_pivot_root - .long _sys_ni_syscall /* sys_mincore */ - .long _sys_ni_syscall /* sys_madvise */ - .long _sys_getdents64 /* 220 */ - .long _sys_fcntl64 - .long _sys_ni_syscall /* reserved for TUX */ - .long _sys_ni_syscall - .long _sys_gettid - .long _sys_ni_syscall /* 225 */ /* sys_readahead */ - .long _sys_setxattr - .long _sys_lsetxattr - .long _sys_fsetxattr - .long _sys_getxattr - .long _sys_lgetxattr /* 230 */ - .long _sys_fgetxattr - .long _sys_listxattr - .long _sys_llistxattr - .long _sys_flistxattr - .long _sys_removexattr /* 235 */ - .long _sys_lremovexattr - .long _sys_fremovexattr - .long _sys_tkill - .long _sys_sendfile64 - .long _sys_futex /* 240 */ - .long _sys_sched_setaffinity - .long _sys_sched_getaffinity - .long _sys_ni_syscall /* sys_set_thread_area */ - .long _sys_ni_syscall /* sys_get_thread_area */ - .long _sys_io_setup /* 245 */ - .long _sys_io_destroy - .long _sys_io_getevents - .long _sys_io_submit - .long _sys_io_cancel - .long _sys_ni_syscall /* 250 */ /* sys_alloc_hugepages */ - .long _sys_ni_syscall /* sys_freec_hugepages */ - .long _sys_exit_group - .long _sys_lookup_dcookie - .long _sys_bfin_spinlock - .long _sys_epoll_create /* 255 */ - .long _sys_epoll_ctl - .long _sys_epoll_wait - .long _sys_ni_syscall /* remap_file_pages */ - .long _sys_set_tid_address - .long _sys_timer_create /* 260 */ - .long _sys_timer_settime - .long _sys_timer_gettime - .long _sys_timer_getoverrun - .long _sys_timer_delete - .long _sys_clock_settime /* 265 */ - .long _sys_clock_gettime - .long _sys_clock_getres - .long _sys_clock_nanosleep - .long _sys_statfs64 - .long _sys_fstatfs64 /* 270 */ - .long _sys_tgkill - .long _sys_utimes - .long _sys_fadvise64_64 - .long _sys_ni_syscall /* vserver */ - .long _sys_ni_syscall /* 275, mbind */ - .long _sys_ni_syscall /* get_mempolicy */ - .long _sys_ni_syscall /* set_mempolicy */ - .long _sys_mq_open - .long _sys_mq_unlink - .long _sys_mq_timedsend /* 280 */ - .long _sys_mq_timedreceive - .long _sys_mq_notify - .long _sys_mq_getsetattr - .long _sys_ni_syscall /* kexec_load */ - .long _sys_waitid /* 285 */ - .long _sys_add_key - .long _sys_request_key - .long _sys_keyctl - .long _sys_ioprio_set - .long _sys_ioprio_get /* 290 */ - .long _sys_inotify_init - .long _sys_inotify_add_watch - .long _sys_inotify_rm_watch - .long _sys_ni_syscall /* migrate_pages */ - .long _sys_openat /* 295 */ - .long _sys_mkdirat - .long _sys_mknodat - .long _sys_fchownat - .long _sys_futimesat - .long _sys_fstatat64 /* 300 */ - .long _sys_unlinkat - .long _sys_renameat - .long _sys_linkat - .long _sys_symlinkat - .long _sys_readlinkat /* 305 */ - .long _sys_fchmodat - .long _sys_faccessat - .long _sys_pselect6 - .long _sys_ppoll - .long _sys_unshare /* 310 */ - .long _sys_sram_alloc - .long _sys_sram_free - .long _sys_dma_memcpy - .long _sys_accept - .long _sys_bind /* 315 */ - .long _sys_connect - .long _sys_getpeername - .long _sys_getsockname - .long _sys_getsockopt - .long _sys_listen /* 320 */ - .long _sys_recv - .long _sys_recvfrom - .long _sys_recvmsg - .long _sys_send - .long _sys_sendmsg /* 325 */ - .long _sys_sendto - .long _sys_setsockopt - .long _sys_shutdown - .long _sys_socket - .long _sys_socketpair /* 330 */ - .long _sys_semctl - .long _sys_semget - .long _sys_semop - .long _sys_msgctl - .long _sys_msgget /* 335 */ - .long _sys_msgrcv - .long _sys_msgsnd - .long _sys_shmat - .long _sys_shmctl - .long _sys_shmdt /* 340 */ - .long _sys_shmget - .rept NR_syscalls-(.-_sys_call_table)/4 - .long _sys_ni_syscall - .endr -_excpt_saved_imask: - .long 0; - -_exception_stack: - .rept 1024 - .long 0; - .endr -_exception_stack_top: - -#if defined(ANOMALY_05000261) -/* Used by the assembly entry point to work around an anomaly. */ -_last_cplb_fault_retx: - .long 0; -#endif -/* - * Single instructions can have multiple faults, which need to be - * handled by traps.c, in irq5. We store the exception cause to ensure - * we don't miss a double fault condition - */ -ENTRY(_in_ptr_excause) - .long 0; -ENTRY(_out_ptr_excause) - .long 0; -ALIGN -ENTRY(_excause_circ_buf) - .rept 4 - .long 0 - .endr diff --git a/trunk/arch/blackfin/mach-common/interrupt.S b/trunk/arch/blackfin/mach-common/interrupt.S deleted file mode 100644 index dd45664f0d02..000000000000 --- a/trunk/arch/blackfin/mach-common/interrupt.S +++ /dev/null @@ -1,253 +0,0 @@ -/* - * File: arch/blackfin/mach-common/interrupt.S - * Based on: - * Author: D. Jeff Dionne - * Kenneth Albanowski - * - * Created: ? - * Description: Interrupt Entries - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include - -#include - -#ifdef CONFIG_I_ENTRY_L1 -.section .l1.text -#else -.text -#endif - -.align 4 /* just in case */ - -/* - * initial interrupt handlers - */ - -#ifndef CONFIG_KGDB - /* interrupt routine for emulation - 0 */ - /* Currently used only if GDB stub is not in - invalid */ - /* gdb-stub set the evt itself */ - /* save registers for post-mortem only */ -ENTRY(_evt_emulation) - SAVE_ALL_SYS -#ifdef CONFIG_FRAME_POINTER - fp = 0; -#endif - r0 = IRQ_EMU; - r1 = sp; - SP += -12; - call _irq_panic; - SP += 12; - /* - GDB stub fills this in by itself (if defined) */ - rte; -#endif - -/* Common interrupt entry code. First we do CLI, then push - * RETI, to keep interrupts disabled, but to allow this state to be changed - * by local_bh_enable. - * R0 contains the interrupt number, while R1 may contain the value of IPEND, - * or garbage if IPEND won't be needed by the ISR. */ -__common_int_entry: - [--sp] = fp; - [--sp] = usp; - - [--sp] = i0; - [--sp] = i1; - [--sp] = i2; - [--sp] = i3; - - [--sp] = m0; - [--sp] = m1; - [--sp] = m2; - [--sp] = m3; - - [--sp] = l0; - [--sp] = l1; - [--sp] = l2; - [--sp] = l3; - - [--sp] = b0; - [--sp] = b1; - [--sp] = b2; - [--sp] = b3; - [--sp] = a0.x; - [--sp] = a0.w; - [--sp] = a1.x; - [--sp] = a1.w; - - [--sp] = LC0; - [--sp] = LC1; - [--sp] = LT0; - [--sp] = LT1; - [--sp] = LB0; - [--sp] = LB1; - - [--sp] = ASTAT; - - [--sp] = r0; /* Skip reserved */ - [--sp] = RETS; - r2 = RETI; - [--sp] = r2; - [--sp] = RETX; - [--sp] = RETN; - [--sp] = RETE; - [--sp] = SEQSTAT; - [--sp] = r1; /* IPEND - R1 may or may not be set up before jumping here. */ - - /* Switch to other method of keeping interrupts disabled. */ -#ifdef CONFIG_DEBUG_HWERR - r1 = 0x3f; - sti r1; -#else - cli r1; -#endif - [--sp] = RETI; /* orig_pc */ - /* Clear all L registers. */ - r1 = 0 (x); - l0 = r1; - l1 = r1; - l2 = r1; - l3 = r1; -#ifdef CONFIG_FRAME_POINTER - fp = 0; -#endif - -#ifdef ANOMALY_05000283 - cc = r7 == r7; - p5.h = 0xffc0; - p5.l = 0x0014; - if cc jump 1f; - r7.l = W[p5]; -1: -#endif - r1 = sp; - SP += -12; - call _do_irq; - SP += 12; - call _return_from_int; -.Lcommon_restore_context: - RESTORE_CONTEXT - rti; - -/* interrupt routine for ivhw - 5 */ -ENTRY(_evt_ivhw) - SAVE_CONTEXT -#ifdef CONFIG_FRAME_POINTER - fp = 0; -#endif -#ifdef ANOMALY_05000283 - cc = r7 == r7; - p5.h = 0xffc0; - p5.l = 0x0014; - if cc jump 1f; - r7.l = W[p5]; -1: -#endif - p0.l = lo(TBUFCTL); - p0.h = hi(TBUFCTL); - r0 = 1; - [p0] = r0; - r0 = IRQ_HWERR; - r1 = sp; - -#ifdef CONFIG_HARDWARE_PM - r7 = SEQSTAT; - r7 = r7 >>> 0xe; - r6 = 0x1F; - r7 = r7 & r6; - r5 = 0x12; - cc = r7 == r5; - if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */ -#endif - - SP += -12; - call _irq_panic; - SP += 12; - rti; -#ifdef CONFIG_HARDWARE_PM -.Lcall_do_ovf: - - SP += -12; - call _pm_overflow; - SP += 12; - - jump .Lcommon_restore_context; -#endif - -/* interrupt routine for evt2 - 2. This is NMI. */ -ENTRY(_evt_evt2) - SAVE_CONTEXT -#ifdef CONFIG_FRAME_POINTER - fp = 0; -#endif -#ifdef ANOMALY_05000283 - cc = r7 == r7; - p5.h = 0xffc0; - p5.l = 0x0014; - if cc jump 1f; - r7.l = W[p5]; -1: -#endif - r0 = IRQ_NMI; - r1 = sp; - SP += -12; - call _asm_do_IRQ; - SP += 12; - RESTORE_CONTEXT - rtn; - -/* interrupt routine for core timer - 6 */ -ENTRY(_evt_timer) - TIMER_INTERRUPT_ENTRY(EVT_IVTMR_P) - -/* interrupt routine for evt7 - 7 */ -ENTRY(_evt_evt7) - INTERRUPT_ENTRY(EVT_IVG7_P) -ENTRY(_evt_evt8) - INTERRUPT_ENTRY(EVT_IVG8_P) -ENTRY(_evt_evt9) - INTERRUPT_ENTRY(EVT_IVG9_P) -ENTRY(_evt_evt10) - INTERRUPT_ENTRY(EVT_IVG10_P) -ENTRY(_evt_evt11) - INTERRUPT_ENTRY(EVT_IVG11_P) -ENTRY(_evt_evt12) - INTERRUPT_ENTRY(EVT_IVG12_P) -ENTRY(_evt_evt13) - INTERRUPT_ENTRY(EVT_IVG13_P) - - - /* interrupt routine for system_call - 15 */ -ENTRY(_evt_system_call) - SAVE_CONTEXT_SYSCALL -#ifdef CONFIG_FRAME_POINTER - fp = 0; -#endif - call _system_call; - jump .Lcommon_restore_context; diff --git a/trunk/arch/blackfin/mach-common/ints-priority-dc.c b/trunk/arch/blackfin/mach-common/ints-priority-dc.c deleted file mode 100644 index f3cf07036c2a..000000000000 --- a/trunk/arch/blackfin/mach-common/ints-priority-dc.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * File: arch/blackfin/mach-common/ints-priority-dc.c - * Based on: - * Author: - * - * Created: ? - * Description: Set up the interupt priorities - * - * Modified: - * 1996 Roman Zippel - * 1999 D. Jeff Dionne - * 2000-2001 Lineo, Inc. D. Jefff Dionne - * 2002 Arcturus Networks Inc. MaTed - * 2003 Metrowerks/Motorola - * 2003 Bas Vermeulen - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#ifdef CONFIG_KGDB -#include -#endif -#include -#include -#include -#include - -/* - * NOTES: - * - we have separated the physical Hardware interrupt from the - * levels that the LINUX kernel sees (see the description in irq.h) - * - - */ - -unsigned long irq_flags = 0; - -/* The number of spurious interrupts */ -atomic_t num_spurious; - -struct ivgx { - /* irq number for request_irq, available in mach-bf561/irq.h */ - int irqno; - /* corresponding bit in the SICA_ISR0 register */ - int isrflag0; - /* corresponding bit in the SICA_ISR1 register */ - int isrflag1; -} ivg_table[NR_PERI_INTS]; - -struct ivg_slice { - /* position of first irq in ivg_table for given ivg */ - struct ivgx *ifirst; - struct ivgx *istop; -} ivg7_13[IVG13 - IVG7 + 1]; - -static void search_IAR(void); - -/* - * Search SIC_IAR and fill tables with the irqvalues - * and their positions in the SIC_ISR register. - */ -static void __init search_IAR(void) -{ - unsigned ivg, irq_pos = 0; - for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { - int irqn; - - ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = &ivg_table[irq_pos]; - - for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { - int iar_shift = (irqn & 7) * 4; - if (ivg == - (0xf & - bfin_read32((unsigned long *)SICA_IAR0 + - (irqn >> 3)) >> iar_shift)) { - ivg_table[irq_pos].irqno = IVG7 + irqn; - ivg_table[irq_pos].isrflag0 = - (irqn < 32 ? (1 << irqn) : 0); - ivg_table[irq_pos].isrflag1 = - (irqn < 32 ? 0 : (1 << (irqn - 32))); - ivg7_13[ivg].istop++; - irq_pos++; - } - } - } -} - -/* - * This is for BF561 internal IRQs - */ - -static void ack_noop(unsigned int irq) -{ - /* Dummy function. */ -} - -static void bf561_core_mask_irq(unsigned int irq) -{ - irq_flags &= ~(1 << irq); - if (!irqs_disabled()) - local_irq_enable(); -} - -static void bf561_core_unmask_irq(unsigned int irq) -{ - irq_flags |= 1 << irq; - /* - * If interrupts are enabled, IMASK must contain the same value - * as irq_flags. Make sure that invariant holds. If interrupts - * are currently disabled we need not do anything; one of the - * callers will take care of setting IMASK to the proper value - * when reenabling interrupts. - * local_irq_enable just does "STI irq_flags", so it's exactly - * what we need. - */ - if (!irqs_disabled()) - local_irq_enable(); - return; -} - -static void bf561_internal_mask_irq(unsigned int irq) -{ - unsigned long irq_mask; - if ((irq - (IRQ_CORETMR + 1)) < 32) { - irq_mask = (1 << (irq - (IRQ_CORETMR + 1))); - bfin_write_SICA_IMASK0(bfin_read_SICA_IMASK0() & ~irq_mask); - } else { - irq_mask = (1 << (irq - (IRQ_CORETMR + 1) - 32)); - bfin_write_SICA_IMASK1(bfin_read_SICA_IMASK1() & ~irq_mask); - } -} - -static void bf561_internal_unmask_irq(unsigned int irq) -{ - unsigned long irq_mask; - - if ((irq - (IRQ_CORETMR + 1)) < 32) { - irq_mask = (1 << (irq - (IRQ_CORETMR + 1))); - bfin_write_SICA_IMASK0(bfin_read_SICA_IMASK0() | irq_mask); - } else { - irq_mask = (1 << (irq - (IRQ_CORETMR + 1) - 32)); - bfin_write_SICA_IMASK1(bfin_read_SICA_IMASK1() | irq_mask); - } - SSYNC(); -} - -static struct irq_chip bf561_core_irqchip = { - .ack = ack_noop, - .mask = bf561_core_mask_irq, - .unmask = bf561_core_unmask_irq, -}; - -static struct irq_chip bf561_internal_irqchip = { - .ack = ack_noop, - .mask = bf561_internal_mask_irq, - .unmask = bf561_internal_unmask_irq, -}; - -#ifdef CONFIG_IRQCHIP_DEMUX_GPIO -static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; -static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; - -static void bf561_gpio_ack_irq(unsigned int irq) -{ - u16 gpionr = irq - IRQ_PF0; - - if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { - set_gpio_data(gpionr, 0); - SSYNC(); - } -} - -static void bf561_gpio_mask_ack_irq(unsigned int irq) -{ - u16 gpionr = irq - IRQ_PF0; - - if(gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { - set_gpio_data(gpionr, 0); - SSYNC(); - } - - set_gpio_maska(gpionr, 0); - SSYNC(); -} - -static void bf561_gpio_mask_irq(unsigned int irq) -{ - set_gpio_maska(irq - IRQ_PF0, 0); - SSYNC(); -} - -static void bf561_gpio_unmask_irq(unsigned int irq) -{ - set_gpio_maska(irq - IRQ_PF0, 1); - SSYNC(); -} - -static unsigned int bf561_gpio_irq_startup(unsigned int irq) -{ - unsigned int ret; - u16 gpionr = irq - IRQ_PF0; - - if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { - - ret = gpio_request(gpionr, NULL); - if(ret) - return ret; - - } - - gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); - bf561_gpio_unmask_irq(irq); - - return ret; - -} - -static void bf561_gpio_irq_shutdown(unsigned int irq) -{ - bf561_gpio_mask_irq(irq); - gpio_free(irq - IRQ_PF0); - gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); -} - -static int bf561_gpio_irq_type(unsigned int irq, unsigned int type) -{ - - unsigned int ret; - u16 gpionr = irq - IRQ_PF0; - - - if (type == IRQ_TYPE_PROBE) { - /* only probe unenabled GPIO interrupt lines */ - if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) - return 0; - type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; - - } - - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | - IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { - - if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { - - ret = gpio_request(gpionr, NULL); - if(ret) - return ret; - - } - - gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); - } else { - gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); - return 0; - } - - - set_gpio_dir(gpionr, 0); - set_gpio_inen(gpionr, 1); - - - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { - gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr); - set_gpio_edge(gpionr, 1); - } else { - set_gpio_edge(gpionr, 0); - gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); - } - - if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) - == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) - set_gpio_both(gpionr, 1); - else - set_gpio_both(gpionr, 0); - - if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) - set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */ - else - set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */ - - SSYNC(); - - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) - set_irq_handler(irq, handle_edge_irq); - else - set_irq_handler(irq, handle_level_irq); - - return 0; -} - -static struct irq_chip bf561_gpio_irqchip = { - .ack = bf561_gpio_ack_irq, - .mask = bf561_gpio_mask_irq, - .mask_ack = bf561_gpio_mask_ack_irq, - .unmask = bf561_gpio_unmask_irq, - .set_type = bf561_gpio_irq_type, - .startup = bf561_gpio_irq_startup, - .shutdown = bf561_gpio_irq_shutdown -}; - -static void bf561_demux_gpio_irq(unsigned int inta_irq, - struct irq_desc *intb_desc) -{ - int irq, flag_d, mask; - u16 gpio; - - switch (inta_irq) { - case IRQ_PROG0_INTA: - irq = IRQ_PF0; - break; - case IRQ_PROG1_INTA: - irq = IRQ_PF16; - break; - case IRQ_PROG2_INTA: - irq = IRQ_PF32; - break; - default: - dump_stack(); - return; - } - - gpio = irq - IRQ_PF0; - - flag_d = get_gpiop_data(gpio); - mask = flag_d & (gpio_enabled[gpio_bank(gpio)] & - get_gpiop_maska(gpio)); - - do { - if (mask & 1) { - struct irq_desc *desc = irq_desc + irq; - desc->handle_irq(irq, desc); - } - irq++; - mask >>= 1; - } while (mask); - - -} - -#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ - -/* - * This function should be called during kernel startup to initialize - * the BFin IRQ handling routines. - */ -int __init init_arch_irq(void) -{ - int irq; - unsigned long ilat = 0; - /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ - bfin_write_SICA_IMASK0(SIC_UNMASK_ALL); - bfin_write_SICA_IMASK1(SIC_UNMASK_ALL); - SSYNC(); - - local_irq_disable(); - - init_exception_buff(); - -#ifndef CONFIG_KGDB - bfin_write_EVT0(evt_emulation); -#endif - bfin_write_EVT2(evt_evt2); - bfin_write_EVT3(trap); - bfin_write_EVT5(evt_ivhw); - bfin_write_EVT6(evt_timer); - bfin_write_EVT7(evt_evt7); - bfin_write_EVT8(evt_evt8); - bfin_write_EVT9(evt_evt9); - bfin_write_EVT10(evt_evt10); - bfin_write_EVT11(evt_evt11); - bfin_write_EVT12(evt_evt12); - bfin_write_EVT13(evt_evt13); - bfin_write_EVT14(evt14_softirq); - bfin_write_EVT15(evt_system_call); - CSYNC(); - - for (irq = 0; irq < SYS_IRQS; irq++) { - if (irq <= IRQ_CORETMR) - set_irq_chip(irq, &bf561_core_irqchip); - else - set_irq_chip(irq, &bf561_internal_irqchip); -#ifdef CONFIG_IRQCHIP_DEMUX_GPIO - if ((irq != IRQ_PROG0_INTA) && - (irq != IRQ_PROG1_INTA) && (irq != IRQ_PROG2_INTA)) { -#endif - set_irq_handler(irq, handle_simple_irq); -#ifdef CONFIG_IRQCHIP_DEMUX_GPIO - } else { - set_irq_chained_handler(irq, bf561_demux_gpio_irq); - } -#endif - - } - -#ifdef CONFIG_IRQCHIP_DEMUX_GPIO - for (irq = IRQ_PF0; irq <= IRQ_PF47; irq++) { - set_irq_chip(irq, &bf561_gpio_irqchip); - /* if configured as edge, then will be changed to do_edge_IRQ */ - set_irq_handler(irq, handle_level_irq); - } -#endif - bfin_write_IMASK(0); - CSYNC(); - ilat = bfin_read_ILAT(); - CSYNC(); - bfin_write_ILAT(ilat); - CSYNC(); - - printk(KERN_INFO "Configuring Blackfin Priority Driven Interrupts\n"); - /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, - * local_irq_enable() - */ - program_IAR(); - /* Therefore it's better to setup IARs before interrupts enabled */ - search_IAR(); - - /* Enable interrupts IVG7-15 */ - irq_flags = irq_flags | IMASK_IVG15 | - IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | - IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW; - - return 0; -} - -#ifdef CONFIG_DO_IRQ_L1 -void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); -#endif - -void do_irq(int vec, struct pt_regs *fp) -{ - if (vec == EVT_IVTMR_P) { - vec = IRQ_CORETMR; - } else { - struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; - struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; - unsigned long sic_status0, sic_status1; - - SSYNC(); - sic_status0 = bfin_read_SICA_IMASK0() & bfin_read_SICA_ISR0(); - sic_status1 = bfin_read_SICA_IMASK1() & bfin_read_SICA_ISR1(); - - for (;; ivg++) { - if (ivg >= ivg_stop) { - atomic_inc(&num_spurious); - return; - } else if ((sic_status0 & ivg->isrflag0) || - (sic_status1 & ivg->isrflag1)) - break; - } - vec = ivg->irqno; - } - asm_do_IRQ(vec, fp); - -#ifdef CONFIG_KGDB - kgdb_process_breakpoint(); -#endif -} diff --git a/trunk/arch/blackfin/mach-common/ints-priority-sc.c b/trunk/arch/blackfin/mach-common/ints-priority-sc.c deleted file mode 100644 index 34b62288ec3c..000000000000 --- a/trunk/arch/blackfin/mach-common/ints-priority-sc.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - * File: arch/blackfin/mach-common/ints-priority-sc.c - * Based on: - * Author: - * - * Created: ? - * Description: Set up the interupt priorities - * - * Modified: - * 1996 Roman Zippel - * 1999 D. Jeff Dionne - * 2000-2001 Lineo, Inc. D. Jefff Dionne - * 2002 Arcturus Networks Inc. MaTed - * 2003 Metrowerks/Motorola - * 2003 Bas Vermeulen - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#ifdef CONFIG_KGDB -#include -#endif -#include -#include -#include -#include - -#ifdef BF537_FAMILY -# define BF537_GENERIC_ERROR_INT_DEMUX -#else -# undef BF537_GENERIC_ERROR_INT_DEMUX -#endif - -/* - * NOTES: - * - we have separated the physical Hardware interrupt from the - * levels that the LINUX kernel sees (see the description in irq.h) - * - - */ - -unsigned long irq_flags = 0; - -/* The number of spurious interrupts */ -atomic_t num_spurious; - -struct ivgx { - /* irq number for request_irq, available in mach-bf533/irq.h */ - int irqno; - /* corresponding bit in the SIC_ISR register */ - int isrflag; -} ivg_table[NR_PERI_INTS]; - -struct ivg_slice { - /* position of first irq in ivg_table for given ivg */ - struct ivgx *ifirst; - struct ivgx *istop; -} ivg7_13[IVG13 - IVG7 + 1]; - -static void search_IAR(void); - -/* - * Search SIC_IAR and fill tables with the irqvalues - * and their positions in the SIC_ISR register. - */ -static void __init search_IAR(void) -{ - unsigned ivg, irq_pos = 0; - for (ivg = 0; ivg <= IVG13 - IVG7; ivg++) { - int irqn; - - ivg7_13[ivg].istop = ivg7_13[ivg].ifirst = - &ivg_table[irq_pos]; - - for (irqn = 0; irqn < NR_PERI_INTS; irqn++) { - int iar_shift = (irqn & 7) * 4; - if (ivg == - (0xf & - bfin_read32((unsigned long *) SIC_IAR0 + - (irqn >> 3)) >> iar_shift)) { - ivg_table[irq_pos].irqno = IVG7 + irqn; - ivg_table[irq_pos].isrflag = 1 << irqn; - ivg7_13[ivg].istop++; - irq_pos++; - } - } - } -} - -/* - * This is for BF533 internal IRQs - */ - -static void ack_noop(unsigned int irq) -{ - /* Dummy function. */ -} - -static void bfin_core_mask_irq(unsigned int irq) -{ - irq_flags &= ~(1 << irq); - if (!irqs_disabled()) - local_irq_enable(); -} - -static void bfin_core_unmask_irq(unsigned int irq) -{ - irq_flags |= 1 << irq; - /* - * If interrupts are enabled, IMASK must contain the same value - * as irq_flags. Make sure that invariant holds. If interrupts - * are currently disabled we need not do anything; one of the - * callers will take care of setting IMASK to the proper value - * when reenabling interrupts. - * local_irq_enable just does "STI irq_flags", so it's exactly - * what we need. - */ - if (!irqs_disabled()) - local_irq_enable(); - return; -} - -static void bfin_internal_mask_irq(unsigned int irq) -{ - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << (irq - (IRQ_CORETMR + 1)))); - SSYNC(); -} - -static void bfin_internal_unmask_irq(unsigned int irq) -{ - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | - (1 << (irq - (IRQ_CORETMR + 1)))); - SSYNC(); -} - -static struct irq_chip bfin_core_irqchip = { - .ack = ack_noop, - .mask = bfin_core_mask_irq, - .unmask = bfin_core_unmask_irq, -}; - -static struct irq_chip bfin_internal_irqchip = { - .ack = ack_noop, - .mask = bfin_internal_mask_irq, - .unmask = bfin_internal_unmask_irq, -}; - -#ifdef BF537_GENERIC_ERROR_INT_DEMUX -static int error_int_mask; - -static void bfin_generic_error_ack_irq(unsigned int irq) -{ - -} - -static void bfin_generic_error_mask_irq(unsigned int irq) -{ - error_int_mask &= ~(1L << (irq - IRQ_PPI_ERROR)); - - if (!error_int_mask) { - local_irq_disable(); - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & - ~(1 << - (IRQ_GENERIC_ERROR - - (IRQ_CORETMR + 1)))); - SSYNC(); - local_irq_enable(); - } -} - -static void bfin_generic_error_unmask_irq(unsigned int irq) -{ - local_irq_disable(); - bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 1 << - (IRQ_GENERIC_ERROR - (IRQ_CORETMR + 1))); - SSYNC(); - local_irq_enable(); - - error_int_mask |= 1L << (irq - IRQ_PPI_ERROR); -} - -static struct irq_chip bfin_generic_error_irqchip = { - .ack = bfin_generic_error_ack_irq, - .mask = bfin_generic_error_mask_irq, - .unmask = bfin_generic_error_unmask_irq, -}; - -static void bfin_demux_error_irq(unsigned int int_err_irq, - struct irq_desc *intb_desc) -{ - int irq = 0; - - SSYNC(); - -#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) - if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK) - irq = IRQ_MAC_ERROR; - else -#endif - if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK) - irq = IRQ_SPORT0_ERROR; - else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK) - irq = IRQ_SPORT1_ERROR; - else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK) - irq = IRQ_PPI_ERROR; - else if (bfin_read_CAN_GIF() & CAN_ERR_MASK) - irq = IRQ_CAN_ERROR; - else if (bfin_read_SPI_STAT() & SPI_ERR_MASK) - irq = IRQ_SPI_ERROR; - else if ((bfin_read_UART0_IIR() & UART_ERR_MASK_STAT1) && - (bfin_read_UART0_IIR() & UART_ERR_MASK_STAT0)) - irq = IRQ_UART0_ERROR; - else if ((bfin_read_UART1_IIR() & UART_ERR_MASK_STAT1) && - (bfin_read_UART1_IIR() & UART_ERR_MASK_STAT0)) - irq = IRQ_UART1_ERROR; - - if (irq) { - if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) { - struct irq_desc *desc = irq_desc + irq; - desc->handle_irq(irq, desc); - } else { - - switch (irq) { - case IRQ_PPI_ERROR: - bfin_write_PPI_STATUS(PPI_ERR_MASK); - break; -#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) - case IRQ_MAC_ERROR: - bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK); - break; -#endif - case IRQ_SPORT0_ERROR: - bfin_write_SPORT0_STAT(SPORT_ERR_MASK); - break; - - case IRQ_SPORT1_ERROR: - bfin_write_SPORT1_STAT(SPORT_ERR_MASK); - break; - - case IRQ_CAN_ERROR: - bfin_write_CAN_GIS(CAN_ERR_MASK); - break; - - case IRQ_SPI_ERROR: - bfin_write_SPI_STAT(SPI_ERR_MASK); - break; - - default: - break; - } - - pr_debug("IRQ %d:" - " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n", - irq); - } - } else - printk(KERN_ERR - "%s : %s : LINE %d :\nIRQ ?: PERIPHERAL ERROR" - " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n", - __FUNCTION__, __FILE__, __LINE__); - - -} -#endif /* BF537_GENERIC_ERROR_INT_DEMUX */ - -#ifdef CONFIG_IRQCHIP_DEMUX_GPIO - -static unsigned short gpio_enabled[gpio_bank(MAX_BLACKFIN_GPIOS)]; -static unsigned short gpio_edge_triggered[gpio_bank(MAX_BLACKFIN_GPIOS)]; - -static void bfin_gpio_ack_irq(unsigned int irq) -{ - u16 gpionr = irq - IRQ_PF0; - - if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { - set_gpio_data(gpionr, 0); - SSYNC(); - } -} - -static void bfin_gpio_mask_ack_irq(unsigned int irq) -{ - u16 gpionr = irq - IRQ_PF0; - - if (gpio_edge_triggered[gpio_bank(gpionr)] & gpio_bit(gpionr)) { - set_gpio_data(gpionr, 0); - SSYNC(); - } - - set_gpio_maska(gpionr, 0); - SSYNC(); -} - -static void bfin_gpio_mask_irq(unsigned int irq) -{ - set_gpio_maska(irq - IRQ_PF0, 0); - SSYNC(); -} - -static void bfin_gpio_unmask_irq(unsigned int irq) -{ - set_gpio_maska(irq - IRQ_PF0, 1); - SSYNC(); -} - -static unsigned int bfin_gpio_irq_startup(unsigned int irq) -{ - unsigned int ret; - u16 gpionr = irq - IRQ_PF0; - - if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { - ret = gpio_request(gpionr, NULL); - if (ret) - return ret; - } - - gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); - bfin_gpio_unmask_irq(irq); - - return ret; -} - -static void bfin_gpio_irq_shutdown(unsigned int irq) -{ - bfin_gpio_mask_irq(irq); - gpio_free(irq - IRQ_PF0); - gpio_enabled[gpio_bank(irq - IRQ_PF0)] &= ~gpio_bit(irq - IRQ_PF0); -} - -static int bfin_gpio_irq_type(unsigned int irq, unsigned int type) -{ - - unsigned int ret; - u16 gpionr = irq - IRQ_PF0; - - if (type == IRQ_TYPE_PROBE) { - /* only probe unenabled GPIO interrupt lines */ - if (gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr)) - return 0; - type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; - } - - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING | - IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) - { - if (!(gpio_enabled[gpio_bank(gpionr)] & gpio_bit(gpionr))) { - ret = gpio_request(gpionr, NULL); - if (ret) - return ret; - } - - gpio_enabled[gpio_bank(gpionr)] |= gpio_bit(gpionr); - } else { - gpio_enabled[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); - return 0; - } - - set_gpio_dir(gpionr, 0); - set_gpio_inen(gpionr, 1); - - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { - gpio_edge_triggered[gpio_bank(gpionr)] |= gpio_bit(gpionr); - set_gpio_edge(gpionr, 1); - } else { - set_gpio_edge(gpionr, 0); - gpio_edge_triggered[gpio_bank(gpionr)] &= ~gpio_bit(gpionr); - } - - if ((type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) - == (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) - set_gpio_both(gpionr, 1); - else - set_gpio_both(gpionr, 0); - - if ((type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW))) - set_gpio_polar(gpionr, 1); /* low or falling edge denoted by one */ - else - set_gpio_polar(gpionr, 0); /* high or rising edge denoted by zero */ - - SSYNC(); - - if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) - set_irq_handler(irq, handle_edge_irq); - else - set_irq_handler(irq, handle_level_irq); - - return 0; -} - - -static struct irq_chip bfin_gpio_irqchip = { - .ack = bfin_gpio_ack_irq, - .mask = bfin_gpio_mask_irq, - .mask_ack = bfin_gpio_mask_ack_irq, - .unmask = bfin_gpio_unmask_irq, - .set_type = bfin_gpio_irq_type, - .startup = bfin_gpio_irq_startup, - .shutdown = bfin_gpio_irq_shutdown -}; - -static void bfin_demux_gpio_irq(unsigned int intb_irq, - struct irq_desc *intb_desc) -{ - u16 i; - - for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=16) { - int irq = IRQ_PF0 + i; - int flag_d = get_gpiop_data(i); - int mask = - flag_d & (gpio_enabled[gpio_bank(i)] & - get_gpiop_maska(i)); - - while (mask) { - if (mask & 1) { - struct irq_desc *desc = irq_desc + irq; - desc->handle_irq(irq, desc); - } - irq++; - mask >>= 1; - } - } -} - -#endif /* CONFIG_IRQCHIP_DEMUX_GPIO */ - -/* - * This function should be called during kernel startup to initialize - * the BFin IRQ handling routines. - */ -int __init init_arch_irq(void) -{ - int irq; - unsigned long ilat = 0; - /* Disable all the peripheral intrs - page 4-29 HW Ref manual */ - bfin_write_SIC_IMASK(SIC_UNMASK_ALL); - SSYNC(); - - local_irq_disable(); - -#ifndef CONFIG_KGDB - bfin_write_EVT0(evt_emulation); -#endif - bfin_write_EVT2(evt_evt2); - bfin_write_EVT3(trap); - bfin_write_EVT5(evt_ivhw); - bfin_write_EVT6(evt_timer); - bfin_write_EVT7(evt_evt7); - bfin_write_EVT8(evt_evt8); - bfin_write_EVT9(evt_evt9); - bfin_write_EVT10(evt_evt10); - bfin_write_EVT11(evt_evt11); - bfin_write_EVT12(evt_evt12); - bfin_write_EVT13(evt_evt13); - bfin_write_EVT14(evt14_softirq); - bfin_write_EVT15(evt_system_call); - CSYNC(); - - for (irq = 0; irq < SYS_IRQS; irq++) { - if (irq <= IRQ_CORETMR) - set_irq_chip(irq, &bfin_core_irqchip); - else - set_irq_chip(irq, &bfin_internal_irqchip); -#ifdef BF537_GENERIC_ERROR_INT_DEMUX - if (irq != IRQ_GENERIC_ERROR) { -#endif - -#ifdef CONFIG_IRQCHIP_DEMUX_GPIO - if ((irq != IRQ_PROG_INTA) /*PORT F & G MASK_A Interrupt*/ -# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)) - && (irq != IRQ_MAC_RX) /*PORT H MASK_A Interrupt*/ -# endif - ) { -#endif - set_irq_handler(irq, handle_simple_irq); -#ifdef CONFIG_IRQCHIP_DEMUX_GPIO - } else { - set_irq_chained_handler(irq, - bfin_demux_gpio_irq); - } -#endif - -#ifdef BF537_GENERIC_ERROR_INT_DEMUX - } else { - set_irq_handler(irq, bfin_demux_error_irq); - } -#endif - } -#ifdef BF537_GENERIC_ERROR_INT_DEMUX - for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++) { - set_irq_chip(irq, &bfin_generic_error_irqchip); - set_irq_handler(irq, handle_level_irq); - } -#endif - -#ifdef CONFIG_IRQCHIP_DEMUX_GPIO - for (irq = IRQ_PF0; irq < NR_IRQS; irq++) { - set_irq_chip(irq, &bfin_gpio_irqchip); - /* if configured as edge, then will be changed to do_edge_IRQ */ - set_irq_handler(irq, handle_level_irq); - } -#endif - bfin_write_IMASK(0); - CSYNC(); - ilat = bfin_read_ILAT(); - CSYNC(); - bfin_write_ILAT(ilat); - CSYNC(); - - printk(KERN_INFO - "Configuring Blackfin Priority Driven Interrupts\n"); - /* IMASK=xxx is equivalent to STI xx or irq_flags=xx, - * local_irq_enable() - */ - program_IAR(); - /* Therefore it's better to setup IARs before interrupts enabled */ - search_IAR(); - - /* Enable interrupts IVG7-15 */ - irq_flags = irq_flags | IMASK_IVG15 | - IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 | - IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | - IMASK_IVGHW; - - return 0; -} - -#ifdef CONFIG_DO_IRQ_L1 -void do_irq(int vec, struct pt_regs *fp)__attribute__((l1_text)); -#endif - -void do_irq(int vec, struct pt_regs *fp) -{ - if (vec == EVT_IVTMR_P) { - vec = IRQ_CORETMR; - } else { - struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst; - struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop; - unsigned long sic_status; - - SSYNC(); - sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR(); - - for (;; ivg++) { - if (ivg >= ivg_stop) { - atomic_inc(&num_spurious); - return; - } else if (sic_status & ivg->isrflag) - break; - } - vec = ivg->irqno; - } - asm_do_IRQ(vec, fp); - -#ifdef CONFIG_KGDB - kgdb_process_breakpoint(); -#endif -} diff --git a/trunk/arch/blackfin/mach-common/irqpanic.c b/trunk/arch/blackfin/mach-common/irqpanic.c deleted file mode 100644 index f05e3dadaf33..000000000000 --- a/trunk/arch/blackfin/mach-common/irqpanic.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * File: arch/blackfin/mach-common/irqpanic.c - * Based on: - * Author: - * - * Created: ? - * Description: panic kernel with dump information - * - * Modified: rgetz - added cache checking code 14Feb06 - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include "../oprofile/op_blackfin.h" - -#ifdef CONFIG_DEBUG_ICACHE_CHECK -#define L1_ICACHE_START 0xffa10000 -#define L1_ICACHE_END 0xffa13fff -void irq_panic(int reason, struct pt_regs *regs) __attribute__ ((l1_text)); -#endif - -/* - * irq_panic - calls panic with string setup - */ -asmlinkage void irq_panic(int reason, struct pt_regs *regs) -{ - int sig = 0; - siginfo_t info; - -#ifdef CONFIG_DEBUG_ICACHE_CHECK - unsigned int cmd, tag, ca, cache_hi, cache_lo, *pa; - unsigned short i, j, die; - unsigned int bad[10][6]; - - /* check entire cache for coherency - * Since printk is in cacheable memory, - * don't call it until you have checked everything - */ - - die = 0; - i = 0; - - /* check icache */ - - for (ca = L1_ICACHE_START; ca <= L1_ICACHE_END && i < 10; ca += 32) { - - /* Grab various address bits for the itest_cmd fields */ - cmd = (((ca & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */ - ((ca & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */ - ((ca & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */ - 0); /* Access Tag, Read access */ - - SSYNC(); - bfin_write_ITEST_COMMAND(cmd); - SSYNC(); - tag = bfin_read_ITEST_DATA0(); - SSYNC(); - - /* if tag is marked as valid, check it */ - if (tag & 1) { - /* The icache is arranged in 4 groups of 64-bits */ - for (j = 0; j < 32; j += 8) { - cmd = ((((ca + j) & 0x3000) << 4) | /* ca[13:12] for SBNK[1:0] */ - (((ca + j) & 0x0c00) << 16) | /* ca[11:10] for WAYSEL[1:0] */ - (((ca + j) & 0x3f8)) | /* ca[09:03] for SET[4:0] and DW[1:0] */ - 4); /* Access Data, Read access */ - - SSYNC(); - bfin_write_ITEST_COMMAND(cmd); - SSYNC(); - - cache_hi = bfin_read_ITEST_DATA1(); - cache_lo = bfin_read_ITEST_DATA0(); - - pa = ((unsigned int *)((tag & 0xffffcc00) | - ((ca + j) & ~(0xffffcc00)))); - - /* - * Debugging this, enable - * - * printk("addr: %08x %08x%08x | %08x%08x\n", - * ((unsigned int *)((tag & 0xffffcc00) | ((ca+j) & ~(0xffffcc00)))), - * cache_hi, cache_lo, *(pa+1), *pa); - */ - - if (cache_hi != *(pa + 1) || cache_lo != *pa) { - /* Since icache is not working, stay out of it, by not printing */ - die = 1; - bad[i][0] = (ca + j); - bad[i][1] = cache_hi; - bad[i][2] = cache_lo; - bad[i][3] = ((tag & 0xffffcc00) | - ((ca + j) & ~(0xffffcc00))); - bad[i][4] = *(pa + 1); - bad[i][5] = *(pa); - i++; - } - } - } - } - if (die) { - printk(KERN_EMERG "icache coherency error\n"); - for (j = 0; j <= i; j++) { - printk(KERN_EMERG - "cache address : %08x cache value : %08x%08x\n", - bad[j][0], bad[j][1], bad[j][2]); - printk(KERN_EMERG - "physical address: %08x SDRAM value : %08x%08x\n", - bad[j][3], bad[j][4], bad[j][5]); - } - panic("icache coherency error"); - } else { - printk(KERN_EMERG "icache checked, and OK\n"); - } -#endif - - printk(KERN_EMERG "\n"); - printk(KERN_EMERG "Exception: IRQ 0x%x entered\n", reason); - printk(KERN_EMERG " code=[0x%08lx], stack frame=0x%08lx, " - " bad PC=0x%08lx\n", - (unsigned long)regs->seqstat, - (unsigned long)regs, - (unsigned long)regs->pc); - if (reason == 0x5) { - printk(KERN_EMERG "----------- HARDWARE ERROR -----------\n"); - - /* There is only need to check for Hardware Errors, since other - * EXCEPTIONS are handled in TRAPS.c (MH) - */ - switch (regs->seqstat & SEQSTAT_HWERRCAUSE) { - case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): /* System MMR Error */ - info.si_code = BUS_ADRALN; - sig = SIGBUS; - printk(KERN_EMERG HWC_x2); - break; - case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): /* External Memory Addressing Error */ - info.si_code = BUS_ADRERR; - sig = SIGBUS; - printk(KERN_EMERG HWC_x3); - break; - case (SEQSTAT_HWERRCAUSE_PERF_FLOW): /* Performance Monitor Overflow */ - printk(KERN_EMERG HWC_x12); - break; - case (SEQSTAT_HWERRCAUSE_RAISE_5): /* RAISE 5 instruction */ - printk(KERN_EMERG HWC_x18); - break; - default: /* Reserved */ - printk(KERN_EMERG HWC_default); - break; - } - } - - regs->ipend = bfin_read_IPEND(); - dump_bfin_regs(regs, (void *)regs->pc); - if (0 == (info.si_signo = sig) || 0 == user_mode(regs)) /* in kernelspace */ - panic("Unhandled IRQ or exceptions!\n"); - else { /* in userspace */ - info.si_errno = 0; - info.si_addr = (void *)regs->pc; - force_sig_info(sig, &info, current); - } -} - -#ifdef CONFIG_HARDWARE_PM -/* - * call the handler of Performance overflow - */ -asmlinkage void pm_overflow(int irq, struct pt_regs *regs) -{ - pm_overflow_handler(irq, regs); -} -#endif diff --git a/trunk/arch/blackfin/mach-common/lock.S b/trunk/arch/blackfin/mach-common/lock.S deleted file mode 100644 index 2cbb15b33925..000000000000 --- a/trunk/arch/blackfin/mach-common/lock.S +++ /dev/null @@ -1,204 +0,0 @@ -/* - * File: arch/blackfin/mach-common/lock.S - * Based on: - * Author: LG Soft India - * - * Created: ? - * Description: kernel locks - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -.text - -#ifdef CONFIG_BLKFIN_CACHE_LOCK - -/* When you come here, it is assumed that - * R0 - Which way to be locked - */ - -ENTRY(_cache_grab_lock) - - [--SP]=( R7:0,P5:0 ); - - P1.H = (IMEM_CONTROL >> 16); - P1.L = (IMEM_CONTROL & 0xFFFF); - P5.H = (ICPLB_ADDR0 >> 16); - P5.L = (ICPLB_ADDR0 & 0xFFFF); - P4.H = (ICPLB_DATA0 >> 16); - P4.L = (ICPLB_DATA0 & 0xFFFF); - R7 = R0; - - /* If the code of interest already resides in the cache - * invalidate the entire cache itself. - * invalidate_entire_icache; - */ - - SP += -12; - [--SP] = RETS; - CALL _invalidate_entire_icache; - RETS = [SP++]; - SP += 12; - - /* Disable the Interrupts*/ - - CLI R3; - -.LLOCK_WAY: - - /* Way0 - 0xFFA133E0 - * Way1 - 0xFFA137E0 - * Way2 - 0xFFA13BE0 Total Way Size = 4K - * Way3 - 0xFFA13FE0 - */ - - /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1] - * Only Way0 of the instruction cache can now be - * replaced by a new code - */ - - R5 = R7; - CC = BITTST(R7,0); - IF CC JUMP .LCLEAR1; - R7 = 0; - BITSET(R7,0); - JUMP .LDONE1; - -.LCLEAR1: - R7 = 0; - BITCLR(R7,0); -.LDONE1: R4 = R7 << 3; - R7 = [P1]; - R7 = R7 | R4; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - - R7 = R5; - CC = BITTST(R7,1); - IF CC JUMP .LCLEAR2; - R7 = 0; - BITSET(R7,1); - JUMP .LDONE2; - -.LCLEAR2: - R7 = 0; - BITCLR(R7,1); -.LDONE2: R4 = R7 << 3; - R7 = [P1]; - R7 = R7 | R4; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - - R7 = R5; - CC = BITTST(R7,2); - IF CC JUMP .LCLEAR3; - R7 = 0; - BITSET(R7,2); - JUMP .LDONE3; -.LCLEAR3: - R7 = 0; - BITCLR(R7,2); -.LDONE3: R4 = R7 << 3; - R7 = [P1]; - R7 = R7 | R4; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - - - R7 = R5; - CC = BITTST(R7,3); - IF CC JUMP .LCLEAR4; - R7 = 0; - BITSET(R7,3); - JUMP .LDONE4; -.LCLEAR4: - R7 = 0; - BITCLR(R7,3); -.LDONE4: R4 = R7 << 3; - R7 = [P1]; - R7 = R7 | R4; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - - STI R3; - - ( R7:0,P5:0 ) = [SP++]; - - RTS; - -/* After the execution of critical code, the code is now locked into - * the cache way. Now we need to set ILOC. - * - * R0 - Which way to be locked - */ - -ENTRY(_cache_lock) - - [--SP]=( R7:0,P5:0 ); - - P1.H = (IMEM_CONTROL >> 16); - P1.L = (IMEM_CONTROL & 0xFFFF); - - /* Disable the Interrupts*/ - CLI R3; - - R7 = [P1]; - R2 = 0xFFFFFF87 (X); - R7 = R7 & R2; - R0 = R0 << 3; - R7 = R0 | R7; - SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ - .align 8; - [P1] = R7; - SSYNC; - /* Renable the Interrupts */ - STI R3; - - ( R7:0,P5:0 ) = [SP++]; - RTS; - -#endif /* BLKFIN_CACHE_LOCK */ - -/* Return the ILOC bits of IMEM_CONTROL - */ - -ENTRY(_read_iloc) - - P1.H = (IMEM_CONTROL >> 16); - P1.L = (IMEM_CONTROL & 0xFFFF); - R1 = 0xF; - R0 = [P1]; - R0 = R0 >> 3; - R0 = R0 & R1; - - RTS; diff --git a/trunk/arch/blackfin/mach-common/pm.c b/trunk/arch/blackfin/mach-common/pm.c deleted file mode 100644 index deb27272c658..000000000000 --- a/trunk/arch/blackfin/mach-common/pm.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * File: arch/blackfin/mach-common/pm.c - * Based on: arm/mach-omap/pm.c - * Author: Cliff Brake Copyright (c) 2001 - * - * Created: 2001 - * Description: Power management for the bfin - * - * Modified: Nicolas Pitre - PXA250 support - * Copyright (c) 2002 Monta Vista Software, Inc. - * David Singleton - OMAP1510 - * Copyright (c) 2002 Monta Vista Software, Inc. - * Dirk Behme - OMAP1510/1610 - * Copyright 2004 - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#include -#include -#include - - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H -#define WAKEUP_TYPE PM_WAKE_HIGH -#endif - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_L -#define WAKEUP_TYPE PM_WAKE_LOW -#endif - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_F -#define WAKEUP_TYPE PM_WAKE_FALLING -#endif - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_R -#define WAKEUP_TYPE PM_WAKE_RISING -#endif - -#ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_EDGE_B -#define WAKEUP_TYPE PM_WAKE_BOTH_EDGES -#endif - -void bfin_pm_suspend_standby_enter(void) -{ -#ifdef CONFIG_PM_WAKEUP_BY_GPIO - gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); -#endif - -#if defined(CONFIG_PM_WAKEUP_BY_GPIO) || defined(CONFIG_PM_WAKEUP_GPIO_API) - { - u32 flags; - - local_irq_save(flags); - - sleep_deeper(gpio_pm_setup()); /*Goto Sleep*/ - - gpio_pm_restore(); - - bfin_write_SIC_IWR(IWR_ENABLE_ALL); - - local_irq_restore(flags); - } -#endif - -#if defined(CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR) - sleep_deeper(CONFIG_PM_WAKEUP_SIC_IWR); - bfin_write_SIC_IWR(IWR_ENABLE_ALL); -#endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ -} - - -/* - * bfin_pm_prepare - Do preliminary suspend work. - * @state: suspend state we're entering. - * - */ -static int bfin_pm_prepare(suspend_state_t state) -{ - int error = 0; - - switch (state) { - case PM_SUSPEND_STANDBY: - break; - case PM_SUSPEND_MEM: - return -ENOTSUPP; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return error; -} - -/* - * bfin_pm_enter - Actually enter a sleep state. - * @state: State we're entering. - * - */ -static int bfin_pm_enter(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_STANDBY: - bfin_pm_suspend_standby_enter(); - break; - case PM_SUSPEND_MEM: - return -ENOTSUPP; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return 0; -} - -/* - * bfin_pm_finish - Finish up suspend sequence. - * @state: State we're coming out of. - * - * This is called after we wake back up (or if entering the sleep state - * failed). - */ -static int bfin_pm_finish(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_STANDBY: - break; - - case PM_SUSPEND_MEM: - return -ENOTSUPP; - - case PM_SUSPEND_DISK: - return -ENOTSUPP; - - default: - return -EINVAL; - } - - return 0; -} - -struct pm_ops bfin_pm_ops = { - .pm_disk_mode = PM_DISK_PLATFORM, - .prepare = bfin_pm_prepare, - .enter = bfin_pm_enter, - .finish = bfin_pm_finish, -}; - -static int __init bfin_pm_init(void) -{ - pm_set_ops(&bfin_pm_ops); - return 0; -} - -__initcall(bfin_pm_init); diff --git a/trunk/arch/blackfin/mm/Makefile b/trunk/arch/blackfin/mm/Makefile deleted file mode 100644 index 2a7202ce01fd..000000000000 --- a/trunk/arch/blackfin/mm/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# arch/blackfin/mm/Makefile -# - -obj-y := blackfin_sram.o init.o diff --git a/trunk/arch/blackfin/mm/blackfin_sram.c b/trunk/arch/blackfin/mm/blackfin_sram.c deleted file mode 100644 index dd0c6501c424..000000000000 --- a/trunk/arch/blackfin/mm/blackfin_sram.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * File: arch/blackfin/mm/blackfin_sram.c - * Based on: - * Author: - * - * Created: - * Description: SRAM driver for Blackfin ADSP-BF5xx - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "blackfin_sram.h" - -spinlock_t l1sram_lock, l1_data_sram_lock, l1_inst_sram_lock; - -#if CONFIG_L1_MAX_PIECE < 16 -#undef CONFIG_L1_MAX_PIECE -#define CONFIG_L1_MAX_PIECE 16 -#endif - -#if CONFIG_L1_MAX_PIECE > 1024 -#undef CONFIG_L1_MAX_PIECE -#define CONFIG_L1_MAX_PIECE 1024 -#endif - -#define SRAM_SLT_NULL 0 -#define SRAM_SLT_FREE 1 -#define SRAM_SLT_ALLOCATED 2 - -/* the data structure for L1 scratchpad and DATA SRAM */ -struct l1_sram_piece { - void *paddr; - int size; - int flag; -}; - -static struct l1_sram_piece l1_ssram[CONFIG_L1_MAX_PIECE]; - -#if L1_DATA_A_LENGTH != 0 -static struct l1_sram_piece l1_data_A_sram[CONFIG_L1_MAX_PIECE]; -#endif - -#if L1_DATA_B_LENGTH != 0 -static struct l1_sram_piece l1_data_B_sram[CONFIG_L1_MAX_PIECE]; -#endif - -#if L1_CODE_LENGTH != 0 -static struct l1_sram_piece l1_inst_sram[CONFIG_L1_MAX_PIECE]; -#endif - -/* L1 Scratchpad SRAM initialization function */ -void l1sram_init(void) -{ - printk(KERN_INFO "Blackfin Scratchpad data SRAM: %d KB\n", - L1_SCRATCH_LENGTH >> 10); - - memset(&l1_ssram, 0x00, sizeof(l1_ssram)); - l1_ssram[0].paddr = (void*)L1_SCRATCH_START; - l1_ssram[0].size = L1_SCRATCH_LENGTH; - l1_ssram[0].flag = SRAM_SLT_FREE; - - /* mutex initialize */ - spin_lock_init(&l1sram_lock); -} - -void l1_data_sram_init(void) -{ -#if L1_DATA_A_LENGTH != 0 - printk(KERN_INFO "Blackfin DATA_A SRAM: %d KB\n", - L1_DATA_A_LENGTH >> 10); - - memset(&l1_data_A_sram, 0x00, sizeof(l1_data_A_sram)); - l1_data_A_sram[0].paddr = (void*)L1_DATA_A_START + - (_ebss_l1 - _sdata_l1); - l1_data_A_sram[0].size = L1_DATA_A_LENGTH - (_ebss_l1 - _sdata_l1); - l1_data_A_sram[0].flag = SRAM_SLT_FREE; -#endif -#if L1_DATA_B_LENGTH != 0 - printk(KERN_INFO "Blackfin DATA_B SRAM: %d KB\n", - L1_DATA_B_LENGTH >> 10); - - memset(&l1_data_B_sram, 0x00, sizeof(l1_data_B_sram)); - l1_data_B_sram[0].paddr = (void*)L1_DATA_B_START; - l1_data_B_sram[0].size = L1_DATA_B_LENGTH; - l1_data_B_sram[0].flag = SRAM_SLT_FREE; -#endif - - /* mutex initialize */ - spin_lock_init(&l1_data_sram_lock); -} - -void l1_inst_sram_init(void) -{ -#if L1_CODE_LENGTH != 0 - printk(KERN_INFO "Blackfin Instruction SRAM: %d KB\n", - L1_CODE_LENGTH >> 10); - - memset(&l1_inst_sram, 0x00, sizeof(l1_inst_sram)); - l1_inst_sram[0].paddr = (void*)L1_CODE_START + (_etext_l1 - _stext_l1); - l1_inst_sram[0].size = L1_CODE_LENGTH - (_etext_l1 - _stext_l1); - l1_inst_sram[0].flag = SRAM_SLT_FREE; -#endif - - /* mutex initialize */ - spin_lock_init(&l1_inst_sram_lock); -} - -/* L1 memory allocate function */ -static void *_l1_sram_alloc(size_t size, struct l1_sram_piece *pfree, int count) -{ - int i, index = 0; - void *addr = NULL; - - if (size <= 0) - return NULL; - - /* Align the size */ - size = (size + 3) & ~3; - - /* not use the good method to match the best slot !!! */ - /* search an available memeory slot */ - for (i = 0; i < count; i++) { - if ((pfree[i].flag == SRAM_SLT_FREE) - && (pfree[i].size >= size)) { - addr = pfree[i].paddr; - pfree[i].flag = SRAM_SLT_ALLOCATED; - index = i; - break; - } - } - if (i >= count) - return NULL; - - /* updated the NULL memeory slot !!! */ - if (pfree[i].size > size) { - for (i = 0; i < count; i++) { - if (pfree[i].flag == SRAM_SLT_NULL) { - pfree[i].flag = SRAM_SLT_FREE; - pfree[i].paddr = addr + size; - pfree[i].size = pfree[index].size - size; - pfree[index].size = size; - break; - } - } - } - - return addr; -} - -/* Allocate the largest available block. */ -static void *_l1_sram_alloc_max(struct l1_sram_piece *pfree, int count, - unsigned long *psize) -{ - unsigned long best = 0; - int i, index = -1; - void *addr = NULL; - - /* search an available memeory slot */ - for (i = 0; i < count; i++) { - if (pfree[i].flag == SRAM_SLT_FREE && pfree[i].size > best) { - addr = pfree[i].paddr; - index = i; - best = pfree[i].size; - } - } - if (index < 0) - return NULL; - *psize = best; - - pfree[index].flag = SRAM_SLT_ALLOCATED; - return addr; -} - -/* L1 memory free function */ -static int _l1_sram_free(const void *addr, - struct l1_sram_piece *pfree, int count) -{ - int i, index = 0; - - /* search the relevant memory slot */ - for (i = 0; i < count; i++) { - if (pfree[i].paddr == addr) { - if (pfree[i].flag != SRAM_SLT_ALLOCATED) { - /* error log */ - return -1; - } - index = i; - break; - } - } - if (i >= count) - return -1; - - pfree[index].flag = SRAM_SLT_FREE; - - /* link the next address slot */ - for (i = 0; i < count; i++) { - if (((pfree[index].paddr + pfree[index].size) == pfree[i].paddr) - && (pfree[i].flag == SRAM_SLT_FREE)) { - pfree[i].flag = SRAM_SLT_NULL; - pfree[index].size += pfree[i].size; - pfree[index].flag = SRAM_SLT_FREE; - break; - } - } - - /* link the last address slot */ - for (i = 0; i < count; i++) { - if (((pfree[i].paddr + pfree[i].size) == pfree[index].paddr) && - (pfree[i].flag == SRAM_SLT_FREE)) { - pfree[index].flag = SRAM_SLT_NULL; - pfree[i].size += pfree[index].size; - break; - } - } - - return 0; -} - -int sram_free(const void *addr) -{ - if (0) {} -#if L1_CODE_LENGTH != 0 - else if (addr >= (void *)L1_CODE_START - && addr < (void *)(L1_CODE_START + L1_CODE_LENGTH)) - return l1_inst_sram_free(addr); -#endif -#if L1_DATA_A_LENGTH != 0 - else if (addr >= (void *)L1_DATA_A_START - && addr < (void *)(L1_DATA_A_START + L1_DATA_A_LENGTH)) - return l1_data_A_sram_free(addr); -#endif -#if L1_DATA_B_LENGTH != 0 - else if (addr >= (void *)L1_DATA_B_START - && addr < (void *)(L1_DATA_B_START + L1_DATA_B_LENGTH)) - return l1_data_B_sram_free(addr); -#endif - else - return -1; -} -EXPORT_SYMBOL(sram_free); - -void *l1_data_A_sram_alloc(size_t size) -{ - unsigned flags; - void *addr = NULL; - - /* add mutex operation */ - spin_lock_irqsave(&l1_data_sram_lock, flags); - -#if L1_DATA_A_LENGTH != 0 - addr = _l1_sram_alloc(size, l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); -#endif - - /* add mutex operation */ - spin_unlock_irqrestore(&l1_data_sram_lock, flags); - - pr_debug("Allocated address in l1_data_A_sram_alloc is 0x%lx+0x%lx\n", - (long unsigned int)addr, size); - - return addr; -} -EXPORT_SYMBOL(l1_data_A_sram_alloc); - -int l1_data_A_sram_free(const void *addr) -{ - unsigned flags; - int ret; - - /* add mutex operation */ - spin_lock_irqsave(&l1_data_sram_lock, flags); - -#if L1_DATA_A_LENGTH != 0 - ret = _l1_sram_free(addr, - l1_data_A_sram, ARRAY_SIZE(l1_data_A_sram)); -#else - ret = -1; -#endif - - /* add mutex operation */ - spin_unlock_irqrestore(&l1_data_sram_lock, flags); - - return ret; -} -EXPORT_SYMBOL(l1_data_A_sram_free); - -void *l1_data_B_sram_alloc(size_t size) -{ -#if L1_DATA_B_LENGTH != 0 - unsigned flags; - void *addr; - - /* add mutex operation */ - spin_lock_irqsave(&l1_data_sram_lock, flags); - - addr = _l1_sram_alloc(size, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); - - /* add mutex operation */ - spin_unlock_irqrestore(&l1_data_sram_lock, flags); - - pr_debug("Allocated address in l1_data_B_sram_alloc is 0x%lx+0x%lx\n", - (long unsigned int)addr, size); - - return addr; -#else - return NULL; -#endif -} -EXPORT_SYMBOL(l1_data_B_sram_alloc); - -int l1_data_B_sram_free(const void *addr) -{ -#if L1_DATA_B_LENGTH != 0 - unsigned flags; - int ret; - - /* add mutex operation */ - spin_lock_irqsave(&l1_data_sram_lock, flags); - - ret = _l1_sram_free(addr, l1_data_B_sram, ARRAY_SIZE(l1_data_B_sram)); - - /* add mutex operation */ - spin_unlock_irqrestore(&l1_data_sram_lock, flags); - - return ret; -#else - return -1; -#endif -} -EXPORT_SYMBOL(l1_data_B_sram_free); - -void *l1_data_sram_alloc(size_t size) -{ - void *addr = l1_data_A_sram_alloc(size); - - if (!addr) - addr = l1_data_B_sram_alloc(size); - - return addr; -} -EXPORT_SYMBOL(l1_data_sram_alloc); - -void *l1_data_sram_zalloc(size_t size) -{ - void *addr = l1_data_sram_alloc(size); - - if (addr) - memset(addr, 0x00, size); - - return addr; -} -EXPORT_SYMBOL(l1_data_sram_zalloc); - -int l1_data_sram_free(const void *addr) -{ - int ret; - ret = l1_data_A_sram_free(addr); - if (ret == -1) - ret = l1_data_B_sram_free(addr); - return ret; -} -EXPORT_SYMBOL(l1_data_sram_free); - -void *l1_inst_sram_alloc(size_t size) -{ -#if L1_DATA_A_LENGTH != 0 - unsigned flags; - void *addr; - - /* add mutex operation */ - spin_lock_irqsave(&l1_inst_sram_lock, flags); - - addr = _l1_sram_alloc(size, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); - - /* add mutex operation */ - spin_unlock_irqrestore(&l1_inst_sram_lock, flags); - - pr_debug("Allocated address in l1_inst_sram_alloc is 0x%lx+0x%lx\n", - (long unsigned int)addr, size); - - return addr; -#else - return NULL; -#endif -} -EXPORT_SYMBOL(l1_inst_sram_alloc); - -int l1_inst_sram_free(const void *addr) -{ -#if L1_CODE_LENGTH != 0 - unsigned flags; - int ret; - - /* add mutex operation */ - spin_lock_irqsave(&l1_inst_sram_lock, flags); - - ret = _l1_sram_free(addr, l1_inst_sram, ARRAY_SIZE(l1_inst_sram)); - - /* add mutex operation */ - spin_unlock_irqrestore(&l1_inst_sram_lock, flags); - - return ret; -#else - return -1; -#endif -} -EXPORT_SYMBOL(l1_inst_sram_free); - -/* L1 Scratchpad memory allocate function */ -void *l1sram_alloc(size_t size) -{ - unsigned flags; - void *addr; - - /* add mutex operation */ - spin_lock_irqsave(&l1sram_lock, flags); - - addr = _l1_sram_alloc(size, l1_ssram, ARRAY_SIZE(l1_ssram)); - - /* add mutex operation */ - spin_unlock_irqrestore(&l1sram_lock, flags); - - return addr; -} - -/* L1 Scratchpad memory allocate function */ -void *l1sram_alloc_max(size_t *psize) -{ - unsigned flags; - void *addr; - - /* add mutex operation */ - spin_lock_irqsave(&l1sram_lock, flags); - - addr = _l1_sram_alloc_max(l1_ssram, ARRAY_SIZE(l1_ssram), psize); - - /* add mutex operation */ - spin_unlock_irqrestore(&l1sram_lock, flags); - - return addr; -} - -/* L1 Scratchpad memory free function */ -int l1sram_free(const void *addr) -{ - unsigned flags; - int ret; - - /* add mutex operation */ - spin_lock_irqsave(&l1sram_lock, flags); - - ret = _l1_sram_free(addr, l1_ssram, ARRAY_SIZE(l1_ssram)); - - /* add mutex operation */ - spin_unlock_irqrestore(&l1sram_lock, flags); - - return ret; -} - -int sram_free_with_lsl(const void *addr) -{ - struct sram_list_struct *lsl, **tmp; - struct mm_struct *mm = current->mm; - - for (tmp = &mm->context.sram_list; *tmp; tmp = &(*tmp)->next) - if ((*tmp)->addr == addr) - goto found; - return -1; -found: - lsl = *tmp; - sram_free(addr); - *tmp = lsl->next; - kfree(lsl); - - return 0; -} -EXPORT_SYMBOL(sram_free_with_lsl); - -void *sram_alloc_with_lsl(size_t size, unsigned long flags) -{ - void *addr = NULL; - struct sram_list_struct *lsl = NULL; - struct mm_struct *mm = current->mm; - - lsl = kmalloc(sizeof(struct sram_list_struct), GFP_KERNEL); - if (!lsl) - return NULL; - memset(lsl, 0, sizeof(*lsl)); - - if (flags & L1_INST_SRAM) - addr = l1_inst_sram_alloc(size); - - if (addr == NULL && (flags & L1_DATA_A_SRAM)) - addr = l1_data_A_sram_alloc(size); - - if (addr == NULL && (flags & L1_DATA_B_SRAM)) - addr = l1_data_B_sram_alloc(size); - - if (addr == NULL) { - kfree(lsl); - return NULL; - } - lsl->addr = addr; - lsl->length = size; - lsl->next = mm->context.sram_list; - mm->context.sram_list = lsl; - return addr; -} -EXPORT_SYMBOL(sram_alloc_with_lsl); diff --git a/trunk/arch/blackfin/mm/blackfin_sram.h b/trunk/arch/blackfin/mm/blackfin_sram.h deleted file mode 100644 index 0fb73b78dd60..000000000000 --- a/trunk/arch/blackfin/mm/blackfin_sram.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * File: arch/blackfin/mm/blackfin_sram.h - * Based on: arch/blackfin/mm/blackfin_sram.c - * Author: Mike Frysinger - * - * Created: Aug 2006 - * Description: Local prototypes meant for internal use only - * - * Modified: - * Copyright 2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __BLACKFIN_SRAM_H__ -#define __BLACKFIN_SRAM_H__ - -extern void l1sram_init(void); -extern void l1_inst_sram_init(void); -extern void l1_data_sram_init(void); -extern void *l1sram_alloc(size_t); - -#endif diff --git a/trunk/arch/blackfin/mm/init.c b/trunk/arch/blackfin/mm/init.c deleted file mode 100644 index 73f72abed432..000000000000 --- a/trunk/arch/blackfin/mm/init.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * File: arch/blackfin/mm/init.c - * Based on: - * Author: - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include "blackfin_sram.h" - -/* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving a inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ -static unsigned long empty_bad_page_table; - -static unsigned long empty_bad_page; - -unsigned long empty_zero_page; - -void show_mem(void) -{ - unsigned long i; - int free = 0, total = 0, reserved = 0, shared = 0; - - int cached = 0; - printk(KERN_INFO "Mem-info:\n"); - show_free_areas(); - i = max_mapnr; - while (i-- > 0) { - total++; - if (PageReserved(mem_map + i)) - reserved++; - else if (PageSwapCache(mem_map + i)) - cached++; - else if (!page_count(mem_map + i)) - free++; - else - shared += page_count(mem_map + i) - 1; - } - printk(KERN_INFO "%d pages of RAM\n", total); - printk(KERN_INFO "%d free pages\n", free); - printk(KERN_INFO "%d reserved pages\n", reserved); - printk(KERN_INFO "%d pages shared\n", shared); - printk(KERN_INFO "%d pages swap cached\n", cached); -} - -/* - * paging_init() continues the virtual memory environment setup which - * was begun by the code in arch/head.S. - * The parameters are pointers to where to stick the starting and ending - * addresses of available kernel virtual memory. - */ -void paging_init(void) -{ - /* - * make sure start_mem is page aligned, otherwise bootmem and - * page_alloc get different views og the world - */ - unsigned long end_mem = memory_end & PAGE_MASK; - - pr_debug("start_mem is %#lx virtual_end is %#lx\n", PAGE_ALIGN(memory_start), end_mem); - - /* - * initialize the bad page table and bad page to point - * to a couple of allocated pages - */ - empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); - memset((void *)empty_zero_page, 0, PAGE_SIZE); - - /* - * Set up SFC/DFC registers (user data space) - */ - set_fs(KERNEL_DS); - - pr_debug("free_area_init -> start_mem is %#lx virtual_end is %#lx\n", - PAGE_ALIGN(memory_start), end_mem); - - { - unsigned long zones_size[MAX_NR_ZONES] = { 0, }; - - zones_size[ZONE_NORMAL] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT; -#ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = 0; -#endif - free_area_init(zones_size); - } -} - -void mem_init(void) -{ - unsigned int codek = 0, datak = 0, initk = 0; - unsigned long tmp; - unsigned int len = _ramend - _rambase; - unsigned long start_mem = memory_start; - unsigned long end_mem = memory_end; - - end_mem &= PAGE_MASK; - high_memory = (void *)end_mem; - - start_mem = PAGE_ALIGN(start_mem); - max_mapnr = num_physpages = MAP_NR(high_memory); - printk(KERN_INFO "Physical pages: %lx\n", num_physpages); - - /* This will put all memory onto the freelists. */ - totalram_pages = free_all_bootmem(); - - codek = (_etext - _stext) >> 10; - datak = (__bss_stop - __bss_start) >> 10; - initk = (__init_end - __init_begin) >> 10; - - tmp = nr_free_pages() << PAGE_SHIFT; - printk(KERN_INFO - "Memory available: %luk/%uk RAM, (%uk init code, %uk kernel code, %uk data, %uk dma)\n", - tmp >> 10, len >> 10, initk, codek, datak, DMA_UNCACHED_REGION >> 10); - - /* Initialize the blackfin L1 Memory. */ - l1sram_init(); - l1_data_sram_init(); - l1_inst_sram_init(); - - /* Allocate this once; never free it. We assume this gives us a - pointer to the start of L1 scratchpad memory; panic if it - doesn't. */ - tmp = (unsigned long)l1sram_alloc(sizeof(struct l1_scratch_task_info)); - if (tmp != (unsigned long)L1_SCRATCH_TASK_INFO) { - printk(KERN_EMERG "mem_init(): Did not get the right address from l1sram_alloc: %08lx != %08lx\n", - tmp, (unsigned long)L1_SCRATCH_TASK_INFO); - panic("No L1, time to give up\n"); - } -} - -#ifdef CONFIG_BLK_DEV_INITRD -void free_initrd_mem(unsigned long start, unsigned long end) -{ - int pages = 0; - for (; start < end; start += PAGE_SIZE) { - ClearPageReserved(virt_to_page(start)); - init_page_count(virt_to_page(start)); - free_page(start); - totalram_pages++; - pages++; - } - printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages); -} -#endif - -void free_initmem(void) -{ -#ifdef CONFIG_RAMKERNEL - unsigned long addr; -/* - * the following code should be cool even if these sections - * are not page aligned. - */ - addr = PAGE_ALIGN((unsigned long)(__init_begin)); - /* next to check that the page we free is not a partial page */ - for (; addr + PAGE_SIZE < (unsigned long)(__init_end); - addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); - free_page(addr); - totalram_pages++; - } - printk(KERN_NOTICE - "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n", - (addr - PAGE_ALIGN((long)__init_begin)) >> 10, - (int)(PAGE_ALIGN((unsigned long)(__init_begin))), - (int)(addr - PAGE_SIZE)); -#endif -} diff --git a/trunk/arch/blackfin/oprofile/Kconfig b/trunk/arch/blackfin/oprofile/Kconfig deleted file mode 100644 index 0a2fd999c941..000000000000 --- a/trunk/arch/blackfin/oprofile/Kconfig +++ /dev/null @@ -1,29 +0,0 @@ -menu "Profiling support" -depends on EXPERIMENTAL - -config PROFILING - bool "Profiling support (EXPERIMENTAL)" - help - Say Y here to enable the extended profiling support mechanisms used - by profilers such as OProfile. - -config OPROFILE - tristate "OProfile system profiling (EXPERIMENTAL)" - depends on PROFILING - help - OProfile is a profiling system capable of profiling the - whole system, include the kernel, kernel modules, libraries, - and applications. - - If unsure, say N. - -config HARDWARE_PM - tristate "Hardware Performance Monitor Profiling" - depends on PROFILING - help - take use of hardware performance monitor to profiling the kernel - and application. - - If unsure, say N. - -endmenu diff --git a/trunk/arch/blackfin/oprofile/Makefile b/trunk/arch/blackfin/oprofile/Makefile deleted file mode 100644 index 634e300d67e2..000000000000 --- a/trunk/arch/blackfin/oprofile/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# arch/blackfin/oprofile/Makefile -# - -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) common.o -oprofile-$(CONFIG_HARDWARE_PM) += op_model_bf533.o diff --git a/trunk/arch/blackfin/oprofile/common.c b/trunk/arch/blackfin/oprofile/common.c deleted file mode 100644 index 009a1700c854..000000000000 --- a/trunk/arch/blackfin/oprofile/common.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * File: arch/blackfin/oprofile/common.c - * Based on: arch/alpha/oprofile/common.c - * Author: Anton Blanchard - * - * Created: - * Description: - * - * Modified: - * Copyright (C) 2004 Anton Blanchard , IBM - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "op_blackfin.h" - -#define BFIN_533_ID 0xE5040003 -#define BFIN_537_ID 0xE5040002 - -static int pfmon_enabled; -static struct mutex pfmon_lock; - -struct op_bfin533_model *model; - -struct op_counter_config ctr[OP_MAX_COUNTER]; - -static int op_bfin_setup(void) -{ - int ret; - - /* Pre-compute the values to stuff in the hardware registers. */ - spin_lock(&oprofilefs_lock); - ret = model->reg_setup(ctr); - spin_unlock(&oprofilefs_lock); - - return ret; -} - -static void op_bfin_shutdown(void) -{ -#if 0 - /* what is the difference between shutdown and stop? */ -#endif -} - -static int op_bfin_start(void) -{ - int ret = -EBUSY; - - printk(KERN_INFO "KSDBG:in %s\n", __FUNCTION__); - mutex_lock(&pfmon_lock); - if (!pfmon_enabled) { - ret = model->start(ctr); - pfmon_enabled = !ret; - } - mutex_unlock(&pfmon_lock); - - return ret; -} - -static void op_bfin_stop(void) -{ - mutex_lock(&pfmon_lock); - if (pfmon_enabled) { - model->stop(); - pfmon_enabled = 0; - } - mutex_unlock(&pfmon_lock); -} - -static int op_bfin_create_files(struct super_block *sb, struct dentry *root) -{ - int i; - - for (i = 0; i < model->num_counters; ++i) { - struct dentry *dir; - char buf[3]; - printk(KERN_INFO "Oprofile: creating files... \n"); - - snprintf(buf, sizeof buf, "%d", i); - dir = oprofilefs_mkdir(sb, root, buf); - - oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); - oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); - oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); - /* - * We dont support per counter user/kernel selection, but - * we leave the entries because userspace expects them - */ - oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); - oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); - oprofilefs_create_ulong(sb, dir, "unit_mask", - &ctr[i].unit_mask); - } - - return 0; -} -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ -#ifdef CONFIG_HARDWARE_PM - unsigned int dspid; - - mutex_init(&pfmon_lock); - - dspid = bfin_read_DSPID(); - - printk(KERN_INFO "Oprofile got the cpu id is 0x%x. \n", dspid); - - switch (dspid) { - case BFIN_533_ID: - model = &op_model_bfin533; - model->num_counters = 2; - break; - case BFIN_537_ID: - model = &op_model_bfin533; - model->num_counters = 2; - break; - default: - return -ENODEV; - } - - ops->cpu_type = model->name; - ops->create_files = op_bfin_create_files; - ops->setup = op_bfin_setup; - ops->shutdown = op_bfin_shutdown; - ops->start = op_bfin_start; - ops->stop = op_bfin_stop; - - printk(KERN_INFO "oprofile: using %s performance monitoring.\n", - ops->cpu_type); - - return 0; -#else - return -1; -#endif -} - -void oprofile_arch_exit(void) -{ -} diff --git a/trunk/arch/blackfin/oprofile/op_blackfin.h b/trunk/arch/blackfin/oprofile/op_blackfin.h deleted file mode 100644 index f88f446c814f..000000000000 --- a/trunk/arch/blackfin/oprofile/op_blackfin.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * File: arch/blackfin/oprofile/op_blackfin.h - * Based on: - * Author: Anton Blanchard - * - * Created: - * Description: - * - * Modified: - * Copyright (C) 2004 Anton Blanchard , IBM - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OP_BLACKFIN_H -#define OP_BLACKFIN_H 1 - -#define OP_MAX_COUNTER 2 - -#include - -/* Per-counter configuration as set via oprofilefs. */ -struct op_counter_config { - unsigned long valid; - unsigned long enabled; - unsigned long event; - unsigned long count; - unsigned long kernel; - unsigned long user; - unsigned long unit_mask; -}; - -/* System-wide configuration as set via oprofilefs. */ -struct op_system_config { - unsigned long enable_kernel; - unsigned long enable_user; -}; - -/* Per-arch configuration */ -struct op_bfin533_model { - int (*reg_setup) (struct op_counter_config *); - int (*start) (struct op_counter_config *); - void (*stop) (void); - int num_counters; - char *name; -}; - -extern struct op_bfin533_model op_model_bfin533; - -static inline unsigned int ctr_read(void) -{ - unsigned int tmp; - - tmp = bfin_read_PFCTL(); - __builtin_bfin_csync(); - - return tmp; -} - -static inline void ctr_write(unsigned int val) -{ - bfin_write_PFCTL(val); - __builtin_bfin_csync(); -} - -static inline void count_read(unsigned int *count) -{ - count[0] = bfin_read_PFCNTR0(); - count[1] = bfin_read_PFCNTR1(); - __builtin_bfin_csync(); -} - -static inline void count_write(unsigned int *count) -{ - bfin_write_PFCNTR0(count[0]); - bfin_write_PFCNTR1(count[1]); - __builtin_bfin_csync(); -} - -extern int pm_overflow_handler(int irq, struct pt_regs *regs); - -#endif diff --git a/trunk/arch/blackfin/oprofile/op_model_bf533.c b/trunk/arch/blackfin/oprofile/op_model_bf533.c deleted file mode 100644 index b7a20a006b49..000000000000 --- a/trunk/arch/blackfin/oprofile/op_model_bf533.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * File: arch/blackfin/oprofile/op_model_bf533.c - * Based on: - * Author: Anton Blanchard - * - * Created: - * Description: - * - * Modified: - * Copyright (C) 2004 Anton Blanchard , IBM - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "op_blackfin.h" - -#define PM_ENABLE 0x01; -#define PM_CTL1_ENABLE 0x18 -#define PM_CTL0_ENABLE 0xC000 -#define COUNT_EDGE_ONLY 0x3000000 - -static int oprofile_running; - -static unsigned curr_pfctl, curr_count[2]; - -static int bfin533_reg_setup(struct op_counter_config *ctr) -{ - unsigned int pfctl = ctr_read(); - unsigned int count[2]; - - /* set Blackfin perf monitor regs with ctr */ - if (ctr[0].enabled) { - pfctl |= (PM_CTL0_ENABLE | ((char)ctr[0].event << 5)); - count[0] = 0xFFFFFFFF - ctr[0].count; - curr_count[0] = count[0]; - } - if (ctr[1].enabled) { - pfctl |= (PM_CTL1_ENABLE | ((char)ctr[1].event << 16)); - count[1] = 0xFFFFFFFF - ctr[1].count; - curr_count[1] = count[1]; - } - - pr_debug("ctr[0].enabled=%d,ctr[1].enabled=%d,ctr[0].event<<5=0x%x,ctr[1].event<<16=0x%x\n", ctr[0].enabled, ctr[1].enabled, ctr[0].event << 5, ctr[1].event << 16); - pfctl |= COUNT_EDGE_ONLY; - curr_pfctl = pfctl; - - pr_debug("write 0x%x to pfctl\n", pfctl); - ctr_write(pfctl); - count_write(count); - - return 0; -} - -static int bfin533_start(struct op_counter_config *ctr) -{ - unsigned int pfctl = ctr_read(); - - pfctl |= PM_ENABLE; - curr_pfctl = pfctl; - - ctr_write(pfctl); - - oprofile_running = 1; - pr_debug("start oprofile counter \n"); - - return 0; -} - -static void bfin533_stop(void) -{ - int pfctl; - - pfctl = ctr_read(); - pfctl &= ~PM_ENABLE; - /* freeze counters */ - ctr_write(pfctl); - - oprofile_running = 0; - pr_debug("stop oprofile counter \n"); -} - -static int get_kernel(void) -{ - int ipend, is_kernel; - - ipend = bfin_read_IPEND(); - - /* test bit 15 */ - is_kernel = ((ipend & 0x8000) != 0); - - return is_kernel; -} - -int pm_overflow_handler(int irq, struct pt_regs *regs) -{ - int is_kernel; - int i, cpu; - unsigned int pc, pfctl; - unsigned int count[2]; - - pr_debug("get interrupt in %s\n", __FUNCTION__); - if (oprofile_running == 0) { - pr_debug("error: entering interrupt when oprofile is stopped.\n\r"); - return -1; - } - - is_kernel = get_kernel(); - cpu = smp_processor_id(); - pc = regs->pc; - pfctl = ctr_read(); - - /* read the two event counter regs */ - count_read(count); - - /* if the counter overflows, add sample to oprofile buffer */ - for (i = 0; i < 2; ++i) { - if (oprofile_running) { - oprofile_add_sample(regs, i); - } - } - - /* reset the perfmon counter */ - ctr_write(curr_pfctl); - count_write(curr_count); - return 0; -} - -struct op_bfin533_model op_model_bfin533 = { - .reg_setup = bfin533_reg_setup, - .start = bfin533_start, - .stop = bfin533_stop, - .num_counters = 2, - .name = "blackfin/bf533" -}; diff --git a/trunk/arch/blackfin/oprofile/timer_int.c b/trunk/arch/blackfin/oprofile/timer_int.c deleted file mode 100644 index 8fba16c846c9..000000000000 --- a/trunk/arch/blackfin/oprofile/timer_int.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * File: arch/blackfin/oprofile/timer_int.c - * Based on: - * Author: Michael Kang - * - * Created: - * Description: - * - * Modified: - * Copyright 2004-2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -#include - -static void enable_sys_timer0() -{ -} -static void disable_sys_timer0() -{ -} - -static irqreturn_t sys_timer0_int_handler(int irq, void *dev_id, - struct pt_regs *regs) -{ - oprofile_add_sample(regs, 0); - return IRQ_HANDLED; -} - -static int sys_timer0_start(void) -{ - enable_sys_timer0(); - return request_irq(IVG11, sys_timer0_int_handler, 0, "sys_timer0", NULL); -} - -static void sys_timer0_stop(void) -{ - disable_sys_timer(); -} - -int __init sys_timer0_init(struct oprofile_operations *ops) -{ - extern int nmi_active; - - if (nmi_active <= 0) - return -ENODEV; - - ops->start = timer_start; - ops->stop = timer_stop; - ops->cpu_type = "timer"; - printk(KERN_INFO "oprofile: using NMI timer interrupt.\n"); - return 0; -} diff --git a/trunk/arch/cris/arch-v10/kernel/ptrace.c b/trunk/arch/cris/arch-v10/kernel/ptrace.c index fd2129a04586..961c0d58ded4 100644 --- a/trunk/arch/cris/arch-v10/kernel/ptrace.c +++ b/trunk/arch/cris/arch-v10/kernel/ptrace.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/cris/arch-v10/kernel/signal.c b/trunk/arch/cris/arch-v10/kernel/signal.c index 41d4a5f93284..19bcad05716f 100644 --- a/trunk/arch/cris/arch-v10/kernel/signal.c +++ b/trunk/arch/cris/arch-v10/kernel/signal.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/cris/arch-v32/drivers/pci/dma.c b/trunk/arch/cris/arch-v32/drivers/pci/dma.c index 832fc63504d4..70d3bf0c92e8 100644 --- a/trunk/arch/cris/arch-v32/drivers/pci/dma.c +++ b/trunk/arch/cris/arch-v32/drivers/pci/dma.c @@ -76,7 +76,7 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, { void __iomem *mem_base; int pages = size >> PAGE_SHIFT; - int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); + int bitmap_size = (pages + 31)/32; if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) goto out; diff --git a/trunk/arch/cris/arch-v32/kernel/fasttimer.c b/trunk/arch/cris/arch-v32/kernel/fasttimer.c index 79e1e4c2ca1d..5daeb6f7f3b7 100644 --- a/trunk/arch/cris/arch-v32/kernel/fasttimer.c +++ b/trunk/arch/cris/arch-v32/kernel/fasttimer.c @@ -603,8 +603,23 @@ void schedule_usleep(unsigned long us) #ifdef CONFIG_PROC_FS static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) + ,int *eof, void *data_unused +#else + ,int unused +#endif + ); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) static struct proc_dir_entry *fasttimer_proc_entry; +#else +static struct proc_dir_entry fasttimer_proc_entry = +{ + 0, 9, "fasttimer", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, NULL /* ops -- default to array */, + &proc_fasttimer_read /* get_info */, +}; +#endif #endif /* CONFIG_PROC_FS */ #ifdef CONFIG_PROC_FS @@ -613,7 +628,12 @@ static struct proc_dir_entry *fasttimer_proc_entry; #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300) static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) + ,int *eof, void *data_unused +#else + ,int unused +#endif + ) { unsigned long flags; int i = 0; @@ -788,7 +808,9 @@ static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len memcpy(buf, bigbuf + offset, len); *start = buf; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) *eof = 1; +#endif return len; } @@ -952,8 +974,12 @@ void fast_timer_init(void) printk("fast_timer_init()\n"); #ifdef CONFIG_PROC_FS +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) if ((fasttimer_proc_entry = create_proc_entry( "fasttimer", 0, 0 ))) fasttimer_proc_entry->read_proc = proc_fasttimer_read; +#else + proc_register_dynamic(&proc_root, &fasttimer_proc_entry); +#endif #endif /* PROC_FS */ if(request_irq(TIMER_INTR_VECT, timer_trig_interrupt, IRQF_DISABLED, "fast timer int", NULL)) diff --git a/trunk/arch/cris/arch-v32/kernel/ptrace.c b/trunk/arch/cris/arch-v32/kernel/ptrace.c index d4d57b741334..82cf2e3624a4 100644 --- a/trunk/arch/cris/arch-v32/kernel/ptrace.c +++ b/trunk/arch/cris/arch-v32/kernel/ptrace.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/cris/arch-v32/vmlinux.lds.S b/trunk/arch/cris/arch-v32/vmlinux.lds.S index dfa25e1542b9..e124fcd766d5 100644 --- a/trunk/arch/cris/arch-v32/vmlinux.lds.S +++ b/trunk/arch/cris/arch-v32/vmlinux.lds.S @@ -91,7 +91,6 @@ SECTIONS } SECURITY_INIT - . = ALIGN (8192); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/cris/kernel/crisksyms.c b/trunk/arch/cris/kernel/crisksyms.c index 105bb5ed48f7..1f20c16ac2a4 100644 --- a/trunk/arch/cris/kernel/crisksyms.c +++ b/trunk/arch/cris/kernel/crisksyms.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/cris/kernel/profile.c b/trunk/arch/cris/kernel/profile.c index aad0a9e5991a..4cfcae620507 100644 --- a/trunk/arch/cris/kernel/profile.c +++ b/trunk/arch/cris/kernel/profile.c @@ -15,47 +15,39 @@ static int prof_running = 0; void cris_profile_sample(struct pt_regs* regs) { - if (!prof_running) - return; - - if (user_mode(regs)) - *(unsigned int*)sample_buffer_pos = current->pid; - else - *(unsigned int*)sample_buffer_pos = 0; - - *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs); - sample_buffer_pos += 8; - - if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) - sample_buffer_pos = sample_buffer; + if (!prof_running) + return; + if (user_mode(regs)) + *(unsigned int*)sample_buffer_pos = current->pid; + else + *(unsigned int*)sample_buffer_pos = 0; + *(unsigned int*)(sample_buffer_pos + 4) = instruction_pointer(regs); + sample_buffer_pos += 8; + if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE) + sample_buffer_pos = sample_buffer; } static ssize_t -read_cris_profile(struct file *file, char __user *buf, - size_t count, loff_t *ppos) +read_cris_profile(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - unsigned long p = *ppos; - - if (p > SAMPLE_BUFFER_SIZE) - return 0; - - if (p + count > SAMPLE_BUFFER_SIZE) - count = SAMPLE_BUFFER_SIZE - p; - if (copy_to_user(buf, sample_buffer + p,count)) + unsigned long p = *ppos; + if (p > SAMPLE_BUFFER_SIZE) + return 0; + if (p + count > SAMPLE_BUFFER_SIZE) + count = SAMPLE_BUFFER_SIZE - p; + if (copy_to_user(buf, sample_buffer + p,count)) return -EFAULT; - - memset(sample_buffer + p, 0, count); - *ppos += count; - - return count; + memset(sample_buffer + p, 0, count); + *ppos += count; + return count; } static ssize_t write_cris_profile(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { - sample_buffer_pos = sample_buffer; - memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); + sample_buffer_pos = sample_buffer; + memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE); } static const struct file_operations cris_proc_profile_operations = { @@ -66,23 +58,16 @@ static const struct file_operations cris_proc_profile_operations = { static int __init init_cris_profile(void) { - struct proc_dir_entry *entry; - - sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); - if (!sample_buffer) { - return -ENOMEM; - } - - sample_buffer_pos = sample_buffer; - - entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL); - if (entry) { - entry->proc_fops = &cris_proc_profile_operations; - entry->size = SAMPLE_BUFFER_SIZE; - } - prof_running = 1; - - return 0; + struct proc_dir_entry *entry; + sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL); + sample_buffer_pos = sample_buffer; + entry = create_proc_entry("system_profile", S_IWUSR | S_IRUGO, NULL); + if (entry) { + entry->proc_fops = &cris_proc_profile_operations; + entry->size = SAMPLE_BUFFER_SIZE; + } + prof_running = 1; + return 0; } __initcall(init_cris_profile); diff --git a/trunk/arch/cris/kernel/ptrace.c b/trunk/arch/cris/kernel/ptrace.c index 1085d037027b..2b6363cbe985 100644 --- a/trunk/arch/cris/kernel/ptrace.c +++ b/trunk/arch/cris/kernel/ptrace.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index eed694312a79..cea237413aa2 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -53,10 +53,6 @@ config ARCH_HAS_ILOG2_U64 bool default y -config ARCH_USES_SLAB_PAGE_STRUCT - bool - default y - mainmenu "Fujitsu FR-V Kernel Configuration" source "init/Kconfig" diff --git a/trunk/arch/frv/kernel/irq.c b/trunk/arch/frv/kernel/irq.c index c7e59dcadee4..87f360a4ea27 100644 --- a/trunk/arch/frv/kernel/irq.c +++ b/trunk/arch/frv/kernel/irq.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/frv/kernel/ptrace.c b/trunk/arch/frv/kernel/ptrace.c index ce88fb95ee59..fcff819b4340 100644 --- a/trunk/arch/frv/kernel/ptrace.c +++ b/trunk/arch/frv/kernel/ptrace.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/frv/kernel/semaphore.c b/trunk/arch/frv/kernel/semaphore.c index 8e182ced1a0f..f278cdf3a72f 100644 --- a/trunk/arch/frv/kernel/semaphore.c +++ b/trunk/arch/frv/kernel/semaphore.c @@ -19,7 +19,7 @@ struct sem_waiter { struct task_struct *task; }; -#ifdef CONFIG_DEBUG_SEMAPHORE +#if SEMAPHORE_DEBUG void semtrace(struct semaphore *sem, const char *str) { if (sem->debug) diff --git a/trunk/arch/frv/kernel/signal.c b/trunk/arch/frv/kernel/signal.c index d64bcaff54cd..85baeae9666a 100644 --- a/trunk/arch/frv/kernel/signal.c +++ b/trunk/arch/frv/kernel/signal.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/frv/kernel/sys_frv.c b/trunk/arch/frv/kernel/sys_frv.c index 26b3df32b9a7..c4d4348c9e8e 100644 --- a/trunk/arch/frv/kernel/sys_frv.c +++ b/trunk/arch/frv/kernel/sys_frv.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/frv/kernel/vmlinux.lds.S b/trunk/arch/frv/kernel/vmlinux.lds.S index 28eae9735ad6..97910e016825 100644 --- a/trunk/arch/frv/kernel/vmlinux.lds.S +++ b/trunk/arch/frv/kernel/vmlinux.lds.S @@ -57,7 +57,6 @@ SECTIONS __alt_instructions_end = .; .altinstr_replacement : { *(.altinstr_replacement) } - . = ALIGN(4096); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/frv/mm/elf-fdpic.c b/trunk/arch/frv/mm/elf-fdpic.c index cac2c01a3a56..9477ccce070e 100644 --- a/trunk/arch/frv/mm/elf-fdpic.c +++ b/trunk/arch/frv/mm/elf-fdpic.c @@ -64,10 +64,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi if (len > TASK_SIZE) return -ENOMEM; - /* handle MAP_FIXED */ - if (flags & MAP_FIXED) - return addr; - /* only honour a hint if we're not going to clobber something doing so */ if (addr) { addr = PAGE_ALIGN(addr); diff --git a/trunk/arch/frv/mm/pgalloc.c b/trunk/arch/frv/mm/pgalloc.c index 598a26ab8ad8..19b13be114a2 100644 --- a/trunk/arch/frv/mm/pgalloc.c +++ b/trunk/arch/frv/mm/pgalloc.c @@ -151,7 +151,9 @@ void __init pgtable_cache_init(void) pgd_cache = kmem_cache_create("pgd", PTRS_PER_PGD * sizeof(pgd_t), PTRS_PER_PGD * sizeof(pgd_t), - SLAB_PANIC, + 0, pgd_ctor, pgd_dtor); + if (!pgd_cache) + panic("pgtable_cache_init(): Cannot create pgd cache"); } diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig index 618dbad696f6..1734d96422c6 100644 --- a/trunk/arch/h8300/Kconfig +++ b/trunk/arch/h8300/Kconfig @@ -49,18 +49,10 @@ config GENERIC_HWEIGHT bool default y -config GENERIC_HARDIRQS - bool - default y - config GENERIC_CALIBRATE_DELAY bool default y -config GENERIC_TIME - bool - default y - config TIME_LOW_RES bool default y diff --git a/trunk/arch/h8300/Makefile b/trunk/arch/h8300/Makefile index b2d896a7e598..40b3f56f3666 100644 --- a/trunk/arch/h8300/Makefile +++ b/trunk/arch/h8300/Makefile @@ -41,7 +41,7 @@ LDFLAGS += $(ldflags-y) CROSS_COMPILE = h8300-elf- LIBGCC := $(shell $(CROSS-COMPILE)$(CC) $(CFLAGS) -print-libgcc-file-name) -head-y := arch/$(ARCH)/platform/$(PLATFORM)/$(BOARD)/crt0_$(MODEL).o +head-y := arch/$(ARCH)/platform/$(platform-y)/$(board-y)/crt0_$(model-y).o core-y += arch/$(ARCH)/kernel/ \ arch/$(ARCH)/mm/ diff --git a/trunk/arch/h8300/boot/Makefile b/trunk/arch/h8300/boot/Makefile index 0bb62e064eea..65086d925ca7 100644 --- a/trunk/arch/h8300/boot/Makefile +++ b/trunk/arch/h8300/boot/Makefile @@ -1,22 +1,12 @@ # arch/h8300/boot/Makefile -targets := vmlinux.srec vmlinux.bin zImage -subdir- := compressed +targets := vmlinux.srec vmlinux.bin OBJCOPYFLAGS_vmlinux.srec := -Osrec OBJCOPYFLAGS_vmlinux.bin := -Obinary -OBJCOPYFLAGS_zImage := -O binary -R .note -R .comment -R .stab -R .stabstr -S $(obj)/vmlinux.srec $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) @echo ' Kernel: $@ is ready' -$(obj)/zImage: $(obj)/compressed/vmlinux FORCE - $(call if_changed,objcopy) - @echo 'Kernel: $@ is ready' - -$(obj)/compressed/vmlinux: FORCE - $(Q)$(MAKE) $(build)=$(obj)/compressed $@ - CLEAN_FILES += arch/$(ARCH)/vmlinux.bin arch/$(ARCH)/vmlinux.srec - diff --git a/trunk/arch/h8300/boot/compressed/Makefile b/trunk/arch/h8300/boot/compressed/Makefile deleted file mode 100644 index 71aac82a8ae0..000000000000 --- a/trunk/arch/h8300/boot/compressed/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# -# linux/arch/sh/boot/compressed/Makefile -# -# create a compressed vmlinux image from the original vmlinux -# - -targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o -EXTRA_AFLAGS := -traditional - -OBJECTS = $(obj)/head.o $(obj)/misc.o - -# -# IMAGE_OFFSET is the load offset of the compression loader -# Assign dummy values if these 2 variables are not defined, -# in order to suppress error message. -# -CONFIG_MEMORY_START ?= 0x00400000 -CONFIG_BOOT_LINK_OFFSET ?= 0x00400000 -IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) - -LDFLAGS_vmlinux := -T $(obj)/vmlinux.lds - -$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE - $(call if_changed,ld) - @: - -$(obj)/vmlinux.bin: vmlinux FORCE - $(call if_changed,objcopy) - -$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE - $(call if_changed,gzip) - -LDFLAGS_piggy.o := -r --format binary --oformat elf32-h8300 -T -OBJCOPYFLAGS := -O binary - -$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE - $(call if_changed,ld) diff --git a/trunk/arch/h8300/boot/compressed/head.S b/trunk/arch/h8300/boot/compressed/head.S deleted file mode 100644 index b8e90d12d19e..000000000000 --- a/trunk/arch/h8300/boot/compressed/head.S +++ /dev/null @@ -1,47 +0,0 @@ -/* - * linux/arch/h8300/boot/compressed/head.S - * - * Copyright (C) 2006 Yoshinori Sato - */ - -.h8300h -#include - -#define SRAM_START 0xff4000 - - .section .text.startup - .global startup -startup: - mov.l #SRAM_START+0x8000, sp - mov.l #__sbss, er0 - mov.l #__ebss, er1 - sub.l er0, er1 - shlr er1 - shlr er1 - sub.l er2, er2 -1: - mov.l er2, @er0 - adds #4, er0 - dec.l #1, er1 - bne 1b - jsr @_decompress_kernel - jmp @0x400000 - - .align 9 -fake_headers_as_bzImage: - .word 0 - .ascii "HdrS" ; header signature - .word 0x0202 ; header version number (>= 0x0105) - ; or else old loadlin-1.5 will fail) - .word 0 ; default_switch - .word 0 ; SETUPSEG - .word 0x1000 - .word 0 ; pointing to kernel version string - .byte 0 ; = 0, old one (LILO, Loadlin, - ; 0xTV: T=0 for LILO - ; V = version - .byte 1 ; Load flags bzImage=1 - .word 0x8000 ; size to move, when setup is not - .long 0x100000 ; 0x100000 = default for big kernel - .long 0 ; address of loaded ramdisk image - .long 0 ; its size in bytes diff --git a/trunk/arch/h8300/boot/compressed/misc.c b/trunk/arch/h8300/boot/compressed/misc.c deleted file mode 100644 index 845074588af0..000000000000 --- a/trunk/arch/h8300/boot/compressed/misc.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * arch/h8300/boot/compressed/misc.c - * - * This is a collection of several routines from gzip-1.0.3 - * adapted for Linux. - * - * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994 - * - * Adapted for h8300 by Yoshinori Sato 2006 - */ - -#include - -/* - * gzip declarations - */ - -#define OF(args) args -#define STATIC static - -#undef memset -#undef memcpy -#define memzero(s, n) memset ((s), 0, (n)) - -typedef unsigned char uch; -typedef unsigned short ush; -typedef unsigned long ulg; - -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ - -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ - -static unsigned insize = 0; /* valid bytes in inbuf */ -static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ -static unsigned outcnt = 0; /* bytes in output buffer */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ -#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ -#define RESERVED 0xC0 /* bit 6,7: reserved */ - -#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf()) - -/* Diagnostic functions */ -#ifdef DEBUG -# define Assert(cond,msg) {if(!(cond)) error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -static int fill_inbuf(void); -static void flush_window(void); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - -extern char input_data[]; -extern int input_len; - -static long bytes_out = 0; -static uch *output_data; -static unsigned long output_ptr = 0; - -static void *malloc(int size); -static void free(void *where); -static void error(char *m); -static void gzip_mark(void **); -static void gzip_release(void **); - -int puts(const char *); - -extern int _text; /* Defined in vmlinux.lds.S */ -extern int _end; -static unsigned long free_mem_ptr; -static unsigned long free_mem_end_ptr; - -#define HEAP_SIZE 0x10000 - -#include "../../../../lib/inflate.c" - -#define SCR *((volatile unsigned char *)0xffff8a) -#define TDR *((volatile unsigned char *)0xffff8b) -#define SSR *((volatile unsigned char *)0xffff8c) - -static void *malloc(int size) -{ - void *p; - - if (size <0) error("Malloc error"); - if (free_mem_ptr == 0) error("Memory error"); - - free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ - - p = (void *)free_mem_ptr; - free_mem_ptr += size; - - if (free_mem_ptr >= free_mem_end_ptr) - error("Out of memory"); - - return p; -} - -static void free(void *where) -{ /* Don't care */ -} - -static void gzip_mark(void **ptr) -{ - *ptr = (void *) free_mem_ptr; -} - -static void gzip_release(void **ptr) -{ - free_mem_ptr = (long) *ptr; -} - -int puts(const char *s) -{ - return 0; -} - -void* memset(void* s, int c, size_t n) -{ - int i; - char *ss = (char*)s; - - for (i=0;i> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; -} - -static void error(char *x) -{ - puts("\n\n"); - puts(x); - puts("\n\n -- System halted"); - - while(1); /* Halt */ -} - -#define STACK_SIZE (4096) -long user_stack [STACK_SIZE]; -long* stack_start = &user_stack[STACK_SIZE]; - -void decompress_kernel(void) -{ - output_data = 0; - output_ptr = (unsigned long)0x400000; - free_mem_ptr = (unsigned long)&_end; - free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; - - makecrc(); - puts("Uncompressing Linux... "); - gunzip(); - puts("Ok, booting the kernel.\n"); -} diff --git a/trunk/arch/h8300/kernel/Makefile b/trunk/arch/h8300/kernel/Makefile index ccc1a7fbf94b..4edbc2ef6ca2 100644 --- a/trunk/arch/h8300/kernel/Makefile +++ b/trunk/arch/h8300/kernel/Makefile @@ -4,8 +4,10 @@ extra-y := vmlinux.lds -obj-y := process.o traps.o ptrace.o irq.o \ +obj-y := process.o traps.o ptrace.o ints.o \ sys_h8300.o time.o semaphore.o signal.o \ - setup.o gpio.o init_task.o syscalls.o + setup.o gpio.o init_task.o syscalls.o devres.o + +devres-y = ../../../kernel/irq/devres.o obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o diff --git a/trunk/arch/h8300/kernel/irq.c b/trunk/arch/h8300/kernel/irq.c deleted file mode 100644 index 43d21e93f41f..000000000000 --- a/trunk/arch/h8300/kernel/irq.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * linux/arch/h8300/kernel/irq.c - * - * Copyright 2007 Yoshinori Sato - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/*#define DEBUG*/ - -extern unsigned long *interrupt_redirect_table; -extern const int h8300_saved_vectors[]; -extern const unsigned long h8300_trap_table[]; -int h8300_enable_irq_pin(unsigned int irq); -void h8300_disable_irq_pin(unsigned int irq); - -#define CPU_VECTOR ((unsigned long *)0x000000) -#define ADDR_MASK (0xffffff) - -static inline int is_ext_irq(unsigned int irq) -{ - return (irq >= EXT_IRQ0 && irq <= (EXT_IRQ0 + EXT_IRQS)); -} - -static void h8300_enable_irq(unsigned int irq) -{ - if (is_ext_irq(irq)) - IER_REGS |= 1 << (irq - EXT_IRQ0); -} - -static void h8300_disable_irq(unsigned int irq) -{ - if (is_ext_irq(irq)) - IER_REGS &= ~(1 << (irq - EXT_IRQ0)); -} - -static void h8300_end_irq(unsigned int irq) -{ -} - -static unsigned int h8300_startup_irq(unsigned int irq) -{ - if (is_ext_irq(irq)) - return h8300_enable_irq_pin(irq); - else - return 0; -} - -static void h8300_shutdown_irq(unsigned int irq) -{ - if (is_ext_irq(irq)) - h8300_disable_irq_pin(irq); -} - -/* - * h8300 interrupt controler implementation - */ -struct irq_chip h8300irq_chip = { - .name = "H8300-INTC", - .startup = h8300_startup_irq, - .shutdown = h8300_shutdown_irq, - .enable = h8300_enable_irq, - .disable = h8300_disable_irq, - .ack = NULL, - .end = h8300_end_irq, -}; - -void ack_bad_irq(unsigned int irq) -{ - printk("unexpected IRQ trap at vector %02x\n", irq); -} - -#if defined(CONFIG_RAMKERNEL) -static unsigned long __init *get_vector_address(void) -{ - unsigned long *rom_vector = CPU_VECTOR; - unsigned long base,tmp; - int vec_no; - - base = rom_vector[EXT_IRQ0] & ADDR_MASK; - - /* check romvector format */ - for (vec_no = EXT_IRQ1; vec_no <= EXT_IRQ0+EXT_IRQS; vec_no++) { - if ((base+(vec_no - EXT_IRQ0)*4) != (rom_vector[vec_no] & ADDR_MASK)) - return NULL; - } - - /* ramvector base address */ - base -= EXT_IRQ0*4; - - /* writerble check */ - tmp = ~(*(volatile unsigned long *)base); - (*(volatile unsigned long *)base) = tmp; - if ((*(volatile unsigned long *)base) != tmp) - return NULL; - return (unsigned long *)base; -} - -static void __init setup_vector(void) -{ - int i; - unsigned long *ramvec,*ramvec_p; - const unsigned long *trap_entry; - const int *saved_vector; - - ramvec = get_vector_address(); - if (ramvec == NULL) - panic("interrupt vector serup failed."); - else - printk(KERN_INFO "virtual vector at 0x%08lx\n",(unsigned long)ramvec); - - /* create redirect table */ - ramvec_p = ramvec; - trap_entry = h8300_trap_table; - saved_vector = h8300_saved_vectors; - for ( i = 0; i < NR_IRQS; i++) { - if (i == *saved_vector) { - ramvec_p++; - saved_vector++; - } else { - if ( i < NR_TRAPS ) { - if (*trap_entry) - *ramvec_p = VECTOR(*trap_entry); - ramvec_p++; - trap_entry++; - } else - *ramvec_p++ = REDIRECT(interrupt_entry); - } - } - interrupt_redirect_table = ramvec; -#ifdef DEBUG - ramvec_p = ramvec; - for (i = 0; i < NR_IRQS; i++) { - if ((i % 8) == 0) - printk(KERN_DEBUG "\n%p: ",ramvec_p); - printk(KERN_DEBUG "%p ",*ramvec_p); - ramvec_p++; - } - printk(KERN_DEBUG "\n"); -#endif -} -#else -#define setup_vector() do { } while(0) -#endif - -void __init init_IRQ(void) -{ - int c; - - setup_vector(); - - for (c = 0; c < NR_IRQS; c++) { - irq_desc[c].status = IRQ_DISABLED; - irq_desc[c].action = NULL; - irq_desc[c].depth = 1; - irq_desc[c].chip = &h8300irq_chip; - } -} - -asmlinkage void do_IRQ(int irq) -{ - irq_enter(); - __do_IRQ(irq); - irq_exit(); -} - -#if defined(CONFIG_PROC_FS) -int show_interrupts(struct seq_file *p, void *v) -{ - int i = *(loff_t *) v, j; - struct irqaction * action; - unsigned long flags; - - if (i == 0) - seq_puts(p, " CPU0"); - - if (i < NR_IRQS) { - spin_lock_irqsave(&irq_desc[i].lock, flags); - action = irq_desc[i].action; - if (!action) - goto unlock; - seq_printf(p, "%3d: ",i); - seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); - seq_printf(p, " %14s", irq_desc[i].chip->name); - seq_printf(p, "-%-8s", irq_desc[i].name); - seq_printf(p, " %s", action->name); - - for (action=action->next; action; action = action->next) - seq_printf(p, ", %s", action->name); - seq_putc(p, '\n'); -unlock: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } - return 0; -} -#endif diff --git a/trunk/arch/h8300/kernel/ptrace.c b/trunk/arch/h8300/kernel/ptrace.c index 8f2411db7eaf..f6031373dc21 100644 --- a/trunk/arch/h8300/kernel/ptrace.c +++ b/trunk/arch/h8300/kernel/ptrace.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/h8300/kernel/setup.c b/trunk/arch/h8300/kernel/setup.c index b2e86d0255e6..313cd8081044 100644 --- a/trunk/arch/h8300/kernel/setup.c +++ b/trunk/arch/h8300/kernel/setup.c @@ -33,7 +33,10 @@ #include #include + +#ifdef CONFIG_BLK_DEV_INITRD #include +#endif #if defined(__H8300H__) #define CPU "H8/300H" diff --git a/trunk/arch/h8300/kernel/sys_h8300.c b/trunk/arch/h8300/kernel/sys_h8300.c index 11ba75a05220..302a2dfe634a 100644 --- a/trunk/arch/h8300/kernel/sys_h8300.c +++ b/trunk/arch/h8300/kernel/sys_h8300.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/h8300/kernel/time.c b/trunk/arch/h8300/kernel/time.c index 330638220a2e..d1ef615ba895 100644 --- a/trunk/arch/h8300/kernel/time.c +++ b/trunk/arch/h8300/kernel/time.c @@ -44,7 +44,7 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs) #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif - profile_tick(CPU_PROFILING); + profile_tick(CPU_PROFILING, regs); } void time_init(void) @@ -66,3 +66,55 @@ void time_init(void) platform_timer_setup(timer_interrupt); } + +/* + * This version of gettimeofday has near microsecond resolution. + */ +void do_gettimeofday(struct timeval *tv) +{ + unsigned long flags; + unsigned long usec, sec; + + read_lock_irqsave(&xtime_lock, flags); + usec = 0; + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + read_unlock_irqrestore(&xtime_lock, flags); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +EXPORT_SYMBOL(do_gettimeofday); + +int do_settimeofday(struct timespec *tv) +{ + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + write_lock_irq(&xtime_lock); + /* This is revolting. We need to set the xtime.tv_usec + * correctly. However, the value in this location is + * is value at the last tick. + * Discover what correction gettimeofday + * would have done, and then undo it! + */ + while (tv->tv_nsec < 0) { + tv->tv_nsec += NSEC_PER_SEC; + tv->tv_sec--; + } + + xtime.tv_sec = tv->tv_sec; + xtime.tv_nsec = tv->tv_nsec; + ntp_clear(); + write_sequnlock_irq(&xtime_lock); + clock_was_set(); + return 0; +} + +EXPORT_SYMBOL(do_settimeofday); diff --git a/trunk/arch/h8300/mm/kmap.c b/trunk/arch/h8300/mm/kmap.c index 5c7af09ae8d1..26ab17286a53 100644 --- a/trunk/arch/h8300/mm/kmap.c +++ b/trunk/arch/h8300/mm/kmap.c @@ -24,14 +24,12 @@ #undef DEBUG -#define VIRT_OFFSET (0x01000000) - /* * Map some physical address range into the kernel address space. */ void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) { - return (void *)(physaddr + VIRT_OFFSET); + return (void *)physaddr; } /* diff --git a/trunk/arch/h8300/platform/h8300h/Makefile b/trunk/arch/h8300/platform/h8300h/Makefile index b24ea08aa0a7..5d42c772f75a 100644 --- a/trunk/arch/h8300/platform/h8300h/Makefile +++ b/trunk/arch/h8300/platform/h8300h/Makefile @@ -4,4 +4,4 @@ # Reuse any files we can from the H8/300H # -obj-y := entry.o irq_pin.o ptrace_h8300h.o +obj-y := entry.o ints_h8300h.o ptrace_h8300h.o diff --git a/trunk/arch/h8300/platform/h8300h/entry.S b/trunk/arch/h8300/platform/h8300h/entry.S index f86ac3b5d4de..d2dea2432fb2 100644 --- a/trunk/arch/h8300/platform/h8300h/entry.S +++ b/trunk/arch/h8300/platform/h8300h/entry.S @@ -30,12 +30,12 @@ mov.l er0,@-sp stc ccr,r0l /* check kernel mode */ + orc #0x10,ccr btst #4,r0l bne 5f mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */ mov.l @sp,er0 - orc #0x10,ccr mov.l @SYMBOL_NAME(sw_ksp),sp sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ mov.l er0,@-sp @@ -165,7 +165,7 @@ SYMBOL_NAME_LABEL(interrupt_entry) dec.l #1,er0 mov.l sp,er1 subs #4,er1 /* adjust ret_pc */ - jsr @SYMBOL_NAME(do_IRQ) + jsr @SYMBOL_NAME(process_int) mov.l @SYMBOL_NAME(irq_stat)+CPUSTAT_SOFTIRQ_PENDING,er0 beq 1f jsr @SYMBOL_NAME(do_softirq) diff --git a/trunk/arch/h8300/platform/h8300h/generic/Makefile b/trunk/arch/h8300/platform/h8300h/generic/Makefile index 32b964a9010e..b6ea7688a616 100644 --- a/trunk/arch/h8300/platform/h8300h/generic/Makefile +++ b/trunk/arch/h8300/platform/h8300h/generic/Makefile @@ -2,5 +2,5 @@ # Makefile for the linux kernel. # -extra-y := crt0_$(MODEL).o obj-y := timer.o +extra-y = crt0_$(MODEL).o diff --git a/trunk/arch/h8300/platform/h8300h/ints_h8300h.c b/trunk/arch/h8300/platform/h8300h/ints_h8300h.c new file mode 100644 index 000000000000..f1777119b871 --- /dev/null +++ b/trunk/arch/h8300/platform/h8300h/ints_h8300h.c @@ -0,0 +1,85 @@ +/* + * linux/arch/h8300/platform/h8300h/ints_h8300h.c + * Interrupt handling CPU variants + * + * Yoshinori Sato + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +/* saved vector list */ +const int __initdata h8300_saved_vectors[]={ +#if defined(CONFIG_GDB_DEBUG) + TRAP3_VEC, +#endif + -1 +}; + +/* trap entry table */ +const unsigned long __initdata h8300_trap_table[NR_TRAPS]={ + 0,0,0,0,0,0,0,0, + (unsigned long)system_call, /* TRAPA #0 */ + 0,0, + (unsigned long)trace_break, /* TRAPA #3 */ +}; + +int h8300_enable_irq_pin(unsigned int irq) +{ + int bitmask; + if (irq < EXT_IRQ0 || irq > EXT_IRQ5) + return 0; + + /* initialize IRQ pin */ + bitmask = 1 << (irq - EXT_IRQ0); + switch(irq) { + case EXT_IRQ0: + case EXT_IRQ1: + case EXT_IRQ2: + case EXT_IRQ3: + if (H8300_GPIO_RESERVE(H8300_GPIO_P8, bitmask) == 0) + return -EBUSY; + H8300_GPIO_DDR(H8300_GPIO_P8, bitmask, H8300_GPIO_INPUT); + break; + case EXT_IRQ4: + case EXT_IRQ5: + if (H8300_GPIO_RESERVE(H8300_GPIO_P9, bitmask) == 0) + return -EBUSY; + H8300_GPIO_DDR(H8300_GPIO_P9, bitmask, H8300_GPIO_INPUT); + break; + } + + return 0; +} + +void h8300_disable_irq_pin(unsigned int irq) +{ + int bitmask; + if (irq < EXT_IRQ0 || irq > EXT_IRQ5) + return; + + /* disable interrupt & release IRQ pin */ + bitmask = 1 << (irq - EXT_IRQ0); + switch(irq) { + case EXT_IRQ0: + case EXT_IRQ1: + case EXT_IRQ2: + case EXT_IRQ3: + *(volatile unsigned char *)IER &= ~bitmask; + H8300_GPIO_FREE(H8300_GPIO_P8, bitmask); + break ; + case EXT_IRQ4: + case EXT_IRQ5: + *(volatile unsigned char *)IER &= ~bitmask; + H8300_GPIO_FREE(H8300_GPIO_P9, bitmask); + break; + } +} diff --git a/trunk/arch/h8300/platform/h8s/entry.S b/trunk/arch/h8300/platform/h8s/entry.S index f3d6b8e8f959..aeb2e9faa9b2 100644 --- a/trunk/arch/h8300/platform/h8s/entry.S +++ b/trunk/arch/h8300/platform/h8s/entry.S @@ -31,13 +31,12 @@ mov.l er0,@-sp stc ccr,r0l /* check kernel mode */ + orc #0x10,ccr btst #4,r0l bne 5f - /* user mode */ - mov.l sp,@SYMBOL_NAME(sw_usp) - mov.l @sp,er0 /* restore saved er0 */ - orc #0x10,ccr /* switch kernel stack */ + mov.l sp,@SYMBOL_NAME(sw_usp) /* user mode */ + mov.l @sp,er0 mov.l @SYMBOL_NAME(sw_ksp),sp sub.l #(LRET-LORIG),sp /* allocate LORIG - LRET */ stm.l er0-er3,@-sp @@ -56,9 +55,8 @@ mov.l er0,@(LER0-LER3:16,sp) /* copy ER0 */ bra 6f 5: - /* kernel mode */ - mov.l @sp,er0 /* restore saved er0 */ - subs #2,sp /* set dummy ccr */ + mov.l @sp,er0 /* kernel mode */ + subs #2,sp /* dummy ccr */ stm.l er0-er3,@-sp mov.w @(LRET-LER3:16,sp),r1 /* copy old ccr */ mov.b r1h,r1l @@ -96,7 +94,6 @@ mov.l @sp+,er1 add.l #(LRET-LER1),sp /* remove LORIG - LRET */ mov.l sp,@SYMBOL_NAME(sw_ksp) - andc #0xef,ccr /* switch to user mode */ mov.l er0,sp bra 8f 7: @@ -176,6 +173,9 @@ SYMBOL_NAME_LABEL(interrupt_entry) SYMBOL_NAME_LABEL(system_call) subs #4,sp /* dummy LVEC */ SAVE_ALL + mov.w @(LCCR:16,sp),r1 + bset #4,r1l + ldc r1l,ccr /* restore ccr */ mov.l er0,er4 mov.l #-ENOSYS,er0 mov.l er0,@(LER0:16,sp) @@ -198,7 +198,6 @@ SYMBOL_NAME_LABEL(system_call) mov.l @(LER1:16,sp),er0 mov.l @(LER2:16,sp),er1 mov.l @(LER3:16,sp),er2 - andc #0x7f,ccr jsr @er4 mov.l er0,@(LER0:16,sp) /* save the return value */ #if defined(CONFIG_SYSCALL_PRINT) diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index 64ad10f984a1..53d62373a524 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -79,10 +79,6 @@ config ARCH_MAY_HAVE_PC_FDC bool default y -config ARCH_USES_SLAB_PAGE_STRUCT - bool - default y - config DMI bool default y @@ -224,7 +220,7 @@ config PARAVIRT config VMI bool "VMI Paravirt-ops support" - depends on PARAVIRT + depends on PARAVIRT && !COMPAT_VDSO help VMI provides a paravirtualized interface to the VMware ESX server (it could be used by other hypervisors in theory too, but is not @@ -575,9 +571,6 @@ choice bool "3G/1G user/kernel split (for full 1G low memory)" config VMSPLIT_2G bool "2G/2G user/kernel split" - config VMSPLIT_2G_OPT - depends on !HIGHMEM - bool "2G/2G user/kernel split (for full 2G low memory)" config VMSPLIT_1G bool "1G/3G user/kernel split" endchoice @@ -585,8 +578,7 @@ endchoice config PAGE_OFFSET hex default 0xB0000000 if VMSPLIT_3G_OPT - default 0x80000000 if VMSPLIT_2G - default 0x78000000 if VMSPLIT_2G_OPT + default 0x78000000 if VMSPLIT_2G default 0x40000000 if VMSPLIT_1G default 0xC0000000 @@ -923,9 +915,12 @@ source kernel/power/Kconfig source "drivers/acpi/Kconfig" -menuconfig APM +menu "APM (Advanced Power Management) BIOS Support" +depends on PM && !X86_VISWS + +config APM tristate "APM (Advanced Power Management) BIOS support" - depends on PM && !X86_VISWS + depends on PM ---help--- APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with @@ -982,10 +977,9 @@ menuconfig APM To compile this driver as a module, choose M here: the module will be called apm. -if APM - config APM_IGNORE_USER_SUSPEND bool "Ignore USER SUSPEND" + depends on APM help This option will ignore USER SUSPEND requests. On machines with a compliant APM BIOS, you want to say N. However, on the NEC Versa M @@ -993,6 +987,7 @@ config APM_IGNORE_USER_SUSPEND config APM_DO_ENABLE bool "Enable PM at boot time" + depends on APM ---help--- Enable APM features at boot time. From page 36 of the APM BIOS specification: "When disabled, the APM BIOS does not automatically @@ -1010,6 +1005,7 @@ config APM_DO_ENABLE config APM_CPU_IDLE bool "Make CPU Idle calls when idle" + depends on APM help Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop. On some machines, this can activate improved power savings, such as @@ -1021,6 +1017,7 @@ config APM_CPU_IDLE config APM_DISPLAY_BLANK bool "Enable console blanking using APM" + depends on APM help Enable console blanking using the APM. Some laptops can use this to turn off the LCD backlight when the screen blanker of the Linux @@ -1032,8 +1029,22 @@ config APM_DISPLAY_BLANK backlight at all, or it might print a lot of errors to the console, especially if you are using gpm. +config APM_RTC_IS_GMT + bool "RTC stores time in GMT" + depends on APM + help + Say Y here if your RTC (Real Time Clock a.k.a. hardware clock) + stores the time in GMT (Greenwich Mean Time). Say N if your RTC + stores localtime. + + It is in fact recommended to store GMT in your RTC, because then you + don't have to worry about daylight savings time changes. The only + reason not to use GMT in your RTC is if you also run a broken OS + that doesn't understand GMT. + config APM_ALLOW_INTS bool "Allow interrupts during APM BIOS calls" + depends on APM help Normally we disable external interrupts while we are making calls to the APM BIOS as a measure to lessen the effects of a badly behaving @@ -1044,12 +1055,13 @@ config APM_ALLOW_INTS config APM_REAL_MODE_POWER_OFF bool "Use real mode APM BIOS call to power off" + depends on APM help Use real mode APM BIOS calls to switch off the computer. This is a work-around for a number of buggy BIOSes. Switch this option on if your computer crashes instead of powering off properly. -endif # APM +endmenu source "arch/i386/kernel/cpu/cpufreq/Kconfig" @@ -1061,7 +1073,6 @@ config PCI bool "PCI support" if !X86_VISWS depends on !X86_VOYAGER default y if X86_VISWS - select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC) help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/trunk/arch/i386/Kconfig.cpu b/trunk/arch/i386/Kconfig.cpu index dce6124cb842..b99c0e2a4e63 100644 --- a/trunk/arch/i386/Kconfig.cpu +++ b/trunk/arch/i386/Kconfig.cpu @@ -43,7 +43,6 @@ config M386 - "Geode GX/LX" For AMD Geode GX and LX processors. - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. - "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above). - - "VIA C7" for VIA C7. If you don't know what to do, choose "386". @@ -204,12 +203,6 @@ config MVIAC3_2 of SSE and tells gcc to treat the CPU as a 686. Note, this kernel will not boot on older (pre model 9) C3s. -config MVIAC7 - bool "VIA C7" - help - Select this for a VIA C7. Selecting this uses the correct cache - shift and tells gcc to treat the CPU as a 686. - endchoice config X86_GENERIC @@ -238,21 +231,16 @@ config X86_L1_CACHE_SHIFT default "7" if MPENTIUM4 || X86_GENERIC default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX - default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MVIAC7 - -config X86_XADD - bool - depends on !M386 - default y + default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 config RWSEM_GENERIC_SPINLOCK bool - depends on !X86_XADD + depends on M386 default y config RWSEM_XCHGADD_ALGORITHM bool - depends on X86_XADD + depends on !M386 default y config ARCH_HAS_ILOG2_U32 @@ -309,7 +297,7 @@ config X86_ALIGNMENT_16 config X86_GOOD_APIC bool - depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 || MVIAC7 + depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 default y config X86_INTEL_USERCOPY @@ -334,18 +322,5 @@ config X86_OOSTORE config X86_TSC bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ default y - -# this should be set for all -march=.. options where the compiler -# generates cmov. -config X86_CMOV - bool - depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7) - default y - -config X86_MINIMUM_CPU_MODEL - int - default "4" if X86_XADD || X86_CMPXCHG || X86_BSWAP - default "0" - diff --git a/trunk/arch/i386/Kconfig.debug b/trunk/arch/i386/Kconfig.debug index b31c0802e1cc..458bc1611933 100644 --- a/trunk/arch/i386/Kconfig.debug +++ b/trunk/arch/i386/Kconfig.debug @@ -85,4 +85,14 @@ config DOUBLEFAULT option saves about 4k and might cause you much additional grey hair. +config DEBUG_PARAVIRT + bool "Enable some paravirtualization debugging" + default n + depends on PARAVIRT && DEBUG_KERNEL + help + Currently deliberately clobbers regs which are allowed to be + clobbered in inlined paravirt hooks, even in native mode. + If turning this off solves a problem, then DISABLE_INTERRUPTS() or + ENABLE_INTERRUPTS() is lying about what registers can be clobbered. + endmenu diff --git a/trunk/arch/i386/Makefile b/trunk/arch/i386/Makefile index 6dc5e5d90fec..bd28f9f9b4b7 100644 --- a/trunk/arch/i386/Makefile +++ b/trunk/arch/i386/Makefile @@ -34,7 +34,7 @@ CHECKFLAGS += -D__i386__ CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return # prevent gcc from keeping the stack 16 byte aligned -CFLAGS += -mpreferred-stack-boundary=4 +CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) # CPU-specific tuning. Anything which can be shared with UML should go here. include $(srctree)/arch/i386/Makefile.cpu diff --git a/trunk/arch/i386/Makefile.cpu b/trunk/arch/i386/Makefile.cpu index e372b584e919..a32c031c90d7 100644 --- a/trunk/arch/i386/Makefile.cpu +++ b/trunk/arch/i386/Makefile.cpu @@ -4,9 +4,9 @@ #-mtune exists since gcc 3.4 HAS_MTUNE := $(call cc-option-yn, -mtune=i386) ifeq ($(HAS_MTUNE),y) -tune = $(call cc-option,-mtune=$(1),$(2)) +tune = $(call cc-option,-mtune=$(1),) else -tune = $(call cc-option,-mcpu=$(1),$(2)) +tune = $(call cc-option,-mcpu=$(1),) endif align := $(cc-option-align) @@ -32,8 +32,7 @@ cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) -cflags-$(CONFIG_MVIAC7) += -march=i686 -cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2) +cflags-$(CONFIG_MCORE2) += -march=i686 $(call cc-option,-mtune=core2,$(call cc-option,-mtune=generic,-mtune=i686)) # AMD Elan support cflags-$(CONFIG_X86_ELAN) += -march=i486 @@ -43,5 +42,5 @@ cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx # add at the end to overwrite eventual tuning options from earlier # cpu entries -cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686)) +cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic) diff --git a/trunk/arch/i386/boot/Makefile b/trunk/arch/i386/boot/Makefile index bfbc32098a4a..e97946626064 100644 --- a/trunk/arch/i386/boot/Makefile +++ b/trunk/arch/i386/boot/Makefile @@ -36,9 +36,9 @@ HOSTCFLAGS_build.o := $(LINUXINCLUDE) # --------------------------------------------------------------------------- $(obj)/zImage: IMAGE_OFFSET := 0x1000 -$(obj)/zImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) +$(obj)/zImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) $(obj)/bzImage: IMAGE_OFFSET := 0x100000 -$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ +$(obj)/bzImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ $(obj)/bzImage: BUILDFLAGS := -b quiet_cmd_image = BUILD $@ diff --git a/trunk/arch/i386/boot/compressed/misc.c b/trunk/arch/i386/boot/compressed/misc.c index b28505c544c9..1ce7017fd627 100644 --- a/trunk/arch/i386/boot/compressed/misc.c +++ b/trunk/arch/i386/boot/compressed/misc.c @@ -189,7 +189,7 @@ static void putstr(const char *); static unsigned long free_mem_ptr; static unsigned long free_mem_end_ptr; -#define HEAP_SIZE 0x4000 +#define HEAP_SIZE 0x3000 static char *vidmem = (char *)0xb8000; static int vidport; diff --git a/trunk/arch/i386/boot/setup.S b/trunk/arch/i386/boot/setup.S index f8b3b9cda2b1..06edf1c66242 100644 --- a/trunk/arch/i386/boot/setup.S +++ b/trunk/arch/i386/boot/setup.S @@ -52,7 +52,6 @@ #include #include #include -#include /* Signature words to ensure LILO loaded us right */ #define SIG1 0xAA55 @@ -82,7 +81,7 @@ start: # This is the setup header, and it must start at %cs:2 (old 0x9020:2) .ascii "HdrS" # header signature - .word 0x0206 # header version number (>= 0x0105) + .word 0x0205 # header version number (>= 0x0105) # or else old loadlin-1.5 will fail) realmode_swtch: .word 0, 0 # default_switch, SETUPSEG start_sys_seg: .word SYSSEG @@ -172,10 +171,6 @@ relocatable_kernel: .byte 0 pad2: .byte 0 pad3: .word 0 -cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, - #added with boot protocol - #version 2.06 - trampoline: call start_of_setup .align 16 # The offset at this point is 0x240 @@ -302,24 +297,7 @@ good_sig: loader_panic_mess: .string "Wrong loader, giving up..." -# check minimum cpuid -# we do this here because it is the last place we can actually -# show a user visible error message. Later the video modus -# might be already messed up. loader_ok: - call verify_cpu - testl %eax,%eax - jz cpu_ok - lea cpu_panic_mess,%si - call prtstr -1: jmp 1b - -cpu_panic_mess: - .asciz "PANIC: CPU too old for this kernel." - -#include "../kernel/verify_cpu.S" - -cpu_ok: # Get memory size (extended mem, kB) xorl %eax, %eax diff --git a/trunk/arch/i386/defconfig b/trunk/arch/i386/defconfig index 9da84412a831..c96911c37aea 100644 --- a/trunk/arch/i386/defconfig +++ b/trunk/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-git3 -# Tue May 1 07:30:51 2007 +# Linux kernel version: 2.6.21-rc3 +# Wed Mar 7 15:29:47 2007 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -108,9 +108,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Processor type and features # -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set CONFIG_SMP=y # CONFIG_X86_PC is not set # CONFIG_X86_ELAN is not set @@ -146,11 +146,9 @@ CONFIG_MPENTIUMIII=y # CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set -# CONFIG_MVIAC7 is not set CONFIG_X86_GENERIC=y CONFIG_X86_CMPXCHG=y CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_X86_XADD=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -164,8 +162,6 @@ CONFIG_X86_GOOD_APIC=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y CONFIG_X86_TSC=y -CONFIG_X86_CMOV=y -CONFIG_X86_MINIMUM_CPU_MODEL=4 CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y CONFIG_NR_CPUS=32 @@ -252,6 +248,7 @@ CONFIG_ACPI_FAN=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y # CONFIG_ACPI_ASUS is not set +# CONFIG_ACPI_IBM is not set # CONFIG_ACPI_TOSHIBA is not set CONFIG_ACPI_BLACKLIST_YEAR=2001 CONFIG_ACPI_DEBUG=y @@ -260,7 +257,10 @@ CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y CONFIG_X86_PM_TIMER=y # CONFIG_ACPI_CONTAINER is not set -# CONFIG_ACPI_SBS is not set + +# +# APM (Advanced Power Management) BIOS Support +# # CONFIG_APM is not set # @@ -277,7 +277,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set # # CPUFreq processor drivers @@ -349,6 +349,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -387,7 +388,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set @@ -443,13 +443,6 @@ CONFIG_IPV6_SIT=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_IEEE80211 is not set # @@ -470,6 +463,10 @@ CONFIG_FW_LOADER=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set # @@ -516,7 +513,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set # CONFIG_SONY_LAPTOP is not set -# CONFIG_THINKPAD_ACPI is not set # # ATA/ATAPI/MFM/RLL support @@ -552,6 +548,7 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -583,6 +580,7 @@ CONFIG_BLK_DEV_PIIX=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -671,7 +669,6 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SRP is not set # @@ -700,7 +697,6 @@ CONFIG_SATA_ACPI=y # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set # CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CS5520 is not set # CONFIG_PATA_CS5530 is not set @@ -766,9 +762,10 @@ CONFIG_IEEE1394=y # Subsystem Options # # CONFIG_IEEE1394_VERBOSEDEBUG is not set +# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set # -# Controllers +# Device Drivers # # @@ -777,11 +774,10 @@ CONFIG_IEEE1394=y CONFIG_IEEE1394_OHCI1394=y # -# Protocols +# Protocol Drivers # # CONFIG_IEEE1394_VIDEO1394 is not set # CONFIG_IEEE1394_SBP2 is not set -# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set # CONFIG_IEEE1394_ETH1394 is not set # CONFIG_IEEE1394_DV1394 is not set CONFIG_IEEE1394_RAWIO=y @@ -824,9 +820,7 @@ CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set -CONFIG_NET_VENDOR_3COM=y -CONFIG_VORTEX=y -# CONFIG_TYPHOON is not set +# CONFIG_NET_VENDOR_3COM is not set # # Tulip family network device support @@ -907,10 +901,9 @@ CONFIG_BNX2=y # CONFIG_TR is not set # -# Wireless LAN +# Wireless LAN (non-hamradio) # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_NET_RADIO is not set # # Wan interfaces @@ -924,6 +917,7 @@ CONFIG_BNX2=y # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y @@ -1056,7 +1050,7 @@ CONFIG_MAX_RAW_DEVS=256 CONFIG_HPET=y # CONFIG_HPET_RTC_IRQ is not set CONFIG_HPET_MMAP=y -# CONFIG_HANGCHECK_TIMER is not set +CONFIG_HANGCHECK_TIMER=y # # TPM devices @@ -1147,14 +1141,6 @@ CONFIG_SOUND_ICH=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set - # # USB support # @@ -1168,7 +1154,6 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set @@ -1219,6 +1204,10 @@ CONFIG_USB_STORAGE=y # # USB Input Devices # +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set @@ -1539,7 +1528,7 @@ CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -CONFIG_TIMER_STATS=y +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set diff --git a/trunk/arch/i386/kernel/Makefile b/trunk/arch/i386/kernel/Makefile index 91cff8dc9e1a..4ae3dcf1d2f0 100644 --- a/trunk/arch/i386/kernel/Makefile +++ b/trunk/arch/i386/kernel/Makefile @@ -34,16 +34,17 @@ obj-y += sysenter.o vsyscall.o obj-$(CONFIG_ACPI_SRAT) += srat.o obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_DOUBLEFAULT) += doublefault.o -obj-$(CONFIG_SERIAL_8250) += legacy_serial.o obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o -obj-$(CONFIG_VMI) += vmi.o vmiclock.o +obj-$(CONFIG_VMI) += vmi.o vmitime.o obj-$(CONFIG_PARAVIRT) += paravirt.o obj-y += pcspeaker.o +EXTRA_AFLAGS := -traditional + obj-$(CONFIG_SCx200) += scx200.o # vsyscall.o contains the vsyscall DSO images as __initdata. diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index 280898b045b2..9ea5b8ecc7e1 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -874,7 +874,7 @@ static void __init acpi_process_madt(void) acpi_ioapic = 1; smp_found_config = 1; - setup_apic_routing(); + clustered_apic_check(); } } if (error == -EINVAL) { diff --git a/trunk/arch/i386/kernel/acpi/earlyquirk.c b/trunk/arch/i386/kernel/acpi/earlyquirk.c index 23f78efc577d..8f7efd38254d 100644 --- a/trunk/arch/i386/kernel/acpi/earlyquirk.c +++ b/trunk/arch/i386/kernel/acpi/earlyquirk.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_ACPI @@ -47,6 +48,24 @@ static int __init check_bridge(int vendor, int device) return 0; } +static void check_intel(void) +{ + u16 vendor, device; + + vendor = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID); + + if (vendor != PCI_VENDOR_ID_INTEL) + return; + + device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); +#ifdef CONFIG_SMP + if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || + device == PCI_DEVICE_ID_INTEL_E7520_MCH || + device == PCI_DEVICE_ID_INTEL_E7525_MCH) + quirk_intel_irqbalance(); +#endif +} + void __init check_acpi_pci(void) { int num, slot, func; @@ -58,6 +77,8 @@ void __init check_acpi_pci(void) if (!early_pci_allowed()) return; + check_intel(); + /* Poor man's PCI discovery */ for (num = 0; num < 32; num++) { for (slot = 0; slot < 32; slot++) { diff --git a/trunk/arch/i386/kernel/alternative.c b/trunk/arch/i386/kernel/alternative.c index d8cda14fff8b..426f59b0106b 100644 --- a/trunk/arch/i386/kernel/alternative.c +++ b/trunk/arch/i386/kernel/alternative.c @@ -5,7 +5,6 @@ #include #include -static int noreplace_smp = 0; static int smp_alt_once = 0; static int debug_alternative = 0; @@ -14,32 +13,14 @@ static int __init bootonly(char *str) smp_alt_once = 1; return 1; } -__setup("smp-alt-boot", bootonly); - static int __init debug_alt(char *str) { debug_alternative = 1; return 1; } -__setup("debug-alternative", debug_alt); -static int __init setup_noreplace_smp(char *str) -{ - noreplace_smp = 1; - return 1; -} -__setup("noreplace-smp", setup_noreplace_smp); - -#ifdef CONFIG_PARAVIRT -static int noreplace_paravirt = 0; - -static int __init setup_noreplace_paravirt(char *str) -{ - noreplace_paravirt = 1; - return 1; -} -__setup("noreplace-paravirt", setup_noreplace_paravirt); -#endif +__setup("smp-alt-boot", bootonly); +__setup("debug-alternative", debug_alt); #define DPRINTK(fmt, args...) if (debug_alternative) \ printk(KERN_DEBUG fmt, args) @@ -151,8 +132,11 @@ static void nop_out(void *insns, unsigned int len) } extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; +extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; extern u8 *__smp_locks[], *__smp_locks_end[]; +extern u8 __smp_alt_begin[], __smp_alt_end[]; + /* Replace instructions with better alternatives for this CPU type. This runs before SMP is initialized to avoid SMP problems with self modifying code. This implies that assymetric systems where @@ -187,6 +171,29 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) #ifdef CONFIG_SMP +static void alternatives_smp_save(struct alt_instr *start, struct alt_instr *end) +{ + struct alt_instr *a; + + DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end); + for (a = start; a < end; a++) { + memcpy(a->replacement + a->replacementlen, + a->instr, + a->instrlen); + } +} + +static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end) +{ + struct alt_instr *a; + + for (a = start; a < end; a++) { + memcpy(a->instr, + a->replacement + a->replacementlen, + a->instrlen); + } +} + static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) { u8 **ptr; @@ -204,9 +211,6 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end { u8 **ptr; - if (noreplace_smp) - return; - for (ptr = start; ptr < end; ptr++) { if (*ptr < text) continue; @@ -241,9 +245,6 @@ void alternatives_smp_module_add(struct module *mod, char *name, struct smp_alt_module *smp; unsigned long flags; - if (noreplace_smp) - return; - if (smp_alt_once) { if (boot_cpu_has(X86_FEATURE_UP)) alternatives_smp_unlock(locks, locks_end, @@ -278,7 +279,7 @@ void alternatives_smp_module_del(struct module *mod) struct smp_alt_module *item; unsigned long flags; - if (smp_alt_once || noreplace_smp) + if (smp_alt_once) return; spin_lock_irqsave(&smp_alt, flags); @@ -309,7 +310,7 @@ void alternatives_smp_switch(int smp) return; #endif - if (noreplace_smp || smp_alt_once) + if (smp_alt_once) return; BUG_ON(!smp && (num_online_cpus() > 1)); @@ -318,6 +319,8 @@ void alternatives_smp_switch(int smp) printk(KERN_INFO "SMP alternatives: switching to SMP code\n"); clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); + alternatives_smp_apply(__smp_alt_instructions, + __smp_alt_instructions_end); list_for_each_entry(mod, &smp_alt_modules, next) alternatives_smp_lock(mod->locks, mod->locks_end, mod->text, mod->text_end); @@ -325,6 +328,8 @@ void alternatives_smp_switch(int smp) printk(KERN_INFO "SMP alternatives: switching to UP code\n"); set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); + apply_alternatives(__smp_alt_instructions, + __smp_alt_instructions_end); list_for_each_entry(mod, &smp_alt_modules, next) alternatives_smp_unlock(mod->locks, mod->locks_end, mod->text, mod->text_end); @@ -335,31 +340,36 @@ void alternatives_smp_switch(int smp) #endif #ifdef CONFIG_PARAVIRT -void apply_paravirt(struct paravirt_patch_site *start, - struct paravirt_patch_site *end) +void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) { - struct paravirt_patch_site *p; - - if (noreplace_paravirt) - return; + struct paravirt_patch *p; for (p = start; p < end; p++) { unsigned int used; used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, p->len); - - BUG_ON(used > p->len); - +#ifdef CONFIG_DEBUG_PARAVIRT + { + int i; + /* Deliberately clobber regs using "not %reg" to find bugs. */ + for (i = 0; i < 3; i++) { + if (p->len - used >= 2 && (p->clobbers & (1 << i))) { + memcpy(p->instr + used, "\xf7\xd0", 2); + p->instr[used+1] |= i; + used += 2; + } + } + } +#endif /* Pad the rest with nops */ nop_out(p->instr + used, p->len - used); } - /* Sync to be conservative, in case we patched following - * instructions */ + /* Sync to be conservative, in case we patched following instructions */ sync_core(); } -extern struct paravirt_patch_site __start_parainstructions[], +extern struct paravirt_patch __start_parainstructions[], __stop_parainstructions[]; #endif /* CONFIG_PARAVIRT */ @@ -386,19 +396,23 @@ void __init alternative_instructions(void) printk(KERN_INFO "SMP alternatives: switching to UP code\n"); set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability); set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability); + apply_alternatives(__smp_alt_instructions, + __smp_alt_instructions_end); alternatives_smp_unlock(__smp_locks, __smp_locks_end, _text, _etext); } free_init_pages("SMP alternatives", - (unsigned long)__smp_locks, - (unsigned long)__smp_locks_end); + (unsigned long)__smp_alt_begin, + (unsigned long)__smp_alt_end); } else { + alternatives_smp_save(__smp_alt_instructions, + __smp_alt_instructions_end); alternatives_smp_module_add(NULL, "core kernel", __smp_locks, __smp_locks_end, _text, _etext); alternatives_smp_switch(0); } #endif - apply_paravirt(__parainstructions, __parainstructions_end); + apply_paravirt(__start_parainstructions, __stop_parainstructions); local_irq_restore(flags); } diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c index 67824f3bb974..93aa911646ad 100644 --- a/trunk/arch/i386/kernel/apic.c +++ b/trunk/arch/i386/kernel/apic.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -128,28 +129,6 @@ static int modern_apic(void) return lapic_get_version() >= 0x14; } -void apic_wait_icr_idle(void) -{ - while (apic_read(APIC_ICR) & APIC_ICR_BUSY) - cpu_relax(); -} - -unsigned long safe_apic_wait_icr_idle(void) -{ - unsigned long send_status; - int timeout; - - timeout = 0; - do { - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - if (!send_status) - break; - udelay(100); - } while (timeout++ < 1000); - - return send_status; -} - /** * enable_NMI_through_LVT0 - enable NMI through local vector table 0 */ diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c index 4112afe712b9..064bbf2861f4 100644 --- a/trunk/arch/i386/kernel/apm.c +++ b/trunk/arch/i386/kernel/apm.c @@ -223,6 +223,7 @@ #include #include #include +#include #include #include #include @@ -232,10 +233,11 @@ #include #include #include -#include #include "io_ports.h" +extern void machine_real_restart(unsigned char *, int); + #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) extern int (*console_blank_hook)(int); #endif @@ -382,6 +384,13 @@ static int ignore_sys_suspend; static int ignore_normal_resume; static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL; +#ifdef CONFIG_APM_RTC_IS_GMT +# define clock_cmos_diff 0 +# define got_clock_diff 1 +#else +static long clock_cmos_diff; +static int got_clock_diff; +#endif static int debug __read_mostly; static int smp __read_mostly; static int apm_disabled = -1; @@ -1172,7 +1181,7 @@ static void reinit_timer(void) unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); - /* set the clock to HZ */ + /* set the clock to 100 Hz */ outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */ udelay(10); outb_p(LATCH & 0xff, PIT_CH0); /* LSB */ diff --git a/trunk/arch/i386/kernel/asm-offsets.c b/trunk/arch/i386/kernel/asm-offsets.c index 27a776c9044d..c37535163bfc 100644 --- a/trunk/arch/i386/kernel/asm-offsets.c +++ b/trunk/arch/i386/kernel/asm-offsets.c @@ -11,11 +11,11 @@ #include #include #include "sigframe.h" -#include #include #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -25,9 +25,6 @@ #define OFFSET(sym, str, mem) \ DEFINE(sym, offsetof(struct str, mem)); -/* workaround for a warning with -Wmissing-prototypes */ -void foo(void); - void foo(void) { OFFSET(SIGCONTEXT_eax, sigcontext, eax); @@ -93,19 +90,18 @@ void foo(void) OFFSET(pbe_next, pbe, next); /* Offset from the sysenter stack to tss.esp0 */ - DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, x86_tss.esp0) - + DEFINE(TSS_sysenter_esp0, offsetof(struct tss_struct, esp0) - sizeof(struct tss_struct)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); - DEFINE(PAGE_SHIFT_asm, PAGE_SHIFT); - DEFINE(PTRS_PER_PTE, PTRS_PER_PTE); - DEFINE(PTRS_PER_PMD, PTRS_PER_PMD); - DEFINE(PTRS_PER_PGD, PTRS_PER_PGD); - - DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK); + DEFINE(VDSO_PRELINK, VDSO_PRELINK); OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); + BLANK(); + OFFSET(PDA_cpu, i386_pda, cpu_number); + OFFSET(PDA_pcurrent, i386_pda, pcurrent); + #ifdef CONFIG_PARAVIRT BLANK(); OFFSET(PARAVIRT_enabled, paravirt_ops, paravirt_enabled); diff --git a/trunk/arch/i386/kernel/cpu/Makefile b/trunk/arch/i386/kernel/cpu/Makefile index 74f27a463db0..010aecfffbc1 100644 --- a/trunk/arch/i386/kernel/cpu/Makefile +++ b/trunk/arch/i386/kernel/cpu/Makefile @@ -2,7 +2,7 @@ # Makefile for x86-compatible CPU details and quirks # -obj-y := common.o proc.o bugs.o +obj-y := common.o proc.o obj-y += amd.o obj-y += cyrix.o @@ -17,5 +17,3 @@ obj-$(CONFIG_X86_MCE) += mcheck/ obj-$(CONFIG_MTRR) += mtrr/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ - -obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o diff --git a/trunk/arch/i386/kernel/cpu/amd.c b/trunk/arch/i386/kernel/cpu/amd.c index 4fec702afd7e..2d47db482972 100644 --- a/trunk/arch/i386/kernel/cpu/amd.c +++ b/trunk/arch/i386/kernel/cpu/amd.c @@ -53,8 +53,6 @@ static __cpuinit int amd_apic_timer_broken(void) return 0; } -int force_mwait __cpuinitdata; - static void __cpuinit init_amd(struct cpuinfo_x86 *c) { u32 l, h; @@ -277,9 +275,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) if (amd_apic_timer_broken()) set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); - - if (c->x86 == 0x10 && !force_mwait) - clear_bit(X86_FEATURE_MWAIT, c->x86_capability); } static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) @@ -319,3 +314,13 @@ int __init amd_init_cpu(void) cpu_devs[X86_VENDOR_AMD] = &amd_cpu_dev; return 0; } + +//early_arch_initcall(amd_init_cpu); + +static int __init amd_exit_cpu(void) +{ + cpu_devs[X86_VENDOR_AMD] = NULL; + return 0; +} + +late_initcall(amd_exit_cpu); diff --git a/trunk/arch/i386/kernel/cpu/bugs.c b/trunk/arch/i386/kernel/cpu/bugs.c deleted file mode 100644 index 54428a2500f3..000000000000 --- a/trunk/arch/i386/kernel/cpu/bugs.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * arch/i386/cpu/bugs.c - * - * Copyright (C) 1994 Linus Torvalds - * - * Cyrix stuff, June 1998 by: - * - Rafael R. Reilova (moved everything from head.S), - * - * - Channing Corn (tests & fixes), - * - Andrew D. Balsa (code cleanup). - */ -#include -#include -#include -#include -#include -#include -#include - -static int __init no_halt(char *s) -{ - boot_cpu_data.hlt_works_ok = 0; - return 1; -} - -__setup("no-hlt", no_halt); - -static int __init mca_pentium(char *s) -{ - mca_pentium_flag = 1; - return 1; -} - -__setup("mca-pentium", mca_pentium); - -static int __init no_387(char *s) -{ - boot_cpu_data.hard_math = 0; - write_cr0(0xE | read_cr0()); - return 1; -} - -__setup("no387", no_387); - -static double __initdata x = 4195835.0; -static double __initdata y = 3145727.0; - -/* - * This used to check for exceptions.. - * However, it turns out that to support that, - * the XMM trap handlers basically had to - * be buggy. So let's have a correct XMM trap - * handler, and forget about printing out - * some status at boot. - * - * We should really only care about bugs here - * anyway. Not features. - */ -static void __init check_fpu(void) -{ - if (!boot_cpu_data.hard_math) { -#ifndef CONFIG_MATH_EMULATION - printk(KERN_EMERG "No coprocessor found and no math emulation present.\n"); - printk(KERN_EMERG "Giving up.\n"); - for (;;) ; -#endif - return; - } - -/* trap_init() enabled FXSR and company _before_ testing for FP problems here. */ - /* Test for the divl bug.. */ - __asm__("fninit\n\t" - "fldl %1\n\t" - "fdivl %2\n\t" - "fmull %2\n\t" - "fldl %1\n\t" - "fsubp %%st,%%st(1)\n\t" - "fistpl %0\n\t" - "fwait\n\t" - "fninit" - : "=m" (*&boot_cpu_data.fdiv_bug) - : "m" (*&x), "m" (*&y)); - if (boot_cpu_data.fdiv_bug) - printk("Hmm, FPU with FDIV bug.\n"); -} - -static void __init check_hlt(void) -{ - if (paravirt_enabled()) - return; - - printk(KERN_INFO "Checking 'hlt' instruction... "); - if (!boot_cpu_data.hlt_works_ok) { - printk("disabled\n"); - return; - } - halt(); - halt(); - halt(); - halt(); - printk("OK.\n"); -} - -/* - * Most 386 processors have a bug where a POPAD can lock the - * machine even from user space. - */ - -static void __init check_popad(void) -{ -#ifndef CONFIG_X86_POPAD_OK - int res, inp = (int) &res; - - printk(KERN_INFO "Checking for popad bug... "); - __asm__ __volatile__( - "movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx " - : "=&a" (res) - : "d" (inp) - : "ecx", "edi" ); - /* If this fails, it means that any user program may lock the CPU hard. Too bad. */ - if (res != 12345678) printk( "Buggy.\n" ); - else printk( "OK.\n" ); -#endif -} - -/* - * Check whether we are able to run this kernel safely on SMP. - * - * - In order to run on a i386, we need to be compiled for i386 - * (for due to lack of "invlpg" and working WP on a i386) - * - In order to run on anything without a TSC, we need to be - * compiled for a i486. - * - In order to support the local APIC on a buggy Pentium machine, - * we need to be compiled with CONFIG_X86_GOOD_APIC disabled, - * which happens implicitly if compiled for a Pentium or lower - * (unless an advanced selection of CPU features is used) as an - * otherwise config implies a properly working local APIC without - * the need to do extra reads from the APIC. -*/ - -static void __init check_config(void) -{ -/* - * We'd better not be a i386 if we're configured to use some - * i486+ only features! (WP works in supervisor mode and the - * new "invlpg" and "bswap" instructions) - */ -#if defined(CONFIG_X86_WP_WORKS_OK) || defined(CONFIG_X86_INVLPG) || defined(CONFIG_X86_BSWAP) - if (boot_cpu_data.x86 == 3) - panic("Kernel requires i486+ for 'invlpg' and other features"); -#endif - -/* - * If we configured ourselves for a TSC, we'd better have one! - */ -#ifdef CONFIG_X86_TSC - if (!cpu_has_tsc && !tsc_disable) - panic("Kernel compiled for Pentium+, requires TSC feature!"); -#endif - -/* - * If we were told we had a good local APIC, check for buggy Pentia, - * i.e. all B steppings and the C2 stepping of P54C when using their - * integrated APIC (see 11AP erratum in "Pentium Processor - * Specification Update"). - */ -#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_GOOD_APIC) - if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL - && cpu_has_apic - && boot_cpu_data.x86 == 5 - && boot_cpu_data.x86_model == 2 - && (boot_cpu_data.x86_mask < 6 || boot_cpu_data.x86_mask == 11)) - panic("Kernel compiled for PMMX+, assumes a local APIC without the read-before-write bug!"); -#endif -} - - -void __init check_bugs(void) -{ - identify_boot_cpu(); -#ifndef CONFIG_SMP - printk("CPU: "); - print_cpu_info(&boot_cpu_data); -#endif - check_config(); - check_fpu(); - check_hlt(); - check_popad(); - init_utsname()->machine[1] = '0' + (boot_cpu_data.x86 > 6 ? 6 : boot_cpu_data.x86); - alternative_instructions(); -} diff --git a/trunk/arch/i386/kernel/cpu/centaur.c b/trunk/arch/i386/kernel/cpu/centaur.c index 473eac883c7b..8c25047975c0 100644 --- a/trunk/arch/i386/kernel/cpu/centaur.c +++ b/trunk/arch/i386/kernel/cpu/centaur.c @@ -469,3 +469,13 @@ int __init centaur_init_cpu(void) cpu_devs[X86_VENDOR_CENTAUR] = ¢aur_cpu_dev; return 0; } + +//early_arch_initcall(centaur_init_cpu); + +static int __init centaur_exit_cpu(void) +{ + cpu_devs[X86_VENDOR_CENTAUR] = NULL; + return 0; +} + +late_initcall(centaur_exit_cpu); diff --git a/trunk/arch/i386/kernel/cpu/common.c b/trunk/arch/i386/kernel/cpu/common.c index 794d593c47eb..dcbbd0a8bfc2 100644 --- a/trunk/arch/i386/kernel/cpu/common.c +++ b/trunk/arch/i386/kernel/cpu/common.c @@ -18,37 +18,15 @@ #include #include #endif +#include #include "cpu.h" -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { - [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, - [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, - [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 }, - [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 }, - /* - * Segments used for calling PnP BIOS have byte granularity. - * They code segments and data segments have fixed 64k limits, - * the transfer segment sizes are set at run time. - */ - [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ - [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */ - [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */ - /* - * The APM segments have byte granularity and their bases - * are set at run time. All have 64k limits. - */ - [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ - /* 16-bit code */ - [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 }, - [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */ +DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); +EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); - [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, - [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 }, -} }; -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); +struct i386_pda *_cpu_pda[NR_CPUS] __read_mostly; +EXPORT_SYMBOL(_cpu_pda); static int cachesize_override __cpuinitdata = -1; static int disable_x86_fxsr __cpuinitdata; @@ -390,7 +368,7 @@ __setup("serialnumber", x86_serial_nr_setup); /* * This does the hard work of actually picking apart the CPU stuff... */ -static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) +void __cpuinit identify_cpu(struct cpuinfo_x86 *c) { int i; @@ -501,22 +479,15 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) /* Init Machine Check Exception if available. */ mcheck_init(c); -} -void __init identify_boot_cpu(void) -{ - identify_cpu(&boot_cpu_data); - sysenter_setup(); + if (c == &boot_cpu_data) + sysenter_setup(); enable_sep_cpu(); - mtrr_bp_init(); -} -void __cpuinit identify_secondary_cpu(struct cpuinfo_x86 *c) -{ - BUG_ON(c == &boot_cpu_data); - identify_cpu(c); - enable_sep_cpu(); - mtrr_ap_init(); + if (c == &boot_cpu_data) + mtrr_bp_init(); + else + mtrr_ap_init(); } #ifdef CONFIG_X86_HT @@ -630,36 +601,129 @@ void __init early_cpu_init(void) #endif } -/* Make sure %fs is initialized properly in idle threads */ +/* Make sure %gs is initialized properly in idle threads */ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) { memset(regs, 0, sizeof(struct pt_regs)); - regs->xfs = __KERNEL_PERCPU; + regs->xfs = __KERNEL_PDA; return regs; } -/* Current gdt points %fs at the "master" per-cpu area: after this, - * it's on the real one. */ -void switch_to_new_gdt(void) +static __cpuinit int alloc_gdt(int cpu) { - struct Xgt_desc_struct gdt_descr; + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + struct desc_struct *gdt; + struct i386_pda *pda; + + gdt = (struct desc_struct *)cpu_gdt_descr->address; + pda = cpu_pda(cpu); + + /* + * This is a horrible hack to allocate the GDT. The problem + * is that cpu_init() is called really early for the boot CPU + * (and hence needs bootmem) but much later for the secondary + * CPUs, when bootmem will have gone away + */ + if (NODE_DATA(0)->bdata->node_bootmem_map) { + BUG_ON(gdt != NULL || pda != NULL); + + gdt = alloc_bootmem_pages(PAGE_SIZE); + pda = alloc_bootmem(sizeof(*pda)); + /* alloc_bootmem(_pages) panics on failure, so no check */ + + memset(gdt, 0, PAGE_SIZE); + memset(pda, 0, sizeof(*pda)); + } else { + /* GDT and PDA might already have been allocated if + this is a CPU hotplug re-insertion. */ + if (gdt == NULL) + gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); + + if (pda == NULL) + pda = kmalloc_node(sizeof(*pda), GFP_KERNEL, cpu_to_node(cpu)); + + if (unlikely(!gdt || !pda)) { + free_pages((unsigned long)gdt, 0); + kfree(pda); + return 0; + } + } + + cpu_gdt_descr->address = (unsigned long)gdt; + cpu_pda(cpu) = pda; + + return 1; +} - gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); - gdt_descr.size = GDT_SIZE - 1; - load_gdt(&gdt_descr); - asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory"); +/* Initial PDA used by boot CPU */ +struct i386_pda boot_pda = { + ._pda = &boot_pda, + .cpu_number = 0, + .pcurrent = &init_task, +}; + +static inline void set_kernel_fs(void) +{ + /* Set %fs for this CPU's PDA. Memory clobber is to create a + barrier with respect to any PDA operations, so the compiler + doesn't move any before here. */ + asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_PDA) : "memory"); } -/* - * cpu_init() initializes state that is per-CPU. Some data is already - * initialized (naturally) in the bootstrap process, such as the GDT - * and IDT. We reload them nevertheless, this function acts as a - * 'CPU state barrier', nothing should get across. - */ -void __cpuinit cpu_init(void) +/* Initialize the CPU's GDT and PDA. The boot CPU does this for + itself, but secondaries find this done for them. */ +__cpuinit int init_gdt(int cpu, struct task_struct *idle) +{ + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + struct desc_struct *gdt; + struct i386_pda *pda; + + /* For non-boot CPUs, the GDT and PDA should already have been + allocated. */ + if (!alloc_gdt(cpu)) { + printk(KERN_CRIT "CPU%d failed to allocate GDT or PDA\n", cpu); + return 0; + } + + gdt = (struct desc_struct *)cpu_gdt_descr->address; + pda = cpu_pda(cpu); + + BUG_ON(gdt == NULL || pda == NULL); + + /* + * Initialize the per-CPU GDT with the boot GDT, + * and set up the GDT descriptor: + */ + memcpy(gdt, cpu_gdt_table, GDT_SIZE); + cpu_gdt_descr->size = GDT_SIZE - 1; + + pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, + (u32 *)&gdt[GDT_ENTRY_PDA].b, + (unsigned long)pda, sizeof(*pda) - 1, + 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */ + + memset(pda, 0, sizeof(*pda)); + pda->_pda = pda; + pda->cpu_number = cpu; + pda->pcurrent = idle; + + return 1; +} + +void __cpuinit cpu_set_gdt(int cpu) +{ + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + + /* Reinit these anyway, even if they've already been done (on + the boot CPU, this will transition from the boot gdt+pda to + the real ones). */ + load_gdt(cpu_gdt_descr); + set_kernel_fs(); +} + +/* Common CPU init for both boot and secondary CPUs */ +static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) { - int cpu = smp_processor_id(); - struct task_struct *curr = current; struct tss_struct * t = &per_cpu(init_tss, cpu); struct thread_struct *thread = &curr->thread; @@ -680,7 +744,6 @@ void __cpuinit cpu_init(void) } load_idt(&idt_descr); - switch_to_new_gdt(); /* * Set up and load the per-CPU TSS and LDT @@ -720,6 +783,38 @@ void __cpuinit cpu_init(void) mxcsr_feature_mask_init(); } +/* Entrypoint to initialize secondary CPU */ +void __cpuinit secondary_cpu_init(void) +{ + int cpu = smp_processor_id(); + struct task_struct *curr = current; + + _cpu_init(cpu, curr); +} + +/* + * cpu_init() initializes state that is per-CPU. Some data is already + * initialized (naturally) in the bootstrap process, such as the GDT + * and IDT. We reload them nevertheless, this function acts as a + * 'CPU state barrier', nothing should get across. + */ +void __cpuinit cpu_init(void) +{ + int cpu = smp_processor_id(); + struct task_struct *curr = current; + + /* Set up the real GDT and PDA, so we can transition from the + boot versions. */ + if (!init_gdt(cpu, curr)) { + /* failed to allocate something; not much we can do... */ + for (;;) + local_irq_enable(); + } + + cpu_set_gdt(cpu); + _cpu_init(cpu, curr); +} + #ifdef CONFIG_HOTPLUG_CPU void __cpuinit cpu_uninit(void) { diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c index a3df9c039bd4..2b030d6ccbf7 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -590,23 +590,20 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle, static int enable_arbiter_disable(void) { struct pci_dev *dev; - int status; int reg; u8 pci_cmd; - status = 1; /* Find PLE133 host bridge */ reg = 0x78; - dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, - NULL); + dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL); /* Find CLE266 host bridge */ if (dev == NULL) { reg = 0x76; - dev = pci_get_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_862X_0, NULL); + dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_862X_0, NULL); /* Find CN400 V-Link host bridge */ if (dev == NULL) - dev = pci_get_device(PCI_VENDOR_ID_VIA, 0x7259, NULL); + dev = pci_find_device(PCI_VENDOR_ID_VIA, 0x7259, NULL); + } if (dev != NULL) { /* Enable access to port 0x22 */ @@ -618,11 +615,10 @@ static int enable_arbiter_disable(void) if (!(pci_cmd & 1<<7)) { printk(KERN_ERR PFX "Can't enable access to port 0x22.\n"); - status = 0; + return 0; } } - pci_dev_put(dev); - return status; + return 1; } return 0; } @@ -633,7 +629,7 @@ static int longhaul_setup_vt8235(void) u8 pci_cmd; /* Find VT8235 southbridge */ - dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL); + dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL); if (dev != NULL) { /* Set transition time to max */ pci_read_config_byte(dev, 0xec, &pci_cmd); @@ -645,7 +641,6 @@ static int longhaul_setup_vt8235(void) pci_read_config_byte(dev, 0xe5, &pci_cmd); pci_cmd |= 1 << 7; pci_write_config_byte(dev, 0xe5, pci_cmd); - pci_dev_put(dev); return 1; } return 0; @@ -683,7 +678,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) sizeof(samuel2_eblcr)); break; case 1 ... 15: - longhaul_version = TYPE_LONGHAUL_V1; + longhaul_version = TYPE_LONGHAUL_V2; if (c->x86_mask < 8) { cpu_model = CPU_SAMUEL2; cpuname = "C3 'Samuel 2' [C5B]"; diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c b/trunk/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c index 4c76b511e194..4786fedca6eb 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/p4-clockmod.c @@ -27,6 +27,7 @@ #include #include #include +#include /* current / set_cpus_allowed() */ #include #include @@ -61,7 +62,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) if (!cpu_online(cpu) || (newstate > DC_DISABLE) || (newstate == DC_RESV)) return -EINVAL; - rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h); + rdmsr(MSR_IA32_THERM_STATUS, l, h); if (l & 0x01) dprintk("CPU#%d currently thermal throttled\n", cpu); @@ -69,10 +70,10 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) if (has_N44_O17_errata[cpu] && (newstate == DC_25PT || newstate == DC_DFLT)) newstate = DC_38PT; - rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); + rdmsr(MSR_IA32_THERM_CONTROL, l, h); if (newstate == DC_DISABLE) { dprintk("CPU#%d disabling modulation\n", cpu); - wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); + wrmsr(MSR_IA32_THERM_CONTROL, l & ~(1<<4), h); } else { dprintk("CPU#%d setting duty cycle to %d%%\n", cpu, ((125 * newstate) / 10)); @@ -83,7 +84,7 @@ static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate) */ l = (l & ~14); l = l | (1<<4) | ((newstate & 0x7)<<1); - wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l, h); + wrmsr(MSR_IA32_THERM_CONTROL, l, h); } return 0; @@ -110,6 +111,7 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, { unsigned int newstate = DC_RESV; struct cpufreq_freqs freqs; + cpumask_t cpus_allowed; int i; if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0], target_freq, relation, &newstate)) @@ -130,8 +132,17 @@ static int cpufreq_p4_target(struct cpufreq_policy *policy, /* run on each logical CPU, see section 13.15.3 of IA32 Intel Architecture Software * Developer's Manual, Volume 3 */ - for_each_cpu_mask(i, policy->cpus) + cpus_allowed = current->cpus_allowed; + + for_each_cpu_mask(i, policy->cpus) { + cpumask_t this_cpu = cpumask_of_cpu(i); + + set_cpus_allowed(current, this_cpu); + BUG_ON(smp_processor_id() != i); + cpufreq_p4_setdc(i, p4clockmod_table[newstate].index); + } + set_cpus_allowed(current, cpus_allowed); /* notifiers */ for_each_cpu_mask(i, policy->cpus) { @@ -245,9 +256,17 @@ static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy) static unsigned int cpufreq_p4_get(unsigned int cpu) { + cpumask_t cpus_allowed; u32 l, h; - rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h); + cpus_allowed = current->cpus_allowed; + + set_cpus_allowed(current, cpumask_of_cpu(cpu)); + BUG_ON(smp_processor_id() != cpu); + + rdmsr(MSR_IA32_THERM_CONTROL, l, h); + + set_cpus_allowed(current, cpus_allowed); if (l & 0x10) { l = l >> 1; diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 7cf3d207b6b3..fe3b67005ebb 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.c @@ -661,8 +661,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); data->powernow_table = powernow_table; - if (first_cpu(cpu_core_map[data->cpu]) == data->cpu) - print_basics(data); + print_basics(data); for (j = 0; j < data->numps; j++) if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid)) @@ -815,8 +814,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) /* fill in data */ data->numps = data->acpi_data.state_count; - if (first_cpu(cpu_core_map[data->cpu]) == data->cpu) - print_basics(data); + print_basics(data); powernow_k8_acpi_pst_values(data, 0); /* notify BIOS that we exist */ diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h index 95be5013c984..0fb2a3001ba5 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h +++ b/trunk/arch/i386/kernel/cpu/cpufreq/powernow-k8.h @@ -215,10 +215,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid); static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); -#ifdef CONFIG_X86_POWERNOW_K8_ACPI static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table); -#endif #ifdef CONFIG_SMP static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 35489fd68852..f43b987f952b 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -720,7 +720,6 @@ static int centrino_target (struct cpufreq_policy *policy, cpu_set(j, set_mask); set_cpus_allowed(current, set_mask); - preempt_disable(); if (unlikely(!cpu_isset(smp_processor_id(), set_mask))) { dprintk("couldn't limit to CPUs in this domain\n"); retval = -EAGAIN; @@ -728,7 +727,6 @@ static int centrino_target (struct cpufreq_policy *policy, /* We haven't started the transition yet. */ goto migrate_end; } - preempt_enable(); break; } @@ -763,13 +761,10 @@ static int centrino_target (struct cpufreq_policy *policy, } wrmsr(MSR_IA32_PERF_CTL, oldmsr, h); - if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { - preempt_enable(); + if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) break; - } cpu_set(j, covered_cpus); - preempt_enable(); } for_each_cpu_mask(k, online_policy_cpus) { @@ -801,11 +796,8 @@ static int centrino_target (struct cpufreq_policy *policy, cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); } } - set_cpus_allowed(current, saved_mask); - return 0; migrate_end: - preempt_enable(); set_cpus_allowed(current, saved_mask); return 0; } diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index b1acc8ce3167..d59277c00911 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index e1c509aa3054..ff0d89806114 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c @@ -17,10 +17,10 @@ #include #include #include +#include #include #include #include -#include #include "speedstep-lib.h" diff --git a/trunk/arch/i386/kernel/cpu/cyrix.c b/trunk/arch/i386/kernel/cpu/cyrix.c index 0b8411a864fb..de27bd07bc9c 100644 --- a/trunk/arch/i386/kernel/cpu/cyrix.c +++ b/trunk/arch/i386/kernel/cpu/cyrix.c @@ -279,7 +279,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) */ if (vendor == PCI_VENDOR_ID_CYRIX && (device == PCI_DEVICE_ID_CYRIX_5510 || device == PCI_DEVICE_ID_CYRIX_5520)) - mark_tsc_unstable("cyrix 5510/5520 detected"); + pit_latch_buggy = 1; } #endif c->x86_cache_size=16; /* Yep 16K integrated cache thats it */ @@ -448,6 +448,16 @@ int __init cyrix_init_cpu(void) return 0; } +//early_arch_initcall(cyrix_init_cpu); + +static int __init cyrix_exit_cpu(void) +{ + cpu_devs[X86_VENDOR_CYRIX] = NULL; + return 0; +} + +late_initcall(cyrix_exit_cpu); + static struct cpu_dev nsc_cpu_dev __cpuinitdata = { .c_vendor = "NSC", .c_ident = { "Geode by NSC" }, @@ -460,3 +470,12 @@ int __init nsc_init_cpu(void) return 0; } +//early_arch_initcall(nsc_init_cpu); + +static int __init nsc_exit_cpu(void) +{ + cpu_devs[X86_VENDOR_NSC] = NULL; + return 0; +} + +late_initcall(nsc_exit_cpu); diff --git a/trunk/arch/i386/kernel/cpu/intel.c b/trunk/arch/i386/kernel/cpu/intel.c index dc4e08147b1f..56fe26584957 100644 --- a/trunk/arch/i386/kernel/cpu/intel.c +++ b/trunk/arch/i386/kernel/cpu/intel.c @@ -188,10 +188,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) } #endif - if (c->x86 == 15) { + if (c->x86 == 15) set_bit(X86_FEATURE_P4, c->x86_capability); - set_bit(X86_FEATURE_SYNC_RDTSC, c->x86_capability); - } if (c->x86 == 6) set_bit(X86_FEATURE_P3, c->x86_capability); if ((c->x86 == 0xf && c->x86_model >= 0x03) || diff --git a/trunk/arch/i386/kernel/cpu/mcheck/k7.c b/trunk/arch/i386/kernel/cpu/mcheck/k7.c index f9fa4142551e..b0862af595aa 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/k7.c +++ b/trunk/arch/i386/kernel/cpu/mcheck/k7.c @@ -75,9 +75,6 @@ void amd_mcheck_init(struct cpuinfo_x86 *c) machine_check_vector = k7_machine_check; wmb(); - if (!cpu_has(c, X86_FEATURE_MCE)) - return; - printk (KERN_INFO "Intel machine check architecture supported.\n"); rdmsr (MSR_IA32_MCG_CAP, l, h); if (l & (1<<8)) /* Control register present ? */ @@ -85,13 +82,9 @@ void amd_mcheck_init(struct cpuinfo_x86 *c) nr_mce_banks = l & 0xff; /* Clear status for MC index 0 separately, we don't touch CTL, - * as some K7 Athlons cause spurious MCEs when its enabled. */ - if (boot_cpu_data.x86 == 6) { - wrmsr (MSR_IA32_MC0_STATUS, 0x0, 0x0); - i = 1; - } else - i = 0; - for (; ix86_vendor) { case X86_VENDOR_AMD: - amd_mcheck_init(c); + if (c->x86==6 || c->x86==15) + amd_mcheck_init(c); break; case X86_VENDOR_INTEL: diff --git a/trunk/arch/i386/kernel/cpu/mcheck/p4.c b/trunk/arch/i386/kernel/cpu/mcheck/p4.c index 1509edfb2313..504434a46011 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/p4.c +++ b/trunk/arch/i386/kernel/cpu/mcheck/p4.c @@ -124,10 +124,13 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) /* P4/Xeon Extended MCE MSR retrieval, return 0 if unsupported */ -static inline void intel_get_extended_msrs(struct intel_mce_extended_msrs *r) +static inline int intel_get_extended_msrs(struct intel_mce_extended_msrs *r) { u32 h; + if (mce_num_extended_msrs == 0) + goto done; + rdmsr (MSR_IA32_MCG_EAX, r->eax, h); rdmsr (MSR_IA32_MCG_EBX, r->ebx, h); rdmsr (MSR_IA32_MCG_ECX, r->ecx, h); @@ -138,6 +141,12 @@ static inline void intel_get_extended_msrs(struct intel_mce_extended_msrs *r) rdmsr (MSR_IA32_MCG_ESP, r->esp, h); rdmsr (MSR_IA32_MCG_EFLAGS, r->eflags, h); rdmsr (MSR_IA32_MCG_EIP, r->eip, h); + + /* can we rely on kmalloc to do a dynamic + * allocation for the reserved registers? + */ +done: + return mce_num_extended_msrs; } static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) @@ -146,6 +155,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) u32 alow, ahigh, high, low; u32 mcgstl, mcgsth; int i; + struct intel_mce_extended_msrs dbg; rdmsr (MSR_IA32_MCG_STATUS, mcgstl, mcgsth); if (mcgstl & (1<<0)) /* Recoverable ? */ @@ -154,9 +164,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl); - if (mce_num_extended_msrs > 0) { - struct intel_mce_extended_msrs dbg; - intel_get_extended_msrs(&dbg); + if (intel_get_extended_msrs(&dbg)) { printk (KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n", smp_processor_id(), dbg.eip, dbg.eflags); printk (KERN_DEBUG "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n", diff --git a/trunk/arch/i386/kernel/cpu/mtrr/generic.c b/trunk/arch/i386/kernel/cpu/mtrr/generic.c index 5367e32e0403..f77fc53db654 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/generic.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/generic.c @@ -20,25 +20,13 @@ struct mtrr_state { mtrr_type def_type; }; -struct fixed_range_block { - int base_msr; /* start address of an MTRR block */ - int ranges; /* number of MTRRs in this block */ -}; - -static struct fixed_range_block fixed_range_blocks[] = { - { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */ - { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */ - { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */ - {} -}; - static unsigned long smp_changes_mask; static struct mtrr_state mtrr_state = {}; #undef MODULE_PARAM_PREFIX #define MODULE_PARAM_PREFIX "mtrr." -static int mtrr_show; +static __initdata int mtrr_show; module_param_named(show, mtrr_show, bool, 0); /* Get the MSR pair relating to a var range */ @@ -49,7 +37,7 @@ get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) rdmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi); } -static void +static void __init get_fixed_ranges(mtrr_type * frs) { unsigned int *p = (unsigned int *) frs; @@ -63,18 +51,12 @@ get_fixed_ranges(mtrr_type * frs) rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]); } -void mtrr_save_fixed_ranges(void *info) -{ - get_fixed_ranges(mtrr_state.fixed_ranges); -} - -static void __cpuinit print_fixed(unsigned base, unsigned step, const mtrr_type*types) +static void __init print_fixed(unsigned base, unsigned step, const mtrr_type*types) { unsigned i; for (i = 0; i < 8; ++i, ++types, base += step) - printk(KERN_INFO "MTRR %05X-%05X %s\n", - base, base + step - 1, mtrr_attrib_to_str(*types)); + printk(KERN_INFO "MTRR %05X-%05X %s\n", base, base + step - 1, mtrr_attrib_to_str(*types)); } /* Grab all of the MTRR state for this CPU into *state */ @@ -165,44 +147,6 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) smp_processor_id(), msr, a, b); } -/** - * Enable and allow read/write of extended fixed-range MTRR bits on K8 CPUs - * see AMD publication no. 24593, chapter 3.2.1 for more information - */ -static inline void k8_enable_fixed_iorrs(void) -{ - unsigned lo, hi; - - rdmsr(MSR_K8_SYSCFG, lo, hi); - mtrr_wrmsr(MSR_K8_SYSCFG, lo - | K8_MTRRFIXRANGE_DRAM_ENABLE - | K8_MTRRFIXRANGE_DRAM_MODIFY, hi); -} - -/** - * Checks and updates an fixed-range MTRR if it differs from the value it - * should have. If K8 extenstions are wanted, update the K8 SYSCFG MSR also. - * see AMD publication no. 24593, chapter 7.8.1, page 233 for more information - * \param msr MSR address of the MTTR which should be checked and updated - * \param changed pointer which indicates whether the MTRR needed to be changed - * \param msrwords pointer to the MSR values which the MSR should have - */ -static void set_fixed_range(int msr, int * changed, unsigned int * msrwords) -{ - unsigned lo, hi; - - rdmsr(msr, lo, hi); - - if (lo != msrwords[0] || hi != msrwords[1]) { - if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && - boot_cpu_data.x86 == 15 && - ((msrwords[0] | msrwords[1]) & K8_MTRR_RDMEM_WRMEM_MASK)) - k8_enable_fixed_iorrs(); - mtrr_wrmsr(msr, msrwords[0], msrwords[1]); - *changed = TRUE; - } -} - int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) /* [SUMMARY] Get a free MTRR. The starting (base) address of the region. @@ -252,21 +196,36 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base, *type = base_lo & 0xff; } -/** - * Checks and updates the fixed-range MTRRs if they differ from the saved set - * \param frs pointer to fixed-range MTRR values, saved by get_fixed_ranges() - */ static int set_fixed_ranges(mtrr_type * frs) { - unsigned long long *saved = (unsigned long long *) frs; + unsigned int *p = (unsigned int *) frs; int changed = FALSE; - int block=-1, range; + int i; + unsigned int lo, hi; - while (fixed_range_blocks[++block].ranges) - for (range=0; range < fixed_range_blocks[block].ranges; range++) - set_fixed_range(fixed_range_blocks[block].base_msr + range, - &changed, (unsigned int *) saved++); + rdmsr(MTRRfix64K_00000_MSR, lo, hi); + if (p[0] != lo || p[1] != hi) { + mtrr_wrmsr(MTRRfix64K_00000_MSR, p[0], p[1]); + changed = TRUE; + } + for (i = 0; i < 2; i++) { + rdmsr(MTRRfix16K_80000_MSR + i, lo, hi); + if (p[2 + i * 2] != lo || p[3 + i * 2] != hi) { + mtrr_wrmsr(MTRRfix16K_80000_MSR + i, p[2 + i * 2], + p[3 + i * 2]); + changed = TRUE; + } + } + + for (i = 0; i < 8; i++) { + rdmsr(MTRRfix4K_C0000_MSR + i, lo, hi); + if (p[6 + i * 2] != lo || p[7 + i * 2] != hi) { + mtrr_wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], + p[7 + i * 2]); + changed = TRUE; + } + } return changed; } @@ -469,7 +428,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i } } - if (base < 0x100) { + if (base + size < 0x100) { printk(KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n", base, size); return -EINVAL; diff --git a/trunk/arch/i386/kernel/cpu/mtrr/main.c b/trunk/arch/i386/kernel/cpu/mtrr/main.c index 02a2f39e5e0a..0acfb6a5a220 100644 --- a/trunk/arch/i386/kernel/cpu/mtrr/main.c +++ b/trunk/arch/i386/kernel/cpu/mtrr/main.c @@ -729,17 +729,6 @@ void mtrr_ap_init(void) local_irq_restore(flags); } -/** - * Save current fixed-range MTRR state of the BSP - */ -void mtrr_save_state(void) -{ - if (smp_processor_id() == 0) - mtrr_save_fixed_ranges(NULL); - else - smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1, 1); -} - static int __init mtrr_init_finialize(void) { if (!mtrr_if) diff --git a/trunk/arch/i386/kernel/cpu/nexgen.c b/trunk/arch/i386/kernel/cpu/nexgen.c index 961fbe1a748f..8bf23cc80c63 100644 --- a/trunk/arch/i386/kernel/cpu/nexgen.c +++ b/trunk/arch/i386/kernel/cpu/nexgen.c @@ -58,3 +58,13 @@ int __init nexgen_init_cpu(void) cpu_devs[X86_VENDOR_NEXGEN] = &nexgen_cpu_dev; return 0; } + +//early_arch_initcall(nexgen_init_cpu); + +static int __init nexgen_exit_cpu(void) +{ + cpu_devs[X86_VENDOR_NEXGEN] = NULL; + return 0; +} + +late_initcall(nexgen_exit_cpu); diff --git a/trunk/arch/i386/kernel/cpu/perfctr-watchdog.c b/trunk/arch/i386/kernel/cpu/perfctr-watchdog.c deleted file mode 100644 index 2b04c8f1db62..000000000000 --- a/trunk/arch/i386/kernel/cpu/perfctr-watchdog.c +++ /dev/null @@ -1,658 +0,0 @@ -/* local apic based NMI watchdog for various CPUs. - This file also handles reservation of performance counters for coordination - with other users (like oprofile). - - Note that these events normally don't tick when the CPU idles. This means - the frequency varies with CPU load. - - Original code for K7/P6 written by Keith Owens */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct nmi_watchdog_ctlblk { - unsigned int cccr_msr; - unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ - unsigned int evntsel_msr; /* the MSR to select the events to handle */ -}; - -/* Interface defining a CPU specific perfctr watchdog */ -struct wd_ops { - int (*reserve)(void); - void (*unreserve)(void); - int (*setup)(unsigned nmi_hz); - void (*rearm)(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz); - void (*stop)(void *); - unsigned perfctr; - unsigned evntsel; - u64 checkbit; -}; - -static struct wd_ops *wd_ops; - -/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's - * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) - */ -#define NMI_MAX_COUNTER_BITS 66 - -/* perfctr_nmi_owner tracks the ownership of the perfctr registers: - * evtsel_nmi_owner tracks the ownership of the event selection - * - different performance counters/ event selection may be reserved for - * different subsystems this reservation system just tries to coordinate - * things a little - */ -static DECLARE_BITMAP(perfctr_nmi_owner, NMI_MAX_COUNTER_BITS); -static DECLARE_BITMAP(evntsel_nmi_owner, NMI_MAX_COUNTER_BITS); - -static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) -{ - return wd_ops ? msr - wd_ops->perfctr : 0; -} - -/* converts an msr to an appropriate reservation bit */ -/* returns the bit offset of the event selection register */ -static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) -{ - return wd_ops ? msr - wd_ops->evntsel : 0; -} - -/* checks for a bit availability (hack for oprofile) */ -int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) -{ - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, perfctr_nmi_owner)); -} - -/* checks the an msr for availability */ -int avail_to_resrv_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, perfctr_nmi_owner)); -} - -int reserve_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, perfctr_nmi_owner)) - return 1; - return 0; -} - -void release_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, perfctr_nmi_owner); -} - -int reserve_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, evntsel_nmi_owner)) - return 1; - return 0; -} - -void release_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, evntsel_nmi_owner); -} - -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); -EXPORT_SYMBOL(reserve_perfctr_nmi); -EXPORT_SYMBOL(release_perfctr_nmi); -EXPORT_SYMBOL(reserve_evntsel_nmi); -EXPORT_SYMBOL(release_evntsel_nmi); - -void disable_lapic_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - if (atomic_read(&nmi_active) <= 0) - return; - - on_each_cpu(wd_ops->stop, NULL, 0, 1); - wd_ops->unreserve(); - - BUG_ON(atomic_read(&nmi_active) != 0); -} - -void enable_lapic_nmi_watchdog(void) -{ - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - /* are we already enabled */ - if (atomic_read(&nmi_active) != 0) - return; - - /* are we lapic aware */ - if (!wd_ops) - return; - if (!wd_ops->reserve()) { - printk(KERN_ERR "NMI watchdog: cannot reserve perfctrs\n"); - return; - } - - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - touch_nmi_watchdog(); -} - -/* - * Activate the NMI watchdog via the local APIC. - */ - -static unsigned int adjust_for_32bit_ctr(unsigned int hz) -{ - u64 counter_val; - unsigned int retval = hz; - - /* - * On Intel CPUs with P6/ARCH_PERFMON only 32 bits in the counter - * are writable, with higher bits sign extending from bit 31. - * So, we can only program the counter with 31 bit values and - * 32nd bit should be 1, for 33.. to be 1. - * Find the appropriate nmi_hz - */ - counter_val = (u64)cpu_khz * 1000; - do_div(counter_val, retval); - if (counter_val > 0x7fffffffULL) { - u64 count = (u64)cpu_khz * 1000; - do_div(count, 0x7fffffffUL); - retval = count + 1; - } - return retval; -} - -static void -write_watchdog_counter(unsigned int perfctr_msr, const char *descr, unsigned nmi_hz) -{ - u64 count = (u64)cpu_khz * 1000; - - do_div(count, nmi_hz); - if(descr) - Dprintk("setting %s to -0x%08Lx\n", descr, count); - wrmsrl(perfctr_msr, 0 - count); -} - -static void write_watchdog_counter32(unsigned int perfctr_msr, - const char *descr, unsigned nmi_hz) -{ - u64 count = (u64)cpu_khz * 1000; - - do_div(count, nmi_hz); - if(descr) - Dprintk("setting %s to -0x%08Lx\n", descr, count); - wrmsr(perfctr_msr, (u32)(-count), 0); -} - -/* AMD K7/K8/Family10h/Family11h support. AMD keeps this interface - nicely stable so there is not much variety */ - -#define K7_EVNTSEL_ENABLE (1 << 22) -#define K7_EVNTSEL_INT (1 << 20) -#define K7_EVNTSEL_OS (1 << 17) -#define K7_EVNTSEL_USR (1 << 16) -#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 -#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - -static int setup_k7_watchdog(unsigned nmi_hz) -{ - unsigned int perfctr_msr, evntsel_msr; - unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_K7_PERFCTR0; - evntsel_msr = MSR_K7_EVNTSEL0; - - wrmsrl(perfctr_msr, 0UL); - - evntsel = K7_EVNTSEL_INT - | K7_EVNTSEL_OS - | K7_EVNTSEL_USR - | K7_NMI_EVENT; - - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - write_watchdog_counter(perfctr_msr, "K7_PERFCTR0",nmi_hz); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= K7_EVNTSEL_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - return 1; -} - -static void single_msr_stop_watchdog(void *arg) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); -} - -static int single_msr_reserve(void) -{ - if (!reserve_perfctr_nmi(wd_ops->perfctr)) - return 0; - - if (!reserve_evntsel_nmi(wd_ops->evntsel)) { - release_perfctr_nmi(wd_ops->perfctr); - return 0; - } - return 1; -} - -static void single_msr_unreserve(void) -{ - release_evntsel_nmi(wd_ops->perfctr); - release_perfctr_nmi(wd_ops->evntsel); -} - -static void single_msr_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz) -{ - /* start the cycle over again */ - write_watchdog_counter(wd->perfctr_msr, NULL, nmi_hz); -} - -static struct wd_ops k7_wd_ops = { - .reserve = single_msr_reserve, - .unreserve = single_msr_unreserve, - .setup = setup_k7_watchdog, - .rearm = single_msr_rearm, - .stop = single_msr_stop_watchdog, - .perfctr = MSR_K7_PERFCTR0, - .evntsel = MSR_K7_EVNTSEL0, - .checkbit = 1ULL<<63, -}; - -/* Intel Model 6 (PPro+,P2,P3,P-M,Core1) */ - -#define P6_EVNTSEL0_ENABLE (1 << 22) -#define P6_EVNTSEL_INT (1 << 20) -#define P6_EVNTSEL_OS (1 << 17) -#define P6_EVNTSEL_USR (1 << 16) -#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 -#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED - -static int setup_p6_watchdog(unsigned nmi_hz) -{ - unsigned int perfctr_msr, evntsel_msr; - unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_P6_PERFCTR0; - evntsel_msr = MSR_P6_EVNTSEL0; - - wrmsrl(perfctr_msr, 0UL); - - evntsel = P6_EVNTSEL_INT - | P6_EVNTSEL_OS - | P6_EVNTSEL_USR - | P6_NMI_EVENT; - - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - nmi_hz = adjust_for_32bit_ctr(nmi_hz); - write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0",nmi_hz); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= P6_EVNTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - return 1; -} - -static void p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz) -{ - /* P6 based Pentium M need to re-unmask - * the apic vector but it doesn't hurt - * other P6 variant. - * ArchPerfom/Core Duo also needs this */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - /* P6/ARCH_PERFMON has 32 bit counter write */ - write_watchdog_counter32(wd->perfctr_msr, NULL,nmi_hz); -} - -static struct wd_ops p6_wd_ops = { - .reserve = single_msr_reserve, - .unreserve = single_msr_unreserve, - .setup = setup_p6_watchdog, - .rearm = p6_rearm, - .stop = single_msr_stop_watchdog, - .perfctr = MSR_P6_PERFCTR0, - .evntsel = MSR_P6_EVNTSEL0, - .checkbit = 1ULL<<39, -}; - -/* Intel P4 performance counters. By far the most complicated of all. */ - -#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) -#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) -#define P4_ESCR_OS (1<<3) -#define P4_ESCR_USR (1<<2) -#define P4_CCCR_OVF_PMI0 (1<<26) -#define P4_CCCR_OVF_PMI1 (1<<27) -#define P4_CCCR_THRESHOLD(N) ((N)<<20) -#define P4_CCCR_COMPLEMENT (1<<19) -#define P4_CCCR_COMPARE (1<<18) -#define P4_CCCR_REQUIRED (3<<16) -#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) -#define P4_CCCR_ENABLE (1<<12) -#define P4_CCCR_OVF (1<<31) - -/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter - CRU_ESCR0 (with any non-null event selector) through a complemented - max threshold. [IA32-Vol3, Section 14.9.9] */ - -static int setup_p4_watchdog(unsigned nmi_hz) -{ - unsigned int perfctr_msr, evntsel_msr, cccr_msr; - unsigned int evntsel, cccr_val; - unsigned int misc_enable, dummy; - unsigned int ht_num; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); - if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) - return 0; - -#ifdef CONFIG_SMP - /* detect which hyperthread we are on */ - if (smp_num_siblings == 2) { - unsigned int ebx, apicid; - - ebx = cpuid_ebx(1); - apicid = (ebx >> 24) & 0xff; - ht_num = apicid & 1; - } else -#endif - ht_num = 0; - - /* performance counters are shared resources - * assign each hyperthread its own set - * (re-use the ESCR0 register, seems safe - * and keeps the cccr_val the same) - */ - if (!ht_num) { - /* logical cpu 0 */ - perfctr_msr = MSR_P4_IQ_PERFCTR0; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR0; - cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); - } else { - /* logical cpu 1 */ - perfctr_msr = MSR_P4_IQ_PERFCTR1; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR1; - cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); - } - - evntsel = P4_ESCR_EVENT_SELECT(0x3F) - | P4_ESCR_OS - | P4_ESCR_USR; - - cccr_val |= P4_CCCR_THRESHOLD(15) - | P4_CCCR_COMPLEMENT - | P4_CCCR_COMPARE - | P4_CCCR_REQUIRED; - - wrmsr(evntsel_msr, evntsel, 0); - wrmsr(cccr_msr, cccr_val, 0); - write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0", nmi_hz); - apic_write(APIC_LVTPC, APIC_DM_NMI); - cccr_val |= P4_CCCR_ENABLE; - wrmsr(cccr_msr, cccr_val, 0); - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = cccr_msr; - return 1; -} - -static void stop_p4_watchdog(void *arg) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - wrmsr(wd->cccr_msr, 0, 0); - wrmsr(wd->evntsel_msr, 0, 0); -} - -static int p4_reserve(void) -{ - if (!reserve_perfctr_nmi(MSR_P4_IQ_PERFCTR0)) - return 0; -#ifdef CONFIG_SMP - if (smp_num_siblings > 1 && !reserve_perfctr_nmi(MSR_P4_IQ_PERFCTR1)) - goto fail1; -#endif - if (!reserve_evntsel_nmi(MSR_P4_CRU_ESCR0)) - goto fail2; - /* RED-PEN why is ESCR1 not reserved here? */ - return 1; - fail2: -#ifdef CONFIG_SMP - if (smp_num_siblings > 1) - release_perfctr_nmi(MSR_P4_IQ_PERFCTR1); - fail1: -#endif - release_perfctr_nmi(MSR_P4_IQ_PERFCTR0); - return 0; -} - -static void p4_unreserve(void) -{ -#ifdef CONFIG_SMP - if (smp_num_siblings > 1) - release_evntsel_nmi(MSR_P4_IQ_PERFCTR1); -#endif - release_evntsel_nmi(MSR_P4_IQ_PERFCTR0); - release_perfctr_nmi(MSR_P4_CRU_ESCR0); -} - -static void p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz) -{ - unsigned dummy; - /* - * P4 quirks: - * - An overflown perfctr will assert its interrupt - * until the OVF flag in its CCCR is cleared. - * - LVTPC is masked on interrupt and must be - * unmasked by the LVTPC handler. - */ - rdmsrl(wd->cccr_msr, dummy); - dummy &= ~P4_CCCR_OVF; - wrmsrl(wd->cccr_msr, dummy); - apic_write(APIC_LVTPC, APIC_DM_NMI); - /* start the cycle over again */ - write_watchdog_counter(wd->perfctr_msr, NULL, nmi_hz); -} - -static struct wd_ops p4_wd_ops = { - .reserve = p4_reserve, - .unreserve = p4_unreserve, - .setup = setup_p4_watchdog, - .rearm = p4_rearm, - .stop = stop_p4_watchdog, - /* RED-PEN this is wrong for the other sibling */ - .perfctr = MSR_P4_BPU_PERFCTR0, - .evntsel = MSR_P4_BSU_ESCR0, - .checkbit = 1ULL<<39, -}; - -/* Watchdog using the Intel architected PerfMon. Used for Core2 and hopefully - all future Intel CPUs. */ - -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - -static int setup_intel_arch_watchdog(unsigned nmi_hz) -{ - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - unsigned int perfctr_msr, evntsel_msr; - unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return 0; - - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR1; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL1; - - wrmsrl(perfctr_msr, 0UL); - - evntsel = ARCH_PERFMON_EVENTSEL_INT - | ARCH_PERFMON_EVENTSEL_OS - | ARCH_PERFMON_EVENTSEL_USR - | ARCH_PERFMON_NMI_EVENT_SEL - | ARCH_PERFMON_NMI_EVENT_UMASK; - - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - nmi_hz = adjust_for_32bit_ctr(nmi_hz); - write_watchdog_counter32(perfctr_msr, "INTEL_ARCH_PERFCTR0", nmi_hz); - apic_write(APIC_LVTPC, APIC_DM_NMI); - evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd_ops->checkbit = 1ULL << (eax.split.bit_width - 1); - return 1; -} - -static struct wd_ops intel_arch_wd_ops = { - .reserve = single_msr_reserve, - .unreserve = single_msr_unreserve, - .setup = setup_intel_arch_watchdog, - .rearm = p6_rearm, - .stop = single_msr_stop_watchdog, - .perfctr = MSR_ARCH_PERFMON_PERFCTR0, - .evntsel = MSR_ARCH_PERFMON_EVENTSEL0, -}; - -static void probe_nmi_watchdog(void) -{ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 && - boot_cpu_data.x86 != 16) - return; - wd_ops = &k7_wd_ops; - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - wd_ops = &intel_arch_wd_ops; - break; - } - switch (boot_cpu_data.x86) { - case 6: - if (boot_cpu_data.x86_model > 0xd) - return; - - wd_ops = &p6_wd_ops; - break; - case 15: - if (boot_cpu_data.x86_model > 0x4) - return; - - wd_ops = &p4_wd_ops; - break; - default: - return; - } - break; - } -} - -/* Interface to nmi.c */ - -int lapic_watchdog_init(unsigned nmi_hz) -{ - if (!wd_ops) { - probe_nmi_watchdog(); - if (!wd_ops) - return -1; - } - - if (!(wd_ops->setup(nmi_hz))) { - printk(KERN_ERR "Cannot setup NMI watchdog on CPU %d\n", - raw_smp_processor_id()); - return -1; - } - - return 0; -} - -void lapic_watchdog_stop(void) -{ - if (wd_ops) - wd_ops->stop(NULL); -} - -unsigned lapic_adjust_nmi_hz(unsigned hz) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - if (wd->perfctr_msr == MSR_P6_PERFCTR0 || - wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR1) - hz = adjust_for_32bit_ctr(hz); - return hz; -} - -int lapic_wd_event(unsigned nmi_hz) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - u64 ctr; - rdmsrl(wd->perfctr_msr, ctr); - if (ctr & wd_ops->checkbit) { /* perfctr still running? */ - return 0; - } - wd_ops->rearm(wd, nmi_hz); - return 1; -} - -int lapic_watchdog_ok(void) -{ - return wd_ops != NULL; -} diff --git a/trunk/arch/i386/kernel/cpu/proc.c b/trunk/arch/i386/kernel/cpu/proc.c index 89d91e6cc972..47e3ebbfb28d 100644 --- a/trunk/arch/i386/kernel/cpu/proc.c +++ b/trunk/arch/i386/kernel/cpu/proc.c @@ -72,7 +72,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) "stc", "100mhzsteps", "hwpstate", - "", /* constant_tsc - moved to flags */ + NULL, + NULL, /* constant_tsc - moved to flags */ /* nothing */ }; struct cpuinfo_x86 *c = v; diff --git a/trunk/arch/i386/kernel/cpu/rise.c b/trunk/arch/i386/kernel/cpu/rise.c index 50076f22e90f..9317f7414989 100644 --- a/trunk/arch/i386/kernel/cpu/rise.c +++ b/trunk/arch/i386/kernel/cpu/rise.c @@ -50,3 +50,12 @@ int __init rise_init_cpu(void) return 0; } +//early_arch_initcall(rise_init_cpu); + +static int __init rise_exit_cpu(void) +{ + cpu_devs[X86_VENDOR_RISE] = NULL; + return 0; +} + +late_initcall(rise_exit_cpu); diff --git a/trunk/arch/i386/kernel/cpu/transmeta.c b/trunk/arch/i386/kernel/cpu/transmeta.c index 6471a5a13202..5678d46863c6 100644 --- a/trunk/arch/i386/kernel/cpu/transmeta.c +++ b/trunk/arch/i386/kernel/cpu/transmeta.c @@ -112,3 +112,13 @@ int __init transmeta_init_cpu(void) cpu_devs[X86_VENDOR_TRANSMETA] = &transmeta_cpu_dev; return 0; } + +//early_arch_initcall(transmeta_init_cpu); + +static int __init transmeta_exit_cpu(void) +{ + cpu_devs[X86_VENDOR_TRANSMETA] = NULL; + return 0; +} + +late_initcall(transmeta_exit_cpu); diff --git a/trunk/arch/i386/kernel/cpu/umc.c b/trunk/arch/i386/kernel/cpu/umc.c index a7a4e75bdcd7..1bf3f87e9c5b 100644 --- a/trunk/arch/i386/kernel/cpu/umc.c +++ b/trunk/arch/i386/kernel/cpu/umc.c @@ -24,3 +24,13 @@ int __init umc_init_cpu(void) cpu_devs[X86_VENDOR_UMC] = &umc_cpu_dev; return 0; } + +//early_arch_initcall(umc_init_cpu); + +static int __init umc_exit_cpu(void) +{ + cpu_devs[X86_VENDOR_UMC] = NULL; + return 0; +} + +late_initcall(umc_exit_cpu); diff --git a/trunk/arch/i386/kernel/crash.c b/trunk/arch/i386/kernel/crash.c index 53589d1b1a05..a5e0e990ea95 100644 --- a/trunk/arch/i386/kernel/crash.c +++ b/trunk/arch/i386/kernel/crash.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/arch/i386/kernel/doublefault.c b/trunk/arch/i386/kernel/doublefault.c index 265c5597efb0..b4d14c2eb345 100644 --- a/trunk/arch/i386/kernel/doublefault.c +++ b/trunk/arch/i386/kernel/doublefault.c @@ -33,7 +33,7 @@ static void doublefault_fn(void) printk("double fault, tss at %08lx\n", tss); if (ptr_ok(tss)) { - struct i386_hw_tss *t = (struct i386_hw_tss *)tss; + struct tss_struct *t = (struct tss_struct *)tss; printk("eip = %08lx, esp = %08lx\n", t->eip, t->esp); @@ -49,21 +49,18 @@ static void doublefault_fn(void) } struct tss_struct doublefault_tss __cacheline_aligned = { - .x86_tss = { - .esp0 = STACK_START, - .ss0 = __KERNEL_DS, - .ldt = 0, - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, + .esp0 = STACK_START, + .ss0 = __KERNEL_DS, + .ldt = 0, + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, - .eip = (unsigned long) doublefault_fn, - /* 0x2 bit is always set */ - .eflags = X86_EFLAGS_SF | 0x2, - .esp = STACK_START, - .es = __USER_DS, - .cs = __KERNEL_CS, - .ss = __KERNEL_DS, - .ds = __USER_DS, + .eip = (unsigned long) doublefault_fn, + .eflags = X86_EFLAGS_SF | 0x2, /* 0x2 bit is always set */ + .esp = STACK_START, + .es = __USER_DS, + .cs = __KERNEL_CS, + .ss = __KERNEL_DS, + .ds = __USER_DS, - .__cr3 = __pa(swapper_pg_dir) - } + .__cr3 = __pa(swapper_pg_dir) }; diff --git a/trunk/arch/i386/kernel/e820.c b/trunk/arch/i386/kernel/e820.c index 9645bb51f76a..70f39560846a 100644 --- a/trunk/arch/i386/kernel/e820.c +++ b/trunk/arch/i386/kernel/e820.c @@ -161,27 +161,26 @@ static struct resource standard_io_resources[] = { { static int __init romsignature(const unsigned char *rom) { - const unsigned short * const ptr = (const unsigned short *)rom; unsigned short sig; - return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; + return probe_kernel_address((const unsigned short *)rom, sig) == 0 && + sig == ROMSIGNATURE; } -static int __init romchecksum(const unsigned char *rom, unsigned long length) +static int __init romchecksum(unsigned char *rom, unsigned long length) { - unsigned char sum, c; + unsigned char sum; - for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) - sum += c; - return !length && !sum; + for (sum = 0; length; length--) + sum += *rom++; + return sum == 0; } static void __init probe_roms(void) { - const unsigned char *rom; unsigned long start, length, upper; - unsigned char c; - int i; + unsigned char *rom; + int i; /* video rom */ upper = adapter_rom_resources[0].start; @@ -192,11 +191,8 @@ static void __init probe_roms(void) video_rom_resource.start = start; - if (probe_kernel_address(rom + 2, c) != 0) - continue; - /* 0 < length <= 0x7f * 512, historically */ - length = c * 512; + length = rom[2] * 512; /* if checksum okay, trust length byte */ if (length && romchecksum(rom, length)) @@ -230,11 +226,8 @@ static void __init probe_roms(void) if (!romsignature(rom)) continue; - if (probe_kernel_address(rom + 2, c) != 0) - continue; - /* 0 < length <= 0x7f * 512, historically */ - length = c * 512; + length = rom[2] * 512; /* but accept any length that fits if checksum okay */ if (!length || start + length > upper || !romchecksum(rom, length)) @@ -393,8 +386,10 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) ____________________33__ ______________________4_ */ + printk("sanitize start\n"); /* if there's only one memory region, don't bother */ if (*pnr_map < 2) { + printk("sanitize bail 0\n"); return -1; } @@ -403,6 +398,7 @@ int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) /* bail out if we find any unreasonable addresses in bios map */ for (i=0; isize; unsigned long long end = start + size; unsigned long type = biosmap->type; + printk("copy_e820_map() start: %016Lx size: %016Lx end: %016Lx type: %ld\n", start, size, end, type); /* Overflow in 64 bits? Ignore the memory map. */ if (start > end) @@ -538,11 +536,17 @@ int __init copy_e820_map(struct e820entry * biosmap, int nr_map) * Not right. Fix it up. */ if (type == E820_RAM) { + printk("copy_e820_map() type is E820_RAM\n"); if (start < 0x100000ULL && end > 0xA0000ULL) { - if (start < 0xA0000ULL) + printk("copy_e820_map() lies in range...\n"); + if (start < 0xA0000ULL) { + printk("copy_e820_map() start < 0xA0000ULL\n"); add_memory_region(start, 0xA0000ULL-start, type); - if (end <= 0x100000ULL) + } + if (end <= 0x100000ULL) { + printk("copy_e820_map() end <= 0x100000ULL\n"); continue; + } start = 0x100000ULL; size = end - start; } @@ -814,26 +818,6 @@ void __init limit_regions(unsigned long long size) print_memory_map("limit_regions endfunc"); } -/* - * This function checks if any part of the range is mapped - * with type. - */ -int -e820_any_mapped(u64 start, u64 end, unsigned type) -{ - int i; - for (i = 0; i < e820.nr_map; i++) { - const struct e820entry *ei = &e820.map[i]; - if (type && ei->type != type) - continue; - if (ei->addr >= end || ei->addr + ei->size <= start) - continue; - return 1; - } - return 0; -} -EXPORT_SYMBOL_GPL(e820_any_mapped); - /* * This function checks if the entire range is mapped with type. * diff --git a/trunk/arch/i386/kernel/efi.c b/trunk/arch/i386/kernel/efi.c index a1808022ea19..8f9c624ace6f 100644 --- a/trunk/arch/i386/kernel/efi.c +++ b/trunk/arch/i386/kernel/efi.c @@ -69,11 +69,13 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) { unsigned long cr4; unsigned long temp; - struct Xgt_desc_struct gdt_descr; + struct Xgt_desc_struct *cpu_gdt_descr; spin_lock(&efi_rt_lock); local_irq_save(efi_rt_eflags); + cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); + /* * If I don't have PSE, I should just duplicate two entries in page * directory. If I have PSE, I just need to duplicate one entry in @@ -103,19 +105,17 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) */ local_flush_tlb(); - gdt_descr.address = __pa(get_cpu_gdt_table(0)); - gdt_descr.size = GDT_SIZE - 1; - load_gdt(&gdt_descr); + cpu_gdt_descr->address = __pa(cpu_gdt_descr->address); + load_gdt(cpu_gdt_descr); } static void efi_call_phys_epilog(void) __releases(efi_rt_lock) { unsigned long cr4; - struct Xgt_desc_struct gdt_descr; + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); - gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); - gdt_descr.size = GDT_SIZE - 1; - load_gdt(&gdt_descr); + cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address); + load_gdt(cpu_gdt_descr); cr4 = read_cr4(); @@ -347,12 +347,14 @@ void __init efi_init(void) printk(KERN_ERR PFX "Woah! Couldn't map the EFI system table.\n"); if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) printk(KERN_ERR PFX "Woah! EFI system table signature incorrect\n"); - if ((efi.systab->hdr.revision >> 16) == 0) - printk(KERN_ERR PFX "Warning: EFI system table version " - "%d.%02d, expected 1.00 or greater\n", + if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0) + printk(KERN_ERR PFX + "Warning: EFI system table major version mismatch: " + "got %d.%02d, expected %d.%02d\n", efi.systab->hdr.revision >> 16, - efi.systab->hdr.revision & 0xffff); - + efi.systab->hdr.revision & 0xffff, + EFI_SYSTEM_TABLE_REVISION >> 16, + EFI_SYSTEM_TABLE_REVISION & 0xffff); /* * Grab some details from the system table */ diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S index b1f16ee65e4d..18bddcb8e9e8 100644 --- a/trunk/arch/i386/kernel/entry.S +++ b/trunk/arch/i386/kernel/entry.S @@ -15,7 +15,7 @@ * I changed all the .align's to 4 (16 byte alignment), as that's faster * on a 486. * - * Stack layout in 'syscall_exit': + * Stack layout in 'ret_from_system_call': * ptrace needs to have all regs on the stack. * if the order here is changed, it needs to be * updated in fork.c:copy_process, signal.c:do_signal, @@ -132,7 +132,7 @@ VM_MASK = 0x00020000 movl $(__USER_DS), %edx; \ movl %edx, %ds; \ movl %edx, %es; \ - movl $(__KERNEL_PERCPU), %edx; \ + movl $(__KERNEL_PDA), %edx; \ movl %edx, %fs #define RESTORE_INT_REGS \ @@ -305,12 +305,16 @@ sysenter_past_esp: pushl $(__USER_CS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET cs, 0*/ +#ifndef CONFIG_COMPAT_VDSO /* * Push current_thread_info()->sysenter_return to the stack. * A tiny bit of offset fixup is necessary - 4*4 means the 4 words * pushed above; +8 corresponds to copy_thread's esp0 setting. */ pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) +#else + pushl $SYSENTER_RETURN +#endif CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eip, 0 @@ -338,7 +342,7 @@ sysenter_past_esp: jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) - DISABLE_INTERRUPTS(CLBR_ANY) + DISABLE_INTERRUPTS(CLBR_ECX|CLBR_EDX) TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx @@ -556,7 +560,9 @@ END(syscall_badsys) #define FIXUP_ESPFIX_STACK \ /* since we are on a wrong stack, we cant make it a C code :( */ \ - PER_CPU(gdt_page, %ebx); \ + movl %fs:PDA_cpu, %ebx; \ + PER_CPU(cpu_gdt_descr, %ebx); \ + movl GDS_address(%ebx), %ebx; \ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ addl %esp, %eax; \ pushl $__KERNEL_DS; \ @@ -629,7 +635,7 @@ ENTRY(name) \ SAVE_ALL; \ TRACE_IRQS_OFF \ movl %esp,%eax; \ - call smp_##name; \ + call smp_/**/name; \ jmp ret_from_intr; \ CFI_ENDPROC; \ ENDPROC(name) @@ -637,6 +643,11 @@ ENDPROC(name) /* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h" +/* This alternate entry is needed because we hijack the apic LVTT */ +#if defined(CONFIG_VMI) && defined(CONFIG_X86_LOCAL_APIC) +BUILD_INTERRUPT(apic_vmi_timer_interrupt,LOCAL_TIMER_VECTOR) +#endif + KPROBE_ENTRY(page_fault) RING0_EC_FRAME pushl $do_page_fault @@ -675,7 +686,7 @@ error_code: pushl %fs CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET fs, 0*/ - movl $(__KERNEL_PERCPU), %ecx + movl $(__KERNEL_PDA), %ecx movl %ecx, %fs UNWIND_ESPFIX_STACK popl %ecx diff --git a/trunk/arch/i386/kernel/head.S b/trunk/arch/i386/kernel/head.S index 9b10af65faaa..3fa7f9389afe 100644 --- a/trunk/arch/i386/kernel/head.S +++ b/trunk/arch/i386/kernel/head.S @@ -34,32 +34,17 @@ /* * This is how much memory *in addition to the memory covered up to - * and including _end* we need mapped initially. - * We need: - * - one bit for each possible page, but only in low memory, which means - * 2^32/4096/8 = 128K worst case (4G/4G split.) - * - enough space to map all low memory, which means - * (2^32/4096) / 1024 pages (worst case, non PAE) - * (2^32/4096) / 512 + 4 pages (worst case for PAE) - * - a few pages for allocator use before the kernel pagetable has - * been set up + * and including _end* we need mapped initially. We need one bit for + * each possible page, but only in low memory, which means + * 2^32/4096/8 = 128K worst case (4G/4G split.) * * Modulo rounding, each megabyte assigned here requires a kilobyte of * memory, which is currently unreclaimed. * * This should be a multiple of a page. */ -LOW_PAGES = 1<<(32-PAGE_SHIFT_asm) +#define INIT_MAP_BEYOND_END (128*1024) -#if PTRS_PER_PMD > 1 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD -#else -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD) -#endif -BOOTBITMAP_SIZE = LOW_PAGES / 8 -ALLOCATOR_SLOP = 4 - -INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm /* * 32-bit kernel entrypoint; only used by the boot CPU. On entry, @@ -162,7 +147,8 @@ page_pde_offset = (__PAGE_OFFSET >> 20); /* * Non-boot CPU entry point; entered from trampoline.S * We can't lgdt here, because lgdt itself uses a data segment, but - * we know the trampoline has already loaded the boot_gdt for us. + * we know the trampoline has already loaded the boot_gdt_table GDT + * for us. * * If cpu hotplug is not supported then this code can go in init section * which will be freed later @@ -332,12 +318,12 @@ is386: movl $2,%ecx # set MP movl %eax,%cr0 call check_x87 + call setup_pda lgdt early_gdt_descr lidt idt_descr ljmp $(__KERNEL_CS),$1f 1: movl $(__KERNEL_DS),%eax # reload all the segment registers movl %eax,%ss # after changing gdt. - movl %eax,%fs # gets reset once there's real percpu movl $(__USER_DS),%eax # DS/ES contains default USER segment movl %eax,%ds @@ -347,17 +333,16 @@ is386: movl $2,%ecx # set MP movl %eax,%gs lldt %ax + movl $(__KERNEL_PDA),%eax + mov %eax,%fs + cld # gcc2 wants the direction flag cleared at all times pushl $0 # fake return address for unwinder #ifdef CONFIG_SMP movb ready, %cl movb $1, ready cmpb $0,%cl # the first CPU calls start_kernel - je 1f - movl $(__KERNEL_PERCPU), %eax - movl %eax,%fs # set this cpu's percpu - jmp initialize_secondary # all other CPUs call initialize_secondary -1: + jne initialize_secondary # all other CPUs call initialize_secondary #endif /* CONFIG_SMP */ jmp start_kernel @@ -380,6 +365,23 @@ check_x87: .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ ret +/* + * Point the GDT at this CPU's PDA. On boot this will be + * cpu_gdt_table and boot_pda; for secondary CPUs, these will be + * that CPU's GDT and PDA. + */ +ENTRY(setup_pda) + /* get the PDA pointer */ + movl start_pda, %eax + + /* slot the PDA address into the GDT */ + mov early_gdt_descr+2, %ecx + mov %ax, (__KERNEL_PDA+0+2)(%ecx) /* base & 0x0000ffff */ + shr $16, %eax + mov %al, (__KERNEL_PDA+4+0)(%ecx) /* base & 0x00ff0000 */ + mov %ah, (__KERNEL_PDA+4+3)(%ecx) /* base & 0xff000000 */ + ret + /* * setup_idt * @@ -552,6 +554,9 @@ ENTRY(empty_zero_page) * This starts the data section. */ .data +ENTRY(start_pda) + .long boot_pda + ENTRY(stack_start) .long init_thread_union+THREAD_SIZE .long __BOOT_DS @@ -583,7 +588,7 @@ fault_msg: .word 0 # 32 bit align gdt_desc.address boot_gdt_descr: .word __BOOT_DS+7 - .long boot_gdt - __PAGE_OFFSET + .long boot_gdt_table - __PAGE_OFFSET .word 0 # 32-bit align idt_desc.address idt_descr: @@ -594,14 +599,67 @@ idt_descr: .word 0 # 32 bit align gdt_desc.address ENTRY(early_gdt_descr) .word GDT_ENTRIES*8-1 - .long per_cpu__gdt_page /* Overwritten for secondary CPUs */ + .long cpu_gdt_table /* - * The boot_gdt must mirror the equivalent in setup.S and is + * The boot_gdt_table must mirror the equivalent in setup.S and is * used only for booting. */ .align L1_CACHE_BYTES -ENTRY(boot_gdt) +ENTRY(boot_gdt_table) .fill GDT_ENTRY_BOOT_CS,8,0 .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ + +/* + * The Global Descriptor Table contains 28 quadwords, per-CPU. + */ + .align L1_CACHE_BYTES +ENTRY(cpu_gdt_table) + .quad 0x0000000000000000 /* NULL descriptor */ + .quad 0x0000000000000000 /* 0x0b reserved */ + .quad 0x0000000000000000 /* 0x13 reserved */ + .quad 0x0000000000000000 /* 0x1b reserved */ + .quad 0x0000000000000000 /* 0x20 unused */ + .quad 0x0000000000000000 /* 0x28 unused */ + .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ + .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ + .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ + .quad 0x0000000000000000 /* 0x4b reserved */ + .quad 0x0000000000000000 /* 0x53 reserved */ + .quad 0x0000000000000000 /* 0x5b reserved */ + + .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ + .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ + .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */ + .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */ + + .quad 0x0000000000000000 /* 0x80 TSS descriptor */ + .quad 0x0000000000000000 /* 0x88 LDT descriptor */ + + /* + * Segments used for calling PnP BIOS have byte granularity. + * They code segments and data segments have fixed 64k limits, + * the transfer segment sizes are set at run time. + */ + .quad 0x00409a000000ffff /* 0x90 32-bit code */ + .quad 0x00009a000000ffff /* 0x98 16-bit code */ + .quad 0x000092000000ffff /* 0xa0 16-bit data */ + .quad 0x0000920000000000 /* 0xa8 16-bit data */ + .quad 0x0000920000000000 /* 0xb0 16-bit data */ + + /* + * The APM segments have byte granularity and their bases + * are set at run time. All have 64k limits. + */ + .quad 0x00409a000000ffff /* 0xb8 APM CS code */ + .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */ + .quad 0x004092000000ffff /* 0xc8 APM DS data */ + + .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */ + .quad 0x00cf92000000ffff /* 0xd8 - PDA */ + .quad 0x0000000000000000 /* 0xe0 - unused */ + .quad 0x0000000000000000 /* 0xe8 - unused */ + .quad 0x0000000000000000 /* 0xf0 - unused */ + .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ + diff --git a/trunk/arch/i386/kernel/i386_ksyms.c b/trunk/arch/i386/kernel/i386_ksyms.c index e3d4b73bfdb0..4afe26e86260 100644 --- a/trunk/arch/i386/kernel/i386_ksyms.c +++ b/trunk/arch/i386/kernel/i386_ksyms.c @@ -28,3 +28,5 @@ EXPORT_SYMBOL(__read_lock_failed); #endif EXPORT_SYMBOL(csum_partial); + +EXPORT_SYMBOL(_proxy_pda); diff --git a/trunk/arch/i386/kernel/i8253.c b/trunk/arch/i386/kernel/i8253.c index f8a3c4054c70..10cef5ca8a5b 100644 --- a/trunk/arch/i386/kernel/i8253.c +++ b/trunk/arch/i386/kernel/i8253.c @@ -110,7 +110,7 @@ void __init setup_pit_timer(void) * Start pit with the boot cpu mask and make it global after the * IO_APIC has been initialized. */ - pit_clockevent.cpumask = cpumask_of_cpu(smp_processor_id()); + pit_clockevent.cpumask = cpumask_of_cpu(0); pit_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, 32); pit_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFF, &pit_clockevent); diff --git a/trunk/arch/i386/kernel/i8259.c b/trunk/arch/i386/kernel/i8259.c index 0499cbe9871a..03abfdb1a6e4 100644 --- a/trunk/arch/i386/kernel/i8259.c +++ b/trunk/arch/i386/kernel/i8259.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index 7f8b7af2b95f..b3ab8ffebd27 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,6 @@ #include #include #include -#include #include #include @@ -661,6 +661,8 @@ static int balanced_irq(void *unused) unsigned long prev_balance_time = jiffies; long time_remaining = balanced_irq_interval; + daemonize("kirqd"); + /* push everything to CPU 0 to give us a starting point. */ for (i = 0 ; i < NR_IRQS ; i++) { irq_desc[i].pending_mask = cpumask_of_cpu(0); @@ -720,9 +722,10 @@ static int __init balanced_irq_init(void) } printk(KERN_INFO "Starting balanced_irq\n"); - if (!IS_ERR(kthread_run(balanced_irq, NULL, "kirqd"))) + if (kernel_thread(balanced_irq, NULL, CLONE_KERNEL) >= 0) return 0; - printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); + else + printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); failed: for_each_possible_cpu(i) { kfree(irq_cpu_data[i].irq_delta); @@ -1400,6 +1403,10 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in enable_8259A_irq(0); } +static inline void UNEXPECTED_IO_APIC(void) +{ +} + void __init print_IO_APIC(void) { int apic, i; @@ -1439,12 +1446,34 @@ void __init print_IO_APIC(void) printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS); + if (reg_00.bits.ID >= get_physical_broadcast()) + UNEXPECTED_IO_APIC(); + if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) + UNEXPECTED_IO_APIC(); printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw); printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); + if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */ + (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */ + (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */ + (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */ + (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */ + (reg_01.bits.entries != 0x2E) && + (reg_01.bits.entries != 0x3F) + ) + UNEXPECTED_IO_APIC(); printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); + if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */ + (reg_01.bits.version != 0x10) && /* oldest IO-APICs */ + (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */ + (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */ + (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */ + ) + UNEXPECTED_IO_APIC(); + if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2) + UNEXPECTED_IO_APIC(); /* * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02, @@ -1454,6 +1483,8 @@ void __init print_IO_APIC(void) if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) { printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); + if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2) + UNEXPECTED_IO_APIC(); } /* @@ -1465,6 +1496,8 @@ void __init print_IO_APIC(void) reg_03.raw != reg_01.raw) { printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw); printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT); + if (reg_03.bits.__reserved_1) + UNEXPECTED_IO_APIC(); } printk(KERN_DEBUG ".... IRQ redirection table:\n"); @@ -2578,19 +2611,19 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) if (irq < 0) return irq; + set_irq_msi(irq, desc); ret = msi_compose_msg(dev, irq, &msg); if (ret < 0) { destroy_irq(irq); return ret; } - set_irq_msi(irq, desc); write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return 0; + return irq; } void arch_teardown_msi_irq(unsigned int irq) diff --git a/trunk/arch/i386/kernel/ioport.c b/trunk/arch/i386/kernel/ioport.c index 3d310a946d76..498e8bc197d5 100644 --- a/trunk/arch/i386/kernel/ioport.c +++ b/trunk/arch/i386/kernel/ioport.c @@ -12,10 +12,10 @@ #include #include #include +#include #include #include #include -#include /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) @@ -113,7 +113,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) * Reset the owner so that a process switch will not set * tss->io_bitmap_base to IO_BITMAP_OFFSET. */ - tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; + tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; tss->io_bitmap_owner = NULL; put_cpu(); diff --git a/trunk/arch/i386/kernel/irq.c b/trunk/arch/i386/kernel/irq.c index d2daf672f4a2..8db8d514c9c0 100644 --- a/trunk/arch/i386/kernel/irq.c +++ b/trunk/arch/i386/kernel/irq.c @@ -24,9 +24,6 @@ DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp; EXPORT_PER_CPU_SYMBOL(irq_stat); -DEFINE_PER_CPU(struct pt_regs *, irq_regs); -EXPORT_PER_CPU_SYMBOL(irq_regs); - /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. diff --git a/trunk/arch/i386/kernel/kprobes.c b/trunk/arch/i386/kernel/kprobes.c index dde828a333c3..b545bc746fce 100644 --- a/trunk/arch/i386/kernel/kprobes.c +++ b/trunk/arch/i386/kernel/kprobes.c @@ -31,8 +31,8 @@ #include #include #include -#include #include +#include #include #include @@ -226,15 +226,24 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) } /* Called with kretprobe_lock held */ -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, +void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)®s->esp; - ri->ret_addr = (kprobe_opcode_t *) *sara; + struct kretprobe_instance *ri; - /* Replace the return addr with trampoline addr */ - *sara = (unsigned long) &kretprobe_trampoline; + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *) *sara; + + /* Replace the return addr with trampoline addr */ + *sara = (unsigned long) &kretprobe_trampoline; + add_rp_inst(ri); + } else { + rp->nmissed++; + } } /* @@ -440,7 +449,8 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) break; } - kretprobe_assert(ri, orig_ret_address, trampoline_address); + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); + spin_unlock_irqrestore(&kretprobe_lock, flags); hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { @@ -743,11 +753,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) return 0; } -int __kprobes arch_trampoline_kprobe(struct kprobe *p) -{ - return 0; -} - int __init arch_init_kprobes(void) { return 0; diff --git a/trunk/arch/i386/kernel/ldt.c b/trunk/arch/i386/kernel/ldt.c index e0b2d17f4f10..b410e5fb034f 100644 --- a/trunk/arch/i386/kernel/ldt.c +++ b/trunk/arch/i386/kernel/ldt.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/i386/kernel/legacy_serial.c b/trunk/arch/i386/kernel/legacy_serial.c deleted file mode 100644 index 21510118544e..000000000000 --- a/trunk/arch/i386/kernel/legacy_serial.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Legacy COM port devices for x86 platforms without PNPBIOS or ACPI. - * Data taken from include/asm-i386/serial.h. - * - * (c) Copyright 2007 Hewlett-Packard Development Company, L.P. - * Bjorn Helgaas - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include - -/* Standard COM flags (except for COM4, because of the 8514 problem) */ -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ) -#define COM4_FLAGS (UPF_BOOT_AUTOCONF | UPF_AUTO_IRQ) -#else -#define COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) -#define COM4_FLAGS UPF_BOOT_AUTOCONF -#endif - -#define PORT(_base,_irq,_flags) \ - { \ - .iobase = _base, \ - .irq = _irq, \ - .uartclk = 1843200, \ - .iotype = UPIO_PORT, \ - .flags = _flags, \ - } - -static struct plat_serial8250_port x86_com_data[] = { - PORT(0x3F8, 4, COM_FLAGS), - PORT(0x2F8, 3, COM_FLAGS), - PORT(0x3E8, 4, COM_FLAGS), - PORT(0x2E8, 3, COM4_FLAGS), - { }, -}; - -static struct platform_device x86_com_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = x86_com_data, - }, -}; - -static int force_legacy_probe; -module_param_named(force, force_legacy_probe, bool, 0); -MODULE_PARM_DESC(force, "Force legacy serial port probe"); - -static int __init serial8250_x86_com_init(void) -{ - if (pnp_platform_devices && !force_legacy_probe) - return -ENODEV; - - return platform_device_register(&x86_com_device); -} - -module_init(serial8250_x86_com_init); - -MODULE_AUTHOR("Bjorn Helgaas"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Generic 8250/16x50 legacy probe module"); diff --git a/trunk/arch/i386/kernel/mpparse.c b/trunk/arch/i386/kernel/mpparse.c index 13abb4ebfb79..4f5983c98669 100644 --- a/trunk/arch/i386/kernel/mpparse.c +++ b/trunk/arch/i386/kernel/mpparse.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -476,7 +477,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) } ++mpc_record; } - setup_apic_routing(); + clustered_apic_check(); if (!num_processors) printk(KERN_ERR "SMP mptable: no processors registered!\n"); return num_processors; diff --git a/trunk/arch/i386/kernel/msr.c b/trunk/arch/i386/kernel/msr.c index 8cd0a91ce107..bcaa6e9b6197 100644 --- a/trunk/arch/i386/kernel/msr.c +++ b/trunk/arch/i386/kernel/msr.c @@ -45,6 +45,104 @@ static struct class *msr_class; +static inline int wrmsr_eio(u32 reg, u32 eax, u32 edx) +{ + int err; + + err = wrmsr_safe(reg, eax, edx); + if (err) + err = -EIO; + return err; +} + +static inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx) +{ + int err; + + err = rdmsr_safe(reg, eax, edx); + if (err) + err = -EIO; + return err; +} + +#ifdef CONFIG_SMP + +struct msr_command { + int err; + u32 reg; + u32 data[2]; +}; + +static void msr_smp_wrmsr(void *cmd_block) +{ + struct msr_command *cmd = (struct msr_command *)cmd_block; + + cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]); +} + +static void msr_smp_rdmsr(void *cmd_block) +{ + struct msr_command *cmd = (struct msr_command *)cmd_block; + + cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]); +} + +static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) +{ + struct msr_command cmd; + int ret; + + preempt_disable(); + if (cpu == smp_processor_id()) { + ret = wrmsr_eio(reg, eax, edx); + } else { + cmd.reg = reg; + cmd.data[0] = eax; + cmd.data[1] = edx; + + smp_call_function_single(cpu, msr_smp_wrmsr, &cmd, 1, 1); + ret = cmd.err; + } + preempt_enable(); + return ret; +} + +static inline int do_rdmsr(int cpu, u32 reg, u32 * eax, u32 * edx) +{ + struct msr_command cmd; + int ret; + + preempt_disable(); + if (cpu == smp_processor_id()) { + ret = rdmsr_eio(reg, eax, edx); + } else { + cmd.reg = reg; + + smp_call_function_single(cpu, msr_smp_rdmsr, &cmd, 1, 1); + + *eax = cmd.data[0]; + *edx = cmd.data[1]; + + ret = cmd.err; + } + preempt_enable(); + return ret; +} + +#else /* ! CONFIG_SMP */ + +static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) +{ + return wrmsr_eio(reg, eax, edx); +} + +static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) +{ + return rdmsr_eio(reg, eax, edx); +} + +#endif /* ! CONFIG_SMP */ + static loff_t msr_seek(struct file *file, loff_t offset, int orig) { loff_t ret = -EINVAL; @@ -76,9 +174,9 @@ static ssize_t msr_read(struct file *file, char __user * buf, return -EINVAL; /* Invalid chunk size */ for (; count; count -= 8) { - err = rdmsr_safe_on_cpu(cpu, reg, &data[0], &data[1]); + err = do_rdmsr(cpu, reg, &data[0], &data[1]); if (err) - return -EIO; + return err; if (copy_to_user(tmp, &data, 8)) return -EFAULT; tmp += 2; @@ -102,9 +200,9 @@ static ssize_t msr_write(struct file *file, const char __user *buf, for (; count; count -= 8) { if (copy_from_user(&data, tmp, 8)) return -EFAULT; - err = wrmsr_safe_on_cpu(cpu, reg, data[0], data[1]); + err = do_wrmsr(cpu, reg, data[0], data[1]); if (err) - return -EIO; + return err; tmp += 2; } diff --git a/trunk/arch/i386/kernel/nmi.c b/trunk/arch/i386/kernel/nmi.c index fba121f7973f..84c3497efb60 100644 --- a/trunk/arch/i386/kernel/nmi.c +++ b/trunk/arch/i386/kernel/nmi.c @@ -20,21 +20,38 @@ #include #include #include +#include #include #include #include -#include #include #include +#include +#include #include "mach_traps.h" int unknown_nmi_panic; int nmi_watchdog_enabled; -static cpumask_t backtrace_mask = CPU_MASK_NONE; +/* perfctr_nmi_owner tracks the ownership of the perfctr registers: + * evtsel_nmi_owner tracks the ownership of the event selection + * - different performance counters/ event selection may be reserved for + * different subsystems this reservation system just tries to coordinate + * things a little + */ + +/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's + * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) + */ +#define NMI_MAX_COUNTER_BITS 66 +#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS) +static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]); +static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]); + +static cpumask_t backtrace_mask = CPU_MASK_NONE; /* nmi_active: * >0: the lapic NMI watchdog is active, but can be disabled * <0: the lapic NMI watchdog has not been set up, and cannot @@ -46,11 +63,206 @@ atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ unsigned int nmi_watchdog = NMI_DEFAULT; static unsigned int nmi_hz = HZ; -static DEFINE_PER_CPU(short, wd_enabled); +struct nmi_watchdog_ctlblk { + int enabled; + u64 check_bit; + unsigned int cccr_msr; + unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ + unsigned int evntsel_msr; /* the MSR to select the events to handle */ +}; +static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); /* local prototypes */ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); +extern void show_registers(struct pt_regs *regs); +extern int unknown_nmi_panic; + +/* converts an msr to an appropriate reservation bit */ +static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) +{ + /* returns the bit offset of the performance counter register */ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + return (msr - MSR_K7_PERFCTR0); + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return (msr - MSR_ARCH_PERFMON_PERFCTR0); + + switch (boot_cpu_data.x86) { + case 6: + return (msr - MSR_P6_PERFCTR0); + case 15: + return (msr - MSR_P4_BPU_PERFCTR0); + } + } + return 0; +} + +/* converts an msr to an appropriate reservation bit */ +static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) +{ + /* returns the bit offset of the event selection register */ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + return (msr - MSR_K7_EVNTSEL0); + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return (msr - MSR_ARCH_PERFMON_EVENTSEL0); + + switch (boot_cpu_data.x86) { + case 6: + return (msr - MSR_P6_EVNTSEL0); + case 15: + return (msr - MSR_P4_BSU_ESCR0); + } + } + return 0; +} + +/* checks for a bit availability (hack for oprofile) */ +int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) +{ + int cpu; + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + for_each_possible_cpu (cpu) { + if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) + return 0; + } + return 1; +} + +/* checks the an msr for availability */ +int avail_to_resrv_perfctr_nmi(unsigned int msr) +{ + unsigned int counter; + int cpu; + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + for_each_possible_cpu (cpu) { + if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) + return 0; + } + return 1; +} + +static int __reserve_perfctr_nmi(int cpu, unsigned int msr) +{ + unsigned int counter; + if (cpu < 0) + cpu = smp_processor_id(); + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0])) + return 1; + return 0; +} + +static void __release_perfctr_nmi(int cpu, unsigned int msr) +{ + unsigned int counter; + if (cpu < 0) + cpu = smp_processor_id(); + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)[0]); +} + +int reserve_perfctr_nmi(unsigned int msr) +{ + int cpu, i; + for_each_possible_cpu (cpu) { + if (!__reserve_perfctr_nmi(cpu, msr)) { + for_each_possible_cpu (i) { + if (i >= cpu) + break; + __release_perfctr_nmi(i, msr); + } + return 0; + } + } + return 1; +} + +void release_perfctr_nmi(unsigned int msr) +{ + int cpu; + for_each_possible_cpu (cpu) { + __release_perfctr_nmi(cpu, msr); + } +} + +int __reserve_evntsel_nmi(int cpu, unsigned int msr) +{ + unsigned int counter; + if (cpu < 0) + cpu = smp_processor_id(); + + counter = nmi_evntsel_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0])) + return 1; + return 0; +} + +static void __release_evntsel_nmi(int cpu, unsigned int msr) +{ + unsigned int counter; + if (cpu < 0) + cpu = smp_processor_id(); + + counter = nmi_evntsel_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]); +} + +int reserve_evntsel_nmi(unsigned int msr) +{ + int cpu, i; + for_each_possible_cpu (cpu) { + if (!__reserve_evntsel_nmi(cpu, msr)) { + for_each_possible_cpu (i) { + if (i >= cpu) + break; + __release_evntsel_nmi(i, msr); + } + return 0; + } + } + return 1; +} + +void release_evntsel_nmi(unsigned int msr) +{ + int cpu; + for_each_possible_cpu (cpu) { + __release_evntsel_nmi(cpu, msr); + } +} + +static __cpuinit inline int nmi_known_cpu(void) +{ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6) + || (boot_cpu_data.x86 == 16)); + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return 1; + else + return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6)); + } + return 0; +} + static int endflag __initdata = 0; #ifdef CONFIG_SMP @@ -72,6 +284,28 @@ static __init void nmi_cpu_busy(void *data) } #endif +static unsigned int adjust_for_32bit_ctr(unsigned int hz) +{ + u64 counter_val; + unsigned int retval = hz; + + /* + * On Intel CPUs with P6/ARCH_PERFMON only 32 bits in the counter + * are writable, with higher bits sign extending from bit 31. + * So, we can only program the counter with 31 bit values and + * 32nd bit should be 1, for 33.. to be 1. + * Find the appropriate nmi_hz + */ + counter_val = (u64)cpu_khz * 1000; + do_div(counter_val, retval); + if (counter_val > 0x7fffffffULL) { + u64 count = (u64)cpu_khz * 1000; + do_div(count, 0x7fffffffUL); + retval = count + 1; + } + return retval; +} + static int __init check_nmi_watchdog(void) { unsigned int *prev_nmi_count; @@ -104,14 +338,14 @@ static int __init check_nmi_watchdog(void) if (!cpu_isset(cpu, cpu_callin_map)) continue; #endif - if (!per_cpu(wd_enabled, cpu)) + if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) continue; if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) { printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", cpu, prev_nmi_count[cpu], nmi_count(cpu)); - per_cpu(wd_enabled, cpu) = 0; + per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0; atomic_dec(&nmi_active); } } @@ -125,8 +359,16 @@ static int __init check_nmi_watchdog(void) /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ - if (nmi_watchdog == NMI_LOCAL_APIC) - nmi_hz = lapic_adjust_nmi_hz(1); + if (nmi_watchdog == NMI_LOCAL_APIC) { + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + nmi_hz = 1; + + if (wd->perfctr_msr == MSR_P6_PERFCTR0 || + wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + nmi_hz = adjust_for_32bit_ctr(nmi_hz); + } + } kfree(prev_nmi_count); return 0; @@ -149,8 +391,85 @@ static int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); +static void disable_lapic_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + + if (atomic_read(&nmi_active) <= 0) + return; + + on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); + + BUG_ON(atomic_read(&nmi_active) != 0); +} + +static void enable_lapic_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + + /* are we already enabled */ + if (atomic_read(&nmi_active) != 0) + return; + + /* are we lapic aware */ + if (nmi_known_cpu() <= 0) + return; -/* Suspend/resume support */ + on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); + touch_nmi_watchdog(); +} + +void disable_timer_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_IO_APIC); + + if (atomic_read(&nmi_active) <= 0) + return; + + disable_irq(0); + on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); + + BUG_ON(atomic_read(&nmi_active) != 0); +} + +void enable_timer_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_IO_APIC); + + if (atomic_read(&nmi_active) == 0) { + touch_nmi_watchdog(); + on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); + enable_irq(0); + } +} + +static void __acpi_nmi_disable(void *__unused) +{ + apic_write_around(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); +} + +/* + * Disable timer based NMIs on all CPUs: + */ +void acpi_nmi_disable(void) +{ + if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) + on_each_cpu(__acpi_nmi_disable, NULL, 0, 1); +} + +static void __acpi_nmi_enable(void *__unused) +{ + apic_write_around(APIC_LVT0, APIC_DM_NMI); +} + +/* + * Enable timer based NMIs on all CPUs: + */ +void acpi_nmi_enable(void) +{ + if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) + on_each_cpu(__acpi_nmi_enable, NULL, 0, 1); +} #ifdef CONFIG_PM @@ -197,7 +516,7 @@ static int __init init_lapic_nmi_sysfs(void) if (nmi_watchdog != NMI_LOCAL_APIC) return 0; - if (atomic_read(&nmi_active) < 0) + if ( atomic_read(&nmi_active) < 0 ) return 0; error = sysdev_class_register(&nmi_sysclass); @@ -210,69 +529,433 @@ late_initcall(init_lapic_nmi_sysfs); #endif /* CONFIG_PM */ -static void __acpi_nmi_enable(void *__unused) +/* + * Activate the NMI watchdog via the local APIC. + * Original code written by Keith Owens. + */ + +static void write_watchdog_counter(unsigned int perfctr_msr, const char *descr) { - apic_write_around(APIC_LVT0, APIC_DM_NMI); + u64 count = (u64)cpu_khz * 1000; + + do_div(count, nmi_hz); + if(descr) + Dprintk("setting %s to -0x%08Lx\n", descr, count); + wrmsrl(perfctr_msr, 0 - count); } -/* - * Enable timer based NMIs on all CPUs: - */ -void acpi_nmi_enable(void) +static void write_watchdog_counter32(unsigned int perfctr_msr, + const char *descr) { - if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) - on_each_cpu(__acpi_nmi_enable, NULL, 0, 1); + u64 count = (u64)cpu_khz * 1000; + + do_div(count, nmi_hz); + if(descr) + Dprintk("setting %s to -0x%08Lx\n", descr, count); + wrmsr(perfctr_msr, (u32)(-count), 0); } -static void __acpi_nmi_disable(void *__unused) +/* Note that these events don't tick when the CPU idles. This means + the frequency varies with CPU load. */ + +#define K7_EVNTSEL_ENABLE (1 << 22) +#define K7_EVNTSEL_INT (1 << 20) +#define K7_EVNTSEL_OS (1 << 17) +#define K7_EVNTSEL_USR (1 << 16) +#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 +#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING + +static int setup_k7_watchdog(void) { - apic_write(APIC_LVT0, APIC_DM_NMI | APIC_LVT_MASKED); + unsigned int perfctr_msr, evntsel_msr; + unsigned int evntsel; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + perfctr_msr = MSR_K7_PERFCTR0; + evntsel_msr = MSR_K7_EVNTSEL0; + if (!__reserve_perfctr_nmi(-1, perfctr_msr)) + goto fail; + + if (!__reserve_evntsel_nmi(-1, evntsel_msr)) + goto fail1; + + wrmsrl(perfctr_msr, 0UL); + + evntsel = K7_EVNTSEL_INT + | K7_EVNTSEL_OS + | K7_EVNTSEL_USR + | K7_NMI_EVENT; + + /* setup the timer */ + wrmsr(evntsel_msr, evntsel, 0); + write_watchdog_counter(perfctr_msr, "K7_PERFCTR0"); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= K7_EVNTSEL_ENABLE; + wrmsr(evntsel_msr, evntsel, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = 0; //unused + wd->check_bit = 1ULL<<63; + return 1; +fail1: + __release_perfctr_nmi(-1, perfctr_msr); +fail: + return 0; } -/* - * Disable timer based NMIs on all CPUs: - */ -void acpi_nmi_disable(void) +static void stop_k7_watchdog(void) { - if (atomic_read(&nmi_active) && nmi_watchdog == NMI_IO_APIC) - on_each_cpu(__acpi_nmi_disable, NULL, 0, 1); + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + wrmsr(wd->evntsel_msr, 0, 0); + + __release_evntsel_nmi(-1, wd->evntsel_msr); + __release_perfctr_nmi(-1, wd->perfctr_msr); +} + +#define P6_EVNTSEL0_ENABLE (1 << 22) +#define P6_EVNTSEL_INT (1 << 20) +#define P6_EVNTSEL_OS (1 << 17) +#define P6_EVNTSEL_USR (1 << 16) +#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 +#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED + +static int setup_p6_watchdog(void) +{ + unsigned int perfctr_msr, evntsel_msr; + unsigned int evntsel; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + perfctr_msr = MSR_P6_PERFCTR0; + evntsel_msr = MSR_P6_EVNTSEL0; + if (!__reserve_perfctr_nmi(-1, perfctr_msr)) + goto fail; + + if (!__reserve_evntsel_nmi(-1, evntsel_msr)) + goto fail1; + + wrmsrl(perfctr_msr, 0UL); + + evntsel = P6_EVNTSEL_INT + | P6_EVNTSEL_OS + | P6_EVNTSEL_USR + | P6_NMI_EVENT; + + /* setup the timer */ + wrmsr(evntsel_msr, evntsel, 0); + nmi_hz = adjust_for_32bit_ctr(nmi_hz); + write_watchdog_counter32(perfctr_msr, "P6_PERFCTR0"); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= P6_EVNTSEL0_ENABLE; + wrmsr(evntsel_msr, evntsel, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = 0; //unused + wd->check_bit = 1ULL<<39; + return 1; +fail1: + __release_perfctr_nmi(-1, perfctr_msr); +fail: + return 0; +} + +static void stop_p6_watchdog(void) +{ + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + wrmsr(wd->evntsel_msr, 0, 0); + + __release_evntsel_nmi(-1, wd->evntsel_msr); + __release_perfctr_nmi(-1, wd->perfctr_msr); +} + +/* Note that these events don't tick when the CPU idles. This means + the frequency varies with CPU load. */ + +#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) +#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) +#define P4_ESCR_OS (1<<3) +#define P4_ESCR_USR (1<<2) +#define P4_CCCR_OVF_PMI0 (1<<26) +#define P4_CCCR_OVF_PMI1 (1<<27) +#define P4_CCCR_THRESHOLD(N) ((N)<<20) +#define P4_CCCR_COMPLEMENT (1<<19) +#define P4_CCCR_COMPARE (1<<18) +#define P4_CCCR_REQUIRED (3<<16) +#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) +#define P4_CCCR_ENABLE (1<<12) +#define P4_CCCR_OVF (1<<31) +/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter + CRU_ESCR0 (with any non-null event selector) through a complemented + max threshold. [IA32-Vol3, Section 14.9.9] */ + +static int setup_p4_watchdog(void) +{ + unsigned int perfctr_msr, evntsel_msr, cccr_msr; + unsigned int evntsel, cccr_val; + unsigned int misc_enable, dummy; + unsigned int ht_num; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) + return 0; + +#ifdef CONFIG_SMP + /* detect which hyperthread we are on */ + if (smp_num_siblings == 2) { + unsigned int ebx, apicid; + + ebx = cpuid_ebx(1); + apicid = (ebx >> 24) & 0xff; + ht_num = apicid & 1; + } else +#endif + ht_num = 0; + + /* performance counters are shared resources + * assign each hyperthread its own set + * (re-use the ESCR0 register, seems safe + * and keeps the cccr_val the same) + */ + if (!ht_num) { + /* logical cpu 0 */ + perfctr_msr = MSR_P4_IQ_PERFCTR0; + evntsel_msr = MSR_P4_CRU_ESCR0; + cccr_msr = MSR_P4_IQ_CCCR0; + cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); + } else { + /* logical cpu 1 */ + perfctr_msr = MSR_P4_IQ_PERFCTR1; + evntsel_msr = MSR_P4_CRU_ESCR0; + cccr_msr = MSR_P4_IQ_CCCR1; + cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); + } + + if (!__reserve_perfctr_nmi(-1, perfctr_msr)) + goto fail; + + if (!__reserve_evntsel_nmi(-1, evntsel_msr)) + goto fail1; + + evntsel = P4_ESCR_EVENT_SELECT(0x3F) + | P4_ESCR_OS + | P4_ESCR_USR; + + cccr_val |= P4_CCCR_THRESHOLD(15) + | P4_CCCR_COMPLEMENT + | P4_CCCR_COMPARE + | P4_CCCR_REQUIRED; + + wrmsr(evntsel_msr, evntsel, 0); + wrmsr(cccr_msr, cccr_val, 0); + write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0"); + apic_write(APIC_LVTPC, APIC_DM_NMI); + cccr_val |= P4_CCCR_ENABLE; + wrmsr(cccr_msr, cccr_val, 0); + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = cccr_msr; + wd->check_bit = 1ULL<<39; + return 1; +fail1: + __release_perfctr_nmi(-1, perfctr_msr); +fail: + return 0; +} + +static void stop_p4_watchdog(void) +{ + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + wrmsr(wd->cccr_msr, 0, 0); + wrmsr(wd->evntsel_msr, 0, 0); + + __release_evntsel_nmi(-1, wd->evntsel_msr); + __release_perfctr_nmi(-1, wd->perfctr_msr); +} + +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK + +static int setup_intel_arch_watchdog(void) +{ + unsigned int ebx; + union cpuid10_eax eax; + unsigned int unused; + unsigned int perfctr_msr, evntsel_msr; + unsigned int evntsel; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebx indicates event present. + */ + cpuid(10, &(eax.full), &ebx, &unused, &unused); + if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || + (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + goto fail; + + perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; + evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; + + if (!__reserve_perfctr_nmi(-1, perfctr_msr)) + goto fail; + + if (!__reserve_evntsel_nmi(-1, evntsel_msr)) + goto fail1; + + wrmsrl(perfctr_msr, 0UL); + + evntsel = ARCH_PERFMON_EVENTSEL_INT + | ARCH_PERFMON_EVENTSEL_OS + | ARCH_PERFMON_EVENTSEL_USR + | ARCH_PERFMON_NMI_EVENT_SEL + | ARCH_PERFMON_NMI_EVENT_UMASK; + + /* setup the timer */ + wrmsr(evntsel_msr, evntsel, 0); + nmi_hz = adjust_for_32bit_ctr(nmi_hz); + write_watchdog_counter32(perfctr_msr, "INTEL_ARCH_PERFCTR0"); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsr(evntsel_msr, evntsel, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = 0; //unused + wd->check_bit = 1ULL << (eax.split.bit_width - 1); + return 1; +fail1: + __release_perfctr_nmi(-1, perfctr_msr); +fail: + return 0; +} + +static void stop_intel_arch_watchdog(void) +{ + unsigned int ebx; + union cpuid10_eax eax; + unsigned int unused; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebx indicates event present. + */ + cpuid(10, &(eax.full), &ebx, &unused, &unused); + if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || + (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return; + + wrmsr(wd->evntsel_msr, 0, 0); + __release_evntsel_nmi(-1, wd->evntsel_msr); + __release_perfctr_nmi(-1, wd->perfctr_msr); } void setup_apic_nmi_watchdog (void *unused) { - if (__get_cpu_var(wd_enabled)) - return; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + /* only support LOCAL and IO APICs for now */ + if ((nmi_watchdog != NMI_LOCAL_APIC) && + (nmi_watchdog != NMI_IO_APIC)) + return; + + if (wd->enabled == 1) + return; /* cheap hack to support suspend/resume */ /* if cpu0 is not active neither should the other cpus */ if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0)) return; - switch (nmi_watchdog) { - case NMI_LOCAL_APIC: - __get_cpu_var(wd_enabled) = 1; /* enable it before to avoid race with handler */ - if (lapic_watchdog_init(nmi_hz) < 0) { - __get_cpu_var(wd_enabled) = 0; + if (nmi_watchdog == NMI_LOCAL_APIC) { + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 && + boot_cpu_data.x86 != 16) + return; + if (!setup_k7_watchdog()) + return; + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + if (!setup_intel_arch_watchdog()) + return; + break; + } + switch (boot_cpu_data.x86) { + case 6: + if (boot_cpu_data.x86_model > 0xd) + return; + + if (!setup_p6_watchdog()) + return; + break; + case 15: + if (boot_cpu_data.x86_model > 0x4) + return; + + if (!setup_p4_watchdog()) + return; + break; + default: + return; + } + break; + default: return; } - /* FALL THROUGH */ - case NMI_IO_APIC: - __get_cpu_var(wd_enabled) = 1; - atomic_inc(&nmi_active); } + wd->enabled = 1; + atomic_inc(&nmi_active); } void stop_apic_nmi_watchdog(void *unused) { + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + /* only support LOCAL and IO APICs for now */ if ((nmi_watchdog != NMI_LOCAL_APIC) && (nmi_watchdog != NMI_IO_APIC)) return; - if (__get_cpu_var(wd_enabled) == 0) + + if (wd->enabled == 0) return; - if (nmi_watchdog == NMI_LOCAL_APIC) - lapic_watchdog_stop(); - __get_cpu_var(wd_enabled) = 0; + + if (nmi_watchdog == NMI_LOCAL_APIC) { + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + stop_k7_watchdog(); + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + stop_intel_arch_watchdog(); + break; + } + switch (boot_cpu_data.x86) { + case 6: + if (boot_cpu_data.x86_model > 0xd) + break; + stop_p6_watchdog(); + break; + case 15: + if (boot_cpu_data.x86_model > 0x4) + break; + stop_p4_watchdog(); + break; + } + break; + default: + return; + } + } + wd->enabled = 0; atomic_dec(&nmi_active); } @@ -328,6 +1011,8 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) unsigned int sum; int touched = 0; int cpu = smp_processor_id(); + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + u64 dummy; int rc=0; /* check for other users first */ @@ -370,20 +1055,53 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) alert_counter[cpu] = 0; } /* see if the nmi watchdog went off */ - if (!__get_cpu_var(wd_enabled)) - return rc; - switch (nmi_watchdog) { - case NMI_LOCAL_APIC: - rc |= lapic_wd_event(nmi_hz); - break; - case NMI_IO_APIC: - /* don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. - */ - rc = 1; - break; + if (wd->enabled) { + if (nmi_watchdog == NMI_LOCAL_APIC) { + rdmsrl(wd->perfctr_msr, dummy); + if (dummy & wd->check_bit){ + /* this wasn't a watchdog timer interrupt */ + goto done; + } + + /* only Intel P4 uses the cccr msr */ + if (wd->cccr_msr != 0) { + /* + * P4 quirks: + * - An overflown perfctr will assert its interrupt + * until the OVF flag in its CCCR is cleared. + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. + */ + rdmsrl(wd->cccr_msr, dummy); + dummy &= ~P4_CCCR_OVF; + wrmsrl(wd->cccr_msr, dummy); + apic_write(APIC_LVTPC, APIC_DM_NMI); + /* start the cycle over again */ + write_watchdog_counter(wd->perfctr_msr, NULL); + } + else if (wd->perfctr_msr == MSR_P6_PERFCTR0 || + wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + /* P6 based Pentium M need to re-unmask + * the apic vector but it doesn't hurt + * other P6 variant. + * ArchPerfom/Core Duo also needs this */ + apic_write(APIC_LVTPC, APIC_DM_NMI); + /* P6/ARCH_PERFMON has 32 bit counter write */ + write_watchdog_counter32(wd->perfctr_msr, NULL); + } else { + /* start the cycle over again */ + write_watchdog_counter(wd->perfctr_msr, NULL); + } + rc = 1; + } else if (nmi_watchdog == NMI_IO_APIC) { + /* don't know how to accurately check for this. + * just assume it was a watchdog timer interrupt + * This matches the old behaviour. + */ + rc = 1; + } } +done: return rc; } @@ -428,7 +1146,7 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, } if (nmi_watchdog == NMI_DEFAULT) { - if (lapic_watchdog_ok()) + if (nmi_known_cpu() > 0) nmi_watchdog = NMI_LOCAL_APIC; else nmi_watchdog = NMI_IO_APIC; @@ -464,3 +1182,11 @@ void __trigger_all_cpu_backtrace(void) EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); +EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); +EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); +EXPORT_SYMBOL(reserve_perfctr_nmi); +EXPORT_SYMBOL(release_perfctr_nmi); +EXPORT_SYMBOL(reserve_evntsel_nmi); +EXPORT_SYMBOL(release_evntsel_nmi); +EXPORT_SYMBOL(disable_timer_nmi_watchdog); +EXPORT_SYMBOL(enable_timer_nmi_watchdog); diff --git a/trunk/arch/i386/kernel/paravirt.c b/trunk/arch/i386/kernel/paravirt.c index 5c10f376bce1..2ec331e03fa9 100644 --- a/trunk/arch/i386/kernel/paravirt.c +++ b/trunk/arch/i386/kernel/paravirt.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -36,7 +35,7 @@ #include /* nop stub */ -void _paravirt_nop(void) +static void native_nop(void) { } @@ -55,148 +54,331 @@ char *memory_setup(void) #define DEF_NATIVE(name, code) \ extern const char start_##name[], end_##name[]; \ asm("start_" #name ": " code "; end_" #name ":") - -DEF_NATIVE(irq_disable, "cli"); -DEF_NATIVE(irq_enable, "sti"); -DEF_NATIVE(restore_fl, "push %eax; popf"); -DEF_NATIVE(save_fl, "pushf; pop %eax"); +DEF_NATIVE(cli, "cli"); +DEF_NATIVE(sti, "sti"); +DEF_NATIVE(popf, "push %eax; popf"); +DEF_NATIVE(pushf, "pushf; pop %eax"); +DEF_NATIVE(pushf_cli, "pushf; pop %eax; cli"); DEF_NATIVE(iret, "iret"); -DEF_NATIVE(irq_enable_sysexit, "sti; sysexit"); -DEF_NATIVE(read_cr2, "mov %cr2, %eax"); -DEF_NATIVE(write_cr3, "mov %eax, %cr3"); -DEF_NATIVE(read_cr3, "mov %cr3, %eax"); -DEF_NATIVE(clts, "clts"); -DEF_NATIVE(read_tsc, "rdtsc"); +DEF_NATIVE(sti_sysexit, "sti; sysexit"); -DEF_NATIVE(ud2a, "ud2a"); +static const struct native_insns +{ + const char *start, *end; +} native_insns[] = { + [PARAVIRT_IRQ_DISABLE] = { start_cli, end_cli }, + [PARAVIRT_IRQ_ENABLE] = { start_sti, end_sti }, + [PARAVIRT_RESTORE_FLAGS] = { start_popf, end_popf }, + [PARAVIRT_SAVE_FLAGS] = { start_pushf, end_pushf }, + [PARAVIRT_SAVE_FLAGS_IRQ_DISABLE] = { start_pushf_cli, end_pushf_cli }, + [PARAVIRT_INTERRUPT_RETURN] = { start_iret, end_iret }, + [PARAVIRT_STI_SYSEXIT] = { start_sti_sysexit, end_sti_sysexit }, +}; static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) { - const unsigned char *start, *end; - unsigned ret; - - switch(type) { -#define SITE(x) case PARAVIRT_PATCH(x): start = start_##x; end = end_##x; goto patch_site - SITE(irq_disable); - SITE(irq_enable); - SITE(restore_fl); - SITE(save_fl); - SITE(iret); - SITE(irq_enable_sysexit); - SITE(read_cr2); - SITE(read_cr3); - SITE(write_cr3); - SITE(clts); - SITE(read_tsc); -#undef SITE - - patch_site: - ret = paravirt_patch_insns(insns, len, start, end); - break; + unsigned int insn_len; - case PARAVIRT_PATCH(make_pgd): - case PARAVIRT_PATCH(make_pte): - case PARAVIRT_PATCH(pgd_val): - case PARAVIRT_PATCH(pte_val): -#ifdef CONFIG_X86_PAE - case PARAVIRT_PATCH(make_pmd): - case PARAVIRT_PATCH(pmd_val): -#endif - /* These functions end up returning exactly what - they're passed, in the same registers. */ - ret = paravirt_patch_nop(); - break; + /* Don't touch it if we don't have a replacement */ + if (type >= ARRAY_SIZE(native_insns) || !native_insns[type].start) + return len; + + insn_len = native_insns[type].end - native_insns[type].start; + /* Similarly if we can't fit replacement. */ + if (len < insn_len) + return len; + + memcpy(insns, native_insns[type].start, insn_len); + return insn_len; +} + +static unsigned long native_get_debugreg(int regno) +{ + unsigned long val = 0; /* Damn you, gcc! */ + + switch (regno) { + case 0: + asm("movl %%db0, %0" :"=r" (val)); break; + case 1: + asm("movl %%db1, %0" :"=r" (val)); break; + case 2: + asm("movl %%db2, %0" :"=r" (val)); break; + case 3: + asm("movl %%db3, %0" :"=r" (val)); break; + case 6: + asm("movl %%db6, %0" :"=r" (val)); break; + case 7: + asm("movl %%db7, %0" :"=r" (val)); break; default: - ret = paravirt_patch_default(type, clobbers, insns, len); + BUG(); + } + return val; +} + +static void native_set_debugreg(int regno, unsigned long value) +{ + switch (regno) { + case 0: + asm("movl %0,%%db0" : /* no output */ :"r" (value)); + break; + case 1: + asm("movl %0,%%db1" : /* no output */ :"r" (value)); + break; + case 2: + asm("movl %0,%%db2" : /* no output */ :"r" (value)); break; + case 3: + asm("movl %0,%%db3" : /* no output */ :"r" (value)); + break; + case 6: + asm("movl %0,%%db6" : /* no output */ :"r" (value)); + break; + case 7: + asm("movl %0,%%db7" : /* no output */ :"r" (value)); + break; + default: + BUG(); } +} - return ret; +void init_IRQ(void) +{ + paravirt_ops.init_IRQ(); } -unsigned paravirt_patch_nop(void) +static void native_clts(void) { - return 0; + asm volatile ("clts"); +} + +static unsigned long native_read_cr0(void) +{ + unsigned long val; + asm volatile("movl %%cr0,%0\n\t" :"=r" (val)); + return val; +} + +static void native_write_cr0(unsigned long val) +{ + asm volatile("movl %0,%%cr0": :"r" (val)); +} + +static unsigned long native_read_cr2(void) +{ + unsigned long val; + asm volatile("movl %%cr2,%0\n\t" :"=r" (val)); + return val; } -unsigned paravirt_patch_ignore(unsigned len) +static void native_write_cr2(unsigned long val) { - return len; + asm volatile("movl %0,%%cr2": :"r" (val)); } -unsigned paravirt_patch_call(void *target, u16 tgt_clobbers, - void *site, u16 site_clobbers, - unsigned len) +static unsigned long native_read_cr3(void) { - unsigned char *call = site; - unsigned long delta = (unsigned long)target - (unsigned long)(call+5); + unsigned long val; + asm volatile("movl %%cr3,%0\n\t" :"=r" (val)); + return val; +} - if (tgt_clobbers & ~site_clobbers) - return len; /* target would clobber too much for this site */ - if (len < 5) - return len; /* call too long for patch site */ +static void native_write_cr3(unsigned long val) +{ + asm volatile("movl %0,%%cr3": :"r" (val)); +} - *call++ = 0xe8; /* call */ - *(unsigned long *)call = delta; +static unsigned long native_read_cr4(void) +{ + unsigned long val; + asm volatile("movl %%cr4,%0\n\t" :"=r" (val)); + return val; +} - return 5; +static unsigned long native_read_cr4_safe(void) +{ + unsigned long val; + /* This could fault if %cr4 does not exist */ + asm("1: movl %%cr4, %0 \n" + "2: \n" + ".section __ex_table,\"a\" \n" + ".long 1b,2b \n" + ".previous \n" + : "=r" (val): "0" (0)); + return val; } -unsigned paravirt_patch_jmp(void *target, void *site, unsigned len) +static void native_write_cr4(unsigned long val) { - unsigned char *jmp = site; - unsigned long delta = (unsigned long)target - (unsigned long)(jmp+5); + asm volatile("movl %0,%%cr4": :"r" (val)); +} - if (len < 5) - return len; /* call too long for patch site */ +static unsigned long native_save_fl(void) +{ + unsigned long f; + asm volatile("pushfl ; popl %0":"=g" (f): /* no input */); + return f; +} - *jmp++ = 0xe9; /* jmp */ - *(unsigned long *)jmp = delta; +static void native_restore_fl(unsigned long f) +{ + asm volatile("pushl %0 ; popfl": /* no output */ + :"g" (f) + :"memory", "cc"); +} - return 5; +static void native_irq_disable(void) +{ + asm volatile("cli": : :"memory"); } -unsigned paravirt_patch_default(u8 type, u16 clobbers, void *site, unsigned len) +static void native_irq_enable(void) { - void *opfunc = *((void **)¶virt_ops + type); - unsigned ret; + asm volatile("sti": : :"memory"); +} - if (opfunc == NULL) - /* If there's no function, patch it with a ud2a (BUG) */ - ret = paravirt_patch_insns(site, len, start_ud2a, end_ud2a); - else if (opfunc == paravirt_nop) - /* If the operation is a nop, then nop the callsite */ - ret = paravirt_patch_nop(); - else if (type == PARAVIRT_PATCH(iret) || - type == PARAVIRT_PATCH(irq_enable_sysexit)) - /* If operation requires a jmp, then jmp */ - ret = paravirt_patch_jmp(opfunc, site, len); - else - /* Otherwise call the function; assume target could - clobber any caller-save reg */ - ret = paravirt_patch_call(opfunc, CLBR_ANY, - site, clobbers, len); +static void native_safe_halt(void) +{ + asm volatile("sti; hlt": : :"memory"); +} - return ret; +static void native_halt(void) +{ + asm volatile("hlt": : :"memory"); } -unsigned paravirt_patch_insns(void *site, unsigned len, - const char *start, const char *end) +static void native_wbinvd(void) { - unsigned insn_len = end - start; + asm volatile("wbinvd": : :"memory"); +} - if (insn_len > len || start == NULL) - insn_len = len; - else - memcpy(site, start, insn_len); +static unsigned long long native_read_msr(unsigned int msr, int *err) +{ + unsigned long long val; + + asm volatile("2: rdmsr ; xorl %0,%0\n" + "1:\n\t" + ".section .fixup,\"ax\"\n\t" + "3: movl %3,%0 ; jmp 1b\n\t" + ".previous\n\t" + ".section __ex_table,\"a\"\n" + " .align 4\n\t" + " .long 2b,3b\n\t" + ".previous" + : "=r" (*err), "=A" (val) + : "c" (msr), "i" (-EFAULT)); + + return val; +} - return insn_len; +static int native_write_msr(unsigned int msr, unsigned long long val) +{ + int err; + asm volatile("2: wrmsr ; xorl %0,%0\n" + "1:\n\t" + ".section .fixup,\"ax\"\n\t" + "3: movl %4,%0 ; jmp 1b\n\t" + ".previous\n\t" + ".section __ex_table,\"a\"\n" + " .align 4\n\t" + " .long 2b,3b\n\t" + ".previous" + : "=a" (err) + : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)), + "i" (-EFAULT)); + return err; } -void init_IRQ(void) +static unsigned long long native_read_tsc(void) { - paravirt_ops.init_IRQ(); + unsigned long long val; + asm volatile("rdtsc" : "=A" (val)); + return val; +} + +static unsigned long long native_read_pmc(void) +{ + unsigned long long val; + asm volatile("rdpmc" : "=A" (val)); + return val; +} + +static void native_load_tr_desc(void) +{ + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); +} + +static void native_load_gdt(const struct Xgt_desc_struct *dtr) +{ + asm volatile("lgdt %0"::"m" (*dtr)); +} + +static void native_load_idt(const struct Xgt_desc_struct *dtr) +{ + asm volatile("lidt %0"::"m" (*dtr)); +} + +static void native_store_gdt(struct Xgt_desc_struct *dtr) +{ + asm ("sgdt %0":"=m" (*dtr)); +} + +static void native_store_idt(struct Xgt_desc_struct *dtr) +{ + asm ("sidt %0":"=m" (*dtr)); +} + +static unsigned long native_store_tr(void) +{ + unsigned long tr; + asm ("str %0":"=r" (tr)); + return tr; +} + +static void native_load_tls(struct thread_struct *t, unsigned int cpu) +{ +#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i] + C(0); C(1); C(2); +#undef C +} + +static inline void native_write_dt_entry(void *dt, int entry, u32 entry_low, u32 entry_high) +{ + u32 *lp = (u32 *)((char *)dt + entry*8); + lp[0] = entry_low; + lp[1] = entry_high; +} + +static void native_write_ldt_entry(void *dt, int entrynum, u32 low, u32 high) +{ + native_write_dt_entry(dt, entrynum, low, high); +} + +static void native_write_gdt_entry(void *dt, int entrynum, u32 low, u32 high) +{ + native_write_dt_entry(dt, entrynum, low, high); +} + +static void native_write_idt_entry(void *dt, int entrynum, u32 low, u32 high) +{ + native_write_dt_entry(dt, entrynum, low, high); +} + +static void native_load_esp0(struct tss_struct *tss, + struct thread_struct *thread) +{ + tss->esp0 = thread->esp0; + + /* This can only happen when SEP is enabled, no need to test "SEP"arately */ + if (unlikely(tss->ss1 != thread->sysenter_cs)) { + tss->ss1 = thread->sysenter_cs; + wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); + } +} + +static void native_io_delay(void) +{ + asm volatile("outb %al,$0x80"); } static void native_flush_tlb(void) @@ -213,11 +395,83 @@ static void native_flush_tlb_global(void) __native_flush_tlb_global(); } -static void native_flush_tlb_single(unsigned long addr) +static void native_flush_tlb_single(u32 addr) { __native_flush_tlb_single(addr); } +#ifndef CONFIG_X86_PAE +static void native_set_pte(pte_t *ptep, pte_t pteval) +{ + *ptep = pteval; +} + +static void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval) +{ + *ptep = pteval; +} + +static void native_set_pmd(pmd_t *pmdp, pmd_t pmdval) +{ + *pmdp = pmdval; +} + +#else /* CONFIG_X86_PAE */ + +static void native_set_pte(pte_t *ptep, pte_t pte) +{ + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} + +static void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte) +{ + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} + +static void native_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) +{ + ptep->pte_low = 0; + smp_wmb(); + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} + +static void native_set_pte_atomic(pte_t *ptep, pte_t pteval) +{ + set_64bit((unsigned long long *)ptep,pte_val(pteval)); +} + +static void native_set_pmd(pmd_t *pmdp, pmd_t pmdval) +{ + set_64bit((unsigned long long *)pmdp,pmd_val(pmdval)); +} + +static void native_set_pud(pud_t *pudp, pud_t pudval) +{ + *pudp = pudval; +} + +static void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + ptep->pte_low = 0; + smp_wmb(); + ptep->pte_high = 0; +} + +static void native_pmd_clear(pmd_t *pmd) +{ + u32 *tmp = (u32 *)pmd; + *tmp = 0; + smp_wmb(); + *(tmp + 1) = 0; +} +#endif /* CONFIG_X86_PAE */ + /* These are in entry.S */ extern void native_iret(void); extern void native_irq_enable_sysexit(void); @@ -233,11 +487,10 @@ struct paravirt_ops paravirt_ops = { .name = "bare hardware", .paravirt_enabled = 0, .kernel_rpl = 0, - .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ .patch = native_patch, .banner = default_banner, - .arch_setup = paravirt_nop, + .arch_setup = native_nop, .memory_setup = machine_specific_memory_setup, .get_wallclock = native_get_wallclock, .set_wallclock = native_set_wallclock, @@ -264,8 +517,8 @@ struct paravirt_ops paravirt_ops = { .safe_halt = native_safe_halt, .halt = native_halt, .wbinvd = native_wbinvd, - .read_msr = native_read_msr_safe, - .write_msr = native_write_msr_safe, + .read_msr = native_read_msr, + .write_msr = native_write_msr, .read_tsc = native_read_tsc, .read_pmc = native_read_pmc, .get_scheduled_cycles = native_read_tsc, @@ -278,9 +531,9 @@ struct paravirt_ops paravirt_ops = { .store_idt = native_store_idt, .store_tr = native_store_tr, .load_tls = native_load_tls, - .write_ldt_entry = write_dt_entry, - .write_gdt_entry = write_dt_entry, - .write_idt_entry = write_dt_entry, + .write_ldt_entry = native_write_ldt_entry, + .write_gdt_entry = native_write_gdt_entry, + .write_idt_entry = native_write_idt_entry, .load_esp0 = native_load_esp0, .set_iopl_mask = native_set_iopl_mask, @@ -292,57 +545,44 @@ struct paravirt_ops paravirt_ops = { .apic_read = native_apic_read, .setup_boot_clock = setup_boot_APIC_clock, .setup_secondary_clock = setup_secondary_APIC_clock, - .startup_ipi_hook = paravirt_nop, #endif - .set_lazy_mode = paravirt_nop, - - .pagetable_setup_start = native_pagetable_setup_start, - .pagetable_setup_done = native_pagetable_setup_done, + .set_lazy_mode = (void *)native_nop, .flush_tlb_user = native_flush_tlb, .flush_tlb_kernel = native_flush_tlb_global, .flush_tlb_single = native_flush_tlb_single, - .flush_tlb_others = native_flush_tlb_others, - .alloc_pt = paravirt_nop, - .alloc_pd = paravirt_nop, - .alloc_pd_clone = paravirt_nop, - .release_pt = paravirt_nop, - .release_pd = paravirt_nop, + .map_pt_hook = (void *)native_nop, + + .alloc_pt = (void *)native_nop, + .alloc_pd = (void *)native_nop, + .alloc_pd_clone = (void *)native_nop, + .release_pt = (void *)native_nop, + .release_pd = (void *)native_nop, .set_pte = native_set_pte, .set_pte_at = native_set_pte_at, .set_pmd = native_set_pmd, - .pte_update = paravirt_nop, - .pte_update_defer = paravirt_nop, - -#ifdef CONFIG_HIGHPTE - .kmap_atomic_pte = kmap_atomic, -#endif - + .pte_update = (void *)native_nop, + .pte_update_defer = (void *)native_nop, #ifdef CONFIG_X86_PAE .set_pte_atomic = native_set_pte_atomic, .set_pte_present = native_set_pte_present, .set_pud = native_set_pud, .pte_clear = native_pte_clear, .pmd_clear = native_pmd_clear, - - .pmd_val = native_pmd_val, - .make_pmd = native_make_pmd, #endif - .pte_val = native_pte_val, - .pgd_val = native_pgd_val, - - .make_pte = native_make_pte, - .make_pgd = native_make_pgd, - .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, - .dup_mmap = paravirt_nop, - .exit_mmap = paravirt_nop, - .activate_mm = paravirt_nop, + .startup_ipi_hook = (void *)native_nop, }; -EXPORT_SYMBOL(paravirt_ops); +/* + * NOTE: CONFIG_PARAVIRT is experimental and the paravirt_ops + * semantics are subject to change. Hence we only do this + * internal-only export of this, until it gets sorted out and + * all lowlevel CPU ops used by modules are separately exported. + */ +EXPORT_SYMBOL_GPL(paravirt_ops); diff --git a/trunk/arch/i386/kernel/pci-dma.c b/trunk/arch/i386/kernel/pci-dma.c index 30b754f7cbec..3ebcea033623 100644 --- a/trunk/arch/i386/kernel/pci-dma.c +++ b/trunk/arch/i386/kernel/pci-dma.c @@ -77,7 +77,7 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, { void __iomem *mem_base = NULL; int pages = size >> PAGE_SHIFT; - int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); + int bitmap_size = (pages + 31)/32; if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0) goto out; diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index d76d9bc33b30..393a67d5d943 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,6 @@ #include #include #include -#include #include #include @@ -57,6 +57,7 @@ #include #include +#include asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); @@ -65,12 +66,6 @@ static int hlt_counter; unsigned long boot_option_idle_override = 0; EXPORT_SYMBOL(boot_option_idle_override); -DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; -EXPORT_PER_CPU_SYMBOL(current_task); - -DEFINE_PER_CPU(int, cpu_number); -EXPORT_PER_CPU_SYMBOL(cpu_number); - /* * Return saved PC of a blocked thread. */ @@ -277,24 +272,25 @@ void __devinit select_idle_routine(const struct cpuinfo_x86 *c) } } -static int __init idle_setup(char *str) +static int __init idle_setup (char *str) { - if (!strcmp(str, "poll")) { + if (!strncmp(str, "poll", 4)) { printk("using polling idle threads.\n"); pm_idle = poll_idle; #ifdef CONFIG_X86_SMP if (smp_num_siblings > 1) printk("WARNING: polling idle and HT enabled, performance may degrade.\n"); #endif - } else if (!strcmp(str, "mwait")) - force_mwait = 1; - else - return -1; + } else if (!strncmp(str, "halt", 4)) { + printk("using halt in idle threads.\n"); + pm_idle = default_idle; + } boot_option_idle_override = 1; - return 0; + return 1; } -early_param("idle", idle_setup); + +__setup("idle=", idle_setup); void show_regs(struct pt_regs * regs) { @@ -347,7 +343,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) regs.xds = __USER_DS; regs.xes = __USER_DS; - regs.xfs = __KERNEL_PERCPU; + regs.xfs = __KERNEL_PDA; regs.orig_eax = -1; regs.eip = (unsigned long) kernel_thread_helper; regs.xcs = __KERNEL_CS | get_kernel_rpl(); @@ -380,7 +376,7 @@ void exit_thread(void) t->io_bitmap_max = 0; tss->io_bitmap_owner = NULL; tss->io_bitmap_max = 0; - tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; + tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET; put_cpu(); } } @@ -559,7 +555,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p, * Disable the bitmap via an invalid offset. We still cache * the previous bitmap owner and the IO bitmap contents: */ - tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET; + tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET; return; } @@ -569,7 +565,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p, * matches the next task, we dont have to do anything but * to set a valid offset in the TSS: */ - tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; + tss->io_bitmap_base = IO_BITMAP_OFFSET; return; } /* @@ -581,7 +577,7 @@ static noinline void __switch_to_xtra(struct task_struct *next_p, * redundant copies when the currently switched task does not * perform any I/O during its timeslice. */ - tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; + tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; } /* @@ -716,7 +712,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas if (prev->gs | next->gs) loadsegment(gs, next->gs); - x86_write_percpu(current_task, next_p); + write_pda(pcurrent, next_p); return prev_p; } diff --git a/trunk/arch/i386/kernel/ptrace.c b/trunk/arch/i386/kernel/ptrace.c index 0c0ceec5de00..4a8f8a259723 100644 --- a/trunk/arch/i386/kernel/ptrace.c +++ b/trunk/arch/i386/kernel/ptrace.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/i386/kernel/quirks.c b/trunk/arch/i386/kernel/quirks.c index 9f6ab1789bb0..34874c398b44 100644 --- a/trunk/arch/i386/kernel/quirks.c +++ b/trunk/arch/i386/kernel/quirks.c @@ -3,10 +3,12 @@ */ #include #include +#include +#include +#include #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) - -static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) +static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev) { u8 config, rev; u32 word; @@ -14,14 +16,12 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) /* BIOS may enable hardware IRQ balancing for * E7520/E7320/E7525(revision ID 0x9 and below) * based platforms. - * Disable SW irqbalance/affinity on those platforms. + * For those platforms, make sure that the genapic is set to 'flat' */ pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); if (rev > 0x9) return; - printk(KERN_INFO "Intel E7520/7320/7525 detected."); - /* enable access to config space*/ pci_read_config_byte(dev, 0xf4, &config); pci_write_config_byte(dev, 0xf4, config|0x2); @@ -29,6 +29,44 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) /* read xTPR register */ raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); + if (!(word & (1 << 13))) { +#ifdef CONFIG_X86_64 + if (genapic != &apic_flat) + panic("APIC mode must be flat on this system\n"); +#elif defined(CONFIG_X86_GENERICARCH) + if (genapic != &apic_default) + panic("APIC mode must be default(flat) on this system. Use apic=default\n"); +#endif + } + + /* put back the original value for config space*/ + if (!(config & 0x2)) + pci_write_config_byte(dev, 0xf4, config); +} + +void __init quirk_intel_irqbalance(void) +{ + u8 config, rev; + u32 word; + + /* BIOS may enable hardware IRQ balancing for + * E7520/E7320/E7525(revision ID 0x9 and below) + * based platforms. + * Disable SW irqbalance/affinity on those platforms. + */ + rev = read_pci_config_byte(0, 0, 0, PCI_CLASS_REVISION); + if (rev > 0x9) + return; + + printk(KERN_INFO "Intel E7520/7320/7525 detected."); + + /* enable access to config space */ + config = read_pci_config_byte(0, 0, 0, 0xf4); + write_pci_config_byte(0, 0, 0, 0xf4, config|0x2); + + /* read xTPR register */ + word = read_pci_config_16(0, 0, 0x40, 0x4c); + if (!(word & (1 << 13))) { printk(KERN_INFO "Disabling irq balancing and affinity\n"); #ifdef CONFIG_IRQBALANCE @@ -37,14 +75,25 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) noirqdebug_setup(""); #ifdef CONFIG_PROC_FS no_irq_affinity = 1; +#endif +#ifdef CONFIG_HOTPLUG_CPU + printk(KERN_INFO "Disabling cpu hotplug control\n"); + enable_cpu_hotplug = 0; +#endif +#ifdef CONFIG_X86_64 + /* force the genapic selection to flat mode so that + * interrupts can be redirected to more than one CPU. + */ + genapic_force = &apic_flat; #endif } - /* put back the original value for config space*/ + /* put back the original value for config space */ if (!(config & 0x2)) - pci_write_config_byte(dev, 0xf4, config); + write_pci_config_byte(0, 0, 0, 0xf4, config); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, verify_quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, verify_quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, verify_quirk_intel_irqbalance); + #endif diff --git a/trunk/arch/i386/kernel/reboot.c b/trunk/arch/i386/kernel/reboot.c index 50dfc65319cd..3514b4153f7f 100644 --- a/trunk/arch/i386/kernel/reboot.c +++ b/trunk/arch/i386/kernel/reboot.c @@ -17,8 +17,7 @@ #include #include #include "mach_reboot.h" -#include -#include +#include /* * Power off function, if any @@ -198,6 +197,8 @@ static unsigned char jump_to_bios [] = */ void machine_real_restart(unsigned char *code, int length) { + unsigned long flags; + local_irq_disable(); /* Write zero to CMOS register number 0x0f, which the BIOS POST @@ -210,9 +211,9 @@ void machine_real_restart(unsigned char *code, int length) safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.) */ - spin_lock(&rtc_lock); + spin_lock_irqsave(&rtc_lock, flags); CMOS_WRITE(0x00, 0x8f); - spin_unlock(&rtc_lock); + spin_unlock_irqrestore(&rtc_lock, flags); /* Remap the kernel at virtual address zero, as well as offset zero from the kernel segment. This assumes the kernel segment starts at @@ -279,7 +280,7 @@ void machine_real_restart(unsigned char *code, int length) EXPORT_SYMBOL(machine_real_restart); #endif -static void native_machine_shutdown(void) +void machine_shutdown(void) { #ifdef CONFIG_SMP int reboot_cpu_id; @@ -315,11 +316,7 @@ static void native_machine_shutdown(void) #endif } -void __attribute__((weak)) mach_reboot_fixups(void) -{ -} - -static void native_machine_emergency_restart(void) +void machine_emergency_restart(void) { if (!reboot_thru_bios) { if (efi_enabled) { @@ -343,17 +340,17 @@ static void native_machine_emergency_restart(void) machine_real_restart(jump_to_bios, sizeof(jump_to_bios)); } -static void native_machine_restart(char * __unused) +void machine_restart(char * __unused) { machine_shutdown(); machine_emergency_restart(); } -static void native_machine_halt(void) +void machine_halt(void) { } -static void native_machine_power_off(void) +void machine_power_off(void) { if (pm_power_off) { machine_shutdown(); @@ -362,35 +359,3 @@ static void native_machine_power_off(void) } -struct machine_ops machine_ops = { - .power_off = native_machine_power_off, - .shutdown = native_machine_shutdown, - .emergency_restart = native_machine_emergency_restart, - .restart = native_machine_restart, - .halt = native_machine_halt, -}; - -void machine_power_off(void) -{ - machine_ops.power_off(); -} - -void machine_shutdown(void) -{ - machine_ops.shutdown(); -} - -void machine_emergency_restart(void) -{ - machine_ops.emergency_restart(); -} - -void machine_restart(char *cmd) -{ - machine_ops.restart(cmd); -} - -void machine_halt(void) -{ - machine_ops.halt(); -} diff --git a/trunk/arch/i386/kernel/reboot_fixups.c b/trunk/arch/i386/kernel/reboot_fixups.c index 2d78d918340f..99aab41a05b0 100644 --- a/trunk/arch/i386/kernel/reboot_fixups.c +++ b/trunk/arch/i386/kernel/reboot_fixups.c @@ -10,7 +10,7 @@ #include #include -#include +#include static void cs5530a_warm_reset(struct pci_dev *dev) { diff --git a/trunk/arch/i386/kernel/signal.c b/trunk/arch/i386/kernel/signal.c index d574e38f0f77..4f99e870c986 100644 --- a/trunk/arch/i386/kernel/signal.c +++ b/trunk/arch/i386/kernel/signal.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/i386/kernel/smp.c b/trunk/arch/i386/kernel/smp.c index 93f202a855fa..0e8977871b1f 100644 --- a/trunk/arch/i386/kernel/smp.c +++ b/trunk/arch/i386/kernel/smp.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -164,20 +165,20 @@ void fastcall send_IPI_self(int vector) } /* - * This is used to send an IPI with no shorthand notation (the destination is - * specified in bits 56 to 63 of the ICR). + * This is only used on smaller machines. */ -static inline void __send_IPI_dest_field(unsigned long mask, int vector) +void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) { + unsigned long mask = cpus_addr(cpumask)[0]; unsigned long cfg; + unsigned long flags; + local_irq_save(flags); + WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]); /* * Wait for idle. */ - if (unlikely(vector == NMI_VECTOR)) - safe_apic_wait_icr_idle(); - else - apic_wait_icr_idle(); + apic_wait_icr_idle(); /* * prepare target chip field @@ -194,25 +195,13 @@ static inline void __send_IPI_dest_field(unsigned long mask, int vector) * Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around(APIC_ICR, cfg); -} - -/* - * This is only used on smaller machines. - */ -void send_IPI_mask_bitmask(cpumask_t cpumask, int vector) -{ - unsigned long mask = cpus_addr(cpumask)[0]; - unsigned long flags; - local_irq_save(flags); - WARN_ON(mask & ~cpus_addr(cpu_online_map)[0]); - __send_IPI_dest_field(mask, vector); local_irq_restore(flags); } void send_IPI_mask_sequence(cpumask_t mask, int vector) { - unsigned long flags; + unsigned long cfg, flags; unsigned int query_cpu; /* @@ -222,10 +211,30 @@ void send_IPI_mask_sequence(cpumask_t mask, int vector) */ local_irq_save(flags); + for (query_cpu = 0; query_cpu < NR_CPUS; ++query_cpu) { if (cpu_isset(query_cpu, mask)) { - __send_IPI_dest_field(cpu_to_logical_apicid(query_cpu), - vector); + + /* + * Wait for idle. + */ + apic_wait_icr_idle(); + + /* + * prepare target chip field + */ + cfg = __prepare_ICR2(cpu_to_logical_apicid(query_cpu)); + apic_write_around(APIC_ICR2, cfg); + + /* + * program the ICR + */ + cfg = __prepare_ICR(0, vector); + + /* + * Send the IPI. The write to APIC_ICR fires this off. + */ + apic_write_around(APIC_ICR, cfg); } } local_irq_restore(flags); @@ -247,6 +256,7 @@ static cpumask_t flush_cpumask; static struct mm_struct * flush_mm; static unsigned long flush_va; static DEFINE_SPINLOCK(tlbstate_lock); +#define FLUSH_ALL 0xffffffff /* * We cannot call mmdrop() because we are in interrupt context, @@ -328,7 +338,7 @@ fastcall void smp_invalidate_interrupt(struct pt_regs *regs) if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) { if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) { - if (flush_va == TLB_FLUSH_ALL) + if (flush_va == FLUSH_ALL) local_flush_tlb(); else __flush_tlb_one(flush_va); @@ -343,11 +353,9 @@ fastcall void smp_invalidate_interrupt(struct pt_regs *regs) put_cpu_no_resched(); } -void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm, - unsigned long va) +static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, + unsigned long va) { - cpumask_t cpumask = *cpumaskp; - /* * A couple of (to be removed) sanity checks: * @@ -358,12 +366,10 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm, BUG_ON(cpu_isset(smp_processor_id(), cpumask)); BUG_ON(!mm); -#ifdef CONFIG_HOTPLUG_CPU /* If a CPU which we ran on has gone down, OK. */ cpus_and(cpumask, cpumask, cpu_online_map); - if (unlikely(cpus_empty(cpumask))) + if (cpus_empty(cpumask)) return; -#endif /* * i'm not happy about this global shared spinlock in the @@ -374,7 +380,17 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm, flush_mm = mm; flush_va = va; - cpus_or(flush_cpumask, cpumask, flush_cpumask); +#if NR_CPUS <= BITS_PER_LONG + atomic_set_mask(cpumask, &flush_cpumask); +#else + { + int k; + unsigned long *flush_mask = (unsigned long *)&flush_cpumask; + unsigned long *cpu_mask = (unsigned long *)&cpumask; + for (k = 0; k < BITS_TO_LONGS(NR_CPUS); ++k) + atomic_set_mask(cpu_mask[k], &flush_mask[k]); + } +#endif /* * We have to send the IPI only to * CPUs affected. @@ -401,7 +417,7 @@ void flush_tlb_current_task(void) local_flush_tlb(); if (!cpus_empty(cpu_mask)) - flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL); + flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } @@ -420,7 +436,7 @@ void flush_tlb_mm (struct mm_struct * mm) leave_mm(smp_processor_id()); } if (!cpus_empty(cpu_mask)) - flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL); + flush_tlb_others(cpu_mask, mm, FLUSH_ALL); preempt_enable(); } @@ -467,7 +483,7 @@ void flush_tlb_all(void) * it goes straight through and wastes no time serializing * anything. Worst case is that we lose a reschedule ... */ -void native_smp_send_reschedule(int cpu) +void smp_send_reschedule(int cpu) { WARN_ON(cpu_is_offline(cpu)); send_IPI_mask(cpumask_of_cpu(cpu), RESCHEDULE_VECTOR); @@ -499,78 +515,36 @@ void unlock_ipi_call_lock(void) static struct call_data_struct *call_data; -static void __smp_call_function(void (*func) (void *info), void *info, - int nonatomic, int wait) -{ - struct call_data_struct data; - int cpus = num_online_cpus() - 1; - - if (!cpus) - return; - - data.func = func; - data.info = info; - atomic_set(&data.started, 0); - data.wait = wait; - if (wait) - atomic_set(&data.finished, 0); - - call_data = &data; - mb(); - - /* Send a message to all other CPUs and wait for them to respond */ - send_IPI_allbutself(CALL_FUNCTION_VECTOR); - - /* Wait for response */ - while (atomic_read(&data.started) != cpus) - cpu_relax(); - - if (wait) - while (atomic_read(&data.finished) != cpus) - cpu_relax(); -} - - /** - * smp_call_function_mask(): Run a function on a set of other CPUs. - * @mask: The set of cpus to run on. Must not include the current cpu. + * smp_call_function(): Run a function on all other CPUs. * @func: The function to run. This must be fast and non-blocking. * @info: An arbitrary pointer to pass to the function. + * @nonatomic: currently unused. * @wait: If true, wait (atomically) until function has completed on other CPUs. * - * Returns 0 on success, else a negative status code. - * - * If @wait is true, then returns once @func has returned; otherwise - * it returns just before the target cpu calls @func. + * Returns 0 on success, else a negative status code. Does not return until + * remote CPUs are nearly ready to execute <> or are or have executed. * * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ -int native_smp_call_function_mask(cpumask_t mask, - void (*func)(void *), void *info, - int wait) +int smp_call_function (void (*func) (void *info), void *info, int nonatomic, + int wait) { struct call_data_struct data; - cpumask_t allbutself; int cpus; - /* Can deadlock when called with interrupts disabled */ - WARN_ON(irqs_disabled()); - /* Holding any lock stops cpus from going down. */ spin_lock(&call_lock); - - allbutself = cpu_online_map; - cpu_clear(smp_processor_id(), allbutself); - - cpus_and(mask, mask, allbutself); - cpus = cpus_weight(mask); - + cpus = num_online_cpus() - 1; if (!cpus) { spin_unlock(&call_lock); return 0; } + /* Can deadlock when called with interrupts disabled */ + WARN_ON(irqs_disabled()); + data.func = func; data.info = info; atomic_set(&data.started, 0); @@ -580,12 +554,9 @@ int native_smp_call_function_mask(cpumask_t mask, call_data = &data; mb(); - - /* Send a message to other CPUs */ - if (cpus_equal(mask, allbutself)) - send_IPI_allbutself(CALL_FUNCTION_VECTOR); - else - send_IPI_mask(mask, CALL_FUNCTION_VECTOR); + + /* Send a message to all other CPUs and wait for them to respond */ + send_IPI_allbutself(CALL_FUNCTION_VECTOR); /* Wait for response */ while (atomic_read(&data.started) != cpus) @@ -598,68 +569,15 @@ int native_smp_call_function_mask(cpumask_t mask, return 0; } - -/** - * smp_call_function(): Run a function on all other CPUs. - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @nonatomic: Unused. - * @wait: If true, wait (atomically) until function has completed on other CPUs. - * - * Returns 0 on success, else a negative status code. - * - * If @wait is true, then returns once @func has returned; otherwise - * it returns just before the target cpu calls @func. - * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ -int smp_call_function(void (*func) (void *info), void *info, int nonatomic, - int wait) -{ - return smp_call_function_mask(cpu_online_map, func, info, wait); -} EXPORT_SYMBOL(smp_call_function); -/** - * smp_call_function_single - Run a function on another CPU - * @cpu: The target CPU. Cannot be the calling CPU. - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @nonatomic: Unused. - * @wait: If true, wait until function has completed on other CPUs. - * - * Returns 0 on success, else a negative status code. - * - * If @wait is true, then returns once @func has returned; otherwise - * it returns just before the target cpu calls @func. - */ -int smp_call_function_single(int cpu, void (*func) (void *info), void *info, - int nonatomic, int wait) -{ - /* prevent preemption and reschedule on another processor */ - int ret; - int me = get_cpu(); - if (cpu == me) { - WARN_ON(1); - put_cpu(); - return -EBUSY; - } - - ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait); - - put_cpu(); - return ret; -} -EXPORT_SYMBOL(smp_call_function_single); - static void stop_this_cpu (void * dummy) { - local_irq_disable(); /* * Remove this CPU: */ cpu_clear(smp_processor_id(), cpu_online_map); + local_irq_disable(); disable_local_APIC(); if (cpu_data[smp_processor_id()].hlt_works_ok) for(;;) halt(); @@ -670,18 +588,13 @@ static void stop_this_cpu (void * dummy) * this function calls the 'stop' function on all other CPUs in the system. */ -void native_smp_send_stop(void) +void smp_send_stop(void) { - /* Don't deadlock on the call lock in panic */ - int nolock = !spin_trylock(&call_lock); - unsigned long flags; + smp_call_function(stop_this_cpu, NULL, 1, 0); - local_irq_save(flags); - __smp_call_function(stop_this_cpu, NULL, 0, 0); - if (!nolock) - spin_unlock(&call_lock); + local_irq_disable(); disable_local_APIC(); - local_irq_restore(flags); + local_irq_enable(); } /* @@ -720,6 +633,77 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs) } } +/* + * this function sends a 'generic call function' IPI to one other CPU + * in the system. + * + * cpu is a standard Linux logical CPU number. + */ +static void +__smp_call_function_single(int cpu, void (*func) (void *info), void *info, + int nonatomic, int wait) +{ + struct call_data_struct data; + int cpus = 1; + + data.func = func; + data.info = info; + atomic_set(&data.started, 0); + data.wait = wait; + if (wait) + atomic_set(&data.finished, 0); + + call_data = &data; + wmb(); + /* Send a message to all other CPUs and wait for them to respond */ + send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR); + + /* Wait for response */ + while (atomic_read(&data.started) != cpus) + cpu_relax(); + + if (!wait) + return; + + while (atomic_read(&data.finished) != cpus) + cpu_relax(); +} + +/* + * smp_call_function_single - Run a function on another CPU + * @func: The function to run. This must be fast and non-blocking. + * @info: An arbitrary pointer to pass to the function. + * @nonatomic: Currently unused. + * @wait: If true, wait until function has completed on other CPUs. + * + * Retrurns 0 on success, else a negative status code. + * + * Does not return until the remote CPU is nearly ready to execute + * or is or has executed. + */ + +int smp_call_function_single(int cpu, void (*func) (void *info), void *info, + int nonatomic, int wait) +{ + /* prevent preemption and reschedule on another processor */ + int me = get_cpu(); + if (cpu == me) { + WARN_ON(1); + put_cpu(); + return -EBUSY; + } + + /* Can deadlock when called with interrupts disabled */ + WARN_ON(irqs_disabled()); + + spin_lock_bh(&call_lock); + __smp_call_function_single(cpu, func, info, nonatomic, wait); + spin_unlock_bh(&call_lock); + put_cpu(); + return 0; +} +EXPORT_SYMBOL(smp_call_function_single); + static int convert_apicid_to_cpu(int apic_id) { int i; @@ -746,14 +730,3 @@ int safe_smp_processor_id(void) return cpuid >= 0 ? cpuid : 0; } - -struct smp_ops smp_ops = { - .smp_prepare_boot_cpu = native_smp_prepare_boot_cpu, - .smp_prepare_cpus = native_smp_prepare_cpus, - .cpu_up = native_cpu_up, - .smp_cpus_done = native_smp_cpus_done, - - .smp_send_stop = native_smp_send_stop, - .smp_send_reschedule = native_smp_send_reschedule, - .smp_call_function_mask = native_smp_call_function_mask, -}; diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index b92cc4e8b3bb..4ff55e675576 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -52,12 +53,13 @@ #include #include #include +#include +#include #include #include #include #include -#include /* Set if we find a B stepping CPU */ static int __devinitdata smp_b_stepping; @@ -98,9 +100,6 @@ EXPORT_SYMBOL(x86_cpu_to_apicid); u8 apicid_2_node[MAX_APICID]; -DEFINE_PER_CPU(unsigned long, this_cpu_off); -EXPORT_PER_CPU_SYMBOL(this_cpu_off); - /* * Trampoline 80x86 program as an array. */ @@ -157,7 +156,7 @@ static void __cpuinit smp_store_cpu_info(int id) *c = boot_cpu_data; if (id!=0) - identify_secondary_cpu(c); + identify_cpu(c); /* * Mask B, Pentium, but not Pentium MMX */ @@ -380,14 +379,14 @@ set_cpu_sibling_map(int cpu) static void __cpuinit start_secondary(void *unused) { /* - * Don't put *anything* before cpu_init(), SMP booting is too - * fragile that we want to limit the things done here to the - * most necessary things. + * Don't put *anything* before secondary_cpu_init(), SMP + * booting is too fragile that we want to limit the + * things done here to the most necessary things. */ #ifdef CONFIG_VMI vmi_bringup(); #endif - cpu_init(); + secondary_cpu_init(); preempt_disable(); smp_callin(); while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) @@ -441,6 +440,12 @@ static void __cpuinit start_secondary(void *unused) */ void __devinit initialize_secondary(void) { + /* + * switch to the per CPU GDT we already set up + * in do_boot_cpu() + */ + cpu_set_gdt(current_thread_info()->cpu); + /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. @@ -458,6 +463,7 @@ extern struct { void * esp; unsigned short ss; } stack_start; +extern struct i386_pda *start_pda; #ifdef CONFIG_NUMA @@ -515,12 +521,12 @@ static void unmap_cpu_to_logical_apicid(int cpu) unmap_cpu_to_node(cpu); } +#if APIC_DEBUG static inline void __inquire_remote_apic(int apicid) { int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; char *names[] = { "ID", "VERSION", "SPIV" }; - int timeout; - unsigned long status; + int timeout, status; printk("Inquiring remote APIC #%d...\n", apicid); @@ -530,9 +536,7 @@ static inline void __inquire_remote_apic(int apicid) /* * Wait for idle. */ - status = safe_apic_wait_icr_idle(); - if (status) - printk("a previous APIC delivery may have failed\n"); + apic_wait_icr_idle(); apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]); @@ -546,13 +550,14 @@ static inline void __inquire_remote_apic(int apicid) switch (status) { case APIC_ICR_RR_VALID: status = apic_read(APIC_RRR); - printk("%lx\n", status); + printk("%08x\n", status); break; default: printk("failed\n"); } } } +#endif #ifdef WAKE_SECONDARY_VIA_NMI /* @@ -563,8 +568,8 @@ static inline void __inquire_remote_apic(int apicid) static int __devinit wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) { - unsigned long send_status, accept_status = 0; - int maxlvt; + unsigned long send_status = 0, accept_status = 0; + int timeout, maxlvt; /* Target chip */ apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid)); @@ -574,7 +579,12 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); Dprintk("Waiting for send to finish...\n"); - send_status = safe_apic_wait_icr_idle(); + timeout = 0; + do { + Dprintk("+"); + udelay(100); + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + } while (send_status && (timeout++ < 1000)); /* * Give the other CPU some time to accept the IPI. @@ -604,8 +614,8 @@ wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) static int __devinit wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) { - unsigned long send_status, accept_status = 0; - int maxlvt, num_starts, j; + unsigned long send_status = 0, accept_status = 0; + int maxlvt, timeout, num_starts, j; /* * Be paranoid about clearing APIC errors. @@ -630,7 +640,12 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) | APIC_DM_INIT); Dprintk("Waiting for send to finish...\n"); - send_status = safe_apic_wait_icr_idle(); + timeout = 0; + do { + Dprintk("+"); + udelay(100); + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + } while (send_status && (timeout++ < 1000)); mdelay(10); @@ -643,7 +658,12 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); Dprintk("Waiting for send to finish...\n"); - send_status = safe_apic_wait_icr_idle(); + timeout = 0; + do { + Dprintk("+"); + udelay(100); + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + } while (send_status && (timeout++ < 1000)); atomic_set(&init_deasserted, 1); @@ -699,7 +719,12 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) Dprintk("Startup point 1.\n"); Dprintk("Waiting for send to finish...\n"); - send_status = safe_apic_wait_icr_idle(); + timeout = 0; + do { + Dprintk("+"); + udelay(100); + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + } while (send_status && (timeout++ < 1000)); /* * Give the other CPU some time to accept the IPI. @@ -763,25 +788,6 @@ static inline struct task_struct * alloc_idle_task(int cpu) #define alloc_idle_task(cpu) fork_idle(cpu) #endif -/* Initialize the CPU's GDT. This is either the boot CPU doing itself - (still using the master per-cpu area), or a CPU doing it for a - secondary which will soon come up. */ -static __cpuinit void init_gdt(int cpu) -{ - struct desc_struct *gdt = get_cpu_gdt_table(cpu); - - pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, - (u32 *)&gdt[GDT_ENTRY_PERCPU].b, - __per_cpu_offset[cpu], 0xFFFFF, - 0x80 | DESCTYPE_S | 0x2, 0x8); - - per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; - per_cpu(cpu_number, cpu) = cpu; -} - -/* Defined in head.S */ -extern struct Xgt_desc_struct early_gdt_descr; - static int __cpuinit do_boot_cpu(int apicid, int cpu) /* * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad @@ -795,12 +801,6 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) unsigned long start_eip; unsigned short nmi_high = 0, nmi_low = 0; - /* - * Save current MTRR state in case it was changed since early boot - * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync: - */ - mtrr_save_state(); - /* * We can't use kernel_thread since we must avoid to * reschedule the child. @@ -809,9 +809,13 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu) if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); - init_gdt(cpu); - per_cpu(current_task, cpu) = idle; - early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); + /* Pre-allocate and initialize the CPU's GDT and PDA so it + doesn't have to do any memory allocation during the + delicate CPU-bringup phase. */ + if (!init_gdt(cpu, idle)) { + printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); + return -1; /* ? */ + } idle->thread.eip = (unsigned long) start_secondary; /* start_eip had better be page-aligned! */ @@ -937,6 +941,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) DECLARE_COMPLETION_ONSTACK(done); struct warm_boot_cpu_info info; int apicid, ret; + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); apicid = x86_cpu_to_apicid[cpu]; if (apicid == BAD_APICID) { @@ -944,6 +949,18 @@ static int __cpuinit __smp_prepare_cpu(int cpu) goto exit; } + /* + * the CPU isn't initialized at boot time, allocate gdt table here. + * cpu_init will initialize it + */ + if (!cpu_gdt_descr->address) { + cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL); + if (!cpu_gdt_descr->address) + printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); + ret = -ENOMEM; + goto exit; + } + info.complete = &done; info.apicid = apicid; info.cpu = cpu; @@ -1156,7 +1173,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) /* These are wrappers to interface to the new boot process. Someone who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */ -void __init native_smp_prepare_cpus(unsigned int max_cpus) +void __init smp_prepare_cpus(unsigned int max_cpus) { smp_commenced_mask = cpumask_of_cpu(0); cpu_callin_map = cpumask_of_cpu(0); @@ -1164,18 +1181,13 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) smp_boot_cpus(max_cpus); } -void __init native_smp_prepare_boot_cpu(void) +void __devinit smp_prepare_boot_cpu(void) { - unsigned int cpu = smp_processor_id(); - - init_gdt(cpu); - switch_to_new_gdt(); - - cpu_set(cpu, cpu_online_map); - cpu_set(cpu, cpu_callout_map); - cpu_set(cpu, cpu_present_map); - cpu_set(cpu, cpu_possible_map); - __get_cpu_var(cpu_state) = CPU_ONLINE; + cpu_set(smp_processor_id(), cpu_online_map); + cpu_set(smp_processor_id(), cpu_callout_map); + cpu_set(smp_processor_id(), cpu_present_map); + cpu_set(smp_processor_id(), cpu_possible_map); + per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; } #ifdef CONFIG_HOTPLUG_CPU @@ -1265,7 +1277,7 @@ void __cpu_die(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -int __cpuinit native_cpu_up(unsigned int cpu) +int __cpuinit __cpu_up(unsigned int cpu) { unsigned long flags; #ifdef CONFIG_HOTPLUG_CPU @@ -1307,10 +1319,15 @@ int __cpuinit native_cpu_up(unsigned int cpu) touch_nmi_watchdog(); } +#ifdef CONFIG_X86_GENERICARCH + if (num_online_cpus() > 8 && genapic == &apic_default) + panic("Default flat APIC routing can't be used with > 8 cpus\n"); +#endif + return 0; } -void __init native_smp_cpus_done(unsigned int max_cpus) +void __init smp_cpus_done(unsigned int max_cpus) { #ifdef CONFIG_X86_IO_APIC setup_ioapic_dest(); diff --git a/trunk/arch/i386/kernel/sys_i386.c b/trunk/arch/i386/kernel/sys_i386.c index e5dcb9379018..4048397f1740 100644 --- a/trunk/arch/i386/kernel/sys_i386.c +++ b/trunk/arch/i386/kernel/sys_i386.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/i386/kernel/syscall_table.S b/trunk/arch/i386/kernel/syscall_table.S index 0772678ceecf..2697e9210e92 100644 --- a/trunk/arch/i386/kernel/syscall_table.S +++ b/trunk/arch/i386/kernel/syscall_table.S @@ -319,4 +319,3 @@ ENTRY(sys_call_table) .long sys_move_pages .long sys_getcpu .long sys_epoll_pwait - .long sys_utimensat /* 320 */ diff --git a/trunk/arch/i386/kernel/sysenter.c b/trunk/arch/i386/kernel/sysenter.c index ff4ee6f3326b..13ca54a85a1c 100644 --- a/trunk/arch/i386/kernel/sysenter.c +++ b/trunk/arch/i386/kernel/sysenter.c @@ -22,26 +22,16 @@ #include #include #include -#include -#include - -enum { - VDSO_DISABLED = 0, - VDSO_ENABLED = 1, - VDSO_COMPAT = 2, -}; - -#ifdef CONFIG_COMPAT_VDSO -#define VDSO_DEFAULT VDSO_COMPAT -#else -#define VDSO_DEFAULT VDSO_ENABLED -#endif /* * Should the kernel map a VDSO page into processes and pass its * address down to glibc upon exec()? */ -unsigned int __read_mostly vdso_enabled = VDSO_DEFAULT; +#ifdef CONFIG_PARAVIRT +unsigned int __read_mostly vdso_enabled = 0; +#else +unsigned int __read_mostly vdso_enabled = 1; +#endif EXPORT_SYMBOL_GPL(vdso_enabled); @@ -56,123 +46,6 @@ __setup("vdso=", vdso_setup); extern asmlinkage void sysenter_entry(void); -static __init void reloc_symtab(Elf32_Ehdr *ehdr, - unsigned offset, unsigned size) -{ - Elf32_Sym *sym = (void *)ehdr + offset; - unsigned nsym = size / sizeof(*sym); - unsigned i; - - for(i = 0; i < nsym; i++, sym++) { - if (sym->st_shndx == SHN_UNDEF || - sym->st_shndx == SHN_ABS) - continue; /* skip */ - - if (sym->st_shndx > SHN_LORESERVE) { - printk(KERN_INFO "VDSO: unexpected st_shndx %x\n", - sym->st_shndx); - continue; - } - - switch(ELF_ST_TYPE(sym->st_info)) { - case STT_OBJECT: - case STT_FUNC: - case STT_SECTION: - case STT_FILE: - sym->st_value += VDSO_HIGH_BASE; - } - } -} - -static __init void reloc_dyn(Elf32_Ehdr *ehdr, unsigned offset) -{ - Elf32_Dyn *dyn = (void *)ehdr + offset; - - for(; dyn->d_tag != DT_NULL; dyn++) - switch(dyn->d_tag) { - case DT_PLTGOT: - case DT_HASH: - case DT_STRTAB: - case DT_SYMTAB: - case DT_RELA: - case DT_INIT: - case DT_FINI: - case DT_REL: - case DT_DEBUG: - case DT_JMPREL: - case DT_VERSYM: - case DT_VERDEF: - case DT_VERNEED: - case DT_ADDRRNGLO ... DT_ADDRRNGHI: - /* definitely pointers needing relocation */ - dyn->d_un.d_ptr += VDSO_HIGH_BASE; - break; - - case DT_ENCODING ... OLD_DT_LOOS-1: - case DT_LOOS ... DT_HIOS-1: - /* Tags above DT_ENCODING are pointers if - they're even */ - if (dyn->d_tag >= DT_ENCODING && - (dyn->d_tag & 1) == 0) - dyn->d_un.d_ptr += VDSO_HIGH_BASE; - break; - - case DT_VERDEFNUM: - case DT_VERNEEDNUM: - case DT_FLAGS_1: - case DT_RELACOUNT: - case DT_RELCOUNT: - case DT_VALRNGLO ... DT_VALRNGHI: - /* definitely not pointers */ - break; - - case OLD_DT_LOOS ... DT_LOOS-1: - case DT_HIOS ... DT_VALRNGLO-1: - default: - if (dyn->d_tag > DT_ENCODING) - printk(KERN_INFO "VDSO: unexpected DT_tag %x\n", - dyn->d_tag); - break; - } -} - -static __init void relocate_vdso(Elf32_Ehdr *ehdr) -{ - Elf32_Phdr *phdr; - Elf32_Shdr *shdr; - int i; - - BUG_ON(memcmp(ehdr->e_ident, ELFMAG, 4) != 0 || - !elf_check_arch(ehdr) || - ehdr->e_type != ET_DYN); - - ehdr->e_entry += VDSO_HIGH_BASE; - - /* rebase phdrs */ - phdr = (void *)ehdr + ehdr->e_phoff; - for (i = 0; i < ehdr->e_phnum; i++) { - phdr[i].p_vaddr += VDSO_HIGH_BASE; - - /* relocate dynamic stuff */ - if (phdr[i].p_type == PT_DYNAMIC) - reloc_dyn(ehdr, phdr[i].p_offset); - } - - /* rebase sections */ - shdr = (void *)ehdr + ehdr->e_shoff; - for(i = 0; i < ehdr->e_shnum; i++) { - if (!(shdr[i].sh_flags & SHF_ALLOC)) - continue; - - shdr[i].sh_addr += VDSO_HIGH_BASE; - - if (shdr[i].sh_type == SHT_SYMTAB || - shdr[i].sh_type == SHT_DYNSYM) - reloc_symtab(ehdr, shdr[i].sh_offset, - shdr[i].sh_size); - } -} - void enable_sep_cpu(void) { int cpu = get_cpu(); @@ -183,33 +56,14 @@ void enable_sep_cpu(void) return; } - tss->x86_tss.ss1 = __KERNEL_CS; - tss->x86_tss.esp1 = sizeof(struct tss_struct) + (unsigned long) tss; + tss->ss1 = __KERNEL_CS; + tss->esp1 = sizeof(struct tss_struct) + (unsigned long) tss; wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0); - wrmsr(MSR_IA32_SYSENTER_ESP, tss->x86_tss.esp1, 0); + wrmsr(MSR_IA32_SYSENTER_ESP, tss->esp1, 0); wrmsr(MSR_IA32_SYSENTER_EIP, (unsigned long) sysenter_entry, 0); put_cpu(); } -static struct vm_area_struct gate_vma; - -static int __init gate_vma_init(void) -{ - gate_vma.vm_mm = NULL; - gate_vma.vm_start = FIXADDR_USER_START; - gate_vma.vm_end = FIXADDR_USER_END; - gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; - gate_vma.vm_page_prot = __P101; - /* - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully interpretable later - * without matching up the same kernel and hardware config to see - * what PC values meant. - */ - gate_vma.vm_flags |= VM_ALWAYSDUMP; - return 0; -} - /* * These symbols are defined by vsyscall.o to mark the bounds * of the ELF DSO images included therein. @@ -218,48 +72,31 @@ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; static struct page *syscall_pages[1]; -static void map_compat_vdso(int map) -{ - static int vdso_mapped; - - if (map == vdso_mapped) - return; - - vdso_mapped = map; - - __set_fixmap(FIX_VDSO, page_to_pfn(syscall_pages[0]) << PAGE_SHIFT, - map ? PAGE_READONLY_EXEC : PAGE_NONE); - - /* flush stray tlbs */ - flush_tlb_all(); -} - int __init sysenter_setup(void) { void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); - const void *vsyscall; - size_t vsyscall_len; - syscall_pages[0] = virt_to_page(syscall_page); - gate_vma_init(); - +#ifdef CONFIG_COMPAT_VDSO + __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY_EXEC); printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); +#endif if (!boot_cpu_has(X86_FEATURE_SEP)) { - vsyscall = &vsyscall_int80_start; - vsyscall_len = &vsyscall_int80_end - &vsyscall_int80_start; - } else { - vsyscall = &vsyscall_sysenter_start; - vsyscall_len = &vsyscall_sysenter_end - &vsyscall_sysenter_start; + memcpy(syscall_page, + &vsyscall_int80_start, + &vsyscall_int80_end - &vsyscall_int80_start); + return 0; } - memcpy(syscall_page, vsyscall, vsyscall_len); - relocate_vdso(syscall_page); + memcpy(syscall_page, + &vsyscall_sysenter_start, + &vsyscall_sysenter_end - &vsyscall_sysenter_start); return 0; } +#ifndef CONFIG_COMPAT_VDSO /* Defined in vsyscall-sysenter.S */ extern void SYSENTER_RETURN; @@ -268,52 +105,36 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) { struct mm_struct *mm = current->mm; unsigned long addr; - int ret = 0; - bool compat; + int ret; down_write(&mm->mmap_sem); - - /* Test compat mode once here, in case someone - changes it via sysctl */ - compat = (vdso_enabled == VDSO_COMPAT); - - map_compat_vdso(compat); - - if (compat) - addr = VDSO_HIGH_BASE; - else { - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); - if (IS_ERR_VALUE(addr)) { - ret = addr; - goto up_fail; - } - - /* - * MAYWRITE to allow gdb to COW and set breakpoints - * - * Make sure the vDSO gets into every core dump. - * Dumping its contents makes post-mortem fully - * interpretable later without matching up the same - * kernel and hardware config to see what PC values - * meant. - */ - ret = install_special_mapping(mm, addr, PAGE_SIZE, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| - VM_ALWAYSDUMP, - syscall_pages); - - if (ret) - goto up_fail; + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); + if (IS_ERR_VALUE(addr)) { + ret = addr; + goto up_fail; } + /* + * MAYWRITE to allow gdb to COW and set breakpoints + * + * Make sure the vDSO gets into every core dump. + * Dumping its contents makes post-mortem fully interpretable later + * without matching up the same kernel and hardware config to see + * what PC values meant. + */ + ret = install_special_mapping(mm, addr, PAGE_SIZE, + VM_READ|VM_EXEC| + VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC| + VM_ALWAYSDUMP, + syscall_pages); + if (ret) + goto up_fail; + current->mm->context.vdso = (void *)addr; current_thread_info()->sysenter_return = - (void *)VDSO_SYM(&SYSENTER_RETURN); - - up_fail: + (void *)VDSO_SYM(&SYSENTER_RETURN); +up_fail: up_write(&mm->mmap_sem); - return ret; } @@ -326,11 +147,6 @@ const char *arch_vma_name(struct vm_area_struct *vma) struct vm_area_struct *get_gate_vma(struct task_struct *tsk) { - struct mm_struct *mm = tsk->mm; - - /* Check to see if this task was created in compat vdso mode */ - if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE) - return &gate_vma; return NULL; } @@ -343,3 +159,4 @@ int in_gate_area_no_task(unsigned long addr) { return 0; } +#endif diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index a665df61f08c..94e5cb091104 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -70,6 +70,8 @@ #include +int pit_latch_buggy; /* extern */ + #include "do_timer.h" unsigned int cpu_khz; /* Detected as we calibrate the TSC */ diff --git a/trunk/arch/i386/kernel/trampoline.S b/trunk/arch/i386/kernel/trampoline.S index f62815f8d06a..2f1814c5cfd7 100644 --- a/trunk/arch/i386/kernel/trampoline.S +++ b/trunk/arch/i386/kernel/trampoline.S @@ -29,7 +29,7 @@ * * TYPE VALUE * R_386_32 startup_32_smp - * R_386_32 boot_gdt + * R_386_32 boot_gdt_table */ #include @@ -62,8 +62,8 @@ r_base = . * to 32 bit. */ - lidtl boot_idt_descr - r_base # load idt with 0, 0 - lgdtl boot_gdt_descr - r_base # load gdt with whatever is appropriate + lidtl boot_idt - r_base # load idt with 0, 0 + lgdtl boot_gdt - r_base # load gdt with whatever is appropriate xor %ax, %ax inc %ax # protected mode (PE) bit @@ -73,11 +73,11 @@ r_base = . # These need to be in the same 64K segment as the above; # hence we don't use the boot_gdt_descr defined in head.S -boot_gdt_descr: +boot_gdt: .word __BOOT_DS + 7 # gdt limit - .long boot_gdt - __PAGE_OFFSET # gdt base + .long boot_gdt_table-__PAGE_OFFSET # gdt base -boot_idt_descr: +boot_idt: .word 0 # idt limit = 0 .long 0 # idt base = 0L diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 4bec0cbf407a..af0d3f70a817 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -52,7 +52,7 @@ #include #include #include -#include +#include #include #include @@ -95,6 +95,20 @@ asmlinkage void machine_check(void); int kstack_depth_to_print = 24; static unsigned int code_bytes = 64; +ATOMIC_NOTIFIER_HEAD(i386die_chain); + +int register_die_notifier(struct notifier_block *nb) +{ + vmalloc_sync_all(); + return atomic_notifier_chain_register(&i386die_chain, nb); +} +EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */ + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&i386die_chain, nb); +} +EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) { @@ -462,6 +476,8 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, siginfo_t *info) { struct task_struct *tsk = current; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; if (regs->eflags & VM_MASK) { if (vm86) @@ -473,18 +489,6 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, goto kernel_trap; trap_signal: { - /* - * We want error_code and trap_no set for userspace faults and - * kernelspace faults which result in die(), but not - * kernelspace faults which are fixed up. die() gives the - * process no chance to handle the signal and notice the - * kernel fault information, so that won't result in polluting - * the information about previously queued, but not yet - * delivered, faults. See also do_general_protection below. - */ - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; - if (info) force_sig_info(signr, info, tsk); else @@ -493,11 +497,8 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86, } kernel_trap: { - if (!fixup_exception(regs)) { - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; + if (!fixup_exception(regs)) die(str, regs, error_code); - } return; } @@ -582,7 +583,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, * and we set the offset field correctly. Then we let the CPU to * restart the faulting instruction. */ - if (tss->x86_tss.io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && + if (tss->io_bitmap_base == INVALID_IO_BITMAP_OFFSET_LAZY && thread->io_bitmap_ptr) { memcpy(tss->io_bitmap, thread->io_bitmap_ptr, thread->io_bitmap_max); @@ -595,13 +596,16 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, thread->io_bitmap_max, 0xff, tss->io_bitmap_max - thread->io_bitmap_max); tss->io_bitmap_max = thread->io_bitmap_max; - tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET; + tss->io_bitmap_base = IO_BITMAP_OFFSET; tss->io_bitmap_owner = thread; put_cpu(); return; } put_cpu(); + current->thread.error_code = error_code; + current->thread.trap_no = 13; + if (regs->eflags & VM_MASK) goto gp_in_vm86; @@ -620,8 +624,6 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, gp_in_kernel: if (!fixup_exception(regs)) { - current->thread.error_code = error_code; - current->thread.trap_no = 13; if (notify_die(DIE_GPF, "general protection fault", regs, error_code, 13, SIGSEGV) == NOTIFY_STOP) return; @@ -733,11 +735,6 @@ static __kprobes void default_do_nmi(struct pt_regs * regs) */ if (nmi_watchdog_tick(regs, reason)) return; -#endif - if (notify_die(DIE_NMI_POST, "nmi_post", regs, reason, 2, 0) - == NOTIFY_STOP) - return; -#ifdef CONFIG_X86_LOCAL_APIC if (!do_nmi_callback(regs, smp_processor_id())) #endif unknown_nmi_error(reason, regs); @@ -1021,7 +1018,9 @@ fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, fastcall unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp) { - struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt; + int cpu = smp_processor_id(); + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address; unsigned long base = (kesp - uesp) & -THREAD_SIZE; unsigned long new_kesp = kesp - base; unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; diff --git a/trunk/arch/i386/kernel/tsc.c b/trunk/arch/i386/kernel/tsc.c index f64b81f3033b..6cb8f5336732 100644 --- a/trunk/arch/i386/kernel/tsc.c +++ b/trunk/arch/i386/kernel/tsc.c @@ -200,10 +200,13 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_freqs *freq = data; + if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) + write_seqlock_irq(&xtime_lock); + if (!ref_freq) { if (!freq->old){ ref_freq = freq->new; - return 0; + goto end; } ref_freq = freq->old; loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy; @@ -230,10 +233,13 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) * TSC based sched_clock turns * to junk w/ cpufreq */ - mark_tsc_unstable("cpufreq changes"); + mark_tsc_unstable(); } } } +end: + if (val != CPUFREQ_RESUMECHANGE && val != CPUFREQ_SUSPENDCHANGE) + write_sequnlock_irq(&xtime_lock); return 0; } @@ -275,12 +281,11 @@ static struct clocksource clocksource_tsc = { CLOCK_SOURCE_MUST_VERIFY, }; -void mark_tsc_unstable(char *reason) +void mark_tsc_unstable(void) { if (!tsc_unstable) { tsc_unstable = 1; tsc_enabled = 0; - printk("Marking TSC unstable due to: %s.\n", reason); /* Can be called before registration */ if (clocksource_tsc.mult) clocksource_change_rating(&clocksource_tsc, 0); diff --git a/trunk/arch/i386/kernel/verify_cpu.S b/trunk/arch/i386/kernel/verify_cpu.S deleted file mode 100644 index e51a8695d54e..000000000000 --- a/trunk/arch/i386/kernel/verify_cpu.S +++ /dev/null @@ -1,65 +0,0 @@ -/* Check if CPU has some minimum CPUID bits - This runs in 16bit mode so that the caller can still use the BIOS - to output errors on the screen */ -#include - -verify_cpu: - pushfl # Save caller passed flags - pushl $0 # Kill any dangerous flags - popfl - -#if CONFIG_X86_MINIMUM_CPU_MODEL >= 4 - pushfl - orl $(1<<18),(%esp) # try setting AC - popfl - pushfl - popl %eax - testl $(1<<18),%eax - jz bad -#endif -#if REQUIRED_MASK1 != 0 - pushfl # standard way to check for cpuid - popl %eax - movl %eax,%ebx - xorl $0x200000,%eax - pushl %eax - popfl - pushfl - popl %eax - cmpl %eax,%ebx - pushfl # standard way to check for cpuid - popl %eax - movl %eax,%ebx - xorl $0x200000,%eax - pushl %eax - popfl - pushfl - popl %eax - cmpl %eax,%ebx - jz bad # REQUIRED_MASK1 != 0 requires CPUID - - movl $0x0,%eax # See if cpuid 1 is implemented - cpuid - cmpl $0x1,%eax - jb bad # no cpuid 1 - - movl $0x1,%eax # Does the cpu have what it takes - cpuid - -#if CONFIG_X86_MINIMUM_CPU_MODEL > 4 -#error add proper model checking here -#endif - - andl $REQUIRED_MASK1,%edx - xorl $REQUIRED_MASK1,%edx - jnz bad -#endif /* REQUIRED_MASK1 */ - - popfl - xor %eax,%eax - ret - -bad: - popfl - movl $1,%eax - ret diff --git a/trunk/arch/i386/kernel/vm86.c b/trunk/arch/i386/kernel/vm86.c index f2dcd1d27c0a..d1b8f2b7aea6 100644 --- a/trunk/arch/i386/kernel/vm86.c +++ b/trunk/arch/i386/kernel/vm86.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/i386/kernel/vmi.c b/trunk/arch/i386/kernel/vmi.c index c8726c424b35..697a70e8c0c9 100644 --- a/trunk/arch/i386/kernel/vmi.c +++ b/trunk/arch/i386/kernel/vmi.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -57,7 +56,7 @@ static int disable_noidle; static int disable_vmi_timer; /* Cached VMI operations */ -static struct { +struct { void (*cpuid)(void /* non-c */); void (*_set_ldt)(u32 selector); void (*set_tr)(u32 selector); @@ -66,15 +65,16 @@ static struct { void (*release_page)(u32, u32); void (*set_pte)(pte_t, pte_t *, unsigned); void (*update_pte)(pte_t *, unsigned); - void (*set_linear_mapping)(int, void *, u32, u32); - void (*_flush_tlb)(int); + void (*set_linear_mapping)(int, u32, u32, u32); + void (*flush_tlb)(int); void (*set_initial_ap_state)(int, int); void (*halt)(void); void (*set_lazy_mode)(int mode); } vmi_ops; -/* Cached VMI operations */ -struct vmi_timer_ops vmi_timer_ops; +/* XXX move this to alternative.h */ +extern struct paravirt_patch __start_parainstructions[], + __stop_parainstructions[]; /* * VMI patching routines. @@ -83,6 +83,11 @@ struct vmi_timer_ops vmi_timer_ops; #define MNEM_JMP 0xe9 #define MNEM_RET 0xc3 +static char irq_save_disable_callout[] = { + MNEM_CALL, 0, 0, 0, 0, + MNEM_CALL, 0, 0, 0, 0, + MNEM_RET +}; #define IRQ_PATCH_INT_MASK 0 #define IRQ_PATCH_DISABLE 5 @@ -130,17 +135,33 @@ static unsigned patch_internal(int call, unsigned len, void *insns) static unsigned vmi_patch(u8 type, u16 clobbers, void *insns, unsigned len) { switch (type) { - case PARAVIRT_PATCH(irq_disable): + case PARAVIRT_IRQ_DISABLE: return patch_internal(VMI_CALL_DisableInterrupts, len, insns); - case PARAVIRT_PATCH(irq_enable): + case PARAVIRT_IRQ_ENABLE: return patch_internal(VMI_CALL_EnableInterrupts, len, insns); - case PARAVIRT_PATCH(restore_fl): + case PARAVIRT_RESTORE_FLAGS: return patch_internal(VMI_CALL_SetInterruptMask, len, insns); - case PARAVIRT_PATCH(save_fl): + case PARAVIRT_SAVE_FLAGS: return patch_internal(VMI_CALL_GetInterruptMask, len, insns); - case PARAVIRT_PATCH(iret): + case PARAVIRT_SAVE_FLAGS_IRQ_DISABLE: + if (len >= 10) { + patch_internal(VMI_CALL_GetInterruptMask, len, insns); + patch_internal(VMI_CALL_DisableInterrupts, len-5, insns+5); + return 10; + } else { + /* + * You bastards didn't leave enough room to + * patch save_flags_irq_disable inline. Patch + * to a helper + */ + BUG_ON(len < 5); + *(char *)insns = MNEM_CALL; + patch_offset(insns, irq_save_disable_callout); + return 5; + } + case PARAVIRT_INTERRUPT_RETURN: return patch_internal(VMI_CALL_IRET, len, insns); - case PARAVIRT_PATCH(irq_enable_sysexit): + case PARAVIRT_STI_SYSEXIT: return patch_internal(VMI_CALL_SYSEXIT, len, insns); default: break; @@ -209,24 +230,24 @@ static void vmi_set_tr(void) static void vmi_load_esp0(struct tss_struct *tss, struct thread_struct *thread) { - tss->x86_tss.esp0 = thread->esp0; + tss->esp0 = thread->esp0; /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->x86_tss.ss1 != thread->sysenter_cs)) { - tss->x86_tss.ss1 = thread->sysenter_cs; + if (unlikely(tss->ss1 != thread->sysenter_cs)) { + tss->ss1 = thread->sysenter_cs; wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); } - vmi_ops.set_kernel_stack(__KERNEL_DS, tss->x86_tss.esp0); + vmi_ops.set_kernel_stack(__KERNEL_DS, tss->esp0); } static void vmi_flush_tlb_user(void) { - vmi_ops._flush_tlb(VMI_FLUSH_TLB); + vmi_ops.flush_tlb(VMI_FLUSH_TLB); } static void vmi_flush_tlb_kernel(void) { - vmi_ops._flush_tlb(VMI_FLUSH_TLB | VMI_FLUSH_GLOBAL); + vmi_ops.flush_tlb(VMI_FLUSH_TLB | VMI_FLUSH_GLOBAL); } /* Stub to do nothing at all; used for delays and unimplemented calls */ @@ -234,6 +255,18 @@ static void vmi_nop(void) { } +/* For NO_IDLE_HZ, we stop the clock when halting the kernel */ +static fastcall void vmi_safe_halt(void) +{ + int idle = vmi_stop_hz_timer(); + vmi_ops.halt(); + if (idle) { + local_irq_disable(); + vmi_account_time_restart_hz_timer(); + local_irq_enable(); + } +} + #ifdef CONFIG_DEBUG_PAGE_TYPE #ifdef CONFIG_X86_PAE @@ -337,11 +370,8 @@ static void vmi_check_page_type(u32 pfn, int type) #define vmi_check_page_type(p,t) do { } while (0) #endif -#ifdef CONFIG_HIGHPTE -static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type) +static void vmi_map_pt_hook(int type, pte_t *va, u32 pfn) { - void *va = kmap_atomic(page, type); - /* * Internally, the VMI ROM must map virtual addresses to physical * addresses for processing MMU updates. By the time MMU updates @@ -355,11 +385,8 @@ static void *vmi_kmap_atomic_pte(struct page *page, enum km_type type) * args: SLOT VA COUNT PFN */ BUG_ON(type != KM_PTE0 && type != KM_PTE1); - vmi_ops.set_linear_mapping((type - KM_PTE0)+1, va, 1, page_to_pfn(page)); - - return va; + vmi_ops.set_linear_mapping((type - KM_PTE0)+1, (u32)va, 1, pfn); } -#endif static void vmi_allocate_pt(u32 pfn) { @@ -416,13 +443,13 @@ static void vmi_release_pd(u32 pfn) ((level) | (is_current_as(mm, user) ? \ (VMI_PAGE_DEFER | VMI_PAGE_CURRENT_AS | ((addr) & VMI_PAGE_VA_MASK)) : 0)) -static void vmi_update_pte(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +static void vmi_update_pte(struct mm_struct *mm, u32 addr, pte_t *ptep) { vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); vmi_ops.update_pte(ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); } -static void vmi_update_pte_defer(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +static void vmi_update_pte_defer(struct mm_struct *mm, u32 addr, pte_t *ptep) { vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); vmi_ops.update_pte(ptep, vmi_flags_addr_defer(mm, addr, VMI_PAGE_PT, 0)); @@ -435,7 +462,7 @@ static void vmi_set_pte(pte_t *ptep, pte_t pte) vmi_ops.set_pte(pte, ptep, VMI_PAGE_PT); } -static void vmi_set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) +static void vmi_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte) { vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); @@ -489,7 +516,7 @@ static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); } -static void vmi_pmd_clear(pmd_t *pmd) +void vmi_pmd_clear(pmd_t *pmd) { const pte_t pte = { 0 }; vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD); @@ -498,6 +525,8 @@ static void vmi_pmd_clear(pmd_t *pmd) #endif #ifdef CONFIG_SMP +extern void setup_pda(void); + static void __devinit vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, unsigned long start_esp) @@ -522,11 +551,13 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, ap.ds = __USER_DS; ap.es = __USER_DS; - ap.fs = __KERNEL_PERCPU; + ap.fs = __KERNEL_PDA; ap.gs = 0; ap.eflags = 0; + setup_pda(); + #ifdef CONFIG_X86_PAE /* efer should match BSP efer. */ if (cpu_has_nx) { @@ -544,9 +575,9 @@ vmi_startup_ipi_hook(int phys_apicid, unsigned long start_eip, } #endif -static void vmi_set_lazy_mode(enum paravirt_lazy_mode mode) +static void vmi_set_lazy_mode(int mode) { - static DEFINE_PER_CPU(enum paravirt_lazy_mode, lazy_mode); + static DEFINE_PER_CPU(int, lazy_mode); if (!vmi_ops.set_lazy_mode) return; @@ -654,7 +685,7 @@ void vmi_bringup(void) { /* We must establish the lowmem mapping for MMU ops to work */ if (vmi_ops.set_linear_mapping) - vmi_ops.set_linear_mapping(0, (void *)__PAGE_OFFSET, max_low_pfn, 0); + vmi_ops.set_linear_mapping(0, __PAGE_OFFSET, max_low_pfn, 0); } /* @@ -709,6 +740,7 @@ do { \ } \ } while (0) + /* * Activate the VMI interface and switch into paravirtualized mode */ @@ -764,6 +796,12 @@ static inline int __init activate_vmi(void) para_fill(irq_disable, DisableInterrupts); para_fill(irq_enable, EnableInterrupts); + /* irq_save_disable !!! sheer pain */ + patch_offset(&irq_save_disable_callout[IRQ_PATCH_INT_MASK], + (char *)paravirt_ops.save_fl); + patch_offset(&irq_save_disable_callout[IRQ_PATCH_DISABLE], + (char *)paravirt_ops.irq_disable); + para_fill(wbinvd, WBINVD); para_fill(read_tsc, RDTSC); @@ -793,8 +831,8 @@ static inline int __init activate_vmi(void) para_wrap(set_lazy_mode, vmi_set_lazy_mode, set_lazy_mode, SetLazyMode); /* user and kernel flush are just handled with different flags to FlushTLB */ - para_wrap(flush_tlb_user, vmi_flush_tlb_user, _flush_tlb, FlushTLB); - para_wrap(flush_tlb_kernel, vmi_flush_tlb_kernel, _flush_tlb, FlushTLB); + para_wrap(flush_tlb_user, vmi_flush_tlb_user, flush_tlb, FlushTLB); + para_wrap(flush_tlb_kernel, vmi_flush_tlb_kernel, flush_tlb, FlushTLB); para_fill(flush_tlb_single, InvalPage); /* @@ -840,13 +878,8 @@ static inline int __init activate_vmi(void) paravirt_ops.release_pt = vmi_release_pt; paravirt_ops.release_pd = vmi_release_pd; } - - /* Set linear is needed in all cases */ - vmi_ops.set_linear_mapping = vmi_get_function(VMI_CALL_SetLinearMapping); -#ifdef CONFIG_HIGHPTE - if (vmi_ops.set_linear_mapping) - paravirt_ops.kmap_atomic_pte = vmi_kmap_atomic_pte; -#endif + para_wrap(map_pt_hook, vmi_map_pt_hook, set_linear_mapping, + SetLinearMapping); /* * These MUST always be patched. Don't support indirect jumps @@ -887,8 +920,8 @@ static inline int __init activate_vmi(void) paravirt_ops.get_wallclock = vmi_get_wallclock; paravirt_ops.set_wallclock = vmi_set_wallclock; #ifdef CONFIG_X86_LOCAL_APIC - paravirt_ops.setup_boot_clock = vmi_time_bsp_init; - paravirt_ops.setup_secondary_clock = vmi_time_ap_init; + paravirt_ops.setup_boot_clock = vmi_timer_setup_boot_alarm; + paravirt_ops.setup_secondary_clock = vmi_timer_setup_secondary_alarm; #endif paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles; paravirt_ops.get_cpu_khz = vmi_cpu_khz; @@ -900,7 +933,11 @@ static inline int __init activate_vmi(void) disable_vmi_timer = 1; } - para_fill(safe_halt, Halt); + /* No idle HZ mode only works if VMI timer and no idle is enabled */ + if (disable_noidle || disable_vmi_timer) + para_fill(safe_halt, Halt); + else + para_wrap(safe_halt, vmi_safe_halt, halt, Halt); /* * Alternative instruction rewriting doesn't happen soon enough @@ -908,7 +945,7 @@ static inline int __init activate_vmi(void) * to do this before IRQs get reenabled. Fortunately, it is * idempotent. */ - apply_paravirt(__parainstructions, __parainstructions_end); + apply_paravirt(__start_parainstructions, __stop_parainstructions); vmi_bringup(); diff --git a/trunk/arch/i386/kernel/vmiclock.c b/trunk/arch/i386/kernel/vmiclock.c deleted file mode 100644 index 26a37f8a8762..000000000000 --- a/trunk/arch/i386/kernel/vmiclock.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * VMI paravirtual timer support routines. - * - * Copyright (C) 2007, VMware, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include "io_ports.h" - -#define VMI_ONESHOT (VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL | vmi_get_alarm_wiring()) -#define VMI_PERIODIC (VMI_ALARM_IS_PERIODIC | VMI_CYCLES_REAL | vmi_get_alarm_wiring()) - -static DEFINE_PER_CPU(struct clock_event_device, local_events); - -static inline u32 vmi_counter(u32 flags) -{ - /* Given VMI_ONESHOT or VMI_PERIODIC, return the corresponding - * cycle counter. */ - return flags & VMI_ALARM_COUNTER_MASK; -} - -/* paravirt_ops.get_wallclock = vmi_get_wallclock */ -unsigned long vmi_get_wallclock(void) -{ - unsigned long long wallclock; - wallclock = vmi_timer_ops.get_wallclock(); // nsec - (void)do_div(wallclock, 1000000000); // sec - - return wallclock; -} - -/* paravirt_ops.set_wallclock = vmi_set_wallclock */ -int vmi_set_wallclock(unsigned long now) -{ - return 0; -} - -/* paravirt_ops.get_scheduled_cycles = vmi_get_sched_cycles */ -unsigned long long vmi_get_sched_cycles(void) -{ - return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE); -} - -/* paravirt_ops.get_cpu_khz = vmi_cpu_khz */ -unsigned long vmi_cpu_khz(void) -{ - unsigned long long khz; - khz = vmi_timer_ops.get_cycle_frequency(); - (void)do_div(khz, 1000); - return khz; -} - -static inline unsigned int vmi_get_timer_vector(void) -{ -#ifdef CONFIG_X86_IO_APIC - return FIRST_DEVICE_VECTOR; -#else - return FIRST_EXTERNAL_VECTOR; -#endif -} - -/** vmi clockchip */ -#ifdef CONFIG_X86_LOCAL_APIC -static unsigned int startup_timer_irq(unsigned int irq) -{ - unsigned long val = apic_read(APIC_LVTT); - apic_write(APIC_LVTT, vmi_get_timer_vector()); - - return (val & APIC_SEND_PENDING); -} - -static void mask_timer_irq(unsigned int irq) -{ - unsigned long val = apic_read(APIC_LVTT); - apic_write(APIC_LVTT, val | APIC_LVT_MASKED); -} - -static void unmask_timer_irq(unsigned int irq) -{ - unsigned long val = apic_read(APIC_LVTT); - apic_write(APIC_LVTT, val & ~APIC_LVT_MASKED); -} - -static void ack_timer_irq(unsigned int irq) -{ - ack_APIC_irq(); -} - -static struct irq_chip vmi_chip __read_mostly = { - .name = "VMI-LOCAL", - .startup = startup_timer_irq, - .mask = mask_timer_irq, - .unmask = unmask_timer_irq, - .ack = ack_timer_irq -}; -#endif - -/** vmi clockevent */ -#define VMI_ALARM_WIRED_IRQ0 0x00000000 -#define VMI_ALARM_WIRED_LVTT 0x00010000 -static int vmi_wiring = VMI_ALARM_WIRED_IRQ0; - -static inline int vmi_get_alarm_wiring(void) -{ - return vmi_wiring; -} - -static void vmi_timer_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - cycle_t now, cycles_per_hz; - BUG_ON(!irqs_disabled()); - - switch (mode) { - case CLOCK_EVT_MODE_ONESHOT: - break; - case CLOCK_EVT_MODE_PERIODIC: - cycles_per_hz = vmi_timer_ops.get_cycle_frequency(); - (void)do_div(cycles_per_hz, HZ); - now = vmi_timer_ops.get_cycle_counter(vmi_counter(VMI_PERIODIC)); - vmi_timer_ops.set_alarm(VMI_PERIODIC, now, cycles_per_hz); - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - switch (evt->mode) { - case CLOCK_EVT_MODE_ONESHOT: - vmi_timer_ops.cancel_alarm(VMI_ONESHOT); - break; - case CLOCK_EVT_MODE_PERIODIC: - vmi_timer_ops.cancel_alarm(VMI_PERIODIC); - break; - default: - break; - } - break; - default: - break; - } -} - -static int vmi_timer_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - /* Unfortunately, set_next_event interface only passes relative - * expiry, but we want absolute expiry. It'd be better if were - * were passed an aboslute expiry, since a bunch of time may - * have been stolen between the time the delta is computed and - * when we set the alarm below. */ - cycle_t now = vmi_timer_ops.get_cycle_counter(vmi_counter(VMI_ONESHOT)); - - BUG_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT); - vmi_timer_ops.set_alarm(VMI_ONESHOT, now + delta, 0); - return 0; -} - -static struct clock_event_device vmi_clockevent = { - .name = "vmi-timer", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .shift = 22, - .set_mode = vmi_timer_set_mode, - .set_next_event = vmi_timer_next_event, - .rating = 1000, - .irq = 0, -}; - -static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &__get_cpu_var(local_events); - evt->event_handler(evt); - return IRQ_HANDLED; -} - -static struct irqaction vmi_clock_action = { - .name = "vmi-timer", - .handler = vmi_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING, - .mask = CPU_MASK_ALL, -}; - -static void __devinit vmi_time_init_clockevent(void) -{ - cycle_t cycles_per_msec; - struct clock_event_device *evt; - - int cpu = smp_processor_id(); - evt = &__get_cpu_var(local_events); - - /* Use cycles_per_msec since div_sc params are 32-bits. */ - cycles_per_msec = vmi_timer_ops.get_cycle_frequency(); - (void)do_div(cycles_per_msec, 1000); - - memcpy(evt, &vmi_clockevent, sizeof(*evt)); - /* Must pick .shift such that .mult fits in 32-bits. Choosing - * .shift to be 22 allows 2^(32-22) cycles per nano-seconds - * before overflow. */ - evt->mult = div_sc(cycles_per_msec, NSEC_PER_MSEC, evt->shift); - /* Upper bound is clockevent's use of ulong for cycle deltas. */ - evt->max_delta_ns = clockevent_delta2ns(ULONG_MAX, evt); - evt->min_delta_ns = clockevent_delta2ns(1, evt); - evt->cpumask = cpumask_of_cpu(cpu); - - printk(KERN_WARNING "vmi: registering clock event %s. mult=%lu shift=%u\n", - evt->name, evt->mult, evt->shift); - clockevents_register_device(evt); -} - -void __init vmi_time_init(void) -{ - /* Disable PIT: BIOSes start PIT CH0 with 18.2hz peridic. */ - outb_p(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */ - - vmi_time_init_clockevent(); - setup_irq(0, &vmi_clock_action); -} - -#ifdef CONFIG_X86_LOCAL_APIC -void __devinit vmi_time_bsp_init(void) -{ - /* - * On APIC systems, we want local timers to fire on each cpu. We do - * this by programming LVTT to deliver timer events to the IRQ handler - * for IRQ-0, since we can't re-use the APIC local timer handler - * without interfering with that code. - */ - clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); - local_irq_disable(); -#ifdef CONFIG_X86_SMP - /* - * XXX handle_percpu_irq only defined for SMP; we need to switch over - * to using it, since this is a local interrupt, which each CPU must - * handle individually without locking out or dropping simultaneous - * local timers on other CPUs. We also don't want to trigger the - * quirk workaround code for interrupts which gets invoked from - * handle_percpu_irq via eoi, so we use our own IRQ chip. - */ - set_irq_chip_and_handler_name(0, &vmi_chip, handle_percpu_irq, "lvtt"); -#else - set_irq_chip_and_handler_name(0, &vmi_chip, handle_edge_irq, "lvtt"); -#endif - vmi_wiring = VMI_ALARM_WIRED_LVTT; - apic_write(APIC_LVTT, vmi_get_timer_vector()); - local_irq_enable(); - clockevents_notify(CLOCK_EVT_NOTIFY_RESUME, NULL); -} - -void __devinit vmi_time_ap_init(void) -{ - vmi_time_init_clockevent(); - apic_write(APIC_LVTT, vmi_get_timer_vector()); -} -#endif - -/** vmi clocksource */ - -static cycle_t read_real_cycles(void) -{ - return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); -} - -static struct clocksource clocksource_vmi = { - .name = "vmi-timer", - .rating = 450, - .read = read_real_cycles, - .mask = CLOCKSOURCE_MASK(64), - .mult = 0, /* to be set */ - .shift = 22, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static int __init init_vmi_clocksource(void) -{ - cycle_t cycles_per_msec; - - if (!vmi_timer_ops.get_cycle_frequency) - return 0; - /* Use khz2mult rather than hz2mult since hz arg is only 32-bits. */ - cycles_per_msec = vmi_timer_ops.get_cycle_frequency(); - (void)do_div(cycles_per_msec, 1000); - - /* Note that clocksource.{mult, shift} converts in the opposite direction - * as clockevents. */ - clocksource_vmi.mult = clocksource_khz2mult(cycles_per_msec, - clocksource_vmi.shift); - - printk(KERN_WARNING "vmi: registering clock source khz=%lld\n", cycles_per_msec); - return clocksource_register(&clocksource_vmi); - -} -module_init(init_vmi_clocksource); diff --git a/trunk/arch/i386/kernel/vmitime.c b/trunk/arch/i386/kernel/vmitime.c new file mode 100644 index 000000000000..9dfb17739b67 --- /dev/null +++ b/trunk/arch/i386/kernel/vmitime.c @@ -0,0 +1,482 @@ +/* + * VMI paravirtual timer support routines. + * + * Copyright (C) 2005, VMware, Inc. + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Send feedback to dhecht@vmware.com + * + */ + +/* + * Portions of this code from arch/i386/kernel/timers/timer_tsc.c. + * Portions of the CONFIG_NO_IDLE_HZ code from arch/s390/kernel/time.c. + * See comments there for proper credits. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#ifdef CONFIG_X86_LOCAL_APIC +#define VMI_ALARM_WIRING VMI_ALARM_WIRED_LVTT +#else +#define VMI_ALARM_WIRING VMI_ALARM_WIRED_IRQ0 +#endif + +/* Cached VMI operations */ +struct vmi_timer_ops vmi_timer_ops; + +#ifdef CONFIG_NO_IDLE_HZ + +/* /proc/sys/kernel/hz_timer state. */ +int sysctl_hz_timer; + +/* Some stats */ +static DEFINE_PER_CPU(unsigned long, vmi_idle_no_hz_irqs); +static DEFINE_PER_CPU(unsigned long, vmi_idle_no_hz_jiffies); +static DEFINE_PER_CPU(unsigned long, idle_start_jiffies); + +#endif /* CONFIG_NO_IDLE_HZ */ + +/* Number of alarms per second. By default this is CONFIG_VMI_ALARM_HZ. */ +static int alarm_hz = CONFIG_VMI_ALARM_HZ; + +/* Cache of the value get_cycle_frequency / HZ. */ +static signed long long cycles_per_jiffy; + +/* Cache of the value get_cycle_frequency / alarm_hz. */ +static signed long long cycles_per_alarm; + +/* The number of cycles accounted for by the 'jiffies'/'xtime' count. + * Protected by xtime_lock. */ +static unsigned long long real_cycles_accounted_system; + +/* The number of cycles accounted for by update_process_times(), per cpu. */ +static DEFINE_PER_CPU(unsigned long long, process_times_cycles_accounted_cpu); + +/* The number of stolen cycles accounted, per cpu. */ +static DEFINE_PER_CPU(unsigned long long, stolen_cycles_accounted_cpu); + +/* Clock source. */ +static cycle_t read_real_cycles(void) +{ + return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_REAL); +} + +static cycle_t read_available_cycles(void) +{ + return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE); +} + +#if 0 +static cycle_t read_stolen_cycles(void) +{ + return vmi_timer_ops.get_cycle_counter(VMI_CYCLES_STOLEN); +} +#endif /* 0 */ + +static struct clocksource clocksource_vmi = { + .name = "vmi-timer", + .rating = 450, + .read = read_real_cycles, + .mask = CLOCKSOURCE_MASK(64), + .mult = 0, /* to be set */ + .shift = 22, + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + + +/* Timer interrupt handler. */ +static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id); + +static struct irqaction vmi_timer_irq = { + .handler = vmi_timer_interrupt, + .flags = IRQF_DISABLED, + .mask = CPU_MASK_NONE, + .name = "VMI-alarm", +}; + +/* Alarm rate */ +static int __init vmi_timer_alarm_rate_setup(char* str) +{ + int alarm_rate; + if (get_option(&str, &alarm_rate) == 1 && alarm_rate > 0) { + alarm_hz = alarm_rate; + printk(KERN_WARNING "VMI timer alarm HZ set to %d\n", alarm_hz); + } + return 1; +} +__setup("vmi_timer_alarm_hz=", vmi_timer_alarm_rate_setup); + + +/* Initialization */ +static void vmi_get_wallclock_ts(struct timespec *ts) +{ + unsigned long long wallclock; + wallclock = vmi_timer_ops.get_wallclock(); // nsec units + ts->tv_nsec = do_div(wallclock, 1000000000); + ts->tv_sec = wallclock; +} + +unsigned long vmi_get_wallclock(void) +{ + struct timespec ts; + vmi_get_wallclock_ts(&ts); + return ts.tv_sec; +} + +int vmi_set_wallclock(unsigned long now) +{ + return -1; +} + +unsigned long long vmi_get_sched_cycles(void) +{ + return read_available_cycles(); +} + +unsigned long vmi_cpu_khz(void) +{ + unsigned long long khz; + + khz = vmi_timer_ops.get_cycle_frequency(); + (void)do_div(khz, 1000); + return khz; +} + +void __init vmi_time_init(void) +{ + unsigned long long cycles_per_sec, cycles_per_msec; + unsigned long flags; + + local_irq_save(flags); + setup_irq(0, &vmi_timer_irq); +#ifdef CONFIG_X86_LOCAL_APIC + set_intr_gate(LOCAL_TIMER_VECTOR, apic_vmi_timer_interrupt); +#endif + + real_cycles_accounted_system = read_real_cycles(); + per_cpu(process_times_cycles_accounted_cpu, 0) = read_available_cycles(); + + cycles_per_sec = vmi_timer_ops.get_cycle_frequency(); + cycles_per_jiffy = cycles_per_sec; + (void)do_div(cycles_per_jiffy, HZ); + cycles_per_alarm = cycles_per_sec; + (void)do_div(cycles_per_alarm, alarm_hz); + cycles_per_msec = cycles_per_sec; + (void)do_div(cycles_per_msec, 1000); + + printk(KERN_WARNING "VMI timer cycles/sec = %llu ; cycles/jiffy = %llu ;" + "cycles/alarm = %llu\n", cycles_per_sec, cycles_per_jiffy, + cycles_per_alarm); + + clocksource_vmi.mult = clocksource_khz2mult(cycles_per_msec, + clocksource_vmi.shift); + if (clocksource_register(&clocksource_vmi)) + printk(KERN_WARNING "Error registering VMITIME clocksource."); + + /* Disable PIT. */ + outb_p(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */ + + /* schedule the alarm. do this in phase with process_times_cycles_accounted_cpu + * reduce the latency calling update_process_times. */ + vmi_timer_ops.set_alarm( + VMI_ALARM_WIRED_IRQ0 | VMI_ALARM_IS_PERIODIC | VMI_CYCLES_AVAILABLE, + per_cpu(process_times_cycles_accounted_cpu, 0) + cycles_per_alarm, + cycles_per_alarm); + + local_irq_restore(flags); +} + +#ifdef CONFIG_X86_LOCAL_APIC + +void __init vmi_timer_setup_boot_alarm(void) +{ + local_irq_disable(); + + /* Route the interrupt to the correct vector. */ + apic_write_around(APIC_LVTT, LOCAL_TIMER_VECTOR); + + /* Cancel the IRQ0 wired alarm, and setup the LVTT alarm. */ + vmi_timer_ops.cancel_alarm(VMI_CYCLES_AVAILABLE); + vmi_timer_ops.set_alarm( + VMI_ALARM_WIRED_LVTT | VMI_ALARM_IS_PERIODIC | VMI_CYCLES_AVAILABLE, + per_cpu(process_times_cycles_accounted_cpu, 0) + cycles_per_alarm, + cycles_per_alarm); + local_irq_enable(); +} + +/* Initialize the time accounting variables for an AP on an SMP system. + * Also, set the local alarm for the AP. */ +void __devinit vmi_timer_setup_secondary_alarm(void) +{ + int cpu = smp_processor_id(); + + /* Route the interrupt to the correct vector. */ + apic_write_around(APIC_LVTT, LOCAL_TIMER_VECTOR); + + per_cpu(process_times_cycles_accounted_cpu, cpu) = read_available_cycles(); + + vmi_timer_ops.set_alarm( + VMI_ALARM_WIRED_LVTT | VMI_ALARM_IS_PERIODIC | VMI_CYCLES_AVAILABLE, + per_cpu(process_times_cycles_accounted_cpu, cpu) + cycles_per_alarm, + cycles_per_alarm); +} + +#endif + +/* Update system wide (real) time accounting (e.g. jiffies, xtime). */ +static void vmi_account_real_cycles(unsigned long long cur_real_cycles) +{ + long long cycles_not_accounted; + + write_seqlock(&xtime_lock); + + cycles_not_accounted = cur_real_cycles - real_cycles_accounted_system; + while (cycles_not_accounted >= cycles_per_jiffy) { + /* systems wide jiffies. */ + do_timer(1); + + cycles_not_accounted -= cycles_per_jiffy; + real_cycles_accounted_system += cycles_per_jiffy; + } + + write_sequnlock(&xtime_lock); +} + +/* Update per-cpu process times. */ +static void vmi_account_process_times_cycles(struct pt_regs *regs, int cpu, + unsigned long long cur_process_times_cycles) +{ + long long cycles_not_accounted; + cycles_not_accounted = cur_process_times_cycles - + per_cpu(process_times_cycles_accounted_cpu, cpu); + + while (cycles_not_accounted >= cycles_per_jiffy) { + /* Account time to the current process. This includes + * calling into the scheduler to decrement the timeslice + * and possibly reschedule.*/ + update_process_times(user_mode(regs)); + /* XXX handle /proc/profile multiplier. */ + profile_tick(CPU_PROFILING); + + cycles_not_accounted -= cycles_per_jiffy; + per_cpu(process_times_cycles_accounted_cpu, cpu) += cycles_per_jiffy; + } +} + +#ifdef CONFIG_NO_IDLE_HZ +/* Update per-cpu idle times. Used when a no-hz halt is ended. */ +static void vmi_account_no_hz_idle_cycles(int cpu, + unsigned long long cur_process_times_cycles) +{ + long long cycles_not_accounted; + unsigned long no_idle_hz_jiffies = 0; + + cycles_not_accounted = cur_process_times_cycles - + per_cpu(process_times_cycles_accounted_cpu, cpu); + + while (cycles_not_accounted >= cycles_per_jiffy) { + no_idle_hz_jiffies++; + cycles_not_accounted -= cycles_per_jiffy; + per_cpu(process_times_cycles_accounted_cpu, cpu) += cycles_per_jiffy; + } + /* Account time to the idle process. */ + account_steal_time(idle_task(cpu), jiffies_to_cputime(no_idle_hz_jiffies)); +} +#endif + +/* Update per-cpu stolen time. */ +static void vmi_account_stolen_cycles(int cpu, + unsigned long long cur_real_cycles, + unsigned long long cur_avail_cycles) +{ + long long stolen_cycles_not_accounted; + unsigned long stolen_jiffies = 0; + + if (cur_real_cycles < cur_avail_cycles) + return; + + stolen_cycles_not_accounted = cur_real_cycles - cur_avail_cycles - + per_cpu(stolen_cycles_accounted_cpu, cpu); + + while (stolen_cycles_not_accounted >= cycles_per_jiffy) { + stolen_jiffies++; + stolen_cycles_not_accounted -= cycles_per_jiffy; + per_cpu(stolen_cycles_accounted_cpu, cpu) += cycles_per_jiffy; + } + /* HACK: pass NULL to force time onto cpustat->steal. */ + account_steal_time(NULL, jiffies_to_cputime(stolen_jiffies)); +} + +/* Body of either IRQ0 interrupt handler (UP no local-APIC) or + * local-APIC LVTT interrupt handler (UP & local-APIC or SMP). */ +static void vmi_local_timer_interrupt(int cpu) +{ + unsigned long long cur_real_cycles, cur_process_times_cycles; + + cur_real_cycles = read_real_cycles(); + cur_process_times_cycles = read_available_cycles(); + /* Update system wide (real) time state (xtime, jiffies). */ + vmi_account_real_cycles(cur_real_cycles); + /* Update per-cpu process times. */ + vmi_account_process_times_cycles(get_irq_regs(), cpu, cur_process_times_cycles); + /* Update time stolen from this cpu by the hypervisor. */ + vmi_account_stolen_cycles(cpu, cur_real_cycles, cur_process_times_cycles); +} + +#ifdef CONFIG_NO_IDLE_HZ + +/* Must be called only from idle loop, with interrupts disabled. */ +int vmi_stop_hz_timer(void) +{ + /* Note that cpu_set, cpu_clear are (SMP safe) atomic on x86. */ + + unsigned long seq, next; + unsigned long long real_cycles_expiry; + int cpu = smp_processor_id(); + + BUG_ON(!irqs_disabled()); + if (sysctl_hz_timer != 0) + return 0; + + cpu_set(cpu, nohz_cpu_mask); + smp_mb(); + + if (rcu_needs_cpu(cpu) || local_softirq_pending() || + (next = next_timer_interrupt(), + time_before_eq(next, jiffies + HZ/CONFIG_VMI_ALARM_HZ))) { + cpu_clear(cpu, nohz_cpu_mask); + return 0; + } + + /* Convert jiffies to the real cycle counter. */ + do { + seq = read_seqbegin(&xtime_lock); + real_cycles_expiry = real_cycles_accounted_system + + (long)(next - jiffies) * cycles_per_jiffy; + } while (read_seqretry(&xtime_lock, seq)); + + /* This cpu is going idle. Disable the periodic alarm. */ + vmi_timer_ops.cancel_alarm(VMI_CYCLES_AVAILABLE); + per_cpu(idle_start_jiffies, cpu) = jiffies; + /* Set the real time alarm to expire at the next event. */ + vmi_timer_ops.set_alarm( + VMI_ALARM_WIRING | VMI_ALARM_IS_ONESHOT | VMI_CYCLES_REAL, + real_cycles_expiry, 0); + return 1; +} + +static void vmi_reenable_hz_timer(int cpu) +{ + /* For /proc/vmi/info idle_hz stat. */ + per_cpu(vmi_idle_no_hz_jiffies, cpu) += jiffies - per_cpu(idle_start_jiffies, cpu); + per_cpu(vmi_idle_no_hz_irqs, cpu)++; + + /* Don't bother explicitly cancelling the one-shot alarm -- at + * worse we will receive a spurious timer interrupt. */ + vmi_timer_ops.set_alarm( + VMI_ALARM_WIRING | VMI_ALARM_IS_PERIODIC | VMI_CYCLES_AVAILABLE, + per_cpu(process_times_cycles_accounted_cpu, cpu) + cycles_per_alarm, + cycles_per_alarm); + /* Indicate this cpu is no longer nohz idle. */ + cpu_clear(cpu, nohz_cpu_mask); +} + +/* Called from interrupt handlers when (local) HZ timer is disabled. */ +void vmi_account_time_restart_hz_timer(void) +{ + unsigned long long cur_real_cycles, cur_process_times_cycles; + int cpu = smp_processor_id(); + + BUG_ON(!irqs_disabled()); + /* Account the time during which the HZ timer was disabled. */ + cur_real_cycles = read_real_cycles(); + cur_process_times_cycles = read_available_cycles(); + /* Update system wide (real) time state (xtime, jiffies). */ + vmi_account_real_cycles(cur_real_cycles); + /* Update per-cpu idle times. */ + vmi_account_no_hz_idle_cycles(cpu, cur_process_times_cycles); + /* Update time stolen from this cpu by the hypervisor. */ + vmi_account_stolen_cycles(cpu, cur_real_cycles, cur_process_times_cycles); + /* Reenable the hz timer. */ + vmi_reenable_hz_timer(cpu); +} + +#endif /* CONFIG_NO_IDLE_HZ */ + +/* UP (and no local-APIC) VMI-timer alarm interrupt handler. + * Handler for IRQ0. Not used when SMP or X86_LOCAL_APIC after + * APIC setup and setup_boot_vmi_alarm() is called. */ +static irqreturn_t vmi_timer_interrupt(int irq, void *dev_id) +{ + vmi_local_timer_interrupt(smp_processor_id()); + return IRQ_HANDLED; +} + +#ifdef CONFIG_X86_LOCAL_APIC + +/* SMP VMI-timer alarm interrupt handler. Handler for LVTT vector. + * Also used in UP when CONFIG_X86_LOCAL_APIC. + * The wrapper code is from arch/i386/kernel/apic.c#smp_apic_timer_interrupt. */ +void smp_apic_vmi_timer_interrupt(struct pt_regs *regs) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + int cpu = smp_processor_id(); + + /* + * the NMI deadlock-detector uses this. + */ + per_cpu(irq_stat,cpu).apic_timer_irqs++; + + /* + * NOTE! We'd better ACK the irq immediately, + * because timer handling can be slow. + */ + ack_APIC_irq(); + + /* + * update_process_times() expects us to have done irq_enter(). + * Besides, if we don't timer interrupts ignore the global + * interrupt lock, which is the WrongThing (tm) to do. + */ + irq_enter(); + vmi_local_timer_interrupt(cpu); + irq_exit(); + set_irq_regs(old_regs); +} + +#endif /* CONFIG_X86_LOCAL_APIC */ diff --git a/trunk/arch/i386/kernel/vmlinux.lds.S b/trunk/arch/i386/kernel/vmlinux.lds.S index 23e8614edeee..6f38f818380b 100644 --- a/trunk/arch/i386/kernel/vmlinux.lds.S +++ b/trunk/arch/i386/kernel/vmlinux.lds.S @@ -26,11 +26,12 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(phys_startup_32) jiffies = jiffies_64; +_proxy_pda = 1; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(7); /* RWE */ - note PT_NOTE FLAGS(0); /* ___ */ + note PT_NOTE FLAGS(4); /* R__ */ } SECTIONS { @@ -60,6 +61,8 @@ SECTIONS __stop___ex_table = .; } + RODATA + BUG_TABLE . = ALIGN(4); @@ -69,8 +72,6 @@ SECTIONS __tracedata_end = .; } - RODATA - /* writeable */ . = ALIGN(4096); .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ @@ -116,11 +117,22 @@ SECTIONS /* might get freed after init */ . = ALIGN(4096); + .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { + __smp_alt_begin = .; + __smp_alt_instructions = .; + *(.smp_altinstructions) + __smp_alt_instructions_end = .; + } + . = ALIGN(4); .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { __smp_locks = .; *(.smp_locks) __smp_locks_end = .; } + .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { + *(.smp_altinstr_replacement) + __smp_alt_end = .; + } /* will be freed after init * Following ALIGN() is required to make sure no other data falls on the * same page where __smp_alt_end is pointing as that page might be freed @@ -166,9 +178,9 @@ SECTIONS } . = ALIGN(4); .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { - __parainstructions = .; + __start_parainstructions = .; *(.parainstructions) - __parainstructions_end = .; + __stop_parainstructions = .; } /* .exit.text is discard at runtime, not link time, to deal with references from .altinstructions and .eh_frame */ @@ -182,7 +194,7 @@ SECTIONS __initramfs_end = .; } #endif - . = ALIGN(4096); + . = ALIGN(L1_CACHE_BYTES); .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { __per_cpu_start = .; *(.data.percpu) diff --git a/trunk/arch/i386/kernel/vsyscall.lds.S b/trunk/arch/i386/kernel/vsyscall.lds.S index 4a8b0ed9b8fb..f66cd11adb72 100644 --- a/trunk/arch/i386/kernel/vsyscall.lds.S +++ b/trunk/arch/i386/kernel/vsyscall.lds.S @@ -7,7 +7,7 @@ SECTIONS { - . = VDSO_PRELINK_asm + SIZEOF_HEADERS; + . = VDSO_PRELINK + SIZEOF_HEADERS; .hash : { *(.hash) } :text .gnu.hash : { *(.gnu.hash) } @@ -21,7 +21,7 @@ SECTIONS For the layouts to match, we need to skip more than enough space for the dynamic symbol table et al. If this amount is insufficient, ld -shared will barf. Just increase it here. */ - . = VDSO_PRELINK_asm + 0x400; + . = VDSO_PRELINK + 0x400; .text : { *(.text) } :text =0x90909090 .note : { *(.note.*) } :text :note diff --git a/trunk/arch/i386/lib/bitops.c b/trunk/arch/i386/lib/bitops.c index afd0045595d4..97db3853dc82 100644 --- a/trunk/arch/i386/lib/bitops.c +++ b/trunk/arch/i386/lib/bitops.c @@ -43,7 +43,7 @@ EXPORT_SYMBOL(find_next_bit); */ int find_next_zero_bit(const unsigned long *addr, int size, int offset) { - const unsigned long *p = addr + (offset >> 5); + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); int set = 0, bit = offset & 31, res; if (bit) { @@ -64,7 +64,7 @@ int find_next_zero_bit(const unsigned long *addr, int size, int offset) /* * No zero yet, search remaining full bytes for a zero */ - res = find_first_zero_bit(p, size - 32 * (p - addr)); + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); return (offset + set + res); } EXPORT_SYMBOL(find_next_zero_bit); diff --git a/trunk/arch/i386/lib/checksum.S b/trunk/arch/i386/lib/checksum.S index adbccd0bbb78..75ffd02654fc 100644 --- a/trunk/arch/i386/lib/checksum.S +++ b/trunk/arch/i386/lib/checksum.S @@ -25,8 +25,6 @@ * 2 of the License, or (at your option) any later version. */ -#include -#include #include /* @@ -38,6 +36,8 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) */ .text +.align 4 +.globl csum_partial #ifndef CONFIG_X86_USE_PPRO_CHECKSUM @@ -48,14 +48,9 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) * Fortunately, it is easy to convert 2-byte alignment to 4-byte * alignment for the unrolled loop. */ -ENTRY(csum_partial) - CFI_STARTPROC +csum_partial: pushl %esi - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET esi, 0 pushl %ebx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ebx, 0 movl 20(%esp),%eax # Function arg: unsigned int sum movl 16(%esp),%ecx # Function arg: int len movl 12(%esp),%esi # Function arg: unsigned char *buff @@ -133,27 +128,16 @@ ENTRY(csum_partial) roll $8, %eax 8: popl %ebx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ebx popl %esi - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE esi ret - CFI_ENDPROC -ENDPROC(csum_partial) #else /* Version for PentiumII/PPro */ -ENTRY(csum_partial) - CFI_STARTPROC +csum_partial: pushl %esi - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET esi, 0 pushl %ebx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ebx, 0 movl 20(%esp),%eax # Function arg: unsigned int sum movl 16(%esp),%ecx # Function arg: int len movl 12(%esp),%esi # Function arg: const unsigned char *buf @@ -261,14 +245,8 @@ ENTRY(csum_partial) roll $8, %eax 90: popl %ebx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ebx popl %esi - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE esi ret - CFI_ENDPROC -ENDPROC(csum_partial) #endif @@ -300,24 +278,19 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, .long 9999b, 6002f ; \ .previous +.align 4 +.globl csum_partial_copy_generic + #ifndef CONFIG_X86_USE_PPRO_CHECKSUM #define ARGBASE 16 #define FP 12 -ENTRY(csum_partial_copy_generic) - CFI_STARTPROC +csum_partial_copy_generic: subl $4,%esp - CFI_ADJUST_CFA_OFFSET 4 pushl %edi - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edi, 0 pushl %esi - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET esi, 0 pushl %ebx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ebx, 0 movl ARGBASE+16(%esp),%eax # sum movl ARGBASE+12(%esp),%ecx # len movl ARGBASE+4(%esp),%esi # src @@ -427,19 +400,10 @@ DST( movb %cl, (%edi) ) .previous popl %ebx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ebx popl %esi - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE esi popl %edi - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edi popl %ecx # equivalent to addl $4,%esp - CFI_ADJUST_CFA_OFFSET -4 ret - CFI_ENDPROC -ENDPROC(csum_partial_copy_generic) #else @@ -457,17 +421,10 @@ ENDPROC(csum_partial_copy_generic) #define ARGBASE 12 -ENTRY(csum_partial_copy_generic) - CFI_STARTPROC +csum_partial_copy_generic: pushl %ebx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ebx, 0 pushl %edi - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edi, 0 pushl %esi - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET esi, 0 movl ARGBASE+4(%esp),%esi #src movl ARGBASE+8(%esp),%edi #dst movl ARGBASE+12(%esp),%ecx #len @@ -528,17 +485,9 @@ DST( movb %dl, (%edi) ) .previous popl %esi - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE esi popl %edi - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edi popl %ebx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ebx ret - CFI_ENDPROC -ENDPROC(csum_partial_copy_generic) #undef ROUND #undef ROUND1 diff --git a/trunk/arch/i386/lib/getuser.S b/trunk/arch/i386/lib/getuser.S index 6d84b53f12a2..62d7f178a326 100644 --- a/trunk/arch/i386/lib/getuser.S +++ b/trunk/arch/i386/lib/getuser.S @@ -8,8 +8,6 @@ * return an error value in addition to the "real" * return value. */ -#include -#include #include @@ -26,19 +24,19 @@ */ .text -ENTRY(__get_user_1) - CFI_STARTPROC +.align 4 +.globl __get_user_1 +__get_user_1: GET_THREAD_INFO(%edx) cmpl TI_addr_limit(%edx),%eax jae bad_get_user 1: movzbl (%eax),%edx xorl %eax,%eax ret - CFI_ENDPROC -ENDPROC(__get_user_1) -ENTRY(__get_user_2) - CFI_STARTPROC +.align 4 +.globl __get_user_2 +__get_user_2: addl $1,%eax jc bad_get_user GET_THREAD_INFO(%edx) @@ -47,11 +45,10 @@ ENTRY(__get_user_2) 2: movzwl -1(%eax),%edx xorl %eax,%eax ret - CFI_ENDPROC -ENDPROC(__get_user_2) -ENTRY(__get_user_4) - CFI_STARTPROC +.align 4 +.globl __get_user_4 +__get_user_4: addl $3,%eax jc bad_get_user GET_THREAD_INFO(%edx) @@ -60,16 +57,11 @@ ENTRY(__get_user_4) 3: movl -3(%eax),%edx xorl %eax,%eax ret - CFI_ENDPROC -ENDPROC(__get_user_4) bad_get_user: - CFI_STARTPROC xorl %edx,%edx movl $-14,%eax ret - CFI_ENDPROC -END(bad_get_user) .section __ex_table,"a" .long 1b,bad_get_user diff --git a/trunk/arch/i386/lib/msr-on-cpu.c b/trunk/arch/i386/lib/msr-on-cpu.c index 7767962f25d3..1c46bda409ff 100644 --- a/trunk/arch/i386/lib/msr-on-cpu.c +++ b/trunk/arch/i386/lib/msr-on-cpu.c @@ -6,7 +6,6 @@ struct msr_info { u32 msr_no; u32 l, h; - int err; }; static void __rdmsr_on_cpu(void *info) @@ -16,38 +15,20 @@ static void __rdmsr_on_cpu(void *info) rdmsr(rv->msr_no, rv->l, rv->h); } -static void __rdmsr_safe_on_cpu(void *info) -{ - struct msr_info *rv = info; - - rv->err = rdmsr_safe(rv->msr_no, &rv->l, &rv->h); -} - -static int _rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h, int safe) +void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) { - int err = 0; preempt_disable(); if (smp_processor_id() == cpu) - if (safe) - err = rdmsr_safe(msr_no, l, h); - else - rdmsr(msr_no, *l, *h); + rdmsr(msr_no, *l, *h); else { struct msr_info rv; rv.msr_no = msr_no; - if (safe) { - smp_call_function_single(cpu, __rdmsr_safe_on_cpu, - &rv, 0, 1); - err = rv.err; - } else { - smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 0, 1); - } + smp_call_function_single(cpu, __rdmsr_on_cpu, &rv, 0, 1); *l = rv.l; *h = rv.h; } preempt_enable(); - return err; } static void __wrmsr_on_cpu(void *info) @@ -57,63 +38,21 @@ static void __wrmsr_on_cpu(void *info) wrmsr(rv->msr_no, rv->l, rv->h); } -static void __wrmsr_safe_on_cpu(void *info) -{ - struct msr_info *rv = info; - - rv->err = wrmsr_safe(rv->msr_no, rv->l, rv->h); -} - -static int _wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h, int safe) +void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) { - int err = 0; preempt_disable(); if (smp_processor_id() == cpu) - if (safe) - err = wrmsr_safe(msr_no, l, h); - else - wrmsr(msr_no, l, h); + wrmsr(msr_no, l, h); else { struct msr_info rv; rv.msr_no = msr_no; rv.l = l; rv.h = h; - if (safe) { - smp_call_function_single(cpu, __wrmsr_safe_on_cpu, - &rv, 0, 1); - err = rv.err; - } else { - smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 0, 1); - } + smp_call_function_single(cpu, __wrmsr_on_cpu, &rv, 0, 1); } preempt_enable(); - return err; -} - -void wrmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) -{ - _wrmsr_on_cpu(cpu, msr_no, l, h, 0); -} - -void rdmsr_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) -{ - _rdmsr_on_cpu(cpu, msr_no, l, h, 0); -} - -/* These "safe" variants are slower and should be used when the target MSR - may not actually exist. */ -int wrmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 l, u32 h) -{ - return _wrmsr_on_cpu(cpu, msr_no, l, h, 1); -} - -int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h) -{ - return _rdmsr_on_cpu(cpu, msr_no, l, h, 1); } EXPORT_SYMBOL(rdmsr_on_cpu); EXPORT_SYMBOL(wrmsr_on_cpu); -EXPORT_SYMBOL(rdmsr_safe_on_cpu); -EXPORT_SYMBOL(wrmsr_safe_on_cpu); diff --git a/trunk/arch/i386/lib/putuser.S b/trunk/arch/i386/lib/putuser.S index f58fba109d18..a32d9f570f48 100644 --- a/trunk/arch/i386/lib/putuser.S +++ b/trunk/arch/i386/lib/putuser.S @@ -8,8 +8,6 @@ * return an error value in addition to the "real" * return value. */ -#include -#include #include @@ -25,28 +23,23 @@ * as they get called from within inline assembly. */ -#define ENTER CFI_STARTPROC ; \ - pushl %ebx ; \ - CFI_ADJUST_CFA_OFFSET 4 ; \ - CFI_REL_OFFSET ebx, 0 ; \ - GET_THREAD_INFO(%ebx) -#define EXIT popl %ebx ; \ - CFI_ADJUST_CFA_OFFSET -4 ; \ - CFI_RESTORE ebx ; \ - ret ; \ - CFI_ENDPROC +#define ENTER pushl %ebx ; GET_THREAD_INFO(%ebx) +#define EXIT popl %ebx ; ret .text -ENTRY(__put_user_1) +.align 4 +.globl __put_user_1 +__put_user_1: ENTER cmpl TI_addr_limit(%ebx),%ecx jae bad_put_user 1: movb %al,(%ecx) xorl %eax,%eax EXIT -ENDPROC(__put_user_1) -ENTRY(__put_user_2) +.align 4 +.globl __put_user_2 +__put_user_2: ENTER movl TI_addr_limit(%ebx),%ebx subl $1,%ebx @@ -55,9 +48,10 @@ ENTRY(__put_user_2) 2: movw %ax,(%ecx) xorl %eax,%eax EXIT -ENDPROC(__put_user_2) -ENTRY(__put_user_4) +.align 4 +.globl __put_user_4 +__put_user_4: ENTER movl TI_addr_limit(%ebx),%ebx subl $3,%ebx @@ -66,9 +60,10 @@ ENTRY(__put_user_4) 3: movl %eax,(%ecx) xorl %eax,%eax EXIT -ENDPROC(__put_user_4) -ENTRY(__put_user_8) +.align 4 +.globl __put_user_8 +__put_user_8: ENTER movl TI_addr_limit(%ebx),%ebx subl $7,%ebx @@ -78,16 +73,10 @@ ENTRY(__put_user_8) 5: movl %edx,4(%ecx) xorl %eax,%eax EXIT -ENDPROC(__put_user_8) bad_put_user: - CFI_STARTPROC simple - CFI_DEF_CFA esp, 2*4 - CFI_OFFSET eip, -1*4 - CFI_OFFSET ebx, -2*4 movl $-14,%eax EXIT -END(bad_put_user) .section __ex_table,"a" .long 1b,bad_put_user diff --git a/trunk/arch/i386/lib/usercopy.c b/trunk/arch/i386/lib/usercopy.c index 9f38b12b4af1..086b3726862a 100644 --- a/trunk/arch/i386/lib/usercopy.c +++ b/trunk/arch/i386/lib/usercopy.c @@ -716,6 +716,7 @@ do { \ unsigned long __copy_to_user_ll(void __user *to, const void *from, unsigned long n) { + BUG_ON((long) n < 0); #ifndef CONFIG_X86_WP_WORKS_OK if (unlikely(boot_cpu_data.wp_works_ok == 0) && ((unsigned long )to) < TASK_SIZE) { @@ -784,6 +785,7 @@ EXPORT_SYMBOL(__copy_to_user_ll); unsigned long __copy_from_user_ll(void *to, const void __user *from, unsigned long n) { + BUG_ON((long)n < 0); if (movsl_is_ok(to, from, n)) __copy_user_zeroing(to, from, n); else @@ -795,6 +797,7 @@ EXPORT_SYMBOL(__copy_from_user_ll); unsigned long __copy_from_user_ll_nozero(void *to, const void __user *from, unsigned long n) { + BUG_ON((long)n < 0); if (movsl_is_ok(to, from, n)) __copy_user(to, from, n); else @@ -807,6 +810,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero); unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, unsigned long n) { + BUG_ON((long)n < 0); #ifdef CONFIG_X86_INTEL_USERCOPY if ( n > 64 && cpu_has_xmm2) n = __copy_user_zeroing_intel_nocache(to, from, n); @@ -821,6 +825,7 @@ unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from, unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from, unsigned long n) { + BUG_ON((long)n < 0); #ifdef CONFIG_X86_INTEL_USERCOPY if ( n > 64 && cpu_has_xmm2) n = __copy_user_intel_nocache(to, from, n); @@ -848,6 +853,7 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) { + BUG_ON((long) n < 0); if (access_ok(VERIFY_WRITE, to, n)) n = __copy_to_user(to, from, n); return n; @@ -873,6 +879,7 @@ EXPORT_SYMBOL(copy_to_user); unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) { + BUG_ON((long) n < 0); if (access_ok(VERIFY_READ, from, n)) n = __copy_from_user(to, from, n); else diff --git a/trunk/arch/i386/mach-default/setup.c b/trunk/arch/i386/mach-default/setup.c index 7f635c7a2381..c78816210706 100644 --- a/trunk/arch/i386/mach-default/setup.c +++ b/trunk/arch/i386/mach-default/setup.c @@ -81,7 +81,7 @@ void __init trap_init_hook(void) static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_NOBALANCING, .mask = CPU_MASK_NONE, .name = "timer" }; diff --git a/trunk/arch/i386/mach-generic/bigsmp.c b/trunk/arch/i386/mach-generic/bigsmp.c index e932d3485ae2..8a210fa915b5 100644 --- a/trunk/arch/i386/mach-generic/bigsmp.c +++ b/trunk/arch/i386/mach-generic/bigsmp.c @@ -45,7 +45,7 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { }; -static int __init probe_bigsmp(void) +static int probe_bigsmp(void) { if (def_to_bigsmp) dmi_bigsmp = 1; diff --git a/trunk/arch/i386/mach-generic/es7000.c b/trunk/arch/i386/mach-generic/es7000.c index b47f951c0ec2..b8963a5a3b25 100644 --- a/trunk/arch/i386/mach-generic/es7000.c +++ b/trunk/arch/i386/mach-generic/es7000.c @@ -25,45 +25,4 @@ static int probe_es7000(void) return 0; } -extern void es7000_sw_apic(void); -static void __init enable_apic_mode(void) -{ - es7000_sw_apic(); - return; -} - -static __init int mps_oem_check(struct mp_config_table *mpc, char *oem, - char *productid) -{ - if (mpc->mpc_oemptr) { - struct mp_config_oemtable *oem_table = - (struct mp_config_oemtable *)mpc->mpc_oemptr; - if (!strncmp(oem, "UNISYS", 6)) - return parse_unisys_oem((char *)oem_table); - } - return 0; -} - -#ifdef CONFIG_ACPI -/* Hook from generic ACPI tables.c */ -static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - unsigned long oem_addr; - if (!find_unisys_acpi_oem_table(&oem_addr)) { - if (es7000_check_dsdt()) - return parse_unisys_oem((char *)oem_addr); - else { - setup_unisys(); - return 1; - } - } - return 0; -} -#else -static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) -{ - return 0; -} -#endif - struct genapic apic_es7000 = APIC_INIT("es7000", probe_es7000); diff --git a/trunk/arch/i386/mach-visws/setup.c b/trunk/arch/i386/mach-visws/setup.c index 1f81f10e03a0..233ee20907b9 100644 --- a/trunk/arch/i386/mach-visws/setup.c +++ b/trunk/arch/i386/mach-visws/setup.c @@ -116,7 +116,7 @@ void __init pre_setup_arch_hook() static struct irqaction irq0 = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_IRQPOLL, + .flags = IRQF_DISABLED, .name = "timer", }; diff --git a/trunk/arch/i386/mach-visws/visws_apic.c b/trunk/arch/i386/mach-visws/visws_apic.c index 710faf71a650..38c2b13124d9 100644 --- a/trunk/arch/i386/mach-visws/visws_apic.c +++ b/trunk/arch/i386/mach-visws/visws_apic.c @@ -18,6 +18,7 @@ #include #include +#include #include #include diff --git a/trunk/arch/i386/mach-voyager/setup.c b/trunk/arch/i386/mach-voyager/setup.c index 2b55694e6400..cfa16c151c8f 100644 --- a/trunk/arch/i386/mach-voyager/setup.c +++ b/trunk/arch/i386/mach-voyager/setup.c @@ -40,16 +40,10 @@ void __init trap_init_hook(void) { } -static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL, - .mask = CPU_MASK_NONE, - .name = "timer" -}; +static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL}; void __init time_init_hook(void) { - irq0.mask = cpumask_of_cpu(safe_smp_processor_id()); setup_irq(0, &irq0); } diff --git a/trunk/arch/i386/mach-voyager/voyager_cat.c b/trunk/arch/i386/mach-voyager/voyager_cat.c index 26a2d4c54b68..943a9473b138 100644 --- a/trunk/arch/i386/mach-voyager/voyager_cat.c +++ b/trunk/arch/i386/mach-voyager/voyager_cat.c @@ -1111,7 +1111,7 @@ voyager_cat_do_common_interrupt(void) printk(KERN_ERR "Voyager front panel switch turned off\n"); voyager_status.switch_off = 1; voyager_status.request_from_kernel = 1; - wake_up_process(voyager_thread); + up(&kvoyagerd_sem); } /* Tell the hardware we're taking care of the * shutdown, otherwise it will power the box off @@ -1157,7 +1157,7 @@ voyager_cat_do_common_interrupt(void) outb(VOYAGER_CAT_END, CAT_CMD); voyager_status.power_fail = 1; voyager_status.request_from_kernel = 1; - wake_up_process(voyager_thread); + up(&kvoyagerd_sem); } diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index 50d9c52070b1..74aeedf277f4 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -535,6 +536,15 @@ do_boot_cpu(__u8 cpu) & ~( voyager_extended_vic_processors & voyager_allowed_boot_processors); + /* For the 486, we can't use the 4Mb page table trick, so + * must map a region of memory */ +#ifdef CONFIG_M486 + int i; + unsigned long *page_table_copies = (unsigned long *) + __get_free_page(GFP_KERNEL); +#endif + pgd_t orig_swapper_pg_dir0; + /* This is an area in head.S which was used to set up the * initial kernel stack. We need to alter this to give the * booting CPU a new stack (taken from its idle process) */ @@ -563,8 +573,6 @@ do_boot_cpu(__u8 cpu) hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF; cpucount++; - alternatives_smp_switch(1); - idle = fork_idle(cpu); if(IS_ERR(idle)) panic("failed fork for CPU%d", cpu); @@ -572,18 +580,39 @@ do_boot_cpu(__u8 cpu) /* init_tasks (in sched.c) is indexed logically */ stack_start.esp = (void *) idle->thread.esp; - init_gdt(cpu, idle); + /* Pre-allocate and initialize the CPU's GDT and PDA so it + doesn't have to do any memory allocation during the + delicate CPU-bringup phase. */ + if (!init_gdt(cpu, idle)) { + printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); + cpucount--; + return; + } + irq_ctx_init(cpu); /* Note: Don't modify initial ss override */ VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, (unsigned long)hijack_source.val, hijack_source.idt.Segment, hijack_source.idt.Offset, stack_start.esp)); - - /* init lowmem identity mapping */ - clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, - min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); - flush_tlb_all(); + /* set the original swapper_pg_dir[0] to map 0 to 4Mb transparently + * (so that the booting CPU can find start_32 */ + orig_swapper_pg_dir0 = swapper_pg_dir[0]; +#ifdef CONFIG_M486 + if(page_table_copies == NULL) + panic("No free memory for 486 page tables\n"); + for(i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++) + page_table_copies[i] = (i * PAGE_SIZE) + | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; + + ((unsigned long *)swapper_pg_dir)[0] = + ((virt_to_phys(page_table_copies)) & PAGE_MASK) + | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; +#else + ((unsigned long *)swapper_pg_dir)[0] = + (virt_to_phys(pg0) & PAGE_MASK) + | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; +#endif if(quad_boot) { printk("CPU %d: non extended Quad boot\n", cpu); @@ -626,7 +655,11 @@ do_boot_cpu(__u8 cpu) udelay(100); } /* reset the page table */ - zap_low_mappings(); + swapper_pg_dir[0] = orig_swapper_pg_dir0; + local_flush_tlb(); +#ifdef CONFIG_M486 + free_page((unsigned long)page_table_copies); +#endif if (cpu_booted_map) { VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n", @@ -739,6 +772,12 @@ initialize_secondary(void) set_current(hard_get_current()); #endif + /* + * switch to the per CPU GDT we already set up + * in do_boot_cpu() + */ + cpu_set_gdt(current_thread_info()->cpu); + /* * We don't actually need to load the full TSS, * basically just the stack pointer and the eip. @@ -1043,11 +1082,20 @@ smp_call_function_interrupt(void) } } -static int -__smp_call_function_mask (void (*func) (void *info), void *info, int retry, - int wait, __u32 mask) +/* Call this function on all CPUs using the function_interrupt above + The function to run. This must be fast and non-blocking. + An arbitrary pointer to pass to the function. + If true, keep retrying until ready. + If true, wait until function has completed on other CPUs. + [RETURNS] 0 on success, else a negative status code. Does not return until + remote CPUs are nearly ready to execute <> or are or have executed. +*/ +int +smp_call_function (void (*func) (void *info), void *info, int retry, + int wait) { struct call_data_struct data; + __u32 mask = cpus_addr(cpu_online_map)[0]; mask &= ~(1< The function to run. This must be fast and non-blocking. - An arbitrary pointer to pass to the function. - If true, keep retrying until ready. - If true, wait until function has completed on other CPUs. - [RETURNS] 0 on success, else a negative status code. Does not return until - remote CPUs are nearly ready to execute <> or are or have executed. -*/ -int -smp_call_function(void (*func) (void *info), void *info, int retry, - int wait) -{ - __u32 mask = cpus_addr(cpu_online_map)[0]; - - return __smp_call_function_mask(func, info, retry, wait, mask); -} EXPORT_SYMBOL(smp_call_function); -/* - * smp_call_function_single - Run a function on another CPU - * @func: The function to run. This must be fast and non-blocking. - * @info: An arbitrary pointer to pass to the function. - * @nonatomic: Currently unused. - * @wait: If true, wait until function has completed on other CPUs. - * - * Retrurns 0 on success, else a negative status code. - * - * Does not return until the remote CPU is nearly ready to execute - * or is or has executed. - */ - -int -smp_call_function_single(int cpu, void (*func) (void *info), void *info, - int nonatomic, int wait) -{ - __u32 mask = 1 << cpu; - - return __smp_call_function_mask(func, info, nonatomic, wait, mask); -} -EXPORT_SYMBOL(smp_call_function_single); - /* Sorry about the name. In an APIC based system, the APICs * themselves are programmed to send a timer interrupt. This is used * by linux to reschedule the processor. Voyager doesn't have this, diff --git a/trunk/arch/i386/mach-voyager/voyager_thread.c b/trunk/arch/i386/mach-voyager/voyager_thread.c index b4b24e0e45e1..f39887359e8e 100644 --- a/trunk/arch/i386/mach-voyager/voyager_thread.c +++ b/trunk/arch/i386/mach-voyager/voyager_thread.c @@ -18,21 +18,39 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include #include #include +#define THREAD_NAME "kvoyagerd" -struct task_struct *voyager_thread; -static __u8 set_timeout; +/* external variables */ +int kvoyagerd_running = 0; +DECLARE_MUTEX_LOCKED(kvoyagerd_sem); + +static int thread(void *); + +static __u8 set_timeout = 0; + +/* Start the machine monitor thread. Return 1 if OK, 0 if fail */ +static int __init +voyager_thread_start(void) +{ + if(kernel_thread(thread, NULL, CLONE_KERNEL) < 0) { + /* This is serious, but not fatal */ + printk(KERN_ERR "Voyager: Failed to create system monitor thread!!!\n"); + return 1; + } + return 0; +} static int execute(const char *string) @@ -92,15 +110,31 @@ check_continuing_condition(void) } } +static void +wakeup(unsigned long unused) +{ + up(&kvoyagerd_sem); +} + static int thread(void *unused) { - printk(KERN_NOTICE "Voyager starting monitor thread\n"); + struct timer_list wakeup_timer; + + kvoyagerd_running = 1; - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(set_timeout ? HZ : MAX_SCHEDULE_TIMEOUT); + daemonize(THREAD_NAME); + set_timeout = 0; + + init_timer(&wakeup_timer); + + sigfillset(¤t->blocked); + + printk(KERN_NOTICE "Voyager starting monitor thread\n"); + + for(;;) { + down_interruptible(&kvoyagerd_sem); VDEBUG(("Voyager Daemon awoken\n")); if(voyager_status.request_from_kernel == 0) { /* probably awoken from timeout */ @@ -109,26 +143,20 @@ thread(void *unused) check_from_kernel(); voyager_status.request_from_kernel = 0; } + if(set_timeout) { + del_timer(&wakeup_timer); + wakeup_timer.expires = HZ + jiffies; + wakeup_timer.function = wakeup; + add_timer(&wakeup_timer); + } } } -static int __init -voyager_thread_start(void) -{ - voyager_thread = kthread_run(thread, NULL, "kvoyagerd"); - if (IS_ERR(voyager_thread)) { - printk(KERN_ERR "Voyager: Failed to create system monitor thread.\n"); - return PTR_ERR(voyager_thread); - } - return 0; -} - - static void __exit voyager_thread_stop(void) { - kthread_stop(voyager_thread); + /* FIXME: do nothing at the moment */ } module_init(voyager_thread_start); -module_exit(voyager_thread_stop); +//module_exit(voyager_thread_stop); diff --git a/trunk/arch/i386/mm/fault.c b/trunk/arch/i386/mm/fault.c index 29d7d61543a1..b8c4e259fc8b 100644 --- a/trunk/arch/i386/mm/fault.c +++ b/trunk/arch/i386/mm/fault.c @@ -14,20 +14,19 @@ #include #include #include +#include #include #include #include #include /* For unblank_screen() */ #include -#include /* for max_low_pfn */ -#include #include #include #include -#include #include #include +#include #include extern void die(const char *,struct pt_regs *,long); @@ -302,6 +301,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, struct mm_struct *mm; struct vm_area_struct * vma; unsigned long address; + unsigned long page; int write, si_code; /* get the address */ @@ -510,9 +510,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, bust_spinlocks(1); if (oops_may_print()) { - __typeof__(pte_val(__pte(0))) page; - -#ifdef CONFIG_X86_PAE + #ifdef CONFIG_X86_PAE if (error_code & 16) { pte_t *pte = lookup_address(address); @@ -521,7 +519,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, "NX-protected page - exploit attempt? " "(uid: %d)\n", current->uid); } -#endif + #endif if (address < PAGE_SIZE) printk(KERN_ALERT "BUG: unable to handle kernel NULL " "pointer dereference"); @@ -531,38 +529,25 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, printk(" at virtual address %08lx\n",address); printk(KERN_ALERT " printing eip:\n"); printk("%08lx\n", regs->eip); - - page = read_cr3(); - page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT]; -#ifdef CONFIG_X86_PAE - printk(KERN_ALERT "*pdpt = %016Lx\n", page); - if ((page >> PAGE_SHIFT) < max_low_pfn - && page & _PAGE_PRESENT) { - page &= PAGE_MASK; - page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT) - & (PTRS_PER_PMD - 1)]; - printk(KERN_ALERT "*pde = %016Lx\n", page); - page &= ~_PAGE_NX; - } -#else + } + page = read_cr3(); + page = ((unsigned long *) __va(page))[address >> 22]; + if (oops_may_print()) printk(KERN_ALERT "*pde = %08lx\n", page); -#endif - - /* - * We must not directly access the pte in the highpte - * case if the page table is located in highmem. - * And let's rather not kmap-atomic the pte, just in case - * it's allocated already. - */ - if ((page >> PAGE_SHIFT) < max_low_pfn - && (page & _PAGE_PRESENT)) { - page &= PAGE_MASK; - page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT) - & (PTRS_PER_PTE - 1)]; - printk(KERN_ALERT "*pte = %0*Lx\n", sizeof(page)*2, (u64)page); - } + /* + * We must not directly access the pte in the highpte + * case, the page table might be allocated in highmem. + * And lets rather not kmap-atomic the pte, just in case + * it's allocated already. + */ +#ifndef CONFIG_HIGHPTE + if ((page & 1) && oops_may_print()) { + page &= PAGE_MASK; + address &= 0x003ff000; + page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; + printk(KERN_ALERT "*pte = %08lx\n", page); } - +#endif tsk->thread.cr2 = address; tsk->thread.trap_no = 14; tsk->thread.error_code = error_code; @@ -603,6 +588,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk); } +#ifndef CONFIG_X86_PAE void vmalloc_sync_all(void) { /* @@ -615,9 +601,6 @@ void vmalloc_sync_all(void) static unsigned long start = TASK_SIZE; unsigned long address; - if (SHARED_KERNEL_PMD) - return; - BUILD_BUG_ON(TASK_SIZE & ~PGDIR_MASK); for (address = start; address >= TASK_SIZE; address += PGDIR_SIZE) { if (!test_bit(pgd_index(address), insync)) { @@ -640,3 +623,4 @@ void vmalloc_sync_all(void) start = address + PGDIR_SIZE; } } +#endif diff --git a/trunk/arch/i386/mm/highmem.c b/trunk/arch/i386/mm/highmem.c index ad8d86cc683e..ac70d09df7ee 100644 --- a/trunk/arch/i386/mm/highmem.c +++ b/trunk/arch/i386/mm/highmem.c @@ -26,7 +26,7 @@ void kunmap(struct page *page) * However when holding an atomic kmap is is not legal to sleep, so atomic * kmaps are appropriate for short, tight code paths only. */ -void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) +void *kmap_atomic(struct page *page, enum km_type type) { enum fixed_addresses idx; unsigned long vaddr; @@ -41,17 +41,12 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) return page_address(page); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); - set_pte(kmap_pte-idx, mk_pte(page, prot)); + set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); arch_flush_lazy_mmu_mode(); return (void*) vaddr; } -void *kmap_atomic(struct page *page, enum km_type type) -{ - return kmap_atomic_prot(page, type, kmap_prot); -} - void kunmap_atomic(void *kvaddr, enum km_type type) { unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; @@ -72,7 +67,6 @@ void kunmap_atomic(void *kvaddr, enum km_type type) #endif } - arch_flush_lazy_mmu_mode(); pagefault_enable(); } diff --git a/trunk/arch/i386/mm/hugetlbpage.c b/trunk/arch/i386/mm/hugetlbpage.c index efdf95ac8031..34728e4afe48 100644 --- a/trunk/arch/i386/mm/hugetlbpage.c +++ b/trunk/arch/i386/mm/hugetlbpage.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -366,12 +367,6 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, if (len > TASK_SIZE) return -ENOMEM; - if (flags & MAP_FIXED) { - if (prepare_hugepage_range(addr, len, pgoff)) - return -EINVAL; - return addr; - } - if (addr) { addr = ALIGN(addr, HPAGE_SIZE); vma = find_vma(mm, addr); diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c index c50782efa5c3..ae436882af7a 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -43,7 +42,6 @@ #include #include #include -#include unsigned int __VMALLOC_RESERVE = 128 << 20; @@ -63,18 +61,17 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd) pmd_t *pmd_table; #ifdef CONFIG_X86_PAE - if (!(pgd_val(*pgd) & _PAGE_PRESENT)) { - pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); - - paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT); - set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); - pud = pud_offset(pgd, 0); - if (pmd_table != pmd_offset(pud, 0)) - BUG(); - } -#endif + pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); + paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT); + set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); + pud = pud_offset(pgd, 0); + if (pmd_table != pmd_offset(pud, 0)) + BUG(); +#else pud = pud_offset(pgd, 0); pmd_table = pmd_offset(pud, 0); +#endif + return pmd_table; } @@ -84,12 +81,14 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd) */ static pte_t * __init one_page_table_init(pmd_t *pmd) { - if (!(pmd_val(*pmd) & _PAGE_PRESENT)) { + if (pmd_none(*pmd)) { pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); - paravirt_alloc_pt(__pa(page_table) >> PAGE_SHIFT); set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); - BUG_ON(page_table != pte_offset_kernel(pmd, 0)); + if (page_table != pte_offset_kernel(pmd, 0)) + BUG(); + + return page_table; } return pte_offset_kernel(pmd, 0); @@ -109,6 +108,7 @@ static pte_t * __init one_page_table_init(pmd_t *pmd) static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base) { pgd_t *pgd; + pud_t *pud; pmd_t *pmd; int pgd_idx, pmd_idx; unsigned long vaddr; @@ -119,10 +119,13 @@ static void __init page_table_range_init (unsigned long start, unsigned long end pgd = pgd_base + pgd_idx; for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) { - pmd = one_md_table_init(pgd); - pmd = pmd + pmd_index(vaddr); + if (pgd_none(*pgd)) + one_md_table_init(pgd); + pud = pud_offset(pgd, vaddr); + pmd = pmd_offset(pud, vaddr); for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { - one_page_table_init(pmd); + if (pmd_none(*pmd)) + one_page_table_init(pmd); vaddr += PMD_SIZE; } @@ -164,22 +167,20 @@ static void __init kernel_physical_mapping_init(pgd_t *pgd_base) /* Map with big pages if possible, otherwise create normal page tables. */ if (cpu_has_pse) { unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1; + if (is_kernel_text(address) || is_kernel_text(address2)) set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC)); else set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE)); - pfn += PTRS_PER_PTE; } else { pte = one_page_table_init(pmd); - for (pte_ofs = 0; - pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; - pte++, pfn++, pte_ofs++, address += PAGE_SIZE) { - if (is_kernel_text(address)) - set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); - else - set_pte(pte, pfn_pte(pfn, PAGE_KERNEL)); + for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) { + if (is_kernel_text(address)) + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); + else + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL)); } } } @@ -336,78 +337,24 @@ extern void __init remap_numa_kva(void); #define remap_numa_kva() do {} while (0) #endif -void __init native_pagetable_setup_start(pgd_t *base) +static void __init pagetable_init (void) { + unsigned long vaddr; + pgd_t *pgd_base = swapper_pg_dir; + #ifdef CONFIG_X86_PAE int i; - - /* - * Init entries of the first-level page table to the - * zero page, if they haven't already been set up. - * - * In a normal native boot, we'll be running on a - * pagetable rooted in swapper_pg_dir, but not in PAE - * mode, so this will end up clobbering the mappings - * for the lower 24Mbytes of the address space, - * without affecting the kernel address space. - */ - for (i = 0; i < USER_PTRS_PER_PGD; i++) - set_pgd(&base[i], - __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); - - /* Make sure kernel address space is empty so that a pagetable - will be allocated for it. */ - memset(&base[USER_PTRS_PER_PGD], 0, - KERNEL_PGD_PTRS * sizeof(pgd_t)); + /* Init entries of the first-level page table to the zero page */ + for (i = 0; i < PTRS_PER_PGD; i++) + set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); #else paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT); #endif -} - -void __init native_pagetable_setup_done(pgd_t *base) -{ -#ifdef CONFIG_X86_PAE - /* - * Add low memory identity-mappings - SMP needs it when - * starting up on an AP from real-mode. In the non-PAE - * case we already have these mappings through head.S. - * All user-space mappings are explicitly cleared after - * SMP startup. - */ - set_pgd(&base[0], base[USER_PTRS_PER_PGD]); -#endif -} - -/* - * Build a proper pagetable for the kernel mappings. Up until this - * point, we've been running on some set of pagetables constructed by - * the boot process. - * - * If we're booting on native hardware, this will be a pagetable - * constructed in arch/i386/kernel/head.S, and not running in PAE mode - * (even if we'll end up running in PAE). The root of the pagetable - * will be swapper_pg_dir. - * - * If we're booting paravirtualized under a hypervisor, then there are - * more options: we may already be running PAE, and the pagetable may - * or may not be based in swapper_pg_dir. In any case, - * paravirt_pagetable_setup_start() will set up swapper_pg_dir - * appropriately for the rest of the initialization to work. - * - * In general, pagetable_init() assumes that the pagetable may already - * be partially populated, and so it avoids stomping on any existing - * mappings. - */ -static void __init pagetable_init (void) -{ - unsigned long vaddr, end; - pgd_t *pgd_base = swapper_pg_dir; - - paravirt_pagetable_setup_start(pgd_base); /* Enable PSE if available */ - if (cpu_has_pse) + if (cpu_has_pse) { set_in_cr4(X86_CR4_PSE); + } /* Enable PGE if available */ if (cpu_has_pge) { @@ -424,12 +371,20 @@ static void __init pagetable_init (void) * created - mappings will be set by set_fixmap(): */ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; - end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK; - page_table_range_init(vaddr, end, pgd_base); + page_table_range_init(vaddr, 0, pgd_base); permanent_kmaps_init(pgd_base); - paravirt_pagetable_setup_done(pgd_base); +#ifdef CONFIG_X86_PAE + /* + * Add low memory identity-mappings - SMP needs it when + * starting up on an AP from real-mode. In the non-PAE + * case we already have these mappings through head.S. + * All user-space mappings are explicitly cleared after + * SMP startup. + */ + set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]); +#endif } #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP) @@ -745,31 +700,24 @@ struct kmem_cache *pmd_cache; void __init pgtable_cache_init(void) { - size_t pgd_size = PTRS_PER_PGD*sizeof(pgd_t); - if (PTRS_PER_PMD > 1) { pmd_cache = kmem_cache_create("pmd", PTRS_PER_PMD*sizeof(pmd_t), PTRS_PER_PMD*sizeof(pmd_t), - SLAB_PANIC, + 0, pmd_ctor, NULL); - if (!SHARED_KERNEL_PMD) { - /* If we're in PAE mode and have a non-shared - kernel pmd, then the pgd size must be a - page size. This is because the pgd_list - links through the page structure, so there - can only be one pgd per page for this to - work. */ - pgd_size = PAGE_SIZE; - } + if (!pmd_cache) + panic("pgtable_cache_init(): cannot create pmd cache"); } pgd_cache = kmem_cache_create("pgd", - pgd_size, - pgd_size, - SLAB_PANIC, + PTRS_PER_PGD*sizeof(pgd_t), + PTRS_PER_PGD*sizeof(pgd_t), + 0, pgd_ctor, - (!SHARED_KERNEL_PMD) ? pgd_dtor : NULL); + PTRS_PER_PMD == 1 ? pgd_dtor : NULL); + if (!pgd_cache) + panic("pgtable_cache_init(): Cannot create pgd cache"); } /* @@ -803,25 +751,13 @@ static int noinline do_test_wp_bit(void) void mark_rodata_ro(void) { - unsigned long start = PFN_ALIGN(_text); - unsigned long size = PFN_ALIGN(_etext) - start; + unsigned long addr = (unsigned long)__start_rodata; -#ifdef CONFIG_HOTPLUG_CPU - /* It must still be possible to apply SMP alternatives. */ - if (num_possible_cpus() <= 1) -#endif - { - change_page_attr(virt_to_page(start), - size >> PAGE_SHIFT, PAGE_KERNEL_RX); - printk("Write protecting the kernel text: %luk\n", size >> 10); - } + for (; addr < (unsigned long)__end_rodata; addr += PAGE_SIZE) + change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO); - start += size; - size = (unsigned long)__end_rodata - start; - change_page_attr(virt_to_page(start), - size >> PAGE_SHIFT, PAGE_KERNEL_RO); - printk("Write protecting the kernel read-only data: %luk\n", - size >> 10); + printk("Write protecting the kernel read-only data: %uk\n", + (__end_rodata - __start_rodata) >> 10); /* * change_page_attr() requires a global_flush_tlb() call after it. @@ -844,7 +780,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) free_page(addr); totalram_pages++; } - printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); + printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); } void free_initmem(void) diff --git a/trunk/arch/i386/mm/pageattr.c b/trunk/arch/i386/mm/pageattr.c index 47bd477c8ecc..412ebbd8adb0 100644 --- a/trunk/arch/i386/mm/pageattr.c +++ b/trunk/arch/i386/mm/pageattr.c @@ -91,7 +91,7 @@ static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) unsigned long flags; set_pte_atomic(kpte, pte); /* change init_mm */ - if (SHARED_KERNEL_PMD) + if (PTRS_PER_PMD > 1) return; spin_lock_irqsave(&pgd_lock, flags); @@ -142,7 +142,7 @@ __change_page_attr(struct page *page, pgprot_t prot) return -EINVAL; kpte_page = virt_to_page(kpte); if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { - if (!pte_huge(*kpte)) { + if ((pte_val(*kpte) & _PAGE_PSE) == 0) { set_pte_atomic(kpte, mk_pte(page, prot)); } else { pgprot_t ref_prot; @@ -158,7 +158,7 @@ __change_page_attr(struct page *page, pgprot_t prot) kpte_page = split; } page_private(kpte_page)++; - } else if (!pte_huge(*kpte)) { + } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL)); BUG_ON(page_private(kpte_page) == 0); page_private(kpte_page)--; diff --git a/trunk/arch/i386/mm/pgtable.c b/trunk/arch/i386/mm/pgtable.c index 9a96c1647428..fa0cfbd551e1 100644 --- a/trunk/arch/i386/mm/pgtable.c +++ b/trunk/arch/i386/mm/pgtable.c @@ -144,8 +144,10 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) } static int fixmaps; +#ifndef CONFIG_COMPAT_VDSO unsigned long __FIXADDR_TOP = 0xfffff000; EXPORT_SYMBOL(__FIXADDR_TOP); +#endif void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags) { @@ -171,8 +173,12 @@ void reserve_top_address(unsigned long reserve) BUG_ON(fixmaps > 0); printk(KERN_INFO "Reserving virtual address space above 0x%08x\n", (int)-reserve); +#ifdef CONFIG_COMPAT_VDSO + BUG_ON(reserve != 0); +#else __FIXADDR_TOP = -reserve - PAGE_SIZE; __VMALLOC_RESERVE += reserve; +#endif } pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) @@ -232,92 +238,42 @@ static inline void pgd_list_del(pgd_t *pgd) set_page_private(next, (unsigned long)pprev); } -#if (PTRS_PER_PMD == 1) -/* Non-PAE pgd constructor */ void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) { unsigned long flags; - /* !PAE, no pagetable sharing */ - memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); - - spin_lock_irqsave(&pgd_lock, flags); + if (PTRS_PER_PMD == 1) { + memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); + spin_lock_irqsave(&pgd_lock, flags); + } - /* must happen under lock */ clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, KERNEL_PGD_PTRS); + + if (PTRS_PER_PMD > 1) + return; + + /* must happen under lock */ paravirt_alloc_pd_clone(__pa(pgd) >> PAGE_SHIFT, - __pa(swapper_pg_dir) >> PAGE_SHIFT, - USER_PTRS_PER_PGD, - KERNEL_PGD_PTRS); + __pa(swapper_pg_dir) >> PAGE_SHIFT, + USER_PTRS_PER_PGD, PTRS_PER_PGD - USER_PTRS_PER_PGD); + pgd_list_add(pgd); spin_unlock_irqrestore(&pgd_lock, flags); } -#else /* PTRS_PER_PMD > 1 */ -/* PAE pgd constructor */ -void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) -{ - /* PAE, kernel PMD may be shared */ - - if (SHARED_KERNEL_PMD) { - clone_pgd_range((pgd_t *)pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - KERNEL_PGD_PTRS); - } else { - unsigned long flags; - - memset(pgd, 0, USER_PTRS_PER_PGD*sizeof(pgd_t)); - spin_lock_irqsave(&pgd_lock, flags); - pgd_list_add(pgd); - spin_unlock_irqrestore(&pgd_lock, flags); - } -} -#endif /* PTRS_PER_PMD */ +/* never called when PTRS_PER_PMD > 1 */ void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused) { unsigned long flags; /* can be called from interrupt context */ - BUG_ON(SHARED_KERNEL_PMD); - paravirt_release_pd(__pa(pgd) >> PAGE_SHIFT); spin_lock_irqsave(&pgd_lock, flags); pgd_list_del(pgd); spin_unlock_irqrestore(&pgd_lock, flags); } -#define UNSHARED_PTRS_PER_PGD \ - (SHARED_KERNEL_PMD ? USER_PTRS_PER_PGD : PTRS_PER_PGD) - -/* If we allocate a pmd for part of the kernel address space, then - make sure its initialized with the appropriate kernel mappings. - Otherwise use a cached zeroed pmd. */ -static pmd_t *pmd_cache_alloc(int idx) -{ - pmd_t *pmd; - - if (idx >= USER_PTRS_PER_PGD) { - pmd = (pmd_t *)__get_free_page(GFP_KERNEL); - - if (pmd) - memcpy(pmd, - (void *)pgd_page_vaddr(swapper_pg_dir[idx]), - sizeof(pmd_t) * PTRS_PER_PMD); - } else - pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); - - return pmd; -} - -static void pmd_cache_free(pmd_t *pmd, int idx) -{ - if (idx >= USER_PTRS_PER_PGD) - free_page((unsigned long)pmd); - else - kmem_cache_free(pmd_cache, pmd); -} - pgd_t *pgd_alloc(struct mm_struct *mm) { int i; @@ -326,12 +282,10 @@ pgd_t *pgd_alloc(struct mm_struct *mm) if (PTRS_PER_PMD == 1 || !pgd) return pgd; - for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) { - pmd_t *pmd = pmd_cache_alloc(i); - + for (i = 0; i < USER_PTRS_PER_PGD; ++i) { + pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL); if (!pmd) goto out_oom; - paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT); set_pgd(&pgd[i], __pgd(1 + __pa(pmd))); } @@ -342,7 +296,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm) pgd_t pgdent = pgd[i]; void* pmd = (void *)__va(pgd_val(pgdent)-1); paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT); - pmd_cache_free(pmd, i); + kmem_cache_free(pmd_cache, pmd); } kmem_cache_free(pgd_cache, pgd); return NULL; @@ -354,11 +308,11 @@ void pgd_free(pgd_t *pgd) /* in the PAE case user pgd entries are overwritten before usage */ if (PTRS_PER_PMD > 1) - for (i = 0; i < UNSHARED_PTRS_PER_PGD; ++i) { + for (i = 0; i < USER_PTRS_PER_PGD; ++i) { pgd_t pgdent = pgd[i]; void* pmd = (void *)__va(pgd_val(pgdent)-1); paravirt_release_pd(__pa(pmd) >> PAGE_SHIFT); - pmd_cache_free(pmd, i); + kmem_cache_free(pmd_cache, pmd); } /* in the non-PAE case, free_pgtables() clears user pgd entries */ kmem_cache_free(pgd_cache, pgd); diff --git a/trunk/arch/i386/oprofile/nmi_int.c b/trunk/arch/i386/oprofile/nmi_int.c index 8e185208dfd4..8fda7be9dd4d 100644 --- a/trunk/arch/i386/oprofile/nmi_int.c +++ b/trunk/arch/i386/oprofile/nmi_int.c @@ -14,10 +14,10 @@ #include #include #include -#include #include #include #include +#include #include "op_counter.h" #include "op_x86_model.h" @@ -414,10 +414,6 @@ int __init op_nmi_init(struct oprofile_operations *ops) user space an consistent name. */ cpu_type = "x86-64/hammer"; break; - case 0x10: - model = &op_athlon_spec; - cpu_type = "x86-64/family10"; - break; } break; diff --git a/trunk/arch/i386/oprofile/nmi_timer_int.c b/trunk/arch/i386/oprofile/nmi_timer_int.c index 1418e36ae7ab..abf0ba52a635 100644 --- a/trunk/arch/i386/oprofile/nmi_timer_int.c +++ b/trunk/arch/i386/oprofile/nmi_timer_int.c @@ -12,11 +12,12 @@ #include #include #include -#include + #include #include #include +#include static int profile_timer_exceptions_notify(struct notifier_block *self, unsigned long val, void *data) diff --git a/trunk/arch/i386/pci/fixup.c b/trunk/arch/i386/pci/fixup.c index b62eafb997bc..8053b17ab647 100644 --- a/trunk/arch/i386/pci/fixup.c +++ b/trunk/arch/i386/pci/fixup.c @@ -354,7 +354,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); } } -DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); /* * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. diff --git a/trunk/arch/i386/pci/i386.c b/trunk/arch/i386/pci/i386.c index bcd2f94b732c..43005f044424 100644 --- a/trunk/arch/i386/pci/i386.c +++ b/trunk/arch/i386/pci/i386.c @@ -246,8 +246,8 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) continue; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available " - "because of resource %d collisions\n", - pci_name(dev), idx); + "because of resource collisions\n", + pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) diff --git a/trunk/arch/i386/pci/init.c b/trunk/arch/i386/pci/init.c index 1cf11af96de2..b21b6da8ab1d 100644 --- a/trunk/arch/i386/pci/init.c +++ b/trunk/arch/i386/pci/init.c @@ -6,7 +6,7 @@ in the right sequence from here. */ static __init int pci_access_init(void) { - int type __attribute__((unused)) = 0; + int type = 0; #ifdef CONFIG_PCI_DIRECT type = pci_direct_probe(); diff --git a/trunk/arch/i386/pci/mmconfig-shared.c b/trunk/arch/i386/pci/mmconfig-shared.c index c7cabeed4d7b..747d8c63b0c4 100644 --- a/trunk/arch/i386/pci/mmconfig-shared.c +++ b/trunk/arch/i386/pci/mmconfig-shared.c @@ -60,19 +60,14 @@ static const char __init *pci_mmcfg_e7520(void) u32 win; pci_conf1_read(0, 0, PCI_DEVFN(0,0), 0xce, 2, &win); - win = win & 0xf000; - if(win == 0x0000 || win == 0xf000) - pci_mmcfg_config_num = 0; - else { - pci_mmcfg_config_num = 1; - pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); - if (!pci_mmcfg_config) - return NULL; - pci_mmcfg_config[0].address = win << 16; - pci_mmcfg_config[0].pci_segment = 0; - pci_mmcfg_config[0].start_bus_number = 0; - pci_mmcfg_config[0].end_bus_number = 255; - } + pci_mmcfg_config_num = 1; + pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); + if (!pci_mmcfg_config) + return NULL; + pci_mmcfg_config[0].address = (win & 0xf000) << 16; + pci_mmcfg_config[0].pci_segment = 0; + pci_mmcfg_config[0].start_bus_number = 0; + pci_mmcfg_config[0].end_bus_number = 255; return "Intel Corporation E7520 Memory Controller Hub"; } @@ -113,10 +108,6 @@ static const char __init *pci_mmcfg_intel_945(void) if ((pciexbar & mask) & 0x0fffffffU) pci_mmcfg_config_num = 0; - /* Don't hit the APIC registers and their friends */ - if ((pciexbar & mask) >= 0xf0000000U) - pci_mmcfg_config_num = 0; - if (pci_mmcfg_config_num) { pci_mmcfg_config = kzalloc(sizeof(pci_mmcfg_config[0]), GFP_KERNEL); if (!pci_mmcfg_config) diff --git a/trunk/arch/i386/power/cpu.c b/trunk/arch/i386/power/cpu.c index 998fd3ec0d68..2c15500f8713 100644 --- a/trunk/arch/i386/power/cpu.c +++ b/trunk/arch/i386/power/cpu.c @@ -21,7 +21,6 @@ unsigned long saved_context_eflags; void __save_processor_state(struct saved_context *ctxt) { - mtrr_save_fixed_ranges(NULL); kernel_fpu_begin(); /* diff --git a/trunk/arch/i386/power/suspend.c b/trunk/arch/i386/power/suspend.c index a0020b913f31..db5e98d2eb73 100644 --- a/trunk/arch/i386/power/suspend.c +++ b/trunk/arch/i386/power/suspend.c @@ -16,9 +16,6 @@ /* Defined in arch/i386/power/swsusp.S */ extern int restore_image(void); -/* References to section boundaries */ -extern const void __nosave_begin, __nosave_end; - /* Pointer to the temporary resume page tables */ pgd_t *resume_pg_dir; @@ -159,14 +156,3 @@ int swsusp_arch_resume(void) restore_image(); return 0; } - -/* - * pfn_is_nosave - check if given pfn is in the 'nosave' section - */ - -int pfn_is_nosave(unsigned long pfn) -{ - unsigned long nosave_begin_pfn = __pa_symbol(&__nosave_begin) >> PAGE_SHIFT; - unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT; - return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); -} diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index e23af4b6ae8c..e19185d26554 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -14,7 +14,6 @@ config IA64 select PCI if (!IA64_HP_SIM) select ACPI if (!IA64_HP_SIM) select PM if (!IA64_HP_SIM) - select ARCH_SUPPORTS_MSI default y help The Itanium Processor Family is Intel's 64-bit successor to @@ -439,16 +438,6 @@ config IA64_PALINFO To use this option, you have to ensure that the "/proc file system support" (CONFIG_PROC_FS) is enabled, too. -config IA64_MC_ERR_INJECT - tristate "MC error injection support" - help - Selets whether support for MC error injection. By enabling the - support, kernel provide sysfs interface for user application to - call MC error injection PAL procedure to inject various errors. - This is a useful tool for MCA testing. - - If you're unsure, do not select this option. - config SGI_SN def_bool y if (IA64_SGI_SN2 || IA64_GENERIC) diff --git a/trunk/arch/ia64/defconfig b/trunk/arch/ia64/defconfig index 90bd9601cdde..153bfdc0182d 100644 --- a/trunk/arch/ia64/defconfig +++ b/trunk/arch/ia64/defconfig @@ -164,7 +164,6 @@ CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y -# CONFIG_MC_ERR_INJECT is not set CONFIG_SGI_SN=y # CONFIG_IA64_ESI is not set diff --git a/trunk/arch/ia64/hp/sim/boot/fw-emu.c b/trunk/arch/ia64/hp/sim/boot/fw-emu.c index 300acd913d9c..5a0a7afcfc3a 100644 --- a/trunk/arch/ia64/hp/sim/boot/fw-emu.c +++ b/trunk/arch/ia64/hp/sim/boot/fw-emu.c @@ -287,7 +287,7 @@ sys_fw_init (const char *args, int arglen) memset(efi_systab, 0, sizeof(efi_systab)); efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE; - efi_systab->hdr.revision = ((1 << 16) | 00); + efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION; efi_systab->hdr.headersize = sizeof(efi_systab->hdr); efi_systab->fw_vendor = __pa("H\0e\0w\0l\0e\0t\0t\0-\0P\0a\0c\0k\0a\0r\0d\0\0"); efi_systab->fw_revision = 1; diff --git a/trunk/arch/ia64/ia32/ia32_ldt.c b/trunk/arch/ia64/ia32/ia32_ldt.c index 16d51c146849..a152738c7d0d 100644 --- a/trunk/arch/ia64/ia32/ia32_ldt.c +++ b/trunk/arch/ia64/ia32/ia32_ldt.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/ia64/ia32/ia32_signal.c b/trunk/arch/ia64/ia32/ia32_signal.c index 10510e585204..b3355a9ca2c3 100644 --- a/trunk/arch/ia64/ia32/ia32_signal.c +++ b/trunk/arch/ia64/ia32/ia32_signal.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/ia32/ia32_support.c b/trunk/arch/ia64/ia32/ia32_support.c index beea7a0b9dc6..6af400a12ca1 100644 --- a/trunk/arch/ia64/ia32/ia32_support.c +++ b/trunk/arch/ia64/ia32/ia32_support.c @@ -252,8 +252,10 @@ ia32_init (void) extern struct kmem_cache *partial_page_cachep; partial_page_cachep = kmem_cache_create("partial_page_cache", - sizeof(struct partial_page), - 0, SLAB_PANIC, NULL, NULL); + sizeof(struct partial_page), 0, 0, + NULL, NULL); + if (!partial_page_cachep) + panic("Cannot create partial page SLAB cache"); } #endif return 0; diff --git a/trunk/arch/ia64/kernel/Makefile b/trunk/arch/ia64/kernel/Makefile index 33e5a598672d..098ee605bf5e 100644 --- a/trunk/arch/ia64/kernel/Makefile +++ b/trunk/arch/ia64/kernel/Makefile @@ -34,7 +34,6 @@ obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_PCI_MSI) += msi_ia64.o mca_recovery-y += mca_drv.o mca_drv_asm.o -obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o obj-$(CONFIG_IA64_ESI) += esi.o ifneq ($(CONFIG_IA64_ESI),) diff --git a/trunk/arch/ia64/kernel/crash.c b/trunk/arch/ia64/kernel/crash.c index aeb79fb28f0b..80a94e707827 100644 --- a/trunk/arch/ia64/kernel/crash.c +++ b/trunk/arch/ia64/kernel/crash.c @@ -16,8 +16,8 @@ #include #include #include -#include +#include #include int kdump_status[NR_CPUS]; @@ -74,7 +74,7 @@ crash_save_this_cpu(void) buf = (u64 *) per_cpu_ptr(crash_notes, cpu); if (!buf) return; - buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS, prstatus, + buf = append_elf_note(buf, "CORE", NT_PRSTATUS, prstatus, sizeof(*prstatus)); final_note(buf); } diff --git a/trunk/arch/ia64/kernel/efi.c b/trunk/arch/ia64/kernel/efi.c index 75ec3478d8a2..f45f91d38cab 100644 --- a/trunk/arch/ia64/kernel/efi.c +++ b/trunk/arch/ia64/kernel/efi.c @@ -445,11 +445,11 @@ efi_init (void) panic("Woah! Can't find EFI system table.\n"); if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) panic("Woah! EFI system table signature incorrect\n"); - if ((efi.systab->hdr.revision >> 16) == 0) - printk(KERN_WARNING "Warning: EFI system table version " - "%d.%02d, expected 1.00 or greater\n", - efi.systab->hdr.revision >> 16, - efi.systab->hdr.revision & 0xffff); + if ((efi.systab->hdr.revision ^ EFI_SYSTEM_TABLE_REVISION) >> 16 != 0) + printk(KERN_WARNING "Warning: EFI system table major version mismatch: " + "got %d.%02d, expected %d.%02d\n", + efi.systab->hdr.revision >> 16, efi.systab->hdr.revision & 0xffff, + EFI_SYSTEM_TABLE_REVISION >> 16, EFI_SYSTEM_TABLE_REVISION & 0xffff); config_tables = __va(efi.systab->tables); @@ -660,29 +660,6 @@ efi_memory_descriptor (unsigned long phys_addr) return NULL; } -static int -efi_memmap_intersects (unsigned long phys_addr, unsigned long size) -{ - void *efi_map_start, *efi_map_end, *p; - efi_memory_desc_t *md; - u64 efi_desc_size; - unsigned long end; - - efi_map_start = __va(ia64_boot_param->efi_memmap); - efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; - efi_desc_size = ia64_boot_param->efi_memdesc_size; - - end = phys_addr + size; - - for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { - md = p; - - if (md->phys_addr < end && efi_md_end(md) > phys_addr) - return 1; - } - return 0; -} - u32 efi_mem_type (unsigned long phys_addr) { @@ -789,28 +766,11 @@ valid_phys_addr_range (unsigned long phys_addr, unsigned long size) int valid_mmap_phys_addr_range (unsigned long pfn, unsigned long size) { - unsigned long phys_addr = pfn << PAGE_SHIFT; - u64 attr; - - attr = efi_mem_attribute(phys_addr, size); - /* - * /dev/mem mmap uses normal user pages, so we don't need the entire - * granule, but the entire region we're mapping must support the same - * attribute. + * MMIO regions are often missing from the EFI memory map. + * We must allow mmap of them for programs like X, so we + * currently can't do any useful validation. */ - if (attr & EFI_MEMORY_WB || attr & EFI_MEMORY_UC) - return 1; - - /* - * Intel firmware doesn't tell us about all the MMIO regions, so - * in general we have to allow mmap requests. But if EFI *does* - * tell us about anything inside this region, we should deny it. - * The user can always map a smaller region to avoid the overlap. - */ - if (efi_memmap_intersects(phys_addr, size)) - return 0; - return 1; } diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index 55fd2d5471e1..e7873eeae448 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -767,7 +767,7 @@ ENTRY(ia64_leave_syscall) ld8.fill r15=[r3] // M0|1 restore r15 mov b6=r18 // I0 restore b6 - LOAD_PHYS_STACK_REG_SIZE(r17) + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A mov f9=f0 // F clear f9 (pKStk) br.cond.dpnt.many skip_rbs_switch // B @@ -775,6 +775,7 @@ ENTRY(ia64_leave_syscall) shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition cover // B add current frame into dirty partition & set cr.ifs ;; +(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 mov r19=ar.bsp // M2 get new backing store pointer mov f10=f0 // F clear f10 @@ -952,7 +953,9 @@ GLOBAL_ENTRY(ia64_leave_kernel) shr.u r18=r19,16 // get byte size of existing "dirty" partition ;; mov r16=ar.bsp // get existing backing store pointer - LOAD_PHYS_STACK_REG_SIZE(r17) + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 + ;; + ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 (pKStk) br.cond.dpnt skip_rbs_switch /* diff --git a/trunk/arch/ia64/kernel/err_inject.c b/trunk/arch/ia64/kernel/err_inject.c deleted file mode 100644 index d3e9f33e8bdd..000000000000 --- a/trunk/arch/ia64/kernel/err_inject.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * err_inject.c - - * 1.) Inject errors to a processor. - * 2.) Query error injection capabilities. - * This driver along with user space code can be acting as an error - * injection tool. - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Written by: Fenghua Yu , Intel Corporation - * Copyright (C) 2006, Intel Corp. All rights reserved. - * - */ -#include -#include -#include -#include -#include - -#define ERR_INJ_DEBUG - -#define ERR_DATA_BUFFER_SIZE 3 // Three 8-byte; - -#define define_one_ro(name) \ -static SYSDEV_ATTR(name, 0444, show_##name, NULL) - -#define define_one_rw(name) \ -static SYSDEV_ATTR(name, 0644, show_##name, store_##name) - -static u64 call_start[NR_CPUS]; -static u64 phys_addr[NR_CPUS]; -static u64 err_type_info[NR_CPUS]; -static u64 err_struct_info[NR_CPUS]; -static struct { - u64 data1; - u64 data2; - u64 data3; -} __attribute__((__aligned__(16))) err_data_buffer[NR_CPUS]; -static s64 status[NR_CPUS]; -static u64 capabilities[NR_CPUS]; -static u64 resources[NR_CPUS]; - -#define show(name) \ -static ssize_t \ -show_##name(struct sys_device *dev, char *buf) \ -{ \ - u32 cpu=dev->id; \ - return sprintf(buf, "%lx\n", name[cpu]); \ -} - -#define store(name) \ -static ssize_t \ -store_##name(struct sys_device *dev, const char *buf, size_t size) \ -{ \ - unsigned int cpu=dev->id; \ - name[cpu] = simple_strtoull(buf, NULL, 16); \ - return size; \ -} - -show(call_start) - -/* It's user's responsibility to call the PAL procedure on a specific - * processor. The cpu number in driver is only used for storing data. - */ -static ssize_t -store_call_start(struct sys_device *dev, const char *buf, size_t size) -{ - unsigned int cpu=dev->id; - unsigned long call_start = simple_strtoull(buf, NULL, 16); - -#ifdef ERR_INJ_DEBUG - printk(KERN_DEBUG "pal_mc_err_inject for cpu%d:\n", cpu); - printk(KERN_DEBUG "err_type_info=%lx,\n", err_type_info[cpu]); - printk(KERN_DEBUG "err_struct_info=%lx,\n", err_struct_info[cpu]); - printk(KERN_DEBUG "err_data_buffer=%lx, %lx, %lx.\n", - err_data_buffer[cpu].data1, - err_data_buffer[cpu].data2, - err_data_buffer[cpu].data3); -#endif - switch (call_start) { - case 0: /* Do nothing. */ - break; - case 1: /* Call pal_mc_error_inject in physical mode. */ - status[cpu]=ia64_pal_mc_error_inject_phys(err_type_info[cpu], - err_struct_info[cpu], - ia64_tpa(&err_data_buffer[cpu]), - &capabilities[cpu], - &resources[cpu]); - break; - case 2: /* Call pal_mc_error_inject in virtual mode. */ - status[cpu]=ia64_pal_mc_error_inject_virt(err_type_info[cpu], - err_struct_info[cpu], - ia64_tpa(&err_data_buffer[cpu]), - &capabilities[cpu], - &resources[cpu]); - break; - default: - status[cpu] = -EINVAL; - break; - } - -#ifdef ERR_INJ_DEBUG - printk(KERN_DEBUG "Returns: status=%d,\n", (int)status[cpu]); - printk(KERN_DEBUG "capapbilities=%lx,\n", capabilities[cpu]); - printk(KERN_DEBUG "resources=%lx\n", resources[cpu]); -#endif - return size; -} - -show(err_type_info) -store(err_type_info) - -static ssize_t -show_virtual_to_phys(struct sys_device *dev, char *buf) -{ - unsigned int cpu=dev->id; - return sprintf(buf, "%lx\n", phys_addr[cpu]); -} - -static ssize_t -store_virtual_to_phys(struct sys_device *dev, const char *buf, size_t size) -{ - unsigned int cpu=dev->id; - u64 virt_addr=simple_strtoull(buf, NULL, 16); - int ret; - - ret = get_user_pages(current, current->mm, virt_addr, - 1, VM_READ, 0, NULL, NULL); - if (ret<=0) { -#ifdef ERR_INJ_DEBUG - printk("Virtual address %lx is not existing.\n",virt_addr); -#endif - return -EINVAL; - } - - phys_addr[cpu] = ia64_tpa(virt_addr); - return size; -} - -show(err_struct_info) -store(err_struct_info) - -static ssize_t -show_err_data_buffer(struct sys_device *dev, char *buf) -{ - unsigned int cpu=dev->id; - - return sprintf(buf, "%lx, %lx, %lx\n", - err_data_buffer[cpu].data1, - err_data_buffer[cpu].data2, - err_data_buffer[cpu].data3); -} - -static ssize_t -store_err_data_buffer(struct sys_device *dev, const char *buf, size_t size) -{ - unsigned int cpu=dev->id; - int ret; - -#ifdef ERR_INJ_DEBUG - printk("write err_data_buffer=[%lx,%lx,%lx] on cpu%d\n", - err_data_buffer[cpu].data1, - err_data_buffer[cpu].data2, - err_data_buffer[cpu].data3, - cpu); -#endif - ret=sscanf(buf, "%lx, %lx, %lx", - &err_data_buffer[cpu].data1, - &err_data_buffer[cpu].data2, - &err_data_buffer[cpu].data3); - if (ret!=ERR_DATA_BUFFER_SIZE) - return -EINVAL; - - return size; -} - -show(status) -show(capabilities) -show(resources) - -define_one_rw(call_start); -define_one_rw(err_type_info); -define_one_rw(err_struct_info); -define_one_rw(err_data_buffer); -define_one_rw(virtual_to_phys); -define_one_ro(status); -define_one_ro(capabilities); -define_one_ro(resources); - -static struct attribute *default_attrs[] = { - &attr_call_start.attr, - &attr_virtual_to_phys.attr, - &attr_err_type_info.attr, - &attr_err_struct_info.attr, - &attr_err_data_buffer.attr, - &attr_status.attr, - &attr_capabilities.attr, - &attr_resources.attr, - NULL -}; - -static struct attribute_group err_inject_attr_group = { - .attrs = default_attrs, - .name = "err_inject" -}; -/* Add/Remove err_inject interface for CPU device */ -static int __cpuinit err_inject_add_dev(struct sys_device * sys_dev) -{ - return sysfs_create_group(&sys_dev->kobj, &err_inject_attr_group); -} - -static int __cpuinit err_inject_remove_dev(struct sys_device * sys_dev) -{ - sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group); - return 0; -} -static int __cpuinit err_inject_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct sys_device *sys_dev; - - sys_dev = get_cpu_sysdev(cpu); - switch (action) { - case CPU_ONLINE: - err_inject_add_dev(sys_dev); - break; - case CPU_DEAD: - err_inject_remove_dev(sys_dev); - break; - } - - return NOTIFY_OK; -} - -static struct notifier_block __cpuinitdata err_inject_cpu_notifier = -{ - .notifier_call = err_inject_cpu_callback, -}; - -static int __init -err_inject_init(void) -{ - int i; - -#ifdef ERR_INJ_DEBUG - printk(KERN_INFO "Enter error injection driver.\n"); -#endif - for_each_online_cpu(i) { - err_inject_cpu_callback(&err_inject_cpu_notifier, CPU_ONLINE, - (void *)(long)i); - } - - register_hotcpu_notifier(&err_inject_cpu_notifier); - - return 0; -} - -static void __exit -err_inject_exit(void) -{ - int i; - struct sys_device *sys_dev; - -#ifdef ERR_INJ_DEBUG - printk(KERN_INFO "Exit error injection driver.\n"); -#endif - for_each_online_cpu(i) { - sys_dev = get_cpu_sysdev(i); - sysfs_remove_group(&sys_dev->kobj, &err_inject_attr_group); - } - unregister_hotcpu_notifier(&err_inject_cpu_notifier); -} - -module_init(err_inject_init); -module_exit(err_inject_exit); - -MODULE_AUTHOR("Fenghua Yu "); -MODULE_DESCRIPTION("MC error injection kenrel sysfs interface"); -MODULE_LICENSE("GPL"); diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index 93d9ab14ba24..dcfbf3e7a9ef 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -87,6 +87,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/ia64/kernel/irq_ia64.c b/trunk/arch/ia64/kernel/irq_ia64.c index 1c5044a80958..456f57b087ca 100644 --- a/trunk/arch/ia64/kernel/irq_ia64.c +++ b/trunk/arch/ia64/kernel/irq_ia64.c @@ -27,6 +27,7 @@ #include /* for rand_initialize_irq() */ #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/kernel/ivt.S b/trunk/arch/ia64/kernel/ivt.S index 34f44d8be00d..6b7fcbd3f6f1 100644 --- a/trunk/arch/ia64/kernel/ivt.S +++ b/trunk/arch/ia64/kernel/ivt.S @@ -374,7 +374,6 @@ ENTRY(alt_dtlb_miss) movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) mov r21=cr.ipsr mov r31=pr - mov r24=PERCPU_ADDR ;; #ifdef CONFIG_DISABLE_VHPT shr.u r22=r16,61 // get the region number into r21 @@ -387,30 +386,22 @@ ENTRY(alt_dtlb_miss) (p8) mov r29=b0 // save b0 (p8) br.cond.dptk dtlb_fault #endif - cmp.ge p10,p11=r16,r24 // access to per_cpu_data? - tbit.z p12,p0=r16,61 // access to region 6? - mov r25=PERCPU_PAGE_SHIFT << 2 - mov r26=PERCPU_PAGE_SIZE - nop.m 0 - nop.b 0 - ;; -(p10) mov r19=IA64_KR(PER_CPU_DATA) -(p11) and r19=r19,r16 // clear non-ppn fields extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on? + shr.u r18=r16,57 // move address bit 61 to bit 4 + and r19=r19,r16 // clear ed, reserved bits, and PTE control bits tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on? ;; -(p10) sub r19=r19,r26 -(p10) mov cr.itir=r25 + andcm r18=0x10,r18 // bit 4=~address-bit(61) cmp.ne p8,p0=r0,r23 (p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field -(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr (p8) br.cond.spnt page_fault dep r21=-1,r21,IA64_PSR_ED_BIT,1 - ;; or r19=r19,r17 // insert PTE control bits into r19 + ;; + or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 (p6) mov cr.ipsr=r21 ;; (p7) itc.d r19 // insert the TLB entry diff --git a/trunk/arch/ia64/kernel/kprobes.c b/trunk/arch/ia64/kernel/kprobes.c index 4f5fd0960ba7..6cb56dd4056d 100644 --- a/trunk/arch/ia64/kernel/kprobes.c +++ b/trunk/arch/ia64/kernel/kprobes.c @@ -29,9 +29,9 @@ #include #include #include -#include #include +#include #include #include @@ -444,8 +444,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) break; } - kretprobe_assert(ri, orig_ret_address, trampoline_address); - + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); regs->cr_iip = orig_ret_address; reset_current_kprobe(); @@ -465,13 +464,23 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) } /* Called with kretprobe_lock held */ -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, +void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { - ri->ret_addr = (kprobe_opcode_t *)regs->b0; + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *)regs->b0; + + /* Replace the return addr with trampoline addr */ + regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; - /* Replace the return addr with trampoline addr */ - regs->b0 = ((struct fnptr *)kretprobe_trampoline)->ip; + add_rp_inst(ri); + } else { + rp->nmissed++; + } } int __kprobes arch_prepare_kprobe(struct kprobe *p) @@ -1012,12 +1021,3 @@ int __init arch_init_kprobes(void) (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; return register_kprobe(&trampoline_p); } - -int __kprobes arch_trampoline_kprobe(struct kprobe *p) -{ - if (p->addr == - (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip) - return 1; - - return 0; -} diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 1d7cc7e2ce32..491687f84fb5 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -71,9 +72,9 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/trunk/arch/ia64/kernel/mca_asm.S b/trunk/arch/ia64/kernel/mca_asm.S index 8c9c26aa6ae0..c6b607c00dee 100644 --- a/trunk/arch/ia64/kernel/mca_asm.S +++ b/trunk/arch/ia64/kernel/mca_asm.S @@ -101,6 +101,14 @@ ia64_do_tlb_purge: ;; srlz.d ;; + // 2. Purge DTR for PERCPU data. + movl r16=PERCPU_ADDR + mov r18=PERCPU_PAGE_SHIFT<<2 + ;; + ptr.d r16,r18 + ;; + srlz.d + ;; // 3. Purge ITR for PAL code. GET_THIS_PADDR(r2, ia64_mca_pal_base) ;; @@ -188,6 +196,22 @@ ia64_reload_tr: srlz.i srlz.d ;; + // 2. Reload DTR register for PERCPU data. + GET_THIS_PADDR(r2, ia64_mca_per_cpu_pte) + ;; + movl r16=PERCPU_ADDR // vaddr + movl r18=PERCPU_PAGE_SHIFT<<2 + ;; + mov cr.itir=r18 + mov cr.ifa=r16 + ;; + ld8 r18=[r2] // load per-CPU PTE + mov r16=IA64_TR_PERCPU_DATA; + ;; + itr.d dtr[r16]=r18 + ;; + srlz.d + ;; // 3. Reload ITR for PAL code. GET_THIS_PADDR(r2, ia64_mca_pal_pte) ;; diff --git a/trunk/arch/ia64/kernel/mca_drv.c b/trunk/arch/ia64/kernel/mca_drv.c index 70b8bdbb7e6f..832cf1e647e8 100644 --- a/trunk/arch/ia64/kernel/mca_drv.c +++ b/trunk/arch/ia64/kernel/mca_drv.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/kernel/patch.c b/trunk/arch/ia64/kernel/patch.c index e796e29f8e15..bc11bb096f58 100644 --- a/trunk/arch/ia64/kernel/patch.c +++ b/trunk/arch/ia64/kernel/patch.c @@ -195,23 +195,3 @@ ia64_patch_gate (void) ia64_patch_vtop(START(vtop), END(vtop)); ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9)); } - -void ia64_patch_phys_stack_reg(unsigned long val) -{ - s32 * offp = (s32 *) __start___phys_stack_reg_patchlist; - s32 * end = (s32 *) __end___phys_stack_reg_patchlist; - u64 ip, mask, imm; - - /* see instruction format A4: adds r1 = imm13, r3 */ - mask = (0x3fUL << 27) | (0x7f << 13); - imm = (((val >> 7) & 0x3f) << 27) | (val & 0x7f) << 13; - - while (offp < end) { - ip = (u64) offp + *offp; - ia64_patch(ip, mask, imm); - ia64_fc(ip); - ++offp; - } - ia64_sync_i(); - ia64_srlz_i(); -} diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index e7191ca30b16..abc7ad035886 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 8bb571a8a738..ae96d4176995 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -20,19 +20,20 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include #include #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index a51f1d0bfb70..af9f8754d847 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index 6e19da122ae3..dc7dd7648ec5 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -75,6 +75,7 @@ extern void ia64_setup_printk_clock(void); DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); +DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); unsigned long ia64_cycles_per_usec; struct ia64_boot_param *ia64_boot_param; struct screen_info screen_info; @@ -868,7 +869,6 @@ void __cpuinit cpu_init (void) { extern void __cpuinit ia64_mmu_init (void *); - static unsigned long max_num_phys_stacked = IA64_NUM_PHYS_STACK_REG; unsigned long num_phys_stacked; pal_vm_info_2_u_t vmi; unsigned int max_ctx; @@ -982,10 +982,7 @@ cpu_init (void) num_phys_stacked = 96; } /* size of physical stacked register partition plus 8 bytes: */ - if (num_phys_stacked > max_num_phys_stacked) { - ia64_patch_phys_stack_reg(num_phys_stacked*8 + 8); - max_num_phys_stacked = num_phys_stacked; - } + __get_cpu_var(ia64_phys_stacked_size_p8) = num_phys_stacked*8 + 8; platform_cpu_init(); pm_idle = default_idle; } diff --git a/trunk/arch/ia64/kernel/signal.c b/trunk/arch/ia64/kernel/signal.c index 0dcd56da6001..77f8b49c7882 100644 --- a/trunk/arch/ia64/kernel/signal.c +++ b/trunk/arch/ia64/kernel/signal.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index a44792d0f3a9..ff7df439da6d 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/kernel/sys_ia64.c b/trunk/arch/ia64/kernel/sys_ia64.c index 1eda194b9559..9ef62a3fbfad 100644 --- a/trunk/arch/ia64/kernel/sys_ia64.c +++ b/trunk/arch/ia64/kernel/sys_ia64.c @@ -13,6 +13,7 @@ #include #include /* doh, must come after sched.h... */ #include +#include #include #include #include @@ -32,13 +33,6 @@ arch_get_unmapped_area (struct file *filp, unsigned long addr, unsigned long len if (len > RGN_MAP_LIMIT) return -ENOMEM; - /* handle fixed mapping: prevent overlap with huge pages */ - if (flags & MAP_FIXED) { - if (is_hugepage_only_range(mm, addr, len)) - return -EINVAL; - return addr; - } - #ifdef CONFIG_HUGETLB_PAGE if (REGION_NUMBER(addr) == RGN_HPAGE) addr = 0; diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index a06667c7acc0..39e0cd3a0884 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -235,7 +235,7 @@ ia64_init_itm (void) static struct irqaction timer_irqaction = { .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_IRQPOLL, + .flags = IRQF_DISABLED, .name = "timer" }; diff --git a/trunk/arch/ia64/kernel/traps.c b/trunk/arch/ia64/kernel/traps.c index 5bfb8be02b70..765cbe5ba6ae 100644 --- a/trunk/arch/ia64/kernel/traps.c +++ b/trunk/arch/ia64/kernel/traps.c @@ -16,17 +16,33 @@ #include #include #include /* for ssleep() */ -#include #include #include #include #include #include +#include fpswa_interface_t *fpswa_interface; EXPORT_SYMBOL(fpswa_interface); +ATOMIC_NOTIFIER_HEAD(ia64die_chain); + +int +register_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&ia64die_chain, nb); +} +EXPORT_SYMBOL_GPL(register_die_notifier); + +int +unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&ia64die_chain, nb); +} +EXPORT_SYMBOL_GPL(unregister_die_notifier); + void __init trap_init (void) { diff --git a/trunk/arch/ia64/kernel/unaligned.c b/trunk/arch/ia64/kernel/unaligned.c index fe6aa5a9f8fa..1e357550c776 100644 --- a/trunk/arch/ia64/kernel/unaligned.c +++ b/trunk/arch/ia64/kernel/unaligned.c @@ -15,6 +15,7 @@ */ #include #include +#include #include #include diff --git a/trunk/arch/ia64/kernel/vmlinux.lds.S b/trunk/arch/ia64/kernel/vmlinux.lds.S index 692382642118..25dd55e4db24 100644 --- a/trunk/arch/ia64/kernel/vmlinux.lds.S +++ b/trunk/arch/ia64/kernel/vmlinux.lds.S @@ -78,13 +78,6 @@ SECTIONS __stop___mca_table = .; } - .data.patch.phys_stack_reg : AT(ADDR(.data.patch.phys_stack_reg) - LOAD_OFFSET) - { - __start___phys_stack_reg_patchlist = .; - *(.data.patch.phys_stack_reg) - __end___phys_stack_reg_patchlist = .; - } - /* Global data */ _data = .; diff --git a/trunk/arch/ia64/mm/discontig.c b/trunk/arch/ia64/mm/discontig.c index 94844442812a..872da7a2accd 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -693,7 +693,6 @@ void __init paging_init(void) zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } -#ifdef CONFIG_MEMORY_HOTPLUG pg_data_t *arch_alloc_nodedata(int nid) { unsigned long size = compute_pernodesize(nid); @@ -711,4 +710,3 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat) pgdat_list[update_node] = update_pgdat; scatter_node_data(); } -#endif diff --git a/trunk/arch/ia64/mm/fault.c b/trunk/arch/ia64/mm/fault.c index 21658e02116c..59f3ab937615 100644 --- a/trunk/arch/ia64/mm/fault.c +++ b/trunk/arch/ia64/mm/fault.c @@ -7,14 +7,15 @@ #include #include #include +#include #include #include -#include #include #include #include #include +#include extern void die (char *, struct pt_regs *, long); diff --git a/trunk/arch/ia64/mm/hugetlbpage.c b/trunk/arch/ia64/mm/hugetlbpage.c index 1346b7f05397..0c7e94edc20e 100644 --- a/trunk/arch/ia64/mm/hugetlbpage.c +++ b/trunk/arch/ia64/mm/hugetlbpage.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -147,14 +148,6 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, u return -ENOMEM; if (len & ~HPAGE_MASK) return -EINVAL; - - /* Handle MAP_FIXED */ - if (flags & MAP_FIXED) { - if (prepare_hugepage_range(addr, len, pgoff)) - return -EINVAL; - return addr; - } - /* This code assumes that RGN_HPAGE != 0. */ if ((REGION_NUMBER(addr) != RGN_HPAGE) || (addr & (HPAGE_SIZE - 1))) addr = HPAGE_REGION_BASE; diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index cffb1e8325e8..4f36987eea72 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -121,7 +121,7 @@ lazy_mmu_prot_update (pte_t pte) return; /* i-cache is already coherent with d-cache */ if (PageCompound(page)) { - order = compound_order(page); + order = (unsigned long) (page[1].lru.prev); flush_icache_range(addr, addr + (1UL << order << PAGE_SHIFT)); } else @@ -355,7 +355,7 @@ setup_gate (void) void __devinit ia64_mmu_init (void *my_cpu_data) { - unsigned long pta, impl_va_bits; + unsigned long psr, pta, impl_va_bits; extern void __devinit tlb_init (void); #ifdef CONFIG_DISABLE_VHPT @@ -364,6 +364,15 @@ ia64_mmu_init (void *my_cpu_data) # define VHPT_ENABLE_BIT 1 #endif + /* Pin mapping for percpu area into TLB */ + psr = ia64_clear_ic(); + ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR, + pte_val(pfn_pte(__pa(my_cpu_data) >> PAGE_SHIFT, PAGE_KERNEL)), + PERCPU_PAGE_SHIFT); + + ia64_set_psr(psr); + ia64_srlz_i(); + /* * Check if the virtually mapped linear page table (VMLPT) overlaps with a mapped * address space. The IA-64 architecture guarantees that at least 50 bits of diff --git a/trunk/arch/ia64/mm/ioremap.c b/trunk/arch/ia64/mm/ioremap.c index 2a140627dfd6..4280c074d64e 100644 --- a/trunk/arch/ia64/mm/ioremap.c +++ b/trunk/arch/ia64/mm/ioremap.c @@ -1,5 +1,5 @@ /* - * (c) Copyright 2006, 2007 Hewlett-Packard Development Company, L.P. + * (c) Copyright 2006 Hewlett-Packard Development Company, L.P. * Bjorn Helgaas * * This program is free software; you can redistribute it and/or modify @@ -10,101 +10,51 @@ #include #include #include -#include -#include #include #include static inline void __iomem * -__ioremap (unsigned long phys_addr) +__ioremap (unsigned long offset, unsigned long size) { - return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr); + return (void __iomem *) (__IA64_UNCACHED_OFFSET | offset); } void __iomem * -ioremap (unsigned long phys_addr, unsigned long size) +ioremap (unsigned long offset, unsigned long size) { - void __iomem *addr; - struct vm_struct *area; - unsigned long offset; - pgprot_t prot; u64 attr; unsigned long gran_base, gran_size; - unsigned long page_base; /* * For things in kern_memmap, we must use the same attribute * as the rest of the kernel. For more details, see * Documentation/ia64/aliasing.txt. */ - attr = kern_mem_attribute(phys_addr, size); + attr = kern_mem_attribute(offset, size); if (attr & EFI_MEMORY_WB) - return (void __iomem *) phys_to_virt(phys_addr); + return (void __iomem *) phys_to_virt(offset); else if (attr & EFI_MEMORY_UC) - return __ioremap(phys_addr); + return __ioremap(offset, size); /* * Some chipsets don't support UC access to memory. If * WB is supported for the whole granule, we prefer that. */ - gran_base = GRANULEROUNDDOWN(phys_addr); - gran_size = GRANULEROUNDUP(phys_addr + size) - gran_base; + gran_base = GRANULEROUNDDOWN(offset); + gran_size = GRANULEROUNDUP(offset + size) - gran_base; if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB) - return (void __iomem *) phys_to_virt(phys_addr); + return (void __iomem *) phys_to_virt(offset); - /* - * WB is not supported for the whole granule, so we can't use - * the region 7 identity mapping. If we can safely cover the - * area with kernel page table mappings, we can use those - * instead. - */ - page_base = phys_addr & PAGE_MASK; - size = PAGE_ALIGN(phys_addr + size) - page_base; - if (efi_mem_attribute(page_base, size) & EFI_MEMORY_WB) { - prot = PAGE_KERNEL; - - /* - * Mappings have to be page-aligned - */ - offset = phys_addr & ~PAGE_MASK; - phys_addr &= PAGE_MASK; - - /* - * Ok, go for it.. - */ - area = get_vm_area(size, VM_IOREMAP); - if (!area) - return NULL; - - area->phys_addr = phys_addr; - addr = (void __iomem *) area->addr; - if (ioremap_page_range((unsigned long) addr, - (unsigned long) addr + size, phys_addr, prot)) { - vunmap((void __force *) addr); - return NULL; - } - - return (void __iomem *) (offset + (char __iomem *)addr); - } - - return __ioremap(phys_addr); + return __ioremap(offset, size); } EXPORT_SYMBOL(ioremap); void __iomem * -ioremap_nocache (unsigned long phys_addr, unsigned long size) +ioremap_nocache (unsigned long offset, unsigned long size) { - if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB) + if (kern_mem_attribute(offset, size) & EFI_MEMORY_WB) return NULL; - return __ioremap(phys_addr); + return __ioremap(offset, size); } EXPORT_SYMBOL(ioremap_nocache); - -void -iounmap (volatile void __iomem *addr) -{ - if (REGION_NUMBER(addr) == RGN_GATE) - vunmap((void *) ((unsigned long) addr & PAGE_MASK)); -} -EXPORT_SYMBOL(iounmap); diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index 3549f3b42592..0e83f3b419b5 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -658,6 +659,8 @@ pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma) return -EINVAL; prot = phys_mem_access_prot(NULL, vma->vm_pgoff, size, vma->vm_page_prot); + if (pgprot_val(prot) != pgprot_val(pgprot_noncached(vma->vm_page_prot))) + return -EINVAL; addr = pci_get_legacy_mem(bus); if (IS_ERR(addr)) diff --git a/trunk/arch/ia64/sn/kernel/huberror.c b/trunk/arch/ia64/sn/kernel/huberror.c index 2c3f9dfca78b..fcf7f93c4b61 100644 --- a/trunk/arch/ia64/sn/kernel/huberror.c +++ b/trunk/arch/ia64/sn/kernel/huberror.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include "ioerror.h" diff --git a/trunk/arch/ia64/sn/kernel/msi_sn.c b/trunk/arch/ia64/sn/kernel/msi_sn.c index 83f190ffe350..49873aa4a37d 100644 --- a/trunk/arch/ia64/sn/kernel/msi_sn.c +++ b/trunk/arch/ia64/sn/kernel/msi_sn.c @@ -87,6 +87,7 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) if (irq < 0) return irq; + set_irq_msi(irq, entry); /* * Set up the vector plumbing. Let the prom (via sn_intr_alloc) * decide which cpu to direct this msi at by default. @@ -143,11 +144,10 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) */ msg.data = 0x100 + irq; - set_irq_msi(irq, entry); write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); - return 0; + return irq; } #ifdef CONFIG_SMP diff --git a/trunk/arch/ia64/sn/kernel/xpc_main.c b/trunk/arch/ia64/sn/kernel/xpc_main.c index e336e1692a73..68355ef6f841 100644 --- a/trunk/arch/ia64/sn/kernel/xpc_main.c +++ b/trunk/arch/ia64/sn/kernel/xpc_main.c @@ -55,9 +55,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -1332,7 +1332,7 @@ xpc_init(void) dev_warn(xpc_part, "can't register reboot notifier\n"); } - /* add ourselves to the die_notifier list */ + /* add ourselves to the die_notifier list (i.e., ia64die_chain) */ ret = register_die_notifier(&xpc_die_notifier); if (ret != 0) { dev_warn(xpc_part, "can't register die notifier\n"); diff --git a/trunk/arch/ia64/sn/kernel/xpnet.c b/trunk/arch/ia64/sn/kernel/xpnet.c index 88fad85ceeff..5419acb89a8c 100644 --- a/trunk/arch/ia64/sn/kernel/xpnet.c +++ b/trunk/arch/ia64/sn/kernel/xpnet.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/trunk/arch/m32r/kernel/m32r_ksyms.c b/trunk/arch/m32r/kernel/m32r_ksyms.c index 41a4c95e06d6..8cbbb0b11e0c 100644 --- a/trunk/arch/m32r/kernel/m32r_ksyms.c +++ b/trunk/arch/m32r/kernel/m32r_ksyms.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/m32r/kernel/signal.c b/trunk/arch/m32r/kernel/signal.c index 916faf6070af..4b156054baa6 100644 --- a/trunk/arch/m32r/kernel/signal.c +++ b/trunk/arch/m32r/kernel/signal.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/m32r/kernel/smpboot.c b/trunk/arch/m32r/kernel/smpboot.c index 3eb305953497..48d376f47e1a 100644 --- a/trunk/arch/m32r/kernel/smpboot.c +++ b/trunk/arch/m32r/kernel/smpboot.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/m32r/kernel/sys_m32r.c b/trunk/arch/m32r/kernel/sys_m32r.c index bda85548de6c..b4e7bcb43540 100644 --- a/trunk/arch/m32r/kernel/sys_m32r.c +++ b/trunk/arch/m32r/kernel/sys_m32r.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/m32r/kernel/vmlinux.lds.S b/trunk/arch/m32r/kernel/vmlinux.lds.S index 6c73bca3f478..439cc257cd1d 100644 --- a/trunk/arch/m32r/kernel/vmlinux.lds.S +++ b/trunk/arch/m32r/kernel/vmlinux.lds.S @@ -110,7 +110,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(4096); + . = ALIGN(32); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/m32r/mm/fault-nommu.c b/trunk/arch/m32r/mm/fault-nommu.c index 88469178ea6b..9880abac3f54 100644 --- a/trunk/arch/m32r/mm/fault-nommu.c +++ b/trunk/arch/m32r/mm/fault-nommu.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include /* For unblank_screen() */ diff --git a/trunk/arch/m32r/mm/fault.c b/trunk/arch/m32r/mm/fault.c index f3935ba24946..037d58e82fb5 100644 --- a/trunk/arch/m32r/mm/fault.c +++ b/trunk/arch/m32r/mm/fault.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index b8536c7c0877..a8e1e604dfa8 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -409,9 +409,6 @@ config STRAM_PROC help Say Y here to report ST-RAM usage statistics in /proc/stram. -config ATARI_KBD_CORE - bool - config HEARTBEAT bool "Use power LED as a heartbeat" if AMIGA || APOLLO || ATARI || MAC ||Q40 default y if !AMIGA && !APOLLO && !ATARI && !MAC && !Q40 && HP300 diff --git a/trunk/arch/m68k/Makefile b/trunk/arch/m68k/Makefile index c20831a7e1a9..34d826d10f1b 100644 --- a/trunk/arch/m68k/Makefile +++ b/trunk/arch/m68k/Makefile @@ -21,7 +21,7 @@ AS += -m68020 LDFLAGS := -m m68kelf ifneq ($(COMPILE_ARCH),$(ARCH)) # prefix for cross-compiling binaries - CROSS_COMPILE = m68k-linux-gnu- + CROSS_COMPILE = m68k-linux- endif ifdef CONFIG_SUN3 diff --git a/trunk/arch/m68k/amiga/amiints.c b/trunk/arch/m68k/amiga/amiints.c index 907a5533c845..28d95cfe8ac0 100644 --- a/trunk/arch/m68k/amiga/amiints.c +++ b/trunk/arch/m68k/amiga/amiints.c @@ -54,7 +54,7 @@ static irqreturn_t ami_int5(int irq, void *dev_id); static struct irq_controller amiga_irq_controller = { .name = "amiga", - .lock = __SPIN_LOCK_UNLOCKED(amiga_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .enable = amiga_enable_irq, .disable = amiga_disable_irq, }; diff --git a/trunk/arch/m68k/amiga/cia.c b/trunk/arch/m68k/amiga/cia.c index c4a4ffd45bc0..7a20058eb380 100644 --- a/trunk/arch/m68k/amiga/cia.c +++ b/trunk/arch/m68k/amiga/cia.c @@ -123,7 +123,7 @@ static void cia_disable_irq(unsigned int irq) static struct irq_controller cia_irq_controller = { .name = "cia", - .lock = __SPIN_LOCK_UNLOCKED(cia_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .enable = cia_enable_irq, .disable = cia_disable_irq, }; @@ -160,7 +160,7 @@ static void auto_disable_irq(unsigned int irq) static struct irq_controller auto_irq_controller = { .name = "auto", - .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .enable = auto_enable_irq, .disable = auto_disable_irq, }; diff --git a/trunk/arch/m68k/amiga/config.c b/trunk/arch/m68k/amiga/config.c index 35748531327d..3204f412cad8 100644 --- a/trunk/arch/m68k/amiga/config.c +++ b/trunk/arch/m68k/amiga/config.c @@ -22,7 +22,9 @@ #include #include #include +#ifdef CONFIG_ZORRO #include +#endif #include #include @@ -60,51 +62,55 @@ static char s_cdtv[] __initdata = "CDTV"; static char s_cd32[] __initdata = "CD32"; static char s_draco[] __initdata = "Draco"; static char *amiga_models[] __initdata = { - [AMI_500-AMI_500] = s_a500, - [AMI_500PLUS-AMI_500] = s_a500p, - [AMI_600-AMI_500] = s_a600, - [AMI_1000-AMI_500] = s_a1000, - [AMI_1200-AMI_500] = s_a1200, - [AMI_2000-AMI_500] = s_a2000, - [AMI_2500-AMI_500] = s_a2500, - [AMI_3000-AMI_500] = s_a3000, - [AMI_3000T-AMI_500] = s_a3000t, - [AMI_3000PLUS-AMI_500] = s_a3000p, - [AMI_4000-AMI_500] = s_a4000, - [AMI_4000T-AMI_500] = s_a4000t, - [AMI_CDTV-AMI_500] = s_cdtv, - [AMI_CD32-AMI_500] = s_cd32, - [AMI_DRACO-AMI_500] = s_draco, + [AMI_500-AMI_500] = s_a500, + [AMI_500PLUS-AMI_500] = s_a500p, + [AMI_600-AMI_500] = s_a600, + [AMI_1000-AMI_500] = s_a1000, + [AMI_1200-AMI_500] = s_a1200, + [AMI_2000-AMI_500] = s_a2000, + [AMI_2500-AMI_500] = s_a2500, + [AMI_3000-AMI_500] = s_a3000, + [AMI_3000T-AMI_500] = s_a3000t, + [AMI_3000PLUS-AMI_500] = s_a3000p, + [AMI_4000-AMI_500] = s_a4000, + [AMI_4000T-AMI_500] = s_a4000t, + [AMI_CDTV-AMI_500] = s_cdtv, + [AMI_CD32-AMI_500] = s_cd32, + [AMI_DRACO-AMI_500] = s_draco, }; static char amiga_model_name[13] = "Amiga "; +extern char m68k_debug_device[]; + static void amiga_sched_init(irq_handler_t handler); /* amiga specific irq functions */ -extern void amiga_init_IRQ(void); +extern void amiga_init_IRQ (void); static void amiga_get_model(char *model); static int amiga_get_hardware_list(char *buffer); /* amiga specific timer functions */ -static unsigned long amiga_gettimeoffset(void); -static int a3000_hwclk(int, struct rtc_time *); -static int a2000_hwclk(int, struct rtc_time *); -static int amiga_set_clock_mmss(unsigned long); -static unsigned int amiga_get_ss(void); -extern void amiga_mksound(unsigned int count, unsigned int ticks); -static void amiga_reset(void); +static unsigned long amiga_gettimeoffset (void); +static int a3000_hwclk (int, struct rtc_time *); +static int a2000_hwclk (int, struct rtc_time *); +static int amiga_set_clock_mmss (unsigned long); +static unsigned int amiga_get_ss (void); +extern void amiga_mksound( unsigned int count, unsigned int ticks ); +static void amiga_reset (void); extern void amiga_init_sound(void); +static void amiga_savekmsg_init(void); static void amiga_mem_console_write(struct console *co, const char *b, unsigned int count); void amiga_serial_console_write(struct console *co, const char *s, unsigned int count); +static void amiga_debug_init(void); #ifdef CONFIG_HEARTBEAT static void amiga_heartbeat(int on); #endif static struct console amiga_console_driver = { - .name = "debug", - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .flags = CON_PRINTBUFFER, + .index = -1, }; @@ -113,24 +119,24 @@ static struct console amiga_console_driver = { */ static struct { - struct resource _ciab, _ciaa, _custom, _kickstart; + struct resource _ciab, _ciaa, _custom, _kickstart; } mb_resources = { - ._ciab = { - .name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff - }, - ._ciaa = { - .name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff - }, - ._custom = { - .name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff - }, - ._kickstart = { - .name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff - } + ._ciab = { + .name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff + }, + ._ciaa = { + .name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff + }, + ._custom = { + .name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff + }, + ._kickstart = { + .name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff + } }; static struct resource rtc_resource = { - .start = 0x00dc0000, .end = 0x00dcffff + .start = 0x00dc0000, .end = 0x00dcffff }; static struct resource ram_resource[NUM_MEMINFO]; @@ -142,57 +148,57 @@ static struct resource ram_resource[NUM_MEMINFO]; int amiga_parse_bootinfo(const struct bi_record *record) { - int unknown = 0; - const unsigned long *data = record->data; + int unknown = 0; + const unsigned long *data = record->data; - switch (record->tag) { + switch (record->tag) { case BI_AMIGA_MODEL: - amiga_model = *data; - break; + amiga_model = *data; + break; case BI_AMIGA_ECLOCK: - amiga_eclock = *data; - break; + amiga_eclock = *data; + break; case BI_AMIGA_CHIPSET: - amiga_chipset = *data; - break; + amiga_chipset = *data; + break; case BI_AMIGA_CHIP_SIZE: - amiga_chip_size = *(const int *)data; - break; + amiga_chip_size = *(const int *)data; + break; case BI_AMIGA_VBLANK: - amiga_vblank = *(const unsigned char *)data; - break; + amiga_vblank = *(const unsigned char *)data; + break; case BI_AMIGA_PSFREQ: - amiga_psfreq = *(const unsigned char *)data; - break; + amiga_psfreq = *(const unsigned char *)data; + break; case BI_AMIGA_AUTOCON: #ifdef CONFIG_ZORRO - if (zorro_num_autocon < ZORRO_NUM_AUTO) { - const struct ConfigDev *cd = (struct ConfigDev *)data; - struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; - dev->rom = cd->cd_Rom; - dev->slotaddr = cd->cd_SlotAddr; - dev->slotsize = cd->cd_SlotSize; - dev->resource.start = (unsigned long)cd->cd_BoardAddr; - dev->resource.end = dev->resource.start + cd->cd_BoardSize - 1; - } else - printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); + if (zorro_num_autocon < ZORRO_NUM_AUTO) { + const struct ConfigDev *cd = (struct ConfigDev *)data; + struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; + dev->rom = cd->cd_Rom; + dev->slotaddr = cd->cd_SlotAddr; + dev->slotsize = cd->cd_SlotSize; + dev->resource.start = (unsigned long)cd->cd_BoardAddr; + dev->resource.end = dev->resource.start+cd->cd_BoardSize-1; + } else + printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); #endif /* CONFIG_ZORRO */ - break; + break; case BI_AMIGA_SERPER: - /* serial port period: ignored here */ - break; + /* serial port period: ignored here */ + break; default: - unknown = 1; - } - return unknown; + unknown = 1; + } + return(unknown); } /* @@ -201,159 +207,159 @@ int amiga_parse_bootinfo(const struct bi_record *record) static void __init amiga_identify(void) { - /* Fill in some default values, if necessary */ - if (amiga_eclock == 0) - amiga_eclock = 709379; - - memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); + /* Fill in some default values, if necessary */ + if (amiga_eclock == 0) + amiga_eclock = 709379; + + memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); + + printk("Amiga hardware found: "); + if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { + printk("[%s] ", amiga_models[amiga_model-AMI_500]); + strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); + } + + switch(amiga_model) { + case AMI_UNKNOWN: + goto Generic; + + case AMI_600: + case AMI_1200: + AMIGAHW_SET(A1200_IDE); + AMIGAHW_SET(PCMCIA); + case AMI_500: + case AMI_500PLUS: + case AMI_1000: + case AMI_2000: + case AMI_2500: + AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ + goto Generic; + + case AMI_3000: + case AMI_3000T: + AMIGAHW_SET(AMBER_FF); + AMIGAHW_SET(MAGIC_REKICK); + /* fall through */ + case AMI_3000PLUS: + AMIGAHW_SET(A3000_SCSI); + AMIGAHW_SET(A3000_CLK); + AMIGAHW_SET(ZORRO3); + goto Generic; + + case AMI_4000T: + AMIGAHW_SET(A4000_SCSI); + /* fall through */ + case AMI_4000: + AMIGAHW_SET(A4000_IDE); + AMIGAHW_SET(A3000_CLK); + AMIGAHW_SET(ZORRO3); + goto Generic; + + case AMI_CDTV: + case AMI_CD32: + AMIGAHW_SET(CD_ROM); + AMIGAHW_SET(A2000_CLK); /* Is this correct? */ + goto Generic; + + Generic: + AMIGAHW_SET(AMI_VIDEO); + AMIGAHW_SET(AMI_BLITTER); + AMIGAHW_SET(AMI_AUDIO); + AMIGAHW_SET(AMI_FLOPPY); + AMIGAHW_SET(AMI_KEYBOARD); + AMIGAHW_SET(AMI_MOUSE); + AMIGAHW_SET(AMI_SERIAL); + AMIGAHW_SET(AMI_PARALLEL); + AMIGAHW_SET(CHIP_RAM); + AMIGAHW_SET(PAULA); + + switch(amiga_chipset) { + case CS_OCS: + case CS_ECS: + case CS_AGA: + switch (amiga_custom.deniseid & 0xf) { + case 0x0c: + AMIGAHW_SET(DENISE_HR); + break; + case 0x08: + AMIGAHW_SET(LISA); + break; + } + break; + default: + AMIGAHW_SET(DENISE); + break; + } + switch ((amiga_custom.vposr>>8) & 0x7f) { + case 0x00: + AMIGAHW_SET(AGNUS_PAL); + break; + case 0x10: + AMIGAHW_SET(AGNUS_NTSC); + break; + case 0x20: + case 0x21: + AMIGAHW_SET(AGNUS_HR_PAL); + break; + case 0x30: + case 0x31: + AMIGAHW_SET(AGNUS_HR_NTSC); + break; + case 0x22: + case 0x23: + AMIGAHW_SET(ALICE_PAL); + break; + case 0x32: + case 0x33: + AMIGAHW_SET(ALICE_NTSC); + break; + } + AMIGAHW_SET(ZORRO); + break; + + case AMI_DRACO: + panic("No support for Draco yet"); + + default: + panic("Unknown Amiga Model"); + } - printk("Amiga hardware found: "); - if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { - printk("[%s] ", amiga_models[amiga_model-AMI_500]); - strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); - } - - switch (amiga_model) { - case AMI_UNKNOWN: - goto Generic; - - case AMI_600: - case AMI_1200: - AMIGAHW_SET(A1200_IDE); - AMIGAHW_SET(PCMCIA); - case AMI_500: - case AMI_500PLUS: - case AMI_1000: - case AMI_2000: - case AMI_2500: - AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ - goto Generic; - - case AMI_3000: - case AMI_3000T: - AMIGAHW_SET(AMBER_FF); - AMIGAHW_SET(MAGIC_REKICK); - /* fall through */ - case AMI_3000PLUS: - AMIGAHW_SET(A3000_SCSI); - AMIGAHW_SET(A3000_CLK); - AMIGAHW_SET(ZORRO3); - goto Generic; - - case AMI_4000T: - AMIGAHW_SET(A4000_SCSI); - /* fall through */ - case AMI_4000: - AMIGAHW_SET(A4000_IDE); - AMIGAHW_SET(A3000_CLK); - AMIGAHW_SET(ZORRO3); - goto Generic; - - case AMI_CDTV: - case AMI_CD32: - AMIGAHW_SET(CD_ROM); - AMIGAHW_SET(A2000_CLK); /* Is this correct? */ - goto Generic; - - Generic: - AMIGAHW_SET(AMI_VIDEO); - AMIGAHW_SET(AMI_BLITTER); - AMIGAHW_SET(AMI_AUDIO); - AMIGAHW_SET(AMI_FLOPPY); - AMIGAHW_SET(AMI_KEYBOARD); - AMIGAHW_SET(AMI_MOUSE); - AMIGAHW_SET(AMI_SERIAL); - AMIGAHW_SET(AMI_PARALLEL); - AMIGAHW_SET(CHIP_RAM); - AMIGAHW_SET(PAULA); - - switch (amiga_chipset) { - case CS_OCS: - case CS_ECS: - case CS_AGA: - switch (amiga_custom.deniseid & 0xf) { - case 0x0c: - AMIGAHW_SET(DENISE_HR); - break; - case 0x08: - AMIGAHW_SET(LISA); - break; - } - break; - default: - AMIGAHW_SET(DENISE); - break; - } - switch ((amiga_custom.vposr>>8) & 0x7f) { - case 0x00: - AMIGAHW_SET(AGNUS_PAL); - break; - case 0x10: - AMIGAHW_SET(AGNUS_NTSC); - break; - case 0x20: - case 0x21: - AMIGAHW_SET(AGNUS_HR_PAL); - break; - case 0x30: - case 0x31: - AMIGAHW_SET(AGNUS_HR_NTSC); - break; - case 0x22: - case 0x23: - AMIGAHW_SET(ALICE_PAL); - break; - case 0x32: - case 0x33: - AMIGAHW_SET(ALICE_NTSC); - break; - } - AMIGAHW_SET(ZORRO); - break; - - case AMI_DRACO: - panic("No support for Draco yet"); - - default: - panic("Unknown Amiga Model"); - } - -#define AMIGAHW_ANNOUNCE(name, str) \ - if (AMIGAHW_PRESENT(name)) \ - printk(str) - - AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); - AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); - AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF "); - AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO "); - AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY "); - AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI "); - AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI "); - AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE "); - AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE "); - AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM "); - AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD "); - AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE "); - AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL "); - AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL "); - AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK "); - AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK "); - AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM "); - AMIGAHW_ANNOUNCE(PAULA, "PAULA "); - AMIGAHW_ANNOUNCE(DENISE, "DENISE "); - AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR "); - AMIGAHW_ANNOUNCE(LISA, "LISA "); - AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL "); - AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC "); - AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL "); - AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC "); - AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL "); - AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC "); - AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); - AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); - if (AMIGAHW_PRESENT(ZORRO)) - printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); - printk("\n"); +#define AMIGAHW_ANNOUNCE(name, str) \ + if (AMIGAHW_PRESENT(name)) \ + printk(str) + + AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); + AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); + AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF "); + AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO "); + AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY "); + AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI "); + AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI "); + AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE "); + AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE "); + AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM "); + AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD "); + AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE "); + AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL "); + AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL "); + AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK "); + AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK "); + AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM "); + AMIGAHW_ANNOUNCE(PAULA, "PAULA "); + AMIGAHW_ANNOUNCE(DENISE, "DENISE "); + AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR "); + AMIGAHW_ANNOUNCE(LISA, "LISA "); + AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL "); + AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC "); + AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL "); + AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC "); + AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL "); + AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC "); + AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); + AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); + if (AMIGAHW_PRESENT(ZORRO)) + printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); + printk("\n"); #undef AMIGAHW_ANNOUNCE } @@ -364,105 +370,119 @@ static void __init amiga_identify(void) void __init config_amiga(void) { - int i; - - amiga_identify(); - - /* Yuk, we don't have PCI memory */ - iomem_resource.name = "Memory"; - for (i = 0; i < 4; i++) - request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); - - mach_sched_init = amiga_sched_init; - mach_init_IRQ = amiga_init_IRQ; - mach_get_model = amiga_get_model; - mach_get_hardware_list = amiga_get_hardware_list; - mach_gettimeoffset = amiga_gettimeoffset; - if (AMIGAHW_PRESENT(A3000_CLK)) { - mach_hwclk = a3000_hwclk; - rtc_resource.name = "A3000 RTC"; - request_resource(&iomem_resource, &rtc_resource); - } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { - mach_hwclk = a2000_hwclk; - rtc_resource.name = "A2000 RTC"; - request_resource(&iomem_resource, &rtc_resource); - } - - /* - * default MAX_DMA=0xffffffff on all machines. If we don't do so, the SCSI - * code will not be able to allocate any mem for transfers, unless we are - * dealing with a Z2 mem only system. /Jes - */ - mach_max_dma_address = 0xffffffff; - - mach_set_clock_mmss = amiga_set_clock_mmss; - mach_get_ss = amiga_get_ss; - mach_reset = amiga_reset; + int i; + + amiga_debug_init(); + amiga_identify(); + + /* Yuk, we don't have PCI memory */ + iomem_resource.name = "Memory"; + for (i = 0; i < 4; i++) + request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); + + mach_sched_init = amiga_sched_init; + mach_init_IRQ = amiga_init_IRQ; + mach_get_model = amiga_get_model; + mach_get_hardware_list = amiga_get_hardware_list; + mach_gettimeoffset = amiga_gettimeoffset; + if (AMIGAHW_PRESENT(A3000_CLK)){ + mach_hwclk = a3000_hwclk; + rtc_resource.name = "A3000 RTC"; + request_resource(&iomem_resource, &rtc_resource); + } + else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */ + mach_hwclk = a2000_hwclk; + rtc_resource.name = "A2000 RTC"; + request_resource(&iomem_resource, &rtc_resource); + } + + mach_max_dma_address = 0xffffffff; /* + * default MAX_DMA=0xffffffff + * on all machines. If we don't + * do so, the SCSI code will not + * be able to allocate any mem + * for transfers, unless we are + * dealing with a Z2 mem only + * system. /Jes + */ + + mach_set_clock_mmss = amiga_set_clock_mmss; + mach_get_ss = amiga_get_ss; + mach_reset = amiga_reset; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = amiga_mksound; + mach_beep = amiga_mksound; #endif #ifdef CONFIG_HEARTBEAT - mach_heartbeat = amiga_heartbeat; + mach_heartbeat = amiga_heartbeat; #endif - /* Fill in the clock values (based on the 700 kHz E-Clock) */ - amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ - amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ - - /* clear all DMA bits */ - amiga_custom.dmacon = DMAF_ALL; - /* ensure that the DMA master bit is set */ - amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; - - /* don't use Z2 RAM as system memory on Z3 capable machines */ - if (AMIGAHW_PRESENT(ZORRO3)) { - int i, j; - u32 disabled_z2mem = 0; - - for (i = 0; i < m68k_num_memory; i++) { - if (m68k_memory[i].addr < 16*1024*1024) { - if (i == 0) { - /* don't cut off the branch we're sitting on */ - printk("Warning: kernel runs in Zorro II memory\n"); - continue; - } - disabled_z2mem += m68k_memory[i].size; - m68k_num_memory--; - for (j = i; j < m68k_num_memory; j++) - m68k_memory[j] = m68k_memory[j+1]; - i--; - } - } - if (disabled_z2mem) - printk("%dK of Zorro II memory will not be used as system memory\n", - disabled_z2mem>>10); + /* Fill in the clock values (based on the 700 kHz E-Clock) */ + amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ + amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ + + /* clear all DMA bits */ + amiga_custom.dmacon = DMAF_ALL; + /* ensure that the DMA master bit is set */ + amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; + + /* don't use Z2 RAM as system memory on Z3 capable machines */ + if (AMIGAHW_PRESENT(ZORRO3)) { + int i, j; + u32 disabled_z2mem = 0; + for (i = 0; i < m68k_num_memory; i++) + if (m68k_memory[i].addr < 16*1024*1024) { + if (i == 0) { + /* don't cut off the branch we're sitting on */ + printk("Warning: kernel runs in Zorro II memory\n"); + continue; } - - /* request all RAM */ - for (i = 0; i < m68k_num_memory; i++) { - ram_resource[i].name = - (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" : - (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" : - "16-bit Slow RAM"; - ram_resource[i].start = m68k_memory[i].addr; - ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1; - request_resource(&iomem_resource, &ram_resource[i]); - } - - /* initialize chipram allocator */ - amiga_chip_init(); - - /* our beloved beeper */ - if (AMIGAHW_PRESENT(AMI_AUDIO)) - amiga_init_sound(); - - /* - * if it is an A3000, set the magic bit that forces - * a hard rekick - */ - if (AMIGAHW_PRESENT(MAGIC_REKICK)) - *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; + disabled_z2mem += m68k_memory[i].size; + m68k_num_memory--; + for (j = i; j < m68k_num_memory; j++) + m68k_memory[j] = m68k_memory[j+1]; + i--; + } + if (disabled_z2mem) + printk("%dK of Zorro II memory will not be used as system memory\n", + disabled_z2mem>>10); + } + + /* request all RAM */ + for (i = 0; i < m68k_num_memory; i++) { + ram_resource[i].name = + (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" : + (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" : + "16-bit Slow RAM"; + ram_resource[i].start = m68k_memory[i].addr; + ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1; + request_resource(&iomem_resource, &ram_resource[i]); + } + + /* initialize chipram allocator */ + amiga_chip_init (); + + /* debugging using chipram */ + if (!strcmp( m68k_debug_device, "mem" )){ + if (!AMIGAHW_PRESENT(CHIP_RAM)) + printk("Warning: no chipram present for debugging\n"); + else { + amiga_savekmsg_init(); + amiga_console_driver.write = amiga_mem_console_write; + register_console(&amiga_console_driver); + } + } + + /* our beloved beeper */ + if (AMIGAHW_PRESENT(AMI_AUDIO)) + amiga_init_sound(); + + /* + * if it is an A3000, set the magic bit that forces + * a hard rekick + */ + if (AMIGAHW_PRESENT(MAGIC_REKICK)) + *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; } static unsigned short jiffy_ticks; @@ -470,12 +490,12 @@ static unsigned short jiffy_ticks; static void __init amiga_sched_init(irq_handler_t timer_routine) { static struct resource sched_res = { - .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, + .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, }; jiffy_ticks = (amiga_eclock+HZ/2)/HZ; if (request_resource(&mb_resources._ciab, &sched_res)) - printk("Cannot allocate ciab.ta{lo,hi}\n"); + printk("Cannot allocate ciab.ta{lo,hi}\n"); ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ ciab.talo = jiffy_ticks % 256; ciab.tahi = jiffy_ticks / 256; @@ -493,7 +513,7 @@ static void __init amiga_sched_init(irq_handler_t timer_routine) #define TICK_SIZE 10000 /* This is always executed with interrupts disabled. */ -static unsigned long amiga_gettimeoffset(void) +static unsigned long amiga_gettimeoffset (void) { unsigned short hi, lo, hi2; unsigned long ticks, offset = 0; @@ -565,15 +585,15 @@ static int a2000_hwclk(int op, struct rtc_time *t) tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD; - while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { - tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; - udelay(70); - tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; + while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) + { + tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; + udelay(70); + tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; } if (!cnt) - printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", - tod_2000.cntrl1); + printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1); if (!op) { /* read */ t->tm_sec = tod_2000.second1 * 10 + tod_2000.second2; @@ -586,7 +606,7 @@ static int a2000_hwclk(int op, struct rtc_time *t) if (t->tm_year <= 69) t->tm_year += 100; - if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)) { + if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)){ if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12) t->tm_hour = 0; else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12) @@ -622,7 +642,7 @@ static int a2000_hwclk(int op, struct rtc_time *t) return 0; } -static int amiga_set_clock_mmss(unsigned long nowtime) +static int amiga_set_clock_mmss (unsigned long nowtime) { short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; @@ -640,7 +660,8 @@ static int amiga_set_clock_mmss(unsigned long nowtime) tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; - while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { + while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) + { tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; udelay(70); tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; @@ -660,7 +681,7 @@ static int amiga_set_clock_mmss(unsigned long nowtime) return 0; } -static unsigned int amiga_get_ss(void) +static unsigned int amiga_get_ss( void ) { unsigned int s; @@ -674,72 +695,71 @@ static unsigned int amiga_get_ss(void) return s; } -static NORET_TYPE void amiga_reset(void) +static NORET_TYPE void amiga_reset( void ) ATTRIB_NORET; -static void amiga_reset(void) +static void amiga_reset (void) { - unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); - unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label); - - local_irq_disable(); - if (CPU_IS_040_OR_060) - /* Setup transparent translation registers for mapping - * of 16 MB kernel segment before disabling translation - */ - asm volatile ("\n" - " move.l %0,%%d0\n" - " and.l #0xff000000,%%d0\n" - " or.w #0xe020,%%d0\n" /* map 16 MB, enable, cacheable */ - " .chip 68040\n" - " movec %%d0,%%itt0\n" - " movec %%d0,%%dtt0\n" - " .chip 68k\n" - " jmp %0@\n" - : /* no outputs */ - : "a" (jmp_addr040) - : "d0"); - else - /* for 680[23]0, just disable translation and jump to the physical - * address of the label - */ - asm volatile ("\n" - " pmove %%tc,%@\n" - " bclr #7,%@\n" - " pmove %@,%%tc\n" - " jmp %0@\n" - : /* no outputs */ - : "a" (jmp_addr)); -jmp_addr_label040: - /* disable translation on '040 now */ - asm volatile ("\n" - " moveq #0,%%d0\n" - " .chip 68040\n" - " movec %%d0,%%tc\n" /* disable MMU */ - " .chip 68k\n" - : /* no outputs */ - : /* no inputs */ - : "d0"); - - jmp_addr_label: - /* pickup reset address from AmigaOS ROM, reset devices and jump - * to reset address - */ - asm volatile ("\n" - " move.w #0x2700,%sr\n" - " lea 0x01000000,%a0\n" - " sub.l %a0@(-0x14),%a0\n" - " move.l %a0@(4),%a0\n" - " subq.l #2,%a0\n" - " jra 1f\n" - /* align on a longword boundary */ - " " __ALIGN_STR "\n" - "1:\n" - " reset\n" - " jmp %a0@"); - - for (;;) - ; + unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); + unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label); + + local_irq_disable(); + if (CPU_IS_040_OR_060) + /* Setup transparent translation registers for mapping + * of 16 MB kernel segment before disabling translation + */ + __asm__ __volatile__ + ("movel %0,%/d0\n\t" + "andl #0xff000000,%/d0\n\t" + "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */ + ".chip 68040\n\t" + "movec %%d0,%%itt0\n\t" + "movec %%d0,%%dtt0\n\t" + ".chip 68k\n\t" + "jmp %0@\n\t" + : /* no outputs */ + : "a" (jmp_addr040)); + else + /* for 680[23]0, just disable translation and jump to the physical + * address of the label + */ + __asm__ __volatile__ + ("pmove %/tc,%@\n\t" + "bclr #7,%@\n\t" + "pmove %@,%/tc\n\t" + "jmp %0@\n\t" + : /* no outputs */ + : "a" (jmp_addr)); + jmp_addr_label040: + /* disable translation on '040 now */ + __asm__ __volatile__ + ("moveq #0,%/d0\n\t" + ".chip 68040\n\t" + "movec %%d0,%%tc\n\t" /* disable MMU */ + ".chip 68k\n\t" + : /* no outputs */ + : /* no inputs */ + : "d0"); + + jmp_addr_label: + /* pickup reset address from AmigaOS ROM, reset devices and jump + * to reset address + */ + __asm__ __volatile__ + ("movew #0x2700,%/sr\n\t" + "leal 0x01000000,%/a0\n\t" + "subl %/a0@(-0x14),%/a0\n\t" + "movel %/a0@(4),%/a0\n\t" + "subql #2,%/a0\n\t" + "bra 1f\n\t" + /* align on a longword boundary */ + __ALIGN_STR "\n" + "1:\n\t" + "reset\n\t" + "jmp %/a0@" : /* Just that gcc scans it for % escapes */ ); + + for (;;); + } @@ -753,11 +773,11 @@ static void amiga_reset(void) #define SAVEKMSG_MAGIC2 0x4B4D5347 /* 'KMSG' */ struct savekmsg { - unsigned long magic1; /* SAVEKMSG_MAGIC1 */ - unsigned long magic2; /* SAVEKMSG_MAGIC2 */ - unsigned long magicptr; /* address of magic1 */ - unsigned long size; - char data[0]; + unsigned long magic1; /* SAVEKMSG_MAGIC1 */ + unsigned long magic2; /* SAVEKMSG_MAGIC2 */ + unsigned long magicptr; /* address of magic1 */ + unsigned long size; + char data[0]; }; static struct savekmsg *savekmsg; @@ -765,132 +785,113 @@ static struct savekmsg *savekmsg; static void amiga_mem_console_write(struct console *co, const char *s, unsigned int count) { - if (savekmsg->size + count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { - memcpy(savekmsg->data + savekmsg->size, s, count); - savekmsg->size += count; - } + if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { + memcpy(savekmsg->data+savekmsg->size, s, count); + savekmsg->size += count; + } } -static int __init amiga_savekmsg_setup(char *arg) +static void amiga_savekmsg_init(void) { - static struct resource debug_res = { .name = "Debug" }; - - if (!MACH_IS_AMIGA || strcmp(arg, "mem")) - goto done; - - if (!AMIGAHW_PRESENT(CHIP_RAM)) { - printk("Warning: no chipram present for debugging\n"); - goto done; - } + static struct resource debug_res = { .name = "Debug" }; - savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); - savekmsg->magic1 = SAVEKMSG_MAGIC1; - savekmsg->magic2 = SAVEKMSG_MAGIC2; - savekmsg->magicptr = ZTWO_PADDR(savekmsg); - savekmsg->size = 0; - - amiga_console_driver.write = amiga_mem_console_write; - register_console(&amiga_console_driver); - -done: - return 0; + savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); + savekmsg->magic1 = SAVEKMSG_MAGIC1; + savekmsg->magic2 = SAVEKMSG_MAGIC2; + savekmsg->magicptr = ZTWO_PADDR(savekmsg); + savekmsg->size = 0; } -early_param("debug", amiga_savekmsg_setup); - static void amiga_serial_putc(char c) { - amiga_custom.serdat = (unsigned char)c | 0x100; - while (!(amiga_custom.serdatr & 0x2000)) - ; + amiga_custom.serdat = (unsigned char)c | 0x100; + while (!(amiga_custom.serdatr & 0x2000)) + ; } void amiga_serial_console_write(struct console *co, const char *s, - unsigned int count) + unsigned int count) { - while (count--) { - if (*s == '\n') - amiga_serial_putc('\r'); - amiga_serial_putc(*s++); - } + while (count--) { + if (*s == '\n') + amiga_serial_putc('\r'); + amiga_serial_putc(*s++); + } } #ifdef CONFIG_SERIAL_CONSOLE void amiga_serial_puts(const char *s) { - amiga_serial_console_write(NULL, s, strlen(s)); + amiga_serial_console_write(NULL, s, strlen(s)); } int amiga_serial_console_wait_key(struct console *co) { - int ch; - - while (!(amiga_custom.intreqr & IF_RBF)) - barrier(); - ch = amiga_custom.serdatr & 0xff; - /* clear the interrupt, so that another character can be read */ - amiga_custom.intreq = IF_RBF; - return ch; + int ch; + + while (!(amiga_custom.intreqr & IF_RBF)) + barrier(); + ch = amiga_custom.serdatr & 0xff; + /* clear the interrupt, so that another character can be read */ + amiga_custom.intreq = IF_RBF; + return ch; } void amiga_serial_gets(struct console *co, char *s, int len) { - int ch, cnt = 0; - - while (1) { - ch = amiga_serial_console_wait_key(co); - - /* Check for backspace. */ - if (ch == 8 || ch == 127) { - if (cnt == 0) { - amiga_serial_putc('\007'); - continue; - } - cnt--; - amiga_serial_puts("\010 \010"); - continue; - } - - /* Check for enter. */ - if (ch == 10 || ch == 13) - break; + int ch, cnt = 0; + + while (1) { + ch = amiga_serial_console_wait_key(co); + + /* Check for backspace. */ + if (ch == 8 || ch == 127) { + if (cnt == 0) { + amiga_serial_putc('\007'); + continue; + } + cnt--; + amiga_serial_puts("\010 \010"); + continue; + } - /* See if line is too long. */ - if (cnt >= len + 1) { - amiga_serial_putc(7); - cnt--; - continue; - } + /* Check for enter. */ + if (ch == 10 || ch == 13) + break; - /* Store and echo character. */ - s[cnt++] = ch; - amiga_serial_putc(ch); + /* See if line is too long. */ + if (cnt >= len + 1) { + amiga_serial_putc(7); + cnt--; + continue; } - /* Print enter. */ - amiga_serial_puts("\r\n"); - s[cnt] = 0; + + /* Store and echo character. */ + s[cnt++] = ch; + amiga_serial_putc(ch); + } + /* Print enter. */ + amiga_serial_puts("\r\n"); + s[cnt] = 0; } #endif -static int __init amiga_debug_setup(char *arg) +static void __init amiga_debug_init(void) { - if (MACH_IS_AMIGA && !strcmp(arg, "ser")) { + if (!strcmp( m68k_debug_device, "ser" )) { /* no initialization required (?) */ amiga_console_driver.write = amiga_serial_console_write; register_console(&amiga_console_driver); } - return 0; } -early_param("debug", amiga_debug_setup); - #ifdef CONFIG_HEARTBEAT static void amiga_heartbeat(int on) { - if (on) - ciaa.pra &= ~2; - else - ciaa.pra |= 2; + if (on) + ciaa.pra &= ~2; + else + ciaa.pra |= 2; } #endif @@ -900,81 +901,81 @@ static void amiga_heartbeat(int on) static void amiga_get_model(char *model) { - strcpy(model, amiga_model_name); + strcpy(model, amiga_model_name); } static int amiga_get_hardware_list(char *buffer) { - int len = 0; - - if (AMIGAHW_PRESENT(CHIP_RAM)) - len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10); - len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n", - amiga_psfreq, amiga_eclock); - if (AMIGAHW_PRESENT(AMI_VIDEO)) { - char *type; - switch (amiga_chipset) { - case CS_OCS: - type = "OCS"; - break; - case CS_ECS: - type = "ECS"; - break; - case CS_AGA: - type = "AGA"; - break; - default: - type = "Old or Unknown"; - break; - } - len += sprintf(buffer+len, "Graphics:\t%s\n", type); + int len = 0; + + if (AMIGAHW_PRESENT(CHIP_RAM)) + len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10); + len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n", + amiga_psfreq, amiga_eclock); + if (AMIGAHW_PRESENT(AMI_VIDEO)) { + char *type; + switch(amiga_chipset) { + case CS_OCS: + type = "OCS"; + break; + case CS_ECS: + type = "ECS"; + break; + case CS_AGA: + type = "AGA"; + break; + default: + type = "Old or Unknown"; + break; } + len += sprintf(buffer+len, "Graphics:\t%s\n", type); + } #define AMIGAHW_ANNOUNCE(name, str) \ - if (AMIGAHW_PRESENT(name)) \ - len += sprintf (buffer+len, "\t%s\n", str) - - len += sprintf (buffer + len, "Detected hardware:\n"); - - AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video"); - AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter"); - AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer"); - AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio"); - AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller"); - AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)"); - AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)"); - AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)"); - AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)"); - AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive"); - AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard"); - AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port"); - AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port"); - AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port"); - AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)"); - AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)"); - AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM"); - AMIGAHW_ANNOUNCE(PAULA, "Paula 8364"); - AMIGAHW_ANNOUNCE(DENISE, "Denise 8362"); - AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373"); - AMIGAHW_ANNOUNCE(LISA, "Lisa 8375"); - AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371"); - AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370"); - AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372"); - AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372"); - AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374"); - AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); - AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); - AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); + if (AMIGAHW_PRESENT(name)) \ + len += sprintf (buffer+len, "\t%s\n", str) + + len += sprintf (buffer + len, "Detected hardware:\n"); + + AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video"); + AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter"); + AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer"); + AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio"); + AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller"); + AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)"); + AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)"); + AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)"); + AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)"); + AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive"); + AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard"); + AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port"); + AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port"); + AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port"); + AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)"); + AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)"); + AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM"); + AMIGAHW_ANNOUNCE(PAULA, "Paula 8364"); + AMIGAHW_ANNOUNCE(DENISE, "Denise 8362"); + AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373"); + AMIGAHW_ANNOUNCE(LISA, "Lisa 8375"); + AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371"); + AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370"); + AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372"); + AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372"); + AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374"); + AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); + AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); + AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); #ifdef CONFIG_ZORRO - if (AMIGAHW_PRESENT(ZORRO)) - len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " - "Device%s\n", - AMIGAHW_PRESENT(ZORRO3) ? "I" : "", - zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); + if (AMIGAHW_PRESENT(ZORRO)) + len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " + "Device%s\n", + AMIGAHW_PRESENT(ZORRO3) ? "I" : "", + zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); #endif /* CONFIG_ZORRO */ #undef AMIGAHW_ANNOUNCE - return len; + return(len); } diff --git a/trunk/arch/m68k/apollo/dn_ints.c b/trunk/arch/m68k/apollo/dn_ints.c index 13bd41bed28e..4274af125998 100644 --- a/trunk/arch/m68k/apollo/dn_ints.c +++ b/trunk/arch/m68k/apollo/dn_ints.c @@ -31,7 +31,7 @@ void apollo_irq_shutdown(unsigned int irq) static struct irq_controller apollo_irq_controller = { .name = "apollo", - .lock = __SPIN_LOCK_UNLOCKED(apollo_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .startup = apollo_irq_startup, .shutdown = apollo_irq_shutdown, }; diff --git a/trunk/arch/m68k/atari/Makefile b/trunk/arch/m68k/atari/Makefile index 2cb86191f0aa..8cb6236b39db 100644 --- a/trunk/arch/m68k/atari/Makefile +++ b/trunk/arch/m68k/atari/Makefile @@ -8,4 +8,3 @@ obj-y := config.o time.o debug.o ataints.o stdma.o \ ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_HADES) += hades-pci.o endif -obj-$(CONFIG_ATARI_KBD_CORE) += atakeyb.o diff --git a/trunk/arch/m68k/atari/ataints.c b/trunk/arch/m68k/atari/ataints.c index b85ca22024c1..7f812641790c 100644 --- a/trunk/arch/m68k/atari/ataints.c +++ b/trunk/arch/m68k/atari/ataints.c @@ -339,7 +339,7 @@ static void atari_shutdown_irq(unsigned int irq) static struct irq_controller atari_irq_controller = { .name = "atari", - .lock = __SPIN_LOCK_UNLOCKED(atari_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .startup = atari_startup_irq, .shutdown = atari_shutdown_irq, .enable = atari_enable_irq, diff --git a/trunk/arch/m68k/atari/atakeyb.c b/trunk/arch/m68k/atari/atakeyb.c deleted file mode 100644 index 1c29603b16b3..000000000000 --- a/trunk/arch/m68k/atari/atakeyb.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * linux/atari/atakeyb.c - * - * Atari Keyboard driver for 680x0 Linux - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -/* - * Atari support by Robert de Vries - * enhanced by Bjoern Brauel and Roman Hodek - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static void atakeyb_rep(unsigned long ignore); -extern unsigned int keymap_count; - -/* Hook for MIDI serial driver */ -void (*atari_MIDI_interrupt_hook) (void); -/* Hook for mouse driver */ -void (*atari_mouse_interrupt_hook) (char *); -/* Hook for keyboard inputdev driver */ -void (*atari_input_keyboard_interrupt_hook) (unsigned char, char); -/* Hook for mouse inputdev driver */ -void (*atari_input_mouse_interrupt_hook) (char *); - -/* variables for IKBD self test: */ - -/* state: 0: off; >0: in progress; >1: 0xf1 received */ -static volatile int ikbd_self_test; -/* timestamp when last received a char */ -static volatile unsigned long self_test_last_rcv; -/* bitmap of keys reported as broken */ -static unsigned long broken_keys[128/(sizeof(unsigned long)*8)] = { 0, }; - -#define BREAK_MASK (0x80) - -/* - * ++roman: The following changes were applied manually: - * - * - The Alt (= Meta) key works in combination with Shift and - * Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends - * Meta-Ctrl-A (0x81) ... - * - * - The parentheses on the keypad send '(' and ')' with all - * modifiers (as would do e.g. keypad '+'), but they cannot be used as - * application keys (i.e. sending Esc O c). - * - * - HELP and UNDO are mapped to be F21 and F24, resp, that send the - * codes "\E[M" and "\E[P". (This is better than the old mapping to - * F11 and F12, because these codes are on Shift+F1/2 anyway.) This - * way, applications that allow their own keyboard mappings - * (e.g. tcsh, X Windows) can be configured to use them in the way - * the label suggests (providing help or undoing). - * - * - Console switching is done with Alt+Fx (consoles 1..10) and - * Shift+Alt+Fx (consoles 11..20). - * - * - The misc. special function implemented in the kernel are mapped - * to the following key combinations: - * - * ClrHome -> Home/Find - * Shift + ClrHome -> End/Select - * Shift + Up -> Page Up - * Shift + Down -> Page Down - * Alt + Help -> show system status - * Shift + Help -> show memory info - * Ctrl + Help -> show registers - * Ctrl + Alt + Del -> Reboot - * Alt + Undo -> switch to last console - * Shift + Undo -> send interrupt - * Alt + Insert -> stop/start output (same as ^S/^Q) - * Alt + Up -> Scroll back console (if implemented) - * Alt + Down -> Scroll forward console (if implemented) - * Alt + CapsLock -> NumLock - * - * ++Andreas: - * - * - Help mapped to K_HELP - * - Undo mapped to K_UNDO (= K_F246) - * - Keypad Left/Right Parenthesis mapped to new K_PPAREN[LR] - */ - -static u_short ataplain_map[NR_KEYS] __initdata = { - 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, - 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf008, 0xf009, - 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, - 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73, - 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b, - 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, - 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf200, - 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, - 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114, - 0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200, - 0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf1ff, 0xf11b, 0xf312, 0xf313, 0xf30d, 0xf30c, 0xf307, - 0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303, - 0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200 -}; - -typedef enum kb_state_t { - KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC -} KB_STATE_T; - -#define IS_SYNC_CODE(sc) ((sc) >= 0x04 && (sc) <= 0xfb) - -typedef struct keyboard_state { - unsigned char buf[6]; - int len; - KB_STATE_T state; -} KEYBOARD_STATE; - -KEYBOARD_STATE kb_state; - -#define DEFAULT_KEYB_REP_DELAY (HZ/4) -#define DEFAULT_KEYB_REP_RATE (HZ/25) - -/* These could be settable by some ioctl() in future... */ -static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY; -static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE; - -static unsigned char rep_scancode; -static struct timer_list atakeyb_rep_timer = { - .function = atakeyb_rep, -}; - -static void atakeyb_rep(unsigned long ignore) -{ - /* Disable keyboard for the time we call handle_scancode(), else a race - * in the keyboard tty queue may happen */ - atari_disable_irq(IRQ_MFP_ACIA); - del_timer(&atakeyb_rep_timer); - - /* A keyboard int may have come in before we disabled the irq, so - * double-check whether rep_scancode is still != 0 */ - if (rep_scancode) { - init_timer(&atakeyb_rep_timer); - atakeyb_rep_timer.expires = jiffies + key_repeat_rate; - add_timer(&atakeyb_rep_timer); - - //handle_scancode(rep_scancode, 1); - if (atari_input_keyboard_interrupt_hook) - atari_input_keyboard_interrupt_hook(rep_scancode, 1); - } - - atari_enable_irq(IRQ_MFP_ACIA); -} - - -/* ++roman: If a keyboard overrun happened, we can't tell in general how much - * bytes have been lost and in which state of the packet structure we are now. - * This usually causes keyboards bytes to be interpreted as mouse movements - * and vice versa, which is very annoying. It seems better to throw away some - * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I - * introduced the RESYNC state for IKBD data. In this state, the bytes up to - * one that really looks like a key event (0x04..0xf2) or the start of a mouse - * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least - * speeds up the resynchronization of the event structure, even if maybe a - * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03, - * it's really hard to decide whether they're mouse or keyboard bytes. Since - * overruns usually occur when moving the Atari mouse rapidly, they're seen as - * mouse bytes here. If this is wrong, only a make code of the keyboard gets - * lost, which isn't too bad. Loosing a break code would be disastrous, - * because then the keyboard repeat strikes... - */ - -static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy) -{ - u_char acia_stat; - int scancode; - int break_flag; - -repeat: - if (acia.mid_ctrl & ACIA_IRQ) - if (atari_MIDI_interrupt_hook) - atari_MIDI_interrupt_hook(); - acia_stat = acia.key_ctrl; - /* check out if the interrupt came from this ACIA */ - if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ)) - return IRQ_HANDLED; - - if (acia_stat & ACIA_OVRN) { - /* a very fast typist or a slow system, give a warning */ - /* ...happens often if interrupts were disabled for too long */ - printk(KERN_DEBUG "Keyboard overrun\n"); - scancode = acia.key_data; - /* Turn off autorepeating in case a break code has been lost */ - del_timer(&atakeyb_rep_timer); - rep_scancode = 0; - if (ikbd_self_test) - /* During self test, don't do resyncing, just process the code */ - goto interpret_scancode; - else if (IS_SYNC_CODE(scancode)) { - /* This code seem already to be the start of a new packet or a - * single scancode */ - kb_state.state = KEYBOARD; - goto interpret_scancode; - } else { - /* Go to RESYNC state and skip this byte */ - kb_state.state = RESYNC; - kb_state.len = 1; /* skip max. 1 another byte */ - goto repeat; - } - } - - if (acia_stat & ACIA_RDRF) { - /* received a character */ - scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */ - tasklet_schedule(&keyboard_tasklet); - interpret_scancode: - switch (kb_state.state) { - case KEYBOARD: - switch (scancode) { - case 0xF7: - kb_state.state = AMOUSE; - kb_state.len = 0; - break; - - case 0xF8: - case 0xF9: - case 0xFA: - case 0xFB: - kb_state.state = RMOUSE; - kb_state.len = 1; - kb_state.buf[0] = scancode; - break; - - case 0xFC: - kb_state.state = CLOCK; - kb_state.len = 0; - break; - - case 0xFE: - case 0xFF: - kb_state.state = JOYSTICK; - kb_state.len = 1; - kb_state.buf[0] = scancode; - break; - - case 0xF1: - /* during self-test, note that 0xf1 received */ - if (ikbd_self_test) { - ++ikbd_self_test; - self_test_last_rcv = jiffies; - break; - } - /* FALL THROUGH */ - - default: - break_flag = scancode & BREAK_MASK; - scancode &= ~BREAK_MASK; - if (ikbd_self_test) { - /* Scancodes sent during the self-test stand for broken - * keys (keys being down). The code *should* be a break - * code, but nevertheless some AT keyboard interfaces send - * make codes instead. Therefore, simply ignore - * break_flag... - */ - int keyval = plain_map[scancode], keytyp; - - set_bit(scancode, broken_keys); - self_test_last_rcv = jiffies; - keyval = plain_map[scancode]; - keytyp = KTYP(keyval) - 0xf0; - keyval = KVAL(keyval); - - printk(KERN_WARNING "Key with scancode %d ", scancode); - if (keytyp == KT_LATIN || keytyp == KT_LETTER) { - if (keyval < ' ') - printk("('^%c') ", keyval + '@'); - else - printk("('%c') ", keyval); - } - printk("is broken -- will be ignored.\n"); - break; - } else if (test_bit(scancode, broken_keys)) - break; - -#if 0 // FIXME; hangs at boot - if (break_flag) { - del_timer(&atakeyb_rep_timer); - rep_scancode = 0; - } else { - del_timer(&atakeyb_rep_timer); - rep_scancode = scancode; - atakeyb_rep_timer.expires = jiffies + key_repeat_delay; - add_timer(&atakeyb_rep_timer); - } -#endif - - // handle_scancode(scancode, !break_flag); - if (atari_input_keyboard_interrupt_hook) - atari_input_keyboard_interrupt_hook((unsigned char)scancode, !break_flag); - break; - } - break; - - case AMOUSE: - kb_state.buf[kb_state.len++] = scancode; - if (kb_state.len == 5) { - kb_state.state = KEYBOARD; - /* not yet used */ - /* wake up someone waiting for this */ - } - break; - - case RMOUSE: - kb_state.buf[kb_state.len++] = scancode; - if (kb_state.len == 3) { - kb_state.state = KEYBOARD; - if (atari_mouse_interrupt_hook) - atari_mouse_interrupt_hook(kb_state.buf); - } - break; - - case JOYSTICK: - kb_state.buf[1] = scancode; - kb_state.state = KEYBOARD; -#ifdef FIXED_ATARI_JOYSTICK - atari_joystick_interrupt(kb_state.buf); -#endif - break; - - case CLOCK: - kb_state.buf[kb_state.len++] = scancode; - if (kb_state.len == 6) { - kb_state.state = KEYBOARD; - /* wake up someone waiting for this. - But will this ever be used, as Linux keeps its own time. - Perhaps for synchronization purposes? */ - /* wake_up_interruptible(&clock_wait); */ - } - break; - - case RESYNC: - if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) { - kb_state.state = KEYBOARD; - goto interpret_scancode; - } - kb_state.len--; - break; - } - } - -#if 0 - if (acia_stat & ACIA_CTS) - /* cannot happen */; -#endif - - if (acia_stat & (ACIA_FE | ACIA_PE)) { - printk("Error in keyboard communication\n"); - } - - /* handle_scancode() can take a lot of time, so check again if - * some character arrived - */ - goto repeat; -} - -/* - * I write to the keyboard without using interrupts, I poll instead. - * This takes for the maximum length string allowed (7) at 7812.5 baud - * 8 data 1 start 1 stop bit: 9.0 ms - * If this takes too long for normal operation, interrupt driven writing - * is the solution. (I made a feeble attempt in that direction but I - * kept it simple for now.) - */ -void ikbd_write(const char *str, int len) -{ - u_char acia_stat; - - if ((len < 1) || (len > 7)) - panic("ikbd: maximum string length exceeded"); - while (len) { - acia_stat = acia.key_ctrl; - if (acia_stat & ACIA_TDRE) { - acia.key_data = *str++; - len--; - } - } -} - -/* Reset (without touching the clock) */ -void ikbd_reset(void) -{ - static const char cmd[2] = { 0x80, 0x01 }; - - ikbd_write(cmd, 2); - - /* - * if all's well code 0xF1 is returned, else the break codes of - * all keys making contact - */ -} - -/* Set mouse button action */ -void ikbd_mouse_button_action(int mode) -{ - char cmd[2] = { 0x07, mode }; - - ikbd_write(cmd, 2); -} - -/* Set relative mouse position reporting */ -void ikbd_mouse_rel_pos(void) -{ - static const char cmd[1] = { 0x08 }; - - ikbd_write(cmd, 1); -} - -/* Set absolute mouse position reporting */ -void ikbd_mouse_abs_pos(int xmax, int ymax) -{ - char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF }; - - ikbd_write(cmd, 5); -} - -/* Set mouse keycode mode */ -void ikbd_mouse_kbd_mode(int dx, int dy) -{ - char cmd[3] = { 0x0A, dx, dy }; - - ikbd_write(cmd, 3); -} - -/* Set mouse threshold */ -void ikbd_mouse_thresh(int x, int y) -{ - char cmd[3] = { 0x0B, x, y }; - - ikbd_write(cmd, 3); -} - -/* Set mouse scale */ -void ikbd_mouse_scale(int x, int y) -{ - char cmd[3] = { 0x0C, x, y }; - - ikbd_write(cmd, 3); -} - -/* Interrogate mouse position */ -void ikbd_mouse_pos_get(int *x, int *y) -{ - static const char cmd[1] = { 0x0D }; - - ikbd_write(cmd, 1); - - /* wait for returning bytes */ -} - -/* Load mouse position */ -void ikbd_mouse_pos_set(int x, int y) -{ - char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF }; - - ikbd_write(cmd, 6); -} - -/* Set Y=0 at bottom */ -void ikbd_mouse_y0_bot(void) -{ - static const char cmd[1] = { 0x0F }; - - ikbd_write(cmd, 1); -} - -/* Set Y=0 at top */ -void ikbd_mouse_y0_top(void) -{ - static const char cmd[1] = { 0x10 }; - - ikbd_write(cmd, 1); -} - -/* Resume */ -void ikbd_resume(void) -{ - static const char cmd[1] = { 0x11 }; - - ikbd_write(cmd, 1); -} - -/* Disable mouse */ -void ikbd_mouse_disable(void) -{ - static const char cmd[1] = { 0x12 }; - - ikbd_write(cmd, 1); -} - -/* Pause output */ -void ikbd_pause(void) -{ - static const char cmd[1] = { 0x13 }; - - ikbd_write(cmd, 1); -} - -/* Set joystick event reporting */ -void ikbd_joystick_event_on(void) -{ - static const char cmd[1] = { 0x14 }; - - ikbd_write(cmd, 1); -} - -/* Set joystick interrogation mode */ -void ikbd_joystick_event_off(void) -{ - static const char cmd[1] = { 0x15 }; - - ikbd_write(cmd, 1); -} - -/* Joystick interrogation */ -void ikbd_joystick_get_state(void) -{ - static const char cmd[1] = { 0x16 }; - - ikbd_write(cmd, 1); -} - -#if 0 -/* This disables all other ikbd activities !!!! */ -/* Set joystick monitoring */ -void ikbd_joystick_monitor(int rate) -{ - static const char cmd[2] = { 0x17, rate }; - - ikbd_write(cmd, 2); - - kb_state.state = JOYSTICK_MONITOR; -} -#endif - -/* some joystick routines not in yet (0x18-0x19) */ - -/* Disable joysticks */ -void ikbd_joystick_disable(void) -{ - static const char cmd[1] = { 0x1A }; - - ikbd_write(cmd, 1); -} - -/* Time-of-day clock set */ -void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second) -{ - char cmd[7] = { 0x1B, year, month, day, hour, minute, second }; - - ikbd_write(cmd, 7); -} - -/* Interrogate time-of-day clock */ -void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second) -{ - static const char cmd[1] = { 0x1C }; - - ikbd_write(cmd, 1); -} - -/* Memory load */ -void ikbd_mem_write(int address, int size, char *data) -{ - panic("Attempt to write data into keyboard memory"); -} - -/* Memory read */ -void ikbd_mem_read(int address, char data[6]) -{ - char cmd[3] = { 0x21, address>>8, address&0xFF }; - - ikbd_write(cmd, 3); - - /* receive data and put it in data */ -} - -/* Controller execute */ -void ikbd_exec(int address) -{ - char cmd[3] = { 0x22, address>>8, address&0xFF }; - - ikbd_write(cmd, 3); -} - -/* Status inquiries (0x87-0x9A) not yet implemented */ - -/* Set the state of the caps lock led. */ -void atari_kbd_leds(unsigned int leds) -{ - char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0}; - - ikbd_write(cmd, 6); -} - -/* - * The original code sometimes left the interrupt line of - * the ACIAs low forever. I hope, it is fixed now. - * - * Martin Rogge, 20 Aug 1995 - */ - -static int atari_keyb_done = 0; - -int __init atari_keyb_init(void) -{ - if (atari_keyb_done) - return 0; - - /* setup key map */ - memcpy(key_maps[0], ataplain_map, sizeof(plain_map)); - - kb_state.state = KEYBOARD; - kb_state.len = 0; - - request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt, IRQ_TYPE_SLOW, - "keyboard/mouse/MIDI", atari_keyboard_interrupt); - - atari_turnoff_irq(IRQ_MFP_ACIA); - do { - /* reset IKBD ACIA */ - acia.key_ctrl = ACIA_RESET | - (atari_switches & ATARI_SWITCH_IKBD) ? ACIA_RHTID : 0; - (void)acia.key_ctrl; - (void)acia.key_data; - - /* reset MIDI ACIA */ - acia.mid_ctrl = ACIA_RESET | - (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0; - (void)acia.mid_ctrl; - (void)acia.mid_data; - - /* divide 500kHz by 64 gives 7812.5 baud */ - /* 8 data no parity 1 start 1 stop bit */ - /* receive interrupt enabled */ - /* RTS low (except if switch selected), transmit interrupt disabled */ - acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RIE) | - ((atari_switches & ATARI_SWITCH_IKBD) ? - ACIA_RHTID : ACIA_RLTID); - - acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | - (atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : 0; - - /* make sure the interrupt line is up */ - } while ((mfp.par_dt_reg & 0x10) == 0); - - /* enable ACIA Interrupts */ - mfp.active_edge &= ~0x10; - atari_turnon_irq(IRQ_MFP_ACIA); - - ikbd_self_test = 1; - ikbd_reset(); - /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's - * self-test is finished */ - self_test_last_rcv = jiffies; - while (time_before(jiffies, self_test_last_rcv + HZ/4)) - barrier(); - /* if not incremented: no 0xf1 received */ - if (ikbd_self_test == 1) - printk(KERN_ERR "WARNING: keyboard self test failed!\n"); - ikbd_self_test = 0; - - ikbd_mouse_disable(); - ikbd_joystick_disable(); - -#ifdef FIXED_ATARI_JOYSTICK - atari_joystick_init(); -#endif - - // flag init done - atari_keyb_done = 1; - return 0; -} - - -int atari_kbdrate(struct kbd_repeat *k) -{ - if (k->delay > 0) { - /* convert from msec to jiffies */ - key_repeat_delay = (k->delay * HZ + 500) / 1000; - if (key_repeat_delay < 1) - key_repeat_delay = 1; - } - if (k->period > 0) { - key_repeat_rate = (k->period * HZ + 500) / 1000; - if (key_repeat_rate < 1) - key_repeat_rate = 1; - } - - k->delay = key_repeat_delay * 1000 / HZ; - k->period = key_repeat_rate * 1000 / HZ; - - return 0; -} - -int atari_kbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode) -{ -#ifdef CONFIG_MAGIC_SYSRQ - /* ALT+HELP pressed? */ - if ((keycode == 98) && ((shift_state & 0xff) == 8)) - *keycodep = 0xff; - else -#endif - *keycodep = keycode; - return 1; -} diff --git a/trunk/arch/m68k/atari/atasound.h b/trunk/arch/m68k/atari/atasound.h new file mode 100644 index 000000000000..1362762b8c0f --- /dev/null +++ b/trunk/arch/m68k/atari/atasound.h @@ -0,0 +1,33 @@ +/* + * Minor numbers for the sound driver. + * + * Unfortunately Creative called the codec chip of SB as a DSP. For this + * reason the /dev/dsp is reserved for digitized audio use. There is a + * device for true DSP processors but it will be called something else. + * In v3.0 it's /dev/sndproc but this could be a temporary solution. + */ + +#define SND_NDEVS 256 /* Number of supported devices */ +#define SND_DEV_CTL 0 /* Control port /dev/mixer */ +#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM + synthesizer and MIDI output) */ +#define SND_DEV_MIDIN 2 /* Raw midi access */ +#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */ +#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */ +#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */ +#define SND_DEV_STATUS 6 /* /dev/sndstat */ +/* #7 not in use now. Was in 2.4. Free for use after v3.0. */ +#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */ +#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ +#define SND_DEV_PSS SND_DEV_SNDPROC + +#define DSP_DEFAULT_SPEED 8000 + +#define ON 1 +#define OFF 0 + +#define MAX_AUDIO_DEV 5 +#define MAX_MIXER_DEV 2 +#define MAX_SYNTH_DEV 3 +#define MAX_MIDI_DEV 6 +#define MAX_TIMER_DEV 3 diff --git a/trunk/arch/m68k/atari/config.c b/trunk/arch/m68k/atari/config.c index e40e5dcaa347..ca5cd4344e3d 100644 --- a/trunk/arch/m68k/atari/config.c +++ b/trunk/arch/m68k/atari/config.c @@ -50,25 +50,70 @@ int atari_dont_touch_floppy_select; int atari_rtc_year_offset; /* local function prototypes */ -static void atari_reset(void); +static void atari_reset( void ); static void atari_get_model(char *model); static int atari_get_hardware_list(char *buffer); /* atari specific irq functions */ extern void atari_init_IRQ (void); -extern void atari_mksound(unsigned int count, unsigned int ticks); +extern void atari_mksound( unsigned int count, unsigned int ticks ); #ifdef CONFIG_HEARTBEAT -static void atari_heartbeat(int on); +static void atari_heartbeat( int on ); #endif /* atari specific timer functions (in time.c) */ -extern void atari_sched_init(irq_handler_t); +extern void atari_sched_init(irq_handler_t ); extern unsigned long atari_gettimeoffset (void); extern int atari_mste_hwclk (int, struct rtc_time *); extern int atari_tt_hwclk (int, struct rtc_time *); extern int atari_mste_set_clock_mmss (unsigned long); extern int atari_tt_set_clock_mmss (unsigned long); +/* atari specific debug functions (in debug.c) */ +extern void atari_debug_init(void); + + +/* I've moved hwreg_present() and hwreg_present_bywrite() out into + * mm/hwtest.c, to avoid having multiple copies of the same routine + * in the kernel [I wanted them in hp300 and they were already used + * in the nubus code. NB: I don't have an Atari so this might (just + * conceivably) break something. + * I've preserved the #if 0 version of hwreg_present_bywrite() here + * for posterity. + * -- Peter Maydell , 05/1998 + */ + +#if 0 +static int __init +hwreg_present_bywrite(volatile void *regp, unsigned char val) +{ + int ret; + long save_sp, save_vbr; + static long tmp_vectors[3] = { [2] = (long)&&after_test }; + + __asm__ __volatile__ + ( "movec %/vbr,%2\n\t" /* save vbr value */ + "movec %4,%/vbr\n\t" /* set up temporary vectors */ + "movel %/sp,%1\n\t" /* save sp */ + "moveq #0,%0\n\t" /* assume not present */ + "moveb %5,%3@\n\t" /* write the hardware reg */ + "cmpb %3@,%5\n\t" /* compare it */ + "seq %0" /* comes here only if reg */ + /* is present */ + : "=d&" (ret), "=r&" (save_sp), "=r&" (save_vbr) + : "a" (regp), "r" (tmp_vectors), "d" (val) + ); + after_test: + __asm__ __volatile__ + ( "movel %0,%/sp\n\t" /* restore sp */ + "movec %1,%/vbr" /* restore vbr */ + : : "r" (save_sp), "r" (save_vbr) : "sp" + ); + + return( ret ); +} +#endif + /* ++roman: This is a more elaborate test for an SCC chip, since the plain * Medusa board generates DTACK at the SCC's standard addresses, but a SCC @@ -78,34 +123,26 @@ extern int atari_tt_set_clock_mmss (unsigned long); * should be readable without trouble (from channel A!). */ -static int __init scc_test(volatile char *ctla) +static int __init scc_test( volatile char *ctla ) { - if (!hwreg_present(ctla)) - return 0; + if (!hwreg_present( ctla )) + return( 0 ); MFPDELAY(); - *ctla = 2; - MFPDELAY(); - *ctla = 0x40; - MFPDELAY(); + *ctla = 2; MFPDELAY(); + *ctla = 0x40; MFPDELAY(); - *ctla = 2; - MFPDELAY(); - if (*ctla != 0x40) - return 0; + *ctla = 2; MFPDELAY(); + if (*ctla != 0x40) return( 0 ); MFPDELAY(); - *ctla = 2; - MFPDELAY(); - *ctla = 0x60; - MFPDELAY(); + *ctla = 2; MFPDELAY(); + *ctla = 0x60; MFPDELAY(); - *ctla = 2; - MFPDELAY(); - if (*ctla != 0x60) - return 0; + *ctla = 2; MFPDELAY(); + if (*ctla != 0x60) return( 0 ); - return 1; + return( 1 ); } @@ -115,65 +152,60 @@ static int __init scc_test(volatile char *ctla) int __init atari_parse_bootinfo(const struct bi_record *record) { - int unknown = 0; - const u_long *data = record->data; + int unknown = 0; + const u_long *data = record->data; - switch (record->tag) { + switch (record->tag) { case BI_ATARI_MCH_COOKIE: - atari_mch_cookie = *data; - break; + atari_mch_cookie = *data; + break; case BI_ATARI_MCH_TYPE: - atari_mch_type = *data; - break; + atari_mch_type = *data; + break; default: - unknown = 1; - break; - } - return unknown; + unknown = 1; + } + return(unknown); } /* Parse the Atari-specific switches= option. */ -static int __init atari_switches_setup(char *str) +void __init atari_switches_setup( const char *str, unsigned len ) { - char switches[strlen(str) + 1]; - char *p; - int ovsc_shift; - char *args = switches; - - if (!MACH_IS_ATARI) - return 0; - - /* copy string to local array, strsep works destructively... */ - strcpy(switches, str); - atari_switches = 0; - - /* parse the options */ - while ((p = strsep(&args, ",")) != NULL) { - if (!*p) - continue; - ovsc_shift = 0; - if (strncmp(p, "ov_", 3) == 0) { - p += 3; - ovsc_shift = ATARI_SWITCH_OVSC_SHIFT; - } - - if (strcmp(p, "ikbd") == 0) { - /* RTS line of IKBD ACIA */ - atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift; - } else if (strcmp(p, "midi") == 0) { - /* RTS line of MIDI ACIA */ - atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift; - } else if (strcmp(p, "snd6") == 0) { - atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift; - } else if (strcmp(p, "snd7") == 0) { - atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift; - } + char switches[len+1]; + char *p; + int ovsc_shift; + char *args = switches; + + /* copy string to local array, strsep works destructively... */ + strlcpy( switches, str, sizeof(switches) ); + atari_switches = 0; + + /* parse the options */ + while ((p = strsep(&args, ",")) != NULL) { + if (!*p) continue; + ovsc_shift = 0; + if (strncmp( p, "ov_", 3 ) == 0) { + p += 3; + ovsc_shift = ATARI_SWITCH_OVSC_SHIFT; } - return 0; -} -early_param("switches", atari_switches_setup); + if (strcmp( p, "ikbd" ) == 0) { + /* RTS line of IKBD ACIA */ + atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift; + } + else if (strcmp( p, "midi" ) == 0) { + /* RTS line of MIDI ACIA */ + atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift; + } + else if (strcmp( p, "snd6" ) == 0) { + atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift; + } + else if (strcmp( p, "snd7" ) == 0) { + atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift; + } + } +} /* @@ -182,281 +214,284 @@ early_param("switches", atari_switches_setup); void __init config_atari(void) { - unsigned short tos_version; + unsigned short tos_version; - memset(&atari_hw_present, 0, sizeof(atari_hw_present)); + memset(&atari_hw_present, 0, sizeof(atari_hw_present)); - /* Change size of I/O space from 64KB to 4GB. */ - ioport_resource.end = 0xFFFFFFFF; + atari_debug_init(); - mach_sched_init = atari_sched_init; - mach_init_IRQ = atari_init_IRQ; - mach_get_model = atari_get_model; - mach_get_hardware_list = atari_get_hardware_list; - mach_gettimeoffset = atari_gettimeoffset; - mach_reset = atari_reset; - mach_max_dma_address = 0xffffff; + ioport_resource.end = 0xFFFFFFFF; /* Change size of I/O space from 64KB + to 4GB. */ + + mach_sched_init = atari_sched_init; + mach_init_IRQ = atari_init_IRQ; + mach_get_model = atari_get_model; + mach_get_hardware_list = atari_get_hardware_list; + mach_gettimeoffset = atari_gettimeoffset; + mach_reset = atari_reset; + mach_max_dma_address = 0xffffff; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = atari_mksound; + mach_beep = atari_mksound; #endif #ifdef CONFIG_HEARTBEAT - mach_heartbeat = atari_heartbeat; + mach_heartbeat = atari_heartbeat; #endif - /* Set switches as requested by the user */ - if (atari_switches & ATARI_SWITCH_IKBD) - acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID; - if (atari_switches & ATARI_SWITCH_MIDI) - acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID; - if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) { - sound_ym.rd_data_reg_sel = 14; - sound_ym.wd_data = sound_ym.rd_data_reg_sel | - ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) | - ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0); - } + /* Set switches as requested by the user */ + if (atari_switches & ATARI_SWITCH_IKBD) + acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID; + if (atari_switches & ATARI_SWITCH_MIDI) + acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID; + if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) { + sound_ym.rd_data_reg_sel = 14; + sound_ym.wd_data = sound_ym.rd_data_reg_sel | + ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) | + ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0); + } + + /* ++bjoern: + * Determine hardware present + */ - /* ++bjoern: - * Determine hardware present - */ - - printk("Atari hardware found: "); - if (MACH_IS_MEDUSA || MACH_IS_HADES) { - /* There's no Atari video hardware on the Medusa, but all the - * addresses below generate a DTACK so no bus error occurs! */ - } else if (hwreg_present(f030_xreg)) { - ATARIHW_SET(VIDEL_SHIFTER); - printk("VIDEL "); - /* This is a temporary hack: If there is Falcon video - * hardware, we assume that the ST-DMA serves SCSI instead of - * ACSI. In the future, there should be a better method for - * this... - */ - ATARIHW_SET(ST_SCSI); - printk("STDMA-SCSI "); - } else if (hwreg_present(tt_palette)) { - ATARIHW_SET(TT_SHIFTER); - printk("TT_SHIFTER "); - } else if (hwreg_present(&shifter.bas_hi)) { - if (hwreg_present(&shifter.bas_lo) && - (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) { - ATARIHW_SET(EXTD_SHIFTER); - printk("EXTD_SHIFTER "); - } else { - ATARIHW_SET(STND_SHIFTER); - printk("STND_SHIFTER "); - } - } - if (hwreg_present(&mfp.par_dt_reg)) { - ATARIHW_SET(ST_MFP); - printk("ST_MFP "); - } - if (hwreg_present(&tt_mfp.par_dt_reg)) { - ATARIHW_SET(TT_MFP); - printk("TT_MFP "); - } - if (hwreg_present(&tt_scsi_dma.dma_addr_hi)) { - ATARIHW_SET(SCSI_DMA); - printk("TT_SCSI_DMA "); - } - if (!MACH_IS_HADES && hwreg_present(&st_dma.dma_hi)) { - ATARIHW_SET(STND_DMA); - printk("STND_DMA "); - } - /* - * The ST-DMA address registers aren't readable - * on all Medusas, so the test below may fail - */ - if (MACH_IS_MEDUSA || - (hwreg_present(&st_dma.dma_vhi) && - (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) && - st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa && - (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) && - st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) { - ATARIHW_SET(EXTD_DMA); - printk("EXTD_DMA "); - } - if (hwreg_present(&tt_scsi.scsi_data)) { - ATARIHW_SET(TT_SCSI); - printk("TT_SCSI "); - } - if (hwreg_present(&sound_ym.rd_data_reg_sel)) { - ATARIHW_SET(YM_2149); - printk("YM2149 "); - } - if (!MACH_IS_MEDUSA && !MACH_IS_HADES && - hwreg_present(&tt_dmasnd.ctrl)) { - ATARIHW_SET(PCM_8BIT); - printk("PCM "); - } - if (!MACH_IS_HADES && hwreg_present(&falcon_codec.unused5)) { - ATARIHW_SET(CODEC); - printk("CODEC "); - } - if (hwreg_present(&dsp56k_host_interface.icr)) { - ATARIHW_SET(DSP56K); - printk("DSP56K "); - } - if (hwreg_present(&tt_scc_dma.dma_ctrl) && + printk( "Atari hardware found: " ); + if (MACH_IS_MEDUSA || MACH_IS_HADES) { + /* There's no Atari video hardware on the Medusa, but all the + * addresses below generate a DTACK so no bus error occurs! */ + } + else if (hwreg_present( f030_xreg )) { + ATARIHW_SET(VIDEL_SHIFTER); + printk( "VIDEL " ); + /* This is a temporary hack: If there is Falcon video + * hardware, we assume that the ST-DMA serves SCSI instead of + * ACSI. In the future, there should be a better method for + * this... + */ + ATARIHW_SET(ST_SCSI); + printk( "STDMA-SCSI " ); + } + else if (hwreg_present( tt_palette )) { + ATARIHW_SET(TT_SHIFTER); + printk( "TT_SHIFTER " ); + } + else if (hwreg_present( &shifter.bas_hi )) { + if (hwreg_present( &shifter.bas_lo ) && + (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) { + ATARIHW_SET(EXTD_SHIFTER); + printk( "EXTD_SHIFTER " ); + } + else { + ATARIHW_SET(STND_SHIFTER); + printk( "STND_SHIFTER " ); + } + } + if (hwreg_present( &mfp.par_dt_reg )) { + ATARIHW_SET(ST_MFP); + printk( "ST_MFP " ); + } + if (hwreg_present( &tt_mfp.par_dt_reg )) { + ATARIHW_SET(TT_MFP); + printk( "TT_MFP " ); + } + if (hwreg_present( &tt_scsi_dma.dma_addr_hi )) { + ATARIHW_SET(SCSI_DMA); + printk( "TT_SCSI_DMA " ); + } + if (!MACH_IS_HADES && hwreg_present( &st_dma.dma_hi )) { + ATARIHW_SET(STND_DMA); + printk( "STND_DMA " ); + } + if (MACH_IS_MEDUSA || /* The ST-DMA address registers aren't readable + * on all Medusas, so the test below may fail */ + (hwreg_present( &st_dma.dma_vhi ) && + (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) && + st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa && + (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) && + st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) { + ATARIHW_SET(EXTD_DMA); + printk( "EXTD_DMA " ); + } + if (hwreg_present( &tt_scsi.scsi_data )) { + ATARIHW_SET(TT_SCSI); + printk( "TT_SCSI " ); + } + if (hwreg_present( &sound_ym.rd_data_reg_sel )) { + ATARIHW_SET(YM_2149); + printk( "YM2149 " ); + } + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present( &tt_dmasnd.ctrl )) { + ATARIHW_SET(PCM_8BIT); + printk( "PCM " ); + } + if (!MACH_IS_HADES && hwreg_present( &falcon_codec.unused5 )) { + ATARIHW_SET(CODEC); + printk( "CODEC " ); + } + if (hwreg_present( &dsp56k_host_interface.icr )) { + ATARIHW_SET(DSP56K); + printk( "DSP56K " ); + } + if (hwreg_present( &tt_scc_dma.dma_ctrl ) && #if 0 - /* This test sucks! Who knows some better? */ - (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) && - (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0) + /* This test sucks! Who knows some better? */ + (tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) && + (tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0) #else - !MACH_IS_MEDUSA && !MACH_IS_HADES + !MACH_IS_MEDUSA && !MACH_IS_HADES #endif - ) { - ATARIHW_SET(SCC_DMA); - printk("SCC_DMA "); - } - if (scc_test(&scc.cha_a_ctrl)) { - ATARIHW_SET(SCC); - printk("SCC "); - } - if (scc_test(&st_escc.cha_b_ctrl)) { - ATARIHW_SET(ST_ESCC); - printk("ST_ESCC "); - } - if (MACH_IS_HADES) { - ATARIHW_SET(VME); - printk("VME "); - } else if (hwreg_present(&tt_scu.sys_mask)) { - ATARIHW_SET(SCU); - /* Assume a VME bus if there's a SCU */ - ATARIHW_SET(VME); - printk("VME SCU "); - } - if (hwreg_present((void *)(0xffff9210))) { - ATARIHW_SET(ANALOG_JOY); - printk("ANALOG_JOY "); - } - if (!MACH_IS_HADES && hwreg_present(blitter.halftone)) { - ATARIHW_SET(BLITTER); - printk("BLITTER "); - } - if (hwreg_present((void *)0xfff00039)) { - ATARIHW_SET(IDE); - printk("IDE "); - } + ) { + ATARIHW_SET(SCC_DMA); + printk( "SCC_DMA " ); + } + if (scc_test( &scc.cha_a_ctrl )) { + ATARIHW_SET(SCC); + printk( "SCC " ); + } + if (scc_test( &st_escc.cha_b_ctrl )) { + ATARIHW_SET( ST_ESCC ); + printk( "ST_ESCC " ); + } + if (MACH_IS_HADES) + { + ATARIHW_SET( VME ); + printk( "VME " ); + } + else if (hwreg_present( &tt_scu.sys_mask )) { + ATARIHW_SET(SCU); + /* Assume a VME bus if there's a SCU */ + ATARIHW_SET( VME ); + printk( "VME SCU " ); + } + if (hwreg_present( (void *)(0xffff9210) )) { + ATARIHW_SET(ANALOG_JOY); + printk( "ANALOG_JOY " ); + } + if (!MACH_IS_HADES && hwreg_present( blitter.halftone )) { + ATARIHW_SET(BLITTER); + printk( "BLITTER " ); + } + if (hwreg_present((void *)0xfff00039)) { + ATARIHW_SET(IDE); + printk( "IDE " ); + } #if 1 /* This maybe wrong */ - if (!MACH_IS_MEDUSA && !MACH_IS_HADES && - hwreg_present(&tt_microwire.data) && - hwreg_present(&tt_microwire.mask) && - (tt_microwire.mask = 0x7ff, - udelay(1), - tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR, - udelay(1), - tt_microwire.data != 0)) { - ATARIHW_SET(MICROWIRE); - while (tt_microwire.mask != 0x7ff) - ; - printk("MICROWIRE "); - } + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present( &tt_microwire.data ) && + hwreg_present( &tt_microwire.mask ) && + (tt_microwire.mask = 0x7ff, + udelay(1), + tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR, + udelay(1), + tt_microwire.data != 0)) { + ATARIHW_SET(MICROWIRE); + while (tt_microwire.mask != 0x7ff) ; + printk( "MICROWIRE " ); + } #endif - if (hwreg_present(&tt_rtc.regsel)) { - ATARIHW_SET(TT_CLK); - printk("TT_CLK "); - mach_hwclk = atari_tt_hwclk; - mach_set_clock_mmss = atari_tt_set_clock_mmss; - } - if (!MACH_IS_HADES && hwreg_present(&mste_rtc.sec_ones)) { - ATARIHW_SET(MSTE_CLK); - printk("MSTE_CLK "); - mach_hwclk = atari_mste_hwclk; - mach_set_clock_mmss = atari_mste_set_clock_mmss; - } - if (!MACH_IS_MEDUSA && !MACH_IS_HADES && - hwreg_present(&dma_wd.fdc_speed) && - hwreg_write(&dma_wd.fdc_speed, 0)) { - ATARIHW_SET(FDCSPEED); - printk("FDC_SPEED "); - } - if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) { - ATARIHW_SET(ACSI); - printk("ACSI "); - } - printk("\n"); - - if (CPU_IS_040_OR_060) - /* Now it seems to be safe to turn of the tt0 transparent - * translation (the one that must not be turned off in - * head.S...) - */ - asm volatile ("\n" - " moveq #0,%%d0\n" - " .chip 68040\n" - " movec %%d0,%%itt0\n" - " movec %%d0,%%dtt0\n" - " .chip 68k" - : /* no outputs */ - : /* no inputs */ - : "d0"); - - /* allocator for memory that must reside in st-ram */ - atari_stram_init(); - - /* Set up a mapping for the VMEbus address region: - * - * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff - * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at - * 0xfe000000 virt., because this can be done with a single - * transparent translation. On the 68040, lots of often unused - * page tables would be needed otherwise. On a MegaSTE or similar, - * the highest byte is stripped off by hardware due to the 24 bit - * design of the bus. - */ - - if (CPU_IS_020_OR_030) { - unsigned long tt1_val; - tt1_val = 0xfe008543; /* Translate 0xfexxxxxx, enable, cache - * inhibit, read and write, FDC mask = 3, - * FDC val = 4 -> Supervisor only */ - asm volatile ("\n" - " .chip 68030\n" - " pmove %0@,%/tt1\n" - " .chip 68k" - : : "a" (&tt1_val)); - } else { - asm volatile ("\n" - " .chip 68040\n" - " movec %0,%%itt1\n" - " movec %0,%%dtt1\n" - " .chip 68k" - : - : "d" (0xfe00a040)); /* Translate 0xfexxxxxx, enable, - * supervisor only, non-cacheable/ - * serialized, writable */ - - } + if (hwreg_present( &tt_rtc.regsel )) { + ATARIHW_SET(TT_CLK); + printk( "TT_CLK " ); + mach_hwclk = atari_tt_hwclk; + mach_set_clock_mmss = atari_tt_set_clock_mmss; + } + if (!MACH_IS_HADES && hwreg_present( &mste_rtc.sec_ones)) { + ATARIHW_SET(MSTE_CLK); + printk( "MSTE_CLK "); + mach_hwclk = atari_mste_hwclk; + mach_set_clock_mmss = atari_mste_set_clock_mmss; + } + if (!MACH_IS_MEDUSA && !MACH_IS_HADES && + hwreg_present( &dma_wd.fdc_speed ) && + hwreg_write( &dma_wd.fdc_speed, 0 )) { + ATARIHW_SET(FDCSPEED); + printk( "FDC_SPEED "); + } + if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) { + ATARIHW_SET(ACSI); + printk( "ACSI " ); + } + printk("\n"); + + if (CPU_IS_040_OR_060) + /* Now it seems to be safe to turn of the tt0 transparent + * translation (the one that must not be turned off in + * head.S...) + */ + __asm__ volatile ("moveq #0,%/d0\n\t" + ".chip 68040\n\t" + "movec %%d0,%%itt0\n\t" + "movec %%d0,%%dtt0\n\t" + ".chip 68k" + : /* no outputs */ + : /* no inputs */ + : "d0"); + + /* allocator for memory that must reside in st-ram */ + atari_stram_init (); + + /* Set up a mapping for the VMEbus address region: + * + * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff + * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at + * 0xfe000000 virt., because this can be done with a single + * transparent translation. On the 68040, lots of often unused + * page tables would be needed otherwise. On a MegaSTE or similar, + * the highest byte is stripped off by hardware due to the 24 bit + * design of the bus. + */ - /* Fetch tos version at Physical 2 */ - /* - * We my not be able to access this address if the kernel is - * loaded to st ram, since the first page is unmapped. On the - * Medusa this is always the case and there is nothing we can do - * about this, so we just assume the smaller offset. For the TT - * we use the fact that in head.S we have set up a mapping - * 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible - * in the last 16MB of the address space. - */ - tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ? - 0xfff : *(unsigned short *)0xff000002; - atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68; + if (CPU_IS_020_OR_030) { + unsigned long tt1_val; + tt1_val = 0xfe008543; /* Translate 0xfexxxxxx, enable, cache + * inhibit, read and write, FDC mask = 3, + * FDC val = 4 -> Supervisor only */ + __asm__ __volatile__ ( ".chip 68030\n\t" + "pmove %0@,%/tt1\n\t" + ".chip 68k" + : : "a" (&tt1_val) ); + } + else { + __asm__ __volatile__ + ( "movel %0,%/d0\n\t" + ".chip 68040\n\t" + "movec %%d0,%%itt1\n\t" + "movec %%d0,%%dtt1\n\t" + ".chip 68k" + : + : "g" (0xfe00a040) /* Translate 0xfexxxxxx, enable, + * supervisor only, non-cacheable/ + * serialized, writable */ + : "d0" ); + + } + + /* Fetch tos version at Physical 2 */ + /* We my not be able to access this address if the kernel is + loaded to st ram, since the first page is unmapped. On the + Medusa this is always the case and there is nothing we can do + about this, so we just assume the smaller offset. For the TT + we use the fact that in head.S we have set up a mapping + 0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible + in the last 16MB of the address space. */ + tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ? + 0xfff : *(unsigned short *)0xff000002; + atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68; } #ifdef CONFIG_HEARTBEAT -static void atari_heartbeat(int on) +static void atari_heartbeat( int on ) { - unsigned char tmp; - unsigned long flags; + unsigned char tmp; + unsigned long flags; - if (atari_dont_touch_floppy_select) - return; + if (atari_dont_touch_floppy_select) + return; - local_irq_save(flags); - sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */ - tmp = sound_ym.rd_data_reg_sel; - sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02); - local_irq_restore(flags); + local_irq_save(flags); + sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */ + tmp = sound_ym.rd_data_reg_sel; + sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02); + local_irq_restore(flags); } #endif @@ -491,171 +526,180 @@ static void atari_heartbeat(int on) /* ++andreas: no need for complicated code, just depend on prefetch */ -static void atari_reset(void) +static void atari_reset (void) { - long tc_val = 0; - long reset_addr; - - /* - * On the Medusa, phys. 0x4 may contain garbage because it's no - * ROM. See above for explanation why we cannot use PTOV(4). - */ - reset_addr = MACH_IS_HADES ? 0x7fe00030 : - MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 : - *(unsigned long *) 0xff000004; - - /* reset ACIA for switch off OverScan, if it's active */ - if (atari_switches & ATARI_SWITCH_OVSC_IKBD) - acia.key_ctrl = ACIA_RESET; - if (atari_switches & ATARI_SWITCH_OVSC_MIDI) - acia.mid_ctrl = ACIA_RESET; - - /* processor independent: turn off interrupts and reset the VBR; - * the caches must be left enabled, else prefetching the final jump - * instruction doesn't work. - */ - local_irq_disable(); - asm volatile ("movec %0,%%vbr" - : : "d" (0)); - - if (CPU_IS_040_OR_060) { - unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); - if (CPU_IS_060) { - /* 68060: clear PCR to turn off superscalar operation */ - asm volatile ("\n" - " .chip 68060\n" - " movec %0,%%pcr\n" - " .chip 68k" - : : "d" (0)); - } - - asm volatile ("\n" - " move.l %0,%%d0\n" - " and.l #0xff000000,%%d0\n" - " or.w #0xe020,%%d0\n" /* map 16 MB, enable, cacheable */ - " .chip 68040\n" - " movec %%d0,%%itt0\n" - " movec %%d0,%%dtt0\n" - " .chip 68k\n" - " jmp %0@" - : : "a" (jmp_addr040) - : "d0"); - jmp_addr_label040: - asm volatile ("\n" - " moveq #0,%%d0\n" - " nop\n" - " .chip 68040\n" - " cinva %%bc\n" - " nop\n" - " pflusha\n" - " nop\n" - " movec %%d0,%%tc\n" - " nop\n" - /* the following setup of transparent translations is needed on the - * Afterburner040 to successfully reboot. Other machines shouldn't - * care about a different tt regs setup, they also didn't care in - * the past that the regs weren't turned off. */ - " move.l #0xffc000,%%d0\n" /* whole insn space cacheable */ - " movec %%d0,%%itt0\n" - " movec %%d0,%%itt1\n" - " or.w #0x40,%/d0\n" /* whole data space non-cacheable/ser. */ - " movec %%d0,%%dtt0\n" - " movec %%d0,%%dtt1\n" - " .chip 68k\n" - " jmp %0@" - : /* no outputs */ - : "a" (reset_addr) - : "d0"); - } else - asm volatile ("\n" - " pmove %0@,%%tc\n" - " jmp %1@" - : /* no outputs */ - : "a" (&tc_val), "a" (reset_addr)); + long tc_val = 0; + long reset_addr; + + /* On the Medusa, phys. 0x4 may contain garbage because it's no + ROM. See above for explanation why we cannot use PTOV(4). */ + reset_addr = MACH_IS_HADES ? 0x7fe00030 : + MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 : + *(unsigned long *) 0xff000004; + + /* reset ACIA for switch off OverScan, if it's active */ + if (atari_switches & ATARI_SWITCH_OVSC_IKBD) + acia.key_ctrl = ACIA_RESET; + if (atari_switches & ATARI_SWITCH_OVSC_MIDI) + acia.mid_ctrl = ACIA_RESET; + + /* processor independent: turn off interrupts and reset the VBR; + * the caches must be left enabled, else prefetching the final jump + * instruction doesn't work. */ + local_irq_disable(); + __asm__ __volatile__ + ("moveq #0,%/d0\n\t" + "movec %/d0,%/vbr" + : : : "d0" ); + + if (CPU_IS_040_OR_060) { + unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); + if (CPU_IS_060) { + /* 68060: clear PCR to turn off superscalar operation */ + __asm__ __volatile__ + ("moveq #0,%/d0\n\t" + ".chip 68060\n\t" + "movec %%d0,%%pcr\n\t" + ".chip 68k" + : : : "d0" ); + } + + __asm__ __volatile__ + ("movel %0,%/d0\n\t" + "andl #0xff000000,%/d0\n\t" + "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */ + ".chip 68040\n\t" + "movec %%d0,%%itt0\n\t" + "movec %%d0,%%dtt0\n\t" + ".chip 68k\n\t" + "jmp %0@\n\t" + : /* no outputs */ + : "a" (jmp_addr040) + : "d0" ); + jmp_addr_label040: + __asm__ __volatile__ + ("moveq #0,%/d0\n\t" + "nop\n\t" + ".chip 68040\n\t" + "cinva %%bc\n\t" + "nop\n\t" + "pflusha\n\t" + "nop\n\t" + "movec %%d0,%%tc\n\t" + "nop\n\t" + /* the following setup of transparent translations is needed on the + * Afterburner040 to successfully reboot. Other machines shouldn't + * care about a different tt regs setup, they also didn't care in + * the past that the regs weren't turned off. */ + "movel #0xffc000,%%d0\n\t" /* whole insn space cacheable */ + "movec %%d0,%%itt0\n\t" + "movec %%d0,%%itt1\n\t" + "orw #0x40,%/d0\n\t" /* whole data space non-cacheable/ser. */ + "movec %%d0,%%dtt0\n\t" + "movec %%d0,%%dtt1\n\t" + ".chip 68k\n\t" + "jmp %0@" + : /* no outputs */ + : "a" (reset_addr) + : "d0"); + } + else + __asm__ __volatile__ + ("pmove %0@,%/tc\n\t" + "jmp %1@" + : /* no outputs */ + : "a" (&tc_val), "a" (reset_addr)); } static void atari_get_model(char *model) { - strcpy(model, "Atari "); - switch (atari_mch_cookie >> 16) { + strcpy(model, "Atari "); + switch (atari_mch_cookie >> 16) { case ATARI_MCH_ST: - if (ATARIHW_PRESENT(MSTE_CLK)) - strcat(model, "Mega ST"); - else - strcat(model, "ST"); - break; + if (ATARIHW_PRESENT(MSTE_CLK)) + strcat (model, "Mega ST"); + else + strcat (model, "ST"); + break; case ATARI_MCH_STE: - if (MACH_IS_MSTE) - strcat(model, "Mega STE"); - else - strcat(model, "STE"); - break; + if (MACH_IS_MSTE) + strcat (model, "Mega STE"); + else + strcat (model, "STE"); + break; case ATARI_MCH_TT: - if (MACH_IS_MEDUSA) - /* Medusa has TT _MCH cookie */ - strcat(model, "Medusa"); - else if (MACH_IS_HADES) - strcat(model, "Hades"); - else - strcat(model, "TT"); - break; + if (MACH_IS_MEDUSA) + /* Medusa has TT _MCH cookie */ + strcat (model, "Medusa"); + else if (MACH_IS_HADES) + strcat(model, "Hades"); + else + strcat (model, "TT"); + break; case ATARI_MCH_FALCON: - strcat(model, "Falcon"); - if (MACH_IS_AB40) - strcat(model, " (with Afterburner040)"); - break; + strcat (model, "Falcon"); + if (MACH_IS_AB40) + strcat (model, " (with Afterburner040)"); + break; default: - sprintf(model + strlen(model), "(unknown mach cookie 0x%lx)", - atari_mch_cookie); - break; - } + sprintf (model + strlen (model), "(unknown mach cookie 0x%lx)", + atari_mch_cookie); + break; + } } static int atari_get_hardware_list(char *buffer) { - int len = 0, i; - - for (i = 0; i < m68k_num_memory; i++) - len += sprintf(buffer+len, "\t%3ld MB at 0x%08lx (%s)\n", - m68k_memory[i].size >> 20, m68k_memory[i].addr, - (m68k_memory[i].addr & 0xff000000 ? - "alternate RAM" : "ST-RAM")); - -#define ATARIHW_ANNOUNCE(name, str) \ - if (ATARIHW_PRESENT(name)) \ - len += sprintf(buffer + len, "\t%s\n", str) - - len += sprintf(buffer + len, "Detected hardware:\n"); - ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter"); - ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter"); - ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter"); - ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter"); - ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator"); - ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound"); - ATARIHW_ANNOUNCE(CODEC, "CODEC Sound"); - ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)"); - ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)"); - ATARIHW_ANNOUNCE(ACSI, "ACSI Interface"); - ATARIHW_ANNOUNCE(IDE, "IDE Interface"); - ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC"); - ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901"); - ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901"); - ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530"); - ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230"); - ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface"); - ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface"); - ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)"); - ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)"); - ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380"); - ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC"); - ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A"); - ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15"); - ATARIHW_ANNOUNCE(SCU, "System Control Unit"); - ATARIHW_ANNOUNCE(BLITTER, "Blitter"); - ATARIHW_ANNOUNCE(VME, "VME Bus"); - ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor"); - - return len; + int len = 0, i; + + for (i = 0; i < m68k_num_memory; i++) + len += sprintf (buffer+len, "\t%3ld MB at 0x%08lx (%s)\n", + m68k_memory[i].size >> 20, m68k_memory[i].addr, + (m68k_memory[i].addr & 0xff000000 ? + "alternate RAM" : "ST-RAM")); + +#define ATARIHW_ANNOUNCE(name,str) \ + if (ATARIHW_PRESENT(name)) \ + len += sprintf (buffer + len, "\t%s\n", str) + + len += sprintf (buffer + len, "Detected hardware:\n"); + ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter"); + ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter"); + ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter"); + ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter"); + ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator"); + ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound"); + ATARIHW_ANNOUNCE(CODEC, "CODEC Sound"); + ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)"); + ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)"); + ATARIHW_ANNOUNCE(ACSI, "ACSI Interface"); + ATARIHW_ANNOUNCE(IDE, "IDE Interface"); + ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC"); + ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901"); + ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901"); + ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530"); + ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230"); + ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface"); + ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface"); + ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)"); + ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)"); + ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380"); + ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC"); + ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A"); + ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15"); + ATARIHW_ANNOUNCE(SCU, "System Control Unit"); + ATARIHW_ANNOUNCE(BLITTER, "Blitter"); + ATARIHW_ANNOUNCE(VME, "VME Bus"); + ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor"); + + return(len); } + +/* + * Local variables: + * c-indent-level: 4 + * tab-width: 8 + * End: + */ diff --git a/trunk/arch/m68k/atari/debug.c b/trunk/arch/m68k/atari/debug.c index fbeed8c8ecbc..4ae01004d8dd 100644 --- a/trunk/arch/m68k/atari/debug.c +++ b/trunk/arch/m68k/atari/debug.c @@ -19,6 +19,8 @@ #include #include +extern char m68k_debug_device[]; + /* Flag that Modem1 port is already initialized and used */ int atari_MFP_init_done; /* Flag that Modem1 port is already initialized and used */ @@ -28,317 +30,317 @@ int atari_SCC_init_done; int atari_SCC_reset_done; static struct console atari_console_driver = { - .name = "debug", - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .flags = CON_PRINTBUFFER, + .index = -1, }; -static inline void ata_mfp_out(char c) +static inline void ata_mfp_out (char c) { - while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ - barrier(); - mfp.usart_dta = c; + while (!(mfp.trn_stat & 0x80)) /* wait for tx buf empty */ + barrier (); + mfp.usart_dta = c; } -void atari_mfp_console_write(struct console *co, const char *str, - unsigned int count) +void atari_mfp_console_write (struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - ata_mfp_out('\r'); - ata_mfp_out(*str++); - } + while (count--) { + if (*str == '\n') + ata_mfp_out( '\r' ); + ata_mfp_out( *str++ ); + } } -static inline void ata_scc_out(char c) +static inline void ata_scc_out (char c) { - do { - MFPDELAY(); - } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ + do { MFPDELAY(); - scc.cha_b_data = c; + } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ + MFPDELAY(); + scc.cha_b_data = c; } -void atari_scc_console_write(struct console *co, const char *str, - unsigned int count) +void atari_scc_console_write (struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - ata_scc_out('\r'); - ata_scc_out(*str++); - } + while (count--) { + if (*str == '\n') + ata_scc_out( '\r' ); + ata_scc_out( *str++ ); + } } -static inline void ata_midi_out(char c) +static inline void ata_midi_out (char c) { - while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */ - barrier(); - acia.mid_data = c; + while (!(acia.mid_ctrl & ACIA_TDRE)) /* wait for tx buf empty */ + barrier (); + acia.mid_data = c; } -void atari_midi_console_write(struct console *co, const char *str, - unsigned int count) +void atari_midi_console_write (struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - ata_midi_out('\r'); - ata_midi_out(*str++); - } + while (count--) { + if (*str == '\n') + ata_midi_out( '\r' ); + ata_midi_out( *str++ ); + } } -static int ata_par_out(char c) +static int ata_par_out (char c) { - unsigned char tmp; - /* This a some-seconds timeout in case no printer is connected */ - unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ; - - while ((mfp.par_dt_reg & 1) && --i) /* wait for BUSY == L */ - ; - if (!i) - return 0; - - sound_ym.rd_data_reg_sel = 15; /* select port B */ - sound_ym.wd_data = c; /* put char onto port */ - sound_ym.rd_data_reg_sel = 14; /* select port A */ - tmp = sound_ym.rd_data_reg_sel; - sound_ym.wd_data = tmp & ~0x20; /* set strobe L */ - MFPDELAY(); /* wait a bit */ - sound_ym.wd_data = tmp | 0x20; /* set strobe H */ - return 1; + unsigned char tmp; + /* This a some-seconds timeout in case no printer is connected */ + unsigned long i = loops_per_jiffy > 1 ? loops_per_jiffy : 10000000/HZ; + + while( (mfp.par_dt_reg & 1) && --i ) /* wait for BUSY == L */ + ; + if (!i) return( 0 ); + + sound_ym.rd_data_reg_sel = 15; /* select port B */ + sound_ym.wd_data = c; /* put char onto port */ + sound_ym.rd_data_reg_sel = 14; /* select port A */ + tmp = sound_ym.rd_data_reg_sel; + sound_ym.wd_data = tmp & ~0x20; /* set strobe L */ + MFPDELAY(); /* wait a bit */ + sound_ym.wd_data = tmp | 0x20; /* set strobe H */ + return( 1 ); } -static void atari_par_console_write(struct console *co, const char *str, - unsigned int count) +static void atari_par_console_write (struct console *co, const char *str, + unsigned int count) { - static int printer_present = 1; + static int printer_present = 1; - if (!printer_present) - return; + if (!printer_present) + return; - while (count--) { - if (*str == '\n') { - if (!ata_par_out('\r')) { - printer_present = 0; - return; - } - } - if (!ata_par_out(*str++)) { - printer_present = 0; - return; - } + while (count--) { + if (*str == '\n') + if (!ata_par_out( '\r' )) { + printer_present = 0; + return; + } + if (!ata_par_out( *str++ )) { + printer_present = 0; + return; } + } } #ifdef CONFIG_SERIAL_CONSOLE int atari_mfp_console_wait_key(struct console *co) { - while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */ - barrier(); - return mfp.usart_dta; + while( !(mfp.rcv_stat & 0x80) ) /* wait for rx buf filled */ + barrier(); + return( mfp.usart_dta ); } int atari_scc_console_wait_key(struct console *co) { - do { - MFPDELAY(); - } while (!(scc.cha_b_ctrl & 0x01)); /* wait for rx buf filled */ + do { MFPDELAY(); - return scc.cha_b_data; + } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ + MFPDELAY(); + return( scc.cha_b_data ); } int atari_midi_console_wait_key(struct console *co) { - while (!(acia.mid_ctrl & ACIA_RDRF)) /* wait for rx buf filled */ - barrier(); - return acia.mid_data; + while( !(acia.mid_ctrl & ACIA_RDRF) ) /* wait for rx buf filled */ + barrier(); + return( acia.mid_data ); } #endif -/* - * The following two functions do a quick'n'dirty initialization of the MFP or +/* The following two functions do a quick'n'dirty initialization of the MFP or * SCC serial ports. They're used by the debugging interface, kgdb, and the - * serial console code. - */ + * serial console code. */ #ifndef CONFIG_SERIAL_CONSOLE -static void __init atari_init_mfp_port(int cflag) +static void __init atari_init_mfp_port( int cflag ) #else -void atari_init_mfp_port(int cflag) +void atari_init_mfp_port( int cflag ) #endif { - /* - * timer values for 1200...115200 bps; > 38400 select 110, 134, or 150 - * bps, resp., and work only correct if there's a RSVE or RSSPEED - */ - static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 }; - int baud = cflag & CBAUD; - int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0; - int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* baud_table[] starts at 1200bps */ - - mfp.trn_stat &= ~0x01; /* disable TX */ - mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ - mfp.tim_ct_cd &= 0x70; /* stop timer D */ - mfp.tim_dt_d = baud_table[baud]; - mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ - mfp.trn_stat |= 0x01; /* enable TX */ - - atari_MFP_init_done = 1; + /* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150 + * bps, resp., and work only correct if there's a RSVE or RSSPEED */ + static int baud_table[9] = { 16, 11, 8, 4, 2, 1, 175, 143, 128 }; + int baud = cflag & CBAUD; + int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x04 : 0x06) : 0; + int csize = ((cflag & CSIZE) == CS7) ? 0x20 : 0x00; + + if (cflag & CBAUDEX) + baud += B38400; + if (baud < B1200 || baud > B38400+2) + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* baud_table[] starts at 1200bps */ + + mfp.trn_stat &= ~0x01; /* disable TX */ + mfp.usart_ctr = parity | csize | 0x88; /* 1:16 clk mode, 1 stop bit */ + mfp.tim_ct_cd &= 0x70; /* stop timer D */ + mfp.tim_dt_d = baud_table[baud]; + mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */ + mfp.trn_stat |= 0x01; /* enable TX */ + + atari_MFP_init_done = 1; } -#define SCC_WRITE(reg, val) \ - do { \ - scc.cha_b_ctrl = (reg); \ - MFPDELAY(); \ - scc.cha_b_ctrl = (val); \ - MFPDELAY(); \ - } while (0) +#define SCC_WRITE(reg,val) \ + do { \ + scc.cha_b_ctrl = (reg); \ + MFPDELAY(); \ + scc.cha_b_ctrl = (val); \ + MFPDELAY(); \ + } while(0) /* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a * delay of ~ 60us. */ -#define LONG_DELAY() \ - do { \ - int i; \ - for (i = 100; i > 0; --i) \ - MFPDELAY(); \ - } while (0) +#define LONG_DELAY() \ + do { \ + int i; \ + for( i = 100; i > 0; --i ) \ + MFPDELAY(); \ + } while(0) #ifndef CONFIG_SERIAL_CONSOLE -static void __init atari_init_scc_port(int cflag) +static void __init atari_init_scc_port( int cflag ) #else -void atari_init_scc_port(int cflag) +void atari_init_scc_port( int cflag ) #endif { - extern int atari_SCC_reset_done; - static int clksrc_table[9] = - /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ - { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; - static int brgsrc_table[9] = - /* reg 14: 0 = RTxC, 2 = PCLK */ - { 2, 2, 2, 2, 2, 2, 0, 2, 2 }; - static int clkmode_table[9] = - /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ - { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; - static int div_table[9] = - /* reg12 (BRG low) */ - { 208, 138, 103, 50, 24, 11, 1, 0, 0 }; - - int baud = cflag & CBAUD; - int clksrc, clkmode, div, reg3, reg5; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* tables starts at 1200bps */ - - clksrc = clksrc_table[baud]; - clkmode = clkmode_table[baud]; - div = div_table[baud]; - if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) { - /* special treatment for TT, where rates >= 38400 are done via TRxC */ - clksrc = 0x28; /* TRxC */ - clkmode = baud == 6 ? 0xc0 : - baud == 7 ? 0x80 : /* really 76800bps */ - 0x40; /* really 153600bps */ - div = 0; - } - - reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40; - reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */; - - (void)scc.cha_b_ctrl; /* reset reg pointer */ - SCC_WRITE(9, 0xc0); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCC_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) - : 0 | 0x04 /* 1 stopbit */ | clkmode); - SCC_WRITE(3, reg3); - SCC_WRITE(5, reg5); - SCC_WRITE(9, 0); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCC_WRITE(10, 0); /* NRZ mode */ - SCC_WRITE(11, clksrc); /* main clock source */ - SCC_WRITE(12, div); /* BRG value */ - SCC_WRITE(13, 0); /* BRG high byte */ - SCC_WRITE(14, brgsrc_table[baud]); - SCC_WRITE(14, brgsrc_table[baud] | (div ? 1 : 0)); - SCC_WRITE(3, reg3 | 1); - SCC_WRITE(5, reg5 | 8); - - atari_SCC_reset_done = 1; - atari_SCC_init_done = 1; + extern int atari_SCC_reset_done; + static int clksrc_table[9] = + /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ + { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; + static int brgsrc_table[9] = + /* reg 14: 0 = RTxC, 2 = PCLK */ + { 2, 2, 2, 2, 2, 2, 0, 2, 2 }; + static int clkmode_table[9] = + /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ + { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; + static int div_table[9] = + /* reg12 (BRG low) */ + { 208, 138, 103, 50, 24, 11, 1, 0, 0 }; + + int baud = cflag & CBAUD; + int clksrc, clkmode, div, reg3, reg5; + + if (cflag & CBAUDEX) + baud += B38400; + if (baud < B1200 || baud > B38400+2) + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* tables starts at 1200bps */ + + clksrc = clksrc_table[baud]; + clkmode = clkmode_table[baud]; + div = div_table[baud]; + if (ATARIHW_PRESENT(TT_MFP) && baud >= 6) { + /* special treatment for TT, where rates >= 38400 are done via TRxC */ + clksrc = 0x28; /* TRxC */ + clkmode = baud == 6 ? 0xc0 : + baud == 7 ? 0x80 : /* really 76800bps */ + 0x40; /* really 153600bps */ + div = 0; + } + + reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40; + reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */; + + (void)scc.cha_b_ctrl; /* reset reg pointer */ + SCC_WRITE( 9, 0xc0 ); /* reset */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCC_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | + 0x04 /* 1 stopbit */ | + clkmode ); + SCC_WRITE( 3, reg3 ); + SCC_WRITE( 5, reg5 ); + SCC_WRITE( 9, 0 ); /* no interrupts */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCC_WRITE( 10, 0 ); /* NRZ mode */ + SCC_WRITE( 11, clksrc ); /* main clock source */ + SCC_WRITE( 12, div ); /* BRG value */ + SCC_WRITE( 13, 0 ); /* BRG high byte */ + SCC_WRITE( 14, brgsrc_table[baud] ); + SCC_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) ); + SCC_WRITE( 3, reg3 | 1 ); + SCC_WRITE( 5, reg5 | 8 ); + + atari_SCC_reset_done = 1; + atari_SCC_init_done = 1; } #ifndef CONFIG_SERIAL_CONSOLE -static void __init atari_init_midi_port(int cflag) +static void __init atari_init_midi_port( int cflag ) #else -void atari_init_midi_port(int cflag) +void atari_init_midi_port( int cflag ) #endif { - int baud = cflag & CBAUD; - int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00; - /* warning 7N1 isn't possible! (instead 7O2 is used...) */ - int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04; - int div; - - /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as - * default) the standard MIDI speed 31250. */ - if (cflag & CBAUDEX) - baud += B38400; - if (baud == B4800) - div = ACIA_DIV64; /* really 7812.5 bps */ - else if (baud == B38400+2 /* 115200 */) - div = ACIA_DIV1; /* really 500 kbps (does that work??) */ - else - div = ACIA_DIV16; /* 31250 bps, standard for MIDI */ - - /* RTS low, ints disabled */ - acia.mid_ctrl = div | csize | parity | + int baud = cflag & CBAUD; + int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00; + /* warning 7N1 isn't possible! (instead 7O2 is used...) */ + int parity = (cflag & PARENB) ? ((cflag & PARODD) ? 0x0c : 0x08) : 0x04; + int div; + + /* 4800 selects 7812.5, 115200 selects 500000, all other (incl. 9600 as + * default) the standard MIDI speed 31250. */ + if (cflag & CBAUDEX) + baud += B38400; + if (baud == B4800) + div = ACIA_DIV64; /* really 7812.5 bps */ + else if (baud == B38400+2 /* 115200 */) + div = ACIA_DIV1; /* really 500 kbps (does that work??) */ + else + div = ACIA_DIV16; /* 31250 bps, standard for MIDI */ + + /* RTS low, ints disabled */ + acia.mid_ctrl = div | csize | parity | ((atari_switches & ATARI_SWITCH_MIDI) ? ACIA_RHTID : ACIA_RLTID); } -static int __init atari_debug_setup(char *arg) +void __init atari_debug_init(void) { - if (!MACH_IS_ATARI) - return 0; - - if (!strcmp(arg, "ser")) - /* defaults to ser2 for a Falcon and ser1 otherwise */ - arg = MACH_IS_FALCON ? "ser2" : "ser1"; - - if (!strcmp(arg, "ser1")) { - /* ST-MFP Modem1 serial port */ - atari_init_mfp_port(B9600|CS8); - atari_console_driver.write = atari_mfp_console_write; - } else if (!strcmp(arg, "ser2")) { - /* SCC Modem2 serial port */ - atari_init_scc_port(B9600|CS8); - atari_console_driver.write = atari_scc_console_write; - } else if (!strcmp(arg, "midi")) { - /* MIDI port */ - atari_init_midi_port(B9600|CS8); - atari_console_driver.write = atari_midi_console_write; - } else if (!strcmp(arg, "par")) { - /* parallel printer */ - atari_turnoff_irq(IRQ_MFP_BUSY); /* avoid ints */ - sound_ym.rd_data_reg_sel = 7; /* select mixer control */ - sound_ym.wd_data = 0xff; /* sound off, ports are output */ - sound_ym.rd_data_reg_sel = 15; /* select port B */ - sound_ym.wd_data = 0; /* no char */ - sound_ym.rd_data_reg_sel = 14; /* select port A */ - sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ - atari_console_driver.write = atari_par_console_write; - } - if (atari_console_driver.write) - register_console(&atari_console_driver); - - return 0; + if (!strcmp( m68k_debug_device, "ser" )) { + /* defaults to ser2 for a Falcon and ser1 otherwise */ + strcpy( m68k_debug_device, MACH_IS_FALCON ? "ser2" : "ser1" ); + + } + + if (!strcmp( m68k_debug_device, "ser1" )) { + /* ST-MFP Modem1 serial port */ + atari_init_mfp_port( B9600|CS8 ); + atari_console_driver.write = atari_mfp_console_write; + } + else if (!strcmp( m68k_debug_device, "ser2" )) { + /* SCC Modem2 serial port */ + atari_init_scc_port( B9600|CS8 ); + atari_console_driver.write = atari_scc_console_write; + } + else if (!strcmp( m68k_debug_device, "midi" )) { + /* MIDI port */ + atari_init_midi_port( B9600|CS8 ); + atari_console_driver.write = atari_midi_console_write; + } + else if (!strcmp( m68k_debug_device, "par" )) { + /* parallel printer */ + atari_turnoff_irq( IRQ_MFP_BUSY ); /* avoid ints */ + sound_ym.rd_data_reg_sel = 7; /* select mixer control */ + sound_ym.wd_data = 0xff; /* sound off, ports are output */ + sound_ym.rd_data_reg_sel = 15; /* select port B */ + sound_ym.wd_data = 0; /* no char */ + sound_ym.rd_data_reg_sel = 14; /* select port A */ + sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x20; /* strobe H */ + atari_console_driver.write = atari_par_console_write; + } + if (atari_console_driver.write) + register_console(&atari_console_driver); } -early_param("debug", atari_debug_setup); +/* + * Local variables: + * c-indent-level: 4 + * tab-width: 8 + * End: + */ diff --git a/trunk/arch/m68k/kernel/entry.S b/trunk/arch/m68k/kernel/entry.S index e162ee685d20..222ce4244564 100644 --- a/trunk/arch/m68k/kernel/entry.S +++ b/trunk/arch/m68k/kernel/entry.S @@ -692,7 +692,7 @@ sys_call_table: .long sys_tgkill /* 265 */ .long sys_utimes .long sys_fadvise64_64 - .long sys_mbind + .long sys_mbind .long sys_get_mempolicy .long sys_set_mempolicy /* 270 */ .long sys_mq_open diff --git a/trunk/arch/m68k/kernel/head.S b/trunk/arch/m68k/kernel/head.S index 05741f233567..6739e87fe825 100644 --- a/trunk/arch/m68k/kernel/head.S +++ b/trunk/arch/m68k/kernel/head.S @@ -3195,7 +3195,7 @@ func_start serial_putc,%d0/%d1/%a0/%a1 jbra L(serial_putc_done) 3: #endif - + L(serial_putc_done): func_return serial_putc diff --git a/trunk/arch/m68k/kernel/ints.c b/trunk/arch/m68k/kernel/ints.c index 60d4d75f5798..b66c97c904b3 100644 --- a/trunk/arch/m68k/kernel/ints.c +++ b/trunk/arch/m68k/kernel/ints.c @@ -59,14 +59,14 @@ static int m68k_first_user_vec; static struct irq_controller auto_irq_controller = { .name = "auto", - .lock = __SPIN_LOCK_UNLOCKED(auto_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .startup = m68k_irq_startup, .shutdown = m68k_irq_shutdown, }; static struct irq_controller user_irq_controller = { .name = "user", - .lock = __SPIN_LOCK_UNLOCKED(user_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .startup = m68k_irq_startup, .shutdown = m68k_irq_shutdown, }; diff --git a/trunk/arch/m68k/kernel/ptrace.c b/trunk/arch/m68k/kernel/ptrace.c index cdba9fd6d82f..7fd2720c3841 100644 --- a/trunk/arch/m68k/kernel/ptrace.c +++ b/trunk/arch/m68k/kernel/ptrace.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/m68k/kernel/setup.c b/trunk/arch/m68k/kernel/setup.c index 610319356691..42b8fd09ea8f 100644 --- a/trunk/arch/m68k/kernel/setup.c +++ b/trunk/arch/m68k/kernel/setup.c @@ -71,6 +71,9 @@ static struct mem_info m68k_ramdisk; static char m68k_command_line[CL_SIZE]; +char m68k_debug_device[6] = ""; +EXPORT_SYMBOL(m68k_debug_device); + void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL; /* machine dependent irq functions */ void (*mach_init_IRQ) (void) __initdata = NULL; @@ -130,78 +133,78 @@ extern void config_hp300(void); extern void config_q40(void); extern void config_sun3x(void); +extern void mac_debugging_short (int, short); +extern void mac_debugging_long (int, long); + #define MASK_256K 0xfffc0000 extern void paging_init(void); static void __init m68k_parse_bootinfo(const struct bi_record *record) { - while (record->tag != BI_LAST) { - int unknown = 0; - const unsigned long *data = record->data; - - switch (record->tag) { - case BI_MACHTYPE: - case BI_CPUTYPE: - case BI_FPUTYPE: - case BI_MMUTYPE: - /* Already set up by head.S */ - break; - - case BI_MEMCHUNK: - if (m68k_num_memory < NUM_MEMINFO) { - m68k_memory[m68k_num_memory].addr = data[0]; - m68k_memory[m68k_num_memory].size = data[1]; - m68k_num_memory++; - } else - printk("m68k_parse_bootinfo: too many memory chunks\n"); - break; - - case BI_RAMDISK: - m68k_ramdisk.addr = data[0]; - m68k_ramdisk.size = data[1]; - break; - - case BI_COMMAND_LINE: - strlcpy(m68k_command_line, (const char *)data, - sizeof(m68k_command_line)); - break; - - default: - if (MACH_IS_AMIGA) - unknown = amiga_parse_bootinfo(record); - else if (MACH_IS_ATARI) - unknown = atari_parse_bootinfo(record); - else if (MACH_IS_MAC) - unknown = mac_parse_bootinfo(record); - else if (MACH_IS_Q40) - unknown = q40_parse_bootinfo(record); - else if (MACH_IS_BVME6000) - unknown = bvme6000_parse_bootinfo(record); - else if (MACH_IS_MVME16x) - unknown = mvme16x_parse_bootinfo(record); - else if (MACH_IS_MVME147) - unknown = mvme147_parse_bootinfo(record); - else if (MACH_IS_HP300) - unknown = hp300_parse_bootinfo(record); - else - unknown = 1; - } - if (unknown) - printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", - record->tag); - record = (struct bi_record *)((unsigned long)record + - record->size); + while (record->tag != BI_LAST) { + int unknown = 0; + const unsigned long *data = record->data; + switch (record->tag) { + case BI_MACHTYPE: + case BI_CPUTYPE: + case BI_FPUTYPE: + case BI_MMUTYPE: + /* Already set up by head.S */ + break; + + case BI_MEMCHUNK: + if (m68k_num_memory < NUM_MEMINFO) { + m68k_memory[m68k_num_memory].addr = data[0]; + m68k_memory[m68k_num_memory].size = data[1]; + m68k_num_memory++; + } else + printk("m68k_parse_bootinfo: too many memory chunks\n"); + break; + + case BI_RAMDISK: + m68k_ramdisk.addr = data[0]; + m68k_ramdisk.size = data[1]; + break; + + case BI_COMMAND_LINE: + strlcpy(m68k_command_line, (const char *)data, sizeof(m68k_command_line)); + break; + + default: + if (MACH_IS_AMIGA) + unknown = amiga_parse_bootinfo(record); + else if (MACH_IS_ATARI) + unknown = atari_parse_bootinfo(record); + else if (MACH_IS_MAC) + unknown = mac_parse_bootinfo(record); + else if (MACH_IS_Q40) + unknown = q40_parse_bootinfo(record); + else if (MACH_IS_BVME6000) + unknown = bvme6000_parse_bootinfo(record); + else if (MACH_IS_MVME16x) + unknown = mvme16x_parse_bootinfo(record); + else if (MACH_IS_MVME147) + unknown = mvme147_parse_bootinfo(record); + else if (MACH_IS_HP300) + unknown = hp300_parse_bootinfo(record); + else + unknown = 1; } + if (unknown) + printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n", + record->tag); + record = (struct bi_record *)((unsigned long)record+record->size); + } - m68k_realnum_memory = m68k_num_memory; + m68k_realnum_memory = m68k_num_memory; #ifdef CONFIG_SINGLE_MEMORY_CHUNK - if (m68k_num_memory > 1) { - printk("Ignoring last %i chunks of physical memory\n", - (m68k_num_memory - 1)); - m68k_num_memory = 1; - } - m68k_memoffset = m68k_memory[0].addr-PAGE_OFFSET; + if (m68k_num_memory > 1) { + printk("Ignoring last %i chunks of physical memory\n", + (m68k_num_memory - 1)); + m68k_num_memory = 1; + } + m68k_memoffset = m68k_memory[0].addr-PAGE_OFFSET; #endif } @@ -212,6 +215,7 @@ void __init setup_arch(char **cmdline_p) unsigned long endmem, startmem; #endif int i; + char *p, *q; /* The bootinfo is located right after the kernel bss */ m68k_parse_bootinfo((const struct bi_record *)&_end); @@ -230,7 +234,7 @@ void __init setup_arch(char **cmdline_p) /* clear the fpu if we have one */ if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { volatile int zero = 0; - asm volatile ("frestore %0" : : "m" (zero)); + asm __volatile__ ("frestore %0" : : "m" (zero)); } #endif @@ -254,7 +258,37 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = m68k_command_line; memcpy(boot_command_line, *cmdline_p, CL_SIZE); - parse_early_param(); + /* Parse the command line for arch-specific options. + * For the m68k, this is currently only "debug=xxx" to enable printing + * certain kernel messages to some machine-specific device. + */ + for( p = *cmdline_p; p && *p; ) { + i = 0; + if (!strncmp( p, "debug=", 6 )) { + strlcpy( m68k_debug_device, p+6, sizeof(m68k_debug_device) ); + if ((q = strchr( m68k_debug_device, ' ' ))) *q = 0; + i = 1; + } +#ifdef CONFIG_ATARI + /* This option must be parsed very early */ + if (!strncmp( p, "switches=", 9 )) { + extern void atari_switches_setup( const char *, int ); + atari_switches_setup( p+9, (q = strchr( p+9, ' ' )) ? + (q - (p+9)) : strlen(p+9) ); + i = 1; + } +#endif + + if (i) { + /* option processed, delete it */ + if ((q = strchr( p, ' ' ))) + strcpy( p, q+1 ); + else + *p = 0; + } else { + if ((p = strchr( p, ' ' ))) ++p; + } + } #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -262,62 +296,62 @@ void __init setup_arch(char **cmdline_p) switch (m68k_machtype) { #ifdef CONFIG_AMIGA - case MACH_AMIGA: + case MACH_AMIGA: config_amiga(); break; #endif #ifdef CONFIG_ATARI - case MACH_ATARI: + case MACH_ATARI: config_atari(); break; #endif #ifdef CONFIG_MAC - case MACH_MAC: + case MACH_MAC: config_mac(); break; #endif #ifdef CONFIG_SUN3 - case MACH_SUN3: + case MACH_SUN3: config_sun3(); break; #endif #ifdef CONFIG_APOLLO - case MACH_APOLLO: + case MACH_APOLLO: config_apollo(); break; #endif #ifdef CONFIG_MVME147 - case MACH_MVME147: + case MACH_MVME147: config_mvme147(); break; #endif #ifdef CONFIG_MVME16x - case MACH_MVME16x: + case MACH_MVME16x: config_mvme16x(); break; #endif #ifdef CONFIG_BVME6000 - case MACH_BVME6000: + case MACH_BVME6000: config_bvme6000(); break; #endif #ifdef CONFIG_HP300 - case MACH_HP300: + case MACH_HP300: config_hp300(); break; #endif #ifdef CONFIG_Q40 - case MACH_Q40: - config_q40(); + case MACH_Q40: + config_q40(); break; #endif #ifdef CONFIG_SUN3X - case MACH_SUN3X: + case MACH_SUN3X: config_sun3x(); break; #endif - default: - panic("No configuration setup"); + default: + panic ("No configuration setup"); } #ifndef CONFIG_SUN3 @@ -346,7 +380,7 @@ void __init setup_arch(char **cmdline_p) reserve_bootmem(m68k_ramdisk.addr, m68k_ramdisk.size); initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr); initrd_end = initrd_start + m68k_ramdisk.size; - printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end); + printk ("initrd: %08lx - %08lx\n", initrd_start, initrd_end); } #endif @@ -368,18 +402,18 @@ void __init setup_arch(char **cmdline_p) #if defined(CONFIG_ISA) && defined(MULTI_ISA) #if defined(CONFIG_Q40) if (MACH_IS_Q40) { - isa_type = Q40_ISA; - isa_sex = 0; + isa_type = Q40_ISA; + isa_sex = 0; } #elif defined(CONFIG_GG2) - if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)) { - isa_type = GG2_ISA; - isa_sex = 0; + if (MACH_IS_AMIGA && AMIGAHW_PRESENT(GG2_ISA)){ + isa_type = GG2_ISA; + isa_sex = 0; } #elif defined(CONFIG_AMIGA_PCMCIA) - if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) { - isa_type = AG_ISA; - isa_sex = 1; + if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)){ + isa_type = AG_ISA; + isa_sex = 1; } #endif #endif @@ -387,66 +421,66 @@ void __init setup_arch(char **cmdline_p) static int show_cpuinfo(struct seq_file *m, void *v) { - const char *cpu, *mmu, *fpu; - unsigned long clockfreq, clockfactor; + const char *cpu, *mmu, *fpu; + unsigned long clockfreq, clockfactor; #define LOOP_CYCLES_68020 (8) #define LOOP_CYCLES_68030 (8) #define LOOP_CYCLES_68040 (3) #define LOOP_CYCLES_68060 (1) - if (CPU_IS_020) { - cpu = "68020"; - clockfactor = LOOP_CYCLES_68020; - } else if (CPU_IS_030) { - cpu = "68030"; - clockfactor = LOOP_CYCLES_68030; - } else if (CPU_IS_040) { - cpu = "68040"; - clockfactor = LOOP_CYCLES_68040; - } else if (CPU_IS_060) { - cpu = "68060"; - clockfactor = LOOP_CYCLES_68060; - } else { - cpu = "680x0"; - clockfactor = 0; - } + if (CPU_IS_020) { + cpu = "68020"; + clockfactor = LOOP_CYCLES_68020; + } else if (CPU_IS_030) { + cpu = "68030"; + clockfactor = LOOP_CYCLES_68030; + } else if (CPU_IS_040) { + cpu = "68040"; + clockfactor = LOOP_CYCLES_68040; + } else if (CPU_IS_060) { + cpu = "68060"; + clockfactor = LOOP_CYCLES_68060; + } else { + cpu = "680x0"; + clockfactor = 0; + } #ifdef CONFIG_M68KFPU_EMU_ONLY - fpu = "none(soft float)"; + fpu="none(soft float)"; #else - if (m68k_fputype & FPU_68881) - fpu = "68881"; - else if (m68k_fputype & FPU_68882) - fpu = "68882"; - else if (m68k_fputype & FPU_68040) - fpu = "68040"; - else if (m68k_fputype & FPU_68060) - fpu = "68060"; - else if (m68k_fputype & FPU_SUNFPA) - fpu = "Sun FPA"; - else - fpu = "none"; + if (m68k_fputype & FPU_68881) + fpu = "68881"; + else if (m68k_fputype & FPU_68882) + fpu = "68882"; + else if (m68k_fputype & FPU_68040) + fpu = "68040"; + else if (m68k_fputype & FPU_68060) + fpu = "68060"; + else if (m68k_fputype & FPU_SUNFPA) + fpu = "Sun FPA"; + else + fpu = "none"; #endif - if (m68k_mmutype & MMU_68851) - mmu = "68851"; - else if (m68k_mmutype & MMU_68030) - mmu = "68030"; - else if (m68k_mmutype & MMU_68040) - mmu = "68040"; - else if (m68k_mmutype & MMU_68060) - mmu = "68060"; - else if (m68k_mmutype & MMU_SUN3) - mmu = "Sun-3"; - else if (m68k_mmutype & MMU_APOLLO) - mmu = "Apollo"; - else - mmu = "unknown"; - - clockfreq = loops_per_jiffy * HZ * clockfactor; - - seq_printf(m, "CPU:\t\t%s\n" + if (m68k_mmutype & MMU_68851) + mmu = "68851"; + else if (m68k_mmutype & MMU_68030) + mmu = "68030"; + else if (m68k_mmutype & MMU_68040) + mmu = "68040"; + else if (m68k_mmutype & MMU_68060) + mmu = "68060"; + else if (m68k_mmutype & MMU_SUN3) + mmu = "Sun-3"; + else if (m68k_mmutype & MMU_APOLLO) + mmu = "Apollo"; + else + mmu = "unknown"; + + clockfreq = loops_per_jiffy*HZ*clockfactor; + + seq_printf(m, "CPU:\t\t%s\n" "MMU:\t\t%s\n" "FPU:\t\t%s\n" "Clocking:\t%lu.%1luMHz\n" @@ -456,7 +490,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) clockfreq/1000000,(clockfreq/100000)%10, loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100, loops_per_jiffy); - return 0; + return 0; } static void *c_start(struct seq_file *m, loff_t *pos) @@ -472,54 +506,44 @@ static void c_stop(struct seq_file *m, void *v) { } struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, + .start = c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, }; int get_hardware_list(char *buffer) { - int len = 0; - char model[80]; - unsigned long mem; - int i; + int len = 0; + char model[80]; + unsigned long mem; + int i; - if (mach_get_model) - mach_get_model(model); - else - strcpy(model, "Unknown m68k"); + if (mach_get_model) + mach_get_model(model); + else + strcpy(model, "Unknown m68k"); - len += sprintf(buffer + len, "Model:\t\t%s\n", model); - for (mem = 0, i = 0; i < m68k_num_memory; i++) - mem += m68k_memory[i].size; - len += sprintf(buffer + len, "System Memory:\t%ldK\n", mem >> 10); + len += sprintf(buffer+len, "Model:\t\t%s\n", model); + for (mem = 0, i = 0; i < m68k_num_memory; i++) + mem += m68k_memory[i].size; + len += sprintf(buffer+len, "System Memory:\t%ldK\n", mem>>10); - if (mach_get_hardware_list) - len += mach_get_hardware_list(buffer + len); + if (mach_get_hardware_list) + len += mach_get_hardware_list(buffer+len); - return len; + return(len); } void check_bugs(void) { #ifndef CONFIG_M68KFPU_EMU if (m68k_fputype == 0) { - printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " - "WHICH IS REQUIRED BY LINUX/M68K ***\n"); - printk(KERN_EMERG "Upgrade your hardware or join the FPU " - "emulation project\n"); - panic("no FPU"); + printk( KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " + "WHICH IS REQUIRED BY LINUX/M68K ***\n" ); + printk( KERN_EMERG "Upgrade your hardware or join the FPU " + "emulation project\n" ); + panic( "no FPU" ); } #endif /* !CONFIG_M68KFPU_EMU */ } - -#ifdef CONFIG_ADB -static int __init adb_probe_sync_enable (char *str) { - extern int __adb_probe_sync; - __adb_probe_sync = 1; - return 1; -} - -__setup("adb_sync", adb_probe_sync_enable); -#endif /* CONFIG_ADB */ diff --git a/trunk/arch/m68k/lib/checksum.c b/trunk/arch/m68k/lib/checksum.c index cf6bb51945a2..aed3be29e06b 100644 --- a/trunk/arch/m68k/lib/checksum.c +++ b/trunk/arch/m68k/lib/checksum.c @@ -320,9 +320,6 @@ csum_partial_copy_from_user(const void __user *src, void *dst, return(sum); } -EXPORT_SYMBOL(csum_partial_copy_from_user); - - /* * copy from kernel space while checksumming, otherwise like csum_partial */ diff --git a/trunk/arch/m68k/mac/baboon.c b/trunk/arch/m68k/mac/baboon.c index 673a1085984d..a1c7ec706741 100644 --- a/trunk/arch/m68k/mac/baboon.c +++ b/trunk/arch/m68k/mac/baboon.c @@ -22,7 +22,7 @@ /* #define DEBUG_BABOON */ /* #define DEBUG_IRQS */ -int baboon_present; +int baboon_present,baboon_active; volatile struct baboon *baboon; irqreturn_t baboon_irq(int, void *); @@ -45,6 +45,7 @@ void __init baboon_init(void) baboon = (struct baboon *) BABOON_BASE; baboon_present = 1; + baboon_active = 0; printk("Baboon detected at %p\n", baboon); } @@ -65,28 +66,26 @@ void __init baboon_register_interrupts(void) irqreturn_t baboon_irq(int irq, void *dev_id) { - int irq_bit, irq_num; + int irq_bit,i; unsigned char events; #ifdef DEBUG_IRQS - printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X\n", + printk("baboon_irq: mb_control %02X mb_ifr %02X mb_status %02X active %02X\n", (uint) baboon->mb_control, (uint) baboon->mb_ifr, - (uint) baboon->mb_status); + (uint) baboon->mb_status, baboon_active); #endif if (!(events = baboon->mb_ifr & 0x07)) return IRQ_NONE; - irq_num = IRQ_BABOON_0; - irq_bit = 1; - do { - if (events & irq_bit) { + for (i = 0, irq_bit = 1 ; i < 3 ; i++, irq_bit <<= 1) { + if (events & irq_bit/* & baboon_active*/) { + baboon_active &= ~irq_bit; + m68k_handle_int(IRQ_BABOON_0 + i); + baboon_active |= irq_bit; baboon->mb_ifr &= ~irq_bit; - m68k_handle_int(irq_num); } - irq_bit <<= 1; - irq_num++; - } while(events >= irq_bit); + } #if 0 if (baboon->mb_ifr & 0x02) macide_ack_intr(NULL); /* for now we need to smash all interrupts */ @@ -96,18 +95,21 @@ irqreturn_t baboon_irq(int irq, void *dev_id) } void baboon_irq_enable(int irq) { + int irq_idx = IRQ_IDX(irq); + #ifdef DEBUG_IRQUSE printk("baboon_irq_enable(%d)\n", irq); #endif - /* FIXME: figure out how to mask and unmask baboon interrupt sources */ - enable_irq(IRQ_NUBUS_C); + baboon_active |= (1 << irq_idx); } void baboon_irq_disable(int irq) { + int irq_idx = IRQ_IDX(irq); + #ifdef DEBUG_IRQUSE printk("baboon_irq_disable(%d)\n", irq); #endif - disable_irq(IRQ_NUBUS_C); + baboon_active &= ~(1 << irq_idx); } void baboon_irq_clear(int irq) { diff --git a/trunk/arch/m68k/mac/config.c b/trunk/arch/m68k/mac/config.c index 5fd413246f89..562b38d00180 100644 --- a/trunk/arch/m68k/mac/config.c +++ b/trunk/arch/m68k/mac/config.c @@ -59,15 +59,15 @@ extern struct mem_info m68k_ramdisk; extern char m68k_command_line[CL_SIZE]; -void *mac_env; /* Loaded by the boot asm */ +void *mac_env; /* Loaded by the boot asm */ /* The phys. video addr. - might be bogus on some machines */ unsigned long mac_orig_videoaddr; /* Mac specific timer functions */ -extern unsigned long mac_gettimeoffset(void); -extern int mac_hwclk(int, struct rtc_time *); -extern int mac_set_clock_mmss(unsigned long); +extern unsigned long mac_gettimeoffset (void); +extern int mac_hwclk (int, struct rtc_time *); +extern int mac_set_clock_mmss (unsigned long); extern int show_mac_interrupts(struct seq_file *, void *); extern void iop_preinit(void); extern void iop_init(void); @@ -82,6 +82,10 @@ extern void mac_mksound(unsigned int, unsigned int); extern void nubus_sweep_video(void); +/* Mac specific debug functions (in debug.c) */ +extern void mac_debug_init(void); +extern void mac_debugging_long(int, long); + static void mac_get_model(char *str); static void mac_sched_init(irq_handler_t vector) @@ -95,52 +99,51 @@ static void mac_sched_init(irq_handler_t vector) int __init mac_parse_bootinfo(const struct bi_record *record) { - int unknown = 0; - const u_long *data = record->data; + int unknown = 0; + const u_long *data = record->data; - switch (record->tag) { + switch (record->tag) { case BI_MAC_MODEL: - mac_bi_data.id = *data; - break; + mac_bi_data.id = *data; + break; case BI_MAC_VADDR: - mac_bi_data.videoaddr = *data; - break; + mac_bi_data.videoaddr = *data; + break; case BI_MAC_VDEPTH: - mac_bi_data.videodepth = *data; - break; + mac_bi_data.videodepth = *data; + break; case BI_MAC_VROW: - mac_bi_data.videorow = *data; - break; + mac_bi_data.videorow = *data; + break; case BI_MAC_VDIM: - mac_bi_data.dimensions = *data; - break; + mac_bi_data.dimensions = *data; + break; case BI_MAC_VLOGICAL: - mac_bi_data.videological = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK); - mac_orig_videoaddr = *data; - break; + mac_bi_data.videological = VIDEOMEMBASE + (*data & ~VIDEOMEMMASK); + mac_orig_videoaddr = *data; + break; case BI_MAC_SCCBASE: - mac_bi_data.sccbase = *data; - break; + mac_bi_data.sccbase = *data; + break; case BI_MAC_BTIME: - mac_bi_data.boottime = *data; - break; + mac_bi_data.boottime = *data; + break; case BI_MAC_GMTBIAS: - mac_bi_data.gmtbias = *data; - break; + mac_bi_data.gmtbias = *data; + break; case BI_MAC_MEMSIZE: - mac_bi_data.memsize = *data; - break; + mac_bi_data.memsize = *data; + break; case BI_MAC_CPUID: - mac_bi_data.cpuid = *data; - break; - case BI_MAC_ROMBASE: - mac_bi_data.rombase = *data; - break; + mac_bi_data.cpuid = *data; + break; + case BI_MAC_ROMBASE: + mac_bi_data.rombase = *data; + break; default: - unknown = 1; - break; - } - return unknown; + unknown = 1; + } + return(unknown); } /* @@ -152,7 +155,6 @@ int __init mac_parse_bootinfo(const struct bi_record *record) static void mac_cache_card_flush(int writeback) { unsigned long flags; - local_irq_save(flags); via_flush_cache(); local_irq_restore(flags); @@ -160,24 +162,28 @@ static void mac_cache_card_flush(int writeback) void __init config_mac(void) { - if (!MACH_IS_MAC) - printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n"); + if (!MACH_IS_MAC) { + printk(KERN_ERR "ERROR: no Mac, but config_mac() called!! \n"); + } - mach_sched_init = mac_sched_init; - mach_init_IRQ = mac_init_IRQ; - mach_get_model = mac_get_model; - mach_gettimeoffset = mac_gettimeoffset; + mach_sched_init = mac_sched_init; + mach_init_IRQ = mac_init_IRQ; + mach_get_model = mac_get_model; + mach_gettimeoffset = mac_gettimeoffset; #warning move to adb/via init #if 0 - mach_hwclk = mac_hwclk; + mach_hwclk = mac_hwclk; #endif - mach_set_clock_mmss = mac_set_clock_mmss; - mach_reset = mac_reset; - mach_halt = mac_poweroff; - mach_power_off = mac_poweroff; + mach_set_clock_mmss = mac_set_clock_mmss; + mach_reset = mac_reset; + mach_halt = mac_poweroff; + mach_power_off = mac_poweroff; mach_max_dma_address = 0xffffffff; +#if 0 + mach_debug_init = mac_debug_init; +#endif #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = mac_mksound; + mach_beep = mac_mksound; #endif #ifdef CONFIG_HEARTBEAT #if 0 @@ -193,22 +199,21 @@ void __init config_mac(void) mac_identify(); mac_report_hardware(); - /* - * AFAIK only the IIci takes a cache card. The IIfx has onboard - * cache ... someone needs to figure out how to tell if it's on or - * not. - */ + /* AFAIK only the IIci takes a cache card. The IIfx has onboard + cache ... someone needs to figure out how to tell if it's on or + not. */ if (macintosh_config->ident == MAC_MODEL_IICI - || macintosh_config->ident == MAC_MODEL_IIFX) + || macintosh_config->ident == MAC_MODEL_IIFX) { mach_l2_flush = mac_cache_card_flush; + } /* * Check for machine specific fixups. */ #ifdef OLD_NUBUS_CODE - nubus_sweep_video(); + nubus_sweep_video(); #endif } @@ -228,7 +233,8 @@ void __init config_mac(void) struct mac_model *macintosh_config; EXPORT_SYMBOL(macintosh_config); -static struct mac_model mac_data_table[] = { +static struct mac_model mac_data_table[]= +{ /* * We'll pretend to be a Macintosh II, that's pretty safe. */ @@ -778,12 +784,12 @@ void mac_identify(void) if (!model) { /* no bootinfo model id -> NetBSD booter was used! */ /* XXX FIXME: breaks for model > 31 */ - model = (mac_bi_data.cpuid >> 2) & 63; - printk(KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n"); + model=(mac_bi_data.cpuid>>2)&63; + printk (KERN_WARNING "No bootinfo model ID, using cpuid instead (hey, use Penguin!)\n"); } macintosh_config = mac_data_table; - for (m = macintosh_config; m->ident != -1; m++) { + for (m = macintosh_config ; m->ident != -1 ; m++) { if (m->ident == model) { macintosh_config = m; break; @@ -795,26 +801,27 @@ void mac_identify(void) /* the serial ports set to "Faster" mode in MacOS. */ iop_preinit(); + mac_debug_init(); - printk(KERN_INFO "Detected Macintosh model: %d \n", model); + printk (KERN_INFO "Detected Macintosh model: %d \n", model); /* * Report booter data: */ - printk(KERN_DEBUG " Penguin bootinfo data:\n"); - printk(KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n", + printk (KERN_DEBUG " Penguin bootinfo data:\n"); + printk (KERN_DEBUG " Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n", mac_bi_data.videoaddr, mac_bi_data.videorow, mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF, mac_bi_data.dimensions >> 16); - printk(KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n", + printk (KERN_DEBUG " Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n", mac_bi_data.videological, mac_orig_videoaddr, mac_bi_data.sccbase); - printk(KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n", + printk (KERN_DEBUG " Boottime: 0x%lx GMTBias: 0x%lx \n", mac_bi_data.boottime, mac_bi_data.gmtbias); - printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n", + printk (KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n", mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize); #if 0 - printk("Ramdisk: addr 0x%lx size 0x%lx\n", + printk ("Ramdisk: addr 0x%lx size 0x%lx\n", m68k_ramdisk.addr, m68k_ramdisk.size); #endif @@ -823,22 +830,22 @@ void mac_identify(void) */ switch (macintosh_config->scsi_type) { case MAC_SCSI_OLD: - MACHW_SET(MAC_SCSI_80); - break; + MACHW_SET(MAC_SCSI_80); + break; case MAC_SCSI_QUADRA: case MAC_SCSI_QUADRA2: case MAC_SCSI_QUADRA3: - MACHW_SET(MAC_SCSI_96); - if ((macintosh_config->ident == MAC_MODEL_Q900) || - (macintosh_config->ident == MAC_MODEL_Q950)) - MACHW_SET(MAC_SCSI_96_2); - break; + MACHW_SET(MAC_SCSI_96); + if ((macintosh_config->ident == MAC_MODEL_Q900) || + (macintosh_config->ident == MAC_MODEL_Q950)) + MACHW_SET(MAC_SCSI_96_2); + break; default: - printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n"); - MACHW_SET(MAC_SCSI_80); - break; - } + printk(KERN_WARNING "config.c: wtf: unknown scsi, using 53c80\n"); + MACHW_SET(MAC_SCSI_80); + break; + } iop_init(); via_init(); oss_init(); @@ -853,6 +860,6 @@ void mac_report_hardware(void) static void mac_get_model(char *str) { - strcpy(str, "Macintosh "); + strcpy(str,"Macintosh "); strcat(str, macintosh_config->name); } diff --git a/trunk/arch/m68k/mac/debug.c b/trunk/arch/m68k/mac/debug.c index 7a5bed5bdc57..4eeb09dc0e8f 100644 --- a/trunk/arch/m68k/mac/debug.c +++ b/trunk/arch/m68k/mac/debug.c @@ -27,6 +27,10 @@ #include #include +extern char m68k_debug_device[]; + +extern struct compat_bootinfo compat_boot_info; + extern unsigned long mac_videobase; extern unsigned long mac_videodepth; extern unsigned long mac_rowbytes; @@ -48,7 +52,7 @@ extern void mac_serial_print(const char *); */ #ifdef DEBUG_SCREEN -static int peng, line; +static int peng=0, line=0; #endif void mac_debugging_short(int pos, short num) @@ -70,14 +74,15 @@ void mac_debugging_short(int pos, short num) } /* calculate current offset */ - pengoffset = (unsigned char *)mac_videobase + - (150+line*2) * mac_rowbytes) + 80 * peng; + pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes) + +80*peng; - pptr = pengoffset; + pptr=pengoffset; - for (i = 0; i < 8 * sizeof(short); i++) { /* # of bits */ + for(i=0;i<8*sizeof(short);i++) /* # of bits */ + { /* value mask for bit i, reverse order */ - *pptr++ = (num & (1 << (8*sizeof(short)-i-1)) ? 0xFF : 0x00); + *pptr++ = (num & ( 1 << (8*sizeof(short)-i-1) ) ? 0xFF : 0x00); } peng++; @@ -110,10 +115,11 @@ void mac_debugging_long(int pos, long addr) pengoffset=(unsigned char *)(mac_videobase+(150+line*2)*mac_rowbytes) +80*peng; - pptr = pengoffset; + pptr=pengoffset; - for (i = 0; i < 8 * sizeof(long); i++) { /* # of bits */ - *pptr++ = (addr & (1 << (8*sizeof(long)-i-1)) ? 0xFF : 0x00); + for(i=0;i<8*sizeof(long);i++) /* # of bits */ + { + *pptr++ = (addr & ( 1 << (8*sizeof(long)-i-1) ) ? 0xFF : 0x00); } peng++; @@ -130,15 +136,16 @@ void mac_debugging_long(int pos, long addr) * TODO: serial debug code */ -struct mac_SCC { - u_char cha_b_ctrl; - u_char char_dummy1; - u_char cha_a_ctrl; - u_char char_dummy2; - u_char cha_b_data; - u_char char_dummy3; - u_char cha_a_data; -}; +struct mac_SCC + { + u_char cha_b_ctrl; + u_char char_dummy1; + u_char cha_a_ctrl; + u_char char_dummy2; + u_char cha_b_data; + u_char char_dummy3; + u_char cha_a_data; + }; # define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase)) @@ -151,9 +158,9 @@ int mac_SCC_reset_done; static int scc_port = -1; static struct console mac_console_driver = { - .name = "debug", - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .flags = CON_PRINTBUFFER, + .index = -1, }; /* @@ -171,8 +178,8 @@ static struct console mac_console_driver = { * this driver if Mac. */ -void mac_debug_console_write(struct console *co, const char *str, - unsigned int count) +void mac_debug_console_write (struct console *co, const char *str, + unsigned int count) { mac_serial_print(str); } @@ -183,50 +190,48 @@ void mac_debug_console_write(struct console *co, const char *str, #define uSEC 1 -static inline void mac_sccb_out(char c) +static inline void mac_sccb_out (char c) { - int i; - - do { - for (i = uSEC; i > 0; --i) - barrier(); - } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ - for (i = uSEC; i > 0; --i) + int i; + do { + for( i = uSEC; i > 0; --i ) barrier(); - scc.cha_b_data = c; + } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ + for( i = uSEC; i > 0; --i ) + barrier(); + scc.cha_b_data = c; } -static inline void mac_scca_out(char c) +static inline void mac_scca_out (char c) { - int i; - - do { - for (i = uSEC; i > 0; --i) - barrier(); - } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ - for (i = uSEC; i > 0; --i) + int i; + do { + for( i = uSEC; i > 0; --i ) barrier(); - scc.cha_a_data = c; + } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ + for( i = uSEC; i > 0; --i ) + barrier(); + scc.cha_a_data = c; } -void mac_sccb_console_write(struct console *co, const char *str, - unsigned int count) +void mac_sccb_console_write (struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - mac_sccb_out('\r'); - mac_sccb_out(*str++); - } + while (count--) { + if (*str == '\n') + mac_sccb_out( '\r' ); + mac_sccb_out( *str++ ); + } } -void mac_scca_console_write(struct console *co, const char *str, - unsigned int count) +void mac_scca_console_write (struct console *co, const char *str, + unsigned int count) { - while (count--) { - if (*str == '\n') - mac_scca_out('\r'); - mac_scca_out(*str++); - } + while (count--) { + if (*str == '\n') + mac_scca_out( '\r' ); + mac_scca_out( *str++ ); + } } @@ -234,41 +239,41 @@ void mac_scca_console_write(struct console *co, const char *str, * SCC serial ports. They're used by the debugging interface, kgdb, and the * serial console code. */ #define SCCB_WRITE(reg,val) \ - do { \ - int i; \ - scc.cha_b_ctrl = (reg); \ - for (i = uSEC; i > 0; --i) \ - barrier(); \ - scc.cha_b_ctrl = (val); \ - for (i = uSEC; i > 0; --i) \ - barrier(); \ - } while(0) + do { \ + int i; \ + scc.cha_b_ctrl = (reg); \ + for( i = uSEC; i > 0; --i ) \ + barrier(); \ + scc.cha_b_ctrl = (val); \ + for( i = uSEC; i > 0; --i ) \ + barrier(); \ + } while(0) #define SCCA_WRITE(reg,val) \ - do { \ - int i; \ - scc.cha_a_ctrl = (reg); \ - for (i = uSEC; i > 0; --i) \ - barrier(); \ - scc.cha_a_ctrl = (val); \ - for (i = uSEC; i > 0; --i) \ - barrier(); \ - } while(0) + do { \ + int i; \ + scc.cha_a_ctrl = (reg); \ + for( i = uSEC; i > 0; --i ) \ + barrier(); \ + scc.cha_a_ctrl = (val); \ + for( i = uSEC; i > 0; --i ) \ + barrier(); \ + } while(0) /* loops_per_jiffy isn't initialized yet, so we can't use udelay(). This does a * delay of ~ 60us. */ /* Mac: loops_per_jiffy min. 19000 ^= .5 us; MFPDELAY was 0.6 us*/ -#define LONG_DELAY() \ - do { \ - int i; \ - for (i = 60*uSEC; i > 0; --i) \ - barrier(); \ - } while(0) +#define LONG_DELAY() \ + do { \ + int i; \ + for( i = 60*uSEC; i > 0; --i ) \ + barrier(); \ + } while(0) #ifndef CONFIG_SERIAL_CONSOLE -static void __init mac_init_scc_port(int cflag, int port) +static void __init mac_init_scc_port( int cflag, int port ) #else -void mac_init_scc_port(int cflag, int port) +void mac_init_scc_port( int cflag, int port ) #endif { extern int mac_SCC_reset_done; @@ -287,102 +292,106 @@ void mac_init_scc_port(int cflag, int port) /* reg12 (BRG low) */ { 94, 62, 46, 22, 10, 4, 1, 0, 0 }; - int baud = cflag & CBAUD; - int clksrc, clkmode, div, reg3, reg5; - - if (cflag & CBAUDEX) - baud += B38400; - if (baud < B1200 || baud > B38400+2) - baud = B9600; /* use default 9600bps for non-implemented rates */ - baud -= B1200; /* tables starts at 1200bps */ - - clksrc = clksrc_table[baud]; - clkmode = clkmode_table[baud]; - div = div_table[baud]; - - reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40); - reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */; - - if (port == 1) { - (void)scc.cha_b_ctrl; /* reset reg pointer */ - SCCB_WRITE(9, 0xc0); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCB_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | - 0x04 /* 1 stopbit */ | - clkmode); - SCCB_WRITE(3, reg3); - SCCB_WRITE(5, reg5); - SCCB_WRITE(9, 0); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCB_WRITE(10, 0); /* NRZ mode */ - SCCB_WRITE(11, clksrc); /* main clock source */ - SCCB_WRITE(12, div); /* BRG value */ - SCCB_WRITE(13, 0); /* BRG high byte */ - SCCB_WRITE(14, 1); - SCCB_WRITE(3, reg3 | 1); - SCCB_WRITE(5, reg5 | 8); - } else if (port == 0) { - (void)scc.cha_a_ctrl; /* reset reg pointer */ - SCCA_WRITE(9, 0xc0); /* reset */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCA_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | - 0x04 /* 1 stopbit */ | - clkmode); - SCCA_WRITE(3, reg3); - SCCA_WRITE(5, reg5); - SCCA_WRITE(9, 0); /* no interrupts */ - LONG_DELAY(); /* extra delay after WR9 access */ - SCCA_WRITE(10, 0); /* NRZ mode */ - SCCA_WRITE(11, clksrc); /* main clock source */ - SCCA_WRITE(12, div); /* BRG value */ - SCCA_WRITE(13, 0); /* BRG high byte */ - SCCA_WRITE(14, 1); - SCCA_WRITE(3, reg3 | 1); - SCCA_WRITE(5, reg5 | 8); - } + int baud = cflag & CBAUD; + int clksrc, clkmode, div, reg3, reg5; + + if (cflag & CBAUDEX) + baud += B38400; + if (baud < B1200 || baud > B38400+2) + baud = B9600; /* use default 9600bps for non-implemented rates */ + baud -= B1200; /* tables starts at 1200bps */ + + clksrc = clksrc_table[baud]; + clkmode = clkmode_table[baud]; + div = div_table[baud]; - mac_SCC_reset_done = 1; - mac_SCC_init_done = 1; + reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40); + reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */; + + if (port == 1) { + (void)scc.cha_b_ctrl; /* reset reg pointer */ + SCCB_WRITE( 9, 0xc0 ); /* reset */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCCB_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | + 0x04 /* 1 stopbit */ | + clkmode ); + SCCB_WRITE( 3, reg3 ); + SCCB_WRITE( 5, reg5 ); + SCCB_WRITE( 9, 0 ); /* no interrupts */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCCB_WRITE( 10, 0 ); /* NRZ mode */ + SCCB_WRITE( 11, clksrc ); /* main clock source */ + SCCB_WRITE( 12, div ); /* BRG value */ + SCCB_WRITE( 13, 0 ); /* BRG high byte */ + SCCB_WRITE( 14, 1 ); + SCCB_WRITE( 3, reg3 | 1 ); + SCCB_WRITE( 5, reg5 | 8 ); + } else if (port == 0) { + (void)scc.cha_a_ctrl; /* reset reg pointer */ + SCCA_WRITE( 9, 0xc0 ); /* reset */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCCA_WRITE( 4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03) : 0 | + 0x04 /* 1 stopbit */ | + clkmode ); + SCCA_WRITE( 3, reg3 ); + SCCA_WRITE( 5, reg5 ); + SCCA_WRITE( 9, 0 ); /* no interrupts */ + LONG_DELAY(); /* extra delay after WR9 access */ + SCCA_WRITE( 10, 0 ); /* NRZ mode */ + SCCA_WRITE( 11, clksrc ); /* main clock source */ + SCCA_WRITE( 12, div ); /* BRG value */ + SCCA_WRITE( 13, 0 ); /* BRG high byte */ + SCCA_WRITE( 14, 1 ); + SCCA_WRITE( 3, reg3 | 1 ); + SCCA_WRITE( 5, reg5 | 8 ); + } + + mac_SCC_reset_done = 1; + mac_SCC_init_done = 1; } #endif /* DEBUG_SERIAL */ -void mac_init_scca_port(int cflag) +void mac_init_scca_port( int cflag ) { mac_init_scc_port(cflag, 0); } -void mac_init_sccb_port(int cflag) +void mac_init_sccb_port( int cflag ) { mac_init_scc_port(cflag, 1); } -static int __init mac_debug_setup(char *arg) +void __init mac_debug_init(void) { - if (!MACH_IS_MAC) - return 0; - #ifdef DEBUG_SERIAL - if (!strcmp(arg, "ser") || !strcmp(arg, "ser1")) { - /* Mac modem port */ - mac_init_scc_port(B9600|CS8, 0); - mac_console_driver.write = mac_scca_console_write; - scc_port = 0; - } else if (!strcmp(arg, "ser2")) { - /* Mac printer port */ - mac_init_scc_port(B9600|CS8, 1); - mac_console_driver.write = mac_sccb_console_write; - scc_port = 1; - } + if ( !strcmp( m68k_debug_device, "ser" ) + || !strcmp( m68k_debug_device, "ser1" )) { + /* Mac modem port */ + mac_init_scc_port( B9600|CS8, 0 ); + mac_console_driver.write = mac_scca_console_write; + scc_port = 0; + } + else if (!strcmp( m68k_debug_device, "ser2" )) { + /* Mac printer port */ + mac_init_scc_port( B9600|CS8, 1 ); + mac_console_driver.write = mac_sccb_console_write; + scc_port = 1; + } #endif #ifdef DEBUG_HEADS - if (!strcmp(arg, "scn") || !strcmp(arg, "con")) { - /* display, using head.S console routines */ - mac_console_driver.write = mac_debug_console_write; - } + if ( !strcmp( m68k_debug_device, "scn" ) + || !strcmp( m68k_debug_device, "con" )) { + /* display, using head.S console routines */ + mac_console_driver.write = mac_debug_console_write; + } #endif - if (mac_console_driver.write) - register_console(&mac_console_driver); - return 0; + if (mac_console_driver.write) + register_console(&mac_console_driver); } -early_param("debug", mac_debug_setup); +/* + * Local variables: + * c-indent-level: 4 + * tab-width: 8 + * End: + */ diff --git a/trunk/arch/m68k/mac/macints.c b/trunk/arch/m68k/mac/macints.c index 0fc72d8f786e..f6fcd754d8f6 100644 --- a/trunk/arch/m68k/mac/macints.c +++ b/trunk/arch/m68k/mac/macints.c @@ -219,7 +219,7 @@ static void mac_disable_irq(unsigned int irq); static struct irq_controller mac_irq_controller = { .name = "mac", - .lock = __SPIN_LOCK_UNLOCKED(mac_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .enable = mac_enable_irq, .disable = mac_disable_irq, }; diff --git a/trunk/arch/m68k/mac/oss.c b/trunk/arch/m68k/mac/oss.c index d7be16917efd..63690819565a 100644 --- a/trunk/arch/m68k/mac/oss.c +++ b/trunk/arch/m68k/mac/oss.c @@ -109,11 +109,13 @@ irqreturn_t oss_irq(int irq, void *dev_id) /* FIXME: how do you clear a pending IRQ? */ if (events & OSS_IP_SOUND) { - oss->irq_pending &= ~OSS_IP_SOUND; /* FIXME: call sound handler */ + oss->irq_pending &= ~OSS_IP_SOUND; } else if (events & OSS_IP_SCSI) { - oss->irq_pending &= ~OSS_IP_SCSI; + oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED; m68k_handle_int(IRQ_MAC_SCSI); + oss->irq_pending &= ~OSS_IP_SCSI; + oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI; } else { /* FIXME: error check here? */ } @@ -141,16 +143,14 @@ irqreturn_t oss_nubus_irq(int irq, void *dev_id) #endif /* There are only six slots on the OSS, not seven */ - i = 6; - irq_bit = 0x40; - do { - --i; - irq_bit >>= 1; + for (i = 0, irq_bit = 1 ; i < 6 ; i++, irq_bit <<= 1) { if (events & irq_bit) { - oss->irq_pending &= ~irq_bit; + oss->irq_level[i] = OSS_IRQLEV_DISABLED; m68k_handle_int(NUBUS_SOURCE_BASE + i); + oss->irq_pending &= ~irq_bit; + oss->irq_level[i] = OSS_IRQLEV_NUBUS; } - } while(events & (irq_bit - 1)); + } return IRQ_HANDLED; } diff --git a/trunk/arch/m68k/mac/psc.c b/trunk/arch/m68k/mac/psc.c index d66f723b17c3..15378a5878c9 100644 --- a/trunk/arch/m68k/mac/psc.c +++ b/trunk/arch/m68k/mac/psc.c @@ -131,8 +131,11 @@ irqreturn_t psc_irq(int irq, void *dev_id) { int pIFR = pIFRbase + ((int) dev_id); int pIER = pIERbase + ((int) dev_id); - int irq_num; - unsigned char irq_bit, events; + int base_irq; + int irq_bit,i; + unsigned char events; + + base_irq = irq << 3; #ifdef DEBUG_IRQS printk("psc_irq: irq %d pIFR = 0x%02X pIER = 0x%02X\n", @@ -143,16 +146,14 @@ irqreturn_t psc_irq(int irq, void *dev_id) if (!events) return IRQ_NONE; - irq_num = irq << 3; - irq_bit = 1; - do { - if (events & irq_bit) { + for (i = 0, irq_bit = 1 ; i < 4 ; i++, irq_bit <<= 1) { + if (events & irq_bit) { + psc_write_byte(pIER, irq_bit); + m68k_handle_int(base_irq + i); psc_write_byte(pIFR, irq_bit); - m68k_handle_int(irq_num); + psc_write_byte(pIER, irq_bit | 0x80); } - irq_num++; - irq_bit <<= 1; - } while (events >= irq_bit); + } return IRQ_HANDLED; } diff --git a/trunk/arch/m68k/mac/via.c b/trunk/arch/m68k/mac/via.c index d5cac72eb3db..e27735be2924 100644 --- a/trunk/arch/m68k/mac/via.c +++ b/trunk/arch/m68k/mac/via.c @@ -13,10 +13,6 @@ * for info. A full-text web search on 6522 AND VIA will probably also * net some usefulness. 20apr1999 * - * Additional data is here (the SY6522 was used in the Mac II etc): - * http://www.6502.org/documents/datasheets/synertek/synertek_sy6522.pdf - * http://www.6502.org/documents/datasheets/synertek/synertek_sy6522_programming_reference.pdf - * * PRAM/RTC access algorithms are from the NetBSD RTC toolkit version 1.08b * by Erik Vogan and adapted to Linux by Joshua M. Thompson (funaho@jurai.org) * @@ -41,7 +37,7 @@ volatile __u8 *via1, *via2; /* See note in mac_via.h about how this is possibly not useful */ volatile long *via_memory_bogon=(long *)&via_memory_bogon; #endif -int rbv_present, via_alt_mapping; +int rbv_present,via_alt_mapping; __u8 rbv_clear; /* @@ -64,19 +60,7 @@ static int gIER,gIFR,gBufA,gBufB; #define MAC_CLOCK_LOW (MAC_CLOCK_TICK&0xFF) #define MAC_CLOCK_HIGH (MAC_CLOCK_TICK>>8) -/* To disable a NuBus slot on Quadras we make the slot IRQ lines outputs, set - * high. On RBV we just use the slot interrupt enable register. On Macs with - * genuine VIA chips we must use nubus_disabled to keep track of disabled slot - * interrupts. When any slot IRQ is disabled we mask the (edge triggered) CA1 - * or "SLOTS" interrupt. When no slot is disabled, we unmask the CA1 interrupt. - * So, on genuine VIAs, having more than one NuBus IRQ can mean trouble, - * because closing one of those drivers can mask all of the NuBus interrupts. - * Also, since we can't mask the unregistered slot IRQs on genuine VIAs, it's - * possible to get interrupts from cards that MacOS or the ROM has configured - * but we have not. FWIW, "Designing Cards and Drivers for Macintosh II and - * Macintosh SE", page 9-8, says, a slot IRQ with no driver would crash MacOS. - */ -static u8 nubus_disabled; +static int nubus_active; void via_debug_dump(void); irqreturn_t via1_irq(int, void *); @@ -154,11 +138,11 @@ void __init via_init(void) printk(KERN_INFO "VIA2 at %p is ", via2); if (rbv_present) { - printk("an RBV\n"); + printk(KERN_INFO "an RBV\n"); } else if (oss_present) { - printk("an OSS\n"); + printk(KERN_INFO "an OSS\n"); } else { - printk("a 6522 or clone\n"); + printk(KERN_INFO "a 6522 or clone\n"); } #ifdef DEBUG_VIA @@ -179,7 +163,6 @@ void __init via_init(void) via1[vT2CL] = 0; via1[vT2CH] = 0; via1[vACR] &= 0x3F; - via1[vACR] &= ~0x03; /* disable port A & B latches */ /* * SE/30: disable video IRQ @@ -210,14 +193,8 @@ void __init via_init(void) /* that the IIfx emulates this alternate mapping using the OSS. */ switch(macintosh_config->ident) { - case MAC_MODEL_P475: - case MAC_MODEL_P475F: - case MAC_MODEL_P575: - case MAC_MODEL_Q605: - case MAC_MODEL_Q605_ACC: case MAC_MODEL_C610: case MAC_MODEL_Q610: - case MAC_MODEL_Q630: case MAC_MODEL_C650: case MAC_MODEL_Q650: case MAC_MODEL_Q700: @@ -251,22 +228,6 @@ void __init via_init(void) via2[vT2CL] = 0; via2[vT2CH] = 0; via2[vACR] &= 0x3F; - via2[vACR] &= ~0x03; /* disable port A & B latches */ - } - - /* - * Set vPCR for SCSI interrupts (but not on RBV) - */ - if (!rbv_present) { - if (macintosh_config->scsi_type == MAC_SCSI_OLD) { - /* CB2 (IRQ) indep. input, positive edge */ - /* CA2 (DRQ) indep. input, positive edge */ - via2[vPCR] = 0x66; - } else { - /* CB2 (IRQ) indep. input, negative edge */ - /* CA2 (DRQ) indep. input, negative edge */ - via2[vPCR] = 0x22; - } } } @@ -395,75 +356,78 @@ int via_get_cache_disable(void) void __init via_nubus_init(void) { + /* don't set nubus_active = 0 here, it kills the Baboon */ + /* interrupt that we've already registered. */ + /* unlock nubus transactions */ - if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) { + if (!rbv_present) { /* set the line to be an output on non-RBV machines */ - if (!rbv_present) + if ((macintosh_config->adb_type != MAC_ADB_PB1) && + (macintosh_config->adb_type != MAC_ADB_PB2)) { via2[vDirB] |= 0x02; + } + } - /* this seems to be an ADB bit on PMU machines */ - /* according to MkLinux. -- jmt */ + /* this seems to be an ADB bit on PMU machines */ + /* according to MkLinux. -- jmt */ + + if ((macintosh_config->adb_type != MAC_ADB_PB1) && + (macintosh_config->adb_type != MAC_ADB_PB2)) { via2[gBufB] |= 0x02; } - /* Disable all the slot interrupts (where possible). */ - - switch (macintosh_config->via_type) { - case MAC_VIA_II: - /* Just make the port A lines inputs. */ - switch(macintosh_config->ident) { - case MAC_MODEL_II: - case MAC_MODEL_IIX: - case MAC_MODEL_IICX: - case MAC_MODEL_SE30: - /* The top two bits are RAM size outputs. */ - via2[vDirA] &= 0xC0; - break; - default: - via2[vDirA] &= 0x80; - } - break; - case MAC_VIA_IIci: - /* RBV. Disable all the slot interrupts. SIER works like IER. */ + /* disable nubus slot interrupts. */ + if (rbv_present) { via2[rSIER] = 0x7F; - break; - case MAC_VIA_QUADRA: - /* Disable the inactive slot interrupts by making those lines outputs. */ + via2[rSIER] = nubus_active | 0x80; + } else { + /* These are ADB bits on PMU */ if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) { - via2[vBufA] |= 0x7F; - via2[vDirA] |= 0x7F; + (macintosh_config->adb_type != MAC_ADB_PB2)) { + switch(macintosh_config->ident) + { + case MAC_MODEL_II: + case MAC_MODEL_IIX: + case MAC_MODEL_IICX: + case MAC_MODEL_SE30: + via2[vBufA] |= 0x3F; + via2[vDirA] = ~nubus_active | 0xc0; + break; + default: + via2[vBufA] = 0xFF; + via2[vDirA] = ~nubus_active; + } } - break; } } /* * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's * via6522.c :-), disable/pending masks added. + * + * The new interrupt architecture in macints.c takes care of a lot of the + * gruntwork for us, including tallying the interrupts and calling the + * handlers on the linked list. All we need to do here is basically generate + * the machspec interrupt number after clearing the interrupt. */ irqreturn_t via1_irq(int irq, void *dev_id) { - int irq_num; - unsigned char irq_bit, events; + int irq_bit, i; + unsigned char events, mask; - events = via1[vIFR] & via1[vIER] & 0x7F; - if (!events) + mask = via1[vIER] & 0x7F; + if (!(events = via1[vIFR] & mask)) return IRQ_NONE; - irq_num = VIA1_SOURCE_BASE; - irq_bit = 1; - do { + for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) if (events & irq_bit) { + via1[vIER] = irq_bit; + m68k_handle_int(VIA1_SOURCE_BASE + i); via1[vIFR] = irq_bit; - m68k_handle_int(irq_num); + via1[vIER] = irq_bit | 0x80; } - ++irq_num; - irq_bit <<= 1; - } while (events >= irq_bit); #if 0 /* freakin' pmu is doing weird stuff */ if (!oss_present) { @@ -484,23 +448,20 @@ irqreturn_t via1_irq(int irq, void *dev_id) irqreturn_t via2_irq(int irq, void *dev_id) { - int irq_num; - unsigned char irq_bit, events; + int irq_bit, i; + unsigned char events, mask; - events = via2[gIFR] & via2[gIER] & 0x7F; - if (!events) + mask = via2[gIER] & 0x7F; + if (!(events = via2[gIFR] & mask)) return IRQ_NONE; - irq_num = VIA2_SOURCE_BASE; - irq_bit = 1; - do { + for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) if (events & irq_bit) { + via2[gIER] = irq_bit; via2[gIFR] = irq_bit | rbv_clear; - m68k_handle_int(irq_num); + m68k_handle_int(VIA2_SOURCE_BASE + i); + via2[gIER] = irq_bit | 0x80; } - ++irq_num; - irq_bit <<= 1; - } while (events >= irq_bit); return IRQ_HANDLED; } @@ -511,75 +472,71 @@ irqreturn_t via2_irq(int irq, void *dev_id) irqreturn_t via_nubus_irq(int irq, void *dev_id) { - int slot_irq; - unsigned char slot_bit, events; - - events = ~via2[gBufA] & 0x7F; - if (rbv_present) - events &= via2[rSIER]; - else - events &= ~via2[vDirA]; - if (!events) + int irq_bit, i; + unsigned char events; + + if (!(events = ~via2[gBufA] & nubus_active)) return IRQ_NONE; - do { - slot_irq = IRQ_NUBUS_F; - slot_bit = 0x40; - do { - if (events & slot_bit) { - events &= ~slot_bit; - m68k_handle_int(slot_irq); - } - --slot_irq; - slot_bit >>= 1; - } while (events); - - /* clear the CA1 interrupt and make certain there's no more. */ - via2[gIFR] = 0x02 | rbv_clear; - events = ~via2[gBufA] & 0x7F; - if (rbv_present) - events &= via2[rSIER]; - else - events &= ~via2[vDirA]; - } while (events); + for (i = 0, irq_bit = 1 ; i < 7 ; i++, irq_bit <<= 1) { + if (events & irq_bit) { + via_irq_disable(NUBUS_SOURCE_BASE + i); + m68k_handle_int(NUBUS_SOURCE_BASE + i); + via_irq_enable(NUBUS_SOURCE_BASE + i); + } + } return IRQ_HANDLED; } void via_irq_enable(int irq) { int irq_src = IRQ_SRC(irq); int irq_idx = IRQ_IDX(irq); + int irq_bit = 1 << irq_idx; #ifdef DEBUG_IRQUSE printk(KERN_DEBUG "via_irq_enable(%d)\n", irq); #endif if (irq_src == 1) { - via1[vIER] = IER_SET_BIT(irq_idx); + via1[vIER] = irq_bit | 0x80; } else if (irq_src == 2) { - if (irq != IRQ_MAC_NUBUS || nubus_disabled == 0) - via2[gIER] = IER_SET_BIT(irq_idx); + /* + * Set vPCR for SCSI interrupts (but not on RBV) + */ + if ((irq_idx == 0) && !rbv_present) { + if (macintosh_config->scsi_type == MAC_SCSI_OLD) { + /* CB2 (IRQ) indep. input, positive edge */ + /* CA2 (DRQ) indep. input, positive edge */ + via2[vPCR] = 0x66; + } else { + /* CB2 (IRQ) indep. input, negative edge */ + /* CA2 (DRQ) indep. input, negative edge */ + via2[vPCR] = 0x22; + } + } + via2[gIER] = irq_bit | 0x80; } else if (irq_src == 7) { - switch (macintosh_config->via_type) { - case MAC_VIA_II: - nubus_disabled &= ~(1 << irq_idx); - /* Enable the CA1 interrupt when no slot is disabled. */ - if (!nubus_disabled) - via2[gIER] = IER_SET_BIT(1); - break; - case MAC_VIA_IIci: - /* On RBV, enable the slot interrupt. - * SIER works like IER. - */ + nubus_active |= irq_bit; + if (rbv_present) { + /* enable the slot interrupt. SIER works like IER. */ via2[rSIER] = IER_SET_BIT(irq_idx); - break; - case MAC_VIA_QUADRA: - /* Make the port A line an input to enable the slot irq. - * But not on PowerBooks, that's ADB. - */ + } else { + /* Make sure the bit is an input, to enable the irq */ + /* But not on PowerBooks, that's ADB... */ if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) - via2[vDirA] &= ~(1 << irq_idx); - break; + (macintosh_config->adb_type != MAC_ADB_PB2)) { + switch(macintosh_config->ident) + { + case MAC_MODEL_II: + case MAC_MODEL_IIX: + case MAC_MODEL_IICX: + case MAC_MODEL_SE30: + via2[vDirA] &= (~irq_bit | 0xc0); + break; + default: + via2[vDirA] &= ~irq_bit; + } + } } } } @@ -587,31 +544,29 @@ void via_irq_enable(int irq) { void via_irq_disable(int irq) { int irq_src = IRQ_SRC(irq); int irq_idx = IRQ_IDX(irq); + int irq_bit = 1 << irq_idx; #ifdef DEBUG_IRQUSE printk(KERN_DEBUG "via_irq_disable(%d)\n", irq); #endif if (irq_src == 1) { - via1[vIER] = IER_CLR_BIT(irq_idx); + via1[vIER] = irq_bit; } else if (irq_src == 2) { - via2[gIER] = IER_CLR_BIT(irq_idx); + via2[gIER] = irq_bit; } else if (irq_src == 7) { - switch (macintosh_config->via_type) { - case MAC_VIA_II: - nubus_disabled |= 1 << irq_idx; - if (nubus_disabled) - via2[gIER] = IER_CLR_BIT(1); - break; - case MAC_VIA_IIci: + if (rbv_present) { + /* disable the slot interrupt. SIER works like IER. */ via2[rSIER] = IER_CLR_BIT(irq_idx); - break; - case MAC_VIA_QUADRA: + } else { + /* disable the nubus irq by changing dir to output */ + /* except on PMU */ if ((macintosh_config->adb_type != MAC_ADB_PB1) && - (macintosh_config->adb_type != MAC_ADB_PB2)) - via2[vDirA] |= 1 << irq_idx; - break; + (macintosh_config->adb_type != MAC_ADB_PB2)) { + via2[vDirA] |= irq_bit; + } } + nubus_active &= ~irq_bit; } } @@ -625,9 +580,7 @@ void via_irq_clear(int irq) { } else if (irq_src == 2) { via2[gIFR] = irq_bit | rbv_clear; } else if (irq_src == 7) { - /* FIXME: There is no way to clear an individual nubus slot - * IRQ flag, other than getting the device to do it. - */ + /* FIXME: hmm.. */ } } @@ -647,7 +600,6 @@ int via_irq_pending(int irq) } else if (irq_src == 2) { return via2[gIFR] & irq_bit; } else if (irq_src == 7) { - /* Always 0 for MAC_VIA_QUADRA if the slot irq is disabled. */ return ~via2[gBufA] & irq_bit; } return 0; diff --git a/trunk/arch/m68k/mvme16x/rtc.c b/trunk/arch/m68k/mvme16x/rtc.c index e341387787ab..272d47eac58d 100644 --- a/trunk/arch/m68k/mvme16x/rtc.c +++ b/trunk/arch/m68k/mvme16x/rtc.c @@ -16,6 +16,7 @@ #include #include #include /* For struct rtc_time and ioctls, etc */ +#include #include #include diff --git a/trunk/arch/m68k/q40/config.c b/trunk/arch/m68k/q40/config.c index 476e18eca758..92f873cc7060 100644 --- a/trunk/arch/m68k/q40/config.c +++ b/trunk/arch/m68k/q40/config.c @@ -35,35 +35,35 @@ #include #include -extern irqreturn_t q40_process_int(int level, struct pt_regs *regs); -extern void q40_init_IRQ(void); +extern irqreturn_t q40_process_int (int level, struct pt_regs *regs); +extern void q40_init_IRQ (void); static void q40_get_model(char *model); static int q40_get_hardware_list(char *buffer); extern void q40_sched_init(irq_handler_t handler); -extern unsigned long q40_gettimeoffset(void); -extern int q40_hwclk(int, struct rtc_time *); -extern unsigned int q40_get_ss(void); -extern int q40_set_clock_mmss(unsigned long); +extern unsigned long q40_gettimeoffset (void); +extern int q40_hwclk (int, struct rtc_time *); +extern unsigned int q40_get_ss (void); +extern int q40_set_clock_mmss (unsigned long); static int q40_get_rtc_pll(struct rtc_pll_info *pll); static int q40_set_rtc_pll(struct rtc_pll_info *pll); -extern void q40_reset(void); +extern void q40_reset (void); void q40_halt(void); extern void q40_waitbut(void); -void q40_set_vectors(void); +void q40_set_vectors (void); -extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/); +extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/ ); +extern char m68k_debug_device[]; static void q40_mem_console_write(struct console *co, const char *b, - unsigned int count); + unsigned int count); extern int ql_ticks; static struct console q40_console_driver = { - .name = "debug", - .write = q40_mem_console_write, - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .flags = CON_PRINTBUFFER, + .index = -1, }; @@ -74,162 +74,150 @@ static int _cpleft; static void q40_mem_console_write(struct console *co, const char *s, unsigned int count) { - const char *p = s; - - if (count < _cpleft) { - while (count-- > 0) { - *q40_mem_cptr = *p++; - q40_mem_cptr += 4; - _cpleft--; - } - } -} - -static int __init q40_debug_setup(char *arg) -{ - /* useful for early debugging stages - writes kernel messages into SRAM */ - if (MACH_IS_Q40 && !strncmp(arg, "mem", 3)) { - /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ - _cpleft = 2000 - ((long)q40_mem_cptr-0xff020000) / 4; - register_console(&q40_console_driver); - } - return 0; + char *p=(char *)s; + + if (count<_cpleft) + while (count-- >0){ + *q40_mem_cptr=*p++; + q40_mem_cptr+=4; + _cpleft--; + } } - -early_param("debug", q40_debug_setup); - #if 0 void printq40(char *str) { - int l = strlen(str); - char *p = q40_mem_cptr; - - while (l-- > 0 && _cpleft-- > 0) { - *p = *str++; - p += 4; - } - q40_mem_cptr = p; + int l=strlen(str); + char *p=q40_mem_cptr; + + while (l-- >0 && _cpleft-- >0) + { + *p=*str++; + p+=4; + } + q40_mem_cptr=p; } #endif -static int halted; +static int halted=0; #ifdef CONFIG_HEARTBEAT static void q40_heartbeat(int on) { - if (halted) - return; + if (halted) return; - if (on) - Q40_LED_ON(); - else - Q40_LED_OFF(); + if (on) + Q40_LED_ON(); + else + Q40_LED_OFF(); } #endif void q40_reset(void) { - halted = 1; - printk("\n\n*******************************************\n" + halted=1; + printk ("\n\n*******************************************\n" "Called q40_reset : press the RESET button!! \n" "*******************************************\n"); Q40_LED_ON(); - while (1) - ; + while(1) ; } void q40_halt(void) { - halted = 1; - printk("\n\n*******************\n" - " Called q40_halt\n" - "*******************\n"); + halted=1; + printk ("\n\n*******************\n" + " Called q40_halt\n" + "*******************\n"); Q40_LED_ON(); - while (1) - ; + while(1) ; } static void q40_get_model(char *model) { - sprintf(model, "Q40"); + sprintf(model, "Q40"); } /* No hardware options on Q40? */ static int q40_get_hardware_list(char *buffer) { - *buffer = '\0'; - return 0; + *buffer = '\0'; + return 0; } -static unsigned int serports[] = -{ - 0x3f8,0x2f8,0x3e8,0x2e8,0 -}; +static unsigned int serports[]={0x3f8,0x2f8,0x3e8,0x2e8,0}; void q40_disable_irqs(void) { - unsigned i, j; + unsigned i,j; - j = 0; - while ((i = serports[j++])) - outb(0, i + UART_IER); - master_outb(0, EXT_ENABLE_REG); - master_outb(0, KEY_IRQ_ENABLE_REG); + j=0; + while((i=serports[j++])) outb(0,i+UART_IER); + master_outb(0,EXT_ENABLE_REG); + master_outb(0,KEY_IRQ_ENABLE_REG); } void __init config_q40(void) { - mach_sched_init = q40_sched_init; + mach_sched_init = q40_sched_init; - mach_init_IRQ = q40_init_IRQ; - mach_gettimeoffset = q40_gettimeoffset; - mach_hwclk = q40_hwclk; - mach_get_ss = q40_get_ss; - mach_get_rtc_pll = q40_get_rtc_pll; - mach_set_rtc_pll = q40_set_rtc_pll; - mach_set_clock_mmss = q40_set_clock_mmss; + mach_init_IRQ = q40_init_IRQ; + mach_gettimeoffset = q40_gettimeoffset; + mach_hwclk = q40_hwclk; + mach_get_ss = q40_get_ss; + mach_get_rtc_pll = q40_get_rtc_pll; + mach_set_rtc_pll = q40_set_rtc_pll; + mach_set_clock_mmss = q40_set_clock_mmss; - mach_reset = q40_reset; - mach_get_model = q40_get_model; - mach_get_hardware_list = q40_get_hardware_list; + mach_reset = q40_reset; + mach_get_model = q40_get_model; + mach_get_hardware_list = q40_get_hardware_list; #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) - mach_beep = q40_mksound; + mach_beep = q40_mksound; #endif #ifdef CONFIG_HEARTBEAT - mach_heartbeat = q40_heartbeat; + mach_heartbeat = q40_heartbeat; #endif - mach_halt = q40_halt; - - /* disable a few things that SMSQ might have left enabled */ - q40_disable_irqs(); - - /* no DMA at all, but ide-scsi requires it.. make sure - * all physical RAM fits into the boundary - otherwise - * allocator may play costly and useless tricks */ - mach_max_dma_address = 1024*1024*1024; + mach_halt = q40_halt; + + /* disable a few things that SMSQ might have left enabled */ + q40_disable_irqs(); + + /* no DMA at all, but ide-scsi requires it.. make sure + * all physical RAM fits into the boundary - otherwise + * allocator may play costly and useless tricks */ + mach_max_dma_address = 1024*1024*1024; + + /* useful for early debugging stages - writes kernel messages into SRAM */ + if (!strncmp( m68k_debug_device,"mem",3 )) + { + /*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/ + _cpleft=2000-((long)q40_mem_cptr-0xff020000)/4; + q40_console_driver.write = q40_mem_console_write; + register_console(&q40_console_driver); + } } int q40_parse_bootinfo(const struct bi_record *rec) { - return 1; + return 1; } -static inline unsigned char bcd2bin(unsigned char b) +static inline unsigned char bcd2bin (unsigned char b) { - return (b >> 4) * 10 + (b & 15); + return ((b>>4)*10 + (b&15)); } -static inline unsigned char bin2bcd(unsigned char b) +static inline unsigned char bin2bcd (unsigned char b) { - return (b / 10) * 16 + (b % 10); + return (((b/10)*16) + (b%10)); } -unsigned long q40_gettimeoffset(void) +unsigned long q40_gettimeoffset (void) { - return 5000 * (ql_ticks != 0); + return 5000*(ql_ticks!=0); } @@ -250,9 +238,9 @@ unsigned long q40_gettimeoffset(void) int q40_hwclk(int op, struct rtc_time *t) { - if (op) { - /* Write.... */ - Q40_RTC_CTRL |= Q40_RTC_WRITE; + if (op) + { /* Write.... */ + Q40_RTC_CTRL |= Q40_RTC_WRITE; Q40_RTC_SECS = bin2bcd(t->tm_sec); Q40_RTC_MINS = bin2bcd(t->tm_min); @@ -263,23 +251,25 @@ int q40_hwclk(int op, struct rtc_time *t) if (t->tm_wday >= 0) Q40_RTC_DOW = bin2bcd(t->tm_wday+1); - Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); - } else { - /* Read.... */ - Q40_RTC_CTRL |= Q40_RTC_READ; - - t->tm_year = bcd2bin (Q40_RTC_YEAR); - t->tm_mon = bcd2bin (Q40_RTC_MNTH)-1; - t->tm_mday = bcd2bin (Q40_RTC_DATE); - t->tm_hour = bcd2bin (Q40_RTC_HOUR); - t->tm_min = bcd2bin (Q40_RTC_MINS); - t->tm_sec = bcd2bin (Q40_RTC_SECS); - - Q40_RTC_CTRL &= ~(Q40_RTC_READ); - - if (t->tm_year < 70) - t->tm_year += 100; - t->tm_wday = bcd2bin(Q40_RTC_DOW)-1; + Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); + } + else + { /* Read.... */ + Q40_RTC_CTRL |= Q40_RTC_READ; + + t->tm_year = bcd2bin (Q40_RTC_YEAR); + t->tm_mon = bcd2bin (Q40_RTC_MNTH)-1; + t->tm_mday = bcd2bin (Q40_RTC_DATE); + t->tm_hour = bcd2bin (Q40_RTC_HOUR); + t->tm_min = bcd2bin (Q40_RTC_MINS); + t->tm_sec = bcd2bin (Q40_RTC_SECS); + + Q40_RTC_CTRL &= ~(Q40_RTC_READ); + + if (t->tm_year < 70) + t->tm_year += 100; + t->tm_wday = bcd2bin(Q40_RTC_DOW)-1; + } return 0; @@ -295,25 +285,29 @@ unsigned int q40_get_ss(void) * clock is out by > 30 minutes. Logic lifted from atari code. */ -int q40_set_clock_mmss(unsigned long nowtime) +int q40_set_clock_mmss (unsigned long nowtime) { int retval = 0; short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; int rtc_minutes; - rtc_minutes = bcd2bin(Q40_RTC_MINS); - if ((rtc_minutes < real_minutes ? - real_minutes - rtc_minutes : - rtc_minutes - real_minutes) < 30) { - Q40_RTC_CTRL |= Q40_RTC_WRITE; + rtc_minutes = bcd2bin (Q40_RTC_MINS); + + if ((rtc_minutes < real_minutes + ? real_minutes - rtc_minutes + : rtc_minutes - real_minutes) < 30) + { + Q40_RTC_CTRL |= Q40_RTC_WRITE; Q40_RTC_MINS = bin2bcd(real_minutes); Q40_RTC_SECS = bin2bcd(real_seconds); Q40_RTC_CTRL &= ~(Q40_RTC_WRITE); - } else + } + else retval = -1; + return retval; } @@ -324,23 +318,21 @@ int q40_set_clock_mmss(unsigned long nowtime) static int q40_get_rtc_pll(struct rtc_pll_info *pll) { - int tmp = Q40_RTC_CTRL; - + int tmp=Q40_RTC_CTRL; pll->pll_value = tmp & Q40_RTC_PLL_MASK; if (tmp & Q40_RTC_PLL_SIGN) pll->pll_value = -pll->pll_value; - pll->pll_max = 31; - pll->pll_min = -31; - pll->pll_posmult = 512; - pll->pll_negmult = 256; - pll->pll_clock = 125829120; - + pll->pll_max=31; + pll->pll_min=-31; + pll->pll_posmult=512; + pll->pll_negmult=256; + pll->pll_clock=125829120; return 0; } static int q40_set_rtc_pll(struct rtc_pll_info *pll) { - if (!pll->pll_ctrl) { + if (!pll->pll_ctrl){ /* the docs are a bit unclear so I am doublesetting */ /* RTC_WRITE here ... */ int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) | diff --git a/trunk/arch/m68k/q40/q40ints.c b/trunk/arch/m68k/q40/q40ints.c index 2fb25ae46a8a..31cc07d8cec4 100644 --- a/trunk/arch/m68k/q40/q40ints.c +++ b/trunk/arch/m68k/q40/q40ints.c @@ -59,7 +59,7 @@ static void q40_irq_shutdown(unsigned int irq) static struct irq_controller q40_irq_controller = { .name = "q40", - .lock = __SPIN_LOCK_UNLOCKED(q40_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .startup = q40_irq_startup, .shutdown = q40_irq_shutdown, .enable = q40_enable_irq, diff --git a/trunk/arch/m68k/sun3/sun3ints.c b/trunk/arch/m68k/sun3/sun3ints.c index 50df34bf80e3..baf74e8de8b5 100644 --- a/trunk/arch/m68k/sun3/sun3ints.c +++ b/trunk/arch/m68k/sun3/sun3ints.c @@ -90,7 +90,7 @@ static void sun3_inthandle(unsigned int irq, struct pt_regs *fp) static struct irq_controller sun3_irq_controller = { .name = "sun3", - .lock = __SPIN_LOCK_UNLOCKED(sun3_irq_controller.lock), + .lock = SPIN_LOCK_UNLOCKED, .startup = m68k_irq_startup, .shutdown = m68k_irq_shutdown, .enable = sun3_enable_irq, @@ -103,7 +103,7 @@ void sun3_init_IRQ(void) m68k_setup_auto_interrupt(sun3_inthandle); m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7); - m68k_setup_user_interrupt(VEC_USER, 128, NULL); + m68k_setup_user_interrupt(VEC_USER, 192, NULL); request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL); request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL); diff --git a/trunk/arch/m68k/sun3x/prom.c b/trunk/arch/m68k/sun3x/prom.c index 48f8eb7b1565..574cf06df9e4 100644 --- a/trunk/arch/m68k/sun3x/prom.c +++ b/trunk/arch/m68k/sun3x/prom.c @@ -34,100 +34,99 @@ e_vector *sun3x_prom_vbr; /* Handle returning to the prom */ void sun3x_halt(void) { - unsigned long flags; + unsigned long flags; - /* Disable interrupts while we mess with things */ - local_irq_save(flags); + /* Disable interrupts while we mess with things */ + local_irq_save(flags); - /* Restore prom vbr */ - asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); + /* Restore prom vbr */ + __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); - /* Restore prom NMI clock */ -// sun3x_disable_intreg(5); - sun3_enable_irq(7); + /* Restore prom NMI clock */ +// sun3x_disable_intreg(5); + sun3_enable_irq(7); - /* Let 'er rip */ - asm volatile ("trap #14"); + /* Let 'er rip */ + __asm__ volatile ("trap #14" : : ); - /* Restore everything */ - sun3_disable_irq(7); - sun3_enable_irq(5); + /* Restore everything */ + sun3_disable_irq(7); + sun3_enable_irq(5); - asm volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); - local_irq_restore(flags); + __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); + local_irq_restore(flags); } void sun3x_reboot(void) { - /* This never returns, don't bother saving things */ - local_irq_disable(); + /* This never returns, don't bother saving things */ + local_irq_disable(); - /* Restore prom vbr */ - asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); + /* Restore prom vbr */ + __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); - /* Restore prom NMI clock */ - sun3_disable_irq(5); - sun3_enable_irq(7); + /* Restore prom NMI clock */ + sun3_disable_irq(5); + sun3_enable_irq(7); - /* Let 'er rip */ - (*romvec->pv_reboot)("vmlinux"); + /* Let 'er rip */ + (*romvec->pv_reboot)("vmlinux"); } +extern char m68k_debug_device[]; + static void sun3x_prom_write(struct console *co, const char *s, unsigned int count) { - while (count--) { - if (*s == '\n') - sun3x_putchar('\r'); - sun3x_putchar(*s++); - } + while (count--) { + if (*s == '\n') + sun3x_putchar('\r'); + sun3x_putchar(*s++); + } } /* debug console - write-only */ static struct console sun3x_debug = { - .name = "debug", - .write = sun3x_prom_write, - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "debug", + .write = sun3x_prom_write, + .flags = CON_PRINTBUFFER, + .index = -1, }; void sun3x_prom_init(void) { - /* Read the vector table */ - - sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR); - sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR); - sun3x_mayget = *(int (**)(void)) (SUN3X_P_MAYGET); - sun3x_mayput = *(int (**)(int)) (SUN3X_P_MAYPUT); - sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT); - sun3x_prom_abort = *(e_vector *) (SUN3X_P_ABORT); - romvec = (struct linux_romvec *)SUN3X_PROM_BASE; - - idprom_init(); - - if (!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) { - printk("Warning: machine reports strange type %02x\n", - idprom->id_machtype); - printk("Pretending it's a 3/80, but very afraid...\n"); - idprom->id_machtype = SM_SUN3X | SM_3_80; - } - - /* point trap #14 at abort. - * XXX this is futile since we restore the vbr first - oops - */ - vectors[VEC_TRAP14] = sun3x_prom_abort; -} + /* Read the vector table */ -static int __init sun3x_debug_setup(char *arg) -{ - /* If debug=prom was specified, start the debug console */ - if (MACH_IS_SUN3X && !strcmp(arg, "prom")) - register_console(&sun3x_debug); - return 0; -} + sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR); + sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR); + sun3x_mayget = *(int (**)(void)) (SUN3X_P_MAYGET); + sun3x_mayput = *(int (**)(int)) (SUN3X_P_MAYPUT); + sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT); + sun3x_prom_abort = *(e_vector *) (SUN3X_P_ABORT); + romvec = (struct linux_romvec *)SUN3X_PROM_BASE; + + idprom_init(); + + if(!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) { + printk("Warning: machine reports strange type %02x\n", + idprom->id_machtype); + printk("Pretending it's a 3/80, but very afraid...\n"); + idprom->id_machtype = SM_SUN3X | SM_3_80; + } -early_param("debug", sun3x_debug_setup); + /* point trap #14 at abort. + * XXX this is futile since we restore the vbr first - oops + */ + vectors[VEC_TRAP14] = sun3x_prom_abort; + + /* If debug=prom was specified, start the debug console */ + + if (!strcmp(m68k_debug_device, "prom")) + register_console(&sun3x_debug); + + +} /* some prom functions to export */ int prom_getintdefault(int node, char *property, int deflt) @@ -142,6 +141,7 @@ int prom_getbool (int node, char *prop) void prom_printf(char *fmt, ...) { + } void prom_halt (void) @@ -159,7 +159,7 @@ prom_get_idprom(char *idbuf, int num_bytes) int i; /* make a copy of the idprom structure */ - for (i = 0; i < num_bytes; i++) + for(i = 0; i < num_bytes; i++) idbuf[i] = ((char *)SUN3X_IDPROM)[i]; return idbuf[0]; diff --git a/trunk/arch/m68knommu/kernel/dma.c b/trunk/arch/m68knommu/kernel/dma.c index 0a25874a2aae..14b19c4161f4 100644 --- a/trunk/arch/m68knommu/kernel/dma.c +++ b/trunk/arch/m68knommu/kernel/dma.c @@ -8,6 +8,7 @@ #include #include #include +#include #include void *dma_alloc_coherent(struct device *dev, size_t size, diff --git a/trunk/arch/m68knommu/kernel/ptrace.c b/trunk/arch/m68knommu/kernel/ptrace.c index f54b6a3dfecb..72d349623575 100644 --- a/trunk/arch/m68knommu/kernel/ptrace.c +++ b/trunk/arch/m68knommu/kernel/ptrace.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/m68knommu/kernel/sys_m68k.c b/trunk/arch/m68knommu/kernel/sys_m68k.c index 48e6b33e8b44..3265b2d734db 100644 --- a/trunk/arch/m68knommu/kernel/sys_m68k.c +++ b/trunk/arch/m68knommu/kernel/sys_m68k.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index b7cb048bc771..130d825e5438 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -784,6 +784,7 @@ config TOSHIBA_RBTX4927 select HAS_TXX9_SERIAL select HW_HAS_PCI select I8259 + select ISA select SWAP_IO_SPACE select SYS_HAS_CPU_TX49XX select SYS_SUPPORTS_32BIT_KERNEL @@ -805,6 +806,7 @@ config TOSHIBA_RBTX4938 select HAS_TXX9_SERIAL select HW_HAS_PCI select I8259 + select ISA select SWAP_IO_SPACE select SYS_HAS_CPU_TX49XX select SYS_SUPPORTS_32BIT_KERNEL @@ -1040,9 +1042,6 @@ config SOC_AU1X00 select SYS_SUPPORTS_APM_EMULATION select SYS_SUPPORTS_KGDB -config SERIAL_RM9000 - bool - config PNX8550 bool select SOC_PNX8550 diff --git a/trunk/arch/mips/cobalt/Makefile b/trunk/arch/mips/cobalt/Makefile index 9565b2104dcd..de017c11f9b7 100644 --- a/trunk/arch/mips/cobalt/Makefile +++ b/trunk/arch/mips/cobalt/Makefile @@ -2,7 +2,7 @@ # Makefile for the Cobalt micro systems family specific parts of the kernel # -obj-y := irq.o reset.o setup.o buttons.o +obj-y := irq.o reset.o setup.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_EARLY_PRINTK) += console.o diff --git a/trunk/arch/mips/cobalt/buttons.c b/trunk/arch/mips/cobalt/buttons.c deleted file mode 100644 index 9e143989c7b8..000000000000 --- a/trunk/arch/mips/cobalt/buttons.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Cobalt buttons platform device. - * - * Copyright (C) 2007 Yoichi Yuasa - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -static struct resource cobalt_buttons_resource __initdata = { - .start = 0x1d000000, - .end = 0x1d000003, - .flags = IORESOURCE_MEM, -}; - -static __init int cobalt_add_buttons(void) -{ - struct platform_device *pd; - int error; - - pd = platform_device_alloc("Cobalt buttons", -1); - if (!pd) - return -ENOMEM; - - error = platform_device_add_resources(pd, &cobalt_buttons_resource, 1); - if (error) - goto err_free_device; - - error = platform_device_add(pd); - if (error) - goto err_free_device; - - return 0; - - err_free_device: - platform_device_put(pd); - return error; -} -device_initcall(cobalt_add_buttons); diff --git a/trunk/arch/mips/configs/rbhma4500_defconfig b/trunk/arch/mips/configs/rbhma4500_defconfig index 7d0f2174614e..29e0df9f4be0 100644 --- a/trunk/arch/mips/configs/rbhma4500_defconfig +++ b/trunk/arch/mips/configs/rbhma4500_defconfig @@ -245,6 +245,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y +CONFIG_ISA=y CONFIG_MMU=y # @@ -572,6 +573,7 @@ CONFIG_MTD_CFI_UTIL=y # # Plug and Play support # +# CONFIG_PNP is not set # CONFIG_PNPACPI is not set # @@ -656,6 +658,7 @@ CONFIG_BLK_DEV_IT8213=m # CONFIG_BLK_DEV_VIA82CXXX is not set CONFIG_BLK_DEV_TC86C001=m # CONFIG_IDE_ARM is not set +# CONFIG_IDE_CHIPSETS is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set # CONFIG_IDEDMA_AUTO is not set @@ -673,6 +676,11 @@ CONFIG_RAID_ATTRS=m # # CONFIG_ATA is not set +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + # # Multi-device support (RAID and LVM) # @@ -734,20 +742,37 @@ CONFIG_NET_ETHERNET=y # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NET_VENDOR_SMC is not set # CONFIG_DM9000 is not set +# CONFIG_NET_VENDOR_RACAL is not set # # Tulip family network device support # # CONFIG_NET_TULIP is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set # CONFIG_HP100 is not set +CONFIG_NET_ISA=y +# CONFIG_E2100 is not set +# CONFIG_EWRK3 is not set +# CONFIG_EEXPRESS is not set +# CONFIG_EEXPRESS_PRO is not set +# CONFIG_HPLAN_PLUS is not set +# CONFIG_HPLAN is not set +# CONFIG_LP486E is not set +# CONFIG_ETH16I is not set CONFIG_NE2000=y +# CONFIG_SEEQ8005 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AC3200 is not set +# CONFIG_APRICOT is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set +# CONFIG_CS89x0 is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set # CONFIG_E100 is not set @@ -808,6 +833,8 @@ CONFIG_NET_RADIO=y # Obsolete Wireless cards support (pre-802.11) # # CONFIG_STRIP is not set +# CONFIG_ARLAN is not set +# CONFIG_WAVELAN is not set # # Wireless 802.11b ISA/PCI cards support @@ -893,6 +920,9 @@ CONFIG_KEYBOARD_ATKBD=y CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_INPORT is not set +# CONFIG_MOUSE_LOGIBM is not set +# CONFIG_MOUSE_PC110PAD is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set # CONFIG_INPUT_TOUCHSCREEN is not set @@ -1042,6 +1072,7 @@ CONFIG_FB_ATY_CT=y # CONFIG_VGA_CONSOLE=y # CONFIG_VGACON_SOFT_SCROLLBACK is not set +# CONFIG_MDA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE is not set diff --git a/trunk/arch/mips/kernel/early_printk.c b/trunk/arch/mips/kernel/early_printk.c index 4fa54b230c09..304efdc5682f 100644 --- a/trunk/arch/mips/kernel/early_printk.c +++ b/trunk/arch/mips/kernel/early_printk.c @@ -33,3 +33,8 @@ void __init setup_early_printk(void) { register_console(&early_console); } + +void __init disable_early_printk(void) +{ + unregister_console(&early_console); +} diff --git a/trunk/arch/mips/kernel/irixelf.c b/trunk/arch/mips/kernel/irixelf.c index 403d96f99e77..3cc25c05d367 100644 --- a/trunk/arch/mips/kernel/irixelf.c +++ b/trunk/arch/mips/kernel/irixelf.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/mips/kernel/irixioctl.c b/trunk/arch/mips/kernel/irixioctl.c index 30f9eb09db3f..e2863821a3dd 100644 --- a/trunk/arch/mips/kernel/irixioctl.c +++ b/trunk/arch/mips/kernel/irixioctl.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/irixsig.c b/trunk/arch/mips/kernel/irixsig.c index 6980deb6dced..2132485caa74 100644 --- a/trunk/arch/mips/kernel/irixsig.c +++ b/trunk/arch/mips/kernel/irixsig.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/ptrace.c b/trunk/arch/mips/kernel/ptrace.c index b5a7b46bbc49..201ae194d1b8 100644 --- a/trunk/arch/mips/kernel/ptrace.c +++ b/trunk/arch/mips/kernel/ptrace.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/signal.c b/trunk/arch/mips/kernel/signal.c index 2a08ce41bf2b..07d67309451a 100644 --- a/trunk/arch/mips/kernel/signal.c +++ b/trunk/arch/mips/kernel/signal.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/signal32.c b/trunk/arch/mips/kernel/signal32.c index 003f8152b9ed..b9a014411f83 100644 --- a/trunk/arch/mips/kernel/signal32.c +++ b/trunk/arch/mips/kernel/signal32.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/signal_n32.c b/trunk/arch/mips/kernel/signal_n32.c index 4cf9ff24d1f7..a9202fa95987 100644 --- a/trunk/arch/mips/kernel/signal_n32.c +++ b/trunk/arch/mips/kernel/signal_n32.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/stacktrace.c b/trunk/arch/mips/kernel/stacktrace.c index ebd9db8d1ece..a586aba337a7 100644 --- a/trunk/arch/mips/kernel/stacktrace.c +++ b/trunk/arch/mips/kernel/stacktrace.c @@ -31,7 +31,8 @@ static void save_raw_context_stack(struct stack_trace *trace, } } -static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs) +static void save_context_stack(struct stack_trace *trace, + struct task_struct *task, struct pt_regs *regs) { unsigned long sp = regs->regs[29]; #ifdef CONFIG_KALLSYMS @@ -40,7 +41,7 @@ static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs) if (raw_show_trace || !__kernel_text_address(pc)) { unsigned long stack_page = - (unsigned long)task_stack_page(current); + (unsigned long)task_stack_page(task); if (stack_page && sp >= stack_page && sp <= stack_page + THREAD_SIZE - 32) save_raw_context_stack(trace, sp); @@ -53,7 +54,7 @@ static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs) trace->entries[trace->nr_entries++] = pc; if (trace->nr_entries >= trace->max_entries) break; - pc = unwind_stack(current, &sp, pc, &ra); + pc = unwind_stack(task, &sp, pc, &ra); } while (pc); #else save_raw_context_stack(trace, sp); @@ -63,13 +64,22 @@ static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs) /* * Save stack-backtrace addresses into a stack_trace buffer. */ -void save_stack_trace(struct stack_trace *trace) +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) { struct pt_regs dummyregs; struct pt_regs *regs = &dummyregs; WARN_ON(trace->nr_entries || !trace->max_entries); - prepare_frametrace(regs); - save_context_stack(trace, regs); + if (task && task != current) { + regs->regs[29] = task->thread.reg29; + regs->regs[31] = 0; + regs->cp0_epc = task->thread.reg31; + } else { + if (!task) + task = current; + prepare_frametrace(regs); + } + + save_context_stack(trace, task, regs); } diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c index 9dd5a2df8eac..26e1a7e78d13 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index ff45a4b8fbaa..493cb29b8a42 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/unaligned.c b/trunk/arch/mips/kernel/unaligned.c index a7d49ae805b4..24b7b053cfe9 100644 --- a/trunk/arch/mips/kernel/unaligned.c +++ b/trunk/arch/mips/kernel/unaligned.c @@ -76,6 +76,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/mips/kernel/vmlinux.lds.S b/trunk/arch/mips/kernel/vmlinux.lds.S index 043f637e3d10..c76b793310c2 100644 --- a/trunk/arch/mips/kernel/vmlinux.lds.S +++ b/trunk/arch/mips/kernel/vmlinux.lds.S @@ -119,7 +119,7 @@ SECTIONS .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; #endif - . = ALIGN(_PAGE_SIZE); + . = ALIGN(32); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/mips/lib/iomap.c b/trunk/arch/mips/lib/iomap.c index e3acb2dad33a..d51d5cb0a4a9 100644 --- a/trunk/arch/mips/lib/iomap.c +++ b/trunk/arch/mips/lib/iomap.c @@ -6,6 +6,7 @@ * (C) Copyright 2007 MIPS Technologies, Inc. * written by Ralf Baechle */ +#include #include #include diff --git a/trunk/arch/mips/math-emu/dsemul.c b/trunk/arch/mips/math-emu/dsemul.c index ea6ba7248489..8079f3d1eca0 100644 --- a/trunk/arch/mips/math-emu/dsemul.c +++ b/trunk/arch/mips/math-emu/dsemul.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/mips/mm/fault.c b/trunk/arch/mips/mm/fault.c index 7ebea331edb8..f9c595dceba9 100644 --- a/trunk/arch/mips/mm/fault.c +++ b/trunk/arch/mips/mm/fault.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /* For unblank_screen() */ #include diff --git a/trunk/arch/mips/pmc-sierra/msp71xx/msp_serial.c b/trunk/arch/mips/pmc-sierra/msp71xx/msp_serial.c deleted file mode 100644 index c41b53faa8f6..000000000000 --- a/trunk/arch/mips/pmc-sierra/msp71xx/msp_serial.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * The setup file for serial related hardware on PMC-Sierra MSP processors. - * - * Copyright 2005 PMC-Sierra, Inc. - * - * 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. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#ifdef CONFIG_KGDB -/* - * kgdb uses serial port 1 so the console can remain on port 0. - * To use port 0 change the definition to read as follows: - * #define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART0_BASE) - */ -#define DEBUG_PORT_BASE KSEG1ADDR(MSP_UART1_BASE) - -int putDebugChar(char c) -{ - volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE; - uint32_t val = (uint32_t)c; - - local_irq_disable(); - while( !(uart[5] & 0x20) ); /* Wait for TXRDY */ - uart[0] = val; - while( !(uart[5] & 0x20) ); /* Wait for TXRDY */ - local_irq_enable(); - - return 1; -} - -char getDebugChar(void) -{ - volatile uint32_t *uart = (volatile uint32_t *)DEBUG_PORT_BASE; - uint32_t val; - - while( !(uart[5] & 0x01) ); /* Wait for RXRDY */ - val = uart[0]; - - return (char)val; -} - -void initDebugPort(unsigned int uartclk, unsigned int baudrate) -{ - unsigned int baud_divisor = (uartclk + 8 * baudrate)/(16 * baudrate); - - /* Enable FIFOs */ - writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | - UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_4, - (char *)DEBUG_PORT_BASE + (UART_FCR * 4)); - - /* Select brtc divisor */ - writeb(UART_LCR_DLAB, (char *)DEBUG_PORT_BASE + (UART_LCR * 4)); - - /* Store divisor lsb */ - writeb(baud_divisor, (char *)DEBUG_PORT_BASE + (UART_TX * 4)); - - /* Store divisor msb */ - writeb(baud_divisor >> 8, (char *)DEBUG_PORT_BASE + (UART_IER * 4)); - - /* Set 8N1 mode */ - writeb(UART_LCR_WLEN8, (char *)DEBUG_PORT_BASE + (UART_LCR * 4)); - - /* Disable flow control */ - writeb(0, (char *)DEBUG_PORT_BASE + (UART_MCR * 4)); - - /* Disable receive interrupt(!) */ - writeb(0, (char *)DEBUG_PORT_BASE + (UART_IER * 4)); -} -#endif - -void __init msp_serial_setup(void) -{ - char *s; - char *endp; - struct uart_port up; - unsigned int uartclk; - - memset(&up, 0, sizeof(up)); - - /* Check if clock was specified in environment */ - s = prom_getenv("uartfreqhz"); - if(!(s && *s && (uartclk = simple_strtoul(s, &endp, 10)) && *endp == 0)) - uartclk = MSP_BASE_BAUD; - ppfinit("UART clock set to %d\n", uartclk); - - /* Initialize first serial port */ - up.mapbase = MSP_UART0_BASE; - up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN); - up.irq = MSP_INT_UART0; - up.uartclk = uartclk; - up.regshift = 2; - up.iotype = UPIO_DWAPB; /* UPIO_MEM like */ - up.flags = STD_COM_FLAGS; - up.type = PORT_16550A; - up.line = 0; - up.private_data = (void*)UART0_STATUS_REG; - if (early_serial_setup(&up)) - printk(KERN_ERR "Early serial init of port 0 failed\n"); - - /* Initialize the second serial port, if one exists */ - switch (mips_machtype) { - case MACH_MSP4200_EVAL: - case MACH_MSP4200_GW: - case MACH_MSP4200_FPGA: - case MACH_MSP7120_EVAL: - case MACH_MSP7120_GW: - case MACH_MSP7120_FPGA: - /* Enable UART1 on MSP4200 and MSP7120 */ - *GPIO_CFG2_REG = 0x00002299; - -#ifdef CONFIG_KGDB - /* Initialize UART1 for kgdb since PMON doesn't */ - if( DEBUG_PORT_BASE == KSEG1ADDR(MSP_UART1_BASE) ) { - if( mips_machtype == MACH_MSP4200_FPGA - || mips_machtype == MACH_MSP7120_FPGA ) - initDebugPort(uartclk,19200); - else - initDebugPort(uartclk,57600); - } -#endif - break; - - default: - return; /* No second serial port, good-bye. */ - } - - up.mapbase = MSP_UART1_BASE; - up.membase = ioremap_nocache(up.mapbase,MSP_UART_REG_LEN); - up.irq = MSP_INT_UART1; - up.line = 1; - up.private_data = (void*)UART1_STATUS_REG; - if (early_serial_setup(&up)) - printk(KERN_ERR "Early serial init of port 1 failed\n"); -} diff --git a/trunk/arch/mips/sgi-ip27/ip27-irq.c b/trunk/arch/mips/sgi-ip27/ip27-irq.c index ba8e0794630c..60ade7690e09 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-irq.c +++ b/trunk/arch/mips/sgi-ip27/ip27-irq.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/sni/irq.c b/trunk/arch/mips/sni/irq.c index 9ccffdfb8289..ad5fc471a004 100644 --- a/trunk/arch/mips/sni/irq.c +++ b/trunk/arch/mips/sni/irq.c @@ -42,7 +42,7 @@ static irqreturn_t sni_isa_irq_handler(int dummy, void *p) struct irqaction sni_isa_irq = { .handler = sni_isa_irq_handler, .name = "ISA", - .flags = IRQF_SHARED + .flags = SA_SHIRQ }; /* diff --git a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c index a0c11efeaeeb..0f7576dfd141 100644 --- a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c @@ -1049,22 +1049,3 @@ static int __init toshiba_rbtx4927_rtc_init(void) return IS_ERR(dev) ? PTR_ERR(dev) : 0; } device_initcall(toshiba_rbtx4927_rtc_init); - -static int __init rbtx4927_ne_init(void) -{ - static struct resource __initdata res[] = { - { - .start = RBTX4927_RTL_8019_BASE, - .end = RBTX4927_RTL_8019_BASE + 0x20 - 1, - .flags = IORESOURCE_IO, - }, { - .start = RBTX4927_RTL_8019_IRQ, - .flags = IORESOURCE_IRQ, - } - }; - struct platform_device *dev = - platform_device_register_simple("ne", -1, - res, ARRAY_SIZE(res)); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} -device_initcall(rbtx4927_ne_init); diff --git a/trunk/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/trunk/arch/mips/tx4938/toshiba_rbtx4938/setup.c index f5d1ce739fcc..66163ba452c8 100644 --- a/trunk/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/trunk/arch/mips/tx4938/toshiba_rbtx4938/setup.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -1038,22 +1037,3 @@ static int __init tx4938_spi_proc_setup(void) __initcall(tx4938_spi_proc_setup); #endif - -static int __init rbtx4938_ne_init(void) -{ - struct resource res[] = { - { - .start = RBTX4938_RTL_8019_BASE, - .end = RBTX4938_RTL_8019_BASE + 0x20 - 1, - .flags = IORESOURCE_IO, - }, { - .start = RBTX4938_RTL_8019_IRQ, - .flags = IORESOURCE_IRQ, - } - }; - struct platform_device *dev = - platform_device_register_simple("ne", -1, - res, ARRAY_SIZE(res)); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} -device_initcall(rbtx4938_ne_init); diff --git a/trunk/arch/parisc/hpux/fs.c b/trunk/arch/parisc/hpux/fs.c index d86e15776779..c7a81a2c014c 100644 --- a/trunk/arch/parisc/hpux/fs.c +++ b/trunk/arch/parisc/hpux/fs.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/parisc/hpux/ioctl.c b/trunk/arch/parisc/hpux/ioctl.c index dede4765852e..b34b4f3c60ec 100644 --- a/trunk/arch/parisc/hpux/ioctl.c +++ b/trunk/arch/parisc/hpux/ioctl.c @@ -34,6 +34,7 @@ */ #include +#include #include #include #include diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index c5c9125dacec..e9d09b020e86 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -388,7 +388,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) static struct irqaction timer_action = { .handler = timer_interrupt, .name = "timer", - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_PERCPU, }; #ifdef CONFIG_SMP diff --git a/trunk/arch/parisc/kernel/ptrace.c b/trunk/arch/parisc/kernel/ptrace.c index 8a0db376e91e..0d0d617b6f21 100644 --- a/trunk/arch/parisc/kernel/ptrace.c +++ b/trunk/arch/parisc/kernel/ptrace.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c index fb35ebc0c4da..9784e405f849 100644 --- a/trunk/arch/parisc/kernel/signal.c +++ b/trunk/arch/parisc/kernel/signal.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/parisc/kernel/signal32.c b/trunk/arch/parisc/kernel/signal32.c index db94affe5c71..1c1a37f73053 100644 --- a/trunk/arch/parisc/kernel/signal32.c +++ b/trunk/arch/parisc/kernel/signal32.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/parisc/kernel/sys_parisc.c b/trunk/arch/parisc/kernel/sys_parisc.c index 4f589216b39e..512642d8f707 100644 --- a/trunk/arch/parisc/kernel/sys_parisc.c +++ b/trunk/arch/parisc/kernel/sys_parisc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -105,11 +106,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, { if (len > TASK_SIZE) return -ENOMEM; - /* Might want to check for cache aliasing issues for MAP_FIXED case - * like ARM or MIPS ??? --BenH. - */ - if (flags & MAP_FIXED) - return addr; if (!addr) addr = TASK_UNMAPPED_BASE; diff --git a/trunk/arch/parisc/kernel/traps.c b/trunk/arch/parisc/kernel/traps.c index 745ff741490a..55bc1471967d 100644 --- a/trunk/arch/parisc/kernel/traps.c +++ b/trunk/arch/parisc/kernel/traps.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/parisc/kernel/unwind.c b/trunk/arch/parisc/kernel/unwind.c index 89c03707eccc..5f75b3e65986 100644 --- a/trunk/arch/parisc/kernel/unwind.c +++ b/trunk/arch/parisc/kernel/unwind.c @@ -216,8 +216,11 @@ static void unwind_frame_regs(struct unwind_frame_info *info) /* Handle some frequent special cases.... */ { char symname[KSYM_NAME_LEN+1]; + char *modname; + unsigned long symsize, offset; - kallsyms_lookup(info->ip, NULL, NULL, NULL, symname); + kallsyms_lookup(info->ip, &symsize, &offset, + &modname, symname); dbg("info->ip = 0x%lx, name = %s\n", info->ip, symname); diff --git a/trunk/arch/parisc/kernel/vmlinux.lds.S b/trunk/arch/parisc/kernel/vmlinux.lds.S index c74585990598..2a8253358c6c 100644 --- a/trunk/arch/parisc/kernel/vmlinux.lds.S +++ b/trunk/arch/parisc/kernel/vmlinux.lds.S @@ -181,7 +181,7 @@ SECTIONS .init.ramfs : { *(.init.ramfs) } __initramfs_end = .; #endif - . = ALIGN(ASM_PAGE_SIZE); + . = ALIGN(32); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 808d2ef80e2f..a54a9a2e36f3 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -117,33 +117,12 @@ config GENERIC_BUG default y depends on BUG -config SYS_SUPPORTS_APM_EMULATION - bool - -# -# Powerpc uses the slab allocator to manage its ptes and the -# page structs of ptes are used for splitting the page table -# lock for configurations supporting more than SPLIT_PTLOCK_CPUS. -# -# In that special configuration the page structs of slabs are modified. -# This setting disables the selection of SLUB as a slab allocator. -# -config ARCH_USES_SLAB_PAGE_STRUCT - bool - default y - depends on SPLIT_PTLOCK_CPUS <= NR_CPUS - config DEFAULT_UIMAGE bool help Used to allow a board to specify it wants a uImage built by default default n -config PPC64_SWSUSP - bool - depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL)) - default y - menu "Processor support" choice prompt "Processor Type" @@ -214,7 +193,6 @@ config 40x config 44x bool "AMCC 44x" select PPC_DCR_NATIVE - select WANT_DEVICE_TREE config E200 bool "Freescale e200" @@ -279,14 +257,9 @@ config PPC_OF_PLATFORM_PCI depends on PPC64 # not supported on 32 bits yet default n -config 4xx - bool - depends on 40x || 44x - default y - config BOOKE bool - depends on E200 || E500 || 44x + depends on E200 || E500 default y config FSL_BOOKE @@ -683,12 +656,11 @@ config MCA config PCI bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \ - || MPC7448HPC2 || PPC_PS3 || PPC_HOLLY + || MPC7448HPC2 || PPC_PS3 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \ && !PPC_85xx && !PPC_86xx default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS default PCI_QSPAN if !4xx && !CPM2 && 8xx - select ARCH_SUPPORTS_MSI help Find out whether your system includes a PCI bus. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index f70e795c262e..86aa3745af7f 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -139,6 +139,10 @@ config BOOTX_TEXT Say Y here to see progress messages from the boot firmware in text mode. Requires either BootX or Open Firmware. +config SERIAL_TEXT_DEBUG + bool "Support for early boot texts over serial port" + depends on 4xx + config PPC_EARLY_DEBUG bool "Early debugging (dangerous)" @@ -203,24 +207,6 @@ config PPC_EARLY_DEBUG_BEAT help Select this to enable early debugging for Celleb with Beat. -config PPC_EARLY_DEBUG_44x - bool "Early serial debugging for IBM/AMCC 44x CPUs" - depends on 44x - select PPC_UDBG_16550 - help - Select this to enable early debugging for IBM 44x chips via the - inbuilt serial port. - endchoice -config PPC_EARLY_DEBUG_44x_PHYSLOW - hex "Low 32 bits of early debug UART physical address" - depends PPC_EARLY_DEBUG_44x - default "0x40000200" - -config PPC_EARLY_DEBUG_44x_PHYSHIGH - hex "EPRN of early debug UART physical address" - depends PPC_EARLY_DEBUG_44x - default "0x1" - endmenu diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile index 81a531d84ff9..794992025d8d 100644 --- a/trunk/arch/powerpc/Makefile +++ b/trunk/arch/powerpc/Makefile @@ -148,7 +148,7 @@ all: $(KBUILD_IMAGE) CPPFLAGS_vmlinux.lds := -Upowerpc -BOOT_TARGETS = zImage zImage.initrd uImage +BOOT_TARGETS = zImage zImage.initrd uImage cuImage PHONY += $(BOOT_TARGETS) diff --git a/trunk/arch/powerpc/boot/44x.c b/trunk/arch/powerpc/boot/44x.c deleted file mode 100644 index d51377d9024f..000000000000 --- a/trunk/arch/powerpc/boot/44x.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2007 David Gibson, IBM Corporation. - * - * Based on earlier code: - * Matt Porter - * Copyright 2002-2005 MontaVista Software Inc. - * - * Eugene Surovegin or - * Copyright (c) 2003, 2004 Zultys Technologies - * - * 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 "types.h" -#include "string.h" -#include "stdio.h" -#include "ops.h" -#include "reg.h" -#include "dcr.h" - -/* Read the 44x memory controller to get size of system memory. */ -void ibm44x_fixup_memsize(void) -{ - int i; - unsigned long memsize, bank_config; - - memsize = 0; - for (i = 0; i < ARRAY_SIZE(sdram_bxcr); i++) { - mtdcr(DCRN_SDRAM0_CFGADDR, sdram_bxcr[i]); - bank_config = mfdcr(DCRN_SDRAM0_CFGDATA); - - if (bank_config & SDRAM_CONFIG_BANK_ENABLE) - memsize += SDRAM_CONFIG_BANK_SIZE(bank_config); - } - - dt_fixup_memory(0, memsize); -} diff --git a/trunk/arch/powerpc/boot/44x.h b/trunk/arch/powerpc/boot/44x.h deleted file mode 100644 index 7b129ad043e1..000000000000 --- a/trunk/arch/powerpc/boot/44x.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * PowerPC 44x related functions - * - * Copyright 2007 David Gibson, IBM Corporation. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ -#ifndef _PPC_BOOT_44X_H_ -#define _PPC_BOOT_44X_H_ - -void ibm44x_fixup_memsize(void); -void ebony_init(void *mac0, void *mac1); - -#endif /* _PPC_BOOT_44X_H_ */ diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 5c384aad1184..3716594ea33e 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -37,15 +37,13 @@ zlib := inffast.c inflate.c inftrees.c zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h zliblinuxheader := zlib.h zconf.h zutil.h -$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \ - $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) +$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \ + $(addprefix $(obj)/,$(zlibheader)) src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ ns16550.c serial.c simple_alloc.c div64.S util.S \ - gunzip_util.c elf_util.c $(zlib) devtree.c \ - 44x.c ebony.c -src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \ - cuboot-ebony.c treeboot-ebony.c + gunzip_util.c elf_util.c $(zlib) devtree.c +src-plat := of.c cuboot-83xx.c cuboot-85xx.c src-boot := $(src-wlib) $(src-plat) empty.c src-boot := $(addprefix $(obj)/, $(src-boot)) @@ -131,14 +129,7 @@ image-$(CONFIG_PPC_CELLEB) += zImage.pseries image-$(CONFIG_PPC_CHRP) += zImage.chrp image-$(CONFIG_PPC_EFIKA) += zImage.chrp image-$(CONFIG_PPC_PMAC) += zImage.pmac -image-$(CONFIG_PPC_HOLLY) += zImage.holly-elf -image-$(CONFIG_DEFAULT_UIMAGE) += uImage - -ifneq ($(CONFIG_DEVICE_TREE),"") -image-$(CONFIG_PPC_83xx) += cuImage.83xx -image-$(CONFIG_PPC_85xx) += cuImage.85xx -image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony -endif +image-$(CONFIG_DEFAULT_UIMAGE) += uImage cuImage # For 32-bit powermacs, build the COFF and miboot images # as well as the ELF images. @@ -147,8 +138,7 @@ image-$(CONFIG_PPC_PMAC) += zImage.coff zImage.miboot endif initrd- := $(patsubst zImage%, zImage.initrd%, $(image-n) $(image-)) -initrd-y := $(patsubst zImage%, zImage.initrd%, \ - $(patsubst treeImage%, treeImage.initrd%, $(image-y))) +initrd-y := $(patsubst zImage%, zImage.initrd%, $(image-y)) initrd-y := $(filter-out $(image-y), $(initrd-y)) targets += $(image-y) $(initrd-y) @@ -169,27 +159,18 @@ $(obj)/zImage.ps3: vmlinux $(obj)/zImage.initrd.ps3: vmlinux @echo " WARNING zImage.initrd.ps3 not supported (yet)" -$(obj)/zImage.holly-elf: vmlinux $(wrapperbits) - $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,) - -$(obj)/zImage.initrd.holly-elf: vmlinux $(wrapperbits) $(obj)/ramdisk.image.gz - $(call if_changed,wrap,holly,$(obj)/dts/holly.dts,,$(obj)/ramdisk.image.gz) - $(obj)/uImage: vmlinux $(wrapperbits) $(call if_changed,wrap,uboot) -# CONFIG_DEVICE_TREE will have "" around it, make sure to strip them -dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\ - ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE:"%"=%) - -$(obj)/cuImage.%: vmlinux $(dts) $(wrapperbits) - $(call if_changed,wrap,cuboot-$*,$(dts)) +cuboot-plat-$(CONFIG_83xx) += 83xx +cuboot-plat-$(CONFIG_85xx) += 85xx +cuboot-plat-y += unknown-platform -$(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits) - $(call if_changed,wrap,treeboot-$*,$(dts)) +dts = $(if $(shell echo $(CONFIG_DEVICE_TREE) | grep '^/'),\ + ,$(srctree)/$(src)/dts/)$(CONFIG_DEVICE_TREE) -$(obj)/treeImage.initrd.%: vmlinux $(dts) $(wrapperbits) - $(call if_changed,wrap,treeboot-$*,$(dts),,$(obj)/ramdisk.image.gz) +$(obj)/cuImage: vmlinux $(wrapperbits) + $(call if_changed,wrap,cuboot-$(word 1,$(cuboot-plat-y)),$(dts)) $(obj)/zImage: $(addprefix $(obj)/, $(image-y)) @rm -f $@; ln $< $@ @@ -200,8 +181,8 @@ install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y)) sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" $< # anything not in $(targets) -clean-files += $(image-) $(initrd-) zImage zImage.initrd cuImage.* \ - treeImage.* +clean-files += $(image-) $(initrd-) zImage zImage.initrd \ + cuImage.elf cuImage.bin.gz # clean up files cached by wrapper clean-kernel := vmlinux.strip vmlinux.bin diff --git a/trunk/arch/powerpc/boot/cuboot-ebony.c b/trunk/arch/powerpc/boot/cuboot-ebony.c deleted file mode 100644 index 4464c5f67acb..000000000000 --- a/trunk/arch/powerpc/boot/cuboot-ebony.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Old U-boot compatibility for Ebony - * - * Author: David Gibson - * - * Copyright 2007 David Gibson, IBM Corporatio. - * Based on cuboot-83xx.c, which is: - * Copyright (c) 2007 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ - -#include "ops.h" -#include "stdio.h" -#include "44x.h" - -#define TARGET_44x -#include "ppcboot.h" - -static bd_t bd; -extern char _end[]; - -BSS_STACK(4096); - -void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7) -{ - unsigned long end_of_ram = bd.bi_memstart + bd.bi_memsize; - unsigned long avail_ram = end_of_ram - (unsigned long)_end; - - memcpy(&bd, (bd_t *)r3, sizeof(bd)); - loader_info.initrd_addr = r4; - loader_info.initrd_size = r4 ? r5 : 0; - loader_info.cmdline = (char *)r6; - loader_info.cmdline_len = r7 - r6; - - simple_alloc_init(_end, avail_ram, 32, 64); - - ebony_init(&bd.bi_enetaddr, &bd.bi_enet1addr); -} diff --git a/trunk/arch/powerpc/boot/dcr.h b/trunk/arch/powerpc/boot/dcr.h deleted file mode 100644 index 877bc97b1e97..000000000000 --- a/trunk/arch/powerpc/boot/dcr.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef _PPC_BOOT_DCR_H_ -#define _PPC_BOOT_DCR_H_ - -#define mfdcr(rn) \ - ({ \ - unsigned long rval; \ - asm volatile("mfdcr %0,%1" : "=r"(rval) : "i"(rn)); \ - rval; \ - }) -#define mtdcr(rn, val) \ - asm volatile("mtdcr %0,%1" : : "i"(rn), "r"(val)) - -/* 440GP/440GX SDRAM controller DCRs */ -#define DCRN_SDRAM0_CFGADDR 0x010 -#define DCRN_SDRAM0_CFGDATA 0x011 - -#define SDRAM0_B0CR 0x40 -#define SDRAM0_B1CR 0x44 -#define SDRAM0_B2CR 0x48 -#define SDRAM0_B3CR 0x4c - -static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2CR, SDRAM0_B3CR }; - -#define SDRAM_CONFIG_BANK_ENABLE 0x00000001 -#define SDRAM_CONFIG_SIZE_MASK 0x000e0000 -#define SDRAM_CONFIG_BANK_SIZE(reg) \ - (0x00400000 << ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17)) - -/* 440GP Clock, PM, chip control */ -#define DCRN_CPC0_SR 0x0b0 -#define DCRN_CPC0_ER 0x0b1 -#define DCRN_CPC0_FR 0x0b2 -#define DCRN_CPC0_SYS0 0x0e0 -#define CPC0_SYS0_TUNE 0xffc00000 -#define CPC0_SYS0_FBDV_MASK 0x003c0000 -#define CPC0_SYS0_FWDVA_MASK 0x00038000 -#define CPC0_SYS0_FWDVB_MASK 0x00007000 -#define CPC0_SYS0_OPDV_MASK 0x00000c00 -#define CPC0_SYS0_EPDV_MASK 0x00000300 -/* Helper macros to compute the actual clock divider values from the - * encodings in the CPC0 register */ -#define CPC0_SYS0_FBDV(reg) \ - ((((((reg) & CPC0_SYS0_FBDV_MASK) >> 18) - 1) & 0xf) + 1) -#define CPC0_SYS0_FWDVA(reg) \ - (8 - (((reg) & CPC0_SYS0_FWDVA_MASK) >> 15)) -#define CPC0_SYS0_FWDVB(reg) \ - (8 - (((reg) & CPC0_SYS0_FWDVB_MASK) >> 12)) -#define CPC0_SYS0_OPDV(reg) \ - ((((reg) & CPC0_SYS0_OPDV_MASK) >> 10) + 1) -#define CPC0_SYS0_EPDV(reg) \ - ((((reg) & CPC0_SYS0_EPDV_MASK) >> 8) + 1) -#define CPC0_SYS0_EXTSL 0x00000080 -#define CPC0_SYS0_RW_MASK 0x00000060 -#define CPC0_SYS0_RL 0x00000010 -#define CPC0_SYS0_ZMIISL_MASK 0x0000000c -#define CPC0_SYS0_BYPASS 0x00000002 -#define CPC0_SYS0_NTO1 0x00000001 -#define DCRN_CPC0_SYS1 0x0e1 -#define DCRN_CPC0_CUST0 0x0e2 -#define DCRN_CPC0_CUST1 0x0e3 -#define DCRN_CPC0_STRP0 0x0e4 -#define DCRN_CPC0_STRP1 0x0e5 -#define DCRN_CPC0_STRP2 0x0e6 -#define DCRN_CPC0_STRP3 0x0e7 -#define DCRN_CPC0_GPIO 0x0e8 -#define DCRN_CPC0_PLB 0x0e9 -#define DCRN_CPC0_CR1 0x0ea -#define DCRN_CPC0_CR0 0x0eb -#define CPC0_CR0_SWE 0x80000000 -#define CPC0_CR0_CETE 0x40000000 -#define CPC0_CR0_U1FCS 0x20000000 -#define CPC0_CR0_U0DTE 0x10000000 -#define CPC0_CR0_U0DRE 0x08000000 -#define CPC0_CR0_U0DC 0x04000000 -#define CPC0_CR0_U1DTE 0x02000000 -#define CPC0_CR0_U1DRE 0x01000000 -#define CPC0_CR0_U1DC 0x00800000 -#define CPC0_CR0_U0EC 0x00400000 -#define CPC0_CR0_U1EC 0x00200000 -#define CPC0_CR0_UDIV_MASK 0x001f0000 -#define CPC0_CR0_UDIV(reg) \ - ((((reg) & CPC0_CR0_UDIV_MASK) >> 16) + 1) -#define DCRN_CPC0_MIRQ0 0x0ec -#define DCRN_CPC0_MIRQ1 0x0ed -#define DCRN_CPC0_JTAGID 0x0ef - -#endif /* _PPC_BOOT_DCR_H_ */ diff --git a/trunk/arch/powerpc/boot/dts/ebony.dts b/trunk/arch/powerpc/boot/dts/ebony.dts deleted file mode 100644 index b67918651c48..000000000000 --- a/trunk/arch/powerpc/boot/dts/ebony.dts +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Device Tree Source for IBM Ebony - * - * Copyright (c) 2006, 2007 IBM Corp. - * Josh Boyer , David Gibson - * - * FIXME: Draft only! - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without - * any warranty of any kind, whether express or implied. - * - * To build: - * dtc -I dts -O asm -o ebony.S -b 0 ebony.dts - * dtc -I dts -O dtb -o ebony.dtb -b 0 ebony.dts - */ - -/ { - #address-cells = <2>; - #size-cells = <1>; - model = "ibm,ebony"; - compatible = "ibm,ebony"; - dcr-parent = <&/cpus/PowerPC,440GP@0>; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - PowerPC,440GP@0 { - device_type = "cpu"; - reg = <0>; - clock-frequency = <0>; // Filled in by zImage - timebase-frequency = <0>; // Filled in by zImage - i-cache-line-size = <32>; - d-cache-line-size = <32>; - i-cache-size = <0>; - d-cache-size = <0>; - dcr-controller; - dcr-access-method = "native"; - }; - }; - - memory { - device_type = "memory"; - reg = <0 0 0>; // Filled in by zImage - }; - - UIC0: interrupt-controller0 { - device_type = "ibm,uic"; - compatible = "ibm,uic-440gp", "ibm,uic"; - interrupt-controller; - cell-index = <0>; - dcr-reg = <0c0 009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - - }; - - UIC1: interrupt-controller1 { - device_type = "ibm,uic"; - compatible = "ibm,uic-440gp", "ibm,uic"; - interrupt-controller; - cell-index = <1>; - dcr-reg = <0d0 009>; - #address-cells = <0>; - #size-cells = <0>; - #interrupt-cells = <2>; - interrupts = <1e 4 1f 4>; /* cascade */ - interrupt-parent = <&UIC0>; - }; - - CPC0: cpc { - device_type = "ibm,cpc"; - compatible = "ibm,cpc-440gp"; - dcr-reg = <0b0 003 0e0 010>; - // FIXME: anything else? - }; - - plb { - device_type = "ibm,plb"; - compatible = "ibm,plb-440gp", "ibm,plb4"; - #address-cells = <2>; - #size-cells = <1>; - ranges; - clock-frequency = <0>; // Filled in by zImage - - SDRAM0: sdram { - device_type = "memory-controller"; - compatible = "ibm,sdram-440gp", "ibm,sdram"; - dcr-reg = <010 2>; - // FIXME: anything else? - }; - - DMA0: dma { - // FIXME: ??? - device_type = "ibm,dma-4xx"; - compatible = "ibm,dma-440gp", "ibm,dma-4xx"; - dcr-reg = <100 027>; - }; - - MAL0: mcmal { - device_type = "mcmal-dma"; - compatible = "ibm,mcmal-440gp", "ibm,mcmal"; - dcr-reg = <180 62>; - num-tx-chans = <4>; - num-rx-chans = <4>; - interrupt-parent = <&MAL0>; - interrupts = <0 1 2 3 4>; - #interrupt-cells = <1>; - #address-cells = <0>; - #size-cells = <0>; - interrupt-map = ; - interrupt-map-mask = ; - }; - - POB0: opb { - device_type = "ibm,opb"; - compatible = "ibm,opb-440gp", "ibm,opb"; - #address-cells = <1>; - #size-cells = <1>; - /* Wish there was a nicer way of specifying a full 32-bit - range */ - ranges = <00000000 1 00000000 80000000 - 80000000 1 80000000 80000000>; - dcr-reg = <090 00b>; - interrupt-parent = <&UIC1>; - interrupts = <7 4>; - clock-frequency = <0>; // Filled in by zImage - - EBC0: ebc { - device_type = "ibm,ebc"; - compatible = "ibm,ebc-440gp"; - dcr-reg = <012 2>; - #address-cells = <2>; - #size-cells = <1>; - clock-frequency = <0>; // Filled in by zImage - ranges = <0 00000000 fff00000 100000 - 1 00000000 48000000 100000 - 2 00000000 ff800000 400000 - 3 00000000 48200000 100000 - 7 00000000 48300000 100000>; - interrupts = <5 4>; - interrupt-parent = <&UIC1>; - - small-flash@0,0 { - device_type = "rom"; - compatible = "direct-mapped"; - probe-type = "JEDEC"; - bank-width = <1>; - partitions = <0 80000>; - partition-names = "OpenBIOS"; - reg = <0 80000 80000>; - }; - - ds1743@1,0 { - /* NVRAM & RTC */ - device_type = "nvram"; - compatible = "ds1743"; - reg = <1 0 2000>; - }; - - large-flash@2,0 { - device_type = "rom"; - compatible = "direct-mapped"; - probe-type = "JEDEC"; - bank-width = <1>; - partitions = <0 380000 - 280000 80000>; - partition-names = "fs", "firmware"; - reg = <2 0 400000>; - }; - - ir@3,0 { - reg = <3 0 10>; - }; - - fpga@7,0 { - compatible = "Ebony-FPGA"; - reg = <7 0 10>; - }; - }; - - UART0: serial@40000200 { - device_type = "serial"; - compatible = "ns16550"; - reg = <40000200 8>; - virtual-reg = ; - clock-frequency = ; - current-speed = <2580>; - interrupt-parent = <&UIC0>; - interrupts = <0 4>; - }; - - UART1: serial@40000300 { - device_type = "serial"; - compatible = "ns16550"; - reg = <40000300 8>; - virtual-reg = ; - clock-frequency = ; - current-speed = <2580>; - interrupt-parent = <&UIC0>; - interrupts = <1 4>; - }; - - IIC0: i2c@40000400 { - /* FIXME */ - device_type = "i2c"; - compatible = "ibm,iic-440gp", "ibm,iic"; - reg = <40000400 14>; - interrupt-parent = <&UIC0>; - interrupts = <2 4>; - }; - IIC1: i2c@40000500 { - /* FIXME */ - device_type = "i2c"; - compatible = "ibm,iic-440gp", "ibm,iic"; - reg = <40000500 14>; - interrupt-parent = <&UIC0>; - interrupts = <3 4>; - }; - - GPIO0: gpio@40000700 { - /* FIXME */ - device_type = "gpio"; - compatible = "ibm,gpio-440gp"; - reg = <40000700 20>; - }; - - ZMII0: emac-zmii@40000780 { - device_type = "emac-zmii"; - compatible = "ibm,zmii-440gp", "ibm,zmii"; - reg = <40000780 c>; - }; - - EMAC0: ethernet@40000800 { - linux,network-index = <0>; - device_type = "network"; - compatible = "ibm,emac-440gp", "ibm,emac"; - interrupt-parent = <&UIC1>; - interrupts = <1c 4 1d 4>; - reg = <40000800 70>; - local-mac-address = [000000000000]; // Filled in by zImage - mal-device = <&MAL0>; - mal-tx-channel = <0 1>; - mal-rx-channel = <0>; - cell-index = <0>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; - phy-mode = "rmii"; - phy-map = <00000001>; - zmii-device = <&ZMII0>; - zmii-channel = <0>; - }; - EMAC1: ethernet@40000900 { - linux,network-index = <1>; - device_type = "network"; - compatible = "ibm,emac-440gp", "ibm,emac"; - interrupt-parent = <&UIC1>; - interrupts = <1e 4 1f 4>; - reg = <40000900 70>; - local-mac-address = [000000000000]; // Filled in by zImage - mal-device = <&MAL0>; - mal-tx-channel = <2 3>; - mal-rx-channel = <1>; - cell-index = <1>; - max-frame-size = <5dc>; - rx-fifo-size = <1000>; - tx-fifo-size = <800>; - phy-mode = "rmii"; - phy-map = <00000001>; - zmii-device = <&ZMII0>; - zmii-channel = <1>; - }; - - - GPT0: gpt@40000a00 { - /* FIXME */ - reg = <40000a00 d4>; - interrupt-parent = <&UIC0>; - interrupts = <12 4 13 4 14 4 15 4 16 4>; - }; - - }; - - PCIX0: pci@1234 { - device_type = "pci"; - /* FIXME */ - reg = <2 0ec00000 8 - 2 0ec80000 f0 - 2 0ec80100 fc>; - }; - }; - - chosen { - linux,stdout-path = "/plb/opb/serial@40000200"; -// linux,initrd-start = <0>; /* FIXME */ -// linux,initrd-end = <0>; -// bootargs = ""; - }; -}; - diff --git a/trunk/arch/powerpc/boot/dts/holly.dts b/trunk/arch/powerpc/boot/dts/holly.dts deleted file mode 100644 index 254499b107f4..000000000000 --- a/trunk/arch/powerpc/boot/dts/holly.dts +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Device Tree Source for IBM Holly (PPC 750CL with TSI controller) - * Copyright 2007, IBM Corporation - * - * Stephen Winiecki - * Josh Boyer - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without - * any warranty of any kind, whether express or implied. - * - * To build: - * dtc -I dts -O asm -o holly.S -b 0 holly.dts - * dtc -I dts -O dtb -o holly.dtb -b 0 holly.dts - */ - -/ { - model = "41K7339"; - compatible = "ibm,holly"; - #address-cells = <1>; - #size-cells = <1>; - - cpus { - #address-cells = <1>; - #size-cells =<0>; - PowerPC,750CL@0 { - device_type = "cpu"; - reg = <0>; - d-cache-line-size = <20>; - i-cache-line-size = <20>; - d-cache-size = <8000>; - i-cache-size = <8000>; - d-cache-sets = <80>; - i-cache-sets = <80>; - timebase-frequency = <2faf080>; - clock-frequency = <23c34600>; - bus-frequency = ; - 32-bit; - }; - }; - - memory@0 { - device_type = "memory"; - reg = <00000000 20000000>; - }; - - tsi109@c0000000 { - device_type = "tsi-bridge"; - compatible = "tsi-bridge"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <00000000 c0000000 00010000>; - reg = ; - - i2c@7000 { - device_type = "i2c"; - compatible = "tsi-i2c"; - interrupt-parent = < &/tsi109@c0000000/pic@7400 >; - interrupts = ; - reg = <7000 400>; - }; - - mdio@6000 { - device_type = "mdio"; - compatible = "tsi-ethernet"; - - PHY1: ethernet-phy@6000 { - device_type = "ethernet-phy"; - compatible = "bcm54xx"; - reg = <6000 50>; - phy-id = <1>; - }; - - PHY2: ethernet-phy@6400 { - device_type = "ethernet-phy"; - compatible = "bcm54xx"; - reg = <6000 50>; - phy-id = <2>; - }; - }; - - ethernet@6200 { - device_type = "network"; - compatible = "tsi-ethernet"; - #address-cells = <1>; - #size-cells = <0>; - reg = <6000 200>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupt-parent = < &/tsi109@c0000000/pic@7400 >; - interrupts = <10 2>; - phy-handle = <&PHY1>; - }; - - ethernet@6600 { - device_type = "network"; - compatible = "tsi-ethernet"; - #address-cells = <1>; - #size-cells = <0>; - reg = <6400 200>; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupt-parent = < &/tsi109@c0000000/pic@7400 >; - interrupts = <11 2>; - phy-handle = <&PHY2>; - }; - - serial@7808 { - device_type = "serial"; - compatible = "ns16550"; - reg = <7808 200>; - virtual-reg = ; - clock-frequency = <3F9C6000>; - current-speed = <1c200>; - interrupt-parent = < &/tsi109@c0000000/pic@7400 >; - interrupts = ; - }; - - serial@7c08 { - device_type = "serial"; - compatible = "ns16550"; - reg = <7c08 200>; - virtual-reg = ; - clock-frequency = <3F9C6000>; - current-speed = <1c200>; - interrupt-parent = < &/tsi109@c0000000/pic@7400 >; - interrupts = ; - }; - - MPIC: pic@7400 { - device_type = "open-pic"; - compatible = "chrp,open-pic"; - interrupt-controller; - #interrupt-cells = <2>; - reg = <7400 400>; - big-endian; - }; - - pci@1000 { - device_type = "pci"; - compatible = "tsi109"; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - reg = <1000 1000>; - bus-range = <0 0>; - /*----------------------------------------------------+ - | PCI memory range. - | 01 denotes I/O space - | 02 denotes 32-bit memory space - +----------------------------------------------------*/ - ranges = <02000000 0 40000000 40000000 0 10000000 - 01000000 0 00000000 7e000000 0 00010000>; - clock-frequency = <7f28154>; - interrupt-parent = < &/tsi109@c0000000/pic@7400 >; - interrupts = <17 2>; - interrupt-map-mask = ; - /*----------------------------------------------------+ - | The INTA, INTB, INTC, INTD are shared. - +----------------------------------------------------*/ - interrupt-map = < - 0800 0 0 1 &RT0 24 0 - 0800 0 0 2 &RT0 25 0 - 0800 0 0 3 &RT0 26 0 - 0800 0 0 4 &RT0 27 0 - - 1000 0 0 1 &RT0 25 0 - 1000 0 0 2 &RT0 26 0 - 1000 0 0 3 &RT0 27 0 - 1000 0 0 4 &RT0 24 0 - - 1800 0 0 1 &RT0 26 0 - 1800 0 0 2 &RT0 27 0 - 1800 0 0 3 &RT0 24 0 - 1800 0 0 4 &RT0 25 0 - - 2000 0 0 1 &RT0 27 0 - 2000 0 0 2 &RT0 24 0 - 2000 0 0 3 &RT0 25 0 - 2000 0 0 4 &RT0 26 0 - >; - - RT0: router@1180 { - device_type = "pic-router"; - interrupt-controller; - big-endian; - clock-frequency = <0>; - #address-cells = <0>; - #interrupt-cells = <2>; - interrupts = <17 2>; - interrupt-parent = < &/tsi109@c0000000/pic@7400 >; - }; - }; - }; - - chosen { - linux,stdout-path = "/tsi109@c0000000/serial@7808"; - bootargs = "console=ttyS0,115200"; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/lite5200.dts b/trunk/arch/powerpc/boot/dts/lite5200.dts index e13ac6ef05a9..ba54c6b40a09 100644 --- a/trunk/arch/powerpc/boot/dts/lite5200.dts +++ b/trunk/arch/powerpc/boot/dts/lite5200.dts @@ -48,7 +48,6 @@ soc5200@f0000000 { model = "fsl,mpc5200"; - compatible = "mpc5200"; revision = "" // from bootloader #interrupt-cells = <3>; device_type = "soc"; @@ -167,7 +166,7 @@ device_type = "mscan"; compatible = "mpc5200-mscan"; cell-index = <1>; - interrupts = <2 12 0>; + interrupts = <1 12 0>; interrupt-parent = <500>; reg = <980 80>; }; @@ -179,7 +178,7 @@ interrupt-parent = <500>; }; - gpio-wkup@c00 { + gpio-wkup@b00 { compatible = "mpc5200-gpio-wkup"; reg = ; interrupts = <1 8 0 0 3 0>; @@ -318,22 +317,20 @@ i2c@3d00 { device_type = "i2c"; - compatible = "mpc5200-i2c\0fsl-i2c"; + compatible = "mpc5200-i2c"; cell-index = <0>; reg = <3d00 40>; interrupts = <2 f 0>; interrupt-parent = <500>; - fsl5200-clocking; }; i2c@3d40 { device_type = "i2c"; - compatible = "mpc5200-i2c\0fsl-i2c"; + compatible = "mpc5200-i2c"; cell-index = <1>; reg = <3d40 40>; interrupts = <2 10 0>; interrupt-parent = <500>; - fsl5200-clocking; }; sram@8000 { device_type = "sram"; diff --git a/trunk/arch/powerpc/boot/dts/lite5200b.dts b/trunk/arch/powerpc/boot/dts/lite5200b.dts index 00211b39a342..2e003081b0d3 100644 --- a/trunk/arch/powerpc/boot/dts/lite5200b.dts +++ b/trunk/arch/powerpc/boot/dts/lite5200b.dts @@ -48,7 +48,6 @@ soc5200@f0000000 { model = "fsl,mpc5200b"; - compatible = "mpc5200"; revision = ""; // from bootloader #interrupt-cells = <3>; device_type = "soc"; @@ -167,7 +166,7 @@ device_type = "mscan"; compatible = "mpc5200b-mscan\0mpc5200-mscan"; cell-index = <1>; - interrupts = <2 12 0>; + interrupts = <1 12 0>; interrupt-parent = <500>; reg = <980 80>; }; @@ -179,7 +178,7 @@ interrupt-parent = <500>; }; - gpio-wkup@c00 { + gpio-wkup@b00 { compatible = "mpc5200b-gpio-wkup\0mpc5200-gpio-wkup"; reg = ; interrupts = <1 8 0 0 3 0>; @@ -323,22 +322,20 @@ i2c@3d00 { device_type = "i2c"; - compatible = "mpc5200b-i2c\0mpc5200-i2c\0fsl-i2c"; + compatible = "mpc5200b-i2c\0mpc5200-i2c"; cell-index = <0>; reg = <3d00 40>; interrupts = <2 f 0>; interrupt-parent = <500>; - fsl5200-clocking; }; i2c@3d40 { device_type = "i2c"; - compatible = "mpc5200b-i2c\0mpc5200-i2c\0fsl-i2c"; + compatible = "mpc5200b-i2c\0mpc5200-i2c"; cell-index = <1>; reg = <3d40 40>; interrupts = <2 10 0>; interrupt-parent = <500>; - fsl5200-clocking; }; sram@8000 { device_type = "sram"; diff --git a/trunk/arch/powerpc/boot/dts/mpc832x_mds.dts b/trunk/arch/powerpc/boot/dts/mpc832x_mds.dts index 93b760696010..c798491f4cd0 100644 --- a/trunk/arch/powerpc/boot/dts/mpc832x_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc832x_mds.dts @@ -306,12 +306,14 @@ interrupts = <11 8>; reg = <3>; device_type = "ethernet-phy"; + interface = <3>; //ENET_100_MII }; phy4: ethernet-phy@04 { interrupt-parent = < &ipic >; interrupts = <12 8>; reg = <4>; device_type = "ethernet-phy"; + interface = <3>; }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts b/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts index be4c35784e49..b55bced1593d 100644 --- a/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts +++ b/trunk/arch/powerpc/boot/dts/mpc832x_rdb.dts @@ -265,12 +265,14 @@ interrupts = <0>; reg = <0>; device_type = "ethernet-phy"; + interface = <3>; //ENET_100_MII }; phy04:ethernet-phy@04 { interrupt-parent = <&pic>; interrupts = <0>; reg = <4>; device_type = "ethernet-phy"; + interface = <3>; }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc836x_mds.dts b/trunk/arch/powerpc/boot/dts/mpc836x_mds.dts index 38c8594df3a4..7f578eb57082 100644 --- a/trunk/arch/powerpc/boot/dts/mpc836x_mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc836x_mds.dts @@ -305,7 +305,6 @@ rx-clock = <0>; tx-clock = <19>; phy-handle = < &phy0 >; - phy-connection-type = "rgmii-id"; pio-handle = < &pio1 >; }; @@ -321,7 +320,6 @@ rx-clock = <0>; tx-clock = <14>; phy-handle = < &phy1 >; - phy-connection-type = "rgmii-id"; pio-handle = < &pio2 >; }; @@ -337,12 +335,14 @@ interrupts = <11 8>; reg = <0>; device_type = "ethernet-phy"; + interface = <6>; //ENET_1000_GMII }; phy1: ethernet-phy@01 { interrupt-parent = < &ipic >; interrupts = <12 8>; reg = <1>; device_type = "ethernet-phy"; + interface = <6>; }; }; diff --git a/trunk/arch/powerpc/boot/dts/mpc8568mds.dts b/trunk/arch/powerpc/boot/dts/mpc8568mds.dts index 948a3b61bd4a..7361b36749cb 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8568mds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8568mds.dts @@ -288,7 +288,6 @@ rx-clock = <0>; tx-clock = <19>; phy-handle = <&qe_phy0>; - phy-connection-type = "gmii"; pio-handle = <&pio1>; }; @@ -304,7 +303,6 @@ rx-clock = <0>; tx-clock = <14>; phy-handle = <&qe_phy1>; - phy-connection-type = "gmii"; pio-handle = <&pio2>; }; @@ -322,24 +320,28 @@ interrupts = <31 1>; reg = <0>; device_type = "ethernet-phy"; + interface = <6>; //ENET_1000_GMII }; qe_phy1: ethernet-phy@01 { interrupt-parent = <&mpic>; interrupts = <32 1>; reg = <1>; device_type = "ethernet-phy"; + interface = <6>; }; qe_phy2: ethernet-phy@02 { interrupt-parent = <&mpic>; interrupts = <31 1>; reg = <2>; device_type = "ethernet-phy"; + interface = <6>; //ENET_1000_GMII }; qe_phy3: ethernet-phy@03 { interrupt-parent = <&mpic>; interrupts = <32 1>; reg = <3>; device_type = "ethernet-phy"; + interface = <6>; //ENET_1000_GMII }; }; diff --git a/trunk/arch/powerpc/boot/ebony.c b/trunk/arch/powerpc/boot/ebony.c deleted file mode 100644 index b1251ee7a102..000000000000 --- a/trunk/arch/powerpc/boot/ebony.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2007 David Gibson, IBM Corporation. - * - * Based on earlier code: - * Copyright (C) Paul Mackerras 1997. - * - * Matt Porter - * Copyright 2002-2005 MontaVista Software Inc. - * - * Eugene Surovegin or - * Copyright (c) 2003, 2004 Zultys Technologies - * - * 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 "types.h" -#include "elf.h" -#include "string.h" -#include "stdio.h" -#include "page.h" -#include "ops.h" -#include "reg.h" -#include "dcr.h" -#include "44x.h" - -extern char _dtb_start[]; -extern char _dtb_end[]; - -static u8 *ebony_mac0, *ebony_mac1; - -/* Calculate 440GP clocks */ -void ibm440gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk) -{ - u32 sys0 = mfdcr(DCRN_CPC0_SYS0); - u32 cr0 = mfdcr(DCRN_CPC0_CR0); - u32 cpu, plb, opb, ebc, tb, uart0, uart1, m; - u32 opdv = CPC0_SYS0_OPDV(sys0); - u32 epdv = CPC0_SYS0_EPDV(sys0); - - if (sys0 & CPC0_SYS0_BYPASS) { - /* Bypass system PLL */ - cpu = plb = sysclk; - } else { - if (sys0 & CPC0_SYS0_EXTSL) - /* PerClk */ - m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv; - else - /* CPU clock */ - m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0); - cpu = sysclk * m / CPC0_SYS0_FWDVA(sys0); - plb = sysclk * m / CPC0_SYS0_FWDVB(sys0); - } - - opb = plb / opdv; - ebc = opb / epdv; - - /* FIXME: Check if this is for all 440GP, or just Ebony */ - if ((mfpvr() & 0xf0000fff) == 0x40000440) - /* Rev. B 440GP, use external system clock */ - tb = sysclk; - else - /* Rev. C 440GP, errata force us to use internal clock */ - tb = cpu; - - if (cr0 & CPC0_CR0_U0EC) - /* External UART clock */ - uart0 = ser_clk; - else - /* Internal UART clock */ - uart0 = plb / CPC0_CR0_UDIV(cr0); - - if (cr0 & CPC0_CR0_U1EC) - /* External UART clock */ - uart1 = ser_clk; - else - /* Internal UART clock */ - uart1 = plb / CPC0_CR0_UDIV(cr0); - - printf("PPC440GP: SysClk = %dMHz (%x)\n\r", - (sysclk + 500000) / 1000000, sysclk); - - dt_fixup_cpu_clocks(cpu, tb, 0); - - dt_fixup_clock("/plb", plb); - dt_fixup_clock("/plb/opb", opb); - dt_fixup_clock("/plb/opb/ebc", ebc); - dt_fixup_clock("/plb/opb/serial@40000200", uart0); - dt_fixup_clock("/plb/opb/serial@40000300", uart1); -} - -static void ebony_fixups(void) -{ - // FIXME: sysclk should be derived by reading the FPGA registers - unsigned long sysclk = 33000000; - - ibm440gp_fixup_clocks(sysclk, 6 * 1843200); - ibm44x_fixup_memsize(); - dt_fixup_mac_addresses(ebony_mac0, ebony_mac1); -} - -#define SPRN_DBCR0 0x134 -#define DBCR0_RST_SYSTEM 0x30000000 - -static void ebony_exit(void) -{ - unsigned long tmp; - - asm volatile ( - "mfspr %0,%1\n" - "oris %0,%0,%2@h\n" - "mtspr %1,%0" - : "=&r"(tmp) : "i"(SPRN_DBCR0), "i"(DBCR0_RST_SYSTEM) - ); - -} - -void ebony_init(void *mac0, void *mac1) -{ - platform_ops.fixups = ebony_fixups; - platform_ops.exit = ebony_exit; - ebony_mac0 = mac0; - ebony_mac1 = mac1; - ft_init(_dtb_start, _dtb_end - _dtb_start, 32); - serial_console_init(); -} diff --git a/trunk/arch/powerpc/boot/holly.c b/trunk/arch/powerpc/boot/holly.c deleted file mode 100644 index 7d6539f5e22c..000000000000 --- a/trunk/arch/powerpc/boot/holly.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2007 IBM Corporation - * - * Stephen Winiecki - * Josh Boyer - * - * Based on earlier code: - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ -#include -#include -#include "types.h" -#include "elf.h" -#include "string.h" -#include "stdio.h" -#include "page.h" -#include "ops.h" -#include "io.h" - -extern char _start[]; -extern char _end[]; -extern char _dtb_start[]; -extern char _dtb_end[]; - -BSS_STACK(4096); - -void platform_init(unsigned long r3, unsigned long r4, unsigned long r5) -{ - u32 heapsize = 0x8000000 - (u32)_end; /* 128M */ - - simple_alloc_init(_end, heapsize, 32, 64); - ft_init(_dtb_start, 0, 4); - serial_console_init(); -} diff --git a/trunk/arch/powerpc/boot/mktree.c b/trunk/arch/powerpc/boot/mktree.c index 45d06a8c7cd1..4cb892993651 100644 --- a/trunk/arch/powerpc/boot/mktree.c +++ b/trunk/arch/powerpc/boot/mktree.c @@ -46,8 +46,8 @@ int main(int argc, char *argv[]) struct stat st; boot_block_t bt; - if (argc < 5) { - fprintf(stderr, "usage: %s \n",argv[0]); + if (argc < 3) { + fprintf(stderr, "usage: %s [entry-point]\n",argv[0]); exit(1); } @@ -61,8 +61,10 @@ int main(int argc, char *argv[]) bt.bb_magic = htonl(0x0052504F); /* If we have the optional entry point parameter, use it */ - bt.bb_dest = htonl(strtoul(argv[3], NULL, 0)); - bt.bb_entry_point = htonl(strtoul(argv[4], NULL, 0)); + if (argc == 4) + bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0)); + else + bt.bb_dest = bt.bb_entry_point = htonl(0x500000); /* We know these from the linker command. * ...and then move it up into memory a little more so the diff --git a/trunk/arch/powerpc/boot/treeboot-ebony.c b/trunk/arch/powerpc/boot/treeboot-ebony.c deleted file mode 100644 index 8436a9c55192..000000000000 --- a/trunk/arch/powerpc/boot/treeboot-ebony.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Old U-boot compatibility for Ebony - * - * Author: David Gibson - * - * Copyright 2007 David Gibson, IBM Corporatio. - * Based on cuboot-83xx.c, which is: - * Copyright (c) 2007 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - */ - -#include "ops.h" -#include "stdio.h" -#include "44x.h" - -extern char _end[]; - -BSS_STACK(4096); - -#define OPENBIOS_MAC_BASE 0xfffffe0c -#define OPENBIOS_MAC_OFFSET 0xc - -void platform_init(void) -{ - unsigned long end_of_ram = 0x8000000; - unsigned long avail_ram = end_of_ram - (unsigned long)_end; - - simple_alloc_init(_end, avail_ram, 32, 64); - ebony_init((u8 *)OPENBIOS_MAC_BASE, - (u8 *)(OPENBIOS_MAC_BASE + OPENBIOS_MAC_OFFSET)); -} diff --git a/trunk/arch/powerpc/boot/wrapper b/trunk/arch/powerpc/boot/wrapper index 2ed8b8b3f0ec..5cedd901201f 100755 --- a/trunk/arch/powerpc/boot/wrapper +++ b/trunk/arch/powerpc/boot/wrapper @@ -163,19 +163,20 @@ fi vmz="$vmz$gzip" -# Extract kernel version information, some platforms want to include -# it in the image header -version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \ - cut -d' ' -f3` -if [ -n "$version" ]; then - uboot_version="-n Linux-$version" -fi +case "$platform" in +uboot|cuboot*) + version=`${CROSS}strings "$kernel" | grep '^Linux version [-0-9.]' | \ + cut -d' ' -f3` + if [ -n "$version" ]; then + version="-n Linux-$version" + fi +esac case "$platform" in uboot) rm -f "$ofile" mkimage -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \ - $uboot_version -d "$vmz" "$ofile" + $version -d "$vmz" "$ofile" if [ -z "$cacheit" ]; then rm -f "$vmz" fi @@ -211,32 +212,25 @@ if [ "$platform" != "miboot" ]; then rm $tmp fi -# Some platforms need the zImage's entry point and base address -base=0x`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1` -entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | cut -d' ' -f3` - # post-processing needed for some platforms case "$platform" in pseries|chrp) $object/addnote "$ofile" ;; pmaccoff) + entry=`objdump -f "$ofile" | grep '^start address ' | \ + cut -d' ' -f3` ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" $object/hack-coff "$ofile" ;; cuboot*) + base=`${CROSS}nm "$ofile" | grep ' _start$' | cut -d' ' -f1` + entry=`${CROSS}objdump -f "$ofile" | grep '^start address ' | \ + cut -d' ' -f3` mv "$ofile" "$ofile".elf ${CROSS}objcopy -O binary "$ofile".elf "$ofile".bin gzip -f -9 "$ofile".bin mkimage -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \ - $uboot_version -d "$ofile".bin.gz "$ofile" - ;; -treeboot*) - mv "$ofile" "$ofile.elf" - $object/mktree "$ofile.elf" "$ofile" "$base" "$entry" - if [ -z "$cacheit" ]; then - rm -f "$ofile.elf" - fi - exit 0 + $version -d "$ofile".bin.gz "$ofile" ;; esac diff --git a/trunk/arch/powerpc/configs/ebony_defconfig b/trunk/arch/powerpc/configs/ebony_defconfig deleted file mode 100644 index c3b96ef3c2d1..000000000000 --- a/trunk/arch/powerpc/configs/ebony_defconfig +++ /dev/null @@ -1,905 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.21 -# Fri May 4 13:47:08 2007 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -# CONFIG_PPC_UDBG_16550 is not set -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -# CONFIG_CLASSIC32 is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_86xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -CONFIG_44x=y -# CONFIG_E200 is not set -CONFIG_PPC_DCR_NATIVE=y -# CONFIG_PPC_DCR_MMIO is not set -CONFIG_PPC_DCR=y -CONFIG_4xx=y -CONFIG_BOOKE=y -CONFIG_PTE_64BIT=y -CONFIG_PHYS_64BIT=y -CONFIG_NOT_COHERENT_CACHE=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -CONFIG_KALLSYMS_EXTRA_PASS=y -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Platform support -# -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PQ2ADS is not set -CONFIG_EBONY=y -CONFIG_440GP=y -# CONFIG_MPIC is not set -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -CONFIG_MATH_EMULATION=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -CONFIG_SECCOMP=y -CONFIG_WANT_DEVICE_TREE=y -CONFIG_DEVICE_TREE="ebony.dts" -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_PPC_INDIRECT_PCI=y -# CONFIG_PPC_INDIRECT_PCI_BE is not set -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_CONSISTENT_START=0xff100000 -CONFIG_CONSISTENT_SIZE=0x00200000 -CONFIG_BOOT_LOAD=0x01000000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=35000 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_NETLINK is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set -CONFIG_IBM_NEW_EMAC=y -CONFIG_IBM_NEW_EMAC_RXB=128 -CONFIG_IBM_NEW_EMAC_TXB=64 -CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -# CONFIG_IBM_NEW_EMAC_DEBUG is not set -CONFIG_IBM_NEW_EMAC_ZMII=y -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_NVRAM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -# CONFIG_FB is not set -# CONFIG_FB_IBM_GXT4500 is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set -# CONFIG_UCC_FAST is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -# CONFIG_DEBUGGER is not set -# CONFIG_BDI_SWITCH is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=y -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/powerpc/configs/holly_defconfig b/trunk/arch/powerpc/configs/holly_defconfig deleted file mode 100644 index be633b9b57c3..000000000000 --- a/trunk/arch/powerpc/configs/holly_defconfig +++ /dev/null @@ -1,1070 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.21 -# Sat May 5 11:02:35 2007 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_IRQ_PER_CPU=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_ARCH_HAS_ILOG2_U32=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y -CONFIG_PPC_OF=y -CONFIG_PPC_UDBG_16550=y -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_AUDIT_ARCH=y -CONFIG_GENERIC_BUG=y -# CONFIG_DEFAULT_UIMAGE is not set - -# -# Processor support -# -CONFIG_CLASSIC32=y -# CONFIG_PPC_82xx is not set -# CONFIG_PPC_83xx is not set -# CONFIG_PPC_85xx is not set -# CONFIG_PPC_86xx is not set -# CONFIG_PPC_8xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_E200 is not set -CONFIG_6xx=y -CONFIG_PPC_FPU=y -# CONFIG_PPC_DCR_NATIVE is not set -# CONFIG_PPC_DCR_MMIO is not set -# CONFIG_ALTIVEC is not set -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_SMP is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set - -# -# Block layer -# -CONFIG_BLOCK=y -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Platform support -# -# CONFIG_PPC_MULTIPLATFORM is not set -CONFIG_EMBEDDED6xx=y -# CONFIG_APUS is not set -# CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set -# CONFIG_PPC_CELL is not set -# CONFIG_PPC_CELL_NATIVE is not set -# CONFIG_PQ2ADS is not set -# CONFIG_LINKSTATION is not set -# CONFIG_MPC7448HPC2 is not set -CONFIG_PPC_HOLLY=y -CONFIG_TSI108_BRIDGE=y -CONFIG_MPIC=y -CONFIG_MPIC_WEIRD=y -# CONFIG_PPC_I8259 is not set -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_PPC_MPC106 is not set -# CONFIG_PPC_970_NAP is not set -# CONFIG_PPC_INDIRECT_IO is not set -# CONFIG_GENERIC_IOMAP is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_TAU is not set -# CONFIG_CPM2 is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SECCOMP is not set -# CONFIG_WANT_DEVICE_TREE is not set -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_ZONE_DMA=y -CONFIG_GENERIC_ISA_DMA=y -# CONFIG_PPC_INDIRECT_PCI is not set -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCIEPORTBUS is not set -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=y -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=131072 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_ESP_CORE is not set -# CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_PLATFORM is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_MACINTOSH_DRIVERS is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -CONFIG_NET_VENDOR_3COM=y -CONFIG_VORTEX=y -# CONFIG_TYPHOON is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_TSI108_ETH=y -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -CONFIG_SERIAL_8250_EXTENDED=y -# CONFIG_SERIAL_8250_MANY_PORTS is not set -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_RSA is not set - -# -# Non-8250 serial port support -# -# CONFIG_SERIAL_UARTLITE is not set -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -# CONFIG_FB is not set -# CONFIG_FB_IBM_GXT4500 is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set -# CONFIG_UCC_FAST is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y - -# -# Instrumentation Support -# -# CONFIG_PROFILING is not set -# CONFIG_KPROBES is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set -CONFIG_DEBUGGER=y -CONFIG_XMON=y -CONFIG_XMON_DEFAULT=y -CONFIG_XMON_DISASSEMBLY=y -# CONFIG_BDI_SWITCH is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_PPC_EARLY_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set diff --git a/trunk/arch/powerpc/configs/mpc832x_mds_defconfig b/trunk/arch/powerpc/configs/mpc832x_mds_defconfig index 83192c0dc5bb..e1b36de6b38c 100644 --- a/trunk/arch/powerpc/configs/mpc832x_mds_defconfig +++ b/trunk/arch/powerpc/configs/mpc832x_mds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc5 -# Mon Apr 9 16:09:16 2007 +# Linux kernel version: 2.6.20-rc5 +# Tue Jan 30 14:27:25 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -34,9 +34,9 @@ CONFIG_DEFAULT_UIMAGE=y CONFIG_PPC_83xx=y # CONFIG_PPC_85xx is not set # CONFIG_PPC_86xx is not set -# CONFIG_PPC_8xx is not set # CONFIG_40x is not set # CONFIG_44x is not set +# CONFIG_8xx is not set # CONFIG_E200 is not set CONFIG_6xx=y CONFIG_83xx=y @@ -63,7 +63,6 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set @@ -72,7 +71,6 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_IKCONFIG is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -125,17 +123,16 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_QUICC_ENGINE=y +CONFIG_PPC_GEN550=y # CONFIG_WANT_EARLY_SERIAL is not set # # Platform support # -# CONFIG_MPC8313_RDB is not set CONFIG_MPC832x_MDS=y -# CONFIG_MPC832x_RDB is not set -# CONFIG_MPC834x_MDS is not set +# CONFIG_MPC834x_SYS is not set # CONFIG_MPC834x_ITX is not set -# CONFIG_MPC836x_MDS is not set +# CONFIG_MPC8360E_PB is not set CONFIG_PPC_MPC832x=y # CONFIG_MPIC is not set @@ -166,7 +163,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=1 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set # CONFIG_PM is not set @@ -176,7 +172,6 @@ CONFIG_ISA_DMA_API=y # # Bus options # -CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -225,7 +220,6 @@ CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -330,7 +324,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # -# CONFIG_PNPACPI is not set # # Block devices @@ -349,6 +342,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -488,21 +482,7 @@ CONFIG_NETDEVICES=y # # PHY device support # -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -CONFIG_DAVICOM_PHY=y -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_FIXED_PHY is not set +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) @@ -544,13 +524,11 @@ CONFIG_UCC_GETH=y # CONFIG_UGETH_FILTERING is not set # CONFIG_UGETH_TX_ON_DEMOND is not set # CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set # # Ethernet (10000 Mbit) # # CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set @@ -643,7 +621,6 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -714,7 +691,6 @@ CONFIG_I2C_MPC=y # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PASEMI is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set # CONFIG_I2C_SIS5595 is not set @@ -762,7 +738,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set @@ -803,11 +778,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - # # Multimedia devices # @@ -821,9 +791,10 @@ CONFIG_HWMON=y # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -834,7 +805,6 @@ CONFIG_HWMON=y # HID Devices # CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # # USB support @@ -898,10 +868,6 @@ CONFIG_USB_ARCH_HAS_EHCI=y # DMA Devices # -# -# Auxiliary Display support -# - # # Virtualization # @@ -1029,7 +995,11 @@ CONFIG_PARTITION_ADVANCED=y # Distributed Lock Manager # # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set + +# +# QE Options +# +CONFIG_UCC_SLOW=y CONFIG_UCC_FAST=y CONFIG_UCC=y @@ -1042,8 +1012,7 @@ CONFIG_BITREVERSE=y CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y +CONFIG_IOMAP_COPY=y # # Instrumentation Support @@ -1063,6 +1032,7 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set # CONFIG_PPC_EARLY_DEBUG is not set # @@ -1091,10 +1061,8 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_GF128MUL is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1108,7 +1076,6 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # diff --git a/trunk/arch/powerpc/configs/mpc832x_rdb_defconfig b/trunk/arch/powerpc/configs/mpc832x_rdb_defconfig index 4a4da875fa4e..56fc0a824458 100644 --- a/trunk/arch/powerpc/configs/mpc832x_rdb_defconfig +++ b/trunk/arch/powerpc/configs/mpc832x_rdb_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc5 -# Mon Apr 9 16:12:43 2007 +# Linux kernel version: 2.6.21-rc3 +# Mon Mar 12 17:32:19 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -125,6 +125,7 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_QUICC_ENGINE=y +CONFIG_PPC_GEN550=y # CONFIG_WANT_EARLY_SERIAL is not set # @@ -489,21 +490,7 @@ CONFIG_NETDEVICES=y # # PHY device support # -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -CONFIG_ICPLUS_PHY=y -# CONFIG_FIXED_PHY is not set +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) @@ -1213,7 +1200,11 @@ CONFIG_NLS_ISO8859_1=y # Distributed Lock Manager # # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set + +# +# QE Options +# +CONFIG_UCC_SLOW=y CONFIG_UCC_FAST=y CONFIG_UCC=y @@ -1247,6 +1238,7 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set # CONFIG_PPC_EARLY_DEBUG is not set # diff --git a/trunk/arch/powerpc/configs/mpc836x_mds_defconfig b/trunk/arch/powerpc/configs/mpc836x_mds_defconfig index 921a151dc778..8eb475cd0df0 100644 --- a/trunk/arch/powerpc/configs/mpc836x_mds_defconfig +++ b/trunk/arch/powerpc/configs/mpc836x_mds_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc5 -# Mon Apr 9 16:14:05 2007 +# Linux kernel version: 2.6.20 +# Sat Feb 17 10:09:26 2007 # # CONFIG_PPC64 is not set CONFIG_PPC32=y @@ -72,7 +72,6 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_IKCONFIG is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -125,6 +124,7 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_QUICC_ENGINE=y +CONFIG_PPC_GEN550=y # CONFIG_WANT_EARLY_SERIAL is not set # @@ -132,7 +132,6 @@ CONFIG_QUICC_ENGINE=y # # CONFIG_MPC8313_RDB is not set # CONFIG_MPC832x_MDS is not set -# CONFIG_MPC832x_RDB is not set # CONFIG_MPC834x_MDS is not set # CONFIG_MPC834x_ITX is not set CONFIG_MPC836x_MDS=y @@ -329,7 +328,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # -# CONFIG_PNPACPI is not set # # Block devices @@ -348,6 +346,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -487,21 +486,7 @@ CONFIG_NETDEVICES=y # # PHY device support # -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=y -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -# CONFIG_SMSC_PHY is not set -# CONFIG_BROADCOM_PHY is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_FIXED_PHY is not set +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) @@ -543,7 +528,6 @@ CONFIG_UCC_GETH=y # CONFIG_UGETH_FILTERING is not set # CONFIG_UGETH_TX_ON_DEMOND is not set # CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set # # Ethernet (10000 Mbit) @@ -761,7 +745,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set @@ -802,11 +785,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - # # Multimedia devices # @@ -820,9 +798,10 @@ CONFIG_HWMON=y # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -1028,7 +1007,11 @@ CONFIG_PARTITION_ADVANCED=y # Distributed Lock Manager # # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set + +# +# QE Options +# +CONFIG_UCC_SLOW=y CONFIG_UCC_FAST=y CONFIG_UCC=y @@ -1062,6 +1045,7 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_BOOTX_TEXT is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set # CONFIG_PPC_EARLY_DEBUG is not set # diff --git a/trunk/arch/powerpc/configs/ps3_defconfig b/trunk/arch/powerpc/configs/ps3_defconfig index fd604968f9a2..0345a2ceec59 100644 --- a/trunk/arch/powerpc/configs/ps3_defconfig +++ b/trunk/arch/powerpc/configs/ps3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21 -# Mon Apr 30 12:03:35 2007 +# Linux kernel version: 2.6.20-rc6 +# Thu Jan 25 13:35:34 2007 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -60,7 +60,6 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set @@ -70,7 +69,6 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_CPUSETS is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y @@ -133,36 +131,13 @@ CONFIG_PPC_MULTIPLATFORM=y # CONFIG_PPC_PSERIES is not set # CONFIG_PPC_ISERIES is not set # CONFIG_PPC_MPC52xx is not set -# CONFIG_PPC_MPC5200 is not set # CONFIG_PPC_PMAC is not set # CONFIG_PPC_MAPLE is not set # CONFIG_PPC_PASEMI is not set -# CONFIG_PPC_CELLEB is not set -CONFIG_PPC_PS3=y - -# -# PS3 Platform Options -# -# CONFIG_PS3_ADVANCED is not set -CONFIG_PS3_HTAB_SIZE=20 -# CONFIG_PS3_DYNAMIC_DMA is not set -CONFIG_PS3_USE_LPAR_ADDR=y -CONFIG_PS3_VUART=y -CONFIG_PS3_PS3AV=y -CONFIG_PS3_SYS_MANAGER=y CONFIG_PPC_CELL=y # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_IBM_CELL_BLADE is not set - -# -# Cell Broadband Engine options -# -CONFIG_SPU_FS=y -CONFIG_SPU_BASE=y -# CONFIG_PQ2ADS is not set -# CONFIG_MPIC is not set -# CONFIG_MPIC_WEIRD is not set -# CONFIG_PPC_I8259 is not set +CONFIG_PPC_PS3=y # CONFIG_U3_DART is not set # CONFIG_PPC_RTAS is not set # CONFIG_MMIO_NVRAM is not set @@ -171,7 +146,24 @@ CONFIG_SPU_BASE=y # CONFIG_PPC_INDIRECT_IO is not set # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set -# CONFIG_CPM2 is not set +# CONFIG_WANT_EARLY_SERIAL is not set +# CONFIG_MPIC is not set + +# +# Cell Broadband Engine options +# +CONFIG_SPU_FS=y +CONFIG_SPU_BASE=y +# CONFIG_CBE_RAS is not set + +# +# PS3 Platform Options +# +CONFIG_PS3_HTAB_SIZE=20 +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_USE_LPAR_ADDR=y +CONFIG_PS3_VUART=y +CONFIG_PS3_PS3AV=y # # Kernel options @@ -187,10 +179,10 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_BKL is not set CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=y -CONFIG_FORCE_MAX_ZONEORDER=13 +CONFIG_FORCE_MAX_ZONEORDER=9 # CONFIG_IOMMU_VMERGE is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_KEXEC=y +# CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set # CONFIG_IRQ_ALL_CPUS is not set # CONFIG_NUMA is not set @@ -211,22 +203,22 @@ CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y -CONFIG_ZONE_DMA_FLAG=1 CONFIG_ARCH_MEMORY_PROBE=y -# CONFIG_PPC_64K_PAGES is not set +CONFIG_PPC_64K_PAGES=y # CONFIG_SCHED_SMT is not set CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="root=/dev/sda1 ip=dhcp" # CONFIG_PM is not set # CONFIG_SECCOMP is not set -# CONFIG_WANT_DEVICE_TREE is not set CONFIG_ISA_DMA_API=y # # Bus options # -CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set # CONFIG_PCI is not set # CONFIG_PCI_DOMAINS is not set @@ -248,13 +240,10 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -272,7 +261,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set -CONFIG_INET_TUNNEL=y +# CONFIG_INET_TUNNEL is not set # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set @@ -281,23 +270,9 @@ CONFIG_INET_TUNNEL=y CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -CONFIG_INET6_XFRM_MODE_BEET=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -CONFIG_IPV6_SIT=y -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -338,31 +313,7 @@ CONFIG_IPV6_SIT=y # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set -CONFIG_BT=m -CONFIG_BT_L2CAP=m -CONFIG_BT_SCO=m -CONFIG_BT_RFCOMM=m -# CONFIG_BT_RFCOMM_TTY is not set -# CONFIG_BT_BNEP is not set -CONFIG_BT_HIDP=m - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y -# CONFIG_BT_HCIUART is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIVHCI is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -CONFIG_WIRELESS_EXT=y +# CONFIG_BT is not set # CONFIG_IEEE80211 is not set # @@ -376,13 +327,16 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set # @@ -393,27 +347,24 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # # Plug and Play support # -# CONFIG_PNPACPI is not set # # Block devices # # CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=65535 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # # Misc devices # +# CONFIG_TIFM_CORE is not set # # ATA/ATAPI/MFM/RLL support @@ -437,7 +388,7 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y # CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=m +# CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set # @@ -462,7 +413,6 @@ CONFIG_CHR_DEV_SG=m # # CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_ESP_CORE is not set # # Serial ATA (prod) and Parallel ATA (experimental) drivers @@ -510,7 +460,7 @@ CONFIG_NETDEVICES=y # Ethernet (10 or 100Mbit) # # CONFIG_NET_ETHERNET is not set -CONFIG_MII=m +CONFIG_MII=y # # Ethernet (1000 Mbit) @@ -525,10 +475,9 @@ CONFIG_MII=m # # -# Wireless LAN +# Wireless LAN (non-hamradio) # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_NET_RADIO is not set # # Wan interfaces @@ -602,8 +551,7 @@ CONFIG_HW_CONSOLE=y # Non-8250 serial port support # CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_LEGACY_PTYS is not set # # IPMI @@ -649,11 +597,6 @@ CONFIG_GEN_RTC=y # CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - # # Multimedia devices # @@ -668,22 +611,15 @@ CONFIG_GEN_RTC=y # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set +CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -# CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set - -# -# Frame buffer hardware drivers -# # CONFIG_FB_OF is not set # CONFIG_FB_VGA16 is not set # CONFIG_FB_S1D13XXX is not set @@ -698,7 +634,7 @@ CONFIG_FB_PS3_DEFAULT_SIZE_M=18 # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y @@ -710,62 +646,17 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound # -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=y -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_PCM_OSS is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# ALSA PowerMac devices -# - -# -# ALSA PowerMac requires I2C -# - -# -# USB devices -# -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set - -# -# SoC audio support -# -# CONFIG_SND_SOC is not set - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set +# CONFIG_SOUND is not set # # HID Devices # CONFIG_HID=y -# CONFIG_HID_DEBUG is not set # # USB support @@ -774,13 +665,13 @@ CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y -# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEBUG=y # # Miscellaneous USB options # -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DEVICE_CLASS is not set +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set @@ -813,7 +704,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # # may also be needed; see USB_STORAGE Help for more information # -CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set @@ -829,16 +720,10 @@ CONFIG_USB_STORAGE=m # # USB Input Devices # -CONFIG_USB_HID=m +CONFIG_USB_HID=y # CONFIG_USB_HIDINPUT_POWERBOOK is not set # CONFIG_HID_FF is not set # CONFIG_USB_HIDDEV is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set @@ -851,7 +736,6 @@ CONFIG_USB_HID=m # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set # # USB Imaging devices @@ -864,16 +748,15 @@ CONFIG_USB_HID=m # # CONFIG_USB_CATC is not set # CONFIG_USB_KAWETH is not set -CONFIG_USB_PEGASUS=m +# CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set -CONFIG_USB_USBNET_MII=m -CONFIG_USB_USBNET=m -# CONFIG_USB_NET_CDCETHER is not set -# CONFIG_USB_NET_DM9601 is not set +CONFIG_USB_USBNET_MII=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_CDCETHER=y # CONFIG_USB_NET_GL620A is not set # CONFIG_USB_NET_NET1080 is not set # CONFIG_USB_NET_PLUSB is not set -CONFIG_USB_NET_MCS7830=m +CONFIG_USB_NET_MCS7830=y # CONFIG_USB_NET_RNDIS_HOST is not set # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set @@ -898,7 +781,6 @@ CONFIG_USB_MON=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -909,8 +791,6 @@ CONFIG_USB_MON=y # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_TEST is not set # # USB DSL modem support @@ -965,10 +845,6 @@ CONFIG_USB_MON=y # DMA Devices # -# -# Auxiliary Display support -# - # # Virtualization # @@ -976,9 +852,7 @@ CONFIG_USB_MON=y # # File systems # -CONFIG_EXT2_FS=m -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT2_FS is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -997,30 +871,27 @@ CONFIG_FS_MBCACHE=y # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y -CONFIG_QUOTA=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -CONFIG_QUOTACTL=y +# CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems # -CONFIG_ISO9660_FS=m +CONFIG_ISO9660_FS=y CONFIG_JOLIET=y # CONFIG_ZISOFS is not set -CONFIG_UDF_FS=m +CONFIG_UDF_FS=y CONFIG_UDF_NLS=y # # DOS/FAT/NT Filesystems # -CONFIG_FAT_FS=m +CONFIG_FAT_FS=y # CONFIG_MSDOS_FS is not set -CONFIG_VFAT_FS=m +CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set @@ -1062,7 +933,7 @@ CONFIG_RAMFS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y +# CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y @@ -1070,16 +941,10 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1139,8 +1004,6 @@ CONFIG_NLS_ISO8859_1=y # Distributed Lock Manager # # CONFIG_DLM is not set -# CONFIG_UCC_SLOW is not set -# CONFIG_UCC_FAST is not set # # Library routines @@ -1151,8 +1014,7 @@ CONFIG_BITREVERSE=y CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y +CONFIG_IOMAP_COPY=y # # Instrumentation Support @@ -1170,16 +1032,16 @@ CONFIG_ENABLE_MUST_CHECK=y # CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set CONFIG_LOG_BUF_SHIFT=17 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_SLAB is not set +CONFIG_DEBUG_SLAB=y +# CONFIG_DEBUG_SLAB_LEAK is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_RWSEMS=y CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1189,10 +1051,8 @@ CONFIG_DEBUG_INFO=y CONFIG_DEBUG_LIST=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUGGER is not set CONFIG_IRQSTACKS=y # CONFIG_BOOTX_TEXT is not set @@ -1203,8 +1063,6 @@ CONFIG_PPC_EARLY_DEBUG=y # CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set # CONFIG_PPC_EARLY_DEBUG_MAPLE is not set # CONFIG_PPC_EARLY_DEBUG_ISERIES is not set -# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set -# CONFIG_PPC_EARLY_DEBUG_BEAT is not set # # Security options @@ -1215,43 +1073,4 @@ CONFIG_PPC_EARLY_DEBUG=y # # Cryptographic options # -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_MANAGER=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# +# CONFIG_CRYPTO is not set diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 3e779f07f21b..e0fa80eca366 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -36,9 +36,7 @@ obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o -obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o suspend.o obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o -obj64-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_64.o swsusp_asm64.o obj32-$(CONFIG_MODULES) += module_32.o ifeq ($(CONFIG_PPC_MERGE),y) @@ -68,7 +66,6 @@ obj-$(CONFIG_MODULES) += $(module-y) pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci32-$(CONFIG_PPC32) := pci_32.o obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) -obj-$(CONFIG_PCI_MSI) += msi.o kexec-$(CONFIG_PPC64) := machine_kexec_64.o kexec-$(CONFIG_PPC32) := machine_kexec_32.o obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y) diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 8f48560b7ee2..0c5150c69175 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -21,12 +21,12 @@ #include #include #include -#include #ifdef CONFIG_PPC64 #include #include #else #include +#include #endif #include @@ -257,11 +257,11 @@ int main(void) DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); +#ifndef CONFIG_PPC64 DEFINE(pbe_address, offsetof(struct pbe, address)); DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address)); DEFINE(pbe_next, offsetof(struct pbe, next)); -#ifndef CONFIG_PPC64 DEFINE(TASK_SIZE, TASK_SIZE); DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28); #endif /* ! CONFIG_PPC64 */ diff --git a/trunk/arch/powerpc/kernel/head_44x.S b/trunk/arch/powerpc/kernel/head_44x.S index 88695963f587..a15d4b8cce48 100644 --- a/trunk/arch/powerpc/kernel/head_44x.S +++ b/trunk/arch/powerpc/kernel/head_44x.S @@ -120,8 +120,8 @@ skpinv: addi r4,r4,1 /* Increment */ * Configure and load pinned entry into TLB slot 63. */ - lis r3,PAGE_OFFSET@h - ori r3,r3,PAGE_OFFSET@l + lis r3,KERNELBASE@h /* Load the kernel virtual address */ + ori r3,r3,KERNELBASE@l /* Kernel is at the base of RAM */ li r4, 0 /* Load the kernel physical address */ @@ -172,28 +172,36 @@ skpinv: addi r4,r4,1 /* Increment */ isync 4: -#ifdef CONFIG_PPC_EARLY_DEBUG_44x - /* Add UART mapping for early debug. */ - +#ifdef CONFIG_SERIAL_TEXT_DEBUG + /* + * Add temporary UART mapping for early debug. + * We can map UART registers wherever we want as long as they don't + * interfere with other system mappings (e.g. with pinned entries). + * For an example of how we handle this - see ocotea.h. --ebs + */ /* pageid fields */ - lis r3,PPC44x_EARLY_DEBUG_VIRTADDR@h - ori r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K + lis r3,UART0_IO_BASE@h + ori r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_4K /* xlat fields */ - lis r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h - ori r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH + lis r4,UART0_PHYS_IO_BASE@h /* RPN depends on SoC */ +#ifndef CONFIG_440EP + ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */ +#endif /* attrib fields */ - li r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G) - li r0,62 /* TLB slot 0 */ + li r5,0 + ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) - tlbwe r3,r0,PPC44x_TLB_PAGEID - tlbwe r4,r0,PPC44x_TLB_XLAT - tlbwe r5,r0,PPC44x_TLB_ATTRIB + li r0,0 /* TLB slot 0 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ /* Force context change */ isync -#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ /* Establish the interrupt vector offsets */ SET_IVOR(0, CriticalInput); @@ -701,6 +709,16 @@ _GLOBAL(giveup_fpu) blr #endif +/* + * extern void abort(void) + * + * At present, this routine just applies a system reset. + */ +_GLOBAL(abort) + mfspr r13,SPRN_DBCR0 + oris r13,r13,DBCR0_RST_SYSTEM@h + mtspr SPRN_DBCR0,r13 + _GLOBAL(set_context) #ifdef CONFIG_BDI_SWITCH diff --git a/trunk/arch/powerpc/kernel/idle.c b/trunk/arch/powerpc/kernel/idle.c index a9e9cbd32975..6e7f50967bab 100644 --- a/trunk/arch/powerpc/kernel/idle.c +++ b/trunk/arch/powerpc/kernel/idle.c @@ -33,11 +33,8 @@ #include #ifdef CONFIG_HOTPLUG_CPU -/* this is used for software suspend, and that shuts down - * CPUs even while the system is still booting... */ #define cpu_should_die() (cpu_is_offline(smp_processor_id()) && \ - (system_state == SYSTEM_RUNNING \ - || system_state == SYSTEM_BOOTING)) + system_state == SYSTEM_RUNNING) #else #define cpu_should_die() 0 #endif diff --git a/trunk/arch/powerpc/kernel/idle_power4.S b/trunk/arch/powerpc/kernel/idle_power4.S index 5328709eeedc..ba3195478600 100644 --- a/trunk/arch/powerpc/kernel/idle_power4.S +++ b/trunk/arch/powerpc/kernel/idle_power4.S @@ -53,24 +53,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) isync b 1b -_GLOBAL(power4_cpu_offline_powersave) - /* Go to NAP now */ - mfmsr r7 - rldicl r0,r7,48,1 - rotldi r0,r0,16 - mtmsrd r0,1 /* hard-disable interrupts */ - li r0,1 - li r6,0 - stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */ - stb r6,PACASOFTIRQEN(r13) /* soft-disable irqs */ -BEGIN_FTR_SECTION - DSSALL - sync -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - ori r7,r7,MSR_EE - oris r7,r7,MSR_POW@h - sync - isync - mtmsrd r7 - isync - blr diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 9ed4931af164..6c83fe229e60 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -67,7 +67,6 @@ #ifdef CONFIG_PPC64 #include #include -#include #endif int __irq_offset_value; @@ -163,16 +162,6 @@ void local_irq_restore(unsigned long en) local_paca->hard_enabled = en; if ((int)mfspr(SPRN_DEC) < 0) mtspr(SPRN_DEC, 1); - - /* - * Force the delivery of pending soft-disabled interrupts on PS3. - * Any HV call will have this side effect. - */ - if (firmware_has_feature(FW_FEATURE_PS3_LV1)) { - u64 tmp; - lv1_get_version_info(&tmp); - } - hard_irq_enable(); } #endif /* CONFIG_PPC64 */ @@ -958,6 +947,33 @@ arch_initcall(irq_late_init); #endif /* CONFIG_PPC_MERGE */ +#ifdef CONFIG_PCI_MSI +int pci_enable_msi(struct pci_dev * pdev) +{ + if (ppc_md.enable_msi) + return ppc_md.enable_msi(pdev); + else + return -1; +} +EXPORT_SYMBOL(pci_enable_msi); + +void pci_disable_msi(struct pci_dev * pdev) +{ + if (ppc_md.disable_msi) + ppc_md.disable_msi(pdev); +} +EXPORT_SYMBOL(pci_disable_msi); + +void pci_scan_msi_device(struct pci_dev *dev) {} +int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;} +void pci_disable_msix(struct pci_dev *dev) {} +void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} +void pci_no_msi(void) {} +EXPORT_SYMBOL(pci_enable_msix); +EXPORT_SYMBOL(pci_disable_msix); + +#endif + #ifdef CONFIG_PPC64 static int __init setup_noirqdistrib(char *str) { diff --git a/trunk/arch/powerpc/kernel/kprobes.c b/trunk/arch/powerpc/kernel/kprobes.c index 0c96611f02f4..ef647e7a9dc3 100644 --- a/trunk/arch/powerpc/kernel/kprobes.c +++ b/trunk/arch/powerpc/kernel/kprobes.c @@ -30,8 +30,8 @@ #include #include #include -#include #include +#include #include #include @@ -126,13 +126,22 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, } /* Called with kretprobe_lock held */ -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, +void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { - ri->ret_addr = (kprobe_opcode_t *)regs->link; - - /* Replace the return addr with trampoline addr */ - regs->link = (unsigned long)kretprobe_trampoline; + struct kretprobe_instance *ri; + + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *)regs->link; + + /* Replace the return addr with trampoline addr */ + regs->link = (unsigned long)kretprobe_trampoline; + add_rp_inst(ri); + } else { + rp->nmissed++; + } } static int __kprobes kprobe_handler(struct pt_regs *regs) @@ -327,7 +336,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) break; } - kretprobe_assert(ri, orig_ret_address, trampoline_address); + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); regs->nip = orig_ret_address; reset_current_kprobe(); @@ -401,7 +410,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) return 1; } -int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) +static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -486,6 +495,14 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, if (post_kprobe_handler(args->regs)) ret = NOTIFY_STOP; break; + case DIE_PAGE_FAULT: + /* kprobe_running() needs smp_processor_id() */ + preempt_disable(); + if (kprobe_running() && + kprobe_fault_handler(args->regs, args->trapnr)) + ret = NOTIFY_STOP; + preempt_enable(); + break; default: break; } @@ -542,11 +559,3 @@ int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } - -int __kprobes arch_trampoline_kprobe(struct kprobe *p) -{ - if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline) - return 1; - - return 0; -} diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c index cea8045ba40b..63dd2c3ad95e 100644 --- a/trunk/arch/powerpc/kernel/legacy_serial.c +++ b/trunk/arch/powerpc/kernel/legacy_serial.c @@ -115,8 +115,7 @@ static int __init add_legacy_soc_port(struct device_node *np, { u64 addr; const u32 *addrp; - upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ - | UPF_FIXED_PORT; + upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; struct device_node *tsi = of_get_parent(np); /* We only support ports that have a clock frequency properly @@ -244,9 +243,9 @@ static int __init add_legacy_pci_port(struct device_node *np, * doesn't work for these settings, you'll have to add your own special * cases here */ - if (of_device_is_compatible(pci_dev, "pci13a8,152") || - of_device_is_compatible(pci_dev, "pci13a8,154") || - of_device_is_compatible(pci_dev, "pci13a8,158")) { + if (device_is_compatible(pci_dev, "pci13a8,152") || + device_is_compatible(pci_dev, "pci13a8,154") || + device_is_compatible(pci_dev, "pci13a8,158")) { addr += 0x200 * lindex; base += 0x200 * lindex; } else { @@ -365,11 +364,11 @@ void __init find_legacy_serial_ports(void) /* Check for known pciclass, and also check wether we have * a device with child nodes for ports or not */ - if (of_device_is_compatible(np, "pciclass,0700") || - of_device_is_compatible(np, "pciclass,070002")) + if (device_is_compatible(np, "pciclass,0700") || + device_is_compatible(np, "pciclass,070002")) pci = np; - else if (of_device_is_compatible(parent, "pciclass,0700") || - of_device_is_compatible(parent, "pciclass,070002")) + else if (device_is_compatible(parent, "pciclass,0700") || + device_is_compatible(parent, "pciclass,070002")) pci = parent; else { of_node_put(parent); diff --git a/trunk/arch/powerpc/kernel/msi.c b/trunk/arch/powerpc/kernel/msi.c deleted file mode 100644 index c62d1012c013..000000000000 --- a/trunk/arch/powerpc/kernel/msi.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2006-2007, Michael Ellerman, IBM Corporation. - * - * 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 - -int arch_msi_check_device(struct pci_dev* dev, int nvec, int type) -{ - if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) { - pr_debug("msi: Platform doesn't provide MSI callbacks.\n"); - return -ENOSYS; - } - - if (ppc_md.msi_check_device) { - pr_debug("msi: Using platform check routine.\n"); - return ppc_md.msi_check_device(dev, nvec, type); - } - - return 0; -} - -int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) -{ - return ppc_md.setup_msi_irqs(dev, nvec, type); -} - -void arch_teardown_msi_irqs(struct pci_dev *dev) -{ - return ppc_md.teardown_msi_irqs(dev); -} diff --git a/trunk/arch/powerpc/kernel/of_device.c b/trunk/arch/powerpc/kernel/of_device.c index a464d67248df..0c8ea7659d92 100644 --- a/trunk/arch/powerpc/kernel/of_device.c +++ b/trunk/arch/powerpc/kernel/of_device.c @@ -27,7 +27,7 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches, match &= node->type && !strcmp(matches->type, node->type); if (matches->compatible[0]) - match &= of_device_is_compatible(node, + match &= device_is_compatible(node, matches->compatible); if (match) return matches; @@ -120,8 +120,8 @@ void of_device_unregister(struct of_device *ofdev) } -ssize_t of_device_get_modalias(struct of_device *ofdev, - char *str, ssize_t len) +static ssize_t of_device_get_modalias(struct of_device *ofdev, + char *str, ssize_t len) { const char *compat; int cplen, i; @@ -239,4 +239,3 @@ EXPORT_SYMBOL(of_dev_get); EXPORT_SYMBOL(of_dev_put); EXPORT_SYMBOL(of_release_dev); EXPORT_SYMBOL(of_device_uevent); -EXPORT_SYMBOL(of_device_get_modalias); diff --git a/trunk/arch/powerpc/kernel/of_platform.c b/trunk/arch/powerpc/kernel/of_platform.c index 84c34d979a88..908ed7926db4 100644 --- a/trunk/arch/powerpc/kernel/of_platform.c +++ b/trunk/arch/powerpc/kernel/of_platform.c @@ -29,6 +29,7 @@ #include #include + /* * The list of OF IDs below is used for matching bus types in the * system whose devices are to be exposed as of_platform_devices. diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index e66064b5093a..f022862de344 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -1658,7 +1658,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, int i; if (page_is_ram(pfn)) - return __pgprot(prot); + return prot; prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 6d05a1f377b5..60d7d4baa227 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -340,7 +340,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, struct pci_dev *dev; const char *type; - dev = alloc_pci_dev(); + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) return NULL; type = of_get_property(node, "device_type", NULL); @@ -1006,9 +1006,8 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, switch ((pci_space >> 24) & 0x3) { case 1: /* I/O space */ - hose->io_base_phys = cpu_phys_addr - pci_addr; - /* handle from 0 to top of I/O window */ - hose->pci_io_size = pci_addr + size; + hose->io_base_phys = cpu_phys_addr; + hose->pci_io_size = size; res = &hose->io_resource; res->flags = IORESOURCE_IO; @@ -1118,8 +1117,8 @@ static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys, } else { /* Root Bus */ res = &hose->io_resource; - *start_phys = hose->io_base_phys + res->start; - *start_virt = (unsigned long) hose->io_base_virt + res->start; + *start_phys = hose->io_base_phys; + *start_virt = (unsigned long) hose->io_base_virt; if (res->end > res->start) *size = res->end - res->start + 1; else { diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c index c96fa9bd35a4..ff252aaead12 100644 --- a/trunk/arch/powerpc/kernel/ppc_ksyms.c +++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c @@ -66,6 +66,7 @@ EXPORT_SYMBOL(clear_pages); EXPORT_SYMBOL(ISA_DMA_THRESHOLD); EXPORT_SYMBOL(DMA_MODE_READ); EXPORT_SYMBOL(DMA_MODE_WRITE); +EXPORT_SYMBOL(__div64_32); EXPORT_SYMBOL(do_signal); EXPORT_SYMBOL(transfer_to_handler); diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 6e2f03566b0d..e509aae2feb3 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index d6047c441034..e27d9d1b6e67 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -635,12 +635,6 @@ static void __init early_cmdline_parse(void) /* ibm,dynamic-reconfiguration-memory property supported */ #define OV5_DRCONF_MEMORY 0x20 #define OV5_LARGE_PAGES 0x10 /* large pages supported */ -/* PCIe/MSI support. Without MSI full PCIe is not supported */ -#ifdef CONFIG_PCI_MSI -#define OV5_MSI 0x01 /* PCIe/MSI support */ -#else -#define OV5_MSI 0x00 -#endif /* CONFIG_PCI_MSI */ /* * The architecture vector has an array of PVR mask/value pairs, @@ -685,7 +679,7 @@ static unsigned char ibm_architecture_vec[] = { /* option vector 5: PAPR/OF options */ 3 - 2, /* length */ 0, /* don't ignore, don't halt */ - OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY | OV5_MSI, + OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY, }; /* Old method - ELF header with PT_NOTE sections */ @@ -973,7 +967,7 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp) * If problems seem to show up, it would be a good start to track * them down. */ -static void __init reserve_mem(u64 base, u64 size) +static void reserve_mem(u64 base, u64 size) { u64 top = base + size; unsigned long cnt = RELOC(mem_reserve_cnt); @@ -2159,7 +2153,7 @@ static void __init fixup_device_tree_efika(void) 3,12,0, 3,13,0, 3,14,0, 3,15,0 }; struct subst_entry efika_subst_table[] = { { "/", "device_type", prop_cstr("efika") }, - { "/builtin", "device_type", prop_cstr("soc") }, + { "/builtin", "compatible", prop_cstr("soc") }, { "/builtin/ata", "compatible", prop_cstr("mpc5200b-ata\0mpc5200-ata"), }, { "/builtin/bestcomm", "compatible", prop_cstr("mpc5200b-bestcomm\0mpc5200-bestcomm") }, { "/builtin/bestcomm", "interrupts", prop_bcomm_irq, sizeof(prop_bcomm_irq) }, diff --git a/trunk/arch/powerpc/kernel/prom_parse.c b/trunk/arch/powerpc/kernel/prom_parse.c index b5c96af955c6..aa40a5307294 100644 --- a/trunk/arch/powerpc/kernel/prom_parse.c +++ b/trunk/arch/powerpc/kernel/prom_parse.c @@ -1042,28 +1042,3 @@ const void *of_get_mac_address(struct device_node *np) } EXPORT_SYMBOL(of_get_mac_address); -int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) -{ - int irq = irq_of_parse_and_map(dev, index); - - /* Only dereference the resource if both the - * resource and the irq are valid. */ - if (r && irq != NO_IRQ) { - r->start = r->end = irq; - r->flags = IORESOURCE_IRQ; - } - - return irq; -} -EXPORT_SYMBOL_GPL(of_irq_to_resource); - -void __iomem *of_iomap(struct device_node *np, int index) -{ - struct resource res; - - if (of_address_to_resource(np, index, &res)) - return NULL; - - return ioremap(res.start, 1 + res.end - res.start); -} -EXPORT_SYMBOL(of_iomap); diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c index f4f391cdd8f5..cc44c7b975aa 100644 --- a/trunk/arch/powerpc/kernel/ptrace.c +++ b/trunk/arch/powerpc/kernel/ptrace.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 6018178708a5..22083ce3cc30 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -582,14 +582,14 @@ void __init setup_per_cpu_areas(void) char *ptr; /* Copy section for each CPU (we discard the original) */ - size = ALIGN(__per_cpu_end - __per_cpu_start, PAGE_SIZE); + size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); #ifdef CONFIG_MODULES if (size < PERCPU_ENOUGH_ROOM) size = PERCPU_ENOUGH_ROOM; #endif for_each_possible_cpu(i) { - ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); + ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size); if (!ptr) panic("Cannot allocate cpu data for CPU %d\n", i); diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index dd1dca5bfa81..6b405a3f43f9 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index 1ce0ae3f6ffc..f72e8e823d78 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index 22f1ef1b3100..d8e503b2e1af 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -176,10 +176,10 @@ static struct call_data_struct { #define SMP_CALL_TIMEOUT 8 /* - * These functions send a 'generic call function' IPI to other online - * CPUS in the system. + * This function sends a 'generic call function' IPI to all other CPUs + * in the system. * - * [SUMMARY] Run a function on other CPUs. + * [SUMMARY] Run a function on all other CPUs. * The function to run. This must be fast and non-blocking. * An arbitrary pointer to pass to the function. * currently unused. @@ -190,26 +190,18 @@ static struct call_data_struct { * You must not call this function with disabled interrupts or from a * hardware interrupt handler or from a bottom half handler. */ -int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, - int wait, cpumask_t map) -{ +int smp_call_function (void (*func) (void *info), void *info, int nonatomic, + int wait) +{ struct call_data_struct data; - int ret = -1, num_cpus; - int cpu; + int ret = -1, cpus; u64 timeout; /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); - /* remove 'self' from the map */ - if (cpu_isset(smp_processor_id(), map)) - cpu_clear(smp_processor_id(), map); - - /* sanity check the map, remove any non-online processors. */ - cpus_and(map, map, cpu_online_map); - if (unlikely(smp_ops == NULL)) - return ret; + return -1; data.func = func; data.info = info; @@ -221,42 +213,40 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, spin_lock(&call_lock); /* Must grab online cpu count with preempt disabled, otherwise * it can change. */ - num_cpus = num_online_cpus() - 1; - if (!num_cpus || cpus_empty(map)) { + cpus = num_online_cpus() - 1; + if (!cpus) { ret = 0; goto out; } call_data = &data; smp_wmb(); - /* Send a message to all CPUs in the map */ - for_each_cpu_mask(cpu, map) - smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION); + /* Send a message to all other CPUs and wait for them to respond */ + smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION); timeout = get_tb() + (u64) SMP_CALL_TIMEOUT * tb_ticks_per_sec; - /* Wait for indication that they have received the message */ - while (atomic_read(&data.started) != num_cpus) { + /* Wait for response */ + while (atomic_read(&data.started) != cpus) { HMT_low(); if (get_tb() >= timeout) { printk("smp_call_function on cpu %d: other cpus not " - "responding (%d)\n", smp_processor_id(), - atomic_read(&data.started)); + "responding (%d)\n", smp_processor_id(), + atomic_read(&data.started)); debugger(NULL); goto out; } } - /* optionally wait for the CPUs to complete */ if (wait) { - while (atomic_read(&data.finished) != num_cpus) { + while (atomic_read(&data.finished) != cpus) { HMT_low(); if (get_tb() >= timeout) { printk("smp_call_function on cpu %d: other " - "cpus not finishing (%d/%d)\n", - smp_processor_id(), - atomic_read(&data.finished), - atomic_read(&data.started)); + "cpus not finishing (%d/%d)\n", + smp_processor_id(), + atomic_read(&data.finished), + atomic_read(&data.started)); debugger(NULL); goto out; } @@ -272,29 +262,8 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, return ret; } -int smp_call_function(void (*func) (void *info), void *info, int nonatomic, - int wait) -{ - return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map); -} EXPORT_SYMBOL(smp_call_function); -int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic, - int wait) -{ - cpumask_t map=CPU_MASK_NONE; - - if (!cpu_online(cpu)) - return -EINVAL; - - if (cpu == smp_processor_id()) - return -EBUSY; - - cpu_set(cpu, map); - return smp_call_function_map(func,info,nonatomic,wait,map); -} -EXPORT_SYMBOL(smp_call_function_single); - void smp_call_function_interrupt(void) { void (*func) (void *info); diff --git a/trunk/arch/powerpc/kernel/suspend.c b/trunk/arch/powerpc/kernel/suspend.c deleted file mode 100644 index 8cee57107541..000000000000 --- a/trunk/arch/powerpc/kernel/suspend.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Suspend support specific for power. - * - * Distribute under GPLv2 - * - * Copyright (c) 2002 Pavel Machek - * Copyright (c) 2001 Patrick Mochel - */ - -#include - -/* References to section boundaries */ -extern const void __nosave_begin, __nosave_end; - -/* - * pfn_is_nosave - check if given pfn is in the 'nosave' section - */ - -int pfn_is_nosave(unsigned long pfn) -{ - unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; - unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) >> PAGE_SHIFT; - return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); -} diff --git a/trunk/arch/powerpc/kernel/swsusp.c b/trunk/arch/powerpc/kernel/swsusp.c deleted file mode 100644 index 064a7ba4f02c..000000000000 --- a/trunk/arch/powerpc/kernel/swsusp.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Common powerpc suspend code for 32 and 64 bits - * - * Copyright 2007 Johannes Berg - * - * 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 - -void save_processor_state(void) -{ - /* - * flush out all the special registers so we don't need - * to save them in the snapshot - */ - flush_fp_to_thread(current); - flush_altivec_to_thread(current); - flush_spe_to_thread(current); - -#ifdef CONFIG_PPC64 - hard_irq_disable(); -#endif - -} - -void restore_processor_state(void) -{ -#ifdef CONFIG_PPC32 - set_context(current->active_mm->context.id, current->active_mm->pgd); -#endif - -#ifdef CONFIG_PPC64 - hard_irq_enable(); -#endif -} diff --git a/trunk/arch/powerpc/kernel/swsusp_64.c b/trunk/arch/powerpc/kernel/swsusp_64.c deleted file mode 100644 index 6f3f0697274e..000000000000 --- a/trunk/arch/powerpc/kernel/swsusp_64.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * PowerPC 64-bit swsusp implementation - * - * Copyright 2006 Johannes Berg - * - * GPLv2 - */ - -#include -#include -#include -#include - -void do_after_copyback(void) -{ - iommu_restore(); - touch_softlockup_watchdog(); - mb(); -} - -void _iommu_save(void) -{ - iommu_save(); -} diff --git a/trunk/arch/powerpc/kernel/swsusp_asm64.S b/trunk/arch/powerpc/kernel/swsusp_asm64.S deleted file mode 100644 index e092c3cbdb9b..000000000000 --- a/trunk/arch/powerpc/kernel/swsusp_asm64.S +++ /dev/null @@ -1,228 +0,0 @@ -/* - * PowerPC 64-bit swsusp implementation - * - * Copyright 2006 Johannes Berg - * - * GPLv2 - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * Structure for storing CPU registers on the save area. - */ -#define SL_r1 0x00 /* stack pointer */ -#define SL_PC 0x08 -#define SL_MSR 0x10 -#define SL_SDR1 0x18 -#define SL_XER 0x20 -#define SL_TB 0x40 -#define SL_r2 0x48 -#define SL_CR 0x50 -#define SL_LR 0x58 -#define SL_r12 0x60 -#define SL_r13 0x68 -#define SL_r14 0x70 -#define SL_r15 0x78 -#define SL_r16 0x80 -#define SL_r17 0x88 -#define SL_r18 0x90 -#define SL_r19 0x98 -#define SL_r20 0xa0 -#define SL_r21 0xa8 -#define SL_r22 0xb0 -#define SL_r23 0xb8 -#define SL_r24 0xc0 -#define SL_r25 0xc8 -#define SL_r26 0xd0 -#define SL_r27 0xd8 -#define SL_r28 0xe0 -#define SL_r29 0xe8 -#define SL_r30 0xf0 -#define SL_r31 0xf8 -#define SL_SIZE SL_r31+8 - -/* these macros rely on the save area being - * pointed to by r11 */ -#define SAVE_SPECIAL(special) \ - mf##special r0 ;\ - std r0, SL_##special(r11) -#define RESTORE_SPECIAL(special) \ - ld r0, SL_##special(r11) ;\ - mt##special r0 -#define SAVE_REGISTER(reg) \ - std reg, SL_##reg(r11) -#define RESTORE_REGISTER(reg) \ - ld reg, SL_##reg(r11) - -/* space for storing cpu state */ - .section .data - .align 5 -swsusp_save_area: - .space SL_SIZE - - .section ".toc","aw" -swsusp_save_area_ptr: - .tc swsusp_save_area[TC],swsusp_save_area -restore_pblist_ptr: - .tc restore_pblist[TC],restore_pblist - - .section .text - .align 5 -_GLOBAL(swsusp_arch_suspend) - ld r11,swsusp_save_area_ptr@toc(r2) - SAVE_SPECIAL(LR) - SAVE_REGISTER(r1) - SAVE_SPECIAL(CR) - SAVE_SPECIAL(TB) - SAVE_REGISTER(r2) - SAVE_REGISTER(r12) - SAVE_REGISTER(r13) - SAVE_REGISTER(r14) - SAVE_REGISTER(r15) - SAVE_REGISTER(r16) - SAVE_REGISTER(r17) - SAVE_REGISTER(r18) - SAVE_REGISTER(r19) - SAVE_REGISTER(r20) - SAVE_REGISTER(r21) - SAVE_REGISTER(r22) - SAVE_REGISTER(r23) - SAVE_REGISTER(r24) - SAVE_REGISTER(r25) - SAVE_REGISTER(r26) - SAVE_REGISTER(r27) - SAVE_REGISTER(r28) - SAVE_REGISTER(r29) - SAVE_REGISTER(r30) - SAVE_REGISTER(r31) - SAVE_SPECIAL(MSR) - SAVE_SPECIAL(SDR1) - SAVE_SPECIAL(XER) - - /* we push the stack up 128 bytes but don't store the - * stack pointer on the stack like a real stackframe */ - addi r1,r1,-128 - - bl _iommu_save - bl swsusp_save - - /* restore LR */ - ld r11,swsusp_save_area_ptr@toc(r2) - RESTORE_SPECIAL(LR) - addi r1,r1,128 - - blr - -/* Resume code */ -_GLOBAL(swsusp_arch_resume) - /* Stop pending alitvec streams and memory accesses */ -BEGIN_FTR_SECTION - DSSALL -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - sync - - ld r12,restore_pblist_ptr@toc(r2) - ld r12,0(r12) - - cmpdi r12,0 - beq- nothing_to_copy - li r15,512 -copyloop: - ld r13,pbe_address(r12) - ld r14,pbe_orig_address(r12) - - mtctr r15 - li r10,0 -copy_page_loop: - ldx r0,r10,r13 - stdx r0,r10,r14 - addi r10,r10,8 - bdnz copy_page_loop - - ld r12,pbe_next(r12) - cmpdi r12,0 - bne+ copyloop -nothing_to_copy: - - /* flush caches */ - lis r3, 0x10 - mtctr r3 - li r3, 0 - ori r3, r3, CONFIG_KERNEL_START>>48 - li r0, 48 - sld r3, r3, r0 - li r0, 0 -1: - dcbf r0,r3 - addi r3,r3,0x20 - bdnz 1b - - sync - - tlbia - - ld r11,swsusp_save_area_ptr@toc(r2) - - RESTORE_SPECIAL(CR) - - /* restore timebase */ - /* load saved tb */ - ld r1, SL_TB(r11) - /* get upper 32 bits of it */ - srdi r2, r1, 32 - /* clear tb lower to avoid wrap */ - li r0, 0 - mttbl r0 - /* set tb upper */ - mttbu r2 - /* set tb lower */ - mttbl r1 - - /* restore registers */ - RESTORE_REGISTER(r1) - RESTORE_REGISTER(r2) - RESTORE_REGISTER(r12) - RESTORE_REGISTER(r13) - RESTORE_REGISTER(r14) - RESTORE_REGISTER(r15) - RESTORE_REGISTER(r16) - RESTORE_REGISTER(r17) - RESTORE_REGISTER(r18) - RESTORE_REGISTER(r19) - RESTORE_REGISTER(r20) - RESTORE_REGISTER(r21) - RESTORE_REGISTER(r22) - RESTORE_REGISTER(r23) - RESTORE_REGISTER(r24) - RESTORE_REGISTER(r25) - RESTORE_REGISTER(r26) - RESTORE_REGISTER(r27) - RESTORE_REGISTER(r28) - RESTORE_REGISTER(r29) - RESTORE_REGISTER(r30) - RESTORE_REGISTER(r31) - /* can't use RESTORE_SPECIAL(MSR) */ - ld r0, SL_MSR(r11) - mtmsrd r0, 0 - RESTORE_SPECIAL(SDR1) - RESTORE_SPECIAL(XER) - - sync - - addi r1,r1,-128 - bl slb_flush_and_rebolt - bl do_after_copyback - addi r1,r1,128 - - ld r11,swsusp_save_area_ptr@toc(r2) - RESTORE_SPECIAL(LR) - - li r3, 0 - blr diff --git a/trunk/arch/powerpc/kernel/syscalls.c b/trunk/arch/powerpc/kernel/syscalls.c index fc6647d332cb..d358866b880f 100644 --- a/trunk/arch/powerpc/kernel/syscalls.c +++ b/trunk/arch/powerpc/kernel/syscalls.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index cae39d9dfe48..933e214c33e8 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -499,4 +499,4 @@ static int __init topology_init(void) return 0; } -subsys_initcall(topology_init); +__initcall(topology_init); diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index bf6445ac9f1c..f7862224fe85 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -33,8 +33,8 @@ #include #include #include -#include +#include #include #include #include @@ -72,6 +72,20 @@ EXPORT_SYMBOL(__debugger_dabr_match); EXPORT_SYMBOL(__debugger_fault_handler); #endif +ATOMIC_NOTIFIER_HEAD(powerpc_die_chain); + +int register_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&powerpc_die_chain, nb); +} +EXPORT_SYMBOL(register_die_notifier); + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&powerpc_die_chain, nb); +} +EXPORT_SYMBOL(unregister_die_notifier); + /* * Trap & Exception support */ diff --git a/trunk/arch/powerpc/kernel/udbg.c b/trunk/arch/powerpc/kernel/udbg.c index 87703df87509..7e0971868fc2 100644 --- a/trunk/arch/powerpc/kernel/udbg.c +++ b/trunk/arch/powerpc/kernel/udbg.c @@ -51,9 +51,6 @@ void __init udbg_early_init(void) udbg_init_pas_realmode(); #elif defined(CONFIG_BOOTX_TEXT) udbg_init_btext(); -#elif defined(CONFIG_PPC_EARLY_DEBUG_44x) - /* PPC44x debug */ - udbg_init_44x_as1(); #endif } @@ -145,22 +142,29 @@ static void udbg_console_write(struct console *con, const char *s, static struct console udbg_console = { .name = "udbg", .write = udbg_console_write, - .flags = CON_PRINTBUFFER | CON_ENABLED | CON_BOOT, + .flags = CON_PRINTBUFFER | CON_ENABLED, .index = -1, }; static int early_console_initialized; -/* called by setup_system */ -void register_early_udbg_console(void) +void __init disable_early_printk(void) { - if (early_console_initialized) + if (!early_console_initialized) return; - if (strstr(boot_command_line, "udbg-immortal")) { printk(KERN_INFO "early console immortal !\n"); - udbg_console.flags &= ~CON_BOOT; + return; } + unregister_console(&udbg_console); + early_console_initialized = 0; +} + +/* called by setup_system */ +void register_early_udbg_console(void) +{ + if (early_console_initialized) + return; early_console_initialized = 1; register_console(&udbg_console); } diff --git a/trunk/arch/powerpc/kernel/udbg_16550.c b/trunk/arch/powerpc/kernel/udbg_16550.c index 7afab5bcd61a..a963f657222b 100644 --- a/trunk/arch/powerpc/kernel/udbg_16550.c +++ b/trunk/arch/powerpc/kernel/udbg_16550.c @@ -191,26 +191,3 @@ void udbg_init_pas_realmode(void) udbg_getc_poll = NULL; } #endif /* CONFIG_PPC_MAPLE */ - -#ifdef CONFIG_PPC_EARLY_DEBUG_44x -#include - -static void udbg_44x_as1_putc(char c) -{ - if (udbg_comport) { - while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) - /* wait for idle */; - as1_writeb(c, &udbg_comport->thr); eieio(); - if (c == '\n') - udbg_44x_as1_putc('\r'); - } -} - -void __init udbg_init_44x_as1(void) -{ - udbg_comport = - (volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; - - udbg_putc = udbg_44x_as1_putc; -} -#endif /* CONFIG_PPC_EARLY_DEBUG_44x */ diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index 4245579edb4e..e46c31b36641 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index 62c1bc12ea39..9eaefac5053f 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -37,7 +37,7 @@ #include #include -extern struct kset devices_subsys; /* needed for vio_find_name() */ +extern struct subsystem devices_subsys; /* needed for vio_find_name() */ static struct vio_dev vio_bus_device = { /* fake "parent" device */ .name = vio_bus_device.dev.bus_id, @@ -117,7 +117,7 @@ static const struct vio_device_id *vio_match_device( { while (ids->type[0] != '\0') { if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && - of_device_is_compatible(dev->dev.archdata.of_node, + device_is_compatible(dev->dev.archdata.of_node, ids->compat)) return ids; ids++; @@ -427,7 +427,7 @@ static struct vio_dev *vio_find_name(const char *kobj_name) { struct kobject *found; - found = kset_find_obj(&devices_subsys, kobj_name); + found = kset_find_obj(&devices_subsys.kset, kobj_name); if (!found) return NULL; diff --git a/trunk/arch/powerpc/kernel/vmlinux.lds.S b/trunk/arch/powerpc/kernel/vmlinux.lds.S index 132067313147..7eefeb4a30e7 100644 --- a/trunk/arch/powerpc/kernel/vmlinux.lds.S +++ b/trunk/arch/powerpc/kernel/vmlinux.lds.S @@ -139,7 +139,11 @@ SECTIONS __initramfs_end = .; } #endif - . = ALIGN(PAGE_SIZE); +#ifdef CONFIG_PPC32 + . = ALIGN(32); +#else + . = ALIGN(128); +#endif .data.percpu : { __per_cpu_start = .; *(.data.percpu) diff --git a/trunk/arch/powerpc/lib/dma-noncoherent.c b/trunk/arch/powerpc/lib/dma-noncoherent.c index 6656d47841d0..48f3d13a3de5 100644 --- a/trunk/arch/powerpc/lib/dma-noncoherent.c +++ b/trunk/arch/powerpc/lib/dma-noncoherent.c @@ -306,15 +306,13 @@ EXPORT_SYMBOL(__dma_free_coherent); static int __init dma_alloc_init(void) { pgd_t *pgd; - pud_t *pud; pmd_t *pmd; pte_t *pte; int ret = 0; do { pgd = pgd_offset(&init_mm, CONSISTENT_BASE); - pud = pud_alloc(&init_mm, pgd, CONSISTENT_BASE); - pmd = pmd_alloc(&init_mm, pud, CONSISTENT_BASE); + pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE); if (!pmd) { printk(KERN_ERR "%s: no pmd tables\n", __func__); ret = -ENOMEM; diff --git a/trunk/arch/powerpc/mm/44x_mmu.c b/trunk/arch/powerpc/mm/44x_mmu.c index ca4dcb07a939..0a0a0487b334 100644 --- a/trunk/arch/powerpc/mm/44x_mmu.c +++ b/trunk/arch/powerpc/mm/44x_mmu.c @@ -24,38 +24,73 @@ * */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include + +#include +#include +#include +#include +#include #include -#include -#include +#include +#include +#include +#include +#include #include "mmu_decl.h" +extern char etext[], _stext[]; + /* Used by the 44x TLB replacement exception handler. * Just needed it declared someplace. */ -unsigned int tlb_44x_index; /* = 0 */ -unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS; +unsigned int tlb_44x_index = 0; +unsigned int tlb_44x_hwater = 62; /* * "Pins" a 256MB TLB entry in AS0 for kernel lowmem */ -static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys) +static void __init +ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys) { - __asm__ __volatile__( - "tlbwe %2,%3,%4\n" - "tlbwe %1,%3,%5\n" - "tlbwe %0,%3,%6\n" + unsigned long attrib = 0; + + __asm__ __volatile__("\ + clrrwi %2,%2,10\n\ + ori %2,%2,%4\n\ + clrrwi %1,%1,10\n\ + li %0,0\n\ + ori %0,%0,%5\n\ + tlbwe %2,%3,%6\n\ + tlbwe %1,%3,%7\n\ + tlbwe %0,%3,%8" : - : "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), - "r" (phys), - "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M), - "r" (tlb_44x_hwater--), /* slot for this TLB entry */ + : "r" (attrib), "r" (phys), "r" (virt), "r" (slot), + "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M), + "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), "i" (PPC44x_TLB_PAGEID), "i" (PPC44x_TLB_XLAT), "i" (PPC44x_TLB_ATTRIB)); } +/* + * MMU_init_hw does the chip-specific initialization of the MMU hardware. + */ void __init MMU_init_hw(void) { flush_instruction_cache(); @@ -63,13 +98,22 @@ void __init MMU_init_hw(void) unsigned long __init mmu_mapin_ram(void) { - unsigned long addr; + unsigned int pinned_tlbs = 1; + int i; + + /* Determine number of entries necessary to cover lowmem */ + pinned_tlbs = (unsigned int) + (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT); + + /* Write upper watermark to save location */ + tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; - /* Pin in enough TLBs to cover any lowmem not covered by the - * initial 256M mapping established in head_44x.S */ - for (addr = PPC_PIN_SIZE; addr < total_lowmem; - addr += PPC_PIN_SIZE) - ppc44x_pin_tlb(addr + PAGE_OFFSET, addr); + /* If necessary, set additional pinned TLBs */ + if (pinned_tlbs > 1) + for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { + unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE; + ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); + } return total_lowmem; } diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index bfe901353142..03aeb3a46077 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include @@ -37,28 +36,40 @@ #include #include #include +#include #include - #ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs) +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) { - int ret = 0; - - /* kprobe_running() needs smp_processor_id() */ - if (!user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, 11)) - ret = 1; - preempt_enable(); - } + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} - return ret; +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } #else -static inline int notify_page_fault(struct pt_regs *regs) +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) { - return 0; + return NOTIFY_DONE; } #endif @@ -164,7 +175,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, is_write = error_code & ESR_DST; #endif /* CONFIG_4xx || CONFIG_BOOKE */ - if (notify_page_fault(regs)) + if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, error_code, + 11, SIGSEGV) == NOTIFY_STOP) return 0; if (trap == 0x300) { diff --git a/trunk/arch/powerpc/mm/hash_native_64.c b/trunk/arch/powerpc/mm/hash_native_64.c index 7b7fe2d7b9dc..79aedaf36f2b 100644 --- a/trunk/arch/powerpc/mm/hash_native_64.c +++ b/trunk/arch/powerpc/mm/hash_native_64.c @@ -26,7 +26,6 @@ #include #include #include -#include #ifdef DEBUG_LOW #define DBG_LOW(fmt...) udbg_printf(fmt) @@ -341,70 +340,31 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va, local_irq_restore(flags); } -#define LP_SHIFT 12 -#define LP_BITS 8 -#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT) - -static void hpte_decode(hpte_t *hpte, unsigned long slot, - int *psize, unsigned long *va) +/* + * XXX This need fixing based on page size. It's only used by + * native_hpte_clear() for now which needs fixing too so they + * make a good pair... + */ +static unsigned long slot2va(unsigned long hpte_v, unsigned long slot) { - unsigned long hpte_r = hpte->r; - unsigned long hpte_v = hpte->v; - unsigned long avpn; - int i, size, shift, penc, avpnm_bits; - - if (!(hpte_v & HPTE_V_LARGE)) - size = MMU_PAGE_4K; - else { - for (i = 0; i < LP_BITS; i++) { - if ((hpte_r & LP_MASK(i+1)) == LP_MASK(i+1)) - break; - } - penc = LP_MASK(i+1) >> LP_SHIFT; - for (size = 0; size < MMU_PAGE_COUNT; size++) { + unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v); + unsigned long va; - /* 4K pages are not represented by LP */ - if (size == MMU_PAGE_4K) - continue; + va = avpn << 23; - /* valid entries have a shift value */ - if (!mmu_psize_defs[size].shift) - continue; + if (! (hpte_v & HPTE_V_LARGE)) { + unsigned long vpi, pteg; - if (penc == mmu_psize_defs[size].penc) - break; - } - } + pteg = slot / HPTES_PER_GROUP; + if (hpte_v & HPTE_V_SECONDARY) + pteg = ~pteg; - /* - * FIXME, the code below works for 16M, 64K, and 4K pages as these - * fall under the p<=23 rules for calculating the virtual address. - * In the case of 16M pages, an extra bit is stolen from the AVPN - * field to achieve the requisite 24 bits. - * - * Does not work for 16G pages or 1 TB segments. - */ - shift = mmu_psize_defs[size].shift; - if (mmu_psize_defs[size].avpnm) - avpnm_bits = __ilog2_u64(mmu_psize_defs[size].avpnm) + 1; - else - avpnm_bits = 0; - if (shift - avpnm_bits <= 23) { - avpn = HPTE_V_AVPN_VAL(hpte_v) << 23; - - if (shift < 23) { - unsigned long vpi, pteg; - - pteg = slot / HPTES_PER_GROUP; - if (hpte_v & HPTE_V_SECONDARY) - pteg = ~pteg; - vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask; - avpn |= (vpi << mmu_psize_defs[size].shift); - } + vpi = ((va >> 28) ^ pteg) & htab_hash_mask; + + va |= vpi << PAGE_SHIFT; } - *va = avpn; - *psize = size; + return va; } /* @@ -414,14 +374,15 @@ static void hpte_decode(hpte_t *hpte, unsigned long slot, * * TODO: add batching support when enabled. remember, no dynamic memory here, * athough there is the control page available... + * + * XXX FIXME: 4k only for now ! */ static void native_hpte_clear(void) { unsigned long slot, slots, flags; hpte_t *hptep = htab_address; - unsigned long hpte_v, va; + unsigned long hpte_v; unsigned long pteg_count; - int psize; pteg_count = htab_hash_mask + 1; @@ -447,9 +408,8 @@ static void native_hpte_clear(void) * already hold the native_tlbie_lock. */ if (hpte_v & HPTE_V_VALID) { - hpte_decode(hptep, slot, &psize, &va); hptep->v = 0; - __tlbie(va, psize); + __tlbie(slot2va(hpte_v, slot), MMU_PAGE_4K); } } diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index 9b226fa7006f..49618461defb 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -103,7 +103,7 @@ int mmu_ci_restrictions; #ifdef CONFIG_DEBUG_PAGEALLOC static u8 *linear_map_hash_slots; static unsigned long linear_map_hash_count; -static DEFINE_SPINLOCK(linear_map_hash_lock); +static spinlock_t linear_map_hash_lock; #endif /* CONFIG_DEBUG_PAGEALLOC */ /* There are definitions of page sizes arrays to be used when none diff --git a/trunk/arch/powerpc/mm/hugetlbpage.c b/trunk/arch/powerpc/mm/hugetlbpage.c index fb959264c104..8508f973d9cc 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage.c +++ b/trunk/arch/powerpc/mm/hugetlbpage.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -565,13 +566,6 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, if (len > TASK_SIZE) return -ENOMEM; - /* handle fixed mapping: prevent overlap with huge pages */ - if (flags & MAP_FIXED) { - if (is_hugepage_only_range(mm, addr, len)) - return -EINVAL; - return addr; - } - if (addr) { addr = PAGE_ALIGN(addr); vma = find_vma(mm, addr); @@ -647,13 +641,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, if (len > TASK_SIZE) return -ENOMEM; - /* handle fixed mapping: prevent overlap with huge pages */ - if (flags & MAP_FIXED) { - if (is_hugepage_only_range(mm, addr, len)) - return -EINVAL; - return addr; - } - /* dont allow allocations above current base */ if (mm->free_area_cache > base) mm->free_area_cache = base; @@ -836,13 +823,6 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, /* Paranoia, caller should have dealt with this */ BUG_ON((addr + len) < addr); - /* Handle MAP_FIXED */ - if (flags & MAP_FIXED) { - if (prepare_hugepage_range(addr, len, pgoff)) - return -EINVAL; - return addr; - } - if (test_thread_flag(TIF_32BIT)) { curareas = current->mm->context.low_htlb_areas; @@ -1077,7 +1057,8 @@ static int __init hugetlbpage_init(void) huge_pgtable_cache = kmem_cache_create("hugepte_cache", HUGEPTE_TABLE_SIZE, HUGEPTE_TABLE_SIZE, - 0, + SLAB_HWCACHE_ALIGN | + SLAB_MUST_HWCACHE_ALIGN, zero_ctor, NULL); if (! huge_pgtable_cache) panic("hugetlbpage_init(): could not create hugepte cache\n"); diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index fe1fe852181a..d12a87ec5ae9 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -183,8 +183,12 @@ void pgtable_cache_init(void) "for size: %08x...\n", name, i, size); pgtable_cache[i] = kmem_cache_create(name, size, size, - SLAB_PANIC, + SLAB_HWCACHE_ALIGN | + SLAB_MUST_HWCACHE_ALIGN, zero_ctor, NULL); + if (! pgtable_cache[i]) + panic("pgtable_cache_init(): could not create %s!\n", + name); } } diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 1a6e08f3298f..c4bcd7546424 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -80,6 +80,7 @@ int page_is_ram(unsigned long pfn) return 0; #endif } +EXPORT_SYMBOL(page_is_ram); pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot) diff --git a/trunk/arch/powerpc/mm/mmu_decl.h b/trunk/arch/powerpc/mm/mmu_decl.h index 2558c34eedaa..9c4538bb04b0 100644 --- a/trunk/arch/powerpc/mm/mmu_decl.h +++ b/trunk/arch/powerpc/mm/mmu_decl.h @@ -40,8 +40,7 @@ extern int __map_without_bats; extern unsigned long ioremap_base; extern unsigned int rtas_data, rtas_size; -struct _PTE; -extern struct _PTE *Hash, *Hash_end; +extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern unsigned int num_tlbcam_entries; diff --git a/trunk/arch/powerpc/mm/pgtable_32.c b/trunk/arch/powerpc/mm/pgtable_32.c index d8232b7a08f7..bca560374927 100644 --- a/trunk/arch/powerpc/mm/pgtable_32.c +++ b/trunk/arch/powerpc/mm/pgtable_32.c @@ -261,7 +261,7 @@ int map_page(unsigned long va, phys_addr_t pa, int flags) int err = -ENOMEM; /* Use upper 10 bits of VA to index the first level map */ - pd = pmd_offset(pud_offset(pgd_offset_k(va), va), va); + pd = pmd_offset(pgd_offset_k(va), va); /* Use middle 10 bits of VA to index the second-level map */ pg = pte_alloc_kernel(pd, va); if (pg != 0) { @@ -354,27 +354,23 @@ int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep, pmd_t **pmdp) { pgd_t *pgd; - pud_t *pud; pmd_t *pmd; pte_t *pte; int retval = 0; pgd = pgd_offset(mm, addr & PAGE_MASK); if (pgd) { - pud = pud_offset(pgd, addr & PAGE_MASK); - if (pud && pud_present(*pud)) { - pmd = pmd_offset(pud, addr & PAGE_MASK); - if (pmd_present(*pmd)) { - pte = pte_offset_map(pmd, addr & PAGE_MASK); - if (pte) { - retval = 1; - *ptep = pte; - if (pmdp) - *pmdp = pmd; - /* XXX caller needs to do pte_unmap, yuck */ - } - } - } + pmd = pmd_offset(pgd, addr & PAGE_MASK); + if (pmd_present(*pmd)) { + pte = pte_offset_map(pmd, addr & PAGE_MASK); + if (pte) { + retval = 1; + *ptep = pte; + if (pmdp) + *pmdp = pmd; + /* XXX caller needs to do pte_unmap, yuck */ + } + } } return(retval); } diff --git a/trunk/arch/powerpc/mm/stab.c b/trunk/arch/powerpc/mm/stab.c index 132c6bc66ce1..eeeacab548e6 100644 --- a/trunk/arch/powerpc/mm/stab.c +++ b/trunk/arch/powerpc/mm/stab.c @@ -227,7 +227,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm) * the first (bolted) segment, so that do_stab_bolted won't get a * recursive segment miss on the segment table itself. */ -void __init stabs_alloc(void) +void stabs_alloc(void) { int cpu; diff --git a/trunk/arch/powerpc/platforms/44x/44x.h b/trunk/arch/powerpc/platforms/44x/44x.h deleted file mode 100644 index 42eabf87fea3..000000000000 --- a/trunk/arch/powerpc/platforms/44x/44x.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __POWERPC_PLATFORMS_44X_44X_H -#define __POWERPC_PLATFORMS_44X_44X_H - -extern u8 as1_readb(volatile u8 __iomem *addr); -extern void as1_writeb(u8 data, volatile u8 __iomem *addr); -extern void ppc44x_reset_system(char *cmd); - -#endif /* __POWERPC_PLATFORMS_44X_44X_H */ diff --git a/trunk/arch/powerpc/platforms/44x/Kconfig b/trunk/arch/powerpc/platforms/44x/Kconfig deleted file mode 100644 index 8e66949e7c67..000000000000 --- a/trunk/arch/powerpc/platforms/44x/Kconfig +++ /dev/null @@ -1,56 +0,0 @@ -#config BAMBOO -# bool "Bamboo" -# depends on 44x -# default n -# select 440EP -# help -# This option enables support for the IBM PPC440EP evaluation board. - -config EBONY - bool "Ebony" - depends on 44x - default y - select 440GP - help - This option enables support for the IBM PPC440GP evaluation board. - -#config LUAN -# bool "Luan" -# depends on 44x -# default n -# select 440SP -# help -# This option enables support for the IBM PPC440SP evaluation board. - -#config OCOTEA -# bool "Ocotea" -# depends on 44x -# default n -# select 440GX -# help -# This option enables support for the IBM PPC440GX evaluation board. - -# 44x specific CPU modules, selected based on the board above. -config 440EP - bool - select PPC_FPU - select IBM440EP_ERR42 - -config 440GP - bool - select IBM_NEW_EMAC_ZMII - -config 440GX - bool - -config 440SP - bool - -config 440A - bool - depends on 440GX - default y - -# 44x errata/workaround config symbols, selected by the CPU models above -config IBM440EP_ERR42 - bool diff --git a/trunk/arch/powerpc/platforms/44x/Makefile b/trunk/arch/powerpc/platforms/44x/Makefile deleted file mode 100644 index 41d0a18a0e44..000000000000 --- a/trunk/arch/powerpc/platforms/44x/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -obj-$(CONFIG_44x) := misc_44x.o -obj-$(CONFIG_EBONY) += ebony.o diff --git a/trunk/arch/powerpc/platforms/44x/ebony.c b/trunk/arch/powerpc/platforms/44x/ebony.c deleted file mode 100644 index ad526eafc90b..000000000000 --- a/trunk/arch/powerpc/platforms/44x/ebony.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Ebony board specific routines - * - * Matt Porter - * Copyright 2002-2005 MontaVista Software Inc. - * - * Eugene Surovegin or - * Copyright (c) 2003-2005 Zultys Technologies - * - * Rewritten and ported to the merged powerpc tree: - * Copyright 2007 David Gibson , IBM Corporation. - * - * 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 "44x.h" - -static struct of_device_id ebony_of_bus[] = { - { .type = "ibm,plb", }, - { .type = "ibm,opb", }, - { .type = "ibm,ebc", }, - {}, -}; - -static int __init ebony_device_probe(void) -{ - if (!machine_is(ebony)) - return 0; - - of_platform_bus_probe(NULL, ebony_of_bus, NULL); - - return 0; -} -device_initcall(ebony_device_probe); - -/* - * Called very early, MMU is off, device-tree isn't unflattened - */ -static int __init ebony_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (!of_flat_dt_is_compatible(root, "ibm,ebony")) - return 0; - - return 1; -} - -static void __init ebony_setup_arch(void) -{ -} - -define_machine(ebony) { - .name = "Ebony", - .probe = ebony_probe, - .setup_arch = ebony_setup_arch, - .progress = udbg_progress, - .init_IRQ = uic_init_tree, - .get_irq = uic_get_irq, - .restart = ppc44x_reset_system, - .calibrate_decr = generic_calibrate_decr, -}; diff --git a/trunk/arch/powerpc/platforms/44x/misc_44x.S b/trunk/arch/powerpc/platforms/44x/misc_44x.S deleted file mode 100644 index 3bce71d5d756..000000000000 --- a/trunk/arch/powerpc/platforms/44x/misc_44x.S +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file contains miscellaneous low-level functions for PPC 44x. - * Copyright 2007 David Gibson , IBM Corporation. - * - * 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 - - .text - -/* - * Do an IO access in AS1 - */ -_GLOBAL(as1_readb) - mfmsr r7 - ori r0,r7,MSR_DS - sync - mtmsr r0 - sync - isync - lbz r3,0(r3) - sync - mtmsr r7 - sync - isync - blr - -_GLOBAL(as1_writeb) - mfmsr r7 - ori r0,r7,MSR_DS - sync - mtmsr r0 - sync - isync - stb r3,0(r4) - sync - mtmsr r7 - sync - isync - blr - -/* - * void ppc44x_reset_system(char *cmd) - * - * At present, this routine just applies a system reset. - */ -_GLOBAL(ppc44x_reset_system) - mfspr r13,SPRN_DBCR0 - oris r13,r13,DBCR0_RST_SYSTEM@h - mtspr SPRN_DBCR0,r13 - b . /* Just in case the reset doesn't work */ diff --git a/trunk/arch/powerpc/platforms/52xx/Kconfig b/trunk/arch/powerpc/platforms/52xx/Kconfig index 3ffaa066c2c8..bc4aa4a80a12 100644 --- a/trunk/arch/powerpc/platforms/52xx/Kconfig +++ b/trunk/arch/powerpc/platforms/52xx/Kconfig @@ -1,6 +1,5 @@ config PPC_MPC52xx bool - select FSL_SOC default n config PPC_MPC5200 diff --git a/trunk/arch/powerpc/platforms/52xx/Makefile b/trunk/arch/powerpc/platforms/52xx/Makefile index b91e39c84d46..07cdbcacf156 100644 --- a/trunk/arch/powerpc/platforms/52xx/Makefile +++ b/trunk/arch/powerpc/platforms/52xx/Makefile @@ -8,5 +8,3 @@ endif obj-$(CONFIG_PPC_EFIKA) += efika.o obj-$(CONFIG_PPC_LITE5200) += lite5200.o - -obj-$(CONFIG_PM) += mpc52xx_sleep.o mpc52xx_pm.o diff --git a/trunk/arch/powerpc/platforms/52xx/efika.c b/trunk/arch/powerpc/platforms/52xx/efika.c index f591a9fc19b9..a6bba97314eb 100644 --- a/trunk/arch/powerpc/platforms/52xx/efika.c +++ b/trunk/arch/powerpc/platforms/52xx/efika.c @@ -184,16 +184,6 @@ static void efika_show_cpuinfo(struct seq_file *m) of_node_put(root); } -#ifdef CONFIG_PM -static void efika_suspend_prepare(void __iomem *mbar) -{ - u8 pin = 4; /* GPIO_WKUP_4 (GPIO_PSC6_0 - IRDA_RX) */ - u8 level = 1; /* wakeup on high level */ - /* IOW. to wake it up, short pins 1 and 3 on IRDA connector */ - mpc52xx_set_wakeup_gpio(pin, level); -} -#endif - static void __init efika_setup_arch(void) { rtas_initialize(); @@ -209,11 +199,6 @@ static void __init efika_setup_arch(void) efika_pcisetup(); -#ifdef CONFIG_PM - mpc52xx_suspend.board_suspend_prepare = efika_suspend_prepare; - mpc52xx_pm_init(); -#endif - if (ppc_md.progress) ppc_md.progress("Linux/PPC " UTS_RELEASE " running on Efika ;-)\n", 0x0); } diff --git a/trunk/arch/powerpc/platforms/52xx/lite5200.c b/trunk/arch/powerpc/platforms/52xx/lite5200.c index 1cfc00dfb99a..8e2646ac417b 100644 --- a/trunk/arch/powerpc/platforms/52xx/lite5200.c +++ b/trunk/arch/powerpc/platforms/52xx/lite5200.c @@ -85,28 +85,6 @@ lite5200_setup_cpu(void) iounmap(gpio); } -#ifdef CONFIG_PM -static u32 descr_a; -static void lite5200_suspend_prepare(void __iomem *mbar) -{ - u8 pin = 1; /* GPIO_WKUP_1 (GPIO_PSC2_4) */ - u8 level = 0; /* wakeup on low level */ - mpc52xx_set_wakeup_gpio(pin, level); - - /* - * power down usb port - * this needs to be called before of-ohci suspend code - */ - descr_a = in_be32(mbar + 0x1048); - out_be32(mbar + 0x1048, (descr_a & ~0x200) | 0x100); -} - -static void lite5200_resume_finish(void __iomem *mbar) -{ - out_be32(mbar + 0x1048, descr_a); -} -#endif - static void __init lite5200_setup_arch(void) { struct device_node *np; @@ -129,12 +107,6 @@ static void __init lite5200_setup_arch(void) mpc52xx_setup_cpu(); /* Generic */ lite5200_setup_cpu(); /* Platorm specific */ -#ifdef CONFIG_PM - mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare; - mpc52xx_suspend.board_resume_finish = lite5200_resume_finish; - mpc52xx_pm_init(); -#endif - #ifdef CONFIG_PCI np = of_find_node_by_type(NULL, "pci"); if (np) { diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pm.c deleted file mode 100644 index fd40044d16cd..000000000000 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "mpc52xx_pic.h" - - -/* these are defined in mpc52xx_sleep.S, and only used here */ -extern void mpc52xx_deep_sleep(void *sram, void *sdram_regs, - struct mpc52xx_cdm *, struct mpc52xx_intr *); -extern void mpc52xx_ds_sram(void); -extern const long mpc52xx_ds_sram_size; -extern void mpc52xx_ds_cached(void); -extern const long mpc52xx_ds_cached_size; - -static void __iomem *mbar; -static void __iomem *sdram; -static struct mpc52xx_cdm __iomem *cdm; -static struct mpc52xx_intr __iomem *intr; -static struct mpc52xx_gpio_wkup __iomem *gpiow; -static void *sram; -static int sram_size; - -struct mpc52xx_suspend mpc52xx_suspend; - -static int mpc52xx_pm_valid(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_STANDBY: - return 1; - default: - return 0; - } -} - -int mpc52xx_set_wakeup_gpio(u8 pin, u8 level) -{ - u16 tmp; - - /* enable gpio */ - out_8(&gpiow->wkup_gpioe, in_8(&gpiow->wkup_gpioe) | (1 << pin)); - /* set as input */ - out_8(&gpiow->wkup_ddr, in_8(&gpiow->wkup_ddr) & ~(1 << pin)); - /* enable deep sleep interrupt */ - out_8(&gpiow->wkup_inten, in_8(&gpiow->wkup_inten) | (1 << pin)); - /* low/high level creates wakeup interrupt */ - tmp = in_be16(&gpiow->wkup_itype); - tmp &= ~(0x3 << (pin * 2)); - tmp |= (!level + 1) << (pin * 2); - out_be16(&gpiow->wkup_itype, tmp); - /* master enable */ - out_8(&gpiow->wkup_maste, 1); - - return 0; -} - -int mpc52xx_pm_prepare(suspend_state_t state) -{ - if (state != PM_SUSPEND_STANDBY) - return -EINVAL; - - /* map the whole register space */ - mbar = mpc52xx_find_and_map("mpc5200"); - if (!mbar) { - printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__); - return -ENOSYS; - } - /* these offsets are from mpc5200 users manual */ - sdram = mbar + 0x100; - cdm = mbar + 0x200; - intr = mbar + 0x500; - gpiow = mbar + 0xc00; - sram = mbar + 0x8000; /* Those will be handled by the */ - sram_size = 0x4000; /* bestcomm driver soon */ - - /* call board suspend code, if applicable */ - if (mpc52xx_suspend.board_suspend_prepare) - mpc52xx_suspend.board_suspend_prepare(mbar); - else { - printk(KERN_ALERT "%s: %i don't know how to wake up the board\n", - __func__, __LINE__); - goto out_unmap; - } - - return 0; - - out_unmap: - iounmap(mbar); - return -ENOSYS; -} - - -char saved_sram[0x4000]; - -int mpc52xx_pm_enter(suspend_state_t state) -{ - u32 clk_enables; - u32 msr, hid0; - u32 intr_main_mask; - void __iomem * irq_0x500 = (void *)CONFIG_KERNEL_START + 0x500; - unsigned long irq_0x500_stop = (unsigned long)irq_0x500 + mpc52xx_ds_cached_size; - char saved_0x500[mpc52xx_ds_cached_size]; - - /* disable all interrupts in PIC */ - intr_main_mask = in_be32(&intr->main_mask); - out_be32(&intr->main_mask, intr_main_mask | 0x1ffff); - - /* don't let DEC expire any time soon */ - mtspr(SPRN_DEC, 0x7fffffff); - - /* save SRAM */ - memcpy(saved_sram, sram, sram_size); - - /* copy low level suspend code to sram */ - memcpy(sram, mpc52xx_ds_sram, mpc52xx_ds_sram_size); - - out_8(&cdm->ccs_sleep_enable, 1); - out_8(&cdm->osc_sleep_enable, 1); - out_8(&cdm->ccs_qreq_test, 1); - - /* disable all but SDRAM and bestcomm (SRAM) clocks */ - clk_enables = in_be32(&cdm->clk_enables); - out_be32(&cdm->clk_enables, clk_enables & 0x00088000); - - /* disable power management */ - msr = mfmsr(); - mtmsr(msr & ~MSR_POW); - - /* enable sleep mode, disable others */ - hid0 = mfspr(SPRN_HID0); - mtspr(SPRN_HID0, (hid0 & ~(HID0_DOZE | HID0_NAP | HID0_DPM)) | HID0_SLEEP); - - /* save original, copy our irq handler, flush from dcache and invalidate icache */ - memcpy(saved_0x500, irq_0x500, mpc52xx_ds_cached_size); - memcpy(irq_0x500, mpc52xx_ds_cached, mpc52xx_ds_cached_size); - flush_icache_range((unsigned long)irq_0x500, irq_0x500_stop); - - /* call low-level sleep code */ - mpc52xx_deep_sleep(sram, sdram, cdm, intr); - - /* restore original irq handler */ - memcpy(irq_0x500, saved_0x500, mpc52xx_ds_cached_size); - flush_icache_range((unsigned long)irq_0x500, irq_0x500_stop); - - /* restore old power mode */ - mtmsr(msr & ~MSR_POW); - mtspr(SPRN_HID0, hid0); - mtmsr(msr); - - out_be32(&cdm->clk_enables, clk_enables); - out_8(&cdm->ccs_sleep_enable, 0); - out_8(&cdm->osc_sleep_enable, 0); - - /* restore SRAM */ - memcpy(sram, saved_sram, sram_size); - - /* restart jiffies */ - wakeup_decrementer(); - - /* reenable interrupts in PIC */ - out_be32(&intr->main_mask, intr_main_mask); - - return 0; -} - -int mpc52xx_pm_finish(suspend_state_t state) -{ - /* call board resume code */ - if (mpc52xx_suspend.board_resume_finish) - mpc52xx_suspend.board_resume_finish(mbar); - - iounmap(mbar); - - return 0; -} - -static struct pm_ops mpc52xx_pm_ops = { - .valid = mpc52xx_pm_valid, - .prepare = mpc52xx_pm_prepare, - .enter = mpc52xx_pm_enter, - .finish = mpc52xx_pm_finish, -}; - -int __init mpc52xx_pm_init(void) -{ - pm_set_ops(&mpc52xx_pm_ops); - return 0; -} diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_sleep.S b/trunk/arch/powerpc/platforms/52xx/mpc52xx_sleep.S deleted file mode 100644 index 4dc170b0ae18..000000000000 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_sleep.S +++ /dev/null @@ -1,154 +0,0 @@ -#include -#include -#include - - -.text - -_GLOBAL(mpc52xx_deep_sleep) -mpc52xx_deep_sleep: /* args r3-r6: SRAM, SDRAM regs, CDM regs, INTR regs */ - - /* enable interrupts */ - mfmsr r7 - ori r7, r7, 0x8000 /* EE */ - mtmsr r7 - sync; isync; - - li r10, 0 /* flag that irq handler sets */ - - /* enable tmr7 (or any other) interrupt */ - lwz r8, 0x14(r6) /* intr->main_mask */ - ori r8, r8, 0x1 - xori r8, r8, 0x1 - stw r8, 0x14(r6) - sync - - /* emulate tmr7 interrupt */ - li r8, 0x1 - stw r8, 0x40(r6) /* intr->main_emulate */ - sync - - /* wait for it to happen */ -1: - cmpi cr0, r10, 1 - bne cr0, 1b - - /* lock icache */ - mfspr r10, SPRN_HID0 - ori r10, r10, 0x2000 - sync; isync; - mtspr SPRN_HID0, r10 - sync; isync; - - - mflr r9 /* save LR */ - - /* jump to sram */ - mtlr r3 - blrl - - mtlr r9 /* restore LR */ - - /* unlock icache */ - mfspr r10, SPRN_HID0 - ori r10, r10, 0x2000 - xori r10, r10, 0x2000 - sync; isync; - mtspr SPRN_HID0, r10 - sync; isync; - - - /* return to C code */ - blr - - -_GLOBAL(mpc52xx_ds_sram) -mpc52xx_ds_sram: - /* put SDRAM into self-refresh */ - lwz r8, 0x4(r4) /* sdram->ctrl */ - - oris r8, r8, 0x8000 /* mode_en */ - stw r8, 0x4(r4) - sync - - ori r8, r8, 0x0002 /* soft_pre */ - stw r8, 0x4(r4) - sync - xori r8, r8, 0x0002 - - xoris r8, r8, 0x8000 /* !mode_en */ - stw r8, 0x4(r4) - sync - - oris r8, r8, 0x5000 - xoris r8, r8, 0x4000 /* ref_en !cke */ - stw r8, 0x4(r4) - sync - - /* disable SDRAM clock */ - lwz r8, 0x14(r5) /* cdm->clkenable */ - ori r8, r8, 0x0008 - xori r8, r8, 0x0008 - stw r8, 0x14(r5) - sync - - - /* put mpc5200 to sleep */ - mfmsr r10 - oris r10, r10, 0x0004 /* POW = 1 */ - sync; isync; - mtmsr r10 - sync; isync; - - - /* enable clock */ - lwz r8, 0x14(r5) - ori r8, r8, 0x0008 - stw r8, 0x14(r5) - sync - - /* get ram out of self-refresh */ - lwz r8, 0x4(r4) - oris r8, r8, 0x5000 /* cke ref_en */ - stw r8, 0x4(r4) - sync - - blr -_GLOBAL(mpc52xx_ds_sram_size) -mpc52xx_ds_sram_size: - .long $-mpc52xx_ds_sram - - -/* ### interrupt handler for wakeup from deep-sleep ### */ -_GLOBAL(mpc52xx_ds_cached) -mpc52xx_ds_cached: - mtspr SPRN_SPRG0, r7 - mtspr SPRN_SPRG1, r8 - - /* disable emulated interrupt */ - mfspr r7, 311 /* MBAR */ - addi r7, r7, 0x540 /* intr->main_emul */ - li r8, 0 - stw r8, 0(r7) - sync - dcbf 0, r7 - - /* acknowledge wakeup, so CCS releases power pown */ - mfspr r7, 311 /* MBAR */ - addi r7, r7, 0x524 /* intr->enc_status */ - lwz r8, 0(r7) - ori r8, r8, 0x0400 - stw r8, 0(r7) - sync - dcbf 0, r7 - - /* flag - we handled the interrupt */ - li r10, 1 - - mfspr r8, SPRN_SPRG1 - mfspr r7, SPRN_SPRG0 - - rfi -_GLOBAL(mpc52xx_ds_cached_size) -mpc52xx_ds_cached_size: - .long $-mpc52xx_ds_cached diff --git a/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c b/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c index 94843ed52a93..fff09f5d6edf 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -111,7 +111,6 @@ static struct of_device_id mpc832x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c index b0b22bb29de7..6b71e9ffb11a 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc832x_rdb.c @@ -73,7 +73,6 @@ static struct of_device_id mpc832x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/83xx/mpc836x_mds.c b/trunk/arch/powerpc/platforms/83xx/mpc836x_mds.c index bceeff8bbfd2..526ed090a446 100644 --- a/trunk/arch/powerpc/platforms/83xx/mpc836x_mds.c +++ b/trunk/arch/powerpc/platforms/83xx/mpc836x_mds.c @@ -118,7 +118,6 @@ static struct of_device_id mpc836x_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc8544_ds.c b/trunk/arch/powerpc/platforms/85xx/mpc8544_ds.c index bec84ffe708e..2867f85e6325 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc8544_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc8544_ds.c @@ -84,7 +84,7 @@ void __init mpc8544_ds_pic_init(void) #ifdef CONFIG_PPC_I8259 /* Initialize the i8259 controller */ for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "chrp,iic")) { + if (device_is_compatible(np, "chrp,iic")) { cascade_node = np; break; } diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 1490eb3ce0d3..7e71636f9098 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -197,7 +197,7 @@ static void __init mpc85xx_cds_pic_init(void) #ifdef CONFIG_PPC_I8259 /* Initialize the i8259 controller */ for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "chrp,iic")) { + if (device_is_compatible(np, "chrp,iic")) { cascade_node = np; break; } diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c index e3dddbfe66ff..54db41689954 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -147,7 +147,6 @@ static struct of_device_id mpc85xx_ids[] = { { .type = "soc", }, { .compatible = "soc", }, { .type = "qe", }, - { .type = "mdio", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 90877565caa3..3d3d98f5bd4a 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -102,7 +102,7 @@ mpc86xx_hpcn_init_irq(void) #ifdef CONFIG_PCI /* Initialize i8259 controller */ for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "chrp,iic")) { + if (device_is_compatible(np, "chrp,iic")) { cascade_node = np; break; } diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig index 361acfa2894c..51e33347c147 100644 --- a/trunk/arch/powerpc/platforms/Kconfig +++ b/trunk/arch/powerpc/platforms/Kconfig @@ -42,7 +42,6 @@ source "arch/powerpc/platforms/83xx/Kconfig" source "arch/powerpc/platforms/85xx/Kconfig" source "arch/powerpc/platforms/86xx/Kconfig" source "arch/powerpc/platforms/embedded6xx/Kconfig" -source "arch/powerpc/platforms/44x/Kconfig" #source "arch/powerpc/platforms/4xx/Kconfig config PPC_NATIVE diff --git a/trunk/arch/powerpc/platforms/Makefile b/trunk/arch/powerpc/platforms/Makefile index d6e041a46d25..452004283f17 100644 --- a/trunk/arch/powerpc/platforms/Makefile +++ b/trunk/arch/powerpc/platforms/Makefile @@ -6,8 +6,7 @@ obj-$(CONFIG_PPC_PMAC) += powermac/ endif endif obj-$(CONFIG_PPC_CHRP) += chrp/ -#obj-$(CONFIG_4xx) += 4xx/ -obj-$(CONFIG_44x) += 44x/ +obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_PPC_MPC52xx) += 52xx/ obj-$(CONFIG_PPC_8xx) += 8xx/ obj-$(CONFIG_PPC_82xx) += 82xx/ diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index 47264e722029..4fc4e92775d0 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -227,7 +227,7 @@ void iic_request_IPIs(void) static int iic_host_match(struct irq_host *h, struct device_node *node) { - return of_device_is_compatible(node, + return device_is_compatible(node, "IBM,CBEA-Internal-Interrupt-Controller"); } @@ -256,7 +256,7 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct, unsigned int node, ext, unit, class; const u32 *val; - if (!of_device_is_compatible(ct, + if (!device_is_compatible(ct, "IBM,CBEA-Internal-Interrupt-Controller")) return -ENODEV; if (intsize != 1) @@ -324,7 +324,7 @@ static int __init setup_iic(void) for (dn = NULL; (dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) { - if (!of_device_is_compatible(dn, + if (!device_is_compatible(dn, "IBM,CBEA-Internal-Interrupt-Controller")) continue; np = of_get_property(dn, "ibm,interrupt-server-ranges", NULL); diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index db6654272e13..54b96183cb64 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -112,7 +112,7 @@ static void __init mpic_init_IRQ(void) for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { - if (!of_device_is_compatible(dn, "CBEA,platform-open-pic")) + if (!device_is_compatible(dn, "CBEA,platform-open-pic")) continue; /* The MPIC driver will get everything it needs from the diff --git a/trunk/arch/powerpc/platforms/cell/spider-pic.c b/trunk/arch/powerpc/platforms/cell/spider-pic.c index 05f4b3d3d756..fb1f15797bbb 100644 --- a/trunk/arch/powerpc/platforms/cell/spider-pic.c +++ b/trunk/arch/powerpc/platforms/cell/spider-pic.c @@ -358,12 +358,12 @@ void __init spider_init_IRQ(void) */ for (dn = NULL; (dn = of_find_node_by_name(dn, "interrupt-controller"));) { - if (of_device_is_compatible(dn, "CBEA,platform-spider-pic")) { + if (device_is_compatible(dn, "CBEA,platform-spider-pic")) { if (of_address_to_resource(dn, 0, &r)) { printk(KERN_WARNING "spider-pic: Failed\n"); continue; } - } else if (of_device_is_compatible(dn, "sti,platform-spider-pic") + } else if (device_is_compatible(dn, "sti,platform-spider-pic") && (chip < 2)) { static long hard_coded_pics[] = { 0x24000008000ul, 0x34000008000ul}; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c index d32db9ffc6eb..3322528fa6eb 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c index fc4ed1ffbd4f..428875c5e4ec 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index a93f328a7317..13e4f70ec8c0 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -71,7 +71,8 @@ spufs_init_once(void *p, struct kmem_cache * cachep, unsigned long flags) { struct spufs_inode_info *ei = p; - if (flags & SLAB_CTOR_CONSTRUCTOR) { + if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == + SLAB_CTOR_CONSTRUCTOR) { inode_init_once(&ei->vfs_inode); } } diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c index b6ecb30e7d58..91030b8abdca 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/sched.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index 29dc59cefc38..8347c4a3f894 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/powerpc/platforms/chrp/pci.c b/trunk/arch/powerpc/platforms/chrp/pci.c index d32fedc991d3..1469d6478f67 100644 --- a/trunk/arch/powerpc/platforms/chrp/pci.c +++ b/trunk/arch/powerpc/platforms/chrp/pci.c @@ -267,7 +267,7 @@ chrp_find_bridges(void) model = of_get_property(dev, "model", NULL); if (model == NULL) model = ""; - if (of_device_is_compatible(dev, "IBM,python")) { + if (device_is_compatible(dev, "IBM,python")) { setup_python(hose, dev); } else if (is_mot || strncmp(model, "Motorola, Grackle", 17) == 0) { diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 373de4c063db..1870038a8e0a 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -448,7 +448,7 @@ static void __init chrp_find_8259(void) /* Look for cascade */ for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "chrp,iic")) { + if (device_is_compatible(np, "chrp,iic")) { pic = np; break; } diff --git a/trunk/arch/powerpc/platforms/chrp/smp.c b/trunk/arch/powerpc/platforms/chrp/smp.c index 3ea0eb78568e..1d2307e87c30 100644 --- a/trunk/arch/powerpc/platforms/chrp/smp.c +++ b/trunk/arch/powerpc/platforms/chrp/smp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig index 8f3c2a73e165..9557908ef545 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig @@ -20,24 +20,16 @@ config MPC7448HPC2 select TSI108_BRIDGE select DEFAULT_UIMAGE select PPC_UDBG_16550 + select MPIC + select MPIC_WEIRD help Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) platform - -config PPC_HOLLY - bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)" - select TSI108_BRIDGE - select PPC_UDBG_16550 - help - Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval - Board with TSI108/9 bridge (Hickory/Holly) endchoice config TSI108_BRIDGE bool - depends on MPC7448HPC2 || PPC_HOLLY - select MPIC - select MPIC_WEIRD + depends on MPC7448HPC2 default y config MPC10X_BRIDGE diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Makefile b/trunk/arch/powerpc/platforms/embedded6xx/Makefile index b39fe4f470d5..d3d11a3cd656 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/Makefile +++ b/trunk/arch/powerpc/platforms/embedded6xx/Makefile @@ -3,4 +3,3 @@ # obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o -obj-$(CONFIG_PPC_HOLLY) += holly.o diff --git a/trunk/arch/powerpc/platforms/embedded6xx/holly.c b/trunk/arch/powerpc/platforms/embedded6xx/holly.c deleted file mode 100644 index 3a0b4a01401c..000000000000 --- a/trunk/arch/powerpc/platforms/embedded6xx/holly.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Board setup routines for the IBM 750GX/CL platform w/ TSI10x bridge - * - * Copyright 2007 IBM Corporation - * - * Stephen Winiecki - * Josh Boyer - * - * Based on code from mpc7448_hpc2.c - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG - -#define HOLLY_PCI_CFG_PHYS 0x7c000000 - -int holly_exclude_device(u_char bus, u_char devfn) -{ - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - else - return PCIBIOS_SUCCESSFUL; -} - -static void holly_remap_bridge(void) -{ - u32 lut_val, lut_addr; - int i; - - printk(KERN_INFO "Remapping PCI bridge\n"); - - /* Re-init the PCI bridge and LUT registers to have mappings that don't - * rely on PIBS - */ - lut_addr = 0x900; - for (i = 0; i < 31; i++) { - tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000201); - lut_addr += 4; - tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0); - lut_addr += 4; - } - - /* Reserve the last LUT entry for PCI I/O space */ - tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000241); - lut_addr += 4; - tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0); - - /* Map PCI I/O space */ - tsi108_write_reg(TSI108_PCI_PFAB_IO_UPPER, 0x0); - tsi108_write_reg(TSI108_PCI_PFAB_IO, 0x1); - - /* Map PCI CFG space */ - tsi108_write_reg(TSI108_PCI_PFAB_BAR0_UPPER, 0x0); - tsi108_write_reg(TSI108_PCI_PFAB_BAR0, 0x7c000000 | 0x01); - - /* We don't need MEM32 and PRM remapping so disable them */ - tsi108_write_reg(TSI108_PCI_PFAB_MEM32, 0x0); - tsi108_write_reg(TSI108_PCI_PFAB_PFM3, 0x0); - tsi108_write_reg(TSI108_PCI_PFAB_PFM4, 0x0); - - /* Set P2O_BAR0 */ - tsi108_write_reg(TSI108_PCI_P2O_BAR0_UPPER, 0x0); - tsi108_write_reg(TSI108_PCI_P2O_BAR0, 0xc0000000); - - /* Init the PCI LUTs to do no remapping */ - lut_addr = 0x500; - lut_val = 0x00000002; - - for (i = 0; i < 32; i++) { - tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, lut_val); - lut_addr += 4; - tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, 0x40000000); - lut_addr += 4; - lut_val += 0x02000000; - } - tsi108_write_reg(TSI108_PCI_P2O_PAGE_SIZES, 0x00007900); - - /* Set 64-bit PCI bus address for system memory */ - tsi108_write_reg(TSI108_PCI_P2O_BAR2_UPPER, 0x0); - tsi108_write_reg(TSI108_PCI_P2O_BAR2, 0x0); -} - -static void __init holly_setup_arch(void) -{ - struct device_node *cpu; - struct device_node *np; - - if (ppc_md.progress) - ppc_md.progress("holly_setup_arch():set_bridge", 0); - - cpu = of_find_node_by_type(NULL, "cpu"); - if (cpu) { - const unsigned int *fp; - - fp = of_get_property(cpu, "clock-frequency", NULL); - if (fp) - loops_per_jiffy = *fp / HZ; - else - loops_per_jiffy = 50000000 / HZ; - of_node_put(cpu); - } - tsi108_csr_vir_base = get_vir_csrbase(); - - /* setup PCI host bridge */ - holly_remap_bridge(); - - np = of_find_node_by_type(NULL, "pci"); - if (np) - tsi108_setup_pci(np, HOLLY_PCI_CFG_PHYS, 1); - - ppc_md.pci_exclude_device = holly_exclude_device; - if (ppc_md.progress) - ppc_md.progress("tsi108: resources set", 0x100); - - printk(KERN_INFO "PPC750GX/CL Platform\n"); -} - -/* - * Interrupt setup and service. Interrrupts on the holly come - * from the four external INT pins, PCI interrupts are routed via - * PCI interrupt control registers, it generates internal IRQ23 - * - * Interrupt routing on the Holly Board: - * TSI108:PB_INT[0] -> CPU0:INT# - * TSI108:PB_INT[1] -> CPU0:MCP# - * TSI108:PB_INT[2] -> N/C - * TSI108:PB_INT[3] -> N/C - */ -static void __init holly_init_IRQ(void) -{ - struct mpic *mpic; - phys_addr_t mpic_paddr = 0; - struct device_node *tsi_pic; -#ifdef CONFIG_PCI - unsigned int cascade_pci_irq; - struct device_node *tsi_pci; - struct device_node *cascade_node = NULL; -#endif - - tsi_pic = of_find_node_by_type(NULL, "open-pic"); - if (tsi_pic) { - unsigned int size; - const void *prop = of_get_property(tsi_pic, "reg", &size); - mpic_paddr = of_translate_address(tsi_pic, prop); - } - - if (mpic_paddr == 0) { - printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__); - return; - } - - pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr); - - mpic = mpic_alloc(tsi_pic, mpic_paddr, - MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | - MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, - 24, - NR_IRQS-4, /* num_sources used */ - "Tsi108_PIC"); - - BUG_ON(mpic == NULL); - - mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); - - mpic_init(mpic); - -#ifdef CONFIG_PCI - tsi_pci = of_find_node_by_type(NULL, "pci"); - if (tsi_pci == NULL) { - printk(KERN_ERR "%s: No tsi108 pci node found !\n", __func__); - return; - } - - cascade_node = of_find_node_by_type(NULL, "pic-router"); - if (cascade_node == NULL) { - printk(KERN_ERR "%s: No tsi108 pci cascade node found !\n", __func__); - return; - } - - cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0); - pr_debug("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq); - tsi108_pci_int_init(cascade_node); - set_irq_data(cascade_pci_irq, mpic); - set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade); -#endif - /* Configure MPIC outputs to CPU0 */ - tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); - of_node_put(tsi_pic); -} - -void holly_show_cpuinfo(struct seq_file *m) -{ - seq_printf(m, "vendor\t\t: IBM\n"); - seq_printf(m, "machine\t\t: PPC750 GX/CL\n"); -} - -void holly_restart(char *cmd) -{ - __be32 __iomem *ocn_bar1 = NULL; - unsigned long bar; - struct device_node *bridge = NULL; - const void *prop; - int size; - phys_addr_t addr = 0xc0000000; - - local_irq_disable(); - - bridge = of_find_node_by_type(NULL, "tsi-bridge"); - if (bridge) { - prop = of_get_property(bridge, "reg", &size); - addr = of_translate_address(bridge, prop); - } - addr += (TSI108_PB_OFFSET + 0x414); - - ocn_bar1 = ioremap(addr, 0x4); - - /* Turn on the BOOT bit so the addresses are correctly - * routed to the HLP interface */ - bar = ioread32be(ocn_bar1); - bar |= 2; - iowrite32be(bar, ocn_bar1); - iosync(); - - /* Set SRR0 to the reset vector and turn on MSR_IP */ - mtspr(SPRN_SRR0, 0xfff00100); - mtspr(SPRN_SRR1, MSR_IP); - - /* Do an rfi to jump back to firmware. Somewhat evil, - * but it works - */ - __asm__ __volatile__("rfi" : : : "memory"); - - /* Spin until reset happens. Shouldn't really get here */ - for (;;) ; -} - -void holly_power_off(void) -{ - local_irq_disable(); - /* No way to shut power off with software */ - for (;;) ; -} - -void holly_halt(void) -{ - holly_power_off(); -} - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init holly_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - if (!of_flat_dt_is_compatible(root, "ibm,holly")) - return 0; - return 1; -} - -static int ppc750_machine_check_exception(struct pt_regs *regs) -{ - const struct exception_table_entry *entry; - - /* Are we prepared to handle this fault */ - if ((entry = search_exception_tables(regs->nip)) != NULL) { - tsi108_clear_pci_cfg_error(); - regs->msr |= MSR_RI; - regs->nip = entry->fixup; - return 1; - } - return 0; -} - -define_machine(holly){ - .name = "PPC750 GX/CL TSI", - .probe = holly_probe, - .setup_arch = holly_setup_arch, - .init_IRQ = holly_init_IRQ, - .show_cpuinfo = holly_show_cpuinfo, - .get_irq = mpic_get_irq, - .restart = holly_restart, - .calibrate_decr = generic_calibrate_decr, - .machine_check_exception = ppc750_machine_check_exception, - .progress = udbg_progress, -}; diff --git a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 4542e0c837c0..c3f64ddb0be6 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -41,7 +41,6 @@ #include #include #include "mpc7448_hpc2.h" -#include #include #include @@ -52,15 +51,16 @@ #define DBG(fmt...) do { } while(0) #endif -#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000 - #ifndef CONFIG_PCI isa_io_base = MPC7448_HPC2_ISA_IO_BASE; isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE; pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; #endif +extern int tsi108_setup_pci(struct device_node *dev); extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); +extern void tsi108_pci_int_init(struct device_node *node); +extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc); int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) { @@ -72,16 +72,28 @@ int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) static void __init mpc7448_hpc2_setup_arch(void) { + struct device_node *cpu; struct device_node *np; if (ppc_md.progress) ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0); + cpu = of_find_node_by_type(NULL, "cpu"); + if (cpu != 0) { + const unsigned int *fp; + + fp = of_get_property(cpu, "clock-frequency", NULL); + if (fp != 0) + loops_per_jiffy = *fp / HZ; + else + loops_per_jiffy = 50000000 / HZ; + of_node_put(cpu); + } tsi108_csr_vir_base = get_vir_csrbase(); /* setup PCI host bridge */ #ifdef CONFIG_PCI for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) - tsi108_setup_pci(np, MPC7448HPC2_PCI_CFG_PHYS, 0); + tsi108_setup_pci(np); ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device; if (ppc_md.progress) @@ -210,6 +222,7 @@ static int __init mpc7448_hpc2_probe(void) static int mpc7448_machine_check_exception(struct pt_regs *regs) { + extern void tsi108_clear_pci_cfg_error(void); const struct exception_table_entry *entry; /* Are we prepared to handle this fault */ diff --git a/trunk/arch/powerpc/platforms/iseries/smp.c b/trunk/arch/powerpc/platforms/iseries/smp.c index 722335e32fd4..aee5908df700 100644 --- a/trunk/arch/powerpc/platforms/iseries/smp.c +++ b/trunk/arch/powerpc/platforms/iseries/smp.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/iseries/viopath.c b/trunk/arch/powerpc/platforms/iseries/viopath.c index 354b8dd2a2c1..2ca2d8a9de97 100644 --- a/trunk/arch/powerpc/platforms/iseries/viopath.c +++ b/trunk/arch/powerpc/platforms/iseries/viopath.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/powerpc/platforms/maple/pci.c b/trunk/arch/powerpc/platforms/maple/pci.c index 7aaa5bbc9363..b1d3b99c3f9d 100644 --- a/trunk/arch/powerpc/platforms/maple/pci.c +++ b/trunk/arch/powerpc/platforms/maple/pci.c @@ -467,15 +467,15 @@ static int __init add_bridge(struct device_node *dev) hose->last_busno = bus_range ? bus_range[1] : 0xff; disp_name = NULL; - if (of_device_is_compatible(dev, "u3-agp")) { + if (device_is_compatible(dev, "u3-agp")) { setup_u3_agp(hose); disp_name = "U3-AGP"; primary = 0; - } else if (of_device_is_compatible(dev, "u3-ht")) { + } else if (device_is_compatible(dev, "u3-ht")) { setup_u3_ht(hose); disp_name = "U3-HT"; primary = 1; - } else if (of_device_is_compatible(dev, "u4-pcie")) { + } else if (device_is_compatible(dev, "u4-pcie")) { setup_u4_pcie(hose); disp_name = "U4-PCIE"; primary = 0; @@ -556,12 +556,12 @@ void __init maple_pci_init(void) continue; if (strcmp(np->type, "pci") && strcmp(np->type, "ht")) continue; - if ((of_device_is_compatible(np, "u4-pcie") || - of_device_is_compatible(np, "u3-agp")) && + if ((device_is_compatible(np, "u4-pcie") || + device_is_compatible(np, "u3-agp")) && add_bridge(np) == 0) of_node_get(np); - if (of_device_is_compatible(np, "u3-ht")) { + if (device_is_compatible(np, "u3-ht")) { of_node_get(np); ht = np; } diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index 354c05861629..2a30c5b2532e 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -231,7 +231,7 @@ static void __init maple_init_IRQ(void) */ for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "open-pic")) { + if (device_is_compatible(np, "open-pic")) { mpic_node = np; break; } diff --git a/trunk/arch/powerpc/platforms/pasemi/cpufreq.c b/trunk/arch/powerpc/platforms/pasemi/cpufreq.c index 3ae083851b01..2a57d6023685 100644 --- a/trunk/arch/powerpc/platforms/pasemi/cpufreq.c +++ b/trunk/arch/powerpc/platforms/pasemi/cpufreq.c @@ -31,7 +31,6 @@ #include #include #include -#include #define SDCASR_REG 0x0100 #define SDCASR_REG_STRIDE 0x1000 @@ -205,8 +204,6 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cur = pas_freqs[cur_astate].frequency; policy->cpus = cpu_online_map; - ppc_proc_freq = policy->cur * 1000ul; - cpufreq_frequency_table_get_attr(pas_freqs, policy->cpu); /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max @@ -273,7 +270,6 @@ static int pas_cpufreq_target(struct cpufreq_policy *policy, cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); mutex_unlock(&pas_switch_mutex); - ppc_proc_freq = freqs.new * 1000ul; return 0; } diff --git a/trunk/arch/powerpc/platforms/pasemi/pci.c b/trunk/arch/powerpc/platforms/pasemi/pci.c index bbc6dfcfaa91..056243da360b 100644 --- a/trunk/arch/powerpc/platforms/pasemi/pci.c +++ b/trunk/arch/powerpc/platforms/pasemi/pci.c @@ -173,6 +173,19 @@ static void __init pas_fixup_phb_resources(void) } +void __devinit pas_pci_irq_fixup(struct pci_dev *dev) +{ + /* DMA is special, 84 interrupts (128 -> 211), all but 128 + * need to be mapped by hand here. + */ + if (dev->vendor == 0x1959 && dev->device == 0xa007) { + int i; + for (i = 129; i < 212; i++) + irq_create_mapping(NULL, i); + } +} + + void __init pas_pci_init(void) { struct device_node *np, *root; diff --git a/trunk/arch/powerpc/platforms/pasemi/setup.c b/trunk/arch/powerpc/platforms/pasemi/setup.c index c5a3f61f8d85..f88f0ec4c8cb 100644 --- a/trunk/arch/powerpc/platforms/pasemi/setup.c +++ b/trunk/arch/powerpc/platforms/pasemi/setup.c @@ -114,7 +114,7 @@ static __init void pas_init_IRQ(void) mpic_node = NULL; for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "open-pic")) { + if (device_is_compatible(np, "open-pic")) { mpic_node = np; break; } @@ -211,10 +211,7 @@ static struct of_device_id pasemi_bus_ids[] = { static int __init pasemi_publish_devices(void) { - if (!machine_is(pasemi)) - return 0; - - /* Publish OF platform devices for SDC and other non-PCI devices */ + /* Publish OF platform devices for southbridge IOs */ of_platform_bus_probe(NULL, pasemi_bus_ids, NULL); return 0; @@ -251,4 +248,5 @@ define_machine(pas) { .calibrate_decr = generic_calibrate_decr, .progress = pas_progress, .machine_check_exception = pas_machine_check_handler, + .pci_irq_fixup = pas_pci_irq_fixup, }; diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c index 1fe35dab0e9e..8943a9456bb7 100644 --- a/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_32.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c index 00f50298c342..567d5523b690 100644 --- a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -357,13 +357,13 @@ static unsigned int g5_cpufreq_get_speed(unsigned int cpu) static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) { + if (policy->cpu != 0) + return -ENODEV; + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = g5_cpu_freqs[g5_query_freq()].frequency; - /* secondary CPUs are tied to the primary one by the - * cpufreq core if in the secondary policy we tell it that - * it actually must be one policy together with all others. */ - policy->cpus = cpu_online_map; + policy->cpus = cpu_possible_map; cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu); return cpufreq_frequency_table_cpuinfo(policy, diff --git a/trunk/arch/powerpc/platforms/powermac/feature.c b/trunk/arch/powerpc/platforms/powermac/feature.c index f29705f8047d..52cfdd86c928 100644 --- a/trunk/arch/powerpc/platforms/powermac/feature.c +++ b/trunk/arch/powerpc/platforms/powermac/feature.c @@ -1418,7 +1418,7 @@ static long g5_eth_phy_reset(struct device_node *node, long param, long value) phy = of_get_next_child(node, NULL); if (!phy) return -ENODEV; - need_reset = of_device_is_compatible(phy, "B5221"); + need_reset = device_is_compatible(phy, "B5221"); of_node_put(phy); if (!need_reset) return 0; @@ -2624,7 +2624,7 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) { if (!compat) break; - if (of_device_is_compatible(node, compat)) + if (device_is_compatible(node, compat)) break; } if (!node) @@ -2728,7 +2728,7 @@ initial_serial_shutdown(struct device_node *np) conn = of_get_property(np, "AAPL,connector", &len); if (conn && (strcmp(conn, "infrared") == 0)) port_type = PMAC_SCC_IRDA; - else if (of_device_is_compatible(np, "cobalt")) + else if (device_is_compatible(np, "cobalt")) modem = 1; else if (slots && slots->count > 0) { if (strcmp(slots->name, "IrDA") == 0) @@ -2787,7 +2787,7 @@ set_initial_features(void) */ np = of_find_node_by_name(NULL, "ethernet"); while(np) { - if (of_device_is_compatible(np, "K2-GMAC")) + if (device_is_compatible(np, "K2-GMAC")) g5_gmac_enable(np, 0, 1); np = of_find_node_by_name(np, "ethernet"); } @@ -2799,7 +2799,7 @@ set_initial_features(void) */ np = of_find_node_by_name(NULL, "firewire"); while(np) { - if (of_device_is_compatible(np, "pci106b,5811")) { + if (device_is_compatible(np, "pci106b,5811")) { macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; g5_fw_enable(np, 0, 1); } @@ -2817,8 +2817,8 @@ set_initial_features(void) np = of_find_node_by_name(NULL, "ethernet"); while(np) { if (np->parent - && of_device_is_compatible(np->parent, "uni-north") - && of_device_is_compatible(np, "gmac")) + && device_is_compatible(np->parent, "uni-north") + && device_is_compatible(np, "gmac")) core99_gmac_enable(np, 0, 1); np = of_find_node_by_name(np, "ethernet"); } @@ -2831,10 +2831,10 @@ set_initial_features(void) np = of_find_node_by_name(NULL, "firewire"); while(np) { if (np->parent - && of_device_is_compatible(np->parent, "uni-north") - && (of_device_is_compatible(np, "pci106b,18") || - of_device_is_compatible(np, "pci106b,30") || - of_device_is_compatible(np, "pci11c1,5811"))) { + && device_is_compatible(np->parent, "uni-north") + && (device_is_compatible(np, "pci106b,18") || + device_is_compatible(np, "pci106b,30") || + device_is_compatible(np, "pci11c1,5811"))) { macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED; core99_firewire_enable(np, 0, 1); } @@ -2845,8 +2845,8 @@ set_initial_features(void) np = of_find_node_by_name(NULL, "ata-6"); while(np) { if (np->parent - && of_device_is_compatible(np->parent, "uni-north") - && of_device_is_compatible(np, "kauai-ata")) { + && device_is_compatible(np->parent, "uni-north") + && device_is_compatible(np, "kauai-ata")) { core99_ata100_enable(np, 1); } np = of_find_node_by_name(np, "ata-6"); diff --git a/trunk/arch/powerpc/platforms/powermac/low_i2c.c b/trunk/arch/powerpc/platforms/powermac/low_i2c.c index 3f507ab9c5e5..5430e146b3e9 100644 --- a/trunk/arch/powerpc/platforms/powermac/low_i2c.c +++ b/trunk/arch/powerpc/platforms/powermac/low_i2c.c @@ -1207,7 +1207,7 @@ static void pmac_i2c_devscan(void (*callback)(struct device_node *dev, if (strcmp(np->name, p->name)) continue; if (p->compatible && - !of_device_is_compatible(np, p->compatible)) + !device_is_compatible(np, p->compatible)) continue; if (p->quirks & pmac_i2c_quirk_skip) break; diff --git a/trunk/arch/powerpc/platforms/powermac/nvram.c b/trunk/arch/powerpc/platforms/powermac/nvram.c index c6f0f9e738e5..692945c14919 100644 --- a/trunk/arch/powerpc/platforms/powermac/nvram.c +++ b/trunk/arch/powerpc/platforms/powermac/nvram.c @@ -553,7 +553,7 @@ static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr) * identify the chip using flash id commands and base ourselves on * a list of known chips IDs */ - if (of_device_is_compatible(dp, "amd-0137")) { + if (device_is_compatible(dp, "amd-0137")) { core99_erase_bank = amd_erase_bank; core99_write_bank = amd_write_bank; } else { @@ -588,7 +588,7 @@ int __init pmac_nvram_init(void) } } - is_core_99 = of_device_is_compatible(dp, "nvram,flash"); + is_core_99 = device_is_compatible(dp, "nvram,flash"); if (is_core_99) { err = core99_nvram_setup(dp, r1.start); goto bail; diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c index c4af9e21ac93..22c4ae4c6934 100644 --- a/trunk/arch/powerpc/platforms/powermac/pci.c +++ b/trunk/arch/powerpc/platforms/powermac/pci.c @@ -934,15 +934,15 @@ static int __init add_bridge(struct device_node *dev) /* 64 bits only bridges */ #ifdef CONFIG_PPC64 - if (of_device_is_compatible(dev, "u3-agp")) { + if (device_is_compatible(dev, "u3-agp")) { setup_u3_agp(hose); disp_name = "U3-AGP"; primary = 0; - } else if (of_device_is_compatible(dev, "u3-ht")) { + } else if (device_is_compatible(dev, "u3-ht")) { setup_u3_ht(hose); disp_name = "U3-HT"; primary = 1; - } else if (of_device_is_compatible(dev, "u4-pcie")) { + } else if (device_is_compatible(dev, "u4-pcie")) { setup_u4_pcie(hose); disp_name = "U4-PCIE"; primary = 0; @@ -953,7 +953,7 @@ static int __init add_bridge(struct device_node *dev) /* 32 bits only bridges */ #ifdef CONFIG_PPC32 - if (of_device_is_compatible(dev, "uni-north")) { + if (device_is_compatible(dev, "uni-north")) { primary = setup_uninorth(hose, &rsrc); disp_name = "UniNorth"; } else if (strcmp(dev->name, "pci") == 0) { @@ -1129,21 +1129,21 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) return 0; uninorth_child = node->parent && - of_device_is_compatible(node->parent, "uni-north"); + device_is_compatible(node->parent, "uni-north"); /* Firewire & GMAC were disabled after PCI probe, the driver is * claiming them, we must re-enable them now. */ if (uninorth_child && !strcmp(node->name, "firewire") && - (of_device_is_compatible(node, "pci106b,18") || - of_device_is_compatible(node, "pci106b,30") || - of_device_is_compatible(node, "pci11c1,5811"))) { + (device_is_compatible(node, "pci106b,18") || + device_is_compatible(node, "pci106b,30") || + device_is_compatible(node, "pci11c1,5811"))) { pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1); pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1); updatecfg = 1; } if (uninorth_child && !strcmp(node->name, "ethernet") && - of_device_is_compatible(node, "gmac")) { + device_is_compatible(node, "gmac")) { pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1); updatecfg = 1; } @@ -1203,18 +1203,18 @@ void __init pmac_pcibios_after_init(void) #endif /* CONFIG_BLK_DEV_IDE */ for_each_node_by_name(nd, "firewire") { - if (nd->parent && (of_device_is_compatible(nd, "pci106b,18") || - of_device_is_compatible(nd, "pci106b,30") || - of_device_is_compatible(nd, "pci11c1,5811")) - && of_device_is_compatible(nd->parent, "uni-north")) { + if (nd->parent && (device_is_compatible(nd, "pci106b,18") || + device_is_compatible(nd, "pci106b,30") || + device_is_compatible(nd, "pci11c1,5811")) + && device_is_compatible(nd->parent, "uni-north")) { pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0); pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0); } } of_node_put(nd); for_each_node_by_name(nd, "ethernet") { - if (nd->parent && of_device_is_compatible(nd, "gmac") - && of_device_is_compatible(nd->parent, "uni-north")) + if (nd->parent && device_is_compatible(nd, "gmac") + && device_is_compatible(nd->parent, "uni-north")) pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0); } of_node_put(nd); diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 87cd6805171a..ae5097ac0378 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -364,7 +364,7 @@ static void __init pmac_pic_probe_oldstyle(void) slave = of_find_node_by_name(master, "mac-io"); /* Check ordering of master & slave */ - if (of_device_is_compatible(master, "gatwick")) { + if (device_is_compatible(master, "gatwick")) { struct device_node *tmp; BUG_ON(slave == NULL); tmp = master; diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index a410bc76a8a8..b820cabac697 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -439,14 +439,76 @@ static void __init find_boot_device(void) #endif } +/* TODO: Merge the suspend-to-ram with the common code !!! + * currently, this is a stub implementation for suspend-to-disk + * only + */ + +#ifdef CONFIG_SOFTWARE_SUSPEND + +static int pmac_pm_prepare(suspend_state_t state) +{ + printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); + + return 0; +} + +static int pmac_pm_enter(suspend_state_t state) +{ + printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); + + /* Giveup the lazy FPU & vec so we don't have to back them + * up from the low level code + */ + enable_kernel_fp(); + +#ifdef CONFIG_ALTIVEC + if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) + enable_kernel_altivec(); +#endif /* CONFIG_ALTIVEC */ + + return 0; +} + +static int pmac_pm_finish(suspend_state_t state) +{ + printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); + + /* Restore userland MMU context */ + set_context(current->active_mm->context.id, current->active_mm->pgd); + + return 0; +} + +static int pmac_pm_valid(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_DISK: + return 1; + /* can't do any other states via generic mechanism yet */ + default: + return 0; + } +} + +static struct pm_ops pmac_pm_ops = { + .pm_disk_mode = PM_DISK_SHUTDOWN, + .prepare = pmac_pm_prepare, + .enter = pmac_pm_enter, + .finish = pmac_pm_finish, + .valid = pmac_pm_valid, +}; + +#endif /* CONFIG_SOFTWARE_SUSPEND */ + static int initializing = 1; static int pmac_late_init(void) { initializing = 0; - /* this is udbg (which is __init) and we can later use it during - * cpu hotplug (in smp_core99_kick_cpu) */ - ppc_md.progress = NULL; +#ifdef CONFIG_SOFTWARE_SUSPEND + pm_set_ops(&pmac_pm_ops); +#endif /* CONFIG_SOFTWARE_SUSPEND */ return 0; } @@ -659,57 +721,12 @@ static int pmac_pci_probe_mode(struct pci_bus *bus) /* We need to use normal PCI probing for the AGP bus, * since the device for the AGP bridge isn't in the tree. */ - if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") || - of_device_is_compatible(node, "u4-pcie"))) + if (bus->self == NULL && (device_is_compatible(node, "u3-agp") || + device_is_compatible(node, "u4-pcie"))) return PCI_PROBE_NORMAL; return PCI_PROBE_DEVTREE; } - -#ifdef CONFIG_HOTPLUG_CPU -/* access per cpu vars from generic smp.c */ -DECLARE_PER_CPU(int, cpu_state); - -static void pmac_cpu_die(void) -{ - /* - * turn off as much as possible, we'll be - * kicked out as this will only be invoked - * on core99 platforms for now ... - */ - - printk(KERN_INFO "CPU#%d offline\n", smp_processor_id()); - __get_cpu_var(cpu_state) = CPU_DEAD; - smp_wmb(); - - /* - * during the path that leads here preemption is disabled, - * reenable it now so that when coming up preempt count is - * zero correctly - */ - preempt_enable(); - - /* - * hard-disable interrupts for the non-NAP case, the NAP code - * needs to re-enable interrupts (but soft-disables them) - */ - hard_irq_disable(); - - while (1) { - /* let's not take timer interrupts too often ... */ - set_dec(0x7fffffff); - - /* should always be true at this point */ - if (cpu_has_feature(CPU_FTR_CAN_NAP)) - power4_cpu_offline_powersave(); - else { - HMT_low(); - HMT_very_low(); - } - } -} -#endif /* CONFIG_HOTPLUG_CPU */ - -#endif /* CONFIG_PPC64 */ +#endif define_machine(powermac) { .name = "PowerMac", @@ -746,6 +763,6 @@ define_machine(powermac) { .phys_mem_access_prot = pci_phys_mem_access_prot, #endif #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64) - .cpu_die = pmac_cpu_die, + .cpu_die = generic_mach_cpu_die, #endif }; diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index 686ed82bde79..6f32c4eca6e5 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -561,7 +562,7 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus) /* Look for the clock chip */ while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) { p = of_get_parent(cc); - ok = p && of_device_is_compatible(p, "uni-n-i2c"); + ok = p && device_is_compatible(p, "uni-n-i2c"); of_node_put(p); if (!ok) continue; @@ -574,11 +575,11 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus) continue; switch (*reg) { case 0xd2: - if (of_device_is_compatible(cc,"pulsar-legacy-slewing")) { + if (device_is_compatible(cc,"pulsar-legacy-slewing")) { pmac_tb_freeze = smp_core99_pulsar_tb_freeze; pmac_tb_pulsar_addr = 0xd2; name = "Pulsar"; - } else if (of_device_is_compatible(cc, "cy28508")) { + } else if (device_is_compatible(cc, "cy28508")) { pmac_tb_freeze = smp_core99_cypress_tb_freeze; name = "Cypress"; } @@ -899,7 +900,7 @@ void smp_core99_cpu_die(unsigned int cpu) cpu_dead[cpu] = 0; } -#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */ +#endif /* Core99 Macs (dual G4s and G5s) */ struct smp_ops_t core99_smp_ops = { @@ -909,16 +910,8 @@ struct smp_ops_t core99_smp_ops = { .setup_cpu = smp_core99_setup_cpu, .give_timebase = smp_core99_give_timebase, .take_timebase = smp_core99_take_timebase, -#if defined(CONFIG_HOTPLUG_CPU) -# if defined(CONFIG_PPC32) +#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32) .cpu_disable = smp_core99_cpu_disable, .cpu_die = smp_core99_cpu_die, -# endif -# if defined(CONFIG_PPC64) - .cpu_disable = generic_cpu_disable, - .cpu_die = generic_cpu_die, - /* intentionally do *NOT* assign cpu_enable, - * the generic code will use kick_cpu then! */ -# endif #endif }; diff --git a/trunk/arch/powerpc/platforms/ps3/htab.c b/trunk/arch/powerpc/platforms/ps3/htab.c index a1409e450c70..ea60c451cf87 100644 --- a/trunk/arch/powerpc/platforms/ps3/htab.c +++ b/trunk/arch/powerpc/platforms/ps3/htab.c @@ -273,8 +273,7 @@ void __init ps3_map_htab(void) result = lv1_map_htab(0, &htab_addr); - htab = (hpte_t *)__ioremap(htab_addr, htab_size, - pgprot_val(PAGE_READONLY_X)); + htab = (hpte_t *)__ioremap(htab_addr, htab_size, PAGE_READONLY_X); DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__, htab_addr, (unsigned long)htab); diff --git a/trunk/arch/powerpc/platforms/ps3/interrupt.c b/trunk/arch/powerpc/platforms/ps3/interrupt.c index 9da82c266ba9..631c30095617 100644 --- a/trunk/arch/powerpc/platforms/ps3/interrupt.c +++ b/trunk/arch/powerpc/platforms/ps3/interrupt.c @@ -89,18 +89,7 @@ struct ps3_private { static DEFINE_PER_CPU(struct ps3_private, ps3_private); -/** - * ps3_virq_setup - virq related setup. - * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be - * serviced on. - * @outlet: The HV outlet from the various create outlet routines. - * @virq: The assigned Linux virq. - * - * Calls irq_create_mapping() to get a virq and sets the chip data to - * ps3_private data. - */ - -int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, +int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet, unsigned int *virq) { int result; @@ -122,6 +111,17 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, goto fail_create; } + /* Binds outlet to cpu + virq. */ + + result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); + + if (result) { + pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", + __func__, __LINE__, ps3_result(result)); + result = -EPERM; + goto fail_connect; + } + pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, outlet, cpu, *virq); @@ -136,118 +136,94 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, return result; fail_set: + lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq); +fail_connect: irq_dispose_mapping(*virq); fail_create: return result; } +EXPORT_SYMBOL_GPL(ps3_alloc_irq); -/** - * ps3_virq_destroy - virq related teardown. - * @virq: The assigned Linux virq. - * - * Clears chip data and calls irq_dispose_mapping() for the virq. - */ - -int ps3_virq_destroy(unsigned int virq) +int ps3_free_irq(unsigned int virq) { + int result; const struct ps3_private *pd = get_irq_chip_data(virq); pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, pd->node, pd->cpu, virq); + result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); + + if (result) + pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", + __func__, __LINE__, ps3_result(result)); + set_irq_chip_data(virq, NULL); irq_dispose_mapping(virq); - - pr_debug("%s:%d <-\n", __func__, __LINE__); - return 0; + return result; } +EXPORT_SYMBOL_GPL(ps3_free_irq); /** - * ps3_irq_plug_setup - Generic outlet and virq related setup. + * ps3_alloc_io_irq - Assign a virq to a system bus device. * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be * serviced on. - * @outlet: The HV outlet from the various create outlet routines. + * @interrupt_id: The device interrupt id read from the system repository. * @virq: The assigned Linux virq. * - * Sets up virq and connects the irq plug. + * An io irq represents a non-virtualized device interrupt. interrupt_id + * coresponds to the interrupt number of the interrupt controller. */ -int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, +int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id, unsigned int *virq) { int result; - struct ps3_private *pd; - - result = ps3_virq_setup(cpu, outlet, virq); - - if (result) { - pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); - goto fail_setup; - } - - pd = get_irq_chip_data(*virq); - - /* Binds outlet to cpu + virq. */ + unsigned long outlet; - result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0); + result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); if (result) { - pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", - __func__, __LINE__, ps3_result(result)); - result = -EPERM; - goto fail_connect; + pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", + __func__, __LINE__, ps3_result(result)); + return result; } - return result; + result = ps3_alloc_irq(cpu, outlet, virq); + BUG_ON(result); -fail_connect: - ps3_virq_destroy(*virq); -fail_setup: return result; } -EXPORT_SYMBOL_GPL(ps3_irq_plug_setup); - -/** - * ps3_irq_plug_destroy - Generic outlet and virq related teardown. - * @virq: The assigned Linux virq. - * - * Disconnects the irq plug and tears down virq. - * Do not call for system bus event interrupts setup with - * ps3_sb_event_receive_port_setup(). - */ +EXPORT_SYMBOL_GPL(ps3_alloc_io_irq); -int ps3_irq_plug_destroy(unsigned int virq) +int ps3_free_io_irq(unsigned int virq) { int result; - const struct ps3_private *pd = get_irq_chip_data(virq); - pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__, - pd->node, pd->cpu, virq); - - result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq); + result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); if (result) - pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n", - __func__, __LINE__, ps3_result(result)); + pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", + __func__, __LINE__, ps3_result(result)); - ps3_virq_destroy(virq); + ps3_free_irq(virq); return result; } -EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy); +EXPORT_SYMBOL_GPL(ps3_free_io_irq); /** - * ps3_event_receive_port_setup - Setup an event receive port. + * ps3_alloc_event_irq - Allocate a virq for use with a system event. * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be * serviced on. * @virq: The assigned Linux virq. * * The virq can be used with lv1_connect_interrupt_event_receive_port() to - * arrange to receive interrupts from system-bus devices, or with - * ps3_send_event_locally() to signal events. + * arrange to receive events, or with ps3_send_event_locally() to signal + * events. */ -int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) +int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq) { int result; unsigned long outlet; @@ -261,27 +237,17 @@ int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq) return result; } - result = ps3_irq_plug_setup(cpu, outlet, virq); + result = ps3_alloc_irq(cpu, outlet, virq); BUG_ON(result); return result; } -EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup); - -/** - * ps3_event_receive_port_destroy - Destroy an event receive port. - * @virq: The assigned Linux virq. - * - * Since ps3_event_receive_port_destroy destroys the receive port outlet, - * SB devices need to call disconnect_interrupt_event_receive_port() before - * this. - */ -int ps3_event_receive_port_destroy(unsigned int virq) +int ps3_free_event_irq(unsigned int virq) { int result; - pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq); + pr_debug(" -> %s:%d\n", __func__, __LINE__); result = lv1_destruct_event_receive_port(virq_to_hw(virq)); @@ -289,17 +255,11 @@ int ps3_event_receive_port_destroy(unsigned int virq) pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", __func__, __LINE__, ps3_result(result)); - /* lv1_destruct_event_receive_port() destroys the IRQ plug, - * so don't call ps3_irq_plug_destroy() here. - */ - - result = ps3_virq_destroy(virq); - BUG_ON(result); + ps3_free_irq(virq); pr_debug(" <- %s:%d\n", __func__, __LINE__); return result; } -EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy); int ps3_send_event_locally(unsigned int virq) { @@ -307,7 +267,7 @@ int ps3_send_event_locally(unsigned int virq) } /** - * ps3_sb_event_receive_port_setup - Setup a system bus event receive port. + * ps3_connect_event_irq - Assign a virq to a system bus device. * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be * serviced on. * @did: The HV device identifier read from the system repository. @@ -318,15 +278,13 @@ int ps3_send_event_locally(unsigned int virq) * coresponds to the software interrupt number. */ -int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, +int ps3_connect_event_irq(enum ps3_cpu_binding cpu, const struct ps3_device_id *did, unsigned int interrupt_id, unsigned int *virq) { - /* this should go in system-bus.c */ - int result; - result = ps3_event_receive_port_setup(cpu, virq); + result = ps3_alloc_event_irq(cpu, virq); if (result) return result; @@ -338,7 +296,7 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" " failed: %s\n", __func__, __LINE__, ps3_result(result)); - ps3_event_receive_port_destroy(*virq); + ps3_free_event_irq(*virq); *virq = NO_IRQ; return result; } @@ -348,13 +306,10 @@ int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu, return 0; } -EXPORT_SYMBOL(ps3_sb_event_receive_port_setup); -int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, +int ps3_disconnect_event_irq(const struct ps3_device_id *did, unsigned int interrupt_id, unsigned int virq) { - /* this should go in system-bus.c */ - int result; pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, @@ -368,65 +323,14 @@ int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did, " failed: %s\n", __func__, __LINE__, ps3_result(result)); - result = ps3_event_receive_port_destroy(virq); - BUG_ON(result); + ps3_free_event_irq(virq); pr_debug(" <- %s:%d\n", __func__, __LINE__); return result; } -EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy); /** - * ps3_io_irq_setup - Setup a system bus io irq. - * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be - * serviced on. - * @interrupt_id: The device interrupt id read from the system repository. - * @virq: The assigned Linux virq. - * - * An io irq represents a non-virtualized device interrupt. interrupt_id - * coresponds to the interrupt number of the interrupt controller. - */ - -int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, - unsigned int *virq) -{ - int result; - unsigned long outlet; - - result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); - - if (result) { - pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", - __func__, __LINE__, ps3_result(result)); - return result; - } - - result = ps3_irq_plug_setup(cpu, outlet, virq); - BUG_ON(result); - - return result; -} -EXPORT_SYMBOL_GPL(ps3_io_irq_setup); - -int ps3_io_irq_destroy(unsigned int virq) -{ - int result; - - result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); - - if (result) - pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", - __func__, __LINE__, ps3_result(result)); - - result = ps3_irq_plug_destroy(virq); - BUG_ON(result); - - return result; -} -EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); - -/** - * ps3_vuart_irq_setup - Setup the system virtual uart virq. + * ps3_alloc_vuart_irq - Configure the system virtual uart virq. * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be * serviced on. * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap. @@ -436,7 +340,7 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_destroy); * freeing the interrupt will return a wrong state error. */ -int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, +int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp, unsigned int *virq) { int result; @@ -455,13 +359,13 @@ int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, return result; } - result = ps3_irq_plug_setup(cpu, outlet, virq); + result = ps3_alloc_irq(cpu, outlet, virq); BUG_ON(result); return result; } -int ps3_vuart_irq_destroy(unsigned int virq) +int ps3_free_vuart_irq(unsigned int virq) { int result; @@ -473,14 +377,13 @@ int ps3_vuart_irq_destroy(unsigned int virq) return result; } - result = ps3_irq_plug_destroy(virq); - BUG_ON(result); + ps3_free_irq(virq); return result; } /** - * ps3_spe_irq_setup - Setup an spe virq. + * ps3_alloc_spe_irq - Configure an spe virq. * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be * serviced on. * @spe_id: The spe_id returned from lv1_construct_logical_spe(). @@ -489,7 +392,7 @@ int ps3_vuart_irq_destroy(unsigned int virq) * */ -int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, +int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id, unsigned int class, unsigned int *virq) { int result; @@ -505,16 +408,15 @@ int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, return result; } - result = ps3_irq_plug_setup(cpu, outlet, virq); + result = ps3_alloc_irq(cpu, outlet, virq); BUG_ON(result); return result; } -int ps3_spe_irq_destroy(unsigned int virq) +int ps3_free_spe_irq(unsigned int virq) { - int result = ps3_irq_plug_destroy(virq); - BUG_ON(result); + ps3_free_irq(virq); return 0; } diff --git a/trunk/arch/powerpc/platforms/ps3/mm.c b/trunk/arch/powerpc/platforms/ps3/mm.c index f8a3e206c584..2014d2b44449 100644 --- a/trunk/arch/powerpc/platforms/ps3/mm.c +++ b/trunk/arch/powerpc/platforms/ps3/mm.c @@ -826,4 +826,5 @@ void __init ps3_mm_init(void) void ps3_mm_shutdown(void) { ps3_mm_region_destroy(&map.r1); + map.total = map.rm.size; } diff --git a/trunk/arch/powerpc/platforms/ps3/setup.c b/trunk/arch/powerpc/platforms/ps3/setup.c index c9894933084f..ac5df9688dcb 100644 --- a/trunk/arch/powerpc/platforms/ps3/setup.c +++ b/trunk/arch/powerpc/platforms/ps3/setup.c @@ -137,12 +137,6 @@ early_param("ps3fb", early_parse_ps3fb); #define prealloc_ps3fb_videomemory() do { } while (0) #endif -static int ps3_set_dabr(u64 dabr) -{ - enum {DABR_USER = 1, DABR_KERNEL = 2,}; - - return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0; -} static void __init ps3_setup_arch(void) { @@ -240,7 +234,6 @@ define_machine(ps3) { .get_boot_time = ps3_get_boot_time, .set_rtc_time = ps3_set_rtc_time, .get_rtc_time = ps3_get_rtc_time, - .set_dabr = ps3_set_dabr, .calibrate_decr = ps3_calibrate_decr, .progress = ps3_progress, .restart = ps3_restart, diff --git a/trunk/arch/powerpc/platforms/ps3/smp.c b/trunk/arch/powerpc/platforms/ps3/smp.c index 8729348c0608..6fb887961a6d 100644 --- a/trunk/arch/powerpc/platforms/ps3/smp.c +++ b/trunk/arch/powerpc/platforms/ps3/smp.c @@ -110,7 +110,7 @@ static void __init ps3_smp_setup_cpu(int cpu) BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); for (i = 0; i < MSG_COUNT; i++) { - result = ps3_event_receive_port_setup(cpu, &virqs[i]); + result = ps3_alloc_event_irq(cpu, &virqs[i]); if (result) continue; @@ -134,13 +134,11 @@ void ps3_smp_cleanup_cpu(int cpu) int i; DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); - for (i = 0; i < MSG_COUNT; i++) { + ps3_free_event_irq(virqs[i]); free_irq(virqs[i], (void*)(long)i); - ps3_event_receive_port_destroy(virqs[i]); virqs[i] = NO_IRQ; } - DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu); } diff --git a/trunk/arch/powerpc/platforms/ps3/spu.c b/trunk/arch/powerpc/platforms/ps3/spu.c index 651437cb2c18..a397e4e17c13 100644 --- a/trunk/arch/powerpc/platforms/ps3/spu.c +++ b/trunk/arch/powerpc/platforms/ps3/spu.c @@ -184,7 +184,7 @@ static int __init setup_areas(struct spu *spu) spu_pdata(spu)->shadow = __ioremap( spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow), - pgprot_val(PAGE_READONLY) | _PAGE_NO_CACHE | _PAGE_GUARDED); + PAGE_READONLY | _PAGE_NO_CACHE | _PAGE_GUARDED); if (!spu_pdata(spu)->shadow) { pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__); goto fail_ioremap; @@ -230,19 +230,19 @@ static int __init setup_interrupts(struct spu *spu) { int result; - result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, + result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, 0, &spu->irqs[0]); if (result) goto fail_alloc_0; - result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, + result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, 1, &spu->irqs[1]); if (result) goto fail_alloc_1; - result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, + result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id, 2, &spu->irqs[2]); if (result) @@ -251,9 +251,9 @@ static int __init setup_interrupts(struct spu *spu) return result; fail_alloc_2: - ps3_spe_irq_destroy(spu->irqs[1]); + ps3_free_spe_irq(spu->irqs[1]); fail_alloc_1: - ps3_spe_irq_destroy(spu->irqs[0]); + ps3_free_spe_irq(spu->irqs[0]); fail_alloc_0: spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; return result; @@ -301,9 +301,9 @@ static int ps3_destroy_spu(struct spu *spu) result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0); BUG_ON(result); - ps3_spe_irq_destroy(spu->irqs[2]); - ps3_spe_irq_destroy(spu->irqs[1]); - ps3_spe_irq_destroy(spu->irqs[0]); + ps3_free_spe_irq(spu->irqs[2]); + ps3_free_spe_irq(spu->irqs[1]); + ps3_free_spe_irq(spu->irqs[0]); spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; diff --git a/trunk/arch/powerpc/platforms/pseries/Makefile b/trunk/arch/powerpc/platforms/pseries/Makefile index ae1fc92dc1c9..90235d598751 100644 --- a/trunk/arch/powerpc/platforms/pseries/Makefile +++ b/trunk/arch/powerpc/platforms/pseries/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_PCI) += pci.o pci_dlpar.o -obj-$(CONFIG_PCI_MSI) += msi.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index 63e23062e982..48fbd442e9df 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -579,36 +579,6 @@ rtas_pci_slot_reset(struct pci_dn *pdn, int state) rc, state, pdn->node->full_name); } -/** - * pcibios_set_pcie_slot_reset - Set PCI-E reset state - * @dev: pci device struct - * @state: reset state to enter - * - * Return value: - * 0 if success - **/ -int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) -{ - struct device_node *dn = pci_device_to_OF_node(dev); - struct pci_dn *pdn = PCI_DN(dn); - - switch (state) { - case pcie_deassert_reset: - rtas_pci_slot_reset(pdn, 0); - break; - case pcie_hot_reset: - rtas_pci_slot_reset(pdn, 1); - break; - case pcie_warm_reset: - rtas_pci_slot_reset(pdn, 3); - break; - default: - return -EINVAL; - }; - - return 0; -} - /** * rtas_set_slot_reset -- assert the pci #RST line for 1/4 second * @pdn: pci device node to be reset. diff --git a/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c index eec684a8e44e..66665c82415c 100644 --- a/trunk/arch/powerpc/platforms/pseries/iommu.c +++ b/trunk/arch/powerpc/platforms/pseries/iommu.c @@ -504,12 +504,6 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) break; } - if (!pdn || !PCI_DN(pdn)) { - printk(KERN_WARNING "pci_dma_dev_setup_pSeriesLP: " - "no DMA window found for pci dev=%s dn=%s\n", - pci_name(dev), dn? dn->full_name : ""); - return; - } DBG(" parent is %s\n", pdn->full_name); /* Check for parent == NULL so we don't try to setup the empty EADS diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index 362dfbc260a6..3a70e8ad7bc8 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -231,13 +231,13 @@ void __init find_udbg_vterm(void) goto out; vtermno = termno[0]; - if (of_device_is_compatible(stdout_node, "hvterm1")) { + if (device_is_compatible(stdout_node, "hvterm1")) { udbg_putc = udbg_putcLP; udbg_getc = udbg_getcLP; udbg_getc_poll = udbg_getc_pollLP; if (add_console) add_preferred_console("hvc", termno[0] & 0xff, NULL); - } else if (of_device_is_compatible(stdout_node, "hvterm-protocol")) { + } else if (device_is_compatible(stdout_node, "hvterm-protocol")) { vtermno = termno[0]; udbg_putc = udbg_hvsi_putc; udbg_getc = udbg_hvsi_getc; diff --git a/trunk/arch/powerpc/platforms/pseries/msi.c b/trunk/arch/powerpc/platforms/pseries/msi.c deleted file mode 100644 index 6063ea2f67ad..000000000000 --- a/trunk/arch/powerpc/platforms/pseries/msi.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2006 Jake Moilanen , IBM Corp. - * Copyright 2006-2007 Michael Ellerman, IBM Corp. - * - * 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; version 2 of the - * License. - * - */ - -#include -#include -#include - -#include -#include -#include - -static int query_token, change_token; - -#define RTAS_QUERY_FN 0 -#define RTAS_CHANGE_FN 1 -#define RTAS_RESET_FN 2 -#define RTAS_CHANGE_MSI_FN 3 -#define RTAS_CHANGE_MSIX_FN 4 - -static struct pci_dn *get_pdn(struct pci_dev *pdev) -{ - struct device_node *dn; - struct pci_dn *pdn; - - dn = pci_device_to_OF_node(pdev); - if (!dn) { - dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n"); - return NULL; - } - - pdn = PCI_DN(dn); - if (!pdn) { - dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n"); - return NULL; - } - - return pdn; -} - -/* RTAS Helpers */ - -static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) -{ - u32 addr, seq_num, rtas_ret[3]; - unsigned long buid; - int rc; - - addr = rtas_config_addr(pdn->busno, pdn->devfn, 0); - buid = pdn->phb->buid; - - seq_num = 1; - do { - if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN) - rc = rtas_call(change_token, 6, 4, rtas_ret, addr, - BUID_HI(buid), BUID_LO(buid), - func, num_irqs, seq_num); - else - rc = rtas_call(change_token, 6, 3, rtas_ret, addr, - BUID_HI(buid), BUID_LO(buid), - func, num_irqs, seq_num); - - seq_num = rtas_ret[1]; - } while (rtas_busy_delay(rc)); - - if (rc == 0) /* Success */ - rc = rtas_ret[0]; - - pr_debug("rtas_msi: ibm,change_msi(func=%d,num=%d) = (%d)\n", - func, num_irqs, rc); - - return rc; -} - -static void rtas_disable_msi(struct pci_dev *pdev) -{ - struct pci_dn *pdn; - - pdn = get_pdn(pdev); - if (!pdn) - return; - - if (rtas_change_msi(pdn, RTAS_CHANGE_FN, 0) != 0) - pr_debug("rtas_msi: Setting MSIs to 0 failed!\n"); -} - -static int rtas_query_irq_number(struct pci_dn *pdn, int offset) -{ - u32 addr, rtas_ret[2]; - unsigned long buid; - int rc; - - addr = rtas_config_addr(pdn->busno, pdn->devfn, 0); - buid = pdn->phb->buid; - - do { - rc = rtas_call(query_token, 4, 3, rtas_ret, addr, - BUID_HI(buid), BUID_LO(buid), offset); - } while (rtas_busy_delay(rc)); - - if (rc) { - pr_debug("rtas_msi: error (%d) querying source number\n", rc); - return rc; - } - - return rtas_ret[0]; -} - -static void rtas_teardown_msi_irqs(struct pci_dev *pdev) -{ - struct msi_desc *entry; - - list_for_each_entry(entry, &pdev->msi_list, list) { - if (entry->irq == NO_IRQ) - continue; - - set_irq_msi(entry->irq, NULL); - irq_dispose_mapping(entry->irq); - } - - rtas_disable_msi(pdev); -} - -static int check_req_msi(struct pci_dev *pdev, int nvec) -{ - struct device_node *dn; - struct pci_dn *pdn; - const u32 *req_msi; - - pdn = get_pdn(pdev); - if (!pdn) - return -ENODEV; - - dn = pdn->node; - - req_msi = of_get_property(dn, "ibm,req#msi", NULL); - if (!req_msi) { - pr_debug("rtas_msi: No ibm,req#msi on %s\n", dn->full_name); - return -ENOENT; - } - - if (*req_msi < nvec) { - pr_debug("rtas_msi: ibm,req#msi requests < %d MSIs\n", nvec); - return -ENOSPC; - } - - return 0; -} - -static int rtas_msi_check_device(struct pci_dev *pdev, int nvec, int type) -{ - if (type == PCI_CAP_ID_MSIX) - pr_debug("rtas_msi: MSI-X untested, trying anyway.\n"); - - return check_req_msi(pdev, nvec); -} - -static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) -{ - struct pci_dn *pdn; - int hwirq, virq, i, rc; - struct msi_desc *entry; - - pdn = get_pdn(pdev); - if (!pdn) - return -ENODEV; - - /* - * Try the new more explicit firmware interface, if that fails fall - * back to the old interface. The old interface is known to never - * return MSI-Xs. - */ - if (type == PCI_CAP_ID_MSI) { - rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); - - if (rc != nvec) { - pr_debug("rtas_msi: trying the old firmware call.\n"); - rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); - } - } else - rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); - - if (rc != nvec) { - pr_debug("rtas_msi: rtas_change_msi() failed\n"); - - /* - * In case of an error it's not clear whether the device is - * left with MSI enabled or not, so we explicitly disable. - */ - goto out_free; - } - - i = 0; - list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = rtas_query_irq_number(pdn, i); - if (hwirq < 0) { - rc = hwirq; - pr_debug("rtas_msi: error (%d) getting hwirq\n", rc); - goto out_free; - } - - virq = irq_create_mapping(NULL, hwirq); - - if (virq == NO_IRQ) { - pr_debug("rtas_msi: Failed mapping hwirq %d\n", hwirq); - rc = -ENOSPC; - goto out_free; - } - - dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq); - set_irq_msi(virq, entry); - unmask_msi_irq(virq); - } - - return 0; - - out_free: - rtas_teardown_msi_irqs(pdev); - return rc; -} - -static void rtas_msi_pci_irq_fixup(struct pci_dev *pdev) -{ - /* No LSI -> leave MSIs (if any) configured */ - if (pdev->irq == NO_IRQ) { - dev_dbg(&pdev->dev, "rtas_msi: no LSI, nothing to do.\n"); - return; - } - - /* No MSI -> MSIs can't have been assigned by fw, leave LSI */ - if (check_req_msi(pdev, 1)) { - dev_dbg(&pdev->dev, "rtas_msi: no req#msi, nothing to do.\n"); - return; - } - - dev_dbg(&pdev->dev, "rtas_msi: disabling existing MSI.\n"); - rtas_disable_msi(pdev); -} - -static int rtas_msi_init(void) -{ - query_token = rtas_token("ibm,query-interrupt-source-number"); - change_token = rtas_token("ibm,change-msi"); - - if ((query_token == RTAS_UNKNOWN_SERVICE) || - (change_token == RTAS_UNKNOWN_SERVICE)) { - pr_debug("rtas_msi: no RTAS tokens, no MSI support.\n"); - return -1; - } - - pr_debug("rtas_msi: Registering RTAS MSI callbacks.\n"); - - WARN_ON(ppc_md.setup_msi_irqs); - ppc_md.setup_msi_irqs = rtas_setup_msi_irqs; - ppc_md.teardown_msi_irqs = rtas_teardown_msi_irqs; - ppc_md.msi_check_device = rtas_msi_check_device; - - WARN_ON(ppc_md.pci_irq_fixup); - ppc_md.pci_irq_fixup = rtas_msi_pci_irq_fixup; - - return 0; -} -arch_initcall(rtas_msi_init); diff --git a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c index ffaf6c5c517b..fdc1a369f767 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -79,7 +79,6 @@ pcibios_remove_pci_devices(struct pci_bus *bus) pci_remove_bus_device(dev); } } -EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); /* Must be called before pci_bus_add_devices */ void diff --git a/trunk/arch/powerpc/platforms/pseries/power.c b/trunk/arch/powerpc/platforms/pseries/power.c index 73e69023d90a..2624b71df73d 100644 --- a/trunk/arch/powerpc/platforms/pseries/power.c +++ b/trunk/arch/powerpc/platforms/pseries/power.c @@ -28,13 +28,13 @@ unsigned long rtas_poweron_auto; /* default and normal state is 0 */ -static ssize_t auto_poweron_show(struct kset *kset, char *buf) +static ssize_t auto_poweron_show(struct subsystem *subsys, char *buf) { return sprintf(buf, "%lu\n", rtas_poweron_auto); } static ssize_t -auto_poweron_store(struct kset *kset, const char *buf, size_t n) +auto_poweron_store(struct subsystem *subsys, const char *buf, size_t n) { int ret; unsigned long ups_restart; @@ -72,12 +72,12 @@ static int __init pm_init(void) { int error = subsystem_register(&power_subsys); if (!error) - error = sysfs_create_group(&power_subsys.kobj, &attr_group); + error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group); return error; } core_initcall(pm_init); #else -extern struct kset power_subsys; +extern struct subsystem power_subsys; static int __init apo_pm_init(void) { diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c index 3a393c7f390e..53aa04101ced 100644 --- a/trunk/arch/powerpc/platforms/pseries/ras.c +++ b/trunk/arch/powerpc/platforms/pseries/ras.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 470db6efaeb6..33eec2822c66 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -168,7 +168,7 @@ static void __init pseries_mpic_init_IRQ(void) /* Look for cascade */ for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "chrp,iic")) { + if (device_is_compatible(np, "chrp,iic")) { cascade = np; break; } diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index b854e7f1001c..896cbf340c42 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -477,7 +477,7 @@ static int xics_host_match(struct irq_host *h, struct device_node *node) * like vdevices, events, etc... The trick we use here is to match * everything here except the legacy 8259 which is compatible "chrp,iic" */ - return !of_device_is_compatible(node, "chrp,iic"); + return !device_is_compatible(node, "chrp,iic"); } static int xics_host_map_direct(struct irq_host *h, unsigned int virq, @@ -618,7 +618,7 @@ static void __init xics_setup_8259_cascade(void) unsigned long intack = 0; for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "chrp,iic")) { + if (device_is_compatible(np, "chrp,iic")) { found = np; break; } diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index 9ce775c38ab7..e96ca9618dbb 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -2,9 +2,7 @@ ifeq ($(CONFIG_PPC64),y) EXTRA_CFLAGS += -mno-minimal-toc endif -mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o -obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) - +obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_MPC106) += grackle.o obj-$(CONFIG_PPC_DCR) += dcr.o @@ -28,6 +26,7 @@ endif # Temporary hack until we have migrated to asm-powerpc ifeq ($(ARCH),powerpc) +obj-$(CONFIG_MTD) += rom.o obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o obj-$(CONFIG_8xx) += mpc8xx_pic.o commproc.o obj-$(CONFIG_UCODE_PATCH) += micropatch.o diff --git a/trunk/arch/powerpc/sysdev/dart_iommu.c b/trunk/arch/powerpc/sysdev/dart_iommu.c index a1d2042bb304..336186dd7f10 100644 --- a/trunk/arch/powerpc/sysdev/dart_iommu.c +++ b/trunk/arch/powerpc/sysdev/dart_iommu.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -55,9 +54,6 @@ static unsigned long dart_tablesize; /* Virtual base address of the DART table */ static u32 *dart_vbase; -#ifdef CONFIG_PM -static u32 *dart_copy; -#endif /* Mapped base address for the dart */ static unsigned int __iomem *dart; @@ -350,48 +346,6 @@ void iommu_init_early_dart(void) set_pci_dma_ops(&dma_direct_ops); } -#ifdef CONFIG_PM -static void iommu_dart_save(void) -{ - memcpy(dart_copy, dart_vbase, 2*1024*1024); -} - -static void iommu_dart_restore(void) -{ - memcpy(dart_vbase, dart_copy, 2*1024*1024); - dart_tlb_invalidate_all(); -} - -static int __init iommu_init_late_dart(void) -{ - unsigned long tbasepfn; - struct page *p; - - /* if no dart table exists then we won't need to save it - * and the area has also not been reserved */ - if (!dart_tablebase) - return 0; - - tbasepfn = __pa(dart_tablebase) >> PAGE_SHIFT; - register_nosave_region_late(tbasepfn, - tbasepfn + ((1<<24) >> PAGE_SHIFT)); - - /* For suspend we need to copy the dart contents because - * it is not part of the regular mapping (see above) and - * thus not saved automatically. The memory for this copy - * must be allocated early because we need 2 MB. */ - p = alloc_pages(GFP_KERNEL, 21 - PAGE_SHIFT); - BUG_ON(!p); - dart_copy = page_address(p); - - ppc_md.iommu_save = iommu_dart_save; - ppc_md.iommu_restore = iommu_dart_restore; - - return 0; -} - -late_initcall(iommu_init_late_dart); -#endif void __init alloc_dart_table(void) { diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 4fd2bec89916..0b84b7c775d8 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -36,8 +36,6 @@ #include #include -#include "mpic.h" - #ifdef DEBUG #define DBG(fmt...) printk(fmt) #else @@ -356,12 +354,6 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, tmp |= 0x22; writel(tmp, fixup->base + 4); spin_unlock_irqrestore(&mpic->fixup_lock, flags); - -#ifdef CONFIG_PM - /* use the lowest bit inverted to the actual HW, - * set if this fixup was enabled, clear otherwise */ - mpic->save_data[source].fixup_data = tmp | 1; -#endif } static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source, @@ -383,58 +375,8 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source, tmp |= 1; writel(tmp, fixup->base + 4); spin_unlock_irqrestore(&mpic->fixup_lock, flags); - -#ifdef CONFIG_PM - /* use the lowest bit inverted to the actual HW, - * set if this fixup was enabled, clear otherwise */ - mpic->save_data[source].fixup_data = tmp & ~1; -#endif } -#ifdef CONFIG_PCI_MSI -static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase, - unsigned int devfn) -{ - u8 __iomem *base; - u8 pos, flags; - u64 addr = 0; - - for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0; - pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) { - u8 id = readb(devbase + pos + PCI_CAP_LIST_ID); - if (id == PCI_CAP_ID_HT) { - id = readb(devbase + pos + 3); - if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_MSI_MAPPING) - break; - } - } - - if (pos == 0) - return; - - base = devbase + pos; - - flags = readb(base + HT_MSI_FLAGS); - if (!(flags & HT_MSI_FLAGS_FIXED)) { - addr = readl(base + HT_MSI_ADDR_LO) & HT_MSI_ADDR_LO_MASK; - addr = addr | ((u64)readl(base + HT_MSI_ADDR_HI) << 32); - } - - printk(KERN_DEBUG "mpic: - HT:%02x.%x %s MSI mapping found @ 0x%lx\n", - PCI_SLOT(devfn), PCI_FUNC(devfn), - flags & HT_MSI_FLAGS_ENABLE ? "enabled" : "disabled", addr); - - if (!(flags & HT_MSI_FLAGS_ENABLE)) - writeb(flags | HT_MSI_FLAGS_ENABLE, base + HT_MSI_FLAGS); -} -#else -static void __init mpic_scan_ht_msi(struct mpic *mpic, u8 __iomem *devbase, - unsigned int devfn) -{ - return; -} -#endif - static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase, unsigned int devfn, u32 vdid) { @@ -526,7 +468,6 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) goto next; mpic_scan_ht_pic(mpic, devbase, devfn, l); - mpic_scan_ht_msi(mpic, devbase, devfn); next: /* next device, if function 0 */ @@ -618,7 +559,7 @@ static irqreturn_t mpic_ipi_action(int irq, void *dev_id) */ -void mpic_unmask_irq(unsigned int irq) +static void mpic_unmask_irq(unsigned int irq) { unsigned int loops = 100000; struct mpic *mpic = mpic_from_irq(irq); @@ -638,7 +579,7 @@ void mpic_unmask_irq(unsigned int irq) } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK); } -void mpic_mask_irq(unsigned int irq) +static void mpic_mask_irq(unsigned int irq) { unsigned int loops = 100000; struct mpic *mpic = mpic_from_irq(irq); @@ -659,7 +600,7 @@ void mpic_mask_irq(unsigned int irq) } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK)); } -void mpic_end_irq(unsigned int irq) +static void mpic_end_irq(unsigned int irq) { struct mpic *mpic = mpic_from_irq(irq); @@ -792,7 +733,7 @@ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type) } } -int mpic_set_irq_type(unsigned int virq, unsigned int flow_type) +static int mpic_set_irq_type(unsigned int virq, unsigned int flow_type) { struct mpic *mpic = mpic_from_irq(virq); unsigned int src = mpic_irq_to_hw(virq); @@ -893,8 +834,6 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, if (hw >= mpic->irq_count) return -EINVAL; - mpic_msi_reserve_hwirq(mpic, hw); - /* Default chip */ chip = &mpic->hc_irq; @@ -1203,10 +1142,8 @@ void __init mpic_init(struct mpic *mpic) /* Do the HT PIC fixups on U3 broken mpic */ DBG("MPIC flags: %x\n", mpic->flags); - if ((mpic->flags & MPIC_U3_HT_IRQS) && (mpic->flags & MPIC_PRIMARY)) { - mpic_scan_ht_pics(mpic); - mpic_u3msi_init(mpic); - } + if ((mpic->flags & MPIC_U3_HT_IRQS) && (mpic->flags & MPIC_PRIMARY)) + mpic_scan_ht_pics(mpic); for (i = 0; i < mpic->num_sources; i++) { /* start with vector = source number, and masked */ @@ -1230,12 +1167,6 @@ void __init mpic_init(struct mpic *mpic) /* Set current processor priority to 0 */ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); - -#ifdef CONFIG_PM - /* allocate memory to save mpic state */ - mpic->save_data = alloc_bootmem(mpic->num_sources * sizeof(struct mpic_irq_save)); - BUG_ON(mpic->save_data == NULL); -#endif } void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) @@ -1402,11 +1333,8 @@ unsigned int mpic_get_one_irq(struct mpic *mpic) #ifdef DEBUG_LOW DBG("%s: get_one_irq(): %d\n", mpic->name, src); #endif - if (unlikely(src == mpic->spurious_vec)) { - if (mpic->flags & MPIC_SPV_EOI) - mpic_eoi(mpic); + if (unlikely(src == mpic->spurious_vec)) return NO_IRQ; - } return irq_linear_revmap(mpic->irqhost, src); } @@ -1489,79 +1417,3 @@ void __devinit smp_mpic_setup_cpu(int cpu) mpic_setup_this_cpu(); } #endif /* CONFIG_SMP */ - -#ifdef CONFIG_PM -static int mpic_suspend(struct sys_device *dev, pm_message_t state) -{ - struct mpic *mpic = container_of(dev, struct mpic, sysdev); - int i; - - for (i = 0; i < mpic->num_sources; i++) { - mpic->save_data[i].vecprio = - mpic_irq_read(i, MPIC_INFO(IRQ_VECTOR_PRI)); - mpic->save_data[i].dest = - mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)); - } - - return 0; -} - -static int mpic_resume(struct sys_device *dev) -{ - struct mpic *mpic = container_of(dev, struct mpic, sysdev); - int i; - - for (i = 0; i < mpic->num_sources; i++) { - mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), - mpic->save_data[i].vecprio); - mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), - mpic->save_data[i].dest); - -#ifdef CONFIG_MPIC_U3_HT_IRQS - { - struct mpic_irq_fixup *fixup = &mpic->fixups[i]; - - if (fixup->base) { - /* we use the lowest bit in an inverted meaning */ - if ((mpic->save_data[i].fixup_data & 1) == 0) - continue; - - /* Enable and configure */ - writeb(0x10 + 2 * fixup->index, fixup->base + 2); - - writel(mpic->save_data[i].fixup_data & ~1, - fixup->base + 4); - } - } -#endif - } /* end for loop */ - - return 0; -} -#endif - -static struct sysdev_class mpic_sysclass = { -#ifdef CONFIG_PM - .resume = mpic_resume, - .suspend = mpic_suspend, -#endif - set_kset_name("mpic"), -}; - -static int mpic_init_sys(void) -{ - struct mpic *mpic = mpics; - int error, id = 0; - - error = sysdev_class_register(&mpic_sysclass); - - while (mpic && !error) { - mpic->sysdev.cls = &mpic_sysclass; - mpic->sysdev.id = id++; - error = sysdev_register(&mpic->sysdev); - mpic = mpic->next; - } - return error; -} - -device_initcall(mpic_init_sys); diff --git a/trunk/arch/powerpc/sysdev/mpic.h b/trunk/arch/powerpc/sysdev/mpic.h deleted file mode 100644 index 3a1c3d2c594d..000000000000 --- a/trunk/arch/powerpc/sysdev/mpic.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _POWERPC_SYSDEV_MPIC_H -#define _POWERPC_SYSDEV_MPIC_H - -/* - * Copyright 2006-2007, Michael Ellerman, IBM Corporation. - * - * 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; version 2 of the - * License. - * - */ - -#ifdef CONFIG_PCI_MSI -extern void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq); -extern int mpic_msi_init_allocator(struct mpic *mpic); -extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num); -extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num); -extern int mpic_u3msi_init(struct mpic *mpic); -#else -static inline void mpic_msi_reserve_hwirq(struct mpic *mpic, - irq_hw_number_t hwirq) -{ - return; -} - -static inline int mpic_u3msi_init(struct mpic *mpic) -{ - return -1; -} -#endif - -extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); -extern void mpic_end_irq(unsigned int irq); -extern void mpic_mask_irq(unsigned int irq); -extern void mpic_unmask_irq(unsigned int irq); - -#endif /* _POWERPC_SYSDEV_MPIC_H */ diff --git a/trunk/arch/powerpc/sysdev/mpic_msi.c b/trunk/arch/powerpc/sysdev/mpic_msi.c deleted file mode 100644 index b076793033c2..000000000000 --- a/trunk/arch/powerpc/sysdev/mpic_msi.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2006-2007, Michael Ellerman, IBM Corporation. - * - * 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; version 2 of the - * License. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -static void __mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq) -{ - pr_debug("mpic: reserving hwirq 0x%lx\n", hwirq); - bitmap_allocate_region(mpic->hwirq_bitmap, hwirq, 0); -} - -void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq) -{ - unsigned long flags; - - /* The mpic calls this even when there is no allocator setup */ - if (!mpic->hwirq_bitmap) - return; - - spin_lock_irqsave(&mpic->bitmap_lock, flags); - __mpic_msi_reserve_hwirq(mpic, hwirq); - spin_unlock_irqrestore(&mpic->bitmap_lock, flags); -} - -irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num) -{ - unsigned long flags; - int offset, order = get_count_order(num); - - spin_lock_irqsave(&mpic->bitmap_lock, flags); - /* - * This is fast, but stricter than we need. We might want to add - * a fallback routine which does a linear search with no alignment. - */ - offset = bitmap_find_free_region(mpic->hwirq_bitmap, mpic->irq_count, - order); - spin_unlock_irqrestore(&mpic->bitmap_lock, flags); - - pr_debug("mpic: allocated 0x%x (2^%d) at offset 0x%x\n", - num, order, offset); - - return offset; -} - -void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num) -{ - unsigned long flags; - int order = get_count_order(num); - - pr_debug("mpic: freeing 0x%x (2^%d) at offset 0x%x\n", - num, order, offset); - - spin_lock_irqsave(&mpic->bitmap_lock, flags); - bitmap_release_region(mpic->hwirq_bitmap, offset, order); - spin_unlock_irqrestore(&mpic->bitmap_lock, flags); -} - -#ifdef CONFIG_MPIC_U3_HT_IRQS -static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) -{ - irq_hw_number_t hwirq; - struct irq_host_ops *ops = mpic->irqhost->ops; - struct device_node *np; - int flags, index, i; - struct of_irq oirq; - - pr_debug("mpic: found U3, guessing msi allocator setup\n"); - - /* Reserve source numbers we know are reserved in the HW */ - for (i = 0; i < 8; i++) - __mpic_msi_reserve_hwirq(mpic, i); - - for (i = 42; i < 46; i++) - __mpic_msi_reserve_hwirq(mpic, i); - - for (i = 100; i < 105; i++) - __mpic_msi_reserve_hwirq(mpic, i); - - np = NULL; - while ((np = of_find_all_nodes(np))) { - pr_debug("mpic: mapping hwirqs for %s\n", np->full_name); - - index = 0; - while (of_irq_map_one(np, index++, &oirq) == 0) { - ops->xlate(mpic->irqhost, NULL, oirq.specifier, - oirq.size, &hwirq, &flags); - __mpic_msi_reserve_hwirq(mpic, hwirq); - } - } - - return 0; -} -#else -static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic) -{ - return -1; -} -#endif - -static int mpic_msi_reserve_dt_hwirqs(struct mpic *mpic) -{ - int i, len; - const u32 *p; - - p = of_get_property(mpic->of_node, "msi-available-ranges", &len); - if (!p) { - pr_debug("mpic: no msi-available-ranges property found on %s\n", - mpic->of_node->full_name); - return -ENODEV; - } - - if (len % 8 != 0) { - printk(KERN_WARNING "mpic: Malformed msi-available-ranges " - "property on %s\n", mpic->of_node->full_name); - return -EINVAL; - } - - bitmap_allocate_region(mpic->hwirq_bitmap, 0, - get_count_order(mpic->irq_count)); - - /* Format is: ( )+ */ - len /= sizeof(u32); - for (i = 0; i < len / 2; i++, p += 2) - mpic_msi_free_hwirqs(mpic, *p, *(p + 1)); - - return 0; -} - -int mpic_msi_init_allocator(struct mpic *mpic) -{ - int rc, size; - - BUG_ON(mpic->hwirq_bitmap); - spin_lock_init(&mpic->bitmap_lock); - - size = BITS_TO_LONGS(mpic->irq_count) * sizeof(long); - pr_debug("mpic: allocator bitmap size is 0x%x bytes\n", size); - - if (mem_init_done) - mpic->hwirq_bitmap = kmalloc(size, GFP_KERNEL); - else - mpic->hwirq_bitmap = alloc_bootmem(size); - - if (!mpic->hwirq_bitmap) { - pr_debug("mpic: ENOMEM allocating allocator bitmap!\n"); - return -ENOMEM; - } - - memset(mpic->hwirq_bitmap, 0, size); - - rc = mpic_msi_reserve_dt_hwirqs(mpic); - if (rc) { - if (mpic->flags & MPIC_U3_HT_IRQS) - rc = mpic_msi_reserve_u3_hwirqs(mpic); - - if (rc) - goto out_free; - } - - return 0; - - out_free: - if (mem_init_done) - kfree(mpic->hwirq_bitmap); - - mpic->hwirq_bitmap = NULL; - return rc; -} diff --git a/trunk/arch/powerpc/sysdev/mpic_u3msi.c b/trunk/arch/powerpc/sysdev/mpic_u3msi.c deleted file mode 100644 index 305b864c25d9..000000000000 --- a/trunk/arch/powerpc/sysdev/mpic_u3msi.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2006, Segher Boessenkool, IBM Corporation. - * Copyright 2006-2007, Michael Ellerman, IBM Corporation. - * - * 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; version 2 of the - * License. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "mpic.h" - -/* A bit ugly, can we get this from the pci_dev somehow? */ -static struct mpic *msi_mpic; - -static void mpic_u3msi_mask_irq(unsigned int irq) -{ - mask_msi_irq(irq); - mpic_mask_irq(irq); -} - -static void mpic_u3msi_unmask_irq(unsigned int irq) -{ - mpic_unmask_irq(irq); - unmask_msi_irq(irq); -} - -static struct irq_chip mpic_u3msi_chip = { - .shutdown = mpic_u3msi_mask_irq, - .mask = mpic_u3msi_mask_irq, - .unmask = mpic_u3msi_unmask_irq, - .eoi = mpic_end_irq, - .set_type = mpic_set_irq_type, - .typename = "MPIC-U3MSI", -}; - -static u64 read_ht_magic_addr(struct pci_dev *pdev, unsigned int pos) -{ - u8 flags; - u32 tmp; - u64 addr; - - pci_read_config_byte(pdev, pos + HT_MSI_FLAGS, &flags); - - if (flags & HT_MSI_FLAGS_FIXED) - return HT_MSI_FIXED_ADDR; - - pci_read_config_dword(pdev, pos + HT_MSI_ADDR_LO, &tmp); - addr = tmp & HT_MSI_ADDR_LO_MASK; - pci_read_config_dword(pdev, pos + HT_MSI_ADDR_HI, &tmp); - addr = addr | ((u64)tmp << 32); - - return addr; -} - -static u64 find_ht_magic_addr(struct pci_dev *pdev) -{ - struct pci_bus *bus; - unsigned int pos; - - for (bus = pdev->bus; bus; bus = bus->parent) { - pos = pci_find_ht_capability(bus->self, HT_CAPTYPE_MSI_MAPPING); - if (pos) - return read_ht_magic_addr(bus->self, pos); - } - - return 0; -} - -static int u3msi_msi_check_device(struct pci_dev *pdev, int nvec, int type) -{ - if (type == PCI_CAP_ID_MSIX) - pr_debug("u3msi: MSI-X untested, trying anyway.\n"); - - /* If we can't find a magic address then MSI ain't gonna work */ - if (find_ht_magic_addr(pdev) == 0) { - pr_debug("u3msi: no magic address found for %s\n", - pci_name(pdev)); - return -ENXIO; - } - - return 0; -} - -static void u3msi_teardown_msi_irqs(struct pci_dev *pdev) -{ - struct msi_desc *entry; - - list_for_each_entry(entry, &pdev->msi_list, list) { - if (entry->irq == NO_IRQ) - continue; - - set_irq_msi(entry->irq, NULL); - mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq), 1); - irq_dispose_mapping(entry->irq); - } - - return; -} - -static void u3msi_compose_msi_msg(struct pci_dev *pdev, int virq, - struct msi_msg *msg) -{ - u64 addr; - - addr = find_ht_magic_addr(pdev); - msg->address_lo = addr & 0xFFFFFFFF; - msg->address_hi = addr >> 32; - msg->data = virq_to_hw(virq); - - pr_debug("u3msi: allocated virq 0x%x (hw 0x%lx) at address 0x%lx\n", - virq, virq_to_hw(virq), addr); -} - -static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) -{ - irq_hw_number_t hwirq; - int rc; - unsigned int virq; - struct msi_desc *entry; - struct msi_msg msg; - - list_for_each_entry(entry, &pdev->msi_list, list) { - hwirq = mpic_msi_alloc_hwirqs(msi_mpic, 1); - if (hwirq < 0) { - rc = hwirq; - pr_debug("u3msi: failed allocating hwirq\n"); - goto out_free; - } - - virq = irq_create_mapping(msi_mpic->irqhost, hwirq); - if (virq == NO_IRQ) { - pr_debug("u3msi: failed mapping hwirq 0x%lx\n", hwirq); - mpic_msi_free_hwirqs(msi_mpic, hwirq, 1); - rc = -ENOSPC; - goto out_free; - } - - set_irq_msi(virq, entry); - set_irq_chip(virq, &mpic_u3msi_chip); - set_irq_type(virq, IRQ_TYPE_EDGE_RISING); - - u3msi_compose_msi_msg(pdev, virq, &msg); - write_msi_msg(virq, &msg); - - hwirq++; - } - - return 0; - - out_free: - u3msi_teardown_msi_irqs(pdev); - return rc; -} - -int mpic_u3msi_init(struct mpic *mpic) -{ - int rc; - - rc = mpic_msi_init_allocator(mpic); - if (rc) { - pr_debug("u3msi: Error allocating bitmap!\n"); - return rc; - } - - pr_debug("u3msi: Registering MPIC U3 MSI callbacks.\n"); - - BUG_ON(msi_mpic); - msi_mpic = mpic; - - WARN_ON(ppc_md.setup_msi_irqs); - ppc_md.setup_msi_irqs = u3msi_setup_msi_irqs; - ppc_md.teardown_msi_irqs = u3msi_teardown_msi_irqs; - ppc_md.msi_check_device = u3msi_msi_check_device; - - return 0; -} diff --git a/trunk/arch/powerpc/sysdev/rom.c b/trunk/arch/powerpc/sysdev/rom.c new file mode 100644 index 000000000000..c855a3b298a3 --- /dev/null +++ b/trunk/arch/powerpc/sysdev/rom.c @@ -0,0 +1,32 @@ +/* + * ROM device registration + * + * (C) 2006 MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include + +static int __init powerpc_flash_init(void) +{ + struct device_node *node = NULL; + + /* + * Register all the devices which type is "rom" + */ + while ((node = of_find_node_by_type(node, "rom")) != NULL) { + if (node->name == NULL) { + printk(KERN_WARNING "powerpc_flash_init: found 'rom' " + "device, but with no name, skipping...\n"); + continue; + } + of_platform_device_create(node, node->name, NULL); + } + return 0; +} + +arch_initcall(powerpc_flash_init); diff --git a/trunk/arch/powerpc/sysdev/tsi108_dev.c b/trunk/arch/powerpc/sysdev/tsi108_dev.c index 7d3b09b7d544..337039ee51e6 100644 --- a/trunk/arch/powerpc/sysdev/tsi108_dev.c +++ b/trunk/arch/powerpc/sysdev/tsi108_dev.c @@ -107,9 +107,8 @@ static int __init tsi108_eth_of_init(void) goto err; } - mac_addr = of_get_mac_address(np); - if (mac_addr) - memcpy(tsi_eth_data.mac_addr, mac_addr, 6); + mac_addr = of_get_property(np, "address", NULL); + memcpy(tsi_eth_data.mac_addr, mac_addr, 6); ph = of_get_property(np, "phy-handle", NULL); phy = of_find_node_by_phandle(*ph); @@ -130,8 +129,6 @@ static int __init tsi108_eth_of_init(void) tsi_eth_data.phyregs = res.start; tsi_eth_data.phy = *phy_id; tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0); - if (of_device_is_compatible(phy, "bcm54xx")) - tsi_eth_data.phy_type = TSI108_PHY_BCM54XX; of_node_put(phy); ret = platform_device_add_data(tsi_eth_dev, &tsi_eth_data, diff --git a/trunk/arch/powerpc/sysdev/tsi108_pci.c b/trunk/arch/powerpc/sysdev/tsi108_pci.c index 2153163fa593..58b9e7f8abf2 100644 --- a/trunk/arch/powerpc/sysdev/tsi108_pci.c +++ b/trunk/arch/powerpc/sysdev/tsi108_pci.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -50,7 +49,6 @@ ((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base) u32 tsi108_pci_cfg_base; -static u32 tsi108_pci_cfg_phys; u32 tsi108_csr_vir_base; static struct device_node *pci_irq_node; static struct irq_host *pci_irq_host; @@ -187,7 +185,7 @@ tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset, void tsi108_clear_pci_cfg_error(void) { - tsi108_clear_pci_error(tsi108_pci_cfg_phys); + tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS); } static struct pci_ops tsi108_direct_pci_ops = { @@ -195,17 +193,17 @@ static struct pci_ops tsi108_direct_pci_ops = { tsi108_direct_write_config }; -int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary) +int __init tsi108_setup_pci(struct device_node *dev) { int len; struct pci_controller *hose; struct resource rsrc; const int *bus_range; - int has_address = 0; + int primary = 0, has_address = 0; /* PCI Config mapping */ - tsi108_pci_cfg_base = (u32)ioremap(cfg_phys, TSI108_PCI_CFG_SIZE); - tsi108_pci_cfg_phys = cfg_phys; + tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS, + TSI108_PCI_CFG_SIZE); DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__, tsi108_pci_cfg_base); diff --git a/trunk/arch/powerpc/sysdev/uic.c b/trunk/arch/powerpc/sysdev/uic.c index 89059895a20d..968fb40af9dc 100644 --- a/trunk/arch/powerpc/sysdev/uic.c +++ b/trunk/arch/powerpc/sysdev/uic.c @@ -221,7 +221,7 @@ static struct uic * __init uic_init_one(struct device_node *node) const u32 *indexp, *dcrreg; int len; - BUG_ON(! of_device_is_compatible(node, "ibm,uic")); + BUG_ON(! device_is_compatible(node, "ibm,uic")); uic = alloc_bootmem(sizeof(*uic)); if (! uic) diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index 28fdf4f50c27..b481db1dacb4 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -1217,6 +1217,7 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp, { unsigned long size, offset; const char *name; + char *modname; *startp = *endp = 0; if (pc == 0) @@ -1224,7 +1225,7 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp, if (setjmp(bus_error_jmp) == 0) { catch_memory_errors = 1; sync(); - name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr); + name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr); if (name != NULL) { *startp = pc - offset; *endp = pc - offset + size; diff --git a/trunk/arch/ppc/8260_io/enet.c b/trunk/arch/ppc/8260_io/enet.c index 4c0a7d732f69..48ce84f5be93 100644 --- a/trunk/arch/ppc/8260_io/enet.c +++ b/trunk/arch/ppc/8260_io/enet.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ppc/8260_io/fcc_enet.c b/trunk/arch/ppc/8260_io/fcc_enet.c index cab395da25da..9db825fe37f0 100644 --- a/trunk/arch/ppc/8260_io/fcc_enet.c +++ b/trunk/arch/ppc/8260_io/fcc_enet.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ppc/8xx_io/enet.c b/trunk/arch/ppc/8xx_io/enet.c index e58288e14369..bfa3f52996d1 100644 --- a/trunk/arch/ppc/8xx_io/enet.c +++ b/trunk/arch/ppc/8xx_io/enet.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ppc/kernel/ppc_htab.c b/trunk/arch/ppc/kernel/ppc_htab.c index aa07b63c0a6c..0a7e42d54eaf 100644 --- a/trunk/arch/ppc/kernel/ppc_htab.c +++ b/trunk/arch/ppc/kernel/ppc_htab.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ppc/kernel/smp.c b/trunk/arch/ppc/kernel/smp.c index 055998575cb4..96a55972b986 100644 --- a/trunk/arch/ppc/kernel/smp.c +++ b/trunk/arch/ppc/kernel/smp.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ppc/kernel/vmlinux.lds.S b/trunk/arch/ppc/kernel/vmlinux.lds.S index 44cd128fb719..a0625562a44b 100644 --- a/trunk/arch/ppc/kernel/vmlinux.lds.S +++ b/trunk/arch/ppc/kernel/vmlinux.lds.S @@ -130,7 +130,7 @@ SECTIONS __ftr_fixup : { *(__ftr_fixup) } __stop___ftr_fixup = .; - . = ALIGN(4096); + . = ALIGN(32); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/ppc/syslib/ppc4xx_sgdma.c b/trunk/arch/ppc/syslib/ppc4xx_sgdma.c index c4b369b50f9c..939abe3c1f45 100644 --- a/trunk/arch/ppc/syslib/ppc4xx_sgdma.c +++ b/trunk/arch/ppc/syslib/ppc4xx_sgdma.c @@ -23,10 +23,11 @@ #include #include #include -#include +#include #include #include +#include #include void diff --git a/trunk/arch/ppc/syslib/virtex_devices.h b/trunk/arch/ppc/syslib/virtex_devices.h index 3d4be1412f60..4a17dd3927c1 100644 --- a/trunk/arch/ppc/syslib/virtex_devices.h +++ b/trunk/arch/ppc/syslib/virtex_devices.h @@ -13,13 +13,6 @@ #include -/* ML300/403 reference design framebuffer driver platform data struct */ -struct xilinxfb_platform_data { - u32 rotate_screen; - u32 screen_height_mm; - u32 screen_width_mm; -}; - void __init virtex_early_serial_map(void); /* Prototype for device fixup routine. Implement this routine in the diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 1a84719be264..e6ec418093e5 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -49,9 +49,6 @@ config GENERIC_BUG config NO_IOMEM def_bool y -config NO_DMA - def_bool y - mainmenu "Linux Kernel Configuration" config S390 diff --git a/trunk/arch/s390/appldata/appldata_net_sum.c b/trunk/arch/s390/appldata/appldata_net_sum.c index 2180ac105b05..a43f3488fecf 100644 --- a/trunk/arch/s390/appldata/appldata_net_sum.c +++ b/trunk/arch/s390/appldata/appldata_net_sum.c @@ -107,7 +107,7 @@ static void appldata_get_net_sum_data(void *data) tx_dropped = 0; collisions = 0; read_lock(&dev_base_lock); - for_each_netdev(dev) { + for (dev = dev_base; dev != NULL; dev = dev->next) { stats = dev->get_stats(dev); rx_packets += stats->rx_packets; tx_packets += stats->tx_packets; diff --git a/trunk/arch/s390/crypto/aes_s390.c b/trunk/arch/s390/crypto/aes_s390.c index 3660ca6a3306..91636353f6f0 100644 --- a/trunk/arch/s390/crypto/aes_s390.c +++ b/trunk/arch/s390/crypto/aes_s390.c @@ -119,8 +119,7 @@ static struct crypto_alg aes_alg = { .cra_name = "aes", .cra_driver_name = "aes-s390", .cra_priority = CRYPT_S390_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_CIPHER | - CRYPTO_ALG_NEED_FALLBACK, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s390_aes_ctx), .cra_module = THIS_MODULE, @@ -207,8 +206,7 @@ static struct crypto_alg ecb_aes_alg = { .cra_name = "ecb(aes)", .cra_driver_name = "ecb-aes-s390", .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | - CRYPTO_ALG_NEED_FALLBACK, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s390_aes_ctx), .cra_type = &crypto_blkcipher_type, @@ -302,8 +300,7 @@ static struct crypto_alg cbc_aes_alg = { .cra_name = "cbc(aes)", .cra_driver_name = "cbc-aes-s390", .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | - CRYPTO_ALG_NEED_FALLBACK, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s390_aes_ctx), .cra_type = &crypto_blkcipher_type, @@ -336,14 +333,10 @@ static int __init aes_init(void) return -EOPNOTSUPP; /* z9 109 and z9 BC/EC only support 128 bit key length */ - if (keylen_flag == AES_KEYLEN_128) { - aes_alg.cra_u.cipher.cia_max_keysize = AES_MIN_KEY_SIZE; - ecb_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE; - cbc_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE; + if (keylen_flag == AES_KEYLEN_128) printk(KERN_INFO "aes_s390: hardware acceleration only available for" "128 bit keys\n"); - } ret = crypto_register_alg(&aes_alg); if (ret) diff --git a/trunk/arch/s390/kernel/compat_signal.c b/trunk/arch/s390/kernel/compat_signal.c index a5692c460bad..80a54a0149ab 100644 --- a/trunk/arch/s390/kernel/compat_signal.c +++ b/trunk/arch/s390/kernel/compat_signal.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/kernel/dis.c b/trunk/arch/s390/kernel/dis.c index a057ebf108a7..dabaf98943d0 100644 --- a/trunk/arch/s390/kernel/dis.c +++ b/trunk/arch/s390/kernel/dis.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #ifndef CONFIG_64BIT #define ONELONG "%08lx: " diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c index 0ea048d350d8..06833ac2b115 100644 --- a/trunk/arch/s390/kernel/ipl.c +++ b/trunk/arch/s390/kernel/ipl.c @@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(diag308); /* SYSFS */ #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \ -static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ +static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ char *page) \ { \ return sprintf(page, _format, _value); \ @@ -173,13 +173,13 @@ static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL); #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \ -static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ +static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ char *page) \ { \ return sprintf(page, _fmt_out, \ (unsigned long long) _value); \ } \ -static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ +static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\ const char *buf, size_t len) \ { \ unsigned long long value; \ @@ -194,12 +194,12 @@ static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ sys_##_prefix##_##_name##_store); #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\ -static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ +static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ char *page) \ { \ return sprintf(page, _fmt_out, _value); \ } \ -static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ +static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\ const char *buf, size_t len) \ { \ if (sscanf(buf, _fmt_in, _value) != 1) \ @@ -272,14 +272,14 @@ void __init setup_ipl_info(void) struct ipl_info ipl_info; EXPORT_SYMBOL_GPL(ipl_info); -static ssize_t ipl_type_show(struct kset *kset, char *page) +static ssize_t ipl_type_show(struct subsystem *subsys, char *page) { return sprintf(page, "%s\n", ipl_type_str(ipl_info.type)); } static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); -static ssize_t sys_ipl_device_show(struct kset *kset, char *page) +static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page) { struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; @@ -371,7 +371,7 @@ static struct attribute_group ipl_fcp_attr_group = { /* CCW ipl device attributes */ -static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page) +static ssize_t ipl_ccw_loadparm_show(struct subsystem *subsys, char *page) { char loadparm[LOADPARM_LEN + 1] = {}; @@ -469,7 +469,7 @@ static void reipl_get_ascii_loadparm(char *loadparm) strstrip(loadparm); } -static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page) +static ssize_t reipl_ccw_loadparm_show(struct subsystem *subsys, char *page) { char buf[LOADPARM_LEN + 1]; @@ -477,7 +477,7 @@ static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page) return sprintf(page, "%s\n", buf); } -static ssize_t reipl_ccw_loadparm_store(struct kset *kset, +static ssize_t reipl_ccw_loadparm_store(struct subsystem *subsys, const char *buf, size_t len) { int i, lp_len; @@ -572,12 +572,12 @@ static int reipl_set_type(enum ipl_type type) return 0; } -static ssize_t reipl_type_show(struct kset *kset, char *page) +static ssize_t reipl_type_show(struct subsystem *subsys, char *page) { return sprintf(page, "%s\n", ipl_type_str(reipl_type)); } -static ssize_t reipl_type_store(struct kset *kset, const char *buf, +static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf, size_t len) { int rc = -EINVAL; @@ -665,12 +665,12 @@ static int dump_set_type(enum dump_type type) return 0; } -static ssize_t dump_type_show(struct kset *kset, char *page) +static ssize_t dump_type_show(struct subsystem *subsys, char *page) { return sprintf(page, "%s\n", dump_type_str(dump_type)); } -static ssize_t dump_type_store(struct kset *kset, const char *buf, +static ssize_t dump_type_store(struct subsystem *subsys, const char *buf, size_t len) { int rc = -EINVAL; @@ -697,12 +697,12 @@ static decl_subsys(shutdown_actions, NULL, NULL); /* on panic */ -static ssize_t on_panic_show(struct kset *kset, char *page) +static ssize_t on_panic_show(struct subsystem *subsys, char *page) { return sprintf(page, "%s\n", shutdown_action_str(on_panic_action)); } -static ssize_t on_panic_store(struct kset *kset, const char *buf, +static ssize_t on_panic_store(struct subsystem *subsys, const char *buf, size_t len) { if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0) diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c index e39333ae0fcf..993f35381496 100644 --- a/trunk/arch/s390/kernel/kprobes.c +++ b/trunk/arch/s390/kernel/kprobes.c @@ -24,8 +24,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -271,13 +271,23 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, } /* Called with kretprobe_lock held */ -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, +void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { - ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14]; + struct kretprobe_instance *ri; - /* Replace the return addr with trampoline addr */ - regs->gprs[14] = (unsigned long)&kretprobe_trampoline; + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14]; + + /* Replace the return addr with trampoline addr */ + regs->gprs[14] = (unsigned long)&kretprobe_trampoline; + + add_rp_inst(ri); + } else { + rp->nmissed++; + } } static int __kprobes kprobe_handler(struct pt_regs *regs) @@ -506,7 +516,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) return 1; } -int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) +static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -593,6 +603,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, ret = NOTIFY_STOP; break; case DIE_TRAP: + case DIE_PAGE_FAULT: /* kprobe_running() needs smp_processor_id() */ preempt_disable(); if (kprobe_running() && @@ -661,10 +672,3 @@ int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } - -int __kprobes arch_trampoline_kprobe(struct kprobe *p) -{ - if (p->addr == (kprobe_opcode_t *) & kretprobe_trampoline) - return 1; - return 0; -} diff --git a/trunk/arch/s390/kernel/process.c b/trunk/arch/s390/kernel/process.c index eb43c3b31269..11d9b0197626 100644 --- a/trunk/arch/s390/kernel/process.c +++ b/trunk/arch/s390/kernel/process.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 6bfb0889eb10..3dfd0985861c 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -65,7 +65,7 @@ long psw_user_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | * User copy operations. */ struct uaccess_ops uaccess; -EXPORT_SYMBOL(uaccess); +EXPORT_SYMBOL_GPL(uaccess); /* * Machine setup.. @@ -74,8 +74,6 @@ unsigned int console_mode = 0; unsigned int console_devno = -1; unsigned int console_irq = -1; unsigned long machine_flags = 0; -unsigned long elf_hwcap = 0; -char elf_platform[ELF_PLATFORM_SIZE]; struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ @@ -751,98 +749,6 @@ setup_memory(void) #endif } -static __init unsigned int stfl(void) -{ - asm volatile( - " .insn s,0xb2b10000,0(0)\n" /* stfl */ - "0:\n" - EX_TABLE(0b,0b)); - return S390_lowcore.stfl_fac_list; -} - -static __init int stfle(unsigned long long *list, int doublewords) -{ - typedef struct { unsigned long long _[doublewords]; } addrtype; - register unsigned long __nr asm("0") = doublewords - 1; - - asm volatile(".insn s,0xb2b00000,%0" /* stfle */ - : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc"); - return __nr + 1; -} - -/* - * Setup hardware capabilities. - */ -static void __init setup_hwcaps(void) -{ - static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 }; - struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; - unsigned long long facility_list_extended; - unsigned int facility_list; - int i; - - facility_list = stfl(); - /* - * The store facility list bits numbers as found in the principles - * of operation are numbered with bit 1UL<<31 as number 0 to - * bit 1UL<<0 as number 31. - * Bit 0: instructions named N3, "backported" to esa-mode - * Bit 2: z/Architecture mode is active - * Bit 7: the store-facility-list-extended facility is installed - * Bit 17: the message-security assist is installed - * Bit 19: the long-displacement facility is installed - * Bit 21: the extended-immediate facility is installed - * These get translated to: - * HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1, - * HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3, - * HWCAP_S390_LDISP bit 4, and HWCAP_S390_EIMM bit 5. - */ - for (i = 0; i < 6; i++) - if (facility_list & (1UL << (31 - stfl_bits[i]))) - elf_hwcap |= 1UL << i; - - /* - * Check for additional facilities with store-facility-list-extended. - * stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0 - * and 1ULL<<0 as bit 63. Bits 0-31 contain the same information - * as stored by stfl, bits 32-xxx contain additional facilities. - * How many facility words are stored depends on the number of - * doublewords passed to the instruction. The additional facilites - * are: - * Bit 43: decimal floating point facility is installed - * translated to: - * HWCAP_S390_DFP bit 6. - */ - if ((elf_hwcap & (1UL << 2)) && - stfle(&facility_list_extended, 1) > 0) { - if (facility_list_extended & (1ULL << (64 - 43))) - elf_hwcap |= 1UL << 6; - } - - switch (cpuinfo->cpu_id.machine) { - case 0x9672: -#if !defined(CONFIG_64BIT) - default: /* Use "g5" as default for 31 bit kernels. */ -#endif - strcpy(elf_platform, "g5"); - break; - case 0x2064: - case 0x2066: -#if defined(CONFIG_64BIT) - default: /* Use "z900" as default for 64 bit kernels. */ -#endif - strcpy(elf_platform, "z900"); - break; - case 0x2084: - case 0x2086: - strcpy(elf_platform, "z990"); - break; - case 0x2094: - strcpy(elf_platform, "z9-109"); - break; - } -} - /* * Setup function called from init/main.c just after the banner * was printed. @@ -898,11 +804,6 @@ setup_arch(char **cmdline_p) __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr; smp_setup_cpu_possible_map(); - /* - * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). - */ - setup_hwcaps(); - /* * Create kernel page tables and switch to virtual addressing. */ @@ -938,12 +839,8 @@ void print_cpu_info(struct cpuinfo_S390 *cpuinfo) static int show_cpuinfo(struct seq_file *m, void *v) { - static const char *hwcap_str[7] = { - "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp" - }; struct cpuinfo_S390 *cpuinfo; unsigned long n = (unsigned long) v - 1; - int i; s390_adjust_jiffies(); preempt_disable(); @@ -953,13 +850,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) "bogomips per cpu: %lu.%02lu\n", num_online_cpus(), loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ))%100); - seq_puts(m, "features\t: "); - for (i = 0; i < 7; i++) - if (hwcap_str[i] && (elf_hwcap & (1UL << i))) - seq_printf(m, "%s ", hwcap_str[i]); - seq_puts(m, "\n"); } - if (cpu_online(n)) { #ifdef CONFIG_SMP if (smp_processor_id() == n) diff --git a/trunk/arch/s390/kernel/signal.c b/trunk/arch/s390/kernel/signal.c index d264671c1b71..3c41907799a1 100644 --- a/trunk/arch/s390/kernel/signal.c +++ b/trunk/arch/s390/kernel/signal.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index b7977027a28f..3754e2031b39 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/kernel/stacktrace.c b/trunk/arch/s390/kernel/stacktrace.c index 515ff9011dd7..2e5c65a1863e 100644 --- a/trunk/arch/s390/kernel/stacktrace.c +++ b/trunk/arch/s390/kernel/stacktrace.c @@ -59,7 +59,7 @@ static unsigned long save_context_stack(struct stack_trace *trace, } } -void save_stack_trace(struct stack_trace *trace) +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) { register unsigned long sp asm ("15"); unsigned long orig_sp, new_sp; @@ -69,16 +69,20 @@ void save_stack_trace(struct stack_trace *trace) new_sp = save_context_stack(trace, &trace->skip, orig_sp, S390_lowcore.panic_stack - PAGE_SIZE, S390_lowcore.panic_stack); - if (new_sp != orig_sp) + if ((new_sp != orig_sp) && !trace->all_contexts) return; new_sp = save_context_stack(trace, &trace->skip, new_sp, S390_lowcore.async_stack - ASYNC_SIZE, S390_lowcore.async_stack); - if (new_sp != orig_sp) + if ((new_sp != orig_sp) && !trace->all_contexts) return; - - save_context_stack(trace, &trace->skip, new_sp, - S390_lowcore.thread_info, - S390_lowcore.thread_info + THREAD_SIZE); + if (task) + save_context_stack(trace, &trace->skip, new_sp, + (unsigned long) task_stack_page(task), + (unsigned long) task_stack_page(task) + THREAD_SIZE); + else + save_context_stack(trace, &trace->skip, new_sp, + S390_lowcore.thread_info, + S390_lowcore.thread_info + THREAD_SIZE); return; } diff --git a/trunk/arch/s390/kernel/sys_s390.c b/trunk/arch/s390/kernel/sys_s390.c index 1c90c7e99978..3a77c22cda78 100644 --- a/trunk/arch/s390/kernel/sys_s390.c +++ b/trunk/arch/s390/kernel/sys_s390.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index 9c2872a7cca7..711dae8da7ad 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c index cbfe73034c30..49dec830373a 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -22,11 +22,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -40,6 +40,7 @@ #include #include #include +#include /* Called from entry.S only */ extern void handle_per_exception(struct pt_regs *regs); @@ -69,6 +70,20 @@ static int kstack_depth_to_print = 12; static int kstack_depth_to_print = 20; #endif /* CONFIG_64BIT */ +ATOMIC_NOTIFIER_HEAD(s390die_chain); + +int register_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&s390die_chain, nb); +} +EXPORT_SYMBOL(register_die_notifier); + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&s390die_chain, nb); +} +EXPORT_SYMBOL(unregister_die_notifier); + /* * For show_trace we have tree different stack to consider: * - the panic stack which is used if the kernel stack has overflown diff --git a/trunk/arch/s390/kernel/vmlinux.lds.S b/trunk/arch/s390/kernel/vmlinux.lds.S index e9d3432aba60..418f6426a949 100644 --- a/trunk/arch/s390/kernel/vmlinux.lds.S +++ b/trunk/arch/s390/kernel/vmlinux.lds.S @@ -107,7 +107,7 @@ SECTIONS . = ALIGN(2); __initramfs_end = .; #endif - . = ALIGN(4096); + . = ALIGN(256); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 8b924b359774..2b76a879a7b5 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include #include +#include #include #ifndef CONFIG_64BIT @@ -52,24 +52,38 @@ extern int sysctl_userprocess_debug; extern void die(const char *,struct pt_regs *,long); #ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs, long err) +static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); +int register_page_fault_notifier(struct notifier_block *nb) { - int ret = 0; - - /* kprobe_running() needs smp_processor_id() */ - if (!user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, 14)) - ret = 1; - preempt_enable(); - } + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} - return ret; +static int __kprobes __notify_page_fault(struct pt_regs *regs, long err) +{ + struct die_args args = { .str = "page fault", + .trapnr = 14, + .signr = SIGSEGV }; + args.regs = regs; + args.err = err; + return atomic_notifier_call_chain(¬ify_page_fault_chain, + DIE_PAGE_FAULT, &args); +} + +static inline int notify_page_fault(struct pt_regs *regs, long err) +{ + if (unlikely(kprobe_running())) + return __notify_page_fault(regs, err); + return NOTIFY_DONE; } #else static inline int notify_page_fault(struct pt_regs *regs, long err) { - return 0; + return NOTIFY_DONE; } #endif @@ -305,7 +319,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write) int space; int si_code; - if (notify_page_fault(regs, error_code)) + if (notify_page_fault(regs, error_code) == NOTIFY_STOP) return; tsk = current; diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index d74eb120a9c6..4d16d8917074 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -22,10 +22,6 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool -config GENERIC_BUG - def_bool y - depends on BUG - config GENERIC_FIND_NEXT_BIT bool default y @@ -92,14 +88,6 @@ config SH_SOLUTION_ENGINE Select SolutionEngine if configuring for a Hitachi SH7709 or SH7750 evaluation board. -config SH_7722_SOLUTION_ENGINE - bool "SolutionEngine7722" - select SOLUTION_ENGINE - select CPU_SUBTYPE_SH7722 - help - Select 7722 SolutionEngine if configuring for a Hitachi SH772 - evaluation board. - config SH_7751_SOLUTION_ENGINE bool "SolutionEngine7751" select SOLUTION_ENGINE @@ -107,14 +95,6 @@ config SH_7751_SOLUTION_ENGINE help Select 7751 SolutionEngine if configuring for a Hitachi SH7751 evaluation board. - -config SH_7780_SOLUTION_ENGINE - bool "SolutionEngine7780" - select SOLUTION_ENGINE - select CPU_SUBTYPE_SH7780 - help - Select 7780 SolutionEngine if configuring for a Renesas SH7780 - evaluation board. config SH_7300_SOLUTION_ENGINE bool "SolutionEngine7300" @@ -213,8 +193,12 @@ config SH_RTS7751R2D Select RTS7751R2D if configuring for a Renesas Technology Sales SH-Graphics board. -config SH_HIGHLANDER - bool "Highlander" +config SH_R7780RP + bool "R7780RP-1" + select CPU_SUBTYPE_SH7780 + help + Select R7780RP-1 if configuring for a Renesas Solutions + HIGHLANDER board. config SH_EDOSK7705 bool "EDOSK7705" @@ -259,12 +243,6 @@ config SH_7619_SOLUTION_ENGINE help Select 7619 SolutionEngine if configuring for a Hitachi SH7619 evaluation board. - -config SH_LBOX_RE2 - bool "L-BOX RE2" - select CPU_SUBTYPE_SH7751R - help - Select L-BOX RE2 if configuring for the NTT COMWARE L-BOX RE2. config SH_UNKNOWN bool "BareCPU" @@ -280,10 +258,6 @@ config SH_UNKNOWN endchoice -source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" -source "arch/sh/boards/renesas/rts7751r2d/Kconfig" -source "arch/sh/boards/renesas/r7780rp/Kconfig" - source "arch/sh/mm/Kconfig" config CF_ENABLER @@ -392,16 +366,6 @@ config SH_STORE_QUEUES Selecting this option will enable an in-kernel API for manipulating the store queues integrated in the SH-4 processors. -config SPECULATIVE_EXECUTION - bool "Speculative subroutine return" - depends on CPU_SUBTYPE_SH7780 && EXPERIMENTAL - help - This enables support for a speculative instruction fetch for - subroutine return. There are various pitfalls associated with - this, as outlined in the SH7780 hardware manual. - - If unsure, say N. - config CPU_HAS_INTEVT bool @@ -434,9 +398,8 @@ config CPU_HAS_PTEA endmenu -menu "Timer and clock configuration" - -if !GENERIC_TIME +menu "Timer support" +depends on !GENERIC_TIME config SH_TMU bool "TMU timer support" @@ -459,11 +422,17 @@ config SH_MTU2 help This enables the use of the MTU2 as the system timer. -endif +endmenu + +source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" + +source "arch/sh/boards/renesas/rts7751r2d/Kconfig" + +source "arch/sh/boards/renesas/r7780rp/Kconfig" config SH_TIMER_IRQ int - default "28" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 + default "28" if CPU_SUBTYPE_SH7780 default "86" if CPU_SUBTYPE_SH7619 default "140" if CPU_SUBTYPE_SH7206 default "16" @@ -493,8 +462,7 @@ config SH_PCLK_FREQ default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ CPU_SUBTYPE_SH7206 - default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 || \ - CPU_SUBTYPE_SH7785 + default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 default "60000000" if CPU_SUBTYPE_SH7751 default "66000000" if CPU_SUBTYPE_SH4_202 help @@ -509,8 +477,6 @@ config SH_CLK_MD help MD2 - MD0 pin setting. -endmenu - menu "CPU Frequency scaling" source "drivers/cpufreq/Kconfig" @@ -529,6 +495,21 @@ config SH_CPU_FREQ endmenu +source "arch/sh/drivers/dma/Kconfig" + +source "arch/sh/cchips/Kconfig" + +config HEARTBEAT + bool "Heartbeat LED" + depends on SH_MPC1211 || SH_SH03 || \ + SOLUTION_ENGINE || \ + SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK || \ + SH_R7780RP + help + Use the power-on LED on your machine as a load meter. The exact + behavior is platform-dependent, but normally the flash frequency is + a hyperbolic function of the 5-minute load average. + source "arch/sh/drivers/Kconfig" endmenu @@ -559,20 +540,6 @@ config KEXEC support. As of this writing the exact hardware interface is strongly in flux, so no good recommendation can be made. -config CRASH_DUMP - bool "kernel crash dumps (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - Generate crash dump after being started by kexec. - This should be normally only set in special crash dump kernels - which are loaded in the main kernel with kexec-tools into - a specially reserved region and then later executed after - a crash by kdump/kexec. The crash dump kernel must be compiled - to a memory address not used by the main kernel using - MEMORY_START. - - For more details see Documentation/kdump/kdump.txt - config SMP bool "Symmetric multi-processing support" ---help--- diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug index b56307294b67..87902e0298e2 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -33,7 +33,6 @@ config EARLY_SCIF_CONSOLE_PORT default "0xffe00000" if CPU_SUBTYPE_SH7780 default "0xfffe9800" if CPU_SUBTYPE_SH7206 default "0xf8420000" if CPU_SUBTYPE_SH7619 - default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705 default "0xffe80000" if CPU_SH4 config EARLY_PRINTK @@ -78,17 +77,16 @@ config 4KSTACKS on the VM subsystem for higher order allocations. This option will also use IRQ stacks to compensate for the reduced stackspace. -config SH_KGDB +config KGDB bool "Include KGDB kernel debugger" select FRAME_POINTER - select DEBUG_INFO help Include in-kernel hooks for kgdb, the Linux kernel source level debugger. See for more information. Unless you are intending to debug the kernel, say N here. menu "KGDB configuration options" - depends on SH_KGDB + depends on KGDB config MORE_COMPILE_OPTIONS bool "Add any additional compile options" @@ -105,16 +103,22 @@ config KGDB_NMI bool "Enter KGDB on NMI" default n +config KGDB_THREAD + bool "Include KGDB thread support" + default y + config SH_KGDB_CONSOLE bool "Console messages through GDB" - depends on !SERIAL_SH_SCI_CONSOLE - select SERIAL_CORE_CONSOLE default n config KGDB_SYSRQ bool "Allow SysRq 'G' to enter KGDB" default y +config KGDB_KERNEL_ASSERTS + bool "Include KGDB kernel assertions" + default n + comment "Serial port setup" config KGDB_DEFPORT @@ -127,7 +131,7 @@ config KGDB_DEFBAUD choice prompt "Parity" - depends on SH_KGDB + depends on KGDB default KGDB_DEFPARITY_N config KGDB_DEFPARITY_N @@ -143,7 +147,7 @@ endchoice choice prompt "Data bits" - depends on SH_KGDB + depends on KGDB default KGDB_DEFBITS_8 config KGDB_DEFBITS_8 diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index 7b1122417050..bd9b1729f8b8 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -47,6 +47,7 @@ cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding cflags-$(CONFIG_SH_DSP) += -Wa,-dsp +cflags-$(CONFIG_SH_KGDB) += -g cflags-$(CONFIG_MORE_COMPILE_OPTIONS) += \ $(shell echo $(CONFIG_COMPILE_OPTIONS) | sed -e 's/"//g') @@ -88,9 +89,7 @@ core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/ # Boards machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x -machdir-$(CONFIG_SH_7722_SOLUTION_ENGINE) := se/7722 machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 -machdir-$(CONFIG_SH_7780_SOLUTION_ENGINE) := se/7780 machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343 machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 @@ -104,7 +103,7 @@ machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705 -machdir-$(CONFIG_SH_HIGHLANDER) := renesas/r7780rp +machdir-$(CONFIG_SH_R7780RP) := renesas/r7780rp machdir-$(CONFIG_SH_7710VOIPGW) := renesas/sh7710voipgw machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev machdir-$(CONFIG_SH_LANDISK) := landisk @@ -112,7 +111,6 @@ machdir-$(CONFIG_SH_TITAN) := titan machdir-$(CONFIG_SH_SHMIN) := shmin machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206 machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619 -machdir-$(CONFIG_SH_LBOX_RE2) := lboxre2 machdir-$(CONFIG_SH_UNKNOWN) := unknown incdir-y := $(notdir $(machdir-y)) diff --git a/trunk/arch/sh/boards/hp6xx/Makefile b/trunk/arch/sh/boards/hp6xx/Makefile index b3124278247c..ff1b7f5b4e91 100644 --- a/trunk/arch/sh/boards/hp6xx/Makefile +++ b/trunk/arch/sh/boards/hp6xx/Makefile @@ -2,6 +2,6 @@ # Makefile for the HP6xx specific parts of the kernel # -obj-y := setup.o +obj-y := setup.o obj-$(CONFIG_PM) += pm.o pm_wakeup.o -obj-$(CONFIG_APM_EMULATION) += hp6xx_apm.o +obj-$(CONFIG_APM) += hp6xx_apm.o diff --git a/trunk/arch/sh/boards/hp6xx/setup.c b/trunk/arch/sh/boards/hp6xx/setup.c index 6aeee85c9785..b5a96649ed26 100644 --- a/trunk/arch/sh/boards/hp6xx/setup.c +++ b/trunk/arch/sh/boards/hp6xx/setup.c @@ -2,7 +2,6 @@ * linux/arch/sh/boards/hp6xx/setup.c * * Copyright (C) 2002 Andriy Skulysh - * Copyright (C) 2007 Kristoffer Ericson * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. @@ -11,7 +10,6 @@ */ #include #include -#include #include #include #include @@ -21,40 +19,6 @@ #define SCPCR 0xa4000116 #define SCPDR 0xa4000136 -/* CF Slot */ -static struct resource cf_ide_resources[] = { - [0] = { - .start = 0x15000000 + 0x1f0, - .end = 0x15000000 + 0x1f0 + 0x08 - 0x01, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 0x15000000 + 0x1fe, - .end = 0x15000000 + 0x1fe + 0x01, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = 93, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device cf_ide_device = { - .name = "pata_platform", - .id = -1, - .num_resources = ARRAY_SIZE(cf_ide_resources), - .resource = cf_ide_resources, -}; - -static struct platform_device *hp6xx_devices[] __initdata = { - &cf_ide_device, -}; - -static int __init hp6xx_devices_setup(void) -{ - return platform_add_devices(hp6xx_devices, ARRAY_SIZE(hp6xx_devices)); -} - static void __init hp6xx_setup(char **cmdline_p) { u8 v8; @@ -96,12 +60,41 @@ static void __init hp6xx_setup(char **cmdline_p) v |= SCPCR_TS_ENABLE; ctrl_outw(v, SCPCR); } -device_initcall(hp6xx_devices_setup); +/* + * XXX: This is stupid, we should have a generic machine vector for the cchips + * and just wrap the platform setup code in to this, as it's the only thing + * that ends up being different. + */ struct sh_machine_vector mv_hp6xx __initmv = { .mv_name = "hp6xx", .mv_setup = hp6xx_setup, .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, + + .mv_inb = hd64461_inb, + .mv_inw = hd64461_inw, + .mv_inl = hd64461_inl, + .mv_outb = hd64461_outb, + .mv_outw = hd64461_outw, + .mv_outl = hd64461_outl, + + .mv_inb_p = hd64461_inb_p, + .mv_inw_p = hd64461_inw, + .mv_inl_p = hd64461_inl, + .mv_outb_p = hd64461_outb_p, + .mv_outw_p = hd64461_outw, + .mv_outl_p = hd64461_outl, + + .mv_insb = hd64461_insb, + .mv_insw = hd64461_insw, + .mv_insl = hd64461_insl, + .mv_outsb = hd64461_outsb, + .mv_outsw = hd64461_outsw, + .mv_outsl = hd64461_outsl, + + .mv_readw = hd64461_readw, + .mv_writew = hd64461_writew, + .mv_irq_demux = hd64461_irq_demux, }; ALIAS_MV(hp6xx) diff --git a/trunk/arch/sh/boards/landisk/Makefile b/trunk/arch/sh/boards/landisk/Makefile index a696b4277fa9..89e4beb2ad47 100644 --- a/trunk/arch/sh/boards/landisk/Makefile +++ b/trunk/arch/sh/boards/landisk/Makefile @@ -2,4 +2,4 @@ # Makefile for I-O DATA DEVICE, INC. "LANDISK Series" # -obj-y := setup.o irq.o psw.o gio.o +obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o diff --git a/trunk/arch/sh/boards/landisk/gio.c b/trunk/arch/sh/boards/landisk/gio.c deleted file mode 100644 index 50d38be62f01..000000000000 --- a/trunk/arch/sh/boards/landisk/gio.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * arch/sh/boards/landisk/gio.c - driver for landisk - * - * This driver will also support the I-O DATA Device, Inc. LANDISK Board. - * LANDISK and USL-5P Button, LED and GIO driver drive function. - * - * Copylight (C) 2006 kogiidena - * Copylight (C) 2002 Atom Create Engineering Co., Ltd. * - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEVCOUNT 4 -#define GIO_MINOR 2 /* GIO minor no. */ - -static dev_t dev; -static struct cdev *cdev_p; -static int openCnt; - -static int gio_open(struct inode *inode, struct file *filp) -{ - int minor; - - minor = MINOR(inode->i_rdev); - if (minor < DEVCOUNT) { - if (openCnt > 0) { - return -EALREADY; - } else { - openCnt++; - return 0; - } - } - return -ENOENT; -} - -static int gio_close(struct inode *inode, struct file *filp) -{ - int minor; - - minor = MINOR(inode->i_rdev); - if (minor < DEVCOUNT) { - openCnt--; - } - return 0; -} - -static int gio_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - unsigned int data; - static unsigned int addr = 0; - - if (cmd & 0x01) { /* write */ - if (copy_from_user(&data, (int *)arg, sizeof(int))) { - return -EFAULT; - } - } - - switch (cmd) { - case GIODRV_IOCSGIOSETADDR: /* addres set */ - addr = data; - break; - - case GIODRV_IOCSGIODATA1: /* write byte */ - ctrl_outb((unsigned char)(0x0ff & data), addr); - break; - - case GIODRV_IOCSGIODATA2: /* write word */ - if (addr & 0x01) { - return -EFAULT; - } - ctrl_outw((unsigned short int)(0x0ffff & data), addr); - break; - - case GIODRV_IOCSGIODATA4: /* write long */ - if (addr & 0x03) { - return -EFAULT; - } - ctrl_outl(data, addr); - break; - - case GIODRV_IOCGGIODATA1: /* read byte */ - data = ctrl_inb(addr); - break; - - case GIODRV_IOCGGIODATA2: /* read word */ - if (addr & 0x01) { - return -EFAULT; - } - data = ctrl_inw(addr); - break; - - case GIODRV_IOCGGIODATA4: /* read long */ - if (addr & 0x03) { - return -EFAULT; - } - data = ctrl_inl(addr); - break; - default: - return -EFAULT; - break; - } - - if ((cmd & 0x01) == 0) { /* read */ - if (copy_to_user((int *)arg, &data, sizeof(int))) { - return -EFAULT; - } - } - return 0; -} - -static struct file_operations gio_fops = { - .owner = THIS_MODULE, - .open = gio_open, /* open */ - .release = gio_close, /* release */ - .ioctl = gio_ioctl, /* ioctl */ -}; - -static int __init gio_init(void) -{ - int error; - - printk(KERN_INFO "gio: driver initialized\n"); - - openCnt = 0; - - if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) { - printk(KERN_ERR - "gio: Couldn't alloc_chrdev_region, error=%d\n", - error); - return 1; - } - - cdev_p = cdev_alloc(); - cdev_p->ops = &gio_fops; - error = cdev_add(cdev_p, dev, DEVCOUNT); - if (error) { - printk(KERN_ERR - "gio: Couldn't cdev_add, error=%d\n", error); - return 1; - } - - return 0; -} - -static void __exit gio_exit(void) -{ - cdev_del(cdev_p); - unregister_chrdev_region(dev, DEVCOUNT); -} - -module_init(gio_init); -module_exit(gio_exit); - -MODULE_LICENSE("GPL"); diff --git a/trunk/arch/sh/boards/landisk/io.c b/trunk/arch/sh/boards/landisk/io.c new file mode 100644 index 000000000000..92498b4947d5 --- /dev/null +++ b/trunk/arch/sh/boards/landisk/io.c @@ -0,0 +1,250 @@ +/* + * arch/sh/boards/landisk/io.c + * + * Copyright (C) 2001 Ian da Silva, Jeremy Siegel + * Based largely on io_se.c. + * + * I/O routine for I-O Data Device, Inc. LANDISK. + * + * Initial version only to support LAN access; some + * placeholder code from io_landisk.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ +/* + * modifed by kogiidena + * 2005.03.03 + */ +#include +#include +#include +#include +#include +#include + +extern void *area5_io_base; /* Area 5 I/O Base address */ +extern void *area6_io_base; /* Area 6 I/O Base address */ + +static inline unsigned long port2adr(unsigned int port) +{ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + if (port == 0x3f6) + return ((unsigned long)area5_io_base + 0x2c); + else + return ((unsigned long)area5_io_base + PA_PIDE_OFFSET + + ((port - 0x1f0) << 1)); + else if ((0x170 <= port && port < 0x178) || port == 0x376) + if (port == 0x376) + return ((unsigned long)area6_io_base + 0x2c); + else + return ((unsigned long)area6_io_base + PA_SIDE_OFFSET + + ((port - 0x170) << 1)); + else + maybebadio((unsigned long)port); + + return port; +} + +/* + * General outline: remap really low stuff [eventually] to SuperIO, + * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) + * is mapped through the PCI IO window. Stuff with high bits (PXSEG) + * should be way beyond the window, and is used w/o translation for + * compatibility. + */ +u8 landisk_inb(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inb(port); + else if (is_pci_ioaddr(port)) + return ctrl_inb(pci_ioaddr(port)); + + return ctrl_inw(port2adr(port)) & 0xff; +} + +u8 landisk_inb_p(unsigned long port) +{ + u8 v; + + if (PXSEG(port)) + v = ctrl_inb(port); + else if (is_pci_ioaddr(port)) + v = ctrl_inb(pci_ioaddr(port)); + else + v = ctrl_inw(port2adr(port)) & 0xff; + + ctrl_delay(); + + return v; +} + +u16 landisk_inw(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inw(port); + else if (is_pci_ioaddr(port)) + return ctrl_inw(pci_ioaddr(port)); + else + maybebadio(port); + + return 0; +} + +u32 landisk_inl(unsigned long port) +{ + if (PXSEG(port)) + return ctrl_inl(port); + else if (is_pci_ioaddr(port)) + return ctrl_inl(pci_ioaddr(port)); + else + maybebadio(port); + + return 0; +} + +void landisk_outb(u8 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outb(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outb(value, pci_ioaddr(port)); + else + ctrl_outw(value, port2adr(port)); +} + +void landisk_outb_p(u8 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outb(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outb(value, pci_ioaddr(port)); + else + ctrl_outw(value, port2adr(port)); + ctrl_delay(); +} + +void landisk_outw(u16 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outw(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outw(value, pci_ioaddr(port)); + else + maybebadio(port); +} + +void landisk_outl(u32 value, unsigned long port) +{ + if (PXSEG(port)) + ctrl_outl(value, port); + else if (is_pci_ioaddr(port)) + ctrl_outl(value, pci_ioaddr(port)); + else + maybebadio(port); +} + +void landisk_insb(unsigned long port, void *dst, unsigned long count) +{ + volatile u16 *p; + u8 *buf = dst; + + if (PXSEG(port)) { + while (count--) + *buf++ = *(volatile u8 *)port; + } else if (is_pci_ioaddr(port)) { + volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); + + while (count--) + *buf++ = *bp; + } else { + p = (volatile u16 *)port2adr(port); + while (count--) + *buf++ = *p & 0xff; + } +} + +void landisk_insw(unsigned long port, void *dst, unsigned long count) +{ + volatile u16 *p; + u16 *buf = dst; + + if (PXSEG(port)) + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port)) + p = (volatile u16 *)pci_ioaddr(port); + else + p = (volatile u16 *)port2adr(port); + while (count--) + *buf++ = *p; +} + +void landisk_insl(unsigned long port, void *dst, unsigned long count) +{ + u32 *buf = dst; + + if (is_pci_ioaddr(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + + while (count--) + *buf++ = *p; + } else + maybebadio(port); +} + +void landisk_outsb(unsigned long port, const void *src, unsigned long count) +{ + volatile u16 *p; + const u8 *buf = src; + + if (PXSEG(port)) + while (count--) + ctrl_outb(*buf++, port); + else if (is_pci_ioaddr(port)) { + volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); + + while (count--) + *bp = *buf++; + } else { + p = (volatile u16 *)port2adr(port); + while (count--) + *p = *buf++; + } +} + +void landisk_outsw(unsigned long port, const void *src, unsigned long count) +{ + volatile u16 *p; + const u16 *buf = src; + + if (PXSEG(port)) + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port)) + p = (volatile u16 *)pci_ioaddr(port); + else + p = (volatile u16 *)port2adr(port); + + while (count--) + *p = *buf++; +} + +void landisk_outsl(unsigned long port, const void *src, unsigned long count) +{ + const u32 *buf = src; + + if (is_pci_ioaddr(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + + while (count--) + *p = *buf++; + } else + maybebadio(port); +} + +void __iomem *landisk_ioport_map(unsigned long port, unsigned int size) +{ + if (PXSEG(port)) + return (void __iomem *)port; + else if (is_pci_ioaddr(port)) + return (void __iomem *)pci_ioaddr(port); + + return (void __iomem *)port2adr(port); +} diff --git a/trunk/arch/sh/boards/landisk/irq.c b/trunk/arch/sh/boards/landisk/irq.c index 258649491d44..3eba6d086d7f 100644 --- a/trunk/arch/sh/boards/landisk/irq.c +++ b/trunk/arch/sh/boards/landisk/irq.c @@ -1,16 +1,18 @@ /* * arch/sh/boards/landisk/irq.c * - * I-O DATA Device, Inc. LANDISK Support - * - * Copyright (C) 2005-2007 kogiidena - * * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * I/O routine for I-O Data Device, Inc. LANDISK. + * + * Initial version only to support LAN access; some + * placeholder code from io_landisk.c left in with the + * expectation of later SuperIO and PCMCIA access. + */ +/* + * modified by kogiidena + * 2005.03.03 */ #include #include @@ -18,27 +20,71 @@ #include #include +static void enable_landisk_irq(unsigned int irq); +static void disable_landisk_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_landisk_irq disable_landisk_irq + +static void ack_landisk_irq(unsigned int irq); +static void end_landisk_irq(unsigned int irq); + +static unsigned int startup_landisk_irq(unsigned int irq) +{ + enable_landisk_irq(irq); + return 0; /* never anything pending */ +} + static void disable_landisk_irq(unsigned int irq) { + unsigned char val; unsigned char mask = 0xff ^ (0x01 << (irq - 5)); - ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK); + /* Set the priority in IPR to 0 */ + val = ctrl_inb(PA_IMASK); + val &= mask; + ctrl_outb(val, PA_IMASK); } static void enable_landisk_irq(unsigned int irq) { + unsigned char val; unsigned char value = (0x01 << (irq - 5)); - ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK); + /* Set priority in IPR back to original value */ + val = ctrl_inb(PA_IMASK); + val |= value; + ctrl_outb(val, PA_IMASK); +} + +static void ack_landisk_irq(unsigned int irq) +{ + disable_landisk_irq(irq); +} + +static void end_landisk_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + enable_landisk_irq(irq); } -static struct irq_chip landisk_irq_chip __read_mostly = { - .name = "LANDISK", - .mask = disable_landisk_irq, - .unmask = enable_landisk_irq, - .mask_ack = disable_landisk_irq, +static struct hw_interrupt_type landisk_irq_type = { + .typename = "LANDISK IRQ", + .startup = startup_landisk_irq, + .shutdown = shutdown_landisk_irq, + .enable = enable_landisk_irq, + .disable = disable_landisk_irq, + .ack = ack_landisk_irq, + .end = end_landisk_irq }; +static void make_landisk_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].chip = &landisk_irq_type; + disable_landisk_irq(irq); +} + /* * Initialize IRQ setting */ @@ -46,11 +92,6 @@ void __init init_landisk_IRQ(void) { int i; - for (i = 5; i < 14; i++) { - disable_irq_nosync(i); - set_irq_chip_and_handler_name(i, &landisk_irq_chip, - handle_level_irq, "level"); - enable_landisk_irq(i); - } - ctrl_outb(0x00, PA_PWRINT_CLR); + for (i = 5; i < 14; i++) + make_landisk_irq(i); } diff --git a/trunk/arch/sh/boards/landisk/landisk_pwb.c b/trunk/arch/sh/boards/landisk/landisk_pwb.c new file mode 100644 index 000000000000..47a63c6617ed --- /dev/null +++ b/trunk/arch/sh/boards/landisk/landisk_pwb.c @@ -0,0 +1,346 @@ +/* + * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch. + * + * This driver will also support the I-O DATA Device, Inc. LANDISK Board. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copylight (C) 2002 Atom Create Engineering Co., Ltd. + * + * LED control drive function added by kogiidena + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define SHUTDOWN_BTN_MINOR 1 /* Shutdown button device minor no. */ +#define LED_MINOR 21 /* LED minor no. */ +#define BTN_MINOR 22 /* BUTTON minor no. */ +#define GIO_MINOR 40 /* GIO minor no. */ + +static int openCnt; +static int openCntLED; +static int openCntGio; +static int openCntBtn; +static int landisk_btn; +static int landisk_btnctrlpid; +/* + * Functions prototypes + */ + +static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg); + +static int swdrv_open(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + filp->private_data = (void *)minor; + + if (minor == SHUTDOWN_BTN_MINOR) { + if (openCnt > 0) { + return -EALREADY; + } else { + openCnt++; + return 0; + } + } else if (minor == LED_MINOR) { + if (openCntLED > 0) { + return -EALREADY; + } else { + openCntLED++; + return 0; + } + } else if (minor == BTN_MINOR) { + if (openCntBtn > 0) { + return -EALREADY; + } else { + openCntBtn++; + return 0; + } + } else if (minor == GIO_MINOR) { + if (openCntGio > 0) { + return -EALREADY; + } else { + openCntGio++; + return 0; + } + } + return -ENOENT; + +} + +static int swdrv_close(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor == SHUTDOWN_BTN_MINOR) { + openCnt--; + } else if (minor == LED_MINOR) { + openCntLED--; + } else if (minor == BTN_MINOR) { + openCntBtn--; + } else if (minor == GIO_MINOR) { + openCntGio--; + } + return 0; +} + +static int swdrv_read(struct file *filp, char *buff, size_t count, + loff_t * ppos) +{ + int minor; + minor = (int)(filp->private_data); + + if (!access_ok(VERIFY_WRITE, (void *)buff, count)) + return -EFAULT; + + if (minor == SHUTDOWN_BTN_MINOR) { + if (landisk_btn & 0x10) { + put_user(1, buff); + return 1; + } else { + return 0; + } + } + return 0; +} + +static int swdrv_write(struct file *filp, const char *buff, size_t count, + loff_t * ppos) +{ + int minor; + minor = (int)(filp->private_data); + + if (minor == SHUTDOWN_BTN_MINOR) { + return count; + } + return count; +} + +static irqreturn_t sw_interrupt(int irq, void *dev_id) +{ + landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS))); + disable_irq(IRQ_BUTTON); + disable_irq(IRQ_POWER); + ctrl_outb(0x00, PA_PWRINT_CLR); + + if (landisk_btnctrlpid != 0) { + kill_proc(landisk_btnctrlpid, SIGUSR1, 1); + landisk_btnctrlpid = 0; + } + + return IRQ_HANDLED; +} + +static const struct file_operations swdrv_fops = { + .read = swdrv_read, /* read */ + .write = swdrv_write, /* write */ + .open = swdrv_open, /* open */ + .release = swdrv_close, /* release */ + .ioctl = gio_ioctl, /* ioctl */ + +}; + +static char banner[] __initdata = + KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n"; + +int __init swdrv_init(void) +{ + int error; + + printk("%s", banner); + + openCnt = 0; + openCntLED = 0; + openCntBtn = 0; + openCntGio = 0; + landisk_btn = 0; + landisk_btnctrlpid = 0; + + if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) { + printk(KERN_ERR + "Button, LED and GIO driver:Couldn't register driver, error=%d\n", + error); + return 1; + } + + if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) { + printk(KERN_ERR "Unable to get IRQ 11.\n"); + return 1; + } + if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) { + printk(KERN_ERR "Unable to get IRQ 12.\n"); + return 1; + } + ctrl_outb(0x00, PA_PWRINT_CLR); + + return 0; +} + +module_init(swdrv_init); + +/* + * gio driver + * + */ + +#include + +static int gio_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int minor; + unsigned int data, mask; + static unsigned int addr = 0; + + minor = (int)(filp->private_data); + + /* access control */ + if (minor == GIO_MINOR) { + ; + } else if (minor == LED_MINOR) { + if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) { + ; + } else { + return -EINVAL; + } + } else if (minor == BTN_MINOR) { + if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) { + ; + } else { + return -EINVAL; + } + } else { + return -EINVAL; + } + + if (cmd & 0x01) { /* write */ + if (copy_from_user(&data, (int *)arg, sizeof(int))) { + return -EFAULT; + } + } + + switch (cmd) { + case GIODRV_IOCSGIOSETADDR: /* addres set */ + addr = data; + break; + + case GIODRV_IOCSGIODATA1: /* write byte */ + ctrl_outb((unsigned char)(0x0ff & data), addr); + break; + + case GIODRV_IOCSGIODATA2: /* write word */ + if (addr & 0x01) { + return -EFAULT; + } + ctrl_outw((unsigned short int)(0x0ffff & data), addr); + break; + + case GIODRV_IOCSGIODATA4: /* write long */ + if (addr & 0x03) { + return -EFAULT; + } + ctrl_outl(data, addr); + break; + + case GIODRV_IOCGGIODATA1: /* read byte */ + data = ctrl_inb(addr); + break; + + case GIODRV_IOCGGIODATA2: /* read word */ + if (addr & 0x01) { + return -EFAULT; + } + data = ctrl_inw(addr); + break; + + case GIODRV_IOCGGIODATA4: /* read long */ + if (addr & 0x03) { + return -EFAULT; + } + data = ctrl_inl(addr); + break; + case GIODRV_IOCSGIO_LED: /* write */ + mask = ((data & 0x00ffffff) << 8) + | ((data & 0x0000ffff) << 16) + | ((data & 0x000000ff) << 24); + landisk_ledparam = data & (~mask); + if (landisk_arch == 0) { /* arch == landisk */ + landisk_ledparam &= 0x03030303; + mask = (~(landisk_ledparam >> 22)) & 0x000c; + landisk_ledparam |= mask; + } else { /* arch == usl-5p */ + mask = (landisk_ledparam >> 24) & 0x0001; + landisk_ledparam |= mask; + landisk_ledparam &= 0x007f7f7f; + } + landisk_ledparam |= 0x80; + break; + case GIODRV_IOCGGIO_LED: /* read */ + data = landisk_ledparam; + if (landisk_arch == 0) { /* arch == landisk */ + data &= 0x03030303; + } else { /* arch == usl-5p */ + ; + } + data &= (~0x080); + break; + case GIODRV_IOCSGIO_BUZZER: /* write */ + landisk_buzzerparam = data; + landisk_ledparam |= 0x80; + break; + case GIODRV_IOCGGIO_LANDISK: /* read */ + data = landisk_arch & 0x01; + break; + case GIODRV_IOCGGIO_BTN: /* read */ + data = (0x0ff & ctrl_inb(PA_PWRINT_CLR)); + data <<= 8; + data |= (0x0ff & ctrl_inb(PA_IMASK)); + data <<= 8; + data |= (0x0ff & landisk_btn); + data <<= 8; + data |= (0x0ff & (~ctrl_inb(PA_STATUS))); + break; + case GIODRV_IOCSGIO_BTNPID: /* write */ + landisk_btnctrlpid = data; + landisk_btn = 0; + if (irq_desc[IRQ_BUTTON].depth) { + enable_irq(IRQ_BUTTON); + } + if (irq_desc[IRQ_POWER].depth) { + enable_irq(IRQ_POWER); + } + break; + case GIODRV_IOCGGIO_BTNPID: /* read */ + data = landisk_btnctrlpid; + break; + default: + return -EFAULT; + break; + } + + if ((cmd & 0x01) == 0) { /* read */ + if (copy_to_user((int *)arg, &data, sizeof(int))) { + return -EFAULT; + } + } + return 0; +} diff --git a/trunk/arch/sh/boards/landisk/psw.c b/trunk/arch/sh/boards/landisk/psw.c deleted file mode 100644 index 5a9b70b5decb..000000000000 --- a/trunk/arch/sh/boards/landisk/psw.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * arch/sh/boards/landisk/psw.c - * - * push switch support for LANDISK and USL-5P - * - * Copyright (C) 2006-2007 Paul Mundt - * Copyright (C) 2007 kogiidena - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include - -static irqreturn_t psw_irq_handler(int irq, void *arg) -{ - struct platform_device *pdev = arg; - struct push_switch *psw = platform_get_drvdata(pdev); - struct push_switch_platform_info *psw_info = pdev->dev.platform_data; - unsigned int sw_value; - int ret = 0; - - sw_value = (0x0ff & (~ctrl_inb(PA_STATUS))); - - /* Nothing to do if there's no state change */ - if (psw->state) { - ret = 1; - goto out; - } - - /* Figure out who raised it */ - if (sw_value & (1 << psw_info->bit)) { - psw->state = 1; - mod_timer(&psw->debounce, jiffies + 50); - ret = 1; - } - -out: - /* Clear the switch IRQs */ - ctrl_outb(0x00, PA_PWRINT_CLR); - - return IRQ_RETVAL(ret); -} - -static struct resource psw_power_resources[] = { - [0] = { - .start = IRQ_POWER, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct resource psw_usl5p_resources[] = { - [0] = { - .start = IRQ_BUTTON, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct push_switch_platform_info psw_power_platform_data = { - .name = "psw_power", - .bit = 4, - .irq_flags = IRQF_SHARED, - .irq_handler = psw_irq_handler, -}; - -static struct push_switch_platform_info psw1_platform_data = { - .name = "psw1", - .bit = 0, - .irq_flags = IRQF_SHARED, - .irq_handler = psw_irq_handler, -}; - -static struct push_switch_platform_info psw2_platform_data = { - .name = "psw2", - .bit = 2, - .irq_flags = IRQF_SHARED, - .irq_handler = psw_irq_handler, -}; - -static struct push_switch_platform_info psw3_platform_data = { - .name = "psw3", - .bit = 1, - .irq_flags = IRQF_SHARED, - .irq_handler = psw_irq_handler, -}; - -static struct platform_device psw_power_switch_device = { - .name = "push-switch", - .id = 0, - .num_resources = ARRAY_SIZE(psw_power_resources), - .resource = psw_power_resources, - .dev = { - .platform_data = &psw_power_platform_data, - }, -}; - -static struct platform_device psw1_switch_device = { - .name = "push-switch", - .id = 1, - .num_resources = ARRAY_SIZE(psw_usl5p_resources), - .resource = psw_usl5p_resources, - .dev = { - .platform_data = &psw1_platform_data, - }, -}; - -static struct platform_device psw2_switch_device = { - .name = "push-switch", - .id = 2, - .num_resources = ARRAY_SIZE(psw_usl5p_resources), - .resource = psw_usl5p_resources, - .dev = { - .platform_data = &psw2_platform_data, - }, -}; - -static struct platform_device psw3_switch_device = { - .name = "push-switch", - .id = 3, - .num_resources = ARRAY_SIZE(psw_usl5p_resources), - .resource = psw_usl5p_resources, - .dev = { - .platform_data = &psw3_platform_data, - }, -}; - -static struct platform_device *psw_devices[] = { - &psw_power_switch_device, - &psw1_switch_device, - &psw2_switch_device, - &psw3_switch_device, -}; - -static int __init psw_init(void) -{ - return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); -} -module_init(psw_init); diff --git a/trunk/arch/sh/boards/landisk/rtc.c b/trunk/arch/sh/boards/landisk/rtc.c new file mode 100644 index 000000000000..0a9a2a2ad05b --- /dev/null +++ b/trunk/arch/sh/boards/landisk/rtc.c @@ -0,0 +1,91 @@ +/* + * arch/sh/boards/landisk/rtc.c -- RTC support + * + * Copyright (C) 2000 Philipp Rumpf + * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka + */ +/* + * modifed by kogiidena + * 2005.09.16 + */ +#include +#include +#include +#include +#include +#include +#include +#include + +extern spinlock_t rtc_lock; + +extern void +rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon, + unsigned int BCD_day, unsigned int BCD_hr, + unsigned int BCD_min, unsigned int BCD_sec); + +extern unsigned long +rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon, + unsigned int *BCD_day, unsigned int *BCD_hr, + unsigned int *BCD_min, unsigned int *BCD_sec); + +void landisk_rtc_gettimeofday(struct timespec *tv) +{ + unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec; + unsigned long flags; + + spin_lock_irqsave(&rtc_lock, flags); + tv->tv_sec = rs5c313_get_cmos_time + (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec); + tv->tv_nsec = 0; + spin_unlock_irqrestore(&rtc_lock, flags); +} + +int landisk_rtc_settimeofday(const time_t secs) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned long flags; + unsigned long nowtime = secs; + unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec; + + spin_lock_irqsave(&rtc_lock, flags); + + rs5c313_get_cmos_time + (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec); + cmos_minutes = BCD_min; + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr, + real_minutes, real_seconds); + } else { + printk(KERN_WARNING + "set_rtc_time: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + spin_unlock_irqrestore(&rtc_lock, flags); + return retval; +} + +void landisk_time_init(void) +{ + rtc_sh_get_time = landisk_rtc_gettimeofday; + rtc_sh_set_time = landisk_rtc_settimeofday; +} diff --git a/trunk/arch/sh/boards/landisk/setup.c b/trunk/arch/sh/boards/landisk/setup.c index a83a5d9587bb..122d69962637 100644 --- a/trunk/arch/sh/boards/landisk/setup.c +++ b/trunk/arch/sh/boards/landisk/setup.c @@ -1,90 +1,144 @@ /* * arch/sh/boards/landisk/setup.c * - * I-O DATA Device, Inc. LANDISK Support. - * * Copyright (C) 2000 Kazumoto Kojima * Copyright (C) 2002 Paul Mundt - * Copylight (C) 2002 Atom Create Engineering Co., Ltd. - * Copyright (C) 2005-2007 kogiidena + * + * I-O DATA Device, Inc. LANDISK Support. + * + * Modified for LANDISK by + * Atom Create Engineering Co., Ltd. 2002. + * + * modifed by kogiidena + * 2005.09.16 * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include -#include -#include #include #include #include +#include #include #include +void landisk_time_init(void); void init_landisk_IRQ(void); +int landisk_ledparam; +int landisk_buzzerparam; +int landisk_arch; + +/* cycle the led's in the clasic knightrider/sun pattern */ +static void heartbeat_landisk(void) +{ + static unsigned int cnt = 0, blink = 0x00, period = 25; + volatile u8 *p = (volatile u8 *)PA_LED; + char data; + + if ((landisk_ledparam & 0x080) == 0) + return; + + cnt += 1; + + if (cnt < period) + return; + + cnt = 0; + blink++; + + data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0; + data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0; + data |= landisk_ledparam; + + /* buzzer */ + if (landisk_buzzerparam & 0x1) { + data |= 0x80; + } else { + data &= 0x7f; + } + *p = data; + + if (((landisk_ledparam & 0x007f7f00) == 0) && + (landisk_buzzerparam == 0)) + landisk_ledparam &= (~0x0080); + + landisk_buzzerparam >>= 1; +} + static void landisk_power_off(void) { ctrl_outb(0x01, PA_SHUTDOWN); } -static struct resource cf_ide_resources[3]; +static void check_usl5p(void) +{ + volatile u8 *p = (volatile u8 *)PA_LED; + u8 tmp1, tmp2; -static struct pata_platform_info pata_info = { - .ioport_shift = 1, -}; + tmp1 = *p; + *p = 0x40; + tmp2 = *p; + *p = tmp1; -static struct platform_device cf_ide_device = { - .name = "pata_platform", - .id = -1, - .num_resources = ARRAY_SIZE(cf_ide_resources), - .resource = cf_ide_resources, - .dev = { - .platform_data = &pata_info, - }, -}; + landisk_arch = (tmp2 == 0x40); + if (landisk_arch == 1) { + /* arch == usl-5p */ + landisk_ledparam = 0x00000380; + landisk_ledparam |= (tmp1 & 0x07c); + } else { + /* arch == landisk */ + landisk_ledparam = 0x02000180; + landisk_ledparam |= 0x04; + } +} -static struct platform_device *landisk_devices[] __initdata = { - &cf_ide_device, -}; +void *area5_io_base; +void *area6_io_base; -static int __init landisk_devices_setup(void) +static int __init landisk_cf_init(void) { pgprot_t prot; - unsigned long paddrbase; - void *cf_ide_base; + unsigned long paddrbase, psize; /* open I/O area window */ paddrbase = virt_to_phys((void *)PA_AREA5_IO); + psize = PAGE_SIZE; prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); - cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); - if (!cf_ide_base) { + area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area5_io_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; } - /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */ - cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40; - cf_ide_resources[0].end = (unsigned long)cf_ide_base + 0x40 + 0x0f; - cf_ide_resources[0].flags = IORESOURCE_IO; - cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c; - cf_ide_resources[1].end = (unsigned long)cf_ide_base + 0x2c + 0x03; - cf_ide_resources[1].flags = IORESOURCE_IO; - cf_ide_resources[2].start = IRQ_FATA; - cf_ide_resources[2].flags = IORESOURCE_IRQ; - - return platform_add_devices(landisk_devices, - ARRAY_SIZE(landisk_devices)); -} + paddrbase = virt_to_phys((void *)PA_AREA6_IO); + psize = PAGE_SIZE; + prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); + area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); + if (!area6_io_base) { + printk("allocate_cf_area : can't open HDD I/O window!\n"); + return -ENOMEM; + } + + printk(KERN_INFO "Allocate Area5/6 success.\n"); -__initcall(landisk_devices_setup); + /* XXX : do we need attribute and common-memory area also? */ + + return 0; +} static void __init landisk_setup(char **cmdline_p) { - /* LED ON */ - ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED); + device_initcall(landisk_cf_init); + + landisk_buzzerparam = 0; + check_usl5p(); printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n"); + + board_time_init = landisk_time_init; pm_power_off = landisk_power_off; } @@ -94,6 +148,29 @@ static void __init landisk_setup(char **cmdline_p) struct sh_machine_vector mv_landisk __initmv = { .mv_name = "LANDISK", .mv_setup = landisk_setup, + .mv_nr_irqs = 72, + .mv_inb = landisk_inb, + .mv_inw = landisk_inw, + .mv_inl = landisk_inl, + .mv_outb = landisk_outb, + .mv_outw = landisk_outw, + .mv_outl = landisk_outl, + .mv_inb_p = landisk_inb_p, + .mv_inw_p = landisk_inw, + .mv_inl_p = landisk_inl, + .mv_outb_p = landisk_outb_p, + .mv_outw_p = landisk_outw, + .mv_outl_p = landisk_outl, + .mv_insb = landisk_insb, + .mv_insw = landisk_insw, + .mv_insl = landisk_insl, + .mv_outsb = landisk_outsb, + .mv_outsw = landisk_outsw, + .mv_outsl = landisk_outsl, + .mv_ioport_map = landisk_ioport_map, .mv_init_irq = init_landisk_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_landisk, +#endif }; ALIAS_MV(landisk) diff --git a/trunk/arch/sh/boards/lboxre2/Makefile b/trunk/arch/sh/boards/lboxre2/Makefile deleted file mode 100644 index e9ed140c06f6..000000000000 --- a/trunk/arch/sh/boards/lboxre2/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the L-BOX RE2 specific parts of the kernel -# Copyright (c) 2007 Nobuhiro Iwamatsu - -obj-y := setup.o irq.o diff --git a/trunk/arch/sh/boards/lboxre2/irq.c b/trunk/arch/sh/boards/lboxre2/irq.c deleted file mode 100644 index 5a1c3bbe7b50..000000000000 --- a/trunk/arch/sh/boards/lboxre2/irq.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * linux/arch/sh/boards/lboxre2/irq.c - * - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * NTT COMWARE L-BOX RE2 Support. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - */ -#include -#include -#include -#include -#include -#include - -/* - * Initialize IRQ setting - */ -void __init init_lboxre2_IRQ(void) -{ - make_imask_irq(IRQ_CF1); - make_imask_irq(IRQ_CF0); - make_imask_irq(IRQ_INTD); - make_imask_irq(IRQ_ETH1); - make_imask_irq(IRQ_ETH0); - make_imask_irq(IRQ_INTA); -} diff --git a/trunk/arch/sh/boards/lboxre2/setup.c b/trunk/arch/sh/boards/lboxre2/setup.c deleted file mode 100644 index 4e20f7c63bf3..000000000000 --- a/trunk/arch/sh/boards/lboxre2/setup.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * linux/arch/sh/boards/lbox/setup.c - * - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * NTT COMWARE L-BOX RE2 Support - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -static struct resource cf_ide_resources[] = { - [0] = { - .start = 0x1f0, - .end = 0x1f0 + 8 , - .flags = IORESOURCE_IO, - }, - [1] = { - .start = 0x1f0 + 0x206, - .end = 0x1f0 +8 + 0x206 + 8, - .flags = IORESOURCE_IO, - }, - [2] = { - .start = IRQ_CF0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device cf_ide_device = { - .name = "pata_platform", - .id = -1, - .num_resources = ARRAY_SIZE(cf_ide_resources), - .resource = cf_ide_resources, -}; - -static struct platform_device *lboxre2_devices[] __initdata = { - &cf_ide_device, -}; - -static int __init lboxre2_devices_setup(void) -{ - u32 cf0_io_base; /* Boot CF base address */ - pgprot_t prot; - unsigned long paddrbase, psize; - - /* open I/O area window */ - paddrbase = virt_to_phys((void*)PA_AREA5_IO); - psize = PAGE_SIZE; - prot = PAGE_KERNEL_PCC( 1 , _PAGE_PCC_IO16); - cf0_io_base = (u32)p3_ioremap(paddrbase, psize, prot.pgprot); - if (!cf0_io_base) { - printk(KERN_ERR "%s : can't open CF I/O window!\n" , __func__ ); - return -ENOMEM; - } - - cf_ide_resources[0].start += cf0_io_base ; - cf_ide_resources[0].end += cf0_io_base ; - cf_ide_resources[1].start += cf0_io_base ; - cf_ide_resources[1].end += cf0_io_base ; - - return platform_add_devices(lboxre2_devices, - ARRAY_SIZE(lboxre2_devices)); - -} -device_initcall(lboxre2_devices_setup); - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_lboxre2 __initmv = { - .mv_name = "L-BOX RE2", - .mv_nr_irqs = 72, - .mv_init_irq = init_lboxre2_IRQ, -}; -ALIAS_MV(lboxre2) diff --git a/trunk/arch/sh/boards/renesas/r7780rp/Kconfig b/trunk/arch/sh/boards/renesas/r7780rp/Kconfig index 9fb11641fe13..c26d9813d239 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/Kconfig +++ b/trunk/arch/sh/boards/renesas/r7780rp/Kconfig @@ -1,24 +1,14 @@ -if SH_HIGHLANDER +if SH_R7780RP -choice - prompt "Highlander options" - default SH_R7780MP - -config SH_R7780RP - bool "R7780RP-1 board support" - select CPU_SUBTYPE_SH7780 +menu "R7780RP options" config SH_R7780MP bool "R7780MP board support" - select CPU_SUBTYPE_SH7780 + default y help Selecting this option will enable support for the mass-production version of the R7780RP. If in doubt, say Y. -config SH_R7785RP - bool "R7785RP board support" - select CPU_SUBTYPE_SH7785 - -endchoice +endmenu endif diff --git a/trunk/arch/sh/boards/renesas/r7780rp/Makefile b/trunk/arch/sh/boards/renesas/r7780rp/Makefile index 609e5d50dde8..ed5f5a9a3b3e 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/Makefile +++ b/trunk/arch/sh/boards/renesas/r7780rp/Makefile @@ -1,7 +1,7 @@ # # Makefile for the R7780RP-1 specific parts of the kernel # -irqinit-y := irq-r7780rp.o -irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o + +obj-y := setup.o irq.o + obj-$(CONFIG_PUSH_SWITCH) += psw.o -obj-y := setup.o irq.o $(irqinit-y) diff --git a/trunk/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/trunk/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c deleted file mode 100644 index f5f358746c9e..000000000000 --- a/trunk/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Renesas Solutions Highlander R7780RP-1 Support. - * - * Copyright (C) 2002 Atom Create Engineering Co., Ltd. - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include - -void __init highlander_init_irq(void) -{ - int i; - - for (i = 0; i < 15; i++) - make_r7780rp_irq(i); -} diff --git a/trunk/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/trunk/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c deleted file mode 100644 index dd6ec4ce44dc..000000000000 --- a/trunk/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Renesas Solutions Highlander R7780RP-1 Support. - * - * Copyright (C) 2002 Atom Create Engineering Co., Ltd. - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include - -void __init highlander_init_irq(void) -{ - ctrl_outw(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */ - - /* Setup the FPGA IRL */ - ctrl_outw(0x0000, PA_IRLPRA); /* FPGA IRLA */ - ctrl_outw(0xe598, PA_IRLPRB); /* FPGA IRLB */ - ctrl_outw(0x7060, PA_IRLPRC); /* FPGA IRLC */ - ctrl_outw(0x0000, PA_IRLPRD); /* FPGA IRLD */ - ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */ - ctrl_outw(0x0000, PA_IRLPRF); /* FPGA IRLF */ - - make_r7780rp_irq(1); /* CF card */ - make_r7780rp_irq(10); /* On-board ethernet */ -} diff --git a/trunk/arch/sh/boards/renesas/r7780rp/irq.c b/trunk/arch/sh/boards/renesas/r7780rp/irq.c index e0b8eb52f376..cc381e197783 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/irq.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/irq.c @@ -14,12 +14,10 @@ #include #include -#ifdef CONFIG_SH_R7780RP -static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; -#elif defined(CONFIG_SH_R7780MP) +#ifdef CONFIG_SH_R7780MP static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; -#elif defined(CONFIG_SH_R7785RP) -static int mask_pos[] = {2, 11, 2, 2, 2, 2, 9, 8, 7, 5, 10, 2, 2, 2, 2, 2}; +#else +static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; #endif static void enable_r7780rp_irq(unsigned int irq) @@ -42,10 +40,17 @@ static struct irq_chip r7780rp_irq_chip __read_mostly = { .mask_ack = disable_r7780rp_irq, }; -void make_r7780rp_irq(unsigned int irq) +/* + * Initialize IRQ setting + */ +void __init init_r7780rp_IRQ(void) { - disable_irq_nosync(irq); - set_irq_chip_and_handler_name(irq, &r7780rp_irq_chip, - handle_level_irq, "level"); - enable_r7780rp_irq(irq); + int i; + + for (i = 0; i < 15; i++) { + disable_irq_nosync(i); + set_irq_chip_and_handler_name(i, &r7780rp_irq_chip, + handle_level_irq, "level"); + enable_r7780rp_irq(i); + } } diff --git a/trunk/arch/sh/boards/renesas/r7780rp/setup.c b/trunk/arch/sh/boards/renesas/r7780rp/setup.c index 0727ef92f2b3..2faba6679e64 100644 --- a/trunk/arch/sh/boards/renesas/r7780rp/setup.c +++ b/trunk/arch/sh/boards/renesas/r7780rp/setup.c @@ -1,13 +1,10 @@ /* * arch/sh/boards/renesas/r7780rp/setup.c * - * Renesas Solutions Highlander Support. - * * Copyright (C) 2002 Atom Create Engineering Co., Ltd. * Copyright (C) 2005 - 2007 Paul Mundt * - * This contains support for the R7780RP-1, R7780MP, and R7785RP - * Highlander modules. + * Renesas Solutions Highlander R7780RP-1 Support. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -21,6 +18,32 @@ #include #include +extern void init_r7780rp_IRQ(void); + +static struct resource m66596_usb_host_resources[] = { + [0] = { + .start = 0xa4800000, + .end = 0xa4ffffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 6, /* irq number */ + .end = 6, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device m66596_usb_host_device = { + .name = "m66596-hcd", + .id = 0, + .dev = { + .dma_mask = NULL, /* don't use dma */ + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(m66596_usb_host_resources), + .resource = m66596_usb_host_resources, +}; + static struct resource cf_ide_resources[] = { [0] = { .start = PA_AREA5_IO + 0x1000, @@ -33,10 +56,10 @@ static struct resource cf_ide_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { -#ifdef CONFIG_SH_R7780RP - .start = 4, -#else +#ifdef CONFIG_SH_R7780MP .start = 1, +#else + .start = 4, #endif .flags = IORESOURCE_IRQ, }, @@ -69,18 +92,15 @@ static struct resource heartbeat_resources[] = { static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - - /* R7785RP has a slightly more sensible FPGA.. */ -#ifndef CONFIG_SH_R7785RP .dev = { .platform_data = heartbeat_bit_pos, }, -#endif .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, }; static struct platform_device *r7780rp_devices[] __initdata = { + &m66596_usb_host_device, &cf_ide_device, &heartbeat_device, }; @@ -90,19 +110,18 @@ static int __init r7780rp_devices_setup(void) return platform_add_devices(r7780rp_devices, ARRAY_SIZE(r7780rp_devices)); } -device_initcall(r7780rp_devices_setup); /* * Platform specific clocks */ static void ivdr_clk_enable(struct clk *clk) { - ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << IVDR_CK_ON), PA_IVDRCTL); + ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << 8), PA_IVDRCTL); } static void ivdr_clk_disable(struct clk *clk) { - ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << IVDR_CK_ON), PA_IVDRCTL); + ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << 8), PA_IVDRCTL); } static struct clk_ops ivdr_clk_ops = { @@ -121,22 +140,22 @@ static struct clk *r7780rp_clocks[] = { static void r7780rp_power_off(void) { - if (mach_is_r7780mp() || mach_is_r7785rp()) - ctrl_outw(0x0001, PA_POFF); +#ifdef CONFIG_SH_R7780MP + ctrl_outw(0x0001, PA_POFF); +#endif } /* * Initialize the board */ -static void __init highlander_setup(char **cmdline_p) +static void __init r7780rp_setup(char **cmdline_p) { u16 ver = ctrl_inw(PA_VERREG); int i; - printk(KERN_INFO "Renesas Solutions Highlander %s support.\n", - mach_is_r7780rp() ? "R7780RP-1" : - mach_is_r7780mp() ? "R7780MP" : - "R7785RP"); + device_initcall(r7780rp_devices_setup); + + printk(KERN_INFO "Renesas Solutions Highlander R7780RP-1 support.\n"); printk(KERN_INFO "Board version: %d (revision %d), " "FPGA version: %d (revision %d)\n", @@ -154,10 +173,9 @@ static void __init highlander_setup(char **cmdline_p) } ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */ - - if (mach_is_r7780rp()) - ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */ - +#ifndef CONFIG_SH_R7780MP + ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */ +#endif ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x01, PA_IVDRCTL); /* Si13112 */ pm_power_off = r7780rp_power_off; @@ -166,10 +184,10 @@ static void __init highlander_setup(char **cmdline_p) /* * The Machine Vector */ -struct sh_machine_vector mv_highlander __initmv = { - .mv_name = "Highlander", +struct sh_machine_vector mv_r7780rp __initmv = { + .mv_name = "Highlander R7780RP-1", + .mv_setup = r7780rp_setup, .mv_nr_irqs = 109, - .mv_setup = highlander_setup, - .mv_init_irq = highlander_init_irq, + .mv_init_irq = init_r7780rp_IRQ, }; -ALIAS_MV(highlander) +ALIAS_MV(r7780rp) diff --git a/trunk/arch/sh/boards/se/770x/io.c b/trunk/arch/sh/boards/se/770x/io.c index c4550473d4c3..9941949331ab 100644 --- a/trunk/arch/sh/boards/se/770x/io.c +++ b/trunk/arch/sh/boards/se/770x/io.c @@ -27,8 +27,6 @@ int sh_pcic_io_dummy; static inline volatile __u16 * port2adr(unsigned int port) { - if (port & 0xff000000) - return ( volatile __u16 *) port; if (port >= 0x2000) return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); else if (port >= 0x1000) diff --git a/trunk/arch/sh/boards/se/770x/irq.c b/trunk/arch/sh/boards/se/770x/irq.c index c8eccff77a04..307ca5da6232 100644 --- a/trunk/arch/sh/boards/se/770x/irq.c +++ b/trunk/arch/sh/boards/se/770x/irq.c @@ -55,34 +55,23 @@ void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs) } static struct ipr_data se770x_ipr_map[] = { - /* - * Super I/O (Just mimic PC): - * 1: keyboard - * 3: serial 0 - * 4: serial 1 - * 5: printer - * 6: floppy - * 8: rtc - * 12: mouse - * 14: ide0 - */ #if defined(CONFIG_CPU_SUBTYPE_SH7705) /* This is default value */ - { 13, 0, 8, 0x0f-13 ,BCR_ILCRA}, - { 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA}, - { 10, 0, 0, 0x0f-10, BCR_ILCRB}, - { 7 , 0, 4, 0x0f- 7, BCR_ILCRC}, - { 3 , 0, 0, 0x0f- 3, BCR_ILCRC}, - { 1 , 0, 12, 0x0f- 1, BCR_ILCRD}, - { 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */ - { 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */ - { 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */ - { 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */ - { 0 , 0, 12, 0x0f , BCR_ILCRF}, - { 4 , 0, 4, 0x0f- 4, BCR_ILCRF}, - { 8 , 0, 12, 0x0f- 8, BCR_ILCRG}, - { 9 , 0, 8, 0x0f- 9, BCR_ILCRG}, - { 11, 0, 4, 0x0f-11, BCR_ILCRG}, + { 0xf-0x2, 0, 8, 0x2 , BCR_ILCRA}, + { 0xf-0xa, 0, 4, 0xa , BCR_ILCRA}, + { 0xf-0x5, 0, 0, 0x5 , BCR_ILCRB}, + { 0xf-0x8, 0, 4, 0x8 , BCR_ILCRC}, + { 0xf-0xc, 0, 0, 0xc , BCR_ILCRC}, + { 0xf-0xe, 0, 12, 0xe , BCR_ILCRD}, + { 0xf-0x3, 0, 4, 0x3 , BCR_ILCRD}, /* LAN */ + { 0xf-0xd, 0, 8, 0xd , BCR_ILCRE}, + { 0xf-0x9, 0, 4, 0x9 , BCR_ILCRE}, + { 0xf-0x1, 0, 0, 0x1 , BCR_ILCRE}, + { 0xf-0xf, 0, 12, 0xf , BCR_ILCRF}, + { 0xf-0xb, 0, 4, 0xb , BCR_ILCRF}, + { 0xf-0x7, 0, 12, 0x7 , BCR_ILCRG}, + { 0xf-0x6, 0, 8, 0x6 , BCR_ILCRG}, + { 0xf-0x4, 0, 4, 0x4 , BCR_ILCRG}, #else { 14, 0, 8, 0x0f-14 ,BCR_ILCRA}, { 12, 0, 4, 0x0f-12 ,BCR_ILCRA}, @@ -92,10 +81,8 @@ static struct ipr_data se770x_ipr_map[] = { { 4, 0, 4, 0x0f- 4 ,BCR_ILCRC}, { 3, 0, 0, 0x0f- 3 ,BCR_ILCRC}, { 1, 0, 12, 0x0f- 1 ,BCR_ILCRD}, -#if defined(CONFIG_STNIC) /* ST NIC */ { 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */ -#endif /* MRSHPC IRQs setting */ { 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */ { 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */ @@ -113,6 +100,18 @@ static struct ipr_data se770x_ipr_map[] = { */ void __init init_se_IRQ(void) { + /* + * Super I/O (Just mimic PC): + * 1: keyboard + * 3: serial 0 + * 4: serial 1 + * 5: printer + * 6: floppy + * 8: rtc + * 12: mouse + * 14: ide0 + */ +#if defined(CONFIG_CPU_SUBTYPE_SH7705) /* Disable all interrupts */ ctrl_outw(0, BCR_ILCRA); ctrl_outw(0, BCR_ILCRB); @@ -121,6 +120,6 @@ void __init init_se_IRQ(void) ctrl_outw(0, BCR_ILCRE); ctrl_outw(0, BCR_ILCRF); ctrl_outw(0, BCR_ILCRG); - +#endif make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map)); } diff --git a/trunk/arch/sh/boards/se/770x/setup.c b/trunk/arch/sh/boards/se/770x/setup.c index 17a2631de3ba..45cbc36b9fb7 100644 --- a/trunk/arch/sh/boards/se/770x/setup.c +++ b/trunk/arch/sh/boards/se/770x/setup.c @@ -63,31 +63,6 @@ static void __init smsc_setup(char **cmdline_p) outb_p(CONFIG_EXIT, CONFIG_PORT); } - -static struct resource cf_ide_resources[] = { - [0] = { - .start = PA_MRSHPC_IO + 0x1f0, - .end = PA_MRSHPC_IO + 0x1f0 + 8, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = PA_MRSHPC_IO + 0x1f0 + 0x206, - .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8, - .flags = IORESOURCE_MEM, - }, - [2] = { - .start = IRQ_CFCARD, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device cf_ide_device = { - .name = "pata_platform", - .id = -1, - .num_resources = ARRAY_SIZE(cf_ide_resources), - .resource = cf_ide_resources, -}; - static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; static struct resource heartbeat_resources[] = { @@ -110,14 +85,13 @@ static struct platform_device heartbeat_device = { static struct platform_device *se_devices[] __initdata = { &heartbeat_device, - &cf_ide_device, }; static int __init se_devices_setup(void) { return platform_add_devices(se_devices, ARRAY_SIZE(se_devices)); } -device_initcall(se_devices_setup); +__initcall(se_devices_setup); /* * The Machine Vector @@ -133,8 +107,6 @@ struct sh_machine_vector mv_se __initmv = { .mv_nr_irqs = 61, #elif defined(CONFIG_CPU_SUBTYPE_SH7705) .mv_nr_irqs = 86, -#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) - .mv_nr_irqs = 104, #endif .mv_inb = se_inb, diff --git a/trunk/arch/sh/boards/se/7722/Makefile b/trunk/arch/sh/boards/se/7722/Makefile deleted file mode 100644 index 8694373389e5..000000000000 --- a/trunk/arch/sh/boards/se/7722/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the HITACHI UL SolutionEngine 7722 specific parts of the kernel -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# - -obj-y := setup.o irq.o diff --git a/trunk/arch/sh/boards/se/7722/irq.c b/trunk/arch/sh/boards/se/7722/irq.c deleted file mode 100644 index 099e5deb77f8..000000000000 --- a/trunk/arch/sh/boards/se/7722/irq.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * linux/arch/sh/boards/se/7722/irq.c - * - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * Hitachi UL SolutionEngine 7722 Support. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include - -#define INTC_INTMSK0 0xFFD00044 -#define INTC_INTMSKCLR0 0xFFD00064 - -static void disable_se7722_irq(unsigned int irq) -{ - struct ipr_data *p = get_irq_chip_data(irq); - ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); -} - -static void enable_se7722_irq(unsigned int irq) -{ - struct ipr_data *p = get_irq_chip_data(irq); - ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); -} - -static struct irq_chip se7722_irq_chip __read_mostly = { - .name = "SE7722", - .mask = disable_se7722_irq, - .unmask = enable_se7722_irq, - .mask_ack = disable_se7722_irq, -}; - -static struct ipr_data ipr_irq_table[] = { - /* irq ,idx,sft, priority , addr */ - { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } , - { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } , - { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } , - { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } , - { SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } , - { EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } , -}; - -int se7722_irq_demux(int irq) -{ - - if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) { - volatile unsigned short intv = - *(volatile unsigned short *)IRQ01_STS; - if (irq == IRQ0_IRQ){ - if(intv & SMC_BIT ) { - return SMC_IRQ; - } else if(intv & USB_BIT) { - return USB_IRQ; - } else { - printk("intv =%04x\n", intv); - return SMC_IRQ; - } - } else if(irq == IRQ1_IRQ){ - if(intv & MRSHPC_BIT0) { - return MRSHPC_IRQ0; - } else if(intv & MRSHPC_BIT1) { - return MRSHPC_IRQ1; - } else if(intv & MRSHPC_BIT2) { - return MRSHPC_IRQ2; - } else if(intv & MRSHPC_BIT3) { - return MRSHPC_IRQ3; - } else { - printk("BIT_EXTENTION =%04x\n", intv); - return EXT_IRQ; - } - } - } - return irq; - -} -/* - * Initialize IRQ setting - */ -void __init init_se7722_IRQ(void) -{ - int i = 0; - ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ - ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */ - ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */ - - for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) { - disable_irq_nosync(ipr_irq_table[i].irq); - set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip, - handle_level_irq, "level"); - set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] ); - disable_se7722_irq(ipr_irq_table[i].irq); - } -} diff --git a/trunk/arch/sh/boards/se/7722/setup.c b/trunk/arch/sh/boards/se/7722/setup.c deleted file mode 100644 index 636ca6c987e0..000000000000 --- a/trunk/arch/sh/boards/se/7722/setup.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * linux/arch/sh/boards/se/7722/setup.c - * - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * Hitachi UL SolutionEngine 7722 Support. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - */ -#include -#include -#include -#include -#include -#include - -/* Heartbeat */ -static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device heartbeat_device = { - .name = "heartbeat", - .id = -1, - .dev = { - .platform_data = heartbeat_bit_pos, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, -}; - -/* SMC91x */ -static struct resource smc91x_eth_resources[] = { - [0] = { - .name = "smc91x-regs" , - .start = PA_LAN + 0x300, - .end = PA_LAN + 0x300 + 0x10 , - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = SMC_IRQ, - .end = SMC_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smc91x_eth_device = { - .name = "smc91x", - .id = 0, - .dev = { - .dma_mask = NULL, /* don't use dma */ - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(smc91x_eth_resources), - .resource = smc91x_eth_resources, -}; - -static struct resource cf_ide_resources[] = { - [0] = { - .start = PA_MRSHPC_IO + 0x1f0, - .end = PA_MRSHPC_IO + 0x1f0 + 8 , - .flags = IORESOURCE_IO, - }, - [1] = { - .start = PA_MRSHPC_IO + 0x1f0 + 0x206, - .end = PA_MRSHPC_IO + 0x1f0 +8 + 0x206 + 8, - .flags = IORESOURCE_IO, - }, - [2] = { - .start = MRSHPC_IRQ0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device cf_ide_device = { - .name = "pata_platform", - .id = -1, - .num_resources = ARRAY_SIZE(cf_ide_resources), - .resource = cf_ide_resources, -}; - -static struct platform_device *se7722_devices[] __initdata = { - &heartbeat_device, - &smc91x_eth_device, - &cf_ide_device, -}; - -static int __init se7722_devices_setup(void) -{ - return platform_add_devices(se7722_devices, - ARRAY_SIZE(se7722_devices)); -} -device_initcall(se7722_devices_setup); - -static void __init se7722_setup(char **cmdline_p) -{ - ctrl_outw(0x010D, FPGA_OUT); /* FPGA */ - - ctrl_outl(0x00051001, MSTPCR0); - ctrl_outl(0x00000000, MSTPCR1); - /* KEYSC, VOU, BEU, CEU, VEU, VPU, LCDC */ - ctrl_outl(0xffffbfC0, MSTPCR2); - - ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ - ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ - - /* LCDC I/O */ - ctrl_outw(0x0020, PORT_PSELD); - - /* SIOF1*/ - ctrl_outw(0x0003, PORT_PSELB); - ctrl_outw(0xe000, PORT_PSELC); - ctrl_outw(0x0000, PORT_PKCR); - - /* LCDC */ - ctrl_outw(0x4020, PORT_PHCR); - ctrl_outw(0x0000, PORT_PLCR); - ctrl_outw(0x0000, PORT_PMCR); - ctrl_outw(0x0002, PORT_PRCR); - ctrl_outw(0x0000, PORT_PXCR); /* LCDC,CS6A */ - - /* KEYSC */ - ctrl_outw(0x0A10, PORT_PSELA); /* BS,SHHID2 */ - ctrl_outw(0x0000, PORT_PYCR); - ctrl_outw(0x0000, PORT_PZCR); -} - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_se7722 __initmv = { - .mv_name = "Solution Engine 7722" , - .mv_setup = se7722_setup , - .mv_nr_irqs = 109 , - .mv_init_irq = init_se7722_IRQ, - .mv_irq_demux = se7722_irq_demux, - -}; -ALIAS_MV(se7722) diff --git a/trunk/arch/sh/boards/se/7751/setup.c b/trunk/arch/sh/boards/se/7751/setup.c index 770defed9c4a..e3feae6ec0bf 100644 --- a/trunk/arch/sh/boards/se/7751/setup.c +++ b/trunk/arch/sh/boards/se/7751/setup.c @@ -14,6 +14,153 @@ #include #include +void init_7751se_IRQ(void); + +#ifdef CONFIG_SH_KGDB +#include +static int kgdb_uart_setup(void); +static struct kgdb_sermap kgdb_uart_sermap = +{ "ttyS", 0, kgdb_uart_setup, NULL }; +#endif + +/* + * Initialize the board + */ +static void __init sh7751se_setup(char **cmdline_p) +{ + /* Call init_smsc() replacement to set up SuperIO. */ + /* XXX: RTC setting comes here */ +#ifdef CONFIG_SH_KGDB + kgdb_register_sermap(&kgdb_uart_sermap); +#endif +} + +/********************************************************************* + * Currently a hack (e.g. does not interact well w/serial.c, lots of * + * hardcoded stuff) but may be useful if SCI/F needs debugging. * + * Mostly copied from x86 code (see files asm-i386/kgdb_local.h and * + * arch/i386/lib/kgdb_serial.c). * + *********************************************************************/ + +#ifdef CONFIG_SH_KGDB +#include +#include +#include +#include + +#define COM1_PORT 0x3f8 /* Base I/O address */ +#define COM1_IRQ 4 /* IRQ not used yet */ +#define COM2_PORT 0x2f8 /* Base I/O address */ +#define COM2_IRQ 3 /* IRQ not used yet */ + +#define SB_CLOCK 1843200 /* Serial baud clock */ +#define SB_BASE (SB_CLOCK/16) +#define SB_MCR UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS + +struct uart_port { + int base; +}; +#define UART_NPORTS 2 +struct uart_port uart_ports[] = { + { COM1_PORT }, + { COM2_PORT }, +}; +struct uart_port *kgdb_uart_port; + +#define UART_IN(reg) inb_p(kgdb_uart_port->base + reg) +#define UART_OUT(reg,v) outb_p((v), kgdb_uart_port->base + reg) + +/* Basic read/write functions for the UART */ +#define UART_LSR_RXCERR (UART_LSR_BI | UART_LSR_FE | UART_LSR_PE) +static int kgdb_uart_getchar(void) +{ + int lsr; + int c = -1; + + while (c == -1) { + lsr = UART_IN(UART_LSR); + if (lsr & UART_LSR_DR) + c = UART_IN(UART_RX); + if ((lsr & UART_LSR_RXCERR)) + c = -1; + } + return c; +} + +static void kgdb_uart_putchar(int c) +{ + while ((UART_IN(UART_LSR) & UART_LSR_THRE) == 0) + ; + UART_OUT(UART_TX, c); +} + +/* + * Initialize UART to configured/requested values. + * (But we don't interrupts yet, or interact w/serial.c) + */ +static int kgdb_uart_setup(void) +{ + int port; + int lcr = 0; + int bdiv = 0; + + if (kgdb_portnum >= UART_NPORTS) { + KGDB_PRINTK("uart port %d invalid.\n", kgdb_portnum); + return -1; + } + + kgdb_uart_port = &uart_ports[kgdb_portnum]; + + /* Init sequence from gdb_hook_interrupt */ + UART_IN(UART_RX); + UART_OUT(UART_IER, 0); + + UART_IN(UART_RX); /* Serial driver comments say */ + UART_IN(UART_IIR); /* this clears interrupt regs */ + UART_IN(UART_MSR); + + /* Figure basic LCR values */ + switch (kgdb_bits) { + case '7': + lcr |= UART_LCR_WLEN7; + break; + default: case '8': + lcr |= UART_LCR_WLEN8; + break; + } + switch (kgdb_parity) { + case 'O': + lcr |= UART_LCR_PARITY; + break; + case 'E': + lcr |= (UART_LCR_PARITY | UART_LCR_EPAR); + break; + default: break; + } + + /* Figure the baud rate divisor */ + bdiv = (SB_BASE/kgdb_baud); + + /* Set the baud rate and LCR values */ + UART_OUT(UART_LCR, (lcr | UART_LCR_DLAB)); + UART_OUT(UART_DLL, (bdiv & 0xff)); + UART_OUT(UART_DLM, ((bdiv >> 8) & 0xff)); + UART_OUT(UART_LCR, lcr); + + /* Set the MCR */ + UART_OUT(UART_MCR, SB_MCR); + + /* Turn off FIFOs for now */ + UART_OUT(UART_FCR, 0); + + /* Setup complete: initialize function pointers */ + kgdb_getchar = kgdb_uart_getchar; + kgdb_putchar = kgdb_uart_putchar; + + return 0; +} +#endif /* CONFIG_SH_KGDB */ + static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; static struct resource heartbeat_resources[] = { @@ -50,6 +197,7 @@ __initcall(se7751_devices_setup); */ struct sh_machine_vector mv_7751se __initmv = { .mv_name = "7751 SolutionEngine", + .mv_setup = sh7751se_setup, .mv_nr_irqs = 72, .mv_inb = sh7751se_inb, diff --git a/trunk/arch/sh/boards/se/7780/Makefile b/trunk/arch/sh/boards/se/7780/Makefile deleted file mode 100644 index 6b88adae3ecc..000000000000 --- a/trunk/arch/sh/boards/se/7780/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the HITACHI UL SolutionEngine 7780 specific parts of the kernel -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# - -obj-y := setup.o irq.o diff --git a/trunk/arch/sh/boards/se/7780/irq.c b/trunk/arch/sh/boards/se/7780/irq.c deleted file mode 100644 index 3d0625c2d07b..000000000000 --- a/trunk/arch/sh/boards/se/7780/irq.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * linux/arch/sh/boards/se/7780/irq.c - * - * Copyright (C) 2006,2007 Nobuhiro Iwamatsu - * - * Hitachi UL SolutionEngine 7780 Support. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include - -#define INTC_INTMSK0 0xFFD00044 -#define INTC_INTMSKCLR0 0xFFD00064 - -static void disable_se7780_irq(unsigned int irq) -{ - struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, INTC_INTMSK0 + p->msk_offset); -} - -static void enable_se7780_irq(unsigned int irq) -{ - struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, INTC_INTMSKCLR0 + p->msk_offset); -} - -static struct irq_chip se7780_irq_chip __read_mostly = { - .name = "SE7780", - .mask = disable_se7780_irq, - .unmask = enable_se7780_irq, - .mask_ack = disable_se7780_irq, -}; - -static struct intc2_data intc2_irq_table[] = { - { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT1 */ - { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT2 */ - { 6, 0, 29, 0, 29, 3 }, /* daughter board EXTINT3 */ - { 8, 0, 28, 0, 28, 3 }, /* SMC 91C111 (LAN) */ - { 10, 0, 27, 0, 27, 3 }, /* daughter board EXTINT4 */ - { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT5 */ - { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT6 */ - { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT7 */ - { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT8 */ - { 0 , 0, 24, 0, 24, 3 }, /* SM501 */ -}; - -/* - * Initialize IRQ setting - */ -void __init init_se7780_IRQ(void) -{ - int i ; - - /* enable all interrupt at FPGA */ - ctrl_outw(0, FPGA_INTMSK1); - /* mask SM501 interrupt */ - ctrl_outw((ctrl_inw(FPGA_INTMSK1) | 0x0002), FPGA_INTMSK1); - /* enable all interrupt at FPGA */ - ctrl_outw(0, FPGA_INTMSK2); - - /* set FPGA INTSEL register */ - /* FPGA + 0x06 */ - ctrl_outw( ((IRQPIN_SM501 << IRQPOS_SM501) | - (IRQPIN_SMC91CX << IRQPOS_SMC91CX)), FPGA_INTSEL1); - - /* FPGA + 0x08 */ - ctrl_outw(((IRQPIN_EXTINT4 << IRQPOS_EXTINT4) | - (IRQPIN_EXTINT3 << IRQPOS_EXTINT3) | - (IRQPIN_EXTINT2 << IRQPOS_EXTINT2) | - (IRQPIN_EXTINT1 << IRQPOS_EXTINT1)), FPGA_INTSEL2); - - /* FPGA + 0x0A */ - ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); - - for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) { - disable_irq_nosync(intc2_irq_table[i].irq); - set_irq_chip_and_handler_name( intc2_irq_table[i].irq, &se7780_irq_chip, - handle_level_irq, "level"); - set_irq_chip_data( intc2_irq_table[i].irq, &intc2_irq_table[i] ); - disable_se7780_irq(intc2_irq_table[i].irq); - } -} diff --git a/trunk/arch/sh/boards/se/7780/setup.c b/trunk/arch/sh/boards/se/7780/setup.c deleted file mode 100644 index df7d08a24c9f..000000000000 --- a/trunk/arch/sh/boards/se/7780/setup.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * linux/arch/sh/boards/se/7780/setup.c - * - * Copyright (C) 2006,2007 Nobuhiro Iwamatsu - * - * Hitachi UL SolutionEngine 7780 Support. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -/* Heartbeat */ -static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - -static struct resource heartbeat_resources[] = { - [0] = { - .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device heartbeat_device = { - .name = "heartbeat", - .id = -1, - .dev = { - .platform_data = heartbeat_bit_pos, - }, - .num_resources = ARRAY_SIZE(heartbeat_resources), - .resource = heartbeat_resources, -}; - -/* SMC91x */ -static struct resource smc91x_eth_resources[] = { - [0] = { - .name = "smc91x-regs" , - .start = PA_LAN + 0x300, - .end = PA_LAN + 0x300 + 0x10 , - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = SMC_IRQ, - .end = SMC_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smc91x_eth_device = { - .name = "smc91x", - .id = 0, - .dev = { - .dma_mask = NULL, /* don't use dma */ - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(smc91x_eth_resources), - .resource = smc91x_eth_resources, -}; - -static struct platform_device *se7780_devices[] __initdata = { - &heartbeat_device, - &smc91x_eth_device, -}; - -static int __init se7780_devices_setup(void) -{ - return platform_add_devices(se7780_devices, - ARRAY_SIZE(se7780_devices)); -} -device_initcall(se7780_devices_setup); - -#define GPIO_PHCR 0xFFEA000E -#define GPIO_PMSELR 0xFFEA0080 -#define GPIO_PECR 0xFFEA0008 - -static void __init se7780_setup(char **cmdline_p) -{ - /* "SH-Linux" on LED Display */ - ctrl_outw( 'S' , PA_LED_DISP + (DISP_SEL0_ADDR << 1) ); - ctrl_outw( 'H' , PA_LED_DISP + (DISP_SEL1_ADDR << 1) ); - ctrl_outw( '-' , PA_LED_DISP + (DISP_SEL2_ADDR << 1) ); - ctrl_outw( 'L' , PA_LED_DISP + (DISP_SEL3_ADDR << 1) ); - ctrl_outw( 'i' , PA_LED_DISP + (DISP_SEL4_ADDR << 1) ); - ctrl_outw( 'n' , PA_LED_DISP + (DISP_SEL5_ADDR << 1) ); - ctrl_outw( 'u' , PA_LED_DISP + (DISP_SEL6_ADDR << 1) ); - ctrl_outw( 'x' , PA_LED_DISP + (DISP_SEL7_ADDR << 1) ); - - printk(KERN_INFO "Hitachi UL Solutions Engine 7780SE03 support.\n"); - - /* - * PCI REQ/GNT setting - * REQ0/GNT0 -> USB - * REQ1/GNT1 -> PC Card - * REQ2/GNT2 -> Serial ATA - * REQ3/GNT3 -> PCI slot - */ - ctrl_outw(0x0213, FPGA_REQSEL); - - /* GPIO setting */ - ctrl_outw(0x0000, GPIO_PECR); - ctrl_outw(ctrl_inw(GPIO_PHCR)&0xfff3, GPIO_PHCR); - ctrl_outw(0x0c00, GPIO_PMSELR); - - /* iVDR Power ON */ - ctrl_outw(0x0001, FPGA_IVDRPW); -} - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_se7780 __initmv = { - .mv_name = "Solution Engine 7780" , - .mv_setup = se7780_setup , - .mv_nr_irqs = 111 , - .mv_init_irq = init_se7780_IRQ, -}; -ALIAS_MV(se7780) diff --git a/trunk/arch/sh/configs/lboxre2_defconfig b/trunk/arch/sh/configs/lboxre2_defconfig deleted file mode 100644 index be86414dcc87..000000000000 --- a/trunk/arch/sh/configs/lboxre2_defconfig +++ /dev/null @@ -1,1271 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc4 -# Sat Mar 24 22:04:27 2007 -# -CONFIG_SUPERH=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_EXTRA_PASS=y -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# System type -# -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_HIGHLANDER is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -CONFIG_SH_LBOX_RE2=y -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH4=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set -# CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -CONFIG_CPU_SUBTYPE_SH7751=y -CONFIG_CPU_SUBTYPE_SH7751R=y -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set -# CONFIG_CPU_SUBTYPE_SH7785 is not set - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set -# CONFIG_CPU_SUBTYPE_SH7722 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x04000000 -CONFIG_VSYSCALL=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_SH_FPU=y -# CONFIG_SH_DSP is not set -# CONFIG_SH_STORE_QUEUES is not set -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_IPR_IRQ=y -CONFIG_CPU_HAS_SR_RB=y -CONFIG_CPU_HAS_PTEA=y - -# -# Timer and clock configuration -# -CONFIG_SH_TMU=y -CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set -CONFIG_SH_PCLK_FREQ=40000000 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Additional SuperH Device Drivers -# -# CONFIG_HEARTBEAT is not set -# CONFIG_PUSH_SWITCH is not set - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_KEXEC=y -# CONFIG_SMP is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC1,115200 root=/dev/sda1" - -# -# Bus options -# -CONFIG_ISA=y -CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=y -CONFIG_PCMCIA_DEBUG=y -CONFIG_PCMCIA=y -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y -CONFIG_CARDBUS=y - -# -# PC-card bridges -# -CONFIG_YENTA=y -CONFIG_YENTA_O2=y -# CONFIG_YENTA_RICOH is not set -# CONFIG_YENTA_TI is not set -# CONFIG_YENTA_TOSHIBA is not set -# CONFIG_PD6729 is not set -# CONFIG_I82092 is not set -# CONFIG_I82365 is not set -# CONFIG_TCIC is not set -CONFIG_PCMCIA_PROBE=y -CONFIG_PCCARD_NONSTATIC=y - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_MULTIPLE_TABLES is not set -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NF_CONNTRACK_ENABLED is not set -# CONFIG_NETFILTER_XTABLES is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNP is not set -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# PCMCIA SCSI adapter support -# -# CONFIG_PCMCIA_AHA152X is not set -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_NINJA_SCSI is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_SYM53C500 is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_LEGACY is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PCMCIA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_QDI is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_WINBOND_VLB is not set -CONFIG_PATA_PLATFORM=y - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_STNIC is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_SMC91X is not set -# CONFIG_NET_VENDOR_RACAL is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_CS89x0 is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -CONFIG_NE2K_PCI=y -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -CONFIG_8139TOO_PIO=y -CONFIG_8139TOO_TUNE_TWISTER=y -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_SC92031 is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -# CONFIG_PCMCIA_3C589 is not set -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_FMVJ18X is not set -CONFIG_PCMCIA_PCNET=y -# CONFIG_PCMCIA_NMCLAN is not set -# CONFIG_PCMCIA_SMC91C92 is not set -# CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_PCMCIA_AXNET is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=2 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_SH is not set -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_EARLY_PRINTK is not set -# CONFIG_SH_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/trunk/arch/sh/configs/r7780rp_defconfig b/trunk/arch/sh/configs/r7780rp_defconfig index 48c6a2194c98..2b75b4896ba5 100644 --- a/trunk/arch/sh/configs/r7780rp_defconfig +++ b/trunk/arch/sh/configs/r7780rp_defconfig @@ -1,11 +1,10 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc7 -# Tue May 1 12:28:39 2007 +# Linux kernel version: 2.6.19 +# Wed Dec 6 11:59:38 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y @@ -14,8 +13,6 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y # CONFIG_GENERIC_TIME is not set CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -34,7 +31,6 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set @@ -45,7 +41,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -103,23 +99,23 @@ CONFIG_DEFAULT_IOSCHED="noop" # System type # # CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7722_SOLUTION_ENGINE is not set # CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7780_SOLUTION_ENGINE is not set # CONFIG_SH_7300_SOLUTION_ENGINE is not set # CONFIG_SH_7343_SOLUTION_ENGINE is not set # CONFIG_SH_73180_SOLUTION_ENGINE is not set # CONFIG_SH_7751_SYSTEMH is not set # CONFIG_SH_HP6XX is not set +# CONFIG_SH_EC3104 is not set # CONFIG_SH_SATURN is not set # CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_BIGSUR is not set # CONFIG_SH_MPC1211 is not set # CONFIG_SH_SH03 is not set # CONFIG_SH_SECUREEDGE5410 is not set # CONFIG_SH_HS7751RVOIP is not set # CONFIG_SH_7710VOIPGW is not set # CONFIG_SH_RTS7751R2D is not set -CONFIG_SH_HIGHLANDER=y +CONFIG_SH_R7780RP=y # CONFIG_SH_EDOSK7705 is not set # CONFIG_SH_SH4202_MICRODEV is not set # CONFIG_SH_LANDISK is not set @@ -127,11 +123,7 @@ CONFIG_SH_HIGHLANDER=y # CONFIG_SH_SHMIN is not set # CONFIG_SH_7206_SOLUTION_ENGINE is not set # CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_LBOX_RE2 is not set # CONFIG_SH_UNKNOWN is not set -CONFIG_SH_R7780RP=y -# CONFIG_SH_R7780MP is not set -# CONFIG_SH_R7785RP is not set # # Processor selection @@ -160,7 +152,6 @@ CONFIG_CPU_SH4A=y # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set -# CONFIG_CPU_SUBTYPE_SH7712 is not set # # SH-4 Processor Support @@ -192,7 +183,6 @@ CONFIG_CPU_SUBTYPE_SH7780=y # # CONFIG_CPU_SUBTYPE_SH73180 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set -# CONFIG_CPU_SUBTYPE_SH7722 is not set # # Memory management options @@ -203,8 +193,6 @@ CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 # CONFIG_32BIT is not set CONFIG_VSYSCALL=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_64KB is not set @@ -222,7 +210,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 # # Cache configuration @@ -239,15 +226,20 @@ CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set CONFIG_SH_STORE_QUEUES=y -CONFIG_SPECULATIVE_EXECUTION=y CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_INTC2_IRQ=y CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y # -# Timer and clock configuration +# Timer support # CONFIG_SH_TMU=y + +# +# R7780RP options +# +CONFIG_SH_R7780MP=y CONFIG_SH_TIMER_IRQ=28 CONFIG_NO_IDLE_HZ=y CONFIG_SH_PCLK_FREQ=32000000 @@ -270,7 +262,6 @@ CONFIG_SH_PCLK_FREQ=32000000 # # Additional SuperH Device Drivers # -# CONFIG_HEARTBEAT is not set CONFIG_PUSH_SWITCH=y # @@ -278,11 +269,9 @@ CONFIG_PUSH_SWITCH=y # # CONFIG_HZ_100 is not set CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 CONFIG_KEXEC=y -# CONFIG_CRASH_DUMP is not set # CONFIG_SMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set @@ -305,6 +294,7 @@ CONFIG_PCI=y CONFIG_SH_PCIDMA_NONCOHERENT=y CONFIG_PCI_AUTO=y CONFIG_PCI_AUTO_UPDATE_RESOURCES=y +# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -344,7 +334,6 @@ CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -436,7 +425,6 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=m # CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # @@ -457,7 +445,6 @@ CONFIG_FW_LOADER=m # # Plug and Play support # -# CONFIG_PNPACPI is not set # # Block devices @@ -474,6 +461,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -493,7 +481,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -513,7 +500,6 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -558,13 +544,11 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set # # Serial ATA (prod) and Parallel ATA (experimental) drivers # CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set # CONFIG_SATA_AHCI is not set # CONFIG_SATA_SVW is not set # CONFIG_ATA_PIIX is not set @@ -580,7 +564,6 @@ CONFIG_SATA_SIL=y # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set # CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set @@ -596,7 +579,6 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_HPT3X2N is not set # CONFIG_PATA_HPT3X3 is not set # CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_MARVELL is not set @@ -703,7 +685,6 @@ CONFIG_8139TOO_8129=y CONFIG_VIA_RHINE=m CONFIG_VIA_RHINE_MMIO=y # CONFIG_VIA_RHINE_NAPI is not set -# CONFIG_SC92031 is not set # # Ethernet (1000 Mbit) @@ -726,13 +707,11 @@ CONFIG_R8169=y # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set # CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set # # Ethernet (10000 Mbit) # # CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set @@ -910,15 +889,9 @@ CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - # # Multimedia devices # @@ -932,8 +905,9 @@ CONFIG_HWMON=y # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -949,20 +923,15 @@ CONFIG_SOUND=m # Open Sound System # CONFIG_SOUND_PRIME=m -# CONFIG_OBSOLETE_OSS is not set +# CONFIG_OSS_OBSOLETE_DRIVER is not set # CONFIG_SOUND_BT878 is not set +# CONFIG_SOUND_ES1371 is not set # CONFIG_SOUND_ICH is not set # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - # # USB support # @@ -1047,14 +1016,6 @@ CONFIG_RTC_DRV_SH=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # @@ -1213,11 +1174,6 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - # # Profiling support # @@ -1228,22 +1184,19 @@ CONFIG_OPROFILE=m # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set +CONFIG_PRINTK_TIME=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_PREEMPT is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set @@ -1251,19 +1204,19 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set -# CONFIG_FRAME_POINTER is not set +CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set -CONFIG_SH_STANDARD_BIOS=y +# CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set -CONFIG_EARLY_PRINTK=y CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set -# CONFIG_SH_KGDB is not set +# CONFIG_KGDB is not set # # Security options @@ -1280,7 +1233,6 @@ CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y @@ -1289,13 +1241,9 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1309,7 +1257,6 @@ CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # @@ -1319,10 +1266,7 @@ CONFIG_CRYPTO_DES=y # # Library routines # -CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/trunk/arch/sh/configs/r7785rp_defconfig b/trunk/arch/sh/configs/r7785rp_defconfig deleted file mode 100644 index 0f5ec649daf8..000000000000 --- a/trunk/arch/sh/configs/r7785rp_defconfig +++ /dev/null @@ -1,1334 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc3 -# Mon Mar 12 14:26:33 2007 -# -CONFIG_SUPERH=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# System type -# -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -CONFIG_SH_HIGHLANDER=y -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_UNKNOWN is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_R7780MP is not set -CONFIG_SH_R7785RP=y - -# -# Processor selection -# -CONFIG_CPU_SH4=y -CONFIG_CPU_SH4A=y -CONFIG_CPU_SHX2=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set -# CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set -CONFIG_CPU_SUBTYPE_SH7785=y - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set -# CONFIG_CPU_SUBTYPE_SH7722 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x08000000 -CONFIG_MEMORY_SIZE=0x08000000 -CONFIG_32BIT=y -# CONFIG_X2TLB is not set -CONFIG_VSYSCALL=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -# CONFIG_HUGETLB_PAGE_SIZE_64K is not set -# CONFIG_HUGETLB_PAGE_SIZE_256K is not set -CONFIG_HUGETLB_PAGE_SIZE_1MB=y -# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set -# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_SH_FPU=y -# CONFIG_SH_DSP is not set -CONFIG_SH_STORE_QUEUES=y -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC2_IRQ=y -CONFIG_CPU_HAS_SR_RB=y -CONFIG_CPU_HAS_PTEA=y - -# -# Timer and clock configuration -# -CONFIG_SH_TMU=y -CONFIG_SH_TIMER_IRQ=28 -CONFIG_NO_IDLE_HZ=y -CONFIG_SH_PCLK_FREQ=50000000 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Additional SuperH Device Drivers -# -CONFIG_HEARTBEAT=y -CONFIG_PUSH_SWITCH=y - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_KEXEC=y -# CONFIG_SMP is not set -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_PREEMPT_BKL=y - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" - -# -# Bus options -# -CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_MULTIPLE_TABLES is not set -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -CONFIG_BRIDGE=m -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set -CONFIG_WIRELESS_EXT=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set -# CONFIG_TIFM_CORE is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -CONFIG_PATA_PLATFORM=y - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_STNIC is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_SMC91X is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NET_PCI is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -CONFIG_R8169=y -# CONFIG_R8169_NAPI is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set -# CONFIG_ATL1 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -# CONFIG_NET_WIRELESS_RTNETLINK is not set - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set -# CONFIG_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support -# -# CONFIG_PRISM54 is not set -# CONFIG_HOSTAP is not set -CONFIG_NET_WIRELESS=y - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=6 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -CONFIG_FB=y -# CONFIG_FIRMWARE_EDID is not set -# CONFIG_FB_DDC is not set -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frambuffer hardware drivers -# -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_EPSON1355 is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set - -# -# Sound -# -CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# -# CONFIG_SND is not set - -# -# Open Sound System -# -CONFIG_SOUND_PRIME=m -# CONFIG_OBSOLETE_OSS is not set -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_M48T86 is not set -CONFIG_RTC_DRV_SH=y -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -CONFIG_MINIX_FS=y -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=y -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -CONFIG_NFSD_V4=y -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -CONFIG_NLS_CODEPAGE_932=y -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Profiling support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=m - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DETECT_SOFTLOCKUP is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_SPINLOCK=y -CONFIG_DEBUG_MUTEXES=y -CONFIG_DEBUG_LOCK_ALLOC=y -# CONFIG_PROVE_LOCKING is not set -CONFIG_LOCKDEP=y -# CONFIG_DEBUG_LOCKDEP is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -CONFIG_DEBUG_LOCKING_API_SELFTESTS=y -CONFIG_STACKTRACE=y -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set -CONFIG_FRAME_POINTER=y -CONFIG_FORCED_INLINING=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set -CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -CONFIG_EARLY_PRINTK=y -CONFIG_DEBUG_STACKOVERFLOW=y -CONFIG_DEBUG_STACK_USAGE=y -# CONFIG_4KSTACKS is not set -# CONFIG_SH_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/trunk/arch/sh/configs/se7705_defconfig b/trunk/arch/sh/configs/se7705_defconfig index 87ae5c1f8629..06ebd6ec0cdb 100644 --- a/trunk/arch/sh/configs/se7705_defconfig +++ b/trunk/arch/sh/configs/se7705_defconfig @@ -1,21 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc5 -# Thu Apr 26 09:16:31 2007 +# Linux kernel version: 2.6.18 +# Tue Oct 3 12:03:04 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -39,9 +33,7 @@ CONFIG_LOCALVERSION_AUTO=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y @@ -99,30 +91,27 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_SOLUTION_ENGINE=y CONFIG_SH_SOLUTION_ENGINE=y # CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7780_SOLUTION_ENGINE is not set # CONFIG_SH_7300_SOLUTION_ENGINE is not set # CONFIG_SH_7343_SOLUTION_ENGINE is not set # CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7722_SOLUTION_ENGINE is not set # CONFIG_SH_7751_SYSTEMH is not set # CONFIG_SH_HP6XX is not set +# CONFIG_SH_EC3104 is not set # CONFIG_SH_SATURN is not set # CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_BIGSUR is not set # CONFIG_SH_MPC1211 is not set # CONFIG_SH_SH03 is not set # CONFIG_SH_SECUREEDGE5410 is not set # CONFIG_SH_HS7751RVOIP is not set # CONFIG_SH_7710VOIPGW is not set # CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_HIGHLANDER is not set +# CONFIG_SH_R7780RP is not set # CONFIG_SH_EDOSK7705 is not set # CONFIG_SH_SH4202_MICRODEV is not set # CONFIG_SH_LANDISK is not set # CONFIG_SH_TITAN is not set # CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_LBOX_RE2 is not set # CONFIG_SH_UNKNOWN is not set # @@ -134,12 +123,6 @@ CONFIG_CPU_SH3=y # SH-2 Processor Support # # CONFIG_CPU_SUBTYPE_SH7604 is not set -# CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7206 is not set # # SH-3 Processor Support @@ -151,7 +134,6 @@ CONFIG_CPU_SUBTYPE_SH7705=y # CONFIG_CPU_SUBTYPE_SH7708 is not set # CONFIG_CPU_SUBTYPE_SH7709 is not set # CONFIG_CPU_SUBTYPE_SH7710 is not set -# CONFIG_CPU_SUBTYPE_SH7712 is not set # # SH-4 Processor Support @@ -176,14 +158,12 @@ CONFIG_CPU_SUBTYPE_SH7705=y # # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set -# CONFIG_CPU_SUBTYPE_SH7785 is not set # # SH4AL-DSP Processor Support # # CONFIG_CPU_SUBTYPE_SH73180 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set -# CONFIG_CPU_SUBTYPE_SH7722 is not set # # Memory management options @@ -193,11 +173,6 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x02000000 CONFIG_VSYSCALL=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -207,7 +182,6 @@ CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 # # Cache configuration @@ -216,31 +190,23 @@ CONFIG_SH7705_CACHE_32KB=y # CONFIG_SH_DIRECT_MAPPED is not set # CONFIG_SH_WRITETHROUGH is not set # CONFIG_SH_OCRAM is not set -CONFIG_CF_ENABLER=y -# CONFIG_CF_AREA5 is not set -CONFIG_CF_AREA6=y -# CONFIG_CF_AREA4 is not set -CONFIG_CF_BASE_ADDR=0xb8000000 +# CONFIG_CF_ENABLER is not set # # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_BIG_ENDIAN is not set # CONFIG_SH_FPU_EMU is not set # CONFIG_SH_DSP is not set # CONFIG_SH_ADC is not set CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_PINT_IRQ=y -CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y # -# Timer and clock configuration +# Timer support # CONFIG_SH_TMU=y -CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 # @@ -257,19 +223,13 @@ CONFIG_SH_PCLK_FREQ=33333333 # Companion Chips # # CONFIG_HD6446X_SERIES is not set - -# -# Additional SuperH Device Drivers -# CONFIG_HEARTBEAT=y -# CONFIG_PUSH_SWITCH is not set # # Kernel features # # CONFIG_HZ_100 is not set CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 # CONFIG_KEXEC is not set @@ -327,7 +287,6 @@ CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -348,13 +307,11 @@ CONFIG_IP_PNP_RARP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -431,7 +388,6 @@ CONFIG_MTD_PARTITIONS=y # User Modules And Translation Layers # CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set @@ -505,7 +461,6 @@ CONFIG_MTD_CFI_UTIL=y # # Plug and Play support # -# CONFIG_PNPACPI is not set # # Block devices @@ -517,13 +472,10 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# -# Misc devices -# - # # ATA/ATAPI/MFM/RLL support # @@ -697,12 +649,17 @@ CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# # CONFIG_RAW_DRIVER is not set # # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -718,7 +675,6 @@ CONFIG_HW_RANDOM=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -727,19 +683,18 @@ CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set # -# Multifunction device drivers +# Misc devices # -# CONFIG_MFD_SM501 is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -749,7 +704,7 @@ CONFIG_HWMON=y # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -757,12 +712,6 @@ CONFIG_HWMON=y # # CONFIG_SOUND is not set -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - # # USB support # @@ -823,14 +772,6 @@ CONFIG_HID=y # DMA Devices # -# -# Auxiliary Display support -# - -# -# Virtualization -# - # # File systems # @@ -838,12 +779,10 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y @@ -889,6 +828,7 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y @@ -937,10 +877,6 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_NLS is not set -# -# Distributed Lock Manager -# - # # Profiling support # @@ -949,18 +885,15 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_SH_KGDB is not set +# CONFIG_KGDB is not set # # Security options @@ -975,7 +908,6 @@ CONFIG_LOG_BUF_SHIFT=14 # # Library routines # -CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=y # CONFIG_CRC16 is not set CONFIG_CRC32=y @@ -983,5 +915,3 @@ CONFIG_CRC32=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/trunk/arch/sh/configs/se7712_defconfig b/trunk/arch/sh/configs/se7712_defconfig deleted file mode 100644 index a5e37dbc5353..000000000000 --- a/trunk/arch/sh/configs/se7712_defconfig +++ /dev/null @@ -1,1088 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc4 -# Wed Mar 28 10:19:02 2007 -# -CONFIG_SUPERH=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -# CONFIG_BUG is not set -CONFIG_ELF_CORE=y -# CONFIG_BASE_FULL is not set -CONFIG_FUTEX=y -CONFIG_EPOLL=y -# CONFIG_SHMEM is not set -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=1 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# System type -# -CONFIG_SOLUTION_ENGINE=y -CONFIG_SH_SOLUTION_ENGINE=y -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_HIGHLANDER is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_LBOX_RE2 is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH3=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set -# CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set -CONFIG_CPU_SUBTYPE_SH7712=y - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set -# CONFIG_CPU_SUBTYPE_SH7785 is not set - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set -# CONFIG_CPU_SUBTYPE_SH7722 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x02000000 -CONFIG_VSYSCALL=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set -CONFIG_CF_ENABLER=y -# CONFIG_CF_AREA5 is not set -CONFIG_CF_AREA6=y -CONFIG_CF_BASE_ADDR=0xb8000000 - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_BIG_ENDIAN is not set -# CONFIG_SH_FPU_EMU is not set -# CONFIG_SH_DSP is not set -# CONFIG_SH_ADC is not set -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_IPR_IRQ=y -CONFIG_CPU_HAS_SR_RB=y - -# -# Timer and clock configuration -# -CONFIG_SH_TMU=y -CONFIG_SH_TIMER_IRQ=16 -# CONFIG_NO_IDLE_HZ is not set -CONFIG_SH_PCLK_FREQ=33333333 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Additional SuperH Device Drivers -# -CONFIG_HEARTBEAT=y -# CONFIG_PUSH_SWITCH is not set - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -# CONFIG_KEXEC is not set -# CONFIG_SMP is not set -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y -# CONFIG_PREEMPT is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC0,115200 root=/dev/sda1" - -# -# Bus options -# -# CONFIG_PCI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_MULTIPATH=y -# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=y -CONFIG_INET_ESP=y -CONFIG_INET_IPCOMP=y -CONFIG_INET_XFRM_TUNNEL=y -CONFIG_INET_TUNNEL=y -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_FIFO=y -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -# CONFIG_NET_SCH_CLK_CPU is not set - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=y -CONFIG_NET_SCH_HTB=y -CONFIG_NET_SCH_HFSC=y -CONFIG_NET_SCH_PRIO=y -CONFIG_NET_SCH_RED=y -CONFIG_NET_SCH_SFQ=y -CONFIG_NET_SCH_TEQL=y -CONFIG_NET_SCH_TBF=y -CONFIG_NET_SCH_GRED=y -CONFIG_NET_SCH_DSMARK=y -CONFIG_NET_SCH_NETEM=y -CONFIG_NET_SCH_INGRESS=y - -# -# Classification -# -CONFIG_NET_CLS=y -# CONFIG_NET_CLS_BASIC is not set -CONFIG_NET_CLS_TCINDEX=y -CONFIG_NET_CLS_ROUTE4=y -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=y -# CONFIG_NET_CLS_U32 is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -# CONFIG_NET_CLS_POLICE is not set -CONFIG_NET_CLS_IND=y -CONFIG_NET_ESTIMATOR=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set -CONFIG_FIB_RULES=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_PATA_PLATFORM=y - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -# CONFIG_INPUT is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=2 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=m -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y - -# -# LED drivers -# - -# -# LED Triggers -# -CONFIG_LEDS_TRIGGERS=y -# CONFIG_LEDS_TRIGGER_TIMER is not set -# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SHIRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DETECT_SOFTLOCKUP is not set -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_LIST is not set -CONFIG_FRAME_POINTER=y -# CONFIG_FORCED_INLINING is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_4KSTACKS is not set -# CONFIG_SH_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_SHA1=y -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_GF128MUL is not set -CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_PCBC=m -# CONFIG_CRYPTO_LRW is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_DEFLATE=y -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_BITREVERSE=y -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/trunk/arch/sh/configs/se7722_defconfig b/trunk/arch/sh/configs/se7722_defconfig deleted file mode 100644 index ca4c663dfa37..000000000000 --- a/trunk/arch/sh/configs/se7722_defconfig +++ /dev/null @@ -1,980 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc7 -# Fri Apr 27 16:30:30 2007 -# -CONFIG_SUPERH=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_RELAY is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# System type -# -CONFIG_SOLUTION_ENGINE=y -# CONFIG_SH_SOLUTION_ENGINE is not set -CONFIG_SH_7722_SOLUTION_ENGINE=y -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7780_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_HIGHLANDER is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_LBOX_RE2 is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH4=y -CONFIG_CPU_SH4A=y -CONFIG_CPU_SH4AL_DSP=y -CONFIG_CPU_SHX2=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set -# CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set -# CONFIG_CPU_SUBTYPE_SH7712 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set -# CONFIG_CPU_SUBTYPE_SH7785 is not set - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set -CONFIG_CPU_SUBTYPE_SH7722=y - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x04000000 -# CONFIG_32BIT is not set -# CONFIG_X2TLB is not set -CONFIG_VSYSCALL=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_HUGETLB_PAGE_SIZE_64K=y -# CONFIG_HUGETLB_PAGE_SIZE_256K is not set -# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set -# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set -# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set -CONFIG_CF_ENABLER=y -# CONFIG_CF_AREA5 is not set -CONFIG_CF_AREA6=y -CONFIG_CF_BASE_ADDR=0xb8000000 - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_BIG_ENDIAN is not set -# CONFIG_SH_FPU is not set -# CONFIG_SH_FPU_EMU is not set -CONFIG_SH_DSP=y -CONFIG_SH_STORE_QUEUES=y -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_IPR_IRQ=y -CONFIG_CPU_HAS_SR_RB=y -CONFIG_CPU_HAS_PTEA=y - -# -# Timer and clock configuration -# -CONFIG_SH_TMU=y -CONFIG_SH_TIMER_IRQ=16 -CONFIG_NO_IDLE_HZ=y -CONFIG_SH_PCLK_FREQ=33333333 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Additional SuperH Device Drivers -# -CONFIG_HEARTBEAT=y -# CONFIG_PUSH_SWITCH is not set - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_KEXEC=y -# CONFIG_CRASH_DUMP is not set -# CONFIG_SMP is not set -# CONFIG_PREEMPT_NONE is not set -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_PREEMPT_BKL=y - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -# CONFIG_CMDLINE_BOOL is not set - -# -# Bus options -# -# CONFIG_PCI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -CONFIG_PATA_PLATFORM=y - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_STNIC is not set -CONFIG_SMC91X=y - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_STOWAWAY is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=2 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set - -# -# RTC drivers -# -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_M48T86 is not set -CONFIG_RTC_DRV_SH=y -# CONFIG_RTC_DRV_TEST is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Distributed Lock Manager -# -# CONFIG_DLM is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_SH_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/trunk/arch/sh/configs/se7780_defconfig b/trunk/arch/sh/configs/se7780_defconfig deleted file mode 100644 index 538661e98793..000000000000 --- a/trunk/arch/sh/configs/se7780_defconfig +++ /dev/null @@ -1,1309 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc3 -# Thu Mar 15 14:06:20 2007 -# -CONFIG_SUPERH=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# Code maturity level options -# -# CONFIG_EXPERIMENTAL is not set -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -# CONFIG_IPC_NS is not set -CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_UTS_NS is not set -# CONFIG_AUDIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_SYSFS_DEPRECATED=y -# CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -# CONFIG_KALLSYMS is not set -# CONFIG_HOTPLUG is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" - -# -# System type -# -CONFIG_SOLUTION_ENGINE=y -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -CONFIG_SH_7780_SOLUTION_ENGINE=y -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_7343_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_HIGHLANDER is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_7206_SOLUTION_ENGINE is not set -# CONFIG_SH_7619_SOLUTION_ENGINE is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH4=y -CONFIG_CPU_SH4A=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set -# CONFIG_CPU_SUBTYPE_SH7619 is not set - -# -# SH-2A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7206 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7770 is not set -CONFIG_CPU_SUBTYPE_SH7780=y -# CONFIG_CPU_SUBTYPE_SH7785 is not set - -# -# SH4AL-DSP Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set -# CONFIG_CPU_SUBTYPE_SH7722 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x08000000 -CONFIG_MEMORY_SIZE=0x08000000 -CONFIG_32BIT=y -CONFIG_VSYSCALL=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_CPU_BIG_ENDIAN is not set -CONFIG_SH_FPU=y -# CONFIG_SH_DSP is not set -# CONFIG_SH_STORE_QUEUES is not set -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC2_IRQ=y -CONFIG_CPU_HAS_SR_RB=y - -# -# Timer and clock configuration -# -CONFIG_SH_TMU=y -CONFIG_SH_TIMER_IRQ=28 -# CONFIG_NO_IDLE_HZ is not set -CONFIG_SH_PCLK_FREQ=33333333 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Additional SuperH Device Drivers -# -CONFIG_HEARTBEAT=y -# CONFIG_PUSH_SWITCH is not set - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_300 is not set -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -# CONFIG_SMP is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00810000 -# CONFIG_UBC_WAKEUP is not set -# CONFIG_CMDLINE_BOOL is not set - -# -# Bus options -# -CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y - -# -# PCCARD (PCMCIA/CardBus) support -# - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_BEET is not set -# CONFIG_IPV6_SIT is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -# CONFIG_MTD_CFI_I1 is not set -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -CONFIG_MTD_ROM=y -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNPACPI is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# Misc devices -# -# CONFIG_SGI_IOC4 is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -# CONFIG_SCSI_NETLINK is not set -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set -# CONFIG_SCSI_SCAN_ASYNC is not set - -# -# SCSI Transports -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_SRP is not set - -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -# CONFIG_ATA_NONSTANDARD is not set -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_SVW is not set -# CONFIG_ATA_PIIX is not set -# CONFIG_SATA_NV is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_PLATFORM is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_VITESSE_PHY is not set -CONFIG_SMSC_PHY=y -# CONFIG_BROADCOM_PHY is not set -# CONFIG_FIXED_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_STNIC is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -CONFIG_SMC91X=y - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_QLA3XXX is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NETXEN_NIC is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=2 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set - -# -# Graphics support -# -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -CONFIG_FB=y -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB_DDC is not set -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_SVGALIB is not set -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set - -# -# Frambuffer hardware drivers -# -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -# CONFIG_FB_ASILIANT is not set -# CONFIG_FB_IMSTT is not set -# CONFIG_FB_EPSON1355 is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_NVIDIA is not set -# CONFIG_FB_RIVA is not set -# CONFIG_FB_MATROX is not set -# CONFIG_FB_RADEON is not set -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_ATY is not set -# CONFIG_FB_S3 is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Logo configuration -# -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_VGA16 is not set -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set -CONFIG_LOGO_SUPERH_CLUT224=y - -# -# Sound -# -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -# CONFIG_SND is not set - -# -# Open Sound System -# -CONFIG_SOUND_PRIME=y -# CONFIG_OBSOLETE_OSS is not set -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set - -# -# HID Devices -# -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -CONFIG_USB_DEBUG=y - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_GTCO is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_IOWARRIOR is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# - -# -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices -# - -# -# Auxiliary Display support -# - -# -# Virtualization -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_PROC_SYSCTL=y -# CONFIG_SYSFS is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_HFSPLUS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_SH_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y diff --git a/trunk/arch/sh/drivers/Kconfig b/trunk/arch/sh/drivers/Kconfig index 420c6b2f33a5..c54c758e6243 100644 --- a/trunk/arch/sh/drivers/Kconfig +++ b/trunk/arch/sh/drivers/Kconfig @@ -1,15 +1,5 @@ -source "arch/sh/drivers/dma/Kconfig" -source "arch/sh/cchips/Kconfig" - menu "Additional SuperH Device Drivers" -config HEARTBEAT - bool "Heartbeat LED" - help - Use the power-on LED on your machine as a load meter. The exact - behavior is platform-dependent, but normally the flash frequency is - a hyperbolic function of the 5-minute load average. - config PUSH_SWITCH tristate "Push switch support" help diff --git a/trunk/arch/sh/drivers/heartbeat.c b/trunk/arch/sh/drivers/heartbeat.c index 23dd6080422f..bc59cb6cd78b 100644 --- a/trunk/arch/sh/drivers/heartbeat.c +++ b/trunk/arch/sh/drivers/heartbeat.c @@ -40,9 +40,16 @@ static void heartbeat_timer(unsigned long data) static unsigned bit = 0, up = 1; ctrl_outw(1 << hd->bit_pos[bit], (unsigned long)hd->base); - bit += up; - if ((bit == 0) || (bit == ARRAY_SIZE(hd->bit_pos)-1)) - up = -up; + if (up) + if (bit == (ARRAY_SIZE(hd->bit_pos) - 1)) { + bit--; + up = 0; + } else + bit++; + else if (bit == 0) + up = 1; + else + bit--; mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT))))); diff --git a/trunk/arch/sh/drivers/pci/Makefile b/trunk/arch/sh/drivers/pci/Makefile index 0e9b532b9fbc..cc8d0d0b1427 100644 --- a/trunk/arch/sh/drivers/pci/Makefile +++ b/trunk/arch/sh/drivers/pci/Makefile @@ -8,15 +8,12 @@ obj-$(CONFIG_PCI_AUTO) += pci-auto.o obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o -obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ dma-dreamcast.o obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o -obj-$(CONFIG_SH_HIGHLANDER) += ops-r7780rp.o fixups-r7780rp.o +obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o obj-$(CONFIG_SH_TITAN) += ops-titan.o obj-$(CONFIG_SH_LANDISK) += ops-landisk.o -obj-$(CONFIG_SH_LBOX_RE2) += ops-lboxre2.o fixups-lboxre2.o -obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += ops-se7780.o fixups-se7780.o diff --git a/trunk/arch/sh/drivers/pci/fixups-lboxre2.c b/trunk/arch/sh/drivers/pci/fixups-lboxre2.c deleted file mode 100644 index 40b19bdfb891..000000000000 --- a/trunk/arch/sh/drivers/pci/fixups-lboxre2.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/sh/drivers/pci/fixups-lboxre2.c - * - * L-BOX RE2 PCI fixups - * - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include "pci-sh4.h" - -#define PCIMCR_MRSET_OFF 0xBFFFFFFF -#define PCIMCR_RFSH_OFF 0xFFFFFFFB - -int pci_fixup_pcic(void) -{ - unsigned long bcr1, mcr; - - bcr1 = inl(SH7751_BCR1); - bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ - pci_write_reg(bcr1, SH4_PCIBCR1); - - /* Enable all interrupts, so we known what to fix */ - pci_write_reg(0x0000c3ff, SH4_PCIINTM); - pci_write_reg(0x0000380f, SH4_PCIAINTM); - pci_write_reg(0xfb900047, SH7751_PCICONF1); - pci_write_reg(0xab000001, SH7751_PCICONF4); - - mcr = inl(SH7751_MCR); - mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; - pci_write_reg(mcr, SH4_PCIMCR); - - pci_write_reg(0x0c000000, SH7751_PCICONF5); - pci_write_reg(0xd0000000, SH7751_PCICONF6); - pci_write_reg(0x0c000000, SH4_PCILAR0); - pci_write_reg(0x00000000, SH4_PCILAR1); - - return 0; -} diff --git a/trunk/arch/sh/drivers/pci/fixups-se7780.c b/trunk/arch/sh/drivers/pci/fixups-se7780.c deleted file mode 100644 index 880cea1c0d89..000000000000 --- a/trunk/arch/sh/drivers/pci/fixups-se7780.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * arch/sh/drivers/pci/fixups-se7780.c - * - * HITACHI UL Solution Engine 7780 PCI fixups - * - * Copyright (C) 2003 Lineo uSolutions, Inc. - * Copyright (C) 2004 - 2006 Paul Mundt - * Copyright (C) 2006 Nobuhiro Iwamatsu - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include "pci-sh4.h" -#include - -int pci_fixup_pcic(void) -{ - ctrl_outl(0x00000001, SH7780_PCI_VCR2); - - /* Enable all interrupts, so we know what to fix */ - pci_write_reg(0x0000C3FF, SH7780_PCIIMR); - pci_write_reg(0x0000380F, SH7780_PCIAINTM); - - /* Set up standard PCI config registers */ - ctrl_outw(0xFB00, PCI_REG(SH7780_PCISTATUS)); - ctrl_outw(0x0047, PCI_REG(SH7780_PCICMD)); - ctrl_outb( 0x00, PCI_REG(SH7780_PCIPIF)); - ctrl_outb( 0x00, PCI_REG(SH7780_PCISUB)); - ctrl_outb( 0x06, PCI_REG(SH7780_PCIBCC)); - ctrl_outw(0x1912, PCI_REG(SH7780_PCISVID)); - ctrl_outw(0x0001, PCI_REG(SH7780_PCISID)); - - pci_write_reg(0x08000000, SH7780_PCIMBAR0); /* PCI */ - pci_write_reg(0x08000000, SH7780_PCILAR0); /* SHwy */ - pci_write_reg(0x07F00001, SH7780_PCILSR); /* size 128M w/ MBAR */ - - pci_write_reg(0x00000000, SH7780_PCIMBAR1); - pci_write_reg(0x00000000, SH7780_PCILAR1); - pci_write_reg(0x00000000, SH7780_PCILSR1); - - pci_write_reg(0xAB000801, SH7780_PCIIBAR); - - /* - * Set the MBR so PCI address is one-to-one with window, - * meaning all calls go straight through... use ifdef to - * catch erroneous assumption. - */ - pci_write_reg(0xFD000000 , SH7780_PCIMBR0); - pci_write_reg(0x00FC0000 , SH7780_PCIMBMR0); /* 16M */ - - /* Set IOBR for window containing area specified in pci.h */ - pci_write_reg(PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE-1), SH7780_PCIIOBR); - pci_write_reg((SH7780_PCI_IO_SIZE-1) & (7 << 18), SH7780_PCIIOBMR); - - pci_write_reg(0xA5000C01, SH7780_PCICR); - - return 0; -} diff --git a/trunk/arch/sh/drivers/pci/ops-landisk.c b/trunk/arch/sh/drivers/pci/ops-landisk.c index bff09ecf3419..d06030815a96 100644 --- a/trunk/arch/sh/drivers/pci/ops-landisk.c +++ b/trunk/arch/sh/drivers/pci/ops-landisk.c @@ -17,8 +17,8 @@ static struct resource sh7751_io_resource = { .name = "SH7751 IO", - .start = SH7751_PCI_IO_BASE, - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, + .start = 0x4000, + .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, .flags = IORESOURCE_IO }; diff --git a/trunk/arch/sh/drivers/pci/ops-lboxre2.c b/trunk/arch/sh/drivers/pci/ops-lboxre2.c deleted file mode 100644 index a13cb764b0b9..000000000000 --- a/trunk/arch/sh/drivers/pci/ops-lboxre2.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * linux/arch/sh/drivers/pci/ops-lboxre2.c - * - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * PCI initialization for the NTT COMWARE L-BOX RE2 - */ -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -static char lboxre2_irq_tab[] __initdata = { - IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - return lboxre2_irq_tab[slot]; -} - -static struct resource sh7751_io_resource = { - .name = "SH7751_IO", - .start = SH7751_PCI_IO_BASE , - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751_mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops sh7751_pci_ops; - -struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; - -EXPORT_SYMBOL(board_pci_channels); - -static struct sh4_pci_address_map sh7751_pci_map = { - .window0 = { - .base = SH7751_CS3_BASE_ADDR, - .size = 0x04000000, - }, - .window1 = { - .base = 0x00000000, /* Unused */ - .size = 0x00000000, /* Unused */ - }, - .flags = SH4_PCIC_NO_RESET, -}; - -int __init pcibios_init_platform(void) -{ - return sh7751_pcic_init(&sh7751_pci_map); -} diff --git a/trunk/arch/sh/drivers/pci/ops-r7780rp.c b/trunk/arch/sh/drivers/pci/ops-r7780rp.c index f2216081ab85..eeea1577e112 100644 --- a/trunk/arch/sh/drivers/pci/ops-r7780rp.c +++ b/trunk/arch/sh/drivers/pci/ops-r7780rp.c @@ -17,25 +17,18 @@ #include #include "pci-sh4.h" -static char r7780rp_irq_tab[] __initdata = { - 0, 1, 2, 3, -}; - -static char r7780mp_irq_tab[] __initdata = { - 65, 66, 67, 68, -}; - int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { - if (mach_is_r7780rp()) - return r7780rp_irq_tab[slot]; - if (mach_is_r7780mp() || mach_is_r7785rp()) - return r7780mp_irq_tab[slot]; - - printk(KERN_ERR "PCI: Bad IRQ mapping " - "request for slot %d, func %d\n", slot, pin-1); - - return -1; + switch (slot) { + case 0: return IRQ_PCISLOT1; /* PCI Interrupt #1 */ + case 1: return IRQ_PCISLOT2; /* PCI Interrupt #2 */ + case 2: return IRQ_PCISLOT3; /* PCI Interrupt #3 */ + case 3: return IRQ_PCISLOT4; /* PCI Interrupt E4 */ + default: + printk(KERN_ERR "PCI: Bad IRQ mapping " + "request for slot %d, func %d\n", slot, pin-1); + return -1; + } } static struct resource sh7780_io_resource = { diff --git a/trunk/arch/sh/drivers/pci/ops-se7780.c b/trunk/arch/sh/drivers/pci/ops-se7780.c deleted file mode 100644 index 212674df5e13..000000000000 --- a/trunk/arch/sh/drivers/pci/ops-se7780.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * linux/arch/sh/drivers/pci/ops-se7780.c - * - * Copyright (C) 2006 Nobuhiro Iwamatsu - * - * PCI initialization for the Hitachi UL Solution Engine 7780SE03 - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - */ -#include -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -/* - * IDSEL = AD16 PCI slot - * IDSEL = AD17 PCI slot - * IDSEL = AD18 Serial ATA Controller (Silicon Image SiL3512A) - * IDSEL = AD19 USB Host Controller (NEC uPD7210100A) - */ - -/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */ -static char se7780_irq_tab[4][16] __initdata = { - /* INTA */ - { 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTB */ - { 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTC */ - { 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* INTD */ - { 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - return se7780_irq_tab[pin-1][slot]; -} - -static struct resource se7780_io_resource = { - .name = "SH7780_IO", - .start = 0x2000, - .end = 0x2000 + SH7780_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource se7780_mem_resource = { - .name = "SH7780_mem", - .start = SH7780_PCI_MEMORY_BASE, - .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops se7780_pci_ops; - -struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &se7780_io_resource, &se7780_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; -EXPORT_SYMBOL(board_pci_channels); - -static struct sh4_pci_address_map se7780_pci_map = { - .window0 = { - .base = SH7780_CS2_BASE_ADDR, - .size = 0x04000000, - }, - .flags = SH4_PCIC_NO_RESET, -}; - -int __init pcibios_init_platform(void) -{ - printk("SH7780 PCI: Finished initialization of the PCI controller\n"); - - /* - * FPGA PCISEL register initialize - * - * CPU || SLOT1 | SLOT2 | S-ATA | USB - * ------------------------------------- - * INTA || INTA | INTD | -- | INTB - * ------------------------------------- - * INTB || INTB | INTA | -- | INTC - * ------------------------------------- - * INTC || INTC | INTB | INTA | -- - * ------------------------------------- - * INTD || INTD | INTC | -- | INTA - * ------------------------------------- - */ - ctrl_outw(0x0013, FPGA_PCI_INTSEL1); - ctrl_outw(0xE402, FPGA_PCI_INTSEL2); - - return sh7780_pcic_init(&se7780_pci_map); -} diff --git a/trunk/arch/sh/drivers/pci/ops-sh4.c b/trunk/arch/sh/drivers/pci/ops-sh4.c index 54232f13e406..2d4371009a5e 100644 --- a/trunk/arch/sh/drivers/pci/ops-sh4.c +++ b/trunk/arch/sh/drivers/pci/ops-sh4.c @@ -162,9 +162,3 @@ char * __init pcibios_setup(char *str) return str; } - -int __attribute__((weak)) pci_fixup_pcic(void) -{ - /* Nothing to do. */ - return 0; -} diff --git a/trunk/arch/sh/drivers/pci/pci-sh4.h b/trunk/arch/sh/drivers/pci/pci-sh4.h index 1901c33cde6a..5a61d6041f2c 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh4.h +++ b/trunk/arch/sh/drivers/pci/pci-sh4.h @@ -1,7 +1,7 @@ #ifndef __PCI_SH4_H #define __PCI_SH4_H -#if defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) +#ifdef CONFIG_CPU_SUBTYPE_SH7780 #include "pci-sh7780.h" #else #include "pci-sh7751.h" diff --git a/trunk/arch/sh/drivers/pci/pci-sh7751.c b/trunk/arch/sh/drivers/pci/pci-sh7751.c index 1aca7fe5783b..9ddff760d3c6 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7751.c +++ b/trunk/arch/sh/drivers/pci/pci-sh7751.c @@ -12,6 +12,7 @@ * License. See linux/COPYING for more information. * */ + #undef DEBUG #include @@ -27,7 +28,7 @@ * Initialization. Try all known PCI access methods. Note that we support * using both PCI BIOS and direct access: in such cases, we use I/O ports * to access config space. - * + * * Note that the platform specific initialization (BSC registers, and memory * space mapping) will be called via the platform defined function * pcibios_init_platform(). @@ -114,7 +115,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable */ - word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | + word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; pci_write_reg(word, SH7751_PCICONF1); @@ -122,10 +123,10 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) word = PCI_BASE_CLASS_BRIDGE << 24; pci_write_reg(word, SH7751_PCICONF2); - /* Set IO and Mem windows to local address - * Make PCI and local address the same for easy 1 to 1 mapping + /* Set IO and Mem windows to local address + * Make PCI and local address the same for easy 1 to 1 mapping * Window0 = map->window0.size @ non-cached area base = SDRAM - * Window1 = map->window1.size @ cached area base = SDRAM + * Window1 = map->window1.size @ cached area base = SDRAM */ word = map->window0.size - 1; pci_write_reg(word, SH4_PCILSR0); @@ -174,7 +175,7 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) case SH7751_CS5_BASE_ADDR: word = __area_sdram_check(5); break; case SH7751_CS6_BASE_ADDR: word = __area_sdram_check(6); break; } - + if (!word) return 0; @@ -193,7 +194,9 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * DMA interrupts... */ +#ifdef CONFIG_SH_RTS7751R2D pci_fixup_pcic(); +#endif /* SH7751 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ diff --git a/trunk/arch/sh/drivers/pci/pci-sh7780.c b/trunk/arch/sh/drivers/pci/pci-sh7780.c index 5508e45d4838..602b644c35ad 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7780.c +++ b/trunk/arch/sh/drivers/pci/pci-sh7780.c @@ -48,7 +48,7 @@ static int __init sh7780_pci_init(void) { unsigned int id; - int ret, match = 0; + int ret; pr_debug("PCI: Starting intialization.\n"); @@ -56,43 +56,19 @@ static int __init sh7780_pci_init(void) /* check for SH7780/SH7780R hardware */ id = pci_read_reg(SH7780_PCIVID); - if ((id & 0xffff) == SH7780_VENDOR_ID) { - switch ((id >> 16) & 0xffff) { - case SH7780_DEVICE_ID: - case SH7781_DEVICE_ID: - case SH7785_DEVICE_ID: - match = 1; - break; - } - } - - if (unlikely(!match)) { + if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) && + (id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) { printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id); return -ENODEV; } /* Setup the INTC */ - if (mach_is_7780se()) { - /* ICR0: IRL=use separately */ - ctrl_outl(0x00C00020, INTC_ICR0); - /* ICR1: detect low level(for 2ndcut) */ - ctrl_outl(0xAAAA0000, INTC_ICR1); - /* INTPRI: priority=3(all) */ - ctrl_outl(0x33333333, INTC_INTPRI); - } else { - /* INTC SH-4 Mode */ - ctrl_outl(0x00200000, INTC_ICR0); - /* enable PCIINTA - PCIINTD */ - ctrl_outl(0x00078000, INTC_INT2MSKCR); - /* disable IRL4-7 Interrupt */ - ctrl_outl(0x40000000, INTC_INTMSK1); - /* disable IRL4-7 Interrupt */ - ctrl_outl(0x0000fffe, INTC_INTMSK2); - /* enable IRL0-3 Interrupt */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); - /* enable IRL0-3 Interrupt */ - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); - } + ctrl_outl(0x00200000, INTC_ICR0); /* INTC SH-4 Mode */ + ctrl_outl(0x00078000, INTC_INT2MSKCR); /* enable PCIINTA - PCIINTD */ + ctrl_outl(0x40000000, INTC_INTMSK1); /* disable IRL4-7 Interrupt */ + ctrl_outl(0x0000fffe, INTC_INTMSK2); /* disable IRL4-7 Interrupt */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); /* enable IRL0-3 Interrupt */ + ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); /* enable IRL0-3 Interrupt */ if ((ret = sh4_pci_check_direct()) != 0) return ret; @@ -162,8 +138,9 @@ int __init sh7780_pcic_init(struct sh4_pci_address_map *map) * DMA interrupts... */ - /* Apply any last-minute PCIC fixups */ +#ifdef CONFIG_SH_R7780RP pci_fixup_pcic(); +#endif /* SH7780 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ diff --git a/trunk/arch/sh/drivers/pci/pci-sh7780.h b/trunk/arch/sh/drivers/pci/pci-sh7780.h index 00d12d0f8c1f..f02d2180a4bc 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7780.h +++ b/trunk/arch/sh/drivers/pci/pci-sh7780.h @@ -14,9 +14,8 @@ /* Platform Specific Values */ #define SH7780_VENDOR_ID 0x1912 -#define SH7781_DEVICE_ID 0x0001 #define SH7780_DEVICE_ID 0x0002 -#define SH7785_DEVICE_ID 0x0007 +#define SH7781_DEVICE_ID 0x0001 /* SH7780 Control Registers */ #define SH7780_PCI_VCR0 0xFE000000 @@ -66,22 +65,6 @@ #define SH7780_PCIPMCSR_BSE 0x046 #define SH7780_PCICDD 0x047 -#define SH7780_PCICR 0x100 /* PCI Control Register */ -#define SH7780_PCILSR 0x104 /* PCI Local Space Register0 */ -#define SH7780_PCILSR1 0x108 /* PCI Local Space Register1 */ -#define SH7780_PCILAR0 0x10C /* PCI Local Address Register1 */ -#define SH7780_PCILAR1 0x110 /* PCI Local Address Register1 */ -#define SH7780_PCIIR 0x114 /* PCI Interrupt Register */ -#define SH7780_PCIIMR 0x118 /* PCI Interrupt Mask Register */ -#define SH7780_PCIAIR 0x11C /* Error Address Register */ -#define SH7780_PCICIR 0x120 /* Error Command/Data Register */ -#define SH7780_PCIAINT 0x130 /* Arbiter Interrupt Register */ -#define SH7780_PCIAINTM 0x134 /* Arbiter Int. Mask Register */ -#define SH7780_PCIBMIR 0x138 /* Error Bus Master Register */ -#define SH7780_PCIPAR 0x1C0 /* PIO Address Register */ -#define SH7780_PCIPINT 0x1CC /* Power Mgmnt Int. Register */ -#define SH7780_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */ - #define SH7780_PCIMBR0 0x1E0 #define SH7780_PCIMBMR0 0x1E4 #define SH7780_PCIMBR2 0x1F0 diff --git a/trunk/arch/sh/drivers/pci/pci-st40.c b/trunk/arch/sh/drivers/pci/pci-st40.c index d67656a44b15..efecb3d5995c 100644 --- a/trunk/arch/sh/drivers/pci/pci-st40.c +++ b/trunk/arch/sh/drivers/pci/pci-st40.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/trunk/arch/sh/kernel/Makefile b/trunk/arch/sh/kernel/Makefile index 9104b6257644..ff30d7f58043 100644 --- a/trunk/arch/sh/kernel/Makefile +++ b/trunk/arch/sh/kernel/Makefile @@ -20,6 +20,5 @@ obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o -obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/trunk/arch/sh/kernel/cf-enabler.c b/trunk/arch/sh/kernel/cf-enabler.c index 0758d48147a0..3e5fa1e24df0 100644 --- a/trunk/arch/sh/kernel/cf-enabler.c +++ b/trunk/arch/sh/kernel/cf-enabler.c @@ -29,7 +29,7 @@ * 0xB8001000 : Common Memory * 0xBA000000 : I/O */ -#if defined(CONFIG_CPU_SH4) +#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4) /* SH4 can't access PCMCIA interface through P2 area. * we must remap it with appropreate attribute bit of the page set. * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */ @@ -71,7 +71,7 @@ static int __init cf_init_default(void) /* You must have enabled the card, and set the level interrupt * before reaching this point. Possibly in boot ROM or boot loader. */ -#if defined(CONFIG_CPU_SH4) +#if defined(CONFIG_IDE) && defined(CONFIG_CPU_SH4) allocate_cf_area(); #endif #if defined(CONFIG_SH_UNKNOWN) @@ -84,25 +84,15 @@ static int __init cf_init_default(void) #if defined(CONFIG_SH_SOLUTION_ENGINE) #include -#elif defined(CONFIG_SH_7722_SOLUTION_ENGINE) -#include -#endif /* - * SolutionEngine Seriese + * SolutionEngine * - * about MS770xSE * 0xB8400000 : Common Memory * 0xB8500000 : Attribute * 0xB8600000 : I/O - * - * about MS7722SE - * 0xB0400000 : Common Memory - * 0xB0500000 : Attribute - * 0xB0600000 : I/O */ -#if defined(CONFIG_SH_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE) static int __init cf_init_se(void) { if ((ctrl_inw(MRSHPC_CSR) & 0x000c) != 0) @@ -119,7 +109,7 @@ static int __init cf_init_se(void) * flag == COMMON/ATTRIBUTE/IO */ /* common window open */ - ctrl_outw(0x8a84, MRSHPC_MW0CR1); + ctrl_outw(0x8a84, MRSHPC_MW0CR1);/* window 0xb8400000 */ if((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0) /* common mode & bus width 16bit SWAP = 1*/ ctrl_outw(0x0b00, MRSHPC_MW0CR2); @@ -128,7 +118,7 @@ static int __init cf_init_se(void) ctrl_outw(0x0300, MRSHPC_MW0CR2); /* attribute window open */ - ctrl_outw(0x8a85, MRSHPC_MW1CR1); + ctrl_outw(0x8a85, MRSHPC_MW1CR1);/* window 0xb8500000 */ if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0) /* attribute mode & bus width 16bit SWAP = 1*/ ctrl_outw(0x0a00, MRSHPC_MW1CR2); @@ -137,7 +127,7 @@ static int __init cf_init_se(void) ctrl_outw(0x0200, MRSHPC_MW1CR2); /* I/O window open */ - ctrl_outw(0x8a86, MRSHPC_IOWCR1); + ctrl_outw(0x8a86, MRSHPC_IOWCR1);/* I/O window 0xb8600000 */ ctrl_outw(0x0008, MRSHPC_CDCR); /* I/O card mode */ if ((ctrl_inw(MRSHPC_CSR) & 0x4000) != 0) ctrl_outw(0x0a00, MRSHPC_IOWCR2); /* bus width 16bit SWAP = 1*/ @@ -153,10 +143,10 @@ static int __init cf_init_se(void) int __init cf_init(void) { - if( mach_is_se() || mach_is_7722se() ){ +#if defined(CONFIG_SH_SOLUTION_ENGINE) + if (MACH_SE) return cf_init_se(); - } - +#endif return cf_init_default(); } diff --git a/trunk/arch/sh/kernel/cpu/clock.c b/trunk/arch/sh/kernel/cpu/clock.c index 014f318f5a05..abb586b12565 100644 --- a/trunk/arch/sh/kernel/cpu/clock.c +++ b/trunk/arch/sh/kernel/cpu/clock.c @@ -1,7 +1,7 @@ /* * arch/sh/kernel/cpu/clock.c - SuperH clock framework * - * Copyright (C) 2005, 2006, 2007 Paul Mundt + * Copyright (C) 2005, 2006 Paul Mundt * * This clock framework is derived from the OMAP version by: * @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -99,17 +98,15 @@ int __clk_enable(struct clk *clk) if (clk->ops && clk->ops->init) clk->ops->init(clk); - kref_get(&clk->kref); - if (clk->flags & CLK_ALWAYS_ENABLED) return 0; if (likely(clk->ops && clk->ops->enable)) clk->ops->enable(clk); + kref_get(&clk->kref); return 0; } -EXPORT_SYMBOL_GPL(__clk_enable); int clk_enable(struct clk *clk) { @@ -122,7 +119,6 @@ int clk_enable(struct clk *clk) return ret; } -EXPORT_SYMBOL_GPL(clk_enable); static void clk_kref_release(struct kref *kref) { @@ -131,17 +127,11 @@ static void clk_kref_release(struct kref *kref) void __clk_disable(struct clk *clk) { - int count = kref_put(&clk->kref, clk_kref_release); - if (clk->flags & CLK_ALWAYS_ENABLED) return; - if (!count) { /* count reaches zero, disable the clock */ - if (likely(clk->ops && clk->ops->disable)) - clk->ops->disable(clk); - } + kref_put(&clk->kref, clk_kref_release); } -EXPORT_SYMBOL_GPL(__clk_disable); void clk_disable(struct clk *clk) { @@ -151,7 +141,6 @@ void clk_disable(struct clk *clk) __clk_disable(clk); spin_unlock_irqrestore(&clock_lock, flags); } -EXPORT_SYMBOL_GPL(clk_disable); int clk_register(struct clk *clk) { @@ -162,18 +151,8 @@ int clk_register(struct clk *clk) mutex_unlock(&clock_list_sem); - if (clk->flags & CLK_ALWAYS_ENABLED) { - pr_debug( "Clock '%s' is ALWAYS_ENABLED\n", clk->name); - if (clk->ops && clk->ops->init) - clk->ops->init(clk); - if (clk->ops && clk->ops->enable) - clk->ops->enable(clk); - pr_debug( "Enabled."); - } - return 0; } -EXPORT_SYMBOL_GPL(clk_register); void clk_unregister(struct clk *clk) { @@ -181,21 +160,13 @@ void clk_unregister(struct clk *clk) list_del(&clk->node); mutex_unlock(&clock_list_sem); } -EXPORT_SYMBOL_GPL(clk_unregister); -unsigned long clk_get_rate(struct clk *clk) +inline unsigned long clk_get_rate(struct clk *clk) { return clk->rate; } -EXPORT_SYMBOL_GPL(clk_get_rate); int clk_set_rate(struct clk *clk, unsigned long rate) -{ - return clk_set_rate_ex(clk, rate, 0); -} -EXPORT_SYMBOL_GPL(clk_set_rate); - -int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) { int ret = -EOPNOTSUPP; @@ -203,7 +174,7 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) unsigned long flags; spin_lock_irqsave(&clock_lock, flags); - ret = clk->ops->set_rate(clk, rate, algo_id); + ret = clk->ops->set_rate(clk, rate); spin_unlock_irqrestore(&clock_lock, flags); } @@ -212,7 +183,6 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id) return ret; } -EXPORT_SYMBOL_GPL(clk_set_rate_ex); void clk_recalc_rate(struct clk *clk) { @@ -227,7 +197,6 @@ void clk_recalc_rate(struct clk *clk) if (unlikely(clk->flags & CLK_RATE_PROPAGATES)) propagate_rate(clk); } -EXPORT_SYMBOL_GPL(clk_recalc_rate); /* * Returns a clock. Note that we first try to use device id on the bus @@ -264,43 +233,18 @@ struct clk *clk_get(struct device *dev, const char *id) return clk; } -EXPORT_SYMBOL_GPL(clk_get); void clk_put(struct clk *clk) { if (clk && !IS_ERR(clk)) module_put(clk->owner); } -EXPORT_SYMBOL_GPL(clk_put); void __init __attribute__ ((weak)) arch_init_clk_ops(struct clk_ops **ops, int type) { } -static int show_clocks(char *buf, char **start, off_t off, - int len, int *eof, void *data) -{ - struct clk *clk; - char *p = buf; - - list_for_each_entry_reverse(clk, &clock_list, node) { - unsigned long rate = clk_get_rate(clk); - - /* - * Don't bother listing dummy clocks with no ancestry - * that only support enable and disable ops. - */ - if (unlikely(!rate && !clk->parent)) - continue; - - p += sprintf(p, "%-12s\t: %ld.%02ldMHz\n", clk->name, - rate / 1000000, (rate % 1000000) / 10000); - } - - return p - buf; -} - int __init clk_init(void) { int i, ret = 0; @@ -312,6 +256,7 @@ int __init clk_init(void) arch_init_clk_ops(&clk->ops, i); ret |= clk_register(clk); + clk_enable(clk); } /* Kick the child clocks.. */ @@ -321,14 +266,35 @@ int __init clk_init(void) return ret; } -static int __init clk_proc_init(void) +int show_clocks(struct seq_file *m) { - struct proc_dir_entry *p; - p = create_proc_read_entry("clocks", S_IRUSR, NULL, - show_clocks, NULL); - if (unlikely(!p)) - return -EINVAL; + struct clk *clk; + + list_for_each_entry_reverse(clk, &clock_list, node) { + unsigned long rate = clk_get_rate(clk); + + /* + * Don't bother listing dummy clocks with no ancestry + * that only support enable and disable ops. + */ + if (unlikely(!rate && !clk->parent)) + continue; + + seq_printf(m, "%-12s\t: %ld.%02ldMHz\n", clk->name, + rate / 1000000, (rate % 1000000) / 10000); + } return 0; } -subsys_initcall(clk_proc_init); + +EXPORT_SYMBOL_GPL(clk_register); +EXPORT_SYMBOL_GPL(clk_unregister); +EXPORT_SYMBOL_GPL(clk_get); +EXPORT_SYMBOL_GPL(clk_put); +EXPORT_SYMBOL_GPL(clk_enable); +EXPORT_SYMBOL_GPL(clk_disable); +EXPORT_SYMBOL_GPL(__clk_enable); +EXPORT_SYMBOL_GPL(__clk_disable); +EXPORT_SYMBOL_GPL(clk_get_rate); +EXPORT_SYMBOL_GPL(clk_set_rate); +EXPORT_SYMBOL_GPL(clk_recalc_rate); diff --git a/trunk/arch/sh/kernel/cpu/init.c b/trunk/arch/sh/kernel/cpu/init.c index 6451ad630174..726acfcb9b77 100644 --- a/trunk/arch/sh/kernel/cpu/init.c +++ b/trunk/arch/sh/kernel/cpu/init.c @@ -41,23 +41,6 @@ __setup("no" __stringify(x), x##_setup); onchip_setup(fpu); onchip_setup(dsp); -#ifdef CONFIG_SPECULATIVE_EXECUTION -#define CPUOPM 0xff2f0000 -#define CPUOPM_RABD (1 << 5) - -static void __init speculative_execution_init(void) -{ - /* Clear RABD */ - ctrl_outl(ctrl_inl(CPUOPM) & ~CPUOPM_RABD, CPUOPM); - - /* Flush the update */ - (void)ctrl_inl(CPUOPM); - ctrl_barrier(); -} -#else -#define speculative_execution_init() do { } while (0) -#endif - /* * Generic first-level cache init */ @@ -278,6 +261,4 @@ asmlinkage void __init sh_cpu_init(void) */ ubc_wakeup(); #endif - - speculative_execution_init(); } diff --git a/trunk/arch/sh/kernel/cpu/irq/Makefile b/trunk/arch/sh/kernel/cpu/irq/Makefile index 1c23308cfc25..0049d217561a 100644 --- a/trunk/arch/sh/kernel/cpu/irq/Makefile +++ b/trunk/arch/sh/kernel/cpu/irq/Makefile @@ -4,6 +4,6 @@ obj-y += imask.o obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o -obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o +obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/trunk/arch/sh/kernel/cpu/irq/intc2.c b/trunk/arch/sh/kernel/cpu/irq/intc2.c index d8e22f4ff0f0..74defe76a058 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc2.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc2.c @@ -18,8 +18,7 @@ #define INTC2_BASE 0xfe080000 #define INTC2_INTMSK (INTC2_BASE + 0x40) #define INTC2_INTMSKCLR (INTC2_BASE + 0x60) -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) #define INTC2_BASE 0xffd40000 #define INTC2_INTMSK (INTC2_BASE + 0x38) #define INTC2_INTMSKCLR (INTC2_BASE + 0x3c) diff --git a/trunk/arch/sh/kernel/cpu/irq/pint.c b/trunk/arch/sh/kernel/cpu/irq/pint.c index 67602685df1a..f60007783a21 100644 --- a/trunk/arch/sh/kernel/cpu/irq/pint.c +++ b/trunk/arch/sh/kernel/cpu/irq/pint.c @@ -18,58 +18,6 @@ #include #include -#if defined(CONFIG_CPU_SUBTYPE_SH7705) -#define INTC_INTER 0xA4000014UL -#define INTC_IPRD 0xA4000018UL -#define INTC_ICR2 0xA4000012UL - -/* PFC */ -#define PORT_PACR 0xA4000100UL -#define PORT_PBCR 0xA4000102UL -#define PORT_PCCR 0xA4000104UL -#define PORT_PDCR 0xA4000106UL -#define PORT_PECR 0xA4000108UL -#define PORT_PFCR 0xA400010AUL -#define PORT_PGCR 0xA400010CUL -#define PORT_PHCR 0xA400010EUL -#define PORT_PJCR 0xA4000110UL -#define PORT_PKCR 0xA4000112UL -#define PORT_PLCR 0xA4000114UL -#define PORT_PMCR 0xA4000118UL -#define PORT_PNCR 0xA400011AUL -#define PORT_PECR2 0xA4050148UL -#define PORT_PFCR2 0xA405014AUL -#define PORT_PNCR2 0xA405015AUL - -/* I/O port */ -#define PORT_PADR 0xA4000120UL -#define PORT_PBDR 0xA4000122UL -#define PORT_PCDR 0xA4000124UL -#define PORT_PDDR 0xA4000126UL -#define PORT_PEDR 0xA4000128UL -#define PORT_PFDR 0xA400012AUL -#define PORT_PGDR 0xA400012CUL -#define PORT_PHDR 0xA400012EUL -#define PORT_PJDR 0xA4000130UL -#define PORT_PKDR 0xA4000132UL -#define PORT_PLDR 0xA4000134UL -#define PORT_PMDR 0xA4000138UL -#define PORT_PNDR 0xA400013AUL - -#define PINT0_IRQ 40 -#define PINT8_IRQ 41 -#define PINT_IRQ_BASE 86 - -#define PINT0_IPR_ADDR INTC_IPRD -#define PINT0_IPR_POS 3 -#define PINT0_PRIORITY 2 - -#define PINT8_IPR_ADDR INTC_IPRD -#define PINT8_IPR_POS 2 -#define PINT8_PRIORITY 2 - -#endif /* CONFIG_CPU_SUBTYPE_SH7705 */ - static unsigned char pint_map[256]; static unsigned long portcr_mask; @@ -178,7 +126,7 @@ int ipr_irq_demux(int irq) unsigned long creg, dreg, d, sav; if (irq == PINT0_IRQ) { -#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7707) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) creg = PORT_PACR; dreg = PORT_PADR; #else @@ -196,7 +144,7 @@ int ipr_irq_demux(int irq) return PINT_IRQ_BASE + pint_map[d]; } else if (irq == PINT8_IRQ) { -#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7707) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) creg = PORT_PBCR; dreg = PORT_PBDR; #else diff --git a/trunk/arch/sh/kernel/cpu/sh3/Makefile b/trunk/arch/sh/kernel/cpu/sh3/Makefile index 09faa056cd43..83905e4e4387 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh3/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o obj-$(CONFIG_CPU_SUBTYPE_SH7300) += setup-sh7300.o obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o -obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH3) := clock-sh3.o diff --git a/trunk/arch/sh/kernel/cpu/sh3/probe.c b/trunk/arch/sh/kernel/cpu/sh3/probe.c index 647623b22edc..821b0ab7b528 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh3/probe.c @@ -78,9 +78,6 @@ int __init detect_cpu_and_cache_system(void) #if defined(CONFIG_CPU_SUBTYPE_SH7710) current_cpu_data.type = CPU_SH7710; #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7712) - current_cpu_data.type = CPU_SH7712; -#endif #if defined(CONFIG_CPU_SUBTYPE_SH7705) current_cpu_data.type = CPU_SH7705; diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 1983fb7ad6ea..a8e41c5241fa 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -2,7 +2,6 @@ * SH7705 Setup * * Copyright (C) 2006 Paul Mundt - * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -15,15 +14,15 @@ static struct plat_sci_port sci_platform_data[] = { { - .mapbase = 0xa4410000, + .mapbase = 0xa4400000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 56, 57, 59 }, + .irqs = { 52, 53, 55, 54 }, }, { - .mapbase = 0xa4400000, + .mapbase = 0xa4410000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 52, 53, 55 }, + .irqs = { 56, 57, 59, 58 }, }, { .flags = 0, } @@ -47,48 +46,3 @@ static int __init sh7705_devices_setup(void) ARRAY_SIZE(sh7705_devices)); } __initcall(sh7705_devices_setup); - -static struct ipr_data sh7705_ipr_map[] = { - /* IRQ, IPR-idx, shift, priority */ - { 16, 0, 12, 2 }, /* TMU0 TUNI*/ - { 17, 0, 8, 2 }, /* TMU1 TUNI */ - { 18, 0, 4, 2 }, /* TMU2 TUNI */ - { 27, 1, 12, 2 }, /* WDT ITI */ - { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ - { 21, 0, 0, 2 }, /* RTC PRI (period) */ - { 22, 0, 0, 2 }, /* RTC CUI (carry) */ - { 48, 4, 12, 7 }, /* DMAC DMTE0 */ - { 49, 4, 12, 7 }, /* DMAC DMTE1 */ - { 50, 4, 12, 7 }, /* DMAC DMTE2 */ - { 51, 4, 12, 7 }, /* DMAC DMTE3 */ - { 52, 4, 8, 3 }, /* SCIF0 ERI */ - { 53, 4, 8, 3 }, /* SCIF0 RXI */ - { 55, 4, 8, 3 }, /* SCIF0 TXI */ - { 56, 4, 4, 3 }, /* SCIF1 ERI */ - { 57, 4, 4, 3 }, /* SCIF1 RXI */ - { 59, 4, 4, 3 }, /* SCIF1 TXI */ -}; - -static unsigned long ipr_offsets[] = { - 0xFFFFFEE2 /* 0: IPRA */ -, 0xFFFFFEE4 /* 1: IPRB */ -, 0xA4000016 /* 2: IPRC */ -, 0xA4000018 /* 3: IPRD */ -, 0xA400001A /* 4: IPRE */ -, 0xA4080000 /* 5: IPRF */ -, 0xA4080002 /* 6: IPRG */ -, 0xA4080004 /* 7: IPRH */ -}; - -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) -{ - if (idx >= ARRAY_SIZE(ipr_offsets)) - return 0; - return ipr_offsets[idx]; -} - -void __init init_IRQ_ipr() -{ - make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map)); -} diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c index c7d7c35fc834..dc9b211cf87f 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c @@ -48,33 +48,24 @@ static struct platform_device *sh7709_devices[] __initdata = { static int __init sh7709_devices_setup(void) { return platform_add_devices(sh7709_devices, - ARRAY_SIZE(sh7709_devices)); + ARRAY_SIZE(sh7709_devices)); } __initcall(sh7709_devices_setup); -#define IPRx(A,N) .addr=A, .shift=N +#define IPRx(A,N) .addr=A, .shift=0*N*-1 #define IPRA(N) IPRx(0xfffffee2UL,N) #define IPRB(N) IPRx(0xfffffee4UL,N) -#define IPRC(N) IPRx(0xa4000016UL,N) -#define IPRD(N) IPRx(0xa4000018UL,N) #define IPRE(N) IPRx(0xa400001aUL,N) static struct ipr_data sh7709_ipr_map[] = { - [16] = { IPRA(12), 2 }, /* TMU TUNI0 */ - [17] = { IPRA(8), 4 }, /* TMU TUNI1 */ - [18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */ - [20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */ - [23 ... 26] = { IPRB(4), 3 }, /* SCI */ - [27] = { IPRB(12), 2 }, /* WDT ITI */ - [32] = { IPRC(0), 1 }, /* IRQ 0 */ - [33] = { IPRC(4), 1 }, /* IRQ 1 */ - [34] = { IPRC(8), 1 }, /* IRQ 2 APM */ - [35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */ - [36] = { IPRD(0), 1 }, /* IRQ 4 */ - [37] = { IPRD(4), 1 }, /* IRQ 5 */ - [48 ... 51] = { IPRE(12), 7 }, /* DMA */ - [52 ... 55] = { IPRE(8), 3 }, /* IRDA */ - [56 ... 59] = { IPRE(4), 3 }, /* SCIF */ + [16] = { IPRA(15-12), 2 }, /* TMU TUNI0 */ + [17] = { IPRA(11-8), 4 }, /* TMU TUNI1 */ + [22] = { IPRA(3-0), 2 }, /* RTC CUI */ + [23 ... 26] = { IPRB(7-4), 3 }, /* SCI */ + [27] = { IPRB(15-12), 2 }, /* WDT ITI */ + [48 ... 51] = { IPRE(15-12), 7 }, /* DMA */ + [52 ... 55] = { IPRE(11-8), 3 }, /* IRDA */ + [56 ... 59] = { IPRE(7-4), 3 }, /* SCIF */ }; void __init init_IRQ_ipr() diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 51760a7e7f1c..895f99ee6a95 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -2,7 +2,6 @@ * SH7710 Setup * * Copyright (C) 2006 Paul Mundt - * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -20,12 +19,6 @@ static struct plat_sci_port sci_platform_data[] = { .type = PORT_SCIF, .irqs = { 52, 53, 55, 54 }, }, { - .mapbase = 0xa4420000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 56, 57, 59, 58 }, - }, { - .flags = 0, } }; @@ -48,56 +41,3 @@ static int __init sh7710_devices_setup(void) ARRAY_SIZE(sh7710_devices)); } __initcall(sh7710_devices_setup); - -static struct ipr_data sh7710_ipr_map[] = { - /* IRQ, IPR-idx, shift, priority */ - { 16, 0, 12, 2 }, /* TMU0 TUNI*/ - { 17, 0, 8, 2 }, /* TMU1 TUNI */ - { 18, 0, 4, 2 }, /* TMU2 TUNI */ - { 27, 1, 12, 2 }, /* WDT ITI */ - { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ - { 21, 0, 0, 2 }, /* RTC PRI (period) */ - { 22, 0, 0, 2 }, /* RTC CUI (carry) */ - { 48, 4, 12, 7 }, /* DMAC DMTE0 */ - { 49, 4, 12, 7 }, /* DMAC DMTE1 */ - { 50, 4, 12, 7 }, /* DMAC DMTE2 */ - { 51, 4, 12, 7 }, /* DMAC DMTE3 */ - { 52, 4, 8, 3 }, /* SCIF0 ERI */ - { 53, 4, 8, 3 }, /* SCIF0 RXI */ - { 54, 4, 8, 3 }, /* SCIF0 BRI */ - { 55, 4, 8, 3 }, /* SCIF0 TXI */ - { 56, 4, 4, 3 }, /* SCIF1 ERI */ - { 57, 4, 4, 3 }, /* SCIF1 RXI */ - { 58, 4, 4, 3 }, /* SCIF1 BRI */ - { 59, 4, 4, 3 }, /* SCIF1 TXI */ - { 76, 5, 8, 7 }, /* DMAC DMTE4 */ - { 77, 5, 8, 7 }, /* DMAC DMTE5 */ - { 80, 6, 12, 5 }, /* EDMAC EINT0 */ - { 81, 6, 8, 5 }, /* EDMAC EINT1 */ - { 82, 6, 4, 5 }, /* EDMAC EINT2 */ -}; - -static unsigned long ipr_offsets[] = { - 0xA414FEE2 /* 0: IPRA */ -, 0xA414FEE4 /* 1: IPRB */ -, 0xA4140016 /* 2: IPRC */ -, 0xA4140018 /* 3: IPRD */ -, 0xA414001A /* 4: IPRE */ -, 0xA4080000 /* 5: IPRF */ -, 0xA4080002 /* 6: IPRG */ -, 0xA4080004 /* 7: IPRH */ -, 0xA4080006 /* 8: IPRI */ -}; - -/* given the IPR index return the address of the IPR register */ -unsigned int map_ipridx_to_addr(int idx) -{ - if (idx >= ARRAY_SIZE(ipr_offsets)) - return 0; - return ipr_offsets[idx]; -} - -void __init init_IRQ_ipr() -{ - make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map)); -} diff --git a/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index fcb2c41bc34e..fa2019aabd74 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/trunk/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -82,8 +82,7 @@ static void shoc_clk_init(struct clk *clk) for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { int divisor = frqcr3_divisors[i]; - if (clk->ops->set_rate(clk, clk->parent->rate / - divisor, 0) == 0) + if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0) break; } diff --git a/trunk/arch/sh/kernel/cpu/sh4/probe.c b/trunk/arch/sh/kernel/cpu/sh4/probe.c index 8cd04904c77a..58950de2696d 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh4/probe.c @@ -124,14 +124,6 @@ int __init detect_cpu_and_cache_system(void) current_cpu_data.dcache.ways = 4; current_cpu_data.flags |= CPU_HAS_LLSC; break; - case 0x3004: - case 0x3007: - current_cpu_data.type = CPU_SH7785; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | - CPU_HAS_LLSC; - break; case 0x3008: if (prr == 0xa0) { current_cpu_data.type = CPU_SH7722; diff --git a/trunk/arch/sh/kernel/cpu/sh4a/Makefile b/trunk/arch/sh/kernel/cpu/sh4a/Makefile index ab7422f8f820..a8f493f2f21f 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh4a/Makefile @@ -5,7 +5,6 @@ # CPU subtype setup obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o -obj-$(CONFIG_CPU_SUBTYPE_SH7785) += setup-sh7785.o obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o @@ -14,8 +13,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o -clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o -clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o +clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o obj-y += $(clock-y) diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c deleted file mode 100644 index 29090035bc5b..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh4a/clock-sh7722.c - * - * SH7722 support for the clock framework - * - * Copyright (c) 2006-2007 Nomad Global Solutions Inc - * Based on code for sh7343 by Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include - -#define SH7722_PLL_FREQ (32000000/8) -#define N (-1) -#define NM (-2) -#define ROUND_NEAREST 0 -#define ROUND_DOWN -1 -#define ROUND_UP +1 - -static int adjust_algos[][3] = { - {}, /* NO_CHANGE */ - { NM, N, 1 }, /* N:1, N:1 */ - { 3, 2, 2 }, /* 3:2:2 */ - { 5, 2, 2 }, /* 5:2:2 */ - { N, 1, 1 }, /* N:1:1 */ - - { N, 1 }, /* N:1 */ - - { N, 1 }, /* N:1 */ - { 3, 2 }, - { 4, 3 }, - { 5, 4 }, - - { N, 1 } -}; - -static unsigned long adjust_pair_of_clocks(unsigned long r1, unsigned long r2, - int m1, int m2, int round_flag) -{ - unsigned long rem, div; - int the_one = 0; - - pr_debug( "Actual values: r1 = %ld\n", r1); - pr_debug( "...............r2 = %ld\n", r2); - - if (m1 == m2) { - r2 = r1; - pr_debug( "setting equal rates: r2 now %ld\n", r2); - } else if ((m2 == N && m1 == 1) || - (m2 == NM && m1 == N)) { /* N:1 or NM:N */ - pr_debug( "Setting rates as 1:N (N:N*M)\n"); - rem = r2 % r1; - pr_debug( "...remainder = %ld\n", rem); - if (rem) { - div = r2 / r1; - pr_debug( "...div = %ld\n", div); - switch (round_flag) { - case ROUND_NEAREST: - the_one = rem >= r1/2 ? 1 : 0; break; - case ROUND_UP: - the_one = 1; break; - case ROUND_DOWN: - the_one = 0; break; - } - - r2 = r1 * (div + the_one); - pr_debug( "...setting r2 to %ld\n", r2); - } - } else if ((m2 == 1 && m1 == N) || - (m2 == N && m1 == NM)) { /* 1:N or N:NM */ - pr_debug( "Setting rates as N:1 (N*M:N)\n"); - rem = r1 % r2; - pr_debug( "...remainder = %ld\n", rem); - if (rem) { - div = r1 / r2; - pr_debug( "...div = %ld\n", div); - switch (round_flag) { - case ROUND_NEAREST: - the_one = rem > r2/2 ? 1 : 0; break; - case ROUND_UP: - the_one = 0; break; - case ROUND_DOWN: - the_one = 1; break; - } - - r2 = r1 / (div + the_one); - pr_debug( "...setting r2 to %ld\n", r2); - } - } else { /* value:value */ - pr_debug( "Setting rates as %d:%d\n", m1, m2); - div = r1 / m1; - r2 = div * m2; - pr_debug( "...div = %ld\n", div); - pr_debug( "...setting r2 to %ld\n", r2); - } - - return r2; -} - -static void adjust_clocks(int originate, int *l, unsigned long v[], - int n_in_line) -{ - int x; - - pr_debug( "Go down from %d...\n", originate); - /* go up recalculation clocks */ - for (x = originate; x>0; x -- ) - v[x-1] = adjust_pair_of_clocks(v[x], v[x-1], - l[x], l[x-1], - ROUND_UP); - - pr_debug( "Go up from %d...\n", originate); - /* go down recalculation clocks */ - for (x = originate; xrate = CONFIG_SH_PCLK_FREQ * (1 + (frqcr >> 24 & 0xF)); -} - -static int master_clk_setrate(struct clk *clk, unsigned long rate, int id) -{ - int div = rate / SH7722_PLL_FREQ; - int master_divs[] = { 2, 3, 4, 6, 8, 16 }; - int index; - unsigned long frqcr; - - if (rate < SH7722_PLL_FREQ * 2) - return -EINVAL; - - for (index = 1; index < ARRAY_SIZE(master_divs); index++) - if (div >= master_divs[index - 1] && div < master_divs[index]) - break; - - if (index >= ARRAY_SIZE(master_divs)) - index = ARRAY_SIZE(master_divs); - div = master_divs[index - 1]; - - frqcr = ctrl_inl(FRQCR); - frqcr &= ~(0xF << 24); - frqcr |= ( (div-1) << 24); - ctrl_outl(frqcr, FRQCR); - - return 0; -} - -static struct clk_ops sh7722_master_clk_ops = { - .init = master_clk_init, - .recalc = master_clk_recalc, - .set_rate = master_clk_setrate, -}; - -struct frqcr_context { - unsigned mask; - unsigned shift; -}; - -struct frqcr_context sh7722_get_clk_context(const char *name) -{ - struct frqcr_context ctx = { 0, }; - - if (!strcmp(name, "peripheral_clk")) { - ctx.shift = 0; - ctx.mask = 0xF; - } else if (!strcmp(name, "sdram_clk")) { - ctx.shift = 4; - ctx.mask = 0xF; - } else if (!strcmp(name, "bus_clk")) { - ctx.shift = 8; - ctx.mask = 0xF; - } else if (!strcmp(name, "sh_clk")) { - ctx.shift = 12; - ctx.mask = 0xF; - } else if (!strcmp(name, "umem_clk")) { - ctx.shift = 16; - ctx.mask = 0xF; - } else if (!strcmp(name, "cpu_clk")) { - ctx.shift = 20; - ctx.mask = 7; - } - return ctx; -} - -/** - * sh7722_find_divisors - find divisor for setting rate - * - * All sh7722 clocks use the same set of multipliers/divisors. This function - * chooses correct divisor to set the rate of clock with parent clock that - * generates frequency of 'parent_rate' - * - * @parent_rate: rate of parent clock - * @rate: requested rate to be set - */ -static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate) -{ - unsigned div2 = parent_rate * 2 / rate; - int index; - - if (rate > parent_rate) - return -EINVAL; - - for (index = 1; index < ARRAY_SIZE(divisors2); index++) { - if (div2 > divisors2[index] && div2 <= divisors2[index]) - break; - } - if (index >= ARRAY_SIZE(divisors2)) - index = ARRAY_SIZE(divisors2) - 1; - return divisors2[index]; -} - -static void sh7722_frqcr_recalc(struct clk *clk) -{ - struct frqcr_context ctx = sh7722_get_clk_context(clk->name); - unsigned long frqcr = ctrl_inl(FRQCR); - int index; - - index = (frqcr >> ctx.shift) & ctx.mask; - clk->rate = clk->parent->rate * 2 / divisors2[index]; -} - -static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate, - int algo_id) -{ - struct frqcr_context ctx = sh7722_get_clk_context(clk->name); - unsigned long parent_rate = clk->parent->rate; - int div; - unsigned long frqcr; - int err = 0; - - /* pretty invalid */ - if (parent_rate < rate) - return -EINVAL; - - /* look for multiplier/divisor pair */ - div = sh7722_find_divisors(parent_rate, rate); - if (div<0) - return div; - - /* calculate new value of clock rate */ - clk->rate = parent_rate * 2 / div; - frqcr = ctrl_inl(FRQCR); - - /* FIXME: adjust as algo_id specifies */ - if (algo_id != NO_CHANGE) { - int originator; - char *algo_group_1[] = { "cpu_clk", "umem_clk", "sh_clk" }; - char *algo_group_2[] = { "sh_clk", "bus_clk" }; - char *algo_group_3[] = { "sh_clk", "sdram_clk" }; - char *algo_group_4[] = { "bus_clk", "peripheral_clk" }; - char *algo_group_5[] = { "cpu_clk", "peripheral_clk" }; - char **algo_current = NULL; - /* 3 is the maximum number of clocks in relation */ - struct clk *ck[3]; - unsigned long values[3]; /* the same comment as above */ - int part_length = -1; - int i; - - /* - * all the steps below only required if adjustion was - * requested - */ - if (algo_id == IUS_N1_N1 || - algo_id == IUS_322 || - algo_id == IUS_522 || - algo_id == IUS_N11) { - algo_current = algo_group_1; - part_length = 3; - } - if (algo_id == SB_N1) { - algo_current = algo_group_2; - part_length = 2; - } - if (algo_id == SB3_N1 || - algo_id == SB3_32 || - algo_id == SB3_43 || - algo_id == SB3_54) { - algo_current = algo_group_3; - part_length = 2; - } - if (algo_id == BP_N1) { - algo_current = algo_group_4; - part_length = 2; - } - if (algo_id == IP_N1) { - algo_current = algo_group_5; - part_length = 2; - } - if (!algo_current) - goto incorrect_algo_id; - - originator = -1; - for (i = 0; i < part_length; i ++ ) { - if (originator >= 0 && !strcmp(clk->name, - algo_current[i])) - originator = i; - ck[i] = clk_get(NULL, algo_current[i]); - values[i] = clk_get_rate(ck[i]); - } - - if (originator >= 0) - adjust_clocks(originator, adjust_algos[algo_id], - values, part_length); - - for (i = 0; i < part_length; i ++ ) { - struct frqcr_context part_ctx; - int part_div; - - if (likely(!err)) { - part_div = sh7722_find_divisors(parent_rate, - rate); - if (part_div > 0) { - part_ctx = sh7722_get_clk_context( - ck[i]->name); - frqcr &= ~(part_ctx.mask << - part_ctx.shift); - frqcr |= part_div << part_ctx.shift; - } else - err = part_div; - } - - ck[i]->ops->recalc(ck[i]); - clk_put(ck[i]); - } - } - - /* was there any error during recalculation ? If so, bail out.. */ - if (unlikely(err!=0)) - goto out_err; - - /* clear FRQCR bits */ - frqcr &= ~(ctx.mask << ctx.shift); - frqcr |= div << ctx.shift; - - /* ...and perform actual change */ - ctrl_outl(frqcr, FRQCR); - return 0; - -incorrect_algo_id: - return -EINVAL; -out_err: - return err; -} - -static struct clk_ops sh7722_frqcr_clk_ops = { - .recalc = sh7722_frqcr_recalc, - .set_rate = sh7722_frqcr_set_rate, -}; - -/* - * clock ops methods for SIU A/B and IrDA clock - * - */ -static int sh7722_siu_which(struct clk *clk) -{ - if (!strcmp(clk->name, "siu_a_clk")) - return 0; - if (!strcmp(clk->name, "siu_b_clk")) - return 1; - if (!strcmp(clk->name, "irda_clk")) - return 2; - return -EINVAL; -} - -static unsigned long sh7722_siu_regs[] = { - [0] = SCLKACR, - [1] = SCLKBCR, - [2] = IrDACLKCR, -}; - -static int sh7722_siu_start_stop(struct clk *clk, int enable) -{ - int siu = sh7722_siu_which(clk); - unsigned long r; - - if (siu < 0) - return siu; - BUG_ON(siu > 2); - r = ctrl_inl(sh7722_siu_regs[siu]); - if (enable) - ctrl_outl(r & ~(1 << 8), sh7722_siu_regs[siu]); - else - ctrl_outl(r | (1 << 8), sh7722_siu_regs[siu]); - return 0; -} - -static void sh7722_siu_enable(struct clk *clk) -{ - sh7722_siu_start_stop(clk, 1); -} - -static void sh7722_siu_disable(struct clk *clk) -{ - sh7722_siu_start_stop(clk, 0); -} - -static void sh7722_video_enable(struct clk *clk) -{ - unsigned long r; - - r = ctrl_inl(VCLKCR); - ctrl_outl( r & ~(1<<8), VCLKCR); -} - -static void sh7722_video_disable(struct clk *clk) -{ - unsigned long r; - - r = ctrl_inl(VCLKCR); - ctrl_outl( r | (1<<8), VCLKCR); -} - -static int sh7722_video_set_rate(struct clk *clk, unsigned long rate, - int algo_id) -{ - unsigned long r; - - r = ctrl_inl(VCLKCR); - r &= ~0x3F; - r |= ((clk->parent->rate / rate - 1) & 0x3F); - ctrl_outl(r, VCLKCR); - return 0; -} - -static void sh7722_video_recalc(struct clk *clk) -{ - unsigned long r; - - r = ctrl_inl(VCLKCR); - clk->rate = clk->parent->rate / ((r & 0x3F) + 1); -} - -static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id) -{ - int siu = sh7722_siu_which(clk); - unsigned long r; - int div; - - if (siu < 0) - return siu; - BUG_ON(siu > 2); - r = ctrl_inl(sh7722_siu_regs[siu]); - div = sh7722_find_divisors(clk->parent->rate, rate); - if (div < 0) - return div; - r = (r & ~0xF) | div; - ctrl_outl(r, sh7722_siu_regs[siu]); - return 0; -} - -static void sh7722_siu_recalc(struct clk *clk) -{ - int siu = sh7722_siu_which(clk); - unsigned long r; - - if (siu < 0) - return /* siu */ ; - BUG_ON(siu > 1); - r = ctrl_inl(sh7722_siu_regs[siu]); - clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF]; -} - -static struct clk_ops sh7722_siu_clk_ops = { - .recalc = sh7722_siu_recalc, - .set_rate = sh7722_siu_set_rate, - .enable = sh7722_siu_enable, - .disable = sh7722_siu_disable, -}; - -static struct clk_ops sh7722_video_clk_ops = { - .recalc = sh7722_video_recalc, - .set_rate = sh7722_video_set_rate, - .enable = sh7722_video_enable, - .disable = sh7722_video_disable, -}; -/* - * and at last, clock definitions themselves - */ -static struct clk sh7722_umem_clock = { - .name = "umem_clk", - .ops = &sh7722_frqcr_clk_ops, -}; - -static struct clk sh7722_sh_clock = { - .name = "sh_clk", - .ops = &sh7722_frqcr_clk_ops, -}; - -static struct clk sh7722_peripheral_clock = { - .name = "peripheral_clk", - .ops = &sh7722_frqcr_clk_ops, -}; - -static struct clk sh7722_sdram_clock = { - .name = "sdram_clk", - .ops = &sh7722_frqcr_clk_ops, -}; - -/* - * these three clocks - SIU A, SIU B, IrDA - share the same clk_ops - * methods of clk_ops determine which register they should access by - * examining clk->name field - */ -static struct clk sh7722_siu_a_clock = { - .name = "siu_a_clk", - .ops = &sh7722_siu_clk_ops, -}; - -static struct clk sh7722_siu_b_clock = { - .name = "siu_b_clk", - .ops = &sh7722_siu_clk_ops, -}; - -static struct clk sh7722_irda_clock = { - .name = "irda_clk", - .ops = &sh7722_siu_clk_ops, -}; - -static struct clk sh7722_video_clock = { - .name = "video_clk", - .ops = &sh7722_video_clk_ops, -}; - -static struct clk *sh7722_clocks[] = { - &sh7722_umem_clock, - &sh7722_sh_clock, - &sh7722_peripheral_clock, - &sh7722_sdram_clock, - &sh7722_siu_a_clock, - &sh7722_siu_b_clock, - &sh7722_irda_clock, - &sh7722_video_clock, -}; - -/* - * init in order: master, module, bus, cpu - */ -struct clk_ops *onchip_ops[] = { - &sh7722_master_clk_ops, - &sh7722_frqcr_clk_ops, - &sh7722_frqcr_clk_ops, - &sh7722_frqcr_clk_ops, -}; - -void __init -arch_init_clk_ops(struct clk_ops **ops, int type) -{ - BUG_ON(type < 0 || type > ARRAY_SIZE(onchip_ops)); - *ops = onchip_ops[type]; -} - -int __init sh7722_clock_init(void) -{ - struct clk *master; - int i; - - master = clk_get(NULL, "master_clk"); - for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) { - pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name); - sh7722_clocks[i]->parent = master; - clk_register(sh7722_clocks[i]); - } - clk_put(master); - return 0; -} -arch_initcall(sh7722_clock_init); diff --git a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7785.c deleted file mode 100644 index 805535aa505e..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh4a/clock-sh7785.c - * - * SH7785 support for the clock framework - * - * Copyright (C) 2007 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -static int ifc_divisors[] = { 1, 2, 4, 6 }; -static int ufc_divisors[] = { 1, 1, 4, 6 }; -static int sfc_divisors[] = { 1, 1, 4, 6 }; -static int bfc_divisors[] = { 1, 1, 1, 1, 1, 12, 16, 18, - 24, 32, 36, 48, 1, 1, 1, 1 }; -static int mfc_divisors[] = { 1, 1, 4, 6 }; -static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, - 24, 32, 36, 48, 1, 1, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= 36; -} - -static struct clk_ops sh7785_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQMR1) & 0x000f); - clk->rate = clk->parent->rate / pfc_divisors[idx]; -} - -static struct clk_ops sh7785_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 16) & 0x000f); - clk->rate = clk->parent->rate / bfc_divisors[idx]; -} - -static struct clk_ops sh7785_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 28) & 0x0003); - clk->rate = clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7785_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7785_clk_ops[] = { - &sh7785_master_clk_ops, - &sh7785_module_clk_ops, - &sh7785_bus_clk_ops, - &sh7785_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7785_clk_ops)) - *ops = sh7785_clk_ops[idx]; -} - -static void shyway_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 20) & 0x0003); - clk->rate = clk->parent->rate / sfc_divisors[idx]; -} - -static struct clk_ops sh7785_shyway_clk_ops = { - .recalc = shyway_clk_recalc, -}; - -static struct clk sh7785_shyway_clk = { - .name = "shyway_clk", - .flags = CLK_ALWAYS_ENABLED, - .ops = &sh7785_shyway_clk_ops, -}; - -static void ddr_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 12) & 0x0003); - clk->rate = clk->parent->rate / mfc_divisors[idx]; -} - -static struct clk_ops sh7785_ddr_clk_ops = { - .recalc = ddr_clk_recalc, -}; - -static struct clk sh7785_ddr_clk = { - .name = "ddr_clk", - .flags = CLK_ALWAYS_ENABLED, - .ops = &sh7785_ddr_clk_ops, -}; - -static void ram_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQMR1) >> 24) & 0x0003); - clk->rate = clk->parent->rate / ufc_divisors[idx]; -} - -static struct clk_ops sh7785_ram_clk_ops = { - .recalc = ram_clk_recalc, -}; - -static struct clk sh7785_ram_clk = { - .name = "ram_clk", - .flags = CLK_ALWAYS_ENABLED, - .ops = &sh7785_ram_clk_ops, -}; - -/* - * Additional SH7785-specific on-chip clocks that aren't already part of the - * clock framework - */ -static struct clk *sh7785_onchip_clocks[] = { - &sh7785_shyway_clk, - &sh7785_ddr_clk, - &sh7785_ram_clk, -}; - -static int __init sh7785_clk_init(void) -{ - struct clk *clk = clk_get(NULL, "master_clk"); - int i; - - for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) { - struct clk *clkp = sh7785_onchip_clocks[i]; - - clkp->parent = clk; - clk_register(clkp); - clk_enable(clkp); - } - - /* - * Now that we have the rest of the clocks registered, we need to - * force the parent clock to propagate so that these clocks will - * automatically figure out their rate. We cheat by handing the - * parent clock its current rate and forcing child propagation. - */ - clk_set_rate(clk, clk_get_rate(clk)); - - clk_put(clk); - - return 0; -} -arch_initcall(sh7785_clk_init); diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c deleted file mode 100644 index 07b0de82cfe6..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * SH7785 Setup - * - * Copyright (C) 2007 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffea0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, - }, { - .mapbase = 0xffeb0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 44, 45, 47, 46 }, - }, - - /* - * The rest of these all have multiplexed IRQs - */ - { - .mapbase = 0xffec0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 60, 60, 60, 60 }, - }, { - .mapbase = 0xffed0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 61, 61, 61, 61 }, - }, { - .mapbase = 0xffee0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 62, 62, 62, 62 }, - }, { - .mapbase = 0xffef0000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 63, 63, 63, 63 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7785_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7785_devices_setup(void) -{ - return platform_add_devices(sh7785_devices, - ARRAY_SIZE(sh7785_devices)); -} -__initcall(sh7785_devices_setup); - -static struct intc2_data intc2_irq_table[] = { - { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ - - { 40, 8, 24, 0, 2, 3 }, /* SCIF0 ERI */ - { 41, 8, 24, 0, 2, 3 }, /* SCIF0 RXI */ - { 42, 8, 24, 0, 2, 3 }, /* SCIF0 BRI */ - { 43, 8, 24, 0, 2, 3 }, /* SCIF0 TXI */ - - { 44, 8, 16, 0, 3, 3 }, /* SCIF1 ERI */ - { 45, 8, 16, 0, 3, 3 }, /* SCIF1 RXI */ - { 46, 8, 16, 0, 3, 3 }, /* SCIF1 BRI */ - { 47, 8, 16, 0, 3, 3 }, /* SCIF1 TXI */ - - { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */ - { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */ - { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */ - { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */ - { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */ - - { 60, 8, 8, 0, 4, 3 }, /* SCIF2 ERI, RXI, BRI, TXI */ - { 60, 8, 0, 0, 5, 3 }, /* SCIF3 ERI, RXI, BRI, TXI */ - { 60, 12, 24, 0, 6, 3 }, /* SCIF4 ERI, RXI, BRI, TXI */ - { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ -}; - -void __init init_IRQ_intc2(void) -{ - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); -} diff --git a/trunk/arch/sh/kernel/crash_dump.c b/trunk/arch/sh/kernel/crash_dump.c deleted file mode 100644 index 4a2ecbe27d8e..000000000000 --- a/trunk/arch/sh/kernel/crash_dump.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * crash_dump.c - Memory preserving reboot related code. - * - * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) - * Copyright (C) IBM Corporation, 2004. All rights reserved - */ - -#include -#include -#include -#include - -/** - * copy_oldmem_page - copy one page from "oldmem" - * @pfn: page frame number to be copied - * @buf: target memory address for the copy; this can be in kernel address - * space or user address space (see @userbuf) - * @csize: number of bytes to copy - * @offset: offset in bytes into the page (based on pfn) to begin the copy - * @userbuf: if set, @buf is in user address space, use copy_to_user(), - * otherwise @buf is in kernel address space, use memcpy(). - * - * Copy a page from "oldmem". For this page, there is no pte mapped - * in the current kernel. We stitch up a pte, similar to kmap_atomic. - */ -ssize_t copy_oldmem_page(unsigned long pfn, char *buf, - size_t csize, unsigned long offset, int userbuf) -{ - void *vaddr; - - if (!csize) - return 0; - - vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); - - if (userbuf) { - if (copy_to_user(buf, (vaddr + offset), csize)) { - iounmap(vaddr); - return -EFAULT; - } - } else - memcpy(buf, (vaddr + offset), csize); - - iounmap(vaddr); - return csize; -} diff --git a/trunk/arch/sh/kernel/early_printk.c b/trunk/arch/sh/kernel/early_printk.c index 9833493d8867..9048c0326d87 100644 --- a/trunk/arch/sh/kernel/early_printk.c +++ b/trunk/arch/sh/kernel/early_printk.c @@ -192,14 +192,20 @@ int __init setup_early_printk(char *buf) } #endif - if (likely(early_console)) { - if (keep_early) - early_console->flags &= ~CON_BOOT; - else - early_console->flags |= CON_BOOT; + if (likely(early_console)) register_console(early_console); - } return 0; } early_param("earlyprintk", setup_early_printk); + +void __init disable_early_printk(void) +{ + if (!early_console_initialized || !early_console) + return; + if (!keep_early) { + printk("disabling early console\n"); + unregister_console(early_console); + } else + printk("keeping early console\n"); +} diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c index 27b923c45b3d..9bdd8a00cd4a 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -45,7 +44,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); } - if (i < sh_mv.mv_nr_irqs) { + if (i < NR_IRQS) { spin_lock_irqsave(&irq_desc[i].lock, flags); action = irq_desc[i].action; if (!action) @@ -62,7 +61,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); unlock: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == sh_mv.mv_nr_irqs) + } else if (i == NR_IRQS) seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); return 0; diff --git a/trunk/arch/sh/kernel/kgdb_stub.c b/trunk/arch/sh/kernel/kgdb_stub.c index a5323364cbca..d8927d85492e 100644 --- a/trunk/arch/sh/kernel/kgdb_stub.c +++ b/trunk/arch/sh/kernel/kgdb_stub.c @@ -6,11 +6,11 @@ * David Grothe , Tigran Aivazian , * Amit S. Kale , William Gatliff , * Ben Lee, Steve Chamberlain and Benoit Miller . - * + * * This version by Henry Bell * Minor modifications by Jeremy Siegel - * - * Contains low-level support for remote debug using GDB. + * + * Contains low-level support for remote debug using GDB. * * To enable debugger support, two things need to happen. A call to * set_debug_traps() is necessary in order to allow any breakpoints @@ -48,7 +48,7 @@ * k kill (Detach GDB) * * d Toggle debug flag - * D Detach GDB + * D Detach GDB * * Hct Set thread t for operations, OK or ENN * c = 'c' (step, cont), c = 'g' (other @@ -58,7 +58,7 @@ * qfThreadInfo Get list of current threads (first) m * qsThreadInfo " " " " " (subsequent) * qOffsets Get section offsets Text=x;Data=y;Bss=z - * + * * TXX Find if thread XX is alive OK or ENN * ? What was the last sigval ? SNN (signal NN) * O Output to GDB console @@ -74,7 +74,7 @@ * '$' or '#'. If starts with two characters followed by * ':', then the existing stubs interpret this as a sequence number. * - * CSUM1 and CSUM2 are ascii hex representation of an 8-bit + * CSUM1 and CSUM2 are ascii hex representation of an 8-bit * checksum of , the most significant nibble is sent first. * the hex digits 0-9,a-f are used. * @@ -86,8 +86,8 @@ * Responses can be run-length encoded to save space. A '*' means that * the next character is an ASCII encoding giving a repeat count which * stands for that many repititions of the character preceding the '*'. - * The encoding is n+29, yielding a printable character where n >=3 - * (which is where RLE starts to win). Don't use an n > 126. + * The encoding is n+29, yielding a printable character where n >=3 + * (which is where RLE starts to win). Don't use an n > 126. * * So "0* " means the same as "0000". */ @@ -100,10 +100,12 @@ #include #include #include + +#ifdef CONFIG_SH_KGDB_CONSOLE #include -#include +#endif + #include -#include #include #include #include @@ -151,6 +153,7 @@ char kgdb_in_gdb_mode; char in_nmi; /* Set during NMI to prevent reentry */ int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */ +int kgdb_halt; /* Exposed for user access */ struct task_struct *kgdb_current; @@ -243,6 +246,14 @@ static char out_buffer[OUTBUFMAX]; static void kgdb_to_gdb(const char *s); +#ifdef CONFIG_KGDB_THREAD +static struct task_struct *trapped_thread; +static struct task_struct *current_thread; +typedef unsigned char threadref[8]; +#define BUF_THREAD_ID_SIZE 16 +#endif + + /* Convert ch to hex */ static int hex(const char ch) { @@ -317,7 +328,7 @@ static int hex_to_int(char **ptr, int *int_value) } /* Copy the binary array pointed to by buf into mem. Fix $, #, - and 0x7d escaped with 0x7d. Return a pointer to the character + and 0x7d escaped with 0x7d. Return a pointer to the character after the last byte written. */ static char *ebin_to_mem(const char *buf, char *mem, int count) { @@ -338,6 +349,66 @@ static char *pack_hex_byte(char *pkt, int byte) return pkt; } +#ifdef CONFIG_KGDB_THREAD + +/* Pack a thread ID */ +static char *pack_threadid(char *pkt, threadref * id) +{ + char *limit; + unsigned char *altid; + + altid = (unsigned char *) id; + + limit = pkt + BUF_THREAD_ID_SIZE; + while (pkt < limit) + pkt = pack_hex_byte(pkt, *altid++); + return pkt; +} + +/* Convert an integer into our threadref */ +static void int_to_threadref(threadref * id, const int value) +{ + unsigned char *scan = (unsigned char *) id; + int i = 4; + + while (i--) + *scan++ = 0; + + *scan++ = (value >> 24) & 0xff; + *scan++ = (value >> 16) & 0xff; + *scan++ = (value >> 8) & 0xff; + *scan++ = (value & 0xff); +} + +/* Return a task structure ptr for a particular pid */ +static struct task_struct *get_thread(int pid) +{ + struct task_struct *thread; + + /* Use PID_MAX w/gdb for pid 0 */ + if (pid == PID_MAX) pid = 0; + + /* First check via PID */ + thread = find_task_by_pid(pid); + + if (thread) + return thread; + + /* Start at the start */ + thread = init_tasks[0]; + + /* Walk along the linked list of tasks */ + do { + if (thread->pid == pid) + return thread; + thread = thread->next_task; + } while (thread != init_tasks[0]); + + return NULL; +} + +#endif /* CONFIG_KGDB_THREAD */ + /* Scan for the start char '$', read the packet and check the checksum */ static void get_packet(char *buffer, int buflen) { @@ -381,7 +452,7 @@ static void get_packet(char *buffer, int buflen) /* Ack successful transfer */ put_debug_char('+'); - /* If a sequence char is present, reply + /* If a sequence char is present, reply the sequence ID */ if (buffer[2] == ':') { put_debug_char(buffer[0]); @@ -540,6 +611,74 @@ static void gdb_regs_to_kgdb_regs(const int *gdb_regs, regs->vbr = gdb_regs[VBR]; } +#ifdef CONFIG_KGDB_THREAD +/* Make a local copy of registers from the specified thread */ +asmlinkage void ret_from_fork(void); +static void thread_regs_to_gdb_regs(const struct task_struct *thread, + int *gdb_regs) +{ + int regno; + int *tregs; + + /* Initialize to zero */ + for (regno = 0; regno < MAXREG; regno++) + gdb_regs[regno] = 0; + + /* Just making sure... */ + if (thread == NULL) + return; + + /* A new fork has pt_regs on the stack from a fork() call */ + if (thread->thread.pc == (unsigned long)ret_from_fork) { + + int vbr_val; + struct pt_regs *kregs; + kregs = (struct pt_regs*)thread->thread.sp; + + gdb_regs[R0] = kregs->regs[R0]; + gdb_regs[R1] = kregs->regs[R1]; + gdb_regs[R2] = kregs->regs[R2]; + gdb_regs[R3] = kregs->regs[R3]; + gdb_regs[R4] = kregs->regs[R4]; + gdb_regs[R5] = kregs->regs[R5]; + gdb_regs[R6] = kregs->regs[R6]; + gdb_regs[R7] = kregs->regs[R7]; + gdb_regs[R8] = kregs->regs[R8]; + gdb_regs[R9] = kregs->regs[R9]; + gdb_regs[R10] = kregs->regs[R10]; + gdb_regs[R11] = kregs->regs[R11]; + gdb_regs[R12] = kregs->regs[R12]; + gdb_regs[R13] = kregs->regs[R13]; + gdb_regs[R14] = kregs->regs[R14]; + gdb_regs[R15] = kregs->regs[R15]; + gdb_regs[PC] = kregs->pc; + gdb_regs[PR] = kregs->pr; + gdb_regs[GBR] = kregs->gbr; + gdb_regs[MACH] = kregs->mach; + gdb_regs[MACL] = kregs->macl; + gdb_regs[SR] = kregs->sr; + + asm("stc vbr, %0":"=r"(vbr_val)); + gdb_regs[VBR] = vbr_val; + return; + } + + /* Otherwise, we have only some registers from switch_to() */ + tregs = (int *)thread->thread.sp; + gdb_regs[R15] = (int)tregs; + gdb_regs[R14] = *tregs++; + gdb_regs[R13] = *tregs++; + gdb_regs[R12] = *tregs++; + gdb_regs[R11] = *tregs++; + gdb_regs[R10] = *tregs++; + gdb_regs[R9] = *tregs++; + gdb_regs[R8] = *tregs++; + gdb_regs[PR] = *tregs++; + gdb_regs[GBR] = *tregs++; + gdb_regs[PC] = thread->thread.pc; +} +#endif /* CONFIG_KGDB_THREAD */ + /* Calculate the new address for after a step */ static short *get_step_address(void) { @@ -620,7 +759,7 @@ static short *get_step_address(void) return (short *) addr; } -/* Set up a single-step. Replace the instruction immediately after the +/* Set up a single-step. Replace the instruction immediately after the current instruction (i.e. next in the expected flow of control) with a trap instruction, so that returning will cause only a single instruction to be executed. Note that this model is slightly broken for instructions @@ -658,11 +797,37 @@ static void undo_single_step(void) /* Send a signal message */ static void send_signal_msg(const int signum) { +#ifndef CONFIG_KGDB_THREAD out_buffer[0] = 'S'; out_buffer[1] = highhex(signum); out_buffer[2] = lowhex(signum); out_buffer[3] = 0; put_packet(out_buffer); +#else /* CONFIG_KGDB_THREAD */ + int threadid; + threadref thref; + char *out = out_buffer; + const char *tstring = "thread"; + + *out++ = 'T'; + *out++ = highhex(signum); + *out++ = lowhex(signum); + + while (*tstring) { + *out++ = *tstring++; + } + *out++ = ':'; + + threadid = trapped_thread->pid; + if (threadid == 0) threadid = PID_MAX; + int_to_threadref(&thref, threadid); + pack_threadid(out, &thref); + out += BUF_THREAD_ID_SIZE; + *out++ = ';'; + + *out = 0; + put_packet(out_buffer); +#endif /* CONFIG_KGDB_THREAD */ } /* Reply that all was well */ @@ -797,7 +962,15 @@ static void step_with_sig_msg(void) /* Send register contents */ static void send_regs_msg(void) { +#ifdef CONFIG_KGDB_THREAD + if (!current_thread) + kgdb_regs_to_gdb_regs(&trap_registers, registers); + else + thread_regs_to_gdb_regs(current_thread, registers); +#else kgdb_regs_to_gdb_regs(&trap_registers, registers); +#endif + mem_to_hex((char *) registers, out_buffer, NUMREGBYTES); put_packet(out_buffer); } @@ -805,13 +978,201 @@ static void send_regs_msg(void) /* Set register contents - currently can't set other thread's registers */ static void set_regs_msg(void) { - kgdb_regs_to_gdb_regs(&trap_registers, registers); - hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES); - gdb_regs_to_kgdb_regs(registers, &trap_registers); - send_ok_msg(); +#ifdef CONFIG_KGDB_THREAD + if (!current_thread) { +#endif + kgdb_regs_to_gdb_regs(&trap_registers, registers); + hex_to_mem(&in_buffer[1], (char *) registers, NUMREGBYTES); + gdb_regs_to_kgdb_regs(registers, &trap_registers); + send_ok_msg(); +#ifdef CONFIG_KGDB_THREAD + } else + send_err_msg(); +#endif } -#ifdef CONFIG_SH_KGDB_CONSOLE + +#ifdef CONFIG_KGDB_THREAD + +/* Set the status for a thread */ +void set_thread_msg(void) +{ + int threadid; + struct task_struct *thread = NULL; + char *ptr; + + switch (in_buffer[1]) { + + /* To select which thread for gG etc messages, i.e. supported */ + case 'g': + + ptr = &in_buffer[2]; + hex_to_int(&ptr, &threadid); + thread = get_thread(threadid); + + /* If we haven't found it */ + if (!thread) { + send_err_msg(); + break; + } + + /* Set current_thread (or not) */ + if (thread == trapped_thread) + current_thread = NULL; + else + current_thread = thread; + send_ok_msg(); + break; + + /* To select which thread for cCsS messages, i.e. unsupported */ + case 'c': + send_ok_msg(); + break; + + default: + send_empty_msg(); + break; + } +} + +/* Is a thread alive? */ +static void thread_status_msg(void) +{ + char *ptr; + int threadid; + struct task_struct *thread = NULL; + + ptr = &in_buffer[1]; + hex_to_int(&ptr, &threadid); + thread = get_thread(threadid); + if (thread) + send_ok_msg(); + else + send_err_msg(); +} +/* Send the current thread ID */ +static void thread_id_msg(void) +{ + int threadid; + threadref thref; + + out_buffer[0] = 'Q'; + out_buffer[1] = 'C'; + + if (current_thread) + threadid = current_thread->pid; + else if (trapped_thread) + threadid = trapped_thread->pid; + else /* Impossible, but just in case! */ + { + send_err_msg(); + return; + } + + /* Translate pid 0 to PID_MAX for gdb */ + if (threadid == 0) threadid = PID_MAX; + + int_to_threadref(&thref, threadid); + pack_threadid(out_buffer + 2, &thref); + out_buffer[2 + BUF_THREAD_ID_SIZE] = '\0'; + put_packet(out_buffer); +} + +/* Send thread info */ +static void thread_info_msg(void) +{ + struct task_struct *thread = NULL; + int threadid; + char *pos; + threadref thref; + + /* Start with 'm' */ + out_buffer[0] = 'm'; + pos = &out_buffer[1]; + + /* For all possible thread IDs - this will overrun if > 44 threads! */ + /* Start at 1 and include PID_MAX (since GDB won't use pid 0...) */ + for (threadid = 1; threadid <= PID_MAX; threadid++) { + + read_lock(&tasklist_lock); + thread = get_thread(threadid); + read_unlock(&tasklist_lock); + + /* If it's a valid thread */ + if (thread) { + int_to_threadref(&thref, threadid); + pack_threadid(pos, &thref); + pos += BUF_THREAD_ID_SIZE; + *pos++ = ','; + } + } + *--pos = 0; /* Lose final comma */ + put_packet(out_buffer); + +} + +/* Return printable info for gdb's 'info threads' command */ +static void thread_extra_info_msg(void) +{ + int threadid; + struct task_struct *thread = NULL; + char buffer[20], *ptr; + int i; + + /* Extract thread ID */ + ptr = &in_buffer[17]; + hex_to_int(&ptr, &threadid); + thread = get_thread(threadid); + + /* If we don't recognise it, say so */ + if (thread == NULL) + strcpy(buffer, "(unknown)"); + else + strcpy(buffer, thread->comm); + + /* Construct packet */ + for (i = 0, ptr = out_buffer; buffer[i]; i++) + ptr = pack_hex_byte(ptr, buffer[i]); + + if (thread->thread.pc == (unsigned long)ret_from_fork) { + strcpy(buffer, ""); + for (i = 0; buffer[i]; i++) + ptr = pack_hex_byte(ptr, buffer[i]); + } + + *ptr = '\0'; + put_packet(out_buffer); +} + +/* Handle all qFooBarBaz messages - have to use an if statement as + opposed to a switch because q messages can have > 1 char id. */ +static void query_msg(void) +{ + const char *q_start = &in_buffer[1]; + + /* qC = return current thread ID */ + if (strncmp(q_start, "C", 1) == 0) + thread_id_msg(); + + /* qfThreadInfo = query all threads (first) */ + else if (strncmp(q_start, "fThreadInfo", 11) == 0) + thread_info_msg(); + + /* qsThreadInfo = query all threads (subsequent). We know we have sent + them all after the qfThreadInfo message, so there are no to send */ + else if (strncmp(q_start, "sThreadInfo", 11) == 0) + put_packet("l"); /* el = last */ + + /* qThreadExtraInfo = supply printable information per thread */ + else if (strncmp(q_start, "ThreadExtraInfo", 15) == 0) + thread_extra_info_msg(); + + /* Unsupported - empty message as per spec */ + else + send_empty_msg(); +} +#endif /* CONFIG_KGDB_THREAD */ + /* * Bring up the ports.. */ @@ -824,9 +1185,6 @@ static int kgdb_serial_setup(void) return 0; } -#else -#define kgdb_serial_setup() 0 -#endif /* The command loop, read and act on requests */ static void kgdb_command_loop(const int excep_code, const int trapa_value) @@ -835,7 +1193,7 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) if (excep_code == NMI_VEC) { #ifndef CONFIG_KGDB_NMI - printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n"); + KGDB_PRINTK("Ignoring unexpected NMI?\n"); return; #else /* CONFIG_KGDB_NMI */ if (!kgdb_enabled) { @@ -849,10 +1207,19 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) if (!kgdb_enabled) return; +#ifdef CONFIG_KGDB_THREAD + /* Until GDB specifies a thread */ + current_thread = NULL; + trapped_thread = current; +#endif + /* Enter GDB mode (e.g. after detach) */ if (!kgdb_in_gdb_mode) { /* Do serial setup, notify user, issue preemptive ack */ - printk(KERN_NOTICE "KGDB: Waiting for GDB\n"); + kgdb_serial_setup(); + KGDB_PRINTK("Waiting for GDB (on %s%d at %d baud)\n", + (kgdb_porttype ? kgdb_porttype->name : ""), + kgdb_portnum, kgdb_baud); kgdb_in_gdb_mode = 1; put_debug_char('+'); } @@ -866,18 +1233,21 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) will later be replaced by its original one. Do NOT do this for trap 0xff, since that indicates a compiled-in breakpoint which will not be replaced (and we would retake the trap forever) */ - if ((excep_code == TRAP_VEC) && (trapa_value != (0x3c << 2))) + if ((excep_code == TRAP_VEC) && (trapa_value != (0xff << 2))) { trap_registers.pc -= 2; + } /* Undo any stepping we may have done */ undo_single_step(); while (1) { + out_buffer[0] = 0; get_packet(in_buffer, BUFMAX); /* Examine first char of buffer to see what we need to do */ switch (in_buffer[0]) { + case '?': /* Send which signal we've received */ send_signal_msg(sigval); break; @@ -921,6 +1291,21 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) step_msg(); return; +#ifdef CONFIG_KGDB_THREAD + + case 'H': /* Task related */ + set_thread_msg(); + break; + + case 'T': /* Query thread status */ + thread_status_msg(); + break; + + case 'q': /* Handle query - currently thread-related */ + query_msg(); + break; +#endif + case 'k': /* 'Kill the program' with a kernel ? */ break; @@ -938,8 +1323,11 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) } /* There has been an exception, most likely a breakpoint. */ -static void handle_exception(struct pt_regs *regs) +asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int excep_code, vbr_val; int count; int trapa_value = ctrl_inl(TRA); @@ -967,7 +1355,7 @@ static void handle_exception(struct pt_regs *regs) kgdb_trapa_val = trapa_value; /* Act on the exception */ - kgdb_command_loop(excep_code, trapa_value); + kgdb_command_loop(excep_code >> 5, trapa_value); kgdb_current = NULL; @@ -985,12 +1373,14 @@ static void handle_exception(struct pt_regs *regs) asm("ldc %0, vbr": :"r"(vbr_val)); } -asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +/* Trigger a breakpoint by function */ +void breakpoint(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); - handle_exception(regs); + if (!kgdb_enabled) { + kgdb_enabled = 1; + kgdb_init(); + } + BREAKPOINT(); } /* Initialise the KGDB data structures and serial configuration */ @@ -1005,16 +1395,24 @@ int kgdb_init(void) kgdb_in_gdb_mode = 0; if (kgdb_serial_setup() != 0) { - printk(KERN_NOTICE "KGDB: serial setup error\n"); + KGDB_PRINTK("serial setup error\n"); return -1; } /* Init ptr to exception handler */ - kgdb_debug_hook = handle_exception; + kgdb_debug_hook = kgdb_handle_exception; kgdb_bus_err_hook = kgdb_handle_bus_error; /* Enter kgdb now if requested, or just report init done */ - printk(KERN_NOTICE "KGDB: stub is initialized.\n"); + if (kgdb_halt) { + kgdb_in_gdb_mode = 1; + put_debug_char('+'); + breakpoint(); + } + else + { + KGDB_PRINTK("stub is initialized.\n"); + } return 0; } @@ -1039,7 +1437,7 @@ static void kgdb_msg_write(const char *s, unsigned count) /* Calculate how many this time */ wcount = (count > MAXOUT) ? MAXOUT : count; - + /* Pack in hex chars */ for (i = 0; i < wcount; i++) bufptr = pack_hex_byte(bufptr, s[i]); @@ -1069,25 +1467,3 @@ void kgdb_console_write(struct console *co, const char *s, unsigned count) kgdb_msg_write(s, count); } #endif - -#ifdef CONFIG_KGDB_SYSRQ -static void sysrq_handle_gdb(int key, struct tty_struct *tty) -{ - printk("Entering GDB stub\n"); - breakpoint(); -} - -static struct sysrq_key_op sysrq_gdb_op = { - .handler = sysrq_handle_gdb, - .help_msg = "Gdb", - .action_msg = "GDB", -}; - -static int gdb_register_sysrq(void) -{ - printk("Registering GDB sysrq handler\n"); - register_sysrq_key('g', &sysrq_gdb_op); - return 0; -} -module_init(gdb_register_sysrq); -#endif diff --git a/trunk/arch/sh/kernel/machine_kexec.c b/trunk/arch/sh/kernel/machine_kexec.c index 790ed69b8666..08587cdb64d6 100644 --- a/trunk/arch/sh/kernel/machine_kexec.c +++ b/trunk/arch/sh/kernel/machine_kexec.c @@ -59,13 +59,13 @@ static void kexec_info(struct kimage *image) printk(" segment[%d]: 0x%08x - 0x%08x (0x%08x)\n", i, (unsigned int)image->segment[i].mem, - (unsigned int)image->segment[i].mem + - image->segment[i].memsz, + (unsigned int)image->segment[i].mem + image->segment[i].memsz, (unsigned int)image->segment[i].memsz); - } + } printk(" start : 0x%08x\n\n", (unsigned int)image->start); } + /* * Do not allocate memory (or fail in any way) in machine_kexec(). * We are past the point of no return, committed to rebooting now. @@ -101,27 +101,6 @@ NORET_TYPE void machine_kexec(struct kimage *image) /* now call it */ rnk = (relocate_new_kernel_t) reboot_code_buffer; - (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); + (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); } -/* crashkernel=size@addr specifies the location to reserve for - * a crash kernel. By reserving this memory we guarantee - * that linux never sets it up as a DMA target. - * Useful for holding code to do something appropriate - * after a kernel panic. - */ -static int __init parse_crashkernel(char *arg) -{ - unsigned long size, base; - size = memparse(arg, &arg); - if (*arg == '@') { - base = memparse(arg+1, &arg); - /* FIXME: Do I want a sanity check - * to validate the memory range? - */ - crashk_res.start = base; - crashk_res.end = base + size - 1; - } - return 0; -} -early_param("crashkernel", parse_crashkernel); diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c index 329b3f3051de..e7607366ac4e 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -7,7 +7,7 @@ * * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002 - 2006 Paul Mundt */ #include #include @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -300,8 +299,7 @@ static void ubc_set_tracing(int asid, unsigned long pc) ctrl_outl(0, UBC_BAMRA); if (current_cpu_data.type == CPU_SH7729 || - current_cpu_data.type == CPU_SH7710 || - current_cpu_data.type == CPU_SH7712) { + current_cpu_data.type == CPU_SH7710) { ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); } else { @@ -497,10 +495,6 @@ asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, /* Rewind */ regs->pc -= 2; - if (notify_die(DIE_TRAP, regs, regs->tra & 0xff, - SIGTRAP) == NOTIFY_STOP) - return; - force_sig(SIGTRAP, current); } @@ -516,10 +510,6 @@ asmlinkage void bug_trap_handler(unsigned long r4, unsigned long r5, /* Rewind */ regs->pc -= 2; - if (notify_die(DIE_TRAP, regs, TRAPA_BUG_OPCODE & 0xff, - SIGTRAP) == NOTIFY_STOP) - return; - #ifdef CONFIG_BUG if (__kernel_text_address(instruction_pointer(regs))) { u16 insn = *(u16 *)instruction_pointer(regs); diff --git a/trunk/arch/sh/kernel/ptrace.c b/trunk/arch/sh/kernel/ptrace.c index 3fb5fc0b550d..855f7246cfff 100644 --- a/trunk/arch/sh/kernel/ptrace.c +++ b/trunk/arch/sh/kernel/ptrace.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 477d2a854fc4..98802ab28211 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -4,7 +4,7 @@ * This file handles the architecture-dependent parts of initialization * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002 - 2006 Paul Mundt */ #include #include @@ -15,22 +15,21 @@ #include #include #include -#include #include #include #include -#include -#include #include #include #include #include #include #include -#include +#ifdef CONFIG_SH_KGDB +#include +static int kgdb_parse_options(char *options); +#endif extern void * __rd_start, * __rd_end; - /* * Machine setup.. */ @@ -206,33 +205,53 @@ static int __init sh_mv_setup(char **cmdline_p) return 0; } -/* - * Register fully available low RAM pages with the bootmem allocator. - */ -static void __init register_bootmem_low_pages(void) +void __init setup_arch(char **cmdline_p) { - unsigned long curr_pfn, last_pfn, pages; + unsigned long bootmap_size; + unsigned long start_pfn, max_pfn, max_low_pfn; + +#ifdef CONFIG_CMDLINE_BOOL + strcpy(COMMAND_LINE, CONFIG_CMDLINE); +#endif + + ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); + +#ifdef CONFIG_BLK_DEV_RAM + rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; + rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); + rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); +#endif + + if (!MOUNT_ROOT_RDONLY) + root_mountflags &= ~MS_RDONLY; + init_mm.start_code = (unsigned long) _text; + init_mm.end_code = (unsigned long) _etext; + init_mm.end_data = (unsigned long) _edata; + init_mm.brk = (unsigned long) _end; + + code_resource.start = (unsigned long)virt_to_phys(_text); + code_resource.end = (unsigned long)virt_to_phys(_etext)-1; + data_resource.start = (unsigned long)virt_to_phys(_etext); + data_resource.end = (unsigned long)virt_to_phys(_edata)-1; + + sh_mv_setup(cmdline_p); + /* - * We are rounding up the start address of usable memory: + * Find the highest page frame number we have available */ - curr_pfn = PFN_UP(__MEMORY_START); + max_pfn = PFN_DOWN(__pa(memory_end)); /* - * ... and at the end of the usable range downwards: + * Determine low and high memory ranges: */ - last_pfn = PFN_DOWN(__pa(memory_end)); - - if (last_pfn > max_low_pfn) - last_pfn = max_low_pfn; - - pages = last_pfn - curr_pfn; - free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages)); -} + max_low_pfn = max_pfn; -void __init setup_bootmem_allocator(unsigned long start_pfn) -{ - unsigned long bootmap_size; + /* + * Partially used pages are not usable - thus + * we are rounding upwards: + */ + start_pfn = PFN_UP(__pa(_end)); /* * Find a proper area for the bootmem bitmap. After this @@ -240,11 +259,31 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) * is intact) must be done via bootmem_alloc(). */ bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, - min_low_pfn, max_low_pfn); + __MEMORY_START>>PAGE_SHIFT, + max_low_pfn); + /* + * Register fully available low RAM pages with the bootmem allocator. + */ + { + unsigned long curr_pfn, last_pfn, pages; + + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(__MEMORY_START); + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(__pa(memory_end)); - register_bootmem_low_pages(); + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + + pages = last_pfn - curr_pfn; + free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn), + PFN_PHYS(pages)); + } - node_set_online(0); /* * Reserve the kernel text and @@ -253,14 +292,14 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) * case of us accidentally initializing the bootmem allocator with * an invalid RAM area. */ - reserve_bootmem(__MEMORY_START+PAGE_SIZE, + reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE, (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START); /* * reserve physical page 0 - it's a special BIOS page on many boxes, * enabling clean reboots, SMP operation, laptop functions. */ - reserve_bootmem(__MEMORY_START, PAGE_SIZE); + reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE); #ifdef CONFIG_BLK_DEV_INITRD ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); @@ -274,8 +313,8 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { - reserve_bootmem(INITRD_START + __MEMORY_START, - INITRD_SIZE); + reserve_bootmem_node(NODE_DATA(0), INITRD_START + + __MEMORY_START, INITRD_SIZE); initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START; initrd_end = initrd_start + INITRD_SIZE; @@ -288,76 +327,6 @@ void __init setup_bootmem_allocator(unsigned long start_pfn) } } #endif -#ifdef CONFIG_KEXEC - if (crashk_res.start != crashk_res.end) - reserve_bootmem(crashk_res.start, - crashk_res.end - crashk_res.start + 1); -#endif -} - -#ifndef CONFIG_NEED_MULTIPLE_NODES -static void __init setup_memory(void) -{ - unsigned long start_pfn; - - /* - * Partially used pages are not usable - thus - * we are rounding upwards: - */ - start_pfn = PFN_UP(__pa(_end)); - setup_bootmem_allocator(start_pfn); -} -#else -extern void __init setup_memory(void); -#endif - -void __init setup_arch(char **cmdline_p) -{ - enable_mmu(); - -#ifdef CONFIG_CMDLINE_BOOL - strcpy(COMMAND_LINE, CONFIG_CMDLINE); -#endif - - ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); - -#ifdef CONFIG_BLK_DEV_RAM - rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; - rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); - rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); -#endif - - if (!MOUNT_ROOT_RDONLY) - root_mountflags &= ~MS_RDONLY; - init_mm.start_code = (unsigned long) _text; - init_mm.end_code = (unsigned long) _etext; - init_mm.end_data = (unsigned long) _edata; - init_mm.brk = (unsigned long) _end; - - code_resource.start = virt_to_phys(_text); - code_resource.end = virt_to_phys(_etext)-1; - data_resource.start = virt_to_phys(_etext); - data_resource.end = virt_to_phys(_edata)-1; - - parse_early_param(); - - sh_mv_setup(cmdline_p); - - /* - * Find the highest page frame number we have available - */ - max_pfn = PFN_DOWN(__pa(memory_end)); - - /* - * Determine low and high memory ranges: - */ - max_low_pfn = max_pfn; - min_low_pfn = __MEMORY_START >> PAGE_SHIFT; - - nodes_clear(node_online_map); - setup_memory(); - paging_init(); - sparse_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; @@ -366,6 +335,8 @@ void __init setup_arch(char **cmdline_p) /* Perform the machine specific initialisation */ if (likely(sh_mv.mv_setup)) sh_mv.mv_setup(cmdline_p); + + paging_init(); } struct sh_machine_vector* __init get_mv_byname(const char* name) @@ -409,7 +380,6 @@ static const char *cpu_name[] = { [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", - [CPU_SH7712] = "SH7712", [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R", @@ -507,7 +477,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) c->loops_per_jiffy/(500000/HZ), (c->loops_per_jiffy/(5000/HZ)) % 100); - return 0; + return show_clocks(m); } static void *c_start(struct seq_file *m, loff_t *pos) @@ -529,3 +499,92 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo, }; #endif /* CONFIG_PROC_FS */ + +#ifdef CONFIG_SH_KGDB +/* + * Parse command-line kgdb options. By default KGDB is enabled, + * entered on error (or other action) using default serial info. + * The command-line option can include a serial port specification + * and an action to override default or configured behavior. + */ +struct kgdb_sermap kgdb_sci_sermap = +{ "ttySC", 5, kgdb_sci_setup, NULL }; + +struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap; +struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap; + +void kgdb_register_sermap(struct kgdb_sermap *map) +{ + struct kgdb_sermap *last; + + for (last = kgdb_serlist; last->next; last = last->next) + ; + last->next = map; + if (!map->namelen) { + map->namelen = strlen(map->name); + } +} + +static int __init kgdb_parse_options(char *options) +{ + char c; + int baud; + + /* Check for port spec (or use default) */ + + /* Determine port type and instance */ + if (!memcmp(options, "tty", 3)) { + struct kgdb_sermap *map = kgdb_serlist; + + while (map && memcmp(options, map->name, map->namelen)) + map = map->next; + + if (!map) { + KGDB_PRINTK("unknown port spec in %s\n", options); + return -1; + } + + kgdb_porttype = map; + kgdb_serial_setup = map->setup_fn; + kgdb_portnum = options[map->namelen] - '0'; + options += map->namelen + 1; + + options = (*options == ',') ? options+1 : options; + + /* Read optional parameters (baud/parity/bits) */ + baud = simple_strtoul(options, &options, 10); + if (baud != 0) { + kgdb_baud = baud; + + c = toupper(*options); + if (c == 'E' || c == 'O' || c == 'N') { + kgdb_parity = c; + options++; + } + + c = *options; + if (c == '7' || c == '8') { + kgdb_bits = c; + options++; + } + options = (*options == ',') ? options+1 : options; + } + } + + /* Check for action specification */ + if (!memcmp(options, "halt", 4)) { + kgdb_halt = 1; + options += 4; + } else if (!memcmp(options, "disabled", 8)) { + kgdb_enabled = 0; + options += 8; + } + + if (*options) { + KGDB_PRINTK("ignored unknown options: %s\n", options); + return 0; + } + return 1; +} +__setup("kgdb=", kgdb_parse_options); +#endif /* CONFIG_SH_KGDB */ diff --git a/trunk/arch/sh/kernel/sh_ksyms.c b/trunk/arch/sh/kernel/sh_ksyms.c index fa91641c1f62..6e0d10fac4a8 100644 --- a/trunk/arch/sh/kernel/sh_ksyms.c +++ b/trunk/arch/sh/kernel/sh_ksyms.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,7 @@ EXPORT_SYMBOL(__div64_32); /* These symbols are generated by the compiler itself */ DECLARE_EXPORT(__udivsi3); +DECLARE_EXPORT(__udivdi3); DECLARE_EXPORT(__sdivsi3); DECLARE_EXPORT(__ashrdi3); DECLARE_EXPORT(__ashldi3); diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c index eb0191c374b6..9f39ef1f73da 100644 --- a/trunk/arch/sh/kernel/signal.c +++ b/trunk/arch/sh/kernel/signal.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh/kernel/stacktrace.c b/trunk/arch/sh/kernel/stacktrace.c index 4bdd2f83535d..0d5268afe80f 100644 --- a/trunk/arch/sh/kernel/stacktrace.c +++ b/trunk/arch/sh/kernel/stacktrace.c @@ -19,7 +19,14 @@ */ void save_stack_trace(struct stack_trace *trace, struct task_struct *task) { - unsigned long *sp = (unsigned long *)current_stack_pointer; + unsigned long *sp; + + if (!task) + task = current; + if (task == current) + sp = (unsigned long *)current_stack_pointer; + else + sp = (unsigned long *)task->thread.sp; while (!kstack_end(sp)) { unsigned long addr = *sp++; diff --git a/trunk/arch/sh/kernel/sys_sh.c b/trunk/arch/sh/kernel/sys_sh.c index 76b1bc7f7029..e18f183e1035 100644 --- a/trunk/arch/sh/kernel/sys_sh.c +++ b/trunk/arch/sh/kernel/sys_sh.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh/kernel/timers/timer-cmt.c b/trunk/arch/sh/kernel/timers/timer-cmt.c index 82de6895ade5..a574b93a4e7b 100644 --- a/trunk/arch/sh/kernel/timers/timer-cmt.c +++ b/trunk/arch/sh/kernel/timers/timer-cmt.c @@ -115,7 +115,7 @@ static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id) static struct irqaction cmt_irq = { .name = "timer", .handler = cmt_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; diff --git a/trunk/arch/sh/kernel/timers/timer-mtu2.c b/trunk/arch/sh/kernel/timers/timer-mtu2.c index b7499a2a9188..fffcd1c09873 100644 --- a/trunk/arch/sh/kernel/timers/timer-mtu2.c +++ b/trunk/arch/sh/kernel/timers/timer-mtu2.c @@ -110,7 +110,7 @@ static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id) static struct irqaction mtu2_irq = { .name = "timer", .handler = mtu2_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; diff --git a/trunk/arch/sh/kernel/timers/timer-tmu.c b/trunk/arch/sh/kernel/timers/timer-tmu.c index d9e3151c891e..e060e71d0785 100644 --- a/trunk/arch/sh/kernel/timers/timer-tmu.c +++ b/trunk/arch/sh/kernel/timers/timer-tmu.c @@ -99,7 +99,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) static struct irqaction tmu_irq = { .name = "timer", .handler = tmu_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; @@ -148,9 +148,7 @@ static int tmu_timer_init(void) /* Start TMU0 */ tmu_timer_stop(); -#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && \ - !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ - !defined(CONFIG_CPU_SUBTYPE_SH7785) +#if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); #endif diff --git a/trunk/arch/sh/kernel/traps.c b/trunk/arch/sh/kernel/traps.c index 7b40f0ff3dfc..e9f168f60f95 100644 --- a/trunk/arch/sh/kernel/traps.c +++ b/trunk/arch/sh/kernel/traps.c @@ -5,7 +5,7 @@ * SuperH version: Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Howells - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002 - 2006 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -18,12 +18,10 @@ #include #include #include -#include #include #include #include #include -#include #ifdef CONFIG_SH_KGDB #include @@ -76,21 +74,7 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top) } } -ATOMIC_NOTIFIER_HEAD(shdie_chain); - -int register_die_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(&shdie_chain, nb); -} -EXPORT_SYMBOL(register_die_notifier); - -int unregister_die_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&shdie_chain, nb); -} -EXPORT_SYMBOL(unregister_die_notifier); - -static DEFINE_SPINLOCK(die_lock); +DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) { @@ -146,6 +130,40 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err) return -EFAULT; } +#ifdef CONFIG_BUG +#ifdef CONFIG_DEBUG_BUGVERBOSE +static inline void do_bug_verbose(struct pt_regs *regs) +{ + struct bug_frame f; + long len; + + if (__copy_from_user(&f, (const void __user *)regs->pc, + sizeof(struct bug_frame))) + return; + + len = __strnlen_user(f.file, PATH_MAX) - 1; + if (unlikely(len < 0 || len >= PATH_MAX)) + f.file = ""; + len = __strnlen_user(f.func, PATH_MAX) - 1; + if (unlikely(len < 0 || len >= PATH_MAX)) + f.func = ""; + + printk(KERN_ALERT "kernel BUG in %s() at %s:%d!\n", + f.func, f.file, f.line); +} +#else +static inline void do_bug_verbose(struct pt_regs *regs) +{ +} +#endif /* CONFIG_DEBUG_BUGVERBOSE */ + +void handle_BUG(struct pt_regs *regs) +{ + do_bug_verbose(regs); + die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); +} +#endif /* CONFIG_BUG */ + /* * handle an instruction that does an unaligned memory access by emulating the * desired behaviour @@ -870,25 +888,6 @@ void __init trap_init(void) per_cpu_trap_init(); } -#ifdef CONFIG_BUG -void handle_BUG(struct pt_regs *regs) -{ - enum bug_trap_type tt; - tt = report_bug(regs->pc); - if (tt == BUG_TRAP_TYPE_WARN) { - regs->pc += 2; - return; - } - - die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); -} - -int is_valid_bugaddr(unsigned long addr) -{ - return addr >= PAGE_OFFSET; -} -#endif - void show_trace(struct task_struct *tsk, unsigned long *sp, struct pt_regs *regs) { diff --git a/trunk/arch/sh/kernel/vmlinux.lds.S b/trunk/arch/sh/kernel/vmlinux.lds.S index d83143cc5ca9..78a6c09875b2 100644 --- a/trunk/arch/sh/kernel/vmlinux.lds.S +++ b/trunk/arch/sh/kernel/vmlinux.lds.S @@ -34,11 +34,9 @@ SECTIONS __ex_table : { *(__ex_table) } __stop___ex_table = .; - _etext = .; /* End of text section */ - RODATA - BUG_TABLE + _etext = .; /* End of text section */ .data : { /* Data */ *(.data) @@ -55,12 +53,8 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.page_aligned : { *(.data.page_aligned) } - __nosave_begin = .; - .data_nosave : { *(.data.nosave) } - . = ALIGN(PAGE_SIZE); - __nosave_end = .; - . = ALIGN(PAGE_SIZE); + . = ALIGN(L1_CACHE_BYTES); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; @@ -116,10 +110,43 @@ SECTIONS * it's a module. */ /DISCARD/ : { + *(.exit.text) + *(.exit.data) *(.exitcall.exit) } - STABS_DEBUG - - DWARF_DEBUG + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging section are relative to the beginning + of the section so we begin .debug at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ } diff --git a/trunk/arch/sh/lib/Makefile b/trunk/arch/sh/lib/Makefile index e23dd1a3fccd..0b9cca5c7cb4 100644 --- a/trunk/arch/sh/lib/Makefile +++ b/trunk/arch/sh/lib/Makefile @@ -3,9 +3,11 @@ # lib-y = delay.o memset.o memmove.o memchr.o \ - checksum.o strlen.o div64.o div64-generic.o + checksum.o strlen.o div64.o udivdi3.o \ + div64-generic.o memcpy-y := memcpy.o memcpy-$(CONFIG_CPU_SH4) := memcpy-sh4.o lib-y += $(memcpy-y) + diff --git a/trunk/arch/sh/lib/udivdi3.c b/trunk/arch/sh/lib/udivdi3.c new file mode 100644 index 000000000000..68f038bf3c50 --- /dev/null +++ b/trunk/arch/sh/lib/udivdi3.c @@ -0,0 +1,16 @@ +/* + * Simple __udivdi3 function which doesn't use FPU. + */ + +#include + +extern u64 __xdiv64_32(u64 n, u32 d); +extern void panic(const char * fmt, ...); + +u64 __udivdi3(u64 n, u64 d) +{ + if (d & ~0xffffffff) + panic("Need true 64-bit/64-bit division"); + return __xdiv64_32(n, (u32)d); +} + diff --git a/trunk/arch/sh/mm/Kconfig b/trunk/arch/sh/mm/Kconfig index 12f3d394dc28..6b0d28ac9241 100644 --- a/trunk/arch/sh/mm/Kconfig +++ b/trunk/arch/sh/mm/Kconfig @@ -67,7 +67,6 @@ config CPU_SUBTYPE_SH7300 config CPU_SUBTYPE_SH7705 bool "Support SH7705 processor" select CPU_SH3 - select CPU_HAS_IPR_IRQ select CPU_HAS_PINT_IRQ config CPU_SUBTYPE_SH7706 @@ -102,17 +101,9 @@ config CPU_SUBTYPE_SH7709 config CPU_SUBTYPE_SH7710 bool "Support SH7710 processor" select CPU_SH3 - select CPU_HAS_IPR_IRQ help Select SH7710 if you have a SH3-DSP SH7710 CPU. -config CPU_SUBTYPE_SH7712 - bool "Support SH7712 processor" - select CPU_SH3 - select CPU_HAS_IPR_IRQ - help - Select SH7712 if you have a SH3-DSP SH7712 CPU. - comment "SH-4 Processor Support" config CPU_SUBTYPE_SH7750 @@ -292,17 +283,6 @@ config VSYSCALL For systems with an MMU that can afford to give up a page, (the default value) say Y. -config NODES_SHIFT - int - default "1" - depends on NEED_MULTIPLE_NODES - -config ARCH_FLATMEM_ENABLE - def_bool y - -config ARCH_POPULATES_NODE_MAP - def_bool y - choice prompt "Kernel page size" default PAGE_SIZE_4KB diff --git a/trunk/arch/sh/mm/fault-nommu.c b/trunk/arch/sh/mm/fault-nommu.c index 923cb456819b..34d4e0c68fbb 100644 --- a/trunk/arch/sh/mm/fault-nommu.c +++ b/trunk/arch/sh/mm/fault-nommu.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sh/mm/fault.c b/trunk/arch/sh/mm/fault.c index 0ecc117cade4..fa5d7f0b9f18 100644 --- a/trunk/arch/sh/mm/fault.c +++ b/trunk/arch/sh/mm/fault.c @@ -2,7 +2,7 @@ * Page fault handler for SH with an MMU. * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2003 - 2007 Paul Mundt + * Copyright (C) 2003 Paul Mundt * * Based on linux/arch/i386/mm/fault.c: * Copyright (C) 1995 Linus Torvalds @@ -15,42 +15,12 @@ #include #include #include -#include #include #include #include #include -#ifdef CONFIG_KPROBES -ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - -/* Hook to register for page fault notifications */ -int register_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); -} - -int unregister_page_fault_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); -} - -static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, - int trap, int sig) -{ - struct die_args args = { - .regs = regs, - .trapnr = trap, - }; - return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); -} -#else -static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, - int trap, int sig) -{ - return NOTIFY_DONE; -} -#endif +extern void die(const char *,struct pt_regs *,long); /* * This routine handles page faults. It determines the address, @@ -69,11 +39,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, siginfo_t info; trace_hardirqs_on(); - - if (notify_page_fault(DIE_PAGE_FAULT, regs, - writeaccess, SIGSEGV) == NOTIFY_STOP) - return; - local_irq_enable(); #ifdef CONFIG_SH_KGDB diff --git a/trunk/arch/sh/mm/hugetlbpage.c b/trunk/arch/sh/mm/hugetlbpage.c index ae8c321d6e2a..cf2c2ee35a37 100644 --- a/trunk/arch/sh/mm/hugetlbpage.c +++ b/trunk/arch/sh/mm/hugetlbpage.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index 4d030988b368..ae957a932375 100644 --- a/trunk/arch/sh/mm/init.c +++ b/trunk/arch/sh/mm/init.c @@ -1,20 +1,37 @@ -/* - * linux/arch/sh/mm/init.c +/* $Id: init.c,v 1.19 2004/02/21 04:42:16 kkojima Exp $ + * + * linux/arch/sh/mm/init.c * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2002, 2004 Paul Mundt * * Based on linux/arch/i386/mm/init.c: * Copyright (C) 1995 Linus Torvalds */ + +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include #include +#include #include +#include #include -#include -#include +#include +#include +#include +#include +#include #include +#include #include #include #include @@ -22,51 +39,37 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD]; +#ifdef CONFIG_MMU +/* It'd be good if these lines were in the standard header file. */ +#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT) +#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn) +#endif + void (*copy_page)(void *from, void *to); void (*clear_page)(void *to); void show_mem(void) { - int total = 0, reserved = 0, free = 0; - int shared = 0, cached = 0, slab = 0; - pg_data_t *pgdat; + int i, total = 0, reserved = 0; + int shared = 0, cached = 0; printk("Mem-info:\n"); show_free_areas(); - - for_each_online_pgdat(pgdat) { - struct page *page, *end; - unsigned long flags; - - pgdat_resize_lock(pgdat, &flags); - page = pgdat->node_mem_map; - end = page + pgdat->node_spanned_pages; - - do { - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (PageSlab(page)) - slab++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - page++; - } while (page < end); - - pgdat_resize_unlock(pgdat, &flags); - } - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); - printk("%d pages of RAM\n", total); - printk("%d free pages\n", free); - printk("%d reserved pages\n", reserved); - printk("%d slab pages\n", slab); - printk("%d pages shared\n", shared); - printk("%d pages swap cached\n", cached); + i = max_mapnr; + while (i-- > 0) { + total++; + if (PageReserved(mem_map+i)) + reserved++; + else if (PageSwapCache(mem_map+i)) + cached++; + else if (page_count(mem_map+i)) + shared += page_count(mem_map+i) - 1; + } + printk("%d pages of RAM\n",total); + printk("%d reserved pages\n",reserved); + printk("%d pages shared\n",shared); + printk("%d pages swap cached\n",cached); } #ifdef CONFIG_MMU @@ -144,38 +147,52 @@ extern char __init_begin, __init_end; */ void __init paging_init(void) { - int nid; + unsigned long zones_size[MAX_NR_ZONES] = { 0, }; - /* We don't need to map the kernel through the TLB, as - * it is permanatly mapped using P1. So clear the - * entire pgd. */ - memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir)); + /* + * Setup some defaults for the zone sizes.. these should be safe + * regardless of distcontiguous memory or MMU settings. + */ + zones_size[ZONE_NORMAL] = __MEMORY_SIZE >> PAGE_SHIFT; +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_HIGHMEM] = 0 >> PAGE_SHIFT; +#endif + +#ifdef CONFIG_MMU + /* + * If we have an MMU, and want to be using it .. we need to adjust + * the zone sizes accordingly, in addition to turning it on. + */ + { + /* We don't need to map the kernel through the TLB, as + * it is permanatly mapped using P1. So clear the + * entire pgd. */ + memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir)); + + /* Turn on the MMU */ + enable_mmu(); + zones_size[ZONE_NORMAL] = MAX_LOW_PFN - START_PFN; + } /* Set an initial value for the MMU.TTB so we don't have to * check for a null value. */ set_TTB(swapper_pg_dir); - for_each_online_node(nid) { - pg_data_t *pgdat = NODE_DATA(nid); - unsigned long max_zone_pfns[MAX_NR_ZONES]; - unsigned long low, start_pfn; - - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - - start_pfn = pgdat->bdata->node_boot_start >> PAGE_SHIFT; - low = pgdat->bdata->node_low_pfn; - - max_zone_pfns[ZONE_NORMAL] = low; - add_active_range(nid, start_pfn, low); - - printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n", - nid, start_pfn, low); - - free_area_init_nodes(max_zone_pfns); - - printk("Node %u: mem_map starts at %p\n", - pgdat->node_id, pgdat->node_mem_map); - } +#elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4) + /* + * If we don't have CONFIG_MMU set and the processor in question + * still has an MMU, care needs to be taken to make sure it doesn't + * stay on.. Since the boot loader could have potentially already + * turned it on, and we clearly don't want it, we simply turn it off. + * + * We don't need to do anything special for the zone sizes, since the + * default values that were already configured up above should be + * satisfactory. + */ + disable_mmu(); +#endif + NODE_DATA(0)->node_mem_map = NULL; + free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0); } static struct kcore_list kcore_mem, kcore_vmalloc; @@ -183,33 +200,18 @@ static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void) { int codesize, reservedpages, datasize, initsize; - int nid; - - reservedpages = 0; + int tmp; + extern unsigned long memory_start; - for_each_online_node(nid) { - pg_data_t *pgdat = NODE_DATA(nid); - unsigned long node_pages = 0; - void *node_high_memory; - int i; - - num_physpages += pgdat->node_present_pages; - - if (pgdat->node_spanned_pages) - node_pages = free_all_bootmem_node(pgdat); - - totalram_pages += node_pages; +#ifdef CONFIG_MMU + high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE); +#else + extern unsigned long memory_end; - for (i = 0; i < node_pages; i++) - if (PageReserved(pgdat->node_mem_map + i)) - reservedpages++; + high_memory = (void *)(memory_end & PAGE_MASK); +#endif - node_high_memory = (void *)((pgdat->node_start_pfn + - pgdat->node_spanned_pages) << - PAGE_SHIFT); - if (node_high_memory > high_memory) - high_memory = node_high_memory; - } + max_mapnr = num_physpages = MAP_NR(high_memory) - MAP_NR(memory_start); /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); @@ -227,6 +229,16 @@ void __init mem_init(void) clear_page = clear_page_nommu; #endif + /* this will put all low memory onto the freelists */ + totalram_pages += free_all_bootmem_node(NODE_DATA(0)); + reservedpages = 0; + for (tmp = 0; tmp < num_physpages; tmp++) + /* + * Only count reserved RAM pages + */ + if (PageReserved(mem_map+tmp)) + reservedpages++; + codesize = (unsigned long) &_etext - (unsigned long) &_text; datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; @@ -238,7 +250,7 @@ void __init mem_init(void) printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " "%dk reserved, %dk data, %dk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), - totalram_pages << (PAGE_SHIFT-10), + max_mapnr << (PAGE_SHIFT-10), codesize >> 10, reservedpages << (PAGE_SHIFT-10), datasize >> 10, @@ -277,3 +289,4 @@ void free_initrd_mem(unsigned long start, unsigned long end) printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif + diff --git a/trunk/arch/sh/mm/pmb.c b/trunk/arch/sh/mm/pmb.c index 02aae06527dc..d0d45e2e0ab3 100644 --- a/trunk/arch/sh/mm/pmb.c +++ b/trunk/arch/sh/mm/pmb.c @@ -311,9 +311,9 @@ static int __init pmb_init(void) BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES)); - pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0, - SLAB_PANIC, pmb_cache_ctor, - pmb_cache_dtor); + pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), + 0, 0, pmb_cache_ctor, pmb_cache_dtor); + BUG_ON(!pmb_cache); jump_to_P2(); diff --git a/trunk/arch/sh/tools/mach-types b/trunk/arch/sh/tools/mach-types index 554f801db67b..4fe0f94cbf42 100644 --- a/trunk/arch/sh/tools/mach-types +++ b/trunk/arch/sh/tools/mach-types @@ -9,7 +9,6 @@ SE SH_SOLUTION_ENGINE 7751SE SH_7751_SOLUTION_ENGINE 7300SE SH_7300_SOLUTION_ENGINE 7343SE SH_7343_SOLUTION_ENGINE -7780SE SH_7780_SOLUTION_ENGINE 73180SE SH_73180_SOLUTION_ENGINE 7751SYSTEMH SH_7751_SYSTEMH HP6XX SH_HP6XX @@ -27,7 +26,6 @@ SH03 SH_SH03 LANDISK SH_LANDISK R7780RP SH_R7780RP R7780MP SH_R7780MP -R7785RP SH_R7785RP TITAN SH_TITAN SHMIN SH_SHMIN 7710VOIPGW SH_7710VOIPGW diff --git a/trunk/arch/sh64/kernel/early_printk.c b/trunk/arch/sh64/kernel/early_printk.c index 4f9131123672..8c8a76e180aa 100644 --- a/trunk/arch/sh64/kernel/early_printk.c +++ b/trunk/arch/sh64/kernel/early_printk.c @@ -79,7 +79,7 @@ static struct console sh_console = { .name = "scifcon", .write = sh_console_write, .setup = sh_console_setup, - .flags = CON_PRINTBUFFER | CON_BOOT, + .flags = CON_PRINTBUFFER, .index = -1, }; @@ -97,3 +97,9 @@ void __init enable_early_printk(void) register_console(&sh_console); } + +void disable_early_printk(void) +{ + unregister_console(&sh_console); +} + diff --git a/trunk/arch/sh64/kernel/irq.c b/trunk/arch/sh64/kernel/irq.c index f68b4f6c9b31..e7e07f8749c9 100644 --- a/trunk/arch/sh64/kernel/irq.c +++ b/trunk/arch/sh64/kernel/irq.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh64/kernel/pci_sh5.c b/trunk/arch/sh64/kernel/pci_sh5.c index 49862e165c06..9dae689b6a9b 100644 --- a/trunk/arch/sh64/kernel/pci_sh5.c +++ b/trunk/arch/sh64/kernel/pci_sh5.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh64/kernel/sh_ksyms.c b/trunk/arch/sh64/kernel/sh_ksyms.c index 461ea3de316f..7aa4b4f7bc5e 100644 --- a/trunk/arch/sh64/kernel/sh_ksyms.c +++ b/trunk/arch/sh64/kernel/sh_ksyms.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sh64/kernel/signal.c b/trunk/arch/sh64/kernel/signal.c index b76bdfa473d6..1666d3efb52e 100644 --- a/trunk/arch/sh64/kernel/signal.c +++ b/trunk/arch/sh64/kernel/signal.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh64/kernel/sys_sh64.c b/trunk/arch/sh64/kernel/sys_sh64.c index 19126daf9f4c..ad0fa4e003e7 100644 --- a/trunk/arch/sh64/kernel/sys_sh64.c +++ b/trunk/arch/sh64/kernel/sys_sh64.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh64/kernel/traps.c b/trunk/arch/sh64/kernel/traps.c index 9d0d58fb29fa..c346d7ef9280 100644 --- a/trunk/arch/sh64/kernel/traps.c +++ b/trunk/arch/sh64/kernel/traps.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh64/kernel/unwind.c b/trunk/arch/sh64/kernel/unwind.c index 1214c78e3584..f934f97f9f9c 100644 --- a/trunk/arch/sh64/kernel/unwind.c +++ b/trunk/arch/sh64/kernel/unwind.c @@ -46,15 +46,15 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc, struct pt_regs *regs) { const char *sym; - char namebuf[128]; - unsigned long offset; + char *modname, namebuf[128]; + unsigned long offset, size; unsigned long prologue = 0; unsigned long fp_displacement = 0; unsigned long fp_prev = 0; unsigned long offset_r14 = 0, offset_r18 = 0; int i, found_prologue_end = 0; - sym = kallsyms_lookup(pc, NULL, &offset, NULL, namebuf); + sym = kallsyms_lookup(pc, &size, &offset, &modname, namebuf); if (!sym) return -EINVAL; diff --git a/trunk/arch/sh64/kernel/vmlinux.lds.S b/trunk/arch/sh64/kernel/vmlinux.lds.S index 4f9616f39830..a59c5e998131 100644 --- a/trunk/arch/sh64/kernel/vmlinux.lds.S +++ b/trunk/arch/sh64/kernel/vmlinux.lds.S @@ -85,7 +85,7 @@ SECTIONS . = ALIGN(PAGE_SIZE); .data.page_aligned : C_PHYS(.data.page_aligned) { *(.data.page_aligned) } - . = ALIGN(PAGE_SIZE); + . = ALIGN(L1_CACHE_BYTES); __per_cpu_start = .; .data.percpu : C_PHYS(.data.percpu) { *(.data.percpu) } __per_cpu_end = . ; diff --git a/trunk/arch/sh64/mach-cayman/iomap.c b/trunk/arch/sh64/mach-cayman/iomap.c index a5c645f02d57..2d06e9a55137 100644 --- a/trunk/arch/sh64/mach-cayman/iomap.c +++ b/trunk/arch/sh64/mach-cayman/iomap.c @@ -9,6 +9,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#include #include #include diff --git a/trunk/arch/sh64/mm/fault.c b/trunk/arch/sh64/mm/fault.c index 4dd8ee8f01ce..4f72ab33bb2b 100644 --- a/trunk/arch/sh64/mm/fault.c +++ b/trunk/arch/sh64/mm/fault.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sh64/mm/hugetlbpage.c b/trunk/arch/sh64/mm/hugetlbpage.c index fa66daa2dfa9..4b455f611146 100644 --- a/trunk/arch/sh64/mm/hugetlbpage.c +++ b/trunk/arch/sh64/mm/hugetlbpage.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sh64/mm/tlbmiss.c b/trunk/arch/sh64/mm/tlbmiss.c index d4c5334186d0..c8615954aaa9 100644 --- a/trunk/arch/sh64/mm/tlbmiss.c +++ b/trunk/arch/sh64/mm/tlbmiss.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc/kernel/head.S b/trunk/arch/sparc/kernel/head.S index 97da13c52563..9a219e8b5ddb 100644 --- a/trunk/arch/sparc/kernel/head.S +++ b/trunk/arch/sparc/kernel/head.S @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include /* TI_UWINMASK */ #include diff --git a/trunk/arch/sparc/kernel/irq.c b/trunk/arch/sparc/kernel/irq.c index bdbefa8a9742..5b4841d067c1 100644 --- a/trunk/arch/sparc/kernel/irq.c +++ b/trunk/arch/sparc/kernel/irq.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc/kernel/process.c b/trunk/arch/sparc/kernel/process.c index 2940d2c1a778..fc874e63a499 100644 --- a/trunk/arch/sparc/kernel/process.c +++ b/trunk/arch/sparc/kernel/process.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc/kernel/setup.c b/trunk/arch/sparc/kernel/setup.c index 64c0ed98820a..eccd8e87f529 100644 --- a/trunk/arch/sparc/kernel/setup.c +++ b/trunk/arch/sparc/kernel/setup.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -41,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc/kernel/signal.c b/trunk/arch/sparc/kernel/signal.c index 9994cac95078..c9301b9143ca 100644 --- a/trunk/arch/sparc/kernel/signal.c +++ b/trunk/arch/sparc/kernel/signal.c @@ -17,6 +17,7 @@ #include #include #include +#include #include /* do_coredum */ #include diff --git a/trunk/arch/sparc/kernel/smp.c b/trunk/arch/sparc/kernel/smp.c index 4d9ad59031bb..6b5f26b0fb75 100644 --- a/trunk/arch/sparc/kernel/smp.c +++ b/trunk/arch/sparc/kernel/smp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc/kernel/sun4d_irq.c b/trunk/arch/sparc/kernel/sun4d_irq.c index 116d6a241ca2..0e27e226e0e2 100644 --- a/trunk/arch/sparc/kernel/sun4d_irq.c +++ b/trunk/arch/sparc/kernel/sun4d_irq.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc/kernel/sun4d_smp.c b/trunk/arch/sparc/kernel/sun4d_smp.c index 098c94f1a322..c69de5d4863d 100644 --- a/trunk/arch/sparc/kernel/sun4d_smp.c +++ b/trunk/arch/sparc/kernel/sun4d_smp.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc/kernel/sun4m_smp.c b/trunk/arch/sparc/kernel/sun4m_smp.c index 63ed19bfd028..e2d9c018bd56 100644 --- a/trunk/arch/sparc/kernel/sun4m_smp.c +++ b/trunk/arch/sparc/kernel/sun4m_smp.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -404,7 +405,7 @@ void __init smp4m_blackbox_current(unsigned *addr) addr[0] = 0x81580000 | rd; /* rd %tbr, reg */ addr[2] = 0x8130200a | rd | rs1; /* srl reg, 0xa, reg */ - addr[4] = 0x8008200c | rd | rs1; /* and reg, 0xc, reg */ + addr[4] = 0x8008200c | rd | rs1; /* and reg, 3, reg */ } void __init sun4m_init_smp(void) diff --git a/trunk/arch/sparc/kernel/sunos_ioctl.c b/trunk/arch/sparc/kernel/sunos_ioctl.c index e613cc6a10ba..32e8274e4357 100644 --- a/trunk/arch/sparc/kernel/sunos_ioctl.c +++ b/trunk/arch/sparc/kernel/sunos_ioctl.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc/kernel/sys_solaris.c b/trunk/arch/sparc/kernel/sys_solaris.c index 2226a5992484..01b07bb440f0 100644 --- a/trunk/arch/sparc/kernel/sys_solaris.c +++ b/trunk/arch/sparc/kernel/sys_solaris.c @@ -12,6 +12,7 @@ #include #include #include +#include #include asmlinkage int diff --git a/trunk/arch/sparc/kernel/systbls.S b/trunk/arch/sparc/kernel/systbls.S index e3f5b8ed4c52..3a69778c8366 100644 --- a/trunk/arch/sparc/kernel/systbls.S +++ b/trunk/arch/sparc/kernel/systbls.S @@ -80,7 +80,6 @@ sys_call_table: /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait -/*310*/ .long sys_utimensat #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -197,6 +196,5 @@ sunos_sys_table: .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys -/*310*/ .long sunos_nosys #endif diff --git a/trunk/arch/sparc/kernel/traps.c b/trunk/arch/sparc/kernel/traps.c index dc9ffea2a4f7..527687afc1c4 100644 --- a/trunk/arch/sparc/kernel/traps.c +++ b/trunk/arch/sparc/kernel/traps.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index f0bb6e60e620..e5c24e0521de 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -65,7 +65,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(4096); + . = ALIGN(32); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/sparc/lib/bitext.c b/trunk/arch/sparc/lib/bitext.c index 764b3eb7b604..2e168d16547f 100644 --- a/trunk/arch/sparc/lib/bitext.c +++ b/trunk/arch/sparc/lib/bitext.c @@ -9,6 +9,7 @@ * fragmentation. */ +#include #include #include diff --git a/trunk/arch/sparc/mm/fault.c b/trunk/arch/sparc/mm/fault.c index c3483365db4b..9eeed3347df3 100644 --- a/trunk/arch/sparc/mm/fault.c +++ b/trunk/arch/sparc/mm/fault.c @@ -18,9 +18,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -30,6 +30,7 @@ #include #include #include +#include #include extern int prom_node_root; diff --git a/trunk/arch/sparc/mm/srmmu.c b/trunk/arch/sparc/mm/srmmu.c index e5eaa8072ae0..0df7121cef07 100644 --- a/trunk/arch/sparc/mm/srmmu.c +++ b/trunk/arch/sparc/mm/srmmu.c @@ -18,13 +18,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig index ad8d6b256a70..590a41b864b9 100644 --- a/trunk/arch/sparc64/Kconfig +++ b/trunk/arch/sparc64/Kconfig @@ -34,10 +34,6 @@ config MMU bool default y -config QUICKLIST - bool - default y - config STACKTRACE_SUPPORT bool default y @@ -310,7 +306,6 @@ config SUN_IO config PCI bool "PCI support" - select ARCH_SUPPORTS_MSI help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index 37c2d3695658..120c9c33b7a6 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,16 +1,15 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21 -# Sun May 6 22:46:54 2007 +# Linux kernel version: 2.6.21-rc4 +# Sat Mar 17 14:18:44 2007 # CONFIG_SPARC=y CONFIG_SPARC64=y -CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TIME_INTERPOLATION=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set @@ -109,9 +108,6 @@ CONFIG_GENERIC_HARDIRQS=y # # General machine setup # -CONFIG_TICK_ONESHOT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y # CONFIG_SMP is not set CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=m @@ -144,7 +140,8 @@ CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y -CONFIG_SPARSEMEM_STATIC=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_RESOURCES_64BIT=y CONFIG_ZONE_DMA_FLAG=0 @@ -154,7 +151,6 @@ CONFIG_SUN_AUXIO=y CONFIG_SUN_IO=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -CONFIG_ARCH_SUPPORTS_MSI=y CONFIG_PCI_MSI=y # CONFIG_PCI_DEBUG is not set CONFIG_SUN_OPENPROMFS=m @@ -182,6 +178,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -222,7 +219,6 @@ CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y -CONFIG_IPV6_OPTIMISTIC_DAD=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m @@ -296,14 +292,6 @@ CONFIG_NET_TCPPROBE=m # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set # @@ -324,6 +312,10 @@ CONFIG_FW_LOADER=y # Connector - unified userspace <-> kernelspace linker # CONFIG_CONNECTOR=m + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set # @@ -391,6 +383,7 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_OPTI621 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y CONFIG_IDEDMA_ONLYDISK=y # CONFIG_BLK_DEV_AEC62XX is not set CONFIG_BLK_DEV_ALI15X3=y @@ -420,6 +413,7 @@ CONFIG_BLK_DEV_ALI15X3=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -449,7 +443,6 @@ CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # CONFIG_SCSI_SCAN_ASYNC is not set -CONFIG_SCSI_WAIT_SCAN=m # # SCSI Transports @@ -492,7 +485,6 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SUNESP is not set # CONFIG_SCSI_SRP is not set @@ -636,10 +628,9 @@ CONFIG_BNX2=m # CONFIG_TR is not set # -# Wireless LAN +# Wireless LAN (non-hamradio) # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_NET_RADIO is not set # # Wan interfaces @@ -704,12 +695,6 @@ CONFIG_KEYBOARD_LKKBD=m # CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y -CONFIG_MOUSE_PS2_ALPS=y -CONFIG_MOUSE_PS2_LOGIPS2PP=y -CONFIG_MOUSE_PS2_SYNAPTICS=y -CONFIG_MOUSE_PS2_LIFEBOOK=y -CONFIG_MOUSE_PS2_TRACKPOINT=y -# CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_SERIAL=y # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set @@ -717,7 +702,6 @@ CONFIG_MOUSE_SERIAL=y CONFIG_INPUT_MISC=y CONFIG_INPUT_SPARCSPKR=y # CONFIG_INPUT_UINPUT is not set -# CONFIG_INPUT_POLLDEV is not set # # Hardware I/O ports @@ -779,8 +763,11 @@ CONFIG_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set + +# +# I2C support +# CONFIG_I2C=y -CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_CHARDEV is not set # @@ -804,17 +791,17 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PASEMI is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set # CONFIG_I2C_STUB is not set -# CONFIG_I2C_TINY_USB is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set # # Miscellaneous I2C Chip support @@ -925,7 +912,7 @@ CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # -# Frame buffer hardware drivers +# Frambuffer hardware drivers # # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set @@ -950,8 +937,6 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set -# CONFIG_FB_XVR500 is not set -# CONFIG_FB_XVR2500 is not set # CONFIG_FB_PCI is not set # CONFIG_FB_VIRTUAL is not set @@ -1108,14 +1093,6 @@ CONFIG_AC97_BUS=m CONFIG_HID=y # CONFIG_HID_DEBUG is not set -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -CONFIG_USB_HIDDEV=y - # # USB support # @@ -1129,7 +1106,6 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set @@ -1180,6 +1156,10 @@ CONFIG_USB_STORAGE=m # # USB Input Devices # +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set @@ -1544,7 +1524,6 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_LRW=m -# CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_BLOWFISH=m diff --git a/trunk/arch/sparc64/kernel/Makefile b/trunk/arch/sparc64/kernel/Makefile index 6bf6fb65bc20..eff0c01d3579 100644 --- a/trunk/arch/sparc64/kernel/Makefile +++ b/trunk/arch/sparc64/kernel/Makefile @@ -17,7 +17,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ - pci_sun4v.o pci_sun4v_asm.o pci_fire.o + pci_sun4v.o pci_sun4v_asm.o obj-$(CONFIG_SMP) += smp.o trampoline.o obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o diff --git a/trunk/arch/sparc64/kernel/central.c b/trunk/arch/sparc64/kernel/central.c index 8230099f0d8a..c65b2f9c98d8 100644 --- a/trunk/arch/sparc64/kernel/central.c +++ b/trunk/arch/sparc64/kernel/central.c @@ -98,7 +98,7 @@ void apply_central_ranges(struct linux_central *central, central->num_central_ranges); } -static void * __init central_alloc_bootmem(unsigned long size) +void * __init central_alloc_bootmem(unsigned long size) { void *ret; @@ -116,7 +116,7 @@ static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r) return ret | (unsigned long) r->phys_addr; } -static void __init probe_other_fhcs(void) +static void probe_other_fhcs(void) { struct device_node *dp; const struct linux_prom64_registers *fpregs; @@ -298,7 +298,7 @@ static void init_all_fhc_hw(void) } -void __init central_probe(void) +void central_probe(void) { struct linux_prom_registers fpregs[6]; const struct linux_prom_registers *pr; diff --git a/trunk/arch/sparc64/kernel/ebus.c b/trunk/arch/sparc64/kernel/ebus.c index ad55a9bb50dd..0ace17bafba4 100644 --- a/trunk/arch/sparc64/kernel/ebus.c +++ b/trunk/arch/sparc64/kernel/ebus.c @@ -13,17 +13,16 @@ #include #include #include -#include #include #include +#include #include #include #include #include #include #include -#include /* EBUS dma library. */ diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index 3edc18e1b818..6241e3dbbd57 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -279,7 +279,7 @@ static void sun4u_irq_enable(unsigned int virt_irq) struct irq_handler_data *data = get_irq_chip_data(virt_irq); if (likely(data)) { - unsigned long cpuid, imap, val; + unsigned long cpuid, imap; unsigned int tid; cpuid = irq_choose_cpu(virt_irq); @@ -287,11 +287,7 @@ static void sun4u_irq_enable(unsigned int virt_irq) tid = sun4u_compute_tid(imap, cpuid); - val = upa_readq(imap); - val &= ~(IMAP_TID_UPA | IMAP_TID_JBUS | - IMAP_AID_SAFARI | IMAP_NID_SAFARI); - val |= tid | IMAP_VALID; - upa_writeq(val, imap); + upa_writel(tid | IMAP_VALID, imap); } } @@ -301,10 +297,10 @@ static void sun4u_irq_disable(unsigned int virt_irq) if (likely(data)) { unsigned long imap = data->imap; - u32 tmp = upa_readq(imap); + u32 tmp = upa_readl(imap); tmp &= ~IMAP_VALID; - upa_writeq(tmp, imap); + upa_writel(tmp, imap); } } @@ -313,7 +309,7 @@ static void sun4u_irq_end(unsigned int virt_irq) struct irq_handler_data *data = get_irq_chip_data(virt_irq); if (likely(data)) - upa_writeq(ICLR_IDLE, data->iclr); + upa_writel(ICLR_IDLE, data->iclr); } static void sun4v_irq_enable(unsigned int virt_irq) @@ -469,7 +465,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) BUG_ON(tlb_type == hypervisor); - ino = (upa_readq(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; + ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; bucket = &ivector_table[ino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); diff --git a/trunk/arch/sparc64/kernel/kprobes.c b/trunk/arch/sparc64/kernel/kprobes.c index c93a15b785fa..ae221f0d4a6f 100644 --- a/trunk/arch/sparc64/kernel/kprobes.c +++ b/trunk/arch/sparc64/kernel/kprobes.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include @@ -313,7 +313,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) return 1; } -int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) +static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -403,6 +403,15 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, if (post_kprobe_handler(args->regs)) ret = NOTIFY_STOP; break; + case DIE_GPF: + case DIE_PAGE_FAULT: + /* kprobe_running() needs smp_processor_id() */ + preempt_disable(); + if (kprobe_running() && + kprobe_fault_handler(args->regs, args->trapnr)) + ret = NOTIFY_STOP; + preempt_enable(); + break; default: break; } diff --git a/trunk/arch/sparc64/kernel/pci.c b/trunk/arch/sparc64/kernel/pci.c index d85e1ed7c3e4..023af41ad68d 100644 --- a/trunk/arch/sparc64/kernel/pci.c +++ b/trunk/arch/sparc64/kernel/pci.c @@ -14,12 +14,13 @@ #include #include #include -#include +#include #include #include #include #include +#include #include #include #include @@ -48,10 +49,10 @@ asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn, #else /* List of all PCI controllers found in the system. */ -struct pci_pbm_info *pci_pbm_root = NULL; +struct pci_controller_info *pci_controller_root = NULL; -/* Each PBM found gets a unique index. */ -int pci_num_pbms = 0; +/* Each PCI controller found gets a unique index. */ +int pci_num_controllers = 0; volatile int pci_poke_in_progress; volatile int pci_poke_cpu = -1; @@ -189,7 +190,6 @@ extern void schizo_init(struct device_node *, const char *); extern void schizo_plus_init(struct device_node *, const char *); extern void tomatillo_init(struct device_node *, const char *); extern void sun4v_pci_init(struct device_node *, const char *); -extern void fire_pci_init(struct device_node *, const char *); static struct { char *model_name; @@ -207,7 +207,6 @@ static struct { { "SUNW,tomatillo", tomatillo_init }, { "pci108e,a801", tomatillo_init }, { "SUNW,sun4v-pci", sun4v_pci_init }, - { "pciex108e,80f0", fire_pci_init }, }; #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ sizeof(pci_controller_table[0])) @@ -291,7 +290,7 @@ extern const struct pci_iommu_ops pci_sun4u_iommu_ops, /* Find each controller in the system, attach and initialize * software state structure for each and link into the - * pci_pbm_root. Setup the controller enough such + * pci_controller_root. Setup the controller enough such * that bus scanning can be done. */ static void __init pci_controller_probe(void) @@ -437,13 +436,6 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, printk(" class: 0x%x device name: %s\n", dev->class, pci_name(dev)); - /* I have seen IDE devices which will not respond to - * the bmdma simplex check reads if bus mastering is - * disabled. - */ - if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) - pci_set_master(dev); - dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; @@ -476,7 +468,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, return dev; } -static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) +static void __init apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) { u32 idx, first, last; @@ -505,9 +497,9 @@ static void __init pci_resource_adjust(struct resource *res, /* Cook up fake bus resources for SUNW,simba PCI bridges which lack * a proper 'ranges' property. */ -static void __devinit apb_fake_ranges(struct pci_dev *dev, - struct pci_bus *bus, - struct pci_pbm_info *pbm) +static void __init apb_fake_ranges(struct pci_dev *dev, + struct pci_bus *bus, + struct pci_pbm_info *pbm) { struct resource *res; u32 first, last; @@ -530,15 +522,15 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev, pci_resource_adjust(res, &pbm->mem_space); } -static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_bus *bus); +static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_bus *bus); #define GET_64BIT(prop, i) ((((u64) (prop)[(i)]) << 32) | (prop)[(i)+1]) -static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_dev *dev) +void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_dev *dev) { struct pci_bus *bus; const u32 *busrange, *ranges; @@ -637,9 +629,9 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, pci_of_scan_bus(pbm, node, bus); } -static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_bus *bus) +static void __init pci_of_scan_bus(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_bus *bus) { struct device_node *child; const u32 *reg; @@ -741,8 +733,9 @@ int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, return PCIBIOS_SUCCESSFUL; } -struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) +struct pci_bus * __init pci_scan_one_pbm(struct pci_pbm_info *pbm) { + struct pci_controller_info *p = pbm->parent; struct device_node *node = pbm->prom_node; struct pci_dev *host_pdev; struct pci_bus *bus; @@ -750,7 +743,7 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) printk("PCI: Scanning PBM %s\n", node->full_name); /* XXX parent device? XXX */ - bus = pci_create_bus(NULL, pbm->pci_first_busno, pbm->pci_ops, pbm); + bus = pci_create_bus(NULL, pbm->pci_first_busno, p->pci_ops, pbm); if (!bus) { printk(KERN_ERR "Failed to create bus for %s\n", node->full_name); @@ -775,10 +768,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) static void __init pci_scan_each_controller_bus(void) { - struct pci_pbm_info *pbm; + struct pci_controller_info *p; - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) - pbm->scan_bus(pbm); + for (p = pci_controller_root; p; p = p->next) + p->scan_bus(p); } extern void power_init(void); @@ -786,7 +779,7 @@ extern void power_init(void); static int __init pcibios_init(void) { pci_controller_probe(); - if (pci_pbm_root == NULL) + if (pci_controller_root == NULL) return 0; pci_scan_each_controller_bus(); @@ -921,8 +914,10 @@ static int __pci_mmap_make_offset_bus(struct pci_dev *pdev, struct vm_area_struc enum pci_mmap_state mmap_state) { struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; + struct pci_controller_info *p; unsigned long space_size, user_offset, user_size; + p = pbm->parent; if (mmap_state == pci_mmap_io) { space_size = (pbm->io_space.end - pbm->io_space.start) + 1; @@ -1075,7 +1070,11 @@ int pci_domain_nr(struct pci_bus *pbus) if (pbm == NULL || pbm->parent == NULL) { ret = -ENXIO; } else { - ret = pbm->index; + struct pci_controller_info *p = pbm->parent; + + ret = p->index; + ret = ((ret << 1) + + ((pbm == &pbm->parent->pbm_B) ? 1 : 0)); } return ret; @@ -1086,12 +1085,17 @@ EXPORT_SYMBOL(pci_domain_nr); int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - int virt_irq; + struct pci_controller_info *p = pbm->parent; + int virt_irq, err; - if (!pbm->setup_msi_irq) + if (!pbm->msi_num || !p->setup_msi_irq) return -EINVAL; - return pbm->setup_msi_irq(&virt_irq, pdev, desc); + err = p->setup_msi_irq(&virt_irq, pdev, desc); + if (err < 0) + return err; + + return virt_irq; } void arch_teardown_msi_irq(unsigned int virt_irq) @@ -1099,11 +1103,12 @@ void arch_teardown_msi_irq(unsigned int virt_irq) struct msi_desc *entry = get_irq_msi(virt_irq); struct pci_dev *pdev = entry->dev; struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; + struct pci_controller_info *p = pbm->parent; - if (!pbm->teardown_msi_irq) + if (!pbm->msi_num || !p->setup_msi_irq) return; - return pbm->teardown_msi_irq(virt_irq, pdev); + return p->teardown_msi_irq(virt_irq, pdev); } #endif /* !(CONFIG_PCI_MSI) */ diff --git a/trunk/arch/sparc64/kernel/pci_common.c b/trunk/arch/sparc64/kernel/pci_common.c index 76faaa8135dd..1e6aeedf43c4 100644 --- a/trunk/arch/sparc64/kernel/pci_common.c +++ b/trunk/arch/sparc64/kernel/pci_common.c @@ -9,26 +9,12 @@ #include #include +#include #include #include -#include #include "pci_impl.h" -void pci_get_pbm_props(struct pci_pbm_info *pbm) -{ - const u32 *val = of_get_property(pbm->prom_node, "bus-range", NULL); - - pbm->pci_first_busno = val[0]; - pbm->pci_last_busno = val[1]; - - val = of_get_property(pbm->prom_node, "ino-bitmap", NULL); - if (val) { - pbm->ino_bitmap = (((u64)val[1] << 32UL) | - ((u64)val[0] << 0UL)); - } -} - static void pci_register_legacy_regions(struct resource *io_res, struct resource *mem_res) { @@ -163,7 +149,8 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) } /* Generic helper routines for PCI error reporting. */ -void pci_scan_for_target_abort(struct pci_pbm_info *pbm, +void pci_scan_for_target_abort(struct pci_controller_info *p, + struct pci_pbm_info *pbm, struct pci_bus *pbus) { struct pci_dev *pdev; @@ -178,16 +165,18 @@ void pci_scan_for_target_abort(struct pci_pbm_info *pbm, PCI_STATUS_REC_TARGET_ABORT)); if (error_bits) { pci_write_config_word(pdev, PCI_STATUS, error_bits); - printk("%s: Device %s saw Target Abort [%016x]\n", - pbm->name, pci_name(pdev), status); + printk("PCI%d(PBM%c): Device [%s] saw Target Abort [%016x]\n", + p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), + pci_name(pdev), status); } } list_for_each_entry(bus, &pbus->children, node) - pci_scan_for_target_abort(pbm, bus); + pci_scan_for_target_abort(p, pbm, bus); } -void pci_scan_for_master_abort(struct pci_pbm_info *pbm, +void pci_scan_for_master_abort(struct pci_controller_info *p, + struct pci_pbm_info *pbm, struct pci_bus *pbus) { struct pci_dev *pdev; @@ -201,16 +190,18 @@ void pci_scan_for_master_abort(struct pci_pbm_info *pbm, (status & (PCI_STATUS_REC_MASTER_ABORT)); if (error_bits) { pci_write_config_word(pdev, PCI_STATUS, error_bits); - printk("%s: Device %s received Master Abort [%016x]\n", - pbm->name, pci_name(pdev), status); + printk("PCI%d(PBM%c): Device [%s] received Master Abort [%016x]\n", + p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), + pci_name(pdev), status); } } list_for_each_entry(bus, &pbus->children, node) - pci_scan_for_master_abort(pbm, bus); + pci_scan_for_master_abort(p, pbm, bus); } -void pci_scan_for_parity_error(struct pci_pbm_info *pbm, +void pci_scan_for_parity_error(struct pci_controller_info *p, + struct pci_pbm_info *pbm, struct pci_bus *pbus) { struct pci_dev *pdev; @@ -225,11 +216,12 @@ void pci_scan_for_parity_error(struct pci_pbm_info *pbm, PCI_STATUS_DETECTED_PARITY)); if (error_bits) { pci_write_config_word(pdev, PCI_STATUS, error_bits); - printk("%s: Device %s saw Parity Error [%016x]\n", - pbm->name, pci_name(pdev), status); + printk("PCI%d(PBM%c): Device [%s] saw Parity Error [%016x]\n", + p->index, ((pbm == &p->pbm_A) ? 'A' : 'B'), + pci_name(pdev), status); } } list_for_each_entry(bus, &pbus->children, node) - pci_scan_for_parity_error(pbm, bus); + pci_scan_for_parity_error(p, pbm, bus); } diff --git a/trunk/arch/sparc64/kernel/pci_fire.c b/trunk/arch/sparc64/kernel/pci_fire.c deleted file mode 100644 index 2e0eb4ee8f71..000000000000 --- a/trunk/arch/sparc64/kernel/pci_fire.c +++ /dev/null @@ -1,390 +0,0 @@ -/* pci_fire.c: Sun4u platform PCI-E controller support. - * - * Copyright (C) 2007 David S. Miller (davem@davemloft.net) - */ -#include -#include -#include -#include - -#include -#include - -#include "pci_impl.h" - -#define fire_read(__reg) \ -({ u64 __ret; \ - __asm__ __volatile__("ldxa [%1] %2, %0" \ - : "=r" (__ret) \ - : "r" (__reg), "i" (ASI_PHYS_BYPASS_EC_E) \ - : "memory"); \ - __ret; \ -}) -#define fire_write(__reg, __val) \ - __asm__ __volatile__("stxa %0, [%1] %2" \ - : /* no outputs */ \ - : "r" (__val), "r" (__reg), \ - "i" (ASI_PHYS_BYPASS_EC_E) \ - : "memory") - -/* Fire config space address format is nearly identical to - * that of SCHIZO and PSYCHO, except that in order to accomodate - * PCI-E extended config space the encoding can handle 12 bits - * of register address: - * - * 32 28 27 20 19 15 14 12 11 2 1 0 - * ------------------------------------------------- - * |0 0 0 0 0| bus | device | function | reg | 0 0 | - * ------------------------------------------------- - */ -#define FIRE_CONFIG_BASE(PBM) ((PBM)->config_space) -#define FIRE_CONFIG_ENCODE(BUS, DEVFN, REG) \ - (((unsigned long)(BUS) << 20) | \ - ((unsigned long)(DEVFN) << 12) | \ - ((unsigned long)(REG))) - -static void *fire_pci_config_mkaddr(struct pci_pbm_info *pbm, - unsigned char bus, - unsigned int devfn, - int where) -{ - if (!pbm) - return NULL; - return (void *) - (FIRE_CONFIG_BASE(pbm) | - FIRE_CONFIG_ENCODE(bus, devfn, where)); -} - -/* FIRE PCI configuration space accessors. */ - -static int fire_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, - int where, int size, u32 *value) -{ - struct pci_pbm_info *pbm = bus_dev->sysdata; - unsigned char bus = bus_dev->number; - u32 *addr; - u16 tmp16; - u8 tmp8; - - if (bus_dev == pbm->pci_bus && devfn == 0x00) - return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, - size, value); - switch (size) { - case 1: - *value = 0xff; - break; - case 2: - *value = 0xffff; - break; - case 4: - *value = 0xffffffff; - break; - } - - addr = fire_pci_config_mkaddr(pbm, bus, devfn, where); - if (!addr) - return PCIBIOS_SUCCESSFUL; - - switch (size) { - case 1: - pci_config_read8((u8 *)addr, &tmp8); - *value = tmp8; - break; - - case 2: - if (where & 0x01) { - printk("pci_read_config_word: misaligned reg [%x]\n", - where); - return PCIBIOS_SUCCESSFUL; - } - pci_config_read16((u16 *)addr, &tmp16); - *value = tmp16; - break; - - case 4: - if (where & 0x03) { - printk("pci_read_config_dword: misaligned reg [%x]\n", - where); - return PCIBIOS_SUCCESSFUL; - } - - pci_config_read32(addr, value); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int fire_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, - int where, int size, u32 value) -{ - struct pci_pbm_info *pbm = bus_dev->sysdata; - unsigned char bus = bus_dev->number; - u32 *addr; - - if (bus_dev == pbm->pci_bus && devfn == 0x00) - return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, - size, value); - addr = fire_pci_config_mkaddr(pbm, bus, devfn, where); - if (!addr) - return PCIBIOS_SUCCESSFUL; - - switch (size) { - case 1: - pci_config_write8((u8 *)addr, value); - break; - - case 2: - if (where & 0x01) { - printk("pci_write_config_word: misaligned reg [%x]\n", - where); - return PCIBIOS_SUCCESSFUL; - } - pci_config_write16((u16 *)addr, value); - break; - - case 4: - if (where & 0x03) { - printk("pci_write_config_dword: misaligned reg [%x]\n", - where); - return PCIBIOS_SUCCESSFUL; - } - - pci_config_write32(addr, value); - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops pci_fire_ops = { - .read = fire_read_pci_cfg, - .write = fire_write_pci_cfg, -}; - -static void pci_fire_scan_bus(struct pci_pbm_info *pbm) -{ - pbm->pci_bus = pci_scan_one_pbm(pbm); - - /* XXX register error interrupt handlers XXX */ -} - -#define FIRE_IOMMU_CONTROL 0x40000UL -#define FIRE_IOMMU_TSBBASE 0x40008UL -#define FIRE_IOMMU_FLUSH 0x40100UL -#define FIRE_IOMMU_FLUSHINV 0x40100UL - -static void pci_fire_pbm_iommu_init(struct pci_pbm_info *pbm) -{ - struct iommu *iommu = pbm->iommu; - u32 vdma[2], dma_mask; - u64 control; - int tsbsize; - - /* No virtual-dma property on these guys, use largest size. */ - vdma[0] = 0xc0000000; /* base */ - vdma[1] = 0x40000000; /* size */ - dma_mask = 0xffffffff; - tsbsize = 128; - - /* Register addresses. */ - iommu->iommu_control = pbm->pbm_regs + FIRE_IOMMU_CONTROL; - iommu->iommu_tsbbase = pbm->pbm_regs + FIRE_IOMMU_TSBBASE; - iommu->iommu_flush = pbm->pbm_regs + FIRE_IOMMU_FLUSH; - iommu->iommu_flushinv = pbm->pbm_regs + FIRE_IOMMU_FLUSHINV; - - /* We use the main control/status register of FIRE as the write - * completion register. - */ - iommu->write_complete_reg = pbm->controller_regs + 0x410000UL; - - /* - * Invalidate TLB Entries. - */ - fire_write(iommu->iommu_flushinv, ~(u64)0); - - pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask); - - fire_write(iommu->iommu_tsbbase, __pa(iommu->page_table) | 0x7UL); - - control = fire_read(iommu->iommu_control); - control |= (0x00000400 /* TSB cache snoop enable */ | - 0x00000300 /* Cache mode */ | - 0x00000002 /* Bypass enable */ | - 0x00000001 /* Translation enable */); - fire_write(iommu->iommu_control, control); -} - -/* Based at pbm->controller_regs */ -#define FIRE_PARITY_CONTROL 0x470010UL -#define FIRE_PARITY_ENAB 0x8000000000000000UL -#define FIRE_FATAL_RESET_CTL 0x471028UL -#define FIRE_FATAL_RESET_SPARE 0x0000000004000000UL -#define FIRE_FATAL_RESET_MB 0x0000000002000000UL -#define FIRE_FATAL_RESET_CPE 0x0000000000008000UL -#define FIRE_FATAL_RESET_APE 0x0000000000004000UL -#define FIRE_FATAL_RESET_PIO 0x0000000000000040UL -#define FIRE_FATAL_RESET_JW 0x0000000000000004UL -#define FIRE_FATAL_RESET_JI 0x0000000000000002UL -#define FIRE_FATAL_RESET_JR 0x0000000000000001UL -#define FIRE_CORE_INTR_ENABLE 0x471800UL - -/* Based at pbm->pbm_regs */ -#define FIRE_TLU_CTRL 0x80000UL -#define FIRE_TLU_CTRL_TIM 0x00000000da000000UL -#define FIRE_TLU_CTRL_QDET 0x0000000000000100UL -#define FIRE_TLU_CTRL_CFG 0x0000000000000001UL -#define FIRE_TLU_DEV_CTRL 0x90008UL -#define FIRE_TLU_LINK_CTRL 0x90020UL -#define FIRE_TLU_LINK_CTRL_CLK 0x0000000000000040UL -#define FIRE_LPU_RESET 0xe2008UL -#define FIRE_LPU_LLCFG 0xe2200UL -#define FIRE_LPU_LLCFG_VC0 0x0000000000000100UL -#define FIRE_LPU_FCTRL_UCTRL 0xe2240UL -#define FIRE_LPU_FCTRL_UCTRL_N 0x0000000000000002UL -#define FIRE_LPU_FCTRL_UCTRL_P 0x0000000000000001UL -#define FIRE_LPU_TXL_FIFOP 0xe2430UL -#define FIRE_LPU_LTSSM_CFG2 0xe2788UL -#define FIRE_LPU_LTSSM_CFG3 0xe2790UL -#define FIRE_LPU_LTSSM_CFG4 0xe2798UL -#define FIRE_LPU_LTSSM_CFG5 0xe27a0UL -#define FIRE_DMC_IENAB 0x31800UL -#define FIRE_DMC_DBG_SEL_A 0x53000UL -#define FIRE_DMC_DBG_SEL_B 0x53008UL -#define FIRE_PEC_IENAB 0x51800UL - -static void pci_fire_hw_init(struct pci_pbm_info *pbm) -{ - u64 val; - - fire_write(pbm->controller_regs + FIRE_PARITY_CONTROL, - FIRE_PARITY_ENAB); - - fire_write(pbm->controller_regs + FIRE_FATAL_RESET_CTL, - (FIRE_FATAL_RESET_SPARE | - FIRE_FATAL_RESET_MB | - FIRE_FATAL_RESET_CPE | - FIRE_FATAL_RESET_APE | - FIRE_FATAL_RESET_PIO | - FIRE_FATAL_RESET_JW | - FIRE_FATAL_RESET_JI | - FIRE_FATAL_RESET_JR)); - - fire_write(pbm->controller_regs + FIRE_CORE_INTR_ENABLE, ~(u64)0); - - val = fire_read(pbm->pbm_regs + FIRE_TLU_CTRL); - val |= (FIRE_TLU_CTRL_TIM | - FIRE_TLU_CTRL_QDET | - FIRE_TLU_CTRL_CFG); - fire_write(pbm->pbm_regs + FIRE_TLU_CTRL, val); - fire_write(pbm->pbm_regs + FIRE_TLU_DEV_CTRL, 0); - fire_write(pbm->pbm_regs + FIRE_TLU_LINK_CTRL, - FIRE_TLU_LINK_CTRL_CLK); - - fire_write(pbm->pbm_regs + FIRE_LPU_RESET, 0); - fire_write(pbm->pbm_regs + FIRE_LPU_LLCFG, - FIRE_LPU_LLCFG_VC0); - fire_write(pbm->pbm_regs + FIRE_LPU_FCTRL_UCTRL, - (FIRE_LPU_FCTRL_UCTRL_N | - FIRE_LPU_FCTRL_UCTRL_P)); - fire_write(pbm->pbm_regs + FIRE_LPU_TXL_FIFOP, - ((0xffff << 16) | (0x0000 << 0))); - fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG2, 3000000); - fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG3, 500000); - fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG4, - (2 << 16) | (140 << 8)); - fire_write(pbm->pbm_regs + FIRE_LPU_LTSSM_CFG5, 0); - - fire_write(pbm->pbm_regs + FIRE_DMC_IENAB, ~(u64)0); - fire_write(pbm->pbm_regs + FIRE_DMC_DBG_SEL_A, 0); - fire_write(pbm->pbm_regs + FIRE_DMC_DBG_SEL_B, 0); - - fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0); -} - -static void pci_fire_pbm_init(struct pci_controller_info *p, - struct device_node *dp, u32 portid) -{ - const struct linux_prom64_registers *regs; - struct pci_pbm_info *pbm; - - if ((portid & 1) == 0) - pbm = &p->pbm_A; - else - pbm = &p->pbm_B; - - pbm->next = pci_pbm_root; - pci_pbm_root = pbm; - - pbm->scan_bus = pci_fire_scan_bus; - pbm->pci_ops = &pci_fire_ops; - - pbm->index = pci_num_pbms++; - - pbm->portid = portid; - pbm->parent = p; - pbm->prom_node = dp; - pbm->name = dp->full_name; - - regs = of_get_property(dp, "reg", NULL); - pbm->pbm_regs = regs[0].phys_addr; - pbm->controller_regs = regs[1].phys_addr - 0x410000UL; - - printk("%s: SUN4U PCIE Bus Module\n", pbm->name); - - pci_determine_mem_io_space(pbm); - - pci_get_pbm_props(pbm); - - pci_fire_hw_init(pbm); - pci_fire_pbm_iommu_init(pbm); -} - -static inline int portid_compare(u32 x, u32 y) -{ - if (x == (y ^ 1)) - return 1; - return 0; -} - -void fire_pci_init(struct device_node *dp, const char *model_name) -{ - struct pci_controller_info *p; - u32 portid = of_getintprop_default(dp, "portid", 0xff); - struct iommu *iommu; - struct pci_pbm_info *pbm; - - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { - if (portid_compare(pbm->portid, portid)) { - pci_fire_pbm_init(pbm->parent, dp, portid); - return; - } - } - - p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) - goto fatal_memory_error; - - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; - - p->pbm_A.iommu = iommu; - - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; - - p->pbm_B.iommu = iommu; - - /* XXX MSI support XXX */ - - /* Like PSYCHO and SCHIZO we have a 2GB aligned area - * for memory space. - */ - pci_memspace_mask = 0x7fffffffUL; - - pci_fire_pbm_init(p, dp, portid); - return; - -fatal_memory_error: - prom_printf("PCI_FIRE: Fatal memory allocation error.\n"); - prom_halt(); -} diff --git a/trunk/arch/sparc64/kernel/pci_impl.h b/trunk/arch/sparc64/kernel/pci_impl.h index 8e38023868aa..1208583fcb83 100644 --- a/trunk/arch/sparc64/kernel/pci_impl.h +++ b/trunk/arch/sparc64/kernel/pci_impl.h @@ -8,129 +8,15 @@ #include #include -#include -#include #include #include -#include -/* The abstraction used here is that there are PCI controllers, - * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules - * underneath. Each PCI bus module uses an IOMMU (shared by both - * PBMs of a controller, or per-PBM), and if a streaming buffer - * is present, each PCI bus module has it's own. (ie. the IOMMU - * might be shared between PBMs, the STC is never shared) - * Furthermore, each PCI bus module controls it's own autonomous - * PCI bus. - */ - -#define PCI_STC_FLUSHFLAG_INIT(STC) \ - (*((STC)->strbuf_flushflag) = 0UL) -#define PCI_STC_FLUSHFLAG_SET(STC) \ - (*((STC)->strbuf_flushflag) != 0UL) - -struct pci_controller_info; - -struct pci_pbm_info { - struct pci_pbm_info *next; - int index; - - /* PCI controller we sit under. */ - struct pci_controller_info *parent; - - /* Physical address base of controller registers. */ - unsigned long controller_regs; - - /* Physical address base of PBM registers. */ - unsigned long pbm_regs; - - /* Physical address of DMA sync register, if any. */ - unsigned long sync_reg; - - /* Opaque 32-bit system bus Port ID. */ - u32 portid; - - /* Opaque 32-bit handle used for hypervisor calls. */ - u32 devhandle; - - /* Chipset version information. */ - int chip_type; -#define PBM_CHIP_TYPE_SABRE 1 -#define PBM_CHIP_TYPE_PSYCHO 2 -#define PBM_CHIP_TYPE_SCHIZO 3 -#define PBM_CHIP_TYPE_SCHIZO_PLUS 4 -#define PBM_CHIP_TYPE_TOMATILLO 5 - int chip_version; - int chip_revision; - - /* Name used for top-level resources. */ - char *name; - - /* OBP specific information. */ - struct device_node *prom_node; - u64 ino_bitmap; - - /* PBM I/O and Memory space resources. */ - struct resource io_space; - struct resource mem_space; - - /* Base of PCI Config space, can be per-PBM or shared. */ - unsigned long config_space; - - /* State of 66MHz capabilities on this PBM. */ - int is_66mhz_capable; - int all_devs_66mhz; - -#ifdef CONFIG_PCI_MSI - /* MSI info. */ - u32 msiq_num; - u32 msiq_ent_count; - u32 msiq_first; - u32 msiq_first_devino; - u32 msi_num; - u32 msi_first; - u32 msi_data_mask; - u32 msix_data_width; - u64 msi32_start; - u64 msi64_start; - u32 msi32_len; - u32 msi64_len; - void *msi_queues; - unsigned long *msi_bitmap; - int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev, - struct msi_desc *entry); - void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev); -#endif /* !(CONFIG_PCI_MSI) */ - - /* This PBM's streaming buffer. */ - struct strbuf stc; - - /* IOMMU state, potentially shared by both PBM segments. */ - struct iommu *iommu; - - /* Now things for the actual PCI bus probes. */ - unsigned int pci_first_busno; - unsigned int pci_last_busno; - struct pci_bus *pci_bus; - void (*scan_bus)(struct pci_pbm_info *); - struct pci_ops *pci_ops; -}; - -struct pci_controller_info { - /* The PCI bus modules controlled by us. */ - struct pci_pbm_info pbm_A; - struct pci_pbm_info pbm_B; -}; - -extern struct pci_pbm_info *pci_pbm_root; +extern struct pci_controller_info *pci_controller_root; extern unsigned long pci_memspace_mask; -extern int pci_num_pbms; +extern int pci_num_controllers; /* PCI bus scanning and fixup support. */ -extern void pci_iommu_table_init(struct iommu *iommu, int tsbsize, - u32 dma_offset, u32 dma_addr_mask); -extern void pci_get_pbm_props(struct pci_pbm_info *pbm); extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm); extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm); @@ -144,9 +30,9 @@ extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev, u32 value); /* Error reporting support. */ -extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *); -extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *); -extern void pci_scan_for_parity_error(struct pci_pbm_info *, struct pci_bus *); +extern void pci_scan_for_target_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); +extern void pci_scan_for_master_abort(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); +extern void pci_scan_for_parity_error(struct pci_controller_info *, struct pci_pbm_info *, struct pci_bus *); /* Configuration space access. */ extern void pci_config_read8(u8 *addr, u8 *ret); diff --git a/trunk/arch/sparc64/kernel/pci_iommu.c b/trunk/arch/sparc64/kernel/pci_iommu.c index dfd6f9f4790b..66712772f494 100644 --- a/trunk/arch/sparc64/kernel/pci_iommu.c +++ b/trunk/arch/sparc64/kernel/pci_iommu.c @@ -8,12 +8,10 @@ #include #include #include -#include -#include +#include #include "iommu_common.h" -#include "pci_impl.h" #define PCI_STC_CTXMATCH_ADDR(STC, CTX) \ ((STC)->strbuf_ctxmatch_base + ((CTX) << 3)) @@ -39,21 +37,17 @@ /* Must be invoked under the IOMMU lock. */ static void __iommu_flushall(struct iommu *iommu) { - if (iommu->iommu_flushinv) { - pci_iommu_write(iommu->iommu_flushinv, ~(u64)0); - } else { - unsigned long tag; - int entry; - - tag = iommu->iommu_flush + (0xa580UL - 0x0210UL); - for (entry = 0; entry < 16; entry++) { - pci_iommu_write(tag, 0); - tag += 8; - } + unsigned long tag; + int entry; - /* Ensure completion of previous PIO writes. */ - (void) pci_iommu_read(iommu->write_complete_reg); + tag = iommu->iommu_flush + (0xa580UL - 0x0210UL); + for (entry = 0; entry < 16; entry++) { + pci_iommu_write(tag, 0); + tag += 8; } + + /* Ensure completion of previous PIO writes. */ + (void) pci_iommu_read(iommu->write_complete_reg); } #define IOPTE_CONSISTENT(CTX) \ diff --git a/trunk/arch/sparc64/kernel/pci_psycho.c b/trunk/arch/sparc64/kernel/pci_psycho.c index 2edcb1dd13c3..253d40ec2245 100644 --- a/trunk/arch/sparc64/kernel/pci_psycho.c +++ b/trunk/arch/sparc64/kernel/pci_psycho.c @@ -12,12 +12,12 @@ #include #include +#include #include #include #include #include #include -#include #include "pci_impl.h" #include "iommu_common.h" @@ -98,8 +98,13 @@ static int psycho_out_of_range(struct pci_pbm_info *pbm, unsigned char bus, unsigned char devfn) { - return ((bus == pbm->pci_first_busno) && - PCI_SLOT(devfn) > 8); + return ((pbm->parent == 0) || + ((pbm == &pbm->parent->pbm_B) && + (bus == pbm->pci_first_busno) && + PCI_SLOT(devfn) > 8) || + ((pbm == &pbm->parent->pbm_A) && + (bus == pbm->pci_first_busno) && + PCI_SLOT(devfn) > 8)); } /* PSYCHO PCI configuration space accessors. */ @@ -260,11 +265,12 @@ static unsigned long stc_error_buf[128]; static unsigned long stc_tag_buf[16]; static unsigned long stc_line_buf[16]; -static void __psycho_check_one_stc(struct pci_pbm_info *pbm, +static void __psycho_check_one_stc(struct pci_controller_info *p, + struct pci_pbm_info *pbm, int is_pbm_a) { struct strbuf *strbuf = &pbm->stc; - unsigned long regbase = pbm->controller_regs; + unsigned long regbase = p->pbm_A.controller_regs; unsigned long err_base, tag_base, line_base; u64 control; int i; @@ -320,8 +326,9 @@ static void __psycho_check_one_stc(struct pci_pbm_info *pbm, unsigned long errval = stc_error_buf[j]; if (errval != 0) { saw_error++; - printk("%s: STC_ERR(%d)[wr(%d)rd(%d)]\n", - pbm->name, + printk("PSYCHO%d(PBM%c): STC_ERR(%d)[wr(%d)rd(%d)]\n", + p->index, + (is_pbm_a ? 'A' : 'B'), j, (errval & PSYCHO_STCERR_WRITE) ? 1 : 0, (errval & PSYCHO_STCERR_READ) ? 1 : 0); @@ -330,16 +337,18 @@ static void __psycho_check_one_stc(struct pci_pbm_info *pbm, if (saw_error != 0) { unsigned long tagval = stc_tag_buf[i]; unsigned long lineval = stc_line_buf[i]; - printk("%s: STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)W(%d)]\n", - pbm->name, + printk("PSYCHO%d(PBM%c): STC_TAG(%d)[PA(%016lx)VA(%08lx)V(%d)W(%d)]\n", + p->index, + (is_pbm_a ? 'A' : 'B'), i, ((tagval & PSYCHO_STCTAG_PPN) >> 19UL), (tagval & PSYCHO_STCTAG_VPN), ((tagval & PSYCHO_STCTAG_VALID) ? 1 : 0), ((tagval & PSYCHO_STCTAG_WRITE) ? 1 : 0)); - printk("%s: STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)" + printk("PSYCHO%d(PBM%c): STC_LINE(%d)[LIDX(%lx)SP(%lx)LADDR(%lx)EP(%lx)" "V(%d)FOFN(%d)]\n", - pbm->name, + p->index, + (is_pbm_a ? 'A' : 'B'), i, ((lineval & PSYCHO_STCLINE_LINDX) >> 21UL), ((lineval & PSYCHO_STCLINE_SPTR) >> 15UL), @@ -353,13 +362,20 @@ static void __psycho_check_one_stc(struct pci_pbm_info *pbm, spin_unlock(&stc_buf_lock); } -static void __psycho_check_stc_error(struct pci_pbm_info *pbm, +static void __psycho_check_stc_error(struct pci_controller_info *p, unsigned long afsr, unsigned long afar, enum psycho_error_type type) { - __psycho_check_one_stc(pbm, - (pbm == &pbm->parent->pbm_A)); + struct pci_pbm_info *pbm; + + pbm = &p->pbm_A; + if (pbm->stc.strbuf_enabled) + __psycho_check_one_stc(p, pbm, 1); + + pbm = &p->pbm_B; + if (pbm->stc.strbuf_enabled) + __psycho_check_one_stc(p, pbm, 0); } /* When an Uncorrectable Error or a PCI Error happens, we @@ -397,12 +413,12 @@ static void __psycho_check_stc_error(struct pci_pbm_info *pbm, #define PSYCHO_IOMMU_DATA_VALID (1UL << 30UL) #define PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL) #define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffUL -static void psycho_check_iommu_error(struct pci_pbm_info *pbm, +static void psycho_check_iommu_error(struct pci_controller_info *p, unsigned long afsr, unsigned long afar, enum psycho_error_type type) { - struct iommu *iommu = pbm->iommu; + struct iommu *iommu = p->pbm_A.iommu; unsigned long iommu_tag[16]; unsigned long iommu_data[16]; unsigned long flags; @@ -433,8 +449,8 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm, type_string = "ECC Error"; break; }; - printk("%s: IOMMU Error, type[%s]\n", - pbm->name, type_string); + printk("PSYCHO%d: IOMMU Error, type[%s]\n", + p->index, type_string); /* Put the IOMMU into diagnostic mode and probe * it's TLB for entries with error status. @@ -449,7 +465,7 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm, psycho_write(iommu->iommu_control, control | PSYCHO_IOMMU_CTRL_DENAB); for (i = 0; i < 16; i++) { - unsigned long base = pbm->controller_regs; + unsigned long base = p->pbm_A.controller_regs; iommu_tag[i] = psycho_read(base + PSYCHO_IOMMU_TAG + (i * 8UL)); @@ -487,20 +503,20 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm, type_string = "ECC Error"; break; }; - printk("%s: IOMMU TAG(%d)[error(%s) wr(%d) str(%d) sz(%dK) vpg(%08lx)]\n", - pbm->name, i, type_string, + printk("PSYCHO%d: IOMMU TAG(%d)[error(%s) wr(%d) str(%d) sz(%dK) vpg(%08lx)]\n", + p->index, i, type_string, ((tag & PSYCHO_IOMMU_TAG_WRITE) ? 1 : 0), ((tag & PSYCHO_IOMMU_TAG_STREAM) ? 1 : 0), ((tag & PSYCHO_IOMMU_TAG_SIZE) ? 64 : 8), (tag & PSYCHO_IOMMU_TAG_VPAGE) << IOMMU_PAGE_SHIFT); - printk("%s: IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n", - pbm->name, i, + printk("PSYCHO%d: IOMMU DATA(%d)[valid(%d) cache(%d) ppg(%016lx)]\n", + p->index, i, ((data & PSYCHO_IOMMU_DATA_VALID) ? 1 : 0), ((data & PSYCHO_IOMMU_DATA_CACHE) ? 1 : 0), (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); } } - __psycho_check_stc_error(pbm, afsr, afar, type); + __psycho_check_stc_error(p, afsr, afar, type); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -525,10 +541,9 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm, static irqreturn_t psycho_ue_intr(int irq, void *dev_id) { - struct pci_pbm_info *pbm = dev_id; - struct pci_controller_info *p = pbm->parent; - unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR; - unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR; + struct pci_controller_info *p = dev_id; + unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFSR; + unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_UE_AFAR; unsigned long afsr, afar, error_bits; int reported; @@ -545,22 +560,22 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) psycho_write(afsr_reg, error_bits); /* Log the error. */ - printk("%s: Uncorrectable Error, primary error type[%s]\n", - pbm->name, + printk("PSYCHO%d: Uncorrectable Error, primary error type[%s]\n", + p->index, (((error_bits & PSYCHO_UEAFSR_PPIO) ? "PIO" : ((error_bits & PSYCHO_UEAFSR_PDRD) ? "DMA Read" : ((error_bits & PSYCHO_UEAFSR_PDWR) ? "DMA Write" : "???"))))); - printk("%s: bytemask[%04lx] dword_offset[%lx] UPA_MID[%02lx] was_block(%d)\n", - pbm->name, + printk("PSYCHO%d: bytemask[%04lx] dword_offset[%lx] UPA_MID[%02lx] was_block(%d)\n", + p->index, (afsr & PSYCHO_UEAFSR_BMSK) >> 32UL, (afsr & PSYCHO_UEAFSR_DOFF) >> 29UL, (afsr & PSYCHO_UEAFSR_MID) >> 24UL, ((afsr & PSYCHO_UEAFSR_BLK) ? 1 : 0)); - printk("%s: UE AFAR [%016lx]\n", pbm->name, afar); - printk("%s: UE Secondary errors [", pbm->name); + printk("PSYCHO%d: UE AFAR [%016lx]\n", p->index, afar); + printk("PSYCHO%d: UE Secondary errors [", p->index); reported = 0; if (afsr & PSYCHO_UEAFSR_SPIO) { reported++; @@ -578,9 +593,8 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) printk("(none)"); printk("]\n"); - /* Interrogate both IOMMUs for error status. */ - psycho_check_iommu_error(&p->pbm_A, afsr, afar, UE_ERR); - psycho_check_iommu_error(&p->pbm_B, afsr, afar, UE_ERR); + /* Interrogate IOMMU for error status. */ + psycho_check_iommu_error(p, afsr, afar, UE_ERR); return IRQ_HANDLED; } @@ -604,9 +618,9 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) static irqreturn_t psycho_ce_intr(int irq, void *dev_id) { - struct pci_pbm_info *pbm = dev_id; - unsigned long afsr_reg = pbm->controller_regs + PSYCHO_CE_AFSR; - unsigned long afar_reg = pbm->controller_regs + PSYCHO_CE_AFAR; + struct pci_controller_info *p = dev_id; + unsigned long afsr_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFSR; + unsigned long afar_reg = p->pbm_A.controller_regs + PSYCHO_CE_AFAR; unsigned long afsr, afar, error_bits; int reported; @@ -623,8 +637,8 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) psycho_write(afsr_reg, error_bits); /* Log the error. */ - printk("%s: Correctable Error, primary error type[%s]\n", - pbm->name, + printk("PSYCHO%d: Correctable Error, primary error type[%s]\n", + p->index, (((error_bits & PSYCHO_CEAFSR_PPIO) ? "PIO" : ((error_bits & PSYCHO_CEAFSR_PDRD) ? @@ -635,16 +649,16 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) /* XXX Use syndrome and afar to print out module string just like * XXX UDB CE trap handler does... -DaveM */ - printk("%s: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] " + printk("PSYCHO%d: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] " "UPA_MID[%02lx] was_block(%d)\n", - pbm->name, + p->index, (afsr & PSYCHO_CEAFSR_ESYND) >> 48UL, (afsr & PSYCHO_CEAFSR_BMSK) >> 32UL, (afsr & PSYCHO_CEAFSR_DOFF) >> 29UL, (afsr & PSYCHO_CEAFSR_MID) >> 24UL, ((afsr & PSYCHO_CEAFSR_BLK) ? 1 : 0)); - printk("%s: CE AFAR [%016lx]\n", pbm->name, afar); - printk("%s: CE Secondary errors [", pbm->name); + printk("PSYCHO%d: CE AFAR [%016lx]\n", p->index, afar); + printk("PSYCHO%d: CE Secondary errors [", p->index); reported = 0; if (afsr & PSYCHO_CEAFSR_SPIO) { reported++; @@ -759,8 +773,8 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) psycho_write(afsr_reg, error_bits); /* Log the error. */ - printk("%s: PCI Error, primary error type[%s]\n", - pbm->name, + printk("PSYCHO%d(PBM%c): PCI Error, primary error type[%s]\n", + p->index, (is_pbm_a ? 'A' : 'B'), (((error_bits & PSYCHO_PCIAFSR_PMA) ? "Master Abort" : ((error_bits & PSYCHO_PCIAFSR_PTA) ? @@ -769,13 +783,15 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) "Excessive Retries" : ((error_bits & PSYCHO_PCIAFSR_PPERR) ? "Parity Error" : "???")))))); - printk("%s: bytemask[%04lx] UPA_MID[%02lx] was_block(%d)\n", - pbm->name, + printk("PSYCHO%d(PBM%c): bytemask[%04lx] UPA_MID[%02lx] was_block(%d)\n", + p->index, (is_pbm_a ? 'A' : 'B'), (afsr & PSYCHO_PCIAFSR_BMSK) >> 32UL, (afsr & PSYCHO_PCIAFSR_MID) >> 25UL, (afsr & PSYCHO_PCIAFSR_BLK) ? 1 : 0); - printk("%s: PCI AFAR [%016lx]\n", pbm->name, afar); - printk("%s: PCI Secondary errors [", pbm->name); + printk("PSYCHO%d(PBM%c): PCI AFAR [%016lx]\n", + p->index, (is_pbm_a ? 'A' : 'B'), afar); + printk("PSYCHO%d(PBM%c): PCI Secondary errors [", + p->index, (is_pbm_a ? 'A' : 'B')); reported = 0; if (afsr & PSYCHO_PCIAFSR_SMA) { reported++; @@ -807,11 +823,11 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) * a bug in the IOMMU support code or a PCI device driver. */ if (error_bits & (PSYCHO_PCIAFSR_PTA | PSYCHO_PCIAFSR_STA)) { - psycho_check_iommu_error(pbm, afsr, afar, PCI_ERR); - pci_scan_for_target_abort(pbm, pbm->pci_bus); + psycho_check_iommu_error(p, afsr, afar, PCI_ERR); + pci_scan_for_target_abort(p, pbm, pbm->pci_bus); } if (error_bits & (PSYCHO_PCIAFSR_PMA | PSYCHO_PCIAFSR_SMA)) - pci_scan_for_master_abort(pbm, pbm->pci_bus); + pci_scan_for_master_abort(p, pbm, pbm->pci_bus); /* For excessive retries, PSYCHO/PBM will abort the device * and there is no way to specifically check for excessive @@ -821,7 +837,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) */ if (error_bits & (PSYCHO_PCIAFSR_PPERR | PSYCHO_PCIAFSR_SPERR)) - pci_scan_for_parity_error(pbm, pbm->pci_bus); + pci_scan_for_parity_error(p, pbm, pbm->pci_bus); return IRQ_HANDLED; } @@ -831,49 +847,34 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) #define PSYCHO_ECCCTRL_EE 0x8000000000000000UL /* Enable ECC Checking */ #define PSYCHO_ECCCTRL_UE 0x4000000000000000UL /* Enable UE Interrupts */ #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ -static void psycho_register_error_handlers(struct pci_pbm_info *pbm) +static void psycho_register_error_handlers(struct pci_controller_info *p) { + struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ struct of_device *op = of_find_device_by_node(pbm->prom_node); - unsigned long base = pbm->controller_regs; + unsigned long base = p->pbm_A.controller_regs; u64 tmp; - int err; if (!op) return; /* Psycho interrupt property order is: - * 0: PCIERR INO for this PBM + * 0: PCIERR PBM B INO * 1: UE ERR * 2: CE ERR * 3: POWER FAIL * 4: SPARE HARDWARE - * 5: POWER MANAGEMENT + * 5: PCIERR PBM A INO */ if (op->num_irqs < 6) return; - /* We really mean to ignore the return result here. Two - * PCI controller share the same interrupt numbers and - * drive the same front-end hardware. Whichever of the - * two get in here first will register the IRQ handler - * the second will just error out since we do not pass in - * IRQF_SHARED. - */ - err = request_irq(op->irqs[1], psycho_ue_intr, 0, - "PSYCHO_UE", pbm); - err = request_irq(op->irqs[2], psycho_ce_intr, 0, - "PSYCHO_CE", pbm); - - /* This one, however, ought not to fail. We can just warn - * about it since the system can still operate properly even - * if this fails. - */ - err = request_irq(op->irqs[0], psycho_pcierr_intr, 0, - "PSYCHO_PCIERR", pbm); - if (err) - printk(KERN_WARNING "%s: Could not register PCIERR, " - "err=%d\n", pbm->name, err); + request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED, "PSYCHO UE", p); + request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED, "PSYCHO CE", p); + request_irq(op->irqs[5], psycho_pcierr_intr, IRQF_SHARED, + "PSYCHO PCIERR-A", &p->pbm_A); + request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED, + "PSYCHO PCIERR-B", &p->pbm_B); /* Enable UE and CE interrupts for controller. */ psycho_write(base + PSYCHO_ECC_CTRL, @@ -917,45 +918,54 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void psycho_scan_bus(struct pci_pbm_info *pbm) +static void pbm_scan_bus(struct pci_controller_info *p, + struct pci_pbm_info *pbm) { - pbm_config_busmastering(pbm); - pbm->is_66mhz_capable = 0; pbm->pci_bus = pci_scan_one_pbm(pbm); +} + +static void psycho_scan_bus(struct pci_controller_info *p) +{ + pbm_config_busmastering(&p->pbm_B); + p->pbm_B.is_66mhz_capable = 0; + pbm_config_busmastering(&p->pbm_A); + p->pbm_A.is_66mhz_capable = 1; + pbm_scan_bus(p, &p->pbm_B); + pbm_scan_bus(p, &p->pbm_A); /* After the PCI bus scan is complete, we can register * the error interrupt handlers. */ - psycho_register_error_handlers(pbm); + psycho_register_error_handlers(p); } -static void psycho_iommu_init(struct pci_pbm_info *pbm) +static void psycho_iommu_init(struct pci_controller_info *p) { - struct iommu *iommu = pbm->iommu; + struct iommu *iommu = p->pbm_A.iommu; unsigned long i; u64 control; /* Register addresses. */ - iommu->iommu_control = pbm->controller_regs + PSYCHO_IOMMU_CONTROL; - iommu->iommu_tsbbase = pbm->controller_regs + PSYCHO_IOMMU_TSBBASE; - iommu->iommu_flush = pbm->controller_regs + PSYCHO_IOMMU_FLUSH; + iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; + iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE; + iommu->iommu_flush = p->pbm_A.controller_regs + PSYCHO_IOMMU_FLUSH; /* PSYCHO's IOMMU lacks ctx flushing. */ iommu->iommu_ctxflush = 0; /* We use the main control register of PSYCHO as the write * completion register. */ - iommu->write_complete_reg = pbm->controller_regs + PSYCHO_CONTROL; + iommu->write_complete_reg = p->pbm_A.controller_regs + PSYCHO_CONTROL; /* * Invalidate TLB Entries. */ - control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL); + control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); control |= PSYCHO_IOMMU_CTRL_DENAB; - psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); for(i = 0; i < 16; i++) { - psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); - psycho_write(pbm->controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); } /* Leave diag mode enabled for full-flushing done @@ -963,17 +973,17 @@ static void psycho_iommu_init(struct pci_pbm_info *pbm) */ pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff); - psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE, + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(iommu->page_table)); - control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL); + control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ); control |= (PSYCHO_IOMMU_TSBSZ_128K | PSYCHO_IOMMU_CTRL_ENAB); - psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); /* If necessary, hook us up for starfire IRQ translations. */ if (this_is_starfire) - starfire_hookup(pbm->portid); + starfire_hookup(p->pbm_A.portid); } #define PSYCHO_IRQ_RETRY 0x1a00UL @@ -988,35 +998,36 @@ static void psycho_iommu_init(struct pci_pbm_info *pbm) #define PSYCHO_PCIDIAG_IPAPAR 0x0000000000000002UL /* Invert PIO address parity */ #define PSYCHO_PCIDIAG_LPBACK 0x0000000000000001UL /* Enable loopback mode */ -static void psycho_controller_hwinit(struct pci_pbm_info *pbm) +static void psycho_controller_hwinit(struct pci_controller_info *p) { u64 tmp; - psycho_write(pbm->controller_regs + PSYCHO_IRQ_RETRY, 5); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5); /* Enable arbiter for all PCI slots. */ - tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIA_CTRL); + tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL); tmp |= PSYCHO_PCICTRL_AEN; - psycho_write(pbm->controller_regs + PSYCHO_PCIA_CTRL, tmp); + psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL, tmp); - tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIB_CTRL); + tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIB_CTRL); tmp |= PSYCHO_PCICTRL_AEN; - psycho_write(pbm->controller_regs + PSYCHO_PCIB_CTRL, tmp); + psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_CTRL, tmp); /* Disable DMA write / PIO read synchronization on * both PCI bus segments. * [ U2P Erratum 1243770, STP2223BGA data sheet ] */ - tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIA_DIAG); + tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_DIAG); tmp |= PSYCHO_PCIDIAG_DDWSYNC; - psycho_write(pbm->controller_regs + PSYCHO_PCIA_DIAG, tmp); + psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIA_DIAG, tmp); - tmp = psycho_read(pbm->controller_regs + PSYCHO_PCIB_DIAG); + tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG); tmp |= PSYCHO_PCIDIAG_DDWSYNC; - psycho_write(pbm->controller_regs + PSYCHO_PCIB_DIAG, tmp); + psycho_write(p->pbm_A.controller_regs + PSYCHO_PCIB_DIAG, tmp); } -static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, +static void psycho_pbm_strbuf_init(struct pci_controller_info *p, + struct pci_pbm_info *pbm, int is_pbm_a) { unsigned long base = pbm->controller_regs; @@ -1077,6 +1088,7 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, static void psycho_pbm_init(struct pci_controller_info *p, struct device_node *dp, int is_pbm_a) { + unsigned int *busrange; struct property *prop; struct pci_pbm_info *pbm; @@ -1085,14 +1097,6 @@ static void psycho_pbm_init(struct pci_controller_info *p, else pbm = &p->pbm_B; - pbm->next = pci_pbm_root; - pci_pbm_root = pbm; - - pbm->scan_bus = psycho_scan_bus; - pbm->pci_ops = &psycho_ops; - - pbm->index = pci_num_pbms++; - pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; pbm->chip_version = 0; prop = of_find_property(dp, "version#", NULL); @@ -1113,9 +1117,12 @@ static void psycho_pbm_init(struct pci_controller_info *p, pci_determine_mem_io_space(pbm); - pci_get_pbm_props(pbm); + prop = of_find_property(dp, "bus-range", NULL); + busrange = prop->value; + pbm->pci_first_busno = busrange[0]; + pbm->pci_last_busno = busrange[1]; - psycho_pbm_strbuf_init(pbm, is_pbm_a); + psycho_pbm_strbuf_init(p, pbm, is_pbm_a); } #define PSYCHO_CONFIGSPACE 0x001000000UL @@ -1124,7 +1131,6 @@ void psycho_init(struct device_node *dp, char *model_name) { struct linux_prom64_registers *pr_regs; struct pci_controller_info *p; - struct pci_pbm_info *pbm; struct iommu *iommu; struct property *prop; u32 upa_portid; @@ -1135,9 +1141,7 @@ void psycho_init(struct device_node *dp, char *model_name) if (prop) upa_portid = *(u32 *) prop->value; - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { - struct pci_controller_info *p = pbm->parent; - + for(p = pci_controller_root; p; p = p->next) { if (p->pbm_A.portid == upa_portid) { is_pbm_a = (p->pbm_A.prom_node == NULL); psycho_pbm_init(p, dp, is_pbm_a); @@ -1157,8 +1161,14 @@ void psycho_init(struct device_node *dp, char *model_name) } p->pbm_A.iommu = p->pbm_B.iommu = iommu; + p->next = pci_controller_root; + pci_controller_root = p; + p->pbm_A.portid = upa_portid; p->pbm_B.portid = upa_portid; + p->index = pci_num_controllers++; + p->scan_bus = psycho_scan_bus; + p->pci_ops = &psycho_ops; prop = of_find_property(dp, "reg", NULL); pr_regs = prop->value; @@ -1175,9 +1185,9 @@ void psycho_init(struct device_node *dp, char *model_name) */ pci_memspace_mask = 0x7fffffffUL; - psycho_controller_hwinit(&p->pbm_A); + psycho_controller_hwinit(p); - psycho_iommu_init(&p->pbm_A); + psycho_iommu_init(p); is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); psycho_pbm_init(p, dp, is_pbm_a); diff --git a/trunk/arch/sparc64/kernel/pci_sabre.c b/trunk/arch/sparc64/kernel/pci_sabre.c index 4cefe6e83b24..397862fbd9e1 100644 --- a/trunk/arch/sparc64/kernel/pci_sabre.c +++ b/trunk/arch/sparc64/kernel/pci_sabre.c @@ -13,12 +13,12 @@ #include #include +#include #include #include #include #include #include -#include #include "pci_impl.h" #include "iommu_common.h" @@ -494,11 +494,11 @@ static struct pci_ops sabre_ops = { }; /* SABRE error handling support. */ -static void sabre_check_iommu_error(struct pci_pbm_info *pbm, +static void sabre_check_iommu_error(struct pci_controller_info *p, unsigned long afsr, unsigned long afar) { - struct iommu *iommu = pbm->iommu; + struct iommu *iommu = p->pbm_A.iommu; unsigned long iommu_tag[16]; unsigned long iommu_data[16]; unsigned long flags; @@ -526,8 +526,8 @@ static void sabre_check_iommu_error(struct pci_pbm_info *pbm, type_string = "Unknown"; break; }; - printk("%s: IOMMU Error, type[%s]\n", - pbm->name, type_string); + printk("SABRE%d: IOMMU Error, type[%s]\n", + p->index, type_string); /* Enter diagnostic mode and probe for error'd * entries in the IOTLB. @@ -536,7 +536,7 @@ static void sabre_check_iommu_error(struct pci_pbm_info *pbm, sabre_write(iommu->iommu_control, (control | SABRE_IOMMUCTRL_DENAB)); for (i = 0; i < 16; i++) { - unsigned long base = pbm->controller_regs; + unsigned long base = p->pbm_A.controller_regs; iommu_tag[i] = sabre_read(base + SABRE_IOMMU_TAG + (i * 8UL)); @@ -566,13 +566,13 @@ static void sabre_check_iommu_error(struct pci_pbm_info *pbm, type_string = "Unknown"; break; }; - printk("%s: IOMMU TAG(%d)[RAW(%016lx)error(%s)wr(%d)sz(%dK)vpg(%08lx)]\n", - pbm->name, i, tag, type_string, + printk("SABRE%d: IOMMU TAG(%d)[RAW(%016lx)error(%s)wr(%d)sz(%dK)vpg(%08lx)]\n", + p->index, i, tag, type_string, ((tag & SABRE_IOMMUTAG_WRITE) ? 1 : 0), ((tag & SABRE_IOMMUTAG_SIZE) ? 64 : 8), ((tag & SABRE_IOMMUTAG_VPN) << IOMMU_PAGE_SHIFT)); - printk("%s: IOMMU DATA(%d)[RAW(%016lx)valid(%d)used(%d)cache(%d)ppg(%016lx)\n", - pbm->name, i, data, + printk("SABRE%d: IOMMU DATA(%d)[RAW(%016lx)valid(%d)used(%d)cache(%d)ppg(%016lx)\n", + p->index, i, data, ((data & SABRE_IOMMUDATA_VALID) ? 1 : 0), ((data & SABRE_IOMMUDATA_USED) ? 1 : 0), ((data & SABRE_IOMMUDATA_CACHE) ? 1 : 0), @@ -584,9 +584,9 @@ static void sabre_check_iommu_error(struct pci_pbm_info *pbm, static irqreturn_t sabre_ue_intr(int irq, void *dev_id) { - struct pci_pbm_info *pbm = dev_id; - unsigned long afsr_reg = pbm->controller_regs + SABRE_UE_AFSR; - unsigned long afar_reg = pbm->controller_regs + SABRE_UECE_AFAR; + struct pci_controller_info *p = dev_id; + unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_UE_AFSR; + unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR; unsigned long afsr, afar, error_bits; int reported; @@ -604,21 +604,21 @@ static irqreturn_t sabre_ue_intr(int irq, void *dev_id) sabre_write(afsr_reg, error_bits); /* Log the error. */ - printk("%s: Uncorrectable Error, primary error type[%s%s]\n", - pbm->name, + printk("SABRE%d: Uncorrectable Error, primary error type[%s%s]\n", + p->index, ((error_bits & SABRE_UEAFSR_PDRD) ? "DMA Read" : ((error_bits & SABRE_UEAFSR_PDWR) ? "DMA Write" : "???")), ((error_bits & SABRE_UEAFSR_PDTE) ? ":Translation Error" : "")); - printk("%s: bytemask[%04lx] dword_offset[%lx] was_block(%d)\n", - pbm->name, + printk("SABRE%d: bytemask[%04lx] dword_offset[%lx] was_block(%d)\n", + p->index, (afsr & SABRE_UEAFSR_BMSK) >> 32UL, (afsr & SABRE_UEAFSR_OFF) >> 29UL, ((afsr & SABRE_UEAFSR_BLK) ? 1 : 0)); - printk("%s: UE AFAR [%016lx]\n", pbm->name, afar); - printk("%s: UE Secondary errors [", pbm->name); + printk("SABRE%d: UE AFAR [%016lx]\n", p->index, afar); + printk("SABRE%d: UE Secondary errors [", p->index); reported = 0; if (afsr & SABRE_UEAFSR_SDRD) { reported++; @@ -637,16 +637,16 @@ static irqreturn_t sabre_ue_intr(int irq, void *dev_id) printk("]\n"); /* Interrogate IOMMU for error status. */ - sabre_check_iommu_error(pbm, afsr, afar); + sabre_check_iommu_error(p, afsr, afar); return IRQ_HANDLED; } static irqreturn_t sabre_ce_intr(int irq, void *dev_id) { - struct pci_pbm_info *pbm = dev_id; - unsigned long afsr_reg = pbm->controller_regs + SABRE_CE_AFSR; - unsigned long afar_reg = pbm->controller_regs + SABRE_UECE_AFAR; + struct pci_controller_info *p = dev_id; + unsigned long afsr_reg = p->pbm_A.controller_regs + SABRE_CE_AFSR; + unsigned long afar_reg = p->pbm_A.controller_regs + SABRE_UECE_AFAR; unsigned long afsr, afar, error_bits; int reported; @@ -663,8 +663,8 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) sabre_write(afsr_reg, error_bits); /* Log the error. */ - printk("%s: Correctable Error, primary error type[%s]\n", - pbm->name, + printk("SABRE%d: Correctable Error, primary error type[%s]\n", + p->index, ((error_bits & SABRE_CEAFSR_PDRD) ? "DMA Read" : ((error_bits & SABRE_CEAFSR_PDWR) ? @@ -673,15 +673,15 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) /* XXX Use syndrome and afar to print out module string just like * XXX UDB CE trap handler does... -DaveM */ - printk("%s: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] " + printk("SABRE%d: syndrome[%02lx] bytemask[%04lx] dword_offset[%lx] " "was_block(%d)\n", - pbm->name, + p->index, (afsr & SABRE_CEAFSR_ESYND) >> 48UL, (afsr & SABRE_CEAFSR_BMSK) >> 32UL, (afsr & SABRE_CEAFSR_OFF) >> 29UL, ((afsr & SABRE_CEAFSR_BLK) ? 1 : 0)); - printk("%s: CE AFAR [%016lx]\n", pbm->name, afar); - printk("%s: CE Secondary errors [", pbm->name); + printk("SABRE%d: CE AFAR [%016lx]\n", p->index, afar); + printk("SABRE%d: CE Secondary errors [", p->index); reported = 0; if (afsr & SABRE_CEAFSR_SDRD) { reported++; @@ -698,13 +698,13 @@ static irqreturn_t sabre_ce_intr(int irq, void *dev_id) return IRQ_HANDLED; } -static irqreturn_t sabre_pcierr_intr_other(struct pci_pbm_info *pbm) +static irqreturn_t sabre_pcierr_intr_other(struct pci_controller_info *p) { unsigned long csr_reg, csr, csr_error_bits; irqreturn_t ret = IRQ_NONE; u16 stat; - csr_reg = pbm->controller_regs + SABRE_PCICTRL; + csr_reg = p->pbm_A.controller_regs + SABRE_PCICTRL; csr = sabre_read(csr_reg); csr_error_bits = csr & SABRE_PCICTRL_SERR; @@ -714,8 +714,8 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_pbm_info *pbm) /* Log 'em. */ if (csr_error_bits & SABRE_PCICTRL_SERR) - printk("%s: PCI SERR signal asserted.\n", - pbm->name); + printk("SABRE%d: PCI SERR signal asserted.\n", + p->index); ret = IRQ_HANDLED; } pci_bus_read_config_word(sabre_root_bus, 0, @@ -725,8 +725,8 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_pbm_info *pbm) PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_SIG_SYSTEM_ERROR)) { - printk("%s: PCI bus error, PCI_STATUS[%04x]\n", - pbm->name, stat); + printk("SABRE%d: PCI bus error, PCI_STATUS[%04x]\n", + p->index, stat); pci_bus_write_config_word(sabre_root_bus, 0, PCI_STATUS, 0xffff); ret = IRQ_HANDLED; @@ -736,13 +736,13 @@ static irqreturn_t sabre_pcierr_intr_other(struct pci_pbm_info *pbm) static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) { - struct pci_pbm_info *pbm = dev_id; + struct pci_controller_info *p = dev_id; unsigned long afsr_reg, afar_reg; unsigned long afsr, afar, error_bits; int reported; - afsr_reg = pbm->controller_regs + SABRE_PIOAFSR; - afar_reg = pbm->controller_regs + SABRE_PIOAFAR; + afsr_reg = p->pbm_A.controller_regs + SABRE_PIOAFSR; + afar_reg = p->pbm_A.controller_regs + SABRE_PIOAFAR; /* Latch error status. */ afar = sabre_read(afar_reg); @@ -755,12 +755,12 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) SABRE_PIOAFSR_SMA | SABRE_PIOAFSR_STA | SABRE_PIOAFSR_SRTRY | SABRE_PIOAFSR_SPERR); if (!error_bits) - return sabre_pcierr_intr_other(pbm); + return sabre_pcierr_intr_other(p); sabre_write(afsr_reg, error_bits); /* Log the error. */ - printk("%s: PCI Error, primary error type[%s]\n", - pbm->name, + printk("SABRE%d: PCI Error, primary error type[%s]\n", + p->index, (((error_bits & SABRE_PIOAFSR_PMA) ? "Master Abort" : ((error_bits & SABRE_PIOAFSR_PTA) ? @@ -769,12 +769,12 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) "Excessive Retries" : ((error_bits & SABRE_PIOAFSR_PPERR) ? "Parity Error" : "???")))))); - printk("%s: bytemask[%04lx] was_block(%d)\n", - pbm->name, + printk("SABRE%d: bytemask[%04lx] was_block(%d)\n", + p->index, (afsr & SABRE_PIOAFSR_BMSK) >> 32UL, (afsr & SABRE_PIOAFSR_BLK) ? 1 : 0); - printk("%s: PCI AFAR [%016lx]\n", pbm->name, afar); - printk("%s: PCI Secondary errors [", pbm->name); + printk("SABRE%d: PCI AFAR [%016lx]\n", p->index, afar); + printk("SABRE%d: PCI Secondary errors [", p->index); reported = 0; if (afsr & SABRE_PIOAFSR_SMA) { reported++; @@ -806,11 +806,11 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) * a bug in the IOMMU support code or a PCI device driver. */ if (error_bits & (SABRE_PIOAFSR_PTA | SABRE_PIOAFSR_STA)) { - sabre_check_iommu_error(pbm, afsr, afar); - pci_scan_for_target_abort(pbm, pbm->pci_bus); + sabre_check_iommu_error(p, afsr, afar); + pci_scan_for_target_abort(p, &p->pbm_A, p->pbm_A.pci_bus); } if (error_bits & (SABRE_PIOAFSR_PMA | SABRE_PIOAFSR_SMA)) - pci_scan_for_master_abort(pbm, pbm->pci_bus); + pci_scan_for_master_abort(p, &p->pbm_A, p->pbm_A.pci_bus); /* For excessive retries, SABRE/PBM will abort the device * and there is no way to specifically check for excessive @@ -820,18 +820,18 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) */ if (error_bits & (SABRE_PIOAFSR_PPERR | SABRE_PIOAFSR_SPERR)) - pci_scan_for_parity_error(pbm, pbm->pci_bus); + pci_scan_for_parity_error(p, &p->pbm_A, p->pbm_A.pci_bus); return IRQ_HANDLED; } -static void sabre_register_error_handlers(struct pci_pbm_info *pbm) +static void sabre_register_error_handlers(struct pci_controller_info *p) { + struct pci_pbm_info *pbm = &p->pbm_A; /* arbitrary */ struct device_node *dp = pbm->prom_node; struct of_device *op; unsigned long base = pbm->controller_regs; u64 tmp; - int err; if (pbm->chip_type == PBM_CHIP_TYPE_SABRE) dp = dp->parent; @@ -858,31 +858,22 @@ static void sabre_register_error_handlers(struct pci_pbm_info *pbm) SABRE_UEAFSR_SDRD | SABRE_UEAFSR_SDWR | SABRE_UEAFSR_SDTE | SABRE_UEAFSR_PDTE)); - err = request_irq(op->irqs[1], sabre_ue_intr, 0, "SABRE_UE", pbm); - if (err) - printk(KERN_WARNING "%s: Couldn't register UE, err=%d.\n", - pbm->name, err); + request_irq(op->irqs[1], sabre_ue_intr, IRQF_SHARED, "SABRE UE", p); sabre_write(base + SABRE_CE_AFSR, (SABRE_CEAFSR_PDRD | SABRE_CEAFSR_PDWR | SABRE_CEAFSR_SDRD | SABRE_CEAFSR_SDWR)); - err = request_irq(op->irqs[2], sabre_ce_intr, 0, "SABRE_CE", pbm); - if (err) - printk(KERN_WARNING "%s: Couldn't register CE, err=%d.\n", - pbm->name, err); - err = request_irq(op->irqs[0], sabre_pcierr_intr, 0, - "SABRE_PCIERR", pbm); - if (err) - printk(KERN_WARNING "%s: Couldn't register PCIERR, err=%d.\n", - pbm->name, err); + request_irq(op->irqs[2], sabre_ce_intr, IRQF_SHARED, "SABRE CE", p); + request_irq(op->irqs[0], sabre_pcierr_intr, IRQF_SHARED, + "SABRE PCIERR", p); tmp = sabre_read(base + SABRE_PCICTRL); tmp |= SABRE_PCICTRL_ERREN; sabre_write(base + SABRE_PCICTRL, tmp); } -static void apb_init(struct pci_bus *sabre_bus) +static void apb_init(struct pci_controller_info *p, struct pci_bus *sabre_bus) { struct pci_dev *pdev; @@ -918,7 +909,7 @@ static void apb_init(struct pci_bus *sabre_bus) } } -static void sabre_scan_bus(struct pci_pbm_info *pbm) +static void sabre_scan_bus(struct pci_controller_info *p) { static int once; struct pci_bus *pbus; @@ -927,7 +918,7 @@ static void sabre_scan_bus(struct pci_pbm_info *pbm) * at 66Mhz, but the front side of APB runs at 33Mhz * for both segments. */ - pbm->is_66mhz_capable = 0; + p->pbm_A.is_66mhz_capable = 0; /* This driver has not been verified to handle * multiple SABREs yet, so trap this. @@ -941,41 +932,41 @@ static void sabre_scan_bus(struct pci_pbm_info *pbm) } once++; - pbus = pci_scan_one_pbm(pbm); + pbus = pci_scan_one_pbm(&p->pbm_A); if (!pbus) return; sabre_root_bus = pbus; - apb_init(pbus); + apb_init(p, pbus); - sabre_register_error_handlers(pbm); + sabre_register_error_handlers(p); } -static void sabre_iommu_init(struct pci_pbm_info *pbm, +static void sabre_iommu_init(struct pci_controller_info *p, int tsbsize, unsigned long dvma_offset, u32 dma_mask) { - struct iommu *iommu = pbm->iommu; + struct iommu *iommu = p->pbm_A.iommu; unsigned long i; u64 control; /* Register addresses. */ - iommu->iommu_control = pbm->controller_regs + SABRE_IOMMU_CONTROL; - iommu->iommu_tsbbase = pbm->controller_regs + SABRE_IOMMU_TSBBASE; - iommu->iommu_flush = pbm->controller_regs + SABRE_IOMMU_FLUSH; - iommu->write_complete_reg = pbm->controller_regs + SABRE_WRSYNC; + iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; + iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE; + iommu->iommu_flush = p->pbm_A.controller_regs + SABRE_IOMMU_FLUSH; + iommu->write_complete_reg = p->pbm_A.controller_regs + SABRE_WRSYNC; /* Sabre's IOMMU lacks ctx flushing. */ iommu->iommu_ctxflush = 0; /* Invalidate TLB Entries. */ - control = sabre_read(pbm->controller_regs + SABRE_IOMMU_CONTROL); + control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL); control |= SABRE_IOMMUCTRL_DENAB; - sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); for(i = 0; i < 16; i++) { - sabre_write(pbm->controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0); - sabre_write(pbm->controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TAG + (i * 8UL), 0); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_DATA + (i * 8UL), 0); } /* Leave diag mode enabled for full-flushing done @@ -983,10 +974,10 @@ static void sabre_iommu_init(struct pci_pbm_info *pbm, */ pci_iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask); - sabre_write(pbm->controller_regs + SABRE_IOMMU_TSBBASE, + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(iommu->page_table)); - control = sabre_read(pbm->controller_regs + SABRE_IOMMU_CONTROL); + control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL); control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ); control |= SABRE_IOMMUCTRL_ENAB; switch(tsbsize) { @@ -1001,23 +992,22 @@ static void sabre_iommu_init(struct pci_pbm_info *pbm, prom_halt(); break; } - sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control); + sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); } -static void sabre_pbm_init(struct pci_controller_info *p, struct pci_pbm_info *pbm, struct device_node *dp) +static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp) { + struct pci_pbm_info *pbm; + + pbm = &p->pbm_A; pbm->name = dp->full_name; printk("%s: SABRE PCI Bus Module\n", pbm->name); - pbm->scan_bus = sabre_scan_bus; - pbm->pci_ops = &sabre_ops; - - pbm->index = pci_num_pbms++; - pbm->chip_type = PBM_CHIP_TYPE_SABRE; pbm->parent = p; pbm->prom_node = dp; - pci_get_pbm_props(pbm); + pbm->pci_first_busno = p->pci_first_busno; + pbm->pci_last_busno = p->pci_last_busno; pci_determine_mem_io_space(pbm); } @@ -1026,9 +1016,9 @@ void sabre_init(struct device_node *dp, char *model_name) { const struct linux_prom64_registers *pr_regs; struct pci_controller_info *p; - struct pci_pbm_info *pbm; struct iommu *iommu; int tsbsize; + const u32 *busrange; const u32 *vdma; u32 upa_portid, dma_mask; u64 clear_irq; @@ -1063,15 +1053,17 @@ void sabre_init(struct device_node *dp, char *model_name) prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n"); prom_halt(); } - pbm = &p->pbm_A; - pbm->iommu = iommu; + p->pbm_A.iommu = iommu; upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); - pbm->next = pci_pbm_root; - pci_pbm_root = pbm; + p->next = pci_controller_root; + pci_controller_root = p; - pbm->portid = upa_portid; + p->pbm_A.portid = upa_portid; + p->index = pci_num_controllers++; + p->scan_bus = sabre_scan_bus; + p->pci_ops = &sabre_ops; /* * Map in SABRE register set and report the presence of this SABRE. @@ -1082,26 +1074,26 @@ void sabre_init(struct device_node *dp, char *model_name) /* * First REG in property is base of entire SABRE register space. */ - pbm->controller_regs = pr_regs[0].phys_addr; + p->pbm_A.controller_regs = pr_regs[0].phys_addr; /* Clear interrupts */ /* PCI first */ for (clear_irq = SABRE_ICLR_A_SLOT0; clear_irq < SABRE_ICLR_B_SLOT0 + 0x80; clear_irq += 8) - sabre_write(pbm->controller_regs + clear_irq, 0x0UL); + sabre_write(p->pbm_A.controller_regs + clear_irq, 0x0UL); /* Then OBIO */ for (clear_irq = SABRE_ICLR_SCSI; clear_irq < SABRE_ICLR_SCSI + 0x80; clear_irq += 8) - sabre_write(pbm->controller_regs + clear_irq, 0x0UL); + sabre_write(p->pbm_A.controller_regs + clear_irq, 0x0UL); /* Error interrupts are enabled later after the bus scan. */ - sabre_write(pbm->controller_regs + SABRE_PCICTRL, + sabre_write(p->pbm_A.controller_regs + SABRE_PCICTRL, (SABRE_PCICTRL_MRLEN | SABRE_PCICTRL_SERR | SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); /* Now map in PCI config space for entire SABRE. */ - pbm->config_space = - (pbm->controller_regs + SABRE_CONFIGSPACE); + p->pbm_A.config_space = + (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); vdma = of_get_property(dp, "virtual-dma", NULL); @@ -1125,10 +1117,14 @@ void sabre_init(struct device_node *dp, char *model_name) prom_halt(); } - sabre_iommu_init(pbm, tsbsize, vdma[0], dma_mask); + sabre_iommu_init(p, tsbsize, vdma[0], dma_mask); + + busrange = of_get_property(dp, "bus-range", NULL); + p->pci_first_busno = busrange[0]; + p->pci_last_busno = busrange[1]; /* * Look for APB underneath. */ - sabre_pbm_init(p, pbm, dp); + sabre_pbm_init(p, dp); } diff --git a/trunk/arch/sparc64/kernel/pci_schizo.c b/trunk/arch/sparc64/kernel/pci_schizo.c index e375d72b8eed..91a7385e5d32 100644 --- a/trunk/arch/sparc64/kernel/pci_schizo.c +++ b/trunk/arch/sparc64/kernel/pci_schizo.c @@ -10,13 +10,12 @@ #include #include +#include #include #include #include #include #include -#include -#include #include "pci_impl.h" #include "iommu_common.h" @@ -239,6 +238,25 @@ static unsigned long stc_line_buf[16]; #define SCHIZO_PCIERR_B_INO 0x33 /* PBM B PCI bus error */ #define SCHIZO_SERR_INO 0x34 /* Safari interface error */ +struct pci_pbm_info *pbm_for_ino(struct pci_controller_info *p, u32 ino) +{ + ino &= IMAP_INO; + if (p->pbm_A.ino_bitmap & (1UL << ino)) + return &p->pbm_A; + if (p->pbm_B.ino_bitmap & (1UL << ino)) + return &p->pbm_B; + + printk("PCI%d: No ino_bitmap entry for ino[%x], bitmaps " + "PBM_A[%016lx] PBM_B[%016lx]", + p->index, ino, + p->pbm_A.ino_bitmap, + p->pbm_B.ino_bitmap); + printk("PCI%d: Using PBM_A, report this problem immediately.\n", + p->index); + + return &p->pbm_A; +} + #define SCHIZO_STC_ERR 0xb800UL /* --> 0xba00 */ #define SCHIZO_STC_TAG 0xba00UL /* --> 0xba80 */ #define SCHIZO_STC_LINE 0xbb00UL /* --> 0xbb80 */ @@ -504,10 +522,9 @@ static void schizo_check_iommu_error(struct pci_controller_info *p, static irqreturn_t schizo_ue_intr(int irq, void *dev_id) { - struct pci_pbm_info *pbm = dev_id; - struct pci_controller_info *p = pbm->parent; - unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR; - unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR; + struct pci_controller_info *p = dev_id; + unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFSR; + unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_UE_AFAR; unsigned long afsr, afar, error_bits; int reported, limit; @@ -532,28 +549,28 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) schizo_write(afsr_reg, error_bits); /* Log the error. */ - printk("%s: Uncorrectable Error, primary error type[%s]\n", - pbm->name, + printk("PCI%d: Uncorrectable Error, primary error type[%s]\n", + p->index, (((error_bits & SCHIZO_UEAFSR_PPIO) ? "PIO" : ((error_bits & SCHIZO_UEAFSR_PDRD) ? "DMA Read" : ((error_bits & SCHIZO_UEAFSR_PDWR) ? "DMA Write" : "???"))))); - printk("%s: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", - pbm->name, + printk("PCI%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", + p->index, (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, (afsr & SCHIZO_UEAFSR_AID) >> 24UL); - printk("%s: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", - pbm->name, + printk("PCI%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", + p->index, (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); - printk("%s: UE AFAR [%016lx]\n", pbm->name, afar); - printk("%s: UE Secondary errors [", pbm->name); + printk("PCI%d: UE AFAR [%016lx]\n", p->index, afar); + printk("PCI%d: UE Secondary errors [", p->index); reported = 0; if (afsr & SCHIZO_UEAFSR_SPIO) { reported++; @@ -593,9 +610,9 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) static irqreturn_t schizo_ce_intr(int irq, void *dev_id) { - struct pci_pbm_info *pbm = dev_id; - unsigned long afsr_reg = pbm->controller_regs + SCHIZO_CE_AFSR; - unsigned long afar_reg = pbm->controller_regs + SCHIZO_CE_AFAR; + struct pci_controller_info *p = dev_id; + unsigned long afsr_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFSR; + unsigned long afar_reg = p->pbm_B.controller_regs + SCHIZO_CE_AFAR; unsigned long afsr, afar, error_bits; int reported, limit; @@ -620,8 +637,8 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id) schizo_write(afsr_reg, error_bits); /* Log the error. */ - printk("%s: Correctable Error, primary error type[%s]\n", - pbm->name, + printk("PCI%d: Correctable Error, primary error type[%s]\n", + p->index, (((error_bits & SCHIZO_CEAFSR_PPIO) ? "PIO" : ((error_bits & SCHIZO_CEAFSR_PDRD) ? @@ -632,20 +649,20 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id) /* XXX Use syndrome and afar to print out module string just like * XXX UDB CE trap handler does... -DaveM */ - printk("%s: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", - pbm->name, + printk("PCI%d: bytemask[%04lx] qword_offset[%lx] SAFARI_AID[%02lx]\n", + p->index, (afsr & SCHIZO_UEAFSR_BMSK) >> 32UL, (afsr & SCHIZO_UEAFSR_QOFF) >> 30UL, (afsr & SCHIZO_UEAFSR_AID) >> 24UL); - printk("%s: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", - pbm->name, + printk("PCI%d: partial[%d] owned_in[%d] mtag[%lx] mtag_synd[%lx] ecc_sync[%lx]\n", + p->index, (afsr & SCHIZO_UEAFSR_PARTIAL) ? 1 : 0, (afsr & SCHIZO_UEAFSR_OWNEDIN) ? 1 : 0, (afsr & SCHIZO_UEAFSR_MTAG) >> 13UL, (afsr & SCHIZO_UEAFSR_MTAGSYND) >> 16UL, (afsr & SCHIZO_UEAFSR_ECCSYND) >> 0UL); - printk("%s: CE AFAR [%016lx]\n", pbm->name, afar); - printk("%s: CE Secondary errors [", pbm->name); + printk("PCI%d: CE AFAR [%016lx]\n", p->index, afar); + printk("PCI%d: CE Secondary errors [", p->index); reported = 0; if (afsr & SCHIZO_CEAFSR_SPIO) { reported++; @@ -864,10 +881,10 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) */ if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { schizo_check_iommu_error(p, PCI_ERR); - pci_scan_for_target_abort(pbm, pbm->pci_bus); + pci_scan_for_target_abort(p, pbm, pbm->pci_bus); } if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) - pci_scan_for_master_abort(pbm, pbm->pci_bus); + pci_scan_for_master_abort(p, pbm, pbm->pci_bus); /* For excessive retries, PSYCHO/PBM will abort the device * and there is no way to specifically check for excessive @@ -877,7 +894,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) */ if (error_bits & (SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_SPERR)) - pci_scan_for_parity_error(pbm, pbm->pci_bus); + pci_scan_for_parity_error(p, pbm, pbm->pci_bus); return IRQ_HANDLED; } @@ -923,23 +940,22 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) */ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) { - struct pci_pbm_info *pbm = dev_id; - struct pci_controller_info *p = pbm->parent; + struct pci_controller_info *p = dev_id; u64 errlog; - errlog = schizo_read(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG); - schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG, + errlog = schizo_read(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRLOG); + schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRLOG, errlog & ~(SAFARI_ERRLOG_ERROUT)); if (!(errlog & BUS_ERROR_UNMAP)) { - printk("%s: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", - pbm->name, errlog); + printk("PCI%d: Unexpected Safari/JBUS error interrupt, errlog[%016lx]\n", + p->index, errlog); return IRQ_HANDLED; } - printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", - pbm->name); + printk("PCI%d: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", + p->index); schizo_check_iommu_error(p, SAFARI_ERR); return IRQ_HANDLED; @@ -956,16 +972,6 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) #define SCHIZO_SAFARI_IRQCTRL 0x10010UL #define SCHIZO_SAFIRQCTRL_EN 0x8000000000000000UL -static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) -{ - ino &= IMAP_INO; - - if (pbm->ino_bitmap & (1UL << ino)) - return 1; - - return 0; -} - /* How the Tomatillo IRQs are routed around is pure guesswork here. * * All the Tomatillo devices I see in prtconf dumps seem to have only @@ -980,11 +986,11 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) * PCI bus units of the same Tomatillo. I still have not really * figured this out... */ -static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) +static void tomatillo_register_error_handlers(struct pci_controller_info *p) { - struct of_device *op = of_find_device_by_node(pbm->prom_node); + struct pci_pbm_info *pbm; + struct of_device *op; u64 tmp, err_mask, err_no_mask; - int err; /* Tomatillo IRQ property layout is: * 0: PCIERR @@ -994,42 +1000,44 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) * 4: POWER FAIL? */ - if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) { - err = request_irq(op->irqs[1], schizo_ue_intr, 0, - "TOMATILLO_UE", pbm); - if (err) - printk(KERN_WARNING "%s: Could not register UE, " - "err=%d\n", pbm->name, err); - } - if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) { - err = request_irq(op->irqs[2], schizo_ce_intr, 0, - "TOMATILLO_CE", pbm); - if (err) - printk(KERN_WARNING "%s: Could not register CE, " - "err=%d\n", pbm->name, err); - } - err = 0; - if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) { - err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, - "TOMATILLO_PCIERR", pbm); - } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) { - err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, - "TOMATILLO_PCIERR", pbm); - } - if (err) - printk(KERN_WARNING "%s: Could not register PCIERR, " - "err=%d\n", pbm->name, err); - - if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) { - err = request_irq(op->irqs[3], schizo_safarierr_intr, 0, - "TOMATILLO_SERR", pbm); - if (err) - printk(KERN_WARNING "%s: Could not register SERR, " - "err=%d\n", pbm->name, err); - } + pbm = pbm_for_ino(p, SCHIZO_UE_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED, + "TOMATILLO_UE", p); + + pbm = pbm_for_ino(p, SCHIZO_CE_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED, + "TOMATILLO CE", p); + + pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, + "TOMATILLO PCIERR-A", pbm); + + + pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, + "TOMATILLO PCIERR-B", pbm); + + pbm = pbm_for_ino(p, SCHIZO_SERR_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED, + "TOMATILLO SERR", p); /* Enable UE and CE interrupts for controller. */ - schizo_write(pbm->controller_regs + SCHIZO_ECC_CTRL, + schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, + (SCHIZO_ECCCTRL_EE | + SCHIZO_ECCCTRL_UE | + SCHIZO_ECCCTRL_CE)); + + schizo_write(p->pbm_B.controller_regs + SCHIZO_ECC_CTRL, (SCHIZO_ECCCTRL_EE | SCHIZO_ECCCTRL_UE | SCHIZO_ECCCTRL_CE)); @@ -1045,10 +1053,15 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) err_no_mask = SCHIZO_PCICTRL_DTO_ERR; - tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); + tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); tmp |= err_mask; tmp &= ~err_no_mask; - schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); + schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp); + + tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL); + tmp |= err_mask; + tmp &= ~err_no_mask; + schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); err_mask = (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | @@ -1057,7 +1070,8 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | SCHIZO_PCIAFSR_STTO); - schizo_write(pbm->pbm_regs + SCHIZO_PCI_AFSR, err_mask); + schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, err_mask); + schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, err_mask); err_mask = (BUS_ERROR_BADCMD | BUS_ERROR_SNOOP_GR | BUS_ERROR_SNOOP_PCI | BUS_ERROR_SNOOP_RD | @@ -1069,18 +1083,22 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) BUS_ERROR_APERR | BUS_ERROR_UNMAP | BUS_ERROR_BUSERR | BUS_ERROR_TIMEOUT); - schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL, + schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, + (SCHIZO_SAFERRCTRL_EN | err_mask)); + schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_ERRCTRL, (SCHIZO_SAFERRCTRL_EN | err_mask)); - schizo_write(pbm->controller_regs + SCHIZO_SAFARI_IRQCTRL, + schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, + (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); + schizo_write(p->pbm_B.controller_regs + SCHIZO_SAFARI_IRQCTRL, (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); } -static void schizo_register_error_handlers(struct pci_pbm_info *pbm) +static void schizo_register_error_handlers(struct pci_controller_info *p) { - struct of_device *op = of_find_device_by_node(pbm->prom_node); + struct pci_pbm_info *pbm; + struct of_device *op; u64 tmp, err_mask, err_no_mask; - int err; /* Schizo IRQ property layout is: * 0: PCIERR @@ -1090,42 +1108,39 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm) * 4: POWER FAIL? */ - if (pbm_routes_this_ino(pbm, SCHIZO_UE_INO)) { - err = request_irq(op->irqs[1], schizo_ue_intr, 0, - "SCHIZO_UE", pbm); - if (err) - printk(KERN_WARNING "%s: Could not register UE, " - "err=%d\n", pbm->name, err); - } - if (pbm_routes_this_ino(pbm, SCHIZO_CE_INO)) { - err = request_irq(op->irqs[2], schizo_ce_intr, 0, - "SCHIZO_CE", pbm); - if (err) - printk(KERN_WARNING "%s: Could not register CE, " - "err=%d\n", pbm->name, err); - } - err = 0; - if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_A_INO)) { - err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, - "SCHIZO_PCIERR", pbm); - } else if (pbm_routes_this_ino(pbm, SCHIZO_PCIERR_B_INO)) { - err = request_irq(op->irqs[0], schizo_pcierr_intr, 0, - "SCHIZO_PCIERR", pbm); - } - if (err) - printk(KERN_WARNING "%s: Could not register PCIERR, " - "err=%d\n", pbm->name, err); - - if (pbm_routes_this_ino(pbm, SCHIZO_SERR_INO)) { - err = request_irq(op->irqs[3], schizo_safarierr_intr, 0, - "SCHIZO_SERR", pbm); - if (err) - printk(KERN_WARNING "%s: Could not register SERR, " - "err=%d\n", pbm->name, err); - } + pbm = pbm_for_ino(p, SCHIZO_UE_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[1], schizo_ue_intr, IRQF_SHARED, + "SCHIZO_UE", p); + + pbm = pbm_for_ino(p, SCHIZO_CE_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[2], schizo_ce_intr, IRQF_SHARED, + "SCHIZO CE", p); + + pbm = pbm_for_ino(p, SCHIZO_PCIERR_A_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, + "SCHIZO PCIERR-A", pbm); + + + pbm = pbm_for_ino(p, SCHIZO_PCIERR_B_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[0], schizo_pcierr_intr, IRQF_SHARED, + "SCHIZO PCIERR-B", pbm); + + pbm = pbm_for_ino(p, SCHIZO_SERR_INO); + op = of_find_device_by_node(pbm->prom_node); + if (op) + request_irq(op->irqs[3], schizo_safarierr_intr, IRQF_SHARED, + "SCHIZO SERR", p); /* Enable UE and CE interrupts for controller. */ - schizo_write(pbm->controller_regs + SCHIZO_ECC_CTRL, + schizo_write(p->pbm_A.controller_regs + SCHIZO_ECC_CTRL, (SCHIZO_ECCCTRL_EE | SCHIZO_ECCCTRL_UE | SCHIZO_ECCCTRL_CE)); @@ -1144,12 +1159,25 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm) /* Enable PCI Error interrupts and clear error * bits for each PBM. */ - tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); + tmp = schizo_read(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL); tmp |= err_mask; tmp &= ~err_no_mask; - schizo_write(pbm->pbm_regs + SCHIZO_PCI_CTRL, tmp); + schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_CTRL, tmp); + + schizo_write(p->pbm_A.pbm_regs + SCHIZO_PCI_AFSR, + (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | + SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | + SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | + SCHIZO_PCIAFSR_SMA | SCHIZO_PCIAFSR_STA | + SCHIZO_PCIAFSR_SRTRY | SCHIZO_PCIAFSR_SPERR | + SCHIZO_PCIAFSR_STTO | SCHIZO_PCIAFSR_SUNUS)); - schizo_write(pbm->pbm_regs + SCHIZO_PCI_AFSR, + tmp = schizo_read(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL); + tmp |= err_mask; + tmp &= ~err_no_mask; + schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_CTRL, tmp); + + schizo_write(p->pbm_B.pbm_regs + SCHIZO_PCI_AFSR, (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_PRTRY | SCHIZO_PCIAFSR_PPERR | SCHIZO_PCIAFSR_PTTO | SCHIZO_PCIAFSR_PUNUS | @@ -1182,8 +1210,11 @@ static void schizo_register_error_handlers(struct pci_pbm_info *pbm) BUS_ERROR_CPU0PS | BUS_ERROR_CPU0PB); #endif - schizo_write(pbm->controller_regs + SCHIZO_SAFARI_ERRCTRL, + schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_ERRCTRL, (SCHIZO_SAFERRCTRL_EN | err_mask)); + + schizo_write(p->pbm_A.controller_regs + SCHIZO_SAFARI_IRQCTRL, + (SCHIZO_SAFIRQCTRL_EN | (BUS_ERROR_UNMAP))); } static void pbm_config_busmastering(struct pci_pbm_info *pbm) @@ -1203,19 +1234,27 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void schizo_scan_bus(struct pci_pbm_info *pbm) +static void schizo_scan_bus(struct pci_controller_info *p) { - pbm_config_busmastering(pbm); - pbm->is_66mhz_capable = - (of_find_property(pbm->prom_node, "66mhz-capable", NULL) + pbm_config_busmastering(&p->pbm_B); + p->pbm_B.is_66mhz_capable = + (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL) + != NULL); + pbm_config_busmastering(&p->pbm_A); + p->pbm_A.is_66mhz_capable = + (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL) != NULL); - pbm->pci_bus = pci_scan_one_pbm(pbm); + p->pbm_B.pci_bus = pci_scan_one_pbm(&p->pbm_B); + p->pbm_A.pci_bus = pci_scan_one_pbm(&p->pbm_A); - if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) - tomatillo_register_error_handlers(pbm); + /* After the PCI bus scan is complete, we can register + * the error interrupt handlers. + */ + if (p->pbm_B.chip_type == PBM_CHIP_TYPE_TOMATILLO) + tomatillo_register_error_handlers(p); else - schizo_register_error_handlers(pbm); + schizo_register_error_handlers(p); } #define SCHIZO_STRBUF_CONTROL (0x02800UL) @@ -1452,8 +1491,10 @@ static void schizo_pbm_init(struct pci_controller_info *p, int chip_type) { const struct linux_prom64_registers *regs; + const unsigned int *busrange; struct pci_pbm_info *pbm; const char *chipset_name; + const u32 *ino_bitmap; int is_pbm_a; switch (chip_type) { @@ -1490,14 +1531,6 @@ static void schizo_pbm_init(struct pci_controller_info *p, else pbm = &p->pbm_B; - pbm->next = pci_pbm_root; - pci_pbm_root = pbm; - - pbm->scan_bus = schizo_scan_bus; - pbm->pci_ops = &schizo_ops; - - pbm->index = pci_num_pbms++; - pbm->portid = portid; pbm->parent = p; pbm->prom_node = dp; @@ -1522,7 +1555,13 @@ static void schizo_pbm_init(struct pci_controller_info *p, pci_determine_mem_io_space(pbm); - pci_get_pbm_props(pbm); + ino_bitmap = of_get_property(dp, "ino-bitmap", NULL); + pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | + ((u64)ino_bitmap[0] << 0UL)); + + busrange = of_get_property(dp, "bus-range", NULL); + pbm->pci_first_busno = busrange[0]; + pbm->pci_last_busno = busrange[1]; schizo_pbm_iommu_init(pbm); schizo_pbm_strbuf_init(pbm); @@ -1541,15 +1580,23 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) static void __schizo_init(struct device_node *dp, char *model_name, int chip_type) { struct pci_controller_info *p; - struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; portid = of_getintprop_default(dp, "portid", 0xff); - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { + for (p = pci_controller_root; p; p = p->next) { + struct pci_pbm_info *pbm; + + if (p->pbm_A.prom_node && p->pbm_B.prom_node) + continue; + + pbm = (p->pbm_A.prom_node ? + &p->pbm_A : + &p->pbm_B); + if (portid_compare(pbm->portid, portid, chip_type)) { - schizo_pbm_init(pbm->parent, dp, portid, chip_type); + schizo_pbm_init(p, dp, portid, chip_type); return; } } @@ -1570,6 +1617,13 @@ static void __schizo_init(struct device_node *dp, char *model_name, int chip_typ p->pbm_B.iommu = iommu; + p->next = pci_controller_root; + pci_controller_root = p; + + p->index = pci_num_controllers++; + p->scan_bus = schizo_scan_bus; + p->pci_ops = &schizo_ops; + /* Like PSYCHO we have a 2GB aligned area for memory space. */ pci_memspace_mask = 0x7fffffffUL; diff --git a/trunk/arch/sparc64/kernel/pci_sun4v.c b/trunk/arch/sparc64/kernel/pci_sun4v.c index 0c76a8891a96..94295c219329 100644 --- a/trunk/arch/sparc64/kernel/pci_sun4v.c +++ b/trunk/arch/sparc64/kernel/pci_sun4v.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -676,15 +677,29 @@ static struct pci_ops pci_sun4v_ops = { }; -static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm) +static void pbm_scan_bus(struct pci_controller_info *p, + struct pci_pbm_info *pbm) +{ + pbm->pci_bus = pci_scan_one_pbm(pbm); +} + +static void pci_sun4v_scan_bus(struct pci_controller_info *p) { struct property *prop; struct device_node *dp; - dp = pbm->prom_node; - prop = of_find_property(dp, "66mhz-capable", NULL); - pbm->is_66mhz_capable = (prop != NULL); - pbm->pci_bus = pci_scan_one_pbm(pbm); + if ((dp = p->pbm_A.prom_node) != NULL) { + prop = of_find_property(dp, "66mhz-capable", NULL); + p->pbm_A.is_66mhz_capable = (prop != NULL); + + pbm_scan_bus(p, &p->pbm_A); + } + if ((dp = p->pbm_B.prom_node) != NULL) { + prop = of_find_property(dp, "66mhz-capable", NULL); + p->pbm_B.is_66mhz_capable = (prop != NULL); + + pbm_scan_bus(p, &p->pbm_B); + } /* XXX register error interrupt handlers XXX */ } @@ -787,6 +802,20 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) pbm->name, sz); } +static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) +{ + struct property *prop; + unsigned int *busrange; + + prop = of_find_property(pbm->prom_node, "bus-range", NULL); + + busrange = prop->value; + + pbm->pci_first_busno = busrange[0]; + pbm->pci_last_busno = busrange[1]; + +} + #ifdef CONFIG_PCI_MSI struct pci_sun4v_msiq_entry { u64 version_type; @@ -990,6 +1019,114 @@ static int msi_queue_alloc(struct pci_pbm_info *pbm) return -EINVAL; } +static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) +{ + const u32 *val; + int len; + + val = of_get_property(pbm->prom_node, "#msi-eqs", &len); + if (!val || len != 4) + goto no_msi; + pbm->msiq_num = *val; + if (pbm->msiq_num) { + const struct msiq_prop { + u32 first_msiq; + u32 num_msiq; + u32 first_devino; + } *mqp; + const struct msi_range_prop { + u32 first_msi; + u32 num_msi; + } *mrng; + const struct addr_range_prop { + u32 msi32_high; + u32 msi32_low; + u32 msi32_len; + u32 msi64_high; + u32 msi64_low; + u32 msi64_len; + } *arng; + + val = of_get_property(pbm->prom_node, "msi-eq-size", &len); + if (!val || len != 4) + goto no_msi; + + pbm->msiq_ent_count = *val; + + mqp = of_get_property(pbm->prom_node, + "msi-eq-to-devino", &len); + if (!mqp || len != sizeof(struct msiq_prop)) + goto no_msi; + + pbm->msiq_first = mqp->first_msiq; + pbm->msiq_first_devino = mqp->first_devino; + + val = of_get_property(pbm->prom_node, "#msi", &len); + if (!val || len != 4) + goto no_msi; + pbm->msi_num = *val; + + mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); + if (!mrng || len != sizeof(struct msi_range_prop)) + goto no_msi; + pbm->msi_first = mrng->first_msi; + + val = of_get_property(pbm->prom_node, "msi-data-mask", &len); + if (!val || len != 4) + goto no_msi; + pbm->msi_data_mask = *val; + + val = of_get_property(pbm->prom_node, "msix-data-width", &len); + if (!val || len != 4) + goto no_msi; + pbm->msix_data_width = *val; + + arng = of_get_property(pbm->prom_node, "msi-address-ranges", + &len); + if (!arng || len != sizeof(struct addr_range_prop)) + goto no_msi; + pbm->msi32_start = ((u64)arng->msi32_high << 32) | + (u64) arng->msi32_low; + pbm->msi64_start = ((u64)arng->msi64_high << 32) | + (u64) arng->msi64_low; + pbm->msi32_len = arng->msi32_len; + pbm->msi64_len = arng->msi64_len; + + if (msi_bitmap_alloc(pbm)) + goto no_msi; + + if (msi_queue_alloc(pbm)) { + msi_bitmap_free(pbm); + goto no_msi; + } + + printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " + "devino[0x%x]\n", + pbm->name, + pbm->msiq_first, pbm->msiq_num, + pbm->msiq_ent_count, + pbm->msiq_first_devino); + printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " + "width[%u]\n", + pbm->name, + pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, + pbm->msix_data_width); + printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " + "addr64[0x%lx:0x%x]\n", + pbm->name, + pbm->msi32_start, pbm->msi32_len, + pbm->msi64_start, pbm->msi64_len); + printk(KERN_INFO "%s: MSI queues at RA [%p]\n", + pbm->name, + pbm->msi_queues); + } + + return; + +no_msi: + pbm->msiq_num = 0; + printk(KERN_INFO "%s: No MSI support.\n", pbm->name); +} static int alloc_msi(struct pci_pbm_info *pbm) { @@ -1032,6 +1169,8 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, if (!devino) goto out_err; + set_irq_msi(*virt_irq_p, entry); + msiqid = ((devino - pbm->msiq_first_devino) + pbm->msiq_first); @@ -1065,8 +1204,6 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, msg.address_lo = pbm->msi32_start; } msg.data = msi_num; - - set_irq_msi(*virt_irq_p, entry); write_msi_msg(*virt_irq_p, &msg); irq_install_pre_handler(*virt_irq_p, @@ -1108,117 +1245,6 @@ static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq, */ sun4v_destroy_msi(virt_irq); } - -static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) -{ - const u32 *val; - int len; - - val = of_get_property(pbm->prom_node, "#msi-eqs", &len); - if (!val || len != 4) - goto no_msi; - pbm->msiq_num = *val; - if (pbm->msiq_num) { - const struct msiq_prop { - u32 first_msiq; - u32 num_msiq; - u32 first_devino; - } *mqp; - const struct msi_range_prop { - u32 first_msi; - u32 num_msi; - } *mrng; - const struct addr_range_prop { - u32 msi32_high; - u32 msi32_low; - u32 msi32_len; - u32 msi64_high; - u32 msi64_low; - u32 msi64_len; - } *arng; - - val = of_get_property(pbm->prom_node, "msi-eq-size", &len); - if (!val || len != 4) - goto no_msi; - - pbm->msiq_ent_count = *val; - - mqp = of_get_property(pbm->prom_node, - "msi-eq-to-devino", &len); - if (!mqp || len != sizeof(struct msiq_prop)) - goto no_msi; - - pbm->msiq_first = mqp->first_msiq; - pbm->msiq_first_devino = mqp->first_devino; - - val = of_get_property(pbm->prom_node, "#msi", &len); - if (!val || len != 4) - goto no_msi; - pbm->msi_num = *val; - - mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); - if (!mrng || len != sizeof(struct msi_range_prop)) - goto no_msi; - pbm->msi_first = mrng->first_msi; - - val = of_get_property(pbm->prom_node, "msi-data-mask", &len); - if (!val || len != 4) - goto no_msi; - pbm->msi_data_mask = *val; - - val = of_get_property(pbm->prom_node, "msix-data-width", &len); - if (!val || len != 4) - goto no_msi; - pbm->msix_data_width = *val; - - arng = of_get_property(pbm->prom_node, "msi-address-ranges", - &len); - if (!arng || len != sizeof(struct addr_range_prop)) - goto no_msi; - pbm->msi32_start = ((u64)arng->msi32_high << 32) | - (u64) arng->msi32_low; - pbm->msi64_start = ((u64)arng->msi64_high << 32) | - (u64) arng->msi64_low; - pbm->msi32_len = arng->msi32_len; - pbm->msi64_len = arng->msi64_len; - - if (msi_bitmap_alloc(pbm)) - goto no_msi; - - if (msi_queue_alloc(pbm)) { - msi_bitmap_free(pbm); - goto no_msi; - } - - printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " - "devino[0x%x]\n", - pbm->name, - pbm->msiq_first, pbm->msiq_num, - pbm->msiq_ent_count, - pbm->msiq_first_devino); - printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " - "width[%u]\n", - pbm->name, - pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, - pbm->msix_data_width); - printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " - "addr64[0x%lx:0x%x]\n", - pbm->name, - pbm->msi32_start, pbm->msi32_len, - pbm->msi64_start, pbm->msi64_len); - printk(KERN_INFO "%s: MSI queues at RA [%p]\n", - pbm->name, - pbm->msi_queues); - } - pbm->setup_msi_irq = pci_sun4v_setup_msi_irq; - pbm->teardown_msi_irq = pci_sun4v_teardown_msi_irq; - - return; - -no_msi: - pbm->msiq_num = 0; - printk(KERN_INFO "%s: No MSI support.\n", pbm->name); -} #else /* CONFIG_PCI_MSI */ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) { @@ -1234,14 +1260,6 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node else pbm = &p->pbm_A; - pbm->next = pci_pbm_root; - pci_pbm_root = pbm; - - pbm->scan_bus = pci_sun4v_scan_bus; - pbm->pci_ops = &pci_sun4v_ops; - - pbm->index = pci_num_pbms++; - pbm->parent = p; pbm->prom_node = dp; @@ -1253,7 +1271,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pci_determine_mem_io_space(pbm); - pci_get_pbm_props(pbm); + pci_sun4v_get_bus_range(pbm); pci_sun4v_iommu_init(pbm); pci_sun4v_msi_init(pbm); } @@ -1261,7 +1279,6 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node void sun4v_pci_init(struct device_node *dp, char *model_name) { struct pci_controller_info *p; - struct pci_pbm_info *pbm; struct iommu *iommu; struct property *prop; struct linux_prom64_registers *regs; @@ -1273,9 +1290,18 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { + for (p = pci_controller_root; p; p = p->next) { + struct pci_pbm_info *pbm; + + if (p->pbm_A.prom_node && p->pbm_B.prom_node) + continue; + + pbm = (p->pbm_A.prom_node ? + &p->pbm_A : + &p->pbm_B); + if (pbm->devhandle == (devhandle ^ 0x40)) { - pci_sun4v_pbm_init(pbm->parent, dp, devhandle); + pci_sun4v_pbm_init(p, dp, devhandle); return; } } @@ -1305,6 +1331,18 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) p->pbm_B.iommu = iommu; + p->next = pci_controller_root; + pci_controller_root = p; + + p->index = pci_num_controllers++; + + p->scan_bus = pci_sun4v_scan_bus; +#ifdef CONFIG_PCI_MSI + p->setup_msi_irq = pci_sun4v_setup_msi_irq; + p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; +#endif + p->pci_ops = &pci_sun4v_ops; + /* Like PSYCHO and SCHIZO we have a 2GB aligned area * for memory space. */ diff --git a/trunk/arch/sparc64/kernel/process.c b/trunk/arch/sparc64/kernel/process.c index 8e3c6e435110..a114151f9fbe 100644 --- a/trunk/arch/sparc64/kernel/process.c +++ b/trunk/arch/sparc64/kernel/process.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc64/kernel/prom.c b/trunk/arch/sparc64/kernel/prom.c index c54d4d8af014..5e1fcd05160d 100644 --- a/trunk/arch/sparc64/kernel/prom.c +++ b/trunk/arch/sparc64/kernel/prom.c @@ -386,9 +386,11 @@ static unsigned int psycho_irq_build(struct device_node *dp, /* Now build the IRQ bucket. */ imap = controller_regs + imap_off; + imap += 4; iclr_off = psycho_iclr_offset(ino); iclr = controller_regs + iclr_off; + iclr += 4; if ((ino & 0x20) == 0) inofixup = ino & 0x03; @@ -396,7 +398,7 @@ static unsigned int psycho_irq_build(struct device_node *dp, return build_irq(inofixup, iclr, imap); } -static void __init psycho_irq_trans_init(struct device_node *dp) +static void psycho_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; @@ -611,9 +613,11 @@ static unsigned int sabre_irq_build(struct device_node *dp, /* Now build the IRQ bucket. */ imap = controller_regs + imap_off; + imap += 4; iclr_off = sabre_iclr_offset(ino); iclr = controller_regs + iclr_off; + iclr += 4; if ((ino & 0x20) == 0) inofixup = ino & 0x03; @@ -636,7 +640,7 @@ static unsigned int sabre_irq_build(struct device_node *dp, return virt_irq; } -static void __init sabre_irq_trans_init(struct device_node *dp) +static void sabre_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; struct sabre_irq_data *irq_data; @@ -675,14 +679,13 @@ static unsigned long schizo_iclr_offset(unsigned long ino) static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs, unsigned int ino) { - - return pbm_regs + schizo_iclr_offset(ino); + return pbm_regs + schizo_iclr_offset(ino) + 4; } static unsigned long schizo_ino_to_imap(unsigned long pbm_regs, unsigned int ino) { - return pbm_regs + schizo_imap_offset(ino); + return pbm_regs + schizo_imap_offset(ino) + 4; } #define schizo_read(__reg) \ @@ -793,8 +796,7 @@ static unsigned int schizo_irq_build(struct device_node *dp, return virt_irq; } -static void __init __schizo_irq_trans_init(struct device_node *dp, - int is_tomatillo) +static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) { const struct linux_prom64_registers *regs; struct schizo_irq_data *irq_data; @@ -816,12 +818,12 @@ static void __init __schizo_irq_trans_init(struct device_node *dp, irq_data->chip_version = of_getintprop_default(dp, "version#", 0); } -static void __init schizo_irq_trans_init(struct device_node *dp) +static void schizo_irq_trans_init(struct device_node *dp) { __schizo_irq_trans_init(dp, 0); } -static void __init tomatillo_irq_trans_init(struct device_node *dp) +static void tomatillo_irq_trans_init(struct device_node *dp) { __schizo_irq_trans_init(dp, 1); } @@ -835,7 +837,7 @@ static unsigned int pci_sun4v_irq_build(struct device_node *dp, return sun4v_build_irq(devhandle, devino); } -static void __init pci_sun4v_irq_trans_init(struct device_node *dp) +static void pci_sun4v_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; @@ -846,85 +848,6 @@ static void __init pci_sun4v_irq_trans_init(struct device_node *dp) dp->irq_trans->data = (void *) (unsigned long) ((regs->phys_addr >> 32UL) & 0x0fffffff); } - -struct fire_irq_data { - unsigned long pbm_regs; - u32 portid; -}; - -#define FIRE_IMAP_BASE 0x001000 -#define FIRE_ICLR_BASE 0x001400 - -static unsigned long fire_imap_offset(unsigned long ino) -{ - return FIRE_IMAP_BASE + (ino * 8UL); -} - -static unsigned long fire_iclr_offset(unsigned long ino) -{ - return FIRE_ICLR_BASE + (ino * 8UL); -} - -static unsigned long fire_ino_to_iclr(unsigned long pbm_regs, - unsigned int ino) -{ - return pbm_regs + fire_iclr_offset(ino); -} - -static unsigned long fire_ino_to_imap(unsigned long pbm_regs, - unsigned int ino) -{ - return pbm_regs + fire_imap_offset(ino); -} - -static unsigned int fire_irq_build(struct device_node *dp, - unsigned int ino, - void *_data) -{ - struct fire_irq_data *irq_data = _data; - unsigned long pbm_regs = irq_data->pbm_regs; - unsigned long imap, iclr; - unsigned long int_ctrlr; - - ino &= 0x3f; - - /* Now build the IRQ bucket. */ - imap = fire_ino_to_imap(pbm_regs, ino); - iclr = fire_ino_to_iclr(pbm_regs, ino); - - /* Set the interrupt controller number. */ - int_ctrlr = 1 << 6; - upa_writeq(int_ctrlr, imap); - - /* The interrupt map registers do not have an INO field - * like other chips do. They return zero in the INO - * field, and the interrupt controller number is controlled - * in bits 6 thru 9. So in order for build_irq() to get - * the INO right we pass it in as part of the fixup - * which will get added to the map register zero value - * read by build_irq(). - */ - ino |= (irq_data->portid << 6); - ino -= int_ctrlr; - return build_irq(ino, iclr, imap); -} - -static void __init fire_irq_trans_init(struct device_node *dp) -{ - const struct linux_prom64_registers *regs; - struct fire_irq_data *irq_data; - - dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); - dp->irq_trans->irq_build = fire_irq_build; - - irq_data = prom_early_alloc(sizeof(struct fire_irq_data)); - - regs = of_get_property(dp, "reg", NULL); - dp->irq_trans->data = irq_data; - - irq_data->pbm_regs = regs[0].phys_addr; - irq_data->portid = of_getintprop_default(dp, "portid", 0); -} #endif /* CONFIG_PCI */ #ifdef CONFIG_SBUS @@ -1072,7 +995,7 @@ static unsigned int sbus_of_build_irq(struct device_node *dp, return build_irq(sbus_level, iclr, imap); } -static void __init sbus_irq_trans_init(struct device_node *dp) +static void sbus_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; @@ -1119,7 +1042,7 @@ static unsigned int central_build_irq(struct device_node *dp, return build_irq(0, iclr, imap); } -static void __init central_irq_trans_init(struct device_node *dp) +static void central_irq_trans_init(struct device_node *dp) { dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); dp->irq_trans->irq_build = central_build_irq; @@ -1133,7 +1056,7 @@ struct irq_trans { }; #ifdef CONFIG_PCI -static struct irq_trans __initdata pci_irq_trans_table[] = { +static struct irq_trans pci_irq_trans_table[] = { { "SUNW,sabre", sabre_irq_trans_init }, { "pci108e,a000", sabre_irq_trans_init }, { "pci108e,a001", sabre_irq_trans_init }, @@ -1146,7 +1069,6 @@ static struct irq_trans __initdata pci_irq_trans_table[] = { { "SUNW,tomatillo", tomatillo_irq_trans_init }, { "pci108e,a801", tomatillo_irq_trans_init }, { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, - { "pciex108e,80f0", fire_irq_trans_init }, }; #endif @@ -1159,7 +1081,7 @@ static unsigned int sun4v_vdev_irq_build(struct device_node *dp, return sun4v_build_irq(devhandle, devino); } -static void __init sun4v_vdev_irq_trans_init(struct device_node *dp) +static void sun4v_vdev_irq_trans_init(struct device_node *dp) { const struct linux_prom64_registers *regs; @@ -1171,7 +1093,7 @@ static void __init sun4v_vdev_irq_trans_init(struct device_node *dp) ((regs->phys_addr >> 32UL) & 0x0fffffff); } -static void __init irq_trans_init(struct device_node *dp) +static void irq_trans_init(struct device_node *dp) { #ifdef CONFIG_PCI const char *model; diff --git a/trunk/arch/sparc64/kernel/sbus.c b/trunk/arch/sparc64/kernel/sbus.c index 91f6e2a74ad5..3b05428cc909 100644 --- a/trunk/arch/sparc64/kernel/sbus.c +++ b/trunk/arch/sparc64/kernel/sbus.c @@ -1002,24 +1002,24 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) u64 control; irq = sbus_build_irq(sbus, SYSIO_UE_INO); - if (request_irq(irq, sysio_ue_handler, 0, - "SYSIO_UE", sbus) < 0) { + if (request_irq(irq, sysio_ue_handler, + IRQF_SHARED, "SYSIO UE", sbus) < 0) { prom_printf("SYSIO[%x]: Cannot register UE interrupt.\n", sbus->portid); prom_halt(); } irq = sbus_build_irq(sbus, SYSIO_CE_INO); - if (request_irq(irq, sysio_ce_handler, 0, - "SYSIO_CE", sbus) < 0) { + if (request_irq(irq, sysio_ce_handler, + IRQF_SHARED, "SYSIO CE", sbus) < 0) { prom_printf("SYSIO[%x]: Cannot register CE interrupt.\n", sbus->portid); prom_halt(); } irq = sbus_build_irq(sbus, SYSIO_SBUSERR_INO); - if (request_irq(irq, sysio_sbus_error_handler, 0, - "SYSIO_SBERR", sbus) < 0) { + if (request_irq(irq, sysio_sbus_error_handler, + IRQF_SHARED, "SYSIO SBUS Error", sbus) < 0) { prom_printf("SYSIO[%x]: Cannot register SBUS Error interrupt.\n", sbus->portid); prom_halt(); diff --git a/trunk/arch/sparc64/kernel/signal.c b/trunk/arch/sparc64/kernel/signal.c index 203e87301005..96d56a8410ad 100644 --- a/trunk/arch/sparc64/kernel/signal.c +++ b/trunk/arch/sparc64/kernel/signal.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc64/kernel/signal32.c b/trunk/arch/sparc64/kernel/signal32.c index 8c1c121330fb..c45f21b881d5 100644 --- a/trunk/arch/sparc64/kernel/signal32.c +++ b/trunk/arch/sparc64/kernel/signal32.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc64/kernel/smp.c b/trunk/arch/sparc64/kernel/smp.c index 8087d67a0cf8..d4f0a70f4845 100644 --- a/trunk/arch/sparc64/kernel/smp.c +++ b/trunk/arch/sparc64/kernel/smp.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -1342,11 +1343,11 @@ void __init setup_per_cpu_areas(void) /* Copy section for each CPU (we discard the original) */ goal = PERCPU_ENOUGH_ROOM; - __per_cpu_shift = PAGE_SHIFT; - for (size = PAGE_SIZE; size < goal; size <<= 1UL) + __per_cpu_shift = 0; + for (size = 1UL; size < goal; size <<= 1UL) __per_cpu_shift++; - ptr = alloc_bootmem_pages(size * NR_CPUS); + ptr = alloc_bootmem(size * NR_CPUS); __per_cpu_base = ptr - __per_cpu_start; diff --git a/trunk/arch/sparc64/kernel/stacktrace.c b/trunk/arch/sparc64/kernel/stacktrace.c index 47f92a59be18..c4d15f2762b9 100644 --- a/trunk/arch/sparc64/kernel/stacktrace.c +++ b/trunk/arch/sparc64/kernel/stacktrace.c @@ -3,16 +3,22 @@ #include #include -void save_stack_trace(struct stack_trace *trace) +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) { unsigned long ksp, fp, thread_base; - struct thread_info *tp = task_thread_info(current); + struct thread_info *tp; - flushw_all(); - __asm__ __volatile__( - "mov %%fp, %0" - : "=r" (ksp) - ); + if (!task) + task = current; + tp = task_thread_info(task); + if (task == current) { + flushw_all(); + __asm__ __volatile__( + "mov %%fp, %0" + : "=r" (ksp) + ); + } else + ksp = tp->ksp; fp = ksp + STACK_BIAS; thread_base = (unsigned long) tp; diff --git a/trunk/arch/sparc64/kernel/sunos_ioctl32.c b/trunk/arch/sparc64/kernel/sunos_ioctl32.c index 75d2bad49839..a05e43d51755 100644 --- a/trunk/arch/sparc64/kernel/sunos_ioctl32.c +++ b/trunk/arch/sparc64/kernel/sunos_ioctl32.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc64/kernel/sys_sparc.c b/trunk/arch/sparc64/kernel/sys_sparc.c index d108eeb0734f..a53d4abb4b49 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc.c +++ b/trunk/arch/sparc64/kernel/sys_sparc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc64/kernel/sys_sparc32.c b/trunk/arch/sparc64/kernel/sys_sparc32.c index abd83129b2e7..7876a0226285 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc32.c +++ b/trunk/arch/sparc64/kernel/sys_sparc32.c @@ -775,25 +775,15 @@ asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, asmlinkage long sys32_utimes(char __user *filename, struct compat_timeval __user *tvs) { - struct timespec tv[2]; + struct timeval ktvs[2]; if (tvs) { - struct timeval ktvs[2]; if (get_tv32(&ktvs[0], tvs) || get_tv32(&ktvs[1], 1+tvs)) return -EFAULT; - - if (ktvs[0].tv_usec < 0 || ktvs[0].tv_usec >= 1000000 || - ktvs[1].tv_usec < 0 || ktvs[1].tv_usec >= 1000000) - return -EINVAL; - - tv[0].tv_sec = ktvs[0].tv_sec; - tv[0].tv_nsec = 1000 * ktvs[0].tv_usec; - tv[1].tv_sec = ktvs[1].tv_sec; - tv[1].tv_nsec = 1000 * ktvs[1].tv_usec; } - return do_utimes(AT_FDCWD, filename, tvs ? tv : NULL, 0); + return do_utimes(AT_FDCWD, filename, (tvs ? &ktvs[0] : NULL)); } /* These are here just in case some old sparc32 binary calls it. */ diff --git a/trunk/arch/sparc64/kernel/systbls.S b/trunk/arch/sparc64/kernel/systbls.S index 5fe7f9ad4a92..48c36fe6dc62 100644 --- a/trunk/arch/sparc64/kernel/systbls.S +++ b/trunk/arch/sparc64/kernel/systbls.S @@ -81,7 +81,6 @@ sys_call_table32: .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait -/*310*/ .word compat_sys_utimensat #endif /* CONFIG_COMPAT */ @@ -153,7 +152,6 @@ sys_call_table: .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait -/*310*/ .word sys_utimensat #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -271,6 +269,5 @@ sunos_sys_table: .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys -/*310*/ .long sunos_nosys #endif diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index dc652f210290..ad67784292db 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -15,9 +15,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -36,12 +36,26 @@ #include #include #include +#include #include #ifdef CONFIG_KMOD #include #endif #include +ATOMIC_NOTIFIER_HEAD(sparc64die_chain); + +int register_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&sparc64die_chain, nb); +} +EXPORT_SYMBOL(register_die_notifier); + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&sparc64die_chain, nb); +} +EXPORT_SYMBOL(unregister_die_notifier); /* When an irrecoverable trap occurs at tl > 0, the trap entry * code logs the trap state registers at every level in the trap diff --git a/trunk/arch/sparc64/kernel/unaligned.c b/trunk/arch/sparc64/kernel/unaligned.c index 953be816fa25..bc18d480dd1c 100644 --- a/trunk/arch/sparc64/kernel/unaligned.c +++ b/trunk/arch/sparc64/kernel/unaligned.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc64/mm/fault.c b/trunk/arch/sparc64/mm/fault.c index b582024d2199..55ae802dc0ad 100644 --- a/trunk/arch/sparc64/mm/fault.c +++ b/trunk/arch/sparc64/mm/fault.c @@ -15,11 +15,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include @@ -29,26 +29,40 @@ #include #include #include +#include #include #ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs) +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); + +/* Hook to register for page fault notifications */ +int register_page_fault_notifier(struct notifier_block *nb) { - int ret = 0; - - /* kprobe_running() needs smp_processor_id() */ - if (!user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, 0)) - ret = 1; - preempt_enable(); - } - return ret; + return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); +} + +int unregister_page_fault_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); +} + +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig + }; + return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } #else -static inline int notify_page_fault(struct pt_regs *regs) +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) { - return 0; + return NOTIFY_DONE; } #endif @@ -107,6 +121,9 @@ static void __kprobes unhandled_fault(unsigned long address, printk(KERN_ALERT "tsk->{mm,active_mm}->pgd = %016lx\n", (tsk->mm ? (unsigned long) tsk->mm->pgd : (unsigned long) tsk->active_mm->pgd)); + if (notify_die(DIE_GPF, "general protection fault", regs, + 0, 0, SIGSEGV) == NOTIFY_STOP) + return; die_if_kernel("Oops", regs); } @@ -283,7 +300,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) fault_code = get_thread_fault_code(); - if (notify_page_fault(regs)) + if (notify_page_fault(DIE_PAGE_FAULT, "page_fault", regs, + fault_code, 0, SIGSEGV) == NOTIFY_STOP) return; si_code = SEGV_MAPERR; diff --git a/trunk/arch/sparc64/mm/hugetlbpage.c b/trunk/arch/sparc64/mm/hugetlbpage.c index eaba9b70b184..00677b5e1d7d 100644 --- a/trunk/arch/sparc64/mm/hugetlbpage.c +++ b/trunk/arch/sparc64/mm/hugetlbpage.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -174,12 +175,6 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr, if (len > task_size) return -ENOMEM; - if (flags & MAP_FIXED) { - if (prepare_hugepage_range(addr, len, pgoff)) - return -EINVAL; - return addr; - } - if (addr) { addr = ALIGN(addr, HPAGE_SIZE); vma = find_vma(mm, addr); diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index d7004eaf1c8e..cafadcbcdf38 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -164,6 +164,30 @@ unsigned long sparc64_kern_sec_context __read_mostly; int bigkernel = 0; +struct kmem_cache *pgtable_cache __read_mostly; + +static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) +{ + clear_page(addr); +} + +extern void tsb_cache_init(void); + +void pgtable_cache_init(void) +{ + pgtable_cache = kmem_cache_create("pgtable_cache", + PAGE_SIZE, PAGE_SIZE, + SLAB_HWCACHE_ALIGN | + SLAB_MUST_HWCACHE_ALIGN, + zero_ctor, + NULL); + if (!pgtable_cache) { + prom_printf("Could not create pgtable_cache\n"); + prom_halt(); + } + tsb_cache_init(); +} + #ifdef CONFIG_DEBUG_DCFLUSH atomic_t dcpage_flushes = ATOMIC_INIT(0); #ifdef CONFIG_SMP diff --git a/trunk/arch/sparc64/mm/tsb.c b/trunk/arch/sparc64/mm/tsb.c index 8eb8a7c76ec9..236d02f41a01 100644 --- a/trunk/arch/sparc64/mm/tsb.c +++ b/trunk/arch/sparc64/mm/tsb.c @@ -252,7 +252,7 @@ static const char *tsb_cache_names[8] = { "tsb_1MB", }; -void __init pgtable_cache_init(void) +void __init tsb_cache_init(void) { unsigned long i; @@ -262,7 +262,8 @@ void __init pgtable_cache_init(void) tsb_caches[i] = kmem_cache_create(name, size, size, - 0, + SLAB_HWCACHE_ALIGN | + SLAB_MUST_HWCACHE_ALIGN, NULL, NULL); if (!tsb_caches[i]) { prom_printf("Could not create %s cache\n", name); diff --git a/trunk/arch/sparc64/solaris/ioctl.c b/trunk/arch/sparc64/solaris/ioctl.c index 18352a498628..330743c5b3d8 100644 --- a/trunk/arch/sparc64/solaris/ioctl.c +++ b/trunk/arch/sparc64/solaris/ioctl.c @@ -686,8 +686,7 @@ static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg) int i = 0; read_lock_bh(&dev_base_lock); - for_each_netdev(d) - i++; + for (d = dev_base; d; d = d->next) i++; read_unlock_bh(&dev_base_lock); if (put_user (i, (int __user *)A(arg))) diff --git a/trunk/arch/sparc64/solaris/ipc.c b/trunk/arch/sparc64/solaris/ipc.c index a531a2cdb381..8cef5fd57b2e 100644 --- a/trunk/arch/sparc64/solaris/ipc.c +++ b/trunk/arch/sparc64/solaris/ipc.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/trunk/arch/sparc64/solaris/misc.c b/trunk/arch/sparc64/solaris/misc.c index 3b67de7455f1..542c808ec2c8 100644 --- a/trunk/arch/sparc64/solaris/misc.c +++ b/trunk/arch/sparc64/solaris/misc.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include diff --git a/trunk/arch/sparc64/solaris/signal.c b/trunk/arch/sparc64/solaris/signal.c index de10c9716cfb..7fa2634e2085 100644 --- a/trunk/arch/sparc64/solaris/signal.c +++ b/trunk/arch/sparc64/solaris/signal.c @@ -5,6 +5,7 @@ */ #include +#include #include #include diff --git a/trunk/arch/sparc64/solaris/socket.c b/trunk/arch/sparc64/solaris/socket.c index cc69847cf240..d3a66ea74a7f 100644 --- a/trunk/arch/sparc64/solaris/socket.c +++ b/trunk/arch/sparc64/solaris/socket.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include diff --git a/trunk/arch/sparc64/solaris/socksys.c b/trunk/arch/sparc64/solaris/socksys.c index e94f6e5d9455..c2864447de82 100644 --- a/trunk/arch/sparc64/solaris/socksys.c +++ b/trunk/arch/sparc64/solaris/socksys.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/um/defconfig b/trunk/arch/um/defconfig index f938fa822146..780cc0a4a128 100644 --- a/trunk/arch/um/defconfig +++ b/trunk/arch/um/defconfig @@ -41,7 +41,6 @@ CONFIG_M686=y # CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set -# CONFIG_MVIAC7 is not set # CONFIG_X86_GENERIC is not set CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y diff --git a/trunk/arch/um/drivers/chan_kern.c b/trunk/arch/um/drivers/chan_kern.c index 3aa351611763..9fdfad649536 100644 --- a/trunk/arch/um/drivers/chan_kern.c +++ b/trunk/arch/um/drivers/chan_kern.c @@ -12,6 +12,7 @@ #include #include #include "chan_kern.h" +#include "user_util.h" #include "kern.h" #include "irq_user.h" #include "sigio.h" diff --git a/trunk/arch/um/drivers/chan_user.c b/trunk/arch/um/drivers/chan_user.c index 13f0bf852b2a..0cad3546cb89 100644 --- a/trunk/arch/um/drivers/chan_user.c +++ b/trunk/arch/um/drivers/chan_user.c @@ -14,6 +14,7 @@ #include #include #include "kern_util.h" +#include "user_util.h" #include "chan_user.h" #include "user.h" #include "os.h" @@ -157,7 +158,7 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) */ err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); if(err < 0){ - printk("fork of winch_thread failed - errno = %d\n", -err); + printk("fork of winch_thread failed - errno = %d\n", errno); goto out_close; } @@ -203,3 +204,14 @@ void register_winch(int fd, struct tty_struct *tty) } } } + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/cow_sys.h b/trunk/arch/um/drivers/cow_sys.h index 15453845d2ba..c6a308464acb 100644 --- a/trunk/arch/um/drivers/cow_sys.h +++ b/trunk/arch/um/drivers/cow_sys.h @@ -2,13 +2,14 @@ #define __COW_SYS_H__ #include "kern_util.h" +#include "user_util.h" #include "os.h" #include "user.h" #include "um_malloc.h" static inline void *cow_malloc(int size) { - return um_kmalloc(size); + return(um_kmalloc(size)); } static inline void cow_free(void *ptr) @@ -20,22 +21,29 @@ static inline void cow_free(void *ptr) static inline char *cow_strdup(char *str) { - return uml_strdup(str); + return(uml_strdup(str)); } static inline int cow_seek_file(int fd, __u64 offset) { - return os_seek_file(fd, offset); + return(os_seek_file(fd, offset)); } static inline int cow_file_size(char *file, unsigned long long *size_out) { - return os_file_size(file, size_out); + return(os_file_size(file, size_out)); } static inline int cow_write_file(int fd, void *buf, int size) { - return os_write_file(fd, buf, size); + return(os_write_file(fd, buf, size)); } #endif + +/* + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/daemon_user.c b/trunk/arch/um/drivers/daemon_user.c index b869e3899683..021b82c7a759 100644 --- a/trunk/arch/um/drivers/daemon_user.c +++ b/trunk/arch/um/drivers/daemon_user.c @@ -14,6 +14,7 @@ #include "net_user.h" #include "daemon.h" #include "kern_util.h" +#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" @@ -38,11 +39,11 @@ static struct sockaddr_un *new_addr(void *name, int len) sun = um_kmalloc(sizeof(struct sockaddr_un)); if(sun == NULL){ printk("new_addr: allocation of sockaddr_un failed\n"); - return NULL; + return(NULL); } sun->sun_family = AF_UNIX; memcpy(sun->sun_path, name, len); - return sun; + return(sun); } static int connect_to_switch(struct daemon_data *pri) @@ -111,7 +112,7 @@ static int connect_to_switch(struct daemon_data *pri) } pri->data_addr = sun; - return fd; + return(fd); out_free: kfree(sun); @@ -119,10 +120,10 @@ static int connect_to_switch(struct daemon_data *pri) os_close_file(fd); out: os_close_file(pri->control); - return err; + return(err); } -static int daemon_user_init(void *data, void *dev) +static void daemon_user_init(void *data, void *dev) { struct daemon_data *pri = data; struct timeval tv; @@ -145,16 +146,13 @@ static int daemon_user_init(void *data, void *dev) if(pri->fd < 0){ kfree(pri->local_addr); pri->local_addr = NULL; - return pri->fd; } - - return 0; } static int daemon_open(void *data) { struct daemon_data *pri = data; - return pri->fd; + return(pri->fd); } static void daemon_remove(void *data) @@ -178,12 +176,12 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) { struct sockaddr_un *data_addr = pri->data_addr; - return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); } static int daemon_set_mtu(int mtu, void *data) { - return mtu; + return(mtu); } const struct net_user_info daemon_user_info = { @@ -196,3 +194,14 @@ const struct net_user_info daemon_user_info = { .delete_address = NULL, .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/fd.c b/trunk/arch/um/drivers/fd.c index 7f083ec47a4f..218aa0e9b792 100644 --- a/trunk/arch/um/drivers/fd.c +++ b/trunk/arch/um/drivers/fd.c @@ -9,6 +9,7 @@ #include #include #include "user.h" +#include "user_util.h" #include "chan_user.h" #include "os.h" #include "um_malloc.h" diff --git a/trunk/arch/um/drivers/harddog_user.c b/trunk/arch/um/drivers/harddog_user.c index 5eeecf8917c3..c495ecf263b1 100644 --- a/trunk/arch/um/drivers/harddog_user.c +++ b/trunk/arch/um/drivers/harddog_user.c @@ -6,6 +6,7 @@ #include #include #include +#include "user_util.h" #include "user.h" #include "mconsole.h" #include "os.h" diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index ced99106f798..f75d7b05c481 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -13,6 +13,7 @@ #include "irq_user.h" #include "line.h" #include "kern.h" +#include "user_util.h" #include "kern_util.h" #include "os.h" #include "irq_kern.h" diff --git a/trunk/arch/um/drivers/mcast_user.c b/trunk/arch/um/drivers/mcast_user.c index d319db16d4ec..b827e82884c9 100644 --- a/trunk/arch/um/drivers/mcast_user.c +++ b/trunk/arch/um/drivers/mcast_user.c @@ -20,6 +20,7 @@ #include "net_user.h" #include "mcast.h" #include "kern_util.h" +#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" @@ -33,21 +34,20 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) sin = um_kmalloc(sizeof(struct sockaddr_in)); if(sin == NULL){ printk("new_addr: allocation of sockaddr_in failed\n"); - return NULL; + return(NULL); } sin->sin_family = AF_INET; sin->sin_addr.s_addr = in_aton(addr); sin->sin_port = htons(port); - return sin; + return(sin); } -static int mcast_user_init(void *data, void *dev) +static void mcast_user_init(void *data, void *dev) { struct mcast_data *pri = data; pri->mcast_addr = new_addr(pri->addr, pri->port); pri->dev = dev; - return 0; } static void mcast_remove(void *data) @@ -107,8 +107,8 @@ static int mcast_open(void *data) err = -errno; printk("mcast_open : data bind failed, errno = %d\n", errno); goto out_close; - } - + } + /* subscribe to the multicast group */ mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; mreq.imr_interface.s_addr = 0; @@ -153,12 +153,12 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) { struct sockaddr_in *data_addr = pri->mcast_addr; - return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); + return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); } static int mcast_set_mtu(int mtu, void *data) { - return mtu; + return(mtu); } const struct net_user_info mcast_user_info = { diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index 542c9ef858f8..65ad2932672c 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -25,6 +25,7 @@ #include "linux/console.h" #include "asm/irq.h" #include "asm/uaccess.h" +#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "mconsole.h" diff --git a/trunk/arch/um/drivers/mconsole_user.c b/trunk/arch/um/drivers/mconsole_user.c index 62e5ad63181a..f02634fbf32a 100644 --- a/trunk/arch/um/drivers/mconsole_user.c +++ b/trunk/arch/um/drivers/mconsole_user.c @@ -17,6 +17,7 @@ #include "sysdep/ptrace.h" #include "mconsole.h" #include "os.h" +#include "user_util.h" static struct mconsole_command commands[] = { /* With uts namespaces, uts information becomes process-specific, so diff --git a/trunk/arch/um/drivers/mmapper_kern.c b/trunk/arch/um/drivers/mmapper_kern.c index e41a08f04694..df3516e47d4d 100644 --- a/trunk/arch/um/drivers/mmapper_kern.c +++ b/trunk/arch/um/drivers/mmapper_kern.c @@ -15,6 +15,7 @@ #include #include #include "mem_user.h" +#include "user_util.h" /* These are set in mmapper_init, which is called at boot time */ static unsigned long mmapper_size; diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index 72773dd54425..859303730b2f 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -21,6 +21,7 @@ #include "linux/ethtool.h" #include "linux/platform_device.h" #include "asm/uaccess.h" +#include "user_util.h" #include "kern_util.h" #include "net_kern.h" #include "net_user.h" @@ -283,7 +284,7 @@ void uml_net_user_timer_expire(unsigned long _conn) #endif } -static void setup_etheraddr(char *str, unsigned char *addr, char *name) +static void setup_etheraddr(char *str, unsigned char *addr) { char *end; int i; @@ -302,34 +303,15 @@ static void setup_etheraddr(char *str, unsigned char *addr, char *name) } str = end + 1; } - if (is_multicast_ether_addr(addr)) { + if(addr[0] & 1){ printk(KERN_ERR - "Attempt to assign a multicast ethernet address to a " + "Attempt to assign a broadcast ethernet address to a " "device disallowed\n"); goto random; } - if (!is_valid_ether_addr(addr)) { - printk(KERN_ERR - "Attempt to assign an invalid ethernet address to a " - "device disallowed\n"); - goto random; - } - if (!is_local_ether_addr(addr)) { - printk(KERN_WARNING - "Warning: attempt to assign a globally valid ethernet " - "address to a device\n"); - printk(KERN_WARNING "You should better enable the 2nd " - "rightmost bit in the first byte of the MAC,\n"); - printk(KERN_WARNING "i.e. %02x:%02x:%02x:%02x:%02x:%02x\n", - addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], - addr[5]); - goto random; - } return; random: - printk(KERN_INFO - "Choosing a random ethernet address for device %s\n", name); random_ether_addr(addr); } @@ -343,53 +325,31 @@ static struct platform_driver uml_net_driver = { }; static int driver_registered; -static void net_device_release(struct device *dev) -{ - struct uml_net *device = dev->driver_data; - struct net_device *netdev = device->dev; - struct uml_net_private *lp = netdev->priv; - - if(lp->remove != NULL) - (*lp->remove)(&lp->user); - list_del(&device->list); - kfree(device); - free_netdev(netdev); -} - -static void eth_configure(int n, void *init, char *mac, - struct transport *transport) +static int eth_configure(int n, void *init, char *mac, + struct transport *transport) { struct uml_net *device; struct net_device *dev; struct uml_net_private *lp; - int err, size; + int save, err, size; - size = transport->private_size + sizeof(struct uml_net_private); + size = transport->private_size + sizeof(struct uml_net_private) + + sizeof(((struct uml_net_private *) 0)->user); device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) { - printk(KERN_ERR "eth_configure failed to allocate struct " - "uml_net\n"); - return; - } - - dev = alloc_etherdev(size); - if (dev == NULL) { - printk(KERN_ERR "eth_configure: failed to allocate struct " - "net_device for eth%d\n", n); - goto out_free_device; + printk(KERN_ERR "eth_configure failed to allocate uml_net\n"); + return(1); } INIT_LIST_HEAD(&device->list); device->index = n; - /* If this name ends up conflicting with an existing registered - * netdevice, that is OK, register_netdev{,ice}() will notice this - * and fail. - */ - snprintf(dev->name, sizeof(dev->name), "eth%d", n); + spin_lock(&devices_lock); + list_add(&device->list, &devices); + spin_unlock(&devices_lock); - setup_etheraddr(mac, device->mac, dev->name); + setup_etheraddr(mac, device->mac); printk(KERN_INFO "Netdevice %d ", n); printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", @@ -397,6 +357,11 @@ static void eth_configure(int n, void *init, char *mac, device->mac[2], device->mac[3], device->mac[4], device->mac[5]); printk(": "); + dev = alloc_etherdev(size); + if (dev == NULL) { + printk(KERN_ERR "eth_configure: failed to allocate device\n"); + return 1; + } lp = dev->priv; /* This points to the transport private data. It's still clear, but we @@ -411,20 +376,47 @@ static void eth_configure(int n, void *init, char *mac, } device->pdev.id = n; device->pdev.name = DRIVER_NAME; - device->pdev.dev.release = net_device_release; - device->pdev.dev.driver_data = device; - if(platform_device_register(&device->pdev)) - goto out_free_netdev; + platform_device_register(&device->pdev); SET_NETDEV_DEV(dev,&device->pdev.dev); + /* If this name ends up conflicting with an existing registered + * netdevice, that is OK, register_netdev{,ice}() will notice this + * and fail. + */ + snprintf(dev->name, sizeof(dev->name), "eth%d", n); device->dev = dev; - /* - * These just fill in a data structure, so there's no failure - * to be worried about. - */ (*transport->kern->init)(dev, init); + dev->mtu = transport->user->max_packet; + dev->open = uml_net_open; + dev->hard_start_xmit = uml_net_start_xmit; + dev->stop = uml_net_close; + dev->get_stats = uml_net_get_stats; + dev->set_multicast_list = uml_net_set_multicast_list; + dev->tx_timeout = uml_net_tx_timeout; + dev->set_mac_address = uml_net_set_mac; + dev->change_mtu = uml_net_change_mtu; + dev->ethtool_ops = ¨_net_ethtool_ops; + dev->watchdog_timeo = (HZ >> 1); + dev->irq = UM_ETH_IRQ; + + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) { + device->dev = NULL; + /* XXX: should we call ->remove() here? */ + free_netdev(dev); + return 1; + } + + /* lp.user is the first four bytes of the transport data, which + * has already been initialized. This structure assignment will + * overwrite that, so we make sure that .user gets overwritten with + * what it already has. + */ + save = lp->user[0]; *lp = ((struct uml_net_private) { .list = LIST_HEAD_INIT(lp->list), .dev = dev, @@ -438,53 +430,20 @@ static void eth_configure(int n, void *init, char *mac, .write = transport->kern->write, .add_address = transport->user->add_address, .delete_address = transport->user->delete_address, - .set_mtu = transport->user->set_mtu }); + .set_mtu = transport->user->set_mtu, + .user = { save } }); init_timer(&lp->tl); spin_lock_init(&lp->lock); lp->tl.function = uml_net_user_timer_expire; memcpy(lp->mac, device->mac, sizeof(lp->mac)); - if ((transport->user->init != NULL) && - ((*transport->user->init)(&lp->user, dev) != 0)) - goto out_unregister; + if (transport->user->init) + (*transport->user->init)(&lp->user, dev); set_ether_mac(dev, device->mac); - dev->mtu = transport->user->max_packet; - dev->open = uml_net_open; - dev->hard_start_xmit = uml_net_start_xmit; - dev->stop = uml_net_close; - dev->get_stats = uml_net_get_stats; - dev->set_multicast_list = uml_net_set_multicast_list; - dev->tx_timeout = uml_net_tx_timeout; - dev->set_mac_address = uml_net_set_mac; - dev->change_mtu = uml_net_change_mtu; - dev->ethtool_ops = ¨_net_ethtool_ops; - dev->watchdog_timeo = (HZ >> 1); - dev->irq = UM_ETH_IRQ; - rtnl_lock(); - err = register_netdevice(dev); - rtnl_unlock(); - if (err) - goto out_undo_user_init; - - spin_lock(&devices_lock); - list_add(&device->list, &devices); - spin_unlock(&devices_lock); - - return; - -out_undo_user_init: - if (transport->user->remove != NULL) - (*transport->user->remove)(&lp->user); -out_unregister: - platform_device_unregister(&device->pdev); - return; /* platform_device_unregister frees dev and device */ -out_free_netdev: - free_netdev(dev); -out_free_device: - kfree(device); + return 0; } static struct uml_net *find_device(int n) @@ -707,9 +666,13 @@ static int net_remove(int n, char **error_out) lp = dev->priv; if(lp->fd > 0) return -EBUSY; + if(lp->remove != NULL) (*lp->remove)(&lp->user); unregister_netdev(dev); platform_device_unregister(&device->pdev); + list_del(&device->list); + kfree(device); + free_netdev(dev); return 0; } diff --git a/trunk/arch/um/drivers/net_user.c b/trunk/arch/um/drivers/net_user.c index 3503cff867c3..0ffd7ac295d4 100644 --- a/trunk/arch/um/drivers/net_user.c +++ b/trunk/arch/um/drivers/net_user.c @@ -14,11 +14,11 @@ #include #include #include "user.h" +#include "user_util.h" #include "kern_util.h" #include "net_user.h" #include "os.h" #include "um_malloc.h" -#include "kern_constants.h" int tap_open_common(void *dev, char *gate_addr) { @@ -216,7 +216,7 @@ static void change(char *dev, char *what, unsigned char *addr, sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], netmask[2], netmask[3]); - output_len = UM_KERN_PAGE_SIZE; + output_len = page_size(); output = um_kmalloc(output_len); if(output == NULL) printk("change : failed to allocate output buffer\n"); diff --git a/trunk/arch/um/drivers/pcap_kern.c b/trunk/arch/um/drivers/pcap_kern.c index c329931673d6..948849343ca4 100644 --- a/trunk/arch/um/drivers/pcap_kern.c +++ b/trunk/arch/um/drivers/pcap_kern.c @@ -29,25 +29,21 @@ void pcap_init(struct net_device *dev, void *data) ppri->promisc = init->promisc; ppri->optimize = init->optimize; ppri->filter = init->filter; - - printk("pcap backend, host interface %s\n", ppri->host_if); } -static int pcap_read(int fd, struct sk_buff **skb, +static int pcap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) { *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); - if(*skb == NULL) - return -ENOMEM; - - return pcap_user_read(fd, skb_mac_header(*skb), + if(*skb == NULL) return(-ENOMEM); + return(pcap_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu + ETH_HEADER_OTHER, - (struct pcap_data *) &lp->user); + (struct pcap_data *) &lp->user)); } static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) { - return -EPERM; + return(-EPERM); } static const struct net_kern_info pcap_kern_info = { @@ -69,12 +65,12 @@ int pcap_setup(char *str, char **mac_out, void *data) .optimize = 0, .filter = NULL }); - remain = split_if_spec(str, &host_if, &init->filter, - &options[0], &options[1], mac_out, NULL); + remain = split_if_spec(str, &host_if, &init->filter, + &options[0], &options[1], NULL); if(remain != NULL){ printk(KERN_ERR "pcap_setup - Extra garbage on " "specification : '%s'\n", remain); - return 0; + return(0); } if(host_if != NULL) @@ -91,13 +87,10 @@ int pcap_setup(char *str, char **mac_out, void *data) init->optimize = 1; else if(!strcmp(options[i], "nooptimize")) init->optimize = 0; - else { - printk("pcap_setup : bad option - '%s'\n", options[i]); - return 0; - } + else printk("pcap_setup : bad option - '%s'\n", options[i]); } - return 1; + return(1); } static struct transport pcap_transport = { diff --git a/trunk/arch/um/drivers/pcap_user.c b/trunk/arch/um/drivers/pcap_user.c index 483aa15222a4..11921a7baa7b 100644 --- a/trunk/arch/um/drivers/pcap_user.c +++ b/trunk/arch/um/drivers/pcap_user.c @@ -13,13 +13,12 @@ #include "pcap_user.h" #include "user.h" #include "um_malloc.h" -#include "kern_constants.h" #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) #define PCAP_FD(p) (*(int *)(p)) -static int pcap_user_init(void *data, void *dev) +static void pcap_user_init(void *data, void *dev) { struct pcap_data *pri = data; pcap_t *p; @@ -27,14 +26,13 @@ static int pcap_user_init(void *data, void *dev) p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors); if(p == NULL){ - printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - " - "'%s'\n", errors); - return -EINVAL; + printk("pcap_user_init : pcap_open_live failed - '%s'\n", + errors); + return; } pri->dev = dev; pri->pcap = p; - return 0; } static int pcap_open(void *data) @@ -44,39 +42,39 @@ static int pcap_open(void *data) int err; if(pri->pcap == NULL) - return -ENODEV; + return(-ENODEV); if(pri->filter != NULL){ err = dev_netmask(pri->dev, &netmask); if(err < 0){ - printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n"); - return -EIO; + printk("pcap_open : dev_netmask failed\n"); + return(-EIO); } pri->compiled = um_kmalloc(sizeof(struct bpf_program)); if(pri->compiled == NULL){ - printk(UM_KERN_ERR "pcap_open : kmalloc failed\n"); - return -ENOMEM; + printk("pcap_open : kmalloc failed\n"); + return(-ENOMEM); } - + err = pcap_compile(pri->pcap, (struct bpf_program *) pri->compiled, pri->filter, pri->optimize, netmask); if(err < 0){ - printk(UM_KERN_ERR "pcap_open : pcap_compile failed - " - "'%s'\n", pcap_geterr(pri->pcap)); - return -EIO; + printk("pcap_open : pcap_compile failed - '%s'\n", + pcap_geterr(pri->pcap)); + return(-EIO); } err = pcap_setfilter(pri->pcap, pri->compiled); if(err < 0){ - printk(UM_KERN_ERR "pcap_open : pcap_setfilter " - "failed - '%s'\n", pcap_geterr(pri->pcap)); - return -EIO; + printk("pcap_open : pcap_setfilter failed - '%s'\n", + pcap_geterr(pri->pcap)); + return(-EIO); } } - - return PCAP_FD(pri->pcap); + + return(PCAP_FD(pri->pcap)); } static void pcap_remove(void *data) @@ -86,8 +84,7 @@ static void pcap_remove(void *data) if(pri->compiled != NULL) pcap_freecode(pri->compiled); - if(pri->pcap != NULL) - pcap_close(pri->pcap); + pcap_close(pri->pcap); } struct pcap_handler_data { @@ -116,13 +113,12 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); if(n < 0){ - printk(UM_KERN_ERR "pcap_dispatch failed - %s\n", - pcap_geterr(pri->pcap)); - return -EIO; + printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap)); + return(-EIO); } else if(n == 0) - return 0; - return hdata.len; + return(0); + return(hdata.len); } const struct net_user_info pcap_user_info = { @@ -135,3 +131,14 @@ const struct net_user_info pcap_user_info = { .delete_address = NULL, .max_packet = MAX_PACKET - ETH_HEADER_OTHER }; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/port_user.c b/trunk/arch/um/drivers/port_user.c index 3f6357d24bee..80508023054f 100644 --- a/trunk/arch/um/drivers/port_user.c +++ b/trunk/arch/um/drivers/port_user.c @@ -13,6 +13,7 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "chan_user.h" diff --git a/trunk/arch/um/drivers/pty.c b/trunk/arch/um/drivers/pty.c index df4976c9eef2..829a5eca8c07 100644 --- a/trunk/arch/um/drivers/pty.c +++ b/trunk/arch/um/drivers/pty.c @@ -4,13 +4,13 @@ */ #include -#include #include #include #include #include #include "chan_user.h" #include "user.h" +#include "user_util.h" #include "kern_util.h" #include "os.h" #include "um_malloc.h" diff --git a/trunk/arch/um/drivers/slip_user.c b/trunk/arch/um/drivers/slip_user.c index 78f0e515da8f..7eddacc53b6e 100644 --- a/trunk/arch/um/drivers/slip_user.c +++ b/trunk/arch/um/drivers/slip_user.c @@ -8,6 +8,7 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "net_user.h" @@ -15,14 +16,12 @@ #include "slip_common.h" #include "os.h" #include "um_malloc.h" -#include "kern_constants.h" -static int slip_user_init(void *data, void *dev) +void slip_user_init(void *data, void *dev) { struct slip_data *pri = data; pri->dev = dev; - return 0; } static int set_up_tty(int fd) @@ -90,7 +89,7 @@ static int slip_tramp(char **argv, int fd) goto out_close; pid = err; - output_len = UM_KERN_PAGE_SIZE; + output_len = page_size(); output = um_kmalloc(output_len); if(output == NULL){ printk("slip_tramp : failed to allocate output buffer\n"); diff --git a/trunk/arch/um/drivers/slirp_user.c b/trunk/arch/um/drivers/slirp_user.c index 39f889fe9949..ce5e85d1de3d 100644 --- a/trunk/arch/um/drivers/slirp_user.c +++ b/trunk/arch/um/drivers/slirp_user.c @@ -7,6 +7,7 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "net_user.h" @@ -14,12 +15,11 @@ #include "slip_common.h" #include "os.h" -static int slirp_user_init(void *data, void *dev) +void slirp_user_init(void *data, void *dev) { struct slirp_data *pri = data; pri->dev = dev; - return 0; } struct slirp_pre_exec_data { diff --git a/trunk/arch/um/drivers/ssl.c b/trunk/arch/um/drivers/ssl.c index fd09ad9e9c0a..4b382a6e710f 100644 --- a/trunk/arch/um/drivers/ssl.c +++ b/trunk/arch/um/drivers/ssl.c @@ -15,6 +15,7 @@ #include "line.h" #include "ssl.h" #include "chan_kern.h" +#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "init.h" @@ -191,12 +192,12 @@ static int ssl_init(void) ssl_driver = register_lines(&driver, &ssl_ops, serial_lines, ARRAY_SIZE(serial_lines)); + lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts); + new_title = add_xterm_umid(opts.xterm_title); if (new_title != NULL) opts.xterm_title = new_title; - lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts); - ssl_init_done = 1; register_console(&ssl_cons); return 0; diff --git a/trunk/arch/um/drivers/stdio_console.c b/trunk/arch/um/drivers/stdio_console.c index 2bb4193ac1aa..76d1f1c980ef 100644 --- a/trunk/arch/um/drivers/stdio_console.c +++ b/trunk/arch/um/drivers/stdio_console.c @@ -22,6 +22,7 @@ #include "stdio_console.h" #include "line.h" #include "chan_kern.h" +#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "mconsole_kern.h" @@ -166,12 +167,12 @@ int stdio_init(void) return -1; printk(KERN_INFO "Initialized stdio console driver\n"); + lines_init(vts, ARRAY_SIZE(vts), &opts); + new_title = add_xterm_umid(opts.xterm_title); if(new_title != NULL) opts.xterm_title = new_title; - lines_init(vts, ARRAY_SIZE(vts), &opts); - con_init_done = 1; register_console(&stdiocons); return 0; diff --git a/trunk/arch/um/drivers/tty.c b/trunk/arch/um/drivers/tty.c index c07d0d562780..d95d64309eaf 100644 --- a/trunk/arch/um/drivers/tty.c +++ b/trunk/arch/um/drivers/tty.c @@ -8,6 +8,7 @@ #include #include #include "chan_user.h" +#include "user_util.h" #include "user.h" #include "os.h" #include "um_malloc.h" diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index 70509ddaac03..8bd9204ac1ab 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -39,6 +39,7 @@ #include "asm/irq.h" #include "asm/types.h" #include "asm/tlbflush.h" +#include "user_util.h" #include "mem_user.h" #include "kern_util.h" #include "kern.h" @@ -89,7 +90,7 @@ static inline int ubd_test_bit(__u64 bit, unsigned char *data) bits = sizeof(data[0]) * 8; n = bit / bits; off = bit % bits; - return (data[n] & (1 << off)) != 0; + return((data[n] & (1 << off)) != 0); } static inline void ubd_set_bit(__u64 bit, unsigned char *data) @@ -146,13 +147,10 @@ struct cow { unsigned long *bitmap; unsigned long bitmap_len; int bitmap_offset; - int data_offset; + int data_offset; }; -#define MAX_SG 64 - struct ubd { - struct list_head restart; /* name (and fd, below) of the file opened for writing, either the * backing or the cow file. */ char *file; @@ -167,17 +165,15 @@ struct ubd { struct platform_device pdev; struct request_queue *queue; spinlock_t lock; - struct scatterlist sg[MAX_SG]; - struct request *request; - int start_sg, end_sg; + int active; }; #define DEFAULT_COW { \ .file = NULL, \ - .fd = -1, \ - .bitmap = NULL, \ + .fd = -1, \ + .bitmap = NULL, \ .bitmap_offset = 0, \ - .data_offset = 0, \ + .data_offset = 0, \ } #define DEFAULT_UBD { \ @@ -187,13 +183,11 @@ struct ubd { .size = -1, \ .boot_openflags = OPEN_FLAGS, \ .openflags = OPEN_FLAGS, \ - .no_cow = 0, \ + .no_cow = 0, \ .shared = 0, \ - .cow = DEFAULT_COW, \ + .cow = DEFAULT_COW, \ .lock = SPIN_LOCK_UNLOCKED, \ - .request = NULL, \ - .start_sg = 0, \ - .end_sg = 0, \ + .active = 0, \ } /* Protected by ubd_lock */ @@ -249,7 +243,7 @@ static void make_ide_entries(char *dev_name) static int fake_ide_setup(char *str) { fake_ide = 1; - return 1; + return(1); } __setup("fake_ide", fake_ide_setup); @@ -267,7 +261,7 @@ static int parse_unit(char **ptr) if(isdigit(*str)) { n = simple_strtoul(str, &end, 0); if(end == str) - return -1; + return(-1); *ptr = end; } else if (('a' <= *str) && (*str <= 'z')) { @@ -275,7 +269,7 @@ static int parse_unit(char **ptr) str++; *ptr = str; } - return n; + return(n); } /* If *index_out == -1 at exit, the passed option was a general one; @@ -442,7 +436,7 @@ static int udb_setup(char *str) { printk("udb%s specified on command line is almost certainly a ubd -> " "udb TYPO\n", str); - return 1; + return(1); } __setup("udb", udb_setup); @@ -473,75 +467,66 @@ static void do_ubd_request(request_queue_t * q); /* Only changed by ubd_init, which is an initcall. */ int thread_fd = -1; -static void ubd_end_request(struct request *req, int bytes, int uptodate) +/* call ubd_finish if you need to serialize */ +static void __ubd_finish(struct request *req, int error) { - if (!end_that_request_first(req, uptodate, bytes >> 9)) { - struct ubd *dev = req->rq_disk->private_data; - unsigned long flags; - - add_disk_randomness(req->rq_disk); - spin_lock_irqsave(&dev->lock, flags); - end_that_request_last(req, uptodate); - spin_unlock_irqrestore(&dev->lock, flags); + int nsect; + + if(error){ + end_request(req, 0); + return; } + nsect = req->current_nr_sectors; + req->sector += nsect; + req->buffer += nsect << 9; + req->errors = 0; + req->nr_sectors -= nsect; + req->current_nr_sectors = 0; + end_request(req, 1); } /* Callable only from interrupt context - otherwise you need to do * spin_lock_irq()/spin_lock_irqsave() */ -static inline void ubd_finish(struct request *req, int bytes) +static inline void ubd_finish(struct request *req, int error) { - if(bytes < 0){ - ubd_end_request(req, 0, 0); - return; - } - ubd_end_request(req, bytes, 1); -} + struct ubd *dev = req->rq_disk->private_data; -static LIST_HEAD(restart); + spin_lock(&dev->lock); + __ubd_finish(req, error); + spin_unlock(&dev->lock); +} /* XXX - move this inside ubd_intr. */ /* Called without dev->lock held, and only in interrupt context. */ static void ubd_handler(void) { - struct io_thread_req *req; + struct io_thread_req req; struct request *rq; - struct ubd *ubd; - struct list_head *list, *next_ele; - unsigned long flags; + struct ubd *dev; int n; - while(1){ - n = os_read_file(thread_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(req)){ - if(n == -EAGAIN) - break; - printk(KERN_ERR "spurious interrupt in ubd_handler, " - "err = %d\n", -n); - return; - } - - rq = req->req; - rq->nr_sectors -= req->length >> 9; - if(rq->nr_sectors == 0) - ubd_finish(rq, rq->hard_nr_sectors << 9); - kfree(req); + n = os_read_file(thread_fd, &req, sizeof(req)); + if(n != sizeof(req)){ + printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " + "err = %d\n", os_getpid(), -n); + return; } - reactivate_fd(thread_fd, UBD_IRQ); - list_for_each_safe(list, next_ele, &restart){ - ubd = container_of(list, struct ubd, restart); - list_del_init(&ubd->restart); - spin_lock_irqsave(&ubd->lock, flags); - do_ubd_request(ubd->queue); - spin_unlock_irqrestore(&ubd->lock, flags); - } + rq = req.req; + dev = rq->rq_disk->private_data; + dev->active = 0; + + ubd_finish(rq, req.error); + reactivate_fd(thread_fd, UBD_IRQ); + spin_lock(&dev->lock); + do_ubd_request(dev->queue); + spin_unlock(&dev->lock); } static irqreturn_t ubd_intr(int irq, void *dev) { ubd_handler(); - return IRQ_HANDLED; + return(IRQ_HANDLED); } /* Only changed by ubd_init, which is an initcall. */ @@ -560,7 +545,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) char *file; file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; - return os_file_size(file, size_out); + return(os_file_size(file, size_out)); } static void ubd_close_dev(struct ubd *ubd_dev) @@ -632,18 +617,10 @@ static int ubd_open_dev(struct ubd *ubd_dev) if(err < 0) goto error; ubd_dev->cow.fd = err; } - return 0; + return(0); error: os_close_file(ubd_dev->fd); - return err; -} - -static void ubd_device_release(struct device *dev) -{ - struct ubd *ubd_dev = dev->driver_data; - - blk_cleanup_queue(ubd_dev->queue); - *ubd_dev = ((struct ubd) DEFAULT_UBD); + return(err); } static int ubd_disk_register(int major, u64 size, int unit, @@ -653,7 +630,7 @@ static int ubd_disk_register(int major, u64 size, int unit, disk = alloc_disk(1 << UBD_SHIFT); if(disk == NULL) - return -ENOMEM; + return(-ENOMEM); disk->major = major; disk->first_minor = unit << UBD_SHIFT; @@ -668,8 +645,6 @@ static int ubd_disk_register(int major, u64 size, int unit, if (major == MAJOR_NR) { ubd_devs[unit].pdev.id = unit; ubd_devs[unit].pdev.name = DRIVER_NAME; - ubd_devs[unit].pdev.dev.release = ubd_device_release; - ubd_devs[unit].pdev.dev.driver_data = &ubd_devs[unit]; platform_device_register(&ubd_devs[unit].pdev); disk->driverfs_dev = &ubd_devs[unit].pdev.dev; } @@ -700,8 +675,6 @@ static int ubd_add(int n, char **error_out) ubd_dev->size = ROUND_BLOCK(ubd_dev->size); - INIT_LIST_HEAD(&ubd_dev->restart); - err = -ENOMEM; ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock); if (ubd_dev->queue == NULL) { @@ -710,7 +683,6 @@ static int ubd_add(int n, char **error_out) } ubd_dev->queue->queuedata = ubd_dev; - blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; @@ -758,14 +730,14 @@ static int ubd_config(char *str, char **error_out) goto err_free; } - mutex_lock(&ubd_lock); + mutex_lock(&ubd_lock); ret = ubd_add(n, error_out); if (ret) ubd_devs[n].file = NULL; - mutex_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); out: - return ret; + return ret; err_free: kfree(str); @@ -780,7 +752,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) n = parse_unit(&name); if((n >= MAX_DEV) || (n < 0)){ *error_out = "ubd_get_config : device number out of range"; - return -1; + return(-1); } ubd_dev = &ubd_devs[n]; @@ -801,27 +773,29 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) out: mutex_unlock(&ubd_lock); - return len; + return(len); } static int ubd_id(char **str, int *start_out, int *end_out) { - int n; + int n; n = parse_unit(str); - *start_out = 0; - *end_out = MAX_DEV - 1; - return n; + *start_out = 0; + *end_out = MAX_DEV - 1; + return n; } static int ubd_remove(int n, char **error_out) { - struct gendisk *disk = ubd_gendisk[n]; struct ubd *ubd_dev; int err = -ENODEV; mutex_lock(&ubd_lock); + if(ubd_gendisk[n] == NULL) + goto out; + ubd_dev = &ubd_devs[n]; if(ubd_dev->file == NULL) @@ -832,11 +806,9 @@ static int ubd_remove(int n, char **error_out) if(ubd_dev->count > 0) goto out; + del_gendisk(ubd_gendisk[n]); + put_disk(ubd_gendisk[n]); ubd_gendisk[n] = NULL; - if(disk != NULL){ - del_gendisk(disk); - put_disk(disk); - } if(fake_gendisk[n] != NULL){ del_gendisk(fake_gendisk[n]); @@ -844,8 +816,10 @@ static int ubd_remove(int n, char **error_out) fake_gendisk[n] = NULL; } - err = 0; + blk_cleanup_queue(ubd_dev->queue); platform_device_unregister(&ubd_dev->pdev); + *ubd_dev = ((struct ubd) DEFAULT_UBD); + err = 0; out: mutex_unlock(&ubd_lock); return err; @@ -858,7 +832,7 @@ static struct mc_device ubd_mc = { .list = LIST_HEAD_INIT(ubd_mc.list), .name = "ubd", .config = ubd_config, - .get_config = ubd_get_config, + .get_config = ubd_get_config, .id = ubd_id, .remove = ubd_remove, }; @@ -880,7 +854,7 @@ static int __init ubd0_init(void) ubd_dev->file = "root_fs"; mutex_unlock(&ubd_lock); - return 0; + return(0); } __initcall(ubd0_init); @@ -908,14 +882,14 @@ static int __init ubd_init(void) return -1; } platform_driver_register(&ubd_driver); - mutex_lock(&ubd_lock); + mutex_lock(&ubd_lock); for (i = 0; i < MAX_DEV; i++){ err = ubd_add(i, &error); if(err) printk(KERN_ERR "Failed to initialize ubd device %d :" "%s\n", i, error); } - mutex_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); return 0; } @@ -939,7 +913,7 @@ static int __init ubd_driver_init(void){ "ubd : Failed to start I/O thread (errno = %d) - " "falling back to synchronous I/O\n", -io_pid); io_pid = -1; - return 0; + return(0); } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, IRQF_DISABLED, "ubd", ubd_devs); @@ -974,7 +948,7 @@ static int ubd_open(struct inode *inode, struct file *filp) err = -EROFS; }*/ out: - return err; + return(err); } static int ubd_release(struct inode * inode, struct file * file) @@ -984,7 +958,7 @@ static int ubd_release(struct inode * inode, struct file * file) if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); - return 0; + return(0); } static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, @@ -1040,7 +1014,7 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) ubd_set_bit(i, (unsigned char *) &req->sector_mask); - } + } } else cowify_bitmap(req->offset, req->length, &req->sector_mask, &req->cow_offset, bitmap, bitmap_offset, @@ -1048,16 +1022,26 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, } /* Called with dev->lock held */ -static void prepare_request(struct request *req, struct io_thread_req *io_req, - unsigned long long offset, int page_offset, - int len, struct page *page) +static int prepare_request(struct request *req, struct io_thread_req *io_req) { struct gendisk *disk = req->rq_disk; struct ubd *ubd_dev = disk->private_data; + __u64 offset; + int len; + + /* This should be impossible now */ + if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){ + printk("Write attempted on readonly ubd device %s\n", + disk->disk_name); + end_request(req, 0); + return(1); + } + + offset = ((__u64) req->sector) << 9; + len = req->current_nr_sectors << 9; io_req->req = req; - io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : - ubd_dev->fd; + io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd; io_req->fds[1] = ubd_dev->fd; io_req->cow_offset = -1; io_req->offset = offset; @@ -1068,66 +1052,45 @@ static void prepare_request(struct request *req, struct io_thread_req *io_req, io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; io_req->offsets[0] = 0; io_req->offsets[1] = ubd_dev->cow.data_offset; - io_req->buffer = page_address(page) + page_offset; + io_req->buffer = req->buffer; io_req->sectorsize = 1 << 9; if(ubd_dev->cow.file != NULL) - cowify_req(io_req, ubd_dev->cow.bitmap, - ubd_dev->cow.bitmap_offset, ubd_dev->cow.bitmap_len); + cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset, + ubd_dev->cow.bitmap_len); + return(0); } /* Called with dev->lock held */ static void do_ubd_request(request_queue_t *q) { - struct io_thread_req *io_req; + struct io_thread_req io_req; struct request *req; - int n; - - while(1){ - struct ubd *dev = q->queuedata; - if(dev->end_sg == 0){ - struct request *req = elv_next_request(q); - if(req == NULL) - return; - - dev->request = req; - blkdev_dequeue_request(req); - dev->start_sg = 0; - dev->end_sg = blk_rq_map_sg(q, req, dev->sg); - } - - req = dev->request; - while(dev->start_sg < dev->end_sg){ - struct scatterlist *sg = &dev->sg[dev->start_sg]; - - io_req = kmalloc(sizeof(struct io_thread_req), - GFP_ATOMIC); - if(io_req == NULL){ - if(list_empty(&dev->restart)) - list_add(&dev->restart, &restart); - return; + int err, n; + + if(thread_fd == -1){ + while((req = elv_next_request(q)) != NULL){ + err = prepare_request(req, &io_req); + if(!err){ + do_io(&io_req); + __ubd_finish(req, io_req.error); } - prepare_request(req, io_req, - (unsigned long long) req->sector << 9, - sg->offset, sg->length, sg->page); - - n = os_write_file(thread_fd, &io_req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)){ - if(n != -EAGAIN) - printk("write to io thread failed, " - "errno = %d\n", -n); - else if(list_empty(&dev->restart)) - list_add(&dev->restart, &restart); - return; - } - - req->sector += sg->length >> 9; - dev->start_sg++; } - dev->end_sg = 0; - dev->request = NULL; + } + else { + struct ubd *dev = q->queuedata; + if(dev->active || (req = elv_next_request(q)) == NULL) + return; + err = prepare_request(req, &io_req); + if(!err){ + dev->active = 1; + n = os_write_file(thread_fd, (char *) &io_req, + sizeof(io_req)); + if(n != sizeof(io_req)) + printk("write to io thread failed, " + "errno = %d\n", -n); + } } } @@ -1157,21 +1120,21 @@ static int ubd_ioctl(struct inode * inode, struct file * file, ubd_id.cyls = ubd_dev->size / (128 * 32 * 512); if(copy_to_user((char __user *) arg, (char *) &ubd_id, sizeof(ubd_id))) - return -EFAULT; - return 0; + return(-EFAULT); + return(0); case CDROMVOLREAD: if(copy_from_user(&volume, (char __user *) arg, sizeof(volume))) - return -EFAULT; + return(-EFAULT); volume.channel0 = 255; volume.channel1 = 255; volume.channel2 = 255; volume.channel3 = 255; if(copy_to_user((char __user *) arg, &volume, sizeof(volume))) - return -EFAULT; - return 0; + return(-EFAULT); + return(0); } - return -EINVAL; + return(-EINVAL); } static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow) @@ -1213,29 +1176,29 @@ static int backing_file_mismatch(char *file, __u64 size, time_t mtime) if(err < 0){ printk("Failed to get modification time of backing file " "\"%s\", err = %d\n", file, -err); - return err; + return(err); } err = os_file_size(file, &actual); if(err < 0){ printk("Failed to get size of backing file \"%s\", " "err = %d\n", file, -err); - return err; + return(err); } - if(actual != size){ + if(actual != size){ /*__u64 can be a long on AMD64 and with %lu GCC complains; so * the typecast.*/ printk("Size mismatch (%llu vs %llu) of COW header vs backing " "file\n", (unsigned long long) size, actual); - return -EINVAL; + return(-EINVAL); } if(modtime != mtime){ printk("mtime mismatch (%ld vs %ld) of COW header vs backing " "file\n", mtime, modtime); - return -EINVAL; + return(-EINVAL); } - return 0; + return(0); } int read_cow_bitmap(int fd, void *buf, int offset, int len) @@ -1244,13 +1207,13 @@ int read_cow_bitmap(int fd, void *buf, int offset, int len) err = os_seek_file(fd, offset); if(err < 0) - return err; + return(err); err = os_read_file(fd, buf, len); if(err < 0) - return err; + return(err); - return 0; + return(0); } int open_ubd_file(char *file, struct openflags *openflags, int shared, @@ -1268,14 +1231,14 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, if (fd < 0) { if ((fd == -ENOENT) && (create_cow_out != NULL)) *create_cow_out = 1; - if (!openflags->w || - ((fd != -EROFS) && (fd != -EACCES))) + if (!openflags->w || + ((fd != -EROFS) && (fd != -EACCES))) return fd; openflags->w = 0; fd = os_open_file(file, *openflags, mode); if (fd < 0) return fd; - } + } if(shared) printk("Not locking \"%s\" on the host\n", file); @@ -1289,7 +1252,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, /* Successful return case! */ if(backing_file_out == NULL) - return fd; + return(fd); err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, &size, §orsize, &align, bitmap_offset_out); @@ -1299,7 +1262,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, goto out_close; } if(err) - return fd; + return(fd); asked_switch = path_requires_switch(*backing_file_out, backing_file, file); @@ -1322,7 +1285,7 @@ int open_ubd_file(char *file, struct openflags *openflags, int shared, cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, bitmap_len_out, data_offset_out); - return fd; + return fd; out_close: os_close_file(fd); return err; @@ -1347,10 +1310,10 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, bitmap_offset_out, bitmap_len_out, data_offset_out); if(!err) - return fd; + return(fd); os_close_file(fd); out: - return err; + return(err); } static int update_bitmap(struct io_thread_req *req) @@ -1358,23 +1321,23 @@ static int update_bitmap(struct io_thread_req *req) int n; if(req->cow_offset == -1) - return 0; + return(0); n = os_seek_file(req->fds[1], req->cow_offset); if(n < 0){ printk("do_io - bitmap lseek failed : err = %d\n", -n); - return 1; + return(1); } n = os_write_file(req->fds[1], &req->bitmap_words, - sizeof(req->bitmap_words)); + sizeof(req->bitmap_words)); if(n != sizeof(req->bitmap_words)){ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, req->fds[1]); - return 1; + return(1); } - return 0; + return(0); } void do_io(struct io_thread_req *req) @@ -1446,14 +1409,13 @@ static int io_count = 0; int io_thread(void *arg) { - struct io_thread_req *req; + struct io_thread_req req; int n; ignore_sigwinch_sig(); while(1){ - n = os_read_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)){ + n = os_read_file(kernel_fd, &req, sizeof(req)); + if(n != sizeof(req)){ if(n < 0) printk("io_thread - read failed, fd = %d, " "err = %d\n", kernel_fd, -n); @@ -1464,10 +1426,9 @@ int io_thread(void *arg) continue; } io_count++; - do_io(req); - n = os_write_file(kernel_fd, &req, - sizeof(struct io_thread_req *)); - if(n != sizeof(struct io_thread_req *)) + do_io(&req); + n = os_write_file(kernel_fd, &req, sizeof(req)); + if(n != sizeof(req)) printk("io_thread - write failed, fd = %d, err = %d\n", kernel_fd, -n); } diff --git a/trunk/arch/um/drivers/ubd_user.c b/trunk/arch/um/drivers/ubd_user.c index 4707b3f14c2f..b94d2bc4fe06 100644 --- a/trunk/arch/um/drivers/ubd_user.c +++ b/trunk/arch/um/drivers/ubd_user.c @@ -16,6 +16,7 @@ #include #include #include "asm/types.h" +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "ubd_user.h" @@ -46,8 +47,8 @@ int start_io_thread(unsigned long sp, int *fd_out) pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD, NULL); if(pid < 0){ - err = -errno; printk("start_io_thread - clone failed : errno = %d\n", errno); + err = -errno; goto out_close; } @@ -59,5 +60,16 @@ int start_io_thread(unsigned long sp, int *fd_out) kernel_fd = -1; *fd_out = -1; out: - return err; + return(err); } + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/drivers/xterm.c b/trunk/arch/um/drivers/xterm.c index 571c2b3325d5..850221d9b4c9 100644 --- a/trunk/arch/um/drivers/xterm.c +++ b/trunk/arch/um/drivers/xterm.c @@ -14,6 +14,7 @@ #include #include "kern_util.h" #include "chan_user.h" +#include "user_util.h" #include "user.h" #include "os.h" #include "xterm.h" diff --git a/trunk/arch/um/include/arch.h b/trunk/arch/um/include/arch.h deleted file mode 100644 index 10ad52daa8c5..000000000000 --- a/trunk/arch/um/include/arch.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __ARCH_H__ -#define __ARCH_H__ - -#include "sysdep/ptrace.h" - -extern void arch_check_bugs(void); -extern int arch_fixup(unsigned long address, union uml_pt_regs *regs); -extern int arch_handle_signal(int sig, union uml_pt_regs *regs); - -#endif diff --git a/trunk/arch/um/include/as-layout.h b/trunk/arch/um/include/as-layout.h deleted file mode 100644 index fccf187bf4e1..000000000000 --- a/trunk/arch/um/include/as-layout.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __START_H__ -#define __START_H__ - -#include "sysdep/ptrace.h" - -struct cpu_task { - int pid; - void *task; -}; - -extern struct cpu_task cpu_tasks[]; - -extern unsigned long low_physmem; -extern unsigned long high_physmem; -extern unsigned long uml_physmem; -extern unsigned long uml_reserved; -extern unsigned long end_vm; -extern unsigned long start_vm; -extern unsigned long long highmem; - -extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; -extern unsigned long _unprotected_end; -extern unsigned long brk_start; - -extern int linux_main(int argc, char **argv); -extern void set_cmdline(char *cmd); - -extern void (*sig_info[])(int, union uml_pt_regs *); - -#endif diff --git a/trunk/arch/um/include/common-offsets.h b/trunk/arch/um/include/common-offsets.h index 5593a8027083..461175f8b1d9 100644 --- a/trunk/arch/um/include/common-offsets.h +++ b/trunk/arch/um/include/common-offsets.h @@ -24,7 +24,5 @@ DEFINE(UM_ELF_CLASS, ELF_CLASS); DEFINE(UM_ELFCLASS32, ELFCLASS32); DEFINE(UM_ELFCLASS64, ELFCLASS64); -DEFINE(UM_NR_CPUS, NR_CPUS); - /* For crypto assembler code. */ DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); diff --git a/trunk/arch/um/include/kern_util.h b/trunk/arch/um/include/kern_util.h index 50a49691e0e6..173af029d12b 100644 --- a/trunk/arch/um/include/kern_util.h +++ b/trunk/arch/um/include/kern_util.h @@ -8,7 +8,6 @@ #include "sysdep/ptrace.h" #include "sysdep/faultinfo.h" -#include "uml-config.h" typedef void (*kern_hndl)(int, union uml_pt_regs *); @@ -24,6 +23,7 @@ struct kern_handlers { extern const struct kern_handlers handlinfo_kern; extern int ncpus; +extern char *linux_prog; extern char *gdb_init; extern int kmalloc_ok; extern int jail; @@ -34,9 +34,7 @@ extern int nsyscalls; UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); -#ifdef UML_CONFIG_MODE_TT extern unsigned long stack_sp(unsigned long page); -#endif extern int kernel_thread_proc(void *data); extern void syscall_segv(int sig); extern int current_pid(void); @@ -44,7 +42,7 @@ extern unsigned long alloc_stack(int order, int atomic); extern int do_signal(void); extern int is_stack_fault(unsigned long sp); extern unsigned long segv(struct faultinfo fi, unsigned long ip, - int is_user, union uml_pt_regs *regs); + int is_user, void *sc); extern int handle_page_fault(unsigned long address, unsigned long ip, int is_write, int is_user, int *code_out); extern void syscall_ready(void); @@ -52,6 +50,7 @@ extern void set_tracing(void *t, int tracing); extern int is_tracing(void *task); extern int segv_syscall(void); extern void kern_finish_exec(void *task, int new_pid, unsigned long stack); +extern int page_size(void); extern unsigned long page_mask(void); extern int need_finish_fork(void); extern void free_stack(unsigned long stack, int order); @@ -59,6 +58,7 @@ extern void add_input_request(int op, void (*proc)(int), void *arg); extern char *current_cmd(void); extern void timer_handler(int sig, union uml_pt_regs *regs); extern int set_signals(int enable); +extern void force_sigbus(void); extern int pid_to_processor_id(int pid); extern void deliver_signals(void *t); extern int next_trap_index(int max); @@ -70,6 +70,7 @@ extern void *syscall_sp(void *t); extern void syscall_trace(union uml_pt_regs *regs, int entryexit); extern int hz(void); extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); +extern int external_pid(void *t); extern void interrupt_end(void); extern void initial_thread_cb(void (*proc)(void *), void *arg); extern int debugger_signal(int status, int pid); @@ -80,6 +81,7 @@ extern int init_parent_proxy(int pid); extern int singlestepping(void *t); extern void check_stack_overflow(void *ptr); extern void relay_signal(int sig, union uml_pt_regs *regs); +extern void not_implemented(void); extern int user_context(unsigned long sp); extern void timer_irq(union uml_pt_regs *regs); extern void unprotect_stack(unsigned long stack); @@ -91,6 +93,7 @@ extern char *uml_strdup(char *string); extern void unprotect_kernel_mem(void); extern void protect_kernel_mem(void); extern void uml_cleanup(void); +extern void set_current(void *t); extern void lock_signalled_task(void *t); extern void IPI_handler(int cpu); extern int jail_setup(char *line, int *add); @@ -115,6 +118,4 @@ extern void time_init_kern(void); extern int __cant_sleep(void); extern void sigio_handler(int sig, union uml_pt_regs *regs); -extern void copy_sc(union uml_pt_regs *regs, void *from); - #endif diff --git a/trunk/arch/um/include/net_kern.h b/trunk/arch/um/include/net_kern.h index 9237056b9103..125ab42df18a 100644 --- a/trunk/arch/um/include/net_kern.h +++ b/trunk/arch/um/include/net_kern.h @@ -40,7 +40,7 @@ struct uml_net_private { void (*add_address)(unsigned char *, unsigned char *, void *); void (*delete_address)(unsigned char *, unsigned char *, void *); int (*set_mtu)(int mtu, void *); - char user[0]; + int user[1]; }; struct net_kern_info { diff --git a/trunk/arch/um/include/net_user.h b/trunk/arch/um/include/net_user.h index cfe7c50634b9..19f207cd70fe 100644 --- a/trunk/arch/um/include/net_user.h +++ b/trunk/arch/um/include/net_user.h @@ -14,7 +14,7 @@ #define UML_NET_VERSION (4) struct net_user_info { - int (*init)(void *, void *); + void (*init)(void *, void *); int (*open)(void *); void (*close)(int, void *); void (*remove)(void *); diff --git a/trunk/arch/um/include/os.h b/trunk/arch/um/include/os.h index 688d181b5f8a..5c74da410451 100644 --- a/trunk/arch/um/include/os.h +++ b/trunk/arch/um/include/os.h @@ -16,8 +16,6 @@ #include "sysdep/tls.h" #include "sysdep/archsetjmp.h" -#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) - #define OS_TYPE_FILE 1 #define OS_TYPE_DIR 2 #define OS_TYPE_SYMLINK 3 @@ -275,9 +273,8 @@ extern void stack_protections(unsigned long address); extern void task_protections(unsigned long address); extern int raw(int fd); extern void setup_machinename(char *machine_out); -extern void setup_hostinfo(char *buf, int len); +extern void setup_hostinfo(void); extern int setjmp_wrapper(void (*proc)(void *, void *), ...); -extern void os_dump_core(void); /* time.c */ #define BILLION (1000 * 1000 * 1000) @@ -300,12 +297,13 @@ extern long syscall_stub_data(struct mm_id * mm_idp, unsigned long *data, int data_count, void **addr, void **stub_addr); extern int map(struct mm_id * mm_idp, unsigned long virt, - unsigned long len, int prot, int phys_fd, + unsigned long len, int r, int w, int x, int phys_fd, unsigned long long offset, int done, void **data); -extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, +extern int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, void **data); extern int protect(struct mm_id * mm_idp, unsigned long addr, - unsigned long len, unsigned int prot, int done, void **data); + unsigned long len, int r, int w, int x, int done, + void **data); /* skas/process.c */ extern int is_skas_winch(int pid, int fd, void *data); @@ -341,11 +339,8 @@ extern void maybe_sigio_broken(int fd, int read); /* skas/trap */ extern void sig_handler_common_skas(int sig, void *sc_ptr); +extern void user_signal(int sig, union uml_pt_regs *regs, int pid); -/* sys-x86_64/prctl.c */ extern int os_arch_prctl(int pid, int code, unsigned long *addr); -/* tty.c */ -int get_pty(void); - #endif diff --git a/trunk/arch/um/include/skas/mode_kern_skas.h b/trunk/arch/um/include/skas/mode_kern_skas.h index 8ee6285dfacc..9cd9c6ec9a63 100644 --- a/trunk/arch/um/include/skas/mode_kern_skas.h +++ b/trunk/arch/um/include/skas/mode_kern_skas.h @@ -33,8 +33,6 @@ extern unsigned long set_task_sizes_skas(unsigned long *task_size_out); extern int start_uml_skas(void); extern int external_pid_skas(struct task_struct *task); extern int thread_pid_skas(struct task_struct *task); -extern void flush_tlb_page_skas(struct vm_area_struct *vma, - unsigned long address); #define kmem_end_skas (host_task_size - 1024 * 1024) diff --git a/trunk/arch/um/include/tlb.h b/trunk/arch/um/include/tlb.h index bcd1a4afb842..8efc1e0f1b84 100644 --- a/trunk/arch/um/include/tlb.h +++ b/trunk/arch/um/include/tlb.h @@ -14,7 +14,9 @@ struct host_vm_op { struct { unsigned long addr; unsigned long len; - unsigned int prot; + unsigned int r:1; + unsigned int w:1; + unsigned int x:1; int fd; __u64 offset; } mmap; @@ -25,7 +27,9 @@ struct host_vm_op { struct { unsigned long addr; unsigned long len; - unsigned int prot; + unsigned int r:1; + unsigned int w:1; + unsigned int x:1; } mprotect; } u; }; diff --git a/trunk/arch/um/include/tt/uaccess-tt.h b/trunk/arch/um/include/tt/uaccess-tt.h index 13a64f61fcf4..b19645f32f24 100644 --- a/trunk/arch/um/include/tt/uaccess-tt.h +++ b/trunk/arch/um/include/tt/uaccess-tt.h @@ -27,6 +27,8 @@ extern unsigned long uml_physmem; #define access_ok_tt(type, addr, size) \ (is_stack(addr, size)) +extern unsigned long get_fault_addr(void); + extern int __do_copy_from_user(void *to, const void *from, int n, void **fault_addr, void **fault_catcher); extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, diff --git a/trunk/arch/um/include/um_malloc.h b/trunk/arch/um/include/um_malloc.h index e6d7c5aa3f4e..0363a9b53f8d 100644 --- a/trunk/arch/um/include/um_malloc.h +++ b/trunk/arch/um/include/um_malloc.h @@ -11,6 +11,7 @@ extern void *um_kmalloc_atomic(int size); extern void kfree(const void *ptr); extern void *um_vmalloc(int size); +extern void *um_vmalloc_atomic(int size); extern void vfree(void *ptr); #endif /* __UM_MALLOC_H__ */ diff --git a/trunk/arch/um/include/user.h b/trunk/arch/um/include/user.h index d380e6d91a90..acadce3f271f 100644 --- a/trunk/arch/um/include/user.h +++ b/trunk/arch/um/include/user.h @@ -6,19 +6,6 @@ #ifndef __USER_H__ #define __USER_H__ -/* - * The usual definition - copied here because the kernel provides its own, - * fancier, type-safe, definition. Using that one would require - * copying too much infrastructure for my taste, so userspace files - * get less checking than kernel files. - */ -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -/* - * This will provide the size_t definition in both kernel and userspace builds - */ -#include - extern void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern int printk(const char *fmt, ...) @@ -26,7 +13,19 @@ extern int printk(const char *fmt, ...) extern void schedule(void); extern int in_aton(char *str); extern int open_gdb_chan(void); -extern size_t strlcpy(char *, const char *, size_t); -extern size_t strlcat(char *, const char *, size_t); +/* These use size_t, however unsigned long is correct on both i386 and x86_64. */ +extern unsigned long strlcpy(char *, const char *, unsigned long); +extern unsigned long strlcat(char *, const char *, unsigned long); #endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/user_util.h b/trunk/arch/um/include/user_util.h new file mode 100644 index 000000000000..023575f67343 --- /dev/null +++ b/trunk/arch/um/include/user_util.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __USER_UTIL_H__ +#define __USER_UTIL_H__ + +#include "sysdep/ptrace.h" + +/* Copied from kernel.h */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) + +extern int mode_tt; + +extern int grantpt(int __fd); +extern int unlockpt(int __fd); +extern char *ptsname(int __fd); + +struct cpu_task { + int pid; + void *task; +}; + +extern struct cpu_task cpu_tasks[]; + +extern void (*sig_info[])(int, union uml_pt_regs *); + +extern unsigned long low_physmem; +extern unsigned long high_physmem; +extern unsigned long uml_physmem; +extern unsigned long uml_reserved; +extern unsigned long end_vm; +extern unsigned long start_vm; +extern unsigned long long highmem; + +extern char host_info[]; + +extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; +extern unsigned long _unprotected_end; +extern unsigned long brk_start; + +extern int pty_output_sigio; +extern int pty_close_sigio; + +extern void *add_signal_handler(int sig, void (*handler)(int)); +extern int linux_main(int argc, char **argv); +extern void set_cmdline(char *cmd); +extern void input_cb(void (*proc)(void *), void *arg, int arg_len); +extern int get_pty(void); +extern int switcheroo(int fd, int prot, void *from, void *to, int size); +extern void do_exec(int old_pid, int new_pid); +extern void tracer_panic(char *msg, ...) + __attribute__ ((format (printf, 1, 2))); +extern int detach(int pid, int sig); +extern int attach(int pid); +extern void kill_child_dead(int pid); +extern int cont(int pid); +extern void check_sigio(void); +extern void arch_check_bugs(void); +extern int cpu_feature(char *what, char *buf, int len); +extern int arch_handle_signal(int sig, union uml_pt_regs *regs); +extern int arch_fixup(unsigned long address, void *sc_ptr); +extern void arch_init_thread(void); +extern int raw(int fd); + +#endif diff --git a/trunk/arch/um/kernel/exec.c b/trunk/arch/um/kernel/exec.c index 356e50f5aaed..121166400e25 100644 --- a/trunk/arch/um/kernel/exec.c +++ b/trunk/arch/um/kernel/exec.c @@ -10,8 +10,8 @@ #include "asm/pgtable.h" #include "asm/tlbflush.h" #include "asm/uaccess.h" +#include "user_util.h" #include "kern_util.h" -#include "as-layout.h" #include "mem_user.h" #include "kern.h" #include "irq_user.h" diff --git a/trunk/arch/um/kernel/init_task.c b/trunk/arch/um/kernel/init_task.c index cda91aa8e703..8cde431348cc 100644 --- a/trunk/arch/um/kernel/init_task.c +++ b/trunk/arch/um/kernel/init_task.c @@ -10,6 +10,7 @@ #include "linux/mqueue.h" #include "asm/uaccess.h" #include "asm/pgtable.h" +#include "user_util.h" #include "mem_user.h" #include "os.h" diff --git a/trunk/arch/um/kernel/initrd.c b/trunk/arch/um/kernel/initrd.c index 16dc43e9d940..82ecf904b09c 100644 --- a/trunk/arch/um/kernel/initrd.c +++ b/trunk/arch/um/kernel/initrd.c @@ -7,6 +7,7 @@ #include "linux/bootmem.h" #include "linux/initrd.h" #include "asm/types.h" +#include "user_util.h" #include "kern_util.h" #include "initrd.h" #include "init.h" @@ -21,20 +22,12 @@ static int __init read_initrd(void) long long size; int err; - if(initrd == NULL) - return 0; - + if(initrd == NULL) return 0; err = os_file_size(initrd, &size); - if(err) - return 0; - + if(err) return 0; area = alloc_bootmem(size); - if(area == NULL) - return 0; - - if(load_initrd(initrd, area, size) == -1) - return 0; - + if(area == NULL) return 0; + if(load_initrd(initrd, area, size) == -1) return 0; initrd_start = (unsigned long) area; initrd_end = initrd_start + size; return 0; @@ -61,15 +54,25 @@ int load_initrd(char *filename, void *buf, int size) fd = os_open_file(filename, of_read(OPENFLAGS()), 0); if(fd < 0){ printk("Opening '%s' failed - err = %d\n", filename, -fd); - return -1; + return(-1); } n = os_read_file(fd, buf, size); if(n != size){ printk("Read of %d bytes from '%s' failed, err = %d\n", size, filename, -n); - return -1; + return(-1); } os_close_file(fd); - return 0; + return(0); } +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/irq.c b/trunk/arch/um/kernel/irq.c index 8f2ed3690315..dbf2f5bc842f 100644 --- a/trunk/arch/um/kernel/irq.c +++ b/trunk/arch/um/kernel/irq.c @@ -25,6 +25,7 @@ #include "asm/system.h" #include "asm/errno.h" #include "asm/uaccess.h" +#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "irq_kern.h" @@ -78,14 +79,6 @@ int show_interrupts(struct seq_file *p, void *v) return 0; } -/* - * This list is accessed under irq_lock, except in sigio_handler, - * where it is safe from being modified. IRQ handlers won't change it - - * if an IRQ source has vanished, it will be freed by free_irqs just - * before returning from sigio_handler. That will process a separate - * list of irqs to free, with its own locking, coming back here to - * remove list elements, taking the irq_lock to do so. - */ static struct irq_fd *active_fds = NULL; static struct irq_fd **last_irq_ptr = &active_fds; @@ -251,7 +244,6 @@ void free_irq_by_fd(int fd) free_irq_by_cb(same_fd, &fd); } -/* Must be called with irq_lock held */ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) { struct irq_fd *irq; @@ -317,12 +309,6 @@ void deactivate_fd(int fd, int irqnum) ignore_sigio_fd(fd); } -/* - * Called just before shutdown in order to provide a clean exec - * environment in case the system is rebooting. No locking because - * that would cause a pointless shutdown hang if something hadn't - * released the lock. - */ int deactivate_all_fds(void) { struct irq_fd *irq; diff --git a/trunk/arch/um/kernel/ksyms.c b/trunk/arch/um/kernel/ksyms.c index 7b3e53fb8070..0e00cf93f900 100644 --- a/trunk/arch/um/kernel/ksyms.c +++ b/trunk/arch/um/kernel/ksyms.c @@ -16,7 +16,7 @@ #include "asm/page.h" #include "asm/tlbflush.h" #include "kern_util.h" -#include "as-layout.h" +#include "user_util.h" #include "mem_user.h" #include "os.h" diff --git a/trunk/arch/um/kernel/mem.c b/trunk/arch/um/kernel/mem.c index 72ff85693a39..df7d662b98ce 100644 --- a/trunk/arch/um/kernel/mem.c +++ b/trunk/arch/um/kernel/mem.c @@ -13,8 +13,8 @@ #include "asm/page.h" #include "asm/fixmap.h" #include "asm/pgalloc.h" +#include "user_util.h" #include "kern_util.h" -#include "as-layout.h" #include "kern.h" #include "mem_user.h" #include "uml_uaccess.h" @@ -216,7 +216,7 @@ static void __init fixaddr_user_init( void) #endif } -void __init paging_init(void) +void paging_init(void) { unsigned long zones_size[MAX_NR_ZONES], vaddr; int i; diff --git a/trunk/arch/um/kernel/physmem.c b/trunk/arch/um/kernel/physmem.c index 3ba6e4c841da..638f3b5f6094 100644 --- a/trunk/arch/um/kernel/physmem.c +++ b/trunk/arch/um/kernel/physmem.c @@ -13,7 +13,7 @@ #include "asm/types.h" #include "asm/pgtable.h" #include "kern_util.h" -#include "as-layout.h" +#include "user_util.h" #include "mode_kern.h" #include "mem.h" #include "mem_user.h" @@ -21,8 +21,229 @@ #include "kern.h" #include "init.h" +struct phys_desc { + struct rb_node rb; + int fd; + __u64 offset; + void *virt; + unsigned long phys; + struct list_head list; +}; + +static struct rb_root phys_mappings = RB_ROOT; + +static struct rb_node **find_rb(void *virt) +{ + struct rb_node **n = &phys_mappings.rb_node; + struct phys_desc *d; + + while(*n != NULL){ + d = rb_entry(*n, struct phys_desc, rb); + if(d->virt == virt) + return n; + + if(d->virt > virt) + n = &(*n)->rb_left; + else + n = &(*n)->rb_right; + } + + return n; +} + +static struct phys_desc *find_phys_mapping(void *virt) +{ + struct rb_node **n = find_rb(virt); + + if(*n == NULL) + return NULL; + + return rb_entry(*n, struct phys_desc, rb); +} + +static void insert_phys_mapping(struct phys_desc *desc) +{ + struct rb_node **n = find_rb(desc->virt); + + if(*n != NULL) + panic("Physical remapping for %p already present", + desc->virt); + + rb_link_node(&desc->rb, rb_parent(*n), n); + rb_insert_color(&desc->rb, &phys_mappings); +} + +LIST_HEAD(descriptor_mappings); + +struct desc_mapping { + int fd; + struct list_head list; + struct list_head pages; +}; + +static struct desc_mapping *find_mapping(int fd) +{ + struct desc_mapping *desc; + struct list_head *ele; + + list_for_each(ele, &descriptor_mappings){ + desc = list_entry(ele, struct desc_mapping, list); + if(desc->fd == fd) + return desc; + } + + return NULL; +} + +static struct desc_mapping *descriptor_mapping(int fd) +{ + struct desc_mapping *desc; + + desc = find_mapping(fd); + if(desc != NULL) + return desc; + + desc = kmalloc(sizeof(*desc), GFP_ATOMIC); + if(desc == NULL) + return NULL; + + *desc = ((struct desc_mapping) + { .fd = fd, + .list = LIST_HEAD_INIT(desc->list), + .pages = LIST_HEAD_INIT(desc->pages) }); + list_add(&desc->list, &descriptor_mappings); + + return desc; +} + +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) +{ + struct desc_mapping *fd_maps; + struct phys_desc *desc; + unsigned long phys; + int err; + + fd_maps = descriptor_mapping(fd); + if(fd_maps == NULL) + return -ENOMEM; + + phys = __pa(virt); + desc = find_phys_mapping(virt); + if(desc != NULL) + panic("Address 0x%p is already substituted\n", virt); + + err = -ENOMEM; + desc = kmalloc(sizeof(*desc), GFP_ATOMIC); + if(desc == NULL) + goto out; + + *desc = ((struct phys_desc) + { .fd = fd, + .offset = offset, + .virt = virt, + .phys = __pa(virt), + .list = LIST_HEAD_INIT(desc->list) }); + insert_phys_mapping(desc); + + list_add(&desc->list, &fd_maps->pages); + + virt = (void *) ((unsigned long) virt & PAGE_MASK); + err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0); + if(!err) + goto out; + + rb_erase(&desc->rb, &phys_mappings); + kfree(desc); + out: + return err; +} + static int physmem_fd = -1; +static void remove_mapping(struct phys_desc *desc) +{ + void *virt = desc->virt; + int err; + + rb_erase(&desc->rb, &phys_mappings); + list_del(&desc->list); + kfree(desc); + + err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0); + if(err) + panic("Failed to unmap block device page from physical memory, " + "errno = %d", -err); +} + +int physmem_remove_mapping(void *virt) +{ + struct phys_desc *desc; + + virt = (void *) ((unsigned long) virt & PAGE_MASK); + desc = find_phys_mapping(virt); + if(desc == NULL) + return 0; + + remove_mapping(desc); + return 1; +} + +void physmem_forget_descriptor(int fd) +{ + struct desc_mapping *desc; + struct phys_desc *page; + struct list_head *ele, *next; + __u64 offset; + void *addr; + int err; + + desc = find_mapping(fd); + if(desc == NULL) + return; + + list_for_each_safe(ele, next, &desc->pages){ + page = list_entry(ele, struct phys_desc, list); + offset = page->offset; + addr = page->virt; + remove_mapping(page); + err = os_seek_file(fd, offset); + if(err) + panic("physmem_forget_descriptor - failed to seek " + "to %lld in fd %d, error = %d\n", + offset, fd, -err); + err = os_read_file(fd, addr, PAGE_SIZE); + if(err < 0) + panic("physmem_forget_descriptor - failed to read " + "from fd %d to 0x%p, error = %d\n", + fd, addr, -err); + } + + list_del(&desc->list); + kfree(desc); +} + +EXPORT_SYMBOL(physmem_forget_descriptor); +EXPORT_SYMBOL(physmem_remove_mapping); +EXPORT_SYMBOL(physmem_subst_mapping); + +void arch_free_page(struct page *page, int order) +{ + void *virt; + int i; + + for(i = 0; i < (1 << order); i++){ + virt = __va(page_to_phys(page + i)); + physmem_remove_mapping(virt); + } +} + +int is_remapped(void *virt) +{ + struct phys_desc *desc = find_phys_mapping(virt); + + return desc != NULL; +} + /* Changed during early boot */ unsigned long high_physmem; @@ -129,9 +350,14 @@ void setup_physmem(unsigned long start, unsigned long reserve_end, int phys_mapping(unsigned long phys, __u64 *offset_out) { + struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK)); int fd = -1; - if(phys < physmem_size){ + if(desc != NULL){ + fd = desc->fd; + *offset_out = desc->offset; + } + else if(phys < physmem_size){ fd = physmem_fd; *offset_out = phys; } diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process.c index 8d2c5496532b..348b272bb766 100644 --- a/trunk/arch/um/kernel/process.c +++ b/trunk/arch/um/kernel/process.c @@ -32,8 +32,8 @@ #include "asm/tlbflush.h" #include "asm/uaccess.h" #include "asm/user.h" +#include "user_util.h" #include "kern_util.h" -#include "as-layout.h" #include "kern.h" #include "signal_kern.h" #include "init.h" @@ -54,9 +54,11 @@ */ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; -static inline int external_pid(struct task_struct *task) +int external_pid(void *t) { - return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task); + struct task_struct *task = t ? t : current; + + return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task)); } int pid_to_processor_id(int pid) @@ -64,10 +66,9 @@ int pid_to_processor_id(int pid) int i; for(i = 0; i < ncpus; i++){ - if(cpu_tasks[i].pid == pid) - return i; + if(cpu_tasks[i].pid == pid) return(i); } - return -1; + return(-1); } void free_stack(unsigned long stack, int order) @@ -84,9 +85,9 @@ unsigned long alloc_stack(int order, int atomic) flags = GFP_ATOMIC; page = __get_free_pages(flags, order); if(page == 0) - return 0; + return(0); stack_protections(page); - return page; + return(page); } int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) @@ -97,11 +98,15 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) current->thread.request.u.thread.arg = arg; pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, ¤t->thread.regs, 0, NULL, NULL); - return pid; + if(pid < 0) + panic("do_fork failed in kernel_thread, errno = %d", pid); + return(pid); } -static inline void set_current(struct task_struct *task) +void set_current(void *t) { + struct task_struct *task = t; + cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task) { external_pid(task), task }); } @@ -123,16 +128,14 @@ void *_switch_to(void *prev, void *next, void *last) prev= current; } while(current->thread.saved_task); - return current->thread.prev_sched; + return(current->thread.prev_sched); } void interrupt_end(void) { - if(need_resched()) - schedule(); - if(test_tsk_thread_flag(current, TIF_SIGPENDING)) - do_signal(); + if(need_resched()) schedule(); + if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal(); } void release_thread(struct task_struct *task) @@ -147,7 +150,7 @@ void exit_thread(void) void *get_current(void) { - return current; + return(current); } int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, @@ -185,12 +188,15 @@ void initial_thread_cb(void (*proc)(void *), void *arg) kmalloc_ok = save_kmalloc_ok; } -#ifdef CONFIG_MODE_TT unsigned long stack_sp(unsigned long page) { - return page + PAGE_SIZE - sizeof(void *); + return(page + PAGE_SIZE - sizeof(void *)); +} + +int current_pid(void) +{ + return(current->pid); } -#endif void default_idle(void) { @@ -215,6 +221,11 @@ void cpu_idle(void) CHOOSE_MODE(init_idle_tt(), init_idle_skas()); } +int page_size(void) +{ + return(PAGE_SIZE); +} + void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t *pte_out) { @@ -225,43 +236,68 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t ptent; if(task->mm == NULL) - return ERR_PTR(-EINVAL); + return(ERR_PTR(-EINVAL)); pgd = pgd_offset(task->mm, addr); if(!pgd_present(*pgd)) - return ERR_PTR(-EINVAL); + return(ERR_PTR(-EINVAL)); pud = pud_offset(pgd, addr); if(!pud_present(*pud)) - return ERR_PTR(-EINVAL); + return(ERR_PTR(-EINVAL)); pmd = pmd_offset(pud, addr); if(!pmd_present(*pmd)) - return ERR_PTR(-EINVAL); + return(ERR_PTR(-EINVAL)); pte = pte_offset_kernel(pmd, addr); ptent = *pte; if(!pte_present(ptent)) - return ERR_PTR(-EINVAL); + return(ERR_PTR(-EINVAL)); if(pte_out != NULL) *pte_out = ptent; - return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); + return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK)); } char *current_cmd(void) { #if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM) - return "(Unknown)"; + return("(Unknown)"); #else void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL); return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr); #endif } +void force_sigbus(void) +{ + printk(KERN_ERR "Killing pid %d because of a lack of memory\n", + current->pid); + lock_kernel(); + sigaddset(¤t->pending.signal, SIGBUS); + recalc_sigpending(); + current->flags |= PF_SIGNALED; + do_exit(SIGBUS | 0x80); +} + void dump_thread(struct pt_regs *regs, struct user *u) { } +void enable_hlt(void) +{ + panic("enable_hlt"); +} + +EXPORT_SYMBOL(enable_hlt); + +void disable_hlt(void) +{ + panic("disable_hlt"); +} + +EXPORT_SYMBOL(disable_hlt); + void *um_kmalloc(int size) { return kmalloc(size, GFP_KERNEL); @@ -277,17 +313,36 @@ void *um_vmalloc(int size) return vmalloc(size); } +void *um_vmalloc_atomic(int size) +{ + return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL); +} + int __cant_sleep(void) { return in_atomic() || irqs_disabled() || in_interrupt(); /* Is in_interrupt() really needed? */ } +unsigned long get_fault_addr(void) +{ + return((unsigned long) current->thread.fault_addr); +} + +EXPORT_SYMBOL(get_fault_addr); + +void not_implemented(void) +{ + printk(KERN_DEBUG "Something isn't implemented in here\n"); +} + +EXPORT_SYMBOL(not_implemented); + int user_context(unsigned long sp) { unsigned long stack; stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); - return stack != (unsigned long) current_thread; + return(stack != (unsigned long) current_thread); } extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; @@ -308,22 +363,22 @@ char *uml_strdup(char *string) int copy_to_user_proc(void __user *to, void *from, int size) { - return copy_to_user(to, from, size); + return(copy_to_user(to, from, size)); } int copy_from_user_proc(void *to, void __user *from, int size) { - return copy_from_user(to, from, size); + return(copy_from_user(to, from, size)); } int clear_user_proc(void __user *buf, int size) { - return clear_user(buf, size); + return(clear_user(buf, size)); } int strlen_user_proc(char __user *str) { - return strlen_user(str); + return(strlen_user(str)); } int smp_sigio_handler(void) @@ -332,14 +387,14 @@ int smp_sigio_handler(void) int cpu = current_thread->cpu; IPI_handler(cpu); if(cpu != 0) - return 1; + return(1); #endif - return 0; + return(0); } int cpu(void) { - return current_thread->cpu; + return(current_thread->cpu); } static atomic_t using_sysemu = ATOMIC_INIT(0); @@ -388,7 +443,7 @@ int __init make_proc_sysemu(void) if (ent == NULL) { printk(KERN_WARNING "Failed to register /proc/sysemu\n"); - return 0; + return(0); } ent->read_proc = proc_read_sysemu; diff --git a/trunk/arch/um/kernel/reboot.c b/trunk/arch/um/kernel/reboot.c index 7e4305a1fd3c..f602623644aa 100644 --- a/trunk/arch/um/kernel/reboot.c +++ b/trunk/arch/um/kernel/reboot.c @@ -6,6 +6,7 @@ #include "linux/module.h" #include "linux/sched.h" #include "asm/smp.h" +#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "os.h" diff --git a/trunk/arch/um/kernel/signal.c b/trunk/arch/um/kernel/signal.c index c4020c3d7857..3c798cdde550 100644 --- a/trunk/arch/um/kernel/signal.c +++ b/trunk/arch/um/kernel/signal.c @@ -17,6 +17,7 @@ #include "asm/signal.h" #include "asm/uaccess.h" #include "asm/unistd.h" +#include "user_util.h" #include "asm/ucontext.h" #include "kern_util.h" #include "signal_kern.h" diff --git a/trunk/arch/um/kernel/skas/exec.c b/trunk/arch/um/kernel/skas/exec.c index 580eb6468949..54b795951372 100644 --- a/trunk/arch/um/kernel/skas/exec.c +++ b/trunk/arch/um/kernel/skas/exec.c @@ -17,17 +17,7 @@ void flush_thread_skas(void) { - void *data = NULL; - unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; - int ret; - - ret = unmap(¤t->mm->context.skas.id, 0, end, 1, &data); - if(ret){ - printk("flush_thread_skas - clearing address space failed, " - "err = %d\n", ret); - force_sig(SIGKILL, current); - } - + force_flush_all(); switch_mm_skas(¤t->mm->context.skas.id); } diff --git a/trunk/arch/um/kernel/skas/process.c b/trunk/arch/um/kernel/skas/process.c index ef36facd8fe9..ae4fa71d3b8b 100644 --- a/trunk/arch/um/kernel/skas/process.c +++ b/trunk/arch/um/kernel/skas/process.c @@ -13,9 +13,9 @@ #include "asm/uaccess.h" #include "asm/atomic.h" #include "kern_util.h" -#include "as-layout.h" #include "skas.h" #include "os.h" +#include "user_util.h" #include "tlb.h" #include "kern.h" #include "mode.h" diff --git a/trunk/arch/um/kernel/skas/tlb.c b/trunk/arch/um/kernel/skas/tlb.c index c0f0693743ba..27eb29ce666b 100644 --- a/trunk/arch/um/kernel/skas/tlb.c +++ b/trunk/arch/um/kernel/skas/tlb.c @@ -10,6 +10,7 @@ #include "asm/page.h" #include "asm/pgtable.h" #include "asm/mmu.h" +#include "user_util.h" #include "mem_user.h" #include "mem.h" #include "skas.h" @@ -27,17 +28,19 @@ static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last, switch(op->type){ case MMAP: ret = map(&mmu->skas.id, op->u.mmap.addr, - op->u.mmap.len, op->u.mmap.prot, - op->u.mmap.fd, op->u.mmap.offset, finished, - flush); + op->u.mmap.len, op->u.mmap.r, op->u.mmap.w, + op->u.mmap.x, op->u.mmap.fd, + op->u.mmap.offset, finished, flush); break; case MUNMAP: - ret = unmap(&mmu->skas.id, op->u.munmap.addr, + ret = unmap(&mmu->skas.id, + (void *) op->u.munmap.addr, op->u.munmap.len, finished, flush); break; case MPROTECT: ret = protect(&mmu->skas.id, op->u.mprotect.addr, - op->u.mprotect.len, op->u.mprotect.prot, + op->u.mprotect.len, op->u.mprotect.r, + op->u.mprotect.w, op->u.mprotect.x, finished, flush); break; default: @@ -89,76 +92,6 @@ void flush_tlb_mm_skas(struct mm_struct *mm) void force_flush_all_skas(void) { - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma = mm->mmap; - - while(vma != NULL) { - fix_range(mm, vma->vm_start, vma->vm_end, 1); - vma = vma->vm_next; - } -} - -void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - struct mm_struct *mm = vma->vm_mm; - void *flush = NULL; - int r, w, x, prot, err = 0; - struct mm_id *mm_id; - - pgd = pgd_offset(mm, address); - if(!pgd_present(*pgd)) - goto kill; - - pud = pud_offset(pgd, address); - if(!pud_present(*pud)) - goto kill; - - pmd = pmd_offset(pud, address); - if(!pmd_present(*pmd)) - goto kill; - - pte = pte_offset_kernel(pmd, address); - - r = pte_read(*pte); - w = pte_write(*pte); - x = pte_exec(*pte); - if (!pte_young(*pte)) { - r = 0; - w = 0; - } else if (!pte_dirty(*pte)) { - w = 0; - } - - mm_id = &mm->context.skas.id; - prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | - (x ? UM_PROT_EXEC : 0)); - if(pte_newpage(*pte)){ - if(pte_present(*pte)){ - unsigned long long offset; - int fd; - - fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset); - err = map(mm_id, address, PAGE_SIZE, prot, fd, offset, - 1, &flush); - } - else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush); - } - else if(pte_newprot(*pte)) - err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush); - - if(err) - goto kill; - - *pte = pte_mkuptodate(*pte); - - return; - -kill: - printk("Failed to flush page for address 0x%lx\n", address); - force_sig(SIGKILL, current); + unsigned long end = proc_mm ? task_size : CONFIG_STUB_START; + fix_range(current->mm, 0, end, 1); } - diff --git a/trunk/arch/um/kernel/smp.c b/trunk/arch/um/kernel/smp.c index e6a7778006ad..759b07053160 100644 --- a/trunk/arch/um/kernel/smp.c +++ b/trunk/arch/um/kernel/smp.c @@ -21,6 +21,7 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); #include "asm/smp.h" #include "asm/processor.h" #include "asm/spinlock.h" +#include "user_util.h" #include "kern_util.h" #include "kern.h" #include "irq_user.h" @@ -89,7 +90,7 @@ static int idle_proc(void *cpup) cpu_set(cpu, cpu_online_map); default_idle(); - return 0; + return(0); } static struct task_struct *idle_thread(int cpu) @@ -97,8 +98,8 @@ static struct task_struct *idle_thread(int cpu) struct task_struct *new_task; unsigned char c; - current->thread.request.u.thread.proc = idle_proc; - current->thread.request.u.thread.arg = (void *) cpu; + current->thread.request.u.thread.proc = idle_proc; + current->thread.request.u.thread.arg = (void *) cpu; new_task = fork_idle(cpu); if(IS_ERR(new_task)) panic("copy_process failed in idle_thread, error = %ld", @@ -109,9 +110,9 @@ static struct task_struct *idle_thread(int cpu) .task = new_task } ); idle_threads[cpu] = new_task; CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, - sizeof(c)), + sizeof(c)), ({ panic("skas mode doesn't support SMP"); })); - return new_task; + return(new_task); } void smp_prepare_cpus(unsigned int maxcpus) @@ -162,13 +163,13 @@ int __cpu_up(unsigned int cpu) cpu_set(cpu, smp_commenced_mask); while (!cpu_isset(cpu, cpu_online_map)) mb(); - return 0; + return(0); } int setup_profiling_timer(unsigned int multiplier) { printk(KERN_INFO "setup_profiling_timer\n"); - return 0; + return(0); } void smp_call_function_slave(int cpu); @@ -204,7 +205,7 @@ void IPI_handler(int cpu) int hard_smp_processor_id(void) { - return pid_to_processor_id(os_getpid()); + return(pid_to_processor_id(os_getpid())); } static DEFINE_SPINLOCK(call_lock); @@ -253,3 +254,14 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, } #endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/syscall.c b/trunk/arch/um/kernel/syscall.c index 237c4eab7cfd..2828c5283227 100644 --- a/trunk/arch/um/kernel/syscall.c +++ b/trunk/arch/um/kernel/syscall.c @@ -18,6 +18,7 @@ #include "asm/mman.h" #include "asm/uaccess.h" #include "kern_util.h" +#include "user_util.h" #include "sysdep/syscalls.h" #include "mode_kern.h" #include "choose-mode.h" diff --git a/trunk/arch/um/kernel/sysrq.c b/trunk/arch/um/kernel/sysrq.c index 93263571d813..f9e02b31a97a 100644 --- a/trunk/arch/um/kernel/sysrq.c +++ b/trunk/arch/um/kernel/sysrq.c @@ -10,6 +10,7 @@ #include "asm/page.h" #include "asm/processor.h" #include "sysrq.h" +#include "user_util.h" /* Catch non-i386 SUBARCH's. */ #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) diff --git a/trunk/arch/um/kernel/time.c b/trunk/arch/um/kernel/time.c index 259c49da7ff5..b1f8b0752419 100644 --- a/trunk/arch/um/kernel/time.c +++ b/trunk/arch/um/kernel/time.c @@ -18,6 +18,7 @@ #include "asm/param.h" #include "asm/current.h" #include "kern_util.h" +#include "user_util.h" #include "mode.h" #include "os.h" @@ -34,8 +35,8 @@ unsigned long long sched_clock(void) return (unsigned long long)jiffies_64 * (1000000000 / HZ); } -#ifdef CONFIG_UML_REAL_TIME_CLOCK static unsigned long long prev_nsecs[NR_CPUS]; +#ifdef CONFIG_UML_REAL_TIME_CLOCK static long long delta[NR_CPUS]; /* Deviation per interval */ #endif @@ -94,12 +95,7 @@ irqreturn_t um_timer(int irq, void *dev) do_timer(1); -#ifdef CONFIG_UML_REAL_TIME_CLOCK nsecs = get_time(); -#else - nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec + - BILLION / HZ; -#endif xtime.tv_sec = nsecs / NSEC_PER_SEC; xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; @@ -132,18 +128,13 @@ void time_init(void) nsecs = os_nsecs(); set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, -nsecs % BILLION); - set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION); late_time_init = register_timer; } void do_gettimeofday(struct timeval *tv) { -#ifdef CONFIG_UML_REAL_TIME_CLOCK unsigned long long nsecs = get_time(); -#else - unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION + - xtime.tv_nsec; -#endif + tv->tv_sec = nsecs / NSEC_PER_SEC; /* Careful about calculations here - this was originally done as * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC @@ -177,8 +168,6 @@ int do_settimeofday(struct timespec *tv) void timer_handler(int sig, union uml_pt_regs *regs) { - if(current_thread->cpu == 0) - timer_irq(regs); local_irq_disable(); irq_enter(); update_process_times(CHOOSE_MODE( @@ -186,4 +175,6 @@ void timer_handler(int sig, union uml_pt_regs *regs) (regs)->skas.is_user)); irq_exit(); local_irq_enable(); + if(current_thread->cpu == 0) + timer_irq(regs); } diff --git a/trunk/arch/um/kernel/tlb.c b/trunk/arch/um/kernel/tlb.c index 8a8d52851443..54a5ff25645a 100644 --- a/trunk/arch/um/kernel/tlb.c +++ b/trunk/arch/um/kernel/tlb.c @@ -6,18 +6,17 @@ #include "linux/mm.h" #include "asm/page.h" #include "asm/pgalloc.h" -#include "asm/pgtable.h" #include "asm/tlbflush.h" #include "choose-mode.h" #include "mode_kern.h" -#include "as-layout.h" +#include "user_util.h" #include "tlb.h" #include "mem.h" #include "mem_user.h" #include "os.h" static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, - unsigned int prot, struct host_vm_op *ops, int *index, + int r, int w, int x, struct host_vm_op *ops, int *index, int last_filled, union mm_context *mmu, void **flush, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) @@ -31,7 +30,8 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, last = &ops[*index]; if((last->type == MMAP) && (last->u.mmap.addr + last->u.mmap.len == virt) && - (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) && + (last->u.mmap.r == r) && (last->u.mmap.w == w) && + (last->u.mmap.x == x) && (last->u.mmap.fd == fd) && (last->u.mmap.offset + last->u.mmap.len == offset)){ last->u.mmap.len += len; return 0; @@ -47,7 +47,9 @@ static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, .u = { .mmap = { .addr = virt, .len = len, - .prot = prot, + .r = r, + .w = w, + .x = x, .fd = fd, .offset = offset } } }); @@ -84,8 +86,8 @@ static int add_munmap(unsigned long addr, unsigned long len, return ret; } -static int add_mprotect(unsigned long addr, unsigned long len, - unsigned int prot, struct host_vm_op *ops, int *index, +static int add_mprotect(unsigned long addr, unsigned long len, int r, int w, + int x, struct host_vm_op *ops, int *index, int last_filled, union mm_context *mmu, void **flush, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) @@ -97,7 +99,8 @@ static int add_mprotect(unsigned long addr, unsigned long len, last = &ops[*index]; if((last->type == MPROTECT) && (last->u.mprotect.addr + last->u.mprotect.len == addr) && - (last->u.mprotect.prot == prot)){ + (last->u.mprotect.r == r) && (last->u.mprotect.w == w) && + (last->u.mprotect.x == x)){ last->u.mprotect.len += len; return 0; } @@ -112,145 +115,114 @@ static int add_mprotect(unsigned long addr, unsigned long len, .u = { .mprotect = { .addr = addr, .len = len, - .prot = prot } } }); + .r = r, + .w = w, + .x = x } } }); return ret; } #define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) -static inline int update_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, struct host_vm_op *ops, - int last_op, int *op_index, int force, - union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, - struct host_vm_op *, int, int, - void **)) -{ - pte_t *pte; - int r, w, x, prot, ret = 0; - - pte = pte_offset_kernel(pmd, addr); - do { - r = pte_read(*pte); - w = pte_write(*pte); - x = pte_exec(*pte); - if (!pte_young(*pte)) { - r = 0; - w = 0; - } else if (!pte_dirty(*pte)) { - w = 0; - } - prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | - (x ? UM_PROT_EXEC : 0)); - if(force || pte_newpage(*pte)){ - if(pte_present(*pte)) - ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, - PAGE_SIZE, prot, ops, op_index, - last_op, mmu, flush, do_ops); - else ret = add_munmap(addr, PAGE_SIZE, ops, op_index, - last_op, mmu, flush, do_ops); - } - else if(pte_newprot(*pte)) - ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index, - last_op, mmu, flush, do_ops); - *pte = pte_mkuptodate(*pte); - } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); - return ret; -} - -static inline int update_pmd_range(pud_t *pud, unsigned long addr, - unsigned long end, struct host_vm_op *ops, - int last_op, int *op_index, int force, - union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, - struct host_vm_op *, int, int, - void **)) -{ - pmd_t *pmd; - unsigned long next; - int ret = 0; - - pmd = pmd_offset(pud, addr); - do { - next = pmd_addr_end(addr, end); - if(!pmd_present(*pmd)){ - if(force || pmd_newpage(*pmd)){ - ret = add_munmap(addr, next - addr, ops, - op_index, last_op, mmu, - flush, do_ops); - pmd_mkuptodate(*pmd); - } - } - else ret = update_pte_range(pmd, addr, next, ops, last_op, - op_index, force, mmu, flush, - do_ops); - } while (pmd++, addr = next, ((addr != end) && !ret)); - return ret; -} - -static inline int update_pud_range(pgd_t *pgd, unsigned long addr, - unsigned long end, struct host_vm_op *ops, - int last_op, int *op_index, int force, - union mm_context *mmu, void **flush, - int (*do_ops)(union mm_context *, - struct host_vm_op *, int, int, - void **)) -{ - pud_t *pud; - unsigned long next; - int ret = 0; - - pud = pud_offset(pgd, addr); - do { - next = pud_addr_end(addr, end); - if(!pud_present(*pud)){ - if(force || pud_newpage(*pud)){ - ret = add_munmap(addr, next - addr, ops, - op_index, last_op, mmu, - flush, do_ops); - pud_mkuptodate(*pud); - } - } - else ret = update_pmd_range(pud, addr, next, ops, last_op, - op_index, force, mmu, flush, - do_ops); - } while (pud++, addr = next, ((addr != end) && !ret)); - return ret; -} - void fix_range_common(struct mm_struct *mm, unsigned long start_addr, unsigned long end_addr, int force, int (*do_ops)(union mm_context *, struct host_vm_op *, int, int, void **)) { - pgd_t *pgd; + pgd_t *npgd; + pud_t *npud; + pmd_t *npmd; + pte_t *npte; union mm_context *mmu = &mm->context; + unsigned long addr, end; + int r, w, x; struct host_vm_op ops[1]; - unsigned long addr = start_addr, next; - int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1; void *flush = NULL; + int op_index = -1, last_op = ARRAY_SIZE(ops) - 1; + int ret = 0; + + if(mm == NULL) + return; ops[0].type = NONE; - pgd = pgd_offset(mm, addr); - do { - next = pgd_addr_end(addr, end_addr); - if(!pgd_present(*pgd)){ - if (force || pgd_newpage(*pgd)){ - ret = add_munmap(addr, next - addr, ops, + for(addr = start_addr; addr < end_addr && !ret;){ + npgd = pgd_offset(mm, addr); + if(!pgd_present(*npgd)){ + end = ADD_ROUND(addr, PGDIR_SIZE); + if(end > end_addr) + end = end_addr; + if(force || pgd_newpage(*npgd)){ + ret = add_munmap(addr, end - addr, ops, &op_index, last_op, mmu, &flush, do_ops); - pgd_mkuptodate(*pgd); + pgd_mkuptodate(*npgd); } + addr = end; + continue; } - else ret = update_pud_range(pgd, addr, next, ops, last_op, - &op_index, force, mmu, &flush, - do_ops); - } while (pgd++, addr = next, ((addr != end_addr) && !ret)); + npud = pud_offset(npgd, addr); + if(!pud_present(*npud)){ + end = ADD_ROUND(addr, PUD_SIZE); + if(end > end_addr) + end = end_addr; + if(force || pud_newpage(*npud)){ + ret = add_munmap(addr, end - addr, ops, + &op_index, last_op, mmu, + &flush, do_ops); + pud_mkuptodate(*npud); + } + addr = end; + continue; + } + + npmd = pmd_offset(npud, addr); + if(!pmd_present(*npmd)){ + end = ADD_ROUND(addr, PMD_SIZE); + if(end > end_addr) + end = end_addr; + if(force || pmd_newpage(*npmd)){ + ret = add_munmap(addr, end - addr, ops, + &op_index, last_op, mmu, + &flush, do_ops); + pmd_mkuptodate(*npmd); + } + addr = end; + continue; + } + + npte = pte_offset_kernel(npmd, addr); + r = pte_read(*npte); + w = pte_write(*npte); + x = pte_exec(*npte); + if (!pte_young(*npte)) { + r = 0; + w = 0; + } else if (!pte_dirty(*npte)) { + w = 0; + } + if(force || pte_newpage(*npte)){ + if(pte_present(*npte)) + ret = add_mmap(addr, + pte_val(*npte) & PAGE_MASK, + PAGE_SIZE, r, w, x, ops, + &op_index, last_op, mmu, + &flush, do_ops); + else ret = add_munmap(addr, PAGE_SIZE, ops, + &op_index, last_op, mmu, + &flush, do_ops); + } + else if(pte_newprot(*npte)) + ret = add_mprotect(addr, PAGE_SIZE, r, w, x, ops, + &op_index, last_op, mmu, + &flush, do_ops); + + *npte = pte_mkuptodate(*npte); + addr += PAGE_SIZE; + } if(!ret) ret = (*do_ops)(mmu, ops, op_index, 1, &flush); - /* This is not an else because ret is modified above */ +/* This is not an else because ret is modified above */ if(ret) { printk("fix_range_common: failed, killing current process\n"); force_sig(SIGKILL, current); @@ -371,6 +343,12 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr) return(pte_offset_map(pmd, addr)); } +void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) +{ + address &= PAGE_MASK; + flush_tlb_range(vma, address, address + PAGE_SIZE); +} + void flush_tlb_all(void) { flush_tlb_mm(current->mm); diff --git a/trunk/arch/um/kernel/trap.c b/trunk/arch/um/kernel/trap.c index abab90c3803f..26f15c458574 100644 --- a/trunk/arch/um/kernel/trap.c +++ b/trunk/arch/um/kernel/trap.c @@ -18,9 +18,8 @@ #include "asm/current.h" #include "asm/irq.h" #include "sysdep/sigcontext.h" +#include "user_util.h" #include "kern_util.h" -#include "as-layout.h" -#include "arch.h" #include "kern.h" #include "chan_kern.h" #include "mconsole_kern.h" @@ -72,8 +71,8 @@ int handle_page_fault(unsigned long address, unsigned long ip, goto out; /* Don't require VM_READ|VM_EXEC for write faults! */ - if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) - goto out; + if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) + goto out; do { survive: @@ -157,23 +156,20 @@ static void segv_handler(int sig, union uml_pt_regs *regs) * the info in the regs. A pointer to the info then would * give us bad data! */ -unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, - union uml_pt_regs *regs) +unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) { struct siginfo si; void *catcher; int err; - int is_write = FAULT_WRITE(fi); - unsigned long address = FAULT_ADDRESS(fi); + int is_write = FAULT_WRITE(fi); + unsigned long address = FAULT_ADDRESS(fi); - if(!is_user && (address >= start_vm) && (address < end_vm)){ - flush_tlb_kernel_vm(); - return 0; - } - else if(current->mm == NULL) { - show_regs(container_of(regs, struct pt_regs, regs)); - panic("Segfault with no mm"); - } + if(!is_user && (address >= start_vm) && (address < end_vm)){ + flush_tlb_kernel_vm(); + return(0); + } + else if(current->mm == NULL) + panic("Segfault with no mm"); if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); @@ -186,28 +182,26 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, catcher = current->thread.fault_catcher; if(!err) - return 0; + return(0); else if(catcher != NULL){ current->thread.fault_addr = (void *) address; do_longjmp(catcher, 1); } else if(current->thread.fault_addr != NULL) panic("fault_addr set but no fault catcher"); - else if(!is_user && arch_fixup(ip, regs)) - return 0; + else if(!is_user && arch_fixup(ip, sc)) + return(0); - if(!is_user) { - show_regs(container_of(regs, struct pt_regs, regs)); + if(!is_user) panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", address, ip); - } if (err == -EACCES) { si.si_signo = SIGBUS; si.si_errno = 0; si.si_code = BUS_ADRERR; si.si_addr = (void __user *)address; - current->thread.arch.faultinfo = fi; + current->thread.arch.faultinfo = fi; force_sig_info(SIGBUS, &si, current); } else if (err == -ENOMEM) { printk("VM: killing process %s\n", current->comm); @@ -216,10 +210,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, BUG_ON(err != -EFAULT); si.si_signo = SIGSEGV; si.si_addr = (void __user *) address; - current->thread.arch.faultinfo = fi; + current->thread.arch.faultinfo = fi; force_sig_info(SIGSEGV, &si, current); } - return 0; + return(0); } void relay_signal(int sig, union uml_pt_regs *regs) @@ -229,12 +223,12 @@ void relay_signal(int sig, union uml_pt_regs *regs) if(!UPT_IS_USER(regs)){ if(sig == SIGBUS) - printk("Bus error - the host /dev/shm or /tmp mount " - "likely just ran out of space\n"); + printk("Bus error - the /dev/shm or /tmp mount likely " + "just ran out of space\n"); panic("Kernel mode signal %d", sig); } - current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); + current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); force_sig(sig, current); } diff --git a/trunk/arch/um/kernel/tt/exec_kern.c b/trunk/arch/um/kernel/tt/exec_kern.c index 98e21743e604..ad66df17d9d7 100644 --- a/trunk/arch/um/kernel/tt/exec_kern.c +++ b/trunk/arch/um/kernel/tt/exec_kern.c @@ -10,6 +10,7 @@ #include "asm/uaccess.h" #include "asm/pgalloc.h" #include "asm/tlbflush.h" +#include "user_util.h" #include "kern_util.h" #include "irq_user.h" #include "mem_user.h" diff --git a/trunk/arch/um/kernel/tt/exec_user.c b/trunk/arch/um/kernel/tt/exec_user.c index 7b5f2181cf51..a92c02ff2ce3 100644 --- a/trunk/arch/um/kernel/tt/exec_user.c +++ b/trunk/arch/um/kernel/tt/exec_user.c @@ -10,6 +10,7 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "ptrace_user.h" diff --git a/trunk/arch/um/kernel/tt/gdb.c b/trunk/arch/um/kernel/tt/gdb.c index 030e4658f36b..8eba8f7dca68 100644 --- a/trunk/arch/um/kernel/tt/gdb.c +++ b/trunk/arch/um/kernel/tt/gdb.c @@ -17,6 +17,7 @@ #include "user.h" #include "debug.h" #include "kern_util.h" +#include "user_util.h" #include "tt.h" #include "sysdep/thread.h" #include "os.h" @@ -114,8 +115,6 @@ struct gdb_data { int err; }; -extern char *linux_prog; - static void config_gdb_cb(void *arg) { struct gdb_data *data = arg; diff --git a/trunk/arch/um/kernel/tt/include/mode_kern-tt.h b/trunk/arch/um/kernel/tt/include/mode_kern-tt.h new file mode 100644 index 000000000000..2a35b15c5fef --- /dev/null +++ b/trunk/arch/um/kernel/tt/include/mode_kern-tt.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __TT_MODE_KERN_H__ +#define __TT_MODE_KERN_H__ + +#include "linux/sched.h" +#include "asm/page.h" +#include "asm/ptrace.h" +#include "asm/uaccess.h" + +extern void switch_to_tt(void *prev, void *next); +extern void flush_thread_tt(void); +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, + unsigned long esp); +extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, + unsigned long stack_top, struct task_struct *p, + struct pt_regs *regs); +extern void release_thread_tt(struct task_struct *task); +extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); +extern void init_idle_tt(void); +extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); +extern void flush_tlb_kernel_vm_tt(void); +extern void __flush_tlb_one_tt(unsigned long addr); +extern void flush_tlb_range_tt(struct vm_area_struct *vma, + unsigned long start, unsigned long end); +extern void flush_tlb_mm_tt(struct mm_struct *mm); +extern void force_flush_all_tt(void); +extern long execute_syscall_tt(void *r); +extern void before_mem_tt(unsigned long brk_start); +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, + unsigned long *task_size_out); +extern int start_uml_tt(void); +extern int external_pid_tt(struct task_struct *task); +extern int thread_pid_tt(struct task_struct *task); + +#define kmem_end_tt (host_task_size - ABOVE_KMEM) + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/tt/mem.c b/trunk/arch/um/kernel/tt/mem.c index d0c3c4975f28..4d1929dfa285 100644 --- a/trunk/arch/um/kernel/tt/mem.c +++ b/trunk/arch/um/kernel/tt/mem.c @@ -8,6 +8,7 @@ #include "asm/uaccess.h" #include "mem_user.h" #include "kern_util.h" +#include "user_util.h" #include "kern.h" #include "tt.h" diff --git a/trunk/arch/um/kernel/tt/mem_user.c b/trunk/arch/um/kernel/tt/mem_user.c index 9774f6360c32..03e589895388 100644 --- a/trunk/arch/um/kernel/tt/mem_user.c +++ b/trunk/arch/um/kernel/tt/mem_user.c @@ -11,6 +11,7 @@ #include #include "tt.h" #include "mem_user.h" +#include "user_util.h" #include "os.h" void remap_data(void *segment_start, void *segment_end, int w) diff --git a/trunk/arch/um/kernel/tt/process_kern.c b/trunk/arch/um/kernel/tt/process_kern.c index c631303cb800..1e86f0bfef72 100644 --- a/trunk/arch/um/kernel/tt/process_kern.c +++ b/trunk/arch/um/kernel/tt/process_kern.c @@ -14,6 +14,7 @@ #include "asm/tlbflush.h" #include "irq_user.h" #include "kern_util.h" +#include "user_util.h" #include "os.h" #include "kern.h" #include "sigcontext.h" @@ -64,8 +65,7 @@ void switch_to_tt(void *prev, void *next) if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); - err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, - sizeof(c)); + err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); if(err != sizeof(c)) panic("read of switch_pipe failed, errno = %d", -err); diff --git a/trunk/arch/um/kernel/tt/ptproxy/proxy.c b/trunk/arch/um/kernel/tt/ptproxy/proxy.c index 420c23f311f3..58800c50b10e 100644 --- a/trunk/arch/um/kernel/tt/ptproxy/proxy.c +++ b/trunk/arch/um/kernel/tt/ptproxy/proxy.c @@ -26,6 +26,7 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml #include "sysdep.h" #include "wait.h" +#include "user_util.h" #include "user.h" #include "os.h" #include "tempfile.h" @@ -338,12 +339,11 @@ int start_debugger(char *prog, int startup, int stop, int *fd_out) "err = %d\n", -fd); exit(1); } - os_write_file(fd, gdb_init_string, - sizeof(gdb_init_string) - 1); + os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1); if(startup){ if(stop){ os_write_file(fd, "b start_kernel\n", - strlen("b start_kernel\n")); + strlen("b start_kernel\n")); } os_write_file(fd, "c\n", strlen("c\n")); } diff --git a/trunk/arch/um/kernel/tt/ptproxy/ptrace.c b/trunk/arch/um/kernel/tt/ptproxy/ptrace.c index 4b4f6179b212..03774427d468 100644 --- a/trunk/arch/um/kernel/tt/ptproxy/ptrace.c +++ b/trunk/arch/um/kernel/tt/ptproxy/ptrace.c @@ -16,6 +16,7 @@ Jeff Dike (jdike@karaya.com) : Modified for integration into uml #include "ptproxy.h" #include "debug.h" +#include "user_util.h" #include "kern_util.h" #include "ptrace_user.h" #include "tt.h" diff --git a/trunk/arch/um/kernel/tt/ptproxy/sysdep.c b/trunk/arch/um/kernel/tt/ptproxy/sysdep.c index e0e1ab0588ad..99f178319d03 100644 --- a/trunk/arch/um/kernel/tt/ptproxy/sysdep.c +++ b/trunk/arch/um/kernel/tt/ptproxy/sysdep.c @@ -13,6 +13,7 @@ terms and conditions. #include #include #include "ptrace_user.h" +#include "user_util.h" #include "user.h" #include "os.h" diff --git a/trunk/arch/um/kernel/tt/ptproxy/wait.c b/trunk/arch/um/kernel/tt/ptproxy/wait.c index bdd4af4b65fc..12f6319d8d76 100644 --- a/trunk/arch/um/kernel/tt/ptproxy/wait.c +++ b/trunk/arch/um/kernel/tt/ptproxy/wait.c @@ -13,6 +13,7 @@ terms and conditions. #include "ptproxy.h" #include "sysdep.h" #include "wait.h" +#include "user_util.h" #include "ptrace_user.h" #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" diff --git a/trunk/arch/um/kernel/tt/syscall_user.c b/trunk/arch/um/kernel/tt/syscall_user.c index f52b47aff1d2..902987bf379b 100644 --- a/trunk/arch/um/kernel/tt/syscall_user.c +++ b/trunk/arch/um/kernel/tt/syscall_user.c @@ -11,6 +11,7 @@ #include "sigcontext.h" #include "ptrace_user.h" #include "task.h" +#include "user_util.h" #include "kern_util.h" #include "syscall.h" #include "tt.h" diff --git a/trunk/arch/um/kernel/tt/tlb.c b/trunk/arch/um/kernel/tt/tlb.c index 7caa24fe05df..ae6217c86135 100644 --- a/trunk/arch/um/kernel/tt/tlb.c +++ b/trunk/arch/um/kernel/tt/tlb.c @@ -12,6 +12,7 @@ #include "asm/pgtable.h" #include "asm/uaccess.h" #include "asm/tlbflush.h" +#include "user_util.h" #include "mem_user.h" #include "os.h" #include "tlb.h" diff --git a/trunk/arch/um/kernel/tt/tracer.c b/trunk/arch/um/kernel/tt/tracer.c index c23588393f6e..b9195355075a 100644 --- a/trunk/arch/um/kernel/tt/tracer.c +++ b/trunk/arch/um/kernel/tt/tracer.c @@ -19,6 +19,7 @@ #include "sigcontext.h" #include "sysdep/sigcontext.h" #include "os.h" +#include "user_util.h" #include "mem_user.h" #include "process.h" #include "kern_util.h" diff --git a/trunk/arch/um/kernel/tt/trap_user.c b/trunk/arch/um/kernel/tt/trap_user.c index 3032eb5e2467..b5d9d64d91e4 100644 --- a/trunk/arch/um/kernel/tt/trap_user.c +++ b/trunk/arch/um/kernel/tt/trap_user.c @@ -8,6 +8,7 @@ #include #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" +#include "user_util.h" #include "kern_util.h" #include "task.h" #include "tt.h" diff --git a/trunk/arch/um/kernel/tt/uaccess_user.c b/trunk/arch/um/kernel/tt/uaccess_user.c index 0e5c82c5e5b7..ed1abcf4d057 100644 --- a/trunk/arch/um/kernel/tt/uaccess_user.c +++ b/trunk/arch/um/kernel/tt/uaccess_user.c @@ -5,6 +5,7 @@ */ #include +#include "user_util.h" #include "uml_uaccess.h" #include "task.h" #include "kern_util.h" diff --git a/trunk/arch/um/kernel/um_arch.c b/trunk/arch/um/kernel/um_arch.c index 1cf954a47fd7..89c6dba731f8 100644 --- a/trunk/arch/um/kernel/um_arch.c +++ b/trunk/arch/um/kernel/um_arch.c @@ -17,7 +17,6 @@ #include "linux/seq_file.h" #include "linux/delay.h" #include "linux/module.h" -#include "linux/utsname.h" #include "asm/page.h" #include "asm/pgtable.h" #include "asm/ptrace.h" @@ -26,9 +25,8 @@ #include "asm/setup.h" #include "ubd_user.h" #include "asm/current.h" +#include "user_util.h" #include "kern_util.h" -#include "as-layout.h" -#include "arch.h" #include "kern.h" #include "mem_user.h" #include "mem.h" @@ -44,7 +42,7 @@ #define DEFAULT_COMMAND_LINE "root=98:0" -/* Changed in add_arg and setup_arch, which run before SMP is started */ +/* Changed in linux_main and setup_arch, which run before SMP is started */ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; static void __init add_arg(char *arg) @@ -58,25 +56,17 @@ static void __init add_arg(char *arg) strcat(command_line, arg); } -/* - * These fields are initialized at boot time and not changed. - * XXX This structure is used only in the non-SMP case. Maybe this - * should be moved to smp.c. - */ -struct cpuinfo_um boot_cpu_data = { +struct cpuinfo_um boot_cpu_data = { .loops_per_jiffy = 0, .ipi_pipe = { -1, -1 } }; unsigned long thread_saved_pc(struct task_struct *task) { - return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, - task)); + return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, + task))); } -/* Changed in setup_arch, which is called in early boot */ -static char host_info[(__NEW_UTS_LEN + 1) * 5]; - static int show_cpuinfo(struct seq_file *m, void *v) { int index = 0; @@ -96,7 +86,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) loops_per_jiffy/(500000/HZ), (loops_per_jiffy/(5000/HZ)) % 100); - return 0; + return(0); } static void *c_start(struct seq_file *m, loff_t *pos) @@ -124,12 +114,14 @@ const struct seq_operations cpuinfo_op = { /* Set in linux_main */ unsigned long host_task_size; unsigned long task_size; + +unsigned long uml_start; + +/* Set in early boot */ unsigned long uml_physmem; -unsigned long uml_reserved; /* Also modified in mem_init */ +unsigned long uml_reserved; unsigned long start_vm; unsigned long end_vm; - -/* Set in uml_ncpus_setup */ int ncpus = 1; #ifdef CONFIG_CMDLINE_ON_HOST @@ -143,8 +135,6 @@ static char *argv1_end = NULL; /* Set in early boot */ static int have_root __initdata = 0; - -/* Set in uml_mem_setup and modified in linux_main */ long long physmem_size = 32 * 1024 * 1024; void set_cmdline(char *cmd) @@ -222,12 +212,12 @@ __uml_setup("debug", no_skas_debug_setup, #ifdef CONFIG_SMP static int __init uml_ncpus_setup(char *line, int *add) { - if (!sscanf(line, "%d", &ncpus)) { - printf("Couldn't parse [%s]\n", line); - return -1; - } + if (!sscanf(line, "%d", &ncpus)) { + printf("Couldn't parse [%s]\n", line); + return -1; + } - return 0; + return 0; } __uml_setup("ncpus=", uml_ncpus_setup, @@ -244,7 +234,7 @@ static int force_tt = 0; static int __init mode_tt_setup(char *line, int *add) { force_tt = 1; - return 0; + return(0); } #else @@ -255,7 +245,7 @@ static int __init mode_tt_setup(char *line, int *add) static int __init mode_tt_setup(char *line, int *add) { printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); - return 0; + return(0); } #else @@ -266,7 +256,7 @@ static int __init mode_tt_setup(char *line, int *add) static int __init mode_tt_setup(char *line, int *add) { printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); - return 0; + return(0); } #endif @@ -284,15 +274,16 @@ int mode_tt = DEFAULT_TT; static int __init Usage(char *line, int *add) { - const char **p; + const char **p; printf(usage_string, init_utsname()->release); - p = &__uml_help_start; - while (p < &__uml_help_end) { - printf("%s", *p); - p++; - } + p = &__uml_help_start; + while (p < &__uml_help_end) { + printf("%s", *p); + p++; + } exit(0); + return 0; } @@ -383,12 +374,13 @@ int __init linux_main(int argc, char **argv) printf("UML running in %s mode\n", mode); + uml_start = (unsigned long) &__binary_start; host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, &task_size); /* - * Setting up handlers to 'sig_info' struct - */ + * Setting up handlers to 'sig_info' struct + */ os_fill_handlinfo(handlinfo_kern); brk_start = (unsigned long) sbrk(0); @@ -404,7 +396,7 @@ int __init linux_main(int argc, char **argv) physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); } - uml_physmem = (unsigned long) &__binary_start & PAGE_MASK; + uml_physmem = uml_start & PAGE_MASK; /* Reserve up to 4M after the current brk */ uml_reserved = ROUND_4M(brk_start) + (1 << 22); @@ -415,7 +407,7 @@ int __init linux_main(int argc, char **argv) argv1_begin = argv[1]; argv1_end = &argv[1][strlen(argv[1])]; #endif - + highmem = 0; iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; @@ -457,12 +449,12 @@ int __init linux_main(int argc, char **argv) printf("Kernel virtual memory size shrunk to %lu bytes\n", virtmem_size); - uml_postsetup(); + uml_postsetup(); task_protections((unsigned long) &init_thread_info); os_flush_stdout(); - return CHOOSE_MODE(start_uml_tt(), start_uml_skas()); + return(CHOOSE_MODE(start_uml_tt(), start_uml_skas())); } extern int uml_exitcode; @@ -474,8 +466,8 @@ static int panic_exit(struct notifier_block *self, unsigned long unused1, show_regs(&(current->thread.regs)); bust_spinlocks(0); uml_exitcode = 1; - os_dump_core(); - return 0; + machine_halt(); + return(0); } static struct notifier_block panic_exit_notifier = { @@ -490,14 +482,14 @@ void __init setup_arch(char **cmdline_p) &panic_exit_notifier); paging_init(); strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - setup_hostinfo(host_info, sizeof host_info); + *cmdline_p = command_line; + setup_hostinfo(); } void __init check_bugs(void) { arch_check_bugs(); - os_check_bugs(); + os_check_bugs(); } void apply_alternatives(struct alt_instr *start, struct alt_instr *end) diff --git a/trunk/arch/um/os-Linux/aio.c b/trunk/arch/um/os-Linux/aio.c index 9bf944f6a1db..6ff12743a0bd 100644 --- a/trunk/arch/um/os-Linux/aio.c +++ b/trunk/arch/um/os-Linux/aio.c @@ -132,10 +132,10 @@ static int aio_thread(void *arg) { .data = (void *) (long) event.data, .err = event.res }); reply_fd = ((struct aio_context *) reply.data)->reply_fd; - err = write(reply_fd, &reply, sizeof(reply)); + err = os_write_file(reply_fd, &reply, sizeof(reply)); if(err != sizeof(reply)) printk("aio_thread - write failed, fd = %d, " - "err = %d\n", reply_fd, errno); + "err = %d\n", reply_fd, -err); } } return 0; @@ -146,31 +146,38 @@ static int aio_thread(void *arg) static int do_not_aio(struct aio_thread_req *req) { char c; - unsigned long long actual; - int n; - - actual = lseek64(req->io_fd, req->offset, SEEK_SET); - if(actual != req->offset) - return -errno; + int err; switch(req->type){ case AIO_READ: - n = read(req->io_fd, req->buf, req->len); + err = os_seek_file(req->io_fd, req->offset); + if(err) + goto out; + + err = os_read_file(req->io_fd, req->buf, req->len); break; case AIO_WRITE: - n = write(req->io_fd, req->buf, req->len); + err = os_seek_file(req->io_fd, req->offset); + if(err) + goto out; + + err = os_write_file(req->io_fd, req->buf, req->len); break; case AIO_MMAP: - n = read(req->io_fd, &c, sizeof(c)); + err = os_seek_file(req->io_fd, req->offset); + if(err) + goto out; + + err = os_read_file(req->io_fd, &c, sizeof(c)); break; default: printk("do_not_aio - bad request type : %d\n", req->type); - return -EINVAL; + err = -EINVAL; + break; } - if(n < 0) - return -errno; - return 0; +out: + return err; } /* These are initialized in initcalls and not changed */ @@ -186,12 +193,12 @@ static int not_aio_thread(void *arg) signal(SIGWINCH, SIG_IGN); while(1){ - err = read(aio_req_fd_r, &req, sizeof(req)); + err = os_read_file(aio_req_fd_r, &req, sizeof(req)); if(err != sizeof(req)){ if(err < 0) printk("not_aio_thread - read failed, " "fd = %d, err = %d\n", aio_req_fd_r, - errno); + -err); else { printk("not_aio_thread - short read, fd = %d, " "length = %d\n", aio_req_fd_r, err); @@ -200,11 +207,11 @@ static int not_aio_thread(void *arg) } err = do_not_aio(&req); reply = ((struct aio_thread_reply) { .data = req.aio, - .err = err }); - err = write(req.aio->reply_fd, &reply, sizeof(reply)); + .err = err }); + err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply)); if(err != sizeof(reply)) printk("not_aio_thread - write failed, fd = %d, " - "err = %d\n", req.aio->reply_fd, errno); + "err = %d\n", req.aio->reply_fd, -err); } return 0; @@ -221,11 +228,6 @@ static int init_aio_24(void) aio_req_fd_w = fds[0]; aio_req_fd_r = fds[1]; - - err = os_set_fd_block(aio_req_fd_w, 0); - if(err) - goto out_close_pipe; - err = run_helper_thread(not_aio_thread, NULL, CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0); if(err < 0) @@ -283,12 +285,10 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len, if(err){ reply = ((struct aio_thread_reply) { .data = aio, .err = err }); - err = write(aio->reply_fd, &reply, sizeof(reply)); - if(err != sizeof(reply)){ - err = -errno; + err = os_write_file(aio->reply_fd, &reply, sizeof(reply)); + if(err != sizeof(reply)) printk("submit_aio_26 - write failed, " "fd = %d, err = %d\n", aio->reply_fd, -err); - } else err = 0; } @@ -383,10 +383,9 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len, }; int err; - err = write(aio_req_fd_w, &req, sizeof(req)); + err = os_write_file(aio_req_fd_w, &req, sizeof(req)); if(err == sizeof(req)) err = 0; - else err = -errno; return err; } diff --git a/trunk/arch/um/os-Linux/drivers/ethertap_user.c b/trunk/arch/um/os-Linux/drivers/ethertap_user.c index acba30161287..863981ba1468 100644 --- a/trunk/arch/um/os-Linux/drivers/ethertap_user.c +++ b/trunk/arch/um/os-Linux/drivers/ethertap_user.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and + * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and * James Leu (jleu@mindspring.net). * Copyright (C) 2001 by various other people who didn't put their name here. * Licensed under the GPL. @@ -16,20 +16,19 @@ #include #include "user.h" #include "kern_util.h" +#include "user_util.h" #include "net_user.h" #include "etap.h" #include "os.h" #include "um_malloc.h" -#include "kern_constants.h" #define MAX_PACKET ETH_MAX_PACKET -static int etap_user_init(void *data, void *dev) +void etap_user_init(void *data, void *dev) { struct ethertap_data *pri = data; pri->dev = dev; - return 0; } struct addr_change { @@ -48,16 +47,13 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask, change.what = op; memcpy(change.addr, addr, sizeof(change.addr)); memcpy(change.netmask, netmask, sizeof(change.netmask)); - CATCH_EINTR(n = write(fd, &change, sizeof(change))); - if(n != sizeof(change)){ - printk("etap_change - request failed, err = %d\n", errno); - return; - } - - output = um_kmalloc(UM_KERN_PAGE_SIZE); + n = os_write_file(fd, &change, sizeof(change)); + if(n != sizeof(change)) + printk("etap_change - request failed, err = %d\n", -n); + output = um_kmalloc(page_size()); if(output == NULL) printk("etap_change : Failed to allocate output buffer\n"); - read_output(fd, output, UM_KERN_PAGE_SIZE); + read_output(fd, output, page_size()); if(output != NULL){ printk("%s", output); kfree(output); @@ -119,15 +115,13 @@ static int etap_tramp(char *dev, char *gate, int control_me, pe_data.data_me = data_me; pid = run_helper(etap_pre_exec, &pe_data, args, NULL); - if(pid < 0) - err = pid; + if(pid < 0) err = pid; os_close_file(data_remote); os_close_file(control_remote); - CATCH_EINTR(n = read(control_me, &c, sizeof(c))); + n = os_read_file(control_me, &c, sizeof(c)); if(n != sizeof(c)){ - err = -errno; - printk("etap_tramp : read of status failed, err = %d\n", -err); - return err; + printk("etap_tramp : read of status failed, err = %d\n", -n); + return(-EINVAL); } if(c != 1){ printk("etap_tramp : uml_net failed\n"); @@ -138,7 +132,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) printk("uml_net didn't exit with status 1\n"); } - return err; + return(err); } static int etap_open(void *data) @@ -148,24 +142,23 @@ static int etap_open(void *data) int data_fds[2], control_fds[2], err, output_len; err = tap_open_common(pri->dev, pri->gate_addr); - if(err) - return err; + if(err) return(err); err = os_pipe(data_fds, 0, 0); if(err < 0){ printk("data os_pipe failed - err = %d\n", -err); - return err; + return(err); } err = os_pipe(control_fds, 1, 0); if(err < 0){ printk("control os_pipe failed - err = %d\n", -err); - return err; + return(err); } - + err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], control_fds[1], data_fds[0], data_fds[1]); - output_len = UM_KERN_PAGE_SIZE; + output_len = page_size(); output = um_kmalloc(output_len); read_output(control_fds[0], output, output_len); @@ -178,13 +171,13 @@ static int etap_open(void *data) if(err < 0){ printk("etap_tramp failed - err = %d\n", -err); - return err; + return(err); } pri->data_fd = data_fds[0]; pri->control_fd = control_fds[0]; iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); - return data_fds[0]; + return(data_fds[0]); } static void etap_close(int fd, void *data) @@ -202,7 +195,7 @@ static void etap_close(int fd, void *data) static int etap_set_mtu(int mtu, void *data) { - return mtu; + return(mtu); } static void etap_add_addr(unsigned char *addr, unsigned char *netmask, @@ -211,8 +204,7 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask, struct ethertap_data *pri = data; tap_check_ips(pri->gate_addr, addr); - if(pri->control_fd == -1) - return; + if(pri->control_fd == -1) return; etap_open_addr(addr, netmask, &pri->control_fd); } @@ -221,8 +213,7 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask, { struct ethertap_data *pri = data; - if(pri->control_fd == -1) - return; + if(pri->control_fd == -1) return; etap_close_addr(addr, netmask, &pri->control_fd); } @@ -236,3 +227,14 @@ const struct net_user_info ethertap_user_info = { .delete_address = etap_del_addr, .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP }; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/os-Linux/drivers/tuntap_user.c b/trunk/arch/um/os-Linux/drivers/tuntap_user.c index 11a9779dc9f1..e846b23f7558 100644 --- a/trunk/arch/um/os-Linux/drivers/tuntap_user.c +++ b/trunk/arch/um/os-Linux/drivers/tuntap_user.c @@ -18,17 +18,17 @@ #include "net_user.h" #include "tuntap.h" #include "kern_util.h" +#include "user_util.h" #include "user.h" #include "os.h" #define MAX_PACKET ETH_MAX_PACKET -static int tuntap_user_init(void *data, void *dev) +void tuntap_user_init(void *data, void *dev) { struct tuntap_data *pri = data; pri->dev = dev; - return 0; } static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, @@ -37,8 +37,7 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, struct tuntap_data *pri = data; tap_check_ips(pri->gate_addr, addr); - if((pri->fd == -1) || pri->fixed_config) - return; + if((pri->fd == -1) || pri->fixed_config) return; open_addr(addr, netmask, pri->dev_name); } @@ -47,8 +46,7 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask, { struct tuntap_data *pri = data; - if((pri->fd == -1) || pri->fixed_config) - return; + if((pri->fd == -1) || pri->fixed_config) return; close_addr(addr, netmask, pri->dev_name); } @@ -60,7 +58,7 @@ struct tuntap_pre_exec_data { static void tuntap_pre_exec(void *arg) { struct tuntap_pre_exec_data *data = arg; - + dup2(data->stdout, 1); os_close_file(data->close_me); } @@ -85,8 +83,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, pid = run_helper(tuntap_pre_exec, &data, argv, NULL); - if(pid < 0) - return -pid; + if(pid < 0) return(-pid); os_close_file(remote); @@ -117,16 +114,16 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, cmsg = CMSG_FIRSTHDR(&msg); if(cmsg == NULL){ printk("tuntap_open_tramp : didn't receive a message\n"); - return -EINVAL; + return(-EINVAL); } if((cmsg->cmsg_level != SOL_SOCKET) || (cmsg->cmsg_type != SCM_RIGHTS)){ printk("tuntap_open_tramp : didn't receive a descriptor\n"); - return -EINVAL; + return(-EINVAL); } *fd_out = ((int *) CMSG_DATA(cmsg))[0]; os_set_exec_close(*fd_out, 1); - return 0; + return(0); } static int tuntap_open(void *data) @@ -138,7 +135,7 @@ static int tuntap_open(void *data) err = tap_open_common(pri->dev, pri->gate_addr); if(err < 0) - return err; + return(err); if(pri->fixed_config){ pri->fd = os_open_file("/dev/net/tun", @@ -146,7 +143,7 @@ static int tuntap_open(void *data) if(pri->fd < 0){ printk("Failed to open /dev/net/tun, err = %d\n", -pri->fd); - return pri->fd; + return(pri->fd); } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; @@ -163,7 +160,7 @@ static int tuntap_open(void *data) if(err < 0){ printk("tuntap_open : os_pipe failed - err = %d\n", -err); - return err; + return(err); } buffer = get_output_buffer(&len); @@ -178,7 +175,7 @@ static int tuntap_open(void *data) printk("%s", output); free_output_buffer(buffer); printk("tuntap_open_tramp failed - err = %d\n", -err); - return err; + return(err); } pri->dev_name = uml_strdup(buffer); @@ -190,7 +187,7 @@ static int tuntap_open(void *data) iter_addresses(pri->dev, open_addr, pri->dev_name); } - return pri->fd; + return(pri->fd); } static void tuntap_close(int fd, void *data) @@ -205,7 +202,7 @@ static void tuntap_close(int fd, void *data) static int tuntap_set_mtu(int mtu, void *data) { - return mtu; + return(mtu); } const struct net_user_info tuntap_user_info = { @@ -218,3 +215,14 @@ const struct net_user_info tuntap_user_info = { .delete_address = tuntap_del_addr, .max_packet = MAX_PACKET }; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/os-Linux/file.c b/trunk/arch/um/os-Linux/file.c index 6f92f732d253..371b4335f46d 100644 --- a/trunk/arch/um/os-Linux/file.c +++ b/trunk/arch/um/os-Linux/file.c @@ -18,6 +18,7 @@ #include "os.h" #include "user.h" #include "kern_util.h" +#include "user_util.h" static void copy_stat(struct uml_stat *dst, struct stat64 *src) { @@ -290,24 +291,56 @@ int os_seek_file(int fd, __u64 offset) return 0; } -int os_read_file(int fd, void *buf, int len) +static int fault_buffer(void *start, int len, + int (*copy_proc)(void *addr, void *buf, int len)) { - int n = read(fd, buf, len); + int page = getpagesize(), i; + char c; - if(n < 0) - return -errno; - return n; + for(i = 0; i < len; i += page){ + if((*copy_proc)(start + i, &c, sizeof(c))) + return -EFAULT; + } + if((len % page) != 0){ + if((*copy_proc)(start + len - 1, &c, sizeof(c))) + return -EFAULT; + } + return 0; } -int os_write_file(int fd, const void *buf, int len) +static int file_io(int fd, void *buf, int len, + int (*io_proc)(int fd, void *buf, int len), + int (*copy_user_proc)(void *addr, void *buf, int len)) { - int n = write(fd, (void *) buf, len); + int n, err; + + do { + n = (*io_proc)(fd, buf, len); + if((n < 0) && (errno == EFAULT)){ + err = fault_buffer(buf, len, copy_user_proc); + if(err) + return err; + n = (*io_proc)(fd, buf, len); + } + } while((n < 0) && (errno == EINTR)); if(n < 0) return -errno; return n; } +int os_read_file(int fd, void *buf, int len) +{ + return file_io(fd, buf, len, (int (*)(int, void *, int)) read, + copy_from_user_proc); +} + +int os_write_file(int fd, const void *buf, int len) +{ + return file_io(fd, (void *) buf, len, + (int (*)(int, void *, int)) write, copy_to_user_proc); +} + int os_file_size(char *file, unsigned long long *size_out) { struct uml_stat buf; diff --git a/trunk/arch/um/os-Linux/helper.c b/trunk/arch/um/os-Linux/helper.c index 97bed16bf4c7..c7ad6306e22f 100644 --- a/trunk/arch/um/os-Linux/helper.c +++ b/trunk/arch/um/os-Linux/helper.c @@ -13,9 +13,9 @@ #include #include "user.h" #include "kern_util.h" +#include "user_util.h" #include "os.h" #include "um_malloc.h" -#include "kern_constants.h" struct helper_data { void (*pre_exec)(void*); @@ -25,18 +25,28 @@ struct helper_data { char *buf; }; +/* Debugging aid, changed only from gdb */ +int helper_pause = 0; + +static void helper_hup(int sig) +{ +} + static int helper_child(void *arg) { struct helper_data *data = arg; char **argv = data->argv; int errval; + if (helper_pause){ + signal(SIGHUP, helper_hup); + pause(); + } if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); errval = execvp_noalloc(data->buf, argv[0], argv); - printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], - -errval); - write(data->fd, &errval, sizeof(errval)); + printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); + os_write_file(data->fd, &errval, sizeof(errval)); kill(os_getpid(), SIGKILL); return 0; } @@ -71,7 +81,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, goto out_close; } - sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *); + sp = stack + page_size() - sizeof(void *); data.pre_exec = pre_exec; data.pre_data = pre_data; data.argv = argv; @@ -88,16 +98,13 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, close(fds[1]); fds[1] = -1; - /* - * Read the errno value from the child, if the exec failed, or get 0 if - * the exec succeeded because the pipe fd was set as close-on-exec. - */ - n = read(fds[0], &ret, sizeof(ret)); + /* Read the errno value from the child, if the exec failed, or get 0 if + * the exec succeeded because the pipe fd was set as close-on-exec. */ + n = os_read_file(fds[0], &ret, sizeof(ret)); if (n == 0) { ret = pid; } else { if (n < 0) { - n = -errno; printk("run_helper : read on pipe failed, ret = %d\n", -n); ret = n; @@ -128,7 +135,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, if (stack == 0) return -ENOMEM; - sp = stack + (UM_KERN_PAGE_SIZE << stack_order) - sizeof(void *); + sp = stack + (page_size() << stack_order) - sizeof(void *); pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); if (pid < 0) { err = -errno; diff --git a/trunk/arch/um/os-Linux/irq.c b/trunk/arch/um/os-Linux/irq.c index a633fa8e0a94..d1b61d474e0a 100644 --- a/trunk/arch/um/os-Linux/irq.c +++ b/trunk/arch/um/os-Linux/irq.c @@ -11,6 +11,7 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "process.h" diff --git a/trunk/arch/um/os-Linux/main.c b/trunk/arch/um/os-Linux/main.c index ea9a23696f36..685feaab65d2 100644 --- a/trunk/arch/um/os-Linux/main.c +++ b/trunk/arch/um/os-Linux/main.c @@ -13,8 +13,8 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" -#include "as-layout.h" #include "mem_user.h" #include "irq_user.h" #include "user.h" @@ -25,7 +25,12 @@ #include "os.h" #include "um_malloc.h" -/* Set in main, unchanged thereafter */ +/* Set in set_stklim, which is called from main and __wrap_malloc. + * __wrap_malloc only calls it if main hasn't started. + */ +unsigned long stacksizelim; + +/* Set in main */ char *linux_prog; #define PGD_BOUND (4 * 1024 * 1024) @@ -47,6 +52,7 @@ static void set_stklim(void) exit(1); } } + stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1); } static __init void do_uml_initcalls(void) @@ -120,7 +126,7 @@ extern int uml_exitcode; extern void scan_elf_aux( char **envp); -int __init main(int argc, char **argv, char **envp) +int main(int argc, char **argv, char **envp) { char **new_argv; int ret, i, err; @@ -218,7 +224,7 @@ int __init main(int argc, char **argv, char **envp) ret = 1; } printf("\n"); - return uml_exitcode; + return(uml_exitcode); } #define CAN_KMALLOC() \ @@ -231,7 +237,7 @@ void *__wrap_malloc(int size) void *ret; if(!CAN_KMALLOC()) - return __real_malloc(size); + return(__real_malloc(size)); else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/ ret = um_kmalloc(size); else ret = um_vmalloc(size); @@ -242,17 +248,16 @@ void *__wrap_malloc(int size) if(ret == NULL) errno = ENOMEM; - return ret; + return(ret); } void *__wrap_calloc(int n, int size) { void *ptr = __wrap_malloc(n * size); - if(ptr == NULL) - return NULL; + if(ptr == NULL) return(NULL); memset(ptr, 0, n * size); - return ptr; + return(ptr); } extern void __real_free(void *); diff --git a/trunk/arch/um/os-Linux/mem.c b/trunk/arch/um/os-Linux/mem.c index c6378c6d10d2..f1ea169db85e 100644 --- a/trunk/arch/um/os-Linux/mem.c +++ b/trunk/arch/um/os-Linux/mem.c @@ -11,6 +11,7 @@ #include #include "kern_util.h" #include "user.h" +#include "user_util.h" #include "mem_user.h" #include "init.h" #include "os.h" @@ -164,8 +165,7 @@ static void which_tmpdir(void) * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). * So it isn't 'static' yet. */ -int __init make_tempfile(const char *template, char **out_tempname, - int do_unlink) +int make_tempfile(const char *template, char **out_tempname, int do_unlink) { char *tempname; int fd; @@ -206,7 +206,7 @@ int __init make_tempfile(const char *template, char **out_tempname, * This proc is used in start_up.c * So it isn't 'static'. */ -int __init create_tmp_file(unsigned long long len) +int create_tmp_file(unsigned long long len) { int fd, err; char zero; @@ -232,16 +232,17 @@ int __init create_tmp_file(unsigned long long len) zero = 0; - err = write(fd, &zero, 1); + err = os_write_file(fd, &zero, 1); if(err != 1){ - perror("write"); + errno = -err; + perror("os_write_file"); exit(1); } return fd; } -int __init create_mem_file(unsigned long long len) +int create_mem_file(unsigned long long len) { int err, fd; @@ -256,7 +257,7 @@ int __init create_mem_file(unsigned long long len) } -void __init check_tmpexec(void) +void check_tmpexec(void) { void *addr; int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); diff --git a/trunk/arch/um/os-Linux/process.c b/trunk/arch/um/os-Linux/process.c index 92a7b59120d6..76bdd6712417 100644 --- a/trunk/arch/um/os-Linux/process.c +++ b/trunk/arch/um/os-Linux/process.c @@ -14,6 +14,7 @@ #include "ptrace_user.h" #include "os.h" #include "user.h" +#include "user_util.h" #include "process.h" #include "irq_user.h" #include "kern_util.h" @@ -21,7 +22,6 @@ #include "skas_ptrace.h" #include "kern_constants.h" #include "uml-config.h" -#include "init.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -40,14 +40,14 @@ unsigned long os_process_pc(int pid) if(fd < 0){ printk("os_process_pc - couldn't open '%s', err = %d\n", proc_stat, -fd); - return ARBITRARY_ADDR; + return(ARBITRARY_ADDR); } - CATCH_EINTR(err = read(fd, buf, sizeof(buf))); + err = os_read_file(fd, buf, sizeof(buf)); if(err < 0){ printk("os_process_pc - couldn't read '%s', err = %d\n", - proc_stat, errno); + proc_stat, -err); os_close_file(fd); - return ARBITRARY_ADDR; + return(ARBITRARY_ADDR); } os_close_file(fd); pc = ARBITRARY_ADDR; @@ -56,7 +56,7 @@ unsigned long os_process_pc(int pid) "%*d %*d %*d %*d %*d %lu", &pc) != 1){ printk("os_process_pc - couldn't find pc in '%s'\n", buf); } - return pc; + return(pc); } int os_process_parent(int pid) @@ -65,22 +65,21 @@ int os_process_parent(int pid) char data[256]; int parent, n, fd; - if(pid == -1) - return -1; + if(pid == -1) return(-1); snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); fd = os_open_file(stat, of_read(OPENFLAGS()), 0); if(fd < 0){ printk("Couldn't open '%s', err = %d\n", stat, -fd); - return FAILURE_PID; + return(FAILURE_PID); } - CATCH_EINTR(n = read(fd, data, sizeof(data))); + n = os_read_file(fd, data, sizeof(data)); os_close_file(fd); if(n < 0){ - printk("Couldn't read '%s', err = %d\n", stat, errno); - return FAILURE_PID; + printk("Couldn't read '%s', err = %d\n", stat, -n); + return(FAILURE_PID); } parent = FAILURE_PID; @@ -88,7 +87,7 @@ int os_process_parent(int pid) if(n != 1) printk("Failed to scan '%s'\n", data); - return parent; + return(parent); } void os_stop_process(int pid) @@ -146,7 +145,7 @@ void os_usr1_process(int pid) int os_getpid(void) { - return syscall(__NR_getpid); + return(syscall(__NR_getpid)); } int os_getpgrp(void) @@ -166,8 +165,8 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, fd, off); if(loc == MAP_FAILED) - return -errno; - return 0; + return(-errno); + return(0); } int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) @@ -176,8 +175,8 @@ int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) (x ? PROT_EXEC : 0)); if(mprotect(addr, len, prot) < 0) - return -errno; - return 0; + return(-errno); + return(0); } int os_unmap_memory(void *addr, int len) @@ -186,15 +185,15 @@ int os_unmap_memory(void *addr, int len) err = munmap(addr, len); if(err < 0) - return -errno; - return 0; + return(-errno); + return(0); } #ifndef MADV_REMOVE #define MADV_REMOVE KERNEL_MADV_REMOVE #endif -int __init os_drop_memory(void *addr, int length) +int os_drop_memory(void *addr, int length) { int err; @@ -204,7 +203,7 @@ int __init os_drop_memory(void *addr, int length) return err; } -int __init can_drop_memory(void) +int can_drop_memory(void) { void *addr; int fd, ok = 0; @@ -245,7 +244,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) if(sig_stack != NULL){ pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER); - set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE); + set_sigstack(sig_stack, pages * page_size()); flags = SA_ONSTACK; } if(usr1_handler){ diff --git a/trunk/arch/um/os-Linux/sigio.c b/trunk/arch/um/os-Linux/sigio.c index 8d4e0c6b8c92..3fc43b33db66 100644 --- a/trunk/arch/um/os-Linux/sigio.c +++ b/trunk/arch/um/os-Linux/sigio.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -17,10 +16,10 @@ #include "init.h" #include "user.h" #include "kern_util.h" +#include "user_util.h" #include "sigio.h" #include "os.h" #include "um_malloc.h" -#include "init.h" /* Protected by sigio_lock(), also used by sigio_cleanup, which is an * exitcall. @@ -69,12 +68,11 @@ static int write_sigio_thread(void *unused) p = &fds->poll[i]; if(p->revents == 0) continue; if(p->fd == sigio_private[1]){ - CATCH_EINTR(n = read(sigio_private[1], &c, - sizeof(c))); + n = os_read_file(sigio_private[1], &c, sizeof(c)); if(n != sizeof(c)) printk("write_sigio_thread : " "read on socket failed, " - "err = %d\n", errno); + "err = %d\n", -n); tmp = current_poll; current_poll = next_poll; next_poll = tmp; @@ -87,10 +85,10 @@ static int write_sigio_thread(void *unused) (fds->used - i) * sizeof(*fds->poll)); } - CATCH_EINTR(n = write(respond_fd, &c, sizeof(c))); + n = os_write_file(respond_fd, &c, sizeof(c)); if(n != sizeof(c)) printk("write_sigio_thread : write on socket " - "failed, err = %d\n", errno); + "failed, err = %d\n", -n); } } @@ -128,15 +126,15 @@ static void update_thread(void) char c; flags = set_signals(0); - n = write(sigio_private[0], &c, sizeof(c)); + n = os_write_file(sigio_private[0], &c, sizeof(c)); if(n != sizeof(c)){ - printk("update_thread : write failed, err = %d\n", errno); + printk("update_thread : write failed, err = %d\n", -n); goto fail; } - CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c))); + n = os_read_file(sigio_private[0], &c, sizeof(c)); if(n != sizeof(c)){ - printk("update_thread : read failed, err = %d\n", errno); + printk("update_thread : read failed, err = %d\n", -n); goto fail; } @@ -322,10 +320,6 @@ static void write_sigio_workaround(void) close(l_write_sigio_fds[1]); } -/* Changed during early boot */ -static int pty_output_sigio = 0; -static int pty_close_sigio = 0; - void maybe_sigio_broken(int fd, int read) { int err; @@ -363,143 +357,3 @@ static void sigio_cleanup(void) } __uml_exitcall(sigio_cleanup); - -/* Used as a flag during SIGIO testing early in boot */ -static volatile int got_sigio = 0; - -static void __init handler(int sig) -{ - got_sigio = 1; -} - -struct openpty_arg { - int master; - int slave; - int err; -}; - -static void openpty_cb(void *arg) -{ - struct openpty_arg *info = arg; - - info->err = 0; - if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) - info->err = -errno; -} - -static int async_pty(int master, int slave) -{ - int flags; - - flags = fcntl(master, F_GETFL); - if(flags < 0) - return -errno; - - if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || - (fcntl(master, F_SETOWN, os_getpid()) < 0)) - return -errno; - - if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) - return -errno; - - return(0); -} - -static void __init check_one_sigio(void (*proc)(int, int)) -{ - struct sigaction old, new; - struct openpty_arg pty = { .master = -1, .slave = -1 }; - int master, slave, err; - - initial_thread_cb(openpty_cb, &pty); - if(pty.err){ - printk("openpty failed, errno = %d\n", -pty.err); - return; - } - - master = pty.master; - slave = pty.slave; - - if((master == -1) || (slave == -1)){ - printk("openpty failed to allocate a pty\n"); - return; - } - - /* Not now, but complain so we now where we failed. */ - err = raw(master); - if (err < 0) - panic("check_sigio : __raw failed, errno = %d\n", -err); - - err = async_pty(master, slave); - if(err < 0) - panic("tty_fds : sigio_async failed, err = %d\n", -err); - - if(sigaction(SIGIO, NULL, &old) < 0) - panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); - new = old; - new.sa_handler = handler; - if(sigaction(SIGIO, &new, NULL) < 0) - panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); - - got_sigio = 0; - (*proc)(master, slave); - - close(master); - close(slave); - - if(sigaction(SIGIO, &old, NULL) < 0) - panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); -} - -static void tty_output(int master, int slave) -{ - int n; - char buf[512]; - - printk("Checking that host ptys support output SIGIO..."); - - memset(buf, 0, sizeof(buf)); - - while(write(master, buf, sizeof(buf)) > 0) ; - if(errno != EAGAIN) - panic("tty_output : write failed, errno = %d\n", errno); - while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; - - if(got_sigio){ - printk("Yes\n"); - pty_output_sigio = 1; - } - else if(n == -EAGAIN) - printk("No, enabling workaround\n"); - else panic("tty_output : read failed, err = %d\n", n); -} - -static void tty_close(int master, int slave) -{ - printk("Checking that host ptys support SIGIO on close..."); - - close(slave); - if(got_sigio){ - printk("Yes\n"); - pty_close_sigio = 1; - } - else printk("No, enabling workaround\n"); -} - -void __init check_sigio(void) -{ - if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && - (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ - printk("No pseudo-terminals available - skipping pty SIGIO " - "check\n"); - return; - } - check_one_sigio(tty_output); - check_one_sigio(tty_close); -} - -/* Here because it only does the SIGIO testing for now */ -void __init os_check_bugs(void) -{ - check_sigio(); -} diff --git a/trunk/arch/um/os-Linux/signal.c b/trunk/arch/um/os-Linux/signal.c index 48d493415301..266768629fee 100644 --- a/trunk/arch/um/os-Linux/signal.c +++ b/trunk/arch/um/os-Linux/signal.c @@ -11,6 +11,7 @@ #include #include #include +#include "user_util.h" #include "user.h" #include "signal_kern.h" #include "sysdep/sigcontext.h" diff --git a/trunk/arch/um/os-Linux/skas/mem.c b/trunk/arch/um/os-Linux/skas/mem.c index 8e490fff3d47..9383e8751ae7 100644 --- a/trunk/arch/um/os-Linux/skas/mem.c +++ b/trunk/arch/um/os-Linux/skas/mem.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -18,17 +17,17 @@ #include "os.h" #include "proc_mm.h" #include "ptrace_user.h" +#include "user_util.h" #include "kern_util.h" #include "task.h" #include "registers.h" #include "uml-config.h" #include "sysdep/ptrace.h" #include "sysdep/stub.h" -#include "init.h" extern unsigned long batch_syscall_stub, __syscall_stub_start; -extern void wait_stub_done(int pid); +extern void wait_stub_done(int pid, int sig, char * fname); static inline unsigned long *check_init_stack(struct mm_id * mm_idp, unsigned long *stack) @@ -40,19 +39,6 @@ static inline unsigned long *check_init_stack(struct mm_id * mm_idp, return stack; } -static unsigned long syscall_regs[MAX_REG_NR]; - -static int __init init_syscall_regs(void) -{ - get_safe_registers(syscall_regs, NULL); - syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + - ((unsigned long) &batch_syscall_stub - - (unsigned long) &__syscall_stub_start); - return 0; -} - -__initcall(init_syscall_regs); - extern int proc_mm; int single_count = 0; @@ -61,11 +47,12 @@ int multi_op_count = 0; static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) { + unsigned long regs[MAX_REG_NR]; int n, i; long ret, offset; unsigned long * data; unsigned long * syscall; - int err, pid = mm_idp->u.pid; + int pid = mm_idp->u.pid; if(proc_mm) #warning Need to look up userspace_pid by cpu @@ -73,21 +60,21 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) multi_count++; - n = ptrace_setregs(pid, syscall_regs); + get_safe_registers(regs, NULL); + regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + ((unsigned long) &batch_syscall_stub - + (unsigned long) &__syscall_stub_start); + + n = ptrace_setregs(pid, regs); if(n < 0){ printk("Registers - \n"); for(i = 0; i < MAX_REG_NR; i++) - printk("\t%d\t0x%lx\n", i, syscall_regs[i]); + printk("\t%d\t0x%lx\n", i, regs[i]); panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", -n); } - err = ptrace(PTRACE_CONT, pid, 0, 0); - if(err) - panic("Failed to continue stub, pid = %d, errno = %d\n", pid, - errno); - - wait_stub_done(pid); + wait_stub_done(pid, 0, "do_syscall_stub"); /* When the stub stops, we find the following values on the * beginning of the stack: @@ -189,10 +176,14 @@ long syscall_stub_data(struct mm_id * mm_idp, return 0; } -int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, - int phys_fd, unsigned long long offset, int done, void **data) +int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, + int r, int w, int x, int phys_fd, unsigned long long offset, + int done, void **data) { - int ret; + int prot, ret; + + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | + (x ? PROT_EXEC : 0); if(proc_mm){ struct proc_mm_op map; @@ -209,11 +200,9 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, .fd = phys_fd, .offset= offset } } } ); - CATCH_EINTR(ret = write(fd, &map, sizeof(map))); - if(ret != sizeof(map)){ - ret = -errno; + ret = os_write_file(fd, &map, sizeof(map)); + if(ret != sizeof(map)) printk("map : /proc/mm map failed, err = %d\n", -ret); - } else ret = 0; } else { @@ -228,8 +217,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot, return ret; } -int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, - int done, void **data) +int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, + void **data) { int ret; @@ -243,11 +232,9 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, { .addr = (unsigned long) addr, .len = len } } } ); - CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap))); - if(ret != sizeof(unmap)){ - ret = -errno; + ret = os_write_file(fd, &unmap, sizeof(unmap)); + if(ret != sizeof(unmap)) printk("unmap - proc_mm write returned %d\n", ret); - } else ret = 0; } else { @@ -262,11 +249,13 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len, } int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, - unsigned int prot, int done, void **data) + int r, int w, int x, int done, void **data) { struct proc_mm_op protect; - int ret; + int prot, ret; + prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | + (x ? PROT_EXEC : 0); if(proc_mm){ int fd = mm_idp->u.mm_fd; @@ -278,11 +267,9 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, .len = len, .prot = prot } } } ); - CATCH_EINTR(ret = write(fd, &protect, sizeof(protect))); - if(ret != sizeof(protect)){ - ret = -errno; + ret = os_write_file(fd, &protect, sizeof(protect)); + if(ret != sizeof(protect)) printk("protect failed, err = %d", -ret); - } else ret = 0; } else { diff --git a/trunk/arch/um/os-Linux/skas/process.c b/trunk/arch/um/os-Linux/skas/process.c index 5c088a55396c..0564422c155f 100644 --- a/trunk/arch/um/os-Linux/skas/process.c +++ b/trunk/arch/um/os-Linux/skas/process.c @@ -18,6 +18,7 @@ #include #include "user.h" #include "sysdep/ptrace.h" +#include "user_util.h" #include "kern_util.h" #include "skas.h" #include "stub-data.h" @@ -33,8 +34,6 @@ #include "uml-config.h" #include "process.h" #include "longjmp.h" -#include "kern_constants.h" -#include "as-layout.h" int is_skas_winch(int pid, int fd, void *data) { @@ -45,58 +44,45 @@ int is_skas_winch(int pid, int fd, void *data) return(1); } -static int ptrace_dump_regs(int pid) -{ - unsigned long regs[MAX_REG_NR]; - int i; - - if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) - return -errno; - else { - printk("Stub registers -\n"); - for(i = 0; i < ARRAY_SIZE(regs); i++) - printk("\t%d - %lx\n", i, regs[i]); - } - - return 0; -} - -/* - * Signals that are OK to receive in the stub - we'll just continue it. - * SIGWINCH will happen when UML is inside a detached screen. - */ -#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH)) - -/* Signals that the stub will finish with - anything else is an error */ -#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP)) - -void wait_stub_done(int pid) +void wait_stub_done(int pid, int sig, char * fname) { int n, status, err; - while(1){ - CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if((n < 0) || !WIFSTOPPED(status)) - goto bad_wait; - - if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0) - break; + do { + if ( sig != -1 ) { + err = ptrace(PTRACE_CONT, pid, 0, sig); + if(err) + panic("%s : continue failed, errno = %d\n", + fname, errno); + } + sig = 0; - err = ptrace(PTRACE_CONT, pid, 0, 0); - if(err) - panic("wait_stub_done : continue failed, errno = %d\n", - errno); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); + } while((n >= 0) && WIFSTOPPED(status) && + ((WSTOPSIG(status) == SIGVTALRM) || + /* running UML inside a detached screen can cause + * SIGWINCHes + */ + (WSTOPSIG(status) == SIGWINCH))); + + if((n < 0) || !WIFSTOPPED(status) || + (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ + unsigned long regs[MAX_REG_NR]; + + if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) + printk("Failed to get registers from stub, " + "errno = %d\n", errno); + else { + int i; + + printk("Stub registers -\n"); + for(i = 0; i < ARRAY_SIZE(regs); i++) + printk("\t%d - %lx\n", i, regs[i]); + } + panic("%s : failed to wait for SIGUSR1/SIGTRAP, " + "pid = %d, n = %d, errno = %d, status = 0x%x\n", + fname, pid, n, errno, status); } - - if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) - return; - -bad_wait: - err = ptrace_dump_regs(pid); - if(err) - printk("Failed to get registers from stub, errno = %d\n", -err); - panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " - "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); } extern unsigned long current_stub_stack(void); @@ -118,11 +104,7 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi) sizeof(struct ptrace_faultinfo)); } else { - err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); - if(err) - panic("Failed to continue stub, pid = %d, errno = %d\n", - pid, errno); - wait_stub_done(pid); + wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo"); /* faultinfo is prepared by the stub-segv-handler at start of * the stub stack page. We just have to copy it. @@ -160,14 +142,9 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); if((err < 0) || !WIFSTOPPED(status) || - (WSTOPSIG(status) != SIGTRAP + 0x80)){ - err = ptrace_dump_regs(pid); - if(err) - printk("Failed to get registers from process, " - "errno = %d\n", -err); + (WSTOPSIG(status) != SIGTRAP + 0x80)) panic("handle_trap - failed to wait at end of syscall, " "errno = %d, status = %d\n", errno, status); - } } handle_syscall(regs); @@ -195,7 +172,7 @@ static int userspace_tramp(void *stack) int fd; __u64 offset; fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); - addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE, + addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(), PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); if(addr == MAP_FAILED){ printk("mapping mmap stub failed, errno = %d\n", @@ -205,8 +182,8 @@ static int userspace_tramp(void *stack) if(stack != NULL){ fd = phys_mapping(to_phys(stack), &offset); - addr = mmap((void *) UML_CONFIG_STUB_DATA, - UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, + addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(), + PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, offset); if(addr == MAP_FAILED){ printk("mapping segfault stack failed, " @@ -222,7 +199,7 @@ static int userspace_tramp(void *stack) (unsigned long) stub_segv_handler - (unsigned long) &__syscall_stub_start; - set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE); + set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGIO); sigaddset(&sa.sa_mask, SIGWINCH); @@ -314,13 +291,10 @@ void userspace(union uml_pt_regs *regs) UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ if(WIFSTOPPED(status)){ - int sig = WSTOPSIG(status); - switch(sig){ + switch(WSTOPSIG(status)){ case SIGSEGV: - if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){ - get_skas_faultinfo(pid, ®s->skas.faultinfo); - (*sig_info[SIGSEGV])(SIGSEGV, regs); - } + if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo) + user_signal(SIGSEGV, regs, pid); else handle_segv(pid, regs); break; case SIGTRAP + 0x80: @@ -335,13 +309,11 @@ void userspace(union uml_pt_regs *regs) case SIGBUS: case SIGFPE: case SIGWINCH: - block_signals(); - (*sig_info[sig])(sig, regs); - unblock_signals(); + user_signal(WSTOPSIG(status), regs, pid); break; default: printk("userspace - child stopped with signal " - "%d\n", sig); + "%d\n", WSTOPSIG(status)); } pid = userspace_pid[0]; interrupt_end(); @@ -353,29 +325,11 @@ void userspace(union uml_pt_regs *regs) } } -static unsigned long thread_regs[MAX_REG_NR]; -static unsigned long thread_fp_regs[HOST_FP_SIZE]; - -static int __init init_thread_regs(void) -{ - get_safe_registers(thread_regs, thread_fp_regs); - /* Set parent's instruction pointer to start of clone-stub */ - thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + - (unsigned long) stub_clone_handler - - (unsigned long) &__syscall_stub_start; - thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - - sizeof(void *); -#ifdef __SIGNAL_FRAMESIZE - thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; -#endif - return 0; -} - -__initcall(init_thread_regs); - int copy_context_skas0(unsigned long new_stack, int pid) { int err; + unsigned long regs[MAX_REG_NR]; + unsigned long fp_regs[HOST_FP_SIZE]; unsigned long current_stack = current_stub_stack(); struct stub_data *data = (struct stub_data *) current_stack; struct stub_data *child_data = (struct stub_data *) new_stack; @@ -390,12 +344,23 @@ int copy_context_skas0(unsigned long new_stack, int pid) .timer = ((struct itimerval) { { 0, 1000000 / hz() }, { 0, 1000000 / hz() }})}); - err = ptrace_setregs(pid, thread_regs); + get_safe_registers(regs, fp_regs); + + /* Set parent's instruction pointer to start of clone-stub */ + regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + + (unsigned long) stub_clone_handler - + (unsigned long) &__syscall_stub_start; + regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - + sizeof(void *); +#ifdef __SIGNAL_FRAMESIZE + regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; +#endif + err = ptrace_setregs(pid, regs); if(err < 0) panic("copy_context_skas0 : PTRACE_SETREGS failed, " "pid = %d, errno = %d\n", pid, -err); - err = ptrace_setfpregs(pid, thread_fp_regs); + err = ptrace_setfpregs(pid, fp_regs); if(err < 0) panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " "pid = %d, errno = %d\n", pid, -err); @@ -406,11 +371,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* Wait, until parent has finished its work: read child's pid from * parent's stack, and check, if bad result. */ - err = ptrace(PTRACE_CONT, pid, 0, 0); - if(err) - panic("Failed to continue new process, pid = %d, " - "errno = %d\n", pid, errno); - wait_stub_done(pid); + wait_stub_done(pid, 0, "copy_context_skas0"); pid = data->err; if(pid < 0) @@ -420,7 +381,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* Wait, until child has finished too: read child's result from * child's stack and check it. */ - wait_stub_done(pid); + wait_stub_done(pid, -1, "copy_context_skas0"); if (child_data->err != UML_CONFIG_STUB_DATA) panic("copy_context_skas0 - stub-child reports error %ld\n", child_data->err); @@ -435,7 +396,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) /* * This is used only, if stub pages are needed, while proc_mm is - * available. Opening /proc/mm creates a new mm_context, which lacks + * availabl. Opening /proc/mm creates a new mm_context, which lacks * the stub-pages. Thus, we map them using /proc/mm-fd */ void map_stub_pages(int fd, unsigned long code, @@ -457,13 +418,12 @@ void map_stub_pages(int fd, unsigned long code, .fd = code_fd, .offset = code_offset } } }); - CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); + n = os_write_file(fd, &mmop, sizeof(mmop)); if(n != sizeof(mmop)){ - n = errno; printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", code, code_fd, (unsigned long long) code_offset); panic("map_stub_pages : /proc/mm map for code failed, " - "err = %d\n", n); + "err = %d\n", -n); } if ( stack ) { @@ -480,10 +440,10 @@ void map_stub_pages(int fd, unsigned long code, .fd = map_fd, .offset = map_offset } } }); - CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); + n = os_write_file(fd, &mmop, sizeof(mmop)); if(n != sizeof(mmop)) panic("map_stub_pages : /proc/mm map for data failed, " - "err = %d\n", errno); + "err = %d\n", -n); } } @@ -520,15 +480,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, SIGVTALRM, -1); - /* - * Can't use UML_SETJMP or UML_LONGJMP here because they save - * and restore signals, with the possible side-effect of - * trying to handle any signals which came when they were - * blocked, which can't be done on this stack. - * Signals must be blocked when jumping back here and restored - * after returning to the jumper. - */ - n = setjmp(initial_jmpbuf); + n = UML_SETJMP(&initial_jmpbuf); switch(n){ case INIT_JMP_NEW_THREAD: (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; @@ -538,7 +490,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) break; case INIT_JMP_CALLBACK: (*cb_proc)(cb_arg); - longjmp(*cb_back, 1); + UML_LONGJMP(cb_back, 1); break; case INIT_JMP_HALT: kmalloc_ok = 0; @@ -549,7 +501,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) default: panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); } - longjmp(*switch_buf, 1); + UML_LONGJMP(switch_buf, 1); } void initial_thread_cb_skas(void (*proc)(void *), void *arg) diff --git a/trunk/arch/um/os-Linux/skas/trap.c b/trunk/arch/um/os-Linux/skas/trap.c index 3b600c2e63b8..9ad5fbec4593 100644 --- a/trunk/arch/um/os-Linux/skas/trap.c +++ b/trunk/arch/um/os-Linux/skas/trap.c @@ -5,8 +5,8 @@ #include #include +#include "user_util.h" #include "kern_util.h" -#include "as-layout.h" #include "task.h" #include "sigcontext.h" #include "skas.h" @@ -15,39 +15,29 @@ #include "sysdep/ptrace_user.h" #include "os.h" -static union uml_pt_regs ksig_regs[UM_NR_CPUS]; - void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; - union uml_pt_regs *r; + struct skas_regs *r; void (*handler)(int, union uml_pt_regs *); - int save_user, save_errno = errno; + int save_errno = errno; + int save_user; /* This is done because to allow SIGSEGV to be delivered inside a SEGV * handler. This can happen in copy_user, and if SEGV is disabled, * the process will die. * XXX Figure out why this is better than SA_NODEFER */ - if(sig == SIGSEGV) { + if(sig == SIGSEGV) change_sig(SIGSEGV, 1); - /* For segfaults, we want the data from the - * sigcontext. In this case, we don't want to mangle - * the process registers, so use a static set of - * registers. For other signals, the process - * registers are OK. - */ - r = &ksig_regs[cpu()]; - copy_sc(r, sc_ptr); - } - else r = TASK_REGS(get_current()); - save_user = r->skas.is_user; - r->skas.is_user = 0; + r = &TASK_REGS(get_current())->skas; + save_user = r->is_user; + r->is_user = 0; if ( sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGTRAP ) { - GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc); + GET_FAULTINFO_FROM_SC(r->faultinfo, sc); } change_sig(SIGUSR1, 1); @@ -59,8 +49,25 @@ void sig_handler_common_skas(int sig, void *sc_ptr) sig != SIGVTALRM && sig != SIGALRM) unblock_signals(); - handler(sig, r); + handler(sig, (union uml_pt_regs *) r); errno = save_errno; - r->skas.is_user = save_user; + r->is_user = save_user; +} + +extern int ptrace_faultinfo; + +void user_signal(int sig, union uml_pt_regs *regs, int pid) +{ + void (*handler)(int, union uml_pt_regs *); + int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || + (sig == SIGILL) || (sig == SIGTRAP)); + + if (segv) + get_skas_faultinfo(pid, ®s->skas.faultinfo); + + handler = sig_info[sig]; + handler(sig, (union uml_pt_regs *) regs); + + unblock_signals(); } diff --git a/trunk/arch/um/os-Linux/start_up.c b/trunk/arch/um/os-Linux/start_up.c index 79471f85eb89..5178eba9afa5 100644 --- a/trunk/arch/um/os-Linux/start_up.c +++ b/trunk/arch/um/os-Linux/start_up.c @@ -17,10 +17,10 @@ #include #include #include -#include #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "signal_kern.h" @@ -329,32 +329,8 @@ static void __init check_ptrace(void) extern void check_tmpexec(void); -static void __init check_coredump_limit(void) +void os_early_checks(void) { - struct rlimit lim; - int err = getrlimit(RLIMIT_CORE, &lim); - - if(err){ - perror("Getting core dump limit"); - return; - } - - printf("Core dump limits :\n\tsoft - "); - if(lim.rlim_cur == RLIM_INFINITY) - printf("NONE\n"); - else printf("%lu\n", lim.rlim_cur); - - printf("\thard - "); - if(lim.rlim_max == RLIM_INFINITY) - printf("NONE\n"); - else printf("%lu\n", lim.rlim_max); -} - -void __init os_early_checks(void) -{ - /* Print out the core dump limits early */ - check_coredump_limit(); - check_ptrace(); /* Need to check this early because mmapping happens before the @@ -552,3 +528,148 @@ int __init parse_iomem(char *str, int *add) out: return 1; } + + +/* Changed during early boot */ +int pty_output_sigio = 0; +int pty_close_sigio = 0; + +/* Used as a flag during SIGIO testing early in boot */ +static volatile int got_sigio = 0; + +static void __init handler(int sig) +{ + got_sigio = 1; +} + +struct openpty_arg { + int master; + int slave; + int err; +}; + +static void openpty_cb(void *arg) +{ + struct openpty_arg *info = arg; + + info->err = 0; + if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) + info->err = -errno; +} + +static int async_pty(int master, int slave) +{ + int flags; + + flags = fcntl(master, F_GETFL); + if(flags < 0) + return -errno; + + if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || + (fcntl(master, F_SETOWN, os_getpid()) < 0)) + return -errno; + + if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) + return -errno; + + return(0); +} + +static void __init check_one_sigio(void (*proc)(int, int)) +{ + struct sigaction old, new; + struct openpty_arg pty = { .master = -1, .slave = -1 }; + int master, slave, err; + + initial_thread_cb(openpty_cb, &pty); + if(pty.err){ + printk("openpty failed, errno = %d\n", -pty.err); + return; + } + + master = pty.master; + slave = pty.slave; + + if((master == -1) || (slave == -1)){ + printk("openpty failed to allocate a pty\n"); + return; + } + + /* Not now, but complain so we now where we failed. */ + err = raw(master); + if (err < 0) + panic("check_sigio : __raw failed, errno = %d\n", -err); + + err = async_pty(master, slave); + if(err < 0) + panic("tty_fds : sigio_async failed, err = %d\n", -err); + + if(sigaction(SIGIO, NULL, &old) < 0) + panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); + new = old; + new.sa_handler = handler; + if(sigaction(SIGIO, &new, NULL) < 0) + panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); + + got_sigio = 0; + (*proc)(master, slave); + + close(master); + close(slave); + + if(sigaction(SIGIO, &old, NULL) < 0) + panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); +} + +static void tty_output(int master, int slave) +{ + int n; + char buf[512]; + + printk("Checking that host ptys support output SIGIO..."); + + memset(buf, 0, sizeof(buf)); + + while(os_write_file(master, buf, sizeof(buf)) > 0) ; + if(errno != EAGAIN) + panic("check_sigio : write failed, errno = %d\n", errno); + while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; + + if(got_sigio){ + printk("Yes\n"); + pty_output_sigio = 1; + } + else if(n == -EAGAIN) printk("No, enabling workaround\n"); + else panic("check_sigio : read failed, err = %d\n", n); +} + +static void tty_close(int master, int slave) +{ + printk("Checking that host ptys support SIGIO on close..."); + + close(slave); + if(got_sigio){ + printk("Yes\n"); + pty_close_sigio = 1; + } + else printk("No, enabling workaround\n"); +} + +void __init check_sigio(void) +{ + if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && + (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ + printk("No pseudo-terminals available - skipping pty SIGIO " + "check\n"); + return; + } + check_one_sigio(tty_output); + check_one_sigio(tty_close); +} + +void os_check_bugs(void) +{ + check_ptrace(); + check_sigio(); +} + diff --git a/trunk/arch/um/os-Linux/sys-i386/tls.c b/trunk/arch/um/os-Linux/sys-i386/tls.c index 32ed41ec1a3d..256532034c62 100644 --- a/trunk/arch/um/os-Linux/sys-i386/tls.c +++ b/trunk/arch/um/os-Linux/sys-i386/tls.c @@ -5,7 +5,7 @@ #include #include "sysdep/tls.h" -#include "user.h" +#include "user_util.h" /* Checks whether host supports TLS, and sets *tls_min according to the value * valid on the host. diff --git a/trunk/arch/um/os-Linux/time.c b/trunk/arch/um/os-Linux/time.c index 5de169b168f6..2115b8beb541 100644 --- a/trunk/arch/um/os-Linux/time.c +++ b/trunk/arch/um/os-Linux/time.c @@ -10,6 +10,7 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "process.h" diff --git a/trunk/arch/um/os-Linux/trap.c b/trunk/arch/um/os-Linux/trap.c index 295da657931a..d221214d2ed5 100644 --- a/trunk/arch/um/os-Linux/trap.c +++ b/trunk/arch/um/os-Linux/trap.c @@ -6,6 +6,7 @@ #include #include #include "kern_util.h" +#include "user_util.h" #include "os.h" #include "mode.h" #include "longjmp.h" diff --git a/trunk/arch/um/os-Linux/tt.c b/trunk/arch/um/os-Linux/tt.c index bcf9359c4e9f..3dc3a02d6263 100644 --- a/trunk/arch/um/os-Linux/tt.c +++ b/trunk/arch/um/os-Linux/tt.c @@ -18,6 +18,7 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "signal_kern.h" @@ -31,7 +32,6 @@ #include "choose-mode.h" #include "mode.h" #include "tempfile.h" -#include "kern_constants.h" int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, int must_succeed) @@ -143,7 +143,7 @@ int outer_tramp(void *arg) int sig = sigkill; t = arg; - t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2, + t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2, t->flags, t->tramp_data); if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); kill(os_getpid(), sig); diff --git a/trunk/arch/um/os-Linux/tty_log.c b/trunk/arch/um/os-Linux/tty_log.c index d11a55baa6bd..c6ba56c1560f 100644 --- a/trunk/arch/um/os-Linux/tty_log.c +++ b/trunk/arch/um/os-Linux/tty_log.c @@ -53,9 +53,9 @@ int open_tty_log(void *tty, void *current_tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - write(tty_log_fd, &data, sizeof(data)); - write(tty_log_fd, ¤t_tty, data.len); - return tty_log_fd; + os_write_file(tty_log_fd, &data, sizeof(data)); + os_write_file(tty_log_fd, ¤t_tty, data.len); + return(tty_log_fd); } sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, @@ -67,7 +67,7 @@ int open_tty_log(void *tty, void *current_tty) printk("open_tty_log : couldn't open '%s', errno = %d\n", buf, -fd); } - return fd; + return(fd); } void close_tty_log(int fd, void *tty) @@ -83,7 +83,7 @@ void close_tty_log(int fd, void *tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - write(tty_log_fd, &data, sizeof(data)); + os_write_file(tty_log_fd, &data, sizeof(data)); return; } os_close_file(fd); @@ -98,21 +98,21 @@ static int log_chunk(int fd, const char *buf, int len) try = (len > sizeof(chunk)) ? sizeof(chunk) : len; missed = copy_from_user_proc(chunk, (char *) buf, try); try -= missed; - n = write(fd, chunk, try); + n = os_write_file(fd, chunk, try); if(n != try) { if(n < 0) - return -errno; - return -EIO; + return(n); + return(-EIO); } if(missed != 0) - return -EFAULT; + return(-EFAULT); len -= try; total += try; buf += try; } - return total; + return(total); } int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) @@ -130,10 +130,10 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) .direction = direction, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - write(tty_log_fd, &data, sizeof(data)); + os_write_file(tty_log_fd, &data, sizeof(data)); } - return log_chunk(fd, buf, len); + return(log_chunk(fd, buf, len)); } void log_exec(char **argv, void *tty) @@ -161,7 +161,7 @@ void log_exec(char **argv, void *tty) .direction = 0, .sec = tv.tv_sec, .usec = tv.tv_usec } ); - write(tty_log_fd, &data, sizeof(data)); + os_write_file(tty_log_fd, &data, sizeof(data)); for(ptr = argv; ; ptr++){ if(copy_from_user_proc(&arg, ptr, sizeof(arg))) @@ -179,7 +179,7 @@ extern void register_tty_logger(int (*opener)(void *, void *), static int register_logger(void) { register_tty_logger(open_tty_log, write_tty_log, close_tty_log); - return 0; + return(0); } __uml_initcall(register_logger); diff --git a/trunk/arch/um/os-Linux/util.c b/trunk/arch/um/os-Linux/util.c index c307a89ed259..56b8a50e8bc2 100644 --- a/trunk/arch/um/os-Linux/util.c +++ b/trunk/arch/um/os-Linux/util.c @@ -21,6 +21,7 @@ #include #include #include +#include "user_util.h" #include "kern_util.h" #include "user.h" #include "mem_user.h" @@ -29,29 +30,28 @@ #include "uml-config.h" #include "os.h" #include "longjmp.h" -#include "kern_constants.h" void stack_protections(unsigned long address) { int prot = PROT_READ | PROT_WRITE | PROT_EXEC; - if(mprotect((void *) address, UM_KERN_PAGE_SIZE, prot) < 0) + if(mprotect((void *) address, page_size(), prot) < 0) panic("protecting stack failed, errno = %d", errno); } void task_protections(unsigned long address) { - unsigned long guard = address + UM_KERN_PAGE_SIZE; - unsigned long stack = guard + UM_KERN_PAGE_SIZE; + unsigned long guard = address + page_size(); + unsigned long stack = guard + page_size(); int prot = 0, pages; #ifdef notdef - if(mprotect((void *) stack, UM_KERN_PAGE_SIZE, prot) < 0) + if(mprotect((void *) stack, page_size(), prot) < 0) panic("protecting guard page failed, errno = %d", errno); #endif pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2; prot = PROT_READ | PROT_WRITE | PROT_EXEC; - if(mprotect((void *) stack, pages * UM_KERN_PAGE_SIZE, prot) < 0) + if(mprotect((void *) stack, pages * page_size(), prot) < 0) panic("protecting stack failed, errno = %d", errno); } @@ -96,13 +96,15 @@ void setup_machinename(char *machine_out) strcpy(machine_out, host.machine); } -void setup_hostinfo(char *buf, int len) +char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1]; + +void setup_hostinfo(void) { struct utsname host; uname(&host); - snprintf(buf, len, "%s %s %s %s %s", host.sysname, host.nodename, - host.release, host.version, host.machine); + sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename, + host.release, host.version, host.machine); } int setjmp_wrapper(void (*proc)(void *, void *), ...) @@ -119,9 +121,3 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...) va_end(args); return n; } - -void os_dump_core(void) -{ - signal(SIGSEGV, SIG_DFL); - abort(); -} diff --git a/trunk/arch/um/sys-i386/bugs.c b/trunk/arch/um/sys-i386/bugs.c index 0393e44813e7..f1bcd399ac90 100644 --- a/trunk/arch/um/sys-i386/bugs.c +++ b/trunk/arch/um/sys-i386/bugs.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -13,6 +13,7 @@ #include "sysdep/ptrace.h" #include "task.h" #include "os.h" +#include "user_util.h" #define MAXTOKEN 64 @@ -31,21 +32,21 @@ static char token(int fd, char *buf, int len, char stop) n = os_read_file(fd, ptr, sizeof(*ptr)); c = *ptr++; if(n != sizeof(*ptr)){ - if(n == 0) - return 0; + if(n == 0) return(0); printk("Reading /proc/cpuinfo failed, err = %d\n", -n); if(n < 0) - return n; - else return -EIO; + return(n); + else + return(-EIO); } } while((c != '\n') && (c != stop) && (ptr < end)); if(ptr == end){ printk("Failed to find '%c' in /proc/cpuinfo\n", stop); - return -1; + return(-1); } *(ptr - 1) = '\0'; - return c; + return(c); } static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) @@ -57,25 +58,48 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) while(1){ c = token(fd, scratch, len - 1, ':'); if(c <= 0) - return 0; + return(0); else if(c != ':'){ printk("Failed to find ':' in /proc/cpuinfo\n"); - return 0; + return(0); } if(!strncmp(scratch, key, strlen(key))) - return 1; + return(1); do { n = os_read_file(fd, &c, sizeof(c)); if(n != sizeof(c)){ printk("Failed to find newline in " "/proc/cpuinfo, err = %d\n", -n); - return 0; + return(0); } } while(c != '\n'); } - return 0; + return(0); +} + +int cpu_feature(char *what, char *buf, int len) +{ + int fd, ret = 0; + + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); + if(fd < 0){ + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); + return(0); + } + + if(!find_cpuinfo_line(fd, what, buf, len)){ + printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); + goto out_close; + } + + token(fd, buf, len, '\n'); + ret = 1; + + out_close: + os_close_file(fd); + return(ret); } static int check_cpu_flag(char *feature, int *have_it) @@ -95,8 +119,7 @@ static int check_cpu_flag(char *feature, int *have_it) goto out; c = token(fd, buf, len - 1, ' '); - if(c < 0) - goto out; + if(c < 0) goto out; else if(c != ' '){ printk("Failed to find ' ' in /proc/cpuinfo\n"); goto out; @@ -104,8 +127,7 @@ static int check_cpu_flag(char *feature, int *have_it) while(1){ c = token(fd, buf, len - 1, ' '); - if(c < 0) - goto out; + if(c < 0) goto out; else if(c == '\n') break; if(!strcmp(buf, feature)){ @@ -114,10 +136,8 @@ static int check_cpu_flag(char *feature, int *have_it) } } out: - if(*have_it == 0) - printk("No\n"); - else if(*have_it == 1) - printk("Yes\n"); + if(*have_it == 0) printk("No\n"); + else if(*have_it == 1) printk("Yes\n"); os_close_file(fd); return 1; } @@ -169,13 +189,12 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) /* This is testing for a cmov (0x0f 0x4x) instruction causing a * SIGILL in init. */ - if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) - return 0; + if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0); if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) panic("SIGILL in init, could not read instructions!\n"); if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) - return 0; + return(0); if(host_has_cmov == 0) panic("SIGILL caused by cmov, which this processor doesn't " @@ -189,5 +208,16 @@ int arch_handle_signal(int sig, union uml_pt_regs *regs) "implements it, boot a filesystem compiled for older " "processors"); else panic("Bad value for host_has_cmov (%d)", host_has_cmov); - return 0; + return(0); } + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-i386/fault.c b/trunk/arch/um/sys-i386/fault.c index 745b4fd49e9f..d0bbcdfdb53f 100644 --- a/trunk/arch/um/sys-i386/fault.c +++ b/trunk/arch/um/sys-i386/fault.c @@ -3,7 +3,9 @@ * Licensed under the GPL */ +#include #include "sysdep/ptrace.h" +#include "sysdep/sigcontext.h" /* These two are from asm-um/uaccess.h and linux/module.h, check them. */ struct exception_table_entry @@ -15,14 +17,26 @@ struct exception_table_entry const struct exception_table_entry *search_exception_tables(unsigned long add); /* Compare this to arch/i386/mm/extable.c:fixup_exception() */ -int arch_fixup(unsigned long address, union uml_pt_regs *regs) +int arch_fixup(unsigned long address, void *sc_ptr) { + struct sigcontext *sc = sc_ptr; const struct exception_table_entry *fixup; fixup = search_exception_tables(address); if(fixup != 0){ - UPT_IP(regs) = fixup->fixup; + sc->eip = fixup->fixup; return(1); } return(0); } + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-i386/ptrace_user.c b/trunk/arch/um/sys-i386/ptrace_user.c index 40ff0c831bd0..01212c88fcc4 100644 --- a/trunk/arch/um/sys-i386/ptrace_user.c +++ b/trunk/arch/um/sys-i386/ptrace_user.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -15,6 +15,7 @@ #include "user.h" #include "os.h" #include "uml-config.h" +#include "user_util.h" int ptrace_getregs(long pid, unsigned long *regs_out) { @@ -44,8 +45,7 @@ int ptrace_setfpregs(long pid, unsigned long *regs) return 0; } -#ifdef UML_CONFIG_MODE_TT - +/* All the below stuff is of interest for TT mode only */ static void write_debugregs(int pid, unsigned long *regs) { struct user *dummy; @@ -128,4 +128,13 @@ void update_debugregs(int seq) } #endif -#endif +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-i386/signal.c b/trunk/arch/um/sys-i386/signal.c index 1cbf95f6858a..3f6acd667717 100644 --- a/trunk/arch/um/sys-i386/signal.c +++ b/trunk/arch/um/sys-i386/signal.c @@ -18,28 +18,6 @@ #include "skas.h" -void copy_sc(union uml_pt_regs *regs, void *from) -{ - struct sigcontext *sc = from; - - REGS_GS(regs->skas.regs) = sc->gs; - REGS_FS(regs->skas.regs) = sc->fs; - REGS_ES(regs->skas.regs) = sc->es; - REGS_DS(regs->skas.regs) = sc->ds; - REGS_EDI(regs->skas.regs) = sc->edi; - REGS_ESI(regs->skas.regs) = sc->esi; - REGS_EBP(regs->skas.regs) = sc->ebp; - REGS_SP(regs->skas.regs) = sc->esp; - REGS_EBX(regs->skas.regs) = sc->ebx; - REGS_EDX(regs->skas.regs) = sc->edx; - REGS_ECX(regs->skas.regs) = sc->ecx; - REGS_EAX(regs->skas.regs) = sc->eax; - REGS_IP(regs->skas.regs) = sc->eip; - REGS_CS(regs->skas.regs) = sc->cs; - REGS_EFLAGS(regs->skas.regs) = sc->eflags; - REGS_SS(regs->skas.regs) = sc->ss; -} - static int copy_sc_from_user_skas(struct pt_regs *regs, struct sigcontext __user *from) { @@ -50,18 +28,33 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, err = copy_from_user(&sc, from, sizeof(sc)); err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs)); if(err) - return err; - - copy_sc(®s->regs, &sc); + return(err); + + REGS_GS(regs->regs.skas.regs) = sc.gs; + REGS_FS(regs->regs.skas.regs) = sc.fs; + REGS_ES(regs->regs.skas.regs) = sc.es; + REGS_DS(regs->regs.skas.regs) = sc.ds; + REGS_EDI(regs->regs.skas.regs) = sc.edi; + REGS_ESI(regs->regs.skas.regs) = sc.esi; + REGS_EBP(regs->regs.skas.regs) = sc.ebp; + REGS_SP(regs->regs.skas.regs) = sc.esp; + REGS_EBX(regs->regs.skas.regs) = sc.ebx; + REGS_EDX(regs->regs.skas.regs) = sc.edx; + REGS_ECX(regs->regs.skas.regs) = sc.ecx; + REGS_EAX(regs->regs.skas.regs) = sc.eax; + REGS_IP(regs->regs.skas.regs) = sc.eip; + REGS_CS(regs->regs.skas.regs) = sc.cs; + REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; + REGS_SS(regs->regs.skas.regs) = sc.ss; err = restore_fp_registers(userspace_pid[0], fpregs); - if(err < 0) { + if(err < 0){ printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " - "errno = %d\n", -err); - return err; + "errno = %d\n", err); + return(1); } - return 0; + return(0); } int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp, @@ -97,16 +90,16 @@ int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *t if(err < 0){ printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, " "errno = %d\n", err); - return 1; + return(1); } to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); sc.fpstate = to_fp; if(err) - return err; + return(err); - return copy_to_user(to, &sc, sizeof(sc)) || - copy_to_user(to_fp, fpregs, sizeof(fpregs)); + return(copy_to_user(to, &sc, sizeof(sc)) || + copy_to_user(to_fp, fpregs, sizeof(fpregs))); } #endif @@ -136,7 +129,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, to->fpstate = to_fp; if(to_fp != NULL) err |= copy_from_user(to_fp, from_fp, fpsize); - return err; + return(err); } int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, @@ -171,15 +164,15 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, sizeof(struct _fpstate)), copy_sc_from_user_skas(to, from)); - return ret; + return(ret); } static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, struct pt_regs *from, unsigned long sp) { - return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), + return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), sizeof(*fp), sp), - copy_sc_to_user_skas(to, fp, from, sp)); + copy_sc_to_user_skas(to, fp, from, sp))); } static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, @@ -192,7 +185,7 @@ static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __u err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, sp); err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); - return err; + return(err); } struct sigframe @@ -366,7 +359,7 @@ long sys_sigreturn(struct pt_regs regs) /* Avoid ERESTART handling */ PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); + return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); segfault: force_sig(SIGSEGV, current); @@ -396,9 +389,20 @@ long sys_rt_sigreturn(struct pt_regs regs) /* Avoid ERESTART handling */ PT_REGS_SYSCALL_NR(¤t->thread.regs) = -1; - return PT_REGS_SYSCALL_RET(¤t->thread.regs); + return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); segfault: force_sig(SIGSEGV, current); return 0; } + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-i386/tls.c b/trunk/arch/um/sys-i386/tls.c index fea8e5e15cc4..643dab585727 100644 --- a/trunk/arch/um/sys-i386/tls.c +++ b/trunk/arch/um/sys-i386/tls.c @@ -23,13 +23,9 @@ #include "skas.h" #endif -/* - * If needed we can detect when it's uninitialized. - * - * These are initialized in an initcall and unchanged thereafter. - */ +/* If needed we can detect when it's uninitialized. */ static int host_supports_tls = -1; -int host_gdt_entry_tls_min; +int host_gdt_entry_tls_min = -1; #ifdef CONFIG_MODE_SKAS int do_set_thread_area_skas(struct user_desc *info) @@ -365,8 +361,7 @@ int ptrace_get_thread_area(struct task_struct *child, int idx, /* XXX: This part is probably common to i386 and x86-64. Don't create a common * file for now, do that when implementing x86-64 support.*/ -static int __init __setup_host_supports_tls(void) -{ +static int __init __setup_host_supports_tls(void) { check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); if (host_supports_tls) { printk(KERN_INFO "Host TLS support detected\n"); diff --git a/trunk/arch/um/sys-i386/user-offsets.c b/trunk/arch/um/sys-i386/user-offsets.c index 29118cf5ff25..447306b20aea 100644 --- a/trunk/arch/um/sys-i386/user-offsets.c +++ b/trunk/arch/um/sys-i386/user-offsets.c @@ -1,10 +1,9 @@ #include -#include #include -#include -#include #include #include +#include +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -48,6 +47,7 @@ void foo(void) OFFSET(HOST_SC_FP_ST, _fpstate, _st); OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env); + DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct)); DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct)); @@ -73,8 +73,4 @@ void foo(void) DEFINE(UM_POLLIN, POLLIN); DEFINE(UM_POLLPRI, POLLPRI); DEFINE(UM_POLLOUT, POLLOUT); - - DEFINE(UM_PROT_READ, PROT_READ); - DEFINE(UM_PROT_WRITE, PROT_WRITE); - DEFINE(UM_PROT_EXEC, PROT_EXEC); } diff --git a/trunk/arch/um/sys-ppc/sigcontext.c b/trunk/arch/um/sys-ppc/sigcontext.c index 4bdc15c89edd..5d430fc994af 100644 --- a/trunk/arch/um/sys-ppc/sigcontext.c +++ b/trunk/arch/um/sys-ppc/sigcontext.c @@ -1,6 +1,7 @@ #include "asm/ptrace.h" #include "asm/sigcontext.h" #include "sysdep/ptrace.h" +#include "user_util.h" /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/trunk/arch/um/sys-x86_64/bugs.c b/trunk/arch/um/sys-x86_64/bugs.c index 095478890371..fdce7ea98ca7 100644 --- a/trunk/arch/um/sys-x86_64/bugs.c +++ b/trunk/arch/um/sys-x86_64/bugs.c @@ -4,7 +4,12 @@ * Licensed under the GPL */ +#include "linux/sched.h" +#include "linux/errno.h" +#include "asm/system.h" +#include "asm/pda.h" #include "sysdep/ptrace.h" +#include "os.h" void arch_init_thread(void) { @@ -16,5 +21,102 @@ void arch_check_bugs(void) int arch_handle_signal(int sig, union uml_pt_regs *regs) { - return 0; + return(0); } + +#define MAXTOKEN 64 + +/* Set during early boot */ +int host_has_cmov = 1; +int host_has_xmm = 0; + +static char token(int fd, char *buf, int len, char stop) +{ + int n; + char *ptr, *end, c; + + ptr = buf; + end = &buf[len]; + do { + n = os_read_file(fd, ptr, sizeof(*ptr)); + c = *ptr++; + if(n != sizeof(*ptr)){ + if(n == 0) return(0); + printk("Reading /proc/cpuinfo failed, err = %d\n", -n); + if(n < 0) + return(n); + else + return(-EIO); + } + } while((c != '\n') && (c != stop) && (ptr < end)); + + if(ptr == end){ + printk("Failed to find '%c' in /proc/cpuinfo\n", stop); + return(-1); + } + *(ptr - 1) = '\0'; + return(c); +} + +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) +{ + int n; + char c; + + scratch[len - 1] = '\0'; + while(1){ + c = token(fd, scratch, len - 1, ':'); + if(c <= 0) + return(0); + else if(c != ':'){ + printk("Failed to find ':' in /proc/cpuinfo\n"); + return(0); + } + + if(!strncmp(scratch, key, strlen(key))) + return(1); + + do { + n = os_read_file(fd, &c, sizeof(c)); + if(n != sizeof(c)){ + printk("Failed to find newline in " + "/proc/cpuinfo, err = %d\n", -n); + return(0); + } + } while(c != '\n'); + } + return(0); +} + +int cpu_feature(char *what, char *buf, int len) +{ + int fd, ret = 0; + + fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); + if(fd < 0){ + printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); + return(0); + } + + if(!find_cpuinfo_line(fd, what, buf, len)){ + printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); + goto out_close; + } + + token(fd, buf, len, '\n'); + ret = 1; + + out_close: + os_close_file(fd); + return(ret); +} + +/* Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-x86_64/fault.c b/trunk/arch/um/sys-x86_64/fault.c index 4636b1465b6c..cee1513c5c31 100644 --- a/trunk/arch/um/sys-x86_64/fault.c +++ b/trunk/arch/um/sys-x86_64/fault.c @@ -4,24 +4,20 @@ * Licensed under the GPL */ -#include "sysdep/ptrace.h" +#include "user.h" -/* These two are from asm-um/uaccess.h and linux/module.h, check them. */ -struct exception_table_entry +int arch_fixup(unsigned long address, void *sc_ptr) { - unsigned long insn; - unsigned long fixup; -}; - -const struct exception_table_entry *search_exception_tables(unsigned long add); -int arch_fixup(unsigned long address, union uml_pt_regs *regs) -{ - const struct exception_table_entry *fixup; - - fixup = search_exception_tables(address); - if(fixup != 0){ - UPT_IP(regs) = fixup->fixup; - return(1); - } + /* XXX search_exception_tables() */ return(0); } + +/* Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/sys-x86_64/signal.c b/trunk/arch/um/sys-x86_64/signal.c index fe8ec04d35bb..af2f017617b4 100644 --- a/trunk/arch/um/sys-x86_64/signal.c +++ b/trunk/arch/um/sys-x86_64/signal.c @@ -20,36 +20,6 @@ #include "skas.h" -void copy_sc(union uml_pt_regs *regs, void *from) -{ - struct sigcontext *sc = from; - -#define GETREG(regs, regno, sc, regname) \ - (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname - - GETREG(regs, R8, sc, r8); - GETREG(regs, R9, sc, r9); - GETREG(regs, R10, sc, r10); - GETREG(regs, R11, sc, r11); - GETREG(regs, R12, sc, r12); - GETREG(regs, R13, sc, r13); - GETREG(regs, R14, sc, r14); - GETREG(regs, R15, sc, r15); - GETREG(regs, RDI, sc, rdi); - GETREG(regs, RSI, sc, rsi); - GETREG(regs, RBP, sc, rbp); - GETREG(regs, RBX, sc, rbx); - GETREG(regs, RDX, sc, rdx); - GETREG(regs, RAX, sc, rax); - GETREG(regs, RCX, sc, rcx); - GETREG(regs, RSP, sc, rsp); - GETREG(regs, RIP, sc, rip); - GETREG(regs, EFLAGS, sc, eflags); - GETREG(regs, CS, sc, cs); - -#undef GETREG -} - static int copy_sc_from_user_skas(struct pt_regs *regs, struct sigcontext __user *from) { @@ -81,7 +51,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, #undef GETREG - return err; + return(err); } int copy_sc_to_user_skas(struct sigcontext __user *to, diff --git a/trunk/arch/um/sys-x86_64/user-offsets.c b/trunk/arch/um/sys-x86_64/user-offsets.c index 0d5fd764c21f..899cebb57c3f 100644 --- a/trunk/arch/um/sys-x86_64/user-offsets.c +++ b/trunk/arch/um/sys-x86_64/user-offsets.c @@ -2,7 +2,6 @@ #include #include #include -#include #define __FRAME_OFFSETS #include #include @@ -58,6 +57,7 @@ void foo(void) OFFSET(HOST_SC_SS, sigcontext, ss); #endif + DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); DEFINE(HOST_XFP_SIZE, 0); DEFINE_LONGS(HOST_RBX, RBX); @@ -94,8 +94,4 @@ void foo(void) DEFINE(UM_POLLIN, POLLIN); DEFINE(UM_POLLPRI, POLLPRI); DEFINE(UM_POLLOUT, POLLOUT); - - DEFINE(UM_PROT_READ, PROT_READ); - DEFINE(UM_PROT_WRITE, PROT_WRITE); - DEFINE(UM_PROT_EXEC, PROT_EXEC); } diff --git a/trunk/arch/v850/Kconfig b/trunk/arch/v850/Kconfig index 5f54c1236c18..50ccc7f57cd0 100644 --- a/trunk/arch/v850/Kconfig +++ b/trunk/arch/v850/Kconfig @@ -37,10 +37,6 @@ config GENERIC_IRQ_PROBE bool default y -config GENERIC_TIME - bool - default y - config TIME_LOW_RES bool default y diff --git a/trunk/arch/v850/kernel/process.c b/trunk/arch/v850/kernel/process.c index e4a4b8e7d5a3..c4f844c86e50 100644 --- a/trunk/arch/v850/kernel/process.c +++ b/trunk/arch/v850/kernel/process.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/v850/kernel/ptrace.c b/trunk/arch/v850/kernel/ptrace.c index a9b09343097d..67e057509664 100644 --- a/trunk/arch/v850/kernel/ptrace.c +++ b/trunk/arch/v850/kernel/ptrace.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/v850/kernel/signal.c b/trunk/arch/v850/kernel/signal.c index bf166e7e762c..17c2d4359b04 100644 --- a/trunk/arch/v850/kernel/signal.c +++ b/trunk/arch/v850/kernel/signal.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/trunk/arch/v850/kernel/syscalls.c b/trunk/arch/v850/kernel/syscalls.c index f9f00ccf5324..d2b1fb19d243 100644 --- a/trunk/arch/v850/kernel/syscalls.c +++ b/trunk/arch/v850/kernel/syscalls.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/v850/kernel/time.c b/trunk/arch/v850/kernel/time.c index f0905b03523b..486e3a441c86 100644 --- a/trunk/arch/v850/kernel/time.c +++ b/trunk/arch/v850/kernel/time.c @@ -90,6 +90,81 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs) return IRQ_HANDLED; } +/* + * This version of gettimeofday has near microsecond resolution. + */ +void do_gettimeofday (struct timeval *tv) +{ +#if 0 /* DAVIDM later if possible */ + extern volatile unsigned long lost_ticks; + unsigned long lost; +#endif + unsigned long flags; + unsigned long usec, sec; + unsigned long seq; + + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + +#if 0 + usec = mach_gettimeoffset ? mach_gettimeoffset () : 0; +#else + usec = 0; +#endif +#if 0 /* DAVIDM later if possible */ + lost = lost_ticks; + if (lost) + usec += lost * (1000000/HZ); +#endif + sec = xtime.tv_sec; + usec += xtime.tv_nsec / 1000; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; +} + +EXPORT_SYMBOL(do_gettimeofday); + +int do_settimeofday(struct timespec *tv) +{ + if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) + return -EINVAL; + + write_seqlock_irq (&xtime_lock); + + /* This is revolting. We need to set the xtime.tv_nsec + * correctly. However, the value in this location is + * is value at the last tick. + * Discover what correction gettimeofday + * would have done, and then undo it! + */ +#if 0 + tv->tv_nsec -= mach_gettimeoffset() * 1000; +#endif + + while (tv->tv_nsec < 0) { + tv->tv_nsec += NSEC_PER_SEC; + tv->tv_sec--; + } + + xtime.tv_sec = tv->tv_sec; + xtime.tv_nsec = tv->tv_nsec; + + ntp_clear(); + + write_sequnlock_irq (&xtime_lock); + clock_was_set(); + return 0; +} + +EXPORT_SYMBOL(do_settimeofday); + static int timer_dev_id; static struct irqaction timer_irqaction = { timer_interrupt, diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 145bb824b2a8..56eb14c98475 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -415,13 +415,13 @@ config OUT_OF_LINE_PFN_TO_PAGE depends on DISCONTIGMEM config NR_CPUS - int "Maximum number of CPUs (2-255)" + int "Maximum number of CPUs (2-256)" range 2 255 depends on SMP default "8" help This allows you to specify the maximum number of CPUs which this - kernel will support. Current maximum is 255 CPUs due to + kernel will support. Current maximum is 256 CPUs due to APIC addressing limits. Less depending on the hardware. This is purely to save memory - each supported CPU requires @@ -565,56 +565,23 @@ config CRASH_DUMP PHYSICAL_START. For more details see Documentation/kdump/kdump.txt -config RELOCATABLE - bool "Build a relocatable kernel(EXPERIMENTAL)" - depends on EXPERIMENTAL - help - Builds a relocatable kernel. This enables loading and running - a kernel binary from a different physical address than it has - been compiled for. - - One use is for the kexec on panic case where the recovery kernel - must live at a different physical address than the primary - kernel. - - Note: If CONFIG_RELOCATABLE=y, then kernel run from the address - it has been loaded at and compile time physical address - (CONFIG_PHYSICAL_START) is ignored. - config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) + default "0x1000000" if CRASH_DUMP default "0x200000" help - This gives the physical address where the kernel is loaded. It - should be aligned to 2MB boundary. - - If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then - bzImage will decompress itself to above physical address and - run from there. Otherwise, bzImage will run from the address where - it has been loaded by the boot loader and will ignore above physical - address. - - In normal kdump cases one does not have to set/change this option - as now bzImage can be compiled as a completely relocatable image - (CONFIG_RELOCATABLE=y) and be used to load and run from a different - address. This option is mainly useful for the folks who don't want - to use a bzImage for capturing the crash dump and want to use a - vmlinux instead. - - So if you are using bzImage for capturing the crash dump, leave - the value here unchanged to 0x200000 and set CONFIG_RELOCATABLE=y. - Otherwise if you plan to use vmlinux for capturing the crash dump - change this value to start of the reserved region (Typically 16MB - 0x1000000). In other words, it can be set based on the "X" value as + This gives the physical address where the kernel is loaded. Normally + for regular kernels this value is 0x200000 (2MB). But in the case + of kexec on panic the fail safe kernel needs to run at a different + address than the panic-ed kernel. This option is used to set the load + address for kernels used to capture crash dump on being kexec'ed + after panic. The default value for crash dump kernels is + 0x1000000 (16MB). This can also be set based on the "X" value as specified in the "crashkernel=YM@XM" command line boot parameter passed to the panic-ed kernel. Typically this parameter is set as crashkernel=64M@16M. Please take a look at Documentation/kdump/kdump.txt for more details about crash dumps. - Usage of bzImage for capturing the crash dump is advantageous as - one does not have to build two kernels. Same kernel can be used - as production kernel and capture kernel. - Don't change this unless you know what you are doing. config SECCOMP @@ -660,6 +627,14 @@ config CC_STACKPROTECTOR_ALL source kernel/Kconfig.hz +config REORDER + bool "Function reordering" + default n + help + This option enables the toolchain to reorder functions for a more + optimal TLB usage. If you have pretty much any version of binutils, + this can increase your kernel build time by roughly one minute. + config K8_NB def_bool y depends on AGP_AMD64 || IOMMU || (PCI && NUMA) @@ -701,7 +676,6 @@ menu "Bus options (PCI etc.)" config PCI bool "PCI support" - select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC) # x86-64 doesn't support PCI BIOS access from long mode so always go direct. config PCI_DIRECT diff --git a/trunk/arch/x86_64/Makefile b/trunk/arch/x86_64/Makefile index 29617ae3926d..2941a915d4ef 100644 --- a/trunk/arch/x86_64/Makefile +++ b/trunk/arch/x86_64/Makefile @@ -40,6 +40,10 @@ cflags-y += -m64 cflags-y += -mno-red-zone cflags-y += -mcmodel=kernel cflags-y += -pipe +cflags-kernel-$(CONFIG_REORDER) += -ffunction-sections +# this makes reading assembly source easier, but produces worse code +# actually it makes the kernel smaller too. +cflags-y += -fno-reorder-blocks cflags-y += -Wno-sign-compare cflags-y += -fno-asynchronous-unwind-tables ifneq ($(CONFIG_DEBUG_INFO),y) diff --git a/trunk/arch/x86_64/boot/Makefile b/trunk/arch/x86_64/boot/Makefile index ee6f6505f95f..deb063e7762d 100644 --- a/trunk/arch/x86_64/boot/Makefile +++ b/trunk/arch/x86_64/boot/Makefile @@ -36,7 +36,7 @@ subdir- := compressed/ #Let make clean descend in compressed/ # --------------------------------------------------------------------------- $(obj)/bzImage: IMAGE_OFFSET := 0x100000 -$(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ +$(obj)/bzImage: EXTRA_AFLAGS := -traditional $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ $(obj)/bzImage: BUILDFLAGS := -b quiet_cmd_image = BUILD $@ diff --git a/trunk/arch/x86_64/boot/compressed/Makefile b/trunk/arch/x86_64/boot/compressed/Makefile index 705a3e33d7e1..e70fa6e1da08 100644 --- a/trunk/arch/x86_64/boot/compressed/Makefile +++ b/trunk/arch/x86_64/boot/compressed/Makefile @@ -8,14 +8,16 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o EXTRA_AFLAGS := -traditional +AFLAGS := $(subst -m64,-m32,$(AFLAGS)) # cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with # -m32 -CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin -LDFLAGS := -m elf_x86_64 +CFLAGS := -m32 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing +LDFLAGS := -m elf_i386 -LDFLAGS_vmlinux := -T -$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE +LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 -m elf_i386 + +$(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE $(call if_changed,ld) @: @@ -25,7 +27,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) -LDFLAGS_piggy.o := -r --format binary --oformat elf64-x86-64 -T +LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE $(call if_changed,ld) diff --git a/trunk/arch/x86_64/boot/compressed/head.S b/trunk/arch/x86_64/boot/compressed/head.S index f9d5692a0106..6f55565e4d42 100644 --- a/trunk/arch/x86_64/boot/compressed/head.S +++ b/trunk/arch/x86_64/boot/compressed/head.S @@ -26,279 +26,116 @@ #include #include -#include #include -#include -.section ".text.head" .code32 .globl startup_32 - + startup_32: cld cli - movl $(__KERNEL_DS), %eax - movl %eax, %ds - movl %eax, %es - movl %eax, %ss - -/* Calculate the delta between where we were compiled to run - * at and where we were actually loaded at. This can only be done - * with a short local call on x86. Nothing else will tell us what - * address we are running at. The reserved chunk of the real-mode - * data at 0x34-0x3f are used as the stack for this calculation. - * Only 4 bytes are needed. - */ - leal 0x40(%esi), %esp - call 1f -1: popl %ebp - subl $1b, %ebp - -/* setup a stack and make sure cpu supports long mode. */ - movl $user_stack_end, %eax - addl %ebp, %eax - movl %eax, %esp - - call verify_cpu - testl %eax, %eax - jnz no_longmode - -/* Compute the delta between where we were compiled to run at - * and where the code will actually run at. - */ -/* %ebp contains the address we are loaded at by the boot loader and %ebx - * contains the address where we should move the kernel image temporarily - * for safe in-place decompression. - */ - -#ifdef CONFIG_RELOCATABLE - movl %ebp, %ebx - addl $(LARGE_PAGE_SIZE -1), %ebx - andl $LARGE_PAGE_MASK, %ebx -#else - movl $CONFIG_PHYSICAL_START, %ebx -#endif - - /* Replace the compressed data size with the uncompressed size */ - subl input_len(%ebp), %ebx - movl output_len(%ebp), %eax - addl %eax, %ebx - /* Add 8 bytes for every 32K input block */ - shrl $12, %eax - addl %eax, %ebx - /* Add 32K + 18 bytes of extra slack and align on a 4K boundary */ - addl $(32768 + 18 + 4095), %ebx - andl $~4095, %ebx + movl $(__KERNEL_DS),%eax + movl %eax,%ds + movl %eax,%es + movl %eax,%fs + movl %eax,%gs + + lss stack_start,%esp + xorl %eax,%eax +1: incl %eax # check that A20 really IS enabled + movl %eax,0x000000 # loop forever if it isn't + cmpl %eax,0x100000 + je 1b /* - * Prepare for entering 64 bit mode + * Initialize eflags. Some BIOS's leave bits like NT set. This would + * confuse the debugger if this code is traced. + * XXX - best to initialize before switching to protected mode. */ - - /* Load new GDT with the 64bit segments using 32bit descriptor */ - leal gdt(%ebp), %eax - movl %eax, gdt+2(%ebp) - lgdt gdt(%ebp) - - /* Enable PAE mode */ - xorl %eax, %eax - orl $(1 << 5), %eax - movl %eax, %cr4 - - /* - * Build early 4G boot pagetable - */ - /* Initialize Page tables to 0*/ - leal pgtable(%ebx), %edi - xorl %eax, %eax - movl $((4096*6)/4), %ecx - rep stosl - - /* Build Level 4 */ - leal pgtable + 0(%ebx), %edi - leal 0x1007 (%edi), %eax - movl %eax, 0(%edi) - - /* Build Level 3 */ - leal pgtable + 0x1000(%ebx), %edi - leal 0x1007(%edi), %eax - movl $4, %ecx -1: movl %eax, 0x00(%edi) - addl $0x00001000, %eax - addl $8, %edi - decl %ecx - jnz 1b - - /* Build Level 2 */ - leal pgtable + 0x2000(%ebx), %edi - movl $0x00000183, %eax - movl $2048, %ecx -1: movl %eax, 0(%edi) - addl $0x00200000, %eax - addl $8, %edi - decl %ecx - jnz 1b - - /* Enable the boot page tables */ - leal pgtable(%ebx), %eax - movl %eax, %cr3 - - /* Enable Long mode in EFER (Extended Feature Enable Register) */ - movl $MSR_EFER, %ecx - rdmsr - btsl $_EFER_LME, %eax - wrmsr - - /* Setup for the jump to 64bit mode - * - * When the jump is performend we will be in long mode but - * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1 - * (and in turn EFER.LMA = 1). To jump into 64bit mode we use - * the new gdt/idt that has __KERNEL_CS with CS.L = 1. - * We place all of the values on our mini stack so lret can - * used to perform that far jump. - */ - pushl $__KERNEL_CS - leal startup_64(%ebp), %eax - pushl %eax - - /* Enter paged protected Mode, activating Long Mode */ - movl $0x80000001, %eax /* Enable Paging and Protected mode */ - movl %eax, %cr0 - - /* Jump from 32bit compatibility mode into 64bit mode. */ - lret - -no_longmode: - /* This isn't an x86-64 CPU so hang */ -1: - hlt - jmp 1b - -#include "../../kernel/verify_cpu.S" - - /* Be careful here startup_64 needs to be at a predictable - * address so I can export it in an ELF header. Bootloaders - * should look at the ELF header to find this address, as - * it may change in the future. - */ - .code64 - .org 0x200 -ENTRY(startup_64) - /* We come here either from startup_32 or directly from a - * 64bit bootloader. If we come here from a bootloader we depend on - * an identity mapped page table being provied that maps our - * entire text+data+bss and hopefully all of memory. - */ - - /* Setup data segments. */ - xorl %eax, %eax - movl %eax, %ds - movl %eax, %es - movl %eax, %ss - - /* Compute the decompressed kernel start address. It is where - * we were loaded at aligned to a 2M boundary. %rbp contains the - * decompressed kernel start address. - * - * If it is a relocatable kernel then decompress and run the kernel - * from load address aligned to 2MB addr, otherwise decompress and - * run the kernel from CONFIG_PHYSICAL_START - */ - - /* Start with the delta to where the kernel will run at. */ -#ifdef CONFIG_RELOCATABLE - leaq startup_32(%rip) /* - $startup_32 */, %rbp - addq $(LARGE_PAGE_SIZE - 1), %rbp - andq $LARGE_PAGE_MASK, %rbp - movq %rbp, %rbx -#else - movq $CONFIG_PHYSICAL_START, %rbp - movq %rbp, %rbx -#endif - - /* Replace the compressed data size with the uncompressed size */ - movl input_len(%rip), %eax - subq %rax, %rbx - movl output_len(%rip), %eax - addq %rax, %rbx - /* Add 8 bytes for every 32K input block */ - shrq $12, %rax - addq %rax, %rbx - /* Add 32K + 18 bytes of extra slack and align on a 4K boundary */ - addq $(32768 + 18 + 4095), %rbx - andq $~4095, %rbx - -/* Copy the compressed kernel to the end of our buffer - * where decompression in place becomes safe. - */ - leaq _end(%rip), %r8 - leaq _end(%rbx), %r9 - movq $_end /* - $startup_32 */, %rcx -1: subq $8, %r8 - subq $8, %r9 - movq 0(%r8), %rax - movq %rax, 0(%r9) - subq $8, %rcx - jnz 1b - -/* - * Jump to the relocated address. - */ - leaq relocated(%rbx), %rax - jmp *%rax - -.section ".text" -relocated: - + pushl $0 + popfl /* * Clear BSS */ - xorq %rax, %rax - leaq _edata(%rbx), %rdi - leaq _end(%rbx), %rcx - subq %rdi, %rcx + xorl %eax,%eax + movl $_edata,%edi + movl $_end,%ecx + subl %edi,%ecx cld rep stosb - - /* Setup the stack */ - leaq user_stack_end(%rip), %rsp - - /* zero EFLAGS after setting rsp */ - pushq $0 - popfq - /* * Do the decompression, and jump to the new kernel.. */ - pushq %rsi # Save the real mode argument - movq %rsi, %rdi # real mode address - leaq _heap(%rip), %rsi # _heap - leaq input_data(%rip), %rdx # input_data - movl input_len(%rip), %eax - movq %rax, %rcx # input_len - movq %rbp, %r8 # output - call decompress_kernel - popq %rsi + subl $16,%esp # place for structure on the stack + movl %esp,%eax + pushl %esi # real mode pointer as second arg + pushl %eax # address of structure as first arg + call decompress_kernel + orl %eax,%eax + jnz 3f + addl $8,%esp + xorl %ebx,%ebx + ljmp $(__KERNEL_CS), $__PHYSICAL_START +/* + * We come here, if we were loaded high. + * We need to move the move-in-place routine down to 0x1000 + * and then start it with the buffer addresses in registers, + * which we got from the stack. + */ +3: + movl %esi,%ebx + movl $move_routine_start,%esi + movl $0x1000,%edi + movl $move_routine_end,%ecx + subl %esi,%ecx + addl $3,%ecx + shrl $2,%ecx + cld + rep + movsl + + popl %esi # discard the address + addl $4,%esp # real mode pointer + popl %esi # low_buffer_start + popl %ecx # lcount + popl %edx # high_buffer_start + popl %eax # hcount + movl $__PHYSICAL_START,%edi + cli # make sure we don't get interrupted + ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine /* - * Jump to the decompressed kernel. + * Routine (template) for moving the decompressed kernel in place, + * if we were high loaded. This _must_ PIC-code ! */ - jmp *%rbp +move_routine_start: + movl %ecx,%ebp + shrl $2,%ecx + rep + movsl + movl %ebp,%ecx + andl $3,%ecx + rep + movsb + movl %edx,%esi + movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0 + addl $3,%ecx + shrl $2,%ecx + rep + movsl + movl %ebx,%esi # Restore setup pointer + xorl %ebx,%ebx + ljmp $(__KERNEL_CS), $__PHYSICAL_START +move_routine_end: - .data -gdt: - .word gdt_end - gdt - .long gdt - .word 0 - .quad 0x0000000000000000 /* NULL descriptor */ - .quad 0x00af9a000000ffff /* __KERNEL_CS */ - .quad 0x00cf92000000ffff /* __KERNEL_DS */ -gdt_end: - .bss -/* Stack for uncompression */ - .balign 4 -user_stack: + +/* Stack for uncompression */ + .align 32 +user_stack: .fill 4096,4,0 -user_stack_end: +stack_start: + .long user_stack+4096 + .word __KERNEL_DS + diff --git a/trunk/arch/x86_64/boot/compressed/misc.c b/trunk/arch/x86_64/boot/compressed/misc.c index f932b0e89096..3755b2e394d0 100644 --- a/trunk/arch/x86_64/boot/compressed/misc.c +++ b/trunk/arch/x86_64/boot/compressed/misc.c @@ -9,95 +9,10 @@ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 */ -#define _LINUX_STRING_H_ 1 -#define __LINUX_BITMAP_H 1 - -#include #include #include #include -/* WARNING!! - * This code is compiled with -fPIC and it is relocated dynamically - * at run time, but no relocation processing is performed. - * This means that it is not safe to place pointers in static structures. - */ - -/* - * Getting to provable safe in place decompression is hard. - * Worst case behaviours need to be analized. - * Background information: - * - * The file layout is: - * magic[2] - * method[1] - * flags[1] - * timestamp[4] - * extraflags[1] - * os[1] - * compressed data blocks[N] - * crc[4] orig_len[4] - * - * resulting in 18 bytes of non compressed data overhead. - * - * Files divided into blocks - * 1 bit (last block flag) - * 2 bits (block type) - * - * 1 block occurs every 32K -1 bytes or when there 50% compression has been achieved. - * The smallest block type encoding is always used. - * - * stored: - * 32 bits length in bytes. - * - * fixed: - * magic fixed tree. - * symbols. - * - * dynamic: - * dynamic tree encoding. - * symbols. - * - * - * The buffer for decompression in place is the length of the - * uncompressed data, plus a small amount extra to keep the algorithm safe. - * The compressed data is placed at the end of the buffer. The output - * pointer is placed at the start of the buffer and the input pointer - * is placed where the compressed data starts. Problems will occur - * when the output pointer overruns the input pointer. - * - * The output pointer can only overrun the input pointer if the input - * pointer is moving faster than the output pointer. A condition only - * triggered by data whose compressed form is larger than the uncompressed - * form. - * - * The worst case at the block level is a growth of the compressed data - * of 5 bytes per 32767 bytes. - * - * The worst case internal to a compressed block is very hard to figure. - * The worst case can at least be boundined by having one bit that represents - * 32764 bytes and then all of the rest of the bytes representing the very - * very last byte. - * - * All of which is enough to compute an amount of extra data that is required - * to be safe. To avoid problems at the block level allocating 5 extra bytes - * per 32767 bytes of data is sufficient. To avoind problems internal to a block - * adding an extra 32767 bytes (the worst case uncompressed block size) is - * sufficient, to ensure that in the worst case the decompressed data for - * block will stop the byte before the compressed data for a block begins. - * To avoid problems with the compressed data's meta information an extra 18 - * bytes are needed. Leading to the formula: - * - * extra_bytes = (uncompressed_size >> 12) + 32768 + 18 + decompressor_size. - * - * Adding 8 bytes per 32K is a bit excessive but much easier to calculate. - * Adding 32768 instead of 32767 just makes for round numbers. - * Adding the decompressor_size is necessary as it musht live after all - * of the data as well. Last I measured the decompressor is about 14K. - * 10K of actuall data and 4K of bss. - * - */ - /* * gzip declarations */ @@ -113,20 +28,15 @@ typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; -#define WSIZE 0x80000000 /* Window size must be at least 32k, - * and a power of two - * We don't actually have a window just - * a huge output buffer so I report - * a 2G windows size, as that should - * always be larger than our output buffer. - */ +#define WSIZE 0x8000 /* Window size must be at least 32k, */ + /* and a power of two */ -static uch *inbuf; /* input buffer */ -static uch *window; /* Sliding window buffer, (and final output buffer) */ +static uch *inbuf; /* input buffer */ +static uch window[WSIZE]; /* Sliding window buffer */ -static unsigned insize; /* valid bytes in inbuf */ -static unsigned inptr; /* index of next byte to be processed in inbuf */ -static unsigned outcnt; /* bytes in output buffer */ +static unsigned insize = 0; /* valid bytes in inbuf */ +static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ +static unsigned outcnt = 0; /* bytes in output buffer */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ @@ -177,6 +87,8 @@ extern unsigned char input_data[]; extern int input_len; static long bytes_out = 0; +static uch *output_data; +static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); @@ -186,10 +98,17 @@ static void *memcpy(void *dest, const void *src, unsigned n); static void putstr(const char *); -static long free_mem_ptr; +extern int end; +static long free_mem_ptr = (long)&end; static long free_mem_end_ptr; -#define HEAP_SIZE 0x7000 +#define INPLACE_MOVE_ROUTINE 0x1000 +#define LOW_BUFFER_START 0x2000 +#define LOW_BUFFER_MAX 0x90000 +#define HEAP_SIZE 0x3000 +static unsigned int low_buffer_end, low_buffer_size; +static int high_loaded =0; +static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/; static char *vidmem = (char *)0xb8000; static int vidport; @@ -299,31 +218,58 @@ static void* memcpy(void* dest, const void* src, unsigned n) */ static int fill_inbuf(void) { - error("ran out of input data"); - return 0; + if (insize != 0) { + error("ran out of input data"); + } + + inbuf = input_data; + insize = input_len; + inptr = 1; + return inbuf[0]; } /* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */ +static void flush_window_low(void) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, *out, ch; + + in = window; + out = &output_data[output_ptr]; + for (n = 0; n < outcnt; n++) { + ch = *out++ = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + output_ptr += (ulg)outcnt; + outcnt = 0; +} + +static void flush_window_high(void) +{ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, ch; + in = window; + for (n = 0; n < outcnt; n++) { + ch = *output_data++ = *in++; + if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + outcnt = 0; +} + static void flush_window(void) { - /* With my window equal to my output buffer - * I only need to compute the crc here. - */ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, ch; - - in = window; - for (n = 0; n < outcnt; n++) { - ch = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - outcnt = 0; + if (high_loaded) flush_window_high(); + else flush_window_low(); } static void error(char *x) @@ -335,8 +281,57 @@ static void error(char *x) while(1); /* Halt */ } -asmlinkage void decompress_kernel(void *rmode, unsigned long heap, - uch *input_data, unsigned long input_len, uch *output) +static void setup_normal_output_buffer(void) +{ +#ifdef STANDARD_MEMORY_BIOS_CALL + if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); +#else + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); +#endif + output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */ + free_mem_end_ptr = (long)real_mode; +} + +struct moveparams { + uch *low_buffer_start; int lcount; + uch *high_buffer_start; int hcount; +}; + +static void setup_output_buffer_if_we_run_high(struct moveparams *mv) +{ + high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); +#ifdef STANDARD_MEMORY_BIOS_CALL + if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); +#else + if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); +#endif + mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START; + low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX + ? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff; + low_buffer_size = low_buffer_end - LOW_BUFFER_START; + high_loaded = 1; + free_mem_end_ptr = (long)high_buffer_start; + if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { + high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); + mv->hcount = 0; /* say: we need not to move high_buffer */ + } + else mv->hcount = -1; + mv->high_buffer_start = high_buffer_start; +} + +static void close_output_buffer_if_we_run_high(struct moveparams *mv) +{ + if (bytes_out > low_buffer_size) { + mv->lcount = low_buffer_size; + if (mv->hcount) + mv->hcount = bytes_out - low_buffer_size; + } else { + mv->lcount = bytes_out; + mv->hcount = 0; + } +} + +int decompress_kernel(struct moveparams *mv, void *rmode) { real_mode = rmode; @@ -351,21 +346,13 @@ asmlinkage void decompress_kernel(void *rmode, unsigned long heap, lines = RM_SCREEN_INFO.orig_video_lines; cols = RM_SCREEN_INFO.orig_video_cols; - window = output; /* Output buffer (Normally at 1M) */ - free_mem_ptr = heap; /* Heap */ - free_mem_end_ptr = heap + HEAP_SIZE; - inbuf = input_data; /* Input buffer */ - insize = input_len; - inptr = 0; - - if ((ulg)output & (__KERNEL_ALIGN - 1)) - error("Destination address not 2M aligned"); - if ((ulg)output >= 0xffffffffffUL) - error("Destination address too large"); + if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); + else setup_output_buffer_if_we_run_high(mv); makecrc(); putstr(".\nDecompressing Linux..."); gunzip(); putstr("done.\nBooting the kernel.\n"); - return; + if (high_loaded) close_output_buffer_if_we_run_high(mv); + return high_loaded; } diff --git a/trunk/arch/x86_64/boot/compressed/vmlinux.lds b/trunk/arch/x86_64/boot/compressed/vmlinux.lds deleted file mode 100644 index 94c13e557fb4..000000000000 --- a/trunk/arch/x86_64/boot/compressed/vmlinux.lds +++ /dev/null @@ -1,44 +0,0 @@ -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") -OUTPUT_ARCH(i386:x86-64) -ENTRY(startup_64) -SECTIONS -{ - /* Be careful parts of head.S assume startup_32 is at - * address 0. - */ - . = 0; - .text : { - _head = . ; - *(.text.head) - _ehead = . ; - *(.text.compressed) - _text = .; /* Text */ - *(.text) - *(.text.*) - _etext = . ; - } - .rodata : { - _rodata = . ; - *(.rodata) /* read-only data */ - *(.rodata.*) - _erodata = . ; - } - .data : { - _data = . ; - *(.data) - *(.data.*) - _edata = . ; - } - .bss : { - _bss = . ; - *(.bss) - *(.bss.*) - *(COMMON) - . = ALIGN(8); - _end = . ; - . = ALIGN(4096); - pgtable = . ; - . = . + 4096 * 6; - _heap = .; - } -} diff --git a/trunk/arch/x86_64/boot/compressed/vmlinux.scr b/trunk/arch/x86_64/boot/compressed/vmlinux.scr index bd1429ce193e..1ed9d791f863 100644 --- a/trunk/arch/x86_64/boot/compressed/vmlinux.scr +++ b/trunk/arch/x86_64/boot/compressed/vmlinux.scr @@ -1,10 +1,9 @@ SECTIONS { - .text.compressed : { + .data : { input_len = .; - LONG(input_data_end - input_data) input_data = .; - *(.data) - output_len = . - 4; - input_data_end = .; + LONG(input_data_end - input_data) input_data = .; + *(.data) + input_data_end = .; } } diff --git a/trunk/arch/x86_64/boot/setup.S b/trunk/arch/x86_64/boot/setup.S index e9e33f949697..770940cc0108 100644 --- a/trunk/arch/x86_64/boot/setup.S +++ b/trunk/arch/x86_64/boot/setup.S @@ -51,7 +51,6 @@ #include #include #include -#include /* Signature words to ensure LILO loaded us right */ #define SIG1 0xAA55 @@ -81,7 +80,7 @@ start: # This is the setup header, and it must start at %cs:2 (old 0x9020:2) .ascii "HdrS" # header signature - .word 0x0206 # header version number (>= 0x0105) + .word 0x0204 # header version number (>= 0x0105) # or else old loadlin-1.5 will fail) realmode_swtch: .word 0, 0 # default_switch, SETUPSEG start_sys_seg: .word SYSSEG @@ -156,20 +155,7 @@ cmd_line_ptr: .long 0 # (Header version 0x0202 or later) # low memory 0x10000 or higher. ramdisk_max: .long 0xffffffff -kernel_alignment: .long 0x200000 # physical addr alignment required for - # protected mode relocatable kernel -#ifdef CONFIG_RELOCATABLE -relocatable_kernel: .byte 1 -#else -relocatable_kernel: .byte 0 -#endif -pad2: .byte 0 -pad3: .word 0 - -cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, - #added with boot protocol - #version 2.06 - + trampoline: call start_of_setup .align 16 # The offset at this point is 0x240 @@ -304,10 +290,64 @@ loader_ok: movw %cs,%ax movw %ax,%ds - call verify_cpu - testl %eax,%eax - jz sse_ok - + /* minimum CPUID flags for x86-64 */ + /* see http://www.x86-64.org/lists/discuss/msg02971.html */ +#define SSE_MASK ((1<<25)|(1<<26)) +#define REQUIRED_MASK1 ((1<<0)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<8)|\ + (1<<13)|(1<<15)|(1<<24)) +#define REQUIRED_MASK2 (1<<29) + + pushfl /* standard way to check for cpuid */ + popl %eax + movl %eax,%ebx + xorl $0x200000,%eax + pushl %eax + popfl + pushfl + popl %eax + cmpl %eax,%ebx + jz no_longmode /* cpu has no cpuid */ + movl $0x0,%eax + cpuid + cmpl $0x1,%eax + jb no_longmode /* no cpuid 1 */ + xor %di,%di + cmpl $0x68747541,%ebx /* AuthenticAMD */ + jnz noamd + cmpl $0x69746e65,%edx + jnz noamd + cmpl $0x444d4163,%ecx + jnz noamd + mov $1,%di /* cpu is from AMD */ +noamd: + movl $0x1,%eax + cpuid + andl $REQUIRED_MASK1,%edx + xorl $REQUIRED_MASK1,%edx + jnz no_longmode + movl $0x80000000,%eax + cpuid + cmpl $0x80000001,%eax + jb no_longmode /* no extended cpuid */ + movl $0x80000001,%eax + cpuid + andl $REQUIRED_MASK2,%edx + xorl $REQUIRED_MASK2,%edx + jnz no_longmode +sse_test: + movl $1,%eax + cpuid + andl $SSE_MASK,%edx + cmpl $SSE_MASK,%edx + je sse_ok + test %di,%di + jz no_longmode /* only try to force SSE on AMD */ + movl $0xc0010015,%ecx /* HWCR */ + rdmsr + btr $15,%eax /* enable SSE */ + wrmsr + xor %di,%di /* don't loop */ + jmp sse_test /* try again */ no_longmode: call beep lea long_mode_panic,%si @@ -317,8 +357,7 @@ no_longmode_loop: long_mode_panic: .string "Your CPU does not support long mode. Use a 32bit distribution." .byte 0 - -#include "../kernel/verify_cpu.S" + sse_ok: popw %ds @@ -807,7 +846,7 @@ gdt_48: # Include video setup & detection code -#include "../../i386/boot/video.S" +#include "video.S" # Setup signature -- must be last setup_sig1: .word SIG1 diff --git a/trunk/arch/x86_64/boot/video.S b/trunk/arch/x86_64/boot/video.S new file mode 100644 index 000000000000..6090516c9c7f --- /dev/null +++ b/trunk/arch/x86_64/boot/video.S @@ -0,0 +1,2043 @@ +/* video.S + * + * Display adapter & video mode setup, version 2.13 (14-May-99) + * + * Copyright (C) 1995 -- 1998 Martin Mares + * Based on the original setup.S code (C) Linus Torvalds and Mats Anderson + * + * Rewritten to use GNU 'as' by Chris Noe May 1999 + * + * For further information, look at Documentation/svga.txt. + * + */ + +/* Enable autodetection of SVGA adapters and modes. */ +#undef CONFIG_VIDEO_SVGA + +/* Enable autodetection of VESA modes */ +#define CONFIG_VIDEO_VESA + +/* Enable compacting of mode table */ +#define CONFIG_VIDEO_COMPACT + +/* Retain screen contents when switching modes */ +#define CONFIG_VIDEO_RETAIN + +/* Enable local mode list */ +#undef CONFIG_VIDEO_LOCAL + +/* Force 400 scan lines for standard modes (hack to fix bad BIOS behaviour */ +#undef CONFIG_VIDEO_400_HACK + +/* Hack that lets you force specific BIOS mode ID and specific dimensions */ +#undef CONFIG_VIDEO_GFX_HACK +#define VIDEO_GFX_BIOS_AX 0x4f02 /* 800x600 on ThinkPad */ +#define VIDEO_GFX_BIOS_BX 0x0102 +#define VIDEO_GFX_DUMMY_RESOLUTION 0x6425 /* 100x37 */ + +/* This code uses an extended set of video mode numbers. These include: + * Aliases for standard modes + * NORMAL_VGA (-1) + * EXTENDED_VGA (-2) + * ASK_VGA (-3) + * Video modes numbered by menu position -- NOT RECOMMENDED because of lack + * of compatibility when extending the table. These are between 0x00 and 0xff. + */ +#define VIDEO_FIRST_MENU 0x0000 + +/* Standard BIOS video modes (BIOS number + 0x0100) */ +#define VIDEO_FIRST_BIOS 0x0100 + +/* VESA BIOS video modes (VESA number + 0x0200) */ +#define VIDEO_FIRST_VESA 0x0200 + +/* Video7 special modes (BIOS number + 0x0900) */ +#define VIDEO_FIRST_V7 0x0900 + +/* Special video modes */ +#define VIDEO_FIRST_SPECIAL 0x0f00 +#define VIDEO_80x25 0x0f00 +#define VIDEO_8POINT 0x0f01 +#define VIDEO_80x43 0x0f02 +#define VIDEO_80x28 0x0f03 +#define VIDEO_CURRENT_MODE 0x0f04 +#define VIDEO_80x30 0x0f05 +#define VIDEO_80x34 0x0f06 +#define VIDEO_80x60 0x0f07 +#define VIDEO_GFX_HACK 0x0f08 +#define VIDEO_LAST_SPECIAL 0x0f09 + +/* Video modes given by resolution */ +#define VIDEO_FIRST_RESOLUTION 0x1000 + +/* The "recalculate timings" flag */ +#define VIDEO_RECALC 0x8000 + +/* Positions of various video parameters passed to the kernel */ +/* (see also include/linux/tty.h) */ +#define PARAM_CURSOR_POS 0x00 +#define PARAM_VIDEO_PAGE 0x04 +#define PARAM_VIDEO_MODE 0x06 +#define PARAM_VIDEO_COLS 0x07 +#define PARAM_VIDEO_EGA_BX 0x0a +#define PARAM_VIDEO_LINES 0x0e +#define PARAM_HAVE_VGA 0x0f +#define PARAM_FONT_POINTS 0x10 + +#define PARAM_LFB_WIDTH 0x12 +#define PARAM_LFB_HEIGHT 0x14 +#define PARAM_LFB_DEPTH 0x16 +#define PARAM_LFB_BASE 0x18 +#define PARAM_LFB_SIZE 0x1c +#define PARAM_LFB_LINELENGTH 0x24 +#define PARAM_LFB_COLORS 0x26 +#define PARAM_VESAPM_SEG 0x2e +#define PARAM_VESAPM_OFF 0x30 +#define PARAM_LFB_PAGES 0x32 +#define PARAM_VESA_ATTRIB 0x34 +#define PARAM_CAPABILITIES 0x36 + +/* Define DO_STORE according to CONFIG_VIDEO_RETAIN */ +#ifdef CONFIG_VIDEO_RETAIN +#define DO_STORE call store_screen +#else +#define DO_STORE +#endif /* CONFIG_VIDEO_RETAIN */ + +# This is the main entry point called by setup.S +# %ds *must* be pointing to the bootsector +video: pushw %ds # We use different segments + pushw %ds # FS contains original DS + popw %fs + pushw %cs # DS is equal to CS + popw %ds + pushw %cs # ES is equal to CS + popw %es + xorw %ax, %ax + movw %ax, %gs # GS is zero + cld + call basic_detect # Basic adapter type testing (EGA/VGA/MDA/CGA) +#ifdef CONFIG_VIDEO_SELECT + movw %fs:(0x01fa), %ax # User selected video mode + cmpw $ASK_VGA, %ax # Bring up the menu + jz vid2 + + call mode_set # Set the mode + jc vid1 + + leaw badmdt, %si # Invalid mode ID + call prtstr +vid2: call mode_menu +vid1: +#ifdef CONFIG_VIDEO_RETAIN + call restore_screen # Restore screen contents +#endif /* CONFIG_VIDEO_RETAIN */ + call store_edid +#endif /* CONFIG_VIDEO_SELECT */ + call mode_params # Store mode parameters + popw %ds # Restore original DS + ret + +# Detect if we have CGA, MDA, EGA or VGA and pass it to the kernel. +basic_detect: + movb $0, %fs:(PARAM_HAVE_VGA) + movb $0x12, %ah # Check EGA/VGA + movb $0x10, %bl + int $0x10 + movw %bx, %fs:(PARAM_VIDEO_EGA_BX) # Identifies EGA to the kernel + cmpb $0x10, %bl # No, it's a CGA/MDA/HGA card. + je basret + + incb adapter + movw $0x1a00, %ax # Check EGA or VGA? + int $0x10 + cmpb $0x1a, %al # 1a means VGA... + jne basret # anything else is EGA. + + incb %fs:(PARAM_HAVE_VGA) # We've detected a VGA + incb adapter +basret: ret + +# Store the video mode parameters for later usage by the kernel. +# This is done by asking the BIOS except for the rows/columns +# parameters in the default 80x25 mode -- these are set directly, +# because some very obscure BIOSes supply insane values. +mode_params: +#ifdef CONFIG_VIDEO_SELECT + cmpb $0, graphic_mode + jnz mopar_gr +#endif + movb $0x03, %ah # Read cursor position + xorb %bh, %bh + int $0x10 + movw %dx, %fs:(PARAM_CURSOR_POS) + movb $0x0f, %ah # Read page/mode/width + int $0x10 + movw %bx, %fs:(PARAM_VIDEO_PAGE) + movw %ax, %fs:(PARAM_VIDEO_MODE) # Video mode and screen width + cmpb $0x7, %al # MDA/HGA => segment differs + jnz mopar0 + + movw $0xb000, video_segment +mopar0: movw %gs:(0x485), %ax # Font size + movw %ax, %fs:(PARAM_FONT_POINTS) # (valid only on EGA/VGA) + movw force_size, %ax # Forced size? + orw %ax, %ax + jz mopar1 + + movb %ah, %fs:(PARAM_VIDEO_COLS) + movb %al, %fs:(PARAM_VIDEO_LINES) + ret + +mopar1: movb $25, %al + cmpb $0, adapter # If we are on CGA/MDA/HGA, the + jz mopar2 # screen must have 25 lines. + + movb %gs:(0x484), %al # On EGA/VGA, use the EGA+ BIOS + incb %al # location of max lines. +mopar2: movb %al, %fs:(PARAM_VIDEO_LINES) + ret + +#ifdef CONFIG_VIDEO_SELECT +# Fetching of VESA frame buffer parameters +mopar_gr: + leaw modelist+1024, %di + movb $0x23, %fs:(PARAM_HAVE_VGA) + movw 16(%di), %ax + movw %ax, %fs:(PARAM_LFB_LINELENGTH) + movw 18(%di), %ax + movw %ax, %fs:(PARAM_LFB_WIDTH) + movw 20(%di), %ax + movw %ax, %fs:(PARAM_LFB_HEIGHT) + movb 25(%di), %al + movb $0, %ah + movw %ax, %fs:(PARAM_LFB_DEPTH) + movb 29(%di), %al + movb $0, %ah + movw %ax, %fs:(PARAM_LFB_PAGES) + movl 40(%di), %eax + movl %eax, %fs:(PARAM_LFB_BASE) + movl 31(%di), %eax + movl %eax, %fs:(PARAM_LFB_COLORS) + movl 35(%di), %eax + movl %eax, %fs:(PARAM_LFB_COLORS+4) + movw 0(%di), %ax + movw %ax, %fs:(PARAM_VESA_ATTRIB) + +# get video mem size + leaw modelist+1024, %di + movw $0x4f00, %ax + int $0x10 + xorl %eax, %eax + movw 18(%di), %ax + movl %eax, %fs:(PARAM_LFB_SIZE) + +# store mode capabilities + movl 10(%di), %eax + movl %eax, %fs:(PARAM_CAPABILITIES) + +# switching the DAC to 8-bit is for <= 8 bpp only + movw %fs:(PARAM_LFB_DEPTH), %ax + cmpw $8, %ax + jg dac_done + +# get DAC switching capability + xorl %eax, %eax + movb 10(%di), %al + testb $1, %al + jz dac_set + +# attempt to switch DAC to 8-bit + movw $0x4f08, %ax + movw $0x0800, %bx + int $0x10 + cmpw $0x004f, %ax + jne dac_set + movb %bh, dac_size # store actual DAC size + +dac_set: +# set color size to DAC size + movb dac_size, %al + movb %al, %fs:(PARAM_LFB_COLORS+0) + movb %al, %fs:(PARAM_LFB_COLORS+2) + movb %al, %fs:(PARAM_LFB_COLORS+4) + movb %al, %fs:(PARAM_LFB_COLORS+6) + +# set color offsets to 0 + movb $0, %fs:(PARAM_LFB_COLORS+1) + movb $0, %fs:(PARAM_LFB_COLORS+3) + movb $0, %fs:(PARAM_LFB_COLORS+5) + movb $0, %fs:(PARAM_LFB_COLORS+7) + +dac_done: +# get protected mode interface informations + movw $0x4f0a, %ax + xorw %bx, %bx + xorw %di, %di + int $0x10 + cmp $0x004f, %ax + jnz no_pm + + movw %es, %fs:(PARAM_VESAPM_SEG) + movw %di, %fs:(PARAM_VESAPM_OFF) +no_pm: ret + +# The video mode menu +mode_menu: + leaw keymsg, %si # "Return/Space/Timeout" message + call prtstr + call flush +nokey: call getkt + + cmpb $0x0d, %al # ENTER ? + je listm # yes - manual mode selection + + cmpb $0x20, %al # SPACE ? + je defmd1 # no - repeat + + call beep + jmp nokey + +defmd1: ret # No mode chosen? Default 80x25 + +listm: call mode_table # List mode table +listm0: leaw name_bann, %si # Print adapter name + call prtstr + movw card_name, %si + orw %si, %si + jnz an2 + + movb adapter, %al + leaw old_name, %si + orb %al, %al + jz an1 + + leaw ega_name, %si + decb %al + jz an1 + + leaw vga_name, %si + jmp an1 + +an2: call prtstr + leaw svga_name, %si +an1: call prtstr + leaw listhdr, %si # Table header + call prtstr + movb $0x30, %dl # DL holds mode number + leaw modelist, %si +lm1: cmpw $ASK_VGA, (%si) # End? + jz lm2 + + movb %dl, %al # Menu selection number + call prtchr + call prtsp2 + lodsw + call prthw # Mode ID + call prtsp2 + movb 0x1(%si), %al + call prtdec # Rows + movb $0x78, %al # the letter 'x' + call prtchr + lodsw + call prtdec # Columns + movb $0x0d, %al # New line + call prtchr + movb $0x0a, %al + call prtchr + incb %dl # Next character + cmpb $0x3a, %dl + jnz lm1 + + movb $0x61, %dl + jmp lm1 + +lm2: leaw prompt, %si # Mode prompt + call prtstr + leaw edit_buf, %di # Editor buffer +lm3: call getkey + cmpb $0x0d, %al # Enter? + jz lment + + cmpb $0x08, %al # Backspace? + jz lmbs + + cmpb $0x20, %al # Printable? + jc lm3 + + cmpw $edit_buf+4, %di # Enough space? + jz lm3 + + stosb + call prtchr + jmp lm3 + +lmbs: cmpw $edit_buf, %di # Backspace + jz lm3 + + decw %di + movb $0x08, %al + call prtchr + call prtspc + movb $0x08, %al + call prtchr + jmp lm3 + +lment: movb $0, (%di) + leaw crlft, %si + call prtstr + leaw edit_buf, %si + cmpb $0, (%si) # Empty string = default mode + jz lmdef + + cmpb $0, 1(%si) # One character = menu selection + jz mnusel + + cmpw $0x6373, (%si) # "scan" => mode scanning + jnz lmhx + + cmpw $0x6e61, 2(%si) + jz lmscan + +lmhx: xorw %bx, %bx # Else => mode ID in hex +lmhex: lodsb + orb %al, %al + jz lmuse1 + + subb $0x30, %al + jc lmbad + + cmpb $10, %al + jc lmhx1 + + subb $7, %al + andb $0xdf, %al + cmpb $10, %al + jc lmbad + + cmpb $16, %al + jnc lmbad + +lmhx1: shlw $4, %bx + orb %al, %bl + jmp lmhex + +lmuse1: movw %bx, %ax + jmp lmuse + +mnusel: lodsb # Menu selection + xorb %ah, %ah + subb $0x30, %al + jc lmbad + + cmpb $10, %al + jc lmuse + + cmpb $0x61-0x30, %al + jc lmbad + + subb $0x61-0x30-10, %al + cmpb $36, %al + jnc lmbad + +lmuse: call mode_set + jc lmdef + +lmbad: leaw unknt, %si + call prtstr + jmp lm2 +lmscan: cmpb $0, adapter # Scanning only on EGA/VGA + jz lmbad + + movw $0, mt_end # Scanning of modes is + movb $1, scanning # done as new autodetection. + call mode_table + jmp listm0 +lmdef: ret + +# Additional parts of mode_set... (relative jumps, you know) +setv7: # Video7 extended modes + DO_STORE + subb $VIDEO_FIRST_V7>>8, %bh + movw $0x6f05, %ax + int $0x10 + stc + ret + +_setrec: jmp setrec # Ugly... +_set_80x25: jmp set_80x25 + +# Aliases for backward compatibility. +setalias: + movw $VIDEO_80x25, %ax + incw %bx + jz mode_set + + movb $VIDEO_8POINT-VIDEO_FIRST_SPECIAL, %al + incw %bx + jnz setbad # Fall-through! + +# Setting of user mode (AX=mode ID) => CF=success +mode_set: + movw %ax, %fs:(0x01fa) # Store mode for use in acpi_wakeup.S + movw %ax, %bx + cmpb $0xff, %ah + jz setalias + + testb $VIDEO_RECALC>>8, %ah + jnz _setrec + + cmpb $VIDEO_FIRST_RESOLUTION>>8, %ah + jnc setres + + cmpb $VIDEO_FIRST_SPECIAL>>8, %ah + jz setspc + + cmpb $VIDEO_FIRST_V7>>8, %ah + jz setv7 + + cmpb $VIDEO_FIRST_VESA>>8, %ah + jnc check_vesa + + orb %ah, %ah + jz setmenu + + decb %ah + jz setbios + +setbad: clc + movb $0, do_restore # The screen needn't be restored + ret + +setvesa: + DO_STORE + subb $VIDEO_FIRST_VESA>>8, %bh + movw $0x4f02, %ax # VESA BIOS mode set call + int $0x10 + cmpw $0x004f, %ax # AL=4f if implemented + jnz setbad # AH=0 if OK + + stc + ret + +setbios: + DO_STORE + int $0x10 # Standard BIOS mode set call + pushw %bx + movb $0x0f, %ah # Check if really set + int $0x10 + popw %bx + cmpb %bl, %al + jnz setbad + + stc + ret + +setspc: xorb %bh, %bh # Set special mode + cmpb $VIDEO_LAST_SPECIAL-VIDEO_FIRST_SPECIAL, %bl + jnc setbad + + addw %bx, %bx + jmp *spec_inits(%bx) + +setmenu: + orb %al, %al # 80x25 is an exception + jz _set_80x25 + + pushw %bx # Set mode chosen from menu + call mode_table # Build the mode table + popw %ax + shlw $2, %ax + addw %ax, %si + cmpw %di, %si + jnc setbad + + movw (%si), %ax # Fetch mode ID +_m_s: jmp mode_set + +setres: pushw %bx # Set mode chosen by resolution + call mode_table + popw %bx + xchgb %bl, %bh +setr1: lodsw + cmpw $ASK_VGA, %ax # End of the list? + jz setbad + + lodsw + cmpw %bx, %ax + jnz setr1 + + movw -4(%si), %ax # Fetch mode ID + jmp _m_s + +check_vesa: +#ifdef CONFIG_FIRMWARE_EDID + leaw modelist+1024, %di + movw $0x4f00, %ax + int $0x10 + cmpw $0x004f, %ax + jnz setbad + + movw 4(%di), %ax + movw %ax, vbe_version +#endif + leaw modelist+1024, %di + subb $VIDEO_FIRST_VESA>>8, %bh + movw %bx, %cx # Get mode information structure + movw $0x4f01, %ax + int $0x10 + addb $VIDEO_FIRST_VESA>>8, %bh + cmpw $0x004f, %ax + jnz setbad + + movb (%di), %al # Check capabilities. + andb $0x19, %al + cmpb $0x09, %al + jz setvesa # This is a text mode + + movb (%di), %al # Check capabilities. + andb $0x99, %al + cmpb $0x99, %al + jnz _setbad # Doh! No linear frame buffer. + + subb $VIDEO_FIRST_VESA>>8, %bh + orw $0x4000, %bx # Use linear frame buffer + movw $0x4f02, %ax # VESA BIOS mode set call + int $0x10 + cmpw $0x004f, %ax # AL=4f if implemented + jnz _setbad # AH=0 if OK + + movb $1, graphic_mode # flag graphic mode + movb $0, do_restore # no screen restore + stc + ret + +_setbad: jmp setbad # Ugly... + +# Recalculate vertical display end registers -- this fixes various +# inconsistencies of extended modes on many adapters. Called when +# the VIDEO_RECALC flag is set in the mode ID. + +setrec: subb $VIDEO_RECALC>>8, %ah # Set the base mode + call mode_set + jnc rct3 + + movw %gs:(0x485), %ax # Font size in pixels + movb %gs:(0x484), %bl # Number of rows + incb %bl + mulb %bl # Number of visible + decw %ax # scan lines - 1 + movw $0x3d4, %dx + movw %ax, %bx + movb $0x12, %al # Lower 8 bits + movb %bl, %ah + outw %ax, %dx + movb $0x07, %al # Bits 8 and 9 in the overflow register + call inidx + xchgb %al, %ah + andb $0xbd, %ah + shrb %bh + jnc rct1 + orb $0x02, %ah +rct1: shrb %bh + jnc rct2 + orb $0x40, %ah +rct2: movb $0x07, %al + outw %ax, %dx + stc +rct3: ret + +# Table of routines for setting of the special modes. +spec_inits: + .word set_80x25 + .word set_8pixel + .word set_80x43 + .word set_80x28 + .word set_current + .word set_80x30 + .word set_80x34 + .word set_80x60 + .word set_gfx + +# Set the 80x25 mode. If already set, do nothing. +set_80x25: + movw $0x5019, force_size # Override possibly broken BIOS +use_80x25: +#ifdef CONFIG_VIDEO_400_HACK + movw $0x1202, %ax # Force 400 scan lines + movb $0x30, %bl + int $0x10 +#else + movb $0x0f, %ah # Get current mode ID + int $0x10 + cmpw $0x5007, %ax # Mode 7 (80x25 mono) is the only one available + jz st80 # on CGA/MDA/HGA and is also available on EGAM + + cmpw $0x5003, %ax # Unknown mode, force 80x25 color + jnz force3 + +st80: cmpb $0, adapter # CGA/MDA/HGA => mode 3/7 is always 80x25 + jz set80 + + movb %gs:(0x0484), %al # This is EGA+ -- beware of 80x50 etc. + orb %al, %al # Some buggy BIOS'es set 0 rows + jz set80 + + cmpb $24, %al # It's hopefully correct + jz set80 +#endif /* CONFIG_VIDEO_400_HACK */ +force3: DO_STORE + movw $0x0003, %ax # Forced set + int $0x10 +set80: stc + ret + +# Set the 80x50/80x43 8-pixel mode. Simple BIOS calls. +set_8pixel: + DO_STORE + call use_80x25 # The base is 80x25 +set_8pt: + movw $0x1112, %ax # Use 8x8 font + xorb %bl, %bl + int $0x10 + movw $0x1200, %ax # Use alternate print screen + movb $0x20, %bl + int $0x10 + movw $0x1201, %ax # Turn off cursor emulation + movb $0x34, %bl + int $0x10 + movb $0x01, %ah # Define cursor scan lines 6-7 + movw $0x0607, %cx + int $0x10 +set_current: + stc + ret + +# Set the 80x28 mode. This mode works on all VGA's, because it's a standard +# 80x25 mode with 14-point fonts instead of 16-point. +set_80x28: + DO_STORE + call use_80x25 # The base is 80x25 +set14: movw $0x1111, %ax # Use 9x14 font + xorb %bl, %bl + int $0x10 + movb $0x01, %ah # Define cursor scan lines 11-12 + movw $0x0b0c, %cx + int $0x10 + stc + ret + +# Set the 80x43 mode. This mode is works on all VGA's. +# It's a 350-scanline mode with 8-pixel font. +set_80x43: + DO_STORE + movw $0x1201, %ax # Set 350 scans + movb $0x30, %bl + int $0x10 + movw $0x0003, %ax # Reset video mode + int $0x10 + jmp set_8pt # Use 8-pixel font + +# Set the 80x30 mode (all VGA's). 480 scanlines, 16-pixel font. +set_80x30: + call use_80x25 # Start with real 80x25 + DO_STORE + movw $0x3cc, %dx # Get CRTC port + inb %dx, %al + movb $0xd4, %dl + rorb %al # Mono or color? + jc set48a + + movb $0xb4, %dl +set48a: movw $0x0c11, %ax # Vertical sync end (also unlocks CR0-7) + call outidx + movw $0x0b06, %ax # Vertical total + call outidx + movw $0x3e07, %ax # (Vertical) overflow + call outidx + movw $0xea10, %ax # Vertical sync start + call outidx + movw $0xdf12, %ax # Vertical display end + call outidx + movw $0xe715, %ax # Vertical blank start + call outidx + movw $0x0416, %ax # Vertical blank end + call outidx + pushw %dx + movb $0xcc, %dl # Misc output register (read) + inb %dx, %al + movb $0xc2, %dl # (write) + andb $0x0d, %al # Preserve clock select bits and color bit + orb $0xe2, %al # Set correct sync polarity + outb %al, %dx + popw %dx + movw $0x501e, force_size + stc # That's all. + ret + +# Set the 80x34 mode (all VGA's). 480 scans, 14-pixel font. +set_80x34: + call set_80x30 # Set 480 scans + call set14 # And 14-pt font + movw $0xdb12, %ax # VGA vertical display end + movw $0x5022, force_size +setvde: call outidx + stc + ret + +# Set the 80x60 mode (all VGA's). 480 scans, 8-pixel font. +set_80x60: + call set_80x30 # Set 480 scans + call set_8pt # And 8-pt font + movw $0xdf12, %ax # VGA vertical display end + movw $0x503c, force_size + jmp setvde + +# Special hack for ThinkPad graphics +set_gfx: +#ifdef CONFIG_VIDEO_GFX_HACK + movw $VIDEO_GFX_BIOS_AX, %ax + movw $VIDEO_GFX_BIOS_BX, %bx + int $0x10 + movw $VIDEO_GFX_DUMMY_RESOLUTION, force_size + stc +#endif + ret + +#ifdef CONFIG_VIDEO_RETAIN + +# Store screen contents to temporary buffer. +store_screen: + cmpb $0, do_restore # Already stored? + jnz stsr + + testb $CAN_USE_HEAP, loadflags # Have we space for storing? + jz stsr + + pushw %ax + pushw %bx + pushw force_size # Don't force specific size + movw $0, force_size + call mode_params # Obtain params of current mode + popw force_size + movb %fs:(PARAM_VIDEO_LINES), %ah + movb %fs:(PARAM_VIDEO_COLS), %al + movw %ax, %bx # BX=dimensions + mulb %ah + movw %ax, %cx # CX=number of characters + addw %ax, %ax # Calculate image size + addw $modelist+1024+4, %ax + cmpw heap_end_ptr, %ax + jnc sts1 # Unfortunately, out of memory + + movw %fs:(PARAM_CURSOR_POS), %ax # Store mode params + leaw modelist+1024, %di + stosw + movw %bx, %ax + stosw + pushw %ds # Store the screen + movw video_segment, %ds + xorw %si, %si + rep + movsw + popw %ds + incb do_restore # Screen will be restored later +sts1: popw %bx + popw %ax +stsr: ret + +# Restore screen contents from temporary buffer. +restore_screen: + cmpb $0, do_restore # Has the screen been stored? + jz res1 + + call mode_params # Get parameters of current mode + movb %fs:(PARAM_VIDEO_LINES), %cl + movb %fs:(PARAM_VIDEO_COLS), %ch + leaw modelist+1024, %si # Screen buffer + lodsw # Set cursor position + movw %ax, %dx + cmpb %cl, %dh + jc res2 + + movb %cl, %dh + decb %dh +res2: cmpb %ch, %dl + jc res3 + + movb %ch, %dl + decb %dl +res3: movb $0x02, %ah + movb $0x00, %bh + int $0x10 + lodsw # Display size + movb %ah, %dl # DL=number of lines + movb $0, %ah # BX=phys. length of orig. line + movw %ax, %bx + cmpb %cl, %dl # Too many? + jc res4 + + pushw %ax + movb %dl, %al + subb %cl, %al + mulb %bl + addw %ax, %si + addw %ax, %si + popw %ax + movb %cl, %dl +res4: cmpb %ch, %al # Too wide? + jc res5 + + movb %ch, %al # AX=width of src. line +res5: movb $0, %cl + xchgb %ch, %cl + movw %cx, %bp # BP=width of dest. line + pushw %es + movw video_segment, %es + xorw %di, %di # Move the data + addw %bx, %bx # Convert BX and BP to _bytes_ + addw %bp, %bp +res6: pushw %si + pushw %di + movw %ax, %cx + rep + movsw + popw %di + popw %si + addw %bp, %di + addw %bx, %si + decb %dl + jnz res6 + + popw %es # Done +res1: ret +#endif /* CONFIG_VIDEO_RETAIN */ + +# Write to indexed VGA register (AL=index, AH=data, DX=index reg. port) +outidx: outb %al, %dx + pushw %ax + movb %ah, %al + incw %dx + outb %al, %dx + decw %dx + popw %ax + ret + +# Build the table of video modes (stored after the setup.S code at the +# `modelist' label. Each video mode record looks like: +# .word MODE-ID (our special mode ID (see above)) +# .byte rows (number of rows) +# .byte columns (number of columns) +# Returns address of the end of the table in DI, the end is marked +# with a ASK_VGA ID. +mode_table: + movw mt_end, %di # Already filled? + orw %di, %di + jnz mtab1x + + leaw modelist, %di # Store standard modes: + movl $VIDEO_80x25 + 0x50190000, %eax # The 80x25 mode (ALL) + stosl + movb adapter, %al # CGA/MDA/HGA -- no more modes + orb %al, %al + jz mtabe + + decb %al + jnz mtabv + + movl $VIDEO_8POINT + 0x502b0000, %eax # The 80x43 EGA mode + stosl + jmp mtabe + +mtab1x: jmp mtab1 + +mtabv: leaw vga_modes, %si # All modes for std VGA + movw $vga_modes_end-vga_modes, %cx + rep # I'm unable to use movsw as I don't know how to store a half + movsb # of the expression above to cx without using explicit shr. + + cmpb $0, scanning # Mode scan requested? + jz mscan1 + + call mode_scan +mscan1: + +#ifdef CONFIG_VIDEO_LOCAL + call local_modes +#endif /* CONFIG_VIDEO_LOCAL */ + +#ifdef CONFIG_VIDEO_VESA + call vesa_modes # Detect VESA VGA modes +#endif /* CONFIG_VIDEO_VESA */ + +#ifdef CONFIG_VIDEO_SVGA + cmpb $0, scanning # Bypass when scanning + jnz mscan2 + + call svga_modes # Detect SVGA cards & modes +mscan2: +#endif /* CONFIG_VIDEO_SVGA */ + +mtabe: + +#ifdef CONFIG_VIDEO_COMPACT + leaw modelist, %si + movw %di, %dx + movw %si, %di +cmt1: cmpw %dx, %si # Scan all modes + jz cmt2 + + leaw modelist, %bx # Find in previous entries + movw 2(%si), %cx +cmt3: cmpw %bx, %si + jz cmt4 + + cmpw 2(%bx), %cx # Found => don't copy this entry + jz cmt5 + + addw $4, %bx + jmp cmt3 + +cmt4: movsl # Copy entry + jmp cmt1 + +cmt5: addw $4, %si # Skip entry + jmp cmt1 + +cmt2: +#endif /* CONFIG_VIDEO_COMPACT */ + + movw $ASK_VGA, (%di) # End marker + movw %di, mt_end +mtab1: leaw modelist, %si # SI=mode list, DI=list end +ret0: ret + +# Modes usable on all standard VGAs +vga_modes: + .word VIDEO_8POINT + .word 0x5032 # 80x50 + .word VIDEO_80x43 + .word 0x502b # 80x43 + .word VIDEO_80x28 + .word 0x501c # 80x28 + .word VIDEO_80x30 + .word 0x501e # 80x30 + .word VIDEO_80x34 + .word 0x5022 # 80x34 + .word VIDEO_80x60 + .word 0x503c # 80x60 +#ifdef CONFIG_VIDEO_GFX_HACK + .word VIDEO_GFX_HACK + .word VIDEO_GFX_DUMMY_RESOLUTION +#endif + +vga_modes_end: +# Detect VESA modes. + +#ifdef CONFIG_VIDEO_VESA +vesa_modes: + cmpb $2, adapter # VGA only + jnz ret0 + + movw %di, %bp # BP=original mode table end + addw $0x200, %di # Buffer space + movw $0x4f00, %ax # VESA Get card info call + int $0x10 + movw %bp, %di + cmpw $0x004f, %ax # Successful? + jnz ret0 + + cmpw $0x4556, 0x200(%di) + jnz ret0 + + cmpw $0x4153, 0x202(%di) + jnz ret0 + + movw $vesa_name, card_name # Set name to "VESA VGA" + pushw %gs + lgsw 0x20e(%di), %si # GS:SI=mode list + movw $128, %cx # Iteration limit +vesa1: +# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst. +# XXX: lodsw %gs:(%si), %ax # Get next mode in the list + gs; lodsw + cmpw $0xffff, %ax # End of the table? + jz vesar + + cmpw $0x0080, %ax # Check validity of mode ID + jc vesa2 + + orb %ah, %ah # Valid IDs: 0x0000-0x007f/0x0100-0x07ff + jz vesan # Certain BIOSes report 0x80-0xff! + + cmpw $0x0800, %ax + jnc vesae + +vesa2: pushw %cx + movw %ax, %cx # Get mode information structure + movw $0x4f01, %ax + int $0x10 + movw %cx, %bx # BX=mode number + addb $VIDEO_FIRST_VESA>>8, %bh + popw %cx + cmpw $0x004f, %ax + jnz vesan # Don't report errors (buggy BIOSES) + + movb (%di), %al # Check capabilities. We require + andb $0x19, %al # a color text mode. + cmpb $0x09, %al + jnz vesan + + cmpw $0xb800, 8(%di) # Standard video memory address required + jnz vesan + + testb $2, (%di) # Mode characteristics supplied? + movw %bx, (%di) # Store mode number + jz vesa3 + + xorw %dx, %dx + movw 0x12(%di), %bx # Width + orb %bh, %bh + jnz vesan + + movb %bl, 0x3(%di) + movw 0x14(%di), %ax # Height + orb %ah, %ah + jnz vesan + + movb %al, 2(%di) + mulb %bl + cmpw $8193, %ax # Small enough for Linux console driver? + jnc vesan + + jmp vesaok + +vesa3: subw $0x8108, %bx # This mode has no detailed info specified, + jc vesan # so it must be a standard VESA mode. + + cmpw $5, %bx + jnc vesan + + movw vesa_text_mode_table(%bx), %ax + movw %ax, 2(%di) +vesaok: addw $4, %di # The mode is valid. Store it. +vesan: loop vesa1 # Next mode. Limit exceeded => error +vesae: leaw vesaer, %si + call prtstr + movw %bp, %di # Discard already found modes. +vesar: popw %gs + ret + +# Dimensions of standard VESA text modes +vesa_text_mode_table: + .byte 60, 80 # 0108 + .byte 25, 132 # 0109 + .byte 43, 132 # 010A + .byte 50, 132 # 010B + .byte 60, 132 # 010C +#endif /* CONFIG_VIDEO_VESA */ + +# Scan for video modes. A bit dirty, but should work. +mode_scan: + movw $0x0100, %cx # Start with mode 0 +scm1: movb $0, %ah # Test the mode + movb %cl, %al + int $0x10 + movb $0x0f, %ah + int $0x10 + cmpb %cl, %al + jnz scm2 # Mode not set + + movw $0x3c0, %dx # Test if it's a text mode + movb $0x10, %al # Mode bits + call inidx + andb $0x03, %al + jnz scm2 + + movb $0xce, %dl # Another set of mode bits + movb $0x06, %al + call inidx + shrb %al + jc scm2 + + movb $0xd4, %dl # Cursor location + movb $0x0f, %al + call inidx + orb %al, %al + jnz scm2 + + movw %cx, %ax # Ok, store the mode + stosw + movb %gs:(0x484), %al # Number of rows + incb %al + stosb + movw %gs:(0x44a), %ax # Number of columns + stosb +scm2: incb %cl + jns scm1 + + movw $0x0003, %ax # Return back to mode 3 + int $0x10 + ret + +tstidx: outw %ax, %dx # OUT DX,AX and inidx +inidx: outb %al, %dx # Read from indexed VGA register + incw %dx # AL=index, DX=index reg port -> AL=data + inb %dx, %al + decw %dx + ret + +# Try to detect type of SVGA card and supply (usually approximate) video +# mode table for it. + +#ifdef CONFIG_VIDEO_SVGA +svga_modes: + leaw svga_table, %si # Test all known SVGA adapters +dosvga: lodsw + movw %ax, %bp # Default mode table + orw %ax, %ax + jz didsv1 + + lodsw # Pointer to test routine + pushw %si + pushw %di + pushw %es + movw $0xc000, %bx + movw %bx, %es + call *%ax # Call test routine + popw %es + popw %di + popw %si + orw %bp, %bp + jz dosvga + + movw %bp, %si # Found, copy the modes + movb svga_prefix, %ah +cpsvga: lodsb + orb %al, %al + jz didsv + + stosw + movsw + jmp cpsvga + +didsv: movw %si, card_name # Store pointer to card name +didsv1: ret + +# Table of all known SVGA cards. For each card, we store a pointer to +# a table of video modes supported by the card and a pointer to a routine +# used for testing of presence of the card. The video mode table is always +# followed by the name of the card or the chipset. +svga_table: + .word ati_md, ati_test + .word oak_md, oak_test + .word paradise_md, paradise_test + .word realtek_md, realtek_test + .word s3_md, s3_test + .word chips_md, chips_test + .word video7_md, video7_test + .word cirrus5_md, cirrus5_test + .word cirrus6_md, cirrus6_test + .word cirrus1_md, cirrus1_test + .word ahead_md, ahead_test + .word everex_md, everex_test + .word genoa_md, genoa_test + .word trident_md, trident_test + .word tseng_md, tseng_test + .word 0 + +# Test routines and mode tables: + +# S3 - The test algorithm was taken from the SuperProbe package +# for XFree86 1.2.1. Report bugs to Christoph.Niemann@linux.org +s3_test: + movw $0x0f35, %cx # we store some constants in cl/ch + movw $0x03d4, %dx + movb $0x38, %al + call inidx + movb %al, %bh # store current CRT-register 0x38 + movw $0x0038, %ax + call outidx # disable writing to special regs + movb %cl, %al # check whether we can write special reg 0x35 + call inidx + movb %al, %bl # save the current value of CRT reg 0x35 + andb $0xf0, %al # clear bits 0-3 + movb %al, %ah + movb %cl, %al # and write it to CRT reg 0x35 + call outidx + call inidx # now read it back + andb %ch, %al # clear the upper 4 bits + jz s3_2 # the first test failed. But we have a + + movb %bl, %ah # second chance + movb %cl, %al + call outidx + jmp s3_1 # do the other tests + +s3_2: movw %cx, %ax # load ah with 0xf and al with 0x35 + orb %bl, %ah # set the upper 4 bits of ah with the orig value + call outidx # write ... + call inidx # ... and reread + andb %cl, %al # turn off the upper 4 bits + pushw %ax + movb %bl, %ah # restore old value in register 0x35 + movb %cl, %al + call outidx + popw %ax + cmpb %ch, %al # setting lower 4 bits was successful => bad + je no_s3 # writing is allowed => this is not an S3 + +s3_1: movw $0x4838, %ax # allow writing to special regs by putting + call outidx # magic number into CRT-register 0x38 + movb %cl, %al # check whether we can write special reg 0x35 + call inidx + movb %al, %bl + andb $0xf0, %al + movb %al, %ah + movb %cl, %al + call outidx + call inidx + andb %ch, %al + jnz no_s3 # no, we can't write => no S3 + + movw %cx, %ax + orb %bl, %ah + call outidx + call inidx + andb %ch, %al + pushw %ax + movb %bl, %ah # restore old value in register 0x35 + movb %cl, %al + call outidx + popw %ax + cmpb %ch, %al + jne no_s31 # writing not possible => no S3 + movb $0x30, %al + call inidx # now get the S3 id ... + leaw idS3, %di + movw $0x10, %cx + repne + scasb + je no_s31 + + movb %bh, %ah + movb $0x38, %al + jmp s3rest + +no_s3: movb $0x35, %al # restore CRT register 0x35 + movb %bl, %ah + call outidx +no_s31: xorw %bp, %bp # Detection failed +s3rest: movb %bh, %ah + movb $0x38, %al # restore old value of CRT register 0x38 + jmp outidx + +idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95 + .byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0 + +s3_md: .byte 0x54, 0x2b, 0x84 + .byte 0x55, 0x19, 0x84 + .byte 0 + .ascii "S3" + .byte 0 + +# ATI cards. +ati_test: + leaw idati, %si + movw $0x31, %di + movw $0x09, %cx + repe + cmpsb + je atiok + + xorw %bp, %bp +atiok: ret + +idati: .ascii "761295520" + +ati_md: .byte 0x23, 0x19, 0x84 + .byte 0x33, 0x2c, 0x84 + .byte 0x22, 0x1e, 0x64 + .byte 0x21, 0x19, 0x64 + .byte 0x58, 0x21, 0x50 + .byte 0x5b, 0x1e, 0x50 + .byte 0 + .ascii "ATI" + .byte 0 + +# AHEAD +ahead_test: + movw $0x200f, %ax + movw $0x3ce, %dx + outw %ax, %dx + incw %dx + inb %dx, %al + cmpb $0x20, %al + je isahed + + cmpb $0x21, %al + je isahed + + xorw %bp, %bp +isahed: ret + +ahead_md: + .byte 0x22, 0x2c, 0x84 + .byte 0x23, 0x19, 0x84 + .byte 0x24, 0x1c, 0x84 + .byte 0x2f, 0x32, 0xa0 + .byte 0x32, 0x22, 0x50 + .byte 0x34, 0x42, 0x50 + .byte 0 + .ascii "Ahead" + .byte 0 + +# Chips & Tech. +chips_test: + movw $0x3c3, %dx + inb %dx, %al + orb $0x10, %al + outb %al, %dx + movw $0x104, %dx + inb %dx, %al + movb %al, %bl + movw $0x3c3, %dx + inb %dx, %al + andb $0xef, %al + outb %al, %dx + cmpb $0xa5, %bl + je cantok + + xorw %bp, %bp +cantok: ret + +chips_md: + .byte 0x60, 0x19, 0x84 + .byte 0x61, 0x32, 0x84 + .byte 0 + .ascii "Chips & Technologies" + .byte 0 + +# Cirrus Logic 5X0 +cirrus1_test: + movw $0x3d4, %dx + movb $0x0c, %al + outb %al, %dx + incw %dx + inb %dx, %al + movb %al, %bl + xorb %al, %al + outb %al, %dx + decw %dx + movb $0x1f, %al + outb %al, %dx + incw %dx + inb %dx, %al + movb %al, %bh + xorb %ah, %ah + shlb $4, %al + movw %ax, %cx + movb %bh, %al + shrb $4, %al + addw %ax, %cx + shlw $8, %cx + addw $6, %cx + movw %cx, %ax + movw $0x3c4, %dx + outw %ax, %dx + incw %dx + inb %dx, %al + andb %al, %al + jnz nocirr + + movb %bh, %al + outb %al, %dx + inb %dx, %al + cmpb $0x01, %al + je iscirr + +nocirr: xorw %bp, %bp +iscirr: movw $0x3d4, %dx + movb %bl, %al + xorb %ah, %ah + shlw $8, %ax + addw $0x0c, %ax + outw %ax, %dx + ret + +cirrus1_md: + .byte 0x1f, 0x19, 0x84 + .byte 0x20, 0x2c, 0x84 + .byte 0x22, 0x1e, 0x84 + .byte 0x31, 0x25, 0x64 + .byte 0 + .ascii "Cirrus Logic 5X0" + .byte 0 + +# Cirrus Logic 54XX +cirrus5_test: + movw $0x3c4, %dx + movb $6, %al + call inidx + movb %al, %bl # BL=backup + movw $6, %ax + call tstidx + cmpb $0x0f, %al + jne c5fail + + movw $0x1206, %ax + call tstidx + cmpb $0x12, %al + jne c5fail + + movb $0x1e, %al + call inidx + movb %al, %bh + movb %bh, %ah + andb $0xc0, %ah + movb $0x1e, %al + call tstidx + andb $0x3f, %al + jne c5xx + + movb $0x1e, %al + movb %bh, %ah + orb $0x3f, %ah + call tstidx + xorb $0x3f, %al + andb $0x3f, %al +c5xx: pushf + movb $0x1e, %al + movb %bh, %ah + outw %ax, %dx + popf + je c5done + +c5fail: xorw %bp, %bp +c5done: movb $6, %al + movb %bl, %ah + outw %ax, %dx + ret + +cirrus5_md: + .byte 0x14, 0x19, 0x84 + .byte 0x54, 0x2b, 0x84 + .byte 0 + .ascii "Cirrus Logic 54XX" + .byte 0 + +# Cirrus Logic 64XX -- no known extra modes, but must be identified, because +# it's misidentified by the Ahead test. +cirrus6_test: + movw $0x3ce, %dx + movb $0x0a, %al + call inidx + movb %al, %bl # BL=backup + movw $0xce0a, %ax + call tstidx + orb %al, %al + jne c2fail + + movw $0xec0a, %ax + call tstidx + cmpb $0x01, %al + jne c2fail + + movb $0xaa, %al + call inidx # 4X, 5X, 7X and 8X are valid 64XX chip ID's. + shrb $4, %al + subb $4, %al + jz c6done + + decb %al + jz c6done + + subb $2, %al + jz c6done + + decb %al + jz c6done + +c2fail: xorw %bp, %bp +c6done: movb $0x0a, %al + movb %bl, %ah + outw %ax, %dx + ret + +cirrus6_md: + .byte 0 + .ascii "Cirrus Logic 64XX" + .byte 0 + +# Everex / Trident +everex_test: + movw $0x7000, %ax + xorw %bx, %bx + int $0x10 + cmpb $0x70, %al + jne noevrx + + shrw $4, %dx + cmpw $0x678, %dx + je evtrid + + cmpw $0x236, %dx + jne evrxok + +evtrid: leaw trident_md, %bp +evrxok: ret + +noevrx: xorw %bp, %bp + ret + +everex_md: + .byte 0x03, 0x22, 0x50 + .byte 0x04, 0x3c, 0x50 + .byte 0x07, 0x2b, 0x64 + .byte 0x08, 0x4b, 0x64 + .byte 0x0a, 0x19, 0x84 + .byte 0x0b, 0x2c, 0x84 + .byte 0x16, 0x1e, 0x50 + .byte 0x18, 0x1b, 0x64 + .byte 0x21, 0x40, 0xa0 + .byte 0x40, 0x1e, 0x84 + .byte 0 + .ascii "Everex/Trident" + .byte 0 + +# Genoa. +genoa_test: + leaw idgenoa, %si # Check Genoa 'clues' + xorw %ax, %ax + movb %es:(0x37), %al + movw %ax, %di + movw $0x04, %cx + decw %si + decw %di +l1: incw %si + incw %di + movb (%si), %al + testb %al, %al + jz l2 + + cmpb %es:(%di), %al +l2: loope l1 + orw %cx, %cx + je isgen + + xorw %bp, %bp +isgen: ret + +idgenoa: .byte 0x77, 0x00, 0x99, 0x66 + +genoa_md: + .byte 0x58, 0x20, 0x50 + .byte 0x5a, 0x2a, 0x64 + .byte 0x60, 0x19, 0x84 + .byte 0x61, 0x1d, 0x84 + .byte 0x62, 0x20, 0x84 + .byte 0x63, 0x2c, 0x84 + .byte 0x64, 0x3c, 0x84 + .byte 0x6b, 0x4f, 0x64 + .byte 0x72, 0x3c, 0x50 + .byte 0x74, 0x42, 0x50 + .byte 0x78, 0x4b, 0x64 + .byte 0 + .ascii "Genoa" + .byte 0 + +# OAK +oak_test: + leaw idoakvga, %si + movw $0x08, %di + movw $0x08, %cx + repe + cmpsb + je isoak + + xorw %bp, %bp +isoak: ret + +idoakvga: .ascii "OAK VGA " + +oak_md: .byte 0x4e, 0x3c, 0x50 + .byte 0x4f, 0x3c, 0x84 + .byte 0x50, 0x19, 0x84 + .byte 0x51, 0x2b, 0x84 + .byte 0 + .ascii "OAK" + .byte 0 + +# WD Paradise. +paradise_test: + leaw idparadise, %si + movw $0x7d, %di + movw $0x04, %cx + repe + cmpsb + je ispara + + xorw %bp, %bp +ispara: ret + +idparadise: .ascii "VGA=" + +paradise_md: + .byte 0x41, 0x22, 0x50 + .byte 0x47, 0x1c, 0x84 + .byte 0x55, 0x19, 0x84 + .byte 0x54, 0x2c, 0x84 + .byte 0 + .ascii "Paradise" + .byte 0 + +# Trident. +trident_test: + movw $0x3c4, %dx + movb $0x0e, %al + outb %al, %dx + incw %dx + inb %dx, %al + xchgb %al, %ah + xorb %al, %al + outb %al, %dx + inb %dx, %al + xchgb %ah, %al + movb %al, %bl # Strange thing ... in the book this wasn't + andb $0x02, %bl # necessary but it worked on my card which + jz setb2 # is a trident. Without it the screen goes + # blurred ... + andb $0xfd, %al + jmp clrb2 + +setb2: orb $0x02, %al +clrb2: outb %al, %dx + andb $0x0f, %ah + cmpb $0x02, %ah + je istrid + + xorw %bp, %bp +istrid: ret + +trident_md: + .byte 0x50, 0x1e, 0x50 + .byte 0x51, 0x2b, 0x50 + .byte 0x52, 0x3c, 0x50 + .byte 0x57, 0x19, 0x84 + .byte 0x58, 0x1e, 0x84 + .byte 0x59, 0x2b, 0x84 + .byte 0x5a, 0x3c, 0x84 + .byte 0 + .ascii "Trident" + .byte 0 + +# Tseng. +tseng_test: + movw $0x3cd, %dx + inb %dx, %al # Could things be this simple ! :-) + movb %al, %bl + movb $0x55, %al + outb %al, %dx + inb %dx, %al + movb %al, %ah + movb %bl, %al + outb %al, %dx + cmpb $0x55, %ah + je istsen + +isnot: xorw %bp, %bp +istsen: ret + +tseng_md: + .byte 0x26, 0x3c, 0x50 + .byte 0x2a, 0x28, 0x64 + .byte 0x23, 0x19, 0x84 + .byte 0x24, 0x1c, 0x84 + .byte 0x22, 0x2c, 0x84 + .byte 0x21, 0x3c, 0x84 + .byte 0 + .ascii "Tseng" + .byte 0 + +# Video7. +video7_test: + movw $0x3cc, %dx + inb %dx, %al + movw $0x3b4, %dx + andb $0x01, %al + jz even7 + + movw $0x3d4, %dx +even7: movb $0x0c, %al + outb %al, %dx + incw %dx + inb %dx, %al + movb %al, %bl + movb $0x55, %al + outb %al, %dx + inb %dx, %al + decw %dx + movb $0x1f, %al + outb %al, %dx + incw %dx + inb %dx, %al + movb %al, %bh + decw %dx + movb $0x0c, %al + outb %al, %dx + incw %dx + movb %bl, %al + outb %al, %dx + movb $0x55, %al + xorb $0xea, %al + cmpb %bh, %al + jne isnot + + movb $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching + ret + +video7_md: + .byte 0x40, 0x2b, 0x50 + .byte 0x43, 0x3c, 0x50 + .byte 0x44, 0x3c, 0x64 + .byte 0x41, 0x19, 0x84 + .byte 0x42, 0x2c, 0x84 + .byte 0x45, 0x1c, 0x84 + .byte 0 + .ascii "Video 7" + .byte 0 + +# Realtek VGA +realtek_test: + leaw idrtvga, %si + movw $0x45, %di + movw $0x0b, %cx + repe + cmpsb + je isrt + + xorw %bp, %bp +isrt: ret + +idrtvga: .ascii "REALTEK VGA" + +realtek_md: + .byte 0x1a, 0x3c, 0x50 + .byte 0x1b, 0x19, 0x84 + .byte 0x1c, 0x1e, 0x84 + .byte 0x1d, 0x2b, 0x84 + .byte 0x1e, 0x3c, 0x84 + .byte 0 + .ascii "REALTEK" + .byte 0 + +#endif /* CONFIG_VIDEO_SVGA */ + +# User-defined local mode table (VGA only) +#ifdef CONFIG_VIDEO_LOCAL +local_modes: + leaw local_mode_table, %si +locm1: lodsw + orw %ax, %ax + jz locm2 + + stosw + movsw + jmp locm1 + +locm2: ret + +# This is the table of local video modes which can be supplied manually +# by the user. Each entry consists of mode ID (word) and dimensions +# (byte for column count and another byte for row count). These modes +# are placed before all SVGA and VESA modes and override them if table +# compacting is enabled. The table must end with a zero word followed +# by NUL-terminated video adapter name. +local_mode_table: + .word 0x0100 # Example: 40x25 + .byte 25,40 + .word 0 + .ascii "Local" + .byte 0 +#endif /* CONFIG_VIDEO_LOCAL */ + +# Read a key and return the ASCII code in al, scan code in ah +getkey: xorb %ah, %ah + int $0x16 + ret + +# Read a key with a timeout of 30 seconds. +# The hardware clock is used to get the time. +getkt: call gettime + addb $30, %al # Wait 30 seconds + cmpb $60, %al + jl lminute + + subb $60, %al +lminute: + movb %al, %cl +again: movb $0x01, %ah + int $0x16 + jnz getkey # key pressed, so get it + + call gettime + cmpb %cl, %al + jne again + + movb $0x20, %al # timeout, return `space' + ret + +# Flush the keyboard buffer +flush: movb $0x01, %ah + int $0x16 + jz empty + + xorb %ah, %ah + int $0x16 + jmp flush + +empty: ret + +# Print hexadecimal number. +prthw: pushw %ax + movb %ah, %al + call prthb + popw %ax +prthb: pushw %ax + shrb $4, %al + call prthn + popw %ax + andb $0x0f, %al +prthn: cmpb $0x0a, %al + jc prth1 + + addb $0x07, %al +prth1: addb $0x30, %al + jmp prtchr + +# Print decimal number in al +prtdec: pushw %ax + pushw %cx + xorb %ah, %ah + movb $0x0a, %cl + idivb %cl + cmpb $0x09, %al + jbe lt100 + + call prtdec + jmp skip10 + +lt100: addb $0x30, %al + call prtchr +skip10: movb %ah, %al + addb $0x30, %al + call prtchr + popw %cx + popw %ax + ret + +store_edid: +#ifdef CONFIG_FIRMWARE_EDID + pushw %es # just save all registers + pushw %ax + pushw %bx + pushw %cx + pushw %dx + pushw %di + + pushw %fs + popw %es + + movl $0x13131313, %eax # memset block with 0x13 + movw $32, %cx + movw $0x140, %di + cld + rep + stosl + + cmpw $0x0200, vbe_version # only do EDID on >= VBE2.0 + jl no_edid + + pushw %es # save ES + xorw %di, %di # Report Capability + pushw %di + popw %es # ES:DI must be 0:0 + movw $0x4f15, %ax + xorw %bx, %bx + xorw %cx, %cx + int $0x10 + popw %es # restore ES + + cmpb $0x00, %ah # call successful + jne no_edid + + cmpb $0x4f, %al # function supported + jne no_edid + + movw $0x4f15, %ax # do VBE/DDC + movw $0x01, %bx + movw $0x00, %cx + movw $0x01, %dx + movw $0x140, %di + int $0x10 + +no_edid: + popw %di # restore all registers + popw %dx + popw %cx + popw %bx + popw %ax + popw %es +#endif + ret + +# VIDEO_SELECT-only variables +mt_end: .word 0 # End of video mode table if built +edit_buf: .space 6 # Line editor buffer +card_name: .word 0 # Pointer to adapter name +scanning: .byte 0 # Performing mode scan +do_restore: .byte 0 # Screen contents altered during mode change +svga_prefix: .byte VIDEO_FIRST_BIOS>>8 # Default prefix for BIOS modes +graphic_mode: .byte 0 # Graphic mode with a linear frame buffer +dac_size: .byte 6 # DAC bit depth +vbe_version: .word 0 # VBE bios version + +# Status messages +keymsg: .ascii "Press to see video modes available, " + .ascii " to continue or wait 30 secs" + .byte 0x0d, 0x0a, 0 + +listhdr: .byte 0x0d, 0x0a + .ascii "Mode: COLSxROWS:" + +crlft: .byte 0x0d, 0x0a, 0 + +prompt: .byte 0x0d, 0x0a + .asciz "Enter mode number or `scan': " + +unknt: .asciz "Unknown mode ID. Try again." + +badmdt: .ascii "You passed an undefined mode number." + .byte 0x0d, 0x0a, 0 + +vesaer: .ascii "Error: Scanning of VESA modes failed. Please " + .ascii "report to ." + .byte 0x0d, 0x0a, 0 + +old_name: .asciz "CGA/MDA/HGA" + +ega_name: .asciz "EGA" + +svga_name: .ascii " " + +vga_name: .asciz "VGA" + +vesa_name: .asciz "VESA" + +name_bann: .asciz "Video adapter: " +#endif /* CONFIG_VIDEO_SELECT */ + +# Other variables: +adapter: .byte 0 # Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA +video_segment: .word 0xb800 # Video memory segment +force_size: .word 0 # Use this size instead of the one in BIOS vars diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 941a7e3aa5fb..b26378815b91 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-git3 -# Tue May 1 07:30:48 2007 +# Linux kernel version: 2.6.21-rc3 +# Wed Mar 7 15:29:47 2007 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -118,11 +118,11 @@ CONFIG_X86_PC=y # CONFIG_X86_VSMP is not set # CONFIG_MK8 is not set # CONFIG_MPSC is not set -CONFIG_MCORE2=y -# CONFIG_GENERIC_CPU is not set -CONFIG_X86_L1_CACHE_BYTES=64 -CONFIG_X86_L1_CACHE_SHIFT=6 -CONFIG_X86_INTERNODE_CACHE_BYTES=64 +# CONFIG_MCORE2 is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_INTERNODE_CACHE_BYTES=128 CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y # CONFIG_MICROCODE is not set @@ -174,7 +174,6 @@ CONFIG_X86_MCE_INTEL=y CONFIG_X86_MCE_AMD=y # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set -# CONFIG_RELOCATABLE is not set CONFIG_PHYSICAL_START=0x200000 CONFIG_SECCOMP=y # CONFIG_CC_STACKPROTECTOR is not set @@ -183,6 +182,7 @@ CONFIG_HZ_250=y # CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 +# CONFIG_REORDER is not set CONFIG_K8_NB=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y @@ -218,6 +218,7 @@ CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=y CONFIG_ACPI_NUMA=y # CONFIG_ACPI_ASUS is not set +# CONFIG_ACPI_IBM is not set # CONFIG_ACPI_TOSHIBA is not set CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set @@ -242,7 +243,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set # # CPUFreq processor drivers @@ -298,6 +299,7 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -332,7 +334,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set @@ -388,13 +389,6 @@ CONFIG_IPV6_SIT=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set # CONFIG_IEEE80211 is not set # @@ -415,6 +409,10 @@ CONFIG_FW_LOADER=y # Connector - unified userspace <-> kernelspace linker # # CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set # @@ -461,7 +459,6 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set # CONFIG_SONY_LAPTOP is not set -# CONFIG_THINKPAD_ACPI is not set # # ATA/ATAPI/MFM/RLL support @@ -497,6 +494,7 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_RZ1000 is not set CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set @@ -527,6 +525,7 @@ CONFIG_BLK_DEV_PDC202XX_NEW=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -585,9 +584,11 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set # CONFIG_SCSI_AIC94XX is not set # CONFIG_SCSI_ARCMSR is not set -# CONFIG_MEGARAID_NEWGEN is not set +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_MM=y +CONFIG_MEGARAID_MAILBOX=y # CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set +CONFIG_MEGARAID_SAS=y # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set @@ -607,7 +608,6 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set -# CONFIG_SCSI_ESP_CORE is not set # CONFIG_SCSI_SRP is not set # @@ -636,7 +636,6 @@ CONFIG_SATA_ACPI=y # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set # CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CS5520 is not set # CONFIG_PATA_CS5530 is not set @@ -688,7 +687,7 @@ CONFIG_BLK_DEV_DM=y CONFIG_FUSION=y CONFIG_FUSION_SPI=y # CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set +CONFIG_FUSION_SAS=y CONFIG_FUSION_MAX_SGE=128 # CONFIG_FUSION_CTL is not set @@ -701,22 +700,19 @@ CONFIG_IEEE1394=y # Subsystem Options # # CONFIG_IEEE1394_VERBOSEDEBUG is not set +# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set # -# Controllers -# - -# -# Texas Instruments PCILynx requires I2C +# Device Drivers # +# CONFIG_IEEE1394_PCILYNX is not set CONFIG_IEEE1394_OHCI1394=y # -# Protocols +# Protocol Drivers # # CONFIG_IEEE1394_VIDEO1394 is not set # CONFIG_IEEE1394_SBP2 is not set -# CONFIG_IEEE1394_ETH1394_ROM_ENTRY is not set # CONFIG_IEEE1394_ETH1394 is not set # CONFIG_IEEE1394_DV1394 is not set CONFIG_IEEE1394_RAWIO=y @@ -779,8 +775,7 @@ CONFIG_TULIP=y # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set -CONFIG_AMD8111_ETH=y -# CONFIG_AMD8111E_NAPI is not set +# CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set CONFIG_B44=y CONFIG_FORCEDETH=y @@ -842,10 +837,9 @@ CONFIG_S2IO=m # CONFIG_TR is not set # -# Wireless LAN +# Wireless LAN (non-hamradio) # -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set +# CONFIG_NET_RADIO is not set # # Wan interfaces @@ -859,6 +853,7 @@ CONFIG_S2IO=m # CONFIG_SHAPER is not set CONFIG_NETCONSOLE=y CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set # CONFIG_NETPOLL_TRAP is not set CONFIG_NET_POLL_CONTROLLER=y @@ -992,7 +987,57 @@ CONFIG_HPET_MMAP=y # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=m +CONFIG_I2C_CHARDEV=m + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_ISA=m +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PASEMI is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # # SPI support @@ -1008,8 +1053,54 @@ CONFIG_HPET_MMAP=y # # Hardware Monitoring support # -# CONFIG_HWMON is not set +CONFIG_HWMON=y # CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_K8TEMP is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +CONFIG_SENSORS_SMSC47B397=m +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_HWMON_DEBUG_CHIP is not set # # Multifunction device drivers @@ -1056,9 +1147,8 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -CONFIG_OBSOLETE_OSS=y +# CONFIG_OBSOLETE_OSS is not set # CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_ES1371 is not set CONFIG_SOUND_ICH=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -1072,14 +1162,6 @@ CONFIG_SOUND_ICH=y CONFIG_HID=y # CONFIG_HID_DEBUG is not set -# -# USB Input Devices -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set - # # USB support # @@ -1093,7 +1175,6 @@ CONFIG_USB=y # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DEVICE_CLASS is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set @@ -1144,6 +1225,10 @@ CONFIG_USB_STORAGE=y # # USB Input Devices # +CONFIG_USB_HID=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +# CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set @@ -1471,7 +1556,7 @@ CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set -CONFIG_TIMER_STATS=y +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set diff --git a/trunk/arch/x86_64/ia32/ia32_binfmt.c b/trunk/arch/x86_64/ia32/ia32_binfmt.c index 185399baaf6d..071100ea1251 100644 --- a/trunk/arch/x86_64/ia32/ia32_binfmt.c +++ b/trunk/arch/x86_64/ia32/ia32_binfmt.c @@ -5,11 +5,6 @@ * This tricks binfmt_elf.c into loading 32bit binaries using lots * of ugly preprocessor tricks. Talk about very very poor man's inheritance. */ -#define __ASM_X86_64_ELF_H 1 - -#undef ELF_CLASS -#define ELF_CLASS ELFCLASS32 - #include #include #include @@ -55,6 +50,9 @@ struct elf_phdr; #undef ELF_ARCH #define ELF_ARCH EM_386 +#undef ELF_CLASS +#define ELF_CLASS ELFCLASS32 + #define ELF_DATA ELFDATA2LSB #define USE_ELF_CORE_DUMP 1 @@ -138,7 +136,7 @@ struct elf_prpsinfo #define user user32 -#undef elf_read_implies_exec +#define __ASM_X86_64_ELF_H 1 #define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X) //#include #include diff --git a/trunk/arch/x86_64/ia32/ia32_signal.c b/trunk/arch/x86_64/ia32/ia32_signal.c index 6ea19c25f90d..359eacc38509 100644 --- a/trunk/arch/x86_64/ia32/ia32_signal.c +++ b/trunk/arch/x86_64/ia32/ia32_signal.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/x86_64/ia32/ia32entry.S b/trunk/arch/x86_64/ia32/ia32entry.S index f21068378272..796df6992f62 100644 --- a/trunk/arch/x86_64/ia32/ia32entry.S +++ b/trunk/arch/x86_64/ia32/ia32entry.S @@ -481,7 +481,11 @@ ia32_sys_call_table: .quad sys_symlink .quad sys_lstat .quad sys_readlink /* 85 */ +#ifdef CONFIG_IA32_AOUT .quad sys_uselib +#else + .quad quiet_ni_syscall +#endif .quad sys_swapon .quad sys_reboot .quad compat_sys_old_readdir @@ -710,10 +714,9 @@ ia32_sys_call_table: .quad compat_sys_get_robust_list .quad sys_splice .quad sys_sync_file_range - .quad sys_tee /* 315 */ + .quad sys_tee .quad compat_sys_vmsplice .quad compat_sys_move_pages .quad sys_getcpu .quad sys_epoll_pwait - .quad compat_sys_utimensat /* 320 */ ia32_syscall_end: diff --git a/trunk/arch/x86_64/ia32/syscall32.c b/trunk/arch/x86_64/ia32/syscall32.c index fc4419ff0355..568ff0df89e7 100644 --- a/trunk/arch/x86_64/ia32/syscall32.c +++ b/trunk/arch/x86_64/ia32/syscall32.c @@ -13,7 +13,6 @@ #include #include #include -#include extern unsigned char syscall32_syscall[], syscall32_syscall_end[]; extern unsigned char syscall32_sysenter[], syscall32_sysenter_end[]; diff --git a/trunk/arch/x86_64/kernel/Makefile b/trunk/arch/x86_64/kernel/Makefile index de1de8a2fd84..bb47e86f3d02 100644 --- a/trunk/arch/x86_64/kernel/Makefile +++ b/trunk/arch/x86_64/kernel/Makefile @@ -8,8 +8,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ x8664_ksyms.o i387.o syscall.o vsyscall.o \ setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ - pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o bugs.o \ - perfctr-watchdog.o + pci-dma.o pci-nommu.o alternative.o hpet.o tsc.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_X86_MCE) += mce.o therm_throt.o @@ -22,7 +21,8 @@ obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o tsc_sync.o obj-y += apic.o nmi.o -obj-y += io_apic.o mpparse.o genapic.o genapic_flat.o +obj-y += io_apic.o mpparse.o \ + genapic.o genapic_cluster.o genapic_flat.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_PM) += suspend.o @@ -32,7 +32,6 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary.o tce.o obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o -obj-$(CONFIG_SERIAL_8250) += legacy_serial.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o obj-$(CONFIG_X86_VSMP) += vsmp.o @@ -50,7 +49,6 @@ CFLAGS_vsyscall.o := $(PROFILING) -g0 therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o bootflag-y += ../../i386/kernel/bootflag.o -legacy_serial-y += ../../i386/kernel/legacy_serial.o cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o topology-y += ../../i386/kernel/topology.o microcode-$(subst m,y,$(CONFIG_MICROCODE)) += ../../i386/kernel/microcode.o @@ -60,4 +58,3 @@ i8237-y += ../../i386/kernel/i8237.o msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o alternative-y += ../../i386/kernel/alternative.o pcspeaker-y += ../../i386/kernel/pcspeaker.o -perfctr-watchdog-y += ../../i386/kernel/cpu/perfctr-watchdog.o diff --git a/trunk/arch/x86_64/kernel/acpi/sleep.c b/trunk/arch/x86_64/kernel/acpi/sleep.c index 195b7034a148..e1548fbe95ae 100644 --- a/trunk/arch/x86_64/kernel/acpi/sleep.c +++ b/trunk/arch/x86_64/kernel/acpi/sleep.c @@ -60,6 +60,19 @@ extern char wakeup_start, wakeup_end; extern unsigned long acpi_copy_wakeup_routine(unsigned long); +static pgd_t low_ptr; + +static void init_low_mapping(void) +{ + pgd_t *slot0 = pgd_offset(current->mm, 0UL); + low_ptr = *slot0; + /* FIXME: We're playing with the current task's page tables here, which + * is potentially dangerous on SMP systems. + */ + set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET)); + local_flush_tlb(); +} + /** * acpi_save_state_mem - save kernel state * @@ -68,6 +81,8 @@ extern unsigned long acpi_copy_wakeup_routine(unsigned long); */ int acpi_save_state_mem(void) { + init_low_mapping(); + memcpy((void *)acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start); acpi_copy_wakeup_routine(acpi_wakeup_address); @@ -80,6 +95,8 @@ int acpi_save_state_mem(void) */ void acpi_restore_state_mem(void) { + set_pgd(pgd_offset(current->mm, 0UL), low_ptr); + local_flush_tlb(); } /** @@ -92,11 +109,10 @@ void acpi_restore_state_mem(void) */ void __init acpi_reserve_bootmem(void) { - acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE*2); - if ((&wakeup_end - &wakeup_start) > (PAGE_SIZE*2)) + acpi_wakeup_address = (unsigned long)alloc_bootmem_low(PAGE_SIZE); + if ((&wakeup_end - &wakeup_start) > PAGE_SIZE) printk(KERN_CRIT - "ACPI: Wakeup code way too big, will crash on attempt" - " to suspend\n"); + "ACPI: Wakeup code way too big, will crash on attempt to suspend\n"); } static int __init acpi_sleep_setup(char *str) diff --git a/trunk/arch/x86_64/kernel/acpi/wakeup.S b/trunk/arch/x86_64/kernel/acpi/wakeup.S index 8550a6ffa275..185faa911db5 100644 --- a/trunk/arch/x86_64/kernel/acpi/wakeup.S +++ b/trunk/arch/x86_64/kernel/acpi/wakeup.S @@ -1,7 +1,6 @@ .text #include #include -#include #include #include @@ -31,28 +30,22 @@ wakeup_code: cld # setup data segment movw %cs, %ax - movw %ax, %ds # Make ds:0 point to wakeup_start + movw %ax, %ds # Make ds:0 point to wakeup_start movw %ax, %ss - # Private stack is needed for ASUS board - mov $(wakeup_stack - wakeup_code), %sp + mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board - pushl $0 # Kill any dangerous flags + pushl $0 # Kill any dangerous flags popfl movl real_magic - wakeup_code, %eax cmpl $0x12345678, %eax jne bogus_real_magic - call verify_cpu # Verify the cpu supports long - # mode - testl %eax, %eax - jnz no_longmode - testl $1, video_flags - wakeup_code jz 1f lcall $0xc000,$3 movw %cs, %ax - movw %ax, %ds # Bios might have played with that + movw %ax, %ds # Bios might have played with that movw %ax, %ss 1: @@ -68,15 +61,12 @@ wakeup_code: movb $0xa2, %al ; outb %al, $0x80 - mov %ds, %ax # Find 32bit wakeup_code addr - movzx %ax, %esi # (Convert %ds:gdt to a liner ptr) - shll $4, %esi - # Fix up the vectors - addl %esi, wakeup_32_vector - wakeup_code - addl %esi, wakeup_long64_vector - wakeup_code - addl %esi, gdt_48a + 2 - wakeup_code # Fixup the gdt pointer - - lidtl %ds:idt_48a - wakeup_code + lidt %ds:idt_48a - wakeup_code + xorl %eax, %eax + movw %ds, %ax # (Convert %ds:gdt to a linear ptr) + shll $4, %eax + addl $(gdta - wakeup_code), %eax + movl %eax, gdt_48a +2 - wakeup_code lgdtl %ds:gdt_48a - wakeup_code # load gdt with whatever is # appropriate @@ -85,63 +75,86 @@ wakeup_code: jmp 1f 1: - ljmpl *(wakeup_32_vector - wakeup_code) - - .balign 4 -wakeup_32_vector: - .long wakeup_32 - wakeup_code - .word __KERNEL32_CS, 0 + .byte 0x66, 0xea # prefix + jmpi-opcode + .long wakeup_32 - __START_KERNEL_map + .word __KERNEL_CS .code32 wakeup_32: # Running in this code, but at low address; paging is not yet turned on. movb $0xa5, %al ; outb %al, $0x80 - movl $__KERNEL_DS, %eax - movl %eax, %ds + /* Check if extended functions are implemented */ + movl $0x80000000, %eax + cpuid + cmpl $0x80000000, %eax + jbe bogus_cpu + wbinvd + mov $0x80000001, %eax + cpuid + btl $29, %edx + jnc bogus_cpu + movl %edx,%edi + + movw $__KERNEL_DS, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs - movw $0x0e00 + 'i', %ds:(0xb8012) - movb $0xa8, %al ; outb %al, $0x80; + movw $__KERNEL_DS, %ax + movw %ax, %ss + + mov $(wakeup_stack - __START_KERNEL_map), %esp + movl saved_magic - __START_KERNEL_map, %eax + cmpl $0x9abcdef0, %eax + jne bogus_32_magic /* * Prepare for entering 64bits mode */ - /* Enable PAE */ + /* Enable PAE mode and PGE */ xorl %eax, %eax btsl $5, %eax + btsl $7, %eax movl %eax, %cr4 /* Setup early boot stage 4 level pagetables */ - leal (wakeup_level4_pgt - wakeup_code)(%esi), %eax + movl $(wakeup_level4_pgt - __START_KERNEL_map), %eax movl %eax, %cr3 - /* Check if nx is implemented */ - movl $0x80000001, %eax - cpuid - movl %edx,%edi - + /* Setup EFER (Extended Feature Enable Register) */ + movl $MSR_EFER, %ecx + rdmsr + /* Fool rdmsr and reset %eax to avoid dependences */ + xorl %eax, %eax /* Enable Long Mode */ - xorl %eax, %eax btsl $_EFER_LME, %eax + /* Enable System Call */ + btsl $_EFER_SCE, %eax - /* No Execute supported? */ + /* No Execute supported? */ btl $20,%edi jnc 1f btsl $_EFER_NX, %eax +1: /* Make changes effective */ -1: movl $MSR_EFER, %ecx - xorl %edx, %edx wrmsr + wbinvd xorl %eax, %eax btsl $31, %eax /* Enable paging and in turn activate Long Mode */ btsl $0, %eax /* Enable protected mode */ + btsl $1, %eax /* Enable MP */ + btsl $4, %eax /* Enable ET */ + btsl $5, %eax /* Enable NE */ + btsl $16, %eax /* Enable WP */ + btsl $18, %eax /* Enable AM */ /* Make changes effective */ movl %eax, %cr0 - /* At this point: CR4.PAE must be 1 CS.L must be 0 @@ -149,6 +162,11 @@ wakeup_32: Next instruction must be a branch This must be on identity-mapped page */ + jmp reach_compatibility_mode +reach_compatibility_mode: + movw $0x0e00 + 'i', %ds:(0xb8012) + movb $0xa8, %al ; outb %al, $0x80; + /* * At this point we're in long mode but in 32bit compatibility mode * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn @@ -156,19 +174,24 @@ wakeup_32: * the new gdt/idt that has __KERNEL_CS with CS.L = 1. */ + movw $0x0e00 + 'n', %ds:(0xb8014) + movb $0xa9, %al ; outb %al, $0x80 + + /* Load new GDT with the 64bit segment using 32bit descriptor */ + movl $(pGDT32 - __START_KERNEL_map), %eax + lgdt (%eax) + + movl $(wakeup_jumpvector - __START_KERNEL_map), %eax /* Finally jump in 64bit mode */ - ljmp *(wakeup_long64_vector - wakeup_code)(%esi) + ljmp *(%eax) - .balign 4 -wakeup_long64_vector: - .long wakeup_long64 - wakeup_code - .word __KERNEL_CS, 0 +wakeup_jumpvector: + .long wakeup_long64 - __START_KERNEL_map + .word __KERNEL_CS .code64 - /* Hooray, we are in Long 64-bit mode (but still running in - * low memory) - */ + /* Hooray, we are in Long 64-bit mode (but still running in low memory) */ wakeup_long64: /* * We must switch to a new descriptor in kernel space for the GDT @@ -176,15 +199,7 @@ wakeup_long64: * addresses where we're currently running on. We have to do that here * because in 32bit we couldn't load a 64bit linear address. */ - lgdt cpu_gdt_descr - - movw $0x0e00 + 'n', %ds:(0xb8014) - movb $0xa9, %al ; outb %al, $0x80 - - movq saved_magic, %rax - movq $0x123456789abcdef0, %rdx - cmpq %rdx, %rax - jne bogus_64_magic + lgdt cpu_gdt_descr - __START_KERNEL_map movw $0x0e00 + 'u', %ds:(0xb8016) @@ -196,58 +211,75 @@ wakeup_long64: movw %ax, %es movw %ax, %fs movw %ax, %gs - movq saved_rsp, %rsp + movq saved_esp, %rsp movw $0x0e00 + 'x', %ds:(0xb8018) - movq saved_rbx, %rbx - movq saved_rdi, %rdi - movq saved_rsi, %rsi - movq saved_rbp, %rbp + movq saved_ebx, %rbx + movq saved_edi, %rdi + movq saved_esi, %rsi + movq saved_ebp, %rbp movw $0x0e00 + '!', %ds:(0xb801a) - movq saved_rip, %rax + movq saved_eip, %rax jmp *%rax .code32 .align 64 gdta: - /* Its good to keep gdt in sync with one in trampoline.S */ .word 0, 0, 0, 0 # dummy - /* ??? Why I need the accessed bit set in order for this to work? */ - .quad 0x00cf9b000000ffff # __KERNEL32_CS - .quad 0x00af9b000000ffff # __KERNEL_CS - .quad 0x00cf93000000ffff # __KERNEL_DS + + .word 0, 0, 0, 0 # unused + + .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) + .word 0 # base address = 0 + .word 0x9B00 # code read/exec. ??? Why I need 0x9B00 (as opposed to 0x9A00 in order for this to work?) + .word 0x00CF # granularity = 4096, 386 + # (+5th nibble of limit) + + .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) + .word 0 # base address = 0 + .word 0x9200 # data read/write + .word 0x00CF # granularity = 4096, 386 + # (+5th nibble of limit) +# this is 64bit descriptor for code + .word 0xFFFF + .word 0 + .word 0x9A00 # code read/exec + .word 0x00AF # as above, but it is long mode and with D=0 idt_48a: .word 0 # idt limit = 0 .word 0, 0 # idt base = 0L gdt_48a: - .word 0x800 # gdt limit=2048, + .word 0x8000 # gdt limit=2048, # 256 GDT entries - .long gdta - wakeup_code # gdt base (relocated in later) + .word 0, 0 # gdt base (filled in later) + +real_save_gdt: .word 0 + .quad 0 real_magic: .quad 0 video_mode: .quad 0 video_flags: .quad 0 -.code16 bogus_real_magic: - movb $0xba,%al ; outb %al,$0x80 + movb $0xba,%al ; outb %al,$0x80 jmp bogus_real_magic -.code64 -bogus_64_magic: +bogus_32_magic: movb $0xb3,%al ; outb %al,$0x80 - jmp bogus_64_magic + jmp bogus_32_magic -.code16 -no_longmode: - movb $0xbc,%al ; outb %al,$0x80 - jmp no_longmode +bogus_31_magic: + movb $0xb1,%al ; outb %al,$0x80 + jmp bogus_31_magic + +bogus_cpu: + movb $0xbc,%al ; outb %al,$0x80 + jmp bogus_cpu -#include "../verify_cpu.S" /* This code uses an extended set of video mode numbers. These include: * Aliases for standard modes @@ -269,7 +301,6 @@ no_longmode: #define VIDEO_FIRST_V7 0x0900 # Setting of user mode (AX=mode ID) => CF=success -.code16 mode_seta: movw %ax, %bx #if 0 @@ -315,18 +346,21 @@ check_vesaa: _setbada: jmp setbada + .code64 +bogus_magic: + movw $0x0e00 + 'B', %ds:(0xb8018) + jmp bogus_magic + +bogus_magic2: + movw $0x0e00 + '2', %ds:(0xb8018) + jmp bogus_magic2 + + wakeup_stack_begin: # Stack grows down .org 0xff0 wakeup_stack: # Just below end of page -.org 0x1000 -ENTRY(wakeup_level4_pgt) - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE - .fill 510,8,0 - /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE - ENTRY(wakeup_end) ## @@ -339,11 +373,28 @@ ENTRY(wakeup_end) # # Returned address is location of code in low memory (past data and stack) # - .code64 ENTRY(acpi_copy_wakeup_routine) pushq %rax + pushq %rcx pushq %rdx + sgdt saved_gdt + sidt saved_idt + sldt saved_ldt + str saved_tss + + movq %cr3, %rdx + movq %rdx, saved_cr3 + movq %cr4, %rdx + movq %rdx, saved_cr4 + movq %cr0, %rdx + movq %rdx, saved_cr0 + sgdt real_save_gdt - wakeup_start (,%rdi) + movl $MSR_EFER, %ecx + rdmsr + movl %eax, saved_efer + movl %edx, saved_efer2 + movl saved_video_mode, %edx movl %edx, video_mode - wakeup_start (,%rdi) movl acpi_video_flags, %edx @@ -352,13 +403,21 @@ ENTRY(acpi_copy_wakeup_routine) movq $0x123456789abcdef0, %rdx movq %rdx, saved_magic - movq saved_magic, %rax - movq $0x123456789abcdef0, %rdx - cmpq %rdx, %rax - jne bogus_64_magic + movl saved_magic - __START_KERNEL_map, %eax + cmpl $0x9abcdef0, %eax + jne bogus_32_magic + + # make sure %cr4 is set correctly (features, etc) + movl saved_cr4 - __START_KERNEL_map, %eax + movq %rax, %cr4 + movl saved_cr0 - __START_KERNEL_map, %eax + movq %rax, %cr0 + jmp 1f # Flush pipelines +1: # restore the regs we used popq %rdx + popq %rcx popq %rax ENTRY(do_suspend_lowlevel_s4bios) ret @@ -391,13 +450,13 @@ do_suspend_lowlevel: movq %r15, saved_context_r15(%rip) pushfq ; popq saved_context_eflags(%rip) - movq $.L97, saved_rip(%rip) + movq $.L97, saved_eip(%rip) - movq %rsp,saved_rsp - movq %rbp,saved_rbp - movq %rbx,saved_rbx - movq %rdi,saved_rdi - movq %rsi,saved_rsi + movq %rsp,saved_esp + movq %rbp,saved_ebp + movq %rbx,saved_ebx + movq %rdi,saved_edi + movq %rsi,saved_esi addq $8, %rsp movl $3, %edi @@ -444,12 +503,25 @@ do_suspend_lowlevel: .data ALIGN -ENTRY(saved_rbp) .quad 0 -ENTRY(saved_rsi) .quad 0 -ENTRY(saved_rdi) .quad 0 -ENTRY(saved_rbx) .quad 0 +ENTRY(saved_ebp) .quad 0 +ENTRY(saved_esi) .quad 0 +ENTRY(saved_edi) .quad 0 +ENTRY(saved_ebx) .quad 0 -ENTRY(saved_rip) .quad 0 -ENTRY(saved_rsp) .quad 0 +ENTRY(saved_eip) .quad 0 +ENTRY(saved_esp) .quad 0 ENTRY(saved_magic) .quad 0 + +ALIGN +# saved registers +saved_gdt: .quad 0,0 +saved_idt: .quad 0,0 +saved_ldt: .quad 0 +saved_tss: .quad 0 + +saved_cr0: .quad 0 +saved_cr3: .quad 0 +saved_cr4: .quad 0 +saved_efer: .quad 0 +saved_efer2: .quad 0 diff --git a/trunk/arch/x86_64/kernel/aperture.c b/trunk/arch/x86_64/kernel/aperture.c index a52af5820592..b487396c4c5b 100644 --- a/trunk/arch/x86_64/kernel/aperture.c +++ b/trunk/arch/x86_64/kernel/aperture.c @@ -51,6 +51,7 @@ static void __init insert_aperture_resource(u32 aper_base, u32 aper_size) static u32 __init allocate_aperture(void) { + pg_data_t *nd0 = NODE_DATA(0); u32 aper_size; void *p; @@ -64,12 +65,12 @@ static u32 __init allocate_aperture(void) * Unfortunately we cannot move it up because that would make the * IOMMU useless. */ - p = __alloc_bootmem_nopanic(aper_size, aper_size, 0); + p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); if (!p || __pa(p)+aper_size > 0xffffffff) { printk("Cannot allocate aperture memory hole (%p,%uK)\n", p, aper_size>>10); if (p) - free_bootmem(__pa(p), aper_size); + free_bootmem_node(nd0, __pa(p), aper_size); return 0; } printk("Mapping aperture over %d KB of RAM @ %lx\n", diff --git a/trunk/arch/x86_64/kernel/apic.c b/trunk/arch/x86_64/kernel/apic.c index 1b0e07bb8728..bd3e45d47c37 100644 --- a/trunk/arch/x86_64/kernel/apic.c +++ b/trunk/arch/x86_64/kernel/apic.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -67,28 +68,6 @@ int using_apic_timer __read_mostly = 0; static void apic_pm_activate(void); -void apic_wait_icr_idle(void) -{ - while (apic_read(APIC_ICR) & APIC_ICR_BUSY) - cpu_relax(); -} - -unsigned int safe_apic_wait_icr_idle(void) -{ - unsigned int send_status; - int timeout; - - timeout = 0; - do { - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - if (!send_status) - break; - udelay(100); - } while (timeout++ < 1000); - - return send_status; -} - void enable_NMI_through_LVT0 (void * dummy) { unsigned int v; @@ -838,15 +817,14 @@ static void setup_APIC_timer(unsigned int clocks) static int __init calibrate_APIC_clock(void) { - unsigned apic, apic_start; - unsigned long tsc, tsc_start; + int apic, apic_start, tsc, tsc_start; int result; /* * Put whatever arbitrary (but long enough) timeout * value into the APIC clock, we just want to get the * counter running for calibration. */ - __setup_APIC_LVTT(4000000000); + __setup_APIC_LVTT(1000000000); apic_start = apic_read(APIC_TMCCT); #ifdef CONFIG_X86_PM_TIMER @@ -857,15 +835,15 @@ static int __init calibrate_APIC_clock(void) } else #endif { - rdtscll(tsc_start); + rdtscl(tsc_start); do { apic = apic_read(APIC_TMCCT); - rdtscll(tsc); + rdtscl(tsc); } while ((tsc - tsc_start) < TICK_COUNT && - (apic_start - apic) < TICK_COUNT); + (apic - apic_start) < TICK_COUNT); - result = (apic_start - apic) * 1000L * tsc_khz / + result = (apic_start - apic) * 1000L * cpu_khz / (tsc - tsc_start); } printk("result %d\n", result); diff --git a/trunk/arch/x86_64/kernel/asm-offsets.c b/trunk/arch/x86_64/kernel/asm-offsets.c index 778953bc636c..96687e2beb2c 100644 --- a/trunk/arch/x86_64/kernel/asm-offsets.c +++ b/trunk/arch/x86_64/kernel/asm-offsets.c @@ -21,14 +21,6 @@ #define BLANK() asm volatile("\n->" : : ) -#define __NO_STUBS 1 -#undef __SYSCALL -#undef _ASM_X86_64_UNISTD_H_ -#define __SYSCALL(nr, sym) [nr] = 1, -static char syscalls[] = { -#include -}; - int main(void) { #define ENTRY(entry) DEFINE(tsk_ ## entry, offsetof(struct task_struct, entry)) @@ -79,7 +71,5 @@ int main(void) DEFINE(TSS_ist, offsetof(struct tss_struct, ist)); BLANK(); DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); - BLANK(); - DEFINE(__NR_syscall_max, sizeof(syscalls) - 1); return 0; } diff --git a/trunk/arch/x86_64/kernel/bugs.c b/trunk/arch/x86_64/kernel/bugs.c deleted file mode 100644 index 12b585b5345d..000000000000 --- a/trunk/arch/x86_64/kernel/bugs.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/x86_64/kernel/bugs.c - * - * Copyright (C) 1994 Linus Torvalds - * Copyright (C) 2000 SuSE - */ - -#include -#include -#include -#include - -void __init check_bugs(void) -{ - identify_cpu(&boot_cpu_data); -#if !defined(CONFIG_SMP) - printk("CPU: "); - print_cpu_info(&boot_cpu_data); -#endif - alternative_instructions(); -} diff --git a/trunk/arch/x86_64/kernel/cpufreq/Kconfig b/trunk/arch/x86_64/kernel/cpufreq/Kconfig index c0749d2479f5..40acb67fb882 100644 --- a/trunk/arch/x86_64/kernel/cpufreq/Kconfig +++ b/trunk/arch/x86_64/kernel/cpufreq/Kconfig @@ -16,9 +16,6 @@ config X86_POWERNOW_K8 help This adds the CPUFreq driver for mobile AMD Opteron/Athlon64 processors. - To compile this driver as a module, choose M here: the - module will be called powernow-k8. - For details, take a look at . If in doubt, say N. @@ -41,9 +38,6 @@ config X86_SPEEDSTEP_CENTRINO mobile CPUs. This means Intel Pentium M (Centrino) CPUs or 64bit enabled Intel Xeons. - To compile this driver as a module, choose M here: the - module will be called speedstep-centrino. - For details, take a look at . If in doubt, say N. @@ -61,9 +55,6 @@ config X86_ACPI_CPUFREQ Processor Performance States. This driver also supports Intel Enhanced Speedstep. - To compile this driver as a module, choose M here: the - module will be called acpi-cpufreq. - For details, take a look at . If in doubt, say N. @@ -71,7 +62,7 @@ config X86_ACPI_CPUFREQ comment "shared options" config X86_ACPI_CPUFREQ_PROC_INTF - bool "/proc/acpi/processor/../performance interface (deprecated)" + bool "/proc/acpi/processor/../performance interface (deprecated)" depends on PROC_FS depends on X86_ACPI_CPUFREQ || X86_SPEEDSTEP_CENTRINO_ACPI || X86_POWERNOW_K8_ACPI help @@ -95,18 +86,16 @@ config X86_P4_CLOCKMOD slowdowns and noticeable latencies. Normally Speedstep should be used instead. - To compile this driver as a module, choose M here: the - module will be called p4-clockmod. - For details, take a look at . Unless you are absolutely sure say N. config X86_SPEEDSTEP_LIB - tristate - default X86_P4_CLOCKMOD + tristate + default X86_P4_CLOCKMOD endif endmenu + diff --git a/trunk/arch/x86_64/kernel/crash.c b/trunk/arch/x86_64/kernel/crash.c index 13432a1ae904..95a7a2c13131 100644 --- a/trunk/arch/x86_64/kernel/crash.c +++ b/trunk/arch/x86_64/kernel/crash.c @@ -17,13 +17,13 @@ #include #include #include -#include #include #include #include #include #include +#include /* This keeps a track of which one is crashing cpu. */ static int crashing_cpu; diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c index 13c6c37610e0..a490fabfcf47 100644 --- a/trunk/arch/x86_64/kernel/e820.c +++ b/trunk/arch/x86_64/kernel/e820.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -27,7 +25,7 @@ #include #include -struct e820map e820; +struct e820map e820 __initdata; /* * PFN of last memory page. @@ -100,7 +98,7 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) * This function checks if any part of the range is mapped * with type. */ -int +int __meminit e820_any_mapped(unsigned long start, unsigned long end, unsigned type) { int i; @@ -114,7 +112,6 @@ e820_any_mapped(unsigned long start, unsigned long end, unsigned type) } return 0; } -EXPORT_SYMBOL_GPL(e820_any_mapped); /* * This function checks if the entire range is mapped with type. @@ -258,6 +255,22 @@ void __init e820_reserve_resources(void) } } +/* Mark pages corresponding to given address range as nosave */ +static void __init +e820_mark_nosave_range(unsigned long start, unsigned long end) +{ + unsigned long pfn, max_pfn; + + if (start >= end) + return; + + printk("Nosave address range: %016lx - %016lx\n", start, end); + max_pfn = end >> PAGE_SHIFT; + for (pfn = start >> PAGE_SHIFT; pfn < max_pfn; pfn++) + if (pfn_valid(pfn)) + SetPageNosave(pfn_to_page(pfn)); +} + /* * Find the ranges of physical addresses that do not correspond to * e820 RAM areas and mark the corresponding pages as nosave for software @@ -276,13 +289,13 @@ void __init e820_mark_nosave_regions(void) struct e820entry *ei = &e820.map[i]; if (paddr < ei->addr) - register_nosave_region(PFN_DOWN(paddr), - PFN_UP(ei->addr)); + e820_mark_nosave_range(paddr, + round_up(ei->addr, PAGE_SIZE)); paddr = round_down(ei->addr + ei->size, PAGE_SIZE); if (ei->type != E820_RAM) - register_nosave_region(PFN_UP(ei->addr), - PFN_DOWN(paddr)); + e820_mark_nosave_range(round_up(ei->addr, PAGE_SIZE), + paddr); if (paddr >= (end_pfn << PAGE_SHIFT)) break; diff --git a/trunk/arch/x86_64/kernel/early-quirks.c b/trunk/arch/x86_64/kernel/early-quirks.c index 990d9c218a5d..fede55a53995 100644 --- a/trunk/arch/x86_64/kernel/early-quirks.c +++ b/trunk/arch/x86_64/kernel/early-quirks.c @@ -71,6 +71,18 @@ static void __init ati_bugs(void) } } +static void intel_bugs(void) +{ + u16 device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); + +#ifdef CONFIG_SMP + if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || + device == PCI_DEVICE_ID_INTEL_E7520_MCH || + device == PCI_DEVICE_ID_INTEL_E7525_MCH) + quirk_intel_irqbalance(); +#endif +} + struct chipset { u16 vendor; void (*f)(void); @@ -80,6 +92,7 @@ static struct chipset early_qrk[] __initdata = { { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, { PCI_VENDOR_ID_VIA, via_bugs }, { PCI_VENDOR_ID_ATI, ati_bugs }, + { PCI_VENDOR_ID_INTEL, intel_bugs}, {} }; diff --git a/trunk/arch/x86_64/kernel/early_printk.c b/trunk/arch/x86_64/kernel/early_printk.c index 56eaa259782b..47b6d90349da 100644 --- a/trunk/arch/x86_64/kernel/early_printk.c +++ b/trunk/arch/x86_64/kernel/early_printk.c @@ -11,10 +11,11 @@ #ifdef __i386__ #include +#define VGABASE (__ISA_IO_base + 0xb8000) #else #include +#define VGABASE ((void __iomem *)0xffffffff800b8000UL) #endif -#define VGABASE (__ISA_IO_base + 0xb8000) static int max_ypos = 25, max_xpos = 80; static int current_ypos = 25, current_xpos = 0; @@ -175,7 +176,7 @@ static noinline long simnow(long cmd, long a, long b, long c) return ret; } -static void __init simnow_init(char *str) +void __init simnow_init(char *str) { char *fn = "klog"; if (*str == '=') @@ -243,12 +244,22 @@ static int __init setup_early_printk(char *buf) early_console = &simnow_console; keep_early = 1; } - - if (keep_early) - early_console->flags &= ~CON_BOOT; - else - early_console->flags |= CON_BOOT; register_console(early_console); return 0; } + early_param("earlyprintk", setup_early_printk); + +void __init disable_early_printk(void) +{ + if (!early_console_initialized || !early_console) + return; + if (!keep_early) { + printk("disabling early console\n"); + unregister_console(early_console); + early_console_initialized = 0; + } else { + printk("keeping early console\n"); + } +} + diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index fa984b53e7e6..ed4350ced3d0 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -701,7 +701,6 @@ END(spurious_interrupt) CFI_ADJUST_CFA_OFFSET 8 pushq %rax /* push real oldrax to the rdi slot */ CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rax,0 leaq \sym(%rip),%rax jmp error_entry CFI_ENDPROC @@ -711,7 +710,6 @@ END(spurious_interrupt) XCPT_FRAME pushq %rax CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rax,0 leaq \sym(%rip),%rax jmp error_entry CFI_ENDPROC @@ -819,7 +817,6 @@ paranoid_schedule\trace: */ KPROBE_ENTRY(error_entry) _frame RDI - CFI_REL_OFFSET rax,0 /* rdi slot contains rax, oldrax contains error code */ cld subq $14*8,%rsp @@ -827,7 +824,6 @@ KPROBE_ENTRY(error_entry) movq %rsi,13*8(%rsp) CFI_REL_OFFSET rsi,RSI movq 14*8(%rsp),%rsi /* load rax from rdi slot */ - CFI_REGISTER rax,rsi movq %rdx,12*8(%rsp) CFI_REL_OFFSET rdx,RDX movq %rcx,11*8(%rsp) @@ -861,7 +857,6 @@ error_swapgs: swapgs error_sti: movq %rdi,RDI(%rsp) - CFI_REL_OFFSET rdi,RDI movq %rsp,%rdi movq ORIG_RAX(%rsp),%rsi /* get error code */ movq $-1,ORIG_RAX(%rsp) diff --git a/trunk/arch/x86_64/kernel/functionlist b/trunk/arch/x86_64/kernel/functionlist new file mode 100644 index 000000000000..7ae18ec12454 --- /dev/null +++ b/trunk/arch/x86_64/kernel/functionlist @@ -0,0 +1,1284 @@ +*(.text.flush_thread) +*(.text.check_poison_obj) +*(.text.copy_page) +*(.text.__set_personality) +*(.text.gart_map_sg) +*(.text.kmem_cache_free) +*(.text.find_get_page) +*(.text._raw_spin_lock) +*(.text.ide_outb) +*(.text.unmap_vmas) +*(.text.copy_page_range) +*(.text.kprobe_handler) +*(.text.__handle_mm_fault) +*(.text.__d_lookup) +*(.text.copy_user_generic) +*(.text.__link_path_walk) +*(.text.get_page_from_freelist) +*(.text.kmem_cache_alloc) +*(.text.drive_cmd_intr) +*(.text.ia32_setup_sigcontext) +*(.text.huge_pte_offset) +*(.text.do_page_fault) +*(.text.page_remove_rmap) +*(.text.release_pages) +*(.text.ide_end_request) +*(.text.__mutex_lock_slowpath) +*(.text.__find_get_block) +*(.text.kfree) +*(.text.vfs_read) +*(.text._raw_spin_unlock) +*(.text.free_hot_cold_page) +*(.text.fget_light) +*(.text.schedule) +*(.text.memcmp) +*(.text.touch_atime) +*(.text.__might_sleep) +*(.text.__down_read_trylock) +*(.text.arch_pick_mmap_layout) +*(.text.find_vma) +*(.text.__make_request) +*(.text.do_generic_mapping_read) +*(.text.mutex_lock_interruptible) +*(.text.__generic_file_aio_read) +*(.text._atomic_dec_and_lock) +*(.text.__wake_up_bit) +*(.text.add_to_page_cache) +*(.text.cache_alloc_debugcheck_after) +*(.text.vm_normal_page) +*(.text.mutex_debug_check_no_locks_freed) +*(.text.net_rx_action) +*(.text.__find_first_zero_bit) +*(.text.put_page) +*(.text._raw_read_lock) +*(.text.__delay) +*(.text.dnotify_parent) +*(.text.do_path_lookup) +*(.text.do_sync_read) +*(.text.do_lookup) +*(.text.bit_waitqueue) +*(.text.file_read_actor) +*(.text.strncpy_from_user) +*(.text.__pagevec_lru_add_active) +*(.text.fget) +*(.text.dput) +*(.text.__strnlen_user) +*(.text.inotify_inode_queue_event) +*(.text.rw_verify_area) +*(.text.ide_intr) +*(.text.inotify_dentry_parent_queue_event) +*(.text.permission) +*(.text.memscan) +*(.text.hpet_rtc_interrupt) +*(.text.do_mmap_pgoff) +*(.text.current_fs_time) +*(.text.vfs_getattr) +*(.text.kmem_flagcheck) +*(.text.mark_page_accessed) +*(.text.free_pages_and_swap_cache) +*(.text.generic_fillattr) +*(.text.__block_prepare_write) +*(.text.__set_page_dirty_nobuffers) +*(.text.link_path_walk) +*(.text.find_get_pages_tag) +*(.text.ide_do_request) +*(.text.__alloc_pages) +*(.text.generic_permission) +*(.text.mod_page_state_offset) +*(.text.free_pgd_range) +*(.text.generic_file_buffered_write) +*(.text.number) +*(.text.ide_do_rw_disk) +*(.text.__brelse) +*(.text.__mod_page_state_offset) +*(.text.rotate_reclaimable_page) +*(.text.find_vma_prepare) +*(.text.find_vma_prev) +*(.text.lru_cache_add_active) +*(.text.__kmalloc_track_caller) +*(.text.smp_invalidate_interrupt) +*(.text.handle_IRQ_event) +*(.text.__find_get_block_slow) +*(.text.do_wp_page) +*(.text.do_select) +*(.text.set_user_nice) +*(.text.sys_read) +*(.text.do_munmap) +*(.text.csum_partial) +*(.text.__do_softirq) +*(.text.may_open) +*(.text.getname) +*(.text.get_empty_filp) +*(.text.__fput) +*(.text.remove_mapping) +*(.text.filp_ctor) +*(.text.poison_obj) +*(.text.unmap_region) +*(.text.test_set_page_writeback) +*(.text.__do_page_cache_readahead) +*(.text.sock_def_readable) +*(.text.ide_outl) +*(.text.shrink_zone) +*(.text.rb_insert_color) +*(.text.get_request) +*(.text.sys_pread64) +*(.text.spin_bug) +*(.text.ide_outsl) +*(.text.mask_and_ack_8259A) +*(.text.filemap_nopage) +*(.text.page_add_file_rmap) +*(.text.find_lock_page) +*(.text.tcp_poll) +*(.text.__mark_inode_dirty) +*(.text.file_ra_state_init) +*(.text.generic_file_llseek) +*(.text.__pagevec_lru_add) +*(.text.page_cache_readahead) +*(.text.n_tty_receive_buf) +*(.text.zonelist_policy) +*(.text.vma_adjust) +*(.text.test_clear_page_dirty) +*(.text.sync_buffer) +*(.text.do_exit) +*(.text.__bitmap_weight) +*(.text.alloc_pages_current) +*(.text.get_unused_fd) +*(.text.zone_watermark_ok) +*(.text.cpuset_update_task_memory_state) +*(.text.__bitmap_empty) +*(.text.sys_munmap) +*(.text.__inode_dir_notify) +*(.text.__generic_file_aio_write_nolock) +*(.text.__pte_alloc) +*(.text.sys_select) +*(.text.vm_acct_memory) +*(.text.vfs_write) +*(.text.__lru_add_drain) +*(.text.prio_tree_insert) +*(.text.generic_file_aio_read) +*(.text.vma_merge) +*(.text.block_write_full_page) +*(.text.__page_set_anon_rmap) +*(.text.apic_timer_interrupt) +*(.text.release_console_sem) +*(.text.sys_write) +*(.text.sys_brk) +*(.text.dup_mm) +*(.text.read_current_timer) +*(.text.ll_rw_block) +*(.text.blk_rq_map_sg) +*(.text.dbg_userword) +*(.text.__block_commit_write) +*(.text.cache_grow) +*(.text.copy_strings) +*(.text.release_task) +*(.text.do_sync_write) +*(.text.unlock_page) +*(.text.load_elf_binary) +*(.text.__follow_mount) +*(.text.__getblk) +*(.text.do_sys_open) +*(.text.current_kernel_time) +*(.text.call_rcu) +*(.text.write_chan) +*(.text.vsnprintf) +*(.text.dummy_inode_setsecurity) +*(.text.submit_bh) +*(.text.poll_freewait) +*(.text.bio_alloc_bioset) +*(.text.skb_clone) +*(.text.page_waitqueue) +*(.text.__mutex_lock_interruptible_slowpath) +*(.text.get_index) +*(.text.csum_partial_copy_generic) +*(.text.bad_range) +*(.text.remove_vma) +*(.text.cp_new_stat) +*(.text.alloc_arraycache) +*(.text.test_clear_page_writeback) +*(.text.strsep) +*(.text.open_namei) +*(.text._raw_read_unlock) +*(.text.get_vma_policy) +*(.text.__down_write_trylock) +*(.text.find_get_pages) +*(.text.tcp_rcv_established) +*(.text.generic_make_request) +*(.text.__block_write_full_page) +*(.text.cfq_set_request) +*(.text.sys_inotify_init) +*(.text.split_vma) +*(.text.__mod_timer) +*(.text.get_options) +*(.text.vma_link) +*(.text.mpage_writepages) +*(.text.truncate_complete_page) +*(.text.tcp_recvmsg) +*(.text.sigprocmask) +*(.text.filemap_populate) +*(.text.sys_close) +*(.text.inotify_dev_queue_event) +*(.text.do_task_stat) +*(.text.__dentry_open) +*(.text.unlink_file_vma) +*(.text.__pollwait) +*(.text.packet_rcv_spkt) +*(.text.drop_buffers) +*(.text.free_pgtables) +*(.text.generic_file_direct_write) +*(.text.copy_process) +*(.text.netif_receive_skb) +*(.text.dnotify_flush) +*(.text.print_bad_pte) +*(.text.anon_vma_unlink) +*(.text.sys_mprotect) +*(.text.sync_sb_inodes) +*(.text.find_inode_fast) +*(.text.dummy_inode_readlink) +*(.text.putname) +*(.text.init_smp_flush) +*(.text.dbg_redzone2) +*(.text.sk_run_filter) +*(.text.may_expand_vm) +*(.text.generic_file_aio_write) +*(.text.find_next_zero_bit) +*(.text.file_kill) +*(.text.audit_getname) +*(.text.arch_unmap_area_topdown) +*(.text.alloc_page_vma) +*(.text.tcp_transmit_skb) +*(.text.rb_next) +*(.text.dbg_redzone1) +*(.text.generic_file_mmap) +*(.text.vfs_fstat) +*(.text.sys_time) +*(.text.page_lock_anon_vma) +*(.text.get_unmapped_area) +*(.text.remote_llseek) +*(.text.__up_read) +*(.text.fd_install) +*(.text.eventpoll_init_file) +*(.text.dma_alloc_coherent) +*(.text.create_empty_buffers) +*(.text.__mutex_unlock_slowpath) +*(.text.dup_fd) +*(.text.d_alloc) +*(.text.tty_ldisc_try) +*(.text.sys_stime) +*(.text.__rb_rotate_right) +*(.text.d_validate) +*(.text.rb_erase) +*(.text.path_release) +*(.text.memmove) +*(.text.invalidate_complete_page) +*(.text.clear_inode) +*(.text.cache_estimate) +*(.text.alloc_buffer_head) +*(.text.smp_call_function_interrupt) +*(.text.flush_tlb_others) +*(.text.file_move) +*(.text.balance_dirty_pages_ratelimited) +*(.text.vma_prio_tree_add) +*(.text.timespec_trunc) +*(.text.mempool_alloc) +*(.text.iget_locked) +*(.text.d_alloc_root) +*(.text.cpuset_populate_dir) +*(.text.anon_vma_prepare) +*(.text.sys_newstat) +*(.text.alloc_page_interleave) +*(.text.__path_lookup_intent_open) +*(.text.__pagevec_free) +*(.text.inode_init_once) +*(.text.free_vfsmnt) +*(.text.__user_walk_fd) +*(.text.cfq_idle_slice_timer) +*(.text.sys_mmap) +*(.text.sys_llseek) +*(.text.prio_tree_remove) +*(.text.filp_close) +*(.text.file_permission) +*(.text.vma_prio_tree_remove) +*(.text.tcp_ack) +*(.text.nameidata_to_filp) +*(.text.sys_lseek) +*(.text.percpu_counter_mod) +*(.text.igrab) +*(.text.__bread) +*(.text.alloc_inode) +*(.text.filldir) +*(.text.__rb_rotate_left) +*(.text.irq_affinity_write_proc) +*(.text.init_request_from_bio) +*(.text.find_or_create_page) +*(.text.tty_poll) +*(.text.tcp_sendmsg) +*(.text.ide_wait_stat) +*(.text.free_buffer_head) +*(.text.flush_signal_handlers) +*(.text.tcp_v4_rcv) +*(.text.nr_blockdev_pages) +*(.text.locks_remove_flock) +*(.text.__iowrite32_copy) +*(.text.do_filp_open) +*(.text.try_to_release_page) +*(.text.page_add_new_anon_rmap) +*(.text.kmem_cache_size) +*(.text.eth_type_trans) +*(.text.try_to_free_buffers) +*(.text.schedule_tail) +*(.text.proc_lookup) +*(.text.no_llseek) +*(.text.kfree_skbmem) +*(.text.do_wait) +*(.text.do_mpage_readpage) +*(.text.vfs_stat_fd) +*(.text.tty_write) +*(.text.705) +*(.text.sync_page) +*(.text.__remove_shared_vm_struct) +*(.text.__kfree_skb) +*(.text.sock_poll) +*(.text.get_request_wait) +*(.text.do_sigaction) +*(.text.do_brk) +*(.text.tcp_event_data_recv) +*(.text.read_chan) +*(.text.pipe_writev) +*(.text.__emul_lookup_dentry) +*(.text.rtc_get_rtc_time) +*(.text.print_objinfo) +*(.text.file_update_time) +*(.text.do_signal) +*(.text.disable_8259A_irq) +*(.text.blk_queue_bounce) +*(.text.__anon_vma_link) +*(.text.__vma_link) +*(.text.vfs_rename) +*(.text.sys_newlstat) +*(.text.sys_newfstat) +*(.text.sys_mknod) +*(.text.__show_regs) +*(.text.iput) +*(.text.get_signal_to_deliver) +*(.text.flush_tlb_page) +*(.text.debug_mutex_wake_waiter) +*(.text.copy_thread) +*(.text.clear_page_dirty_for_io) +*(.text.buffer_io_error) +*(.text.vfs_permission) +*(.text.truncate_inode_pages_range) +*(.text.sys_recvfrom) +*(.text.remove_suid) +*(.text.mark_buffer_dirty) +*(.text.local_bh_enable) +*(.text.get_zeroed_page) +*(.text.get_vmalloc_info) +*(.text.flush_old_exec) +*(.text.dummy_inode_permission) +*(.text.__bio_add_page) +*(.text.prio_tree_replace) +*(.text.notify_change) +*(.text.mntput_no_expire) +*(.text.fput) +*(.text.__end_that_request_first) +*(.text.wake_up_bit) +*(.text.unuse_mm) +*(.text.shrink_icache_memory) +*(.text.sched_balance_self) +*(.text.__pmd_alloc) +*(.text.pipe_poll) +*(.text.normal_poll) +*(.text.__free_pages) +*(.text.follow_mount) +*(.text.cdrom_start_packet_command) +*(.text.blk_recount_segments) +*(.text.bio_put) +*(.text.__alloc_skb) +*(.text.__wake_up) +*(.text.vm_stat_account) +*(.text.sys_fcntl) +*(.text.sys_fadvise64) +*(.text._raw_write_unlock) +*(.text.__pud_alloc) +*(.text.alloc_page_buffers) +*(.text.vfs_llseek) +*(.text.sockfd_lookup) +*(.text._raw_write_lock) +*(.text.put_compound_page) +*(.text.prune_dcache) +*(.text.pipe_readv) +*(.text.mempool_free) +*(.text.make_ahead_window) +*(.text.lru_add_drain) +*(.text.constant_test_bit) +*(.text.__clear_user) +*(.text.arch_unmap_area) +*(.text.anon_vma_link) +*(.text.sys_chroot) +*(.text.setup_arg_pages) +*(.text.radix_tree_preload) +*(.text.init_rwsem) +*(.text.generic_osync_inode) +*(.text.generic_delete_inode) +*(.text.do_sys_poll) +*(.text.dev_queue_xmit) +*(.text.default_llseek) +*(.text.__writeback_single_inode) +*(.text.vfs_ioctl) +*(.text.__up_write) +*(.text.unix_poll) +*(.text.sys_rt_sigprocmask) +*(.text.sock_recvmsg) +*(.text.recalc_bh_state) +*(.text.__put_unused_fd) +*(.text.process_backlog) +*(.text.locks_remove_posix) +*(.text.lease_modify) +*(.text.expand_files) +*(.text.end_buffer_read_nobh) +*(.text.d_splice_alias) +*(.text.debug_mutex_init_waiter) +*(.text.copy_from_user) +*(.text.cap_vm_enough_memory) +*(.text.show_vfsmnt) +*(.text.release_sock) +*(.text.pfifo_fast_enqueue) +*(.text.half_md4_transform) +*(.text.fs_may_remount_ro) +*(.text.do_fork) +*(.text.copy_hugetlb_page_range) +*(.text.cache_free_debugcheck) +*(.text.__tcp_select_window) +*(.text.task_handoff_register) +*(.text.sys_open) +*(.text.strlcpy) +*(.text.skb_copy_datagram_iovec) +*(.text.set_up_list3s) +*(.text.release_open_intent) +*(.text.qdisc_restart) +*(.text.n_tty_chars_in_buffer) +*(.text.inode_change_ok) +*(.text.__downgrade_write) +*(.text.debug_mutex_unlock) +*(.text.add_timer_randomness) +*(.text.sock_common_recvmsg) +*(.text.set_bh_page) +*(.text.printk_lock) +*(.text.path_release_on_umount) +*(.text.ip_output) +*(.text.ide_build_dmatable) +*(.text.__get_user_8) +*(.text.end_buffer_read_sync) +*(.text.__d_path) +*(.text.d_move) +*(.text.del_timer) +*(.text.constant_test_bit) +*(.text.blockable_page_cache_readahead) +*(.text.tty_read) +*(.text.sys_readlink) +*(.text.sys_faccessat) +*(.text.read_swap_cache_async) +*(.text.pty_write_room) +*(.text.page_address_in_vma) +*(.text.kthread) +*(.text.cfq_exit_io_context) +*(.text.__tcp_push_pending_frames) +*(.text.sys_pipe) +*(.text.submit_bio) +*(.text.pid_revalidate) +*(.text.page_referenced_file) +*(.text.lock_sock) +*(.text.get_page_state_node) +*(.text.generic_block_bmap) +*(.text.do_setitimer) +*(.text.dev_queue_xmit_nit) +*(.text.copy_from_read_buf) +*(.text.__const_udelay) +*(.text.console_conditional_schedule) +*(.text.wake_up_new_task) +*(.text.wait_for_completion_interruptible) +*(.text.tcp_rcv_rtt_update) +*(.text.sys_mlockall) +*(.text.set_fs_altroot) +*(.text.schedule_timeout) +*(.text.nr_free_pagecache_pages) +*(.text.nf_iterate) +*(.text.mapping_tagged) +*(.text.ip_queue_xmit) +*(.text.ip_local_deliver) +*(.text.follow_page) +*(.text.elf_map) +*(.text.dummy_file_permission) +*(.text.dispose_list) +*(.text.dentry_open) +*(.text.dentry_iput) +*(.text.bio_alloc) +*(.text.wait_on_page_bit) +*(.text.vfs_readdir) +*(.text.vfs_lstat) +*(.text.seq_escape) +*(.text.__posix_lock_file) +*(.text.mm_release) +*(.text.kref_put) +*(.text.ip_rcv) +*(.text.__iget) +*(.text.free_pages) +*(.text.find_mergeable_anon_vma) +*(.text.find_extend_vma) +*(.text.dummy_inode_listsecurity) +*(.text.bio_add_page) +*(.text.__vm_enough_memory) +*(.text.vfs_stat) +*(.text.tty_paranoia_check) +*(.text.tcp_read_sock) +*(.text.tcp_data_queue) +*(.text.sys_uname) +*(.text.sys_renameat) +*(.text.__strncpy_from_user) +*(.text.__mutex_init) +*(.text.__lookup_hash) +*(.text.kref_get) +*(.text.ip_route_input) +*(.text.__insert_inode_hash) +*(.text.do_sock_write) +*(.text.blk_done_softirq) +*(.text.__wake_up_sync) +*(.text.__vma_link_rb) +*(.text.tty_ioctl) +*(.text.tracesys) +*(.text.sys_getdents) +*(.text.sys_dup) +*(.text.stub_execve) +*(.text.sha_transform) +*(.text.radix_tree_tag_clear) +*(.text.put_unused_fd) +*(.text.put_files_struct) +*(.text.mpage_readpages) +*(.text.may_delete) +*(.text.kmem_cache_create) +*(.text.ip_mc_output) +*(.text.interleave_nodes) +*(.text.groups_search) +*(.text.generic_drop_inode) +*(.text.generic_commit_write) +*(.text.fcntl_setlk) +*(.text.exit_mmap) +*(.text.end_page_writeback) +*(.text.__d_rehash) +*(.text.debug_mutex_free_waiter) +*(.text.csum_ipv6_magic) +*(.text.count) +*(.text.cleanup_rbuf) +*(.text.check_spinlock_acquired_node) +*(.text.can_vma_merge_after) +*(.text.bio_endio) +*(.text.alloc_pidmap) +*(.text.write_ldt) +*(.text.vmtruncate_range) +*(.text.vfs_create) +*(.text.__user_walk) +*(.text.update_send_head) +*(.text.unmap_underlying_metadata) +*(.text.tty_ldisc_deref) +*(.text.tcp_setsockopt) +*(.text.tcp_send_ack) +*(.text.sys_pause) +*(.text.sys_gettimeofday) +*(.text.sync_dirty_buffer) +*(.text.strncmp) +*(.text.release_posix_timer) +*(.text.proc_file_read) +*(.text.prepare_to_wait) +*(.text.locks_mandatory_locked) +*(.text.interruptible_sleep_on_timeout) +*(.text.inode_sub_bytes) +*(.text.in_group_p) +*(.text.hrtimer_try_to_cancel) +*(.text.filldir64) +*(.text.fasync_helper) +*(.text.dummy_sb_pivotroot) +*(.text.d_lookup) +*(.text.d_instantiate) +*(.text.__d_find_alias) +*(.text.cpu_idle_wait) +*(.text.cond_resched_lock) +*(.text.chown_common) +*(.text.blk_congestion_wait) +*(.text.activate_page) +*(.text.unlock_buffer) +*(.text.tty_wakeup) +*(.text.tcp_v4_do_rcv) +*(.text.tcp_current_mss) +*(.text.sys_openat) +*(.text.sys_fchdir) +*(.text.strnlen_user) +*(.text.strnlen) +*(.text.strchr) +*(.text.sock_common_getsockopt) +*(.text.skb_checksum) +*(.text.remove_wait_queue) +*(.text.rb_replace_node) +*(.text.radix_tree_node_ctor) +*(.text.pty_chars_in_buffer) +*(.text.profile_hit) +*(.text.prio_tree_left) +*(.text.pgd_clear_bad) +*(.text.pfifo_fast_dequeue) +*(.text.page_referenced) +*(.text.open_exec) +*(.text.mmput) +*(.text.mm_init) +*(.text.__ide_dma_off_quietly) +*(.text.ide_dma_intr) +*(.text.hrtimer_start) +*(.text.get_io_context) +*(.text.__get_free_pages) +*(.text.find_first_zero_bit) +*(.text.file_free_rcu) +*(.text.dummy_socket_sendmsg) +*(.text.do_unlinkat) +*(.text.do_arch_prctl) +*(.text.destroy_inode) +*(.text.can_vma_merge_before) +*(.text.block_sync_page) +*(.text.block_prepare_write) +*(.text.bio_init) +*(.text.arch_ptrace) +*(.text.wake_up_inode) +*(.text.wait_on_retry_sync_kiocb) +*(.text.vma_prio_tree_next) +*(.text.tcp_rcv_space_adjust) +*(.text.__tcp_ack_snd_check) +*(.text.sys_utime) +*(.text.sys_recvmsg) +*(.text.sys_mremap) +*(.text.sys_bdflush) +*(.text.sleep_on) +*(.text.set_page_dirty_lock) +*(.text.seq_path) +*(.text.schedule_timeout_interruptible) +*(.text.sched_fork) +*(.text.rt_run_flush) +*(.text.profile_munmap) +*(.text.prepare_binprm) +*(.text.__pagevec_release_nonlru) +*(.text.m_show) +*(.text.lookup_mnt) +*(.text.__lookup_mnt) +*(.text.lock_timer_base) +*(.text.is_subdir) +*(.text.invalidate_bh_lru) +*(.text.init_buffer_head) +*(.text.ifind_fast) +*(.text.ide_dma_start) +*(.text.__get_page_state) +*(.text.flock_to_posix_lock) +*(.text.__find_symbol) +*(.text.do_futex) +*(.text.do_execve) +*(.text.dirty_writeback_centisecs_handler) +*(.text.dev_watchdog) +*(.text.can_share_swap_page) +*(.text.blkdev_put) +*(.text.bio_get_nr_vecs) +*(.text.xfrm_compile_policy) +*(.text.vma_prio_tree_insert) +*(.text.vfs_lstat_fd) +*(.text.__user_path_lookup_open) +*(.text.thread_return) +*(.text.tcp_send_delayed_ack) +*(.text.sock_def_error_report) +*(.text.shrink_slab) +*(.text.serial_out) +*(.text.seq_read) +*(.text.secure_ip_id) +*(.text.search_binary_handler) +*(.text.proc_pid_unhash) +*(.text.pagevec_lookup) +*(.text.new_inode) +*(.text.memcpy_toiovec) +*(.text.locks_free_lock) +*(.text.__lock_page) +*(.text.__lock_buffer) +*(.text.load_module) +*(.text.is_bad_inode) +*(.text.invalidate_inode_buffers) +*(.text.insert_vm_struct) +*(.text.inode_setattr) +*(.text.inode_add_bytes) +*(.text.ide_read_24) +*(.text.ide_get_error_location) +*(.text.ide_do_drive_cmd) +*(.text.get_locked_pte) +*(.text.get_filesystem_list) +*(.text.generic_file_open) +*(.text.follow_down) +*(.text.find_next_bit) +*(.text.__find_first_bit) +*(.text.exit_mm) +*(.text.exec_keys) +*(.text.end_buffer_write_sync) +*(.text.end_bio_bh_io_sync) +*(.text.dummy_socket_shutdown) +*(.text.d_rehash) +*(.text.d_path) +*(.text.do_ioctl) +*(.text.dget_locked) +*(.text.copy_thread_group_keys) +*(.text.cdrom_end_request) +*(.text.cap_bprm_apply_creds) +*(.text.blk_rq_bio_prep) +*(.text.__bitmap_intersects) +*(.text.bio_phys_segments) +*(.text.bio_free) +*(.text.arch_get_unmapped_area_topdown) +*(.text.writeback_in_progress) +*(.text.vfs_follow_link) +*(.text.tcp_rcv_state_process) +*(.text.tcp_check_space) +*(.text.sys_stat) +*(.text.sys_rt_sigreturn) +*(.text.sys_rt_sigaction) +*(.text.sys_remap_file_pages) +*(.text.sys_pwrite64) +*(.text.sys_fchownat) +*(.text.sys_fchmodat) +*(.text.strncat) +*(.text.strlcat) +*(.text.strcmp) +*(.text.steal_locks) +*(.text.sock_create) +*(.text.sk_stream_rfree) +*(.text.sk_stream_mem_schedule) +*(.text.skip_atoi) +*(.text.sk_alloc) +*(.text.show_stat) +*(.text.set_fs_pwd) +*(.text.set_binfmt) +*(.text.pty_unthrottle) +*(.text.proc_symlink) +*(.text.pipe_release) +*(.text.pageout) +*(.text.n_tty_write_wakeup) +*(.text.n_tty_ioctl) +*(.text.nr_free_zone_pages) +*(.text.migration_thread) +*(.text.mempool_free_slab) +*(.text.meminfo_read_proc) +*(.text.max_sane_readahead) +*(.text.lru_cache_add) +*(.text.kill_fasync) +*(.text.kernel_read) +*(.text.invalidate_mapping_pages) +*(.text.inode_has_buffers) +*(.text.init_once) +*(.text.inet_sendmsg) +*(.text.idedisk_issue_flush) +*(.text.generic_file_write) +*(.text.free_more_memory) +*(.text.__free_fdtable) +*(.text.filp_dtor) +*(.text.exit_sem) +*(.text.exit_itimers) +*(.text.error_interrupt) +*(.text.end_buffer_async_write) +*(.text.eligible_child) +*(.text.elf_map) +*(.text.dump_task_regs) +*(.text.dummy_task_setscheduler) +*(.text.dummy_socket_accept) +*(.text.dummy_file_free_security) +*(.text.__down_read) +*(.text.do_sock_read) +*(.text.do_sigaltstack) +*(.text.do_mremap) +*(.text.current_io_context) +*(.text.cpu_swap_callback) +*(.text.copy_vma) +*(.text.cap_bprm_set_security) +*(.text.blk_insert_request) +*(.text.bio_map_kern_endio) +*(.text.bio_hw_segments) +*(.text.bictcp_cong_avoid) +*(.text.add_interrupt_randomness) +*(.text.wait_for_completion) +*(.text.version_read_proc) +*(.text.unix_write_space) +*(.text.tty_ldisc_ref_wait) +*(.text.tty_ldisc_put) +*(.text.try_to_wake_up) +*(.text.tcp_v4_tw_remember_stamp) +*(.text.tcp_try_undo_dsack) +*(.text.tcp_may_send_now) +*(.text.sys_waitid) +*(.text.sys_sched_getparam) +*(.text.sys_getppid) +*(.text.sys_getcwd) +*(.text.sys_dup2) +*(.text.sys_chmod) +*(.text.sys_chdir) +*(.text.sprintf) +*(.text.sock_wfree) +*(.text.sock_aio_write) +*(.text.skb_drop_fraglist) +*(.text.skb_dequeue) +*(.text.set_close_on_exec) +*(.text.set_brk) +*(.text.seq_puts) +*(.text.SELECT_DRIVE) +*(.text.sched_exec) +*(.text.return_EIO) +*(.text.remove_from_page_cache) +*(.text.rcu_start_batch) +*(.text.__put_task_struct) +*(.text.proc_pid_readdir) +*(.text.proc_get_inode) +*(.text.prepare_to_wait_exclusive) +*(.text.pipe_wait) +*(.text.pipe_new) +*(.text.pdflush_operation) +*(.text.__pagevec_release) +*(.text.pagevec_lookup_tag) +*(.text.packet_rcv) +*(.text.n_tty_set_room) +*(.text.nr_free_pages) +*(.text.__net_timestamp) +*(.text.mpage_end_io_read) +*(.text.mod_timer) +*(.text.__memcpy) +*(.text.mb_cache_shrink_fn) +*(.text.lock_rename) +*(.text.kstrdup) +*(.text.is_ignored) +*(.text.int_very_careful) +*(.text.inotify_inode_is_dead) +*(.text.inotify_get_cookie) +*(.text.inode_get_bytes) +*(.text.init_timer) +*(.text.init_dev) +*(.text.inet_getname) +*(.text.ide_map_sg) +*(.text.__ide_dma_end) +*(.text.hrtimer_get_remaining) +*(.text.get_task_mm) +*(.text.get_random_int) +*(.text.free_pipe_info) +*(.text.filemap_write_and_wait_range) +*(.text.exit_thread) +*(.text.enter_idle) +*(.text.end_that_request_first) +*(.text.end_8259A_irq) +*(.text.dummy_file_alloc_security) +*(.text.do_group_exit) +*(.text.debug_mutex_init) +*(.text.cpuset_exit) +*(.text.cpu_idle) +*(.text.copy_semundo) +*(.text.copy_files) +*(.text.chrdev_open) +*(.text.cdrom_transfer_packet_command) +*(.text.cdrom_mode_sense) +*(.text.blk_phys_contig_segment) +*(.text.blk_get_queue) +*(.text.bio_split) +*(.text.audit_alloc) +*(.text.anon_pipe_buf_release) +*(.text.add_wait_queue_exclusive) +*(.text.add_wait_queue) +*(.text.acct_process) +*(.text.account) +*(.text.zeromap_page_range) +*(.text.yield) +*(.text.writeback_acquire) +*(.text.worker_thread) +*(.text.wait_on_page_writeback_range) +*(.text.__wait_on_buffer) +*(.text.vscnprintf) +*(.text.vmalloc_to_pfn) +*(.text.vgacon_save_screen) +*(.text.vfs_unlink) +*(.text.vfs_rmdir) +*(.text.unregister_md_personality) +*(.text.unlock_new_inode) +*(.text.unix_stream_sendmsg) +*(.text.unix_stream_recvmsg) +*(.text.unhash_process) +*(.text.udp_v4_lookup_longway) +*(.text.tty_ldisc_flush) +*(.text.tty_ldisc_enable) +*(.text.tty_hung_up_p) +*(.text.tty_buffer_free_all) +*(.text.tso_fragment) +*(.text.try_to_del_timer_sync) +*(.text.tcp_v4_err) +*(.text.tcp_unhash) +*(.text.tcp_seq_next) +*(.text.tcp_select_initial_window) +*(.text.tcp_sacktag_write_queue) +*(.text.tcp_cwnd_validate) +*(.text.sys_vhangup) +*(.text.sys_uselib) +*(.text.sys_symlink) +*(.text.sys_signal) +*(.text.sys_poll) +*(.text.sys_mount) +*(.text.sys_kill) +*(.text.sys_ioctl) +*(.text.sys_inotify_add_watch) +*(.text.sys_getuid) +*(.text.sys_getrlimit) +*(.text.sys_getitimer) +*(.text.sys_getgroups) +*(.text.sys_ftruncate) +*(.text.sysfs_lookup) +*(.text.sys_exit_group) +*(.text.stub_fork) +*(.text.sscanf) +*(.text.sock_map_fd) +*(.text.sock_get_timestamp) +*(.text.__sock_create) +*(.text.smp_call_function_single) +*(.text.sk_stop_timer) +*(.text.skb_copy_and_csum_datagram) +*(.text.__skb_checksum_complete) +*(.text.single_next) +*(.text.sigqueue_alloc) +*(.text.shrink_dcache_parent) +*(.text.select_idle_routine) +*(.text.run_workqueue) +*(.text.run_local_timers) +*(.text.remove_inode_hash) +*(.text.remove_dquot_ref) +*(.text.register_binfmt) +*(.text.read_cache_pages) +*(.text.rb_last) +*(.text.pty_open) +*(.text.proc_root_readdir) +*(.text.proc_pid_flush) +*(.text.proc_pident_lookup) +*(.text.proc_fill_super) +*(.text.proc_exe_link) +*(.text.posix_locks_deadlock) +*(.text.pipe_iov_copy_from_user) +*(.text.opost) +*(.text.nf_register_hook) +*(.text.netif_rx_ni) +*(.text.m_start) +*(.text.mpage_writepage) +*(.text.mm_alloc) +*(.text.memory_open) +*(.text.mark_buffer_async_write) +*(.text.lru_add_drain_all) +*(.text.locks_init_lock) +*(.text.locks_delete_lock) +*(.text.lock_hrtimer_base) +*(.text.load_script) +*(.text.__kill_fasync) +*(.text.ip_mc_sf_allow) +*(.text.__ioremap) +*(.text.int_with_check) +*(.text.int_sqrt) +*(.text.install_thread_keyring) +*(.text.init_page_buffers) +*(.text.inet_sock_destruct) +*(.text.idle_notifier_register) +*(.text.ide_execute_command) +*(.text.ide_end_drive_cmd) +*(.text.__ide_dma_host_on) +*(.text.hrtimer_run_queues) +*(.text.hpet_mask_rtc_irq_bit) +*(.text.__get_zone_counts) +*(.text.get_zone_counts) +*(.text.get_write_access) +*(.text.get_fs_struct) +*(.text.get_dirty_limits) +*(.text.generic_readlink) +*(.text.free_hot_page) +*(.text.finish_wait) +*(.text.find_inode) +*(.text.find_first_bit) +*(.text.__filemap_fdatawrite_range) +*(.text.__filemap_copy_from_user_iovec) +*(.text.exit_aio) +*(.text.elv_set_request) +*(.text.elv_former_request) +*(.text.dup_namespace) +*(.text.dupfd) +*(.text.dummy_socket_getsockopt) +*(.text.dummy_sb_post_mountroot) +*(.text.dummy_quotactl) +*(.text.dummy_inode_rename) +*(.text.__do_SAK) +*(.text.do_pipe) +*(.text.do_fsync) +*(.text.d_instantiate_unique) +*(.text.d_find_alias) +*(.text.deny_write_access) +*(.text.dentry_unhash) +*(.text.d_delete) +*(.text.datagram_poll) +*(.text.cpuset_fork) +*(.text.cpuid_read) +*(.text.copy_namespace) +*(.text.cond_resched) +*(.text.check_version) +*(.text.__change_page_attr) +*(.text.cfq_slab_kill) +*(.text.cfq_completed_request) +*(.text.cdrom_pc_intr) +*(.text.cdrom_decode_status) +*(.text.cap_capset_check) +*(.text.blk_put_request) +*(.text.bio_fs_destructor) +*(.text.bictcp_min_cwnd) +*(.text.alloc_chrdev_region) +*(.text.add_element) +*(.text.acct_update_integrals) +*(.text.write_boundary_block) +*(.text.writeback_release) +*(.text.writeback_inodes) +*(.text.wake_up_state) +*(.text.__wake_up_locked) +*(.text.wake_futex) +*(.text.wait_task_inactive) +*(.text.__wait_on_freeing_inode) +*(.text.wait_noreap_copyout) +*(.text.vmstat_start) +*(.text.vgacon_do_font_op) +*(.text.vfs_readv) +*(.text.vfs_quota_sync) +*(.text.update_queue) +*(.text.unshare_files) +*(.text.unmap_vm_area) +*(.text.unix_socketpair) +*(.text.unix_release_sock) +*(.text.unix_detach_fds) +*(.text.unix_create1) +*(.text.unix_bind) +*(.text.udp_sendmsg) +*(.text.udp_rcv) +*(.text.udp_queue_rcv_skb) +*(.text.uart_write) +*(.text.uart_startup) +*(.text.uart_open) +*(.text.tty_vhangup) +*(.text.tty_termios_baud_rate) +*(.text.tty_release) +*(.text.tty_ldisc_ref) +*(.text.throttle_vm_writeout) +*(.text.058) +*(.text.tcp_xmit_probe_skb) +*(.text.tcp_v4_send_check) +*(.text.tcp_v4_destroy_sock) +*(.text.tcp_sync_mss) +*(.text.tcp_snd_test) +*(.text.tcp_slow_start) +*(.text.tcp_send_fin) +*(.text.tcp_rtt_estimator) +*(.text.tcp_parse_options) +*(.text.tcp_ioctl) +*(.text.tcp_init_tso_segs) +*(.text.tcp_init_cwnd) +*(.text.tcp_getsockopt) +*(.text.tcp_fin) +*(.text.tcp_connect) +*(.text.tcp_cong_avoid) +*(.text.__tcp_checksum_complete_user) +*(.text.task_dumpable) +*(.text.sys_wait4) +*(.text.sys_utimes) +*(.text.sys_symlinkat) +*(.text.sys_socketpair) +*(.text.sys_rmdir) +*(.text.sys_readahead) +*(.text.sys_nanosleep) +*(.text.sys_linkat) +*(.text.sys_fstat) +*(.text.sysfs_readdir) +*(.text.sys_execve) +*(.text.sysenter_tracesys) +*(.text.sys_chown) +*(.text.stub_clone) +*(.text.strrchr) +*(.text.strncpy) +*(.text.stopmachine_set_state) +*(.text.sock_sendmsg) +*(.text.sock_release) +*(.text.sock_fasync) +*(.text.sock_close) +*(.text.sk_stream_write_space) +*(.text.sk_reset_timer) +*(.text.skb_split) +*(.text.skb_recv_datagram) +*(.text.skb_queue_tail) +*(.text.sk_attach_filter) +*(.text.si_swapinfo) +*(.text.simple_strtoll) +*(.text.set_termios) +*(.text.set_task_comm) +*(.text.set_shrinker) +*(.text.set_normalized_timespec) +*(.text.set_brk) +*(.text.serial_in) +*(.text.seq_printf) +*(.text.secure_dccp_sequence_number) +*(.text.rwlock_bug) +*(.text.rt_hash_code) +*(.text.__rta_fill) +*(.text.__request_resource) +*(.text.relocate_new_kernel) +*(.text.release_thread) +*(.text.release_mem) +*(.text.rb_prev) +*(.text.rb_first) +*(.text.random_poll) +*(.text.__put_super_and_need_restart) +*(.text.pty_write) +*(.text.ptrace_stop) +*(.text.proc_self_readlink) +*(.text.proc_root_lookup) +*(.text.proc_root_link) +*(.text.proc_pid_make_inode) +*(.text.proc_pid_attr_write) +*(.text.proc_lookupfd) +*(.text.proc_delete_inode) +*(.text.posix_same_owner) +*(.text.posix_block_lock) +*(.text.poll_initwait) +*(.text.pipe_write) +*(.text.pipe_read_fasync) +*(.text.pipe_ioctl) +*(.text.pdflush) +*(.text.pci_user_read_config_dword) +*(.text.page_readlink) +*(.text.null_lseek) +*(.text.nf_hook_slow) +*(.text.netlink_sock_destruct) +*(.text.netlink_broadcast) +*(.text.neigh_resolve_output) +*(.text.name_to_int) +*(.text.mwait_idle) +*(.text.mutex_trylock) +*(.text.mutex_debug_check_no_locks_held) +*(.text.m_stop) +*(.text.mpage_end_io_write) +*(.text.mpage_alloc) +*(.text.move_page_tables) +*(.text.mounts_open) +*(.text.__memset) +*(.text.memcpy_fromiovec) +*(.text.make_8259A_irq) +*(.text.lookup_user_key_possessed) +*(.text.lookup_create) +*(.text.locks_insert_lock) +*(.text.locks_alloc_lock) +*(.text.kthread_should_stop) +*(.text.kswapd) +*(.text.kobject_uevent) +*(.text.kobject_get_path) +*(.text.kobject_get) +*(.text.klist_children_put) +*(.text.__ip_route_output_key) +*(.text.ip_flush_pending_frames) +*(.text.ip_compute_csum) +*(.text.ip_append_data) +*(.text.ioc_set_batching) +*(.text.invalidate_inode_pages) +*(.text.__invalidate_device) +*(.text.install_arg_page) +*(.text.in_sched_functions) +*(.text.inotify_unmount_inodes) +*(.text.init_once) +*(.text.init_cdrom_command) +*(.text.inet_stream_connect) +*(.text.inet_sk_rebuild_header) +*(.text.inet_csk_addr2sockaddr) +*(.text.inet_create) +*(.text.ifind) +*(.text.ide_setup_dma) +*(.text.ide_outsw) +*(.text.ide_fixstring) +*(.text.ide_dma_setup) +*(.text.ide_cdrom_packet) +*(.text.ide_cd_put) +*(.text.ide_build_sglist) +*(.text.i8259A_shutdown) +*(.text.hung_up_tty_ioctl) +*(.text.hrtimer_nanosleep) +*(.text.hrtimer_init) +*(.text.hrtimer_cancel) +*(.text.hash_futex) +*(.text.group_send_sig_info) +*(.text.grab_cache_page_nowait) +*(.text.get_wchan) +*(.text.get_stack) +*(.text.get_page_state) +*(.text.getnstimeofday) +*(.text.get_node) +*(.text.get_kprobe) +*(.text.generic_unplug_device) +*(.text.free_task) +*(.text.frag_show) +*(.text.find_next_zero_string) +*(.text.filp_open) +*(.text.fillonedir) +*(.text.exit_io_context) +*(.text.exit_idle) +*(.text.exact_lock) +*(.text.eth_header) +*(.text.dummy_unregister_security) +*(.text.dummy_socket_post_create) +*(.text.dummy_socket_listen) +*(.text.dummy_quota_on) +*(.text.dummy_inode_follow_link) +*(.text.dummy_file_receive) +*(.text.dummy_file_mprotect) +*(.text.dummy_file_lock) +*(.text.dummy_file_ioctl) +*(.text.dummy_bprm_post_apply_creds) +*(.text.do_writepages) +*(.text.__down_interruptible) +*(.text.do_notify_resume) +*(.text.do_acct_process) +*(.text.del_timer_sync) +*(.text.default_rebuild_header) +*(.text.d_callback) +*(.text.dcache_readdir) +*(.text.ctrl_dumpfamily) +*(.text.cpuset_rmdir) +*(.text.copy_strings_kernel) +*(.text.con_write_room) +*(.text.complete_all) +*(.text.collect_sigign_sigcatch) +*(.text.clear_user) +*(.text.check_unthrottle) +*(.text.cdrom_release) +*(.text.cdrom_newpc_intr) +*(.text.cdrom_ioctl) +*(.text.cdrom_check_status) +*(.text.cdev_put) +*(.text.cdev_add) +*(.text.cap_ptrace) +*(.text.cap_bprm_secureexec) +*(.text.cache_alloc_refill) +*(.text.bmap) +*(.text.blk_run_queue) +*(.text.blk_queue_dma_alignment) +*(.text.blk_ordered_req_seq) +*(.text.blk_backing_dev_unplug) +*(.text.__bitmap_subset) +*(.text.__bitmap_and) +*(.text.bio_unmap_user) +*(.text.__bforget) +*(.text.bd_forget) +*(.text.bad_pipe_w) +*(.text.bad_get_user) +*(.text.audit_free) +*(.text.anon_vma_ctor) +*(.text.anon_pipe_buf_map) +*(.text.alloc_sock_iocb) +*(.text.alloc_fdset) +*(.text.aio_kick_handler) +*(.text.__add_entropy_words) +*(.text.add_disk_randomness) diff --git a/trunk/arch/x86_64/kernel/genapic.c b/trunk/arch/x86_64/kernel/genapic.c index 47496a40e84f..0b3603adf56d 100644 --- a/trunk/arch/x86_64/kernel/genapic.c +++ b/trunk/arch/x86_64/kernel/genapic.c @@ -11,54 +11,120 @@ #include #include #include -#include #include #include #include +#include #include #include -#include -#ifdef CONFIG_ACPI +#if defined(CONFIG_ACPI) #include #endif /* which logical CPU number maps to which CPU (physical APIC ID) */ -u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly - = { [0 ... NR_CPUS-1] = BAD_APICID }; +u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID }; EXPORT_SYMBOL(x86_cpu_to_apicid); +u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; -u8 x86_cpu_to_log_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; +extern struct genapic apic_cluster; +extern struct genapic apic_flat; +extern struct genapic apic_physflat; -struct genapic __read_mostly *genapic = &apic_flat; +struct genapic *genapic = &apic_flat; +struct genapic *genapic_force; /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. */ -void __init setup_apic_routing(void) +void __init clustered_apic_check(void) { -#ifdef CONFIG_ACPI + long i; + u8 clusters, max_cluster; + u8 id; + u8 cluster_cnt[NUM_APIC_CLUSTERS]; + int max_apic = 0; + + /* genapic selection can be forced because of certain quirks. + */ + if (genapic_force) { + genapic = genapic_force; + goto print; + } + +#if defined(CONFIG_ACPI) /* - * Quirk: some x86_64 machines can only use physical APIC mode - * regardless of how many processors are present (x86_64 ES7000 - * is an example). + * Some x86_64 machines use physical APIC mode regardless of how many + * procs/clusters are present (x86_64 ES7000 is an example). */ - if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID && - (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) + if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID) + if (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) { + genapic = &apic_cluster; + goto print; + } +#endif + + memset(cluster_cnt, 0, sizeof(cluster_cnt)); + for (i = 0; i < NR_CPUS; i++) { + id = bios_cpu_apicid[i]; + if (id == BAD_APICID) + continue; + if (id > max_apic) + max_apic = id; + cluster_cnt[APIC_CLUSTERID(id)]++; + } + + /* Don't use clustered mode on AMD platforms. */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { genapic = &apic_physflat; - else +#ifndef CONFIG_HOTPLUG_CPU + /* In the CPU hotplug case we cannot use broadcast mode + because that opens a race when a CPU is removed. + Stay at physflat mode in this case. + It is bad to do this unconditionally though. Once + we have ACPI platform support for CPU hotplug + we should detect hotplug capablity from ACPI tables and + only do this when really needed. -AK */ + if (max_apic <= 8) + genapic = &apic_flat; #endif + goto print; + } - if (cpus_weight(cpu_possible_map) <= 8) - genapic = &apic_flat; - else + clusters = 0; + max_cluster = 0; + + for (i = 0; i < NUM_APIC_CLUSTERS; i++) { + if (cluster_cnt[i] > 0) { + ++clusters; + if (cluster_cnt[i] > max_cluster) + max_cluster = cluster_cnt[i]; + } + } + + /* + * If we have clusters <= 1 and CPUs <= 8 in cluster 0, then flat mode, + * else if max_cluster <= 4 and cluster_cnt[15] == 0, clustered logical + * else physical mode. + * (We don't use lowest priority delivery + HW APIC IRQ steering, so + * can ignore the clustered logical case and go straight to physical.) + */ + if (clusters <= 1 && max_cluster <= 8 && cluster_cnt[0] == max_cluster) { +#ifdef CONFIG_HOTPLUG_CPU + /* Don't use APIC shortcuts in CPU hotplug to avoid races */ genapic = &apic_physflat; +#else + genapic = &apic_flat; +#endif + } else + genapic = &apic_cluster; +print: printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name); } -/* Same for both flat and physical. */ +/* Same for both flat and clustered. */ void send_IPI_self(int vector) { diff --git a/trunk/arch/x86_64/kernel/genapic_cluster.c b/trunk/arch/x86_64/kernel/genapic_cluster.c new file mode 100644 index 000000000000..73d76308b955 --- /dev/null +++ b/trunk/arch/x86_64/kernel/genapic_cluster.c @@ -0,0 +1,137 @@ +/* + * Copyright 2004 James Cleverdon, IBM. + * Subject to the GNU Public License, v.2 + * + * Clustered APIC subarch code. Up to 255 CPUs, physical delivery. + * (A more realistic maximum is around 230 CPUs.) + * + * Hacked for x86-64 by James Cleverdon from i386 architecture code by + * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and + * James Cleverdon. + */ +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * Set up the logical destination ID. + * + * Intel recommends to set DFR, LDR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ +static void cluster_init_apic_ldr(void) +{ + unsigned long val, id; + long i, count; + u8 lid; + u8 my_id = hard_smp_processor_id(); + u8 my_cluster = APIC_CLUSTER(my_id); + + /* Create logical APIC IDs by counting CPUs already in cluster. */ + for (count = 0, i = NR_CPUS; --i >= 0; ) { + lid = x86_cpu_to_log_apicid[i]; + if (lid != BAD_APICID && APIC_CLUSTER(lid) == my_cluster) + ++count; + } + /* + * We only have a 4 wide bitmap in cluster mode. There's no way + * to get above 60 CPUs and still give each one it's own bit. + * But, we're using physical IRQ delivery, so we don't care. + * Use bit 3 for the 4th through Nth CPU in each cluster. + */ + if (count >= XAPIC_DEST_CPUS_SHIFT) + count = 3; + id = my_cluster | (1UL << count); + x86_cpu_to_log_apicid[smp_processor_id()] = id; + apic_write(APIC_DFR, APIC_DFR_CLUSTER); + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; + val |= SET_APIC_LOGICAL_ID(id); + apic_write(APIC_LDR, val); +} + +/* Start with all IRQs pointing to boot CPU. IRQ balancing will shift them. */ + +static cpumask_t cluster_target_cpus(void) +{ + return cpumask_of_cpu(0); +} + +static cpumask_t cluster_vector_allocation_domain(int cpu) +{ + cpumask_t domain = CPU_MASK_NONE; + cpu_set(cpu, domain); + return domain; +} + +static void cluster_send_IPI_mask(cpumask_t mask, int vector) +{ + send_IPI_mask_sequence(mask, vector); +} + +static void cluster_send_IPI_allbutself(int vector) +{ + cpumask_t mask = cpu_online_map; + + cpu_clear(smp_processor_id(), mask); + + if (!cpus_empty(mask)) + cluster_send_IPI_mask(mask, vector); +} + +static void cluster_send_IPI_all(int vector) +{ + cluster_send_IPI_mask(cpu_online_map, vector); +} + +static int cluster_apic_id_registered(void) +{ + return 1; +} + +static unsigned int cluster_cpu_mask_to_apicid(cpumask_t cpumask) +{ + int cpu; + + /* + * We're using fixed IRQ delivery, can only return one phys APIC ID. + * May as well be the first. + */ + cpu = first_cpu(cpumask); + if ((unsigned)cpu < NR_CPUS) + return x86_cpu_to_apicid[cpu]; + else + return BAD_APICID; +} + +/* cpuid returns the value latched in the HW at reset, not the APIC ID + * register's value. For any box whose BIOS changes APIC IDs, like + * clustered APIC systems, we must use hard_smp_processor_id. + * + * See Intel's IA-32 SW Dev's Manual Vol2 under CPUID. + */ +static unsigned int phys_pkg_id(int index_msb) +{ + return hard_smp_processor_id() >> index_msb; +} + +struct genapic apic_cluster = { + .name = "clustered", + .int_delivery_mode = dest_Fixed, + .int_dest_mode = (APIC_DEST_PHYSICAL != 0), + .target_cpus = cluster_target_cpus, + .vector_allocation_domain = cluster_vector_allocation_domain, + .apic_id_registered = cluster_apic_id_registered, + .init_apic_ldr = cluster_init_apic_ldr, + .send_IPI_all = cluster_send_IPI_all, + .send_IPI_allbutself = cluster_send_IPI_allbutself, + .send_IPI_mask = cluster_send_IPI_mask, + .cpu_mask_to_apicid = cluster_cpu_mask_to_apicid, + .phys_pkg_id = phys_pkg_id, +}; diff --git a/trunk/arch/x86_64/kernel/genapic_flat.c b/trunk/arch/x86_64/kernel/genapic_flat.c index ecb01eefdd27..7c01db8fa9d1 100644 --- a/trunk/arch/x86_64/kernel/genapic_flat.c +++ b/trunk/arch/x86_64/kernel/genapic_flat.c @@ -8,7 +8,6 @@ * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and * James Cleverdon. */ -#include #include #include #include @@ -17,7 +16,6 @@ #include #include #include -#include static cpumask_t flat_target_cpus(void) { @@ -62,10 +60,31 @@ static void flat_init_apic_ldr(void) static void flat_send_IPI_mask(cpumask_t cpumask, int vector) { unsigned long mask = cpus_addr(cpumask)[0]; + unsigned long cfg; unsigned long flags; local_irq_save(flags); - __send_IPI_dest_field(mask, vector, APIC_DEST_LOGICAL); + + /* + * Wait for idle. + */ + apic_wait_icr_idle(); + + /* + * prepare target chip field + */ + cfg = __prepare_ICR2(mask); + apic_write(APIC_ICR2, cfg); + + /* + * program the ICR + */ + cfg = __prepare_ICR(0, vector, APIC_DEST_LOGICAL); + + /* + * Send the IPI. The write to APIC_ICR fires this off. + */ + apic_write(APIC_ICR, cfg); local_irq_restore(flags); } diff --git a/trunk/arch/x86_64/kernel/head.S b/trunk/arch/x86_64/kernel/head.S index 1fab487dee86..598a4d0351fc 100644 --- a/trunk/arch/x86_64/kernel/head.S +++ b/trunk/arch/x86_64/kernel/head.S @@ -5,7 +5,6 @@ * Copyright (C) 2000 Pavel Machek * Copyright (C) 2000 Karsten Keil * Copyright (C) 2001,2002 Andi Kleen - * Copyright (C) 2005 Eric Biederman */ @@ -14,131 +13,97 @@ #include #include #include -#include #include #include #include - + /* we are not able to switch in one step to the final KERNEL ADRESS SPACE - * because we need identity-mapped pages. - * + * because we need identity-mapped pages on setup so define __START_KERNEL to + * 0x100000 for this stage + * */ .text .section .bootstrap.text - .code64 - .globl startup_64 -startup_64: - + .code32 + .globl startup_32 +/* %bx: 1 if coming from smp trampoline on secondary cpu */ +startup_32: + /* - * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 1, - * and someone has loaded an identity mapped page table - * for us. These identity mapped page tables map all of the - * kernel pages and possibly all of memory. - * - * %esi holds a physical pointer to real_mode_data. - * - * We come here either directly from a 64bit bootloader, or from - * arch/x86_64/boot/compressed/head.S. - * - * We only come here initially at boot nothing else comes here. - * - * Since we may be loaded at an address different from what we were - * compiled to run at we first fixup the physical addresses in our page - * tables and then reload them. + * At this point the CPU runs in 32bit protected mode (CS.D = 1) with + * paging disabled and the point of this file is to switch to 64bit + * long mode with a kernel mapping for kerneland to jump into the + * kernel virtual addresses. + * There is no stack until we set one up. */ - /* Compute the delta between the address I am compiled to run at and the - * address I am actually running at. - */ - leaq _text(%rip), %rbp - subq $_text - __START_KERNEL_map, %rbp - - /* Is the address not 2M aligned? */ - movq %rbp, %rax - andl $~LARGE_PAGE_MASK, %eax - testl %eax, %eax - jnz bad_address - - /* Is the address too large? */ - leaq _text(%rip), %rdx - movq $PGDIR_SIZE, %rax - cmpq %rax, %rdx - jae bad_address - - /* Fixup the physical addresses in the page table + /* Initialize the %ds segment register */ + movl $__KERNEL_DS,%eax + movl %eax,%ds + + /* Load new GDT with the 64bit segments using 32bit descriptor */ + lgdt pGDT32 - __START_KERNEL_map + + /* If the CPU doesn't support CPUID this will double fault. + * Unfortunately it is hard to check for CPUID without a stack. */ - addq %rbp, init_level4_pgt + 0(%rip) - addq %rbp, init_level4_pgt + (258*8)(%rip) - addq %rbp, init_level4_pgt + (511*8)(%rip) - - addq %rbp, level3_ident_pgt + 0(%rip) - addq %rbp, level3_kernel_pgt + (510*8)(%rip) - - /* Add an Identity mapping if I am above 1G */ - leaq _text(%rip), %rdi - andq $LARGE_PAGE_MASK, %rdi - - movq %rdi, %rax - shrq $PUD_SHIFT, %rax - andq $(PTRS_PER_PUD - 1), %rax - jz ident_complete - - leaq (level2_spare_pgt - __START_KERNEL_map + _KERNPG_TABLE)(%rbp), %rdx - leaq level3_ident_pgt(%rip), %rbx - movq %rdx, 0(%rbx, %rax, 8) - - movq %rdi, %rax - shrq $PMD_SHIFT, %rax - andq $(PTRS_PER_PMD - 1), %rax - leaq __PAGE_KERNEL_LARGE_EXEC(%rdi), %rdx - leaq level2_spare_pgt(%rip), %rbx - movq %rdx, 0(%rbx, %rax, 8) -ident_complete: - - /* Fixup the kernel text+data virtual addresses + + /* Check if extended functions are implemented */ + movl $0x80000000, %eax + cpuid + cmpl $0x80000000, %eax + jbe no_long_mode + /* Check if long mode is implemented */ + mov $0x80000001, %eax + cpuid + btl $29, %edx + jnc no_long_mode + + /* + * Prepare for entering 64bits mode */ - leaq level2_kernel_pgt(%rip), %rdi - leaq 4096(%rdi), %r8 - /* See if it is a valid page table entry */ -1: testq $1, 0(%rdi) - jz 2f - addq %rbp, 0(%rdi) - /* Go to the next page */ -2: addq $8, %rdi - cmp %r8, %rdi - jne 1b - - /* Fixup phys_base */ - addq %rbp, phys_base(%rip) -#ifdef CONFIG_SMP - addq %rbp, trampoline_level4_pgt + 0(%rip) - addq %rbp, trampoline_level4_pgt + (511*8)(%rip) -#endif -#ifdef CONFIG_ACPI_SLEEP - addq %rbp, wakeup_level4_pgt + 0(%rip) - addq %rbp, wakeup_level4_pgt + (511*8)(%rip) -#endif + /* Enable PAE mode */ + xorl %eax, %eax + btsl $5, %eax + movl %eax, %cr4 - /* Due to ENTRY(), sometimes the empty space gets filled with - * zeros. Better take a jmp than relying on empty space being - * filled with 0x90 (nop) - */ - jmp secondary_startup_64 -ENTRY(secondary_startup_64) + /* Setup early boot stage 4 level pagetables */ + movl $(boot_level4_pgt - __START_KERNEL_map), %eax + movl %eax, %cr3 + + /* Setup EFER (Extended Feature Enable Register) */ + movl $MSR_EFER, %ecx + rdmsr + + /* Enable Long Mode */ + btsl $_EFER_LME, %eax + + /* Make changes effective */ + wrmsr + + xorl %eax, %eax + btsl $31, %eax /* Enable paging and in turn activate Long Mode */ + btsl $0, %eax /* Enable protected mode */ + /* Make changes effective */ + movl %eax, %cr0 /* - * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 1, - * and someone has loaded a mapped page table. - * - * %esi holds a physical pointer to real_mode_data. - * - * We come here either from startup_64 (using physical addresses) - * or from trampoline.S (using virtual addresses). - * - * Using virtual addresses from trampoline.S removes the need - * to have any identity mapped pages in the kernel page table - * after the boot processor executes this code. + * At this point we're in long mode but in 32bit compatibility mode + * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn + * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use + * the new gdt/idt that has __KERNEL_CS with CS.L = 1. + */ + ljmp $__KERNEL_CS, $(startup_64 - __START_KERNEL_map) + + .code64 + .org 0x100 + .globl startup_64 +startup_64: + /* We come here either from startup_32 + * or directly from a 64bit bootloader. + * Since we may have come directly from a bootloader we + * reload the page tables here. */ /* Enable PAE mode and PGE */ @@ -148,15 +113,9 @@ ENTRY(secondary_startup_64) movq %rax, %cr4 /* Setup early boot stage 4 level pagetables. */ - movq $(init_level4_pgt - __START_KERNEL_map), %rax - addq phys_base(%rip), %rax + movq $(boot_level4_pgt - __START_KERNEL_map), %rax movq %rax, %cr3 - /* Ensure I am executing from virtual addresses */ - movq $1f, %rax - jmp *%rax -1: - /* Check if nx is implemented */ movl $0x80000001, %eax cpuid @@ -165,11 +124,17 @@ ENTRY(secondary_startup_64) /* Setup EFER (Extended Feature Enable Register) */ movl $MSR_EFER, %ecx rdmsr - btsl $_EFER_SCE, %eax /* Enable System Call */ - btl $20,%edi /* No Execute supported? */ + + /* Enable System Call */ + btsl $_EFER_SCE, %eax + + /* No Execute supported? */ + btl $20,%edi jnc 1f btsl $_EFER_NX, %eax -1: wrmsr /* Make changes effective */ +1: + /* Make changes effective */ + wrmsr /* Setup cr0 */ #define CR0_PM 1 /* protected mode */ @@ -196,7 +161,7 @@ ENTRY(secondary_startup_64) * addresses where we're currently running on. We have to do that here * because in 32bit we couldn't load a 64bit linear address. */ - lgdt cpu_gdt_descr(%rip) + lgdt cpu_gdt_descr /* set up data segments. actually 0 would do too */ movl $__KERNEL_DS,%eax @@ -247,9 +212,6 @@ initial_code: init_rsp: .quad init_thread_union+THREAD_SIZE-8 -bad_address: - jmp bad_address - ENTRY(early_idt_handler) cmpl $2,early_recursion_flag(%rip) jz 1f @@ -278,66 +240,110 @@ early_idt_msg: early_idt_ripmsg: .asciz "RIP %s\n" -.balign PAGE_SIZE +.code32 +ENTRY(no_long_mode) + /* This isn't an x86-64 CPU so hang */ +1: + jmp 1b + +.org 0xf00 + .globl pGDT32 +pGDT32: + .word gdt_end-cpu_gdt_table-1 + .long cpu_gdt_table-__START_KERNEL_map + +.org 0xf10 +ljumpvector: + .long startup_64-__START_KERNEL_map + .word __KERNEL_CS +ENTRY(stext) +ENTRY(_stext) + + $page = 0 #define NEXT_PAGE(name) \ - .balign PAGE_SIZE; \ + $page = $page + 1; \ + .org $page * 0x1000; \ + phys_/**/name = $page * 0x1000 + __PHYSICAL_START; \ ENTRY(name) -/* Automate the creation of 1 to 1 mapping pmd entries */ -#define PMDS(START, PERM, COUNT) \ - i = 0 ; \ - .rept (COUNT) ; \ - .quad (START) + (i << 21) + (PERM) ; \ - i = i + 1 ; \ - .endr - - /* - * This default setting generates an ident mapping at address 0x100000 - * and a mapping for the kernel that precisely maps virtual address - * 0xffffffff80000000 to physical address 0x000000. (always using - * 2Mbyte large pages provided by PAE mode) - */ NEXT_PAGE(init_level4_pgt) - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE - .fill 257,8,0 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE - .fill 252,8,0 - /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE + /* This gets initialized in x86_64_start_kernel */ + .fill 512,8,0 NEXT_PAGE(level3_ident_pgt) - .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad phys_level2_ident_pgt | 0x007 .fill 511,8,0 NEXT_PAGE(level3_kernel_pgt) .fill 510,8,0 /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */ - .quad level2_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE + .quad phys_level2_kernel_pgt | 0x007 .fill 1,8,0 NEXT_PAGE(level2_ident_pgt) - /* Since I easily can, map the first 1G. - * Don't set NX because code runs from these pages. - */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC, PTRS_PER_PMD) - + /* 40MB for bootup. */ + i = 0 + .rept 20 + .quad i << 21 | 0x083 + i = i + 1 + .endr + /* Temporary mappings for the super early allocator in arch/x86_64/mm/init.c */ + .globl temp_boot_pmds +temp_boot_pmds: + .fill 492,8,0 + NEXT_PAGE(level2_kernel_pgt) /* 40MB kernel mapping. The kernel code cannot be bigger than that. When you change this change KERNEL_TEXT_SIZE in page.h too. */ /* (2^48-(2*1024*1024*1024)-((2^39)*511)-((2^30)*510)) = 0 */ - PMDS(0x0000000000000000, __PAGE_KERNEL_LARGE_EXEC|_PAGE_GLOBAL, - KERNEL_TEXT_SIZE/PMD_SIZE) + i = 0 + .rept 20 + .quad i << 21 | 0x183 + i = i + 1 + .endr /* Module mapping starts here */ - .fill (PTRS_PER_PMD - (KERNEL_TEXT_SIZE/PMD_SIZE)),8,0 + .fill 492,8,0 -NEXT_PAGE(level2_spare_pgt) - .fill 512,8,0 +NEXT_PAGE(level3_physmem_pgt) + .quad phys_level2_kernel_pgt | 0x007 /* so that __va works even before pagetable_init */ + .fill 511,8,0 -#undef PMDS #undef NEXT_PAGE .data + +#ifdef CONFIG_ACPI_SLEEP + .align PAGE_SIZE +ENTRY(wakeup_level4_pgt) + .quad phys_level3_ident_pgt | 0x007 + .fill 255,8,0 + .quad phys_level3_physmem_pgt | 0x007 + .fill 254,8,0 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ + .quad phys_level3_kernel_pgt | 0x007 +#endif + +#ifndef CONFIG_HOTPLUG_CPU + __INITDATA +#endif + /* + * This default setting generates an ident mapping at address 0x100000 + * and a mapping for the kernel that precisely maps virtual address + * 0xffffffff80000000 to physical address 0x000000. (always using + * 2Mbyte large pages provided by PAE mode) + */ + .align PAGE_SIZE +ENTRY(boot_level4_pgt) + .quad phys_level3_ident_pgt | 0x007 + .fill 255,8,0 + .quad phys_level3_physmem_pgt | 0x007 + .fill 254,8,0 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ + .quad phys_level3_kernel_pgt | 0x007 + + .data + .align 16 .globl cpu_gdt_descr cpu_gdt_descr: @@ -351,10 +357,6 @@ gdt: .endr #endif -ENTRY(phys_base) - /* This must match the first entry in level2_kernel_pgt */ - .quad 0x0000000000000000 - /* We need valid kernel segments for data and code in long mode too * IRET will check the segment types kkeil 2000/10/28 * Also sysret mandates a special GDT layout @@ -368,13 +370,13 @@ ENTRY(phys_base) ENTRY(cpu_gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ - .quad 0x00cf9b000000ffff /* __KERNEL32_CS */ - .quad 0x00af9b000000ffff /* __KERNEL_CS */ - .quad 0x00cf93000000ffff /* __KERNEL_DS */ - .quad 0x00cffb000000ffff /* __USER32_CS */ - .quad 0x00cff3000000ffff /* __USER_DS, __USER32_DS */ - .quad 0x00affb000000ffff /* __USER_CS */ .quad 0x0 /* unused */ + .quad 0x00af9a000000ffff /* __KERNEL_CS */ + .quad 0x00cf92000000ffff /* __KERNEL_DS */ + .quad 0x00cffa000000ffff /* __USER32_CS */ + .quad 0x00cff2000000ffff /* __USER_DS, __USER32_DS */ + .quad 0x00affa000000ffff /* __USER_CS */ + .quad 0x00cf9a000000ffff /* __KERNEL32_CS */ .quad 0,0 /* TSS */ .quad 0,0 /* LDT */ .quad 0,0,0 /* three TLS descriptors */ diff --git a/trunk/arch/x86_64/kernel/head64.c b/trunk/arch/x86_64/kernel/head64.c index 213d90e04755..5f197b0a330a 100644 --- a/trunk/arch/x86_64/kernel/head64.c +++ b/trunk/arch/x86_64/kernel/head64.c @@ -18,16 +18,8 @@ #include #include #include -#include #include -static void __init zap_identity_mappings(void) -{ - pgd_t *pgd = pgd_offset_k(0UL); - pgd_clear(pgd); - __flush_tlb(); -} - /* Don't add a printk in there. printk relies on the PDA which is not initialized yet. */ static void __init clear_bss(void) @@ -37,24 +29,25 @@ static void __init clear_bss(void) } #define NEW_CL_POINTER 0x228 /* Relative to real mode data */ -#define OLD_CL_MAGIC_ADDR 0x20 +#define OLD_CL_MAGIC_ADDR 0x90020 #define OLD_CL_MAGIC 0xA33F -#define OLD_CL_OFFSET 0x22 +#define OLD_CL_BASE_ADDR 0x90000 +#define OLD_CL_OFFSET 0x90022 static void __init copy_bootdata(char *real_mode_data) { - unsigned long new_data; + int new_data; char * command_line; memcpy(x86_boot_params, real_mode_data, BOOT_PARAM_SIZE); - new_data = *(u32 *) (x86_boot_params + NEW_CL_POINTER); + new_data = *(int *) (x86_boot_params + NEW_CL_POINTER); if (!new_data) { - if (OLD_CL_MAGIC != *(u16 *)(real_mode_data + OLD_CL_MAGIC_ADDR)) { + if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) { return; } - new_data = __pa(real_mode_data) + *(u16 *)(real_mode_data + OLD_CL_OFFSET); + new_data = OLD_CL_BASE_ADDR + * (u16 *) OLD_CL_OFFSET; } - command_line = __va(new_data); + command_line = (char *) ((u64)(new_data)); memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); } @@ -62,30 +55,26 @@ void __init x86_64_start_kernel(char * real_mode_data) { int i; - /* - * Make sure kernel is aligned to 2MB address. Catching it at compile - * time is better. Change your config file and compile the kernel - * for a 2MB aligned address (CONFIG_PHYSICAL_START) - */ - BUILD_BUG_ON(CONFIG_PHYSICAL_START & (__KERNEL_ALIGN - 1)); - /* clear bss before set_intr_gate with early_idt_handler */ clear_bss(); - /* Make NULL pointers segfault */ - zap_identity_mappings(); - for (i = 0; i < IDT_ENTRIES; i++) set_intr_gate(i, early_idt_handler); asm volatile("lidt %0" :: "m" (idt_descr)); early_printk("Kernel alive\n"); + /* + * switch to init_level4_pgt from boot_level4_pgt + */ + memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t)); + asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt))); + for (i = 0; i < NR_CPUS; i++) cpu_pda(i) = &boot_cpu_pda[i]; pda_init(0); - copy_bootdata(__va(real_mode_data)); + copy_bootdata(real_mode_data); #ifdef CONFIG_SMP cpu_set(0, cpu_online_map); #endif diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index 4b326655b208..489426682772 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index 4d582589fa89..c6a5bc7e8118 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -906,6 +907,10 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in enable_8259A_irq(0); } +void __init UNEXPECTED_IO_APIC(void) +{ +} + void __apicdebuginit print_IO_APIC(void) { int apic, i; @@ -941,16 +946,40 @@ void __apicdebuginit print_IO_APIC(void) printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid); printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); + if (reg_00.bits.__reserved_1 || reg_00.bits.__reserved_2) + UNEXPECTED_IO_APIC(); printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)®_01); printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries); + if ( (reg_01.bits.entries != 0x0f) && /* older (Neptune) boards */ + (reg_01.bits.entries != 0x17) && /* typical ISA+PCI boards */ + (reg_01.bits.entries != 0x1b) && /* Compaq Proliant boards */ + (reg_01.bits.entries != 0x1f) && /* dual Xeon boards */ + (reg_01.bits.entries != 0x22) && /* bigger Xeon boards */ + (reg_01.bits.entries != 0x2E) && + (reg_01.bits.entries != 0x3F) && + (reg_01.bits.entries != 0x03) + ) + UNEXPECTED_IO_APIC(); printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ); printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version); + if ( (reg_01.bits.version != 0x01) && /* 82489DX IO-APICs */ + (reg_01.bits.version != 0x02) && /* 82801BA IO-APICs (ICH2) */ + (reg_01.bits.version != 0x10) && /* oldest IO-APICs */ + (reg_01.bits.version != 0x11) && /* Pentium/Pro IO-APICs */ + (reg_01.bits.version != 0x13) && /* Xeon IO-APICs */ + (reg_01.bits.version != 0x20) /* Intel P64H (82806 AA) */ + ) + UNEXPECTED_IO_APIC(); + if (reg_01.bits.__reserved_1 || reg_01.bits.__reserved_2) + UNEXPECTED_IO_APIC(); if (reg_01.bits.version >= 0x10) { printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw); printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration); + if (reg_02.bits.__reserved_1 || reg_02.bits.__reserved_2) + UNEXPECTED_IO_APIC(); } printk(KERN_DEBUG ".... IRQ redirection table:\n"); @@ -1378,7 +1407,8 @@ static void irq_complete_move(unsigned int irq) vector = ~get_irq_regs()->orig_rax; me = smp_processor_id(); - if ((vector == cfg->vector) && cpu_isset(me, cfg->domain)) { + if ((vector == cfg->vector) && + cpu_isset(smp_processor_id(), cfg->domain)) { cpumask_t cleanup_mask; cpus_and(cleanup_mask, cfg->old_domain, cpu_online_map); @@ -1953,18 +1983,18 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) if (irq < 0) return irq; + set_irq_msi(irq, desc); ret = msi_compose_msg(dev, irq, &msg); if (ret < 0) { destroy_irq(irq); return ret; } - set_irq_msi(irq, desc); write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return 0; + return irq; } void arch_teardown_msi_irq(unsigned int irq) diff --git a/trunk/arch/x86_64/kernel/ioport.c b/trunk/arch/x86_64/kernel/ioport.c index 653efa30b0f4..745b1f0f494e 100644 --- a/trunk/arch/x86_64/kernel/ioport.c +++ b/trunk/arch/x86_64/kernel/ioport.c @@ -12,10 +12,10 @@ #include #include #include +#include #include #include #include -#include /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) diff --git a/trunk/arch/x86_64/kernel/kprobes.c b/trunk/arch/x86_64/kernel/kprobes.c index d4a0d0ac9935..209c8c0bec71 100644 --- a/trunk/arch/x86_64/kernel/kprobes.c +++ b/trunk/arch/x86_64/kernel/kprobes.c @@ -37,10 +37,10 @@ #include #include #include -#include #include #include +#include #include void jprobe_return_end(void); @@ -266,14 +266,23 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) } /* Called with kretprobe_lock held */ -void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, +void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)regs->rsp; + struct kretprobe_instance *ri; - ri->ret_addr = (kprobe_opcode_t *) *sara; - /* Replace the return addr with trampoline addr */ - *sara = (unsigned long) &kretprobe_trampoline; + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; + ri->ret_addr = (kprobe_opcode_t *) *sara; + + /* Replace the return addr with trampoline addr */ + *sara = (unsigned long) &kretprobe_trampoline; + add_rp_inst(ri); + } else { + rp->nmissed++; + } } int __kprobes kprobe_handler(struct pt_regs *regs) @@ -438,7 +447,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) break; } - kretprobe_assert(ri, orig_ret_address, trampoline_address); + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); regs->rip = orig_ret_address; reset_current_kprobe(); @@ -743,11 +752,3 @@ int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } - -int __kprobes arch_trampoline_kprobe(struct kprobe *p) -{ - if (p->addr == (kprobe_opcode_t *)&kretprobe_trampoline) - return 1; - - return 0; -} diff --git a/trunk/arch/x86_64/kernel/ldt.c b/trunk/arch/x86_64/kernel/ldt.c index bc9ffd5c19cc..d7e5d0cf4285 100644 --- a/trunk/arch/x86_64/kernel/ldt.c +++ b/trunk/arch/x86_64/kernel/ldt.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/x86_64/kernel/machine_kexec.c b/trunk/arch/x86_64/kernel/machine_kexec.c index c3a554703672..0497e3bd5bff 100644 --- a/trunk/arch/x86_64/kernel/machine_kexec.c +++ b/trunk/arch/x86_64/kernel/machine_kexec.c @@ -189,21 +189,21 @@ NORET_TYPE void machine_kexec(struct kimage *image) control_page = page_address(image->control_code_page) + PAGE_SIZE; memcpy(control_page, relocate_kernel, PAGE_SIZE); - page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page); + page_list[PA_CONTROL_PAGE] = __pa(control_page); page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = virt_to_phys(&kexec_pgd); + page_list[PA_PGD] = __pa(kexec_pgd); page_list[VA_PGD] = (unsigned long)kexec_pgd; - page_list[PA_PUD_0] = virt_to_phys(&kexec_pud0); + page_list[PA_PUD_0] = __pa(kexec_pud0); page_list[VA_PUD_0] = (unsigned long)kexec_pud0; - page_list[PA_PMD_0] = virt_to_phys(&kexec_pmd0); + page_list[PA_PMD_0] = __pa(kexec_pmd0); page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PTE_0] = virt_to_phys(&kexec_pte0); + page_list[PA_PTE_0] = __pa(kexec_pte0); page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PUD_1] = virt_to_phys(&kexec_pud1); + page_list[PA_PUD_1] = __pa(kexec_pud1); page_list[VA_PUD_1] = (unsigned long)kexec_pud1; - page_list[PA_PMD_1] = virt_to_phys(&kexec_pmd1); + page_list[PA_PMD_1] = __pa(kexec_pmd1); page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; - page_list[PA_PTE_1] = virt_to_phys(&kexec_pte1); + page_list[PA_PTE_1] = __pa(kexec_pte1); page_list[VA_PTE_1] = (unsigned long)kexec_pte1; page_list[PA_TABLE_PAGE] = diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index 442169640e45..8011a8e1c7d4 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -20,10 +20,10 @@ #include #include #include -#include #include #include #include +#include #include #include @@ -323,13 +323,10 @@ void mce_log_therm_throt_event(unsigned int cpu, __u64 status) #endif /* CONFIG_X86_MCE_INTEL */ /* - * Periodic polling timer for "silent" machine check errors. If the - * poller finds an MCE, poll 2x faster. When the poller finds no more - * errors, poll 2x slower (up to check_interval seconds). + * Periodic polling timer for "silent" machine check errors. */ static int check_interval = 5 * 60; /* 5 minutes */ -static int next_interval; /* in jiffies */ static void mcheck_timer(struct work_struct *work); static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer); @@ -342,6 +339,7 @@ static void mcheck_check_cpu(void *info) static void mcheck_timer(struct work_struct *work) { on_each_cpu(mcheck_check_cpu, NULL, 1, 1); + schedule_delayed_work(&mcheck_work, check_interval * HZ); /* * It's ok to read stale data here for notify_user and @@ -351,30 +349,17 @@ static void mcheck_timer(struct work_struct *work) * writes. */ if (notify_user && console_logged) { - static unsigned long last_print; - unsigned long now = jiffies; - - /* if we logged an MCE, reduce the polling interval */ - next_interval = max(next_interval/2, HZ/100); notify_user = 0; clear_bit(0, &console_logged); - if (time_after_eq(now, last_print + (check_interval*HZ))) { - last_print = now; - printk(KERN_INFO "Machine check events logged\n"); - } - } else { - next_interval = min(next_interval*2, check_interval*HZ); + printk(KERN_INFO "Machine check events logged\n"); } - - schedule_delayed_work(&mcheck_work, next_interval); } static __init int periodic_mcheck_init(void) { - next_interval = check_interval * HZ; - if (next_interval) - schedule_delayed_work(&mcheck_work, next_interval); + if (check_interval) + schedule_delayed_work(&mcheck_work, check_interval*HZ); return 0; } __initcall(periodic_mcheck_init); @@ -612,13 +597,12 @@ static int mce_resume(struct sys_device *dev) /* Reinit MCEs after user configuration changes */ static void mce_restart(void) { - if (next_interval) + if (check_interval) cancel_delayed_work(&mcheck_work); /* Timer race is harmless here */ on_each_cpu(mce_init, NULL, 1, 1); - next_interval = check_interval * HZ; - if (next_interval) - schedule_delayed_work(&mcheck_work, next_interval); + if (check_interval) + schedule_delayed_work(&mcheck_work, check_interval*HZ); } static struct sysdev_class mce_sysclass = { diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index 61ae57eb9e4c..455aa0b932f0 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -299,7 +300,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) } } } - setup_apic_routing(); + clustered_apic_check(); if (!num_processors) printk(KERN_ERR "MPTABLE: no processors registered!\n"); return num_processors; diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 931c64bad5e6..dfab9f167366 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -21,17 +21,34 @@ #include #include #include -#include #include #include #include +#include #include +#include int unknown_nmi_panic; int nmi_watchdog_enabled; int panic_on_unrecovered_nmi; +/* perfctr_nmi_owner tracks the ownership of the perfctr registers: + * evtsel_nmi_owner tracks the ownership of the event selection + * - different performance counters/ event selection may be reserved for + * different subsystems this reservation system just tries to coordinate + * things a little + */ + +/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's + * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) + */ +#define NMI_MAX_COUNTER_BITS 66 +#define NMI_MAX_COUNTER_LONGS BITS_TO_LONGS(NMI_MAX_COUNTER_BITS) + +static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner[NMI_MAX_COUNTER_LONGS]); +static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[NMI_MAX_COUNTER_LONGS]); + static cpumask_t backtrace_mask = CPU_MASK_NONE; /* nmi_active: @@ -46,11 +63,191 @@ int panic_on_timeout; unsigned int nmi_watchdog = NMI_DEFAULT; static unsigned int nmi_hz = HZ; -static DEFINE_PER_CPU(short, wd_enabled); +struct nmi_watchdog_ctlblk { + int enabled; + u64 check_bit; + unsigned int cccr_msr; + unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ + unsigned int evntsel_msr; /* the MSR to select the events to handle */ +}; +static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); /* local prototypes */ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); +/* converts an msr to an appropriate reservation bit */ +static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) +{ + /* returns the bit offset of the performance counter register */ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + return (msr - MSR_K7_PERFCTR0); + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return (msr - MSR_ARCH_PERFMON_PERFCTR0); + else + return (msr - MSR_P4_BPU_PERFCTR0); + } + return 0; +} + +/* converts an msr to an appropriate reservation bit */ +static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) +{ + /* returns the bit offset of the event selection register */ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + return (msr - MSR_K7_EVNTSEL0); + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return (msr - MSR_ARCH_PERFMON_EVENTSEL0); + else + return (msr - MSR_P4_BSU_ESCR0); + } + return 0; +} + +/* checks for a bit availability (hack for oprofile) */ +int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) +{ + int cpu; + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + for_each_possible_cpu (cpu) { + if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + return 0; + } + return 1; +} + +/* checks the an msr for availability */ +int avail_to_resrv_perfctr_nmi(unsigned int msr) +{ + unsigned int counter; + int cpu; + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + for_each_possible_cpu (cpu) { + if (test_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + return 0; + } + return 1; +} + +static int __reserve_perfctr_nmi(int cpu, unsigned int msr) +{ + unsigned int counter; + if (cpu < 0) + cpu = smp_processor_id(); + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + if (!test_and_set_bit(counter, &per_cpu(perfctr_nmi_owner, cpu))) + return 1; + return 0; +} + +static void __release_perfctr_nmi(int cpu, unsigned int msr) +{ + unsigned int counter; + if (cpu < 0) + cpu = smp_processor_id(); + + counter = nmi_perfctr_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + clear_bit(counter, &per_cpu(perfctr_nmi_owner, cpu)); +} + +int reserve_perfctr_nmi(unsigned int msr) +{ + int cpu, i; + for_each_possible_cpu (cpu) { + if (!__reserve_perfctr_nmi(cpu, msr)) { + for_each_possible_cpu (i) { + if (i >= cpu) + break; + __release_perfctr_nmi(i, msr); + } + return 0; + } + } + return 1; +} + +void release_perfctr_nmi(unsigned int msr) +{ + int cpu; + for_each_possible_cpu (cpu) + __release_perfctr_nmi(cpu, msr); +} + +int __reserve_evntsel_nmi(int cpu, unsigned int msr) +{ + unsigned int counter; + if (cpu < 0) + cpu = smp_processor_id(); + + counter = nmi_evntsel_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + if (!test_and_set_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0])) + return 1; + return 0; +} + +static void __release_evntsel_nmi(int cpu, unsigned int msr) +{ + unsigned int counter; + if (cpu < 0) + cpu = smp_processor_id(); + + counter = nmi_evntsel_msr_to_bit(msr); + BUG_ON(counter > NMI_MAX_COUNTER_BITS); + + clear_bit(counter, &per_cpu(evntsel_nmi_owner, cpu)[0]); +} + +int reserve_evntsel_nmi(unsigned int msr) +{ + int cpu, i; + for_each_possible_cpu (cpu) { + if (!__reserve_evntsel_nmi(cpu, msr)) { + for_each_possible_cpu (i) { + if (i >= cpu) + break; + __release_evntsel_nmi(i, msr); + } + return 0; + } + } + return 1; +} + +void release_evntsel_nmi(unsigned int msr) +{ + int cpu; + for_each_possible_cpu (cpu) { + __release_evntsel_nmi(cpu, msr); + } +} + +static __cpuinit inline int nmi_known_cpu(void) +{ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + return boot_cpu_data.x86 == 15 || boot_cpu_data.x86 == 16; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return 1; + else + return (boot_cpu_data.x86 == 15); + } + return 0; +} + /* Run after command line and cpu_init init, but before all other checks */ void nmi_watchdog_default(void) { @@ -80,6 +277,23 @@ static __init void nmi_cpu_busy(void *data) } #endif +static unsigned int adjust_for_32bit_ctr(unsigned int hz) +{ + unsigned int retval = hz; + + /* + * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter + * are writable, with higher bits sign extending from bit 31. + * So, we can only program the counter with 31 bit values and + * 32nd bit should be 1, for 33.. to be 1. + * Find the appropriate nmi_hz + */ + if ((((u64)cpu_khz * 1000) / retval) > 0x7fffffffULL) { + retval = ((u64)cpu_khz * 1000) / 0x7fffffffUL + 1; + } + return retval; +} + int __init check_nmi_watchdog (void) { int *counts; @@ -108,14 +322,14 @@ int __init check_nmi_watchdog (void) mdelay((20*1000)/nmi_hz); // wait 20 ticks for_each_online_cpu(cpu) { - if (!per_cpu(wd_enabled, cpu)) + if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) continue; if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) { printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", cpu, counts[cpu], cpu_pda(cpu)->__nmi_count); - per_cpu(wd_enabled, cpu) = 0; + per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0; atomic_dec(&nmi_active); } } @@ -130,8 +344,13 @@ int __init check_nmi_watchdog (void) /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ - if (nmi_watchdog == NMI_LOCAL_APIC) - nmi_hz = lapic_adjust_nmi_hz(1); + if (nmi_watchdog == NMI_LOCAL_APIC) { + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + nmi_hz = 1; + if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) + nmi_hz = adjust_for_32bit_ctr(nmi_hz); + } kfree(counts); return 0; @@ -160,6 +379,57 @@ int __init setup_nmi_watchdog(char *str) __setup("nmi_watchdog=", setup_nmi_watchdog); +static void disable_lapic_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + + if (atomic_read(&nmi_active) <= 0) + return; + + on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); + + BUG_ON(atomic_read(&nmi_active) != 0); +} + +static void enable_lapic_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + + /* are we already enabled */ + if (atomic_read(&nmi_active) != 0) + return; + + /* are we lapic aware */ + if (nmi_known_cpu() <= 0) + return; + + on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); + touch_nmi_watchdog(); +} + +void disable_timer_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_IO_APIC); + + if (atomic_read(&nmi_active) <= 0) + return; + + disable_irq(0); + on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); + + BUG_ON(atomic_read(&nmi_active) != 0); +} + +void enable_timer_nmi_watchdog(void) +{ + BUG_ON(nmi_watchdog != NMI_IO_APIC); + + if (atomic_read(&nmi_active) == 0) { + touch_nmi_watchdog(); + on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); + enable_irq(0); + } +} static void __acpi_nmi_disable(void *__unused) { @@ -245,9 +515,275 @@ late_initcall(init_lapic_nmi_sysfs); #endif /* CONFIG_PM */ +/* + * Activate the NMI watchdog via the local APIC. + * Original code written by Keith Owens. + */ + +/* Note that these events don't tick when the CPU idles. This means + the frequency varies with CPU load. */ + +#define K7_EVNTSEL_ENABLE (1 << 22) +#define K7_EVNTSEL_INT (1 << 20) +#define K7_EVNTSEL_OS (1 << 17) +#define K7_EVNTSEL_USR (1 << 16) +#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 +#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING + +static int setup_k7_watchdog(void) +{ + unsigned int perfctr_msr, evntsel_msr; + unsigned int evntsel; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + perfctr_msr = MSR_K7_PERFCTR0; + evntsel_msr = MSR_K7_EVNTSEL0; + if (!__reserve_perfctr_nmi(-1, perfctr_msr)) + goto fail; + + if (!__reserve_evntsel_nmi(-1, evntsel_msr)) + goto fail1; + + /* Simulator may not support it */ + if (checking_wrmsrl(evntsel_msr, 0UL)) + goto fail2; + wrmsrl(perfctr_msr, 0UL); + + evntsel = K7_EVNTSEL_INT + | K7_EVNTSEL_OS + | K7_EVNTSEL_USR + | K7_NMI_EVENT; + + /* setup the timer */ + wrmsr(evntsel_msr, evntsel, 0); + wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= K7_EVNTSEL_ENABLE; + wrmsr(evntsel_msr, evntsel, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = 0; //unused + wd->check_bit = 1ULL<<63; + return 1; +fail2: + __release_evntsel_nmi(-1, evntsel_msr); +fail1: + __release_perfctr_nmi(-1, perfctr_msr); +fail: + return 0; +} + +static void stop_k7_watchdog(void) +{ + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + wrmsr(wd->evntsel_msr, 0, 0); + + __release_evntsel_nmi(-1, wd->evntsel_msr); + __release_perfctr_nmi(-1, wd->perfctr_msr); +} + +/* Note that these events don't tick when the CPU idles. This means + the frequency varies with CPU load. */ + +#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) +#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) +#define P4_ESCR_OS (1<<3) +#define P4_ESCR_USR (1<<2) +#define P4_CCCR_OVF_PMI0 (1<<26) +#define P4_CCCR_OVF_PMI1 (1<<27) +#define P4_CCCR_THRESHOLD(N) ((N)<<20) +#define P4_CCCR_COMPLEMENT (1<<19) +#define P4_CCCR_COMPARE (1<<18) +#define P4_CCCR_REQUIRED (3<<16) +#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) +#define P4_CCCR_ENABLE (1<<12) +#define P4_CCCR_OVF (1<<31) +/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter + CRU_ESCR0 (with any non-null event selector) through a complemented + max threshold. [IA32-Vol3, Section 14.9.9] */ + +static int setup_p4_watchdog(void) +{ + unsigned int perfctr_msr, evntsel_msr, cccr_msr; + unsigned int evntsel, cccr_val; + unsigned int misc_enable, dummy; + unsigned int ht_num; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) + return 0; + +#ifdef CONFIG_SMP + /* detect which hyperthread we are on */ + if (smp_num_siblings == 2) { + unsigned int ebx, apicid; + + ebx = cpuid_ebx(1); + apicid = (ebx >> 24) & 0xff; + ht_num = apicid & 1; + } else +#endif + ht_num = 0; + + /* performance counters are shared resources + * assign each hyperthread its own set + * (re-use the ESCR0 register, seems safe + * and keeps the cccr_val the same) + */ + if (!ht_num) { + /* logical cpu 0 */ + perfctr_msr = MSR_P4_IQ_PERFCTR0; + evntsel_msr = MSR_P4_CRU_ESCR0; + cccr_msr = MSR_P4_IQ_CCCR0; + cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); + } else { + /* logical cpu 1 */ + perfctr_msr = MSR_P4_IQ_PERFCTR1; + evntsel_msr = MSR_P4_CRU_ESCR0; + cccr_msr = MSR_P4_IQ_CCCR1; + cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); + } + + if (!__reserve_perfctr_nmi(-1, perfctr_msr)) + goto fail; + + if (!__reserve_evntsel_nmi(-1, evntsel_msr)) + goto fail1; + + evntsel = P4_ESCR_EVENT_SELECT(0x3F) + | P4_ESCR_OS + | P4_ESCR_USR; + + cccr_val |= P4_CCCR_THRESHOLD(15) + | P4_CCCR_COMPLEMENT + | P4_CCCR_COMPARE + | P4_CCCR_REQUIRED; + + wrmsr(evntsel_msr, evntsel, 0); + wrmsr(cccr_msr, cccr_val, 0); + wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); + apic_write(APIC_LVTPC, APIC_DM_NMI); + cccr_val |= P4_CCCR_ENABLE; + wrmsr(cccr_msr, cccr_val, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = cccr_msr; + wd->check_bit = 1ULL<<39; + return 1; +fail1: + __release_perfctr_nmi(-1, perfctr_msr); +fail: + return 0; +} + +static void stop_p4_watchdog(void) +{ + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + wrmsr(wd->cccr_msr, 0, 0); + wrmsr(wd->evntsel_msr, 0, 0); + + __release_evntsel_nmi(-1, wd->evntsel_msr); + __release_perfctr_nmi(-1, wd->perfctr_msr); +} + +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK + +static int setup_intel_arch_watchdog(void) +{ + unsigned int ebx; + union cpuid10_eax eax; + unsigned int unused; + unsigned int perfctr_msr, evntsel_msr; + unsigned int evntsel; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebx indicates event present. + */ + cpuid(10, &(eax.full), &ebx, &unused, &unused); + if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || + (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + goto fail; + + perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; + evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; + + if (!__reserve_perfctr_nmi(-1, perfctr_msr)) + goto fail; + + if (!__reserve_evntsel_nmi(-1, evntsel_msr)) + goto fail1; + + wrmsrl(perfctr_msr, 0UL); + + evntsel = ARCH_PERFMON_EVENTSEL_INT + | ARCH_PERFMON_EVENTSEL_OS + | ARCH_PERFMON_EVENTSEL_USR + | ARCH_PERFMON_NMI_EVENT_SEL + | ARCH_PERFMON_NMI_EVENT_UMASK; + + /* setup the timer */ + wrmsr(evntsel_msr, evntsel, 0); + + nmi_hz = adjust_for_32bit_ctr(nmi_hz); + wrmsr(perfctr_msr, (u32)(-((u64)cpu_khz * 1000 / nmi_hz)), 0); + + apic_write(APIC_LVTPC, APIC_DM_NMI); + evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; + wrmsr(evntsel_msr, evntsel, 0); + + wd->perfctr_msr = perfctr_msr; + wd->evntsel_msr = evntsel_msr; + wd->cccr_msr = 0; //unused + wd->check_bit = 1ULL << (eax.split.bit_width - 1); + return 1; +fail1: + __release_perfctr_nmi(-1, perfctr_msr); +fail: + return 0; +} + +static void stop_intel_arch_watchdog(void) +{ + unsigned int ebx; + union cpuid10_eax eax; + unsigned int unused; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebx indicates event present. + */ + cpuid(10, &(eax.full), &ebx, &unused, &unused); + if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || + (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return; + + wrmsr(wd->evntsel_msr, 0, 0); + + __release_evntsel_nmi(-1, wd->evntsel_msr); + __release_perfctr_nmi(-1, wd->perfctr_msr); +} + void setup_apic_nmi_watchdog(void *unused) { - if (__get_cpu_var(wd_enabled) == 1) + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + + /* only support LOCAL and IO APICs for now */ + if ((nmi_watchdog != NMI_LOCAL_APIC) && + (nmi_watchdog != NMI_IO_APIC)) + return; + + if (wd->enabled == 1) return; /* cheap hack to support suspend/resume */ @@ -255,31 +791,62 @@ void setup_apic_nmi_watchdog(void *unused) if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0)) return; - switch (nmi_watchdog) { - case NMI_LOCAL_APIC: - __get_cpu_var(wd_enabled) = 1; - if (lapic_watchdog_init(nmi_hz) < 0) { - __get_cpu_var(wd_enabled) = 0; + if (nmi_watchdog == NMI_LOCAL_APIC) { + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) + return; + if (!setup_k7_watchdog()) + return; + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + if (!setup_intel_arch_watchdog()) + return; + break; + } + if (!setup_p4_watchdog()) + return; + break; + default: return; } - /* FALL THROUGH */ - case NMI_IO_APIC: - __get_cpu_var(wd_enabled) = 1; - atomic_inc(&nmi_active); } + wd->enabled = 1; + atomic_inc(&nmi_active); } void stop_apic_nmi_watchdog(void *unused) { + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + /* only support LOCAL and IO APICs for now */ if ((nmi_watchdog != NMI_LOCAL_APIC) && (nmi_watchdog != NMI_IO_APIC)) return; - if (__get_cpu_var(wd_enabled) == 0) + + if (wd->enabled == 0) return; - if (nmi_watchdog == NMI_LOCAL_APIC) - lapic_watchdog_stop(); - __get_cpu_var(wd_enabled) = 0; + + if (nmi_watchdog == NMI_LOCAL_APIC) { + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) + return; + stop_k7_watchdog(); + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + stop_intel_arch_watchdog(); + break; + } + stop_p4_watchdog(); + break; + default: + return; + } + } + wd->enabled = 0; atomic_dec(&nmi_active); } @@ -318,7 +885,9 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) int sum; int touched = 0; int cpu = smp_processor_id(); - int rc = 0; + struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + u64 dummy; + int rc=0; /* check for other users first */ if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) @@ -365,20 +934,55 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) } /* see if the nmi watchdog went off */ - if (!__get_cpu_var(wd_enabled)) - return rc; - switch (nmi_watchdog) { - case NMI_LOCAL_APIC: - rc |= lapic_wd_event(nmi_hz); - break; - case NMI_IO_APIC: - /* don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. - */ - rc = 1; - break; + if (wd->enabled) { + if (nmi_watchdog == NMI_LOCAL_APIC) { + rdmsrl(wd->perfctr_msr, dummy); + if (dummy & wd->check_bit){ + /* this wasn't a watchdog timer interrupt */ + goto done; + } + + /* only Intel uses the cccr msr */ + if (wd->cccr_msr != 0) { + /* + * P4 quirks: + * - An overflown perfctr will assert its interrupt + * until the OVF flag in its CCCR is cleared. + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. + */ + rdmsrl(wd->cccr_msr, dummy); + dummy &= ~P4_CCCR_OVF; + wrmsrl(wd->cccr_msr, dummy); + apic_write(APIC_LVTPC, APIC_DM_NMI); + /* start the cycle over again */ + wrmsrl(wd->perfctr_msr, + -((u64)cpu_khz * 1000 / nmi_hz)); + } else if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + /* + * ArchPerfom/Core Duo needs to re-unmask + * the apic vector + */ + apic_write(APIC_LVTPC, APIC_DM_NMI); + /* ARCH_PERFMON has 32 bit counter writes */ + wrmsr(wd->perfctr_msr, + (u32)(-((u64)cpu_khz * 1000 / nmi_hz)), 0); + } else { + /* start the cycle over again */ + wrmsrl(wd->perfctr_msr, + -((u64)cpu_khz * 1000 / nmi_hz)); + } + rc = 1; + } else if (nmi_watchdog == NMI_IO_APIC) { + /* don't know how to accurately check for this. + * just assume it was a watchdog timer interrupt + * This matches the old behaviour. + */ + rc = 1; + } else + printk(KERN_WARNING "Unknown enabled NMI hardware?!\n"); } +done: return rc; } @@ -463,4 +1067,12 @@ void __trigger_all_cpu_backtrace(void) EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); +EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); +EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); +EXPORT_SYMBOL(reserve_perfctr_nmi); +EXPORT_SYMBOL(release_perfctr_nmi); +EXPORT_SYMBOL(reserve_evntsel_nmi); +EXPORT_SYMBOL(release_evntsel_nmi); +EXPORT_SYMBOL(disable_timer_nmi_watchdog); +EXPORT_SYMBOL(enable_timer_nmi_watchdog); EXPORT_SYMBOL(touch_nmi_watchdog); diff --git a/trunk/arch/x86_64/kernel/pci-calgary.c b/trunk/arch/x86_64/kernel/pci-calgary.c index 5bd20b542c1e..04480c3b68f5 100644 --- a/trunk/arch/x86_64/kernel/pci-calgary.c +++ b/trunk/arch/x86_64/kernel/pci-calgary.c @@ -507,7 +507,7 @@ void* calgary_alloc_coherent(struct device *dev, size_t size, return ret; } -static const struct dma_mapping_ops calgary_dma_ops = { +static struct dma_mapping_ops calgary_dma_ops = { .alloc_coherent = calgary_alloc_coherent, .map_single = calgary_map_single, .unmap_single = calgary_unmap_single, diff --git a/trunk/arch/x86_64/kernel/pci-gart.c b/trunk/arch/x86_64/kernel/pci-gart.c index 373ef66ca1dc..0bae862e9a55 100644 --- a/trunk/arch/x86_64/kernel/pci-gart.c +++ b/trunk/arch/x86_64/kernel/pci-gart.c @@ -22,13 +22,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include #include @@ -556,7 +556,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) extern int agp_amd64_init(void); -static const struct dma_mapping_ops gart_dma_ops = { +static struct dma_mapping_ops gart_dma_ops = { .mapping_error = NULL, .map_single = gart_map_single, .map_simple = gart_map_simple, diff --git a/trunk/arch/x86_64/kernel/pci-nommu.c b/trunk/arch/x86_64/kernel/pci-nommu.c index 6dade0c867cc..df09ab05a1bd 100644 --- a/trunk/arch/x86_64/kernel/pci-nommu.c +++ b/trunk/arch/x86_64/kernel/pci-nommu.c @@ -79,7 +79,7 @@ void nommu_unmap_sg(struct device *dev, struct scatterlist *sg, { } -const struct dma_mapping_ops nommu_dma_ops = { +struct dma_mapping_ops nommu_dma_ops = { .map_single = nommu_map_single, .unmap_single = nommu_unmap_single, .map_sg = nommu_map_sg, diff --git a/trunk/arch/x86_64/kernel/pci-swiotlb.c b/trunk/arch/x86_64/kernel/pci-swiotlb.c index 4b4569abc60c..eb18be5a6569 100644 --- a/trunk/arch/x86_64/kernel/pci-swiotlb.c +++ b/trunk/arch/x86_64/kernel/pci-swiotlb.c @@ -12,7 +12,7 @@ int swiotlb __read_mostly; EXPORT_SYMBOL(swiotlb); -const struct dma_mapping_ops swiotlb_dma_ops = { +struct dma_mapping_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, .alloc_coherent = swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index 5909039f37aa..d8d5ccc245c8 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include @@ -47,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -288,18 +288,16 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) static int __init idle_setup (char *str) { - if (!strcmp(str, "poll")) { + if (!strncmp(str, "poll", 4)) { printk("using polling idle threads.\n"); pm_idle = poll_idle; - } else if (!strcmp(str, "mwait")) - force_mwait = 1; - else - return -1; + } boot_option_idle_override = 1; - return 0; + return 1; } -early_param("idle", idle_setup); + +__setup("idle=", idle_setup); /* Prints also some state that isn't saved in the pt_regs */ void __show_regs(struct pt_regs * regs) diff --git a/trunk/arch/x86_64/kernel/ptrace.c b/trunk/arch/x86_64/kernel/ptrace.c index 9409117b9f19..4326a690a509 100644 --- a/trunk/arch/x86_64/kernel/ptrace.c +++ b/trunk/arch/x86_64/kernel/ptrace.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/x86_64/kernel/reboot.c b/trunk/arch/x86_64/kernel/reboot.c index c116b54d422e..2d6769847456 100644 --- a/trunk/arch/x86_64/kernel/reboot.c +++ b/trunk/arch/x86_64/kernel/reboot.c @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index db51577bda32..3d98b696881d 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -79,8 +79,6 @@ int bootloader_type; unsigned long saved_video_mode; -int force_mwait __cpuinitdata; - /* * Early DMI memory */ @@ -207,10 +205,10 @@ static void discover_ebda(void) * there is a real-mode segmented pointer pointing to the * 4K EBDA area at 0x40E */ - ebda_addr = *(unsigned short *)__va(EBDA_ADDR_POINTER); + ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER; ebda_addr <<= 4; - ebda_size = *(unsigned short *)__va(ebda_addr); + ebda_size = *(unsigned short *)(unsigned long)ebda_addr; /* Round EBDA up to pages */ if (ebda_size == 0) @@ -276,6 +274,8 @@ void __init setup_arch(char **cmdline_p) dmi_scan_machine(); + zap_low_mappings(0); + #ifdef CONFIG_ACPI /* * Initialize the ACPI boot-time table parser (gets the RSDP and SDT). @@ -329,8 +329,15 @@ void __init setup_arch(char **cmdline_p) #endif #ifdef CONFIG_SMP + /* + * But first pinch a few for the stack/trampoline stuff + * FIXME: Don't need the extra page at 4K, but need to fix + * trampoline before removing it. (see the GDT stuff) + */ + reserve_bootmem_generic(PAGE_SIZE, PAGE_SIZE); + /* Reserve SMP trampoline */ - reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, 2*PAGE_SIZE); + reserve_bootmem_generic(SMP_TRAMPOLINE_BASE, PAGE_SIZE); #endif #ifdef CONFIG_ACPI_SLEEP @@ -605,10 +612,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) /* RDTSC can be speculated around */ clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); - - /* Family 10 doesn't support C states in MWAIT so don't use it */ - if (c->x86 == 0x10 && !force_mwait) - clear_bit(X86_FEATURE_MWAIT, &c->x86_capability); } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) @@ -984,8 +987,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) "stc", "100mhzsteps", "hwpstate", - "", /* tsc invariant mapped to constant_tsc */ - /* nothing */ + NULL, /* tsc invariant mapped to constant_tsc */ + NULL, + /* nothing */ /* constant_tsc - moved to flags */ }; diff --git a/trunk/arch/x86_64/kernel/setup64.c b/trunk/arch/x86_64/kernel/setup64.c index 64379a80d763..6a70b55f719d 100644 --- a/trunk/arch/x86_64/kernel/setup64.c +++ b/trunk/arch/x86_64/kernel/setup64.c @@ -103,9 +103,9 @@ void __init setup_per_cpu_areas(void) if (!NODE_DATA(cpu_to_node(i))) { printk("cpu with no node %d, num_online_nodes %d\n", i, num_online_nodes()); - ptr = alloc_bootmem_pages(size); + ptr = alloc_bootmem(size); } else { - ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); + ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size); } if (!ptr) panic("Cannot allocate cpu data for CPU %d\n", i); @@ -201,6 +201,7 @@ void __cpuinit cpu_init (void) /* CPU 0 is initialised in head64.c */ if (cpu != 0) { pda_init(cpu); + zap_low_mappings(cpu); } else estacks = boot_exception_stacks; diff --git a/trunk/arch/x86_64/kernel/signal.c b/trunk/arch/x86_64/kernel/signal.c index 290f5d8037cd..49ec324cd141 100644 --- a/trunk/arch/x86_64/kernel/signal.c +++ b/trunk/arch/x86_64/kernel/signal.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -140,7 +141,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) goto badframe; #ifdef DEBUG_SIG - printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs->rip,regs->rsp,frame,eax); + printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs.rip,regs.rsp,frame,eax); #endif if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->rsp) == -EFAULT) @@ -300,7 +301,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, if (test_thread_flag(TIF_SINGLESTEP)) ptrace_notify(SIGTRAP); #ifdef DEBUG_SIG - printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%p\n", + printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif @@ -462,7 +463,7 @@ void do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) { #ifdef DEBUG_SIG - printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%p pending:%x\n", + printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n", thread_info_flags, regs->rip, regs->rsp, __builtin_return_address(0),signal_pending(current)); #endif diff --git a/trunk/arch/x86_64/kernel/smp.c b/trunk/arch/x86_64/kernel/smp.c index 2ff468591625..af1ec4d23cf8 100644 --- a/trunk/arch/x86_64/kernel/smp.c +++ b/trunk/arch/x86_64/kernel/smp.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -451,34 +452,42 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, } EXPORT_SYMBOL(smp_call_function); -static void stop_this_cpu(void *dummy) +void smp_stop_cpu(void) { - local_irq_disable(); + unsigned long flags; /* * Remove this CPU: */ cpu_clear(smp_processor_id(), cpu_online_map); + local_irq_save(flags); disable_local_APIC(); + local_irq_restore(flags); +} + +static void smp_really_stop_cpu(void *dummy) +{ + smp_stop_cpu(); for (;;) halt(); } void smp_send_stop(void) { - int nolock; - unsigned long flags; - + int nolock = 0; if (reboot_force) return; - /* Don't deadlock on the call lock in panic */ - nolock = !spin_trylock(&call_lock); - local_irq_save(flags); - __smp_call_function(stop_this_cpu, NULL, 0, 0); + if (!spin_trylock(&call_lock)) { + /* ignore locking because we have panicked anyways */ + nolock = 1; + } + __smp_call_function(smp_really_stop_cpu, NULL, 0, 0); if (!nolock) spin_unlock(&call_lock); + + local_irq_disable(); disable_local_APIC(); - local_irq_restore(flags); + local_irq_enable(); } /* diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 32f50783edc8..cd4643a37022 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -42,23 +42,25 @@ #include #include +#include #include #include #include #include #include #include -#include #include #include #include +#include #include #include #include #include #include #include +#include /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -66,6 +68,7 @@ EXPORT_SYMBOL(smp_num_siblings); /* Last level cache ID of each logical CPU */ u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; +EXPORT_SYMBOL(cpu_llc_id); /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map __read_mostly; @@ -389,8 +392,7 @@ static void inquire_remote_apic(int apicid) { unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; char *names[] = { "ID", "VERSION", "SPIV" }; - int timeout; - unsigned int status; + int timeout, status; printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid); @@ -400,9 +402,7 @@ static void inquire_remote_apic(int apicid) /* * Wait for idle. */ - status = safe_apic_wait_icr_idle(); - if (status) - printk("a previous APIC delivery may have failed\n"); + apic_wait_icr_idle(); apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); apic_write(APIC_ICR, APIC_DM_REMRD | regs[i]); @@ -430,8 +430,8 @@ static void inquire_remote_apic(int apicid) */ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int start_rip) { - unsigned long send_status, accept_status = 0; - int maxlvt, num_starts, j; + unsigned long send_status = 0, accept_status = 0; + int maxlvt, timeout, num_starts, j; Dprintk("Asserting INIT.\n"); @@ -447,7 +447,12 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta | APIC_DM_INIT); Dprintk("Waiting for send to finish...\n"); - send_status = safe_apic_wait_icr_idle(); + timeout = 0; + do { + Dprintk("+"); + udelay(100); + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + } while (send_status && (timeout++ < 1000)); mdelay(10); @@ -460,7 +465,12 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta apic_write(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); Dprintk("Waiting for send to finish...\n"); - send_status = safe_apic_wait_icr_idle(); + timeout = 0; + do { + Dprintk("+"); + udelay(100); + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + } while (send_status && (timeout++ < 1000)); mb(); atomic_set(&init_deasserted, 1); @@ -499,7 +509,12 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta Dprintk("Startup point 1.\n"); Dprintk("Waiting for send to finish...\n"); - send_status = safe_apic_wait_icr_idle(); + timeout = 0; + do { + Dprintk("+"); + udelay(100); + send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; + } while (send_status && (timeout++ < 1000)); /* * Give the other CPU some time to accept the IPI. @@ -930,12 +945,6 @@ int __cpuinit __cpu_up(unsigned int cpu) return -ENOSYS; } - /* - * Save current MTRR state in case it was changed since early boot - * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync: - */ - mtrr_save_state(); - per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; /* Boot it! */ err = do_boot_cpu(cpu, apicid); @@ -956,6 +965,13 @@ int __cpuinit __cpu_up(unsigned int cpu) while (!cpu_isset(cpu, cpu_online_map)) cpu_relax(); + + if (num_online_cpus() > 8 && genapic == &apic_flat) { + printk(KERN_WARNING + "flat APIC routing can't be used with > 8 cpus\n"); + BUG(); + } + err = 0; return err; diff --git a/trunk/arch/x86_64/kernel/stacktrace.c b/trunk/arch/x86_64/kernel/stacktrace.c index cb9109113584..65ac2c6b34a6 100644 --- a/trunk/arch/x86_64/kernel/stacktrace.c +++ b/trunk/arch/x86_64/kernel/stacktrace.c @@ -21,7 +21,8 @@ save_stack_warning_symbol(void *data, char *msg, unsigned long symbol) static int save_stack_stack(void *data, char *name) { - return -1; + struct stack_trace *trace = (struct stack_trace *)data; + return trace->all_contexts ? 0 : -1; } static void save_stack_address(void *data, unsigned long addr) @@ -45,10 +46,11 @@ static struct stacktrace_ops save_stack_ops = { /* * Save stack-backtrace addresses into a stack_trace buffer. */ -void save_stack_trace(struct stack_trace *trace) +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) { - dump_trace(current, NULL, NULL, &save_stack_ops, trace); + dump_trace(task, NULL, NULL, &save_stack_ops, trace); if (trace->nr_entries < trace->max_entries) trace->entries[trace->nr_entries++] = ULONG_MAX; } EXPORT_SYMBOL(save_stack_trace); + diff --git a/trunk/arch/x86_64/kernel/suspend.c b/trunk/arch/x86_64/kernel/suspend.c index 6a5a98f2a75c..91f7e678bae7 100644 --- a/trunk/arch/x86_64/kernel/suspend.c +++ b/trunk/arch/x86_64/kernel/suspend.c @@ -12,10 +12,6 @@ #include #include #include -#include - -/* References to section boundaries */ -extern const void __nosave_begin, __nosave_end; struct saved_context saved_context; @@ -37,6 +33,7 @@ void __save_processor_state(struct saved_context *ctxt) asm volatile ("str %0" : "=m" (ctxt->tr)); /* XMM0..XMM15 should be handled by kernel_fpu_begin(). */ + /* EFER should be constant for kernel version, no need to handle it. */ /* * segment registers */ @@ -49,12 +46,10 @@ void __save_processor_state(struct saved_context *ctxt) rdmsrl(MSR_FS_BASE, ctxt->fs_base); rdmsrl(MSR_GS_BASE, ctxt->gs_base); rdmsrl(MSR_KERNEL_GS_BASE, ctxt->gs_kernel_base); - mtrr_save_fixed_ranges(NULL); /* * control registers */ - rdmsrl(MSR_EFER, ctxt->efer); asm volatile ("movq %%cr0, %0" : "=r" (ctxt->cr0)); asm volatile ("movq %%cr2, %0" : "=r" (ctxt->cr2)); asm volatile ("movq %%cr3, %0" : "=r" (ctxt->cr3)); @@ -80,7 +75,6 @@ void __restore_processor_state(struct saved_context *ctxt) /* * control registers */ - wrmsrl(MSR_EFER, ctxt->efer); asm volatile ("movq %0, %%cr8" :: "r" (ctxt->cr8)); asm volatile ("movq %0, %%cr4" :: "r" (ctxt->cr4)); asm volatile ("movq %0, %%cr3" :: "r" (ctxt->cr3)); @@ -225,15 +219,4 @@ int swsusp_arch_resume(void) restore_image(); return 0; } - -/* - * pfn_is_nosave - check if given pfn is in the 'nosave' section - */ - -int pfn_is_nosave(unsigned long pfn) -{ - unsigned long nosave_begin_pfn = __pa_symbol(&__nosave_begin) >> PAGE_SHIFT; - unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT; - return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); -} #endif /* CONFIG_SOFTWARE_SUSPEND */ diff --git a/trunk/arch/x86_64/kernel/suspend_asm.S b/trunk/arch/x86_64/kernel/suspend_asm.S index 16d183f67bc1..bfbe00763c68 100644 --- a/trunk/arch/x86_64/kernel/suspend_asm.S +++ b/trunk/arch/x86_64/kernel/suspend_asm.S @@ -71,10 +71,9 @@ loop: jmp loop done: /* go back to the original page tables */ - movq $(init_level4_pgt - __START_KERNEL_map), %rax - addq phys_base(%rip), %rax - movq %rax, %cr3 - + leaq init_level4_pgt(%rip), %rax + subq $__START_KERNEL_map, %rax + movq %rax, %cr3 /* Flush TLB, including "global" things (vmalloc) */ movq mmu_cr4_features(%rip), %rax movq %rax, %rdx diff --git a/trunk/arch/x86_64/kernel/sys_x86_64.c b/trunk/arch/x86_64/kernel/sys_x86_64.c index d067d9a2ad27..76bf7c241fe4 100644 --- a/trunk/arch/x86_64/kernel/sys_x86_64.c +++ b/trunk/arch/x86_64/kernel/sys_x86_64.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -92,9 +93,6 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long start_addr; unsigned long begin, end; - if (flags & MAP_FIXED) - return addr; - find_start_end(flags, &begin, &end); if (len > end) diff --git a/trunk/arch/x86_64/kernel/syscall.c b/trunk/arch/x86_64/kernel/syscall.c index 63d592c276cc..213fd6ab789d 100644 --- a/trunk/arch/x86_64/kernel/syscall.c +++ b/trunk/arch/x86_64/kernel/syscall.c @@ -3,7 +3,6 @@ #include #include #include -#include #define __NO_STUBS diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 4a0895bacf51..75d73a9aa9ff 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -39,11 +39,13 @@ #include #include #include +#include #include #include #include -#include -#include + +extern void i8254_timer_resume(void); +extern int using_apic_timer; static char *timename = NULL; @@ -250,51 +252,6 @@ static unsigned long get_cmos_time(void) return mktime(year, mon, day, hour, min, sec); } -/* calibrate_cpu is used on systems with fixed rate TSCs to determine - * processor frequency */ -#define TICK_COUNT 100000000 -static unsigned int __init tsc_calibrate_cpu_khz(void) -{ - int tsc_start, tsc_now; - int i, no_ctr_free; - unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0; - unsigned long flags; - - for (i = 0; i < 4; i++) - if (avail_to_resrv_perfctr_nmi_bit(i)) - break; - no_ctr_free = (i == 4); - if (no_ctr_free) { - i = 3; - rdmsrl(MSR_K7_EVNTSEL3, evntsel3); - wrmsrl(MSR_K7_EVNTSEL3, 0); - rdmsrl(MSR_K7_PERFCTR3, pmc3); - } else { - reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i); - reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i); - } - local_irq_save(flags); - /* start meauring cycles, incrementing from 0 */ - wrmsrl(MSR_K7_PERFCTR0 + i, 0); - wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76); - rdtscl(tsc_start); - do { - rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now); - tsc_now = get_cycles_sync(); - } while ((tsc_now - tsc_start) < TICK_COUNT); - - local_irq_restore(flags); - if (no_ctr_free) { - wrmsrl(MSR_K7_EVNTSEL3, 0); - wrmsrl(MSR_K7_PERFCTR3, pmc3); - wrmsrl(MSR_K7_EVNTSEL3, evntsel3); - } else { - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); - } - - return pmc_now * tsc_khz / (tsc_now - tsc_start); -} /* * pit_calibrate_tsc() uses the speaker output (channel 2) of @@ -328,7 +285,7 @@ static unsigned int __init pit_calibrate_tsc(void) #define PIT_MODE 0x43 #define PIT_CH0 0x40 -static void __pit_init(int val, u8 mode) +static void __init __pit_init(int val, u8 mode) { unsigned long flags; @@ -344,12 +301,12 @@ void __init pit_init(void) __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */ } -void pit_stop_interrupt(void) +void __init pit_stop_interrupt(void) { __pit_init(0, 0x30); /* mode 0 */ } -void stop_timer_interrupt(void) +void __init stop_timer_interrupt(void) { char *name; if (hpet_address) { @@ -363,10 +320,7 @@ void stop_timer_interrupt(void) } static struct irqaction irq0 = { - .handler = timer_interrupt, - .flags = IRQF_DISABLED | IRQF_IRQPOLL, - .mask = CPU_MASK_NONE, - .name = "timer" + timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL }; void __init time_init(void) @@ -385,29 +339,23 @@ void __init time_init(void) if (hpet_use_timer) { /* set tick_nsec to use the proper rate for HPET */ tick_nsec = TICK_NSEC_HPET; - tsc_khz = hpet_calibrate_tsc(); + cpu_khz = hpet_calibrate_tsc(); timename = "HPET"; } else { pit_init(); - tsc_khz = pit_calibrate_tsc(); + cpu_khz = pit_calibrate_tsc(); timename = "PIT"; } - cpu_khz = tsc_khz; - if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && - boot_cpu_data.x86_vendor == X86_VENDOR_AMD && - boot_cpu_data.x86 == 16) - cpu_khz = tsc_calibrate_cpu_khz(); - if (unsynchronized_tsc()) - mark_tsc_unstable("TSCs unsynchronized"); + mark_tsc_unstable(); if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) vgetcpu_mode = VGETCPU_RDTSCP; else vgetcpu_mode = VGETCPU_LSL; - set_cyc2ns_scale(tsc_khz); + set_cyc2ns_scale(cpu_khz); printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); init_tsc_clocksource(); diff --git a/trunk/arch/x86_64/kernel/trampoline.S b/trunk/arch/x86_64/kernel/trampoline.S index e7e2764c461b..c79b99a9e2f6 100644 --- a/trunk/arch/x86_64/kernel/trampoline.S +++ b/trunk/arch/x86_64/kernel/trampoline.S @@ -3,7 +3,6 @@ * Trampoline.S Derived from Setup.S by Linus Torvalds * * 4 Jan 1997 Michael Chastain: changed to gnu as. - * 15 Sept 2005 Eric Biederman: 64bit PIC support * * Entry: CS:IP point to the start of our code, we are * in real mode with no stack, but the rest of the @@ -18,20 +17,15 @@ * and IP is zero. Thus, data addresses need to be absolute * (no relocation) and are taken with regard to r_base. * - * With the addition of trampoline_level4_pgt this code can - * now enter a 64bit kernel that lives at arbitrary 64bit - * physical addresses. - * * If you work on this file, check the object module with objdump * --full-contents --reloc to make sure there are no relocation - * entries. + * entries. For the GDT entry we do hand relocation in smpboot.c + * because of 64bit linker limitations. */ #include -#include -#include -#include #include +#include .data @@ -39,33 +33,15 @@ ENTRY(trampoline_data) r_base = . - cli # We should be safe anyway wbinvd mov %cs, %ax # Code and data in the same place mov %ax, %ds - mov %ax, %es - mov %ax, %ss + cli # We should be safe anyway movl $0xA5A5A5A5, trampoline_data - r_base # write marker for master knows we're running - # Setup stack - movw $(trampoline_stack_end - r_base), %sp - - call verify_cpu # Verify the cpu supports long mode - testl %eax, %eax # Check for return code - jnz no_longmode - - mov %cs, %ax - movzx %ax, %esi # Find the 32bit trampoline location - shll $4, %esi - - # Fixup the vectors - addl %esi, startup_32_vector - r_base - addl %esi, startup_64_vector - r_base - addl %esi, tgdt + 2 - r_base # Fixup the gdt pointer - /* * GDT tables in non default location kernel can be beyond 16MB and * lgdt will not be able to load the address as in real mode default @@ -73,94 +49,23 @@ r_base = . * to 32 bit. */ - lidtl tidt - r_base # load idt with 0, 0 - lgdtl tgdt - r_base # load gdt with whatever is appropriate + lidtl idt_48 - r_base # load idt with 0, 0 + lgdtl gdt_48 - r_base # load gdt with whatever is appropriate xor %ax, %ax inc %ax # protected mode (PE) bit lmsw %ax # into protected mode - - # flush prefetch and jump to startup_32 - ljmpl *(startup_32_vector - r_base) - - .code32 - .balign 4 -startup_32: - movl $__KERNEL_DS, %eax # Initialize the %ds segment register - movl %eax, %ds - - xorl %eax, %eax - btsl $5, %eax # Enable PAE mode - movl %eax, %cr4 - - # Setup trampoline 4 level pagetables - leal (trampoline_level4_pgt - r_base)(%esi), %eax - movl %eax, %cr3 - - movl $MSR_EFER, %ecx - movl $(1 << _EFER_LME), %eax # Enable Long Mode - xorl %edx, %edx - wrmsr - - xorl %eax, %eax - btsl $31, %eax # Enable paging and in turn activate Long Mode - btsl $0, %eax # Enable protected mode - movl %eax, %cr0 - - /* - * At this point we're in long mode but in 32bit compatibility mode - * with EFER.LME = 1, CS.L = 0, CS.D = 1 (and in turn - * EFER.LMA = 1). Now we want to jump in 64bit mode, to do that we use - * the new gdt/idt that has __KERNEL_CS with CS.L = 1. - */ - ljmp *(startup_64_vector - r_base)(%esi) - - .code64 - .balign 4 -startup_64: - # Now jump into the kernel using virtual addresses - movq $secondary_startup_64, %rax - jmp *%rax - - .code16 -no_longmode: - hlt - jmp no_longmode -#include "verify_cpu.S" + # flaush prefetch and jump to startup_32 in arch/x86_64/kernel/head.S + ljmpl $__KERNEL32_CS, $(startup_32-__START_KERNEL_map) # Careful these need to be in the same 64K segment as the above; -tidt: +idt_48: .word 0 # idt limit = 0 .word 0, 0 # idt base = 0L - # Duplicate the global descriptor table - # so the kernel can live anywhere - .balign 4 -tgdt: - .short tgdt_end - tgdt # gdt limit - .long tgdt - r_base - .short 0 - .quad 0x00cf9b000000ffff # __KERNEL32_CS - .quad 0x00af9b000000ffff # __KERNEL_CS - .quad 0x00cf93000000ffff # __KERNEL_DS -tgdt_end: - - .balign 4 -startup_32_vector: - .long startup_32 - r_base - .word __KERNEL32_CS, 0 - - .balign 4 -startup_64_vector: - .long startup_64 - r_base - .word __KERNEL_CS, 0 - -trampoline_stack: - .org 0x1000 -trampoline_stack_end: -ENTRY(trampoline_level4_pgt) - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE - .fill 510,8,0 - .quad level3_kernel_pgt - __START_KERNEL_map + _KERNPG_TABLE +gdt_48: + .short GDT_ENTRIES*8 - 1 # gdt limit + .long cpu_gdt_table-__START_KERNEL_map -ENTRY(trampoline_end) +.globl trampoline_end +trampoline_end: diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index 8c2ac41187c1..09d2e8a10a49 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -40,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +71,22 @@ asmlinkage void alignment_check(void); asmlinkage void machine_check(void); asmlinkage void spurious_interrupt_bug(void); +ATOMIC_NOTIFIER_HEAD(die_chain); +EXPORT_SYMBOL(die_chain); + +int register_die_notifier(struct notifier_block *nb) +{ + vmalloc_sync_all(); + return atomic_notifier_chain_register(&die_chain, nb); +} +EXPORT_SYMBOL(register_die_notifier); /* used modular by kdb */ + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&die_chain, nb); +} +EXPORT_SYMBOL(unregister_die_notifier); /* used modular by kdb */ + static inline void conditional_sti(struct pt_regs *regs) { if (regs->eflags & X86_EFLAGS_IF) @@ -410,7 +426,8 @@ void show_registers(struct pt_regs *regs) const int cpu = smp_processor_id(); struct task_struct *cur = cpu_pda(cpu)->pcurrent; - rsp = regs->rsp; + rsp = regs->rsp; + printk("CPU %d ", cpu); __show_regs(regs); printk("Process %s (pid: %d, threadinfo %p, task %p)\n", @@ -421,6 +438,7 @@ void show_registers(struct pt_regs *regs) * time of the fault.. */ if (in_kernel) { + printk("Stack: "); _show_stack(NULL, regs, (unsigned long*)rsp); @@ -563,20 +581,10 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, { struct task_struct *tsk = current; - if (user_mode(regs)) { - /* - * We want error_code and trap_no set for userspace - * faults and kernelspace faults which result in - * die(), but not kernelspace faults which are fixed - * up. die() gives the process no chance to handle - * the signal and notice the kernel fault information, - * so that won't result in polluting the information - * about previously queued, but not yet delivered, - * faults. See also do_general_protection below. - */ - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = trapnr; + if (user_mode(regs)) { if (exception_trace && unhandled_signal(tsk, signr)) printk(KERN_INFO "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", @@ -597,11 +605,8 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, fixup = search_exception_tables(regs->rip); if (fixup) regs->rip = fixup->fixup; - else { - tsk->thread.error_code = error_code; - tsk->thread.trap_no = trapnr; + else die(str, regs, error_code); - } return; } } @@ -677,10 +682,10 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, conditional_sti(regs); - if (user_mode(regs)) { - tsk->thread.error_code = error_code; - tsk->thread.trap_no = 13; + tsk->thread.error_code = error_code; + tsk->thread.trap_no = 13; + if (user_mode(regs)) { if (exception_trace && unhandled_signal(tsk, SIGSEGV)) printk(KERN_INFO "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", @@ -699,9 +704,6 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, regs->rip = fixup->fixup; return; } - - tsk->thread.error_code = error_code; - tsk->thread.trap_no = 13; if (notify_die(DIE_GPF, "general protection fault", regs, error_code, 13, SIGSEGV) == NOTIFY_STOP) return; @@ -776,8 +778,6 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs) */ if (nmi_watchdog_tick(regs,reason)) return; - if (notify_die(DIE_NMI_POST, "nmi_post", regs, reason, 2, 0) - == NOTIFY_STOP) if (!do_nmi_callback(regs,cpu)) unknown_nmi_error(reason, regs); diff --git a/trunk/arch/x86_64/kernel/tsc.c b/trunk/arch/x86_64/kernel/tsc.c index 48f9a8e6aa91..1a0edbbffaa0 100644 --- a/trunk/arch/x86_64/kernel/tsc.c +++ b/trunk/arch/x86_64/kernel/tsc.c @@ -13,8 +13,6 @@ static int notsc __initdata = 0; unsigned int cpu_khz; /* TSC clocks / usec, not used here */ EXPORT_SYMBOL(cpu_khz); -unsigned int tsc_khz; -EXPORT_SYMBOL(tsc_khz); static unsigned int cyc2ns_scale __read_mostly; @@ -79,7 +77,7 @@ static void handle_cpufreq_delayed_get(struct work_struct *v) static unsigned int ref_freq = 0; static unsigned long loops_per_jiffy_ref = 0; -static unsigned long tsc_khz_ref = 0; +static unsigned long cpu_khz_ref = 0; static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data) @@ -101,7 +99,7 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, if (!ref_freq) { ref_freq = freq->old; loops_per_jiffy_ref = *lpj; - tsc_khz_ref = tsc_khz; + cpu_khz_ref = cpu_khz; } if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || @@ -109,12 +107,12 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, *lpj = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); - tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); + cpu_khz = cpufreq_scale(cpu_khz_ref, ref_freq, freq->new); if (!(freq->flags & CPUFREQ_CONST_LOOPS)) - mark_tsc_unstable("cpufreq changes"); + mark_tsc_unstable(); } - set_cyc2ns_scale(tsc_khz_ref); + set_cyc2ns_scale(cpu_khz_ref); return 0; } @@ -199,11 +197,10 @@ static struct clocksource clocksource_tsc = { .vread = vread_tsc, }; -void mark_tsc_unstable(char *reason) +void mark_tsc_unstable(void) { if (!tsc_unstable) { tsc_unstable = 1; - printk("Marking TSC unstable due to %s\n", reason); /* Change only the rating, when not registered */ if (clocksource_tsc.mult) clocksource_change_rating(&clocksource_tsc, 0); @@ -216,7 +213,7 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable); void __init init_tsc_clocksource(void) { if (!notsc) { - clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, + clocksource_tsc.mult = clocksource_khz2mult(cpu_khz, clocksource_tsc.shift); if (check_tsc_unstable()) clocksource_tsc.rating = 0; diff --git a/trunk/arch/x86_64/kernel/tsc_sync.c b/trunk/arch/x86_64/kernel/tsc_sync.c index 355f5f506c81..014f0db45dfa 100644 --- a/trunk/arch/x86_64/kernel/tsc_sync.c +++ b/trunk/arch/x86_64/kernel/tsc_sync.c @@ -50,7 +50,7 @@ static __cpuinit void check_tsc_warp(void) /* * The measurement runs for 20 msecs: */ - end = start + tsc_khz * 20ULL; + end = start + cpu_khz * 20ULL; now = start; for (i = 0; ; i++) { @@ -138,7 +138,7 @@ void __cpuinit check_tsc_sync_source(int cpu) printk("\n"); printk(KERN_WARNING "Measured %Ld cycles TSC warp between CPUs," " turning off TSC clock.\n", max_warp); - mark_tsc_unstable("check_tsc_sync_source failed"); + mark_tsc_unstable(); nr_warps = 0; max_warp = 0; last_tsc = 0; diff --git a/trunk/arch/x86_64/kernel/verify_cpu.S b/trunk/arch/x86_64/kernel/verify_cpu.S deleted file mode 100644 index e035f5948199..000000000000 --- a/trunk/arch/x86_64/kernel/verify_cpu.S +++ /dev/null @@ -1,119 +0,0 @@ -/* - * - * verify_cpu.S - Code for cpu long mode and SSE verification. This - * code has been borrowed from boot/setup.S and was introduced by - * Andi Kleen. - * - * Copyright (c) 2007 Andi Kleen (ak@suse.de) - * Copyright (c) 2007 Eric Biederman (ebiederm@xmission.com) - * Copyright (c) 2007 Vivek Goyal (vgoyal@in.ibm.com) - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - * - * This is a common code for verification whether CPU supports - * long mode and SSE or not. It is not called directly instead this - * file is included at various places and compiled in that context. - * Following are the current usage. - * - * This file is included by both 16bit and 32bit code. - * - * arch/x86_64/boot/setup.S : Boot cpu verification (16bit) - * arch/x86_64/boot/compressed/head.S: Boot cpu verification (32bit) - * arch/x86_64/kernel/trampoline.S: secondary processor verfication (16bit) - * arch/x86_64/kernel/acpi/wakeup.S:Verfication at resume (16bit) - * - * verify_cpu, returns the status of cpu check in register %eax. - * 0: Success 1: Failure - * - * The caller needs to check for the error code and take the action - * appropriately. Either display a message or halt. - */ - -#include - -verify_cpu: - pushfl # Save caller passed flags - pushl $0 # Kill any dangerous flags - popfl - - /* minimum CPUID flags for x86-64 as defined by AMD */ -#define M(x) (1<<(x)) -#define M2(a,b) M(a)|M(b) -#define M4(a,b,c,d) M(a)|M(b)|M(c)|M(d) - -#define SSE_MASK \ - (M2(X86_FEATURE_XMM,X86_FEATURE_XMM2)) -#define REQUIRED_MASK1 \ - (M4(X86_FEATURE_FPU,X86_FEATURE_PSE,X86_FEATURE_TSC,X86_FEATURE_MSR)|\ - M4(X86_FEATURE_PAE,X86_FEATURE_CX8,X86_FEATURE_PGE,X86_FEATURE_CMOV)|\ - M(X86_FEATURE_FXSR)) -#define REQUIRED_MASK2 \ - (M(X86_FEATURE_LM - 32)) - - pushfl # standard way to check for cpuid - popl %eax - movl %eax,%ebx - xorl $0x200000,%eax - pushl %eax - popfl - pushfl - popl %eax - cmpl %eax,%ebx - jz verify_cpu_no_longmode # cpu has no cpuid - - movl $0x0,%eax # See if cpuid 1 is implemented - cpuid - cmpl $0x1,%eax - jb verify_cpu_no_longmode # no cpuid 1 - - xor %di,%di - cmpl $0x68747541,%ebx # AuthenticAMD - jnz verify_cpu_noamd - cmpl $0x69746e65,%edx - jnz verify_cpu_noamd - cmpl $0x444d4163,%ecx - jnz verify_cpu_noamd - mov $1,%di # cpu is from AMD - -verify_cpu_noamd: - movl $0x1,%eax # Does the cpu have what it takes - cpuid - andl $REQUIRED_MASK1,%edx - xorl $REQUIRED_MASK1,%edx - jnz verify_cpu_no_longmode - - movl $0x80000000,%eax # See if extended cpuid is implemented - cpuid - cmpl $0x80000001,%eax - jb verify_cpu_no_longmode # no extended cpuid - - movl $0x80000001,%eax # Does the cpu have what it takes - cpuid - andl $REQUIRED_MASK2,%edx - xorl $REQUIRED_MASK2,%edx - jnz verify_cpu_no_longmode - -verify_cpu_sse_test: - movl $1,%eax - cpuid - andl $SSE_MASK,%edx - cmpl $SSE_MASK,%edx - je verify_cpu_sse_ok - test %di,%di - jz verify_cpu_no_longmode # only try to force SSE on AMD - movl $0xc0010015,%ecx # HWCR - rdmsr - btr $15,%eax # enable SSE - wrmsr - xor %di,%di # don't loop - jmp verify_cpu_sse_test # try again - -verify_cpu_no_longmode: - popfl # Restore caller passed flags - movl $1,%eax - ret -verify_cpu_sse_ok: - popfl # Restore caller passed flags - xorl %eax, %eax - ret diff --git a/trunk/arch/x86_64/kernel/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index 88cfa50b424d..5176ecf006ee 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -29,7 +29,9 @@ SECTIONS .text : AT(ADDR(.text) - LOAD_OFFSET) { /* First the code that has to be first for bootstrapping */ *(.bootstrap.text) - _stext = .; + /* Then all the functions that are "hot" in profiles, to group them + onto the same hugetlb entry */ + #include "functionlist" /* Then the rest */ *(.text) SCHED_TEXT @@ -48,10 +50,10 @@ SECTIONS __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } __stop___ex_table = .; - BUG_TABLE - RODATA + BUG_TABLE + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { @@ -92,12 +94,6 @@ SECTIONS { *(.vsyscall_gtod_data) } vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data); - - .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) - { *(.vsyscall_1) } - .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) - { *(.vsyscall_2) } - .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) } vgetcpu_mode = VVIRT(.vgetcpu_mode); @@ -105,6 +101,10 @@ SECTIONS .jiffies : AT(VLOAD(.jiffies)) { *(.jiffies) } jiffies = VVIRT(.jiffies); + .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) + { *(.vsyscall_1) } + .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) + { *(.vsyscall_2) } .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) { *(.vsyscall_3) } @@ -194,7 +194,7 @@ SECTIONS __initramfs_end = .; #endif - . = ALIGN(4096); + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); __per_cpu_start = .; .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/x86_64/kernel/vsyscall.c b/trunk/arch/x86_64/kernel/vsyscall.c index dc32cef96195..b43c698cf7d3 100644 --- a/trunk/arch/x86_64/kernel/vsyscall.c +++ b/trunk/arch/x86_64/kernel/vsyscall.c @@ -45,34 +45,14 @@ #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) #define __syscall_clobber "r11","rcx","memory" -#define __pa_vsymbol(x) \ - ({unsigned long v; \ - extern char __vsyscall_0; \ - asm("" : "=r" (v) : "0" (x)); \ - ((v - VSYSCALL_FIRST_PAGE) + __pa_symbol(&__vsyscall_0)); }) -/* - * vsyscall_gtod_data contains data that is : - * - readonly from vsyscalls - * - writen by timer interrupt or systcl (/proc/sys/kernel/vsyscall64) - * Try to keep this structure as small as possible to avoid cache line ping pongs - */ struct vsyscall_gtod_data_t { - seqlock_t lock; - - /* open coded 'struct timespec' */ - time_t wall_time_sec; - u32 wall_time_nsec; - - int sysctl_enabled; + seqlock_t lock; + int sysctl_enabled; + struct timeval wall_time_tv; struct timezone sys_tz; - struct { /* extract of a clocksource struct */ - cycle_t (*vread)(void); - cycle_t cycle_last; - cycle_t mask; - u32 mult; - u32 shift; - } clock; + cycle_t offset_base; + struct clocksource clock; }; int __vgetcpu_mode __section_vgetcpu_mode; @@ -88,13 +68,9 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); /* copy vsyscall data */ - vsyscall_gtod_data.clock.vread = clock->vread; - vsyscall_gtod_data.clock.cycle_last = clock->cycle_last; - vsyscall_gtod_data.clock.mask = clock->mask; - vsyscall_gtod_data.clock.mult = clock->mult; - vsyscall_gtod_data.clock.shift = clock->shift; - vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; - vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; + vsyscall_gtod_data.clock = *clock; + vsyscall_gtod_data.wall_time_tv.tv_sec = wall_time->tv_sec; + vsyscall_gtod_data.wall_time_tv.tv_usec = wall_time->tv_nsec/1000; vsyscall_gtod_data.sys_tz = sys_tz; write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); } @@ -129,8 +105,7 @@ static __always_inline long time_syscall(long *t) static __always_inline void do_vgettimeofday(struct timeval * tv) { cycle_t now, base, mask, cycle_delta; - unsigned seq; - unsigned long mult, shift, nsec; + unsigned long seq, mult, shift, nsec_delta; cycle_t (*vread)(void); do { seq = read_seqbegin(&__vsyscall_gtod_data.lock); @@ -146,20 +121,21 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) mult = __vsyscall_gtod_data.clock.mult; shift = __vsyscall_gtod_data.clock.shift; - tv->tv_sec = __vsyscall_gtod_data.wall_time_sec; - nsec = __vsyscall_gtod_data.wall_time_nsec; + *tv = __vsyscall_gtod_data.wall_time_tv; + } while (read_seqretry(&__vsyscall_gtod_data.lock, seq)); /* calculate interval: */ cycle_delta = (now - base) & mask; /* convert to nsecs: */ - nsec += (cycle_delta * mult) >> shift; + nsec_delta = (cycle_delta * mult) >> shift; - while (nsec >= NSEC_PER_SEC) { + /* convert to usecs and add to timespec: */ + tv->tv_usec += nsec_delta / NSEC_PER_USEC; + while (tv->tv_usec > USEC_PER_SEC) { tv->tv_sec += 1; - nsec -= NSEC_PER_SEC; + tv->tv_usec -= USEC_PER_SEC; } - tv->tv_usec = nsec / NSEC_PER_USEC; } int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) @@ -175,13 +151,11 @@ int __vsyscall(0) vgettimeofday(struct timeval * tv, struct timezone * tz) * unlikely */ time_t __vsyscall(1) vtime(time_t *t) { - time_t result; if (unlikely(!__vsyscall_gtod_data.sysctl_enabled)) return time_syscall(t); - result = __vsyscall_gtod_data.wall_time_sec; - if (t) - *t = result; - return result; + else if (t) + *t = __vsyscall_gtod_data.wall_time_tv.tv_sec; + return __vsyscall_gtod_data.wall_time_tv.tv_sec; } /* Fast way to get current CPU and node. @@ -250,10 +224,10 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, return ret; /* gcc has some trouble with __va(__pa()), so just do it this way. */ - map1 = ioremap(__pa_vsymbol(&vsysc1), 2); + map1 = ioremap(__pa_symbol(&vsysc1), 2); if (!map1) return -ENOMEM; - map2 = ioremap(__pa_vsymbol(&vsysc2), 2); + map2 = ioremap(__pa_symbol(&vsysc2), 2); if (!map2) { ret = -ENOMEM; goto out; diff --git a/trunk/arch/x86_64/mm/fault.c b/trunk/arch/x86_64/mm/fault.c index bfb62a13d7ee..6ada7231f3ab 100644 --- a/trunk/arch/x86_64/mm/fault.c +++ b/trunk/arch/x86_64/mm/fault.c @@ -15,22 +15,22 @@ #include #include #include +#include #include #include #include #include /* For unblank_screen() */ #include -#include #include #include #include -#include #include #include #include #include #include +#include #include /* Page fault error code bits */ @@ -585,7 +585,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, } DEFINE_SPINLOCK(pgd_lock); -LIST_HEAD(pgd_list); +struct page *pgd_list; void vmalloc_sync_all(void) { @@ -605,7 +605,8 @@ void vmalloc_sync_all(void) if (pgd_none(*pgd_ref)) continue; spin_lock(&pgd_lock); - list_for_each_entry(page, &pgd_list, lru) { + for (page = pgd_list; page; + page = (struct page *)page->index) { pgd_t *pgd; pgd = (pgd_t *)page_address(page) + pgd_index(address); if (pgd_none(*pgd)) diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 1336da8bdee1..ec31534eb104 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -22,12 +22,10 @@ #include #include #include -#include #include #include #include #include -#include #include #include @@ -48,7 +46,7 @@ #define Dprintk(x...) #endif -const struct dma_mapping_ops* dma_ops; +struct dma_mapping_ops* dma_ops; EXPORT_SYMBOL(dma_ops); static unsigned long dma_reserve __initdata; @@ -74,11 +72,6 @@ void show_mem(void) for_each_online_pgdat(pgdat) { for (i = 0; i < pgdat->node_spanned_pages; ++i) { - /* this loop can take a while with 256 GB and 4k pages - so update the NMI watchdog */ - if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) { - touch_nmi_watchdog(); - } page = pfn_to_page(pgdat->node_start_pfn + i); total++; if (PageReserved(page)) @@ -172,11 +165,25 @@ __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot) set_pte_phys(address, phys, prot); } -unsigned long __meminitdata table_start, table_end; +unsigned long __initdata table_start, table_end; -static __meminit void *alloc_low_page(unsigned long *phys) +extern pmd_t temp_boot_pmds[]; + +static struct temp_map { + pmd_t *pmd; + void *address; + int allocated; +} temp_mappings[] __initdata = { + { &temp_boot_pmds[0], (void *)(40UL * 1024 * 1024) }, + { &temp_boot_pmds[1], (void *)(42UL * 1024 * 1024) }, + {} +}; + +static __meminit void *alloc_low_page(int *index, unsigned long *phys) { - unsigned long pfn = table_end++; + struct temp_map *ti; + int i; + unsigned long pfn = table_end++, paddr; void *adr; if (after_bootmem) { @@ -187,63 +194,57 @@ static __meminit void *alloc_low_page(unsigned long *phys) if (pfn >= end_pfn) panic("alloc_low_page: ran out of memory"); - - adr = early_ioremap(pfn * PAGE_SIZE, PAGE_SIZE); + for (i = 0; temp_mappings[i].allocated; i++) { + if (!temp_mappings[i].pmd) + panic("alloc_low_page: ran out of temp mappings"); + } + ti = &temp_mappings[i]; + paddr = (pfn << PAGE_SHIFT) & PMD_MASK; + set_pmd(ti->pmd, __pmd(paddr | _KERNPG_TABLE | _PAGE_PSE)); + ti->allocated = 1; + __flush_tlb(); + adr = ti->address + ((pfn << PAGE_SHIFT) & ~PMD_MASK); memset(adr, 0, PAGE_SIZE); - *phys = pfn * PAGE_SIZE; - return adr; -} + *index = i; + *phys = pfn * PAGE_SIZE; + return adr; +} -static __meminit void unmap_low_page(void *adr) +static __meminit void unmap_low_page(int i) { + struct temp_map *ti; if (after_bootmem) return; - early_iounmap(adr, PAGE_SIZE); + ti = &temp_mappings[i]; + set_pmd(ti->pmd, __pmd(0)); + ti->allocated = 0; } /* Must run before zap_low_mappings */ -__meminit void *early_ioremap(unsigned long addr, unsigned long size) +__init void *early_ioremap(unsigned long addr, unsigned long size) { - unsigned long vaddr; - pmd_t *pmd, *last_pmd; - int i, pmds; - - pmds = ((addr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE; - vaddr = __START_KERNEL_map; - pmd = level2_kernel_pgt; - last_pmd = level2_kernel_pgt + PTRS_PER_PMD - 1; - for (; pmd <= last_pmd; pmd++, vaddr += PMD_SIZE) { - for (i = 0; i < pmds; i++) { - if (pmd_present(pmd[i])) - goto next; - } - vaddr += addr & ~PMD_MASK; - addr &= PMD_MASK; - for (i = 0; i < pmds; i++, addr += PMD_SIZE) - set_pmd(pmd + i,__pmd(addr | _KERNPG_TABLE | _PAGE_PSE)); - __flush_tlb(); - return (void *)vaddr; - next: - ; + unsigned long map = round_down(addr, LARGE_PAGE_SIZE); + + /* actually usually some more */ + if (size >= LARGE_PAGE_SIZE) { + return NULL; } - printk("early_ioremap(0x%lx, %lu) failed\n", addr, size); - return NULL; + set_pmd(temp_mappings[0].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); + map += LARGE_PAGE_SIZE; + set_pmd(temp_mappings[1].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); + __flush_tlb(); + return temp_mappings[0].address + (addr & (LARGE_PAGE_SIZE-1)); } /* To avoid virtual aliases later */ -__meminit void early_iounmap(void *addr, unsigned long size) +__init void early_iounmap(void *addr, unsigned long size) { - unsigned long vaddr; - pmd_t *pmd; - int i, pmds; - - vaddr = (unsigned long)addr; - pmds = ((vaddr & ~PMD_MASK) + size + ~PMD_MASK) / PMD_SIZE; - pmd = level2_kernel_pgt + pmd_index(vaddr); - for (i = 0; i < pmds; i++) - pmd_clear(pmd + i); + if ((void *)round_down((unsigned long)addr, LARGE_PAGE_SIZE) != temp_mappings[0].address) + printk("early_iounmap: bad address %p\n", addr); + set_pmd(temp_mappings[0].pmd, __pmd(0)); + set_pmd(temp_mappings[1].pmd, __pmd(0)); __flush_tlb(); } @@ -288,6 +289,7 @@ static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigne for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE ) { + int map; unsigned long pmd_phys; pud_t *pud = pud_page + pud_index(addr); pmd_t *pmd; @@ -305,12 +307,12 @@ static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigne continue; } - pmd = alloc_low_page(&pmd_phys); + pmd = alloc_low_page(&map, &pmd_phys); spin_lock(&init_mm.page_table_lock); set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); phys_pmd_init(pmd, addr, end); spin_unlock(&init_mm.page_table_lock); - unmap_low_page(pmd); + unmap_low_page(map); } __flush_tlb(); } @@ -362,6 +364,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) end = (unsigned long)__va(end); for (; start < end; start = next) { + int map; unsigned long pud_phys; pgd_t *pgd = pgd_offset_k(start); pud_t *pud; @@ -369,7 +372,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) if (after_bootmem) pud = pud_offset(pgd, start & PGDIR_MASK); else - pud = alloc_low_page(&pud_phys); + pud = alloc_low_page(&map, &pud_phys); next = start + PGDIR_SIZE; if (next > end) @@ -377,7 +380,7 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) phys_pud_init(pud, __pa(start), __pa(next)); if (!after_bootmem) set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys)); - unmap_low_page(pud); + unmap_low_page(map); } if (!after_bootmem) @@ -385,6 +388,21 @@ void __meminit init_memory_mapping(unsigned long start, unsigned long end) __flush_tlb_all(); } +void __cpuinit zap_low_mappings(int cpu) +{ + if (cpu == 0) { + pgd_t *pgd = pgd_offset_k(0UL); + pgd_clear(pgd); + } else { + /* + * For AP's, zap the low identity mappings by changing the cr3 + * to init_level4_pgt and doing local flush tlb all + */ + asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt))); + } + __flush_tlb_all(); +} + #ifndef CONFIG_NUMA void __init paging_init(void) { @@ -561,6 +579,15 @@ void __init mem_init(void) reservedpages << (PAGE_SHIFT-10), datasize >> 10, initsize >> 10); + +#ifdef CONFIG_SMP + /* + * Sync boot_level4_pgt mappings with the init_level4_pgt + * except for the low identity mappings which are already zapped + * in init_level4_pgt. This sync-up is essential for AP's bringup + */ + memcpy(boot_level4_pgt+1, init_level4_pgt+1, (PTRS_PER_PGD-1)*sizeof(pgd_t)); +#endif } void free_init_pages(char *what, unsigned long begin, unsigned long end) @@ -570,23 +597,21 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) if (begin >= end) return; - printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); + printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); for (addr = begin; addr < end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); memset((void *)(addr & ~(PAGE_SIZE-1)), POISON_FREE_INITMEM, PAGE_SIZE); - if (addr >= __START_KERNEL_map) - change_page_attr_addr(addr, 1, __pgprot(0)); free_page(addr); totalram_pages++; } - if (addr > __START_KERNEL_map) - global_flush_tlb(); } void free_initmem(void) { + memset(__initdata_begin, POISON_FREE_INITDATA, + __initdata_end - __initdata_begin); free_init_pages("unused kernel memory", (unsigned long)(&__init_begin), (unsigned long)(&__init_end)); @@ -596,23 +621,13 @@ void free_initmem(void) void mark_rodata_ro(void) { - unsigned long start = (unsigned long)_stext, end; - -#ifdef CONFIG_HOTPLUG_CPU - /* It must still be possible to apply SMP alternatives. */ - if (num_possible_cpus() > 1) - start = (unsigned long)_etext; -#endif - end = (unsigned long)__end_rodata; - start = (start + PAGE_SIZE - 1) & PAGE_MASK; - end &= PAGE_MASK; - if (end <= start) - return; + unsigned long addr = (unsigned long)__start_rodata; - change_page_attr_addr(start, (end - start) >> PAGE_SHIFT, PAGE_KERNEL_RO); + for (; addr < (unsigned long)__end_rodata; addr += PAGE_SIZE) + change_page_attr_addr(addr, 1, PAGE_KERNEL_RO); - printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", - (end - start) >> 10); + printk ("Write protecting the kernel read-only data: %luk\n", + (__end_rodata - __start_rodata) >> 10); /* * change_page_attr_addr() requires a global_flush_tlb() call after it. diff --git a/trunk/arch/x86_64/mm/ioremap.c b/trunk/arch/x86_64/mm/ioremap.c index 6cac90aa5032..c6e5e8d401a4 100644 --- a/trunk/arch/x86_64/mm/ioremap.c +++ b/trunk/arch/x86_64/mm/ioremap.c @@ -13,21 +13,12 @@ #include #include #include - #include #include #include #include #include -unsigned long __phys_addr(unsigned long x) -{ - if (x >= __START_KERNEL_map) - return x - __START_KERNEL_map + phys_base; - return x - PAGE_OFFSET; -} -EXPORT_SYMBOL(__phys_addr); - #define ISA_START_ADDRESS 0xa0000 #define ISA_END_ADDRESS 0x100000 diff --git a/trunk/arch/x86_64/mm/k8topology.c b/trunk/arch/x86_64/mm/k8topology.c index f983c75825d0..b5b8dba28b4e 100644 --- a/trunk/arch/x86_64/mm/k8topology.c +++ b/trunk/arch/x86_64/mm/k8topology.c @@ -49,8 +49,11 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) int found = 0; u32 reg; unsigned numnodes; + nodemask_t nodes_parsed; unsigned dualcore = 0; + nodes_clear(nodes_parsed); + if (!early_pci_allowed()) return -1; @@ -62,8 +65,6 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) reg = read_pci_config(0, nb, 0, 0x60); numnodes = ((reg >> 4) & 0xF) + 1; - if (numnodes <= 1) - return -1; printk(KERN_INFO "Number of nodes %d\n", numnodes); @@ -101,7 +102,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) nodeid, (base>>8)&3, (limit>>8) & 3); return -1; } - if (node_isset(nodeid, node_possible_map)) { + if (node_isset(nodeid, nodes_parsed)) { printk(KERN_INFO "Node %d already present. Skipping\n", nodeid); continue; @@ -154,7 +155,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) prevbase = base; - node_set(nodeid, node_possible_map); + node_set(nodeid, nodes_parsed); } if (!found) diff --git a/trunk/arch/x86_64/mm/numa.c b/trunk/arch/x86_64/mm/numa.c index 51548947ad3b..41b8fb069924 100644 --- a/trunk/arch/x86_64/mm/numa.c +++ b/trunk/arch/x86_64/mm/numa.c @@ -273,213 +273,125 @@ void __init numa_init_array(void) #ifdef CONFIG_NUMA_EMU /* Numa emulation */ -#define E820_ADDR_HOLE_SIZE(start, end) \ - (e820_hole_size((start) >> PAGE_SHIFT, (end) >> PAGE_SHIFT) << \ - PAGE_SHIFT) -char *cmdline __initdata; +int numa_fake __initdata = 0; /* - * Setups up nid to range from addr to addr + size. If the end boundary is - * greater than max_addr, then max_addr is used instead. The return value is 0 - * if there is additional memory left for allocation past addr and -1 otherwise. - * addr is adjusted to be at the end of the node. + * This function is used to find out if the start and end correspond to + * different zones. */ -static int __init setup_node_range(int nid, struct bootnode *nodes, u64 *addr, - u64 size, u64 max_addr) +int zone_cross_over(unsigned long start, unsigned long end) { - int ret = 0; - nodes[nid].start = *addr; - *addr += size; - if (*addr >= max_addr) { - *addr = max_addr; - ret = -1; - } - nodes[nid].end = *addr; - node_set(nid, node_possible_map); - printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n", nid, - nodes[nid].start, nodes[nid].end, - (nodes[nid].end - nodes[nid].start) >> 20); - return ret; + if ((start < (MAX_DMA32_PFN << PAGE_SHIFT)) && + (end >= (MAX_DMA32_PFN << PAGE_SHIFT))) + return 1; + return 0; } -/* - * Splits num_nodes nodes up equally starting at node_start. The return value - * is the number of nodes split up and addr is adjusted to be at the end of the - * last node allocated. - */ -static int __init split_nodes_equally(struct bootnode *nodes, u64 *addr, - u64 max_addr, int node_start, - int num_nodes) +static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) { - unsigned int big; - u64 size; - int i; + int i, big; + struct bootnode nodes[MAX_NUMNODES]; + unsigned long sz, old_sz; + unsigned long hole_size; + unsigned long start, end; + unsigned long max_addr = (end_pfn << PAGE_SHIFT); - if (num_nodes <= 0) - return -1; - if (num_nodes > MAX_NUMNODES) - num_nodes = MAX_NUMNODES; - size = (max_addr - *addr - E820_ADDR_HOLE_SIZE(*addr, max_addr)) / - num_nodes; - /* - * Calculate the number of big nodes that can be allocated as a result - * of consolidating the leftovers. - */ - big = ((size & ~FAKE_NODE_MIN_HASH_MASK) * num_nodes) / - FAKE_NODE_MIN_SIZE; - - /* Round down to nearest FAKE_NODE_MIN_SIZE. */ - size &= FAKE_NODE_MIN_HASH_MASK; - if (!size) { - printk(KERN_ERR "Not enough memory for each node. " - "NUMA emulation disabled.\n"); - return -1; - } + start = (start_pfn << PAGE_SHIFT); + hole_size = e820_hole_size(start, max_addr); + sz = (max_addr - start - hole_size) / numa_fake; - for (i = node_start; i < num_nodes + node_start; i++) { - u64 end = *addr + size; - if (i < big) - end += FAKE_NODE_MIN_SIZE; - /* - * The final node can have the remaining system RAM. Other - * nodes receive roughly the same amount of available pages. - */ - if (i == num_nodes + node_start - 1) - end = max_addr; - else - while (end - *addr - E820_ADDR_HOLE_SIZE(*addr, end) < - size) { - end += FAKE_NODE_MIN_SIZE; - if (end > max_addr) { - end = max_addr; - break; - } - } - if (setup_node_range(i, nodes, addr, end - *addr, max_addr) < 0) - break; - } - return i - node_start + 1; -} + /* Kludge needed for the hash function */ -/* - * Splits the remaining system RAM into chunks of size. The remaining memory is - * always assigned to a final node and can be asymmetric. Returns the number of - * nodes split. - */ -static int __init split_nodes_by_size(struct bootnode *nodes, u64 *addr, - u64 max_addr, int node_start, u64 size) -{ - int i = node_start; - size = (size << 20) & FAKE_NODE_MIN_HASH_MASK; - while (!setup_node_range(i++, nodes, addr, size, max_addr)) - ; - return i - node_start; -} - -/* - * Sets up the system RAM area from start_pfn to end_pfn according to the - * numa=fake command-line option. - */ -static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) -{ - struct bootnode nodes[MAX_NUMNODES]; - u64 addr = start_pfn << PAGE_SHIFT; - u64 max_addr = end_pfn << PAGE_SHIFT; - int num_nodes = 0; - int coeff_flag; - int coeff = -1; - int num = 0; - u64 size; - int i; + old_sz = sz; + /* + * Round down to the nearest FAKE_NODE_MIN_SIZE. + */ + sz &= FAKE_NODE_MIN_HASH_MASK; - memset(&nodes, 0, sizeof(nodes)); /* - * If the numa=fake command-line is just a single number N, split the - * system RAM into N fake nodes. + * We ensure that each node is at least 64MB big. Smaller than this + * size can cause VM hiccups. */ - if (!strchr(cmdline, '*') && !strchr(cmdline, ',')) { - num_nodes = split_nodes_equally(nodes, &addr, max_addr, 0, - simple_strtol(cmdline, NULL, 0)); - if (num_nodes < 0) - return num_nodes; - goto out; + if (sz == 0) { + printk(KERN_INFO "Not enough memory for %d nodes. Reducing " + "the number of nodes\n", numa_fake); + numa_fake = (max_addr - start - hole_size) / FAKE_NODE_MIN_SIZE; + printk(KERN_INFO "Number of fake nodes will be = %d\n", + numa_fake); + sz = FAKE_NODE_MIN_SIZE; } - - /* Parse the command line. */ - for (coeff_flag = 0; ; cmdline++) { - if (*cmdline && isdigit(*cmdline)) { - num = num * 10 + *cmdline - '0'; - continue; - } - if (*cmdline == '*') { - if (num > 0) - coeff = num; - coeff_flag = 1; + /* + * Find out how many nodes can get an extra NODE_MIN_SIZE granule. + * This logic ensures the extra memory gets distributed among as many + * nodes as possible (as compared to one single node getting all that + * extra memory. + */ + big = ((old_sz - sz) * numa_fake) / FAKE_NODE_MIN_SIZE; + printk(KERN_INFO "Fake node Size: %luMB hole_size: %luMB big nodes: " + "%d\n", + (sz >> 20), (hole_size >> 20), big); + memset(&nodes,0,sizeof(nodes)); + end = start; + for (i = 0; i < numa_fake; i++) { + /* + * In case we are not able to allocate enough memory for all + * the nodes, we reduce the number of fake nodes. + */ + if (end >= max_addr) { + numa_fake = i - 1; + break; } - if (!*cmdline || *cmdline == ',') { - if (!coeff_flag) - coeff = 1; - /* - * Round down to the nearest FAKE_NODE_MIN_SIZE. - * Command-line coefficients are in megabytes. - */ - size = ((u64)num << 20) & FAKE_NODE_MIN_HASH_MASK; - if (size) - for (i = 0; i < coeff; i++, num_nodes++) - if (setup_node_range(num_nodes, nodes, - &addr, size, max_addr) < 0) - goto done; - if (!*cmdline) + start = nodes[i].start = end; + /* + * Final node can have all the remaining memory. + */ + if (i == numa_fake-1) + sz = max_addr - start; + end = nodes[i].start + sz; + /* + * Fir "big" number of nodes get extra granule. + */ + if (i < big) + end += FAKE_NODE_MIN_SIZE; + /* + * Iterate over the range to ensure that this node gets at + * least sz amount of RAM (excluding holes) + */ + while ((end - start - e820_hole_size(start, end)) < sz) { + end += FAKE_NODE_MIN_SIZE; + if (end >= max_addr) break; - coeff_flag = 0; - coeff = -1; - } - num = 0; - } -done: - if (!num_nodes) - return -1; - /* Fill remainder of system RAM, if appropriate. */ - if (addr < max_addr) { - if (coeff_flag && coeff < 0) { - /* Split remaining nodes into num-sized chunks */ - num_nodes += split_nodes_by_size(nodes, &addr, max_addr, - num_nodes, num); - goto out; } - switch (*(cmdline - 1)) { - case '*': - /* Split remaining nodes into coeff chunks */ - if (coeff <= 0) + /* + * Look at the next node to make sure there is some real memory + * to map. Bad things happen when the only memory present + * in a zone on a fake node is IO hole. + */ + while (e820_hole_size(end, end + FAKE_NODE_MIN_SIZE) > 0) { + if (zone_cross_over(start, end + sz)) { + end = (MAX_DMA32_PFN << PAGE_SHIFT); break; - num_nodes += split_nodes_equally(nodes, &addr, max_addr, - num_nodes, coeff); - break; - case ',': - /* Do not allocate remaining system RAM */ - break; - default: - /* Give one final node */ - setup_node_range(num_nodes, nodes, &addr, - max_addr - addr, max_addr); - num_nodes++; + } + if (end >= max_addr) + break; + end += FAKE_NODE_MIN_SIZE; } - } -out: - memnode_shift = compute_hash_shift(nodes, num_nodes); - if (memnode_shift < 0) { - memnode_shift = 0; - printk(KERN_ERR "No NUMA hash function found. NUMA emulation " - "disabled.\n"); - return -1; - } - - /* - * We need to vacate all active ranges that may have been registered by - * SRAT. - */ - remove_all_active_ranges(); - for_each_node_mask(i, node_possible_map) { + if (end > max_addr) + end = max_addr; + nodes[i].end = end; + printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n", + i, + nodes[i].start, nodes[i].end, + (nodes[i].end - nodes[i].start) >> 20); + node_set_online(i); + } + memnode_shift = compute_hash_shift(nodes, numa_fake); + if (memnode_shift < 0) { + memnode_shift = 0; + printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n"); + return -1; + } + for_each_online_node(i) { e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT, nodes[i].end >> PAGE_SHIFT); setup_node_bootmem(i, nodes[i].start, nodes[i].end); @@ -487,32 +399,26 @@ static int __init numa_emulation(unsigned long start_pfn, unsigned long end_pfn) numa_init_array(); return 0; } -#undef E820_ADDR_HOLE_SIZE -#endif /* CONFIG_NUMA_EMU */ +#endif void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) { int i; - nodes_clear(node_possible_map); - #ifdef CONFIG_NUMA_EMU - if (cmdline && !numa_emulation(start_pfn, end_pfn)) + if (numa_fake && !numa_emulation(start_pfn, end_pfn)) return; - nodes_clear(node_possible_map); #endif #ifdef CONFIG_ACPI_NUMA if (!numa_off && !acpi_scan_nodes(start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT)) return; - nodes_clear(node_possible_map); #endif #ifdef CONFIG_K8_NUMA if (!numa_off && !k8_scan_nodes(start_pfn<= __START_KERNEL_map - && address < __START_KERNEL_map + KERNEL_TEXT_SIZE) { - address = (unsigned long)__va(__pa(address)); - kernel_map = 1; - } - down_write(&init_mm.mmap_sem); for (i = 0; i < numpages; i++, address += PAGE_SIZE) { unsigned long pfn = __pa(address) >> PAGE_SHIFT; - if (!kernel_map || pte_present(pfn_pte(0, prot))) { - err = __change_page_attr(address, pfn, prot, PAGE_KERNEL); - if (err) - break; - } + err = __change_page_attr(address, pfn, prot, PAGE_KERNEL); + if (err) + break; /* Handle kernel mapping too which aliases part of the * lowmem */ if (__pa(address) < KERNEL_TEXT_SIZE) { diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 1e76bb0a7277..2efe215fc76a 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -419,21 +419,19 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) return -1; } - node_possible_map = nodes_parsed; - /* Finally register nodes */ - for_each_node_mask(i, node_possible_map) + for_each_node_mask(i, nodes_parsed) setup_node_bootmem(i, nodes[i].start, nodes[i].end); /* Try again in case setup_node_bootmem missed one due to missing bootmem */ - for_each_node_mask(i, node_possible_map) + for_each_node_mask(i, nodes_parsed) if (!node_online(i)) setup_node_bootmem(i, nodes[i].start, nodes[i].end); for (i = 0; i < NR_CPUS; i++) { if (cpu_to_node[i] == NUMA_NO_NODE) continue; - if (!node_isset(cpu_to_node[i], node_possible_map)) + if (!node_isset(cpu_to_node[i], nodes_parsed)) numa_set_node(i, NUMA_NO_NODE); } numa_init_array(); diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c index ce758bab95b1..795bd5ac6f4c 100644 --- a/trunk/arch/xtensa/kernel/process.c +++ b/trunk/arch/xtensa/kernel/process.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/xtensa/kernel/ptrace.c b/trunk/arch/xtensa/kernel/ptrace.c index 14104ff63093..8b6d3d0623b6 100644 --- a/trunk/arch/xtensa/kernel/ptrace.c +++ b/trunk/arch/xtensa/kernel/ptrace.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/xtensa/kernel/signal.c b/trunk/arch/xtensa/kernel/signal.c index 58107672a619..c6d9880a4cdb 100644 --- a/trunk/arch/xtensa/kernel/signal.c +++ b/trunk/arch/xtensa/kernel/signal.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/xtensa/kernel/vmlinux.lds.S b/trunk/arch/xtensa/kernel/vmlinux.lds.S index 4fbd66a52a88..ab6370054cee 100644 --- a/trunk/arch/xtensa/kernel/vmlinux.lds.S +++ b/trunk/arch/xtensa/kernel/vmlinux.lds.S @@ -198,7 +198,7 @@ SECTIONS __ftr_fixup : { *(__ftr_fixup) } __stop___ftr_fixup = .; - . = ALIGN(4096); + . = ALIGN(32); __per_cpu_start = .; .data.percpu : { *(.data.percpu) } __per_cpu_end = .; diff --git a/trunk/arch/xtensa/kernel/xtensa_ksyms.c b/trunk/arch/xtensa/kernel/xtensa_ksyms.c index cd7e6a020602..0b4cb93db5a3 100644 --- a/trunk/arch/xtensa/kernel/xtensa_ksyms.c +++ b/trunk/arch/xtensa/kernel/xtensa_ksyms.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/xtensa/platform-iss/network.c b/trunk/arch/xtensa/platform-iss/network.c index 4bfe333be229..ab05bff40104 100644 --- a/trunk/arch/xtensa/platform-iss/network.c +++ b/trunk/arch/xtensa/platform-iss/network.c @@ -251,7 +251,7 @@ static int tuntap_open(struct iss_net_private *lp) memset(&ifr, 0, sizeof ifr); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name); + strlcpy(ifr.ifr_name, dev_name, sizeof ifr.ifr_name - 1); if ((err = simc_ioctl(fd, TUNSETIFF, (void*) &ifr)) < 0) { printk("Failed to set interface, returned %d " diff --git a/trunk/arch/xtensa/platform-iss/setup.c b/trunk/arch/xtensa/platform-iss/setup.c index f60c8cf6dfbe..c8a42b60c57a 100644 --- a/trunk/arch/xtensa/platform-iss/setup.c +++ b/trunk/arch/xtensa/platform-iss/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index 640aa839d63f..ef126277b4b3 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -569,7 +569,7 @@ static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, static int as_close_req(struct as_data *ad, struct as_io_context *aic, struct request *rq) { - unsigned long delay; /* jiffies */ + unsigned long delay; /* milliseconds */ sector_t last = ad->last_sector[ad->batch_data_dir]; sector_t next = rq->sector; sector_t delta; /* acceptable close offset (in sectors) */ @@ -578,11 +578,11 @@ static int as_close_req(struct as_data *ad, struct as_io_context *aic, if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished) delay = 0; else - delay = jiffies - ad->antic_start; + delay = ((jiffies - ad->antic_start) * 1000) / HZ; if (delay == 0) delta = 8192; - else if (delay <= (20 * HZ / 1000) && delay <= ad->antic_expire) + else if (delay <= 20 && delay <= ad->antic_expire) delta = 8192 << delay; else return 1; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index baef5fc7cff8..64df3fa303b0 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -2090,11 +2090,13 @@ static void cfq_slab_kill(void) static int __init cfq_slab_setup(void) { - cfq_pool = KMEM_CACHE(cfq_queue, 0); + cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0, + NULL, NULL); if (!cfq_pool) goto fail; - cfq_ioc_pool = KMEM_CACHE(cfq_io_context, 0); + cfq_ioc_pool = kmem_cache_create("cfq_ioc_pool", + sizeof(struct cfq_io_context), 0, 0, NULL, NULL); if (!cfq_ioc_pool) goto fail; diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index b5664440896c..441432a142f2 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -17,7 +17,7 @@ #include #include -struct kset block_subsys; +struct subsystem block_subsys; static DEFINE_MUTEX(block_subsys_lock); /* @@ -221,7 +221,7 @@ static void *part_start(struct seq_file *part, loff_t *pos) loff_t l = *pos; mutex_lock(&block_subsys_lock); - list_for_each(p, &block_subsys.list) + list_for_each(p, &block_subsys.kset.list) if (!l--) return list_entry(p, struct gendisk, kobj.entry); return NULL; @@ -231,7 +231,7 @@ static void *part_next(struct seq_file *part, void *v, loff_t *pos) { struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; ++*pos; - return p==&block_subsys.list ? NULL : + return p==&block_subsys.kset.list ? NULL : list_entry(p, struct gendisk, kobj.entry); } @@ -246,7 +246,7 @@ static int show_partition(struct seq_file *part, void *v) int n; char buf[BDEVNAME_SIZE]; - if (&sgp->kobj.entry == block_subsys.list.next) + if (&sgp->kobj.entry == block_subsys.kset.list.next) seq_puts(part, "major minor #blocks name\n\n"); /* Don't show non-partitionable removeable devices or empty devices */ @@ -565,7 +565,7 @@ static void *diskstats_start(struct seq_file *part, loff_t *pos) struct list_head *p; mutex_lock(&block_subsys_lock); - list_for_each(p, &block_subsys.list) + list_for_each(p, &block_subsys.kset.list) if (!k--) return list_entry(p, struct gendisk, kobj.entry); return NULL; @@ -575,7 +575,7 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos) { struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; ++*pos; - return p==&block_subsys.list ? NULL : + return p==&block_subsys.kset.list ? NULL : list_entry(p, struct gendisk, kobj.entry); } diff --git a/trunk/block/ioctl.c b/trunk/block/ioctl.c index f7e3e8abf887..e06dbe9bc858 100644 --- a/trunk/block/ioctl.c +++ b/trunk/block/ioctl.c @@ -80,7 +80,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user } /* all seems OK */ fsync_bdev(bdevp); - invalidate_bdev(bdevp); + invalidate_bdev(bdevp, 0); mutex_lock_nested(&bdev->bd_mutex, 1); delete_partition(disk, part); @@ -236,7 +236,7 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, lock_kernel(); fsync_bdev(bdev); - invalidate_bdev(bdev); + invalidate_bdev(bdev, 0); unlock_kernel(); return 0; diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index d99d402953a3..123003a90477 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -1925,8 +1925,6 @@ blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) blk_queue_max_hw_segments(q, MAX_HW_SEGMENTS); blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); - q->sg_reserved_size = INT_MAX; - /* * all done */ @@ -2558,7 +2556,6 @@ int blk_rq_map_kern(request_queue_t *q, struct request *rq, void *kbuf, bio->bi_rw |= (1 << BIO_RW); blk_rq_bio_prep(q, rq, bio); - blk_queue_bounce(q, &rq->bio); rq->buffer = rq->data = NULL; return 0; } diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index e83f1dbf7c29..65c6a3cba6d6 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -78,9 +78,7 @@ static int sg_set_timeout(request_queue_t *q, int __user *p) static int sg_get_reserved_size(request_queue_t *q, int __user *p) { - unsigned val = min(q->sg_reserved_size, q->max_sectors << 9); - - return put_user(val, p); + return put_user(q->sg_reserved_size, p); } static int sg_set_reserved_size(request_queue_t *q, int __user *p) diff --git a/trunk/crypto/cryptomgr.c b/trunk/crypto/cryptomgr.c index 6958ea83ee44..e5fb7cca5107 100644 --- a/trunk/crypto/cryptomgr.c +++ b/trunk/crypto/cryptomgr.c @@ -24,8 +24,6 @@ #include "internal.h" struct cryptomgr_param { - struct task_struct *thread; - struct rtattr *tb[CRYPTOA_MAX]; struct { @@ -81,6 +79,7 @@ static int cryptomgr_probe(void *data) static int cryptomgr_schedule_probe(struct crypto_larval *larval) { + struct task_struct *thread; struct cryptomgr_param *param; const char *name = larval->alg.cra_name; const char *p; @@ -130,8 +129,8 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) memcpy(param->larval.name, larval->alg.cra_name, CRYPTO_MAX_ALG_NAME); - param->thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); - if (IS_ERR(param->thread)) + thread = kthread_run(cryptomgr_probe, param, "cryptomgr"); + if (IS_ERR(thread)) goto err_free_param; return NOTIFY_STOP; diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index 26ca9031ea49..920c975bb6d4 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -58,7 +58,7 @@ obj-$(CONFIG_GAMEPORT) += input/gameport/ obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_RTC_LIB) += rtc/ -obj-y += i2c/ +obj-$(CONFIG_I2C) += i2c/ obj-$(CONFIG_W1) += w1/ obj-$(CONFIG_HWMON) += hwmon/ obj-$(CONFIG_PHONE) += telephony/ diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 41427a41f620..4334c208841a 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -245,35 +245,6 @@ arch_initcall(init_acpi_device_notify); #if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) -#ifdef CONFIG_PM -static u32 rtc_handler(void *context) -{ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_disable_event(ACPI_EVENT_RTC, 0); - return ACPI_INTERRUPT_HANDLED; -} - -static inline void rtc_wake_setup(void) -{ - acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); -} - -static void rtc_wake_on(struct device *dev) -{ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_enable_event(ACPI_EVENT_RTC, 0); -} - -static void rtc_wake_off(struct device *dev) -{ - acpi_disable_event(ACPI_EVENT_RTC, 0); -} -#else -#define rtc_wake_setup() do{}while(0) -#define rtc_wake_on NULL -#define rtc_wake_off NULL -#endif - /* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find * its device node and pass extra config data. This helps its driver use * capabilities that the now-obsolete mc146818 didn't have, and informs it @@ -312,24 +283,11 @@ static int __init acpi_rtc_init(void) struct device *dev = get_rtc_dev(); if (dev) { - rtc_wake_setup(); - rtc_info.wake_on = rtc_wake_on; - rtc_info.wake_off = rtc_wake_off; - - /* workaround bug in some ACPI tables */ - if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) { - DBG("bogus FADT month_alarm\n"); - acpi_gbl_FADT.month_alarm = 0; - } - rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; rtc_info.rtc_century = acpi_gbl_FADT.century; - /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */ - if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE) - printk(PREFIX "RTC can wake from S4\n"); - + /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */ dev->platform_data = &rtc_info; @@ -338,7 +296,7 @@ static int __init acpi_rtc_init(void) put_device(dev); } else - DBG("RTC unavailable?\n"); + pr_debug("ACPI: RTC unavailable?\n"); return 0; } /* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index 4dd0dabe81cb..8fcd6a15517f 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -228,7 +228,7 @@ int __init acpi_numa_init(void) return 0; } -int __meminit acpi_get_pxm(acpi_handle h) +int acpi_get_pxm(acpi_handle h) { unsigned long pxm; acpi_status status; @@ -246,7 +246,7 @@ int __meminit acpi_get_pxm(acpi_handle h) } EXPORT_SYMBOL(acpi_get_pxm); -int __meminit acpi_get_node(acpi_handle *handle) +int acpi_get_node(acpi_handle *handle) { int pxm, node = -1; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index c2bed56915e1..971eca4864fa 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index ee5759bef945..ae0654cd11ea 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -475,7 +475,7 @@ static void acpi_processor_idle(void) #ifdef CONFIG_GENERIC_TIME /* TSC halts in C2, so notify users */ - mark_tsc_unstable("possible TSC halt in C2"); + mark_tsc_unstable(); #endif /* Re-enable interrupts */ local_irq_enable(); @@ -517,7 +517,7 @@ static void acpi_processor_idle(void) #ifdef CONFIG_GENERIC_TIME /* TSC halts in C3, so notify users */ - mark_tsc_unstable("TSC halts in C3"); + mark_tsc_unstable(); #endif /* Re-enable interrupts */ local_irq_enable(); diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index c4efc0c17f8f..2f2e7964226d 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -433,6 +433,49 @@ static int acpi_processor_perf_open_fs(struct inode *inode, struct file *file) PDE(inode)->data); } +static ssize_t +acpi_processor_write_performance(struct file *file, + const char __user * buffer, + size_t count, loff_t * data) +{ + int result = 0; + struct seq_file *m = file->private_data; + struct acpi_processor *pr = m->private; + struct acpi_processor_performance *perf; + char state_string[12] = { '\0' }; + unsigned int new_state = 0; + struct cpufreq_policy policy; + + + if (!pr || (count > sizeof(state_string) - 1)) + return -EINVAL; + + perf = pr->performance; + if (!perf) + return -EINVAL; + + if (copy_from_user(state_string, buffer, count)) + return -EFAULT; + + state_string[count] = '\0'; + new_state = simple_strtoul(state_string, NULL, 0); + + if (new_state >= perf->state_count) + return -EINVAL; + + cpufreq_get_policy(&policy, pr->id); + + policy.cpu = pr->id; + policy.min = perf->states[new_state].core_frequency * 1000; + policy.max = perf->states[new_state].core_frequency * 1000; + + result = cpufreq_set_policy(&policy); + if (result) + return result; + + return count; +} + static void acpi_cpufreq_add_file(struct acpi_processor *pr) { struct proc_dir_entry *entry = NULL; @@ -444,9 +487,10 @@ static void acpi_cpufreq_add_file(struct acpi_processor *pr) /* add file 'performance' [R/W] */ entry = create_proc_entry(ACPI_PROCESSOR_FILE_PERFORMANCE, - S_IFREG | S_IRUGO, + S_IFREG | S_IRUGO | S_IWUSR, acpi_device_dir(device)); if (entry){ + acpi_processor_perf_fops.write = acpi_processor_write_performance; entry->proc_fops = &acpi_processor_perf_fops; entry->data = acpi_driver_data(device); entry->owner = THIS_MODULE; diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 6b3b8a522476..d80dd84e5bfd 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -302,7 +302,7 @@ static void acpi_device_shutdown(struct device *dev) return ; } -struct bus_type acpi_bus_type = { +static struct bus_type acpi_bus_type = { .name = "acpi", .suspend = acpi_device_suspend, .resume = acpi_device_resume, diff --git a/trunk/drivers/acpi/sleep/proc.c b/trunk/drivers/acpi/sleep/proc.c index 5a76e5be61d5..2d912b71e543 100644 --- a/trunk/drivers/acpi/sleep/proc.c +++ b/trunk/drivers/acpi/sleep/proc.c @@ -60,7 +60,7 @@ acpi_system_write_sleep(struct file *file, state = simple_strtoul(str, NULL, 0); #ifdef CONFIG_SOFTWARE_SUSPEND if (state == 4) { - error = pm_suspend(PM_SUSPEND_DISK); + error = software_suspend(); goto Done; } #endif @@ -70,14 +70,6 @@ acpi_system_write_sleep(struct file *file, } #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ -#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) -/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ -#else -#define HAVE_ACPI_LEGACY_ALARM -#endif - -#ifdef HAVE_ACPI_LEGACY_ALARM - static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) { u32 sec, min, hr; @@ -349,8 +341,6 @@ acpi_system_write_alarm(struct file *file, end: return_VALUE(result ? result : count); } -#endif /* HAVE_ACPI_LEGACY_ALARM */ - extern struct list_head acpi_wakeup_device_list; extern spinlock_t acpi_device_lock; @@ -474,7 +464,6 @@ static const struct file_operations acpi_system_sleep_fops = { }; #endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ -#ifdef HAVE_ACPI_LEGACY_ALARM static const struct file_operations acpi_system_alarm_fops = { .open = acpi_system_alarm_open_fs, .read = seq_read, @@ -490,9 +479,8 @@ static u32 rtc_handler(void *context) return ACPI_INTERRUPT_HANDLED; } -#endif /* HAVE_ACPI_LEGACY_ALARM */ -static int __init acpi_sleep_proc_init(void) +static int acpi_sleep_proc_init(void) { struct proc_dir_entry *entry = NULL; @@ -508,7 +496,6 @@ static int __init acpi_sleep_proc_init(void) entry->proc_fops = &acpi_system_sleep_fops; #endif -#ifdef HAVE_ACPI_LEGACY_ALARM /* 'alarm' [R/W] */ entry = create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR, @@ -516,9 +503,6 @@ static int __init acpi_sleep_proc_init(void) if (entry) entry->proc_fops = &acpi_system_alarm_fops; - acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); -#endif /* HAVE_ACPI_LEGACY_ALARM */ - /* 'wakeup device' [R/W] */ entry = create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR, @@ -526,6 +510,7 @@ static int __init acpi_sleep_proc_init(void) if (entry) entry->proc_fops = &acpi_system_wakeup_device_fops; + acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); return 0; } diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index 45dbdc14915f..365c306c7cf8 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -550,21 +550,13 @@ config PATA_WINBOND_VLB config PATA_PLATFORM tristate "Generic platform device PATA support" - depends on EMBEDDED || ARCH_RPC + depends on EMBEDDED help This option enables support for generic directly connected ATA devices commonly found on embedded systems. If unsure, say N. -config PATA_ICSIDE - tristate "Acorn ICS PATA support" - depends on ARM && ARCH_ACORN - help - On Acorn systems, say Y here if you wish to use the ICS PATA - interface card. This is not required for ICS partition support. - If you are unsure, say N to this. - config PATA_IXP4XX_CF tristate "IXP4XX Compact Flash support" depends on ARCH_IXP4XX diff --git a/trunk/drivers/ata/Makefile b/trunk/drivers/ata/Makefile index 6f42a0e2812d..b7055e302650 100644 --- a/trunk/drivers/ata/Makefile +++ b/trunk/drivers/ata/Makefile @@ -62,7 +62,6 @@ obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o obj-$(CONFIG_PATA_SCC) += pata_scc.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o -obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o # Should be last but one libata driver obj-$(CONFIG_ATA_GENERIC) += ata_generic.o # Should be last libata driver diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index d9617892fc23..34c5534ed64c 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -874,8 +874,7 @@ static int ahci_clo(struct ata_port *ap) return 0; } -static int ahci_softreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) +static int ahci_softreset(struct ata_port *ap, unsigned int *class) { struct ahci_port_priv *pp = ap->private_data; void __iomem *port_mmio = ahci_port_base(ap); @@ -960,13 +959,15 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class, */ msleep(150); - rc = ata_wait_ready(ap, deadline); - /* link occupied, -ENODEV too is an error */ - if (rc) { - reason = "device not ready"; - goto fail; + *class = ATA_DEV_NONE; + if (ata_port_online(ap)) { + if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { + rc = -EIO; + reason = "device not ready"; + goto fail; + } + *class = ahci_dev_classify(ap); } - *class = ahci_dev_classify(ap); DPRINTK("EXIT, class=%u\n", *class); return 0; @@ -978,8 +979,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class, return rc; } -static int ahci_hardreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) +static int ahci_hardreset(struct ata_port *ap, unsigned int *class) { struct ahci_port_priv *pp = ap->private_data; u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; @@ -995,7 +995,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, tf.command = 0x80; ata_tf_to_fis(&tf, d2h_fis, 0); - rc = sata_std_hardreset(ap, class, deadline); + rc = sata_std_hardreset(ap, class); ahci_start_engine(ap); @@ -1008,8 +1008,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class, return rc; } -static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) +static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class) { int rc; @@ -1017,8 +1016,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class, ahci_stop_engine(ap); - rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context), - deadline); + rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context)); /* vt8251 needs SError cleared for the port to operate */ ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR)); diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 4a795fdb6a02..55d306a3e538 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -625,18 +625,17 @@ static int ich_pata_cable_detect(struct ata_port *ap) /** * piix_pata_prereset - prereset for PATA host controller * @ap: Target port - * @deadline: deadline jiffies for the operation * * LOCKING: * None (inherited from caller). */ -static int piix_pata_prereset(struct ata_port *ap, unsigned long deadline) +static int piix_pata_prereset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } static void piix_pata_error_handler(struct ata_port *ap) @@ -645,6 +644,7 @@ static void piix_pata_error_handler(struct ata_port *ap) ata_std_postreset); } + static void piix_sata_error_handler(struct ata_port *ap) { ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL, diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index a7950885d18e..ca67484af1eb 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -2979,71 +2979,23 @@ int ata_busy_sleep(struct ata_port *ap, return 0; } -/** - * ata_wait_ready - sleep until BSY clears, or timeout - * @ap: port containing status register to be polled - * @deadline: deadline jiffies for the operation - * - * Sleep until ATA Status register bit BSY clears, or timeout - * occurs. - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * 0 on success, -errno otherwise. - */ -int ata_wait_ready(struct ata_port *ap, unsigned long deadline) -{ - unsigned long start = jiffies; - int warned = 0; - - while (1) { - u8 status = ata_chk_status(ap); - unsigned long now = jiffies; - - if (!(status & ATA_BUSY)) - return 0; - if (status == 0xff) - return -ENODEV; - if (time_after(now, deadline)) - return -EBUSY; - - if (!warned && time_after(now, start + 5 * HZ) && - (deadline - now > 3 * HZ)) { - ata_port_printk(ap, KERN_WARNING, - "port is slow to respond, please be patient " - "(Status 0x%x)\n", status); - warned = 1; - } - - msleep(50); - } -} - -static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask, - unsigned long deadline) +static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) { struct ata_ioports *ioaddr = &ap->ioaddr; unsigned int dev0 = devmask & (1 << 0); unsigned int dev1 = devmask & (1 << 1); - int rc, ret = 0; + unsigned long timeout; /* if device 0 was found in ata_devchk, wait for its * BSY bit to clear */ - if (dev0) { - rc = ata_wait_ready(ap, deadline); - if (rc) { - if (rc != -ENODEV) - return rc; - ret = rc; - } - } + if (dev0) + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); /* if device 1 was found in ata_devchk, wait for * register access, then wait for BSY to clear */ + timeout = jiffies + ATA_TMOUT_BOOT; while (dev1) { u8 nsect, lbal; @@ -3052,18 +3004,14 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask, lbal = ioread8(ioaddr->lbal_addr); if ((nsect == 1) && (lbal == 1)) break; - if (time_after(jiffies, deadline)) - return -EBUSY; - msleep(50); /* give drive a breather */ - } - if (dev1) { - rc = ata_wait_ready(ap, deadline); - if (rc) { - if (rc != -ENODEV) - return rc; - ret = rc; + if (time_after(jiffies, timeout)) { + dev1 = 0; + break; } + msleep(50); /* give drive a breather */ } + if (dev1) + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); /* is all this really necessary? */ ap->ops->dev_select(ap, 0); @@ -3071,12 +3019,10 @@ static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask, ap->ops->dev_select(ap, 1); if (dev0) ap->ops->dev_select(ap, 0); - - return ret; } -static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask, - unsigned long deadline) +static unsigned int ata_bus_softreset(struct ata_port *ap, + unsigned int devmask) { struct ata_ioports *ioaddr = &ap->ioaddr; @@ -3106,9 +3052,11 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask, * pulldown resistor. */ if (ata_check_status(ap) == 0xFF) - return -ENODEV; + return 0; + + ata_bus_post_reset(ap, devmask); - return ata_bus_post_reset(ap, devmask, deadline); + return 0; } /** @@ -3137,7 +3085,6 @@ void ata_bus_reset(struct ata_port *ap) unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; u8 err; unsigned int dev0, dev1 = 0, devmask = 0; - int rc; DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no); @@ -3159,11 +3106,9 @@ void ata_bus_reset(struct ata_port *ap) ap->ops->dev_select(ap, 0); /* issue bus reset */ - if (ap->flags & ATA_FLAG_SRST) { - rc = ata_bus_softreset(ap, devmask, jiffies + 40 * HZ); - if (rc && rc != -ENODEV) + if (ap->flags & ATA_FLAG_SRST) + if (ata_bus_softreset(ap, devmask)) goto err_out; - } /* * determine by signature whether we have ATA or ATAPI devices @@ -3205,37 +3150,29 @@ void ata_bus_reset(struct ata_port *ap) * sata_phy_debounce - debounce SATA phy status * @ap: ATA port to debounce SATA phy status for * @params: timing parameters { interval, duratinon, timeout } in msec - * @deadline: deadline jiffies for the operation * * Make sure SStatus of @ap reaches stable state, determined by * holding the same value where DET is not 1 for @duration polled * every @interval, before @timeout. Timeout constraints the - * beginning of the stable state. Because DET gets stuck at 1 on - * some controllers after hot unplugging, this functions waits + * beginning of the stable state. Because, after hot unplugging, + * DET gets stuck at 1 on some controllers, this functions waits * until timeout then returns 0 if DET is stable at 1. * - * @timeout is further limited by @deadline. The sooner of the - * two is used. - * * LOCKING: * Kernel thread context (may sleep) * * RETURNS: * 0 on success, -errno on failure. */ -int sata_phy_debounce(struct ata_port *ap, const unsigned long *params, - unsigned long deadline) +int sata_phy_debounce(struct ata_port *ap, const unsigned long *params) { unsigned long interval_msec = params[0]; - unsigned long duration = msecs_to_jiffies(params[1]); - unsigned long last_jiffies, t; + unsigned long duration = params[1] * HZ / 1000; + unsigned long timeout = jiffies + params[2] * HZ / 1000; + unsigned long last_jiffies; u32 last, cur; int rc; - t = jiffies + msecs_to_jiffies(params[2]); - if (time_before(t, deadline)) - deadline = t; - if ((rc = sata_scr_read(ap, SCR_STATUS, &cur))) return rc; cur &= 0xf; @@ -3251,7 +3188,7 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params, /* DET stable? */ if (cur == last) { - if (cur == 1 && time_before(jiffies, deadline)) + if (cur == 1 && time_before(jiffies, timeout)) continue; if (time_after(jiffies, last_jiffies + duration)) return 0; @@ -3262,8 +3199,8 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params, last = cur; last_jiffies = jiffies; - /* check deadline */ - if (time_after(jiffies, deadline)) + /* check timeout */ + if (time_after(jiffies, timeout)) return -EBUSY; } } @@ -3272,7 +3209,6 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params, * sata_phy_resume - resume SATA phy * @ap: ATA port to resume SATA phy for * @params: timing parameters { interval, duratinon, timeout } in msec - * @deadline: deadline jiffies for the operation * * Resume SATA phy of @ap and debounce it. * @@ -3282,8 +3218,7 @@ int sata_phy_debounce(struct ata_port *ap, const unsigned long *params, * RETURNS: * 0 on success, -errno on failure. */ -int sata_phy_resume(struct ata_port *ap, const unsigned long *params, - unsigned long deadline) +int sata_phy_resume(struct ata_port *ap, const unsigned long *params) { u32 scontrol; int rc; @@ -3301,19 +3236,43 @@ int sata_phy_resume(struct ata_port *ap, const unsigned long *params, */ msleep(200); - return sata_phy_debounce(ap, params, deadline); + return sata_phy_debounce(ap, params); +} + +static void ata_wait_spinup(struct ata_port *ap) +{ + struct ata_eh_context *ehc = &ap->eh_context; + unsigned long end, secs; + int rc; + + /* first, debounce phy if SATA */ + if (ap->cbl == ATA_CBL_SATA) { + rc = sata_phy_debounce(ap, sata_deb_timing_hotplug); + + /* if debounced successfully and offline, no need to wait */ + if ((rc == 0 || rc == -EOPNOTSUPP) && ata_port_offline(ap)) + return; + } + + /* okay, let's give the drive time to spin up */ + end = ehc->i.hotplug_timestamp + ATA_SPINUP_WAIT * HZ / 1000; + secs = ((end - jiffies) + HZ - 1) / HZ; + + if (time_after(jiffies, end)) + return; + + if (secs > 5) + ata_port_printk(ap, KERN_INFO, "waiting for device to spin up " + "(%lu secs)\n", secs); + + schedule_timeout_uninterruptible(end - jiffies); } /** * ata_std_prereset - prepare for reset * @ap: ATA port to be reset - * @deadline: deadline jiffies for the operation * - * @ap is about to be reset. Initialize it. Failure from - * prereset makes libata abort whole reset sequence and give up - * that port, so prereset should be best-effort. It does its - * best to prepare for reset sequence but if things go wrong, it - * should just whine, not fail. + * @ap is about to be reset. Initialize it. * * LOCKING: * Kernel thread context (may sleep) @@ -3321,41 +3280,41 @@ int sata_phy_resume(struct ata_port *ap, const unsigned long *params, * RETURNS: * 0 on success, -errno otherwise. */ -int ata_std_prereset(struct ata_port *ap, unsigned long deadline) +int ata_std_prereset(struct ata_port *ap) { struct ata_eh_context *ehc = &ap->eh_context; const unsigned long *timing = sata_ehc_deb_timing(ehc); int rc; - /* handle link resume */ + /* handle link resume & hotplug spinup */ if ((ehc->i.flags & ATA_EHI_RESUME_LINK) && (ap->flags & ATA_FLAG_HRST_TO_RESUME)) ehc->i.action |= ATA_EH_HARDRESET; + if ((ehc->i.flags & ATA_EHI_HOTPLUGGED) && + (ap->flags & ATA_FLAG_SKIP_D2H_BSY)) + ata_wait_spinup(ap); + /* if we're about to do hardreset, nothing more to do */ if (ehc->i.action & ATA_EH_HARDRESET) return 0; /* if SATA, resume phy */ if (ap->cbl == ATA_CBL_SATA) { - rc = sata_phy_resume(ap, timing, deadline); - /* whine about phy resume failure but proceed */ - if (rc && rc != -EOPNOTSUPP) + rc = sata_phy_resume(ap, timing); + if (rc && rc != -EOPNOTSUPP) { + /* phy resume failed */ ata_port_printk(ap, KERN_WARNING, "failed to resume " "link for reset (errno=%d)\n", rc); + return rc; + } } /* Wait for !BSY if the controller can wait for the first D2H * Reg FIS and we don't know that no device is attached. */ - if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) { - rc = ata_wait_ready(ap, deadline); - if (rc) { - ata_port_printk(ap, KERN_WARNING, "device not ready " - "(errno=%d), forcing hardreset\n", rc); - ehc->i.action |= ATA_EH_HARDRESET; - } - } + if (!(ap->flags & ATA_FLAG_SKIP_D2H_BSY) && !ata_port_offline(ap)) + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); return 0; } @@ -3364,7 +3323,6 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline) * ata_std_softreset - reset host port via ATA SRST * @ap: port to reset * @classes: resulting classes of attached devices - * @deadline: deadline jiffies for the operation * * Reset host port using ATA SRST. * @@ -3374,12 +3332,10 @@ int ata_std_prereset(struct ata_port *ap, unsigned long deadline) * RETURNS: * 0 on success, -errno otherwise. */ -int ata_std_softreset(struct ata_port *ap, unsigned int *classes, - unsigned long deadline) +int ata_std_softreset(struct ata_port *ap, unsigned int *classes) { unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; - unsigned int devmask = 0; - int rc; + unsigned int devmask = 0, err_mask; u8 err; DPRINTK("ENTER\n"); @@ -3400,11 +3356,11 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes, /* issue bus reset */ DPRINTK("about to softreset, devmask=%x\n", devmask); - rc = ata_bus_softreset(ap, devmask, deadline); - /* if link is occupied, -ENODEV too is an error */ - if (rc && (rc != -ENODEV || sata_scr_valid(ap))) { - ata_port_printk(ap, KERN_ERR, "SRST failed (errno=%d)\n", rc); - return rc; + err_mask = ata_bus_softreset(ap, devmask); + if (err_mask) { + ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n", + err_mask); + return -EIO; } /* determine by signature whether we have ATA or ATAPI devices */ @@ -3421,7 +3377,6 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes, * sata_port_hardreset - reset port via SATA phy reset * @ap: port to reset * @timing: timing parameters { interval, duratinon, timeout } in msec - * @deadline: deadline jiffies for the operation * * SATA phy-reset host port using DET bits of SControl register. * @@ -3431,8 +3386,7 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes, * RETURNS: * 0 on success, -errno otherwise. */ -int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing, - unsigned long deadline) +int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing) { u32 scontrol; int rc; @@ -3471,7 +3425,7 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing, msleep(1); /* bring phy back */ - rc = sata_phy_resume(ap, timing, deadline); + rc = sata_phy_resume(ap, timing); out: DPRINTK("EXIT, rc=%d\n", rc); return rc; @@ -3481,7 +3435,6 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing, * sata_std_hardreset - reset host port via SATA phy reset * @ap: port to reset * @class: resulting class of attached device - * @deadline: deadline jiffies for the operation * * SATA phy-reset host port using DET bits of SControl register, * wait for !BSY and classify the attached device. @@ -3492,8 +3445,7 @@ int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing, * RETURNS: * 0 on success, -errno otherwise. */ -int sata_std_hardreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) +int sata_std_hardreset(struct ata_port *ap, unsigned int *class) { const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context); int rc; @@ -3501,7 +3453,7 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class, DPRINTK("ENTER\n"); /* do hardreset */ - rc = sata_port_hardreset(ap, timing, deadline); + rc = sata_port_hardreset(ap, timing); if (rc) { ata_port_printk(ap, KERN_ERR, "COMRESET failed (errno=%d)\n", rc); @@ -3518,12 +3470,10 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class, /* wait a while before checking status, see SRST for more info */ msleep(150); - rc = ata_wait_ready(ap, deadline); - /* link occupied, -ENODEV too is an error */ - if (rc) { + if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { ata_port_printk(ap, KERN_ERR, - "COMRESET failed (errno=%d)\n", rc); - return rc; + "COMRESET failed (device not ready)\n"); + return -EIO; } ap->ops->dev_select(ap, 0); /* probably unnecessary */ @@ -6843,7 +6793,6 @@ EXPORT_SYMBOL_GPL(ata_port_disable); EXPORT_SYMBOL_GPL(ata_ratelimit); EXPORT_SYMBOL_GPL(ata_wait_register); EXPORT_SYMBOL_GPL(ata_busy_sleep); -EXPORT_SYMBOL_GPL(ata_wait_ready); EXPORT_SYMBOL_GPL(ata_port_queue_task); EXPORT_SYMBOL_GPL(ata_scsi_ioctl); EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index 8256655ce7d9..2bff9adcacf1 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -50,28 +50,6 @@ enum { ATA_EH_SPDN_FALLBACK_TO_PIO = (1 << 2), }; -/* Waiting in ->prereset can never be reliable. It's sometimes nice - * to wait there but it can't be depended upon; otherwise, we wouldn't - * be resetting. Just give it enough time for most drives to spin up. - */ -enum { - ATA_EH_PRERESET_TIMEOUT = 10 * HZ, -}; - -/* The following table determines how we sequence resets. Each entry - * represents timeout for that try. The first try can be soft or - * hardreset. All others are hardreset if available. In most cases - * the first reset w/ 10sec timeout should succeed. Following entries - * are mostly for error handling, hotplug and retarded devices. - */ -static const unsigned long ata_eh_reset_timeouts[] = { - 10 * HZ, /* most drives spin up by 10sec */ - 10 * HZ, /* > 99% working drives spin up before 20sec */ - 35 * HZ, /* give > 30 secs of idleness for retarded devices */ - 5 * HZ, /* and sweet one last chance */ - /* > 1 min has elapsed, give up */ -}; - static void __ata_port_freeze(struct ata_port *ap); static void ata_eh_finish(struct ata_port *ap); #ifdef CONFIG_PM @@ -1580,14 +1558,14 @@ static void ata_eh_report(struct ata_port *ap) } static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset, - unsigned int *classes, unsigned long deadline) + unsigned int *classes) { int i, rc; for (i = 0; i < ATA_MAX_DEVICES; i++) classes[i] = ATA_DEV_UNKNOWN; - rc = reset(ap, classes, deadline); + rc = reset(ap, classes); if (rc) return rc; @@ -1625,9 +1603,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, { struct ata_eh_context *ehc = &ap->eh_context; unsigned int *classes = ehc->classes; + int tries = ATA_EH_RESET_TRIES; int verbose = !(ehc->i.flags & ATA_EHI_QUIET); - int try = 0; - unsigned long deadline; unsigned int action; ata_reset_fn_t reset; int i, did_followup_srst, rc; @@ -1647,7 +1624,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ehc->i.action |= ATA_EH_HARDRESET; if (prereset) { - rc = prereset(ap, jiffies + ATA_EH_PRERESET_TIMEOUT); + rc = prereset(ap); if (rc) { if (rc == -ENOENT) { ata_port_printk(ap, KERN_DEBUG, @@ -1688,8 +1665,6 @@ static int ata_eh_reset(struct ata_port *ap, int classify, } retry: - deadline = jiffies + ata_eh_reset_timeouts[try++]; - /* shut up during boot probing */ if (verbose) ata_port_printk(ap, KERN_INFO, "%s resetting port\n", @@ -1701,7 +1676,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, else ehc->i.flags |= ATA_EHI_DID_SOFTRESET; - rc = ata_do_reset(ap, reset, classes, deadline); + rc = ata_do_reset(ap, reset, classes); did_followup_srst = 0; if (reset == hardreset && @@ -1718,7 +1693,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, } ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); - rc = ata_do_reset(ap, reset, classes, deadline); + rc = ata_do_reset(ap, reset, classes); if (rc == 0 && classify && classes[0] == ATA_DEV_UNKNOWN) { @@ -1728,21 +1703,22 @@ static int ata_eh_reset(struct ata_port *ap, int classify, } } - if (rc && try < ARRAY_SIZE(ata_eh_reset_timeouts)) { - unsigned long now = jiffies; - - if (time_before(now, deadline)) { - unsigned long delta = deadline - jiffies; + if (rc && --tries) { + const char *type; - ata_port_printk(ap, KERN_WARNING, "reset failed " - "(errno=%d), retrying in %u secs\n", - rc, (jiffies_to_msecs(delta) + 999) / 1000); + if (reset == softreset) { + if (did_followup_srst) + type = "follow-up soft"; + else + type = "soft"; + } else + type = "hard"; - schedule_timeout_uninterruptible(delta); - } + ata_port_printk(ap, KERN_WARNING, + "%sreset failed, retrying in 5 secs\n", type); + ssleep(5); - if (reset == hardreset && - try == ARRAY_SIZE(ata_eh_reset_timeouts) - 1) + if (reset == hardreset) sata_down_spd_limit(ap); if (hardreset) reset = hardreset; diff --git a/trunk/drivers/ata/pata_amd.c b/trunk/drivers/ata/pata_amd.c index 67c7e87dec04..536ee892ab72 100644 --- a/trunk/drivers/ata/pata_amd.c +++ b/trunk/drivers/ata/pata_amd.c @@ -121,13 +121,12 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse /** * amd_probe_init - perform reset handling * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Reset sequence checking enable bits to see which ports are * active. */ -static int amd_pre_reset(struct ata_port *ap, unsigned long deadline) +static int amd_pre_reset(struct ata_port *ap) { static const struct pci_bits amd_enable_bits[] = { { 0x40, 1, 0x02, 0x02 }, @@ -139,7 +138,8 @@ static int amd_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); + } static void amd_error_handler(struct ata_port *ap) @@ -227,8 +227,7 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev) * space for us. */ -static int nv_pre_reset(struct ata_port *ap, unsigned long deadline) -{ +static int nv_pre_reset(struct ata_port *ap) { static const struct pci_bits nv_enable_bits[] = { { 0x50, 1, 0x02, 0x02 }, { 0x50, 1, 0x01, 0x01 } @@ -239,7 +238,7 @@ static int nv_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no])) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } static void nv_error_handler(struct ata_port *ap) diff --git a/trunk/drivers/ata/pata_artop.c b/trunk/drivers/ata/pata_artop.c index ef51940c3adb..00e9ec342db0 100644 --- a/trunk/drivers/ata/pata_artop.c +++ b/trunk/drivers/ata/pata_artop.c @@ -39,7 +39,7 @@ static int clock = 0; -static int artop6210_pre_reset(struct ata_port *ap, unsigned long deadline) +static int artop6210_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); const struct pci_bits artop_enable_bits[] = { @@ -49,8 +49,7 @@ static int artop6210_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** @@ -71,13 +70,12 @@ static void artop6210_error_handler(struct ata_port *ap) /** * artop6260_pre_reset - check for 40/80 pin * @ap: Port - * @deadline: deadline jiffies for the operation * * The ARTOP hardware reports the cable detect bits in register 0x49. * Nothing complicated needed here. */ -static int artop6260_pre_reset(struct ata_port *ap, unsigned long deadline) +static int artop6260_pre_reset(struct ata_port *ap) { static const struct pci_bits artop_enable_bits[] = { { 0x4AU, 1U, 0x02UL, 0x02UL }, /* port 0 */ @@ -89,8 +87,7 @@ static int artop6260_pre_reset(struct ata_port *ap, unsigned long deadline) /* Odd numbered device ids are the units with enable bits (the -R cards) */ if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_atiixp.c b/trunk/drivers/ata/pata_atiixp.c index 21515381b5b3..39c871a3ddac 100644 --- a/trunk/drivers/ata/pata_atiixp.c +++ b/trunk/drivers/ata/pata_atiixp.c @@ -33,7 +33,7 @@ enum { ATIIXP_IDE_UDMA_MODE = 0x56 }; -static int atiixp_pre_reset(struct ata_port *ap, unsigned long deadline) +static int atiixp_pre_reset(struct ata_port *ap) { static const struct pci_bits atiixp_enable_bits[] = { { 0x48, 1, 0x01, 0x00 }, @@ -44,7 +44,7 @@ static int atiixp_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } static void atiixp_error_handler(struct ata_port *ap) diff --git a/trunk/drivers/ata/pata_cs5535.c b/trunk/drivers/ata/pata_cs5535.c index 22006ae71941..08cccc9c659b 100644 --- a/trunk/drivers/ata/pata_cs5535.c +++ b/trunk/drivers/ata/pata_cs5535.c @@ -72,7 +72,6 @@ /** * cs5535_cable_detect - detect cable type * @ap: Port to detect on - * @deadline: deadline jiffies for the operation * * Perform cable detection for ATA66 capable cable. Return a libata * cable type. diff --git a/trunk/drivers/ata/pata_efar.c b/trunk/drivers/ata/pata_efar.c index d0f52e034906..a3216850bba1 100644 --- a/trunk/drivers/ata/pata_efar.c +++ b/trunk/drivers/ata/pata_efar.c @@ -27,13 +27,12 @@ /** * efar_pre_reset - Enable bits * @ap: Port - * @deadline: deadline jiffies for the operation * * Perform cable detection for the EFAR ATA interface. This is * different to the PIIX arrangement */ -static int efar_pre_reset(struct ata_port *ap, unsigned long deadline) +static int efar_pre_reset(struct ata_port *ap) { static const struct pci_bits efar_enable_bits[] = { { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ @@ -44,7 +43,7 @@ static int efar_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no])) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_hpt366.c b/trunk/drivers/ata/pata_hpt366.c index e64e05e5c7fe..93cfa6d300a5 100644 --- a/trunk/drivers/ata/pata_hpt366.c +++ b/trunk/drivers/ata/pata_hpt366.c @@ -220,7 +220,7 @@ static int hpt36x_cable_detect(struct ata_port *ap) return ATA_CBL_PATA80; } -static int hpt36x_pre_reset(struct ata_port *ap, unsigned long deadline) +static int hpt36x_pre_reset(struct ata_port *ap) { static const struct pci_bits hpt36x_enable_bits[] = { { 0x50, 1, 0x04, 0x04 }, @@ -231,7 +231,7 @@ static int hpt36x_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no])) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_hpt37x.c b/trunk/drivers/ata/pata_hpt37x.c index 1614e8c822a4..41d831296347 100644 --- a/trunk/drivers/ata/pata_hpt37x.c +++ b/trunk/drivers/ata/pata_hpt37x.c @@ -307,12 +307,11 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask) /** * hpt37x_pre_reset - reset the hpt37x bus * @ap: ATA port to reset - * @deadline: deadline jiffies for the operation * * Perform the initial reset handling for the 370/372 and 374 func 0 */ -static int hpt37x_pre_reset(struct ata_port *ap, unsigned long deadline) +static int hpt37x_pre_reset(struct ata_port *ap) { u8 scr2, ata66; struct pci_dev *pdev = to_pci_dev(ap->host->dev); @@ -339,7 +338,7 @@ static int hpt37x_pre_reset(struct ata_port *ap, unsigned long deadline) pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** @@ -354,7 +353,7 @@ static void hpt37x_error_handler(struct ata_port *ap) ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset); } -static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline) +static int hpt374_pre_reset(struct ata_port *ap) { static const struct pci_bits hpt37x_enable_bits[] = { { 0x50, 1, 0x04, 0x04 }, @@ -389,7 +388,7 @@ static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline) pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_hpt3x2n.c b/trunk/drivers/ata/pata_hpt3x2n.c index ea1037d67860..6a34521b9e01 100644 --- a/trunk/drivers/ata/pata_hpt3x2n.c +++ b/trunk/drivers/ata/pata_hpt3x2n.c @@ -148,14 +148,13 @@ static int hpt3x2n_cable_detect(struct ata_port *ap) * Reset the hardware and state machine, */ -static int hpt3xn_pre_reset(struct ata_port *ap, unsigned long deadline) +static int hpt3xn_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); /* Reset the state machine */ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_icside.c b/trunk/drivers/ata/pata_icside.c deleted file mode 100644 index dbc8ee2adcf0..000000000000 --- a/trunk/drivers/ata/pata_icside.c +++ /dev/null @@ -1,686 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DRV_NAME "pata_icside" - -#define ICS_IDENT_OFFSET 0x2280 - -#define ICS_ARCIN_V5_INTRSTAT 0x0000 -#define ICS_ARCIN_V5_INTROFFSET 0x0004 - -#define ICS_ARCIN_V6_INTROFFSET_1 0x2200 -#define ICS_ARCIN_V6_INTRSTAT_1 0x2290 -#define ICS_ARCIN_V6_INTROFFSET_2 0x3200 -#define ICS_ARCIN_V6_INTRSTAT_2 0x3290 - -struct portinfo { - unsigned int dataoffset; - unsigned int ctrloffset; - unsigned int stepping; -}; - -static const struct portinfo pata_icside_portinfo_v5 = { - .dataoffset = 0x2800, - .ctrloffset = 0x2b80, - .stepping = 6, -}; - -static const struct portinfo pata_icside_portinfo_v6_1 = { - .dataoffset = 0x2000, - .ctrloffset = 0x2380, - .stepping = 6, -}; - -static const struct portinfo pata_icside_portinfo_v6_2 = { - .dataoffset = 0x3000, - .ctrloffset = 0x3380, - .stepping = 6, -}; - -#define PATA_ICSIDE_MAX_SG 128 - -struct pata_icside_state { - void __iomem *irq_port; - void __iomem *ioc_base; - unsigned int type; - unsigned int dma; - struct { - u8 port_sel; - u8 disabled; - unsigned int speed[ATA_MAX_DEVICES]; - } port[2]; - struct scatterlist sg[PATA_ICSIDE_MAX_SG]; -}; - -#define ICS_TYPE_A3IN 0 -#define ICS_TYPE_A3USER 1 -#define ICS_TYPE_V6 3 -#define ICS_TYPE_V5 15 -#define ICS_TYPE_NOTYPE ((unsigned int)-1) - -/* ---------------- Version 5 PCB Support Functions --------------------- */ -/* Prototype: pata_icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr) - * Purpose : enable interrupts from card - */ -static void pata_icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr) -{ - struct pata_icside_state *state = ec->irq_data; - - writeb(0, state->irq_port + ICS_ARCIN_V5_INTROFFSET); -} - -/* Prototype: pata_icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr) - * Purpose : disable interrupts from card - */ -static void pata_icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr) -{ - struct pata_icside_state *state = ec->irq_data; - - readb(state->irq_port + ICS_ARCIN_V5_INTROFFSET); -} - -static const expansioncard_ops_t pata_icside_ops_arcin_v5 = { - .irqenable = pata_icside_irqenable_arcin_v5, - .irqdisable = pata_icside_irqdisable_arcin_v5, -}; - - -/* ---------------- Version 6 PCB Support Functions --------------------- */ -/* Prototype: pata_icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) - * Purpose : enable interrupts from card - */ -static void pata_icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) -{ - struct pata_icside_state *state = ec->irq_data; - void __iomem *base = state->irq_port; - - if (!state->port[0].disabled) - writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1); - if (!state->port[1].disabled) - writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2); -} - -/* Prototype: pata_icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) - * Purpose : disable interrupts from card - */ -static void pata_icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) -{ - struct pata_icside_state *state = ec->irq_data; - - readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); - readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); -} - -/* Prototype: pata_icside_irqprobe(struct expansion_card *ec) - * Purpose : detect an active interrupt from card - */ -static int pata_icside_irqpending_arcin_v6(struct expansion_card *ec) -{ - struct pata_icside_state *state = ec->irq_data; - - return readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 || - readb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1; -} - -static const expansioncard_ops_t pata_icside_ops_arcin_v6 = { - .irqenable = pata_icside_irqenable_arcin_v6, - .irqdisable = pata_icside_irqdisable_arcin_v6, - .irqpending = pata_icside_irqpending_arcin_v6, -}; - - -/* - * SG-DMA support. - * - * Similar to the BM-DMA, but we use the RiscPCs IOMD DMA controllers. - * There is only one DMA controller per card, which means that only - * one drive can be accessed at one time. NOTE! We do not enforce that - * here, but we rely on the main IDE driver spotting that both - * interfaces use the same IRQ, which should guarantee this. - */ - -/* - * Configure the IOMD to give the appropriate timings for the transfer - * mode being requested. We take the advice of the ATA standards, and - * calculate the cycle time based on the transfer mode, and the EIDE - * MW DMA specs that the drive provides in the IDENTIFY command. - * - * We have the following IOMD DMA modes to choose from: - * - * Type Active Recovery Cycle - * A 250 (250) 312 (550) 562 (800) - * B 187 (200) 250 (550) 437 (750) - * C 125 (125) 125 (375) 250 (500) - * D 62 (50) 125 (375) 187 (425) - * - * (figures in brackets are actual measured timings on DIOR/DIOW) - * - * However, we also need to take care of the read/write active and - * recovery timings: - * - * Read Write - * Mode Active -- Recovery -- Cycle IOMD type - * MW0 215 50 215 480 A - * MW1 80 50 50 150 C - * MW2 70 25 25 120 C - */ -static void pata_icside_set_dmamode(struct ata_port *ap, struct ata_device *adev) -{ - struct pata_icside_state *state = ap->host->private_data; - struct ata_timing t; - unsigned int cycle; - char iomd_type; - - /* - * DMA is based on a 16MHz clock - */ - if (ata_timing_compute(adev, adev->dma_mode, &t, 1000, 1)) - return; - - /* - * Choose the IOMD cycle timing which ensure that the interface - * satisfies the measured active, recovery and cycle times. - */ - if (t.active <= 50 && t.recover <= 375 && t.cycle <= 425) - iomd_type = 'D', cycle = 187; - else if (t.active <= 125 && t.recover <= 375 && t.cycle <= 500) - iomd_type = 'C', cycle = 250; - else if (t.active <= 200 && t.recover <= 550 && t.cycle <= 750) - iomd_type = 'B', cycle = 437; - else - iomd_type = 'A', cycle = 562; - - ata_dev_printk(adev, KERN_INFO, "timings: act %dns rec %dns cyc %dns (%c)\n", - t.active, t.recover, t.cycle, iomd_type); - - state->port[ap->port_no].speed[adev->devno] = cycle; -} - -static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct pata_icside_state *state = ap->host->private_data; - struct scatterlist *sg, *rsg = state->sg; - unsigned int write = qc->tf.flags & ATA_TFLAG_WRITE; - - /* - * We are simplex; BUG if we try to fiddle with DMA - * while it's active. - */ - BUG_ON(dma_channel_active(state->dma)); - - /* - * Copy ATAs scattered sg list into a contiguous array of sg - */ - ata_for_each_sg(sg, qc) { - memcpy(rsg, sg, sizeof(*sg)); - rsg++; - } - - /* - * Route the DMA signals to the correct interface - */ - writeb(state->port[ap->port_no].port_sel, state->ioc_base); - - set_dma_speed(state->dma, state->port[ap->port_no].speed[qc->dev->devno]); - set_dma_sg(state->dma, state->sg, rsg - state->sg); - set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ); - - /* issue r/w command */ - ap->ops->exec_command(ap, &qc->tf); -} - -static void pata_icside_bmdma_start(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct pata_icside_state *state = ap->host->private_data; - - BUG_ON(dma_channel_active(state->dma)); - enable_dma(state->dma); -} - -static void pata_icside_bmdma_stop(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct pata_icside_state *state = ap->host->private_data; - - disable_dma(state->dma); - - /* see ata_bmdma_stop */ - ata_altstatus(ap); -} - -static u8 pata_icside_bmdma_status(struct ata_port *ap) -{ - struct pata_icside_state *state = ap->host->private_data; - void __iomem *irq_port; - - irq_port = state->irq_port + (ap->port_no ? ICS_ARCIN_V6_INTRSTAT_2 : - ICS_ARCIN_V6_INTRSTAT_1); - - return readb(irq_port) & 1 ? ATA_DMA_INTR : 0; -} - -static int icside_dma_init(struct ata_probe_ent *ae, struct expansion_card *ec) -{ - struct pata_icside_state *state = ae->private_data; - int i; - - for (i = 0; i < ATA_MAX_DEVICES; i++) { - state->port[0].speed[i] = 480; - state->port[1].speed[i] = 480; - } - - if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) { - state->dma = ec->dma; - ae->mwdma_mask = 0x07; /* MW0..2 */ - } - - return 0; -} - - -static int pata_icside_port_start(struct ata_port *ap) -{ - /* No PRD to alloc */ - return ata_pad_alloc(ap, ap->dev); -} - -static struct scsi_host_template pata_icside_sht = { - .module = THIS_MODULE, - .name = DRV_NAME, - .ioctl = ata_scsi_ioctl, - .queuecommand = ata_scsi_queuecmd, - .can_queue = ATA_DEF_QUEUE, - .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = PATA_ICSIDE_MAX_SG, - .cmd_per_lun = ATA_SHT_CMD_PER_LUN, - .emulated = ATA_SHT_EMULATED, - .use_clustering = ATA_SHT_USE_CLUSTERING, - .proc_name = DRV_NAME, - .dma_boundary = ~0, /* no dma boundaries */ - .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, - .bios_param = ata_std_bios_param, -}; - -/* wish this was exported from libata-core */ -static void ata_dummy_noret(struct ata_port *port) -{ -} - -/* - * We need to shut down unused ports to prevent spurious interrupts. - * FIXME: the libata core doesn't call this function for PATA interfaces. - */ -static void pata_icside_port_disable(struct ata_port *ap) -{ - struct pata_icside_state *state = ap->host->private_data; - - ata_port_printk(ap, KERN_ERR, "disabling icside port\n"); - - ata_port_disable(ap); - - state->port[ap->port_no].disabled = 1; - - if (state->type == ICS_TYPE_V6) { - /* - * Disable interrupts from this port, otherwise we - * receive spurious interrupts from the floating - * interrupt line. - */ - void __iomem *irq_port = state->irq_port + - (ap->port_no ? ICS_ARCIN_V6_INTROFFSET_2 : ICS_ARCIN_V6_INTROFFSET_1); - readb(irq_port); - } -} - -static u8 pata_icside_irq_ack(struct ata_port *ap, unsigned int chk_drq) -{ - unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; - u8 status; - - status = ata_busy_wait(ap, bits, 1000); - if (status & bits) - if (ata_msg_err(ap)) - printk(KERN_ERR "abnormal status 0x%X\n", status); - - if (ata_msg_intr(ap)) - printk(KERN_INFO "%s: irq ack: drv_stat 0x%X\n", - __FUNCTION__, status); - - return status; -} - -static struct ata_port_operations pata_icside_port_ops = { - .port_disable = pata_icside_port_disable, - - .set_dmamode = pata_icside_set_dmamode, - - .tf_load = ata_tf_load, - .tf_read = ata_tf_read, - .exec_command = ata_exec_command, - .check_status = ata_check_status, - .dev_select = ata_std_dev_select, - - .bmdma_setup = pata_icside_bmdma_setup, - .bmdma_start = pata_icside_bmdma_start, - - .data_xfer = ata_data_xfer_noirq, - - /* no need to build any PRD tables for DMA */ - .qc_prep = ata_noop_qc_prep, - .qc_issue = ata_qc_issue_prot, - - .freeze = ata_bmdma_freeze, - .thaw = ata_bmdma_thaw, - .error_handler = ata_bmdma_error_handler, - .post_internal_cmd = pata_icside_bmdma_stop, - - .irq_handler = ata_interrupt, - .irq_clear = ata_dummy_noret, - .irq_on = ata_irq_on, - .irq_ack = pata_icside_irq_ack, - - .port_start = pata_icside_port_start, - - .bmdma_stop = pata_icside_bmdma_stop, - .bmdma_status = pata_icside_bmdma_status, -}; - -static void -pata_icside_add_port(struct ata_probe_ent *ae, void __iomem *base, - const struct portinfo *info) -{ - struct ata_ioports *ioaddr = &ae->port[ae->n_ports++]; - void __iomem *cmd = base + info->dataoffset; - - ioaddr->cmd_addr = cmd; - ioaddr->data_addr = cmd + (ATA_REG_DATA << info->stepping); - ioaddr->error_addr = cmd + (ATA_REG_ERR << info->stepping); - ioaddr->feature_addr = cmd + (ATA_REG_FEATURE << info->stepping); - ioaddr->nsect_addr = cmd + (ATA_REG_NSECT << info->stepping); - ioaddr->lbal_addr = cmd + (ATA_REG_LBAL << info->stepping); - ioaddr->lbam_addr = cmd + (ATA_REG_LBAM << info->stepping); - ioaddr->lbah_addr = cmd + (ATA_REG_LBAH << info->stepping); - ioaddr->device_addr = cmd + (ATA_REG_DEVICE << info->stepping); - ioaddr->status_addr = cmd + (ATA_REG_STATUS << info->stepping); - ioaddr->command_addr = cmd + (ATA_REG_CMD << info->stepping); - - ioaddr->ctl_addr = base + info->ctrloffset; - ioaddr->altstatus_addr = ioaddr->ctl_addr; -} - -static int __init -pata_icside_register_v5(struct ata_probe_ent *ae, struct expansion_card *ec) -{ - struct pata_icside_state *state = ae->private_data; - void __iomem *base; - - base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), - ecard_resource_len(ec, ECARD_RES_MEMC)); - if (!base) - return -ENOMEM; - - state->irq_port = base; - - ec->irqaddr = base + ICS_ARCIN_V5_INTRSTAT; - ec->irqmask = 1; - ec->irq_data = state; - ec->ops = &pata_icside_ops_arcin_v5; - - /* - * Be on the safe side - disable interrupts - */ - ec->ops->irqdisable(ec, ec->irq); - - pata_icside_add_port(ae, base, &pata_icside_portinfo_v5); - - return 0; -} - -static int __init -pata_icside_register_v6(struct ata_probe_ent *ae, struct expansion_card *ec) -{ - struct pata_icside_state *state = ae->private_data; - void __iomem *ioc_base, *easi_base; - unsigned int sel = 0; - int ret; - - ioc_base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), - ecard_resource_len(ec, ECARD_RES_IOCFAST)); - if (!ioc_base) { - ret = -ENOMEM; - goto out; - } - - easi_base = ioc_base; - - if (ecard_resource_flags(ec, ECARD_RES_EASI)) { - easi_base = ioremap(ecard_resource_start(ec, ECARD_RES_EASI), - ecard_resource_len(ec, ECARD_RES_EASI)); - if (!easi_base) { - ret = -ENOMEM; - goto unmap_slot; - } - - /* - * Enable access to the EASI region. - */ - sel = 1 << 5; - } - - writeb(sel, ioc_base); - - ec->irq_data = state; - ec->ops = &pata_icside_ops_arcin_v6; - - state->irq_port = easi_base; - state->ioc_base = ioc_base; - state->port[0].port_sel = sel; - state->port[1].port_sel = sel | 1; - - /* - * Be on the safe side - disable interrupts - */ - ec->ops->irqdisable(ec, ec->irq); - - /* - * Find and register the interfaces. - */ - pata_icside_add_port(ae, easi_base, &pata_icside_portinfo_v6_1); - pata_icside_add_port(ae, easi_base, &pata_icside_portinfo_v6_2); - - /* - * FIXME: work around libata's aversion to calling port_disable. - * This permanently disables interrupts on port 0 - bad luck if - * you have a drive on that port. - */ - state->port[0].disabled = 1; - - return icside_dma_init(ae, ec); - - unmap_slot: - iounmap(ioc_base); - out: - return ret; -} - -static int __devinit -pata_icside_probe(struct expansion_card *ec, const struct ecard_id *id) -{ - struct pata_icside_state *state; - struct ata_probe_ent ae; - void __iomem *idmem; - int ret; - - ret = ecard_request_resources(ec); - if (ret) - goto out; - - state = kzalloc(sizeof(struct pata_icside_state), GFP_KERNEL); - if (!state) { - ret = -ENOMEM; - goto release; - } - - state->type = ICS_TYPE_NOTYPE; - state->dma = NO_DMA; - - idmem = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), - ecard_resource_len(ec, ECARD_RES_IOCFAST)); - if (idmem) { - unsigned int type; - - type = readb(idmem + ICS_IDENT_OFFSET) & 1; - type |= (readb(idmem + ICS_IDENT_OFFSET + 4) & 1) << 1; - type |= (readb(idmem + ICS_IDENT_OFFSET + 8) & 1) << 2; - type |= (readb(idmem + ICS_IDENT_OFFSET + 12) & 1) << 3; - iounmap(idmem); - - state->type = type; - } - - memset(&ae, 0, sizeof(ae)); - INIT_LIST_HEAD(&ae.node); - ae.dev = &ec->dev; - ae.port_ops = &pata_icside_port_ops; - ae.sht = &pata_icside_sht; - ae.pio_mask = 0x1f; - ae.irq = ec->irq; - ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST; - ae._host_flags = ATA_HOST_SIMPLEX; - ae.private_data = state; - - switch (state->type) { - case ICS_TYPE_A3IN: - dev_warn(&ec->dev, "A3IN unsupported\n"); - ret = -ENODEV; - break; - - case ICS_TYPE_A3USER: - dev_warn(&ec->dev, "A3USER unsupported\n"); - ret = -ENODEV; - break; - - case ICS_TYPE_V5: - ret = pata_icside_register_v5(&ae, ec); - break; - - case ICS_TYPE_V6: - ret = pata_icside_register_v6(&ae, ec); - break; - - default: - dev_warn(&ec->dev, "unknown interface type\n"); - ret = -ENODEV; - break; - } - - if (ret == 0) - ret = ata_device_add(&ae) == 0 ? -ENODEV : 0; - - if (ret == 0) - goto out; - - kfree(state); - release: - ecard_release_resources(ec); - out: - return ret; -} - -static void pata_icside_shutdown(struct expansion_card *ec) -{ - struct ata_host *host = ecard_get_drvdata(ec); - unsigned long flags; - - /* - * Disable interrupts from this card. We need to do - * this before disabling EASI since we may be accessing - * this register via that region. - */ - local_irq_save(flags); - if (ec->ops) - ec->ops->irqdisable(ec, ec->irq); - local_irq_restore(flags); - - /* - * Reset the ROM pointer so that we can read the ROM - * after a soft reboot. This also disables access to - * the IDE taskfile via the EASI region. - */ - if (host) { - struct pata_icside_state *state = host->private_data; - if (state->ioc_base) - writeb(0, state->ioc_base); - } -} - -static void __devexit pata_icside_remove(struct expansion_card *ec) -{ - struct ata_host *host = ecard_get_drvdata(ec); - struct pata_icside_state *state = host->private_data; - - ata_host_detach(host); - - pata_icside_shutdown(ec); - - /* - * don't NULL out the drvdata - devres/libata wants it - * to free the ata_host structure. - */ - ec->ops = NULL; - ec->irq_data = NULL; - - if (state->dma != NO_DMA) - free_dma(state->dma); - if (state->ioc_base) - iounmap(state->ioc_base); - if (state->ioc_base != state->irq_port) - iounmap(state->irq_port); - - kfree(state); - ecard_release_resources(ec); -} - -static const struct ecard_id pata_icside_ids[] = { - { MANU_ICS, PROD_ICS_IDE }, - { MANU_ICS2, PROD_ICS2_IDE }, - { 0xffff, 0xffff } -}; - -static struct ecard_driver pata_icside_driver = { - .probe = pata_icside_probe, - .remove = __devexit_p(pata_icside_remove), - .shutdown = pata_icside_shutdown, - .id_table = pata_icside_ids, - .drv = { - .name = DRV_NAME, - }, -}; - -static int __init pata_icside_init(void) -{ - return ecard_register_driver(&pata_icside_driver); -} - -static void __exit pata_icside_exit(void) -{ - ecard_remove_driver(&pata_icside_driver); -} - -MODULE_AUTHOR("Russell King "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("ICS PATA driver"); - -module_init(pata_icside_init); -module_exit(pata_icside_exit); diff --git a/trunk/drivers/ata/pata_it8213.c b/trunk/drivers/ata/pata_it8213.c index 17bf9f3ed013..011306ef8334 100644 --- a/trunk/drivers/ata/pata_it8213.c +++ b/trunk/drivers/ata/pata_it8213.c @@ -24,13 +24,12 @@ /** * it8213_pre_reset - check for 40/80 pin * @ap: Port - * @deadline: deadline jiffies for the operation * * Filter out ports by the enable bits before doing the normal reset * and probe. */ -static int it8213_pre_reset(struct ata_port *ap, unsigned long deadline) +static int it8213_pre_reset(struct ata_port *ap) { static const struct pci_bits it8213_enable_bits[] = { { 0x41U, 1U, 0x80UL, 0x80UL }, /* port 0 */ @@ -38,8 +37,7 @@ static int it8213_pre_reset(struct ata_port *ap, unsigned long deadline) struct pci_dev *pdev = to_pci_dev(ap->host->dev); if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no])) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_jmicron.c b/trunk/drivers/ata/pata_jmicron.c index 1daf78ac6efb..43763c99ea02 100644 --- a/trunk/drivers/ata/pata_jmicron.c +++ b/trunk/drivers/ata/pata_jmicron.c @@ -30,17 +30,16 @@ typedef enum { /** * jmicron_pre_reset - check for 40/80 pin * @ap: Port - * @deadline: deadline jiffies for the operation * * Perform the PATA port setup we need. - * + * On the Jmicron 361/363 there is a single PATA port that can be mapped * either as primary or secondary (or neither). We don't do any policy * and setup here. We assume that has been done by init_one and the * BIOS. */ -static int jmicron_pre_reset(struct ata_port *ap, unsigned long deadline) +static int jmicron_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 control; @@ -103,7 +102,7 @@ static int jmicron_pre_reset(struct ata_port *ap, unsigned long deadline) ap->cbl = ATA_CBL_SATA; break; } - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_marvell.c b/trunk/drivers/ata/pata_marvell.c index 837b7fe77dc7..d9b94a1b6954 100644 --- a/trunk/drivers/ata/pata_marvell.c +++ b/trunk/drivers/ata/pata_marvell.c @@ -25,12 +25,11 @@ /** * marvell_pre_reset - check for 40/80 pin * @ap: Port - * @deadline: deadline jiffies for the operation * * Perform the PATA port setup we need. */ -static int marvell_pre_reset(struct ata_port *ap, unsigned long deadline) +static int marvell_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); u32 devices; @@ -53,8 +52,7 @@ static int marvell_pre_reset(struct ata_port *ap, unsigned long deadline) if ((pdev->device == 0x6145) && (ap->port_no == 0) && (!(devices & 0x10))) /* PATA enable ? */ return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } static int marvell_cable_detect(struct ata_port *ap) @@ -69,7 +67,6 @@ static int marvell_cable_detect(struct ata_port *ap) case 1: /* Legacy SATA port */ return ATA_CBL_SATA; } - BUG(); return 0; /* Our BUG macro needs the right markup */ } diff --git a/trunk/drivers/ata/pata_mpiix.c b/trunk/drivers/ata/pata_mpiix.c index 3bfbd495f643..987c5fafab08 100644 --- a/trunk/drivers/ata/pata_mpiix.c +++ b/trunk/drivers/ata/pata_mpiix.c @@ -46,15 +46,14 @@ enum { SECONDARY = (1 << 14) }; -static int mpiix_pre_reset(struct ata_port *ap, unsigned long deadline) +static int mpiix_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const struct pci_bits mpiix_enable_bits = { 0x6D, 1, 0x80, 0x80 }; if (!pci_test_config_bits(pdev, &mpiix_enable_bits)) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_ns87410.c b/trunk/drivers/ata/pata_ns87410.c index ebc58a907d26..078aeda9cf8d 100644 --- a/trunk/drivers/ata/pata_ns87410.c +++ b/trunk/drivers/ata/pata_ns87410.c @@ -33,12 +33,11 @@ /** * ns87410_pre_reset - probe begin * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Check enabled ports */ -static int ns87410_pre_reset(struct ata_port *ap, unsigned long deadline) +static int ns87410_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const struct pci_bits ns87410_enable_bits[] = { @@ -48,8 +47,7 @@ static int ns87410_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no])) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_oldpiix.c b/trunk/drivers/ata/pata_oldpiix.c index 4d75d32e5826..dea4690340d1 100644 --- a/trunk/drivers/ata/pata_oldpiix.c +++ b/trunk/drivers/ata/pata_oldpiix.c @@ -30,12 +30,11 @@ /** * oldpiix_pre_reset - probe begin * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int oldpiix_pre_reset(struct ata_port *ap, unsigned long deadline) +static int oldpiix_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const struct pci_bits oldpiix_enable_bits[] = { @@ -45,8 +44,7 @@ static int oldpiix_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no])) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_opti.c b/trunk/drivers/ata/pata_opti.c index 0af8a2c77cc9..13b63e21838d 100644 --- a/trunk/drivers/ata/pata_opti.c +++ b/trunk/drivers/ata/pata_opti.c @@ -47,12 +47,11 @@ enum { /** * opti_pre_reset - probe begin * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int opti_pre_reset(struct ata_port *ap, unsigned long deadline) +static int opti_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const struct pci_bits opti_enable_bits[] = { @@ -62,8 +61,7 @@ static int opti_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no])) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_optidma.c b/trunk/drivers/ata/pata_optidma.c index 2843e480f216..b70e04c144df 100644 --- a/trunk/drivers/ata/pata_optidma.c +++ b/trunk/drivers/ata/pata_optidma.c @@ -48,12 +48,11 @@ static int pci_clock; /* 0 = 33 1 = 25 */ /** * optidma_pre_reset - probe begin * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int optidma_pre_reset(struct ata_port *ap, unsigned long deadline) +static int optidma_pre_reset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); static const struct pci_bits optidma_enable_bits = { @@ -63,7 +62,7 @@ static int optidma_pre_reset(struct ata_port *ap, unsigned long deadline) if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits)) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_pdc2027x.c b/trunk/drivers/ata/pata_pdc2027x.c index 0d2cc49fde4b..a61cbc110688 100644 --- a/trunk/drivers/ata/pata_pdc2027x.c +++ b/trunk/drivers/ata/pata_pdc2027x.c @@ -301,7 +301,6 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap) /** * pdc2027x_prereset - prereset for PATA host controller * @ap: Target port - * @deadline: deadline jiffies for the operation * * Probeinit including cable detection. * @@ -309,12 +308,12 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap) * None (inherited from caller). */ -static int pdc2027x_prereset(struct ata_port *ap, unsigned long deadline) +static int pdc2027x_prereset(struct ata_port *ap) { /* Check whether port enabled */ if (!pdc2027x_port_enabled(ap)) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } /** diff --git a/trunk/drivers/ata/pata_serverworks.c b/trunk/drivers/ata/pata_serverworks.c index b6e020383dd9..3956ef26936d 100644 --- a/trunk/drivers/ata/pata_serverworks.c +++ b/trunk/drivers/ata/pata_serverworks.c @@ -139,14 +139,12 @@ static struct sv_cable_table cable_detect[] = { /** * serverworks_cable_detect - cable detection * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Perform cable detection according to the device and subvendor * identifications */ -static int serverworks_cable_detect(struct ata_port *ap) -{ +static int serverworks_cable_detect(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); struct sv_cable_table *cb = cable_detect; diff --git a/trunk/drivers/ata/pata_sil680.c b/trunk/drivers/ata/pata_sil680.c index a5886f061c0b..6770820cfca9 100644 --- a/trunk/drivers/ata/pata_sil680.c +++ b/trunk/drivers/ata/pata_sil680.c @@ -94,13 +94,11 @@ static int sil680_cable_detect(struct ata_port *ap) { /** * sil680_bus_reset - reset the SIL680 bus * @ap: ATA port to reset - * @deadline: deadline jiffies for the operation * * Perform the SIL680 housekeeping when doing an ATA bus reset */ -static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes, - unsigned long deadline) +static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); unsigned long addr = sil680_selreg(ap, 0); @@ -110,7 +108,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes, pci_write_config_byte(pdev, addr, reset | 0x03); udelay(25); pci_write_config_byte(pdev, addr, reset); - return ata_std_softreset(ap, classes, deadline); + return ata_std_softreset(ap, classes); } static void sil680_error_handler(struct ata_port *ap) diff --git a/trunk/drivers/ata/pata_sis.c b/trunk/drivers/ata/pata_sis.c index f5838cc11728..a3fbcee6fb33 100644 --- a/trunk/drivers/ata/pata_sis.c +++ b/trunk/drivers/ata/pata_sis.c @@ -88,7 +88,6 @@ static int sis_port_base(struct ata_device *adev) /** * sis_133_cable_detect - check for 40/80 pin * @ap: Port - * @deadline: deadline jiffies for the operation * * Perform cable detection for the later UDMA133 capable * SiS chipset. @@ -109,7 +108,6 @@ static int sis_133_cable_detect(struct ata_port *ap) /** * sis_66_cable_detect - check for 40/80 pin * @ap: Port - * @deadline: deadline jiffies for the operation * * Perform cable detection on the UDMA66, UDMA100 and early UDMA133 * SiS IDE controllers. @@ -132,12 +130,11 @@ static int sis_66_cable_detect(struct ata_port *ap) /** * sis_pre_reset - probe begin * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int sis_pre_reset(struct ata_port *ap, unsigned long deadline) +static int sis_pre_reset(struct ata_port *ap) { static const struct pci_bits sis_enable_bits[] = { { 0x4aU, 1U, 0x02UL, 0x02UL }, /* port 0 */ @@ -148,8 +145,7 @@ static int sis_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } diff --git a/trunk/drivers/ata/pata_sl82c105.c b/trunk/drivers/ata/pata_sl82c105.c index 9aeffdbe2829..da9e22b25753 100644 --- a/trunk/drivers/ata/pata_sl82c105.c +++ b/trunk/drivers/ata/pata_sl82c105.c @@ -44,12 +44,11 @@ enum { /** * sl82c105_pre_reset - probe begin * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int sl82c105_pre_reset(struct ata_port *ap, unsigned long deadline) +static int sl82c105_pre_reset(struct ata_port *ap) { static const struct pci_bits sl82c105_enable_bits[] = { { 0x40, 1, 0x01, 0x01 }, @@ -59,7 +58,7 @@ static int sl82c105_pre_reset(struct ata_port *ap, unsigned long deadline) if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no])) return -ENOENT; - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } diff --git a/trunk/drivers/ata/pata_triflex.c b/trunk/drivers/ata/pata_triflex.c index 349887bf5b93..e618ffd6e944 100644 --- a/trunk/drivers/ata/pata_triflex.c +++ b/trunk/drivers/ata/pata_triflex.c @@ -48,12 +48,11 @@ /** * triflex_prereset - probe begin * @ap: ATA port - * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int triflex_prereset(struct ata_port *ap, unsigned long deadline) +static int triflex_prereset(struct ata_port *ap) { static const struct pci_bits triflex_enable_bits[] = { { 0x80, 1, 0x01, 0x01 }, @@ -64,8 +63,7 @@ static int triflex_prereset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no])) return -ENOENT; - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } diff --git a/trunk/drivers/ata/pata_via.c b/trunk/drivers/ata/pata_via.c index 362beb2f489c..96b71791d2f4 100644 --- a/trunk/drivers/ata/pata_via.c +++ b/trunk/drivers/ata/pata_via.c @@ -154,7 +154,7 @@ static int via_cable_detect(struct ata_port *ap) { return ATA_CBL_PATA40; } -static int via_pre_reset(struct ata_port *ap, unsigned long deadline) +static int via_pre_reset(struct ata_port *ap) { const struct via_isa_bridge *config = ap->host->private_data; @@ -167,8 +167,7 @@ static int via_pre_reset(struct ata_port *ap, unsigned long deadline) if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no])) return -ENOENT; } - - return ata_std_prereset(ap, deadline); + return ata_std_prereset(ap); } diff --git a/trunk/drivers/ata/sata_inic162x.c b/trunk/drivers/ata/sata_inic162x.c index b3b62e985f19..f099a1d83a00 100644 --- a/trunk/drivers/ata/sata_inic162x.c +++ b/trunk/drivers/ata/sata_inic162x.c @@ -420,8 +420,7 @@ static void inic_thaw(struct ata_port *ap) * SRST and SControl hardreset don't give valid signature on this * controller. Only controller specific hardreset mechanism works. */ -static int inic_hardreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) +static int inic_hardreset(struct ata_port *ap, unsigned int *class) { void __iomem *port_base = inic_port_base(ap); void __iomem *idma_ctl = port_base + PORT_IDMA_CTL; @@ -438,7 +437,7 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class, msleep(1); writew(val & ~IDMA_CTL_RST_ATA, idma_ctl); - rc = sata_phy_resume(ap, timing, deadline); + rc = sata_phy_resume(ap, timing); if (rc) { ata_port_printk(ap, KERN_WARNING, "failed to resume " "link after reset (errno=%d)\n", rc); @@ -452,12 +451,10 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class, /* wait a while before checking status */ msleep(150); - rc = ata_wait_ready(ap, deadline); - /* link occupied, -ENODEV too is an error */ - if (rc) { - ata_port_printk(ap, KERN_WARNING, "device not ready " - "after hardreset (errno=%d)\n", rc); - return rc; + if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { + ata_port_printk(ap, KERN_WARNING, + "device busy after hardreset\n"); + return -EIO; } ata_tf_read(ap, &tf); diff --git a/trunk/drivers/ata/sata_nv.c b/trunk/drivers/ata/sata_nv.c index e2e795e58236..02169740ed24 100644 --- a/trunk/drivers/ata/sata_nv.c +++ b/trunk/drivers/ata/sata_nv.c @@ -1405,8 +1405,7 @@ static void nv_ck804_thaw(struct ata_port *ap) writeb(mask, mmio_base + NV_INT_ENABLE_CK804); } -static int nv_hardreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) +static int nv_hardreset(struct ata_port *ap, unsigned int *class) { unsigned int dummy; @@ -1414,7 +1413,7 @@ static int nv_hardreset(struct ata_port *ap, unsigned int *class, * some controllers. Don't classify on hardreset. For more * info, see http://bugme.osdl.org/show_bug.cgi?id=3352 */ - return sata_std_hardreset(ap, &dummy, deadline); + return sata_std_hardreset(ap, &dummy); } static void nv_error_handler(struct ata_port *ap) diff --git a/trunk/drivers/ata/sata_sil24.c b/trunk/drivers/ata/sata_sil24.c index b97ee9f31aec..e6223ba667da 100644 --- a/trunk/drivers/ata/sata_sil24.c +++ b/trunk/drivers/ata/sata_sil24.c @@ -534,8 +534,7 @@ static int sil24_init_port(struct ata_port *ap) return 0; } -static int sil24_softreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) +static int sil24_softreset(struct ata_port *ap, unsigned int *class) { void __iomem *port = ap->ioaddr.cmd_addr; struct sil24_port_priv *pp = ap->private_data; @@ -567,7 +566,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class, mask = (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR) << PORT_IRQ_RAW_SHIFT; irq_stat = ata_wait_register(port + PORT_IRQ_STAT, mask, 0x0, - 100, jiffies_to_msecs(deadline - jiffies)); + 100, ATA_TMOUT_BOOT / HZ * 1000); writel(irq_stat, port + PORT_IRQ_STAT); /* clear IRQs */ irq_stat >>= PORT_IRQ_RAW_SHIFT; @@ -595,8 +594,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class, return -EIO; } -static int sil24_hardreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) +static int sil24_hardreset(struct ata_port *ap, unsigned int *class) { void __iomem *port = ap->ioaddr.cmd_addr; const char *reason; @@ -617,7 +615,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class, /* SStatus oscillates between zero and valid status after * DEV_RST, debounce it. */ - rc = sata_phy_debounce(ap, sata_deb_timing_long, deadline); + rc = sata_phy_debounce(ap, sata_deb_timing_long); if (rc) { reason = "PHY debouncing failed"; goto err; diff --git a/trunk/drivers/ata/sata_svw.c b/trunk/drivers/ata/sata_svw.c index 17246734fe76..cc07aac10e8c 100644 --- a/trunk/drivers/ata/sata_svw.c +++ b/trunk/drivers/ata/sata_svw.c @@ -288,7 +288,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start, /* Match it to a port node */ index = (ap == ap->host->ports[0]) ? 0 : 1; for (np = np->child; np != NULL; np = np->sibling) { - const u32 *reg = of_get_property(np, "reg", NULL); + const u32 *reg = get_property(np, "reg", NULL); if (!reg) continue; if (index == *reg) diff --git a/trunk/drivers/ata/sata_via.c b/trunk/drivers/ata/sata_via.c index 305ab7c68ca5..1d855f55f5f7 100644 --- a/trunk/drivers/ata/sata_via.c +++ b/trunk/drivers/ata/sata_via.c @@ -268,7 +268,6 @@ static void svia_noop_freeze(struct ata_port *ap) /** * vt6420_prereset - prereset for vt6420 * @ap: target ATA port - * @deadline: deadline jiffies for the operation * * SCR registers on vt6420 are pieces of shit and may hang the * whole machine completely if accessed with the wrong timing. @@ -285,7 +284,7 @@ static void svia_noop_freeze(struct ata_port *ap) * RETURNS: * 0 on success, -errno otherwise. */ -static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) +static int vt6420_prereset(struct ata_port *ap) { struct ata_eh_context *ehc = &ap->eh_context; unsigned long timeout = jiffies + (HZ * 5); @@ -330,7 +329,7 @@ static int vt6420_prereset(struct ata_port *ap, unsigned long deadline) skip_scr: /* wait for !BSY */ - ata_wait_ready(ap, deadline); + ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); return 0; } diff --git a/trunk/drivers/atm/adummy.c b/trunk/drivers/atm/adummy.c index 2ebd07f2ef81..8d60c4eb54fe 100644 --- a/trunk/drivers/atm/adummy.c +++ b/trunk/drivers/atm/adummy.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/base/Makefile b/trunk/drivers/base/Makefile index b39ea3f59c9b..e9eb7382ac3a 100644 --- a/trunk/drivers/base/Makefile +++ b/trunk/drivers/base/Makefile @@ -2,10 +2,10 @@ obj-y := core.o sys.o bus.o dd.o \ driver.o class.o platform.o \ - cpu.o firmware.o init.o map.o devres.o \ + cpu.o firmware.o init.o map.o dmapool.o \ + dma-mapping.o devres.o \ attribute_container.o transport_class.o obj-y += power/ -obj-$(CONFIG_HAS_DMA) += dma-mapping.o dmapool.o obj-$(CONFIG_ISA) += isa.o obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o diff --git a/trunk/drivers/base/base.h b/trunk/drivers/base/base.h index 5512d84452f2..d597f2659b23 100644 --- a/trunk/drivers/base/base.h +++ b/trunk/drivers/base/base.h @@ -45,5 +45,3 @@ struct class_device_attribute *to_class_dev_attr(struct attribute *_attr) extern char *make_class_name(const char *name, struct kobject *kobj); extern void devres_release_all(struct device *dev); - -extern struct kset devices_subsys; diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index dca734819e50..1d76e2349654 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -17,7 +17,7 @@ #include "power/power.h" #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) -#define to_bus(obj) container_of(obj, struct bus_type, subsys.kobj) +#define to_bus(obj) container_of(obj, struct bus_type, subsys.kset.kobj) /* * sysfs bindings for drivers @@ -123,7 +123,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) { int error; if (get_bus(bus)) { - error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); + error = sysfs_create_file(&bus->subsys.kset.kobj, &attr->attr); put_bus(bus); } else error = -EINVAL; @@ -133,7 +133,7 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) { if (get_bus(bus)) { - sysfs_remove_file(&bus->subsys.kobj, &attr->attr); + sysfs_remove_file(&bus->subsys.kset.kobj, &attr->attr); put_bus(bus); } } @@ -397,7 +397,7 @@ static void device_remove_attrs(struct bus_type * bus, struct device * dev) static int make_deprecated_bus_links(struct device *dev) { return sysfs_create_link(&dev->kobj, - &dev->bus->subsys.kobj, "bus"); + &dev->bus->subsys.kset.kobj, "bus"); } static void remove_deprecated_bus_links(struct device *dev) @@ -431,7 +431,7 @@ int bus_add_device(struct device * dev) if (error) goto out_id; error = sysfs_create_link(&dev->kobj, - &dev->bus->subsys.kobj, "subsystem"); + &dev->bus->subsys.kset.kobj, "subsystem"); if (error) goto out_subsys; error = make_deprecated_bus_links(dev); @@ -810,7 +810,7 @@ int bus_register(struct bus_type * bus) BLOCKING_INIT_NOTIFIER_HEAD(&bus->bus_notifier); - retval = kobject_set_name(&bus->subsys.kobj, "%s", bus->name); + retval = kobject_set_name(&bus->subsys.kset.kobj, "%s", bus->name); if (retval) goto out; @@ -820,13 +820,13 @@ int bus_register(struct bus_type * bus) goto out; kobject_set_name(&bus->devices.kobj, "devices"); - bus->devices.kobj.parent = &bus->subsys.kobj; + bus->devices.subsys = &bus->subsys; retval = kset_register(&bus->devices); if (retval) goto bus_devices_fail; kobject_set_name(&bus->drivers.kobj, "drivers"); - bus->drivers.kobj.parent = &bus->subsys.kobj; + bus->drivers.subsys = &bus->subsys; bus->drivers.ktype = &ktype_driver; retval = kset_register(&bus->drivers); if (retval) diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c index 20c4ea6eb50d..80bbb2074636 100644 --- a/trunk/drivers/base/class.c +++ b/trunk/drivers/base/class.c @@ -19,8 +19,10 @@ #include #include "base.h" +extern struct subsystem devices_subsys; + #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) -#define to_class(obj) container_of(obj, struct class, subsys.kobj) +#define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) static ssize_t class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) @@ -78,7 +80,7 @@ int class_create_file(struct class * cls, const struct class_attribute * attr) { int error; if (cls) { - error = sysfs_create_file(&cls->subsys.kobj, &attr->attr); + error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr); } else error = -EINVAL; return error; @@ -87,7 +89,7 @@ int class_create_file(struct class * cls, const struct class_attribute * attr) void class_remove_file(struct class * cls, const struct class_attribute * attr) { if (cls) - sysfs_remove_file(&cls->subsys.kobj, &attr->attr); + sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr); } static struct class *class_get(struct class *cls) @@ -145,7 +147,7 @@ int class_register(struct class * cls) INIT_LIST_HEAD(&cls->interfaces); kset_init(&cls->class_dirs); init_MUTEX(&cls->sem); - error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name); + error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name); if (error) return error; @@ -609,7 +611,7 @@ int class_device_add(struct class_device *class_dev) if (parent_class_dev) class_dev->kobj.parent = &parent_class_dev->kobj; else - class_dev->kobj.parent = &parent_class->subsys.kobj; + class_dev->kobj.parent = &parent_class->subsys.kset.kobj; error = kobject_add(&class_dev->kobj); if (error) @@ -617,7 +619,7 @@ int class_device_add(struct class_device *class_dev) /* add the needed attributes to this device */ error = sysfs_create_link(&class_dev->kobj, - &parent_class->subsys.kobj, "subsystem"); + &parent_class->subsys.kset.kobj, "subsystem"); if (error) goto out3; class_dev->uevent_attr.attr.name = "uevent"; @@ -915,8 +917,8 @@ int __init classes_init(void) /* ick, this is ugly, the things we go through to keep from showing up * in sysfs... */ subsystem_init(&class_obj_subsys); - if (!class_obj_subsys.kobj.parent) - class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; + if (!class_obj_subsys.kset.subsys) + class_obj_subsys.kset.subsys = &class_obj_subsys; return 0; } diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index b78fc1e68264..8aa090da1cd7 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -252,7 +252,7 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, struct kobject *top_kobj; struct kset *kset; char *envp[32]; - char *data = NULL; + char data[PAGE_SIZE]; char *pos; int i; size_t count = 0; @@ -276,10 +276,6 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, if (!kset->uevent_ops->filter(kset, &dev->kobj)) goto out; - data = (char *)get_zeroed_page(GFP_KERNEL); - if (!data) - return -ENOMEM; - /* let the kset specific function add its keys */ pos = data; retval = kset->uevent_ops->uevent(kset, &dev->kobj, @@ -294,7 +290,6 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, count += sprintf(pos, "%s\n", envp[i]); } out: - free_page((unsigned long)data); return count; } @@ -565,7 +560,7 @@ static struct kobject * get_device_parent(struct device *dev, /* Set the parent to the class, not the parent device */ /* this keeps sysfs from having a symlink to make old udevs happy */ if (dev->class) - return &dev->class->subsys.kobj; + return &dev->class->subsys.kset.kobj; else if (parent) return &parent->kobj; @@ -577,7 +572,7 @@ static struct kobject *virtual_device_parent(struct device *dev) static struct kobject *virtual_dir = NULL; if (!virtual_dir) - virtual_dir = kobject_add_dir(&devices_subsys.kobj, "virtual"); + virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); return virtual_dir; } @@ -711,12 +706,12 @@ int device_add(struct device *dev) } if (dev->class) { - sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj, + sysfs_create_link(&dev->kobj, &dev->class->subsys.kset.kobj, "subsystem"); /* If this is not a "fake" compatible device, then create the * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kobj) - sysfs_create_link(&dev->class->subsys.kobj, + if (dev->kobj.parent != &dev->class->subsys.kset.kobj) + sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, dev->bus_id); if (parent) { sysfs_create_link(&dev->kobj, &dev->parent->kobj, @@ -774,8 +769,8 @@ int device_add(struct device *dev) sysfs_remove_link(&dev->kobj, "subsystem"); /* If this is not a "fake" compatible device, remove the * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kobj) - sysfs_remove_link(&dev->class->subsys.kobj, + if (dev->kobj.parent != &dev->class->subsys.kset.kobj) + sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); if (parent) { #ifdef CONFIG_SYSFS_DEPRECATED @@ -875,8 +870,8 @@ void device_del(struct device * dev) sysfs_remove_link(&dev->kobj, "subsystem"); /* If this is not a "fake" compatible device, remove the * symlink from the class to the device. */ - if (dev->kobj.parent != &dev->class->subsys.kobj) - sysfs_remove_link(&dev->class->subsys.kobj, + if (dev->kobj.parent != &dev->class->subsys.kset.kobj) + sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); if (parent) { #ifdef CONFIG_SYSFS_DEPRECATED @@ -1192,9 +1187,9 @@ int device_rename(struct device *dev, char *new_name) #endif if (dev->class) { - sysfs_remove_link(&dev->class->subsys.kobj, + sysfs_remove_link(&dev->class->subsys.kset.kobj, old_symlink_name); - sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, + sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, dev->bus_id); } put_device(dev); diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c index 92428e55b0c2..18dba8e78da7 100644 --- a/trunk/drivers/base/dd.c +++ b/trunk/drivers/base/dd.c @@ -226,10 +226,12 @@ static int device_probe_drivers(void *data) * * Walk the list of drivers that the bus has and call * driver_probe_device() for each pair. If a compatible - * pair is found, break out and return. + * pair is found, break out and return. If the bus specifies + * multithreaded probing, walking the list of drivers is done + * on a probing thread. * * Returns 1 if the device was bound to a driver; - * 0 if no matching device was found; + * 0 if no matching device was found or multithreaded probing is done; * -ENODEV if the device is not registered. * * When called for a USB interface, @dev->parent->sem must be held. @@ -237,6 +239,7 @@ static int device_probe_drivers(void *data) int device_attach(struct device * dev) { int ret = 0; + struct task_struct *probe_task = ERR_PTR(-ENOMEM); down(&dev->sem); if (dev->driver) { @@ -248,7 +251,12 @@ int device_attach(struct device * dev) ret = 0; } } else { - ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); + if (dev->bus->multithread_probe) + probe_task = kthread_run(device_probe_drivers, dev, + "probe-%s", dev->bus_id); + if(IS_ERR(probe_task)) + ret = bus_for_each_drv(dev->bus, NULL, dev, + __device_attach); } up(&dev->sem); return ret; @@ -375,6 +383,33 @@ void driver_detach(struct device_driver * drv) } } +#ifdef CONFIG_PCI_MULTITHREAD_PROBE +static int __init wait_for_probes(void) +{ + DEFINE_WAIT(wait); + + printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__, + atomic_read(&probe_count)); + if (!atomic_read(&probe_count)) + return 0; + while (atomic_read(&probe_count)) { + prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE); + if (atomic_read(&probe_count)) + schedule(); + } + finish_wait(&probe_waitqueue, &wait); + return 0; +} + +core_initcall_sync(wait_for_probes); +postcore_initcall_sync(wait_for_probes); +arch_initcall_sync(wait_for_probes); +subsys_initcall_sync(wait_for_probes); +fs_initcall_sync(wait_for_probes); +device_initcall_sync(wait_for_probes); +late_initcall_sync(wait_for_probes); +#endif + EXPORT_SYMBOL_GPL(device_bind_driver); EXPORT_SYMBOL_GPL(device_release_driver); EXPORT_SYMBOL_GPL(device_attach); diff --git a/trunk/drivers/base/firmware.c b/trunk/drivers/base/firmware.c index 90c862932169..cb1b98ae0d58 100644 --- a/trunk/drivers/base/firmware.c +++ b/trunk/drivers/base/firmware.c @@ -17,13 +17,13 @@ static decl_subsys(firmware, NULL, NULL); -int firmware_register(struct kset *s) +int firmware_register(struct subsystem * s) { - kobj_set_kset_s(s, firmware_subsys); + kset_set_kset_s(s, firmware_subsys); return subsystem_register(s); } -void firmware_unregister(struct kset *s) +void firmware_unregister(struct subsystem * s) { subsystem_unregister(s); } diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index eb84d9d44645..30480f6f2af2 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -160,11 +160,6 @@ static void platform_device_release(struct device *dev) * * Create a platform device object which can have other objects attached * to it, and which will have attached objects freed when it is released. - * - * This device will be marked as not supporting hotpluggable drivers; no - * device add/remove uevents will be generated. In the unusual case that - * the device isn't being dynamically allocated as a legacy "probe the - * hardware" driver, infrastructure code should reverse this marking. */ struct platform_device *platform_device_alloc(const char *name, unsigned int id) { @@ -177,12 +172,6 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id) pa->pdev.id = id; device_initialize(&pa->pdev.dev); pa->pdev.dev.release = platform_device_release; - - /* prevent hotplug "modprobe $(MODALIAS)" from causing trouble in - * legacy probe-the-hardware drivers, which don't properly split - * out device enumeration logic from drivers. - */ - pa->pdev.dev.uevent_suppress = 1; } return pa ? &pa->pdev : NULL; @@ -303,22 +292,20 @@ EXPORT_SYMBOL_GPL(platform_device_add); * @pdev: platform device we're removing * * Note that this function will also release all memory- and port-based - * resources owned by the device (@dev->resource). This function - * must _only_ be externally called in error cases. All other usage - * is a bug. + * resources owned by the device (@dev->resource). */ void platform_device_del(struct platform_device *pdev) { int i; if (pdev) { - device_del(&pdev->dev); - for (i = 0; i < pdev->num_resources; i++) { struct resource *r = &pdev->resource[i]; if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO)) release_resource(r); } + + device_del(&pdev->dev); } } EXPORT_SYMBOL_GPL(platform_device_del); @@ -362,13 +349,6 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); * memory allocated for the device allows drivers using such devices * to be unloaded iwithout waiting for the last reference to the device * to be dropped. - * - * This interface is primarily intended for use with legacy drivers - * which probe hardware directly. Because such drivers create sysfs - * device nodes themselves, rather than letting system infrastructure - * handle such device enumeration tasks, they don't fully conform to - * the Linux driver model. In particular, when such drivers are built - * as modules, they can't be "hotplugged". */ struct platform_device *platform_device_register_simple(char *name, unsigned int id, struct resource *res, unsigned int num) diff --git a/trunk/drivers/base/power/shutdown.c b/trunk/drivers/base/power/shutdown.c index a47ee1b70d20..58b6f77a1b34 100644 --- a/trunk/drivers/base/power/shutdown.c +++ b/trunk/drivers/base/power/shutdown.c @@ -16,6 +16,8 @@ #define to_dev(node) container_of(node, struct device, kobj.entry) +extern struct subsystem devices_subsys; + /** * We handle system devices differently - we suspend and shut them @@ -34,7 +36,7 @@ void device_shutdown(void) { struct device * dev, *devn; - list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.list, + list_for_each_entry_safe_reverse(dev, devn, &devices_subsys.kset.list, kobj.entry) { if (dev->bus && dev->bus->shutdown) { dev_dbg(dev, "shutdown\n"); diff --git a/trunk/drivers/base/sys.c b/trunk/drivers/base/sys.c index 29f1291966c1..04e5db445c74 100644 --- a/trunk/drivers/base/sys.c +++ b/trunk/drivers/base/sys.c @@ -25,7 +25,7 @@ #include "base.h" -extern struct kset devices_subsys; +extern struct subsystem devices_subsys; #define to_sysdev(k) container_of(k, struct sys_device, kobj) #define to_sysdev_attr(a) container_of(a, struct sysdev_attribute, attr) @@ -138,7 +138,7 @@ int sysdev_class_register(struct sysdev_class * cls) pr_debug("Registering sysdev class '%s'\n", kobject_name(&cls->kset.kobj)); INIT_LIST_HEAD(&cls->drivers); - cls->kset.kobj.parent = &system_subsys.kobj; + cls->kset.subsys = &system_subsys; kset_set_kset_s(cls, system_subsys); return kset_register(&cls->kset); } @@ -309,7 +309,7 @@ void sysdev_shutdown(void) pr_debug("Shutting Down System Devices\n"); down(&sysdev_drivers_lock); - list_for_each_entry_reverse(cls, &system_subsys.list, + list_for_each_entry_reverse(cls, &system_subsys.kset.list, kset.kobj.entry) { struct sys_device * sysdev; @@ -384,7 +384,7 @@ int sysdev_suspend(pm_message_t state) pr_debug("Suspending System Devices\n"); - list_for_each_entry_reverse(cls, &system_subsys.list, + list_for_each_entry_reverse(cls, &system_subsys.kset.list, kset.kobj.entry) { pr_debug("Suspending type '%s':\n", @@ -457,7 +457,7 @@ int sysdev_suspend(pm_message_t state) } /* resume other classes */ - list_for_each_entry_continue(cls, &system_subsys.list, + list_for_each_entry_continue(cls, &system_subsys.kset.list, kset.kobj.entry) { list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { pr_debug(" %s\n", kobject_name(&err_dev->kobj)); @@ -483,7 +483,7 @@ int sysdev_resume(void) pr_debug("Resuming System Devices\n"); - list_for_each_entry(cls, &system_subsys.list, kset.kobj.entry) { + list_for_each_entry(cls, &system_subsys.kset.list, kset.kobj.entry) { struct sys_device * sysdev; pr_debug("Resuming type '%s':\n", @@ -501,7 +501,7 @@ int sysdev_resume(void) int __init system_bus_init(void) { - system_subsys.kobj.parent = &devices_subsys.kobj; + system_subsys.kset.kobj.parent = &devices_subsys.kset.kobj; return subsystem_register(&system_subsys); } diff --git a/trunk/drivers/block/acsi_slm.c b/trunk/drivers/block/acsi_slm.c index 1d9d9b4f48cc..e2e043290963 100644 --- a/trunk/drivers/block/acsi_slm.c +++ b/trunk/drivers/block/acsi_slm.c @@ -65,6 +65,7 @@ not be guaranteed. There are several ways to assure this: #include #include #include +#include #include #include diff --git a/trunk/drivers/block/amiflop.c b/trunk/drivers/block/amiflop.c index 27a139025ced..5d6562171533 100644 --- a/trunk/drivers/block/amiflop.c +++ b/trunk/drivers/block/amiflop.c @@ -1480,7 +1480,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, break; case FDFMTEND: floppy_off(drive); - invalidate_bdev(inode->i_bdev); + invalidate_bdev(inode->i_bdev, 0); break; case FDGETPRM: memset((void *)&getprm, 0, sizeof (getprm)); diff --git a/trunk/drivers/block/aoe/aoecmd.c b/trunk/drivers/block/aoe/aoecmd.c index 01fbdd38e3be..1a6aeac5a1c3 100644 --- a/trunk/drivers/block/aoe/aoecmd.c +++ b/trunk/drivers/block/aoe/aoecmd.c @@ -194,15 +194,15 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) sl = sl_tail = NULL; read_lock(&dev_base_lock); - for_each_netdev(ifp) { + for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) { dev_hold(ifp); if (!is_aoe_netif(ifp)) - goto cont; + continue; skb = new_skb(sizeof *h + sizeof *ch); if (skb == NULL) { printk(KERN_INFO "aoe: skb alloc failure\n"); - goto cont; + continue; } skb_put(skb, sizeof *h + sizeof *ch); skb->dev = ifp; @@ -221,8 +221,6 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) skb->next = sl; sl = skb; -cont: - dev_put(ifp); } read_unlock(&dev_base_lock); diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 370dfe1c422e..65a725cd3422 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -45,10 +45,6 @@ #include #include #include -#include -#include -#include -#include #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) #define DRIVER_NAME "HP CISS Driver (v 3.6.14)" @@ -1156,30 +1152,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, kfree(ioc); return status; } - - /* scsi_cmd_ioctl handles these, below, though some are not */ - /* very meaningful for cciss. SG_IO is the main one people want. */ - - case SG_GET_VERSION_NUM: - case SG_SET_TIMEOUT: - case SG_GET_TIMEOUT: - case SG_GET_RESERVED_SIZE: - case SG_SET_RESERVED_SIZE: - case SG_EMULATED_HOST: - case SG_IO: - case SCSI_IOCTL_SEND_COMMAND: - return scsi_cmd_ioctl(filep, disk, cmd, argp); - - /* scsi_cmd_ioctl would normally handle these, below, but */ - /* they aren't a good fit for cciss, as CD-ROMs are */ - /* not supported, and we don't have any bus/target/lun */ - /* which we present to the kernel. */ - - case CDROM_SEND_PACKET: - case CDROMCLOSETRAY: - case CDROMEJECT: - case SCSI_IOCTL_GET_IDLUN: - case SCSI_IOCTL_GET_BUS_NUMBER: default: return -ENOTTY; } @@ -1262,7 +1234,7 @@ static void cciss_softirq_done(struct request *rq) pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); } - complete_buffers(rq->bio, (rq->errors == 0)); + complete_buffers(rq->bio, rq->errors); if (blk_fs_request(rq)) { const int rw = rq_data_dir(rq); @@ -1276,7 +1248,7 @@ static void cciss_softirq_done(struct request *rq) add_disk_randomness(rq->rq_disk); spin_lock_irqsave(&h->lock, flags); - end_that_request_last(rq, (rq->errors == 0)); + end_that_request_last(rq, rq->errors); cmd_free(h, cmd, 1); cciss_check_queues(h); spin_unlock_irqrestore(&h->lock, flags); @@ -2364,44 +2336,6 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) start_io(h); } -static inline int evaluate_target_status(CommandList_struct *cmd) -{ - unsigned char sense_key; - int error_count = 1; - - if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */ - if (!blk_pc_request(cmd->rq)) - printk(KERN_WARNING "cciss: cmd %p " - "has SCSI Status 0x%x\n", - cmd, cmd->err_info->ScsiStatus); - return error_count; - } - - /* check the sense key */ - sense_key = 0xf & cmd->err_info->SenseInfo[2]; - /* no status or recovered error */ - if ((sense_key == 0x0) || (sense_key == 0x1)) - error_count = 0; - - if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */ - if (error_count != 0) - printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION" - " sense key = 0x%x\n", cmd, sense_key); - return error_count; - } - - /* SG_IO or similar, copy sense data back */ - if (cmd->rq->sense) { - if (cmd->rq->sense_len > cmd->err_info->SenseLen) - cmd->rq->sense_len = cmd->err_info->SenseLen; - memcpy(cmd->rq->sense, cmd->err_info->SenseInfo, - cmd->rq->sense_len); - } else - cmd->rq->sense_len = 0; - - return error_count; -} - /* checks the status of the job and calls complete buffers to mark all * buffers for the completed job. Note that this function does not need * to hold the hba/queue lock. @@ -2409,99 +2343,109 @@ static inline int evaluate_target_status(CommandList_struct *cmd) static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, int timeout) { + int status = 1; int retry_cmd = 0; - struct request *rq = cmd->rq; - - rq->errors = 0; if (timeout) - rq->errors = 1; + status = 0; - if (cmd->err_info->CommandStatus == 0) /* no error has occurred */ - goto after_error_processing; + if (cmd->err_info->CommandStatus != 0) { /* an error has occurred */ + switch (cmd->err_info->CommandStatus) { + unsigned char sense_key; + case CMD_TARGET_STATUS: + status = 0; - switch (cmd->err_info->CommandStatus) { - case CMD_TARGET_STATUS: - rq->errors = evaluate_target_status(cmd); - break; - case CMD_DATA_UNDERRUN: - if (blk_fs_request(cmd->rq)) { + if (cmd->err_info->ScsiStatus == 0x02) { + printk(KERN_WARNING "cciss: cmd %p " + "has CHECK CONDITION " + " byte 2 = 0x%x\n", cmd, + cmd->err_info->SenseInfo[2] + ); + /* check the sense key */ + sense_key = 0xf & cmd->err_info->SenseInfo[2]; + /* no status or recovered error */ + if ((sense_key == 0x0) || (sense_key == 0x1)) { + status = 1; + } + } else { + printk(KERN_WARNING "cciss: cmd %p " + "has SCSI Status 0x%x\n", + cmd, cmd->err_info->ScsiStatus); + } + break; + case CMD_DATA_UNDERRUN: printk(KERN_WARNING "cciss: cmd %p has" " completed with data underrun " "reported\n", cmd); - cmd->rq->data_len = cmd->err_info->ResidualCnt; - } - break; - case CMD_DATA_OVERRUN: - if (blk_fs_request(cmd->rq)) + break; + case CMD_DATA_OVERRUN: printk(KERN_WARNING "cciss: cmd %p has" " completed with data overrun " "reported\n", cmd); - break; - case CMD_INVALID: - printk(KERN_WARNING "cciss: cmd %p is " - "reported invalid\n", cmd); - rq->errors = 1; - break; - case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: cmd %p has " - "protocol error \n", cmd); - rq->errors = 1; - break; - case CMD_HARDWARE_ERR: - printk(KERN_WARNING "cciss: cmd %p had " - " hardware error\n", cmd); - rq->errors = 1; - break; - case CMD_CONNECTION_LOST: - printk(KERN_WARNING "cciss: cmd %p had " - "connection lost\n", cmd); - rq->errors = 1; - break; - case CMD_ABORTED: - printk(KERN_WARNING "cciss: cmd %p was " - "aborted\n", cmd); - rq->errors = 1; - break; - case CMD_ABORT_FAILED: - printk(KERN_WARNING "cciss: cmd %p reports " - "abort failed\n", cmd); - rq->errors = 1; - break; - case CMD_UNSOLICITED_ABORT: - printk(KERN_WARNING "cciss%d: unsolicited " - "abort %p\n", h->ctlr, cmd); - if (cmd->retry_count < MAX_CMD_RETRIES) { - retry_cmd = 1; - printk(KERN_WARNING - "cciss%d: retrying %p\n", h->ctlr, cmd); - cmd->retry_count++; - } else - printk(KERN_WARNING - "cciss%d: %p retried too " - "many times\n", h->ctlr, cmd); - rq->errors = 1; - break; - case CMD_TIMEOUT: - printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); - rq->errors = 1; - break; - default: - printk(KERN_WARNING "cciss: cmd %p returned " - "unknown status %x\n", cmd, - cmd->err_info->CommandStatus); - rq->errors = 1; + break; + case CMD_INVALID: + printk(KERN_WARNING "cciss: cmd %p is " + "reported invalid\n", cmd); + status = 0; + break; + case CMD_PROTOCOL_ERR: + printk(KERN_WARNING "cciss: cmd %p has " + "protocol error \n", cmd); + status = 0; + break; + case CMD_HARDWARE_ERR: + printk(KERN_WARNING "cciss: cmd %p had " + " hardware error\n", cmd); + status = 0; + break; + case CMD_CONNECTION_LOST: + printk(KERN_WARNING "cciss: cmd %p had " + "connection lost\n", cmd); + status = 0; + break; + case CMD_ABORTED: + printk(KERN_WARNING "cciss: cmd %p was " + "aborted\n", cmd); + status = 0; + break; + case CMD_ABORT_FAILED: + printk(KERN_WARNING "cciss: cmd %p reports " + "abort failed\n", cmd); + status = 0; + break; + case CMD_UNSOLICITED_ABORT: + printk(KERN_WARNING "cciss%d: unsolicited " + "abort %p\n", h->ctlr, cmd); + if (cmd->retry_count < MAX_CMD_RETRIES) { + retry_cmd = 1; + printk(KERN_WARNING + "cciss%d: retrying %p\n", h->ctlr, cmd); + cmd->retry_count++; + } else + printk(KERN_WARNING + "cciss%d: %p retried too " + "many times\n", h->ctlr, cmd); + status = 0; + break; + case CMD_TIMEOUT: + printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); + status = 0; + break; + default: + printk(KERN_WARNING "cciss: cmd %p returned " + "unknown status %x\n", cmd, + cmd->err_info->CommandStatus); + status = 0; + } } - -after_error_processing: - /* We need to return this command */ if (retry_cmd) { resend_cciss_cmd(h, cmd); return; } - cmd->rq->data_len = 0; + cmd->rq->completion_data = cmd; + cmd->rq->errors = status; blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE); blk_complete_request(cmd->rq); } @@ -2595,40 +2539,32 @@ static void do_cciss_request(request_queue_t *q) #endif /* CCISS_DEBUG */ c->Header.SGList = c->Header.SGTotal = seg; - if (likely(blk_fs_request(creq))) { - if(h->cciss_read == CCISS_READ_10) { - c->Request.CDB[1] = 0; - c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB - c->Request.CDB[3] = (start_blk >> 16) & 0xff; - c->Request.CDB[4] = (start_blk >> 8) & 0xff; - c->Request.CDB[5] = start_blk & 0xff; - c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB - c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; - c->Request.CDB[8] = creq->nr_sectors & 0xff; - c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; - } else { - c->Request.CDBLen = 16; - c->Request.CDB[1]= 0; - c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB - c->Request.CDB[3]= (start_blk >> 48) & 0xff; - c->Request.CDB[4]= (start_blk >> 40) & 0xff; - c->Request.CDB[5]= (start_blk >> 32) & 0xff; - c->Request.CDB[6]= (start_blk >> 24) & 0xff; - c->Request.CDB[7]= (start_blk >> 16) & 0xff; - c->Request.CDB[8]= (start_blk >> 8) & 0xff; - c->Request.CDB[9]= start_blk & 0xff; - c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff; - c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff; - c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff; - c->Request.CDB[13]= creq->nr_sectors & 0xff; - c->Request.CDB[14] = c->Request.CDB[15] = 0; - } - } else if (blk_pc_request(creq)) { - c->Request.CDBLen = creq->cmd_len; - memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB); + if(h->cciss_read == CCISS_READ_10) { + c->Request.CDB[1] = 0; + c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB + c->Request.CDB[3] = (start_blk >> 16) & 0xff; + c->Request.CDB[4] = (start_blk >> 8) & 0xff; + c->Request.CDB[5] = start_blk & 0xff; + c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB + c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; + c->Request.CDB[8] = creq->nr_sectors & 0xff; + c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; } else { - printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type); - BUG(); + c->Request.CDBLen = 16; + c->Request.CDB[1]= 0; + c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB + c->Request.CDB[3]= (start_blk >> 48) & 0xff; + c->Request.CDB[4]= (start_blk >> 40) & 0xff; + c->Request.CDB[5]= (start_blk >> 32) & 0xff; + c->Request.CDB[6]= (start_blk >> 24) & 0xff; + c->Request.CDB[7]= (start_blk >> 16) & 0xff; + c->Request.CDB[8]= (start_blk >> 8) & 0xff; + c->Request.CDB[9]= start_blk & 0xff; + c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff; + c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff; + c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff; + c->Request.CDB[13]= creq->nr_sectors & 0xff; + c->Request.CDB[14] = c->Request.CDB[15] = 0; } spin_lock_irq(q->queue_lock); diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index 90961a8ea895..bb15051ffbe0 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -35,6 +35,7 @@ #include +#include #include #include #include diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 3587cb434371..5231ed7e723f 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -4334,10 +4334,7 @@ static int __init floppy_init(void) if (err) goto out_flush_work; - err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); - if (err) - goto out_unreg_platform_dev; - + device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); /* to be cleaned up... */ disks[drive]->private_data = (void *)(long)drive; disks[drive]->queue = floppy_queue; @@ -4348,8 +4345,6 @@ static int __init floppy_init(void) return 0; -out_unreg_platform_dev: - platform_device_unregister(&floppy_device[drive]); out_flush_work: flush_scheduled_work(); if (usage_count) diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index af6d7274a7cc..6b5b64207407 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -77,8 +77,9 @@ #include -static LIST_HEAD(loop_devices); -static DEFINE_MUTEX(loop_devices_mutex); +static int max_loop = 8; +static struct loop_device *loop_dev; +static struct gendisk **disks; /* * Transfer functions @@ -182,7 +183,7 @@ figure_loop_size(struct loop_device *lo) if (unlikely((loff_t)x != size)) return -EFBIG; - set_capacity(lo->lo_disk, x); + set_capacity(disks[lo->lo_number], x); return 0; } @@ -811,7 +812,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, lo->lo_queue->queuedata = lo; lo->lo_queue->unplug_fn = loop_unplug; - set_capacity(lo->lo_disk, size); + set_capacity(disks[lo->lo_number], size); bd_set_size(bdev, size << 9); set_blocksize(bdev, lo_blocksize); @@ -831,8 +832,8 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, lo->lo_device = NULL; lo->lo_backing_file = NULL; lo->lo_flags = 0; - set_capacity(lo->lo_disk, 0); - invalidate_bdev(bdev); + set_capacity(disks[lo->lo_number], 0); + invalidate_bdev(bdev, 0); bd_set_size(bdev, 0); mapping_set_gfp_mask(mapping, lo->old_gfp_mask); lo->lo_state = Lo_unbound; @@ -916,8 +917,8 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); - invalidate_bdev(bdev); - set_capacity(lo->lo_disk, 0); + invalidate_bdev(bdev, 0); + set_capacity(disks[lo->lo_number], 0); bd_set_size(bdev, 0); mapping_set_gfp_mask(filp->f_mapping, gfp); lo->lo_state = Lo_unbound; @@ -1321,18 +1322,6 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a } #endif -static struct loop_device *loop_find_dev(int number) -{ - struct loop_device *lo; - - list_for_each_entry(lo, &loop_devices, lo_list) { - if (lo->lo_number == number) - return lo; - } - return NULL; -} - -static struct loop_device *loop_init_one(int i); static int lo_open(struct inode *inode, struct file *file) { struct loop_device *lo = inode->i_bdev->bd_disk->private_data; @@ -1341,11 +1330,6 @@ static int lo_open(struct inode *inode, struct file *file) lo->lo_refcnt++; mutex_unlock(&lo->lo_ctl_mutex); - mutex_lock(&loop_devices_mutex); - if (!loop_find_dev(lo->lo_number + 1)) - loop_init_one(lo->lo_number + 1); - mutex_unlock(&loop_devices_mutex); - return 0; } @@ -1373,9 +1357,8 @@ static struct block_device_operations lo_fops = { /* * And now the modules code and kernel interface. */ -static int max_loop; module_param(max_loop, int, 0); -MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand"); +MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); @@ -1400,7 +1383,7 @@ int loop_unregister_transfer(int number) xfer_funcs[n] = NULL; - list_for_each_entry(lo, &loop_devices, lo_list) { + for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { mutex_lock(&lo->lo_ctl_mutex); if (lo->lo_encryption == xfer) @@ -1415,110 +1398,91 @@ int loop_unregister_transfer(int number) EXPORT_SYMBOL(loop_register_transfer); EXPORT_SYMBOL(loop_unregister_transfer); -static struct loop_device *loop_init_one(int i) -{ - struct loop_device *lo; - struct gendisk *disk; - - lo = kzalloc(sizeof(*lo), GFP_KERNEL); - if (!lo) - goto out; - - lo->lo_queue = blk_alloc_queue(GFP_KERNEL); - if (!lo->lo_queue) - goto out_free_dev; - - disk = lo->lo_disk = alloc_disk(1); - if (!disk) - goto out_free_queue; - - mutex_init(&lo->lo_ctl_mutex); - lo->lo_number = i; - lo->lo_thread = NULL; - init_waitqueue_head(&lo->lo_event); - spin_lock_init(&lo->lo_lock); - disk->major = LOOP_MAJOR; - disk->first_minor = i; - disk->fops = &lo_fops; - disk->private_data = lo; - disk->queue = lo->lo_queue; - sprintf(disk->disk_name, "loop%d", i); - add_disk(disk); - list_add_tail(&lo->lo_list, &loop_devices); - return lo; - -out_free_queue: - blk_cleanup_queue(lo->lo_queue); -out_free_dev: - kfree(lo); -out: - return ERR_PTR(-ENOMEM); -} - -static void loop_del_one(struct loop_device *lo) -{ - del_gendisk(lo->lo_disk); - blk_cleanup_queue(lo->lo_queue); - put_disk(lo->lo_disk); - list_del(&lo->lo_list); - kfree(lo); -} - -static struct kobject *loop_probe(dev_t dev, int *part, void *data) -{ - unsigned int number = dev & MINORMASK; - struct loop_device *lo; - - mutex_lock(&loop_devices_mutex); - lo = loop_find_dev(number); - if (lo == NULL) - lo = loop_init_one(number); - mutex_unlock(&loop_devices_mutex); - - *part = 0; - if (IS_ERR(lo)) - return (void *)lo; - else - return &lo->lo_disk->kobj; -} - static int __init loop_init(void) { - struct loop_device *lo; + int i; + + if (max_loop < 1 || max_loop > 256) { + printk(KERN_WARNING "loop: invalid max_loop (must be between" + " 1 and 256), using default (8)\n"); + max_loop = 8; + } if (register_blkdev(LOOP_MAJOR, "loop")) return -EIO; - blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS, - THIS_MODULE, loop_probe, NULL, NULL); - lo = loop_init_one(0); - if (IS_ERR(lo)) - goto out; + loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL); + if (!loop_dev) + goto out_mem1; + memset(loop_dev, 0, max_loop * sizeof(struct loop_device)); - if (max_loop) { - printk(KERN_INFO "loop: the max_loop option is obsolete " - "and will be removed in March 2008\n"); + disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL); + if (!disks) + goto out_mem2; + for (i = 0; i < max_loop; i++) { + disks[i] = alloc_disk(1); + if (!disks[i]) + goto out_mem3; } - printk(KERN_INFO "loop: module loaded\n"); + + for (i = 0; i < max_loop; i++) { + struct loop_device *lo = &loop_dev[i]; + struct gendisk *disk = disks[i]; + + memset(lo, 0, sizeof(*lo)); + lo->lo_queue = blk_alloc_queue(GFP_KERNEL); + if (!lo->lo_queue) + goto out_mem4; + mutex_init(&lo->lo_ctl_mutex); + lo->lo_number = i; + lo->lo_thread = NULL; + init_waitqueue_head(&lo->lo_event); + spin_lock_init(&lo->lo_lock); + disk->major = LOOP_MAJOR; + disk->first_minor = i; + disk->fops = &lo_fops; + sprintf(disk->disk_name, "loop%d", i); + disk->private_data = lo; + disk->queue = lo->lo_queue; + } + + /* We cannot fail after we call this, so another loop!*/ + for (i = 0; i < max_loop; i++) + add_disk(disks[i]); + printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop); return 0; -out: +out_mem4: + while (i--) + blk_cleanup_queue(loop_dev[i].lo_queue); + i = max_loop; +out_mem3: + while (i--) + put_disk(disks[i]); + kfree(disks); +out_mem2: + kfree(loop_dev); +out_mem1: unregister_blkdev(LOOP_MAJOR, "loop"); printk(KERN_ERR "loop: ran out of memory\n"); return -ENOMEM; } -static void __exit loop_exit(void) +static void loop_exit(void) { - struct loop_device *lo, *next; - - list_for_each_entry_safe(lo, next, &loop_devices, lo_list) - loop_del_one(lo); + int i; - blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS); + for (i = 0; i < max_loop; i++) { + del_gendisk(disks[i]); + blk_cleanup_queue(loop_dev[i].lo_queue); + put_disk(disks[i]); + } if (unregister_blkdev(LOOP_MAJOR, "loop")) printk(KERN_WARNING "loop: cannot unregister blkdev\n"); + + kfree(disks); + kfree(loop_dev); } module_init(loop_init); diff --git a/trunk/drivers/block/rd.c b/trunk/drivers/block/rd.c index 43d4ebcb3b44..485aa87e9bcd 100644 --- a/trunk/drivers/block/rd.c +++ b/trunk/drivers/block/rd.c @@ -403,7 +403,7 @@ static void __exit rd_cleanup(void) struct block_device *bdev = rd_bdev[i]; rd_bdev[i] = NULL; if (bdev) { - invalidate_bdev(bdev); + invalidate_bdev(bdev, 1); blkdev_put(bdev); } del_gendisk(rd_disks[i]); diff --git a/trunk/drivers/block/umem.c b/trunk/drivers/block/umem.c index 6f5d6203d725..5872036e8ae6 100644 --- a/trunk/drivers/block/umem.c +++ b/trunk/drivers/block/umem.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/bluetooth/hci_usb.c b/trunk/drivers/bluetooth/hci_usb.c index b0238b46dded..406af579ac3a 100644 --- a/trunk/drivers/bluetooth/hci_usb.c +++ b/trunk/drivers/bluetooth/hci_usb.c @@ -114,16 +114,10 @@ static struct usb_device_id blacklist_ids[] = { { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 }, - /* Broadcom BCM2045 */ - { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_WRONG_SCO_MTU }, - /* IBM/Lenovo ThinkPad with Broadcom chip */ { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_WRONG_SCO_MTU }, - /* Targus ACB10US */ - { USB_DEVICE(0x0a5c, 0x2100), .driver_info = HCI_RESET }, - /* ANYCOM Bluetooth USB-200 and USB-250 */ { USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET }, diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c index 3625a05bc3d3..b36f44d4d1bf 100644 --- a/trunk/drivers/cdrom/cdrom.c +++ b/trunk/drivers/cdrom/cdrom.c @@ -2384,7 +2384,7 @@ static int cdrom_ioctl_reset(struct cdrom_device_info *cdi, return -EACCES; if (!CDROM_CAN(CDC_RESET)) return -ENOSYS; - invalidate_bdev(bdev); + invalidate_bdev(bdev, 0); return cdi->ops->reset(cdi); } diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 1e32fb834eb8..d0c978fbc204 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -127,7 +127,7 @@ config ROCKETPORT config CYCLADES tristate "Cyclades async mux support" - depends on SERIAL_NONSTANDARD && (PCI || ISA) + depends on SERIAL_NONSTANDARD ---help--- This driver supports Cyclades Z and Y multiserial boards. You would need something like this to connect more than two modems to @@ -905,8 +905,8 @@ config SONYPI To compile this driver as a module, choose M here: the module will be called sonypi. -config GPIO_TB0219 - tristate "TANBAC TB0219 GPIO support" +config TANBAC_TB0219 + tristate "TANBAC TB0219 base board support" depends on TANBAC_TB022X select GPIO_VR41XX @@ -1071,11 +1071,5 @@ config TELCLOCK /sys/devices/platform/telco_clock, with a number of files for controlling the behavior of this hardware. -config DEVPORT - bool - depends on !M68K - depends on ISA || PCI - default y - endmenu diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 2f56ecc035aa..ae8567cc529c 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -91,7 +91,7 @@ obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o -obj-$(CONFIG_GPIO_TB0219) += tb0219.o +obj-$(CONFIG_TANBAC_TB0219) += tb0219.o obj-$(CONFIG_TELCLOCK) += tlclk.o obj-$(CONFIG_WATCHDOG) += watchdog/ diff --git a/trunk/drivers/char/agp/ali-agp.c b/trunk/drivers/char/agp/ali-agp.c index 4941ddb78939..5b684fddcc03 100644 --- a/trunk/drivers/char/agp/ali-agp.c +++ b/trunk/drivers/char/agp/ali-agp.c @@ -145,7 +145,6 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) void *addr = agp_generic_alloc_page(agp_bridge); u32 temp; - global_flush_tlb(); if (!addr) return NULL; @@ -161,7 +160,6 @@ static void ali_destroy_page(void * addr) if (addr) { global_cache_flush(); /* is this really needed? --hch */ agp_generic_destroy_page(addr); - global_flush_tlb(); } } diff --git a/trunk/drivers/char/agp/alpha-agp.c b/trunk/drivers/char/agp/alpha-agp.c index aa8f3a39a704..b0acf41c0db9 100644 --- a/trunk/drivers/char/agp/alpha-agp.c +++ b/trunk/drivers/char/agp/alpha-agp.c @@ -173,7 +173,7 @@ alpha_core_agp_setup(void) /* * Build a fake pci_dev struct */ - pdev = alloc_pci_dev(); + pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!pdev) return -ENOMEM; pdev->vendor = 0xffff; diff --git a/trunk/drivers/char/agp/amd64-agp.c b/trunk/drivers/char/agp/amd64-agp.c index c9f0f250d78f..485720486d60 100644 --- a/trunk/drivers/char/agp/amd64-agp.c +++ b/trunk/drivers/char/agp/amd64-agp.c @@ -14,7 +14,6 @@ #include #include #include /* PAGE_SIZE */ -#include #include #include "agp.h" @@ -260,6 +259,7 @@ static const struct agp_bridge_driver amd_8151_driver = { /* Some basic sanity checks for the aperture. */ static int __devinit aperture_valid(u64 aper, u32 size) { + u32 pfn, c; if (aper == 0) { printk(KERN_ERR PFX "No aperture\n"); return 0; @@ -272,9 +272,14 @@ static int __devinit aperture_valid(u64 aper, u32 size) printk(KERN_ERR PFX "Aperture out of bounds\n"); return 0; } - if (e820_any_mapped(aper, aper + size, E820_RAM)) { - printk(KERN_ERR PFX "Aperture pointing to RAM\n"); - return 0; + pfn = aper >> PAGE_SHIFT; + for (c = 0; c < size/PAGE_SIZE; c++) { + if (!pfn_valid(pfn + c)) + break; + if (!PageReserved(pfn_to_page(pfn + c))) { + printk(KERN_ERR PFX "Aperture pointing to RAM\n"); + return 0; + } } /* Request the Aperture. This catches cases when someone else diff --git a/trunk/drivers/char/agp/generic.c b/trunk/drivers/char/agp/generic.c index 45aeb917ec63..f902d71947ba 100644 --- a/trunk/drivers/char/agp/generic.c +++ b/trunk/drivers/char/agp/generic.c @@ -51,6 +51,28 @@ int agp_memory_reserved; */ EXPORT_SYMBOL_GPL(agp_memory_reserved); +#if defined(CONFIG_X86) +int map_page_into_agp(struct page *page) +{ + int i; + i = change_page_attr(page, 1, PAGE_KERNEL_NOCACHE); + /* Caller's responsibility to call global_flush_tlb() for + * performance reasons */ + return i; +} +EXPORT_SYMBOL_GPL(map_page_into_agp); + +int unmap_page_from_agp(struct page *page) +{ + int i; + i = change_page_attr(page, 1, PAGE_KERNEL); + /* Caller's responsibility to call global_flush_tlb() for + * performance reasons */ + return i; +} +EXPORT_SYMBOL_GPL(unmap_page_from_agp); +#endif + /* * Generic routines for handling agp_memory structures - * They use the basic page allocation routines to do the brunt of the work. diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c index 9c69f2e761f5..55392a45a14b 100644 --- a/trunk/drivers/char/agp/intel-agp.c +++ b/trunk/drivers/char/agp/intel-agp.c @@ -186,9 +186,8 @@ static void *i8xx_alloc_pages(void) return NULL; if (change_page_attr(page, 4, PAGE_KERNEL_NOCACHE) < 0) { - change_page_attr(page, 4, PAGE_KERNEL); global_flush_tlb(); - __free_pages(page, 2); + __free_page(page); return NULL; } global_flush_tlb(); @@ -210,7 +209,7 @@ static void i8xx_destroy_pages(void *addr) global_flush_tlb(); put_page(page); unlock_page(page); - __free_pages(page, 2); + free_pages((unsigned long)addr, 2); atomic_dec(&agp_bridge->current_memory_agp); } @@ -316,6 +315,9 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) struct agp_memory *new; void *addr; + if (pg_count != 1 && pg_count != 4) + return NULL; + switch (pg_count) { case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); global_flush_tlb(); diff --git a/trunk/drivers/char/agp/nvidia-agp.c b/trunk/drivers/char/agp/nvidia-agp.c index 6cd7373dcdf4..0c9dab557c94 100644 --- a/trunk/drivers/char/agp/nvidia-agp.c +++ b/trunk/drivers/char/agp/nvidia-agp.c @@ -320,11 +320,11 @@ static int __devinit agp_nvidia_probe(struct pci_dev *pdev, u8 cap_ptr; nvidia_private.dev_1 = - pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); + pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1)); nvidia_private.dev_2 = - pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2)); + pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2)); nvidia_private.dev_3 = - pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0)); + pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0)); if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) { printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 " @@ -443,9 +443,6 @@ static int __init agp_nvidia_init(void) static void __exit agp_nvidia_cleanup(void) { pci_unregister_driver(&agp_nvidia_pci_driver); - pci_dev_put(nvidia_private.dev_1); - pci_dev_put(nvidia_private.dev_2); - pci_dev_put(nvidia_private.dev_3); } module_init(agp_nvidia_init); diff --git a/trunk/drivers/char/agp/parisc-agp.c b/trunk/drivers/char/agp/parisc-agp.c index f4562cc22343..3d83b461ccad 100644 --- a/trunk/drivers/char/agp/parisc-agp.c +++ b/trunk/drivers/char/agp/parisc-agp.c @@ -329,7 +329,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa) struct agp_bridge_data *bridge; int error = 0; - fake_bridge_dev = alloc_pci_dev(); + fake_bridge_dev = kmalloc(sizeof (struct pci_dev), GFP_KERNEL); if (!fake_bridge_dev) { error = -ENOMEM; goto fail; diff --git a/trunk/drivers/char/agp/sgi-agp.c b/trunk/drivers/char/agp/sgi-agp.c index cda608c42bea..ee8f50edde1b 100644 --- a/trunk/drivers/char/agp/sgi-agp.c +++ b/trunk/drivers/char/agp/sgi-agp.c @@ -47,8 +47,9 @@ static void *sgi_tioca_alloc_page(struct agp_bridge_data *bridge) nid = info->ca_closest_node; page = alloc_pages_node(nid, GFP_KERNEL, 0); - if (!page) - return NULL; + if (page == NULL) { + return 0; + } get_page(page); SetPageLocked(page); diff --git a/trunk/drivers/char/agp/sis-agp.c b/trunk/drivers/char/agp/sis-agp.c index eb1a1c738190..125f4282d955 100644 --- a/trunk/drivers/char/agp/sis-agp.c +++ b/trunk/drivers/char/agp/sis-agp.c @@ -143,6 +143,96 @@ static struct agp_bridge_driver sis_driver = { .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; +static struct agp_device_ids sis_agp_device_ids[] __devinitdata = +{ + { + .device_id = PCI_DEVICE_ID_SI_5591_AGP, + .chipset_name = "5591", + }, + { + .device_id = PCI_DEVICE_ID_SI_530, + .chipset_name = "530", + }, + { + .device_id = PCI_DEVICE_ID_SI_540, + .chipset_name = "540", + }, + { + .device_id = PCI_DEVICE_ID_SI_550, + .chipset_name = "550", + }, + { + .device_id = PCI_DEVICE_ID_SI_620, + .chipset_name = "620", + }, + { + .device_id = PCI_DEVICE_ID_SI_630, + .chipset_name = "630", + }, + { + .device_id = PCI_DEVICE_ID_SI_635, + .chipset_name = "635", + }, + { + .device_id = PCI_DEVICE_ID_SI_645, + .chipset_name = "645", + }, + { + .device_id = PCI_DEVICE_ID_SI_646, + .chipset_name = "646", + }, + { + .device_id = PCI_DEVICE_ID_SI_648, + .chipset_name = "648", + }, + { + .device_id = PCI_DEVICE_ID_SI_650, + .chipset_name = "650", + }, + { + .device_id = PCI_DEVICE_ID_SI_651, + .chipset_name = "651", + }, + { + .device_id = PCI_DEVICE_ID_SI_655, + .chipset_name = "655", + }, + { + .device_id = PCI_DEVICE_ID_SI_661, + .chipset_name = "661", + }, + { + .device_id = PCI_DEVICE_ID_SI_730, + .chipset_name = "730", + }, + { + .device_id = PCI_DEVICE_ID_SI_735, + .chipset_name = "735", + }, + { + .device_id = PCI_DEVICE_ID_SI_740, + .chipset_name = "740", + }, + { + .device_id = PCI_DEVICE_ID_SI_741, + .chipset_name = "741", + }, + { + .device_id = PCI_DEVICE_ID_SI_745, + .chipset_name = "745", + }, + { + .device_id = PCI_DEVICE_ID_SI_746, + .chipset_name = "746", + }, + { + .device_id = PCI_DEVICE_ID_SI_760, + .chipset_name = "760", + }, + { }, /* dummy final entry, always present */ +}; + + // chipsets that require the 'delay hack' static int sis_broken_chipsets[] __devinitdata = { PCI_DEVICE_ID_SI_648, @@ -179,15 +269,29 @@ static void __devinit sis_get_driver(struct agp_bridge_data *bridge) static int __devinit agp_sis_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + struct agp_device_ids *devs = sis_agp_device_ids; struct agp_bridge_data *bridge; u8 cap_ptr; + int j; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); if (!cap_ptr) return -ENODEV; + /* probe for known chipsets */ + for (j = 0; devs[j].chipset_name; j++) { + if (pdev->device == devs[j].device_id) { + printk(KERN_INFO PFX "Detected SiS %s chipset\n", + devs[j].chipset_name); + goto found; + } + } + + printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x)\n", + pdev->device); + return -ENODEV; - printk(KERN_INFO PFX "Detected SiS chipset - id:%i\n", pdev->device); +found: bridge = agp_alloc_bridge(); if (!bridge) return -ENOMEM; @@ -216,172 +320,12 @@ static void __devexit agp_sis_remove(struct pci_dev *pdev) static struct pci_device_id agp_sis_pci_table[] = { { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_5591_AGP, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_530, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_540, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_550, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_620, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_630, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_635, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_645, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_646, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_648, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_650, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_651, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_655, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_661, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_730, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_735, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_740, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_741, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_745, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_746, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_760, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_ANY_ID, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { } }; diff --git a/trunk/drivers/char/agp/sworks-agp.c b/trunk/drivers/char/agp/sworks-agp.c index 551ef25063ef..55212a3811fd 100644 --- a/trunk/drivers/char/agp/sworks-agp.c +++ b/trunk/drivers/char/agp/sworks-agp.c @@ -455,6 +455,15 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, u32 temp, temp2; u8 cap_ptr = 0; + /* Everything is on func 1 here so we are hardcoding function one */ + bridge_dev = pci_find_slot((unsigned int)pdev->bus->number, + PCI_DEVFN(0, 1)); + if (!bridge_dev) { + printk(KERN_INFO PFX "Detected a Serverworks chipset " + "but could not find the secondary device.\n"); + return -ENODEV; + } + cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); switch (pdev->device) { @@ -474,15 +483,6 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, return -ENODEV; } - /* Everything is on func 1 here so we are hardcoding function one */ - bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number, - PCI_DEVFN(0, 1)); - if (!bridge_dev) { - printk(KERN_INFO PFX "Detected a Serverworks chipset " - "but could not find the secondary device.\n"); - return -ENODEV; - } - serverworks_private.svrwrks_dev = bridge_dev; serverworks_private.gart_addr_ofs = 0x10; @@ -515,7 +515,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, bridge->driver = &sworks_driver; bridge->dev_private_data = &serverworks_private, - bridge->dev = pci_dev_get(pdev); + bridge->dev = pdev; pci_set_drvdata(pdev, bridge); return agp_add_bridge(bridge); @@ -525,11 +525,8 @@ static void __devexit agp_serverworks_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - pci_dev_put(bridge->dev); agp_remove_bridge(bridge); agp_put_bridge(bridge); - pci_dev_put(serverworks_private.svrwrks_dev); - serverworks_private.svrwrks_dev = NULL; } static struct pci_device_id agp_serverworks_pci_table[] = { diff --git a/trunk/drivers/char/agp/uninorth-agp.c b/trunk/drivers/char/agp/uninorth-agp.c index 42c0a600b1ac..91b062126a68 100644 --- a/trunk/drivers/char/agp/uninorth-agp.c +++ b/trunk/drivers/char/agp/uninorth-agp.c @@ -613,7 +613,7 @@ static int __devinit agp_uninorth_probe(struct pci_dev *pdev, uninorth_node = of_find_node_by_name(NULL, "u3"); } if (uninorth_node) { - const int *revprop = of_get_property(uninorth_node, + const int *revprop = get_property(uninorth_node, "device-rev", NULL); if (revprop != NULL) uninorth_rev = *revprop & 0x3f; diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index 4eaceabd8cea..0e2b72f2b887 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -1574,7 +1574,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) if (timeout && time_after(jiffies, orig_jiffies + timeout)) break; } - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); #endif @@ -1700,7 +1700,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, #endif schedule(); } - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&info->open_wait, &wait); if (extra_count) state->count++; diff --git a/trunk/drivers/char/briq_panel.c b/trunk/drivers/char/briq_panel.c index ed53f541d9e8..c70d52ace8b2 100644 --- a/trunk/drivers/char/briq_panel.c +++ b/trunk/drivers/char/briq_panel.c @@ -206,7 +206,7 @@ static int __init briq_panel_init(void) const char *machine; int i; - machine = of_get_property(root, "model", NULL); + machine = get_property(root, "model", NULL); if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) { of_node_put(root); return -ENODEV; diff --git a/trunk/drivers/char/consolemap.c b/trunk/drivers/char/consolemap.c index fd40b959afdd..b99b7561260d 100644 --- a/trunk/drivers/char/consolemap.c +++ b/trunk/drivers/char/consolemap.c @@ -626,10 +626,10 @@ conv_uni_to_pc(struct vc_data *conp, long ucs) /* Only 16-bit codes supported at this time */ if (ucs > 0xffff) - return -4; /* Not found */ - else if (ucs < 0x20) + ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */ + else if (ucs < 0x20 || ucs >= 0xfffe) return -1; /* Not a printable character */ - else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f)) + else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f)) return -2; /* Zero-width space */ /* * UNI_DIRECT_BASE indicates the start of the region in the User Zone diff --git a/trunk/drivers/char/cs5535_gpio.c b/trunk/drivers/char/cs5535_gpio.c index fe6d2407baed..c02d9e99e050 100644 --- a/trunk/drivers/char/cs5535_gpio.c +++ b/trunk/drivers/char/cs5535_gpio.c @@ -44,7 +44,6 @@ static struct pci_device_id divil_pci[] = { { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, { } /* NULL entry */ }; -MODULE_DEVICE_TABLE(pci, divil_pci); static struct cdev cs5535_gpio_cdev; diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index c72ee97d3892..16dc5d1d3cb4 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -10,14 +10,15 @@ * * Initially written by Randolph Bentson . * Modified and maintained by Marcio Saito . + * Currently maintained by Cyclades team . * - * Copyright (C) 2007 Jiri Slaby + * For Technical support and installation problems, please send e-mail + * to support@cyclades.com. * * Much of the design and some of the code came from serial.c * which was copyright (C) 1991, 1992 Linus Torvalds. It was * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, * and then fixed as suggested by Michael K. Johnson 12/12/92. - * Converted to pci probing and cleaned up by Jiri Slaby. * * This version supports shared IRQ's (only for PCI boards). * @@ -590,7 +591,7 @@ * */ -#define CY_VERSION "2.5" +#define CY_VERSION "2.4" /* If you need to install more boards than NR_CARDS, change the constant in the definition below. No other change is necessary to support up to @@ -623,6 +624,12 @@ #undef CY_ENABLE_MONITORING #undef CY_PCI_DEBUG +#if 0 +#define PAUSE __asm__("nop") +#else +#define PAUSE do {} while (0) +#endif + /* * Include section */ @@ -652,6 +659,17 @@ #include #include +#define CY_LOCK(info,flags) \ + do { \ + spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \ + } while (0) + +#define CY_UNLOCK(info,flags) \ + do { \ + spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \ + } while (0) + +#include #include #include @@ -664,13 +682,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch); #define IS_CYC_Z(card) ((card).num_chips == -1) #define Z_FPGA_CHECK(card) \ - ((readl(&((struct RUNTIME_9060 __iomem *) \ + ((cy_readl(&((struct RUNTIME_9060 __iomem *) \ ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) -#define ISZLOADED(card) (((ZO_V1==readl(&((struct RUNTIME_9060 __iomem *) \ +#define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \ ((card).ctl_addr))->mail_box_0)) || \ Z_FPGA_CHECK(card)) && \ - (ZFIRM_ID==readl(&((struct FIRM_ID __iomem *) \ + (ZFIRM_ID==cy_readl(&((struct FIRM_ID __iomem *) \ ((card).base_addr+ID_ADDRESS))->signature))) #ifndef SERIAL_XMIT_SIZE @@ -707,8 +725,8 @@ static unsigned int cy_isa_addresses[] = { #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) #ifdef MODULE -static long maddr[NR_CARDS]; -static int irq[NR_CARDS]; +static long maddr[NR_CARDS] = { 0, }; +static int irq[NR_CARDS] = { 0, }; module_param_array(maddr, long, NULL, 0); module_param_array(irq, int, NULL, 0); @@ -721,6 +739,11 @@ module_param_array(irq, int, NULL, 0); */ static struct cyclades_card cy_card[NR_CARDS]; +/* This is the per-channel data structure containing pointers, flags + and variables for the port. This driver supports a maximum of NR_PORTS. +*/ +static struct cyclades_port cy_port[NR_PORTS]; + static int cy_next_channel; /* next minor available */ /* @@ -802,6 +825,9 @@ static int cy_chip_offset[] = { 0x0000, /* PCI related definitions */ +static unsigned short cy_pci_nboard; +static unsigned short cy_isa_nboard; +static unsigned short cy_nboard; #ifdef CONFIG_PCI static struct pci_device_id cy_pci_dev_id[] __devinitdata = { { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */ @@ -819,7 +845,7 @@ MODULE_DEVICE_TABLE(pci, cy_pci_dev_id); static void cy_start(struct tty_struct *); static void set_line_char(struct cyclades_port *); -static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32); +static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong); #ifdef CONFIG_ISA static unsigned detect_isa_irq(void __iomem *); #endif /* CONFIG_ISA */ @@ -832,6 +858,7 @@ static void cyz_poll(unsigned long); /* The Cyclades-Z polling cycle is defined by this variable */ static long cyz_polling_cycle = CZ_DEF_POLL; +static int cyz_timeron = 0; static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); #else /* CONFIG_CYZ_INTR */ @@ -844,14 +871,21 @@ static inline int serial_paranoia_check(struct cyclades_port *info, { #ifdef SERIAL_PARANOIA_CHECK if (!info) { - printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) " - "in %s\n", name, routine); + printk("cyc Warning: null cyclades_port for (%s) in %s\n", + name, routine); + return 1; + } + + if ((long)info < (long)(&cy_port[0]) || + (long)(&cy_port[NR_PORTS]) < (long)info) { + printk("cyc Warning: cyclades_port out of range for (%s) in " + "%s\n", name, routine); return 1; } if (info->magic != CYCLADES_MAGIC) { - printk(KERN_WARNING "cyc Warning: bad magic number for serial " - "struct (%s) in %s\n", name, routine); + printk("cyc Warning: bad magic number for serial struct (%s) " + "in %s\n", name, routine); return 1; } #endif @@ -909,16 +943,22 @@ do_softint(struct work_struct *work) if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) wake_up_interruptible(&info->open_wait); #ifdef CONFIG_CYZ_INTR - if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) && - !timer_pending(&cyz_rx_full_timer[info->line])) - mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1); + if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) { + if (cyz_rx_full_timer[info->line].function == NULL) { + cyz_rx_full_timer[info->line].expires = jiffies + 1; + cyz_rx_full_timer[info->line].function = cyz_rx_restart; + cyz_rx_full_timer[info->line].data = + (unsigned long)info; + add_timer(&cyz_rx_full_timer[info->line]); + } + } #endif if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) wake_up_interruptible(&info->delta_msr_wait); tty_wakeup(tty); #ifdef Z_WAKE if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) - complete(&info->shutdown_wait); + wake_up_interruptible(&info->shutdown_wait); #endif } /* do_softint */ @@ -935,11 +975,11 @@ do_softint(struct work_struct *work) */ static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) { - unsigned int i; + volatile int i; /* Check to see that the previous command has completed */ for (i = 0; i < 100; i++) { - if (readb(base_addr + (CyCCR << index)) == 0) { + if (cy_readb(base_addr + (CyCCR << index)) == 0) { break; } udelay(10L); @@ -982,7 +1022,7 @@ static unsigned detect_isa_irq(void __iomem * address) cy_writeb(address + (CyCAR << index), 0); cy_writeb(address + (CySRER << index), - readb(address + (CySRER << index)) | CyTxRdy); + cy_readb(address + (CySRER << index)) | CyTxRdy); local_irq_restore(flags); /* Wait ... */ @@ -992,11 +1032,11 @@ static unsigned detect_isa_irq(void __iomem * address) irq = probe_irq_off(irqs); /* Clean up */ - save_xir = (u_char) readb(address + (CyTIR << index)); - save_car = readb(address + (CyCAR << index)); + save_xir = (u_char) cy_readb(address + (CyTIR << index)); + save_car = cy_readb(address + (CyCAR << index)); cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); cy_writeb(address + (CySRER << index), - readb(address + (CySRER << index)) & ~CyTxRdy); + cy_readb(address + (CySRER << index)) & ~CyTxRdy); cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); cy_writeb(address + (CyCAR << index), (save_car)); cy_writeb(address + (Cy_ClrIntr << index), 0); @@ -1011,43 +1051,45 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, { struct cyclades_port *info; struct tty_struct *tty; - int char_count; - int j, len, mdm_change, mdm_status, outch; + volatile int char_count; + int i, j, len, mdm_change, mdm_status, outch; int save_xir, channel, save_car; char data; if (status & CySRReceive) { /* reception interrupt */ #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); + printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip); #endif /* determine the channel & change to that context */ spin_lock(&cinfo->card_lock); - save_xir = (u_char) readb(base_addr + (CyRIR << index)); + save_xir = (u_char) cy_readb(base_addr + (CyRIR << index)); channel = (u_short) (save_xir & CyIRChannel); - info = &cinfo->ports[channel + chip * 4]; - save_car = readb(base_addr + (CyCAR << index)); + i = channel + chip * 4 + cinfo->first_line; + info = &cy_port[i]; + info->last_active = jiffies; + save_car = cy_readb(base_addr + (CyCAR << index)); cy_writeb(base_addr + (CyCAR << index), save_xir); /* if there is nowhere to put the data, discard it */ - if (info->tty == NULL) { - j = (readb(base_addr + (CyRIVR << index)) & + if (info->tty == 0) { + j = (cy_readb(base_addr + (CyRIVR << index)) & CyIVRMask); if (j == CyIVRRxEx) { /* exception */ - data = readb(base_addr + (CyRDSR << index)); + data = cy_readb(base_addr + (CyRDSR << index)); } else { /* normal character reception */ - char_count = readb(base_addr + + char_count = cy_readb(base_addr + (CyRDCR << index)); while (char_count--) { - data = readb(base_addr + + data = cy_readb(base_addr + (CyRDSR << index)); } } } else { /* there is an open port for this data */ tty = info->tty; - j = (readb(base_addr + (CyRIVR << index)) & + j = (cy_readb(base_addr + (CyRIVR << index)) & CyIVRMask); if (j == CyIVRRxEx) { /* exception */ - data = readb(base_addr + (CyRDSR << index)); + data = cy_readb(base_addr + (CyRDSR << index)); /* For statistics only */ if (data & CyBREAK) @@ -1068,7 +1110,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, if (data & CyBREAK) { tty_insert_flip_char( tty, - readb( + cy_readb( base_addr + (CyRDSR << index)), @@ -1081,7 +1123,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, } else if (data & CyFRAME) { tty_insert_flip_char( tty, - readb( + cy_readb( base_addr + (CyRDSR << index)), @@ -1093,7 +1135,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, /* Pieces of seven... */ tty_insert_flip_char( tty, - readb( + cy_readb( base_addr + (CyRDSR << index)), @@ -1112,7 +1154,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, */ tty_insert_flip_char( tty, - readb( + cy_readb( base_addr + (CyRDSR << index)), @@ -1144,7 +1186,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, } } else { /* normal character reception */ /* load # chars available from the chip */ - char_count = readb(base_addr + + char_count = cy_readb(base_addr + (CyRDCR << index)); #ifdef CY_ENABLE_MONITORING @@ -1156,7 +1198,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, #endif len = tty_buffer_request_room(tty, char_count); while (len--) { - data = readb(base_addr + + data = cy_readb(base_addr + (CyRDSR << index)); tty_insert_flip_char(tty, data, TTY_NORMAL); @@ -1181,27 +1223,29 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, is empty, we know we can always stuff a dozen characters. */ #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); + printk("cyy_interrupt: xmit intr, chip %d\n\r", chip); #endif /* determine the channel & change to that context */ spin_lock(&cinfo->card_lock); - save_xir = (u_char) readb(base_addr + (CyTIR << index)); + save_xir = (u_char) cy_readb(base_addr + (CyTIR << index)); channel = (u_short) (save_xir & CyIRChannel); - save_car = readb(base_addr + (CyCAR << index)); + i = channel + chip * 4 + cinfo->first_line; + save_car = cy_readb(base_addr + (CyCAR << index)); cy_writeb(base_addr + (CyCAR << index), save_xir); /* validate the port# (as configured and open) */ - if (channel + chip * 4 >= cinfo->nports) { + if ((i < 0) || (NR_PORTS <= i)) { cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & + cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy); goto txend; } - info = &cinfo->ports[channel + chip * 4]; - if (info->tty == NULL) { + info = &cy_port[i]; + info->last_active = jiffies; + if (info->tty == 0) { cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & + cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy); goto txdone; } @@ -1234,29 +1278,29 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, while (char_count-- > 0) { if (!info->xmit_cnt) { - if (readb(base_addr + (CySRER << index)) & + if (cy_readb(base_addr + (CySRER << index)) & CyTxMpty) { cy_writeb(base_addr + (CySRER << index), - readb(base_addr + + cy_readb(base_addr + (CySRER << index)) & ~CyTxMpty); } else { cy_writeb(base_addr + (CySRER << index), - (readb(base_addr + + (cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy) | CyTxMpty); } goto txdone; } - if (info->xmit_buf == NULL) { + if (info->xmit_buf == 0) { cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & + cy_readb(base_addr + (CySRER << index))& ~CyTxRdy); goto txdone; } if (info->tty->stopped || info->tty->hw_stopped) { cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & + cy_readb(base_addr + (CySRER << index))& ~CyTxRdy); goto txdone; } @@ -1289,6 +1333,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, 0); info->icount.tx++; char_count--; + } else { } } } @@ -1308,16 +1353,19 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, /* determine the channel & change to that context */ spin_lock(&cinfo->card_lock); - save_xir = (u_char) readb(base_addr + (CyMIR << index)); + save_xir = (u_char) cy_readb(base_addr + (CyMIR << index)); channel = (u_short) (save_xir & CyIRChannel); - info = &cinfo->ports[channel + chip * 4]; - save_car = readb(base_addr + (CyCAR << index)); + info = &cy_port[channel + chip * 4 + cinfo->first_line]; + info->last_active = jiffies; + save_car = cy_readb(base_addr + (CyCAR << index)); cy_writeb(base_addr + (CyCAR << index), save_xir); - mdm_change = readb(base_addr + (CyMISR << index)); - mdm_status = readb(base_addr + (CyMSVR1 << index)); + mdm_change = cy_readb(base_addr + (CyMISR << index)); + mdm_status = cy_readb(base_addr + (CyMSVR1 << index)); - if (info->tty) { + if (info->tty == 0) { /* no place for data, ignore it */ + ; + } else { if (mdm_change & CyANY_DELTA) { /* For statistics only */ if (mdm_change & CyDCD) @@ -1350,7 +1398,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, info->tty->hw_stopped = 0; cy_writeb(base_addr + (CySRER << index), - readb(base_addr + + cy_readb(base_addr + (CySRER << index))| CyTxRdy); @@ -1364,17 +1412,17 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, info->tty->hw_stopped = 1; cy_writeb(base_addr + (CySRER << index), - readb(base_addr + + cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy); } } } -/* if (mdm_change & CyDSR) { + if (mdm_change & CyDSR) { } if (mdm_change & CyRI) { - }*/ + } } /* end of service */ cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); @@ -1390,16 +1438,16 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, static irqreturn_t cyy_interrupt(int irq, void *dev_id) { int status; - struct cyclades_card *cinfo = dev_id; + struct cyclades_card *cinfo; void __iomem *base_addr, *card_base_addr; int chip; int index; int too_many; int had_work; - if (unlikely(cinfo == NULL)) { + if ((cinfo = (struct cyclades_card *)dev_id) == 0) { #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",irq); + printk("cyy_interrupt: spurious interrupt %d\n\r", irq); #endif return IRQ_NONE; /* spurious interrupt */ } @@ -1407,10 +1455,6 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) card_base_addr = cinfo->base_addr; index = cinfo->bus_index; - /* card was not initialized yet (e.g. DEBUG_SHIRQ) */ - if (unlikely(card_base_addr == NULL)) - return IRQ_HANDLED; - /* This loop checks all chips in the card. Make a note whenever _any_ chip had some work to do, as this is considered an indication that there will be more to do. Only when no chip @@ -1422,7 +1466,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); too_many = 0; - while ((status = readb(base_addr + + while ((status = cy_readb(base_addr + (CySVRR << index))) != 0x00) { had_work++; /* The purpose of the following test is to ensure that @@ -1454,7 +1498,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) static int cyz_fetch_msg(struct cyclades_card *cinfo, - __u32 * channel, __u8 * cmd, __u32 * param) + uclong * channel, ucchar * cmd, uclong * param) { struct FIRM_ID __iomem *firm_id; struct ZFW_CTRL __iomem *zfw_ctrl; @@ -1465,15 +1509,16 @@ cyz_fetch_msg(struct cyclades_card *cinfo, if (!ISZLOADED(*cinfo)) { return -1; } - zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); + zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & + 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; - loc_doorbell = readl(&((struct RUNTIME_9060 __iomem *) + loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *) (cinfo->ctl_addr))->loc_doorbell); if (loc_doorbell) { *cmd = (char)(0xff & loc_doorbell); - *channel = readl(&board_ctrl->fwcmd_channel); - *param = (__u32) readl(&board_ctrl->fwcmd_param); + *channel = cy_readl(&board_ctrl->fwcmd_channel); + *param = (uclong) cy_readl(&board_ctrl->fwcmd_param); cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> loc_doorbell, 0xffffffff); return 1; @@ -1483,27 +1528,28 @@ cyz_fetch_msg(struct cyclades_card *cinfo, static int cyz_issue_cmd(struct cyclades_card *cinfo, - __u32 channel, __u8 cmd, __u32 param) + uclong channel, ucchar cmd, uclong param) { struct FIRM_ID __iomem *firm_id; struct ZFW_CTRL __iomem *zfw_ctrl; struct BOARD_CTRL __iomem *board_ctrl; - __u32 __iomem *pci_doorbell; + unsigned long __iomem *pci_doorbell; int index; firm_id = cinfo->base_addr + ID_ADDRESS; if (!ISZLOADED(*cinfo)) { return -1; } - zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); + zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & + 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; index = 0; pci_doorbell = &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; - while ((readl(pci_doorbell) & 0xff) != 0) { + while ((cy_readl(pci_doorbell) & 0xff) != 0) { if (index++ == 1000) { - return (int)(readl(pci_doorbell) & 0xff); + return (int)(cy_readl(pci_doorbell) & 0xff); } udelay(50L); } @@ -1515,30 +1561,34 @@ cyz_issue_cmd(struct cyclades_card *cinfo, } /* cyz_issue_cmd */ static void -cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, - struct BUF_CTRL __iomem *buf_ctrl) +cyz_handle_rx(struct cyclades_port *info, + volatile struct CH_CTRL __iomem * ch_ctrl, + volatile struct BUF_CTRL __iomem * buf_ctrl) { - struct cyclades_card *cinfo = info->card; + struct cyclades_card *cinfo = &cy_card[info->card]; struct tty_struct *tty = info->tty; - int char_count; + volatile int char_count; int len; #ifdef BLOCKMOVE - unsigned char *buf; + int small_count; #else char data; #endif - __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; + volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; - rx_get = new_rx_get = readl(&buf_ctrl->rx_get); - rx_put = readl(&buf_ctrl->rx_put); - rx_bufsize = readl(&buf_ctrl->rx_bufsize); - rx_bufaddr = readl(&buf_ctrl->rx_bufaddr); + rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get); + rx_put = cy_readl(&buf_ctrl->rx_put); + rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize); + rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr); if (rx_put >= rx_get) char_count = rx_put - rx_get; else char_count = rx_put - rx_get + rx_bufsize; if (char_count) { + info->last_active = jiffies; + info->jiffies[1] = jiffies; + #ifdef CY_ENABLE_MONITORING info->mon.int_count++; info->mon.char_count += char_count; @@ -1546,7 +1596,7 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, info->mon.char_max = char_count; info->mon.char_last = char_count; #endif - if (tty == NULL) { + if (tty == 0) { /* flush received characters */ new_rx_get = (new_rx_get + char_count) & (rx_bufsize - 1); @@ -1556,28 +1606,30 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, /* we'd like to use memcpy(t, f, n) and memset(s, c, count) for performance, but because of buffer boundaries, there may be several steps to the operation */ - while (1) { - len = tty_prepare_flip_string(tty, &buf, - char_count); - if (!len) - break; - - len = min_t(unsigned int, min(len, char_count), - rx_bufsize - new_rx_get); - - memcpy_fromio(buf, cinfo->base_addr + - rx_bufaddr + new_rx_get, len); + while (0 < (small_count = min_t(unsigned int, + rx_bufsize - new_rx_get, + min_t(unsigned int, TTY_FLIPBUF_SIZE - + tty->flip.count, char_count)))){ + memcpy_fromio(tty->flip.char_buf_ptr, + (char *)(cinfo->base_addr + rx_bufaddr + + new_rx_get), + small_count); - new_rx_get = (new_rx_get + len) & + tty->flip.char_buf_ptr += small_count; + memset(tty->flip.flag_buf_ptr, TTY_NORMAL, + small_count); + tty->flip.flag_buf_ptr += small_count; + new_rx_get = (new_rx_get + small_count) & (rx_bufsize - 1); - char_count -= len; - info->icount.rx += len; - info->idle_stats.recv_bytes += len; + char_count -= small_count; + info->icount.rx += small_count; + info->idle_stats.recv_bytes += small_count; + tty->flip.count += small_count; } #else len = tty_buffer_request_room(tty, char_count); while (len--) { - data = readb(cinfo->base_addr + rx_bufaddr + + data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1); tty_insert_flip_char(tty, data, TTY_NORMAL); @@ -1588,12 +1640,13 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, #ifdef CONFIG_CYZ_INTR /* Recalculate the number of chars in the RX buffer and issue a cmd in case it's higher than the RX high water mark */ - rx_put = readl(&buf_ctrl->rx_put); + rx_put = cy_readl(&buf_ctrl->rx_put); if (rx_put >= rx_get) char_count = rx_put - rx_get; else char_count = rx_put - rx_get + rx_bufsize; - if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) { + if (char_count >= (int)cy_readl(&buf_ctrl-> + rx_threshold)) { cy_sched_event(info, Cy_EVENT_Z_RX_FULL); } #endif @@ -1606,25 +1659,26 @@ cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, } static void -cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, - struct BUF_CTRL __iomem *buf_ctrl) +cyz_handle_tx(struct cyclades_port *info, + volatile struct CH_CTRL __iomem * ch_ctrl, + volatile struct BUF_CTRL __iomem * buf_ctrl) { - struct cyclades_card *cinfo = info->card; + struct cyclades_card *cinfo = &cy_card[info->card]; struct tty_struct *tty = info->tty; char data; - int char_count; + volatile int char_count; #ifdef BLOCKMOVE int small_count; #endif - __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr; + volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr; if (info->xmit_cnt <= 0) /* Nothing to transmit */ return; - tx_get = readl(&buf_ctrl->tx_get); - tx_put = readl(&buf_ctrl->tx_put); - tx_bufsize = readl(&buf_ctrl->tx_bufsize); - tx_bufaddr = readl(&buf_ctrl->tx_bufaddr); + tx_get = cy_readl(&buf_ctrl->tx_get); + tx_put = cy_readl(&buf_ctrl->tx_put); + tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); + tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr); if (tx_put >= tx_get) char_count = tx_get - tx_put - 1 + tx_bufsize; else @@ -1632,8 +1686,9 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, if (char_count) { - if (tty == NULL) + if (tty == 0) { goto ztxdone; + } if (info->x_char) { /* send special char */ data = info->x_char; @@ -1643,6 +1698,8 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, info->x_char = 0; char_count--; info->icount.tx++; + info->last_active = jiffies; + info->jiffies[2] = jiffies; } #ifdef BLOCKMOVE while (0 < (small_count = min_t(unsigned int, @@ -1662,6 +1719,8 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, info->xmit_cnt -= small_count; info->xmit_tail = (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1); + info->last_active = jiffies; + info->jiffies[2] = jiffies; } #else while (info->xmit_cnt && char_count) { @@ -1674,6 +1733,8 @@ cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, tx_put = (tx_put + 1) & (tx_bufsize - 1); char_count--; info->icount.tx++; + info->last_active = jiffies; + info->jiffies[2] = jiffies; } #endif ztxdone: @@ -1689,32 +1750,33 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) { struct tty_struct *tty; struct cyclades_port *info; - static struct FIRM_ID __iomem *firm_id; - static struct ZFW_CTRL __iomem *zfw_ctrl; - static struct BOARD_CTRL __iomem *board_ctrl; - static struct CH_CTRL __iomem *ch_ctrl; - static struct BUF_CTRL __iomem *buf_ctrl; - __u32 channel; - __u8 cmd; - __u32 param; - __u32 hw_ver, fw_ver; + static volatile struct FIRM_ID __iomem *firm_id; + static volatile struct ZFW_CTRL __iomem *zfw_ctrl; + static volatile struct BOARD_CTRL __iomem *board_ctrl; + static volatile struct CH_CTRL __iomem *ch_ctrl; + static volatile struct BUF_CTRL __iomem *buf_ctrl; + uclong channel; + ucchar cmd; + uclong param; + uclong hw_ver, fw_ver; int special_count; int delta_count; firm_id = cinfo->base_addr + ID_ADDRESS; - zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); + zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & + 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; - fw_ver = readl(&board_ctrl->fw_version); - hw_ver = readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> + fw_ver = cy_readl(&board_ctrl->fw_version); + hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> mail_box_0); while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { special_count = 0; delta_count = 0; - info = &cinfo->ports[channel]; - if ((tty = info->tty) == NULL) + info = &cy_port[channel + cinfo->first_line]; + if ((tty = info->tty) == 0) { continue; - + } ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); @@ -1739,7 +1801,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) delta_count++; if (info->flags & ASYNC_CHECK_CD) { if ((fw_ver > 241 ? ((u_long) param) : - readl(&ch_ctrl->rs_status)) & + cy_readl(&ch_ctrl->rs_status)) & C_RS_DCD) { cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP); @@ -1771,8 +1833,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) case C_CM_INTBACK2: /* Reception Interrupt */ #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " - "port %ld\n", info->card, channel); + printk("cyz_interrupt: rcvd intr, card %d, " + "port %ld\n\r", info->card, channel); #endif cyz_handle_rx(info, ch_ctrl, buf_ctrl); break; @@ -1781,8 +1843,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) case C_CM_INTBACK: /* Transmission Interrupt */ #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " - "port %ld\n", info->card, channel); + printk("cyz_interrupt: xmit intr, card %d, " + "port %ld\n\r", info->card, channel); #endif cyz_handle_tx(info, ch_ctrl, buf_ctrl); break; @@ -1803,19 +1865,18 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) #ifdef CONFIG_CYZ_INTR static irqreturn_t cyz_interrupt(int irq, void *dev_id) { - struct cyclades_card *cinfo = dev_id; + struct cyclades_card *cinfo; - if (unlikely(cinfo == NULL)) { + if ((cinfo = (struct cyclades_card *)dev_id) == 0) { #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",irq); + printk("cyz_interrupt: spurious interrupt %d\n\r", irq); #endif return IRQ_NONE; /* spurious interrupt */ } - if (unlikely(!ISZLOADED(*cinfo))) { + if (!ISZLOADED(*cinfo)) { #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyz_interrupt: board not yet loaded " - "(IRQ%d).\n", irq); + printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq); #endif return IRQ_NONE; } @@ -1829,18 +1890,19 @@ static irqreturn_t cyz_interrupt(int irq, void *dev_id) static void cyz_rx_restart(unsigned long arg) { struct cyclades_port *info = (struct cyclades_port *)arg; - struct cyclades_card *card = info->card; int retval; - __u32 channel = info->line - card->first_line; + int card = info->card; + uclong channel = (info->line) - (cy_card[card].first_line); unsigned long flags; - spin_lock_irqsave(&card->card_lock, flags); - retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L); + CY_LOCK(info, flags); + retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L); if (retval != 0) { - printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n", + printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", info->line, retval); } - spin_unlock_irqrestore(&card->card_lock, flags); + cyz_rx_full_timer[info->line].function = NULL; + CY_UNLOCK(info, flags); } #else /* CONFIG_CYZ_INTR */ @@ -1850,14 +1912,14 @@ static void cyz_poll(unsigned long arg) struct cyclades_card *cinfo; struct cyclades_port *info; struct tty_struct *tty; - static struct FIRM_ID *firm_id; - static struct ZFW_CTRL *zfw_ctrl; - static struct BOARD_CTRL *board_ctrl; - static struct CH_CTRL *ch_ctrl; - static struct BUF_CTRL *buf_ctrl; - unsigned long expires = jiffies + HZ; + static volatile struct FIRM_ID *firm_id; + static volatile struct ZFW_CTRL *zfw_ctrl; + static volatile struct BOARD_CTRL *board_ctrl; + static volatile struct CH_CTRL *ch_ctrl; + static volatile struct BUF_CTRL *buf_ctrl; int card, port; + cyz_timerlist.expires = jiffies + (HZ); for (card = 0; card < NR_CARDS; card++) { cinfo = &cy_card[card]; @@ -1868,12 +1930,12 @@ static void cyz_poll(unsigned long arg) firm_id = cinfo->base_addr + ID_ADDRESS; zfw_ctrl = cinfo->base_addr + - (readl(&firm_id->zfwctrl_addr) & 0xfffff); + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); board_ctrl = &(zfw_ctrl->board_ctrl); /* Skip first polling cycle to avoid racing conditions with the FW */ if (!cinfo->intr_enabled) { - cinfo->nports = (int)readl(&board_ctrl->n_channel); + cinfo->nports = (int)cy_readl(&board_ctrl->n_channel); cinfo->intr_enabled = 1; continue; } @@ -1881,7 +1943,7 @@ static void cyz_poll(unsigned long arg) cyz_handle_cmd(cinfo); for (port = 0; port < cinfo->nports; port++) { - info = &cinfo->ports[port]; + info = &cy_port[port + cinfo->first_line]; tty = info->tty; ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); @@ -1891,9 +1953,9 @@ static void cyz_poll(unsigned long arg) cyz_handle_tx(info, ch_ctrl, buf_ctrl); } /* poll every 'cyz_polling_cycle' period */ - expires = jiffies + cyz_polling_cycle; + cyz_timerlist.expires = jiffies + cyz_polling_cycle; } - mod_timer(&cyz_timerlist, expires); + add_timer(&cyz_timerlist); } /* cyz_poll */ #endif /* CONFIG_CYZ_INTR */ @@ -1906,21 +1968,20 @@ static void cyz_poll(unsigned long arg) */ static int startup(struct cyclades_port *info) { - struct cyclades_card *card; unsigned long flags; int retval = 0; void __iomem *base_addr; - int chip, channel, index; + int card, chip, channel, index; unsigned long page; card = info->card; - channel = info->line - card->first_line; + channel = (info->line) - (cy_card[card].first_line); page = get_zeroed_page(GFP_KERNEL); if (!page) return -ENOMEM; - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); if (info->flags & ASYNC_INITIALIZED) { free_page(page); @@ -1940,22 +2001,24 @@ static int startup(struct cyclades_port *info) else info->xmit_buf = (unsigned char *)page; - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); set_line_char(info); - if (!IS_CYC_Z(*card)) { + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = cy_card[card].base_addr + + (cy_chip_offset[chip] << index); #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, " - "base_addr %p\n", - card, chip, channel, base_addr); + printk("cyc startup card %d, chip %d, channel %d, " + "base_addr %lx\n", + card, chip, channel, (long)base_addr); + /**/ #endif - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); @@ -1971,14 +2034,14 @@ static int startup(struct cyclades_port *info) cy_writeb(base_addr + (CyMSVR2 << index), CyDTR); #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:startup raising DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - readb(base_addr + (CyMSVR1 << index)), - readb(base_addr + (CyMSVR2 << index))); + printk("cyc:startup raising DTR\n"); + printk(" status: 0x%x, 0x%x\n", + cy_readb(base_addr + (CyMSVR1 << index)), + cy_readb(base_addr + (CyMSVR2 << index))); #endif cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) | CyRxData); + cy_readb(base_addr + (CySRER << index)) | CyRxData); info->flags |= ASYNC_INITIALIZED; if (info->tty) { @@ -1991,7 +2054,7 @@ static int startup(struct cyclades_port *info) info->idle_stats.recv_idle = info->idle_stats.xmit_idle = jiffies; - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } else { struct FIRM_ID __iomem *firm_id; @@ -2000,23 +2063,24 @@ static int startup(struct cyclades_port *info) struct CH_CTRL __iomem *ch_ctrl; int retval; - base_addr = card->base_addr; + base_addr = cy_card[card].base_addr; firm_id = base_addr + ID_ADDRESS; - if (!ISZLOADED(*card)) { + if (!ISZLOADED(cy_card[card])) { return -ENODEV; } - zfw_ctrl = card->base_addr + - (readl(&firm_id->zfwctrl_addr) & 0xfffff); + zfw_ctrl = cy_card[card].base_addr + + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; ch_ctrl = zfw_ctrl->ch_ctrl; #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc startup Z card %d, channel %d, " - "base_addr %p\n", card, channel, base_addr); + printk("cyc startup Z card %d, channel %d, base_addr %lx\n", + card, channel, (long)base_addr); + /**/ #endif - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); #ifdef Z_WAKE @@ -2038,31 +2102,33 @@ static int startup(struct cyclades_port *info) #endif /* CONFIG_CYZ_INTR */ #endif /* Z_WAKE */ - retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); + retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); if (retval != 0) { - printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was " - "%x\n", info->line, retval); + printk("cyc:startup(1) retval on ttyC%d was %x\n", + info->line, retval); } /* Flush RX buffers before raising DTR and RTS */ - retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L); + retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, + 0L); if (retval != 0) { - printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was " - "%x\n", info->line, retval); + printk("cyc:startup(2) retval on ttyC%d was %x\n", + info->line, retval); } /* set timeout !!! */ /* set RTS and DTR !!! */ cy_writel(&ch_ctrl[channel].rs_control, - readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | + cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR); - retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); + retval = cyz_issue_cmd(&cy_card[info->card], channel, + C_CM_IOCTLM, 0L); if (retval != 0) { - printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was " - "%x\n", info->line, retval); + printk("cyc:startup(3) retval on ttyC%d was %x\n", + info->line, retval); } #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:startup raising Z DTR\n"); + printk("cyc:startup raising Z DTR\n"); #endif /* enable send, recv, modem !!! */ @@ -2078,50 +2144,51 @@ static int startup(struct cyclades_port *info) info->idle_stats.recv_idle = info->idle_stats.xmit_idle = jiffies; - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc startup done\n"); + printk(" cyc startup done\n"); #endif return 0; errout: - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); return retval; } /* startup */ static void start_xmit(struct cyclades_port *info) { - struct cyclades_card *card; unsigned long flags; void __iomem *base_addr; - int chip, channel, index; + int card, chip, channel, index; card = info->card; - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = (info->line) - (cy_card[card].first_line); + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = cy_card[card].base_addr + + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), channel); cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) | CyTxRdy); - spin_unlock_irqrestore(&card->card_lock, flags); + cy_readb(base_addr + (CySRER << index)) | CyTxRdy); + CY_UNLOCK(info, flags); } else { #ifdef CONFIG_CYZ_INTR int retval; - spin_lock_irqsave(&card->card_lock, flags); - retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L); + CY_LOCK(info, flags); + retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, + 0L); if (retval != 0) { - printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was " - "%x\n", info->line, retval); + printk("cyc:start_xmit retval on ttyC%d was %x\n", + info->line, retval); } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); #else /* CONFIG_CYZ_INTR */ /* Don't have to do anything at this time */ #endif /* CONFIG_CYZ_INTR */ @@ -2134,30 +2201,30 @@ static void start_xmit(struct cyclades_port *info) */ static void shutdown(struct cyclades_port *info) { - struct cyclades_card *card; unsigned long flags; void __iomem *base_addr; - int chip, channel, index; + int card, chip, channel, index; if (!(info->flags & ASYNC_INITIALIZED)) { return; } card = info->card; - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = info->line - cy_card[card].first_line; + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = cy_card[card].base_addr + + (cy_chip_offset[chip] << index); #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, " - "channel %d, base_addr %p\n", - card, chip, channel, base_addr); + printk("cyc shutdown Y card %d, chip %d, channel %d, " + "base_addr %lx\n", + card, chip, channel, (long)base_addr); #endif - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); /* Clear delta_msr_wait queue to avoid mem leaks. */ wake_up_interruptible(&info->delta_msr_wait); @@ -2173,10 +2240,10 @@ static void shutdown(struct cyclades_port *info) cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc shutdown dropping DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - readb(base_addr + (CyMSVR1 << index)), - readb(base_addr + (CyMSVR2 << index))); + printk("cyc shutdown dropping DTR\n"); + printk(" status: 0x%x, 0x%x\n", + cy_readb(base_addr + (CyMSVR1 << index)), + cy_readb(base_addr + (CyMSVR2 << index))); #endif } cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index); @@ -2187,7 +2254,7 @@ static void shutdown(struct cyclades_port *info) set_bit(TTY_IO_ERROR, &info->tty->flags); } info->flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } else { struct FIRM_ID __iomem *firm_id; struct ZFW_CTRL __iomem *zfw_ctrl; @@ -2195,23 +2262,23 @@ static void shutdown(struct cyclades_port *info) struct CH_CTRL __iomem *ch_ctrl; int retval; - base_addr = card->base_addr; + base_addr = cy_card[card].base_addr; #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " - "base_addr %p\n", card, channel, base_addr); + printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n", + card, channel, (long)base_addr); #endif firm_id = base_addr + ID_ADDRESS; - if (!ISZLOADED(*card)) { + if (!ISZLOADED(cy_card[card])) { return; } - zfw_ctrl = card->base_addr + - (readl(&firm_id->zfwctrl_addr) & 0xfffff); + zfw_ctrl = cy_card[card].base_addr + + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; ch_ctrl = zfw_ctrl->ch_ctrl; - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); if (info->xmit_buf) { unsigned char *temp; @@ -2222,16 +2289,16 @@ static void shutdown(struct cyclades_port *info) if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { cy_writel(&ch_ctrl[channel].rs_control, - (__u32)(readl(&ch_ctrl[channel].rs_control) & + (uclong)(cy_readl(&ch_ctrl[channel].rs_control)& ~(C_RS_RTS | C_RS_DTR))); - retval = cyz_issue_cmd(info->card, channel, + retval = cyz_issue_cmd(&cy_card[info->card], channel, C_CM_IOCTLM, 0L); if (retval != 0) { - printk(KERN_ERR"cyc:shutdown retval on ttyC%d " - "was %x\n", info->line, retval); + printk("cyc:shutdown retval on ttyC%d was %x\n", + info->line, retval); } #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:shutdown dropping Z DTR\n"); + printk("cyc:shutdown dropping Z DTR\n"); #endif } @@ -2240,11 +2307,11 @@ static void shutdown(struct cyclades_port *info) } info->flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc shutdown done\n"); + printk(" cyc shutdown done\n"); #endif } /* shutdown */ @@ -2265,7 +2332,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, int retval; void __iomem *base_addr; - cinfo = info->card; + cinfo = &cy_card[info->card]; channel = info->line - cinfo->first_line; /* @@ -2273,8 +2340,9 @@ block_til_ready(struct tty_struct *tty, struct file *filp, * until it's done, and then try again. */ if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { - wait_event_interruptible(info->close_wait, - !(info->flags & ASYNC_CLOSING)); + if (info->flags & ASYNC_CLOSING) { + interruptible_sleep_on(&info->close_wait); + } return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; } @@ -2297,16 +2365,17 @@ block_til_ready(struct tty_struct *tty, struct file *filp, retval = 0; add_wait_queue(&info->open_wait, &wait); #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, " - "count = %d\n", info->line, info->count); + printk("cyc block_til_ready before block: ttyC%d, count = %d\n", + info->line, info->count); + /**/ #endif - spin_lock_irqsave(&cinfo->card_lock, flags); + CY_LOCK(info, flags); if (!tty_hung_up_p(filp)) info->count--; - spin_unlock_irqrestore(&cinfo->card_lock, flags); + CY_UNLOCK(info, flags); #ifdef CY_DEBUG_COUNT - printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to " - "%d\n", current->pid, info->count); + printk("cyc block_til_ready: (%d): decrementing count to %d\n", + current->pid, info->count); #endif info->blocked_open++; @@ -2317,7 +2386,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); while (1) { - spin_lock_irqsave(&cinfo->card_lock, flags); + CY_LOCK(info, flags); if ((tty->termios->c_cflag & CBAUD)) { cy_writeb(base_addr + (CyCAR << index), (u_char) channel); @@ -2326,14 +2395,15 @@ block_til_ready(struct tty_struct *tty, struct file *filp, cy_writeb(base_addr + (CyMSVR2 << index), CyDTR); #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:block_til_ready raising " - "DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - readb(base_addr + (CyMSVR1 << index)), - readb(base_addr + (CyMSVR2 << index))); + printk("cyc:block_til_ready raising DTR\n"); + printk(" status: 0x%x, 0x%x\n", + cy_readb(base_addr + + (CyMSVR1 << index)), + cy_readb(base_addr + + (CyMSVR2 << index))); #endif } - spin_unlock_irqrestore(&cinfo->card_lock, flags); + CY_UNLOCK(info, flags); set_current_state(TASK_INTERRUPTIBLE); if (tty_hung_up_p(filp) || @@ -2343,25 +2413,26 @@ block_til_ready(struct tty_struct *tty, struct file *filp, break; } - spin_lock_irqsave(&cinfo->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || - (readb(base_addr + + (cy_readb(base_addr + (CyMSVR1 << index)) & CyDCD))) { - spin_unlock_irqrestore(&cinfo->card_lock, flags); + CY_UNLOCK(info, flags); break; } - spin_unlock_irqrestore(&cinfo->card_lock, flags); + CY_UNLOCK(info, flags); if (signal_pending(current)) { retval = -ERESTARTSYS; break; } #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc block_til_ready blocking: " - "ttyC%d, count = %d\n", - info->line, info->count); + printk("cyc block_til_ready blocking: ttyC%d, " + "count = %d\n", + info->line, info->count); + /**/ #endif schedule(); } @@ -2375,30 +2446,31 @@ block_til_ready(struct tty_struct *tty, struct file *filp, base_addr = cinfo->base_addr; firm_id = base_addr + ID_ADDRESS; if (!ISZLOADED(*cinfo)) { - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&info->open_wait, &wait); return -EINVAL; } - zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)& 0xfffff); + zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & + 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; ch_ctrl = zfw_ctrl->ch_ctrl; while (1) { if ((tty->termios->c_cflag & CBAUD)) { cy_writel(&ch_ctrl[channel].rs_control, - readl(&ch_ctrl[channel].rs_control) | - C_RS_RTS | C_RS_DTR); - retval = cyz_issue_cmd(cinfo, - channel, C_CM_IOCTLM, 0L); + cy_readl(&ch_ctrl[channel]. + rs_control) | (C_RS_RTS | + C_RS_DTR)); + retval = cyz_issue_cmd(&cy_card[info->card], + channel, C_CM_IOCTLM, 0L); if (retval != 0) { - printk(KERN_ERR "cyc:block_til_ready " - "retval on ttyC%d was %x\n", + printk("cyc:block_til_ready retval on " + "ttyC%d was %x\n", info->line, retval); } #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:block_til_ready raising " - "Z DTR\n"); + printk("cyc:block_til_ready raising Z DTR\n"); #endif } @@ -2410,7 +2482,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, break; } if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || - (readl(&ch_ctrl[channel].rs_status) & + (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) { break; } @@ -2419,26 +2491,28 @@ block_til_ready(struct tty_struct *tty, struct file *filp, break; } #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc block_til_ready blocking: " - "ttyC%d, count = %d\n", - info->line, info->count); + printk("cyc block_til_ready blocking: ttyC%d, " + "count = %d\n", + info->line, info->count); + /**/ #endif schedule(); } } - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&info->open_wait, &wait); if (!tty_hung_up_p(filp)) { info->count++; #ifdef CY_DEBUG_COUNT - printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing " - "count to %d\n", current->pid, info->count); + printk("cyc:block_til_ready (%d): incrementing count to %d\n", + current->pid, info->count); #endif } info->blocked_open--; #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, " - "count = %d\n", info->line, info->count); + printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n", + info->line, info->count); + /**/ #endif if (retval) return retval; @@ -2453,20 +2527,13 @@ block_til_ready(struct tty_struct *tty, struct file *filp, static int cy_open(struct tty_struct *tty, struct file *filp) { struct cyclades_port *info; - unsigned int i; int retval, line; line = tty->index; if ((line < 0) || (NR_PORTS <= line)) { return -ENODEV; } - for (i = 0; i < NR_CARDS; i++) - if (line < cy_card[i].first_line + cy_card[i].nports && - line >= cy_card[i].first_line) - break; - if (i >= NR_CARDS) - return -ENODEV; - info = &cy_card[i].ports[line - cy_card[i].first_line]; + info = &cy_port[line]; if (info->line < 0) { return -ENODEV; } @@ -2475,23 +2542,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp) treat it as absent from the system. This will make the user pay attention. */ - if (IS_CYC_Z(*info->card)) { - struct cyclades_card *cinfo = info->card; + if (IS_CYC_Z(cy_card[info->card])) { + struct cyclades_card *cinfo = &cy_card[info->card]; struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; if (!ISZLOADED(*cinfo)) { - if (((ZE_V1 == readl(&((struct RUNTIME_9060 __iomem *) + if (((ZE_V1 == cy_readl( + &((struct RUNTIME_9060 __iomem *) (cinfo->ctl_addr))->mail_box_0)) && Z_FPGA_CHECK(*cinfo)) && - (ZFIRM_HLT == readl( + (ZFIRM_HLT == cy_readl( &firm_id->signature))) { - printk(KERN_ERR "cyc:Cyclades-Z Error: you " - "need an external power supply for " - "this number of ports.\nFirmware " - "halted.\n"); + printk("cyc:Cyclades-Z Error: you need an " + "external power supply for this number " + "of ports.\n\rFirmware halted.\r\n"); } else { - printk(KERN_ERR "cyc:Cyclades-Z firmware not " - "yet loaded\n"); + printk("cyc:Cyclades-Z firmware not yet " + "loaded\n"); } return -ENODEV; } @@ -2505,23 +2572,24 @@ static int cy_open(struct tty_struct *tty, struct file *filp) struct BOARD_CTRL __iomem *board_ctrl; zfw_ctrl = cinfo->base_addr + - (readl(&firm_id->zfwctrl_addr) & - 0xfffff); + (cy_readl(&firm_id->zfwctrl_addr) & + 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; /* Enable interrupts on the PLX chip */ cy_writew(cinfo->ctl_addr + 0x68, - readw(cinfo->ctl_addr + 0x68) | 0x0900); + cy_readw(cinfo->ctl_addr + + 0x68) | 0x0900); /* Enable interrupts on the FW */ retval = cyz_issue_cmd(cinfo, 0, C_CM_IRQ_ENBL, 0L); if (retval != 0) { - printk(KERN_ERR "cyc:IRQ enable retval " - "was %x\n", retval); + printk("cyc:IRQ enable retval was %x\n", + retval); } cinfo->nports = - (int)readl(&board_ctrl->n_channel); + (int)cy_readl(&board_ctrl->n_channel); cinfo->intr_enabled = 1; } } @@ -2531,7 +2599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) return -ENODEV; } #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line); + printk("cyc:cy_open ttyC%d\n", info->line); /* */ #endif tty->driver_data = info; info->tty = tty; @@ -2539,12 +2607,12 @@ static int cy_open(struct tty_struct *tty, struct file *filp) return -ENODEV; } #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line, - info->count); + printk("cyc:cy_open ttyC%d, count = %d\n", info->line, info->count); + /**/ #endif info->count++; #ifdef CY_DEBUG_COUNT - printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n", + printk("cyc:cy_open (%d): incrementing count to %d\n", current->pid, info->count); #endif @@ -2552,8 +2620,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) * If the port is the middle of closing, bail out now */ if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { - wait_event_interruptible(info->close_wait, - !(info->flags & ASYNC_CLOSING)); + if (info->flags & ASYNC_CLOSING) + interruptible_sleep_on(&info->close_wait); return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; } @@ -2568,8 +2636,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) retval = block_til_ready(tty, filp, info); if (retval) { #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready " - "with %d\n", retval); + printk("cyc:cy_open returning after block_til_ready with %d\n", + retval); #endif return retval; } @@ -2577,7 +2645,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) info->throttle = 0; #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc:cy_open done\n"); + printk(" cyc:cy_open done\n"); + /**/ #endif return 0; } /* cy_open */ @@ -2587,10 +2656,9 @@ static int cy_open(struct tty_struct *tty, struct file *filp) */ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) { - struct cyclades_card *card; - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; void __iomem *base_addr; - int chip, channel, index; + int card, chip, channel, index; unsigned long orig_jiffies; int char_time; @@ -2629,19 +2697,20 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) if (!timeout || timeout > 2 * info->timeout) timeout = 2 * info->timeout; #ifdef CY_DEBUG_WAIT_UNTIL_SENT - printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...", - timeout, char_time, jiffies); + printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time); + printk("jiff=%lu...", jiffies); #endif card = info->card; - channel = (info->line) - (card->first_line); - if (!IS_CYC_Z(*card)) { + channel = (info->line) - (cy_card[card].first_line); + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); - while (readb(base_addr + (CySRER << index)) & CyTxRdy) { + index = cy_card[card].bus_index; + base_addr = + cy_card[card].base_addr + (cy_chip_offset[chip] << index); + while (cy_readb(base_addr + (CySRER << index)) & CyTxRdy) { #ifdef CY_DEBUG_WAIT_UNTIL_SENT - printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); + printk("Not clean (jiff=%lu)...", jiffies); #endif if (msleep_interruptible(jiffies_to_msecs(char_time))) break; @@ -2649,11 +2718,13 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) timeout)) break; } + } else { + /* Nothing to do! */ } /* Run one more char cycle */ msleep_interruptible(jiffies_to_msecs(char_time * 5)); #ifdef CY_DEBUG_WAIT_UNTIL_SENT - printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); + printk("Clean (jiff=%lu)...done\n", jiffies); #endif } @@ -2662,29 +2733,25 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) */ static void cy_close(struct tty_struct *tty, struct file *filp) { - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; unsigned long flags; #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line); + printk("cyc:cy_close ttyC%d\n", info->line); #endif if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { return; } - card = info->card; - - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); /* If the TTY is being hung up, nothing to do */ if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); return; } #ifdef CY_DEBUG_OPEN - printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line, - info->count); + printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count); #endif if ((tty->count == 1) && (info->count != 1)) { /* @@ -2694,22 +2761,22 @@ static void cy_close(struct tty_struct *tty, struct file *filp) * one, we've got real problems, since it means the * serial port won't be shutdown. */ - printk(KERN_ERR "cyc:cy_close: bad serial port count; " - "tty->count is 1, info->count is %d\n", info->count); + printk("cyc:cy_close: bad serial port count; tty->count is 1, " + "info->count is %d\n", info->count); info->count = 1; } #ifdef CY_DEBUG_COUNT - printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n", + printk("cyc:cy_close at (%d): decrementing count to %d\n", current->pid, info->count - 1); #endif if (--info->count < 0) { #ifdef CY_DEBUG_COUNT - printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n"); + printk("cyc:cyc_close setting count to 0\n"); #endif info->count = 0; } if (info->count) { - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); return; } info->flags |= ASYNC_CLOSING; @@ -2719,80 +2786,81 @@ static void cy_close(struct tty_struct *tty, struct file *filp) * the line discipline to only process XON/XOFF characters. */ tty->closing = 1; - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); if (info->closing_wait != CY_CLOSING_WAIT_NONE) { tty_wait_until_sent(tty, info->closing_wait); } - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); - if (!IS_CYC_Z(*card)) { - int channel = info->line - card->first_line; - int index = card->bus_index; - void __iomem *base_addr = card->base_addr + + if (!IS_CYC_Z(cy_card[info->card])) { + int channel = info->line - cy_card[info->card].first_line; + int index = cy_card[info->card].bus_index; + void __iomem *base_addr = cy_card[info->card].base_addr + (cy_chip_offset[channel >> 2] << index); /* Stop accepting input */ channel &= 0x03; cy_writeb(base_addr + (CyCAR << index), (u_char) channel); cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & ~CyRxData); + cy_readb(base_addr + (CySRER << index)) & ~CyRxData); if (info->flags & ASYNC_INITIALIZED) { /* Waiting for on-board buffers to be empty before closing the port */ - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); cy_wait_until_sent(tty, info->timeout); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); } } else { #ifdef Z_WAKE /* Waiting for on-board buffers to be empty before closing the port */ - void __iomem *base_addr = card->base_addr; + void __iomem *base_addr = cy_card[info->card].base_addr; struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; struct ZFW_CTRL __iomem *zfw_ctrl = - base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); + base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl; - int channel = info->line - card->first_line; + int channel = info->line - cy_card[info->card].first_line; int retval; - if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { - retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L); + if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { + retval = cyz_issue_cmd(&cy_card[info->card], channel, + C_CM_IOCTLW, 0L); if (retval != 0) { - printk(KERN_DEBUG "cyc:cy_close retval on " - "ttyC%d was %x\n", info->line, retval); + printk("cyc:cy_close retval on ttyC%d was %x\n", + info->line, retval); } - spin_unlock_irqrestore(&card->card_lock, flags); - wait_for_completion_interruptible(&info->shutdown_wait); - spin_lock_irqsave(&card->card_lock, flags); + CY_UNLOCK(info, flags); + interruptible_sleep_on(&info->shutdown_wait); + CY_LOCK(info, flags); } #endif } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); shutdown(info); if (tty->driver->flush_buffer) tty->driver->flush_buffer(tty); tty_ldisc_flush(tty); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); tty->closing = 0; info->event = 0; info->tty = NULL; if (info->blocked_open) { - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); if (info->close_delay) { msleep_interruptible(jiffies_to_msecs (info->close_delay)); } wake_up_interruptible(&info->open_wait); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); } info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); wake_up_interruptible(&info->close_wait); #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_close done\n"); + printk(" cyc:cy_close done\n"); #endif - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } /* cy_close */ /* This routine gets called when tty_write has put something into @@ -2810,12 +2878,12 @@ static void cy_close(struct tty_struct *tty, struct file *filp) */ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) { - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; unsigned long flags; int c, ret = 0; #ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line); + printk("cyc:cy_write ttyC%d\n", info->line); /* */ #endif if (serial_paranoia_check(info, tty->name, "cy_write")) { @@ -2825,7 +2893,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) if (!info->xmit_buf) return 0; - spin_lock_irqsave(&info->card->card_lock, flags); + CY_LOCK(info, flags); while (1) { c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), (int)(SERIAL_XMIT_SIZE - info->xmit_head))); @@ -2841,7 +2909,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) count -= c; ret += c; } - spin_unlock_irqrestore(&info->card->card_lock, flags); + CY_UNLOCK(info, flags); info->idle_stats.xmit_bytes += ret; info->idle_stats.xmit_idle = jiffies; @@ -2861,11 +2929,11 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) */ static void cy_put_char(struct tty_struct *tty, unsigned char ch) { - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; unsigned long flags; #ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line); + printk("cyc:cy_put_char ttyC%d\n", info->line); #endif if (serial_paranoia_check(info, tty->name, "cy_put_char")) @@ -2874,9 +2942,9 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) if (!info->xmit_buf) return; - spin_lock_irqsave(&info->card->card_lock, flags); + CY_LOCK(info, flags); if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { - spin_unlock_irqrestore(&info->card->card_lock, flags); + CY_UNLOCK(info, flags); return; } @@ -2885,7 +2953,7 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) info->xmit_cnt++; info->idle_stats.xmit_bytes++; info->idle_stats.xmit_idle = jiffies; - spin_unlock_irqrestore(&info->card->card_lock, flags); + CY_UNLOCK(info, flags); } /* cy_put_char */ /* @@ -2894,10 +2962,10 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) */ static void cy_flush_chars(struct tty_struct *tty) { - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; #ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line); + printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */ #endif if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) @@ -2918,11 +2986,11 @@ static void cy_flush_chars(struct tty_struct *tty) */ static int cy_write_room(struct tty_struct *tty) { - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; int ret; #ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line); + printk("cyc:cy_write_room ttyC%d\n", info->line); /* */ #endif if (serial_paranoia_check(info, tty->name, "cy_write_room")) @@ -2935,49 +3003,46 @@ static int cy_write_room(struct tty_struct *tty) static int cy_chars_in_buffer(struct tty_struct *tty) { - struct cyclades_card *card; - struct cyclades_port *info = tty->driver_data; - int channel; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int card, channel; if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) return 0; card = info->card; - channel = (info->line) - (card->first_line); + channel = (info->line) - (cy_card[card].first_line); #ifdef Z_EXT_CHARS_IN_BUFFER if (!IS_CYC_Z(cy_card[card])) { #endif /* Z_EXT_CHARS_IN_BUFFER */ #ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", - info->line, info->xmit_cnt); + printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */ #endif return info->xmit_cnt; #ifdef Z_EXT_CHARS_IN_BUFFER } else { - static struct FIRM_ID *firm_id; - static struct ZFW_CTRL *zfw_ctrl; - static struct CH_CTRL *ch_ctrl; - static struct BUF_CTRL *buf_ctrl; + static volatile struct FIRM_ID *firm_id; + static volatile struct ZFW_CTRL *zfw_ctrl; + static volatile struct CH_CTRL *ch_ctrl; + static volatile struct BUF_CTRL *buf_ctrl; int char_count; - __u32 tx_put, tx_get, tx_bufsize; + volatile uclong tx_put, tx_get, tx_bufsize; - firm_id = card->base_addr + ID_ADDRESS; - zfw_ctrl = card->base_addr + - (readl(&firm_id->zfwctrl_addr) & 0xfffff); + firm_id = cy_card[card].base_addr + ID_ADDRESS; + zfw_ctrl = cy_card[card].base_addr + + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); - tx_get = readl(&buf_ctrl->tx_get); - tx_put = readl(&buf_ctrl->tx_put); - tx_bufsize = readl(&buf_ctrl->tx_bufsize); + tx_get = cy_readl(&buf_ctrl->tx_get); + tx_put = cy_readl(&buf_ctrl->tx_put); + tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); if (tx_put >= tx_get) char_count = tx_put - tx_get; else char_count = tx_put - tx_get + tx_bufsize; #ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", - info->line, info->xmit_cnt + char_count); + printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count); /* */ #endif return info->xmit_cnt + char_count; } @@ -2990,10 +3055,10 @@ static int cy_chars_in_buffer(struct tty_struct *tty) * ------------------------------------------------------------ */ -static void cyy_baud_calc(struct cyclades_port *info, __u32 baud) +static void cyy_baud_calc(struct cyclades_port *info, uclong baud) { int co, co_val, bpr; - __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : + uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 25000000); if (baud == 0) { @@ -3021,10 +3086,9 @@ static void cyy_baud_calc(struct cyclades_port *info, __u32 baud) */ static void set_line_char(struct cyclades_port *info) { - struct cyclades_card *card; unsigned long flags; void __iomem *base_addr; - int chip, channel, index; + int card, chip, channel, index; unsigned cflag, iflag; unsigned short chip_number; int baud, baud_rate = 0; @@ -3054,12 +3118,12 @@ static void set_line_char(struct cyclades_port *info) } card = info->card; - channel = info->line - card->first_line; + channel = (info->line) - (cy_card[card].first_line); chip_number = channel / 4; - if (!IS_CYC_Z(*card)) { + if (!IS_CYC_Z(cy_card[card])) { - index = card->bus_index; + index = cy_card[card].bus_index; /* baud rate */ baud = tty_get_baud_rate(info->tty); @@ -3177,9 +3241,10 @@ static void set_line_char(struct cyclades_port *info) chip = channel >> 2; channel &= 0x03; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + base_addr = cy_card[card].base_addr + + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); /* tx and rx baud rate */ @@ -3211,7 +3276,8 @@ static void set_line_char(struct cyclades_port *info) if (C_CLOCAL(info->tty)) { /* without modem intr */ cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) | CyMdmCh); + cy_readb(base_addr + + (CySRER << index)) | CyMdmCh); /* act on 1->0 modem transitions */ if ((cflag & CRTSCTS) && info->rflow) { cy_writeb(base_addr + (CyMCOR1 << index), @@ -3225,7 +3291,7 @@ static void set_line_char(struct cyclades_port *info) } else { /* without modem intr */ cy_writeb(base_addr + (CySRER << index), - readb(base_addr + + cy_readb(base_addr + (CySRER << index)) | CyMdmCh); /* act on 1->0 modem transitions */ if ((cflag & CRTSCTS) && info->rflow) { @@ -3250,10 +3316,10 @@ static void set_line_char(struct cyclades_port *info) ~CyDTR); } #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_line_char dropping DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - readb(base_addr + (CyMSVR1 << index)), - readb(base_addr + (CyMSVR2 << index))); + printk("cyc:set_line_char dropping DTR\n"); + printk(" status: 0x%x, 0x%x\n", + cy_readb(base_addr + (CyMSVR1 << index)), + cy_readb(base_addr + (CyMSVR2 << index))); #endif } else { if (info->rtsdtr_inv) { @@ -3264,17 +3330,17 @@ static void set_line_char(struct cyclades_port *info) CyDTR); } #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_line_char raising DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - readb(base_addr + (CyMSVR1 << index)), - readb(base_addr + (CyMSVR2 << index))); + printk("cyc:set_line_char raising DTR\n"); + printk(" status: 0x%x, 0x%x\n", + cy_readb(base_addr + (CyMSVR1 << index)), + cy_readb(base_addr + (CyMSVR2 << index))); #endif } if (info->tty) { clear_bit(TTY_IO_ERROR, &info->tty->flags); } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } else { struct FIRM_ID __iomem *firm_id; @@ -3282,16 +3348,16 @@ static void set_line_char(struct cyclades_port *info) struct BOARD_CTRL __iomem *board_ctrl; struct CH_CTRL __iomem *ch_ctrl; struct BUF_CTRL __iomem *buf_ctrl; - __u32 sw_flow; + uclong sw_flow; int retval; - firm_id = card->base_addr + ID_ADDRESS; - if (!ISZLOADED(*card)) { + firm_id = cy_card[card].base_addr + ID_ADDRESS; + if (!ISZLOADED(cy_card[card])) { return; } - zfw_ctrl = card->base_addr + - (readl(&firm_id->zfwctrl_addr) & 0xfffff); + zfw_ctrl = cy_card[card].base_addr + + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; @@ -3342,10 +3408,10 @@ static void set_line_char(struct cyclades_port *info) } if (cflag & CSTOPB) { cy_writel(&ch_ctrl->comm_data_l, - readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); + cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); } else { cy_writel(&ch_ctrl->comm_data_l, - readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); + cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); } if (cflag & PARENB) { if (cflag & PARODD) { @@ -3360,10 +3426,12 @@ static void set_line_char(struct cyclades_port *info) /* CTS flow control flag */ if (cflag & CRTSCTS) { cy_writel(&ch_ctrl->hw_flow, - readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS); + cy_readl(&ch_ctrl-> + hw_flow) | C_RS_CTS | C_RS_RTS); } else { - cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) & - ~(C_RS_CTS | C_RS_RTS)); + cy_writel(&ch_ctrl->hw_flow, + cy_readl(&ch_ctrl-> + hw_flow) & ~(C_RS_CTS | C_RS_RTS)); } /* As the HW flow control is done in firmware, the driver doesn't need to care about it */ @@ -3378,10 +3446,10 @@ static void set_line_char(struct cyclades_port *info) } cy_writel(&ch_ctrl->sw_flow, sw_flow); - retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); + retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); if (retval != 0) { - printk(KERN_ERR "cyc:set_line_char retval on ttyC%d " - "was %x\n", info->line, retval); + printk("cyc:set_line_char retval on ttyC%d was %x\n", + info->line, retval); } /* CD sensitivity */ @@ -3393,22 +3461,22 @@ static void set_line_char(struct cyclades_port *info) if (baud == 0) { /* baud rate is zero, turn off line */ cy_writel(&ch_ctrl->rs_control, - readl(&ch_ctrl->rs_control) & ~C_RS_DTR); + cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR); #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n"); + printk("cyc:set_line_char dropping Z DTR\n"); #endif } else { cy_writel(&ch_ctrl->rs_control, - readl(&ch_ctrl->rs_control) | C_RS_DTR); + cy_readl(&ch_ctrl->rs_control) | C_RS_DTR); #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n"); + printk("cyc:set_line_char raising Z DTR\n"); #endif } - retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM,0L); + retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTLM,0L); if (retval != 0) { - printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d " - "was %x\n", info->line, retval); + printk("cyc:set_line_char(2) retval on ttyC%d was %x\n", + info->line, retval); } if (info->tty) { @@ -3422,15 +3490,14 @@ get_serial_info(struct cyclades_port *info, struct serial_struct __user * retinfo) { struct serial_struct tmp; - struct cyclades_card *cinfo = info->card; + struct cyclades_card *cinfo = &cy_card[info->card]; if (!retinfo) return -EFAULT; memset(&tmp, 0, sizeof(tmp)); tmp.type = info->type; tmp.line = info->line; - tmp.port = (info->card - cy_card) * 0x100 + info->line - - cinfo->first_line; + tmp.port = info->card * 0x100 + info->line - cinfo->first_line; tmp.irq = cinfo->irq; tmp.flags = info->flags; tmp.close_delay = info->close_delay; @@ -3499,25 +3566,25 @@ set_serial_info(struct cyclades_port *info, */ static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) { - struct cyclades_card *card; - int chip, channel, index; + int card, chip, channel, index; unsigned char status; unsigned int result; unsigned long flags; void __iomem *base_addr; card = info->card; - channel = (info->line) - (card->first_line); - if (!IS_CYC_Z(*card)) { + channel = (info->line) - (cy_card[card].first_line); + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = + cy_card[card].base_addr + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&card->card_lock, flags); - status = readb(base_addr + (CySRER << index)) & + CY_LOCK(info, flags); + status = cy_readb(base_addr + (CySRER << index)) & (CyTxRdy | CyTxMpty); - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); result = (status ? 0 : TIOCSER_TEMT); } else { /* Not supported yet */ @@ -3528,9 +3595,8 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) static int cy_tiocmget(struct tty_struct *tty, struct file *file) { - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - int chip, channel, index; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int card, chip, channel, index; void __iomem *base_addr; unsigned long flags; unsigned char status; @@ -3545,18 +3611,19 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) return -ENODEV; card = info->card; - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = (info->line) - (cy_card[card].first_line); + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = + cy_card[card].base_addr + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); - status = readb(base_addr + (CyMSVR1 << index)); - status |= readb(base_addr + (CyMSVR2 << index)); - spin_unlock_irqrestore(&card->card_lock, flags); + status = cy_readb(base_addr + (CyMSVR1 << index)); + status |= cy_readb(base_addr + (CyMSVR2 << index)); + CY_UNLOCK(info, flags); if (info->rtsdtr_inv) { result = ((status & CyRTS) ? TIOCM_DTR : 0) | @@ -3570,14 +3637,19 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) ((status & CyDSR) ? TIOCM_DSR : 0) | ((status & CyCTS) ? TIOCM_CTS : 0); } else { - base_addr = card->base_addr; - firm_id = card->base_addr + ID_ADDRESS; - if (ISZLOADED(*card)) { - zfw_ctrl = card->base_addr + - (readl(&firm_id->zfwctrl_addr) & 0xfffff); + base_addr = cy_card[card].base_addr; + + if (cy_card[card].num_chips != -1) { + return -EINVAL; + } + + firm_id = cy_card[card].base_addr + ID_ADDRESS; + if (ISZLOADED(cy_card[card])) { + zfw_ctrl = cy_card[card].base_addr + + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; ch_ctrl = zfw_ctrl->ch_ctrl; - lstatus = readl(&ch_ctrl[channel].rs_status); + lstatus = cy_readl(&ch_ctrl[channel].rs_status); result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | @@ -3597,9 +3669,8 @@ static int cy_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) { - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - int chip, channel, index; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int card, chip, channel, index; void __iomem *base_addr; unsigned long flags; struct FIRM_ID __iomem *firm_id; @@ -3612,15 +3683,16 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, return -ENODEV; card = info->card; - channel = (info->line) - (card->first_line); - if (!IS_CYC_Z(*card)) { + channel = (info->line) - (cy_card[card].first_line); + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = + cy_card[card].base_addr + (cy_chip_offset[chip] << index); if (set & TIOCM_RTS) { - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); if (info->rtsdtr_inv) { @@ -3630,10 +3702,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, cy_writeb(base_addr + (CyMSVR1 << index), CyRTS); } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } if (clear & TIOCM_RTS) { - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); if (info->rtsdtr_inv) { @@ -3643,10 +3715,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } if (set & TIOCM_DTR) { - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); if (info->rtsdtr_inv) { @@ -3657,15 +3729,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, CyDTR); } #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - readb(base_addr + (CyMSVR1 << index)), - readb(base_addr + (CyMSVR2 << index))); + printk("cyc:set_modem_info raising DTR\n"); + printk(" status: 0x%x, 0x%x\n", + cy_readb(base_addr + (CyMSVR1 << index)), + cy_readb(base_addr + (CyMSVR2 << index))); #endif - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } if (clear & TIOCM_DTR) { - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); if (info->rtsdtr_inv) { @@ -3677,69 +3749,68 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, } #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n"); - printk(KERN_DEBUG " status: 0x%x, 0x%x\n", - readb(base_addr + (CyMSVR1 << index)), - readb(base_addr + (CyMSVR2 << index))); + printk("cyc:set_modem_info dropping DTR\n"); + printk(" status: 0x%x, 0x%x\n", + cy_readb(base_addr + (CyMSVR1 << index)), + cy_readb(base_addr + (CyMSVR2 << index))); #endif - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } } else { - base_addr = card->base_addr; + base_addr = cy_card[card].base_addr; - firm_id = card->base_addr + ID_ADDRESS; - if (ISZLOADED(*card)) { - zfw_ctrl = card->base_addr + - (readl(&firm_id->zfwctrl_addr) & 0xfffff); + firm_id = cy_card[card].base_addr + ID_ADDRESS; + if (ISZLOADED(cy_card[card])) { + zfw_ctrl = cy_card[card].base_addr + + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); board_ctrl = &zfw_ctrl->board_ctrl; ch_ctrl = zfw_ctrl->ch_ctrl; if (set & TIOCM_RTS) { - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writel(&ch_ctrl[channel].rs_control, - readl(&ch_ctrl[channel].rs_control) | - C_RS_RTS); - spin_unlock_irqrestore(&card->card_lock, flags); + cy_readl(&ch_ctrl[channel]. + rs_control) | C_RS_RTS); + CY_UNLOCK(info, flags); } if (clear & TIOCM_RTS) { - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writel(&ch_ctrl[channel].rs_control, - readl(&ch_ctrl[channel].rs_control) & - ~C_RS_RTS); - spin_unlock_irqrestore(&card->card_lock, flags); + cy_readl(&ch_ctrl[channel]. + rs_control) & ~C_RS_RTS); + CY_UNLOCK(info, flags); } if (set & TIOCM_DTR) { - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writel(&ch_ctrl[channel].rs_control, - readl(&ch_ctrl[channel].rs_control) | - C_RS_DTR); + cy_readl(&ch_ctrl[channel]. + rs_control) | C_RS_DTR); #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_modem_info raising " - "Z DTR\n"); + printk("cyc:set_modem_info raising Z DTR\n"); #endif - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } if (clear & TIOCM_DTR) { - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writel(&ch_ctrl[channel].rs_control, - readl(&ch_ctrl[channel].rs_control) & - ~C_RS_DTR); + cy_readl(&ch_ctrl[channel]. + rs_control) & ~C_RS_DTR); #ifdef CY_DEBUG_DTR - printk(KERN_DEBUG "cyc:set_modem_info clearing " - "Z DTR\n"); + printk("cyc:set_modem_info clearing Z DTR\n"); #endif - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } } else { return -ENODEV; } - spin_lock_irqsave(&card->card_lock, flags); - retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); + CY_LOCK(info, flags); + retval = cyz_issue_cmd(&cy_card[info->card], + channel, C_CM_IOCTLM, 0L); if (retval != 0) { - printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d " - "was %x\n", info->line, retval); + printk("cyc:set_modem_info retval on ttyC%d was %x\n", + info->line, retval); } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } return 0; } /* cy_tiocmset */ @@ -3749,17 +3820,14 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, */ static void cy_break(struct tty_struct *tty, int break_state) { - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->name, "cy_break")) return; - card = info->card; - - spin_lock_irqsave(&card->card_lock, flags); - if (!IS_CYC_Z(*card)) { + CY_LOCK(info, flags); + if (!IS_CYC_Z(cy_card[info->card])) { /* Let the transmit ISR take care of this (since it requires stuffing characters into the output stream). */ @@ -3767,18 +3835,18 @@ static void cy_break(struct tty_struct *tty, int break_state) if (!info->breakon) { info->breakon = 1; if (!info->xmit_cnt) { - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); start_xmit(info); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); } } } else { if (!info->breakoff) { info->breakoff = 1; if (!info->xmit_cnt) { - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); start_xmit(info); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); } } } @@ -3786,25 +3854,24 @@ static void cy_break(struct tty_struct *tty, int break_state) int retval; if (break_state == -1) { - retval = cyz_issue_cmd(card, - info->line - card->first_line, + retval = cyz_issue_cmd(&cy_card[info->card], + info->line - cy_card[info->card].first_line, C_CM_SET_BREAK, 0L); if (retval != 0) { - printk(KERN_ERR "cyc:cy_break (set) retval on " - "ttyC%d was %x\n", info->line, retval); + printk("cyc:cy_break (set) retval on ttyC%d " + "was %x\n", info->line, retval); } } else { - retval = cyz_issue_cmd(card, - info->line - card->first_line, + retval = cyz_issue_cmd(&cy_card[info->card], + info->line - cy_card[info->card].first_line, C_CM_CLR_BREAK, 0L); if (retval != 0) { - printk(KERN_DEBUG "cyc:cy_break (clr) retval " - "on ttyC%d was %x\n", info->line, - retval); + printk("cyc:cy_break (clr) retval on ttyC%d " + "was %x\n", info->line, retval); } } } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } /* cy_break */ static int @@ -3822,27 +3889,28 @@ get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) static int set_threshold(struct cyclades_port *info, unsigned long value) { - struct cyclades_card *card; void __iomem *base_addr; - int channel, chip, index; + int card, channel, chip, index; unsigned long flags; card = info->card; - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = info->line - cy_card[card].first_line; + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; + index = cy_card[card].bus_index; base_addr = - card->base_addr + (cy_chip_offset[chip] << index); + cy_card[card].base_addr + (cy_chip_offset[chip] << index); info->cor3 &= ~CyREC_FIFO; info->cor3 |= value & CyREC_FIFO; - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCOR3 << index), info->cor3); cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); + } else { + /* Nothing to do! */ } return 0; } /* set_threshold */ @@ -3850,23 +3918,25 @@ static int set_threshold(struct cyclades_port *info, unsigned long value) static int get_threshold(struct cyclades_port *info, unsigned long __user * value) { - struct cyclades_card *card; void __iomem *base_addr; - int channel, chip, index; + int card, channel, chip, index; unsigned long tmp; card = info->card; - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = info->line - cy_card[card].first_line; + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = + cy_card[card].base_addr + (cy_chip_offset[chip] << index); - tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; + tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; return put_user(tmp, value); + } else { + /* Nothing to do! */ + return 0; } - return 0; } /* get_threshold */ static int @@ -3884,45 +3954,49 @@ get_default_threshold(struct cyclades_port *info, unsigned long __user * value) static int set_timeout(struct cyclades_port *info, unsigned long value) { - struct cyclades_card *card; void __iomem *base_addr; - int channel, chip, index; + int card, channel, chip, index; unsigned long flags; card = info->card; - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = info->line - cy_card[card].first_line; + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = + cy_card[card].base_addr + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyRTPR << index), value & 0xff); - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); + } else { + /* Nothing to do! */ } return 0; } /* set_timeout */ static int get_timeout(struct cyclades_port *info, unsigned long __user * value) { - struct cyclades_card *card; void __iomem *base_addr; - int channel, chip, index; + int card, channel, chip, index; unsigned long tmp; card = info->card; - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = info->line - cy_card[card].first_line; + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + (cy_chip_offset[chip] << index); + index = cy_card[card].bus_index; + base_addr = + cy_card[card].base_addr + (cy_chip_offset[chip] << index); - tmp = readb(base_addr + (CyRTPR << index)); + tmp = cy_readb(base_addr + (CyRTPR << index)); return put_user(tmp, value); + } else { + /* Nothing to do! */ + return 0; } - return 0; } /* get_timeout */ static int set_default_timeout(struct cyclades_port *info, unsigned long value) @@ -3946,7 +4020,7 @@ static int cy_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; struct cyclades_icount cprev, cnow; /* kernel counter temps */ struct serial_icounter_struct __user *p_cuser; /* user space */ int ret_val = 0; @@ -3957,8 +4031,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, return -ENODEV; #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", - info->line, cmd, arg); + printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */ #endif switch (cmd) { @@ -4003,6 +4076,14 @@ cy_ioctl(struct tty_struct *tty, struct file *file, case CYGETRTSDTR_INV: ret_val = info->rtsdtr_inv; break; + case CYGETCARDINFO: + if (copy_to_user(argp, &cy_card[info->card], + sizeof(struct cyclades_card))) { + ret_val = -EFAULT; + break; + } + ret_val = 0; + break; case CYGETCD1400VER: ret_val = info->chip_rev; break; @@ -4038,22 +4119,34 @@ cy_ioctl(struct tty_struct *tty, struct file *file, * Caller should use TIOCGICOUNT to see which one it was */ case TIOCMIWAIT: - spin_lock_irqsave(&info->card->card_lock, flags); + CY_LOCK(info, flags); /* note the counters on entry */ - cnow = info->icount; - spin_unlock_irqrestore(&info->card->card_lock, flags); - ret_val = wait_event_interruptible(info->delta_msr_wait, ({ - cprev = cnow; - spin_lock_irqsave(&info->card->card_lock, flags); + cprev = info->icount; + CY_UNLOCK(info, flags); + while (1) { + interruptible_sleep_on(&info->delta_msr_wait); + /* see if a signal did it */ + if (signal_pending(current)) { + return -ERESTARTSYS; + } + + CY_LOCK(info, flags); cnow = info->icount; /* atomic copy */ - spin_unlock_irqrestore(&info->card->card_lock, flags); + CY_UNLOCK(info, flags); - ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || - ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || - ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || - ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)); - })); - break; + if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && + cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { + return -EIO; /* no change => error */ + } + if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || + ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || + ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || + ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { + return 0; + } + cprev = cnow; + } + /* NOTREACHED */ /* * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) @@ -4062,9 +4155,9 @@ cy_ioctl(struct tty_struct *tty, struct file *file, * RI where only 0->1 is counted. */ case TIOCGICOUNT: - spin_lock_irqsave(&info->card->card_lock, flags); + CY_LOCK(info, flags); cnow = info->icount; - spin_unlock_irqrestore(&info->card->card_lock, flags); + CY_UNLOCK(info, flags); p_cuser = argp; ret_val = put_user(cnow.cts, &p_cuser->cts); if (ret_val) @@ -4106,7 +4199,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, } #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_ioctl done\n"); + printk(" cyc:cy_ioctl done\n"); #endif return ret_val; @@ -4120,10 +4213,10 @@ cy_ioctl(struct tty_struct *tty, struct file *file, */ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line); + printk("cyc:cy_set_termios ttyC%d\n", info->line); #endif if (tty->termios->c_cflag == old_termios->c_cflag && @@ -4155,9 +4248,8 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) */ static void cy_send_xchar(struct tty_struct *tty, char ch) { - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - int channel; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int card, channel; if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) return; @@ -4168,13 +4260,15 @@ static void cy_send_xchar(struct tty_struct *tty, char ch) cy_start(tty); card = info->card; - channel = info->line - card->first_line; + channel = info->line - cy_card[card].first_line; - if (IS_CYC_Z(*card)) { + if (IS_CYC_Z(cy_card[card])) { if (ch == STOP_CHAR(tty)) - cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L); + cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXOFF, + 0L); else if (ch == START_CHAR(tty)) - cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L); + cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXON, + 0L); } } @@ -4184,16 +4278,15 @@ static void cy_send_xchar(struct tty_struct *tty, char ch) */ static void cy_throttle(struct tty_struct *tty) { - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; unsigned long flags; void __iomem *base_addr; - int chip, channel, index; + int card, chip, channel, index; #ifdef CY_DEBUG_THROTTLE char buf[64]; - printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf), + printk("cyc:throttle %s: %d....ttyC%d\n", tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty), info->line); #endif @@ -4204,22 +4297,22 @@ static void cy_throttle(struct tty_struct *tty) card = info->card; if (I_IXOFF(tty)) { - if (!IS_CYC_Z(*card)) + if (!IS_CYC_Z(cy_card[card])) cy_send_xchar(tty, STOP_CHAR(tty)); else info->throttle = 1; } if (tty->termios->c_cflag & CRTSCTS) { - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = info->line - cy_card[card].first_line; + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + + index = cy_card[card].bus_index; + base_addr = cy_card[card].base_addr + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); if (info->rtsdtr_inv) { @@ -4229,7 +4322,7 @@ static void cy_throttle(struct tty_struct *tty) cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } else { info->throttle = 1; } @@ -4243,17 +4336,16 @@ static void cy_throttle(struct tty_struct *tty) */ static void cy_unthrottle(struct tty_struct *tty) { - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; unsigned long flags; void __iomem *base_addr; - int chip, channel, index; + int card, chip, channel, index; #ifdef CY_DEBUG_THROTTLE char buf[64]; - printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", - tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty),info->line); + printk("cyc:unthrottle %s: %d....ttyC%d\n", tty_name(tty, buf), + tty->ldisc.chars_in_buffer(tty), info->line); #endif if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) { @@ -4269,15 +4361,15 @@ static void cy_unthrottle(struct tty_struct *tty) if (tty->termios->c_cflag & CRTSCTS) { card = info->card; - channel = info->line - card->first_line; - if (!IS_CYC_Z(*card)) { + channel = info->line - cy_card[card].first_line; + if (!IS_CYC_Z(cy_card[card])) { chip = channel >> 2; channel &= 0x03; - index = card->bus_index; - base_addr = card->base_addr + + index = cy_card[card].bus_index; + base_addr = cy_card[card].base_addr + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) channel); if (info->rtsdtr_inv) { @@ -4287,7 +4379,7 @@ static void cy_unthrottle(struct tty_struct *tty) cy_writeb(base_addr + (CyMSVR1 << index), CyRTS); } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } else { info->throttle = 0; } @@ -4300,96 +4392,102 @@ static void cy_unthrottle(struct tty_struct *tty) static void cy_stop(struct tty_struct *tty) { struct cyclades_card *cinfo; - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; void __iomem *base_addr; int chip, channel, index; unsigned long flags; #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line); + printk("cyc:cy_stop ttyC%d\n", info->line); /* */ #endif if (serial_paranoia_check(info, tty->name, "cy_stop")) return; - cinfo = info->card; + cinfo = &cy_card[info->card]; channel = info->line - cinfo->first_line; if (!IS_CYC_Z(*cinfo)) { index = cinfo->bus_index; chip = channel >> 2; channel &= 0x03; - base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); + base_addr = cy_card[info->card].base_addr + + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&cinfo->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char)(channel & 0x0003)); /* index channel */ cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & ~CyTxRdy); - spin_unlock_irqrestore(&cinfo->card_lock, flags); + cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy); + CY_UNLOCK(info, flags); + } else { + /* Nothing to do! */ } } /* cy_stop */ static void cy_start(struct tty_struct *tty) { struct cyclades_card *cinfo; - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; void __iomem *base_addr; int chip, channel, index; unsigned long flags; #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line); + printk("cyc:cy_start ttyC%d\n", info->line); /* */ #endif if (serial_paranoia_check(info, tty->name, "cy_start")) return; - cinfo = info->card; + cinfo = &cy_card[info->card]; channel = info->line - cinfo->first_line; index = cinfo->bus_index; if (!IS_CYC_Z(*cinfo)) { chip = channel >> 2; channel &= 0x03; - base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); + base_addr = cy_card[info->card].base_addr + + (cy_chip_offset[chip] << index); - spin_lock_irqsave(&cinfo->card_lock, flags); + CY_LOCK(info, flags); cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */ cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) | CyTxRdy); - spin_unlock_irqrestore(&cinfo->card_lock, flags); + cy_readb(base_addr + (CySRER << index)) | CyTxRdy); + CY_UNLOCK(info, flags); + } else { + /* Nothing to do! */ } } /* cy_start */ static void cy_flush_buffer(struct tty_struct *tty) { - struct cyclades_port *info = tty->driver_data; - struct cyclades_card *card; - int channel, retval; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; + int card, channel, retval; unsigned long flags; #ifdef CY_DEBUG_IO - printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); + printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */ #endif if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) return; card = info->card; - channel = info->line - card->first_line; + channel = (info->line) - (cy_card[card].first_line); - spin_lock_irqsave(&card->card_lock, flags); + CY_LOCK(info, flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); - if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board + if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board buffers as well */ - spin_lock_irqsave(&card->card_lock, flags); - retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); + CY_LOCK(info, flags); + retval = + cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L); if (retval != 0) { - printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " - "was %x\n", info->line, retval); + printk("cyc: flush_buffer retval on ttyC%d was %x\n", + info->line, retval); } - spin_unlock_irqrestore(&card->card_lock, flags); + CY_UNLOCK(info, flags); } tty_wakeup(tty); } /* cy_flush_buffer */ @@ -4399,10 +4497,10 @@ static void cy_flush_buffer(struct tty_struct *tty) */ static void cy_hangup(struct tty_struct *tty) { - struct cyclades_port *info = tty->driver_data; + struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; #ifdef CY_DEBUG_OTHER - printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line); + printk("cyc:cy_hangup ttyC%d\n", info->line); /* */ #endif if (serial_paranoia_check(info, tty->name, "cy_hangup")) @@ -4413,8 +4511,7 @@ static void cy_hangup(struct tty_struct *tty) info->event = 0; info->count = 0; #ifdef CY_DEBUG_COUNT - printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", - current->pid); + printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid); #endif info->tty = NULL; info->flags &= ~ASYNC_NORMAL_ACTIVE; @@ -4429,107 +4526,10 @@ static void cy_hangup(struct tty_struct *tty) * --------------------------------------------------------------------- */ -static int __devinit cy_init_card(struct cyclades_card *cinfo) -{ - struct cyclades_port *info; - u32 mailbox; - unsigned int nports; - unsigned short chip_number; - int index, port; - - spin_lock_init(&cinfo->card_lock); - - if (IS_CYC_Z(*cinfo)) { /* Cyclades-Z */ - mailbox = readl(&((struct RUNTIME_9060 __iomem *) - cinfo->ctl_addr)->mail_box_0); - nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8; - cinfo->intr_enabled = 0; - cinfo->nports = 0; /* Will be correctly set later, after - Z FW is loaded */ - } else { - index = cinfo->bus_index; - nports = cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips; - } - - cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL); - if (cinfo->ports == NULL) { - printk(KERN_ERR "Cyclades: cannot allocate ports\n"); - cinfo->nports = 0; - return -ENOMEM; - } - - for (port = cinfo->first_line; port < cinfo->first_line + nports; - port++) { - info = &cinfo->ports[port - cinfo->first_line]; - info->magic = CYCLADES_MAGIC; - info->card = cinfo; - info->line = port; - info->flags = STD_COM_FLAGS; - info->closing_wait = CLOSING_WAIT_DELAY; - info->close_delay = 5 * HZ / 10; - - INIT_WORK(&info->tqueue, do_softint); - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_completion(&info->shutdown_wait); - init_waitqueue_head(&info->delta_msr_wait); - - if (IS_CYC_Z(*cinfo)) { - info->type = PORT_STARTECH; - if (mailbox == ZO_V1) - info->xmit_fifo_size = CYZ_FIFO_SIZE; - else - info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE; -#ifdef CONFIG_CYZ_INTR - setup_timer(&cyz_rx_full_timer[port], - cyz_rx_restart, (unsigned long)info); -#endif - } else { - info->type = PORT_CIRRUS; - info->xmit_fifo_size = CyMAX_CHAR_FIFO; - info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; - info->cor2 = CyETC; - info->cor3 = 0x08; /* _very_ small rcv threshold */ - - chip_number = (port - cinfo->first_line) / 4; - if ((info->chip_rev = readb(cinfo->base_addr + - (cy_chip_offset[chip_number] << - index) + (CyGFRCR << index))) >= - CD1400_REV_J) { - /* It is a CD1400 rev. J or later */ - info->tbpr = baud_bpr_60[13]; /* Tx BPR */ - info->tco = baud_co_60[13]; /* Tx CO */ - info->rbpr = baud_bpr_60[13]; /* Rx BPR */ - info->rco = baud_co_60[13]; /* Rx CO */ - info->rtsdtr_inv = 1; - } else { - info->tbpr = baud_bpr_25[13]; /* Tx BPR */ - info->tco = baud_co_25[13]; /* Tx CO */ - info->rbpr = baud_bpr_25[13]; /* Rx BPR */ - info->rco = baud_co_25[13]; /* Rx CO */ - info->rtsdtr_inv = 0; - } - info->read_status_mask = CyTIMEOUT | CySPECHAR | - CyBREAK | CyPARITY | CyFRAME | CyOVERRUN; - } - - } - -#ifndef CONFIG_CYZ_INTR - if (IS_CYC_Z(*cinfo) && !timer_pending(&cyz_timerlist)) { - mod_timer(&cyz_timerlist, jiffies + 1); -#ifdef CY_PCI_DEBUG - printk(KERN_DEBUG "Cyclades-Z polling initialized\n"); -#endif - } -#endif - return 0; -} - /* initialize chips on Cyclom-Y card -- return number of valid chips (which is number of ports/4) */ -static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, - int index) +static unsigned short __init +cyy_init_card(void __iomem * true_base_addr, int index) { unsigned int chip_number; void __iomem *base_addr; @@ -4544,7 +4544,7 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, base_addr = true_base_addr + (cy_chip_offset[chip_number] << index); mdelay(1); - if (readb(base_addr + (CyCCR << index)) != 0x00) { + if (cy_readb(base_addr + (CyCCR << index)) != 0x00) { /************* printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", chip_number, (unsigned long)base_addr); @@ -4561,7 +4561,7 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, chip 4 GFRCR register appears at chip 0, there is no chip 4 and this must be a Cyclom-16Y, not a Cyclom-32Ye. */ - if (chip_number == 4 && readb(true_base_addr + + if (chip_number == 4 && cy_readb(true_base_addr + (cy_chip_offset[0] << index) + (CyGFRCR << index)) == 0) { return chip_number; @@ -4570,7 +4570,7 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); mdelay(1); - if (readb(base_addr + (CyGFRCR << index)) == 0x00) { + if (cy_readb(base_addr + (CyGFRCR << index)) == 0x00) { /* printk(" chip #%d at %#6lx is not responding ", chip_number, (unsigned long)base_addr); @@ -4578,7 +4578,7 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, */ return chip_number; } - if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) != + if ((0xf0 & (cy_readb(base_addr + (CyGFRCR << index)))) != 0x40) { /* printk(" chip #%d at %#6lx is not valid (GFRCR == " @@ -4589,7 +4589,7 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, return chip_number; } cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL); - if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) { + if (cy_readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) { /* It is a CD1400 rev. J or later */ /* Impossible to reach 5ms with this chip. Changed to 2ms instead (f = 500 Hz). */ @@ -4602,7 +4602,7 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, /* printk(" chip #%d at %#6lx is rev 0x%2x\n", chip_number, (unsigned long)base_addr, - readb(base_addr+(CyGFRCR< NR_PORTS) { - printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " - "more channels are available. Change NR_PORTS " - "in cyclades.c and recompile kernel.\n", + printk("Cyclom-Y/ISA found at 0x%lx ", (unsigned long)cy_isa_address); - iounmap(cy_isa_address); + printk("but no more channels are available.\n"); + printk("Change NR_PORTS in cyclades.c and recompile " + "kernel.\n"); return nboard; } /* fill the next cy_card structure available */ for (j = 0; j < NR_CARDS; j++) { - if (cy_card[j].base_addr == NULL) + if (cy_card[j].base_addr == 0) break; } if (j == NR_CARDS) { /* no more cy_cards available */ - printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " - "more cards can be used. Change NR_CARDS in " - "cyclades.c and recompile kernel.\n", + printk("Cyclom-Y/ISA found at 0x%lx ", (unsigned long)cy_isa_address); - iounmap(cy_isa_address); + printk("but no more cards can be used .\n"); + printk("Change NR_CARDS in cyclades.c and recompile " + "kernel.\n"); return nboard; } /* allocate IRQ */ if (request_irq(cy_isa_irq, cyy_interrupt, IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { - printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " - "could not allocate IRQ#%d.\n", - (unsigned long)cy_isa_address, cy_isa_irq); - iounmap(cy_isa_address); + printk("Cyclom-Y/ISA found at 0x%lx ", + (unsigned long)cy_isa_address); + printk("but could not allocate IRQ#%d.\n", cy_isa_irq); return nboard; } @@ -4712,23 +4704,15 @@ static int __init cy_detect_isa(void) cy_card[j].bus_index = 0; cy_card[j].first_line = cy_next_channel; cy_card[j].num_chips = cy_isa_nchan / 4; - if (cy_init_card(&cy_card[j])) { - cy_card[j].base_addr = NULL; - free_irq(cy_isa_irq, &cy_card[j]); - iounmap(cy_isa_address); - continue; - } nboard++; - printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: " - "%d channels starting from port %d\n", + /* print message */ + printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ", j + 1, (unsigned long)cy_isa_address, (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), - cy_isa_irq, cy_isa_nchan, cy_next_channel); - - for (j = cy_next_channel; - j < cy_next_channel + cy_isa_nchan; j++) - tty_register_device(cy_serial_driver, j, NULL); + cy_isa_irq); + printk("%d channels starting from port %d.\n", + cy_isa_nchan, cy_next_channel); cy_next_channel += cy_isa_nchan; } return nboard; @@ -4737,310 +4721,510 @@ static int __init cy_detect_isa(void) #endif /* CONFIG_ISA */ } /* cy_detect_isa */ -#ifdef CONFIG_PCI -static void __devinit plx_init(void __iomem * addr, __u32 initctl) +static void plx_init(void __iomem * addr, uclong initctl) { /* Reset PLX */ - cy_writel(addr + initctl, readl(addr + initctl) | 0x40000000); + cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000); udelay(100L); - cy_writel(addr + initctl, readl(addr + initctl) & ~0x40000000); + cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000); /* Reload Config. Registers from EEPROM */ - cy_writel(addr + initctl, readl(addr + initctl) | 0x20000000); + cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000); udelay(100L); - cy_writel(addr + initctl, readl(addr + initctl) & ~0x20000000); + cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000); } -static int __devinit cy_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +/* + * --------------------------------------------------------------------- + * cy_detect_pci() - Test PCI bus presence and Cyclom-Ye/PCI. + * sets global variables and return the number of PCI boards found. + * --------------------------------------------------------------------- + */ +static int __init cy_detect_pci(void) { - void __iomem *addr0 = NULL, *addr2 = NULL; - char *card_name = NULL; - u32 mailbox; - unsigned int device_id, nchan = 0, card_no, i; - unsigned char plx_ver; - int retval, irq; - - retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "cannot enable device\n"); - goto err; - } +#ifdef CONFIG_PCI - /* read PCI configuration area */ - irq = pdev->irq; - device_id = pdev->device & ~PCI_DEVICE_ID_MASK; + struct pci_dev *pdev = NULL; + unsigned char cyy_rev_id; + unsigned char cy_pci_irq = 0; + uclong cy_pci_phys0, cy_pci_phys2; + void __iomem *cy_pci_addr0, *cy_pci_addr2; + unsigned short i, j, cy_pci_nchan, plx_ver; + unsigned short device_id, dev_index = 0; + uclong mailbox; + uclong ZeIndex = 0; + void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS]; + uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS]; + unsigned char Ze_irq[NR_CARDS]; + struct pci_dev *Ze_pdev[NR_CARDS]; -#if defined(__alpha__) - if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ - dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low " - "addresses on Alpha systems.\n"); - retval = -EIO; - goto err_dis; - } + for (i = 0; i < NR_CARDS; i++) { + /* look for a Cyclades card by vendor and device id */ + while ((device_id = cy_pci_dev_id[dev_index].device) != 0) { + if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES, + device_id, pdev)) == NULL) { + dev_index++; /* try next device id */ + } else { + break; /* found a board */ + } + } + + if (device_id == 0) + break; + + if (pci_enable_device(pdev)) + continue; + + /* read PCI configuration area */ + cy_pci_irq = pdev->irq; + cy_pci_phys0 = pci_resource_start(pdev, 0); + cy_pci_phys2 = pci_resource_start(pdev, 2); + pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id); + + device_id &= ~PCI_DEVICE_ID_MASK; + + if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || + device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { +#ifdef CY_PCI_DEBUG + printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", + pdev->bus->number, pdev->devfn); + printk("rev_id=%d) IRQ%d\n", + cyy_rev_id, (int)cy_pci_irq); + printk("Cyclom-Y/PCI:found winaddr=0x%lx " + "ctladdr=0x%lx\n", + (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); #endif - if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { - dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low " - "addresses\n"); - retval = -EIO; - goto err_dis; - } - if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { - dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring " - "it...\n"); - pdev->resource[2].flags &= ~IORESOURCE_IO; - } + if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { + printk(" Warning: PCI I/O bit incorrectly " + "set. Ignoring it...\n"); + pdev->resource[2].flags &= ~IORESOURCE_IO; + } - retval = pci_request_regions(pdev, "cyclades"); - if (retval) { - dev_err(&pdev->dev, "failed to reserve resources\n"); - goto err_dis; - } + /* Although we don't use this I/O region, we should + request it from the kernel anyway, to avoid problems + with other drivers accessing it. */ + if (pci_request_regions(pdev, "Cyclom-Y") != 0) { + printk(KERN_ERR "cyclades: failed to reserve " + "PCI resources\n"); + continue; + } +#if defined(__alpha__) + if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ + printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", + pdev->bus->number, pdev->devfn); + printk("rev_id=%d) IRQ%d\n", + cyy_rev_id, (int)cy_pci_irq); + printk("Cyclom-Y/PCI:found winaddr=0x%lx " + "ctladdr=0x%lx\n", + (ulong)cy_pci_phys2, + (ulong)cy_pci_phys0); + printk("Cyclom-Y/PCI not supported for low " + "addresses in Alpha systems.\n"); + i--; + continue; + } +#endif + cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl); + cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin); - retval = -EIO; - if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || - device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { - card_name = "Cyclom-Y"; +#ifdef CY_PCI_DEBUG + printk("Cyclom-Y/PCI: relocate winaddr=0x%lx " + "ctladdr=0x%lx\n", + (u_long)cy_pci_addr2, (u_long)cy_pci_addr0); +#endif + cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP * + cyy_init_card(cy_pci_addr2, 1)); + if (cy_pci_nchan == 0) { + printk("Cyclom-Y PCI host card with "); + printk("no Serial-Modules at 0x%lx.\n", + (ulong) cy_pci_phys2); + i--; + continue; + } + if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { + printk("Cyclom-Y/PCI found at 0x%lx ", + (ulong) cy_pci_phys2); + printk("but no channels are available.\n"); + printk("Change NR_PORTS in cyclades.c and " + "recompile kernel.\n"); + return i; + } + /* fill the next cy_card structure available */ + for (j = 0; j < NR_CARDS; j++) { + if (cy_card[j].base_addr == 0) + break; + } + if (j == NR_CARDS) { /* no more cy_cards available */ + printk("Cyclom-Y/PCI found at 0x%lx ", + (ulong) cy_pci_phys2); + printk("but no more cards can be used.\n"); + printk("Change NR_CARDS in cyclades.c and " + "recompile kernel.\n"); + return i; + } - addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); - if (addr0 == NULL) { - dev_err(&pdev->dev, "can't remap ctl region\n"); - goto err_reg; - } - addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); - if (addr2 == NULL) { - dev_err(&pdev->dev, "can't remap base region\n"); - goto err_unmap; - } + /* allocate IRQ */ + if (request_irq(cy_pci_irq, cyy_interrupt, + IRQF_SHARED, "Cyclom-Y", &cy_card[j])) { + printk("Cyclom-Y/PCI found at 0x%lx ", + (ulong) cy_pci_phys2); + printk("but could not allocate IRQ%d.\n", + cy_pci_irq); + return i; + } - nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1); - if (nchan == 0) { - dev_err(&pdev->dev, "Cyclom-Y PCI host card with no " - "Serial-Modules\n"); - return -EIO; - } - } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { - struct RUNTIME_9060 __iomem *ctl_addr; + /* set cy_card */ + cy_card[j].base_phys = (ulong) cy_pci_phys2; + cy_card[j].ctl_phys = (ulong) cy_pci_phys0; + cy_card[j].base_addr = cy_pci_addr2; + cy_card[j].ctl_addr = cy_pci_addr0; + cy_card[j].irq = (int)cy_pci_irq; + cy_card[j].bus_index = 1; + cy_card[j].first_line = cy_next_channel; + cy_card[j].num_chips = cy_pci_nchan / 4; + cy_card[j].pdev = pdev; + + /* enable interrupts in the PCI interface */ + plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f; + switch (plx_ver) { + case PLX_9050: + + cy_writeb(cy_pci_addr0 + 0x4c, 0x43); + break; - ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); - if (addr0 == NULL) { - dev_err(&pdev->dev, "can't remap ctl region\n"); - goto err_reg; - } + case PLX_9060: + case PLX_9080: + default: /* Old boards, use PLX_9060 */ + + plx_init(cy_pci_addr0, 0x6c); + /* For some yet unknown reason, once the PLX9060 reloads + the EEPROM, the IRQ is lost and, thus, we have to + re-write it to the PCI config. registers. + This will remain here until we find a permanent + fix. */ + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, + cy_pci_irq); + + cy_writew(cy_pci_addr0 + 0x68, + cy_readw(cy_pci_addr0 + + 0x68) | 0x0900); + break; + } - /* Disable interrupts on the PLX before resetting it */ - cy_writew(addr0 + 0x68, - readw(addr0 + 0x68) & ~0x0900); - - plx_init(addr0, 0x6c); - /* For some yet unknown reason, once the PLX9060 reloads - the EEPROM, the IRQ is lost and, thus, we have to - re-write it to the PCI config. registers. - This will remain here until we find a permanent - fix. */ - pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); - - mailbox = (u32)readl(&ctl_addr->mail_box_0); - - addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ? - CyPCI_Ze_win : CyPCI_Zwin); - if (addr2 == NULL) { - dev_err(&pdev->dev, "can't remap base region\n"); - goto err_unmap; - } + /* print message */ + printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", + j + 1, (ulong)cy_pci_phys2, + (ulong) (cy_pci_phys2 + CyPCI_Ywin - 1), + (int)cy_pci_irq); + printk("%d channels starting from port %d.\n", + cy_pci_nchan, cy_next_channel); + + cy_next_channel += cy_pci_nchan; + } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { + /* print message */ + printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", + pdev->bus->number, pdev->devfn); + printk("rev_id=%d) IRQ%d\n", + cyy_rev_id, (int)cy_pci_irq); + printk("Cyclades-Z/PCI: found winaddr=0x%lx " + "ctladdr=0x%lx\n", + (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); + printk("Cyclades-Z/PCI not supported for low " + "addresses\n"); + break; + } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { +#ifdef CY_PCI_DEBUG + printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", + pdev->bus->number, pdev->devfn); + printk("rev_id=%d) IRQ%d\n", + cyy_rev_id, (int)cy_pci_irq); + printk("Cyclades-Z/PCI: found winaddr=0x%lx " + "ctladdr=0x%lx\n", + (ulong) cy_pci_phys2, (ulong) cy_pci_phys0); +#endif + cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl); + + /* Disable interrupts on the PLX before resetting it */ + cy_writew(cy_pci_addr0 + 0x68, + cy_readw(cy_pci_addr0 + 0x68) & ~0x0900); + + plx_init(cy_pci_addr0, 0x6c); + /* For some yet unknown reason, once the PLX9060 reloads + the EEPROM, the IRQ is lost and, thus, we have to + re-write it to the PCI config. registers. + This will remain here until we find a permanent + fix. */ + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, + cy_pci_irq); + + mailbox = + (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) + cy_pci_addr0)->mail_box_0); + + if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { + printk(" Warning: PCI I/O bit incorrectly " + "set. Ignoring it...\n"); + pdev->resource[2].flags &= ~IORESOURCE_IO; + } - if (mailbox == ZE_V1) { - card_name = "Cyclades-Ze"; + /* Although we don't use this I/O region, we should + request it from the kernel anyway, to avoid problems + with other drivers accessing it. */ + if (pci_request_regions(pdev, "Cyclades-Z") != 0) { + printk(KERN_ERR "cyclades: failed to reserve " + "PCI resources\n"); + continue; + } - readl(&ctl_addr->mail_box_0); - nchan = ZE_V1_NPORTS; - } else { - card_name = "Cyclades-8Zo"; + if (mailbox == ZE_V1) { + cy_pci_addr2 = ioremap(cy_pci_phys2, + CyPCI_Ze_win); + if (ZeIndex == NR_CARDS) { + printk("Cyclades-Ze/PCI found at " + "0x%lx but no more cards can " + "be used.\nChange NR_CARDS in " + "cyclades.c and recompile " + "kernel.\n", + (ulong)cy_pci_phys2); + } else { + Ze_phys0[ZeIndex] = cy_pci_phys0; + Ze_phys2[ZeIndex] = cy_pci_phys2; + Ze_addr0[ZeIndex] = cy_pci_addr0; + Ze_addr2[ZeIndex] = cy_pci_addr2; + Ze_irq[ZeIndex] = cy_pci_irq; + Ze_pdev[ZeIndex] = pdev; + ZeIndex++; + } + i--; + continue; + } else { + cy_pci_addr2 = ioremap(cy_pci_phys2,CyPCI_Zwin); + } #ifdef CY_PCI_DEBUG + printk("Cyclades-Z/PCI: relocate winaddr=0x%lx " + "ctladdr=0x%lx\n", + (ulong) cy_pci_addr2, (ulong) cy_pci_addr0); if (mailbox == ZO_V1) { - cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); - dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA " - "id %lx, ver %lx\n", (ulong)(0xff & - readl(&((struct CUSTOM_REG *)addr2)-> - fpga_id)), (ulong)(0xff & - readl(&((struct CUSTOM_REG *)addr2)-> - fpga_version))); - cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); + cy_writel(&((struct RUNTIME_9060 *) + (cy_pci_addr0))->loc_addr_base, + WIN_CREG); + PAUSE; + printk("Cyclades-8Zo/PCI: FPGA id %lx, ver " + "%lx\n", (ulong) (0xff & + cy_readl(&((struct CUSTOM_REG *) + (cy_pci_addr2))->fpga_id)), + (ulong)(0xff & + cy_readl(&((struct CUSTOM_REG *) + (cy_pci_addr2))-> + fpga_version))); + cy_writel(&((struct RUNTIME_9060 *) + (cy_pci_addr0))->loc_addr_base, + WIN_RAM); } else { - dev_info(&pdev->dev, "Cyclades-Z/PCI: New " - "Cyclades-Z board. FPGA not loaded\n"); + printk("Cyclades-Z/PCI: New Cyclades-Z board. " + "FPGA not loaded\n"); } #endif /* The following clears the firmware id word. This ensures that the driver will not attempt to talk to the board until it has been properly initialized. */ + PAUSE; if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) - cy_writel(addr2 + ID_ADDRESS, 0L); + cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L); /* This must be a Cyclades-8Zo/PCI. The extendable version will have a different device_id and will be allocated its maximum number of ports. */ - nchan = 8; + cy_pci_nchan = 8; + + if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { + printk("Cyclades-8Zo/PCI found at 0x%lx but" + "no channels are available.\nChange " + "NR_PORTS in cyclades.c and recompile " + "kernel.\n", (ulong)cy_pci_phys2); + return i; + } + + /* fill the next cy_card structure available */ + for (j = 0; j < NR_CARDS; j++) { + if (cy_card[j].base_addr == 0) + break; + } + if (j == NR_CARDS) { /* no more cy_cards available */ + printk("Cyclades-8Zo/PCI found at 0x%lx but" + "no more cards can be used.\nChange " + "NR_CARDS in cyclades.c and recompile " + "kernel.\n", (ulong)cy_pci_phys2); + return i; + } +#ifdef CONFIG_CYZ_INTR + /* allocate IRQ only if board has an IRQ */ + if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { + if (request_irq(cy_pci_irq, cyz_interrupt, + IRQF_SHARED, "Cyclades-Z", + &cy_card[j])) { + printk("Cyclom-8Zo/PCI found at 0x%lx " + "but could not allocate " + "IRQ%d.\n", (ulong)cy_pci_phys2, + cy_pci_irq); + return i; + } + } +#endif /* CONFIG_CYZ_INTR */ + + /* set cy_card */ + cy_card[j].base_phys = cy_pci_phys2; + cy_card[j].ctl_phys = cy_pci_phys0; + cy_card[j].base_addr = cy_pci_addr2; + cy_card[j].ctl_addr = cy_pci_addr0; + cy_card[j].irq = (int)cy_pci_irq; + cy_card[j].bus_index = 1; + cy_card[j].first_line = cy_next_channel; + cy_card[j].num_chips = -1; + cy_card[j].pdev = pdev; + + /* print message */ +#ifdef CONFIG_CYZ_INTR + /* don't report IRQ if board is no IRQ */ + if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) + printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, " + "IRQ%d, ", j + 1, (ulong)cy_pci_phys2, + (ulong) (cy_pci_phys2 + CyPCI_Zwin - 1), + (int)cy_pci_irq); + else +#endif /* CONFIG_CYZ_INTR */ + printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ", + j + 1, (ulong)cy_pci_phys2, + (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1)); + + printk("%d channels starting from port %d.\n", + cy_pci_nchan, cy_next_channel); + cy_next_channel += cy_pci_nchan; } } - if ((cy_next_channel + nchan) > NR_PORTS) { - dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " - "channels are available. Change NR_PORTS in " - "cyclades.c and recompile kernel.\n"); - goto err_unmap; - } - /* fill the next cy_card structure available */ - for (card_no = 0; card_no < NR_CARDS; card_no++) { - if (cy_card[card_no].base_addr == NULL) - break; - } - if (card_no == NR_CARDS) { /* no more cy_cards available */ - dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " - "more cards can be used. Change NR_CARDS in " - "cyclades.c and recompile kernel.\n"); - goto err_unmap; - } + for (; ZeIndex != 0 && i < NR_CARDS; i++) { + cy_pci_phys0 = Ze_phys0[0]; + cy_pci_phys2 = Ze_phys2[0]; + cy_pci_addr0 = Ze_addr0[0]; + cy_pci_addr2 = Ze_addr2[0]; + cy_pci_irq = Ze_irq[0]; + pdev = Ze_pdev[0]; + for (j = 0; j < ZeIndex - 1; j++) { + Ze_phys0[j] = Ze_phys0[j + 1]; + Ze_phys2[j] = Ze_phys2[j + 1]; + Ze_addr0[j] = Ze_addr0[j + 1]; + Ze_addr2[j] = Ze_addr2[j + 1]; + Ze_irq[j] = Ze_irq[j + 1]; + Ze_pdev[j] = Ze_pdev[j + 1]; + } + ZeIndex--; + mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) + cy_pci_addr0)->mail_box_0); +#ifdef CY_PCI_DEBUG + printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n", + (ulong)cy_pci_addr2, (ulong)cy_pci_addr0); + printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not " + "loaded\n"); +#endif + PAUSE; + /* This must be the new Cyclades-Ze/PCI. */ + cy_pci_nchan = ZE_V1_NPORTS; + + if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { + printk("Cyclades-Ze/PCI found at 0x%lx but no channels " + "are available.\nChange NR_PORTS in cyclades.c " + "and recompile kernel.\n", + (ulong) cy_pci_phys2); + return i; + } - if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || - device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { - /* allocate IRQ */ - retval = request_irq(irq, cyy_interrupt, - IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]); - if (retval) { - dev_err(&pdev->dev, "could not allocate IRQ\n"); - goto err_unmap; + /* fill the next cy_card structure available */ + for (j = 0; j < NR_CARDS; j++) { + if (cy_card[j].base_addr == 0) + break; + } + if (j == NR_CARDS) { /* no more cy_cards available */ + printk("Cyclades-Ze/PCI found at 0x%lx but no more " + "cards can be used.\nChange NR_CARDS in " + "cyclades.c and recompile kernel.\n", + (ulong) cy_pci_phys2); + return i; } - cy_card[card_no].num_chips = nchan / 4; - } else { #ifdef CONFIG_CYZ_INTR /* allocate IRQ only if board has an IRQ */ - if (irq != 0 && irq != 255) { - retval = request_irq(irq, cyz_interrupt, + if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { + if (request_irq(cy_pci_irq, cyz_interrupt, IRQF_SHARED, "Cyclades-Z", - &cy_card[card_no]); - if (retval) { - dev_err(&pdev->dev, "could not allocate IRQ\n"); - goto err_unmap; + &cy_card[j])) { + printk("Cyclom-Ze/PCI found at 0x%lx ", + (ulong) cy_pci_phys2); + printk("but could not allocate IRQ%d.\n", + cy_pci_irq); + return i; } } #endif /* CONFIG_CYZ_INTR */ - cy_card[card_no].num_chips = -1; - } - /* set cy_card */ - cy_card[card_no].base_addr = addr2; - cy_card[card_no].ctl_addr = addr0; - cy_card[card_no].irq = irq; - cy_card[card_no].bus_index = 1; - cy_card[card_no].first_line = cy_next_channel; - retval = cy_init_card(&cy_card[card_no]); - if (retval) - goto err_null; - - pci_set_drvdata(pdev, &cy_card[card_no]); - - if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || - device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { - /* enable interrupts in the PCI interface */ - plx_ver = readb(addr2 + CyPLX_VER) & 0x0f; - switch (plx_ver) { - case PLX_9050: - - cy_writeb(addr0 + 0x4c, 0x43); - break; - - case PLX_9060: - case PLX_9080: - default: /* Old boards, use PLX_9060 */ + /* set cy_card */ + cy_card[j].base_phys = cy_pci_phys2; + cy_card[j].ctl_phys = cy_pci_phys0; + cy_card[j].base_addr = cy_pci_addr2; + cy_card[j].ctl_addr = cy_pci_addr0; + cy_card[j].irq = (int)cy_pci_irq; + cy_card[j].bus_index = 1; + cy_card[j].first_line = cy_next_channel; + cy_card[j].num_chips = -1; + cy_card[j].pdev = pdev; - plx_init(addr0, 0x6c); - /* For some yet unknown reason, once the PLX9060 reloads - the EEPROM, the IRQ is lost and, thus, we have to - re-write it to the PCI config. registers. - This will remain here until we find a permanent - fix. */ - pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); + /* print message */ +#ifdef CONFIG_CYZ_INTR + /* don't report IRQ if board is no IRQ */ + if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) + printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", + j + 1, (ulong) cy_pci_phys2, + (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1), + (int)cy_pci_irq); + else +#endif /* CONFIG_CYZ_INTR */ + printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ", + j + 1, (ulong) cy_pci_phys2, + (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1)); - cy_writew(addr0 + 0x68, readw(addr0 + 0x68) | 0x0900); - break; - } + printk("%d channels starting from port %d.\n", + cy_pci_nchan, cy_next_channel); + cy_next_channel += cy_pci_nchan; } - - dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " - "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); - for (i = cy_next_channel; i < cy_next_channel + nchan; i++) - tty_register_device(cy_serial_driver, i, &pdev->dev); - cy_next_channel += nchan; - + if (ZeIndex != 0) { + printk("Cyclades-Ze/PCI found at 0x%x but no more cards can be " + "used.\nChange NR_CARDS in cyclades.c and recompile " + "kernel.\n", (unsigned int)Ze_phys2[0]); + } + return i; +#else return 0; -err_null: - cy_card[card_no].base_addr = NULL; - free_irq(irq, &cy_card[card_no]); -err_unmap: - pci_iounmap(pdev, addr0); - if (addr2) - pci_iounmap(pdev, addr2); -err_reg: - pci_release_regions(pdev); -err_dis: - pci_disable_device(pdev); -err: - return retval; -} +#endif /* ifdef CONFIG_PCI */ +} /* cy_detect_pci */ -static void __devexit cy_pci_remove(struct pci_dev *pdev) +/* + * This routine prints out the appropriate serial driver version number + * and identifies which options were configured into this driver. + */ +static inline void show_version(void) { - struct cyclades_card *cinfo = pci_get_drvdata(pdev); - unsigned int i; - - /* non-Z with old PLX */ - if (!IS_CYC_Z(*cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) == - PLX_9050) - cy_writeb(cinfo->ctl_addr + 0x4c, 0); - else -#ifndef CONFIG_CYZ_INTR - if (!IS_CYC_Z(*cinfo)) -#endif - cy_writew(cinfo->ctl_addr + 0x68, - readw(cinfo->ctl_addr + 0x68) & ~0x0900); - - pci_iounmap(pdev, cinfo->base_addr); - if (cinfo->ctl_addr) - pci_iounmap(pdev, cinfo->ctl_addr); - if (cinfo->irq -#ifndef CONFIG_CYZ_INTR - && !IS_CYC_Z(*cinfo) -#endif /* CONFIG_CYZ_INTR */ - ) - free_irq(cinfo->irq, cinfo); - pci_release_regions(pdev); - - cinfo->base_addr = NULL; - for (i = cinfo->first_line; i < cinfo->first_line + - cinfo->nports; i++) - tty_unregister_device(cy_serial_driver, i); - cinfo->nports = 0; - kfree(cinfo->ports); -} - -static struct pci_driver cy_pci_driver = { - .name = "cyclades", - .id_table = cy_pci_dev_id, - .probe = cy_pci_probe, - .remove = __devexit_p(cy_pci_remove) -}; -#endif + printk("Cyclades driver " CY_VERSION "\n"); + printk(" built %s %s\n", __DATE__, __TIME__); +} /* show_version */ static int cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, int *eof, void *data) { struct cyclades_port *info; - unsigned int i, j; + int i; int len = 0; off_t begin = 0; off_t pos = 0; @@ -5054,34 +5238,33 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, len += size; /* Output one line for each known port */ - for (i = 0; i < NR_CARDS; i++) - for (j = 0; j < cy_card[i].nports; j++) { - info = &cy_card[i].ports[j]; - - if (info->count) - size = sprintf(buf + len, "%3d %8lu %10lu %8lu " - "%10lu %8lu %9lu %6ld\n", info->line, - (cur_jifs - info->idle_stats.in_use) / - HZ, info->idle_stats.xmit_bytes, - (cur_jifs - info->idle_stats.xmit_idle)/ - HZ, info->idle_stats.recv_bytes, - (cur_jifs - info->idle_stats.recv_idle)/ - HZ, info->idle_stats.overruns, - (long)info->tty->ldisc.num); - else - size = sprintf(buf + len, "%3d %8lu %10lu %8lu " - "%10lu %8lu %9lu %6ld\n", - info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); - len += size; - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto done; + for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) { + info = &cy_port[i]; + + if (info->count) + size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " + "%8lu %9lu %6ld\n", info->line, + (cur_jifs - info->idle_stats.in_use) / HZ, + info->idle_stats.xmit_bytes, + (cur_jifs - info->idle_stats.xmit_idle) / HZ, + info->idle_stats.recv_bytes, + (cur_jifs - info->idle_stats.recv_idle) / HZ, + info->idle_stats.overruns, + (long)info->tty->ldisc.num); + else + size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " + "%8lu %9lu %6ld\n", + info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); + len += size; + pos = begin + len; + + if (pos < offset) { + len = 0; + begin = pos; } + if (pos > offset + length) + goto done; + } *eof = 1; done: *start = buf + (offset - begin); /* Start of wanted data */ @@ -5136,15 +5319,18 @@ static const struct tty_operations cy_ops = { static int __init cy_init(void) { - unsigned int nboards; - int retval = -ENOMEM; + struct cyclades_port *info; + struct cyclades_card *cinfo; + int number_z_boards = 0; + int board, port, i, index; + unsigned long mailbox; + unsigned short chip_number; + int nports; cy_serial_driver = alloc_tty_driver(NR_PORTS); if (!cy_serial_driver) - goto err; - - printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n", - __DATE__, __TIME__); + return -ENOMEM; + show_version(); /* Initialize the tty_driver structure */ @@ -5158,13 +5344,15 @@ static int __init cy_init(void) cy_serial_driver->init_termios = tty_std_termios; cy_serial_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(cy_serial_driver, &cy_ops); - retval = tty_register_driver(cy_serial_driver); - if (retval) { - printk(KERN_ERR "Couldn't register Cyclades serial driver\n"); - goto err_frtty; + if (tty_register_driver(cy_serial_driver)) + panic("Couldn't register Cyclades serial driver\n"); + + for (i = 0; i < NR_CARDS; i++) { + /* base_addr=0 indicates board not found */ + cy_card[i].base_addr = NULL; } /* the code below is responsible to find the boards. Each different @@ -5175,68 +5363,223 @@ static int __init cy_init(void) the cy_next_channel. */ /* look for isa boards */ - nboards = cy_detect_isa(); + cy_isa_nboard = cy_detect_isa(); -#ifdef CONFIG_PCI /* look for pci boards */ - retval = pci_register_driver(&cy_pci_driver); - if (retval && !nboards) - goto err_unr; + cy_pci_nboard = cy_detect_pci(); + + cy_nboard = cy_isa_nboard + cy_pci_nboard; + + /* invalidate remaining cy_card structures */ + for (i = 0; i < NR_CARDS; i++) { + if (cy_card[i].base_addr == 0) { + cy_card[i].first_line = -1; + cy_card[i].ctl_addr = NULL; + cy_card[i].irq = 0; + cy_card[i].bus_index = 0; + cy_card[i].first_line = 0; + cy_card[i].num_chips = 0; + } + } + /* invalidate remaining cy_port structures */ + for (i = cy_next_channel; i < NR_PORTS; i++) { + cy_port[i].line = -1; + cy_port[i].magic = -1; + } + + /* initialize per-port data structures for each valid board found */ + for (board = 0; board < cy_nboard; board++) { + cinfo = &cy_card[board]; + if (cinfo->num_chips == -1) { /* Cyclades-Z */ + number_z_boards++; + mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *) + cy_card[board].ctl_addr)-> + mail_box_0); + nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8; + cinfo->intr_enabled = 0; + cinfo->nports = 0; /* Will be correctly set later, after + Z FW is loaded */ + spin_lock_init(&cinfo->card_lock); + for (port = cinfo->first_line; + port < cinfo->first_line + nports; port++) { + info = &cy_port[port]; + info->magic = CYCLADES_MAGIC; + info->type = PORT_STARTECH; + info->card = board; + info->line = port; + info->chip_rev = 0; + info->flags = STD_COM_FLAGS; + info->tty = NULL; + if (mailbox == ZO_V1) + info->xmit_fifo_size = CYZ_FIFO_SIZE; + else + info->xmit_fifo_size = + 4 * CYZ_FIFO_SIZE; + info->cor1 = 0; + info->cor2 = 0; + info->cor3 = 0; + info->cor4 = 0; + info->cor5 = 0; + info->tbpr = 0; + info->tco = 0; + info->rbpr = 0; + info->rco = 0; + info->custom_divisor = 0; + info->close_delay = 5 * HZ / 10; + info->closing_wait = CLOSING_WAIT_DELAY; + info->icount.cts = info->icount.dsr = + info->icount.rng = info->icount.dcd = 0; + info->icount.rx = info->icount.tx = 0; + info->icount.frame = info->icount.parity = 0; + info->icount.overrun = info->icount.brk = 0; + info->x_char = 0; + info->event = 0; + info->count = 0; + info->blocked_open = 0; + info->default_threshold = 0; + info->default_timeout = 0; + INIT_WORK(&info->tqueue, do_softint); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->shutdown_wait); + init_waitqueue_head(&info->delta_msr_wait); + /* info->session */ + /* info->pgrp */ + info->read_status_mask = 0; + /* info->timeout */ + /* Bentson's vars */ + info->jiffies[0] = 0; + info->jiffies[1] = 0; + info->jiffies[2] = 0; + info->rflush_count = 0; +#ifdef CONFIG_CYZ_INTR + init_timer(&cyz_rx_full_timer[port]); + cyz_rx_full_timer[port].function = NULL; #endif + } + continue; + } else { /* Cyclom-Y of some kind */ + index = cinfo->bus_index; + spin_lock_init(&cinfo->card_lock); + cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips; + for (port = cinfo->first_line; + port < cinfo->first_line + cinfo->nports; port++) { + info = &cy_port[port]; + info->magic = CYCLADES_MAGIC; + info->type = PORT_CIRRUS; + info->card = board; + info->line = port; + info->flags = STD_COM_FLAGS; + info->tty = NULL; + info->xmit_fifo_size = CyMAX_CHAR_FIFO; + info->cor1 = + CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; + info->cor2 = CyETC; + info->cor3 = 0x08; /* _very_ small rcv threshold */ + info->cor4 = 0; + info->cor5 = 0; + info->custom_divisor = 0; + info->close_delay = 5 * HZ / 10; + info->closing_wait = CLOSING_WAIT_DELAY; + info->icount.cts = info->icount.dsr = + info->icount.rng = info->icount.dcd = 0; + info->icount.rx = info->icount.tx = 0; + info->icount.frame = info->icount.parity = 0; + info->icount.overrun = info->icount.brk = 0; + chip_number = (port - cinfo->first_line) / 4; + if ((info->chip_rev = + cy_readb(cinfo->base_addr + + (cy_chip_offset[chip_number] << + index) + (CyGFRCR << index))) >= + CD1400_REV_J) { + /* It is a CD1400 rev. J or later */ + info->tbpr = baud_bpr_60[13]; /* Tx BPR */ + info->tco = baud_co_60[13]; /* Tx CO */ + info->rbpr = baud_bpr_60[13]; /* Rx BPR */ + info->rco = baud_co_60[13]; /* Rx CO */ + info->rflow = 0; + info->rtsdtr_inv = 1; + } else { + info->tbpr = baud_bpr_25[13]; /* Tx BPR */ + info->tco = baud_co_25[13]; /* Tx CO */ + info->rbpr = baud_bpr_25[13]; /* Rx BPR */ + info->rco = baud_co_25[13]; /* Rx CO */ + info->rflow = 0; + info->rtsdtr_inv = 0; + } + info->x_char = 0; + info->event = 0; + info->count = 0; + info->blocked_open = 0; + info->default_threshold = 0; + info->default_timeout = 0; + INIT_WORK(&info->tqueue, do_softint); + init_waitqueue_head(&info->open_wait); + init_waitqueue_head(&info->close_wait); + init_waitqueue_head(&info->shutdown_wait); + init_waitqueue_head(&info->delta_msr_wait); + /* info->session */ + /* info->pgrp */ + info->read_status_mask = + CyTIMEOUT | CySPECHAR | CyBREAK + | CyPARITY | CyFRAME | CyOVERRUN; + /* info->timeout */ + } + } + } + +#ifndef CONFIG_CYZ_INTR + if (number_z_boards && !cyz_timeron) { + cyz_timeron++; + cyz_timerlist.expires = jiffies + 1; + add_timer(&cyz_timerlist); +#ifdef CY_PCI_DEBUG + printk("Cyclades-Z polling initialized\n"); +#endif + } +#endif /* CONFIG_CYZ_INTR */ return 0; -err_unr: - tty_unregister_driver(cy_serial_driver); -err_frtty: - put_tty_driver(cy_serial_driver); -err: - return retval; + } /* cy_init */ static void __exit cy_cleanup_module(void) { - struct cyclades_card *card; int i, e1; #ifndef CONFIG_CYZ_INTR - del_timer_sync(&cyz_timerlist); + if (cyz_timeron){ + cyz_timeron = 0; + del_timer(&cyz_timerlist); + } #endif /* CONFIG_CYZ_INTR */ if ((e1 = tty_unregister_driver(cy_serial_driver))) - printk(KERN_ERR "failed to unregister Cyclades serial " - "driver(%d)\n", e1); + printk("cyc: failed to unregister Cyclades serial driver(%d)\n", + e1); -#ifdef CONFIG_PCI - pci_unregister_driver(&cy_pci_driver); -#endif + put_tty_driver(cy_serial_driver); for (i = 0; i < NR_CARDS; i++) { - card = &cy_card[i]; - if (card->base_addr) { - /* clear interrupt */ - cy_writeb(card->base_addr + Cy_ClrIntr, 0); - iounmap(card->base_addr); - if (card->ctl_addr) - iounmap(card->ctl_addr); - if (card->irq + if (cy_card[i].base_addr) { + iounmap(cy_card[i].base_addr); + if (cy_card[i].ctl_addr) + iounmap(cy_card[i].ctl_addr); + if (cy_card[i].irq #ifndef CONFIG_CYZ_INTR - && !IS_CYC_Z(*card) + && cy_card[i].num_chips != -1 /* not a Z card */ #endif /* CONFIG_CYZ_INTR */ ) - free_irq(card->irq, card); - for (e1 = card->first_line; - e1 < card->first_line + - card->nports; e1++) - tty_unregister_device(cy_serial_driver, e1); - kfree(card->ports); + free_irq(cy_card[i].irq, &cy_card[i]); +#ifdef CONFIG_PCI + if (cy_card[i].pdev) + pci_release_regions(cy_card[i].pdev); +#endif } } - - put_tty_driver(cy_serial_driver); } /* cy_cleanup_module */ module_init(cy_init); module_exit(cy_cleanup_module); MODULE_LICENSE("GPL"); -MODULE_VERSION(CY_VERSION); diff --git a/trunk/drivers/char/digi.h b/trunk/drivers/char/digi.h new file mode 100644 index 000000000000..19df0e879b1b --- /dev/null +++ b/trunk/drivers/char/digi.h @@ -0,0 +1,71 @@ +/* Definitions for DigiBoard ditty(1) command. */ + +#if !defined(TIOCMODG) +#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */ +#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */ +#endif + +#if !defined(TIOCMSET) +#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */ +#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */ +#endif + +#if !defined(TIOCMBIC) +#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */ +#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */ +#endif + +#if !defined(TIOCSDTR) +#define TIOCSDTR (('e'<<8) | 0) /* set DTR */ +#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */ +#endif + +/************************************************************************ + * Ioctl command arguments for DIGI parameters. + ************************************************************************/ +#define DIGI_GETA (('e'<<8) | 94) /* Read params */ + +#define DIGI_SETA (('e'<<8) | 95) /* Set params */ +#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */ +#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */ + +#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */ + /* control characters */ +#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */ + /* control characters */ +#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */ + /* flow control chars */ +#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */ + /* flow control chars */ + +struct digiflow_struct { + unsigned char startc; /* flow cntl start char */ + unsigned char stopc; /* flow cntl stop char */ +}; + +typedef struct digiflow_struct digiflow_t; + + +/************************************************************************ + * Values for digi_flags + ************************************************************************/ +#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ +#define DIGI_FAST 0x0002 /* Fast baud rates */ +#define RTSPACE 0x0004 /* RTS input flow control */ +#define CTSPACE 0x0008 /* CTS output flow control */ +#define DSRPACE 0x0010 /* DSR output flow control */ +#define DCDPACE 0x0020 /* DCD output flow control */ +#define DTRPACE 0x0040 /* DTR input flow control */ +#define DIGI_FORCEDCD 0x0100 /* Force carrier */ +#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ +#define DIGI_AIXON 0x0400 /* Aux flow control in fep */ + + +/************************************************************************ + * Structure used with ioctl commands for DIGI parameters. + ************************************************************************/ +struct digi_struct { + unsigned short digi_flags; /* Flags (see above) */ +}; + +typedef struct digi_struct digi_t; diff --git a/trunk/drivers/char/drm/README.drm b/trunk/drivers/char/drm/README.drm index af74cd79a279..6441e01e587c 100644 --- a/trunk/drivers/char/drm/README.drm +++ b/trunk/drivers/char/drm/README.drm @@ -1,6 +1,6 @@ ************************************************************ * For the very latest on DRI development, please see: * -* http://dri.freedesktop.org/ * +* http://dri.sourceforge.net/ * ************************************************************ The Direct Rendering Manager (drm) is a device-independent kernel-level @@ -26,19 +26,21 @@ ways: Documentation on the DRI is available from: - http://dri.freedesktop.org/wiki/Documentation - http://sourceforge.net/project/showfiles.php?group_id=387 - http://dri.sourceforge.net/doc/ + http://precisioninsight.com/piinsights.html For specific information about kernel-level support, see: The Direct Rendering Manager, Kernel Support for the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/drm_low_level.html + http://precisioninsight.com/dr/drm.html Hardware Locking for the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/hardware_locking_low_level.html + http://precisioninsight.com/dr/locking.html A Security Analysis of the Direct Rendering Infrastructure - http://dri.sourceforge.net/doc/security_low_level.html + http://precisioninsight.com/dr/security.html +************************************************************ +* For the very latest on DRI development, please see: * +* http://dri.sourceforge.net/ * +************************************************************ diff --git a/trunk/drivers/char/drm/ati_pcigart.c b/trunk/drivers/char/drm/ati_pcigart.c index 5b91bc04ea4e..bd7be09ea53d 100644 --- a/trunk/drivers/char/drm/ati_pcigart.c +++ b/trunk/drivers/char/drm/ati_pcigart.c @@ -33,44 +33,59 @@ #include "drmP.h" +#if PAGE_SIZE == 65536 +# define ATI_PCIGART_TABLE_ORDER 0 +# define ATI_PCIGART_TABLE_PAGES (1 << 0) +#elif PAGE_SIZE == 16384 +# define ATI_PCIGART_TABLE_ORDER 1 +# define ATI_PCIGART_TABLE_PAGES (1 << 1) +#elif PAGE_SIZE == 8192 +# define ATI_PCIGART_TABLE_ORDER 2 +# define ATI_PCIGART_TABLE_PAGES (1 << 2) +#elif PAGE_SIZE == 4096 +# define ATI_PCIGART_TABLE_ORDER 3 +# define ATI_PCIGART_TABLE_PAGES (1 << 3) +#else +# error - PAGE_SIZE not 64K, 16K, 8K or 4K +#endif + +# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */ # define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ -static void *drm_ati_alloc_pcigart_table(int order) +static void *drm_ati_alloc_pcigart_table(void) { unsigned long address; struct page *page; int i; - - DRM_DEBUG("%s: alloc %d order\n", __FUNCTION__, order); + DRM_DEBUG("%s\n", __FUNCTION__); address = __get_free_pages(GFP_KERNEL | __GFP_COMP, - order); + ATI_PCIGART_TABLE_ORDER); if (address == 0UL) { return NULL; } page = virt_to_page(address); - for (i = 0; i < order; i++, page++) + for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) SetPageReserved(page); DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); return (void *)address; } -static void drm_ati_free_pcigart_table(void *address, int order) +static void drm_ati_free_pcigart_table(void *address) { struct page *page; int i; - int num_pages = 1 << order; DRM_DEBUG("%s\n", __FUNCTION__); page = virt_to_page((unsigned long)address); - for (i = 0; i < num_pages; i++, page++) + for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) ClearPageReserved(page); - free_pages((unsigned long)address, order); + free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER); } int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) @@ -78,8 +93,6 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) drm_sg_mem_t *entry = dev->sg; unsigned long pages; int i; - int order; - int num_pages, max_pages; /* we need to support large memory configurations */ if (!entry) { @@ -87,19 +100,15 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) return 0; } - order = drm_order((gart_info->table_size + (PAGE_SIZE-1)) / PAGE_SIZE); - num_pages = 1 << order; - if (gart_info->bus_addr) { if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { pci_unmap_single(dev->pdev, gart_info->bus_addr, - num_pages * PAGE_SIZE, + ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, PCI_DMA_TODEVICE); } - max_pages = (gart_info->table_size / sizeof(u32)); - pages = (entry->pages <= max_pages) - ? entry->pages : max_pages; + pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) + ? entry->pages : ATI_MAX_PCIGART_PAGES; for (i = 0; i < pages; i++) { if (!entry->busaddr[i]) @@ -114,12 +123,13 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) if (gart_info->gart_table_location == DRM_ATI_GART_MAIN && gart_info->addr) { - drm_ati_free_pcigart_table(gart_info->addr, order); + drm_ati_free_pcigart_table(gart_info->addr); gart_info->addr = NULL; } return 1; } + EXPORT_SYMBOL(drm_ati_pcigart_cleanup); int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) @@ -129,9 +139,6 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) unsigned long pages; u32 *pci_gart, page_base, bus_address = 0; int i, j, ret = 0; - int order; - int max_pages; - int num_pages; if (!entry) { DRM_ERROR("no scatter/gather memory!\n"); @@ -141,10 +148,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); - order = drm_order((gart_info->table_size + - (PAGE_SIZE-1)) / PAGE_SIZE); - num_pages = 1 << order; - address = drm_ati_alloc_pcigart_table(order); + address = drm_ati_alloc_pcigart_table(); if (!address) { DRM_ERROR("cannot allocate PCI GART page!\n"); goto done; @@ -156,13 +160,11 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) } bus_address = pci_map_single(dev->pdev, address, - num_pages * PAGE_SIZE, - PCI_DMA_TODEVICE); + ATI_PCIGART_TABLE_PAGES * + PAGE_SIZE, PCI_DMA_TODEVICE); if (bus_address == 0) { DRM_ERROR("unable to map PCIGART pages!\n"); - order = drm_order((gart_info->table_size + - (PAGE_SIZE-1)) / PAGE_SIZE); - drm_ati_free_pcigart_table(address, order); + drm_ati_free_pcigart_table(address); address = NULL; goto done; } @@ -175,11 +177,10 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) pci_gart = (u32 *) address; - max_pages = (gart_info->table_size / sizeof(u32)); - pages = (entry->pages <= max_pages) - ? entry->pages : max_pages; + pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) + ? entry->pages : ATI_MAX_PCIGART_PAGES; - memset(pci_gart, 0, max_pages * sizeof(u32)); + memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32)); for (i = 0; i < pages; i++) { /* we need to support large memory configurations */ @@ -197,18 +198,10 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) page_base = (u32) entry->busaddr[i]; for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { - switch(gart_info->gart_reg_if) { - case DRM_ATI_GART_IGP: - *pci_gart = cpu_to_le32((page_base) | 0xc); - break; - case DRM_ATI_GART_PCIE: + if (gart_info->is_pcie) *pci_gart = cpu_to_le32((page_base >> 8) | 0xc); - break; - default: - case DRM_ATI_GART_PCI: + else *pci_gart = cpu_to_le32(page_base); - break; - } pci_gart++; page_base += ATI_PCIGART_PAGE_SIZE; } @@ -227,4 +220,5 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) gart_info->bus_addr = bus_address; return ret; } + EXPORT_SYMBOL(drm_ati_pcigart_init); diff --git a/trunk/drivers/char/drm/drm.h b/trunk/drivers/char/drm/drm.h index 089198491f16..8db9041e306c 100644 --- a/trunk/drivers/char/drm/drm.h +++ b/trunk/drivers/char/drm/drm.h @@ -654,13 +654,11 @@ typedef struct drm_set_version { /** * Device specific ioctls should only be in their respective headers - * The device specific ioctl range is from 0x40 to 0x99. - * Generic IOCTLS restart at 0xA0. + * The device specific ioctl range is from 0x40 to 0x79. * * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and * drmCommandReadWrite(). */ #define DRM_COMMAND_BASE 0x40 -#define DRM_COMMAND_END 0xA0 #endif diff --git a/trunk/drivers/char/drm/drmP.h b/trunk/drivers/char/drm/drmP.h index d494315752a2..85d99e21e188 100644 --- a/trunk/drivers/char/drm/drmP.h +++ b/trunk/drivers/char/drm/drmP.h @@ -414,10 +414,6 @@ typedef struct drm_lock_data { struct file *filp; /**< File descr of lock holder (0=kernel) */ wait_queue_head_t lock_queue; /**< Queue of blocked processes */ unsigned long lock_time; /**< Time of last lock in jiffies */ - spinlock_t spinlock; - uint32_t kernel_waiters; - uint32_t user_waiters; - int idle_has_lock; } drm_lock_data_t; /** @@ -519,17 +515,12 @@ typedef struct drm_vbl_sig { #define DRM_ATI_GART_MAIN 1 #define DRM_ATI_GART_FB 2 -#define DRM_ATI_GART_PCI 1 -#define DRM_ATI_GART_PCIE 2 -#define DRM_ATI_GART_IGP 3 - typedef struct ati_pcigart_info { int gart_table_location; - int gart_reg_if; + int is_pcie; void *addr; dma_addr_t bus_addr; drm_local_map_t mapping; - int table_size; } drm_ati_pcigart_info; /* @@ -599,8 +590,6 @@ struct drm_driver { void (*reclaim_buffers) (struct drm_device * dev, struct file * filp); void (*reclaim_buffers_locked) (struct drm_device *dev, struct file *filp); - void (*reclaim_buffers_idlelocked) (struct drm_device *dev, - struct file * filp); unsigned long (*get_map_ofs) (drm_map_t * map); unsigned long (*get_reg_ofs) (struct drm_device * dev); void (*set_version) (struct drm_device * dev, drm_set_version_t * sv); @@ -775,7 +764,7 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, } #ifdef __alpha__ -#define drm_get_pci_domain(dev) dev->hose->index +#define drm_get_pci_domain(dev) dev->hose->bus->number #else #define drm_get_pci_domain(dev) 0 #endif @@ -926,18 +915,9 @@ extern int drm_lock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); extern int drm_unlock(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -extern int drm_lock_take(drm_lock_data_t *lock_data, unsigned int context); -extern int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context); -extern void drm_idlelock_take(drm_lock_data_t *lock_data); -extern void drm_idlelock_release(drm_lock_data_t *lock_data); - -/* - * These are exported to drivers so that they can implement fencing using - * DMA quiscent + idle. DMA quiescent usually requires the hardware lock. - */ - -extern int drm_i_have_hw_lock(struct file *filp); -extern int drm_kernel_take_hw_lock(struct file *filp); +extern int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context); +extern int drm_lock_free(drm_device_t * dev, + __volatile__ unsigned int *lock, unsigned int context); /* Buffer management support (drm_bufs.h) */ extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index c11345856ffe..a6828cc14e58 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -57,8 +57,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, list_for_each(list, &dev->maplist->head) { drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); if (entry->map && map->type == entry->map->type && - ((entry->map->offset == map->offset) || - (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) { + entry->map->offset == map->offset) { return entry; } } @@ -181,20 +180,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, if (map->type == _DRM_REGISTERS) map->handle = ioremap(map->offset, map->size); break; - case _DRM_SHM: - list = drm_find_matching_map(dev, map); - if (list != NULL) { - if(list->map->size != map->size) { - DRM_DEBUG("Matching maps of type %d with " - "mismatched sizes, (%ld vs %ld)\n", - map->type, map->size, list->map->size); - list->map->size = map->size; - } - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - *maplist = list; - return 0; - } + case _DRM_SHM: map->handle = vmalloc_user(map->size); DRM_DEBUG("%lu %d %p\n", map->size, drm_order(map->size), map->handle); @@ -213,45 +200,15 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ } break; - case _DRM_AGP: { - drm_agp_mem_t *entry; - int valid = 0; - - if (!drm_core_has_AGP(dev)) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EINVAL; - } + case _DRM_AGP: + if (drm_core_has_AGP(dev)) { #ifdef __alpha__ - map->offset += dev->hose->mem_space->start; + map->offset += dev->hose->mem_space->start; #endif - /* Note: dev->agp->base may actually be 0 when the DRM - * is not in control of AGP space. But if user space is - * it should already have added the AGP base itself. - */ - map->offset += dev->agp->base; - map->mtrr = dev->agp->agp_mtrr; /* for getmap */ - - /* This assumes the DRM is in total control of AGP space. - * It's not always the case as AGP can be in the control - * of user space (i.e. i810 driver). So this loop will get - * skipped and we double check that dev->agp->memory is - * actually set as well as being invalid before EPERM'ing - */ - for (entry = dev->agp->memory; entry; entry = entry->next) { - if ((map->offset >= entry->bound) && - (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) { - valid = 1; - break; - } + map->offset += dev->agp->base; + map->mtrr = dev->agp->agp_mtrr; /* for getmap */ } - if (dev->agp->memory && !valid) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - return -EPERM; - } - DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size); - break; - } case _DRM_SCATTER_GATHER: if (!dev->sg) { drm_free(map, sizeof(*map), DRM_MEM_MAPS); @@ -310,7 +267,7 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, *maplist = list; return 0; - } +} int drm_addmap(drm_device_t * dev, unsigned int offset, unsigned int size, drm_map_type_t type, @@ -562,7 +519,6 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) { drm_device_dma_t *dma = dev->dma; drm_buf_entry_t *entry; - drm_agp_mem_t *agp_entry; drm_buf_t *buf; unsigned long offset; unsigned long agp_offset; @@ -573,7 +529,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) int page_order; int total; int byte_count; - int i, valid; + int i; drm_buf_t **temp_buflist; if (!dma) @@ -604,19 +560,6 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) if (dev->queue_count) return -EBUSY; /* Not while in use */ - /* Make sure buffers are located in AGP memory that we own */ - valid = 0; - for (agp_entry = dev->agp->memory; agp_entry; agp_entry = agp_entry->next) { - if ((agp_offset >= agp_entry->bound) && - (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) { - valid = 1; - break; - } - } - if (dev->agp->memory && !valid) { - DRM_DEBUG("zone invalid\n"); - return -EINVAL; - } spin_lock(&dev->count_lock); if (dev->buf_use) { spin_unlock(&dev->count_lock); diff --git a/trunk/drivers/char/drm/drm_drv.c b/trunk/drivers/char/drm/drm_drv.c index 8e77b7ed0f44..f5b9b2480c14 100644 --- a/trunk/drivers/char/drm/drm_drv.c +++ b/trunk/drivers/char/drm/drm_drv.c @@ -15,6 +15,8 @@ * #define DRIVER_DESC "Matrox G200/G400" * #define DRIVER_DATE "20001127" * + * #define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( mga_ioctls ) + * * #define drm_x mga_##x * \endcode */ @@ -118,7 +120,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, }; -#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) +#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) /** * Take down the DRM device. @@ -494,14 +496,11 @@ int drm_ioctl(struct inode *inode, struct file *filp, (long)old_encode_dev(priv->head->device), priv->authenticated); - if ((nr >= DRM_CORE_IOCTL_COUNT) && - ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) - goto err_i1; - if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && - (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) - ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; - else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) + if (nr < DRIVER_IOCTL_COUNT) ioctl = &drm_ioctls[nr]; + else if ((nr >= DRM_COMMAND_BASE) + && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) + ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; else goto err_i1; diff --git a/trunk/drivers/char/drm/drm_fops.c b/trunk/drivers/char/drm/drm_fops.c index 3b159cab3bc8..898f47dafec0 100644 --- a/trunk/drivers/char/drm/drm_fops.c +++ b/trunk/drivers/char/drm/drm_fops.c @@ -46,7 +46,6 @@ static int drm_setup(drm_device_t * dev) drm_local_map_t *map; int i; int ret; - u32 sareapage; if (dev->driver->firstopen) { ret = dev->driver->firstopen(dev); @@ -57,8 +56,7 @@ static int drm_setup(drm_device_t * dev) dev->magicfree.next = NULL; /* prebuild the SAREA */ - sareapage = max_t(unsigned, SAREA_MAX, PAGE_SIZE); - i = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); + i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); if (i != 0) return i; @@ -86,7 +84,7 @@ static int drm_setup(drm_device_t * dev) INIT_LIST_HEAD(&dev->ctxlist->head); dev->vmalist = NULL; - dev->sigdata.lock = NULL; + dev->sigdata.lock = dev->lock.hw_lock = NULL; init_waitqueue_head(&dev->lock.lock_queue); dev->queue_count = 0; dev->queue_reserved = 0; @@ -356,55 +354,57 @@ int drm_release(struct inode *inode, struct file *filp) current->pid, (long)old_encode_dev(priv->head->device), dev->open_count); - if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { - if (drm_i_have_hw_lock(filp)) { - dev->driver->reclaim_buffers_locked(dev, filp); - } else { - unsigned long _end=jiffies + 3*DRM_HZ; - int locked = 0; - - drm_idlelock_take(&dev->lock); - - /* - * Wait for a while. - */ - - do{ - spin_lock(&dev->lock.spinlock); - locked = dev->lock.idle_has_lock; - spin_unlock(&dev->lock.spinlock); - if (locked) - break; - schedule(); - } while (!time_after_eq(jiffies, _end)); - - if (!locked) { - DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n" - "\tdriver to use reclaim_buffers_idlelocked() instead.\n" - "\tI will go on reclaiming the buffers anyway.\n"); - } - - dev->driver->reclaim_buffers_locked(dev, filp); - drm_idlelock_release(&dev->lock); - } - } - - if (dev->driver->reclaim_buffers_idlelocked && dev->lock.hw_lock) { - - drm_idlelock_take(&dev->lock); - dev->driver->reclaim_buffers_idlelocked(dev, filp); - drm_idlelock_release(&dev->lock); - - } - - if (drm_i_have_hw_lock(filp)) { + if (priv->lock_count && dev->lock.hw_lock && + _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && + dev->lock.filp == filp) { DRM_DEBUG("File %p released, freeing lock for context %d\n", filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - drm_lock_free(&dev->lock, + if (dev->driver->reclaim_buffers_locked) + dev->driver->reclaim_buffers_locked(dev, filp); + + drm_lock_free(dev, &dev->lock.hw_lock->lock, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); - } + /* FIXME: may require heavy-handed reset of + hardware at this point, possibly + processed via a callback to the X + server. */ + } else if (dev->driver->reclaim_buffers_locked && priv->lock_count + && dev->lock.hw_lock) { + /* The lock is required to reclaim buffers */ + DECLARE_WAITQUEUE(entry, current); + + add_wait_queue(&dev->lock.lock_queue, &entry); + for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); + if (!dev->lock.hw_lock) { + /* Device has been unregistered */ + retcode = -EINTR; + break; + } + if (drm_lock_take(&dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + dev->lock.filp = filp; + dev->lock.lock_time = jiffies; + atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); + break; /* Got lock */ + } + /* Contention */ + schedule(); + if (signal_pending(current)) { + retcode = -ERESTARTSYS; + break; + } + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&dev->lock.lock_queue, &entry); + if (!retcode) { + dev->driver->reclaim_buffers_locked(dev, filp); + drm_lock_free(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT); + } + } if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) && !dev->driver->reclaim_buffers_locked) { diff --git a/trunk/drivers/char/drm/drm_hashtab.c b/trunk/drivers/char/drm/drm_hashtab.c index 31acb621dcce..a0b2d6802ae4 100644 --- a/trunk/drivers/char/drm/drm_hashtab.c +++ b/trunk/drivers/char/drm/drm_hashtab.c @@ -43,16 +43,7 @@ int drm_ht_create(drm_open_hash_t *ht, unsigned int order) ht->size = 1 << order; ht->order = order; ht->fill = 0; - ht->table = NULL; - ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE); - if (!ht->use_vmalloc) { - ht->table = drm_calloc(ht->size, sizeof(*ht->table), - DRM_MEM_HASHTAB); - } - if (!ht->table) { - ht->use_vmalloc = 1; - ht->table = vmalloc(ht->size*sizeof(*ht->table)); - } + ht->table = vmalloc(ht->size*sizeof(*ht->table)); if (!ht->table) { DRM_ERROR("Out of memory for hash table\n"); return -ENOMEM; @@ -192,11 +183,7 @@ int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item) void drm_ht_remove(drm_open_hash_t *ht) { if (ht->table) { - if (ht->use_vmalloc) - vfree(ht->table); - else - drm_free(ht->table, ht->size * sizeof(*ht->table), - DRM_MEM_HASHTAB); + vfree(ht->table); ht->table = NULL; } } diff --git a/trunk/drivers/char/drm/drm_hashtab.h b/trunk/drivers/char/drm/drm_hashtab.h index 613091c970af..40afec05bff8 100644 --- a/trunk/drivers/char/drm/drm_hashtab.h +++ b/trunk/drivers/char/drm/drm_hashtab.h @@ -47,7 +47,6 @@ typedef struct drm_open_hash{ unsigned int order; unsigned int fill; struct hlist_head *table; - int use_vmalloc; } drm_open_hash_t; diff --git a/trunk/drivers/char/drm/drm_irq.c b/trunk/drivers/char/drm/drm_irq.c index 2e75331fd83e..9d00c51fe2c4 100644 --- a/trunk/drivers/char/drm/drm_irq.c +++ b/trunk/drivers/char/drm/drm_irq.c @@ -424,7 +424,7 @@ static void drm_locked_tasklet_func(unsigned long data) spin_lock_irqsave(&dev->tasklet_lock, irqflags); if (!dev->locked_tasklet_func || - !drm_lock_take(&dev->lock, + !drm_lock_take(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT)) { spin_unlock_irqrestore(&dev->tasklet_lock, irqflags); return; @@ -435,7 +435,7 @@ static void drm_locked_tasklet_func(unsigned long data) dev->locked_tasklet_func(dev); - drm_lock_free(&dev->lock, + drm_lock_free(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); dev->locked_tasklet_func = NULL; diff --git a/trunk/drivers/char/drm/drm_lock.c b/trunk/drivers/char/drm/drm_lock.c index befd1af19dfe..e9993ba461a2 100644 --- a/trunk/drivers/char/drm/drm_lock.c +++ b/trunk/drivers/char/drm/drm_lock.c @@ -35,6 +35,9 @@ #include "drmP.h" +static int drm_lock_transfer(drm_device_t * dev, + __volatile__ unsigned int *lock, + unsigned int context); static int drm_notifier(void *priv); /** @@ -77,9 +80,6 @@ int drm_lock(struct inode *inode, struct file *filp, return -EINVAL; add_wait_queue(&dev->lock.lock_queue, &entry); - spin_lock(&dev->lock.spinlock); - dev->lock.user_waiters++; - spin_unlock(&dev->lock.spinlock); for (;;) { __set_current_state(TASK_INTERRUPTIBLE); if (!dev->lock.hw_lock) { @@ -87,7 +87,7 @@ int drm_lock(struct inode *inode, struct file *filp, ret = -EINTR; break; } - if (drm_lock_take(&dev->lock, lock.context)) { + if (drm_lock_take(&dev->lock.hw_lock->lock, lock.context)) { dev->lock.filp = filp; dev->lock.lock_time = jiffies; atomic_inc(&dev->counts[_DRM_STAT_LOCKS]); @@ -101,14 +101,12 @@ int drm_lock(struct inode *inode, struct file *filp, break; } } - spin_lock(&dev->lock.spinlock); - dev->lock.user_waiters--; - spin_unlock(&dev->lock.spinlock); __set_current_state(TASK_RUNNING); remove_wait_queue(&dev->lock.lock_queue, &entry); - DRM_DEBUG( "%d %s\n", lock.context, ret ? "interrupted" : "has lock" ); - if (ret) return ret; + DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); + if (ret) + return ret; sigemptyset(&dev->sigmask); sigaddset(&dev->sigmask, SIGSTOP); @@ -129,12 +127,14 @@ int drm_lock(struct inode *inode, struct file *filp, } } + /* dev->driver->kernel_context_switch isn't used by any of the x86 + * drivers but is used by the Sparc driver. + */ if (dev->driver->kernel_context_switch && dev->last_context != lock.context) { dev->driver->kernel_context_switch(dev, dev->last_context, lock.context); } - return 0; } @@ -184,8 +184,12 @@ int drm_unlock(struct inode *inode, struct file *filp, if (dev->driver->kernel_context_switch_unlock) dev->driver->kernel_context_switch_unlock(dev); else { - if (drm_lock_free(&dev->lock,lock.context)) { - /* FIXME: Should really bail out here. */ + drm_lock_transfer(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT); + + if (drm_lock_free(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + DRM_ERROR("\n"); } } @@ -202,26 +206,18 @@ int drm_unlock(struct inode *inode, struct file *filp, * * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction. */ -int drm_lock_take(drm_lock_data_t *lock_data, - unsigned int context) +int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - spin_lock(&lock_data->spinlock); do { old = *lock; if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT; - else { - new = context | _DRM_LOCK_HELD | - ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ? - _DRM_LOCK_CONT : 0); - } + else + new = context | _DRM_LOCK_HELD; prev = cmpxchg(lock, old, new); } while (prev != old); - spin_unlock(&lock_data->spinlock); - if (_DRM_LOCKING_CONTEXT(old) == context) { if (old & _DRM_LOCK_HELD) { if (context != DRM_KERNEL_CONTEXT) { @@ -231,8 +227,7 @@ int drm_lock_take(drm_lock_data_t *lock_data, return 0; } } - - if ((_DRM_LOCKING_CONTEXT(new)) == context && (new & _DRM_LOCK_HELD)) { + if (new == (context | _DRM_LOCK_HELD)) { /* Have lock */ return 1; } @@ -251,13 +246,13 @@ int drm_lock_take(drm_lock_data_t *lock_data, * Resets the lock file pointer. * Marks the lock as held by the given context, via the \p cmpxchg instruction. */ -static int drm_lock_transfer(drm_lock_data_t *lock_data, +static int drm_lock_transfer(drm_device_t * dev, + __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - lock_data->filp = NULL; + dev->lock.filp = NULL; do { old = *lock; new = context | _DRM_LOCK_HELD; @@ -277,32 +272,23 @@ static int drm_lock_transfer(drm_lock_data_t *lock_data, * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task * waiting on the lock queue. */ -int drm_lock_free(drm_lock_data_t *lock_data, unsigned int context) +int drm_lock_free(drm_device_t * dev, + __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - spin_lock(&lock_data->spinlock); - if (lock_data->kernel_waiters != 0) { - drm_lock_transfer(lock_data, 0); - lock_data->idle_has_lock = 1; - spin_unlock(&lock_data->spinlock); - return 1; - } - spin_unlock(&lock_data->spinlock); + dev->lock.filp = NULL; do { old = *lock; - new = _DRM_LOCKING_CONTEXT(old); + new = 0; prev = cmpxchg(lock, old, new); } while (prev != old); - if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { DRM_ERROR("%d freed heavyweight lock held by %d\n", context, _DRM_LOCKING_CONTEXT(old)); return 1; } - wake_up_interruptible(&lock_data->lock_queue); + wake_up_interruptible(&dev->lock.lock_queue); return 0; } @@ -336,67 +322,3 @@ static int drm_notifier(void *priv) } while (prev != old); return 0; } - -/** - * This function returns immediately and takes the hw lock - * with the kernel context if it is free, otherwise it gets the highest priority when and if - * it is eventually released. - * - * This guarantees that the kernel will _eventually_ have the lock _unless_ it is held - * by a blocked process. (In the latter case an explicit wait for the hardware lock would cause - * a deadlock, which is why the "idlelock" was invented). - * - * This should be sufficient to wait for GPU idle without - * having to worry about starvation. - */ - -void drm_idlelock_take(drm_lock_data_t *lock_data) -{ - int ret = 0; - - spin_lock(&lock_data->spinlock); - lock_data->kernel_waiters++; - if (!lock_data->idle_has_lock) { - - spin_unlock(&lock_data->spinlock); - ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT); - spin_lock(&lock_data->spinlock); - - if (ret == 1) - lock_data->idle_has_lock = 1; - } - spin_unlock(&lock_data->spinlock); -} -EXPORT_SYMBOL(drm_idlelock_take); - -void drm_idlelock_release(drm_lock_data_t *lock_data) -{ - unsigned int old, prev; - volatile unsigned int *lock = &lock_data->hw_lock->lock; - - spin_lock(&lock_data->spinlock); - if (--lock_data->kernel_waiters == 0) { - if (lock_data->idle_has_lock) { - do { - old = *lock; - prev = cmpxchg(lock, old, DRM_KERNEL_CONTEXT); - } while (prev != old); - wake_up_interruptible(&lock_data->lock_queue); - lock_data->idle_has_lock = 0; - } - } - spin_unlock(&lock_data->spinlock); -} -EXPORT_SYMBOL(drm_idlelock_release); - - -int drm_i_have_hw_lock(struct file *filp) -{ - DRM_DEVICE; - - return (priv->lock_count && dev->lock.hw_lock && - _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) && - dev->lock.filp == filp); -} - -EXPORT_SYMBOL(drm_i_have_hw_lock); diff --git a/trunk/drivers/char/drm/drm_mm.c b/trunk/drivers/char/drm/drm_mm.c index 2ec1d9f26264..9b46b85027d0 100644 --- a/trunk/drivers/char/drm/drm_mm.c +++ b/trunk/drivers/char/drm/drm_mm.c @@ -274,6 +274,7 @@ int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) return drm_mm_create_tail_node(mm, start, size); } +EXPORT_SYMBOL(drm_mm_init); void drm_mm_takedown(drm_mm_t * mm) { @@ -294,3 +295,4 @@ void drm_mm_takedown(drm_mm_t * mm) drm_free(entry, sizeof(*entry), DRM_MEM_MM); } +EXPORT_SYMBOL(drm_mm_takedown); diff --git a/trunk/drivers/char/drm/drm_os_linux.h b/trunk/drivers/char/drm/drm_os_linux.h index 0fe7b4497927..2908b72daa6e 100644 --- a/trunk/drivers/char/drm/drm_os_linux.h +++ b/trunk/drivers/char/drm/drm_os_linux.h @@ -70,6 +70,9 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size) #endif +/** Task queue handler arguments */ +#define DRM_TASKQUEUE_ARGS void *arg + /** For data going into the kernel through the ioctl argument */ #define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \ if ( copy_from_user(&arg1, arg2, arg3) ) \ diff --git a/trunk/drivers/char/drm/drm_pciids.h b/trunk/drivers/char/drm/drm_pciids.h index 31cdde83713b..ad54b845978b 100644 --- a/trunk/drivers/char/drm/drm_pciids.h +++ b/trunk/drivers/char/drm/drm_pciids.h @@ -102,7 +102,6 @@ {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ @@ -231,10 +230,10 @@ {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \ - {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \ {0, 0, 0} #define i810_PCI_IDS \ @@ -297,6 +296,5 @@ {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} diff --git a/trunk/drivers/char/drm/drm_proc.c b/trunk/drivers/char/drm/drm_proc.c index b204498d1a28..7fd0da712142 100644 --- a/trunk/drivers/char/drm/drm_proc.c +++ b/trunk/drivers/char/drm/drm_proc.c @@ -72,7 +72,7 @@ static struct drm_proc_list { #endif }; -#define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list) +#define DRM_PROC_ENTRIES (sizeof(drm_proc_list)/sizeof(drm_proc_list[0])) /** * Initialize the DRI proc filesystem for a device. diff --git a/trunk/drivers/char/drm/drm_stub.c b/trunk/drivers/char/drm/drm_stub.c index 19408adcc775..120d10256feb 100644 --- a/trunk/drivers/char/drm/drm_stub.c +++ b/trunk/drivers/char/drm/drm_stub.c @@ -62,7 +62,6 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, spin_lock_init(&dev->count_lock); spin_lock_init(&dev->drw_lock); spin_lock_init(&dev->tasklet_lock); - spin_lock_init(&dev->lock.spinlock); init_timer(&dev->timer); mutex_init(&dev->struct_mutex); mutex_init(&dev->ctxlist_mutex); diff --git a/trunk/drivers/char/drm/drm_vm.c b/trunk/drivers/char/drm/drm_vm.c index 35540cfb43dd..54a632848955 100644 --- a/trunk/drivers/char/drm/drm_vm.c +++ b/trunk/drivers/char/drm/drm_vm.c @@ -41,30 +41,6 @@ static void drm_vm_open(struct vm_area_struct *vma); static void drm_vm_close(struct vm_area_struct *vma); -static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma) -{ - pgprot_t tmp = vm_get_page_prot(vma->vm_flags); - -#if defined(__i386__) || defined(__x86_64__) - if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) { - pgprot_val(tmp) |= _PAGE_PCD; - pgprot_val(tmp) &= ~_PAGE_PWT; - } -#elif defined(__powerpc__) - pgprot_val(tmp) |= _PAGE_NO_CACHE; - if (map_type == _DRM_REGISTERS) - pgprot_val(tmp) |= _PAGE_GUARDED; -#endif -#if defined(__ia64__) - if (efi_range_is_wc(vma->vm_start, vma->vm_end - - vma->vm_start)) - tmp = pgprot_writecombine(tmp); - else - tmp = pgprot_noncached(tmp); -#endif - return tmp; -} - /** * \c nopage method for AGP virtual memory. * @@ -175,7 +151,8 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, offset = address - vma->vm_start; i = (unsigned long)map->handle + offset; - page = vmalloc_to_page((void *)i); + page = (map->type == _DRM_CONSISTENT) ? + virt_to_page((void *)i) : vmalloc_to_page((void *)i); if (!page) return NOPAGE_SIGBUS; get_page(page); @@ -412,7 +389,7 @@ static struct vm_operations_struct drm_vm_sg_ops = { * Create a new drm_vma_entry structure as the \p vma private data entry and * add it to drm_device::vmalist. */ -static void drm_vm_open_locked(struct vm_area_struct *vma) +static void drm_vm_open(struct vm_area_struct *vma) { drm_file_t *priv = vma->vm_file->private_data; drm_device_t *dev = priv->head->dev; @@ -424,23 +401,15 @@ static void drm_vm_open_locked(struct vm_area_struct *vma) vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); if (vma_entry) { + mutex_lock(&dev->struct_mutex); vma_entry->vma = vma; vma_entry->next = dev->vmalist; vma_entry->pid = current->pid; dev->vmalist = vma_entry; + mutex_unlock(&dev->struct_mutex); } } -static void drm_vm_open(struct vm_area_struct *vma) -{ - drm_file_t *priv = vma->vm_file->private_data; - drm_device_t *dev = priv->head->dev; - - mutex_lock(&dev->struct_mutex); - drm_vm_open_locked(vma); - mutex_unlock(&dev->struct_mutex); -} - /** * \c close method for all virtual memory types. * @@ -491,6 +460,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) drm_device_dma_t *dma; unsigned long length = vma->vm_end - vma->vm_start; + lock_kernel(); dev = priv->head->dev; dma = dev->dma; DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n", @@ -498,8 +468,10 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) /* Length must match exact page count */ if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { + unlock_kernel(); return -EINVAL; } + unlock_kernel(); if (!capable(CAP_SYS_ADMIN) && (dma->flags & _DRM_DMA_USE_PCI_RO)) { @@ -522,7 +494,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; /* Don't swap */ vma->vm_file = filp; /* Needed for drm_vm_open() */ - drm_vm_open_locked(vma); + drm_vm_open(vma); return 0; } @@ -557,7 +529,7 @@ EXPORT_SYMBOL(drm_core_get_reg_ofs); * according to the mapping type and remaps the pages. Finally sets the file * pointer and calls vm_open(). */ -static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) +int drm_mmap(struct file *filp, struct vm_area_struct *vma) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; @@ -593,7 +565,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) return -EPERM; /* Check for valid size. */ - if (map->size < vma->vm_end - vma->vm_start) + if (map->size != vma->vm_end - vma->vm_start) return -EINVAL; if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) { @@ -628,16 +600,37 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) /* fall through to _DRM_FRAME_BUFFER... */ case _DRM_FRAME_BUFFER: case _DRM_REGISTERS: - offset = dev->driver->get_reg_ofs(dev); +#if defined(__i386__) || defined(__x86_64__) + if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) { + pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; + pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; + } +#elif defined(__powerpc__) + pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE; + if (map->type == _DRM_REGISTERS) + pgprot_val(vma->vm_page_prot) |= _PAGE_GUARDED; +#endif vma->vm_flags |= VM_IO; /* not in core dump */ - vma->vm_page_prot = drm_io_prot(map->type, vma); +#if defined(__ia64__) + if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start)) + vma->vm_page_prot = + pgprot_writecombine(vma->vm_page_prot); + else + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +#endif + offset = dev->driver->get_reg_ofs(dev); #ifdef __sparc__ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -#endif if (io_remap_pfn_range(vma, vma->vm_start, (map->offset + offset) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) +#else + if (io_remap_pfn_range(vma, vma->vm_start, + (map->offset + offset) >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, + vma->vm_page_prot)) +#endif return -EAGAIN; DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," " offset = 0x%lx\n", @@ -645,15 +638,10 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) vma->vm_start, vma->vm_end, map->offset + offset); vma->vm_ops = &drm_vm_ops; break; - case _DRM_CONSISTENT: - /* Consistent memory is really like shared memory. But - * it's allocated in a different way, so avoid nopage */ - if (remap_pfn_range(vma, vma->vm_start, - page_to_pfn(virt_to_page(map->handle)), - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - /* fall through to _DRM_SHM */ case _DRM_SHM: + case _DRM_CONSISTENT: + /* Consistent memory is really like shared memory. It's only + * allocate in a different way */ vma->vm_ops = &drm_vm_shm_ops; vma->vm_private_data = (void *)map; /* Don't let this area swap. Change when @@ -671,20 +659,8 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; /* Don't swap */ vma->vm_file = filp; /* Needed for drm_vm_open() */ - drm_vm_open_locked(vma); + drm_vm_open(vma); return 0; } -int drm_mmap(struct file *filp, struct vm_area_struct *vma) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->head->dev; - int ret; - - mutex_lock(&dev->struct_mutex); - ret = drm_mmap_locked(filp, vma); - mutex_unlock(&dev->struct_mutex); - - return ret; -} EXPORT_SYMBOL(drm_mmap); diff --git a/trunk/drivers/char/drm/i915_dma.c b/trunk/drivers/char/drm/i915_dma.c index 1ba15d9a171a..9354ce3b0093 100644 --- a/trunk/drivers/char/drm/i915_dma.c +++ b/trunk/drivers/char/drm/i915_dma.c @@ -34,8 +34,7 @@ #define IS_I965G(dev) (dev->pci_device == 0x2972 || \ dev->pci_device == 0x2982 || \ dev->pci_device == 0x2992 || \ - dev->pci_device == 0x29A2 || \ - dev->pci_device == 0x2A02) + dev->pci_device == 0x29A2) /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time diff --git a/trunk/drivers/char/drm/r128_cce.c b/trunk/drivers/char/drm/r128_cce.c index 1014602c43a7..db5a60450e68 100644 --- a/trunk/drivers/char/drm/r128_cce.c +++ b/trunk/drivers/char/drm/r128_cce.c @@ -560,10 +560,9 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init) if (dev_priv->is_pci) { #endif dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; - dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE; dev_priv->gart_info.addr = NULL; dev_priv->gart_info.bus_addr = 0; - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; + dev_priv->gart_info.is_pcie = 0; if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { DRM_ERROR("failed to init PCI GART!\n"); dev->dev_private = (void *)dev_priv; diff --git a/trunk/drivers/char/drm/r128_drv.h b/trunk/drivers/char/drm/r128_drv.h index 9086835686dc..f1efb49de8df 100644 --- a/trunk/drivers/char/drm/r128_drv.h +++ b/trunk/drivers/char/drm/r128_drv.h @@ -383,8 +383,6 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd, #define R128_PERFORMANCE_BOXES 0 -#define R128_PCIGART_TABLE_SIZE 32768 - #define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) #define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) diff --git a/trunk/drivers/char/drm/radeon_cp.c b/trunk/drivers/char/drm/radeon_cp.c index 68338389d836..5ed965688293 100644 --- a/trunk/drivers/char/drm/radeon_cp.c +++ b/trunk/drivers/char/drm/radeon_cp.c @@ -830,15 +830,6 @@ static int RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) return RADEON_READ(RADEON_PCIE_DATA); } -static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr) -{ - u32 ret; - RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f); - ret = RADEON_READ(RADEON_IGPGART_DATA); - RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f); - return ret; -} - #if RADEON_FIFO_DEBUG static void radeon_status(drm_radeon_private_t * dev_priv) { @@ -1276,44 +1267,7 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) } } -/* Enable or disable IGP GART on the chip */ -static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) -{ - u32 temp, tmp; - - tmp = RADEON_READ(RADEON_AIC_CNTL); - if (on) { - DRM_DEBUG("programming igpgart %08X %08lX %08X\n", - dev_priv->gart_vm_start, - (long)dev_priv->gart_info.bus_addr, - dev_priv->gart_size); - - RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000); - RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, 0x1); - RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800); - RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR, - dev_priv->gart_info.bus_addr); - - temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39); - RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp); - - RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start); - dev_priv->gart_size = 32*1024*1024; - RADEON_WRITE(RADEON_MC_AGP_LOCATION, - (((dev_priv->gart_vm_start - 1 + - dev_priv->gart_size) & 0xffff0000) | - (dev_priv->gart_vm_start >> 16))); - - temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_ENABLE); - RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, temp); - - RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); - RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1); - RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH); - RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0); - } -} - +/* Enable or disable PCI-E GART on the chip */ static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) { u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); @@ -1348,11 +1302,6 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { u32 tmp; - if (dev_priv->flags & RADEON_IS_IGPGART) { - radeon_set_igpgart(dev_priv, on); - return; - } - if (dev_priv->flags & RADEON_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; @@ -1611,8 +1560,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) if (dev_priv->flags & RADEON_IS_AGP) { base = dev->agp->base; /* Check if valid */ - if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location && - base < (dev_priv->fb_location + dev_priv->fb_size - 1)) { + if ((base + dev_priv->gart_size) > dev_priv->fb_location && + base < (dev_priv->fb_location + dev_priv->fb_size)) { DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n", dev->agp->base); base = 0; @@ -1622,8 +1571,8 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) /* If not or if AGP is at 0 (Macs), try to put it elsewhere */ if (base == 0) { base = dev_priv->fb_location + dev_priv->fb_size; - if (base < dev_priv->fb_location || - ((base + dev_priv->gart_size) & 0xfffffffful) < base) + if (((base + dev_priv->gart_size) & 0xfffffffful) + < base) base = dev_priv->fb_location - dev_priv->gart_size; } @@ -1671,22 +1620,20 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) #endif { /* if we have an offset set from userspace */ - if (dev_priv->pcigart_offset_set) { + if (dev_priv->pcigart_offset) { dev_priv->gart_info.bus_addr = dev_priv->pcigart_offset + dev_priv->fb_location; dev_priv->gart_info.mapping.offset = dev_priv->gart_info.bus_addr; dev_priv->gart_info.mapping.size = - dev_priv->gart_info.table_size; + RADEON_PCIGART_TABLE_SIZE; drm_core_ioremap(&dev_priv->gart_info.mapping, dev); dev_priv->gart_info.addr = dev_priv->gart_info.mapping.handle; - if (dev_priv->flags & RADEON_IS_PCIE) - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE; - else - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; + dev_priv->gart_info.is_pcie = + !!(dev_priv->flags & RADEON_IS_PCIE); dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; @@ -1694,10 +1641,6 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->gart_info.addr, dev_priv->pcigart_offset); } else { - if (dev_priv->flags & RADEON_IS_IGPGART) - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP; - else - dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI; dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; dev_priv->gart_info.addr = NULL; @@ -1771,7 +1714,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) { drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); - dev_priv->gart_info.addr = 0; + dev_priv->gart_info.addr = NULL; } } /* only clear to the start of flags */ @@ -2279,8 +2222,6 @@ int radeon_driver_firstopen(struct drm_device *dev) drm_local_map_t *map; drm_radeon_private_t *dev_priv = dev->dev_private; - dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - ret = drm_addmap(dev, drm_get_resource_start(dev, 2), drm_get_resource_len(dev, 2), _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); diff --git a/trunk/drivers/char/drm/radeon_drm.h b/trunk/drivers/char/drm/radeon_drm.h index 66c4b6fed04f..8d6350dd5360 100644 --- a/trunk/drivers/char/drm/radeon_drm.h +++ b/trunk/drivers/char/drm/radeon_drm.h @@ -707,7 +707,6 @@ typedef struct drm_radeon_setparam { #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ -#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ /* 1.14: Clients can allocate/free a surface */ diff --git a/trunk/drivers/char/drm/radeon_drv.h b/trunk/drivers/char/drm/radeon_drv.h index 54f49ef4bef0..8b105f1460a7 100644 --- a/trunk/drivers/char/drm/radeon_drv.h +++ b/trunk/drivers/char/drm/radeon_drv.h @@ -95,11 +95,9 @@ * 1.24- Add general-purpose packet for manipulating scratch registers (r300) * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, * new packet type) - * 1.26- Add support for variable size PCI(E) gart aperture - * 1.27- Add support for IGP GART */ #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 27 +#define DRIVER_MINOR 25 #define DRIVER_PATCHLEVEL 0 /* @@ -145,7 +143,6 @@ enum radeon_chip_flags { RADEON_IS_PCIE = 0x00200000UL, RADEON_NEW_MEMMAP = 0x00400000UL, RADEON_IS_PCI = 0x00800000UL, - RADEON_IS_IGPGART = 0x01000000UL, }; #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ @@ -243,6 +240,7 @@ typedef struct drm_radeon_private { int do_boxes; int page_flipping; + int current_page; u32 color_fmt; unsigned int front_offset; @@ -282,7 +280,6 @@ typedef struct drm_radeon_private { struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES]; unsigned long pcigart_offset; - unsigned int pcigart_offset_set; drm_ati_pcigart_info gart_info; u32 scratch_ages[5]; @@ -435,15 +432,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_PCIE_TX_GART_END_LO 0x16 #define RADEON_PCIE_TX_GART_END_HI 0x17 -#define RADEON_IGPGART_INDEX 0x168 -#define RADEON_IGPGART_DATA 0x16c -#define RADEON_IGPGART_UNK_18 0x18 -#define RADEON_IGPGART_CTRL 0x2b -#define RADEON_IGPGART_BASE_ADDR 0x2c -#define RADEON_IGPGART_FLUSH 0x2e -#define RADEON_IGPGART_ENABLE 0x38 -#define RADEON_IGPGART_UNK_39 0x39 - #define RADEON_MPP_TB_CONFIG 0x01c0 #define RADEON_MEM_CNTL 0x0140 #define RADEON_MEM_SDRAM_MODE_REG 0x0158 @@ -976,14 +964,6 @@ do { \ RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \ } while (0) -#define RADEON_WRITE_IGPGART( addr, val ) \ -do { \ - RADEON_WRITE( RADEON_IGPGART_INDEX, \ - ((addr) & 0x7f) | (1 << 8)); \ - RADEON_WRITE( RADEON_IGPGART_DATA, (val) ); \ - RADEON_WRITE( RADEON_IGPGART_INDEX, 0x7f ); \ -} while (0) - #define RADEON_WRITE_PCIE( addr, val ) \ do { \ RADEON_WRITE8( RADEON_PCIE_INDEX, \ diff --git a/trunk/drivers/char/drm/radeon_state.c b/trunk/drivers/char/drm/radeon_state.c index 98c5f1d3a8e7..938eccb78cc0 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -773,7 +773,7 @@ static void radeon_clear_box(drm_radeon_private_t * dev_priv, RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS); - if (dev_priv->sarea_priv->pfCurrentPage == 1) { + if (dev_priv->page_flipping && dev_priv->current_page == 1) { OUT_RING(dev_priv->front_pitch_offset); } else { OUT_RING(dev_priv->back_pitch_offset); @@ -861,7 +861,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, dev_priv->stats.clears++; - if (dev_priv->sarea_priv->pfCurrentPage == 1) { + if (dev_priv->page_flipping && dev_priv->current_page == 1) { unsigned int tmp = flags; flags &= ~(RADEON_FRONT | RADEON_BACK); @@ -1382,7 +1382,7 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) /* Make this work even if front & back are flipped: */ OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); - if (dev_priv->sarea_priv->pfCurrentPage == 0) { + if (dev_priv->current_page == 0) { OUT_RING(dev_priv->back_pitch_offset); OUT_RING(dev_priv->front_pitch_offset); } else { @@ -1416,12 +1416,12 @@ static void radeon_cp_dispatch_flip(drm_device_t * dev) { drm_radeon_private_t *dev_priv = dev->dev_private; drm_sarea_t *sarea = (drm_sarea_t *) dev_priv->sarea->handle; - int offset = (dev_priv->sarea_priv->pfCurrentPage == 1) + int offset = (dev_priv->current_page == 1) ? dev_priv->front_offset : dev_priv->back_offset; RING_LOCALS; - DRM_DEBUG("%s: pfCurrentPage=%d\n", + DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", __FUNCTION__, - dev_priv->sarea_priv->pfCurrentPage); + dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage); /* Do some trivial performance monitoring... */ @@ -1449,8 +1449,8 @@ static void radeon_cp_dispatch_flip(drm_device_t * dev) * performing the swapbuffer ioctl. */ dev_priv->sarea_priv->last_frame++; - dev_priv->sarea_priv->pfCurrentPage = - 1 - dev_priv->sarea_priv->pfCurrentPage; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = + 1 - dev_priv->current_page; BEGIN_RING(2); @@ -2152,10 +2152,24 @@ static int radeon_do_init_pageflip(drm_device_t * dev) ADVANCE_RING(); dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; - if (dev_priv->sarea_priv->pfCurrentPage != 1) - dev_priv->sarea_priv->pfCurrentPage = 0; + return 0; +} + +/* Called whenever a client dies, from drm_release. + * NOTE: Lock isn't necessarily held when this is called! + */ +static int radeon_do_cleanup_pageflip(drm_device_t * dev) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG("\n"); + + if (dev_priv->current_page != 0) + radeon_cp_dispatch_flip(dev); + dev_priv->page_flipping = 0; return 0; } @@ -3131,16 +3145,10 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS) break; case RADEON_SETPARAM_PCIGART_LOCATION: dev_priv->pcigart_offset = sp.value; - dev_priv->pcigart_offset_set = 1; break; case RADEON_SETPARAM_NEW_MEMMAP: dev_priv->new_memmap = sp.value; break; - case RADEON_SETPARAM_PCIGART_TABLE_SIZE: - dev_priv->gart_info.table_size = sp.value; - if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE) - dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE; - break; default: DRM_DEBUG("Invalid parameter %d\n", sp.param); return DRM_ERR(EINVAL); @@ -3160,7 +3168,9 @@ void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) { if (dev->dev_private) { drm_radeon_private_t *dev_priv = dev->dev_private; - dev_priv->page_flipping = 0; + if (dev_priv->page_flipping) { + radeon_do_cleanup_pageflip(dev); + } radeon_mem_release(filp, dev_priv->gart_heap); radeon_mem_release(filp, dev_priv->fb_heap); radeon_surfaces_release(filp, dev_priv); @@ -3169,14 +3179,6 @@ void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp) void radeon_driver_lastclose(drm_device_t * dev) { - if (dev->dev_private) { - drm_radeon_private_t *dev_priv = dev->dev_private; - - if (dev_priv->sarea_priv && - dev_priv->sarea_priv->pfCurrentPage != 0) - radeon_cp_dispatch_flip(dev); - } - radeon_do_release(dev); } diff --git a/trunk/drivers/char/drm/sis_drv.c b/trunk/drivers/char/drm/sis_drv.c index 690e0af8e7c2..3d5b3218b6ff 100644 --- a/trunk/drivers/char/drm/sis_drv.c +++ b/trunk/drivers/char/drm/sis_drv.c @@ -71,7 +71,7 @@ static struct drm_driver driver = { .context_dtor = NULL, .dma_quiescent = sis_idle, .reclaim_buffers = NULL, - .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, + .reclaim_buffers_locked = sis_reclaim_buffers_locked, .lastclose = sis_lastclose, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, diff --git a/trunk/drivers/char/drm/via_dma.c b/trunk/drivers/char/drm/via_dma.c index 13a9c5ca4593..c0539c6299cf 100644 --- a/trunk/drivers/char/drm/via_dma.c +++ b/trunk/drivers/char/drm/via_dma.c @@ -252,7 +252,7 @@ static int via_dma_init(DRM_IOCTL_ARGS) break; case VIA_DMA_INITIALIZED: retcode = (dev_priv->ring.virtual_start != NULL) ? - 0 : DRM_ERR(EFAULT); + 0 : DRM_ERR(EFAULT); break; default: retcode = DRM_ERR(EINVAL); @@ -432,34 +432,56 @@ static int via_hook_segment(drm_via_private_t * dev_priv, { int paused, count; volatile uint32_t *paused_at = dev_priv->last_pause_ptr; - uint32_t reader,ptr; - paused = 0; via_flush_write_combine(); - (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1); - *paused_at = pause_addr_lo; + while (!*(via_get_dma(dev_priv) - 1)) ; + *dev_priv->last_pause_ptr = pause_addr_lo; via_flush_write_combine(); - (void) *paused_at; - reader = *(dev_priv->hw_addr_ptr); - ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + - dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; + + /* + * The below statement is inserted to really force the flush. + * Not sure it is needed. + */ + + while (!*dev_priv->last_pause_ptr) ; dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1; + while (!*dev_priv->last_pause_ptr) ; - if ((ptr - reader) <= dev_priv->dma_diff ) { - count = 10000000; - while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--); + paused = 0; + count = 20; + + while (!(paused = (VIA_READ(0x41c) & 0x80000000)) && count--) ; + if ((count <= 8) && (count >= 0)) { + uint32_t rgtr, ptr; + rgtr = *(dev_priv->hw_addr_ptr); + ptr = ((volatile char *)dev_priv->last_pause_ptr - + dev_priv->dma_ptr) + dev_priv->dma_offset + + (uint32_t) dev_priv->agpAddr + 4 - CMDBUF_ALIGNMENT_SIZE; + if (rgtr <= ptr) { + DRM_ERROR + ("Command regulator\npaused at count %d, address %x, " + "while current pause address is %x.\n" + "Please mail this message to " + "\n", count, + rgtr, ptr); + } } if (paused && !no_pci_fire) { - reader = *(dev_priv->hw_addr_ptr); - if ((ptr - reader) == dev_priv->dma_diff) { + uint32_t rgtr, ptr; + uint32_t ptr_low; - /* - * There is a concern that these writes may stall the PCI bus - * if the GPU is not idle. However, idling the GPU first - * doesn't make a difference. - */ + count = 1000000; + while ((VIA_READ(VIA_REG_STATUS) & VIA_CMD_RGTR_BUSY) + && count--) ; + rgtr = *(dev_priv->hw_addr_ptr); + ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) + + dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; + + ptr_low = (ptr > 3 * CMDBUF_ALIGNMENT_SIZE) ? + ptr - 3 * CMDBUF_ALIGNMENT_SIZE : 0; + if (rgtr <= ptr && rgtr >= ptr_low) { VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi); VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo); @@ -472,9 +494,6 @@ static int via_hook_segment(drm_via_private_t * dev_priv, static int via_wait_idle(drm_via_private_t * dev_priv) { int count = 10000000; - - while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && count--); - while (count-- && (VIA_READ(VIA_REG_STATUS) & (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY))) ; @@ -518,9 +537,6 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) uint32_t end_addr, end_addr_lo; uint32_t command; uint32_t agp_base; - uint32_t ptr; - uint32_t reader; - int count; dev_priv->dma_low = 0; @@ -538,7 +554,7 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) &pause_addr_hi, &pause_addr_lo, 1) - 1; via_flush_write_combine(); - (void) *(volatile uint32_t *)dev_priv->last_pause_ptr; + while (!*dev_priv->last_pause_ptr) ; VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16)); VIA_WRITE(VIA_REG_TRANSPACE, command); @@ -550,24 +566,6 @@ static void via_cmdbuf_start(drm_via_private_t * dev_priv) DRM_WRITEMEMORYBARRIER(); VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK); VIA_READ(VIA_REG_TRANSPACE); - - dev_priv->dma_diff = 0; - - count = 10000000; - while (!(VIA_READ(0x41c) & 0x80000000) && count--); - - reader = *(dev_priv->hw_addr_ptr); - ptr = ((volatile char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) + - dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4; - - /* - * This is the difference between where we tell the - * command reader to pause and where it actually pauses. - * This differs between hw implementation so we need to - * detect it. - */ - - dev_priv->dma_diff = ptr - reader; } static void via_pad_cache(drm_via_private_t * dev_priv, int qwords) @@ -594,6 +592,7 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) uint32_t pause_addr_lo, pause_addr_hi; uint32_t jump_addr_lo, jump_addr_hi; volatile uint32_t *last_pause_ptr; + uint32_t dma_low_save1, dma_low_save2; agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr; via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi, @@ -620,10 +619,30 @@ static void via_cmdbuf_jump(drm_via_private_t * dev_priv) &pause_addr_lo, 0); *last_pause_ptr = pause_addr_lo; + dma_low_save1 = dev_priv->dma_low; - via_hook_segment( dev_priv, jump_addr_hi, jump_addr_lo, 0); -} + /* + * Now, set a trap that will pause the regulator if it tries to rerun the old + * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause + * and reissues the jump command over PCI, while the regulator has already taken the jump + * and actually paused at the current buffer end). + * There appears to be no other way to detect this condition, since the hw_addr_pointer + * does not seem to get updated immediately when a jump occurs. + */ + last_pause_ptr = + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + &pause_addr_lo, 0) - 1; + via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi, + &pause_addr_lo, 0); + *last_pause_ptr = pause_addr_lo; + + dma_low_save2 = dev_priv->dma_low; + dev_priv->dma_low = dma_low_save1; + via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0); + dev_priv->dma_low = dma_low_save2; + via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0); +} static void via_cmdbuf_rewind(drm_via_private_t * dev_priv) { diff --git a/trunk/drivers/char/drm/via_drv.c b/trunk/drivers/char/drm/via_drv.c index 2d4957ab256a..bb9dde8b1911 100644 --- a/trunk/drivers/char/drm/via_drv.c +++ b/trunk/drivers/char/drm/via_drv.c @@ -52,8 +52,7 @@ static struct drm_driver driver = { .dma_quiescent = via_driver_dma_quiescent, .dri_library_name = dri_library_name, .reclaim_buffers = drm_core_reclaim_buffers, - .reclaim_buffers_locked = NULL, - .reclaim_buffers_idlelocked = via_reclaim_buffers_locked, + .reclaim_buffers_locked = via_reclaim_buffers_locked, .lastclose = via_lastclose, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, diff --git a/trunk/drivers/char/drm/via_drv.h b/trunk/drivers/char/drm/via_drv.h index b46ca8e6306d..8b8778d4a423 100644 --- a/trunk/drivers/char/drm/via_drv.h +++ b/trunk/drivers/char/drm/via_drv.h @@ -29,11 +29,11 @@ #define DRIVER_NAME "via" #define DRIVER_DESC "VIA Unichrome / Pro" -#define DRIVER_DATE "20070202" +#define DRIVER_DATE "20061227" #define DRIVER_MAJOR 2 #define DRIVER_MINOR 11 -#define DRIVER_PATCHLEVEL 1 +#define DRIVER_PATCHLEVEL 0 #include "via_verifier.h" @@ -93,7 +93,6 @@ typedef struct drm_via_private { unsigned long vram_offset; unsigned long agp_offset; drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES]; - uint32_t dma_diff; } drm_via_private_t; enum via_family { diff --git a/trunk/drivers/char/drm/via_mm.h b/trunk/drivers/char/drm/via_mm.h new file mode 100644 index 000000000000..d57efda57c76 --- /dev/null +++ b/trunk/drivers/char/drm/via_mm.h @@ -0,0 +1,40 @@ +/* + * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +#ifndef _via_drm_mm_h_ +#define _via_drm_mm_h_ + +typedef struct { + unsigned int context; + unsigned int size; + unsigned long offset; + unsigned long free; +} drm_via_mm_t; + +typedef struct { + unsigned int size; + unsigned long handle; + void *virtual; +} drm_via_dma_t; + +#endif diff --git a/trunk/drivers/char/ds1620.c b/trunk/drivers/char/ds1620.c index 334ad5bbe6b6..3d7efc26aad6 100644 --- a/trunk/drivers/char/ds1620.c +++ b/trunk/drivers/char/ds1620.c @@ -4,6 +4,7 @@ */ #include #include +#include #include #include #include diff --git a/trunk/drivers/char/dsp56k.c b/trunk/drivers/char/dsp56k.c index 9b8278e1f4f8..db984e481d4c 100644 --- a/trunk/drivers/char/dsp56k.c +++ b/trunk/drivers/char/dsp56k.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/char/dtlk.c b/trunk/drivers/char/dtlk.c index abde6ddefe69..d8dbdb916232 100644 --- a/trunk/drivers/char/dtlk.c +++ b/trunk/drivers/char/dtlk.c @@ -62,6 +62,7 @@ #include /* for __init, module_{init,exit} */ #include /* for POLLIN, etc. */ #include /* local header file for DoubleTalk values */ +#include #ifdef TRACING #define TRACE_TEXT(str) printk(str); @@ -324,22 +325,16 @@ static int dtlk_release(struct inode *inode, struct file *file) static int __init dtlk_init(void) { - int err; - dtlk_port_lpc = 0; dtlk_port_tts = 0; dtlk_busy = 0; dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops); - if (dtlk_major < 0) { + if (dtlk_major == 0) { printk(KERN_ERR "DoubleTalk PC - cannot register device\n"); - return dtlk_major; - } - err = dtlk_dev_probe(); - if (err) { - unregister_chrdev(dtlk_major, "dtlk"); - return err; + return 0; } - printk(", MAJOR %d\n", dtlk_major); + if (dtlk_dev_probe() == 0) + printk(", MAJOR %d\n", dtlk_major); init_waitqueue_head(&dtlk_process_list); diff --git a/trunk/drivers/char/ec3104_keyb.c b/trunk/drivers/char/ec3104_keyb.c index 020011495d91..77f58ed6d59a 100644 --- a/trunk/drivers/char/ec3104_keyb.c +++ b/trunk/drivers/char/ec3104_keyb.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index c6c56fb8ba50..de5be30484ad 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -949,7 +949,7 @@ static int block_til_ready(struct tty_struct *tty, } /* End forever while */ - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&ch->open_wait, &wait); if (!tty_hung_up_p(filp)) ch->count++; diff --git a/trunk/drivers/char/genrtc.c b/trunk/drivers/char/genrtc.c index 49f914e79216..23b25ada65ea 100644 --- a/trunk/drivers/char/genrtc.c +++ b/trunk/drivers/char/genrtc.c @@ -207,7 +207,7 @@ static ssize_t gen_rtc_read(struct file *file, char __user *buf, sizeof(unsigned long); } out: - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&gen_rtc_wait, &wait); return retval; diff --git a/trunk/drivers/char/hangcheck-timer.c b/trunk/drivers/char/hangcheck-timer.c index f0e7263dfcde..ae76a9ffe89f 100644 --- a/trunk/drivers/char/hangcheck-timer.c +++ b/trunk/drivers/char/hangcheck-timer.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/char/hvc_console.c b/trunk/drivers/char/hvc_console.c index 322bc5f7d86b..0f9ed7b46a6d 100644 --- a/trunk/drivers/char/hvc_console.c +++ b/trunk/drivers/char/hvc_console.c @@ -111,7 +111,7 @@ static int last_hvc = -1; * lock held. If successful, this function increments the kobject reference * count against the target hvc_struct so it should be released when finished. */ -static struct hvc_struct *hvc_get_by_index(int index) +struct hvc_struct *hvc_get_by_index(int index) { struct hvc_struct *hp; unsigned long flags; @@ -150,8 +150,7 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = * hvc_console_setup() finds adapters. */ -static void hvc_console_print(struct console *co, const char *b, - unsigned count) +void hvc_console_print(struct console *co, const char *b, unsigned count) { char c[N_OUTBUF] __ALIGNED__; unsigned i = 0, n = 0; @@ -209,7 +208,7 @@ static int __init hvc_console_setup(struct console *co, char *options) return 0; } -static struct console hvc_con_driver = { +struct console hvc_con_driver = { .name = "hvc", .write = hvc_console_print, .device = hvc_console_device, @@ -279,6 +278,7 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops) return 0; } +EXPORT_SYMBOL(hvc_instantiate); /* Wake the sleeping khvcd */ static void hvc_kick(void) @@ -792,6 +792,7 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, return hp; } +EXPORT_SYMBOL(hvc_alloc); int __devexit hvc_remove(struct hvc_struct *hp) { @@ -827,10 +828,11 @@ int __devexit hvc_remove(struct hvc_struct *hp) tty_hangup(tty); return 0; } +EXPORT_SYMBOL(hvc_remove); /* Driver initialization. Follow console initialization. This is where the TTY * interfaces start to become available. */ -static int __init hvc_init(void) +int __init hvc_init(void) { struct tty_driver *drv; diff --git a/trunk/drivers/char/hvc_iseries.c b/trunk/drivers/char/hvc_iseries.c index b37f1d5a5be6..ec420fe8a908 100644 --- a/trunk/drivers/char/hvc_iseries.c +++ b/trunk/drivers/char/hvc_iseries.c @@ -579,7 +579,7 @@ static int hvc_find_vtys(void) if (!vtermno) continue; - if (!of_device_is_compatible(vty, "IBM,iSeries-vty")) + if (!device_is_compatible(vty, "IBM,iSeries-vty")) continue; if (num_found == 0) diff --git a/trunk/drivers/char/hvc_vio.c b/trunk/drivers/char/hvc_vio.c index 79711aa4b41d..94a542e20efb 100644 --- a/trunk/drivers/char/hvc_vio.c +++ b/trunk/drivers/char/hvc_vio.c @@ -157,7 +157,7 @@ static int hvc_find_vtys(void) if (!vtermno) continue; - if (of_device_is_compatible(vty, "hvterm1")) { + if (device_is_compatible(vty, "hvterm1")) { hvc_instantiate(*vtermno, num_found, &hvc_get_put_ops); ++num_found; } diff --git a/trunk/drivers/char/hw_random/intel-rng.c b/trunk/drivers/char/hw_random/intel-rng.c index 4ae9811d1a6c..cc1046e6ee02 100644 --- a/trunk/drivers/char/hw_random/intel-rng.c +++ b/trunk/drivers/char/hw_random/intel-rng.c @@ -24,11 +24,10 @@ * warranty of any kind, whether express or implied. */ -#include -#include #include +#include #include -#include +#include #include @@ -218,117 +217,30 @@ static struct hwrng intel_rng = { .data_read = intel_rng_data_read, }; -struct intel_rng_hw { - struct pci_dev *dev; - void __iomem *mem; - u8 bios_cntl_off; - u8 bios_cntl_val; - u8 fwh_dec_en1_off; - u8 fwh_dec_en1_val; -}; -static int __init intel_rng_hw_init(void *_intel_rng_hw) -{ - struct intel_rng_hw *intel_rng_hw = _intel_rng_hw; - u8 mfc, dvc; - - /* interrupts disabled in stop_machine_run call */ - - if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK)) - pci_write_config_byte(intel_rng_hw->dev, - intel_rng_hw->fwh_dec_en1_off, - intel_rng_hw->fwh_dec_en1_val | - FWH_F8_EN_MASK); - if (!(intel_rng_hw->bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK)) - pci_write_config_byte(intel_rng_hw->dev, - intel_rng_hw->bios_cntl_off, - intel_rng_hw->bios_cntl_val | - BIOS_CNTL_WRITE_ENABLE_MASK); - - writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem); - writeb(INTEL_FWH_READ_ID_CMD, intel_rng_hw->mem); - mfc = readb(intel_rng_hw->mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS); - dvc = readb(intel_rng_hw->mem + INTEL_FWH_DEVICE_CODE_ADDRESS); - writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem); - - if (!(intel_rng_hw->bios_cntl_val & - (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))) - pci_write_config_byte(intel_rng_hw->dev, - intel_rng_hw->bios_cntl_off, - intel_rng_hw->bios_cntl_val); - if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK)) - pci_write_config_byte(intel_rng_hw->dev, - intel_rng_hw->fwh_dec_en1_off, - intel_rng_hw->fwh_dec_en1_val); +#ifdef CONFIG_SMP +static char __initdata waitflag; - if (mfc != INTEL_FWH_MANUFACTURER_CODE || - (dvc != INTEL_FWH_DEVICE_CODE_8M && - dvc != INTEL_FWH_DEVICE_CODE_4M)) { - printk(KERN_ERR PFX "FWH not detected\n"); - return -ENODEV; - } - - return 0; -} - -static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw, - struct pci_dev *dev) +static void __init intel_init_wait(void *unused) { - intel_rng_hw->bios_cntl_val = 0xff; - intel_rng_hw->fwh_dec_en1_val = 0xff; - intel_rng_hw->dev = dev; - - /* Check for Intel 82802 */ - if (dev->device < 0x2640) { - intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD; - intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_OLD; - } else { - intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW; - intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_NEW; - } - - pci_read_config_byte(dev, intel_rng_hw->fwh_dec_en1_off, - &intel_rng_hw->fwh_dec_en1_val); - pci_read_config_byte(dev, intel_rng_hw->bios_cntl_off, - &intel_rng_hw->bios_cntl_val); - - if ((intel_rng_hw->bios_cntl_val & - (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) - == BIOS_CNTL_LOCK_ENABLE_MASK) { - static __initdata /*const*/ char warning[] = - KERN_WARNING PFX "Firmware space is locked read-only. " - KERN_WARNING PFX "If you can't or\n don't want to " - KERN_WARNING PFX "disable this in firmware setup, and " - KERN_WARNING PFX "if\n you are certain that your " - KERN_WARNING PFX "system has a functional\n RNG, try" - KERN_WARNING PFX "using the 'no_fwh_detect' option.\n"; - - if (no_fwh_detect) - return -ENODEV; - printk(warning); - return -EBUSY; - } - - intel_rng_hw->mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); - if (intel_rng_hw->mem == NULL) - return -EBUSY; - - return 0; + while (waitflag) + cpu_relax(); } - +#endif static int __init mod_init(void) { int err = -ENODEV; - int i; + unsigned i; struct pci_dev *dev = NULL; - void __iomem *mem = mem; - u8 hw_status; - struct intel_rng_hw *intel_rng_hw; + void __iomem *mem; + unsigned long flags; + u8 bios_cntl_off, fwh_dec_en1_off; + u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff; + u8 hw_status, mfc, dvc; for (i = 0; !dev && pci_tbl[i].vendor; ++i) - dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, - NULL); + dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL); if (!dev) goto out; /* Device not found. */ @@ -338,18 +250,39 @@ static int __init mod_init(void) goto fwh_done; } - intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL); - if (!intel_rng_hw) { + /* Check for Intel 82802 */ + if (dev->device < 0x2640) { + fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD; + bios_cntl_off = BIOS_CNTL_REG_OLD; + } else { + fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW; + bios_cntl_off = BIOS_CNTL_REG_NEW; + } + + pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val); + pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val); + + if ((bios_cntl_val & + (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) + == BIOS_CNTL_LOCK_ENABLE_MASK) { + static __initdata /*const*/ char warning[] = + KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n" + KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n" + KERN_WARNING PFX "you are certain that your system has a functional\n" + KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n"; + pci_dev_put(dev); + if (no_fwh_detect) + goto fwh_done; + printk(warning); + err = -EBUSY; goto out; } - err = intel_init_hw_struct(intel_rng_hw, dev); - if (err) { + mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); + if (mem == NULL) { pci_dev_put(dev); - kfree(intel_rng_hw); - if (err == -ENODEV) - goto fwh_done; + err = -EBUSY; goto out; } @@ -357,18 +290,59 @@ static int __init mod_init(void) * Since the BIOS code/data is going to disappear from its normal * location with the Read ID command, all activity on the system * must be stopped until the state is back to normal. - * - * Use stop_machine_run because IPIs can be blocked by disabling - * interrupts. */ - err = stop_machine_run(intel_rng_hw_init, intel_rng_hw, NR_CPUS); +#ifdef CONFIG_SMP + set_mb(waitflag, 1); + if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) { + set_mb(waitflag, 0); + pci_dev_put(dev); + printk(KERN_ERR PFX "cannot run on all processors\n"); + err = -EAGAIN; + goto err_unmap; + } +#endif + local_irq_save(flags); + + if (!(fwh_dec_en1_val & FWH_F8_EN_MASK)) + pci_write_config_byte(dev, + fwh_dec_en1_off, + fwh_dec_en1_val | FWH_F8_EN_MASK); + if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK)) + pci_write_config_byte(dev, + bios_cntl_off, + bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK); + + writeb(INTEL_FWH_RESET_CMD, mem); + writeb(INTEL_FWH_READ_ID_CMD, mem); + mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS); + dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS); + writeb(INTEL_FWH_RESET_CMD, mem); + + if (!(bios_cntl_val & + (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))) + pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val); + if (!(fwh_dec_en1_val & FWH_F8_EN_MASK)) + pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val); + + local_irq_restore(flags); +#ifdef CONFIG_SMP + /* Tell other CPUs to resume. */ + set_mb(waitflag, 0); +#endif + + iounmap(mem); pci_dev_put(dev); - iounmap(intel_rng_hw->mem); - kfree(intel_rng_hw); - if (err) + + if (mfc != INTEL_FWH_MANUFACTURER_CODE || + (dvc != INTEL_FWH_DEVICE_CODE_8M && + dvc != INTEL_FWH_DEVICE_CODE_4M)) { + printk(KERN_ERR PFX "FWH not detected\n"); + err = -ENODEV; goto out; + } fwh_done: + err = -ENOMEM; mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); if (!mem) @@ -378,21 +352,22 @@ static int __init mod_init(void) /* Check for Random Number Generator */ err = -ENODEV; hw_status = hwstatus_get(mem); - if ((hw_status & INTEL_RNG_PRESENT) == 0) { - iounmap(mem); - goto out; - } + if ((hw_status & INTEL_RNG_PRESENT) == 0) + goto err_unmap; printk(KERN_INFO "Intel 82802 RNG detected\n"); err = hwrng_register(&intel_rng); if (err) { printk(KERN_ERR PFX "RNG registering failed (%d)\n", err); - iounmap(mem); + goto err_unmap; } out: return err; +err_unmap: + iounmap(mem); + goto out; } static void __exit mod_exit(void) diff --git a/trunk/drivers/char/hw_random/via-rng.c b/trunk/drivers/char/hw_random/via-rng.c index ec435cb25c4f..9ebf84d18655 100644 --- a/trunk/drivers/char/hw_random/via-rng.c +++ b/trunk/drivers/char/hw_random/via-rng.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/char/i8k.c b/trunk/drivers/char/i8k.c index 0289705967de..353d9f3cf8d7 100644 --- a/trunk/drivers/char/i8k.c +++ b/trunk/drivers/char/i8k.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/char/ip27-rtc.c b/trunk/drivers/char/ip27-rtc.c index 932264a657d0..a48da02aad2f 100644 --- a/trunk/drivers/char/ip27-rtc.c +++ b/trunk/drivers/char/ip27-rtc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 6c5d15de3317..e22146546add 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -9,7 +9,6 @@ * source@mvista.com * * Copyright 2002 MontaVista Software Inc. - * Copyright 2006 IBM Corp., Christian Krafft * * 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 @@ -65,11 +64,6 @@ #include #include -#ifdef CONFIG_PPC_OF -#include -#include -#endif - #define PFX "ipmi_si: " /* Measure times between events in the driver. */ @@ -82,12 +76,6 @@ #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a short timeout */ -/* Bit for BMC global enables. */ -#define IPMI_BMC_RCV_MSG_INTR 0x01 -#define IPMI_BMC_EVT_MSG_INTR 0x02 -#define IPMI_BMC_EVT_MSG_BUFF 0x04 -#define IPMI_BMC_SYS_LOG 0x08 - enum si_intf_state { SI_NORMAL, SI_GETTING_FLAGS, @@ -96,9 +84,7 @@ enum si_intf_state { SI_CLEARING_FLAGS_THEN_SET_IRQ, SI_GETTING_MESSAGES, SI_ENABLE_INTERRUPTS1, - SI_ENABLE_INTERRUPTS2, - SI_DISABLE_INTERRUPTS1, - SI_DISABLE_INTERRUPTS2 + SI_ENABLE_INTERRUPTS2 /* FIXME - add watchdog stuff. */ }; @@ -347,17 +333,6 @@ static void start_enable_irq(struct smi_info *smi_info) smi_info->si_state = SI_ENABLE_INTERRUPTS1; } -static void start_disable_irq(struct smi_info *smi_info) -{ - unsigned char msg[2]; - - msg[0] = (IPMI_NETFN_APP_REQUEST << 2); - msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; - - smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); - smi_info->si_state = SI_DISABLE_INTERRUPTS1; -} - static void start_clear_flags(struct smi_info *smi_info) { unsigned char msg[3]; @@ -378,7 +353,7 @@ static void start_clear_flags(struct smi_info *smi_info) static inline void disable_si_irq(struct smi_info *smi_info) { if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { - start_disable_irq(smi_info); + disable_irq_nosync(smi_info->irq); smi_info->interrupt_disabled = 1; } } @@ -386,7 +361,7 @@ static inline void disable_si_irq(struct smi_info *smi_info) static inline void enable_si_irq(struct smi_info *smi_info) { if ((smi_info->irq) && (smi_info->interrupt_disabled)) { - start_enable_irq(smi_info); + enable_irq(smi_info->irq); smi_info->interrupt_disabled = 0; } } @@ -608,9 +583,7 @@ static void handle_transaction_done(struct smi_info *smi_info) } else { msg[0] = (IPMI_NETFN_APP_REQUEST << 2); msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; - msg[2] = (msg[3] | - IPMI_BMC_RCV_MSG_INTR | - IPMI_BMC_EVT_MSG_INTR); + msg[2] = msg[3] | 1; /* enable msg queue int */ smi_info->handlers->start_transaction( smi_info->si_sm, msg, 3); smi_info->si_state = SI_ENABLE_INTERRUPTS2; @@ -632,45 +605,6 @@ static void handle_transaction_done(struct smi_info *smi_info) smi_info->si_state = SI_NORMAL; break; } - - case SI_DISABLE_INTERRUPTS1: - { - unsigned char msg[4]; - - /* We got the flags from the SMI, now handle them. */ - smi_info->handlers->get_result(smi_info->si_sm, msg, 4); - if (msg[2] != 0) { - printk(KERN_WARNING - "ipmi_si: Could not disable interrupts" - ", failed get.\n"); - smi_info->si_state = SI_NORMAL; - } else { - msg[0] = (IPMI_NETFN_APP_REQUEST << 2); - msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; - msg[2] = (msg[3] & - ~(IPMI_BMC_RCV_MSG_INTR | - IPMI_BMC_EVT_MSG_INTR)); - smi_info->handlers->start_transaction( - smi_info->si_sm, msg, 3); - smi_info->si_state = SI_DISABLE_INTERRUPTS2; - } - break; - } - - case SI_DISABLE_INTERRUPTS2: - { - unsigned char msg[4]; - - /* We got the flags from the SMI, now handle them. */ - smi_info->handlers->get_result(smi_info->si_sm, msg, 4); - if (msg[2] != 0) { - printk(KERN_WARNING - "ipmi_si: Could not disable interrupts" - ", failed set.\n"); - } - smi_info->si_state = SI_NORMAL; - break; - } } } @@ -924,6 +858,9 @@ static void smi_timeout(unsigned long data) struct timeval t; #endif + if (atomic_read(&smi_info->stop_operation)) + return; + spin_lock_irqsave(&(smi_info->si_lock), flags); #ifdef DEBUG_TIMING do_gettimeofday(&t); @@ -979,11 +916,15 @@ static irqreturn_t si_irq_handler(int irq, void *data) smi_info->interrupts++; spin_unlock(&smi_info->count_lock); + if (atomic_read(&smi_info->stop_operation)) + goto out; + #ifdef DEBUG_TIMING do_gettimeofday(&t); printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif smi_event_handler(smi_info, 0); + out: spin_unlock_irqrestore(&(smi_info->si_lock), flags); return IRQ_HANDLED; } @@ -1065,7 +1006,6 @@ static DEFINE_MUTEX(smi_infos_lock); static int smi_num; /* Used to sequence the SMIs */ #define DEFAULT_REGSPACING 1 -#define DEFAULT_REGSIZE 1 static int si_trydefaults = 1; static char *si_type[SI_MAX_PARMS]; @@ -1171,7 +1111,7 @@ static int std_irq_setup(struct smi_info *info) if (info->si_type == SI_BT) { rv = request_irq(info->irq, si_bt_irq_handler, - IRQF_SHARED | IRQF_DISABLED, + IRQF_DISABLED, DEVICE_NAME, info); if (!rv) @@ -1181,7 +1121,7 @@ static int std_irq_setup(struct smi_info *info) } else rv = request_irq(info->irq, si_irq_handler, - IRQF_SHARED | IRQF_DISABLED, + IRQF_DISABLED, DEVICE_NAME, info); if (rv) { @@ -1761,11 +1701,15 @@ static u32 ipmi_acpi_gpe(void *context) smi_info->interrupts++; spin_unlock(&smi_info->count_lock); + if (atomic_read(&smi_info->stop_operation)) + goto out; + #ifdef DEBUG_TIMING do_gettimeofday(&t); printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif smi_event_handler(smi_info, 0); + out: spin_unlock_irqrestore(&(smi_info->si_lock), flags); return ACPI_INTERRUPT_HANDLED; @@ -2189,15 +2133,12 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, info->irq_setup = std_irq_setup; info->dev = &pdev->dev; - pci_set_drvdata(pdev, info); return try_smi_init(info); } static void __devexit ipmi_pci_remove(struct pci_dev *pdev) { - struct smi_info *info = pci_get_drvdata(pdev); - cleanup_one_si(info); } #ifdef CONFIG_PM @@ -2231,99 +2172,6 @@ static struct pci_driver ipmi_pci_driver = { #endif /* CONFIG_PCI */ -#ifdef CONFIG_PPC_OF -static int __devinit ipmi_of_probe(struct of_device *dev, - const struct of_device_id *match) -{ - struct smi_info *info; - struct resource resource; - const int *regsize, *regspacing, *regshift; - struct device_node *np = dev->node; - int ret; - int proplen; - - dev_info(&dev->dev, PFX "probing via device tree\n"); - - ret = of_address_to_resource(np, 0, &resource); - if (ret) { - dev_warn(&dev->dev, PFX "invalid address from OF\n"); - return ret; - } - - regsize = get_property(np, "reg-size", &proplen); - if (regsize && proplen != 4) { - dev_warn(&dev->dev, PFX "invalid regsize from OF\n"); - return -EINVAL; - } - - regspacing = get_property(np, "reg-spacing", &proplen); - if (regspacing && proplen != 4) { - dev_warn(&dev->dev, PFX "invalid regspacing from OF\n"); - return -EINVAL; - } - - regshift = get_property(np, "reg-shift", &proplen); - if (regshift && proplen != 4) { - dev_warn(&dev->dev, PFX "invalid regshift from OF\n"); - return -EINVAL; - } - - info = kzalloc(sizeof(*info), GFP_KERNEL); - - if (!info) { - dev_err(&dev->dev, - PFX "could not allocate memory for OF probe\n"); - return -ENOMEM; - } - - info->si_type = (enum si_type) match->data; - info->addr_source = "device-tree"; - info->io_setup = mem_setup; - info->irq_setup = std_irq_setup; - - info->io.addr_type = IPMI_MEM_ADDR_SPACE; - info->io.addr_data = resource.start; - - info->io.regsize = regsize ? *regsize : DEFAULT_REGSIZE; - info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING; - info->io.regshift = regshift ? *regshift : 0; - - info->irq = irq_of_parse_and_map(dev->node, 0); - info->dev = &dev->dev; - - dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n", - info->io.addr_data, info->io.regsize, info->io.regspacing, - info->irq); - - dev->dev.driver_data = (void*) info; - - return try_smi_init(info); -} - -static int __devexit ipmi_of_remove(struct of_device *dev) -{ - cleanup_one_si(dev->dev.driver_data); - return 0; -} - -static struct of_device_id ipmi_match[] = -{ - { .type = "ipmi", .compatible = "ipmi-kcs", .data = (void *)(unsigned long) SI_KCS }, - { .type = "ipmi", .compatible = "ipmi-smic", .data = (void *)(unsigned long) SI_SMIC }, - { .type = "ipmi", .compatible = "ipmi-bt", .data = (void *)(unsigned long) SI_BT }, - {}, -}; - -static struct of_platform_driver ipmi_of_platform_driver = -{ - .name = "ipmi", - .match_table = ipmi_match, - .probe = ipmi_of_probe, - .remove = __devexit_p(ipmi_of_remove), -}; -#endif /* CONFIG_PPC_OF */ - - static int try_get_dev_id(struct smi_info *smi_info) { unsigned char msg[2]; @@ -2953,10 +2801,6 @@ static __devinit int init_ipmi_si(void) } #endif -#ifdef CONFIG_PPC_OF - of_register_platform_driver(&ipmi_of_platform_driver); -#endif - if (si_trydefaults) { mutex_lock(&smi_infos_lock); if (list_empty(&smi_infos)) { @@ -2994,33 +2838,28 @@ static void cleanup_one_si(struct smi_info *to_clean) list_del(&to_clean->link); - /* Tell the driver that we are shutting down. */ - atomic_inc(&to_clean->stop_operation); + /* Tell the timer and interrupt handlers that we are shutting + down. */ + spin_lock_irqsave(&(to_clean->si_lock), flags); + spin_lock(&(to_clean->msg_lock)); - /* Make sure the timer and thread are stopped and will not run - again. */ - wait_for_timer_and_thread(to_clean); - - /* Timeouts are stopped, now make sure the interrupts are off - for the device. A little tricky with locks to make sure - there are no races. */ - spin_lock_irqsave(&to_clean->si_lock, flags); - while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { - spin_unlock_irqrestore(&to_clean->si_lock, flags); - poll(to_clean); - schedule_timeout_uninterruptible(1); - spin_lock_irqsave(&to_clean->si_lock, flags); - } - disable_si_irq(to_clean); - spin_unlock_irqrestore(&to_clean->si_lock, flags); - while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { - poll(to_clean); - schedule_timeout_uninterruptible(1); - } + atomic_inc(&to_clean->stop_operation); - /* Clean up interrupts and make sure that everything is done. */ if (to_clean->irq_cleanup) to_clean->irq_cleanup(to_clean); + + spin_unlock(&(to_clean->msg_lock)); + spin_unlock_irqrestore(&(to_clean->si_lock), flags); + + /* Wait until we know that we are out of any interrupt + handlers might have been running before we freed the + interrupt. */ + synchronize_sched(); + + wait_for_timer_and_thread(to_clean); + + /* Interrupts and timeouts are stopped, now make sure the + interface is in a clean state. */ while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { poll(to_clean); schedule_timeout_uninterruptible(1); @@ -3059,10 +2898,6 @@ static __exit void cleanup_ipmi_si(void) pci_unregister_driver(&ipmi_pci_driver); #endif -#ifdef CONFIG_PPC_OF - of_unregister_platform_driver(&ipmi_of_platform_driver); -#endif - mutex_lock(&smi_infos_lock); list_for_each_entry_safe(e, tmp_e, &smi_infos, link) cleanup_one_si(e); diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index 147c12047cf3..6b634e8d9519 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -50,18 +49,9 @@ #include #include #include -#include #include - -#ifdef CONFIG_X86 -/* This is ugly, but I've determined that x86 is the only architecture - that can reasonably support the IPMI NMI watchdog timeout at this - time. If another architecture adds this capability somehow, it - will have to be a somewhat different mechanism and I have no idea - how it will work. So in the unlikely event that another - architecture supports this, we can figure out a good generic - mechanism for it at that time. */ -#define HAVE_DIE_NMI_POST +#ifdef CONFIG_X86_LOCAL_APIC +#include #endif #define PFX "IPMI Watchdog: " @@ -327,11 +317,6 @@ static unsigned char ipmi_version_minor; /* If a pretimeout occurs, this is used to allow only one panic to happen. */ static atomic_t preop_panic_excl = ATOMIC_INIT(-1); -#ifdef HAVE_DIE_NMI_POST -static int testing_nmi; -static int nmi_handler_registered; -#endif - static int ipmi_heartbeat(void); static void panic_halt_ipmi_heartbeat(void); @@ -373,10 +358,6 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, int hbnow = 0; - /* These can be cleared as we are setting the timeout. */ - ipmi_start_timer_on_heartbeat = 0; - pretimeout_since_last_heartbeat = 0; - data[0] = 0; WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); @@ -451,12 +432,13 @@ static int ipmi_set_timeout(int do_heartbeat) wait_for_completion(&set_timeout_wait); - mutex_unlock(&set_timeout_lock); - if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) || ((send_heartbeat_now) && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) + { rv = ipmi_heartbeat(); + } + mutex_unlock(&set_timeout_lock); out: return rv; @@ -536,10 +518,12 @@ static int ipmi_heartbeat(void) int rv; struct ipmi_system_interface_addr addr; - if (ipmi_ignore_heartbeat) + if (ipmi_ignore_heartbeat) { return 0; + } if (ipmi_start_timer_on_heartbeat) { + ipmi_start_timer_on_heartbeat = 0; ipmi_watchdog_state = action_val; return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); } else if (pretimeout_since_last_heartbeat) { @@ -547,6 +531,7 @@ static int ipmi_heartbeat(void) We don't want to set the action, though, we want to leave that alone (thus it can't be combined with the above operation. */ + pretimeout_since_last_heartbeat = 0; return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); } @@ -934,45 +919,6 @@ static void ipmi_register_watchdog(int ipmi_intf) printk(KERN_CRIT PFX "Unable to register misc device\n"); } -#ifdef HAVE_DIE_NMI_POST - if (nmi_handler_registered) { - int old_pretimeout = pretimeout; - int old_timeout = timeout; - int old_preop_val = preop_val; - - /* Set the pretimeout to go off in a second and give - ourselves plenty of time to stop the timer. */ - ipmi_watchdog_state = WDOG_TIMEOUT_RESET; - preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ - pretimeout = 99; - timeout = 100; - - testing_nmi = 1; - - rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); - if (rv) { - printk(KERN_WARNING PFX "Error starting timer to" - " test NMI: 0x%x. The NMI pretimeout will" - " likely not work\n", rv); - rv = 0; - goto out_restore; - } - - msleep(1500); - - if (testing_nmi != 2) { - printk(KERN_WARNING PFX "IPMI NMI didn't seem to" - " occur. The NMI pretimeout will" - " likely not work\n"); - } - out_restore: - testing_nmi = 0; - preop_val = old_preop_val; - pretimeout = old_pretimeout; - timeout = old_timeout; - } -#endif - out: up_write(®ister_sem); @@ -982,10 +928,6 @@ static void ipmi_register_watchdog(int ipmi_intf) ipmi_watchdog_state = action_val; ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); printk(KERN_INFO PFX "Starting now!\n"); - } else { - /* Stop the timer now. */ - ipmi_watchdog_state = WDOG_TIMEOUT_NONE; - ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); } } @@ -1022,28 +964,17 @@ static void ipmi_unregister_watchdog(int ipmi_intf) up_write(®ister_sem); } -#ifdef HAVE_DIE_NMI_POST +#ifdef HAVE_NMI_HANDLER static int -ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) +ipmi_nmi(void *dev_id, int cpu, int handled) { - if (val != DIE_NMI_POST) - return NOTIFY_OK; - - if (testing_nmi) { - testing_nmi = 2; - return NOTIFY_STOP; - } - /* If we are not expecting a timeout, ignore it. */ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) - return NOTIFY_OK; - - if (preaction_val != WDOG_PRETIMEOUT_NMI) - return NOTIFY_OK; + return NOTIFY_DONE; /* If no one else handled the NMI, we assume it was the IPMI watchdog. */ - if (preop_val == WDOG_PREOP_PANIC) { + if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) { /* On some machines, the heartbeat will give an error and not work unless we re-enable the timer. So do so. */ @@ -1052,12 +983,18 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) panic(PFX "pre-timeout"); } - return NOTIFY_STOP; + return NOTIFY_DONE; } -static struct notifier_block ipmi_nmi_handler = { - .notifier_call = ipmi_nmi +static struct nmi_handler ipmi_nmi_handler = +{ + .link = LIST_HEAD_INIT(ipmi_nmi_handler.link), + .dev_name = "ipmi_watchdog", + .dev_id = NULL, + .handler = ipmi_nmi, + .priority = 0, /* Call us last. */ }; +int nmi_handler_registered; #endif static int wdog_reboot_handler(struct notifier_block *this, @@ -1174,7 +1111,7 @@ static int preaction_op(const char *inval, char *outval) preaction_val = WDOG_PRETIMEOUT_NONE; else if (strcmp(inval, "pre_smi") == 0) preaction_val = WDOG_PRETIMEOUT_SMI; -#ifdef HAVE_DIE_NMI_POST +#ifdef HAVE_NMI_HANDLER else if (strcmp(inval, "pre_nmi") == 0) preaction_val = WDOG_PRETIMEOUT_NMI; #endif @@ -1208,7 +1145,7 @@ static int preop_op(const char *inval, char *outval) static void check_parms(void) { -#ifdef HAVE_DIE_NMI_POST +#ifdef HAVE_NMI_HANDLER int do_nmi = 0; int rv; @@ -1221,9 +1158,20 @@ static void check_parms(void) preop_op("preop_none", NULL); do_nmi = 0; } +#ifdef CONFIG_X86_LOCAL_APIC + if (nmi_watchdog == NMI_IO_APIC) { + printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC" + " mode (value is %d), that is incompatible" + " with using NMI in the IPMI watchdog." + " Disabling IPMI nmi pretimeout.\n", + nmi_watchdog); + preaction_val = WDOG_PRETIMEOUT_NONE; + do_nmi = 0; + } +#endif } if (do_nmi && !nmi_handler_registered) { - rv = register_die_notifier(&ipmi_nmi_handler); + rv = request_nmi(&ipmi_nmi_handler); if (rv) { printk(KERN_WARNING PFX "Can't register nmi handler\n"); @@ -1231,7 +1179,7 @@ static void check_parms(void) } else nmi_handler_registered = 1; } else if (!do_nmi && nmi_handler_registered) { - unregister_die_notifier(&ipmi_nmi_handler); + release_nmi(&ipmi_nmi_handler); nmi_handler_registered = 0; } #endif @@ -1267,9 +1215,9 @@ static int __init ipmi_wdog_init(void) rv = ipmi_smi_watcher_register(&smi_watcher); if (rv) { -#ifdef HAVE_DIE_NMI_POST - if (nmi_handler_registered) - unregister_die_notifier(&ipmi_nmi_handler); +#ifdef HAVE_NMI_HANDLER + if (preaction_val == WDOG_PRETIMEOUT_NMI) + release_nmi(&ipmi_nmi_handler); #endif atomic_notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); @@ -1288,9 +1236,9 @@ static void __exit ipmi_wdog_exit(void) ipmi_smi_watcher_unregister(&smi_watcher); ipmi_unregister_watchdog(watchdog_ifnum); -#ifdef HAVE_DIE_NMI_POST +#ifdef HAVE_NMI_HANDLER if (nmi_handler_registered) - unregister_die_notifier(&ipmi_nmi_handler); + release_nmi(&ipmi_nmi_handler); #endif atomic_notifier_chain_unregister(&panic_notifier_list, diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index 761f77740d67..43ab9edc76f5 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -137,10 +137,11 @@ #define InterruptTheCard(base) outw(0, (base) + 0xc) #define ClearInterrupt(base) inw((base) + 0x0a) -#define pr_dbg(str...) pr_debug("ISICOM: " str) #ifdef DEBUG +#define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str) #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) #else +#define pr_dbg(str...) do { } while (0) #define isicom_paranoia_check(a, b, c) 0 #endif diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index 1b094509b1d2..cb8d691576da 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -41,6 +41,7 @@ #include #include +static void kbd_disconnect(struct input_handle *handle); extern void ctrl_alt_del(void); /* @@ -109,7 +110,7 @@ struct kbd_struct kbd_table[MAX_NR_CONSOLES]; static struct kbd_struct *kbd = kbd_table; struct vt_spawn_console vt_spawn_con = { - .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock), + .lock = SPIN_LOCK_UNLOCKED, .pid = NULL, .sig = 0, }; @@ -158,41 +159,65 @@ static int sysrq_alt_use; static int sysrq_alt; /* - * Translation of scancodes to keycodes. We set them on only the first - * keyboard in the list that accepts the scancode and keycode. - * Explanation for not choosing the first attached keyboard anymore: - * USB keyboards for example have two event devices: one for all "normal" - * keys and one for extra function keys (like "volume up", "make coffee", - * etc.). So this means that scancodes for the extra function keys won't - * be valid for the first event device, but will be for the second. + * Translation of scancodes to keycodes. We set them on only the first attached + * keyboard - for per-keyboard setting, /dev/input/event is more useful. */ int getkeycode(unsigned int scancode) { - struct input_handle *handle; - int keycode; - int error = -ENODEV; + struct list_head *node; + struct input_dev *dev = NULL; - list_for_each_entry(handle, &kbd_handler.h_list, h_node) { - error = handle->dev->getkeycode(handle->dev, scancode, &keycode); - if (!error) - return keycode; + list_for_each(node, &kbd_handler.h_list) { + struct input_handle *handle = to_handle_h(node); + if (handle->dev->keycodesize) { + dev = handle->dev; + break; + } } - return error; + if (!dev) + return -ENODEV; + + if (scancode >= dev->keycodemax) + return -EINVAL; + + return INPUT_KEYCODE(dev, scancode); } int setkeycode(unsigned int scancode, unsigned int keycode) { - struct input_handle *handle; - int error = -ENODEV; + struct list_head *node; + struct input_dev *dev = NULL; + unsigned int i, oldkey; - list_for_each_entry(handle, &kbd_handler.h_list, h_node) { - error = handle->dev->setkeycode(handle->dev, scancode, keycode); - if (!error) + list_for_each(node, &kbd_handler.h_list) { + struct input_handle *handle = to_handle_h(node); + if (handle->dev->keycodesize) { + dev = handle->dev; break; + } } - return error; + if (!dev) + return -ENODEV; + + if (scancode >= dev->keycodemax) + return -EINVAL; + if (keycode < 0 || keycode > KEY_MAX) + return -EINVAL; + if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) + return -EINVAL; + + oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode); + + clear_bit(oldkey, dev->keybit); + set_bit(keycode, dev->keybit); + + for (i = 0; i < dev->keycodemax; i++) + if (INPUT_KEYCODE(dev,i) == oldkey) + set_bit(oldkey, dev->keybit); + + return 0; } /* @@ -200,9 +225,10 @@ int setkeycode(unsigned int scancode, unsigned int keycode) */ static void kd_nosound(unsigned long ignored) { - struct input_handle *handle; + struct list_head *node; - list_for_each_entry(handle, &kbd_handler.h_list, h_node) { + list_for_each(node, &kbd_handler.h_list) { + struct input_handle *handle = to_handle_h(node); if (test_bit(EV_SND, handle->dev->evbit)) { if (test_bit(SND_TONE, handle->dev->sndbit)) input_inject_event(handle, EV_SND, SND_TONE, 0); @@ -1135,7 +1161,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) if (emulate_raw(vc, keycode, !down << 7)) - if (keycode < BTN_MISC && printk_ratelimit()) + if (keycode < BTN_MISC) printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode); #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */ @@ -1259,11 +1285,11 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, * likes it, it can open it and get events from it. In this (kbd_connect) * function, we should decide which VT to bind that keyboard to initially. */ -static int kbd_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static struct input_handle *kbd_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id) { struct input_handle *handle; - int error; int i; for (i = KEY_RESERVED; i < BTN_MISC; i++) @@ -1271,37 +1297,24 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev, break; if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) - return -ENODEV; + return NULL; handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); if (!handle) - return -ENOMEM; + return NULL; handle->dev = dev; handle->handler = handler; handle->name = "kbd"; - error = input_register_handle(handle); - if (error) - goto err_free_handle; - - error = input_open_device(handle); - if (error) - goto err_unregister_handle; - - return 0; + input_open_device(handle); - err_unregister_handle: - input_unregister_handle(handle); - err_free_handle: - kfree(handle); - return error; + return handle; } static void kbd_disconnect(struct input_handle *handle) { input_close_device(handle); - input_unregister_handle(handle); kfree(handle); } diff --git a/trunk/drivers/char/lp.c b/trunk/drivers/char/lp.c index 62051f8b0910..b51d08be0bcf 100644 --- a/trunk/drivers/char/lp.c +++ b/trunk/drivers/char/lp.c @@ -118,6 +118,7 @@ #include #include #include +#include #include #include #include @@ -138,6 +139,9 @@ /* if you have more than 8 printers, remember to increase LP_NO */ #define LP_NO 8 +/* ROUND_UP macro from fs/select.c */ +#define ROUND_UP(x,y) (((x)+(y)-1)/(y)) + static struct lp_struct lp_table[LP_NO]; static unsigned int lp_count = 0; @@ -648,7 +652,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, (par_timeout.tv_usec < 0)) { return -EINVAL; } - to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ); + to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ); to_jiffies += par_timeout.tv_sec * (long) HZ; if (to_jiffies <= 0) { return -EINVAL; @@ -799,7 +803,7 @@ static int lp_register(int nr, struct parport *port) if (reset) lp_reset(nr); - class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev, + class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL, "lp%d", nr); printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, diff --git a/trunk/drivers/char/mem.c b/trunk/drivers/char/mem.c index cc9a9d0df979..5f066963f171 100644 --- a/trunk/drivers/char/mem.c +++ b/trunk/drivers/char/mem.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -551,7 +552,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, return virtr + wrote; } -#ifdef CONFIG_DEVPORT +#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) static ssize_t read_port(struct file * file, char __user * buf, size_t count, loff_t *ppos) { @@ -834,7 +835,7 @@ static const struct file_operations null_fops = { .splice_write = splice_write_null, }; -#ifdef CONFIG_DEVPORT +#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) static const struct file_operations port_fops = { .llseek = memory_lseek, .read = read_port, @@ -912,7 +913,7 @@ static int memory_open(struct inode * inode, struct file * filp) case 3: filp->f_op = &null_fops; break; -#ifdef CONFIG_DEVPORT +#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) case 4: filp->f_op = &port_fops; break; @@ -959,7 +960,7 @@ static const struct { {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, {3, "null", S_IRUGO | S_IWUGO, &null_fops}, -#ifdef CONFIG_DEVPORT +#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, #endif {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, diff --git a/trunk/drivers/char/misc.c b/trunk/drivers/char/misc.c index 4e6fb9651a16..7e975f606924 100644 --- a/trunk/drivers/char/misc.c +++ b/trunk/drivers/char/misc.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -54,7 +53,7 @@ * Head entry for the doubly linked miscdevice list */ static LIST_HEAD(misc_list); -static DEFINE_MUTEX(misc_mtx); +static DECLARE_MUTEX(misc_sem); /* * Assigned numbers, used for dynamic minors @@ -70,7 +69,7 @@ static void *misc_seq_start(struct seq_file *seq, loff_t *pos) struct miscdevice *p; loff_t off = 0; - mutex_lock(&misc_mtx); + down(&misc_sem); list_for_each_entry(p, &misc_list, list) { if (*pos == off++) return p; @@ -90,7 +89,7 @@ static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void misc_seq_stop(struct seq_file *seq, void *v) { - mutex_unlock(&misc_mtx); + up(&misc_sem); } static int misc_seq_show(struct seq_file *seq, void *v) @@ -130,7 +129,7 @@ static int misc_open(struct inode * inode, struct file * file) int err = -ENODEV; const struct file_operations *old_fops, *new_fops = NULL; - mutex_lock(&misc_mtx); + down(&misc_sem); list_for_each_entry(c, &misc_list, list) { if (c->minor == minor) { @@ -140,9 +139,9 @@ static int misc_open(struct inode * inode, struct file * file) } if (!new_fops) { - mutex_unlock(&misc_mtx); + up(&misc_sem); request_module("char-major-%d-%d", MISC_MAJOR, minor); - mutex_lock(&misc_mtx); + down(&misc_sem); list_for_each_entry(c, &misc_list, list) { if (c->minor == minor) { @@ -166,7 +165,7 @@ static int misc_open(struct inode * inode, struct file * file) } fops_put(old_fops); fail: - mutex_unlock(&misc_mtx); + up(&misc_sem); return err; } @@ -202,10 +201,10 @@ int misc_register(struct miscdevice * misc) INIT_LIST_HEAD(&misc->list); - mutex_lock(&misc_mtx); + down(&misc_sem); list_for_each_entry(c, &misc_list, list) { if (c->minor == misc->minor) { - mutex_unlock(&misc_mtx); + up(&misc_sem); return -EBUSY; } } @@ -216,7 +215,7 @@ int misc_register(struct miscdevice * misc) if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) break; if (i<0) { - mutex_unlock(&misc_mtx); + up(&misc_sem); return -EBUSY; } misc->minor = i; @@ -239,7 +238,7 @@ int misc_register(struct miscdevice * misc) */ list_add(&misc->list, &misc_list); out: - mutex_unlock(&misc_mtx); + up(&misc_sem); return err; } @@ -260,13 +259,13 @@ int misc_deregister(struct miscdevice * misc) if (list_empty(&misc->list)) return -EINVAL; - mutex_lock(&misc_mtx); + down(&misc_sem); list_del(&misc->list); device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); if (i < DYNAMIC_MINORS && i>0) { misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); } - mutex_unlock(&misc_mtx); + up(&misc_sem); return 0; } diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index e0d35c20c04f..7dbaee8d9402 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -1582,7 +1582,7 @@ int MoxaDriverIoctl(unsigned int cmd, unsigned long arg, int port) if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) return -EFAULT; - if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0) + if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS) return -EINVAL; switch(cmd) @@ -2529,8 +2529,6 @@ static int moxaloadbios(int cardno, unsigned char __user *tmp, int len) void __iomem *baseAddr; int i; - if(len < 0 || len > sizeof(moxaBuff)) - return -EINVAL; if(copy_from_user(moxaBuff, tmp, len)) return -EFAULT; baseAddr = moxa_boards[cardno].basemem; @@ -2578,7 +2576,7 @@ static int moxaload320b(int cardno, unsigned char __user *tmp, int len) void __iomem *baseAddr; int i; - if(len < 0 || len > sizeof(moxaBuff)) + if(len > sizeof(moxaBuff)) return -EINVAL; if(copy_from_user(moxaBuff, tmp, len)) return -EFAULT; @@ -2598,8 +2596,6 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) void __iomem *baseAddr, *ofsAddr; int retval, port, i; - if(len < 0 || len > sizeof(moxaBuff)) - return -EINVAL; if(copy_from_user(moxaBuff, tmp, len)) return -EFAULT; baseAddr = moxa_boards[cardno].basemem; diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 5953a45d7e96..80a01150b86c 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/char/mxser_new.c b/trunk/drivers/char/mxser_new.c index 6cde448cd5b2..f7603b6aeb87 100644 --- a/trunk/drivers/char/mxser_new.c +++ b/trunk/drivers/char/mxser_new.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/char/n_r3964.c b/trunk/drivers/char/n_r3964.c index 14557a4822c0..65f2d3a96b85 100644 --- a/trunk/drivers/char/n_r3964.c +++ b/trunk/drivers/char/n_r3964.c @@ -1088,13 +1088,13 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, /* block until there is a message: */ add_wait_queue(&pInfo->read_wait, &wait); repeat: - __set_current_state(TASK_INTERRUPTIBLE); + current->state = TASK_INTERRUPTIBLE; pMsg = remove_msg(pInfo, pClient); if (!pMsg && !signal_pending(current)) { schedule(); goto repeat; } - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&pInfo->read_wait, &wait); } diff --git a/trunk/drivers/char/pcmcia/synclink_cs.c b/trunk/drivers/char/pcmcia/synclink_cs.c index 13808f6083a0..157b1d09ab55 100644 --- a/trunk/drivers/char/pcmcia/synclink_cs.c +++ b/trunk/drivers/char/pcmcia/synclink_cs.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/char/ppdev.c b/trunk/drivers/char/ppdev.c index 84ac64fc48a1..4abd1eff61d6 100644 --- a/trunk/drivers/char/ppdev.c +++ b/trunk/drivers/char/ppdev.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -751,7 +752,7 @@ static const struct file_operations pp_fops = { static void pp_attach(struct parport *port) { - device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number), + device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), "parport%d", port->number); } diff --git a/trunk/drivers/char/riscom8.c b/trunk/drivers/char/riscom8.c index 3494e3fc44bf..70145254fb9d 100644 --- a/trunk/drivers/char/riscom8.c +++ b/trunk/drivers/char/riscom8.c @@ -980,7 +980,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, } schedule(); } - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&port->open_wait, &wait); if (!tty_hung_up_p(filp)) port->count++; diff --git a/trunk/drivers/char/rocket.c b/trunk/drivers/char/rocket.c index 61a63da420c2..76357c855ce3 100644 --- a/trunk/drivers/char/rocket.c +++ b/trunk/drivers/char/rocket.c @@ -65,6 +65,10 @@ /****** Kernel includes ******/ +#ifdef MODVERSIONS +#include +#endif + #include #include #include @@ -81,7 +85,6 @@ #include #include #include -#include #include #include #include @@ -90,6 +93,7 @@ #include #include #include +#include #include /****** RocketPort includes ******/ @@ -698,7 +702,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) } } spin_lock_init(&info->slock); - mutex_init(&info->write_mtx); + sema_init(&info->write_sem, 1); rp_table[line] = info; if (pci_dev) tty_register_device(rocket_driver, line, &pci_dev->dev); @@ -943,7 +947,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, #endif schedule(); /* Don't hold spinlock here, will hang PC */ } - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&info->open_wait, &wait); spin_lock_irqsave(&info->slock, flags); @@ -1598,7 +1602,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) if (signal_pending(current)) break; } - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); #endif @@ -1657,11 +1661,8 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch) if (rocket_paranoia_check(info, "rp_put_char")) return; - /* - * Grab the port write mutex, locking out other processes that try to - * write to this port - */ - mutex_lock(&info->write_mtx); + /* Grab the port write semaphore, locking out other processes that try to write to this port */ + down(&info->write_sem); #ifdef ROCKET_DEBUG_WRITE printk(KERN_INFO "rp_put_char %c...", ch); @@ -1683,12 +1684,12 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch) info->xmit_fifo_room--; } spin_unlock_irqrestore(&info->slock, flags); - mutex_unlock(&info->write_mtx); + up(&info->write_sem); } /* * Exception handler - write routine, called when user app writes to the device. - * A per port write mutex is used to protect from another process writing to + * A per port write semaphore is used to protect from another process writing to * this port at the same time. This other process could be running on the other CPU * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). * Spinlocks protect the info xmit members. @@ -1705,7 +1706,7 @@ static int rp_write(struct tty_struct *tty, if (count <= 0 || rocket_paranoia_check(info, "rp_write")) return 0; - mutex_lock_interruptible(&info->write_mtx); + down_interruptible(&info->write_sem); #ifdef ROCKET_DEBUG_WRITE printk(KERN_INFO "rp_write %d chars...", count); @@ -1776,7 +1777,7 @@ static int rp_write(struct tty_struct *tty, wake_up_interruptible(&tty->poll_wait); #endif } - mutex_unlock(&info->write_mtx); + up(&info->write_sem); return retval; } @@ -1851,12 +1852,6 @@ static void rp_flush_buffer(struct tty_struct *tty) #ifdef CONFIG_PCI -static struct pci_device_id __devinitdata rocket_pci_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, - { } -}; -MODULE_DEVICE_TABLE(pci, rocket_pci_ids); - /* * Called when a PCI card is found. Retrieves and stores model information, * init's aiopic and serial port hardware. diff --git a/trunk/drivers/char/rocket_int.h b/trunk/drivers/char/rocket_int.h index 89b4d7b10d12..3a8bcc85bc14 100644 --- a/trunk/drivers/char/rocket_int.h +++ b/trunk/drivers/char/rocket_int.h @@ -15,8 +15,6 @@ #define ROCKET_TYPE_MODEMIII 3 #define ROCKET_TYPE_PC104 4 -#include - #include #include @@ -1173,7 +1171,7 @@ struct r_port { struct wait_queue *close_wait; #endif spinlock_t slock; - struct mutex write_mtx; + struct semaphore write_sem; }; #define RPORT_MAGIC 0x525001 diff --git a/trunk/drivers/char/rtc.c b/trunk/drivers/char/rtc.c index 20380a2c4dee..c7dac9b13351 100644 --- a/trunk/drivers/char/rtc.c +++ b/trunk/drivers/char/rtc.c @@ -388,7 +388,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf, if (!retval) retval = count; out: - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&rtc_wait, &wait); return retval; diff --git a/trunk/drivers/char/selection.c b/trunk/drivers/char/selection.c index a69f094d1ed3..74cff839c857 100644 --- a/trunk/drivers/char/selection.c +++ b/trunk/drivers/char/selection.c @@ -299,7 +299,7 @@ int paste_selection(struct tty_struct *tty) pasted += count; } remove_wait_queue(&vc->paste_wait, &wait); - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; tty_ldisc_deref(ld); return 0; diff --git a/trunk/drivers/char/serial167.c b/trunk/drivers/char/serial167.c index c585b4738f86..5fd314adc1f2 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/drivers/char/serial167.c @@ -1892,7 +1892,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, #endif schedule(); } - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; remove_wait_queue(&info->open_wait, &wait); if (!tty_hung_up_p(filp)) { info->count++; diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index f02a0795983f..ce4db6f52362 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -4010,13 +4010,8 @@ static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info) for ( i=0; inum_tx_holding_buffers; ++i) { info->tx_holding_buffers[i].buffer = kmalloc(info->max_frame_size, GFP_KERNEL); - if (info->tx_holding_buffers[i].buffer == NULL) { - for (--i; i >= 0; i--) { - kfree(info->tx_holding_buffers[i].buffer); - info->tx_holding_buffers[i].buffer = NULL; - } + if ( info->tx_holding_buffers[i].buffer == NULL ) return -ENOMEM; - } } return 0; diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index 2a7736b5f2f7..0a367cd4121f 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -3415,9 +3415,6 @@ static void device_init(int adapter_num, struct pci_dev *pdev) } } } - - for (i=0; i < port_count; ++i) - tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev)); } static int __devinit init_one(struct pci_dev *dev, @@ -3469,8 +3466,6 @@ static void slgt_cleanup(void) printk("unload %s %s\n", driver_name, driver_version); if (serial_driver) { - for (info=slgt_device_list ; info != NULL ; info=info->next_device) - tty_unregister_device(serial_driver, info->line); if ((rc = tty_unregister_driver(serial_driver))) DBGERR(("tty_unregister_driver error=%d\n", rc)); put_tty_driver(serial_driver); @@ -3511,10 +3506,23 @@ static int __init slgt_init(void) printk("%s %s\n", driver_name, driver_version); + slgt_device_count = 0; + if ((rc = pci_register_driver(&pci_driver)) < 0) { + printk("%s pci_register_driver error=%d\n", driver_name, rc); + return rc; + } + pci_registered = 1; + + if (!slgt_device_list) { + printk("%s no devices found\n",driver_name); + pci_unregister_driver(&pci_driver); + return -ENODEV; + } + serial_driver = alloc_tty_driver(MAX_DEVICES); if (!serial_driver) { - printk("%s can't allocate tty driver\n", driver_name); - return -ENOMEM; + rc = -ENOMEM; + goto error; } /* Initialize the tty_driver structure */ @@ -3531,7 +3539,7 @@ static int __init slgt_init(void) B9600 | CS8 | CREAD | HUPCL | CLOCAL; serial_driver->init_termios.c_ispeed = 9600; serial_driver->init_termios.c_ospeed = 9600; - serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; + serial_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(serial_driver, &ops); if ((rc = tty_register_driver(serial_driver)) < 0) { DBGERR(("%s can't register serial driver\n", driver_name)); @@ -3544,16 +3552,6 @@ static int __init slgt_init(void) driver_name, driver_version, serial_driver->major); - slgt_device_count = 0; - if ((rc = pci_register_driver(&pci_driver)) < 0) { - printk("%s pci_register_driver error=%d\n", driver_name, rc); - goto error; - } - pci_registered = 1; - - if (!slgt_device_list) - printk("%s no devices found\n",driver_name); - return 0; error: diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c index 39cc318011ea..1d8c4ae61551 100644 --- a/trunk/drivers/char/sysrq.c +++ b/trunk/drivers/char/sysrq.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/char/tipar.c b/trunk/drivers/char/tipar.c index 35b40b996534..47fb20f69695 100644 --- a/trunk/drivers/char/tipar.c +++ b/trunk/drivers/char/tipar.c @@ -442,7 +442,7 @@ tipar_register(int nr, struct parport *port) } class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, - TIPAR_MINOR + nr), port->dev, "par%d", nr); + TIPAR_MINOR + nr), NULL, "par%d", nr); /* Display informations */ pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 9bb542913b86..e5a254a434f8 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -24,9 +24,7 @@ */ #include -#include #include - #include "tpm.h" enum tpm_const { @@ -330,10 +328,10 @@ static void timeout_work(struct work_struct *work) { struct tpm_chip *chip = container_of(work, struct tpm_chip, work); - mutex_lock(&chip->buffer_mutex); + down(&chip->buffer_mutex); atomic_set(&chip->data_pending, 0); memset(chip->data_buffer, 0, TPM_BUFSIZE); - mutex_unlock(&chip->buffer_mutex); + up(&chip->buffer_mutex); } /* @@ -382,7 +380,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, return -E2BIG; } - mutex_lock(&chip->tpm_mutex); + down(&chip->tpm_mutex); if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { dev_err(chip->dev, @@ -421,7 +419,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, dev_err(chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc); out: - mutex_unlock(&chip->tpm_mutex); + up(&chip->tpm_mutex); return rc; } @@ -944,12 +942,12 @@ int tpm_release(struct inode *inode, struct file *file) { struct tpm_chip *chip = file->private_data; - flush_scheduled_work(); spin_lock(&driver_lock); file->private_data = NULL; + chip->num_opens--; del_singleshot_timer_sync(&chip->user_read_timer); + flush_scheduled_work(); atomic_set(&chip->data_pending, 0); - chip->num_opens--; put_device(chip->dev); kfree(chip->data_buffer); spin_unlock(&driver_lock); @@ -968,14 +966,14 @@ ssize_t tpm_write(struct file *file, const char __user *buf, while (atomic_read(&chip->data_pending) != 0) msleep(TPM_TIMEOUT); - mutex_lock(&chip->buffer_mutex); + down(&chip->buffer_mutex); if (in_size > TPM_BUFSIZE) in_size = TPM_BUFSIZE; if (copy_from_user (chip->data_buffer, (void __user *) buf, in_size)) { - mutex_unlock(&chip->buffer_mutex); + up(&chip->buffer_mutex); return -EFAULT; } @@ -983,7 +981,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf, out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); atomic_set(&chip->data_pending, out_size); - mutex_unlock(&chip->buffer_mutex); + up(&chip->buffer_mutex); /* Set a timeout by which the reader must come claim the result */ mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); @@ -1006,10 +1004,10 @@ ssize_t tpm_read(struct file *file, char __user *buf, if (size < ret_size) ret_size = size; - mutex_lock(&chip->buffer_mutex); + down(&chip->buffer_mutex); if (copy_to_user(buf, chip->data_buffer, ret_size)) ret_size = -EFAULT; - mutex_unlock(&chip->buffer_mutex); + up(&chip->buffer_mutex); } return ret_size; @@ -1099,16 +1097,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend /* Driver specific per-device data */ chip = kzalloc(sizeof(*chip), GFP_KERNEL); - devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); - - if (chip == NULL || devname == NULL) { - kfree(chip); - kfree(devname); + if (chip == NULL) return NULL; - } - mutex_init(&chip->buffer_mutex); - mutex_init(&chip->tpm_mutex); + init_MUTEX(&chip->buffer_mutex); + init_MUTEX(&chip->tpm_mutex); INIT_LIST_HEAD(&chip->list); INIT_WORK(&chip->work, timeout_work); @@ -1131,6 +1124,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend set_bit(chip->dev_num, dev_mask); + devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); chip->vendor.miscdev.name = devname; diff --git a/trunk/drivers/char/tpm/tpm.h b/trunk/drivers/char/tpm/tpm.h index b2e2b002a1bb..bb9a43c6cf3d 100644 --- a/trunk/drivers/char/tpm/tpm.h +++ b/trunk/drivers/char/tpm/tpm.h @@ -19,9 +19,9 @@ * */ #include +#include #include #include -#include #include #include #include @@ -95,11 +95,11 @@ struct tpm_chip { /* Data passed to and from the tpm via the read/write calls */ u8 *data_buffer; atomic_t data_pending; - struct mutex buffer_mutex; + struct semaphore buffer_mutex; struct timer_list user_read_timer; /* user needs to claim result */ struct work_struct work; - struct mutex tpm_mutex; /* tpm is processing */ + struct semaphore tpm_mutex; /* tpm is processing */ struct tpm_vendor_specific vendor; diff --git a/trunk/drivers/char/tpm/tpm_atmel.h b/trunk/drivers/char/tpm/tpm_atmel.h index c912d8691cbd..3c852009196e 100644 --- a/trunk/drivers/char/tpm/tpm_atmel.h +++ b/trunk/drivers/char/tpm/tpm_atmel.h @@ -47,12 +47,12 @@ static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size) if (!dn) return NULL; - if (!of_device_is_compatible(dn, "AT97SC3201")) { + if (!device_is_compatible(dn, "AT97SC3201")) { of_node_put(dn); return NULL; } - reg = of_get_property(dn, "reg", ®len); + reg = get_property(dn, "reg", ®len); naddrc = of_n_addr_cells(dn); nsizec = of_n_size_cells(dn); diff --git a/trunk/drivers/char/tpm/tpm_infineon.c b/trunk/drivers/char/tpm/tpm_infineon.c index 967002a5a1e5..1353b5a6bae8 100644 --- a/trunk/drivers/char/tpm/tpm_infineon.c +++ b/trunk/drivers/char/tpm/tpm_infineon.c @@ -30,60 +30,12 @@ #define TPM_MAX_TRIES 5000 #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 -#define TPM_INF_IO_PORT 0x0 -#define TPM_INF_IO_MEM 0x1 - -#define TPM_INF_ADDR 0x0 -#define TPM_INF_DATA 0x1 - -struct tpm_inf_dev { - int iotype; - - void __iomem *mem_base; /* MMIO ioremap'd addr */ - unsigned long map_base; /* phys MMIO base */ - unsigned long map_size; /* MMIO region size */ - unsigned int index_off; /* index register offset */ - - unsigned int data_regs; /* Data registers */ - unsigned int data_size; - - unsigned int config_port; /* IO Port config index reg */ - unsigned int config_size; -}; - -static struct tpm_inf_dev tpm_dev; - -static inline void tpm_data_out(unsigned char data, unsigned char offset) -{ - if (tpm_dev.iotype == TPM_INF_IO_PORT) - outb(data, tpm_dev.data_regs + offset); - else - writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset); -} - -static inline unsigned char tpm_data_in(unsigned char offset) -{ - if (tpm_dev.iotype == TPM_INF_IO_PORT) - return inb(tpm_dev.data_regs + offset); - else - return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset); -} - -static inline void tpm_config_out(unsigned char data, unsigned char offset) -{ - if (tpm_dev.iotype == TPM_INF_IO_PORT) - outb(data, tpm_dev.config_port + offset); - else - writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset); -} - -static inline unsigned char tpm_config_in(unsigned char offset) -{ - if (tpm_dev.iotype == TPM_INF_IO_PORT) - return inb(tpm_dev.config_port + offset); - else - return readb(tpm_dev.mem_base + tpm_dev.index_off + offset); -} +/* These values will be filled after PnP-call */ +static int TPM_INF_DATA; +static int TPM_INF_ADDR; +static int TPM_INF_BASE; +static int TPM_INF_ADDR_LEN; +static int TPM_INF_PORT_LEN; /* TPM header definitions */ enum infineon_tpm_header { @@ -153,7 +105,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) if (clear_wrfifo) { for (i = 0; i < 4096; i++) { - status = tpm_data_in(WRFIFO); + status = inb(chip->vendor.base + WRFIFO); if (status == 0xff) { if (check == 5) break; @@ -173,8 +125,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) */ i = 0; do { - status = tpm_data_in(RDFIFO); - status = tpm_data_in(STAT); + status = inb(chip->vendor.base + RDFIFO); + status = inb(chip->vendor.base + STAT); i++; if (i == TPM_MAX_TRIES) return -EIO; @@ -187,7 +139,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) int status; int i; for (i = 0; i < TPM_MAX_TRIES; i++) { - status = tpm_data_in(STAT); + status = inb(chip->vendor.base + STAT); /* check the status-register if wait_for_bit is set */ if (status & 1 << wait_for_bit) break; @@ -206,7 +158,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) { wait(chip, STAT_XFE); - tpm_data_out(sendbyte, WRFIFO); + outb(sendbyte, chip->vendor.base + WRFIFO); } /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more @@ -253,7 +205,7 @@ static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) ret = wait(chip, STAT_RDA); if (ret) return -EIO; - buf[i] = tpm_data_in(RDFIFO); + buf[i] = inb(chip->vendor.base + RDFIFO); } if (buf[0] != TPM_VL_VER) { @@ -268,7 +220,7 @@ static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count) for (i = 0; i < size; i++) { wait(chip, STAT_RDA); - buf[i] = tpm_data_in(RDFIFO); + buf[i] = inb(chip->vendor.base + RDFIFO); } if ((size == 0x6D00) && (buf[1] == 0x80)) { @@ -317,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) u8 count_high, count_low, count_4, count_3, count_2, count_1; /* Disabling Reset, LP and IRQC */ - tpm_data_out(RESET_LP_IRQC_DISABLE, CMD); + outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD); ret = empty_fifo(chip, 1); if (ret) { @@ -368,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip) static u8 tpm_inf_status(struct tpm_chip *chip) { - return tpm_data_in(STAT); + return inb(chip->vendor.base + STAT); } static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); @@ -429,88 +381,51 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, /* read IO-ports through PnP */ if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { - - tpm_dev.iotype = TPM_INF_IO_PORT; - - tpm_dev.config_port = pnp_port_start(dev, 0); - tpm_dev.config_size = pnp_port_len(dev, 0); - tpm_dev.data_regs = pnp_port_start(dev, 1); - tpm_dev.data_size = pnp_port_len(dev, 1); - if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) { + TPM_INF_ADDR = pnp_port_start(dev, 0); + TPM_INF_ADDR_LEN = pnp_port_len(dev, 0); + TPM_INF_DATA = (TPM_INF_ADDR + 1); + TPM_INF_BASE = pnp_port_start(dev, 1); + TPM_INF_PORT_LEN = pnp_port_len(dev, 1); + if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) { rc = -EINVAL; goto err_last; } dev_info(&dev->dev, "Found %s with ID %s\n", dev->name, dev_id->id); - if (!((tpm_dev.data_regs >> 8) & 0xff)) { + if (!((TPM_INF_BASE >> 8) & 0xff)) { rc = -EINVAL; goto err_last; } /* publish my base address and request region */ - if (request_region(tpm_dev.data_regs, tpm_dev.data_size, - "tpm_infineon0") == NULL) { + if (request_region + (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { rc = -EINVAL; goto err_last; } - if (request_region(tpm_dev.config_port, tpm_dev.config_size, - "tpm_infineon0") == NULL) { - release_region(tpm_dev.data_regs, tpm_dev.data_size); + if (request_region + (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) { rc = -EINVAL; goto err_last; } - } else if (pnp_mem_valid(dev, 0) && - !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) { - - tpm_dev.iotype = TPM_INF_IO_MEM; - - tpm_dev.map_base = pnp_mem_start(dev, 0); - tpm_dev.map_size = pnp_mem_len(dev, 0); - - dev_info(&dev->dev, "Found %s with ID %s\n", - dev->name, dev_id->id); - - /* publish my base address and request region */ - if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size, - "tpm_infineon0") == NULL) { - rc = -EINVAL; - goto err_last; - } - - tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size); - if (tpm_dev.mem_base == NULL) { - release_mem_region(tpm_dev.map_base, tpm_dev.map_size); - rc = -EINVAL; - goto err_last; - } - - /* - * The only known MMIO based Infineon TPM system provides - * a single large mem region with the device config - * registers at the default TPM_ADDR. The data registers - * seem like they could be placed anywhere within the MMIO - * region, but lets just put them at zero offset. - */ - tpm_dev.index_off = TPM_ADDR; - tpm_dev.data_regs = 0x0; } else { rc = -EINVAL; goto err_last; } /* query chip for its vendor, its version number a.s.o. */ - tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); - tpm_config_out(IDVENL, TPM_INF_ADDR); - vendorid[1] = tpm_config_in(TPM_INF_DATA); - tpm_config_out(IDVENH, TPM_INF_ADDR); - vendorid[0] = tpm_config_in(TPM_INF_DATA); - tpm_config_out(IDPDL, TPM_INF_ADDR); - productid[1] = tpm_config_in(TPM_INF_DATA); - tpm_config_out(IDPDH, TPM_INF_ADDR); - productid[0] = tpm_config_in(TPM_INF_DATA); - tpm_config_out(CHIP_ID1, TPM_INF_ADDR); - version[1] = tpm_config_in(TPM_INF_DATA); - tpm_config_out(CHIP_ID2, TPM_INF_ADDR); - version[0] = tpm_config_in(TPM_INF_DATA); + outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); + outb(IDVENL, TPM_INF_ADDR); + vendorid[1] = inb(TPM_INF_DATA); + outb(IDVENH, TPM_INF_ADDR); + vendorid[0] = inb(TPM_INF_DATA); + outb(IDPDL, TPM_INF_ADDR); + productid[1] = inb(TPM_INF_DATA); + outb(IDPDH, TPM_INF_ADDR); + productid[0] = inb(TPM_INF_DATA); + outb(CHIP_ID1, TPM_INF_ADDR); + version[1] = inb(TPM_INF_DATA); + outb(CHIP_ID2, TPM_INF_ADDR); + version[0] = inb(TPM_INF_DATA); switch ((productid[0] << 8) | productid[1]) { case 6: @@ -527,54 +442,51 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { /* configure TPM with IO-ports */ - tpm_config_out(IOLIMH, TPM_INF_ADDR); - tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA); - tpm_config_out(IOLIML, TPM_INF_ADDR); - tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA); + outb(IOLIMH, TPM_INF_ADDR); + outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA); + outb(IOLIML, TPM_INF_ADDR); + outb((TPM_INF_BASE & 0xff), TPM_INF_DATA); /* control if IO-ports are set correctly */ - tpm_config_out(IOLIMH, TPM_INF_ADDR); - ioh = tpm_config_in(TPM_INF_DATA); - tpm_config_out(IOLIML, TPM_INF_ADDR); - iol = tpm_config_in(TPM_INF_DATA); + outb(IOLIMH, TPM_INF_ADDR); + ioh = inb(TPM_INF_DATA); + outb(IOLIML, TPM_INF_ADDR); + iol = inb(TPM_INF_DATA); - if ((ioh << 8 | iol) != tpm_dev.data_regs) { + if ((ioh << 8 | iol) != TPM_INF_BASE) { dev_err(&dev->dev, - "Could not set IO-data registers to 0x%x\n", - tpm_dev.data_regs); + "Could not set IO-ports to 0x%x\n", + TPM_INF_BASE); rc = -EIO; goto err_release_region; } /* activate register */ - tpm_config_out(TPM_DAR, TPM_INF_ADDR); - tpm_config_out(0x01, TPM_INF_DATA); - tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); + outb(TPM_DAR, TPM_INF_ADDR); + outb(0x01, TPM_INF_DATA); + outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); /* disable RESET, LP and IRQC */ - tpm_data_out(RESET_LP_IRQC_DISABLE, CMD); + outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD); /* Finally, we're done, print some infos */ dev_info(&dev->dev, "TPM found: " - "config base 0x%lx, " - "data base 0x%lx, " + "config base 0x%x, " + "io base 0x%x, " "chip version 0x%02x%02x, " "vendor id 0x%x%x (Infineon), " "product id 0x%02x%02x" "%s\n", - tpm_dev.iotype == TPM_INF_IO_PORT ? - tpm_dev.config_port : - tpm_dev.map_base + tpm_dev.index_off, - tpm_dev.iotype == TPM_INF_IO_PORT ? - tpm_dev.data_regs : - tpm_dev.map_base + tpm_dev.data_regs, + TPM_INF_ADDR, + TPM_INF_BASE, version[0], version[1], vendorid[0], vendorid[1], productid[0], productid[1], chipname); - if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) + if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) { goto err_release_region; - + } + chip->vendor.base = TPM_INF_BASE; return 0; } else { rc = -ENODEV; @@ -582,13 +494,8 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, } err_release_region: - if (tpm_dev.iotype == TPM_INF_IO_PORT) { - release_region(tpm_dev.data_regs, tpm_dev.data_size); - release_region(tpm_dev.config_port, tpm_dev.config_size); - } else { - iounmap(tpm_dev.mem_base); - release_mem_region(tpm_dev.map_base, tpm_dev.map_size); - } + release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); + release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); err_last: return rc; @@ -599,14 +506,8 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) struct tpm_chip *chip = pnp_get_drvdata(dev); if (chip) { - if (tpm_dev.iotype == TPM_INF_IO_PORT) { - release_region(tpm_dev.data_regs, tpm_dev.data_size); - release_region(tpm_dev.config_port, - tpm_dev.config_size); - } else { - iounmap(tpm_dev.mem_base); - release_mem_region(tpm_dev.map_base, tpm_dev.map_size); - } + release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); + release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); tpm_remove_hardware(chip->dev); } } @@ -638,5 +539,5 @@ module_exit(cleanup_inf); MODULE_AUTHOR("Marcel Selhorst "); MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); -MODULE_VERSION("1.9"); +MODULE_VERSION("1.8"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 7710a6a77d97..7a32df594907 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -141,6 +141,8 @@ static DECLARE_MUTEX(allocated_ptys_lock); static int ptmx_open(struct inode *, struct file *); #endif +extern void disable_early_printk(void); + static void initialize_tty_struct(struct tty_struct *tty); static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); @@ -153,8 +155,8 @@ int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); static int tty_fasync(int fd, struct file * filp, int on); static void release_tty(struct tty_struct *tty, int idx); -static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); -static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); +static struct pid *__proc_set_tty(struct task_struct *tsk, + struct tty_struct *tty); /** * alloc_tty_struct - allocate a tty object @@ -1532,9 +1534,10 @@ void disassociate_ctty(int on_exit) } spin_lock_irq(¤t->sighand->siglock); - put_pid(current->signal->tty_old_pgrp); + tty_pgrp = current->signal->tty_old_pgrp; current->signal->tty_old_pgrp = NULL; spin_unlock_irq(¤t->sighand->siglock); + put_pid(tty_pgrp); mutex_lock(&tty_mutex); /* It is possible that do_tty_hangup has free'd this tty */ @@ -1559,18 +1562,6 @@ void disassociate_ctty(int on_exit) unlock_kernel(); } -/** - * - * no_tty - Ensure the current process does not have a controlling tty - */ -void no_tty(void) -{ - struct task_struct *tsk = current; - if (tsk->signal->leader) - disassociate_ctty(0); - proc_clear_tty(tsk); -} - /** * stop_tty - propogate flow control @@ -2517,6 +2508,7 @@ static int tty_open(struct inode * inode, struct file * filp) int index; dev_t device = inode->i_rdev; unsigned short saved_flags = filp->f_flags; + struct pid *old_pgrp; nonseekable_open(inode, filp); @@ -2610,15 +2602,17 @@ static int tty_open(struct inode * inode, struct file * filp) goto retry_open; } + old_pgrp = NULL; mutex_lock(&tty_mutex); spin_lock_irq(¤t->sighand->siglock); if (!noctty && current->signal->leader && !current->signal->tty && tty->session == NULL) - __proc_set_tty(current, tty); + old_pgrp = __proc_set_tty(current, tty); spin_unlock_irq(¤t->sighand->siglock); mutex_unlock(&tty_mutex); + put_pid(old_pgrp); return 0; } @@ -3293,7 +3287,9 @@ int tty_ioctl(struct inode * inode, struct file * file, case TIOCNOTTY: if (current->signal->tty != tty) return -ENOTTY; - no_tty(); + if (current->signal->leader) + disassociate_ctty(0); + proc_clear_tty(current); return 0; case TIOCSCTTY: return tiocsctty(tty, arg); @@ -3724,10 +3720,11 @@ int tty_register_driver(struct tty_driver *driver) if (driver->flags & TTY_DRIVER_INSTALLED) return 0; - if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { - p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); + if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) { + p = kmalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); if (!p) return -ENOMEM; + memset(p, 0, driver->num * 3 * sizeof(void *)); } if (!driver->major) { @@ -3770,9 +3767,7 @@ int tty_register_driver(struct tty_driver *driver) if (!driver->put_char) driver->put_char = tty_default_put_char; - mutex_lock(&tty_mutex); list_add(&driver->tty_drivers, &tty_drivers); - mutex_unlock(&tty_mutex); if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) { for(i = 0; i < driver->num; i++) @@ -3798,9 +3793,8 @@ int tty_unregister_driver(struct tty_driver *driver) unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), driver->num); - mutex_lock(&tty_mutex); + list_del(&driver->tty_drivers); - mutex_unlock(&tty_mutex); /* * Free the termios and termios_locked structures because @@ -3843,9 +3837,11 @@ void proc_clear_tty(struct task_struct *p) p->signal->tty = NULL; spin_unlock_irq(&p->sighand->siglock); } +EXPORT_SYMBOL(proc_clear_tty); -static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) +static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) { + struct pid *old_pgrp; if (tty) { /* We should not have a session or pgrp to here but.... */ put_pid(tty->session); @@ -3853,16 +3849,21 @@ static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) tty->session = get_pid(task_session(tsk)); tty->pgrp = get_pid(task_pgrp(tsk)); } - put_pid(tsk->signal->tty_old_pgrp); + old_pgrp = tsk->signal->tty_old_pgrp; tsk->signal->tty = tty; tsk->signal->tty_old_pgrp = NULL; + return old_pgrp; } -static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) +void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) { + struct pid *old_pgrp; + spin_lock_irq(&tsk->sighand->siglock); - __proc_set_tty(tsk, tty); + old_pgrp = __proc_set_tty(tsk, tty); spin_unlock_irq(&tsk->sighand->siglock); + + put_pid(old_pgrp); } struct tty_struct *get_current_tty(void) @@ -3897,6 +3898,9 @@ void __init console_init(void) * set up the console device so that later boot sequences can * inform about problems etc.. */ +#ifdef CONFIG_EARLY_PRINTK + disable_early_printk(); +#endif call = __con_initcall_start; while (call < __con_initcall_end) { (*call)(); diff --git a/trunk/drivers/char/vc_screen.c b/trunk/drivers/char/vc_screen.c index 83aeedda200c..791930320a13 100644 --- a/trunk/drivers/char/vc_screen.c +++ b/trunk/drivers/char/vc_screen.c @@ -28,13 +28,12 @@ #include #include #include -#include #include #include #include #include +#include #include - #include #include #include @@ -71,11 +70,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) { int size; - mutex_lock(&con_buf_mtx); + down(&con_buf_sem); size = vcs_size(file->f_path.dentry->d_inode); switch (orig) { default: - mutex_unlock(&con_buf_mtx); + up(&con_buf_sem); return -EINVAL; case 2: offset += size; @@ -86,11 +85,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) break; } if (offset < 0 || offset > size) { - mutex_unlock(&con_buf_mtx); + up(&con_buf_sem); return -EINVAL; } file->f_pos = offset; - mutex_unlock(&con_buf_mtx); + up(&con_buf_sem); return file->f_pos; } @@ -107,7 +106,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) unsigned short *org = NULL; ssize_t ret; - mutex_lock(&con_buf_mtx); + down(&con_buf_sem); pos = *ppos; @@ -264,7 +263,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) ret = read; unlock_out: release_console_sem(); - mutex_unlock(&con_buf_mtx); + up(&con_buf_sem); return ret; } @@ -281,7 +280,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) u16 *org0 = NULL, *org = NULL; size_t ret; - mutex_lock(&con_buf_mtx); + down(&con_buf_sem); pos = *ppos; @@ -451,7 +450,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) unlock_out: release_console_sem(); - mutex_unlock(&con_buf_mtx); + up(&con_buf_sem); return ret; } diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index bbd9fc412877..1bbb45b937fd 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -86,7 +86,6 @@ #include #include #include -#include #include #include #include @@ -158,8 +157,6 @@ static void blank_screen_t(unsigned long dummy); static void set_palette(struct vc_data *vc); static int printable; /* Is console ready for printing? */ -static int default_utf8; -module_param(default_utf8, int, S_IRUGO | S_IWUSR); /* * ignore_poke: don't unblank the screen when things are typed. This is @@ -351,12 +348,10 @@ void update_region(struct vc_data *vc, unsigned long start, int count) /* Structure of attributes is hardware-dependent */ -static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, - u8 _underline, u8 _reverse, u8 _italic) +static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse) { if (vc->vc_sw->con_build_attr) - return vc->vc_sw->con_build_attr(vc, _color, _intensity, - _blink, _underline, _reverse, _italic); + return vc->vc_sw->con_build_attr(vc, _color, _intensity, _blink, _underline, _reverse); #ifndef VT_BUF_VRAM_ONLY /* @@ -373,13 +368,10 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 a = vc->vc_color; if (!vc->vc_can_do_color) return _intensity | - (_italic ? 2 : 0) | (_underline ? 4 : 0) | (_reverse ? 8 : 0) | (_blink ? 0x80 : 0); - if (_italic) - a = (a & 0xF0) | vc->vc_itcolor; - else if (_underline) + if (_underline) a = (a & 0xf0) | vc->vc_ulcolor; else if (_intensity == 0) a = (a & 0xf0) | vc->vc_ulcolor; @@ -400,10 +392,8 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, static void update_attr(struct vc_data *vc) { - vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, - vc->vc_blink, vc->vc_underline, - vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); - vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; + vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm); + vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm) << 8) | ' '; } /* Note: inverting the screen twice should revert to the original state */ @@ -944,10 +934,6 @@ int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; -module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR); -module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR); -module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR); - /* * gotoxy() must verify all boundaries, because the arguments * might also be negative. If the given position is out of @@ -1146,7 +1132,6 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi static void default_attr(struct vc_data *vc) { vc->vc_intensity = 1; - vc->vc_italic = 0; vc->vc_underline = 0; vc->vc_reverse = 0; vc->vc_blink = 0; @@ -1169,9 +1154,6 @@ static void csi_m(struct vc_data *vc) case 2: vc->vc_intensity = 0; break; - case 3: - vc->vc_italic = 1; - break; case 4: vc->vc_underline = 1; break; @@ -1212,9 +1194,6 @@ static void csi_m(struct vc_data *vc) case 22: vc->vc_intensity = 1; break; - case 23: - vc->vc_italic = 0; - break; case 24: vc->vc_underline = 0; break; @@ -1475,7 +1454,6 @@ static void save_cur(struct vc_data *vc) vc->vc_saved_x = vc->vc_x; vc->vc_saved_y = vc->vc_y; vc->vc_s_intensity = vc->vc_intensity; - vc->vc_s_italic = vc->vc_italic; vc->vc_s_underline = vc->vc_underline; vc->vc_s_blink = vc->vc_blink; vc->vc_s_reverse = vc->vc_reverse; @@ -1490,7 +1468,6 @@ static void restore_cur(struct vc_data *vc) { gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y); vc->vc_intensity = vc->vc_s_intensity; - vc->vc_italic = vc->vc_s_italic; vc->vc_underline = vc->vc_s_underline; vc->vc_blink = vc->vc_s_blink; vc->vc_reverse = vc->vc_s_reverse; @@ -1520,7 +1497,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) vc->vc_charset = 0; vc->vc_need_wrap = 0; vc->vc_report_mouse = 0; - vc->vc_utf = default_utf8; + vc->vc_utf = 0; vc->vc_utf_count = 0; vc->vc_disp_ctrl = 0; @@ -1953,47 +1930,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) * kernel memory allocation is available. */ char con_buf[CON_BUF_SIZE]; -DEFINE_MUTEX(con_buf_mtx); - -/* is_double_width() is based on the wcwidth() implementation by - * Markus Kuhn -- 2003-05-20 (Unicode 4.0) - * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - */ -struct interval { - uint32_t first; - uint32_t last; -}; - -static int bisearch(uint32_t ucs, const struct interval *table, int max) -{ - int min = 0; - int mid; - - if (ucs < table[0].first || ucs > table[max].last) - return 0; - while (max >= min) { - mid = (min + max) / 2; - if (ucs > table[mid].last) - min = mid + 1; - else if (ucs < table[mid].first) - max = mid - 1; - else - return 1; - } - return 0; -} - -static int is_double_width(uint32_t ucs) -{ - static const struct interval double_width[] = { - { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E }, - { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF }, - { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, { 0xFFE0, 0xFFE6 }, - { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } - }; - return bisearch(ucs, double_width, - sizeof(double_width) / sizeof(*double_width) - 1); -} +DECLARE_MUTEX(con_buf_sem); /* acquires console_sem */ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) @@ -2011,10 +1948,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co unsigned int currcons; unsigned long draw_from = 0, draw_to = 0; struct vc_data *vc; - unsigned char vc_attr; - uint8_t rescan; - uint8_t inverse; - uint8_t width; u16 himask, charmask; const unsigned char *orig_buf = NULL; int orig_count; @@ -2050,7 +1983,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co /* At this point 'buf' is guaranteed to be a kernel buffer * and therefore no access to userspace (and therefore sleeping) - * will be needed. The con_buf_mtx serializes all tty based + * will be needed. The con_buf_sem serializes all tty based * console rendering and vcs write/read operations. We hold * the console spinlock during the entire write. */ @@ -2077,86 +2010,53 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co buf++; n++; count--; - rescan = 0; - inverse = 0; - width = 1; /* Do no translation at all in control states */ if (vc->vc_state != ESnormal) { tc = c; } else if (vc->vc_utf && !vc->vc_disp_ctrl) { - /* Combine UTF-8 into Unicode in vc_utf_char. - * vc_utf_count is the number of continuation bytes still - * expected to arrive. - * vc_npar is the number of continuation bytes arrived so - * far - */ + /* Combine UTF-8 into Unicode */ + /* Malformed sequences as sequences of replacement glyphs */ rescan_last_byte: - if ((c & 0xc0) == 0x80) { - /* Continuation byte received */ - static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff }; + if(c > 0x7f) { if (vc->vc_utf_count) { - vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); - vc->vc_npar++; - if (--vc->vc_utf_count) { - /* Still need some bytes */ - continue; - } - /* Got a whole character */ - c = vc->vc_utf_char; - /* Reject overlong sequences */ - if (c <= utf8_length_changes[vc->vc_npar - 1] || - c > utf8_length_changes[vc->vc_npar]) - c = 0xfffd; + if ((c & 0xc0) == 0x80) { + vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); + if (--vc->vc_utf_count) { + vc->vc_npar++; + continue; + } + tc = c = vc->vc_utf_char; + } else + goto replacement_glyph; } else { - /* Unexpected continuation byte */ - vc->vc_utf_count = 0; - c = 0xfffd; - } - } else { - /* Single ASCII byte or first byte of a sequence received */ - if (vc->vc_utf_count) { - /* Continuation byte expected */ - rescan = 1; - vc->vc_utf_count = 0; - c = 0xfffd; - } else if (c > 0x7f) { - /* First byte of a multibyte sequence received */ - vc->vc_npar = 0; - if ((c & 0xe0) == 0xc0) { - vc->vc_utf_count = 1; - vc->vc_utf_char = (c & 0x1f); - } else if ((c & 0xf0) == 0xe0) { - vc->vc_utf_count = 2; - vc->vc_utf_char = (c & 0x0f); - } else if ((c & 0xf8) == 0xf0) { - vc->vc_utf_count = 3; - vc->vc_utf_char = (c & 0x07); - } else if ((c & 0xfc) == 0xf8) { - vc->vc_utf_count = 4; - vc->vc_utf_char = (c & 0x03); - } else if ((c & 0xfe) == 0xfc) { - vc->vc_utf_count = 5; - vc->vc_utf_char = (c & 0x01); - } else { - /* 254 and 255 are invalid */ - c = 0xfffd; - } - if (vc->vc_utf_count) { - /* Still need some bytes */ + vc->vc_npar = 0; + if ((c & 0xe0) == 0xc0) { + vc->vc_utf_count = 1; + vc->vc_utf_char = (c & 0x1f); + } else if ((c & 0xf0) == 0xe0) { + vc->vc_utf_count = 2; + vc->vc_utf_char = (c & 0x0f); + } else if ((c & 0xf8) == 0xf0) { + vc->vc_utf_count = 3; + vc->vc_utf_char = (c & 0x07); + } else if ((c & 0xfc) == 0xf8) { + vc->vc_utf_count = 4; + vc->vc_utf_char = (c & 0x03); + } else if ((c & 0xfe) == 0xfc) { + vc->vc_utf_count = 5; + vc->vc_utf_char = (c & 0x01); + } else + goto replacement_glyph; continue; - } - } - /* Nothing to do if an ASCII byte was received */ + } + } else { + if (vc->vc_utf_count) + goto replacement_glyph; + tc = c; } - /* End of UTF-8 decoding. */ - /* c is the received character, or U+FFFD for invalid sequences. */ - /* Replace invalid Unicode code points with U+FFFD too */ - if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) - c = 0xfffd; - tc = c; } else { /* no utf or alternate charset mode */ - tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; + tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; } /* If the original code was a control character we @@ -2176,80 +2076,56 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co && (c != 128+27); if (vc->vc_state == ESnormal && ok) { - if (vc->vc_utf && !vc->vc_disp_ctrl) { - if (is_double_width(c)) - width = 2; - } /* Now try to find out how to display it */ tc = conv_uni_to_pc(vc, tc); if (tc & ~charmask) { - if (tc == -1 || tc == -2) { - continue; /* nothing to display */ - } - /* Glyph not found */ - if (!(vc->vc_utf && !vc->vc_disp_ctrl) && !(c & ~charmask)) { - /* In legacy mode use the glyph we get by a 1:1 mapping. - This would make absolutely no sense with Unicode in mind. */ - tc = c; - } else { - /* Display U+FFFD. If it's not found, display an inverse question mark. */ - tc = conv_uni_to_pc(vc, 0xfffd); - if (tc < 0) { - inverse = 1; - tc = conv_uni_to_pc(vc, '?'); - if (tc < 0) tc = '?'; - } - } + if ( tc == -4 ) { + /* If we got -4 (not found) then see if we have + defined a replacement character (U+FFFD) */ +replacement_glyph: + tc = conv_uni_to_pc(vc, 0xfffd); + if (!(tc & ~charmask)) + goto display_glyph; + } else if ( tc != -3 ) + continue; /* nothing to display */ + /* no hash table or no replacement -- + * hope for the best */ + if ( c & ~charmask ) + tc = '?'; + else + tc = c; } - if (!inverse) { - vc_attr = vc->vc_attr; +display_glyph: + if (vc->vc_need_wrap || vc->vc_decim) + FLUSH + if (vc->vc_need_wrap) { + cr(vc); + lf(vc); + } + if (vc->vc_decim) + insert_char(vc, 1); + scr_writew(himask ? + ((vc->vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : + (vc->vc_attr << 8) + tc, + (u16 *) vc->vc_pos); + if (DO_UPDATE(vc) && draw_x < 0) { + draw_x = vc->vc_x; + draw_from = vc->vc_pos; + } + if (vc->vc_x == vc->vc_cols - 1) { + vc->vc_need_wrap = vc->vc_decawm; + draw_to = vc->vc_pos + 2; } else { - /* invert vc_attr */ - if (!vc->vc_can_do_color) { - vc_attr = (vc->vc_attr) ^ 0x08; - } else if (vc->vc_hi_font_mask == 0x100) { - vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4); - } else { - vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4); - } + vc->vc_x++; + draw_to = (vc->vc_pos += 2); } - - while (1) { - if (vc->vc_need_wrap || vc->vc_decim) - FLUSH - if (vc->vc_need_wrap) { - cr(vc); - lf(vc); - } - if (vc->vc_decim) - insert_char(vc, 1); - scr_writew(himask ? - ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : - (vc_attr << 8) + tc, - (u16 *) vc->vc_pos); - if (DO_UPDATE(vc) && draw_x < 0) { - draw_x = vc->vc_x; - draw_from = vc->vc_pos; - } - if (vc->vc_x == vc->vc_cols - 1) { - vc->vc_need_wrap = vc->vc_decawm; - draw_to = vc->vc_pos + 2; - } else { - vc->vc_x++; - draw_to = (vc->vc_pos += 2); + if (vc->vc_utf_count) { + if (vc->vc_npar) { + vc->vc_npar--; + goto display_glyph; } - - if (!--width) break; - - tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */ - if (tc < 0) tc = ' '; - } - - if (rescan) { - rescan = 0; - inverse = 0; - width = 1; + vc->vc_utf_count = 0; c = orig; goto rescan_last_byte; } @@ -2705,11 +2581,6 @@ static void con_close(struct tty_struct *tty, struct file *filp) mutex_unlock(&tty_mutex); } -static int default_italic_color = 2; // green (ASCII) -static int default_underline_color = 3; // cyan (ASCII) -module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR); -module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR); - static void vc_init(struct vc_data *vc, unsigned int rows, unsigned int cols, int do_clear) { @@ -2729,8 +2600,7 @@ static void vc_init(struct vc_data *vc, unsigned int rows, vc->vc_palette[k++] = default_blu[j] ; } vc->vc_def_color = 0x07; /* white */ - vc->vc_ulcolor = default_underline_color; - vc->vc_itcolor = default_italic_color; + vc->vc_ulcolor = 0x0f; /* bold white */ vc->vc_halfcolor = 0x08; /* grey */ init_waitqueue_head(&vc->paste_wait); reset_terminal(vc, do_clear); diff --git a/trunk/drivers/char/vt_ioctl.c b/trunk/drivers/char/vt_ioctl.c index c6f6f4209739..c9f2dd620e87 100644 --- a/trunk/drivers/char/vt_ioctl.c +++ b/trunk/drivers/char/vt_ioctl.c @@ -1061,7 +1061,7 @@ int vt_waitactive(int vt) schedule(); } remove_wait_queue(&vt_activate_queue, &wait); - __set_current_state(TASK_RUNNING); + current->state = TASK_RUNNING; return retval; } diff --git a/trunk/drivers/char/watchdog/omap_wdt.c b/trunk/drivers/char/watchdog/omap_wdt.c index b36fa8de2131..84074a697dce 100644 --- a/trunk/drivers/char/watchdog/omap_wdt.c +++ b/trunk/drivers/char/watchdog/omap_wdt.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/char/watchdog/sc1200wdt.c b/trunk/drivers/char/watchdog/sc1200wdt.c index 2f7ba7a514fe..1e4a8d751a71 100644 --- a/trunk/drivers/char/watchdog/sc1200wdt.c +++ b/trunk/drivers/char/watchdog/sc1200wdt.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/char/watchdog/scx200_wdt.c b/trunk/drivers/char/watchdog/scx200_wdt.c index d4fd0fa2f176..fc0e0347f9d2 100644 --- a/trunk/drivers/char/watchdog/scx200_wdt.c +++ b/trunk/drivers/char/watchdog/scx200_wdt.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/cpufreq/Kconfig b/trunk/drivers/cpufreq/Kconfig index 993fa7b89253..d155e81b5c97 100644 --- a/trunk/drivers/cpufreq/Kconfig +++ b/trunk/drivers/cpufreq/Kconfig @@ -9,9 +9,6 @@ config CPU_FREQ clock speed, you need to either enable a dynamic cpufreq governor (see below) after boot, or use a userspace tool. - To compile this driver as a module, choose M here: the - module will be called cpufreq. - For details, take a look at . If in doubt, say N. @@ -19,7 +16,7 @@ config CPU_FREQ if CPU_FREQ config CPU_FREQ_TABLE - tristate + tristate config CPU_FREQ_DEBUG bool "Enable CPUfreq debugging" @@ -35,26 +32,19 @@ config CPU_FREQ_DEBUG 4 to activate CPUfreq governor debugging config CPU_FREQ_STAT - tristate "CPU frequency translation statistics" - select CPU_FREQ_TABLE - default y - help - This driver exports CPU frequency statistics information through sysfs - file system. - - To compile this driver as a module, choose M here: the - module will be called cpufreq_stats. - - If in doubt, say N. + tristate "CPU frequency translation statistics" + select CPU_FREQ_TABLE + default y + help + This driver exports CPU frequency statistics information through sysfs + file system config CPU_FREQ_STAT_DETAILS - bool "CPU frequency translation statistics details" - depends on CPU_FREQ_STAT - help - This will show detail CPU frequency translation table in sysfs file - system. - - If in doubt, say N. + bool "CPU frequency translation statistics details" + depends on CPU_FREQ_STAT + help + This will show detail CPU frequency translation table in sysfs file + system # Note that it is not currently possible to set the other governors (such as ondemand) # as the default, since if they fail to initialise, cpufreq will be @@ -88,38 +78,29 @@ config CPU_FREQ_DEFAULT_GOV_USERSPACE endchoice config CPU_FREQ_GOV_PERFORMANCE - tristate "'performance' governor" - help + tristate "'performance' governor" + help This cpufreq governor sets the frequency statically to the highest available CPU frequency. - To compile this driver as a module, choose M here: the - module will be called cpufreq_performance. - If in doubt, say Y. config CPU_FREQ_GOV_POWERSAVE - tristate "'powersave' governor" - help + tristate "'powersave' governor" + help This cpufreq governor sets the frequency statically to the lowest available CPU frequency. - To compile this driver as a module, choose M here: the - module will be called cpufreq_powersave. - If in doubt, say Y. config CPU_FREQ_GOV_USERSPACE - tristate "'userspace' governor for userspace frequency scaling" - help + tristate "'userspace' governor for userspace frequency scaling" + help Enable this cpufreq governor when you either want to set the CPU frequency manually or when an userspace program shall be able to set the CPU dynamically, like on LART . - To compile this driver as a module, choose M here: the - module will be called cpufreq_userspace. - For details, take a look at . If in doubt, say Y. @@ -135,9 +116,6 @@ config CPU_FREQ_GOV_ONDEMAND do fast frequency switching (i.e, very low latency frequency transitions). - To compile this driver as a module, choose M here: the - module will be called cpufreq_ondemand. - For details, take a look at linux/Documentation/cpu-freq. If in doubt, say N. @@ -158,9 +136,6 @@ config CPU_FREQ_GOV_CONSERVATIVE step-by-step latency issues between the minimum and maximum frequency transitions in the CPU) you will probably want to use this governor. - To compile this driver as a module, choose M here: the - module will be called cpufreq_conservative. - For details, take a look at linux/Documentation/cpu-freq. If in doubt, say N. diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 893dbaf386fb..3162010900c9 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -768,9 +768,6 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) unlock_policy_rwsem_write(cpu); goto err_out; } - policy->user_policy.min = policy->cpuinfo.min_freq; - policy->user_policy.max = policy->cpuinfo.max_freq; - policy->user_policy.governor = policy->governor; #ifdef CONFIG_SMP for_each_cpu_mask(j, policy->cpus) { @@ -861,13 +858,10 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) policy->governor = NULL; /* to assure that the starting sequence is * run in cpufreq_set_policy */ - - /* set default policy */ - ret = __cpufreq_set_policy(policy, &new_policy); - policy->user_policy.policy = policy->policy; - unlock_policy_rwsem_write(cpu); + /* set default policy */ + ret = cpufreq_set_policy(&new_policy); if (ret) { dprintk("setting policy failed\n"); goto err_out_unregister; @@ -1625,6 +1619,43 @@ static int __cpufreq_set_policy(struct cpufreq_policy *data, return ret; } +/** + * cpufreq_set_policy - set a new CPUFreq policy + * @policy: policy to be set. + * + * Sets a new CPU frequency and voltage scaling policy. + */ +int cpufreq_set_policy(struct cpufreq_policy *policy) +{ + int ret = 0; + struct cpufreq_policy *data; + + if (!policy) + return -EINVAL; + + data = cpufreq_cpu_get(policy->cpu); + if (!data) + return -EINVAL; + + if (unlikely(lock_policy_rwsem_write(policy->cpu))) + return -EINVAL; + + + ret = __cpufreq_set_policy(data, policy); + data->user_policy.min = data->min; + data->user_policy.max = data->max; + data->user_policy.policy = data->policy; + data->user_policy.governor = data->governor; + + unlock_policy_rwsem_write(policy->cpu); + + cpufreq_cpu_put(data); + + return ret; +} +EXPORT_SYMBOL(cpufreq_set_policy); + + /** * cpufreq_update_policy - re-evaluate an existing cpufreq policy * @cpu: CPU which shall be re-evaluated diff --git a/trunk/drivers/cpufreq/cpufreq_ondemand.c b/trunk/drivers/cpufreq/cpufreq_ondemand.c index 8532bb79e5fc..8d053f500fc2 100644 --- a/trunk/drivers/cpufreq/cpufreq_ondemand.c +++ b/trunk/drivers/cpufreq/cpufreq_ondemand.c @@ -470,7 +470,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info) dbs_info->enable = 1; ondemand_powersave_bias_init(); dbs_info->sample_type = DBS_NORMAL_SAMPLE; - INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer); + INIT_DELAYED_WORK(&dbs_info->work, do_dbs_timer); queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, delay); } diff --git a/trunk/drivers/edac/i82875p_edac.c b/trunk/drivers/edac/i82875p_edac.c index 2800b3e614a9..161fe09a6d38 100644 --- a/trunk/drivers/edac/i82875p_edac.c +++ b/trunk/drivers/edac/i82875p_edac.c @@ -261,6 +261,10 @@ static void i82875p_check(struct mem_ctl_info *mci) i82875p_process_error_info(mci, &info, 1); } +#ifdef CONFIG_PROC_FS +extern int pci_proc_attach_device(struct pci_dev *); +#endif + /* Return 0 on success or 1 on failure. */ static int i82875p_setup_overfl_dev(struct pci_dev *pdev, struct pci_dev **ovrfl_pdev, void __iomem **ovrfl_window) @@ -283,12 +287,17 @@ static int i82875p_setup_overfl_dev(struct pci_dev *pdev, if (dev == NULL) return 1; - - pci_bus_add_device(dev); } *ovrfl_pdev = dev; +#ifdef CONFIG_PROC_FS + if ((dev->procent == NULL) && pci_proc_attach_device(dev)) { + i82875p_printk(KERN_ERR, "%s(): Failed to attach overflow " + "device\n", __func__); + return 1; + } +#endif /* CONFIG_PROC_FS */ if (pci_enable_device(dev)) { i82875p_printk(KERN_ERR, "%s(): Failed to enable overflow " "device\n", __func__); diff --git a/trunk/drivers/eisa/virtual_root.c b/trunk/drivers/eisa/virtual_root.c index 3074879f231f..9b4fcac03ad5 100644 --- a/trunk/drivers/eisa/virtual_root.c +++ b/trunk/drivers/eisa/virtual_root.c @@ -47,7 +47,7 @@ static void virtual_eisa_release (struct device *dev) /* nothing really to do here */ } -static int __init virtual_eisa_root_init (void) +static int virtual_eisa_root_init (void) { int r; diff --git a/trunk/drivers/firmware/efivars.c b/trunk/drivers/firmware/efivars.c index 1324984a4c35..c6281ccd4fe7 100644 --- a/trunk/drivers/firmware/efivars.c +++ b/trunk/drivers/firmware/efivars.c @@ -409,7 +409,7 @@ static struct kobj_type ktype_efivar = { }; static ssize_t -dummy(struct kset *kset, char *buf) +dummy(struct subsystem *sub, char *buf) { return -ENODEV; } @@ -422,7 +422,7 @@ efivar_unregister(struct efivar_entry *var) static ssize_t -efivar_create(struct kset *kset, const char *buf, size_t count) +efivar_create(struct subsystem *sub, const char *buf, size_t count) { struct efi_variable *new_var = (struct efi_variable *)buf; struct efivar_entry *search_efivar, *n; @@ -480,7 +480,7 @@ efivar_create(struct kset *kset, const char *buf, size_t count) } static ssize_t -efivar_delete(struct kset *kset, const char *buf, size_t count) +efivar_delete(struct subsystem *sub, const char *buf, size_t count) { struct efi_variable *del_var = (struct efi_variable *)buf; struct efivar_entry *search_efivar, *n; @@ -551,11 +551,11 @@ static struct subsys_attribute *var_subsys_attrs[] = { * the efivars driver */ static ssize_t -systab_read(struct kset *kset, char *buf) +systab_read(struct subsystem *entry, char *buf) { char *str = buf; - if (!kset || !buf) + if (!entry || !buf) return -EINVAL; if (efi.mps != EFI_INVALID_TABLE_ADDR) @@ -687,7 +687,7 @@ efivars_init(void) goto out_free; } - kobj_set_kset_s(&vars_subsys, efi_subsys); + kset_set_kset_s(&vars_subsys, efi_subsys); error = subsystem_register(&vars_subsys); diff --git a/trunk/drivers/hid/hid-core.c b/trunk/drivers/hid/hid-core.c index 6ec04e79f685..62e21cc73938 100644 --- a/trunk/drivers/hid/hid-core.c +++ b/trunk/drivers/hid/hid-core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/hwmon/Kconfig b/trunk/drivers/hwmon/Kconfig index 3ba3a5221c41..6d105a1d41b1 100644 --- a/trunk/drivers/hwmon/Kconfig +++ b/trunk/drivers/hwmon/Kconfig @@ -2,7 +2,9 @@ # Hardware monitoring chip drivers configuration # -menuconfig HWMON +menu "Hardware Monitoring support" + +config HWMON tristate "Hardware Monitoring support" default y help @@ -21,15 +23,13 @@ menuconfig HWMON This support can also be built as a module. If so, the module will be called hwmon. -if HWMON - config HWMON_VID tristate default n config SENSORS_ABITUGURU tristate "Abit uGuru" - depends on EXPERIMENTAL + depends on HWMON && EXPERIMENTAL help If you say yes here you get support for the Abit uGuru chips sensor part. The voltage and frequency control parts of the Abit @@ -39,19 +39,9 @@ config SENSORS_ABITUGURU This driver can also be built as a module. If so, the module will be called abituguru. -config SENSORS_AD7418 - tristate "Analog Devices AD7416, AD7417 and AD7418" - depends on I2C && EXPERIMENTAL - help - If you say yes here you get support for the Analog Devices - AD7416, AD7417 and AD7418 temperature monitoring chips. - - This driver can also be built as a module. If so, the module - will be called ad7418. - config SENSORS_ADM1021 tristate "Analog Devices ADM1021 and compatibles" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for Analog Devices ADM1021 and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, @@ -63,7 +53,7 @@ config SENSORS_ADM1021 config SENSORS_ADM1025 tristate "Analog Devices ADM1025 and compatibles" - depends on I2C + depends on HWMON && I2C select HWMON_VID help If you say yes here you get support for Analog Devices ADM1025 @@ -74,7 +64,7 @@ config SENSORS_ADM1025 config SENSORS_ADM1026 tristate "Analog Devices ADM1026 and compatibles" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select HWMON_VID help If you say yes here you get support for Analog Devices ADM1026 @@ -85,7 +75,7 @@ config SENSORS_ADM1026 config SENSORS_ADM1029 tristate "Analog Devices ADM1029" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL help If you say yes here you get support for Analog Devices ADM1029 sensor chip. @@ -96,7 +86,7 @@ config SENSORS_ADM1029 config SENSORS_ADM1031 tristate "Analog Devices ADM1031 and compatibles" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL help If you say yes here you get support for Analog Devices ADM1031 and ADM1030 sensor chips. @@ -106,7 +96,7 @@ config SENSORS_ADM1031 config SENSORS_ADM9240 tristate "Analog Devices ADM9240 and compatibles" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select HWMON_VID help If you say yes here you get support for Analog Devices ADM9240, @@ -117,7 +107,7 @@ config SENSORS_ADM9240 config SENSORS_K8TEMP tristate "AMD Athlon64/FX or Opteron temperature sensor" - depends on X86 && PCI && EXPERIMENTAL + depends on HWMON && X86 && PCI && EXPERIMENTAL help If you say yes here you get support for the temperature sensor(s) inside your CPU. Supported is whole AMD K8 @@ -129,7 +119,7 @@ config SENSORS_K8TEMP config SENSORS_AMS tristate "Apple Motion Sensor driver" - depends on PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL + depends on HWMON && PPC_PMAC && !PPC64 && INPUT && ((ADB_PMU && I2C = y) || (ADB_PMU && !I2C) || I2C) && EXPERIMENTAL help Support for the motion sensor included in PowerBooks. Includes implementations for PMU and I2C. @@ -154,7 +144,7 @@ config SENSORS_AMS_I2C config SENSORS_ASB100 tristate "Asus ASB100 Bach" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select HWMON_VID help If you say yes here you get support for the ASB100 Bach sensor @@ -165,7 +155,7 @@ config SENSORS_ASB100 config SENSORS_ATXP1 tristate "Attansic ATXP1 VID controller" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select HWMON_VID help If you say yes here you get support for the Attansic ATXP1 VID @@ -179,7 +169,7 @@ config SENSORS_ATXP1 config SENSORS_DS1621 tristate "Dallas Semiconductor DS1621 and DS1625" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for Dallas Semiconductor DS1621 and DS1625 sensor chips. @@ -189,7 +179,7 @@ config SENSORS_DS1621 config SENSORS_F71805F tristate "Fintek F71805F/FG and F71872F/FG" - depends on EXPERIMENTAL + depends on HWMON && EXPERIMENTAL help If you say yes here you get support for hardware monitoring features of the Fintek F71805F/FG and F71872F/FG Super-I/O @@ -200,7 +190,7 @@ config SENSORS_F71805F config SENSORS_FSCHER tristate "FSC Hermes" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for Fujitsu Siemens Computers Hermes sensor chips. @@ -210,7 +200,7 @@ config SENSORS_FSCHER config SENSORS_FSCPOS tristate "FSC Poseidon" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for Fujitsu Siemens Computers Poseidon sensor chips. @@ -220,7 +210,7 @@ config SENSORS_FSCPOS config SENSORS_GL518SM tristate "Genesys Logic GL518SM" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for Genesys Logic GL518SM sensor chips. @@ -230,7 +220,7 @@ config SENSORS_GL518SM config SENSORS_GL520SM tristate "Genesys Logic GL520SM" - depends on I2C + depends on HWMON && I2C select HWMON_VID help If you say yes here you get support for Genesys Logic GL520SM @@ -239,17 +229,9 @@ config SENSORS_GL520SM This driver can also be built as a module. If so, the module will be called gl520sm. -config SENSORS_CORETEMP - tristate "Intel Core (2) Duo/Solo temperature sensor" - depends on X86 && EXPERIMENTAL - help - If you say yes here you get support for the temperature - sensor inside your CPU. Supported all are all known variants - of Intel Core family. - config SENSORS_IT87 tristate "ITE IT87xx and compatibles" - depends on I2C + depends on HWMON && I2C select I2C_ISA select HWMON_VID help @@ -261,7 +243,7 @@ config SENSORS_IT87 config SENSORS_LM63 tristate "National Semiconductor LM63" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for the National Semiconductor LM63 remote diode digital temperature sensor with integrated fan @@ -273,7 +255,7 @@ config SENSORS_LM63 config SENSORS_LM70 tristate "National Semiconductor LM70" - depends on SPI_MASTER && EXPERIMENTAL + depends on HWMON && SPI_MASTER && EXPERIMENTAL help If you say yes here you get support for the National Semiconductor LM70 digital temperature sensor chip. @@ -283,7 +265,7 @@ config SENSORS_LM70 config SENSORS_LM75 tristate "National Semiconductor LM75 and compatibles" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for National Semiconductor LM75 sensor chips and clones: Dallas Semiconductor DS75 and DS1775 (in @@ -298,7 +280,7 @@ config SENSORS_LM75 config SENSORS_LM77 tristate "National Semiconductor LM77" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for National Semiconductor LM77 sensor chips. @@ -308,7 +290,8 @@ config SENSORS_LM77 config SENSORS_LM78 tristate "National Semiconductor LM78 and compatibles" - depends on I2C + depends on HWMON && I2C + select I2C_ISA select HWMON_VID help If you say yes here you get support for National Semiconductor LM78, @@ -319,7 +302,7 @@ config SENSORS_LM78 config SENSORS_LM80 tristate "National Semiconductor LM80" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL help If you say yes here you get support for National Semiconductor LM80 sensor chips. @@ -329,7 +312,7 @@ config SENSORS_LM80 config SENSORS_LM83 tristate "National Semiconductor LM83 and compatibles" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for National Semiconductor LM82 and LM83 sensor chips. @@ -339,7 +322,7 @@ config SENSORS_LM83 config SENSORS_LM85 tristate "National Semiconductor LM85 and compatibles" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select HWMON_VID help If you say yes here you get support for National Semiconductor LM85 @@ -350,7 +333,7 @@ config SENSORS_LM85 config SENSORS_LM87 tristate "National Semiconductor LM87" - depends on I2C + depends on HWMON && I2C select HWMON_VID help If you say yes here you get support for National Semiconductor LM87 @@ -361,7 +344,7 @@ config SENSORS_LM87 config SENSORS_LM90 tristate "National Semiconductor LM90 and compatibles" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for National Semiconductor LM90, LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657 and @@ -375,7 +358,7 @@ config SENSORS_LM90 config SENSORS_LM92 tristate "National Semiconductor LM92 and compatibles" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for National Semiconductor LM92 and Maxim MAX6635 sensor chips. @@ -385,26 +368,16 @@ config SENSORS_LM92 config SENSORS_MAX1619 tristate "Maxim MAX1619 sensor chip" - depends on I2C + depends on HWMON && I2C help If you say yes here you get support for MAX1619 sensor chip. This driver can also be built as a module. If so, the module will be called max1619. -config SENSORS_MAX6650 - tristate "Maxim MAX6650 sensor chip" - depends on I2C && EXPERIMENTAL - help - If you say yes here you get support for the MAX6650 / MAX6651 - sensor chips. - - This driver can also be built as a module. If so, the module - will be called max6650. - config SENSORS_PC87360 tristate "National Semiconductor PC87360 family" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select I2C_ISA select HWMON_VID help @@ -419,7 +392,7 @@ config SENSORS_PC87360 config SENSORS_PC87427 tristate "National Semiconductor PC87427" - depends on EXPERIMENTAL + depends on HWMON && EXPERIMENTAL help If you say yes here you get access to the hardware monitoring functions of the National Semiconductor PC87427 Super-I/O chip. @@ -432,7 +405,7 @@ config SENSORS_PC87427 config SENSORS_SIS5595 tristate "Silicon Integrated Systems Corp. SiS5595" - depends on I2C && PCI && EXPERIMENTAL + depends on HWMON && I2C && PCI && EXPERIMENTAL select I2C_ISA help If you say yes here you get support for the integrated sensors in @@ -443,28 +416,28 @@ config SENSORS_SIS5595 config SENSORS_SMSC47M1 tristate "SMSC LPC47M10x and compatibles" + depends on HWMON && I2C + select I2C_ISA help If you say yes here you get support for the integrated fan monitoring and control capabilities of the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x, LPC47M14x, LPC47M15x, - LPC47M192, LPC47M292 and LPC47M997 chips. + LPC47M192 and LPC47M997 chips. - The temperature and voltage sensor features of the LPC47M15x, - LPC47M192, LPC47M292 and LPC47M997 are supported by another - driver, select also "SMSC LPC47M192 and compatibles" below for - those. + The temperature and voltage sensor features of the LPC47M192 + and LPC47M997 are supported by another driver, select also + "SMSC LPC47M192 and compatibles" below for those. This driver can also be built as a module. If so, the module will be called smsc47m1. config SENSORS_SMSC47M192 tristate "SMSC LPC47M192 and compatibles" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select HWMON_VID help If you say yes here you get support for the temperature and - voltage sensors of the SMSC LPC47M192, LPC47M15x, LPC47M292 - and LPC47M997 chips. + voltage sensors of the SMSC LPC47M192 and LPC47M997 chips. The fan monitoring and control capabilities of these chips are supported by another driver, select @@ -476,7 +449,8 @@ config SENSORS_SMSC47M192 config SENSORS_SMSC47B397 tristate "SMSC LPC47B397-NC" - depends on EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL + select I2C_ISA help If you say yes here you get support for the SMSC LPC47B397-NC sensor chip. @@ -486,7 +460,7 @@ config SENSORS_SMSC47B397 config SENSORS_VIA686A tristate "VIA686A" - depends on I2C && PCI + depends on HWMON && I2C && PCI select I2C_ISA help If you say yes here you get support for the integrated sensors in @@ -497,7 +471,7 @@ config SENSORS_VIA686A config SENSORS_VT1211 tristate "VIA VT1211" - depends on EXPERIMENTAL + depends on HWMON && EXPERIMENTAL select HWMON_VID help If you say yes here then you get support for hardware monitoring @@ -508,7 +482,7 @@ config SENSORS_VT1211 config SENSORS_VT8231 tristate "VIA VT8231" - depends on I2C && PCI && EXPERIMENTAL + depends on HWMON && I2C && PCI && EXPERIMENTAL select HWMON_VID select I2C_ISA help @@ -520,7 +494,8 @@ config SENSORS_VT8231 config SENSORS_W83781D tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F" - depends on I2C + depends on HWMON && I2C + select I2C_ISA select HWMON_VID help If you say yes here you get support for the Winbond W8378x series @@ -532,7 +507,7 @@ config SENSORS_W83781D config SENSORS_W83791D tristate "Winbond W83791D" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select HWMON_VID help If you say yes here you get support for the Winbond W83791D chip. @@ -542,7 +517,7 @@ config SENSORS_W83791D config SENSORS_W83792D tristate "Winbond W83792D" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL help If you say yes here you get support for the Winbond W83792D chip. @@ -551,7 +526,7 @@ config SENSORS_W83792D config SENSORS_W83793 tristate "Winbond W83793" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select HWMON_VID help If you say yes here you get support for the Winbond W83793 @@ -562,7 +537,7 @@ config SENSORS_W83793 config SENSORS_W83L785TS tristate "Winbond W83L785TS-S" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL help If you say yes here you get support for the Winbond W83L785TS-S sensor chip, which is used on the Asus A7N8X, among other @@ -573,6 +548,8 @@ config SENSORS_W83L785TS config SENSORS_W83627HF tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF" + depends on HWMON && I2C + select I2C_ISA select HWMON_VID help If you say yes here you get support for the Winbond W836X7 series @@ -584,7 +561,7 @@ config SENSORS_W83627HF config SENSORS_W83627EHF tristate "Winbond W83627EHF" - depends on I2C && EXPERIMENTAL + depends on HWMON && I2C && EXPERIMENTAL select I2C_ISA help If you say yes here you get preliminary support for the hardware @@ -600,7 +577,7 @@ config SENSORS_W83627EHF config SENSORS_HDAPS tristate "IBM Hard Drive Active Protection System (hdaps)" - depends on INPUT && X86 + depends on HWMON && INPUT && X86 default n help This driver provides support for the IBM Hard Drive Active Protection @@ -617,32 +594,9 @@ config SENSORS_HDAPS Say Y here if you have an applicable laptop and want to experience the awesome power of hdaps. -config SENSORS_APPLESMC - tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)" - depends on HWMON && INPUT && X86 - select NEW_LEDS - select LEDS_CLASS - default n - help - This driver provides support for the Apple System Management - Controller, which provides an accelerometer (Apple Sudden Motion - Sensor), light sensors, temperature sensors, keyboard backlight - control and fan control. - - Only Intel-based Apple's computers are supported (MacBook Pro, - MacBook, MacMini). - - Data from the different sensors, keyboard backlight control and fan - control are accessible via sysfs. - - This driver also provides an absolute input class device, allowing - the laptop to act as a pinball machine-esque joystick. - - Say Y here if you have an applicable laptop and want to experience - the awesome power of applesmc. - config HWMON_DEBUG_CHIP bool "Hardware Monitoring Chip debugging messages" + depends on HWMON default n help Say Y here if you want the I2C chip drivers to produce a bunch of @@ -650,4 +604,4 @@ config HWMON_DEBUG_CHIP a problem with I2C support and want to see more of what is going on. -endif # HWMON +endmenu diff --git a/trunk/drivers/hwmon/Makefile b/trunk/drivers/hwmon/Makefile index cfaf338919dd..4165c27a2f25 100644 --- a/trunk/drivers/hwmon/Makefile +++ b/trunk/drivers/hwmon/Makefile @@ -14,17 +14,14 @@ obj-$(CONFIG_SENSORS_W83781D) += w83781d.o obj-$(CONFIG_SENSORS_W83791D) += w83791d.o obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o -obj-$(CONFIG_SENSORS_AD7418) += ad7418.o obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o -obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o obj-$(CONFIG_SENSORS_AMS) += ams/ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o -obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o obj-$(CONFIG_SENSORS_F71805F) += f71805f.o obj-$(CONFIG_SENSORS_FSCHER) += fscher.o @@ -46,7 +43,6 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_LM92) += lm92.o obj-$(CONFIG_SENSORS_MAX1619) += max1619.o -obj-$(CONFIG_SENSORS_MAX6650) += max6650.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_PC87427) += pc87427.o obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o diff --git a/trunk/drivers/hwmon/ad7418.c b/trunk/drivers/hwmon/ad7418.c deleted file mode 100644 index cc8b624a1e51..000000000000 --- a/trunk/drivers/hwmon/ad7418.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * An hwmon driver for the Analog Devices AD7416/17/18 - * Copyright (C) 2006-07 Tower Technologies - * - * Author: Alessandro Zummo - * - * Based on lm75.c - * Copyright (C) 1998-99 Frodo Looijaard - * - * 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 - version 2. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lm75.h" - -#define DRV_VERSION "0.3" - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x28, I2C_CLIENT_END }; -/* Insmod parameters */ -I2C_CLIENT_INSMOD_3(ad7416, ad7417, ad7418); - -/* AD7418 registers */ -#define AD7418_REG_TEMP_IN 0x00 -#define AD7418_REG_CONF 0x01 -#define AD7418_REG_TEMP_HYST 0x02 -#define AD7418_REG_TEMP_OS 0x03 -#define AD7418_REG_ADC 0x04 -#define AD7418_REG_CONF2 0x05 - -#define AD7418_REG_ADC_CH(x) ((x) << 5) -#define AD7418_CH_TEMP AD7418_REG_ADC_CH(0) - -static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN, - AD7418_REG_TEMP_HYST, - AD7418_REG_TEMP_OS }; - -struct ad7418_data { - struct i2c_client client; - struct class_device *class_dev; - struct attribute_group attrs; - enum chips type; - struct mutex lock; - int adc_max; /* number of ADC channels */ - char valid; - unsigned long last_updated; /* In jiffies */ - s16 temp[3]; /* Register values */ - u16 in[4]; -}; - -static int ad7418_attach_adapter(struct i2c_adapter *adapter); -static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind); -static int ad7418_detach_client(struct i2c_client *client); - -static struct i2c_driver ad7418_driver = { - .driver = { - .name = "ad7418", - }, - .attach_adapter = ad7418_attach_adapter, - .detach_client = ad7418_detach_client, -}; - -/* All registers are word-sized, except for the configuration registers. - * AD7418 uses a high-byte first convention. Do NOT use those functions to - * access the configuration registers CONF and CONF2, as they are byte-sized. - */ -static inline int ad7418_read(struct i2c_client *client, u8 reg) -{ - return swab16(i2c_smbus_read_word_data(client, reg)); -} - -static inline int ad7418_write(struct i2c_client *client, u8 reg, u16 value) -{ - return i2c_smbus_write_word_data(client, reg, swab16(value)); -} - -static void ad7418_init_client(struct i2c_client *client) -{ - struct ad7418_data *data = i2c_get_clientdata(client); - - int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF); - if (reg < 0) { - dev_err(&client->dev, "cannot read configuration register\n"); - } else { - dev_info(&client->dev, "configuring for mode 1\n"); - i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe); - - if (data->type == ad7417 || data->type == ad7418) - i2c_smbus_write_byte_data(client, - AD7418_REG_CONF2, 0x00); - } -} - -static struct ad7418_data *ad7418_update_device(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct ad7418_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->lock); - - if (time_after(jiffies, data->last_updated + HZ + HZ / 2) - || !data->valid) { - u8 cfg; - int i, ch; - - /* read config register and clear channel bits */ - cfg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF); - cfg &= 0x1F; - - i2c_smbus_write_byte_data(client, AD7418_REG_CONF, - cfg | AD7418_CH_TEMP); - udelay(30); - - for (i = 0; i < 3; i++) { - data->temp[i] = ad7418_read(client, AD7418_REG_TEMP[i]); - } - - for (i = 0, ch = 4; i < data->adc_max; i++, ch--) { - i2c_smbus_write_byte_data(client, - AD7418_REG_CONF, - cfg | AD7418_REG_ADC_CH(ch)); - - udelay(15); - data->in[data->adc_max - 1 - i] = - ad7418_read(client, AD7418_REG_ADC); - } - - /* restore old configuration value */ - ad7418_write(client, AD7418_REG_CONF, cfg); - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->lock); - - return data; -} - -static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct ad7418_data *data = ad7418_update_device(dev); - return sprintf(buf, "%d\n", - LM75_TEMP_FROM_REG(data->temp[attr->index])); -} - -static ssize_t show_adc(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct ad7418_data *data = ad7418_update_device(dev); - - return sprintf(buf, "%d\n", - ((data->in[attr->index] >> 6) * 2500 + 512) / 1024); -} - -static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct i2c_client *client = to_i2c_client(dev); - struct ad7418_data *data = i2c_get_clientdata(client); - int temp = simple_strtol(buf, NULL, 10); - - mutex_lock(&data->lock); - data->temp[attr->index] = LM75_TEMP_TO_REG(temp); - ad7418_write(client, AD7418_REG_TEMP[attr->index], data->temp[attr->index]); - mutex_unlock(&data->lock); - return count; -} - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); -static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, - show_temp, set_temp, 1); -static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, - show_temp, set_temp, 2); - -static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_adc, NULL, 0); -static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 1); -static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2); -static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3); - -static int ad7418_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) - return 0; - return i2c_probe(adapter, &addr_data, ad7418_detect); -} - -static struct attribute *ad7416_attributes[] = { - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - NULL -}; - -static struct attribute *ad7417_attributes[] = { - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_in1_input.dev_attr.attr, - &sensor_dev_attr_in2_input.dev_attr.attr, - &sensor_dev_attr_in3_input.dev_attr.attr, - &sensor_dev_attr_in4_input.dev_attr.attr, - NULL -}; - -static struct attribute *ad7418_attributes[] = { - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_in1_input.dev_attr.attr, - NULL -}; - -static int ad7418_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct ad7418_data *data; - int err = 0; - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA)) - goto exit; - - if (!(data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = &data->client; - client->addr = address; - client->adapter = adapter; - client->driver = &ad7418_driver; - - i2c_set_clientdata(client, data); - - mutex_init(&data->lock); - - /* AD7418 has a curious behaviour on registers 6 and 7. They - * both always read 0xC071 and are not documented on the datasheet. - * We use them to detect the chip. - */ - if (kind <= 0) { - int reg, reg6, reg7; - - /* the AD7416 lies within this address range, but I have - * no means to check. - */ - if (address >= 0x48 && address <= 0x4f) { - /* XXX add tests for AD7416 here */ - /* data->type = ad7416; */ - } - /* here we might have AD7417 or AD7418 */ - else if (address >= 0x28 && address <= 0x2f) { - reg6 = i2c_smbus_read_word_data(client, 0x06); - reg7 = i2c_smbus_read_word_data(client, 0x07); - - if (address == 0x28 && reg6 == 0xC071 && reg7 == 0xC071) - data->type = ad7418; - - /* XXX add tests for AD7417 here */ - - - /* both AD7417 and AD7418 have bits 0-5 of - * the CONF2 register at 0 - */ - reg = i2c_smbus_read_byte_data(client, - AD7418_REG_CONF2); - if (reg & 0x3F) - data->type = any_chip; /* detection failed */ - } - } else { - dev_dbg(&adapter->dev, "detection forced\n"); - } - - if (kind > 0) - data->type = kind; - else if (kind < 0 && data->type == any_chip) { - err = -ENODEV; - goto exit_free; - } - - switch (data->type) { - case any_chip: - case ad7416: - data->adc_max = 0; - data->attrs.attrs = ad7416_attributes; - strlcpy(client->name, "ad7416", I2C_NAME_SIZE); - break; - - case ad7417: - data->adc_max = 4; - data->attrs.attrs = ad7417_attributes; - strlcpy(client->name, "ad7417", I2C_NAME_SIZE); - break; - - case ad7418: - data->adc_max = 1; - data->attrs.attrs = ad7418_attributes; - strlcpy(client->name, "ad7418", I2C_NAME_SIZE); - break; - } - - if ((err = i2c_attach_client(client))) - goto exit_free; - - dev_info(&client->dev, "%s chip found\n", client->name); - - /* Initialize the AD7418 chip */ - ad7418_init_client(client); - - /* Register sysfs hooks */ - if ((err = sysfs_create_group(&client->dev.kobj, &data->attrs))) - goto exit_detach; - - data->class_dev = hwmon_device_register(&client->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - goto exit_remove; - } - - return 0; - -exit_remove: - sysfs_remove_group(&client->dev.kobj, &data->attrs); -exit_detach: - i2c_detach_client(client); -exit_free: - kfree(data); -exit: - return err; -} - -static int ad7418_detach_client(struct i2c_client *client) -{ - struct ad7418_data *data = i2c_get_clientdata(client); - hwmon_device_unregister(data->class_dev); - sysfs_remove_group(&client->dev.kobj, &data->attrs); - i2c_detach_client(client); - kfree(data); - return 0; -} - -static int __init ad7418_init(void) -{ - return i2c_add_driver(&ad7418_driver); -} - -static void __exit ad7418_exit(void) -{ - i2c_del_driver(&ad7418_driver); -} - -MODULE_AUTHOR("Alessandro Zummo "); -MODULE_DESCRIPTION("AD7416/17/18 driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -module_init(ad7418_init); -module_exit(ad7418_exit); diff --git a/trunk/drivers/hwmon/ams/ams-core.c b/trunk/drivers/hwmon/ams/ams-core.c index 6db973739725..f5ebad561412 100644 --- a/trunk/drivers/hwmon/ams/ams-core.c +++ b/trunk/drivers/hwmon/ams/ams-core.c @@ -144,7 +144,7 @@ int ams_sensor_attach(void) const u32 *prop; /* Get orientation */ - prop = of_get_property(ams_info.of_node, "orientation", NULL); + prop = get_property(ams_info.of_node, "orientation", NULL); if (!prop) return -ENODEV; ams_info.orient1 = *prop; @@ -208,17 +208,20 @@ int __init ams_init(void) #ifdef CONFIG_SENSORS_AMS_I2C np = of_find_node_by_name(NULL, "accelerometer"); - if (np && of_device_is_compatible(np, "AAPL,accelerometer_1")) + if (np && device_is_compatible(np, "AAPL,accelerometer_1")) /* Found I2C motion sensor */ return ams_i2c_init(np); #endif #ifdef CONFIG_SENSORS_AMS_PMU np = of_find_node_by_name(NULL, "sms"); - if (np && of_device_is_compatible(np, "sms")) + if (np && device_is_compatible(np, "sms")) /* Found PMU motion sensor */ return ams_pmu_init(np); #endif + + printk(KERN_ERR "ams: No motion sensor found.\n"); + return -ENODEV; } diff --git a/trunk/drivers/hwmon/ams/ams-i2c.c b/trunk/drivers/hwmon/ams/ams-i2c.c index 957760536a4c..485d333bcb3e 100644 --- a/trunk/drivers/hwmon/ams/ams-i2c.c +++ b/trunk/drivers/hwmon/ams/ams-i2c.c @@ -85,17 +85,17 @@ static int ams_i2c_write(u8 reg, u8 value) static int ams_i2c_cmd(enum ams_i2c_cmd cmd) { s32 result; - int count = 3; + int remaining = HZ / 20; ams_i2c_write(AMS_COMMAND, cmd); - msleep(5); + mdelay(5); - while (count--) { + while (remaining) { result = ams_i2c_read(AMS_COMMAND); if (result == 0 || result & 0x80) return 0; - schedule_timeout_uninterruptible(HZ / 20); + remaining = schedule_timeout(remaining); } return -1; @@ -276,7 +276,7 @@ int __init ams_i2c_init(struct device_node *np) ams_info.bustype = BUS_I2C; /* look for bus either using "reg" or by path */ - prop = of_get_property(ams_info.of_node, "reg", NULL); + prop = get_property(ams_info.of_node, "reg", NULL); if (!prop) { result = -ENODEV; diff --git a/trunk/drivers/hwmon/ams/ams-pmu.c b/trunk/drivers/hwmon/ams/ams-pmu.c index 9463e9768f6f..1b01c215bfe7 100644 --- a/trunk/drivers/hwmon/ams/ams-pmu.c +++ b/trunk/drivers/hwmon/ams/ams-pmu.c @@ -160,7 +160,7 @@ int __init ams_pmu_init(struct device_node *np) ams_info.bustype = BUS_HOST; /* Get PMU command, should be 0x4e, but we can never know */ - prop = of_get_property(ams_info.of_node, "reg", NULL); + prop = get_property(ams_info.of_node, "reg", NULL); if (!prop) { result = -ENODEV; goto exit; diff --git a/trunk/drivers/hwmon/applesmc.c b/trunk/drivers/hwmon/applesmc.c deleted file mode 100644 index 3215f9c87f32..000000000000 --- a/trunk/drivers/hwmon/applesmc.c +++ /dev/null @@ -1,1339 +0,0 @@ -/* - * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature - * sensors, fan control, keyboard backlight control) used in Intel-based Apple - * computers. - * - * Copyright (C) 2007 Nicolas Boichat - * - * Based on hdaps.c driver: - * Copyright (C) 2005 Robert Love - * Copyright (C) 2005 Jesper Juhl - * - * Fan control based on smcFanControl: - * Copyright (C) 2006 Hendrik Holtmann - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License v2 as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* data port used by Apple SMC */ -#define APPLESMC_DATA_PORT 0x300 -/* command/status port used by Apple SMC */ -#define APPLESMC_CMD_PORT 0x304 - -#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */ - -#define APPLESMC_MAX_DATA_LENGTH 32 - -#define APPLESMC_STATUS_MASK 0x0f -#define APPLESMC_READ_CMD 0x10 -#define APPLESMC_WRITE_CMD 0x11 -#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12 -#define APPLESMC_GET_KEY_TYPE_CMD 0x13 - -#define KEY_COUNT_KEY "#KEY" /* r-o ui32 */ - -#define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */ -#define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */ -#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */ - -#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */ - -#define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */ -#define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */ -#define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */ -#define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */ - -#define FANS_COUNT "FNum" /* r-o ui8 */ -#define FANS_MANUAL "FS! " /* r-w ui16 */ -#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */ -#define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */ -#define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */ -#define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */ -#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */ -#define FAN_POSITION "F0ID" /* r-o char[16] */ - -/* - * Temperature sensors keys (sp78 - 2 bytes). - * First set for Macbook(Pro), second for Macmini. - */ -static const char* temperature_sensors_sets[][13] = { - { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", - "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, - { "TC0D", "TC0P", NULL } -}; - -/* List of keys used to read/write fan speeds */ -static const char* fan_speed_keys[] = { - FAN_ACTUAL_SPEED, - FAN_MIN_SPEED, - FAN_MAX_SPEED, - FAN_SAFE_SPEED, - FAN_TARGET_SPEED -}; - -#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ -#define INIT_WAIT_MSECS 50 /* ... in 50ms increments */ - -#define APPLESMC_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */ -#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */ -#define APPLESMC_INPUT_FLAT 4 - -#define SENSOR_X 0 -#define SENSOR_Y 1 -#define SENSOR_Z 2 - -/* Structure to be passed to DMI_MATCH function */ -struct dmi_match_data { -/* Indicates whether this computer has an accelerometer. */ - int accelerometer; -/* Indicates whether this computer has light sensors and keyboard backlight. */ - int light; -/* Indicates which temperature sensors set to use. */ - int temperature_set; -}; - -static const int debug; -static struct platform_device *pdev; -static s16 rest_x; -static s16 rest_y; -static struct timer_list applesmc_timer; -static struct input_dev *applesmc_idev; -static struct class_device *hwmon_class_dev; - -/* Indicates whether this computer has an accelerometer. */ -static unsigned int applesmc_accelerometer; - -/* Indicates whether this computer has light sensors and keyboard backlight. */ -static unsigned int applesmc_light; - -/* Indicates which temperature sensors set to use. */ -static unsigned int applesmc_temperature_set; - -static struct mutex applesmc_lock; - -/* - * Last index written to key_at_index sysfs file, and value to use for all other - * key_at_index_* sysfs files. - */ -static unsigned int key_at_index; - -static struct workqueue_struct *applesmc_led_wq; - -/* - * __wait_status - Wait up to 2ms for the status port to get a certain value - * (masked with 0x0f), returning zero if the value is obtained. Callers must - * hold applesmc_lock. - */ -static int __wait_status(u8 val) -{ - unsigned int i; - - val = val & APPLESMC_STATUS_MASK; - - for (i = 0; i < 200; i++) { - if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) { - if (debug) - printk(KERN_DEBUG - "Waited %d us for status %x\n", - i*10, val); - return 0; - } - udelay(10); - } - - printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n", - val, inb(APPLESMC_CMD_PORT)); - - return -EIO; -} - -/* - * applesmc_read_key - reads len bytes from a given key, and put them in buffer. - * Returns zero on success or a negative error on failure. Callers must - * hold applesmc_lock. - */ -static int applesmc_read_key(const char* key, u8* buffer, u8 len) -{ - int i; - - if (len > APPLESMC_MAX_DATA_LENGTH) { - printk(KERN_ERR "applesmc_read_key: cannot read more than " - "%d bytes\n", APPLESMC_MAX_DATA_LENGTH); - return -EINVAL; - } - - outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT); - if (__wait_status(0x0c)) - return -EIO; - - for (i = 0; i < 4; i++) { - outb(key[i], APPLESMC_DATA_PORT); - if (__wait_status(0x04)) - return -EIO; - } - if (debug) - printk(KERN_DEBUG "<%s", key); - - outb(len, APPLESMC_DATA_PORT); - if (debug) - printk(KERN_DEBUG ">%x", len); - - for (i = 0; i < len; i++) { - if (__wait_status(0x05)) - return -EIO; - buffer[i] = inb(APPLESMC_DATA_PORT); - if (debug) - printk(KERN_DEBUG "<%x", buffer[i]); - } - if (debug) - printk(KERN_DEBUG "\n"); - - return 0; -} - -/* - * applesmc_write_key - writes len bytes from buffer to a given key. - * Returns zero on success or a negative error on failure. Callers must - * hold applesmc_lock. - */ -static int applesmc_write_key(const char* key, u8* buffer, u8 len) -{ - int i; - - if (len > APPLESMC_MAX_DATA_LENGTH) { - printk(KERN_ERR "applesmc_write_key: cannot write more than " - "%d bytes\n", APPLESMC_MAX_DATA_LENGTH); - return -EINVAL; - } - - outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT); - if (__wait_status(0x0c)) - return -EIO; - - for (i = 0; i < 4; i++) { - outb(key[i], APPLESMC_DATA_PORT); - if (__wait_status(0x04)) - return -EIO; - } - - outb(len, APPLESMC_DATA_PORT); - - for (i = 0; i < len; i++) { - if (__wait_status(0x04)) - return -EIO; - outb(buffer[i], APPLESMC_DATA_PORT); - } - - return 0; -} - -/* - * applesmc_get_key_at_index - get key at index, and put the result in key - * (char[6]). Returns zero on success or a negative error on failure. Callers - * must hold applesmc_lock. - */ -static int applesmc_get_key_at_index(int index, char* key) -{ - int i; - u8 readkey[4]; - readkey[0] = index >> 24; - readkey[1] = index >> 16; - readkey[2] = index >> 8; - readkey[3] = index; - - outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT); - if (__wait_status(0x0c)) - return -EIO; - - for (i = 0; i < 4; i++) { - outb(readkey[i], APPLESMC_DATA_PORT); - if (__wait_status(0x04)) - return -EIO; - } - - outb(4, APPLESMC_DATA_PORT); - - for (i = 0; i < 4; i++) { - if (__wait_status(0x05)) - return -EIO; - key[i] = inb(APPLESMC_DATA_PORT); - } - key[4] = 0; - - return 0; -} - -/* - * applesmc_get_key_type - get key type, and put the result in type (char[6]). - * Returns zero on success or a negative error on failure. Callers must - * hold applesmc_lock. - */ -static int applesmc_get_key_type(char* key, char* type) -{ - int i; - - outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT); - if (__wait_status(0x0c)) - return -EIO; - - for (i = 0; i < 4; i++) { - outb(key[i], APPLESMC_DATA_PORT); - if (__wait_status(0x04)) - return -EIO; - } - - outb(5, APPLESMC_DATA_PORT); - - for (i = 0; i < 6; i++) { - if (__wait_status(0x05)) - return -EIO; - type[i] = inb(APPLESMC_DATA_PORT); - } - type[5] = 0; - - return 0; -} - -/* - * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must - * hold applesmc_lock. - */ -static int applesmc_read_motion_sensor(int index, s16* value) -{ - u8 buffer[2]; - int ret; - - switch (index) { - case SENSOR_X: - ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2); - break; - case SENSOR_Y: - ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2); - break; - case SENSOR_Z: - ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2); - break; - default: - ret = -EINVAL; - } - - *value = ((s16)buffer[0] << 8) | buffer[1]; - - return ret; -} - -/* - * applesmc_device_init - initialize the accelerometer. Returns zero on success - * and negative error code on failure. Can sleep. - */ -static int applesmc_device_init(void) -{ - int total, ret = -ENXIO; - u8 buffer[2]; - - if (!applesmc_accelerometer) - return 0; - - mutex_lock(&applesmc_lock); - - for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { - if (debug) - printk(KERN_DEBUG "applesmc try %d\n", total); - if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) && - (buffer[0] != 0x00 || buffer[1] != 0x00)) { - if (total == INIT_TIMEOUT_MSECS) { - printk(KERN_DEBUG "applesmc: device has" - " already been initialized" - " (0x%02x, 0x%02x).\n", - buffer[0], buffer[1]); - } else { - printk(KERN_DEBUG "applesmc: device" - " successfully initialized" - " (0x%02x, 0x%02x).\n", - buffer[0], buffer[1]); - } - ret = 0; - goto out; - } - buffer[0] = 0xe0; - buffer[1] = 0x00; - applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2); - msleep(INIT_WAIT_MSECS); - } - - printk(KERN_WARNING "applesmc: failed to init the device\n"); - -out: - mutex_unlock(&applesmc_lock); - return ret; -} - -/* - * applesmc_get_fan_count - get the number of fans. Callers must NOT hold - * applesmc_lock. - */ -static int applesmc_get_fan_count(void) -{ - int ret; - u8 buffer[1]; - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_key(FANS_COUNT, buffer, 1); - - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return buffer[0]; -} - -/* Device model stuff */ -static int applesmc_probe(struct platform_device *dev) -{ - int ret; - - ret = applesmc_device_init(); - if (ret) - return ret; - - printk(KERN_INFO "applesmc: device successfully initialized.\n"); - return 0; -} - -static int applesmc_resume(struct platform_device *dev) -{ - return applesmc_device_init(); -} - -static struct platform_driver applesmc_driver = { - .probe = applesmc_probe, - .resume = applesmc_resume, - .driver = { - .name = "applesmc", - .owner = THIS_MODULE, - }, -}; - -/* - * applesmc_calibrate - Set our "resting" values. Callers must - * hold applesmc_lock. - */ -static void applesmc_calibrate(void) -{ - applesmc_read_motion_sensor(SENSOR_X, &rest_x); - applesmc_read_motion_sensor(SENSOR_Y, &rest_y); - rest_x = -rest_x; -} - -static int applesmc_idev_open(struct input_dev *dev) -{ - add_timer(&applesmc_timer); - - return 0; -} - -static void applesmc_idev_close(struct input_dev *dev) -{ - del_timer_sync(&applesmc_timer); -} - -static void applesmc_idev_poll(unsigned long unused) -{ - s16 x, y; - - /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ - if (!mutex_trylock(&applesmc_lock)) { - mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD); - return; - } - - if (applesmc_read_motion_sensor(SENSOR_X, &x)) - goto out; - if (applesmc_read_motion_sensor(SENSOR_Y, &y)) - goto out; - - x = -x; - input_report_abs(applesmc_idev, ABS_X, x - rest_x); - input_report_abs(applesmc_idev, ABS_Y, y - rest_y); - input_sync(applesmc_idev); - -out: - mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD); - - mutex_unlock(&applesmc_lock); -} - -/* Sysfs Files */ - -static ssize_t applesmc_position_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret; - s16 x, y, z; - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_motion_sensor(SENSOR_X, &x); - if (ret) - goto out; - ret = applesmc_read_motion_sensor(SENSOR_Y, &y); - if (ret) - goto out; - ret = applesmc_read_motion_sensor(SENSOR_Z, &z); - if (ret) - goto out; - -out: - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z); -} - -static ssize_t applesmc_light_show(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - int ret; - u8 left = 0, right = 0; - u8 buffer[6]; - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, 6); - left = buffer[2]; - if (ret) - goto out; - ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6); - right = buffer[2]; - -out: - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right); -} - -/* Displays degree Celsius * 1000 */ -static ssize_t applesmc_show_temperature(struct device *dev, - struct device_attribute *devattr, char *sysfsbuf) -{ - int ret; - u8 buffer[2]; - unsigned int temp; - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - const char* key = - temperature_sensors_sets[applesmc_temperature_set][attr->index]; - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_key(key, buffer, 2); - temp = buffer[0]*1000; - temp += (buffer[1] >> 6) * 250; - - mutex_unlock(&applesmc_lock); - - if (ret) - return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); -} - -static ssize_t applesmc_show_fan_speed(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - int ret; - unsigned int speed = 0; - char newkey[5]; - u8 buffer[2]; - struct sensor_device_attribute_2 *sensor_attr = - to_sensor_dev_attr_2(attr); - - newkey[0] = fan_speed_keys[sensor_attr->nr][0]; - newkey[1] = '0' + sensor_attr->index; - newkey[2] = fan_speed_keys[sensor_attr->nr][2]; - newkey[3] = fan_speed_keys[sensor_attr->nr][3]; - newkey[4] = 0; - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_key(newkey, buffer, 2); - speed = ((buffer[0] << 8 | buffer[1]) >> 2); - - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed); -} - -static ssize_t applesmc_store_fan_speed(struct device *dev, - struct device_attribute *attr, - const char *sysfsbuf, size_t count) -{ - int ret; - u32 speed; - char newkey[5]; - u8 buffer[2]; - struct sensor_device_attribute_2 *sensor_attr = - to_sensor_dev_attr_2(attr); - - speed = simple_strtoul(sysfsbuf, NULL, 10); - - if (speed > 0x4000) /* Bigger than a 14-bit value */ - return -EINVAL; - - newkey[0] = fan_speed_keys[sensor_attr->nr][0]; - newkey[1] = '0' + sensor_attr->index; - newkey[2] = fan_speed_keys[sensor_attr->nr][2]; - newkey[3] = fan_speed_keys[sensor_attr->nr][3]; - newkey[4] = 0; - - mutex_lock(&applesmc_lock); - - buffer[0] = (speed >> 6) & 0xff; - buffer[1] = (speed << 2) & 0xff; - ret = applesmc_write_key(newkey, buffer, 2); - - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return count; -} - -static ssize_t applesmc_show_fan_manual(struct device *dev, - struct device_attribute *devattr, char *sysfsbuf) -{ - int ret; - u16 manual = 0; - u8 buffer[2]; - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_key(FANS_MANUAL, buffer, 2); - manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01; - - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual); -} - -static ssize_t applesmc_store_fan_manual(struct device *dev, - struct device_attribute *devattr, - const char *sysfsbuf, size_t count) -{ - int ret; - u8 buffer[2]; - u32 input; - u16 val; - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - - input = simple_strtoul(sysfsbuf, NULL, 10); - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_key(FANS_MANUAL, buffer, 2); - val = (buffer[0] << 8 | buffer[1]); - if (ret) - goto out; - - if (input) - val = val | (0x01 << attr->index); - else - val = val & ~(0x01 << attr->index); - - buffer[0] = (val >> 8) & 0xFF; - buffer[1] = val & 0xFF; - - ret = applesmc_write_key(FANS_MANUAL, buffer, 2); - -out: - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return count; -} - -static ssize_t applesmc_show_fan_position(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - int ret; - char newkey[5]; - u8 buffer[17]; - struct sensor_device_attribute_2 *sensor_attr = - to_sensor_dev_attr_2(attr); - - newkey[0] = FAN_POSITION[0]; - newkey[1] = '0' + sensor_attr->index; - newkey[2] = FAN_POSITION[2]; - newkey[3] = FAN_POSITION[3]; - newkey[4] = 0; - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_key(newkey, buffer, 16); - buffer[16] = 0; - - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4); -} - -static ssize_t applesmc_calibrate_show(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y); -} - -static ssize_t applesmc_calibrate_store(struct device *dev, - struct device_attribute *attr, const char *sysfsbuf, size_t count) -{ - mutex_lock(&applesmc_lock); - applesmc_calibrate(); - mutex_unlock(&applesmc_lock); - - return count; -} - -/* Store the next backlight value to be written by the work */ -static unsigned int backlight_value; - -static void applesmc_backlight_set(struct work_struct *work) -{ - u8 buffer[2]; - - mutex_lock(&applesmc_lock); - buffer[0] = backlight_value; - buffer[1] = 0x00; - applesmc_write_key(BACKLIGHT_KEY, buffer, 2); - mutex_unlock(&applesmc_lock); -} -static DECLARE_WORK(backlight_work, &applesmc_backlight_set); - -static void applesmc_brightness_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - int ret; - - backlight_value = value; - ret = queue_work(applesmc_led_wq, &backlight_work); - - if (debug && (!ret)) - printk(KERN_DEBUG "applesmc: work was already on the queue.\n"); -} - -static ssize_t applesmc_key_count_show(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - int ret; - u8 buffer[4]; - u32 count; - - mutex_lock(&applesmc_lock); - - ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4); - count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) + - ((u32)buffer[2]<<8) + buffer[3]; - - mutex_unlock(&applesmc_lock); - if (ret) - return ret; - else - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count); -} - -static ssize_t applesmc_key_at_index_read_show(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - char key[5]; - char info[6]; - int ret; - - mutex_lock(&applesmc_lock); - - ret = applesmc_get_key_at_index(key_at_index, key); - - if (ret || !key[0]) { - mutex_unlock(&applesmc_lock); - - return -EINVAL; - } - - ret = applesmc_get_key_type(key, info); - - if (ret) { - mutex_unlock(&applesmc_lock); - - return ret; - } - - /* - * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than - * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf. - */ - ret = applesmc_read_key(key, sysfsbuf, info[0]); - - mutex_unlock(&applesmc_lock); - - if (!ret) { - return info[0]; - } - else { - return ret; - } -} - -static ssize_t applesmc_key_at_index_data_length_show(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - char key[5]; - char info[6]; - int ret; - - mutex_lock(&applesmc_lock); - - ret = applesmc_get_key_at_index(key_at_index, key); - - if (ret || !key[0]) { - mutex_unlock(&applesmc_lock); - - return -EINVAL; - } - - ret = applesmc_get_key_type(key, info); - - mutex_unlock(&applesmc_lock); - - if (!ret) - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]); - else - return ret; -} - -static ssize_t applesmc_key_at_index_type_show(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - char key[5]; - char info[6]; - int ret; - - mutex_lock(&applesmc_lock); - - ret = applesmc_get_key_at_index(key_at_index, key); - - if (ret || !key[0]) { - mutex_unlock(&applesmc_lock); - - return -EINVAL; - } - - ret = applesmc_get_key_type(key, info); - - mutex_unlock(&applesmc_lock); - - if (!ret) - return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1); - else - return ret; -} - -static ssize_t applesmc_key_at_index_name_show(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - char key[5]; - int ret; - - mutex_lock(&applesmc_lock); - - ret = applesmc_get_key_at_index(key_at_index, key); - - mutex_unlock(&applesmc_lock); - - if (!ret && key[0]) - return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); - else - return -EINVAL; -} - -static ssize_t applesmc_key_at_index_show(struct device *dev, - struct device_attribute *attr, char *sysfsbuf) -{ - return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index); -} - -static ssize_t applesmc_key_at_index_store(struct device *dev, - struct device_attribute *attr, const char *sysfsbuf, size_t count) -{ - mutex_lock(&applesmc_lock); - - key_at_index = simple_strtoul(sysfsbuf, NULL, 10); - - mutex_unlock(&applesmc_lock); - - return count; -} - -static struct led_classdev applesmc_backlight = { - .name = "smc:kbd_backlight", - .default_trigger = "nand-disk", - .brightness_set = applesmc_brightness_set, -}; - -static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL); -static DEVICE_ATTR(calibrate, 0644, - applesmc_calibrate_show, applesmc_calibrate_store); - -static struct attribute *accelerometer_attributes[] = { - &dev_attr_position.attr, - &dev_attr_calibrate.attr, - NULL -}; - -static const struct attribute_group accelerometer_attributes_group = - { .attrs = accelerometer_attributes }; - -static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL); - -static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL); -static DEVICE_ATTR(key_at_index, 0644, - applesmc_key_at_index_show, applesmc_key_at_index_store); -static DEVICE_ATTR(key_at_index_name, 0444, - applesmc_key_at_index_name_show, NULL); -static DEVICE_ATTR(key_at_index_type, 0444, - applesmc_key_at_index_type_show, NULL); -static DEVICE_ATTR(key_at_index_data_length, 0444, - applesmc_key_at_index_data_length_show, NULL); -static DEVICE_ATTR(key_at_index_data, 0444, - applesmc_key_at_index_read_show, NULL); - -static struct attribute *key_enumeration_attributes[] = { - &dev_attr_key_count.attr, - &dev_attr_key_at_index.attr, - &dev_attr_key_at_index_name.attr, - &dev_attr_key_at_index_type.attr, - &dev_attr_key_at_index_data_length.attr, - &dev_attr_key_at_index_data.attr, - NULL -}; - -static const struct attribute_group key_enumeration_group = - { .attrs = key_enumeration_attributes }; - -/* - * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries. - * - show actual speed - * - show/store minimum speed - * - show maximum speed - * - show safe speed - * - show/store target speed - * - show/store manual mode - */ -#define sysfs_fan_speeds_offset(offset) \ -static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \ - applesmc_show_fan_speed, NULL, 0, offset-1); \ -\ -static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \ - applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \ -\ -static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \ - applesmc_show_fan_speed, NULL, 2, offset-1); \ -\ -static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \ - applesmc_show_fan_speed, NULL, 3, offset-1); \ -\ -static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \ - applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \ -\ -static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \ - applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \ -\ -static SENSOR_DEVICE_ATTR(fan##offset##_position, S_IRUGO, \ - applesmc_show_fan_position, NULL, offset-1); \ -\ -static struct attribute *fan##offset##_attributes[] = { \ - &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \ - &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \ - &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \ - &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \ - &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \ - &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \ - &sensor_dev_attr_fan##offset##_position.dev_attr.attr, \ - NULL \ -}; - -/* - * Create the needed functions for each fan using the macro defined above - * (2 fans are supported) - */ -sysfs_fan_speeds_offset(1); -sysfs_fan_speeds_offset(2); - -static const struct attribute_group fan_attribute_groups[] = { - { .attrs = fan1_attributes }, - { .attrs = fan2_attributes } -}; - -/* - * Temperature sensors sysfs entries. - */ -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, - applesmc_show_temperature, NULL, 0); -static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, - applesmc_show_temperature, NULL, 1); -static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, - applesmc_show_temperature, NULL, 2); -static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, - applesmc_show_temperature, NULL, 3); -static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, - applesmc_show_temperature, NULL, 4); -static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, - applesmc_show_temperature, NULL, 5); -static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, - applesmc_show_temperature, NULL, 6); -static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, - applesmc_show_temperature, NULL, 7); -static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, - applesmc_show_temperature, NULL, 8); -static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, - applesmc_show_temperature, NULL, 9); -static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, - applesmc_show_temperature, NULL, 10); -static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, - applesmc_show_temperature, NULL, 11); - -static struct attribute *temperature_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp4_input.dev_attr.attr, - &sensor_dev_attr_temp5_input.dev_attr.attr, - &sensor_dev_attr_temp6_input.dev_attr.attr, - &sensor_dev_attr_temp7_input.dev_attr.attr, - &sensor_dev_attr_temp8_input.dev_attr.attr, - &sensor_dev_attr_temp9_input.dev_attr.attr, - &sensor_dev_attr_temp10_input.dev_attr.attr, - &sensor_dev_attr_temp11_input.dev_attr.attr, - &sensor_dev_attr_temp12_input.dev_attr.attr, - NULL -}; - -static const struct attribute_group temperature_attributes_group = - { .attrs = temperature_attributes }; - -/* Module stuff */ - -/* - * applesmc_dmi_match - found a match. return one, short-circuiting the hunt. - */ -static int applesmc_dmi_match(struct dmi_system_id *id) -{ - int i = 0; - struct dmi_match_data* dmi_data = id->driver_data; - printk(KERN_INFO "applesmc: %s detected:\n", id->ident); - applesmc_accelerometer = dmi_data->accelerometer; - printk(KERN_INFO "applesmc: - Model %s accelerometer\n", - applesmc_accelerometer ? "with" : "without"); - applesmc_light = dmi_data->light; - printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n", - applesmc_light ? "with" : "without"); - - applesmc_temperature_set = dmi_data->temperature_set; - while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL) - i++; - printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i); - return 1; -} - -/* Create accelerometer ressources */ -static int applesmc_create_accelerometer(void) -{ - int ret; - - ret = sysfs_create_group(&pdev->dev.kobj, - &accelerometer_attributes_group); - if (ret) - goto out; - - applesmc_idev = input_allocate_device(); - if (!applesmc_idev) { - ret = -ENOMEM; - goto out_sysfs; - } - - /* initial calibrate for the input device */ - applesmc_calibrate(); - - /* initialize the input class */ - applesmc_idev->name = "applesmc"; - applesmc_idev->id.bustype = BUS_HOST; - applesmc_idev->cdev.dev = &pdev->dev; - applesmc_idev->evbit[0] = BIT(EV_ABS); - applesmc_idev->open = applesmc_idev_open; - applesmc_idev->close = applesmc_idev_close; - input_set_abs_params(applesmc_idev, ABS_X, - -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); - input_set_abs_params(applesmc_idev, ABS_Y, - -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); - - ret = input_register_device(applesmc_idev); - if (ret) - goto out_idev; - - /* start up our timer for the input device */ - init_timer(&applesmc_timer); - applesmc_timer.function = applesmc_idev_poll; - applesmc_timer.expires = jiffies + APPLESMC_POLL_PERIOD; - - return 0; - -out_idev: - input_free_device(applesmc_idev); - -out_sysfs: - sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); - -out: - printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret); - return ret; -} - -/* Release all ressources used by the accelerometer */ -static void applesmc_release_accelerometer(void) -{ - del_timer_sync(&applesmc_timer); - input_unregister_device(applesmc_idev); - sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group); -} - -static __initdata struct dmi_match_data applesmc_dmi_data[] = { -/* MacBook Pro: accelerometer, backlight and temperature set 0 */ - { .accelerometer = 1, .light = 1, .temperature_set = 0 }, -/* MacBook: accelerometer and temperature set 0 */ - { .accelerometer = 1, .light = 0, .temperature_set = 0 }, -/* MacBook: temperature set 1 */ - { .accelerometer = 0, .light = 0, .temperature_set = 1 } -}; - -/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". - * So we need to put "Apple MacBook Pro" before "Apple MacBook". */ -static __initdata struct dmi_system_id applesmc_whitelist[] = { - { applesmc_dmi_match, "Apple MacBook Pro", { - DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), - DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, - (void*)&applesmc_dmi_data[0]}, - { applesmc_dmi_match, "Apple MacBook", { - DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), - DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, - (void*)&applesmc_dmi_data[1]}, - { applesmc_dmi_match, "Apple Macmini", { - DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), - DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, - (void*)&applesmc_dmi_data[2]}, - { .ident = NULL } -}; - -static int __init applesmc_init(void) -{ - int ret; - int count; - int i; - - mutex_init(&applesmc_lock); - - if (!dmi_check_system(applesmc_whitelist)) { - printk(KERN_WARNING "applesmc: supported laptop not found!\n"); - ret = -ENODEV; - goto out; - } - - if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS, - "applesmc")) { - ret = -ENXIO; - goto out; - } - - ret = platform_driver_register(&applesmc_driver); - if (ret) - goto out_region; - - pdev = platform_device_register_simple("applesmc", -1, NULL, 0); - if (IS_ERR(pdev)) { - ret = PTR_ERR(pdev); - goto out_driver; - } - - /* Create key enumeration sysfs files */ - ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group); - if (ret) - goto out_device; - - /* create fan files */ - count = applesmc_get_fan_count(); - if (count < 0) { - printk(KERN_ERR "applesmc: Cannot get the number of fans.\n"); - } else { - printk(KERN_INFO "applesmc: %d fans found.\n", count); - - switch (count) { - default: - printk(KERN_WARNING "applesmc: More than 2 fans found," - " but at most 2 fans are supported" - " by the driver.\n"); - case 2: - ret = sysfs_create_group(&pdev->dev.kobj, - &fan_attribute_groups[1]); - if (ret) - goto out_key_enumeration; - case 1: - ret = sysfs_create_group(&pdev->dev.kobj, - &fan_attribute_groups[0]); - if (ret) - goto out_fan_1; - case 0: - ; - } - } - - for (i = 0; - temperature_sensors_sets[applesmc_temperature_set][i] != NULL; - i++) { - if (temperature_attributes[i] == NULL) { - printk(KERN_ERR "applesmc: More temperature sensors " - "in temperature_sensors_sets (at least %i)" - "than available sysfs files in " - "temperature_attributes (%i), please report " - "this bug.\n", i, i-1); - goto out_temperature; - } - ret = sysfs_create_file(&pdev->dev.kobj, - temperature_attributes[i]); - if (ret) - goto out_temperature; - } - - if (applesmc_accelerometer) { - ret = applesmc_create_accelerometer(); - if (ret) - goto out_temperature; - } - - if (applesmc_light) { - /* Add light sensor file */ - ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr); - if (ret) - goto out_accelerometer; - - /* Create the workqueue */ - applesmc_led_wq = create_singlethread_workqueue("applesmc-led"); - if (!applesmc_led_wq) { - ret = -ENOMEM; - goto out_light_sysfs; - } - - /* register as a led device */ - ret = led_classdev_register(&pdev->dev, &applesmc_backlight); - if (ret < 0) - goto out_light_wq; - } - - hwmon_class_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(hwmon_class_dev)) { - ret = PTR_ERR(hwmon_class_dev); - goto out_light_ledclass; - } - - printk(KERN_INFO "applesmc: driver successfully loaded.\n"); - - return 0; - -out_light_ledclass: - if (applesmc_light) - led_classdev_unregister(&applesmc_backlight); -out_light_wq: - if (applesmc_light) - destroy_workqueue(applesmc_led_wq); -out_light_sysfs: - if (applesmc_light) - sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); -out_accelerometer: - if (applesmc_accelerometer) - applesmc_release_accelerometer(); -out_temperature: - sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); - sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]); -out_fan_1: - sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]); -out_key_enumeration: - sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); -out_device: - platform_device_unregister(pdev); -out_driver: - platform_driver_unregister(&applesmc_driver); -out_region: - release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); -out: - printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret); - return ret; -} - -static void __exit applesmc_exit(void) -{ - hwmon_device_unregister(hwmon_class_dev); - if (applesmc_light) { - led_classdev_unregister(&applesmc_backlight); - destroy_workqueue(applesmc_led_wq); - sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr); - } - if (applesmc_accelerometer) - applesmc_release_accelerometer(); - sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group); - sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]); - sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]); - sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); - platform_device_unregister(pdev); - platform_driver_unregister(&applesmc_driver); - release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS); - - printk(KERN_INFO "applesmc: driver unloaded.\n"); -} - -module_init(applesmc_init); -module_exit(applesmc_exit); - -MODULE_AUTHOR("Nicolas Boichat"); -MODULE_DESCRIPTION("Apple SMC"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c deleted file mode 100644 index 03b1f650d1c4..000000000000 --- a/trunk/drivers/hwmon/coretemp.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * coretemp.c - Linux kernel module for hardware monitoring - * - * Copyright (C) 2007 Rudolf Marek - * - * Inspired from many hwmon drivers - * - * 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; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRVNAME "coretemp" - -typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_LABEL, SHOW_NAME } SHOW; - -/* - * Functions declaration - */ - -static struct coretemp_data *coretemp_update_device(struct device *dev); - -struct coretemp_data { - struct class_device *class_dev; - struct mutex update_lock; - const char *name; - u32 id; - char valid; /* zero until following fields are valid */ - unsigned long last_updated; /* in jiffies */ - int temp; - int tjmax; - u8 alarm; -}; - -static struct coretemp_data *coretemp_update_device(struct device *dev); - -/* - * Sysfs stuff - */ - -static ssize_t show_name(struct device *dev, struct device_attribute - *devattr, char *buf) -{ - int ret; - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct coretemp_data *data = dev_get_drvdata(dev); - - if (attr->index == SHOW_NAME) - ret = sprintf(buf, "%s\n", data->name); - else /* show label */ - ret = sprintf(buf, "Core %d\n", data->id); - return ret; -} - -static ssize_t show_alarm(struct device *dev, struct device_attribute - *devattr, char *buf) -{ - struct coretemp_data *data = coretemp_update_device(dev); - /* read the Out-of-spec log, never clear */ - return sprintf(buf, "%d\n", data->alarm); -} - -static ssize_t show_temp(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct coretemp_data *data = coretemp_update_device(dev); - int err; - - if (attr->index == SHOW_TEMP) - err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN; - else - err = sprintf(buf, "%d\n", data->tjmax); - - return err; -} - -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, - SHOW_TEMP); -static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, - SHOW_TJMAX); -static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL); -static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); -static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME); - -static struct attribute *coretemp_attributes[] = { - &sensor_dev_attr_name.dev_attr.attr, - &sensor_dev_attr_temp1_label.dev_attr.attr, - &dev_attr_temp1_crit_alarm.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_crit.dev_attr.attr, - NULL -}; - -static const struct attribute_group coretemp_group = { - .attrs = coretemp_attributes, -}; - -static struct coretemp_data *coretemp_update_device(struct device *dev) -{ - struct coretemp_data *data = dev_get_drvdata(dev); - - mutex_lock(&data->update_lock); - - if (!data->valid || time_after(jiffies, data->last_updated + HZ)) { - u32 eax, edx; - - data->valid = 0; - rdmsr_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); - data->alarm = (eax >> 5) & 1; - /* update only if data has been valid */ - if (eax & 0x80000000) { - data->temp = data->tjmax - (((eax >> 16) - & 0x7f) * 1000); - data->valid = 1; - } else { - dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax); - } - data->last_updated = jiffies; - } - - mutex_unlock(&data->update_lock); - return data; -} - -static int __devinit coretemp_probe(struct platform_device *pdev) -{ - struct coretemp_data *data; - struct cpuinfo_x86 *c = &(cpu_data)[pdev->id]; - int err; - u32 eax, edx; - - if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) { - err = -ENOMEM; - dev_err(&pdev->dev, "Out of memory\n"); - goto exit; - } - - data->id = pdev->id; - data->name = "coretemp"; - mutex_init(&data->update_lock); - /* Tjmax default is 100 degrees C */ - data->tjmax = 100000; - - /* test if we can access the THERM_STATUS MSR */ - err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx); - if (err) { - dev_err(&pdev->dev, - "Unable to access THERM_STATUS MSR, giving up\n"); - goto exit_free; - } - - /* Some processors have Tjmax 85 following magic should detect it - Intel won't disclose the information without signed NDA, but - individuals cannot sign it. Catch(ed) 22. - */ - - if (((c->x86_model == 0xf) && (c->x86_mask > 3)) || - (c->x86_model == 0xe)) { - err = rdmsr_safe_on_cpu(data->id, 0xee, &eax, &edx); - if (err) { - dev_warn(&pdev->dev, - "Unable to access MSR 0xEE, Tjmax left at %d " - "degrees C\n", data->tjmax/1000); - } else if (eax & 0x40000000) { - data->tjmax = 85000; - } - } - - platform_set_drvdata(pdev, data); - - if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group))) - goto exit_free; - - data->class_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - dev_err(&pdev->dev, "Class registration failed (%d)\n", - err); - goto exit_class; - } - - return 0; - -exit_class: - sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); -exit_free: - kfree(data); -exit: - return err; -} - -static int __devexit coretemp_remove(struct platform_device *pdev) -{ - struct coretemp_data *data = platform_get_drvdata(pdev); - - hwmon_device_unregister(data->class_dev); - sysfs_remove_group(&pdev->dev.kobj, &coretemp_group); - platform_set_drvdata(pdev, NULL); - kfree(data); - return 0; -} - -static struct platform_driver coretemp_driver = { - .driver = { - .owner = THIS_MODULE, - .name = DRVNAME, - }, - .probe = coretemp_probe, - .remove = __devexit_p(coretemp_remove), -}; - -struct pdev_entry { - struct list_head list; - struct platform_device *pdev; - unsigned int cpu; -}; - -static LIST_HEAD(pdev_list); -static DEFINE_MUTEX(pdev_list_mutex); - -static int __cpuinit coretemp_device_add(unsigned int cpu) -{ - int err; - struct platform_device *pdev; - struct pdev_entry *pdev_entry; - - pdev = platform_device_alloc(DRVNAME, cpu); - if (!pdev) { - err = -ENOMEM; - printk(KERN_ERR DRVNAME ": Device allocation failed\n"); - goto exit; - } - - pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL); - if (!pdev_entry) { - err = -ENOMEM; - goto exit_device_put; - } - - err = platform_device_add(pdev); - if (err) { - printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", - err); - goto exit_device_free; - } - - pdev_entry->pdev = pdev; - pdev_entry->cpu = cpu; - mutex_lock(&pdev_list_mutex); - list_add_tail(&pdev_entry->list, &pdev_list); - mutex_unlock(&pdev_list_mutex); - - return 0; - -exit_device_free: - kfree(pdev_entry); -exit_device_put: - platform_device_put(pdev); -exit: - return err; -} - -#ifdef CONFIG_HOTPLUG_CPU -void coretemp_device_remove(unsigned int cpu) -{ - struct pdev_entry *p, *n; - mutex_lock(&pdev_list_mutex); - list_for_each_entry_safe(p, n, &pdev_list, list) { - if (p->cpu == cpu) { - platform_device_unregister(p->pdev); - list_del(&p->list); - kfree(p); - } - } - mutex_unlock(&pdev_list_mutex); -} - -static int coretemp_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long) hcpu; - - switch (action) { - case CPU_ONLINE: - coretemp_device_add(cpu); - break; - case CPU_DEAD: - coretemp_device_remove(cpu); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block __cpuinitdata coretemp_cpu_notifier = { - .notifier_call = coretemp_cpu_callback, -}; -#endif /* !CONFIG_HOTPLUG_CPU */ - -static int __init coretemp_init(void) -{ - int i, err = -ENODEV; - struct pdev_entry *p, *n; - - printk(KERN_NOTICE DRVNAME ": This driver uses undocumented features " - "of Core CPU. Temperature might be wrong!\n"); - - /* quick check if we run Intel */ - if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL) - goto exit; - - err = platform_driver_register(&coretemp_driver); - if (err) - goto exit; - - for_each_online_cpu(i) { - struct cpuinfo_x86 *c = &(cpu_data)[i]; - - /* check if family 6, models e, f */ - if ((c->cpuid_level < 0) || (c->x86 != 0x6) || - !((c->x86_model == 0xe) || (c->x86_model == 0xf))) { - - /* supported CPU not found, but report the unknown - family 6 CPU */ - if ((c->x86 == 0x6) && (c->x86_model > 0xf)) - printk(KERN_WARNING DRVNAME ": Unknown CPU " - "model %x\n", c->x86_model); - continue; - } - - err = coretemp_device_add(i); - if (err) - goto exit_devices_unreg; - } - if (list_empty(&pdev_list)) { - err = -ENODEV; - goto exit_driver_unreg; - } - -#ifdef CONFIG_HOTPLUG_CPU - register_hotcpu_notifier(&coretemp_cpu_notifier); -#endif - return 0; - -exit_devices_unreg: - mutex_lock(&pdev_list_mutex); - list_for_each_entry_safe(p, n, &pdev_list, list) { - platform_device_unregister(p->pdev); - list_del(&p->list); - kfree(p); - } - mutex_unlock(&pdev_list_mutex); -exit_driver_unreg: - platform_driver_unregister(&coretemp_driver); -exit: - return err; -} - -static void __exit coretemp_exit(void) -{ - struct pdev_entry *p, *n; -#ifdef CONFIG_HOTPLUG_CPU - unregister_hotcpu_notifier(&coretemp_cpu_notifier); -#endif - mutex_lock(&pdev_list_mutex); - list_for_each_entry_safe(p, n, &pdev_list, list) { - platform_device_unregister(p->pdev); - list_del(&p->list); - kfree(p); - } - mutex_unlock(&pdev_list_mutex); - platform_driver_unregister(&coretemp_driver); -} - -MODULE_AUTHOR("Rudolf Marek "); -MODULE_DESCRIPTION("Intel Core temperature monitor"); -MODULE_LICENSE("GPL"); - -module_init(coretemp_init) -module_exit(coretemp_exit) diff --git a/trunk/drivers/hwmon/f71805f.c b/trunk/drivers/hwmon/f71805f.c index cdbe309b8fc4..7c2973487122 100644 --- a/trunk/drivers/hwmon/f71805f.c +++ b/trunk/drivers/hwmon/f71805f.c @@ -35,7 +35,6 @@ #include #include #include -#include #include static struct platform_device *pdev; @@ -1141,13 +1140,6 @@ static int __devinit f71805f_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start + ADDR_REG_OFFSET, 2, DRVNAME)) { - err = -EBUSY; - dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", - (unsigned long)(res->start + ADDR_REG_OFFSET), - (unsigned long)(res->start + ADDR_REG_OFFSET + 1)); - goto exit_free; - } data->addr = res->start; data->name = names[sio_data->kind]; mutex_init(&data->update_lock); @@ -1173,7 +1165,7 @@ static int __devinit f71805f_probe(struct platform_device *pdev) /* Register sysfs interface files */ if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group))) - goto exit_release_region; + goto exit_free; if (data->has_in & (1 << 4)) { /* in4 */ if ((err = sysfs_create_group(&pdev->dev.kobj, &f71805f_group_optin[0]))) @@ -1227,8 +1219,6 @@ static int __devinit f71805f_probe(struct platform_device *pdev) for (i = 0; i < 4; i++) sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_optin[i]); sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); -exit_release_region: - release_region(res->start + ADDR_REG_OFFSET, 2); exit_free: platform_set_drvdata(pdev, NULL); kfree(data); @@ -1239,7 +1229,6 @@ static int __devinit f71805f_probe(struct platform_device *pdev) static int __devexit f71805f_remove(struct platform_device *pdev) { struct f71805f_data *data = platform_get_drvdata(pdev); - struct resource *res; int i; platform_set_drvdata(pdev, NULL); @@ -1250,9 +1239,6 @@ static int __devexit f71805f_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &f71805f_group_pwm_freq); kfree(data); - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start + ADDR_REG_OFFSET, 2); - return 0; } diff --git a/trunk/drivers/hwmon/hdaps.c b/trunk/drivers/hwmon/hdaps.c index f82fa2d23f95..bf759ea545ac 100644 --- a/trunk/drivers/hwmon/hdaps.c +++ b/trunk/drivers/hwmon/hdaps.c @@ -30,12 +30,10 @@ #include #include #include -#include #include #include #include #include - #include #define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ @@ -73,10 +71,10 @@ static u8 km_activity; static int rest_x; static int rest_y; -static DEFINE_MUTEX(hdaps_mtx); +static DECLARE_MUTEX(hdaps_sem); /* - * __get_latch - Get the value from a given port. Callers must hold hdaps_mtx. + * __get_latch - Get the value from a given port. Callers must hold hdaps_sem. */ static inline u8 __get_latch(u16 port) { @@ -85,7 +83,7 @@ static inline u8 __get_latch(u16 port) /* * __check_latch - Check a port latch for a given value. Returns zero if the - * port contains the given value. Callers must hold hdaps_mtx. + * port contains the given value. Callers must hold hdaps_sem. */ static inline int __check_latch(u16 port, u8 val) { @@ -96,7 +94,7 @@ static inline int __check_latch(u16 port, u8 val) /* * __wait_latch - Wait up to 100us for a port latch to get a certain value, - * returning zero if the value is obtained. Callers must hold hdaps_mtx. + * returning zero if the value is obtained. Callers must hold hdaps_sem. */ static int __wait_latch(u16 port, u8 val) { @@ -113,7 +111,7 @@ static int __wait_latch(u16 port, u8 val) /* * __device_refresh - request a refresh from the accelerometer. Does not wait - * for refresh to complete. Callers must hold hdaps_mtx. + * for refresh to complete. Callers must hold hdaps_sem. */ static void __device_refresh(void) { @@ -127,7 +125,7 @@ static void __device_refresh(void) /* * __device_refresh_sync - request a synchronous refresh from the * accelerometer. We wait for the refresh to complete. Returns zero if - * successful and nonzero on error. Callers must hold hdaps_mtx. + * successful and nonzero on error. Callers must hold hdaps_sem. */ static int __device_refresh_sync(void) { @@ -137,7 +135,7 @@ static int __device_refresh_sync(void) /* * __device_complete - indicate to the accelerometer that we are done reading - * data, and then initiate an async refresh. Callers must hold hdaps_mtx. + * data, and then initiate an async refresh. Callers must hold hdaps_sem. */ static inline void __device_complete(void) { @@ -155,7 +153,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val) { int ret; - mutex_lock(&hdaps_mtx); + down(&hdaps_sem); /* do a sync refresh -- we need to be sure that we read fresh data */ ret = __device_refresh_sync(); @@ -166,7 +164,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val) __device_complete(); out: - mutex_unlock(&hdaps_mtx); + up(&hdaps_sem); return ret; } @@ -201,9 +199,9 @@ static int hdaps_read_pair(unsigned int port1, unsigned int port2, { int ret; - mutex_lock(&hdaps_mtx); + down(&hdaps_sem); ret = __hdaps_read_pair(port1, port2, val1, val2); - mutex_unlock(&hdaps_mtx); + up(&hdaps_sem); return ret; } @@ -216,7 +214,7 @@ static int hdaps_device_init(void) { int total, ret = -ENXIO; - mutex_lock(&hdaps_mtx); + down(&hdaps_sem); outb(0x13, 0x1610); outb(0x01, 0x161f); @@ -282,7 +280,7 @@ static int hdaps_device_init(void) } out: - mutex_unlock(&hdaps_mtx); + up(&hdaps_sem); return ret; } @@ -316,7 +314,7 @@ static struct platform_driver hdaps_driver = { }; /* - * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mtx. + * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem. */ static void hdaps_calibrate(void) { @@ -328,7 +326,7 @@ static void hdaps_mousedev_poll(unsigned long unused) int x, y; /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ - if (mutex_trylock(&hdaps_mtx)) { + if (down_trylock(&hdaps_sem)) { mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD); return; } @@ -343,7 +341,7 @@ static void hdaps_mousedev_poll(unsigned long unused) mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); out: - mutex_unlock(&hdaps_mtx); + up(&hdaps_sem); } @@ -423,9 +421,9 @@ static ssize_t hdaps_calibrate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - mutex_lock(&hdaps_mtx); + down(&hdaps_sem); hdaps_calibrate(); - mutex_unlock(&hdaps_mtx); + up(&hdaps_sem); return count; } diff --git a/trunk/drivers/hwmon/hwmon-vid.c b/trunk/drivers/hwmon/hwmon-vid.c index 5aab23b93e24..b80f6ed5acfc 100644 --- a/trunk/drivers/hwmon/hwmon-vid.c +++ b/trunk/drivers/hwmon/hwmon-vid.c @@ -166,16 +166,16 @@ static struct vrm_model vrm_models[] = { {X86_VENDOR_INTEL, 0x6, 0xE, ANY, 14}, /* Intel Core (65 nm) */ {X86_VENDOR_INTEL, 0x6, 0xF, ANY, 110}, /* Intel Conroe */ {X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */ + {X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */ {X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */ {X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90}, /* P4 Willamette */ {X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90}, /* P4 Northwood */ {X86_VENDOR_INTEL, 0xF, ANY, ANY, 100}, /* Prescott and above assume VRD 10 */ + {X86_VENDOR_INTEL, 0x10, ANY, ANY, 0}, /* Itanium 2 */ {X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */ {X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */ {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */ - {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */ - {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */ - {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */ + {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M */ {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ }; diff --git a/trunk/drivers/hwmon/lm75.c b/trunk/drivers/hwmon/lm75.c index a40166ffad12..7c65b8bb6d72 100644 --- a/trunk/drivers/hwmon/lm75.c +++ b/trunk/drivers/hwmon/lm75.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include "lm75.h" @@ -40,12 +39,10 @@ I2C_CLIENT_INSMOD_1(lm75); /* Many LM75 constants specified below */ /* The LM75 registers */ +#define LM75_REG_TEMP 0x00 #define LM75_REG_CONF 0x01 -static const u8 LM75_REG_TEMP[3] = { - 0x00, /* input */ - 0x03, /* max */ - 0x02, /* hyst */ -}; +#define LM75_REG_TEMP_HYST 0x02 +#define LM75_REG_TEMP_OS 0x03 /* Each client has this additional data */ struct lm75_data { @@ -54,10 +51,9 @@ struct lm75_data { struct mutex update_lock; char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ - u16 temp[3]; /* Register values, - 0 = input - 1 = max - 2 = hyst */ + u16 temp_input; /* Register values */ + u16 temp_max; + u16 temp_hyst; }; static int lm75_attach_adapter(struct i2c_adapter *adapter); @@ -79,36 +75,35 @@ static struct i2c_driver lm75_driver = { .detach_client = lm75_detach_client, }; -static ssize_t show_temp(struct device *dev, struct device_attribute *da, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm75_data *data = lm75_update_device(dev); - return sprintf(buf, "%d\n", - LM75_TEMP_FROM_REG(data->temp[attr->index])); +#define show(value) \ +static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + struct lm75_data *data = lm75_update_device(dev); \ + return sprintf(buf, "%d\n", LM75_TEMP_FROM_REG(data->value)); \ } - -static ssize_t set_temp(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct i2c_client *client = to_i2c_client(dev); - struct lm75_data *data = i2c_get_clientdata(client); - int nr = attr->index; - unsigned long temp = simple_strtoul(buf, NULL, 10); - - mutex_lock(&data->update_lock); - data->temp[nr] = LM75_TEMP_TO_REG(temp); - lm75_write_value(client, LM75_REG_TEMP[nr], data->temp[nr]); - mutex_unlock(&data->update_lock); - return count; +show(temp_max); +show(temp_hyst); +show(temp_input); + +#define set(value, reg) \ +static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + struct i2c_client *client = to_i2c_client(dev); \ + struct lm75_data *data = i2c_get_clientdata(client); \ + int temp = simple_strtoul(buf, NULL, 10); \ + \ + mutex_lock(&data->update_lock); \ + data->value = LM75_TEMP_TO_REG(temp); \ + lm75_write_value(client, reg, data->value); \ + mutex_unlock(&data->update_lock); \ + return count; \ } +set(temp_max, LM75_REG_TEMP_OS); +set(temp_hyst, LM75_REG_TEMP_HYST); -static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, - show_temp, set_temp, 1); -static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, - show_temp, set_temp, 2); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); +static DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, set_temp_max); +static DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, show_temp_hyst, set_temp_hyst); +static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL); static int lm75_attach_adapter(struct i2c_adapter *adapter) { @@ -118,9 +113,9 @@ static int lm75_attach_adapter(struct i2c_adapter *adapter) } static struct attribute *lm75_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp1_max.attr, + &dev_attr_temp1_max_hyst.attr, NULL }; @@ -288,12 +283,11 @@ static struct lm75_data *lm75_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { - int i; dev_dbg(&client->dev, "Starting lm75 update\n"); - for (i = 0; i < ARRAY_SIZE(data->temp); i++) - data->temp[i] = lm75_read_value(client, - LM75_REG_TEMP[i]); + data->temp_input = lm75_read_value(client, LM75_REG_TEMP); + data->temp_max = lm75_read_value(client, LM75_REG_TEMP_OS); + data->temp_hyst = lm75_read_value(client, LM75_REG_TEMP_HYST); data->last_updated = jiffies; data->valid = 1; } diff --git a/trunk/drivers/hwmon/lm78.c b/trunk/drivers/hwmon/lm78.c index 9fb572f03ba5..886786c33916 100644 --- a/trunk/drivers/hwmon/lm78.c +++ b/trunk/drivers/hwmon/lm78.c @@ -2,7 +2,6 @@ lm78.c - Part of lm_sensors, Linux kernel modules for hardware monitoring Copyright (c) 1998, 1999 Frodo Looijaard - Copyright (c) 2007 Jean Delvare 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 @@ -24,18 +23,13 @@ #include #include #include -#include -#include +#include #include #include -#include #include #include #include -/* ISA device, if found */ -static struct platform_device *pdev; - /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, @@ -127,8 +121,12 @@ static inline int TEMP_FROM_REG(s8 val) a bit - except if there could be more than one SMBus. Groan. No solution for this yet. */ -/* For ISA chips, we abuse the i2c_client addr and name fields. We also use - the driver field to differentiate between I2C and ISA chips. */ +/* This module may seem overly long and complicated. In fact, it is not so + bad. Quite a lot of bookkeeping is done. A real driver can often cut + some corners. */ + +/* For each registered chip, we need to keep some data in memory. + The structure is dynamically allocated. */ struct lm78_data { struct i2c_client client; struct class_device *class_dev; @@ -154,16 +152,14 @@ struct lm78_data { static int lm78_attach_adapter(struct i2c_adapter *adapter); +static int lm78_isa_attach_adapter(struct i2c_adapter *adapter); static int lm78_detect(struct i2c_adapter *adapter, int address, int kind); static int lm78_detach_client(struct i2c_client *client); -static int __devinit lm78_isa_probe(struct platform_device *pdev); -static int __devexit lm78_isa_remove(struct platform_device *pdev); - -static int lm78_read_value(struct lm78_data *data, u8 reg); -static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value); +static int lm78_read_value(struct i2c_client *client, u8 reg); +static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value); static struct lm78_data *lm78_update_device(struct device *dev); -static void lm78_init_device(struct lm78_data *data); +static void lm78_init_client(struct i2c_client *client); static struct i2c_driver lm78_driver = { @@ -175,78 +171,95 @@ static struct i2c_driver lm78_driver = { .detach_client = lm78_detach_client, }; -static struct platform_driver lm78_isa_driver = { +static struct i2c_driver lm78_isa_driver = { .driver = { .owner = THIS_MODULE, - .name = "lm78", + .name = "lm78-isa", }, - .probe = lm78_isa_probe, - .remove = lm78_isa_remove, + .attach_adapter = lm78_isa_attach_adapter, + .detach_client = lm78_detach_client, }; /* 7 Voltages */ -static ssize_t show_in(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_in(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = lm78_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index])); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr])); } -static ssize_t show_in_min(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_in_min(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = lm78_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index])); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr])); } -static ssize_t show_in_max(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_in_max(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = lm78_update_device(dev); - return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index])); + return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr])); } -static ssize_t set_in_min(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t set_in_min(struct device *dev, const char *buf, + size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm78_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct lm78_data *data = i2c_get_clientdata(client); unsigned long val = simple_strtoul(buf, NULL, 10); - int nr = attr->index; mutex_lock(&data->update_lock); data->in_min[nr] = IN_TO_REG(val); - lm78_write_value(data, LM78_REG_IN_MIN(nr), data->in_min[nr]); + lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]); mutex_unlock(&data->update_lock); return count; } -static ssize_t set_in_max(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t set_in_max(struct device *dev, const char *buf, + size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm78_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct lm78_data *data = i2c_get_clientdata(client); unsigned long val = simple_strtoul(buf, NULL, 10); - int nr = attr->index; mutex_lock(&data->update_lock); data->in_max[nr] = IN_TO_REG(val); - lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]); + lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]); mutex_unlock(&data->update_lock); return count; } #define show_in_offset(offset) \ -static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ - show_in, NULL, offset); \ -static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in_min, set_in_min, offset); \ -static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in_max, set_in_max, offset); +static ssize_t \ + show_in##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_in(dev, buf, offset); \ +} \ +static DEVICE_ATTR(in##offset##_input, S_IRUGO, \ + show_in##offset, NULL); \ +static ssize_t \ + show_in##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_in_min(dev, buf, offset); \ +} \ +static ssize_t \ + show_in##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_in_max(dev, buf, offset); \ +} \ +static ssize_t set_in##offset##_min (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return set_in_min(dev, buf, count, offset); \ +} \ +static ssize_t set_in##offset##_max (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return set_in_max(dev, buf, count, offset); \ +} \ +static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ + show_in##offset##_min, set_in##offset##_min); \ +static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ + show_in##offset##_max, set_in##offset##_max); show_in_offset(0); show_in_offset(1); @@ -257,49 +270,46 @@ show_in_offset(5); show_in_offset(6); /* Temperature */ -static ssize_t show_temp(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) { struct lm78_data *data = lm78_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp)); } -static ssize_t show_temp_over(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_temp_over(struct device *dev, struct device_attribute *attr, char *buf) { struct lm78_data *data = lm78_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over)); } -static ssize_t set_temp_over(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lm78_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct lm78_data *data = i2c_get_clientdata(client); long val = simple_strtol(buf, NULL, 10); mutex_lock(&data->update_lock); data->temp_over = TEMP_TO_REG(val); - lm78_write_value(data, LM78_REG_TEMP_OVER, data->temp_over); + lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over); mutex_unlock(&data->update_lock); return count; } -static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *attr, char *buf) { struct lm78_data *data = lm78_update_device(dev); return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst)); } -static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct lm78_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct lm78_data *data = i2c_get_clientdata(client); long val = simple_strtol(buf, NULL, 10); mutex_lock(&data->update_lock); data->temp_hyst = TEMP_TO_REG(val); - lm78_write_value(data, LM78_REG_TEMP_HYST, data->temp_hyst); + lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst); mutex_unlock(&data->update_lock); return count; } @@ -311,59 +321,49 @@ static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp_hyst, set_temp_hyst); /* 3 Fans */ -static ssize_t show_fan(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_fan(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = lm78_update_device(dev); - int nr = attr->index; return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr])) ); } -static ssize_t show_fan_min(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_fan_min(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = lm78_update_device(dev); - int nr = attr->index; return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])) ); } -static ssize_t set_fan_min(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t set_fan_min(struct device *dev, const char *buf, + size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm78_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct lm78_data *data = i2c_get_clientdata(client); unsigned long val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); - lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); + lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); mutex_unlock(&data->update_lock); return count; } -static ssize_t show_fan_div(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_fan_div(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct lm78_data *data = lm78_update_device(dev); - return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); + return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) ); } /* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of least surprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ -static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +static ssize_t set_fan_div(struct device *dev, const char *buf, + size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct lm78_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct lm78_data *data = i2c_get_clientdata(client); unsigned long val = simple_strtoul(buf, NULL, 10); unsigned long min; u8 reg; @@ -378,13 +378,13 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, case 4: data->fan_div[nr] = 2; break; case 8: data->fan_div[nr] = 3; break; default: - dev_err(dev, "fan_div value %ld not " + dev_err(&client->dev, "fan_div value %ld not " "supported. Choose one of 1, 2, 4 or 8!\n", val); mutex_unlock(&data->update_lock); return -EINVAL; } - reg = lm78_read_value(data, LM78_REG_VID_FANDIV); + reg = lm78_read_value(client, LM78_REG_VID_FANDIV); switch (nr) { case 0: reg = (reg & 0xcf) | (data->fan_div[nr] << 4); @@ -393,36 +393,63 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da, reg = (reg & 0x3f) | (data->fan_div[nr] << 6); break; } - lm78_write_value(data, LM78_REG_VID_FANDIV, reg); + lm78_write_value(client, LM78_REG_VID_FANDIV, reg); data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); - lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); + lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]); mutex_unlock(&data->update_lock); return count; } -#define show_fan_offset(offset) \ -static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ - show_fan, NULL, offset - 1); \ -static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - show_fan_min, set_fan_min, offset - 1); +#define show_fan_offset(offset) \ +static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_fan(dev, buf, offset - 1); \ +} \ +static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_fan_min(dev, buf, offset - 1); \ +} \ +static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_fan_div(dev, buf, offset - 1); \ +} \ +static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return set_fan_min(dev, buf, count, offset - 1); \ +} \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\ +static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ + show_fan_##offset##_min, set_fan_##offset##_min); + +static ssize_t set_fan_1_div(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + return set_fan_div(dev, buf, count, 0) ; +} + +static ssize_t set_fan_2_div(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) +{ + return set_fan_div(dev, buf, count, 1) ; +} show_fan_offset(1); show_fan_offset(2); show_fan_offset(3); /* Fan 3 divisor is locked in H/W */ -static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, - show_fan_div, set_fan_div, 0); -static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, - show_fan_div, set_fan_div, 1); -static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2); +static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, + show_fan_1_div, set_fan_1_div); +static DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, + show_fan_2_div, set_fan_2_div); +static DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_3_div, NULL); /* VID */ -static ssize_t show_vid(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf) { struct lm78_data *data = lm78_update_device(dev); return sprintf(buf, "%d\n", vid_from_reg(data->vid, 82)); @@ -430,8 +457,7 @@ static ssize_t show_vid(struct device *dev, struct device_attribute *da, static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL); /* Alarms */ -static ssize_t show_alarms(struct device *dev, struct device_attribute *da, - char *buf) +static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) { struct lm78_data *data = lm78_update_device(dev); return sprintf(buf, "%u\n", data->alarms); @@ -449,40 +475,45 @@ static int lm78_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, lm78_detect); } +static int lm78_isa_attach_adapter(struct i2c_adapter *adapter) +{ + return lm78_detect(adapter, isa_address, -1); +} + static struct attribute *lm78_attributes[] = { - &sensor_dev_attr_in0_input.dev_attr.attr, - &sensor_dev_attr_in0_min.dev_attr.attr, - &sensor_dev_attr_in0_max.dev_attr.attr, - &sensor_dev_attr_in1_input.dev_attr.attr, - &sensor_dev_attr_in1_min.dev_attr.attr, - &sensor_dev_attr_in1_max.dev_attr.attr, - &sensor_dev_attr_in2_input.dev_attr.attr, - &sensor_dev_attr_in2_min.dev_attr.attr, - &sensor_dev_attr_in2_max.dev_attr.attr, - &sensor_dev_attr_in3_input.dev_attr.attr, - &sensor_dev_attr_in3_min.dev_attr.attr, - &sensor_dev_attr_in3_max.dev_attr.attr, - &sensor_dev_attr_in4_input.dev_attr.attr, - &sensor_dev_attr_in4_min.dev_attr.attr, - &sensor_dev_attr_in4_max.dev_attr.attr, - &sensor_dev_attr_in5_input.dev_attr.attr, - &sensor_dev_attr_in5_min.dev_attr.attr, - &sensor_dev_attr_in5_max.dev_attr.attr, - &sensor_dev_attr_in6_input.dev_attr.attr, - &sensor_dev_attr_in6_min.dev_attr.attr, - &sensor_dev_attr_in6_max.dev_attr.attr, + &dev_attr_in0_input.attr, + &dev_attr_in0_min.attr, + &dev_attr_in0_max.attr, + &dev_attr_in1_input.attr, + &dev_attr_in1_min.attr, + &dev_attr_in1_max.attr, + &dev_attr_in2_input.attr, + &dev_attr_in2_min.attr, + &dev_attr_in2_max.attr, + &dev_attr_in3_input.attr, + &dev_attr_in3_min.attr, + &dev_attr_in3_max.attr, + &dev_attr_in4_input.attr, + &dev_attr_in4_min.attr, + &dev_attr_in4_max.attr, + &dev_attr_in5_input.attr, + &dev_attr_in5_min.attr, + &dev_attr_in5_max.attr, + &dev_attr_in6_input.attr, + &dev_attr_in6_min.attr, + &dev_attr_in6_max.attr, &dev_attr_temp1_input.attr, &dev_attr_temp1_max.attr, &dev_attr_temp1_max_hyst.attr, - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan1_min.dev_attr.attr, - &sensor_dev_attr_fan1_div.dev_attr.attr, - &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan2_min.dev_attr.attr, - &sensor_dev_attr_fan2_div.dev_attr.attr, - &sensor_dev_attr_fan3_input.dev_attr.attr, - &sensor_dev_attr_fan3_min.dev_attr.attr, - &sensor_dev_attr_fan3_div.dev_attr.attr, + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + &dev_attr_fan3_input.attr, + &dev_attr_fan3_min.attr, + &dev_attr_fan3_div.attr, &dev_attr_alarms.attr, &dev_attr_cpu0_vid.attr, @@ -493,17 +524,6 @@ static const struct attribute_group lm78_group = { .attrs = lm78_attributes, }; -/* I2C devices get this name attribute automatically, but for ISA devices - we must create it by ourselves. */ -static ssize_t show_name(struct device *dev, struct device_attribute - *devattr, char *buf) -{ - struct lm78_data *data = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", data->client.name); -} -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - /* This function is called by i2c_probe */ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) { @@ -511,10 +531,54 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) struct i2c_client *new_client; struct lm78_data *data; const char *client_name = ""; + int is_isa = i2c_is_isa_adapter(adapter); - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + if (!is_isa && + !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { err = -ENODEV; - goto ERROR1; + goto ERROR0; + } + + /* Reserve the ISA region */ + if (is_isa) + if (!request_region(address, LM78_EXTENT, + lm78_isa_driver.driver.name)) { + err = -EBUSY; + goto ERROR0; + } + + /* Probe whether there is anything available on this address. Already + done for SMBus clients */ + if (kind < 0) { + if (is_isa) { + +#define REALLY_SLOW_IO + /* We need the timeouts for at least some LM78-like + chips. But only if we read 'undefined' registers. */ + i = inb_p(address + 1); + if (inb_p(address + 2) != i) { + err = -ENODEV; + goto ERROR1; + } + if (inb_p(address + 3) != i) { + err = -ENODEV; + goto ERROR1; + } + if (inb_p(address + 7) != i) { + err = -ENODEV; + goto ERROR1; + } +#undef REALLY_SLOW_IO + + /* Let's just hope nothing breaks here */ + i = inb_p(address + 5) & 0x7f; + outb_p(~i & 0x7f, address + 5); + if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) { + outb_p(i, address + 5); + err = -ENODEV; + goto ERROR1; + } + } } /* OK. For now, we presume we have a valid client. We now create the @@ -527,19 +591,22 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) } new_client = &data->client; + if (is_isa) + mutex_init(&data->lock); i2c_set_clientdata(new_client, data); new_client->addr = address; new_client->adapter = adapter; - new_client->driver = &lm78_driver; + new_client->driver = is_isa ? &lm78_isa_driver : &lm78_driver; + new_client->flags = 0; /* Now, we do the remaining detection. */ if (kind < 0) { - if (lm78_read_value(data, LM78_REG_CONFIG) & 0x80) { + if (lm78_read_value(new_client, LM78_REG_CONFIG) & 0x80) { err = -ENODEV; goto ERROR2; } - if (lm78_read_value(data, LM78_REG_I2C_ADDR) != - address) { + if (!is_isa && (lm78_read_value( + new_client, LM78_REG_I2C_ADDR) != address)) { err = -ENODEV; goto ERROR2; } @@ -547,7 +614,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) /* Determine the chip type. */ if (kind <= 0) { - i = lm78_read_value(data, LM78_REG_CHIPID); + i = lm78_read_value(new_client, LM78_REG_CHIPID); if (i == 0x00 || i == 0x20 /* LM78 */ || i == 0x40) /* LM78-J */ kind = lm78; @@ -574,12 +641,21 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) strlcpy(new_client->name, client_name, I2C_NAME_SIZE); data->type = kind; + data->valid = 0; + mutex_init(&data->update_lock); + /* Tell the I2C layer a new client has arrived */ if ((err = i2c_attach_client(new_client))) goto ERROR2; /* Initialize the LM78 chip */ - lm78_init_device(data); + lm78_init_client(new_client); + + /* A few vars need to be filled upon startup */ + for (i = 0; i < 3; i++) { + data->fan_min[i] = lm78_read_value(new_client, + LM78_REG_FAN_MIN(i)); + } /* Register sysfs hooks */ if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group))) @@ -600,6 +676,9 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind) ERROR2: kfree(data); ERROR1: + if (is_isa) + release_region(address, LM78_EXTENT); +ERROR0: return err; } @@ -614,77 +693,9 @@ static int lm78_detach_client(struct i2c_client *client) if ((err = i2c_detach_client(client))) return err; - kfree(data); - - return 0; -} - -static int __devinit lm78_isa_probe(struct platform_device *pdev) -{ - int err; - struct lm78_data *data; - struct resource *res; - const char *name; - - /* Reserve the ISA region */ - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, LM78_EXTENT, "lm78")) { - err = -EBUSY; - goto exit; - } - - if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit_release_region; - } - mutex_init(&data->lock); - data->client.addr = res->start; - i2c_set_clientdata(&data->client, data); - platform_set_drvdata(pdev, data); - - if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) { - data->type = lm79; - name = "lm79"; - } else { - data->type = lm78; - name = "lm78"; - } - strlcpy(data->client.name, name, I2C_NAME_SIZE); - - /* Initialize the LM78 chip */ - lm78_init_device(data); - - /* Register sysfs hooks */ - if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group)) - || (err = device_create_file(&pdev->dev, &dev_attr_name))) - goto exit_remove_files; - - data->class_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - goto exit_remove_files; - } - - return 0; - - exit_remove_files: - sysfs_remove_group(&pdev->dev.kobj, &lm78_group); - device_remove_file(&pdev->dev, &dev_attr_name); - kfree(data); - exit_release_region: - release_region(res->start, LM78_EXTENT); - exit: - return err; -} - -static int __devexit lm78_isa_remove(struct platform_device *pdev) -{ - struct lm78_data *data = platform_get_drvdata(pdev); + if(i2c_is_isa_client(client)) + release_region(client->addr, LM78_EXTENT); - hwmon_device_unregister(data->class_dev); - sysfs_remove_group(&pdev->dev.kobj, &lm78_group); - device_remove_file(&pdev->dev, &dev_attr_name); - release_region(data->client.addr, LM78_EXTENT); kfree(data); return 0; @@ -695,12 +706,11 @@ static int __devexit lm78_isa_remove(struct platform_device *pdev) separately. We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks, would slow down the LM78 access and should not be necessary. */ -static int lm78_read_value(struct lm78_data *data, u8 reg) +static int lm78_read_value(struct i2c_client *client, u8 reg) { - struct i2c_client *client = &data->client; - - if (!client->driver) { /* ISA device */ - int res; + int res; + if (i2c_is_isa_client(client)) { + struct lm78_data *data = i2c_get_clientdata(client); mutex_lock(&data->lock); outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); res = inb_p(client->addr + LM78_DATA_REG_OFFSET); @@ -717,11 +727,10 @@ static int lm78_read_value(struct lm78_data *data, u8 reg) would slow down the LM78 access and should not be necessary. There are some ugly typecasts here, but the good new is - they should nowhere else be necessary! */ -static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value) +static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value) { - struct i2c_client *client = &data->client; - - if (!client->driver) { /* ISA device */ + if (i2c_is_isa_client(client)) { + struct lm78_data *data = i2c_get_clientdata(client); mutex_lock(&data->lock); outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET); outb_p(value, client->addr + LM78_DATA_REG_OFFSET); @@ -731,29 +740,20 @@ static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -static void lm78_init_device(struct lm78_data *data) +static void lm78_init_client(struct i2c_client *client) { - u8 config; - int i; + u8 config = lm78_read_value(client, LM78_REG_CONFIG); /* Start monitoring */ - config = lm78_read_value(data, LM78_REG_CONFIG); - if ((config & 0x09) != 0x01) - lm78_write_value(data, LM78_REG_CONFIG, + if (!(config & 0x01)) + lm78_write_value(client, LM78_REG_CONFIG, (config & 0xf7) | 0x01); - - /* A few vars need to be filled upon startup */ - for (i = 0; i < 3; i++) { - data->fan_min[i] = lm78_read_value(data, - LM78_REG_FAN_MIN(i)); - } - - mutex_init(&data->update_lock); } static struct lm78_data *lm78_update_device(struct device *dev) { - struct lm78_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct lm78_data *data = i2c_get_clientdata(client); int i; mutex_lock(&data->update_lock); @@ -761,39 +761,39 @@ static struct lm78_data *lm78_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { - dev_dbg(dev, "Starting lm78 update\n"); + dev_dbg(&client->dev, "Starting lm78 update\n"); for (i = 0; i <= 6; i++) { data->in[i] = - lm78_read_value(data, LM78_REG_IN(i)); + lm78_read_value(client, LM78_REG_IN(i)); data->in_min[i] = - lm78_read_value(data, LM78_REG_IN_MIN(i)); + lm78_read_value(client, LM78_REG_IN_MIN(i)); data->in_max[i] = - lm78_read_value(data, LM78_REG_IN_MAX(i)); + lm78_read_value(client, LM78_REG_IN_MAX(i)); } for (i = 0; i < 3; i++) { data->fan[i] = - lm78_read_value(data, LM78_REG_FAN(i)); + lm78_read_value(client, LM78_REG_FAN(i)); data->fan_min[i] = - lm78_read_value(data, LM78_REG_FAN_MIN(i)); + lm78_read_value(client, LM78_REG_FAN_MIN(i)); } - data->temp = lm78_read_value(data, LM78_REG_TEMP); + data->temp = lm78_read_value(client, LM78_REG_TEMP); data->temp_over = - lm78_read_value(data, LM78_REG_TEMP_OVER); + lm78_read_value(client, LM78_REG_TEMP_OVER); data->temp_hyst = - lm78_read_value(data, LM78_REG_TEMP_HYST); - i = lm78_read_value(data, LM78_REG_VID_FANDIV); + lm78_read_value(client, LM78_REG_TEMP_HYST); + i = lm78_read_value(client, LM78_REG_VID_FANDIV); data->vid = i & 0x0f; if (data->type == lm79) data->vid |= - (lm78_read_value(data, LM78_REG_CHIPID) & + (lm78_read_value(client, LM78_REG_CHIPID) & 0x01) << 4; else data->vid |= 0x10; data->fan_div[0] = (i >> 4) & 0x03; data->fan_div[1] = i >> 6; - data->alarms = lm78_read_value(data, LM78_REG_ALARM1) + - (lm78_read_value(data, LM78_REG_ALARM2) << 8); + data->alarms = lm78_read_value(client, LM78_REG_ALARM1) + + (lm78_read_value(client, LM78_REG_ALARM2) << 8); data->last_updated = jiffies; data->valid = 1; @@ -805,154 +805,26 @@ static struct lm78_data *lm78_update_device(struct device *dev) return data; } -/* return 1 if a supported chip is found, 0 otherwise */ -static int __init lm78_isa_found(unsigned short address) -{ - int val, save, found = 0; - - if (!request_region(address, LM78_EXTENT, "lm78")) - return 0; - -#define REALLY_SLOW_IO - /* We need the timeouts for at least some LM78-like - chips. But only if we read 'undefined' registers. */ - val = inb_p(address + 1); - if (inb_p(address + 2) != val - || inb_p(address + 3) != val - || inb_p(address + 7) != val) - goto release; -#undef REALLY_SLOW_IO - - /* We should be able to change the 7 LSB of the address port. The - MSB (busy flag) should be clear initially, set after the write. */ - save = inb_p(address + LM78_ADDR_REG_OFFSET); - if (save & 0x80) - goto release; - val = ~save & 0x7f; - outb_p(val, address + LM78_ADDR_REG_OFFSET); - if (inb_p(address + LM78_ADDR_REG_OFFSET) != (val | 0x80)) { - outb_p(save, address + LM78_ADDR_REG_OFFSET); - goto release; - } - - /* We found a device, now see if it could be an LM78 */ - outb_p(LM78_REG_CONFIG, address + LM78_ADDR_REG_OFFSET); - val = inb_p(address + LM78_DATA_REG_OFFSET); - if (val & 0x80) - goto release; - outb_p(LM78_REG_I2C_ADDR, address + LM78_ADDR_REG_OFFSET); - val = inb_p(address + LM78_DATA_REG_OFFSET); - if (val < 0x03 || val > 0x77) /* Not a valid I2C address */ - goto release; - - /* The busy flag should be clear again */ - if (inb_p(address + LM78_ADDR_REG_OFFSET) & 0x80) - goto release; - - /* Explicitly prevent the misdetection of Winbond chips */ - outb_p(0x4f, address + LM78_ADDR_REG_OFFSET); - val = inb_p(address + LM78_DATA_REG_OFFSET); - if (val == 0xa3 || val == 0x5c) - goto release; - - /* Explicitly prevent the misdetection of ITE chips */ - outb_p(0x58, address + LM78_ADDR_REG_OFFSET); - val = inb_p(address + LM78_DATA_REG_OFFSET); - if (val == 0x90) - goto release; - - /* Determine the chip type */ - outb_p(LM78_REG_CHIPID, address + LM78_ADDR_REG_OFFSET); - val = inb_p(address + LM78_DATA_REG_OFFSET); - if (val == 0x00 /* LM78 */ - || val == 0x40 /* LM78-J */ - || (val & 0xfe) == 0xc0) /* LM79 */ - found = 1; - - if (found) - pr_info("lm78: Found an %s chip at %#x\n", - val & 0x80 ? "LM79" : "LM78", (int)address); - - release: - release_region(address, LM78_EXTENT); - return found; -} - -static int __init lm78_isa_device_add(unsigned short address) -{ - struct resource res = { - .start = address, - .end = address + LM78_EXTENT, - .name = "lm78", - .flags = IORESOURCE_IO, - }; - int err; - - pdev = platform_device_alloc("lm78", address); - if (!pdev) { - err = -ENOMEM; - printk(KERN_ERR "lm78: Device allocation failed\n"); - goto exit; - } - - err = platform_device_add_resources(pdev, &res, 1); - if (err) { - printk(KERN_ERR "lm78: Device resource addition failed " - "(%d)\n", err); - goto exit_device_put; - } - - err = platform_device_add(pdev); - if (err) { - printk(KERN_ERR "lm78: Device addition failed (%d)\n", - err); - goto exit_device_put; - } - - return 0; - - exit_device_put: - platform_device_put(pdev); - exit: - pdev = NULL; - return err; -} - static int __init sm_lm78_init(void) { int res; res = i2c_add_driver(&lm78_driver); if (res) - goto exit; - - if (lm78_isa_found(isa_address)) { - res = platform_driver_register(&lm78_isa_driver); - if (res) - goto exit_unreg_i2c_driver; + return res; - /* Sets global pdev as a side effect */ - res = lm78_isa_device_add(isa_address); - if (res) - goto exit_unreg_isa_driver; - } + /* Don't exit if this one fails, we still want the I2C variants + to work! */ + if (i2c_isa_add_driver(&lm78_isa_driver)) + isa_address = 0; return 0; - - exit_unreg_isa_driver: - platform_driver_unregister(&lm78_isa_driver); - exit_unreg_i2c_driver: - i2c_del_driver(&lm78_driver); - exit: - return res; } static void __exit sm_lm78_exit(void) { - if (pdev) { - platform_device_unregister(pdev); - platform_driver_unregister(&lm78_isa_driver); - } + if (isa_address) + i2c_isa_del_driver(&lm78_isa_driver); i2c_del_driver(&lm78_driver); } diff --git a/trunk/drivers/hwmon/lm87.c b/trunk/drivers/hwmon/lm87.c index 988ae1c4aada..3ce825489e34 100644 --- a/trunk/drivers/hwmon/lm87.c +++ b/trunk/drivers/hwmon/lm87.c @@ -747,7 +747,6 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind) } if (!(data->channel & CHAN_NO_VID)) { - data->vrm = vid_which_vrm(); if ((err = device_create_file(&new_client->dev, &dev_attr_cpu0_vid)) || (err = device_create_file(&new_client->dev, @@ -780,6 +779,7 @@ static void lm87_init_client(struct i2c_client *client) u8 config; data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE); + data->vrm = vid_which_vrm(); config = lm87_read_value(client, LM87_REG_CONFIG); if (!(config & 0x01)) { diff --git a/trunk/drivers/hwmon/max6650.c b/trunk/drivers/hwmon/max6650.c deleted file mode 100644 index 8415664f33c2..000000000000 --- a/trunk/drivers/hwmon/max6650.c +++ /dev/null @@ -1,693 +0,0 @@ -/* - * max6650.c - Part of lm_sensors, Linux kernel modules for hardware - * monitoring. - * - * (C) 2007 by Hans J. Koch - * - * based on code written by John Morris - * Copyright (c) 2003 Spirent Communications - * and Claus Gindhart - * - * This module has only been tested with the MAX6650 chip. It should - * also work with the MAX6651. It does not distinguish max6650 and max6651 - * chips. - * - * Tha datasheet was last seen at: - * - * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Addresses to scan. There are four disjoint possibilities, by pin config. - */ - -static unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b, I2C_CLIENT_END}; - -/* - * Insmod parameters - */ - -/* fan_voltage: 5=5V fan, 12=12V fan, 0=don't change */ -static int fan_voltage; -/* prescaler: Possible values are 1, 2, 4, 8, 16 or 0 for don't change */ -static int prescaler; -/* clock: The clock frequency of the chip the driver should assume */ -static int clock = 254000; - -module_param(fan_voltage, int, S_IRUGO); -module_param(prescaler, int, S_IRUGO); -module_param(clock, int, S_IRUGO); - -I2C_CLIENT_INSMOD_1(max6650); - -/* - * MAX 6650/6651 registers - */ - -#define MAX6650_REG_SPEED 0x00 -#define MAX6650_REG_CONFIG 0x02 -#define MAX6650_REG_GPIO_DEF 0x04 -#define MAX6650_REG_DAC 0x06 -#define MAX6650_REG_ALARM_EN 0x08 -#define MAX6650_REG_ALARM 0x0A -#define MAX6650_REG_TACH0 0x0C -#define MAX6650_REG_TACH1 0x0E -#define MAX6650_REG_TACH2 0x10 -#define MAX6650_REG_TACH3 0x12 -#define MAX6650_REG_GPIO_STAT 0x14 -#define MAX6650_REG_COUNT 0x16 - -/* - * Config register bits - */ - -#define MAX6650_CFG_V12 0x08 -#define MAX6650_CFG_PRESCALER_MASK 0x07 -#define MAX6650_CFG_PRESCALER_2 0x01 -#define MAX6650_CFG_PRESCALER_4 0x02 -#define MAX6650_CFG_PRESCALER_8 0x03 -#define MAX6650_CFG_PRESCALER_16 0x04 -#define MAX6650_CFG_MODE_MASK 0x30 -#define MAX6650_CFG_MODE_ON 0x00 -#define MAX6650_CFG_MODE_OFF 0x10 -#define MAX6650_CFG_MODE_CLOSED_LOOP 0x20 -#define MAX6650_CFG_MODE_OPEN_LOOP 0x30 -#define MAX6650_COUNT_MASK 0x03 - -/* Minimum and maximum values of the FAN-RPM */ -#define FAN_RPM_MIN 240 -#define FAN_RPM_MAX 30000 - -#define DIV_FROM_REG(reg) (1 << (reg & 7)) - -static int max6650_attach_adapter(struct i2c_adapter *adapter); -static int max6650_detect(struct i2c_adapter *adapter, int address, int kind); -static int max6650_init_client(struct i2c_client *client); -static int max6650_detach_client(struct i2c_client *client); -static struct max6650_data *max6650_update_device(struct device *dev); - -/* - * Driver data (common to all clients) - */ - -static struct i2c_driver max6650_driver = { - .driver = { - .name = "max6650", - }, - .attach_adapter = max6650_attach_adapter, - .detach_client = max6650_detach_client, -}; - -/* - * Client data (each client gets its own) - */ - -struct max6650_data -{ - struct i2c_client client; - struct class_device *class_dev; - struct mutex update_lock; - char valid; /* zero until following fields are valid */ - unsigned long last_updated; /* in jiffies */ - - /* register values */ - u8 speed; - u8 config; - u8 tach[4]; - u8 count; - u8 dac; -}; - -static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct max6650_data *data = max6650_update_device(dev); - int rpm; - - /* - * Calculation details: - * - * Each tachometer counts over an interval given by the "count" - * register (0.25, 0.5, 1 or 2 seconds). This module assumes - * that the fans produce two pulses per revolution (this seems - * to be the most common). - */ - - rpm = ((data->tach[attr->index] * 120) / DIV_FROM_REG(data->count)); - return sprintf(buf, "%d\n", rpm); -} - -/* - * Set the fan speed to the specified RPM (or read back the RPM setting). - * This works in closed loop mode only. Use pwm1 for open loop speed setting. - * - * The MAX6650/1 will automatically control fan speed when in closed loop - * mode. - * - * Assumptions: - * - * 1) The MAX6650/1 internal 254kHz clock frequency is set correctly. Use - * the clock module parameter if you need to fine tune this. - * - * 2) The prescaler (low three bits of the config register) has already - * been set to an appropriate value. Use the prescaler module parameter - * if your BIOS doesn't initialize the chip properly. - * - * The relevant equations are given on pages 21 and 22 of the datasheet. - * - * From the datasheet, the relevant equation when in regulation is: - * - * [fCLK / (128 x (KTACH + 1))] = 2 x FanSpeed / KSCALE - * - * where: - * - * fCLK is the oscillator frequency (either the 254kHz internal - * oscillator or the externally applied clock) - * - * KTACH is the value in the speed register - * - * FanSpeed is the speed of the fan in rps - * - * KSCALE is the prescaler value (1, 2, 4, 8, or 16) - * - * When reading, we need to solve for FanSpeed. When writing, we need to - * solve for KTACH. - * - * Note: this tachometer is completely separate from the tachometers - * used to measure the fan speeds. Only one fan's speed (fan1) is - * controlled. - */ - -static ssize_t get_target(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct max6650_data *data = max6650_update_device(dev); - int kscale, ktach, rpm; - - /* - * Use the datasheet equation: - * - * FanSpeed = KSCALE x fCLK / [256 x (KTACH + 1)] - * - * then multiply by 60 to give rpm. - */ - - kscale = DIV_FROM_REG(data->config); - ktach = data->speed; - rpm = 60 * kscale * clock / (256 * (ktach + 1)); - return sprintf(buf, "%d\n", rpm); -} - -static ssize_t set_target(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct max6650_data *data = i2c_get_clientdata(client); - int rpm = simple_strtoul(buf, NULL, 10); - int kscale, ktach; - - rpm = SENSORS_LIMIT(rpm, FAN_RPM_MIN, FAN_RPM_MAX); - - /* - * Divide the required speed by 60 to get from rpm to rps, then - * use the datasheet equation: - * - * KTACH = [(fCLK x KSCALE) / (256 x FanSpeed)] - 1 - */ - - mutex_lock(&data->update_lock); - - kscale = DIV_FROM_REG(data->config); - ktach = ((clock * kscale) / (256 * rpm / 60)) - 1; - if (ktach < 0) - ktach = 0; - if (ktach > 255) - ktach = 255; - data->speed = ktach; - - i2c_smbus_write_byte_data(client, MAX6650_REG_SPEED, data->speed); - - mutex_unlock(&data->update_lock); - - return count; -} - -/* - * Get/set the fan speed in open loop mode using pwm1 sysfs file. - * Speed is given as a relative value from 0 to 255, where 255 is maximum - * speed. Note that this is done by writing directly to the chip's DAC, - * it won't change the closed loop speed set by fan1_target. - * Also note that due to rounding errors it is possible that you don't read - * back exactly the value you have set. - */ - -static ssize_t get_pwm(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - int pwm; - struct max6650_data *data = max6650_update_device(dev); - - /* Useful range for dac is 0-180 for 12V fans and 0-76 for 5V fans. - Lower DAC values mean higher speeds. */ - if (data->config & MAX6650_CFG_V12) - pwm = 255 - (255 * (int)data->dac)/180; - else - pwm = 255 - (255 * (int)data->dac)/76; - - if (pwm < 0) - pwm = 0; - - return sprintf(buf, "%d\n", pwm); -} - -static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct max6650_data *data = i2c_get_clientdata(client); - int pwm = simple_strtoul(buf, NULL, 10); - - pwm = SENSORS_LIMIT(pwm, 0, 255); - - mutex_lock(&data->update_lock); - - if (data->config & MAX6650_CFG_V12) - data->dac = 180 - (180 * pwm)/255; - else - data->dac = 76 - (76 * pwm)/255; - - i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, data->dac); - - mutex_unlock(&data->update_lock); - - return count; -} - -/* - * Get/Set controller mode: - * Possible values: - * 0 = Fan always on - * 1 = Open loop, Voltage is set according to speed, not regulated. - * 2 = Closed loop, RPM for all fans regulated by fan1 tachometer - */ - -static ssize_t get_enable(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct max6650_data *data = max6650_update_device(dev); - int mode = (data->config & MAX6650_CFG_MODE_MASK) >> 4; - int sysfs_modes[4] = {0, 1, 2, 1}; - - return sprintf(buf, "%d\n", sysfs_modes[mode]); -} - -static ssize_t set_enable(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct max6650_data *data = i2c_get_clientdata(client); - int mode = simple_strtoul(buf, NULL, 10); - int max6650_modes[3] = {0, 3, 2}; - - if ((mode < 0)||(mode > 2)) { - dev_err(&client->dev, - "illegal value for pwm1_enable (%d)\n", mode); - return -EINVAL; - } - - mutex_lock(&data->update_lock); - - data->config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); - data->config = (data->config & ~MAX6650_CFG_MODE_MASK) - | (max6650_modes[mode] << 4); - - i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, data->config); - - mutex_unlock(&data->update_lock); - - return count; -} - -/* - * Read/write functions for fan1_div sysfs file. The MAX6650 has no such - * divider. We handle this by converting between divider and counttime: - * - * (counttime == k) <==> (divider == 2^k), k = 0, 1, 2, or 3 - * - * Lower values of k allow to connect a faster fan without the risk of - * counter overflow. The price is lower resolution. You can also set counttime - * using the module parameter. Note that the module parameter "prescaler" also - * influences the behaviour. Unfortunately, there's no sysfs attribute - * defined for that. See the data sheet for details. - */ - -static ssize_t get_div(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct max6650_data *data = max6650_update_device(dev); - - return sprintf(buf, "%d\n", DIV_FROM_REG(data->count)); -} - -static ssize_t set_div(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - struct i2c_client *client = to_i2c_client(dev); - struct max6650_data *data = i2c_get_clientdata(client); - int div = simple_strtoul(buf, NULL, 10); - - mutex_lock(&data->update_lock); - switch (div) { - case 1: - data->count = 0; - break; - case 2: - data->count = 1; - break; - case 4: - data->count = 2; - break; - case 8: - data->count = 3; - break; - default: - dev_err(&client->dev, - "illegal value for fan divider (%d)\n", div); - return -EINVAL; - } - - i2c_smbus_write_byte_data(client, MAX6650_REG_COUNT, data->count); - mutex_unlock(&data->update_lock); - - return count; -} - -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); -static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); -static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); -static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, get_fan, NULL, 3); -static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target); -static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div); -static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable); -static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); - - -static struct attribute *max6650_attrs[] = { - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan3_input.dev_attr.attr, - &sensor_dev_attr_fan4_input.dev_attr.attr, - &dev_attr_fan1_target.attr, - &dev_attr_fan1_div.attr, - &dev_attr_pwm1_enable.attr, - &dev_attr_pwm1.attr, - NULL -}; - -static struct attribute_group max6650_attr_grp = { - .attrs = max6650_attrs, -}; - -/* - * Real code - */ - -static int max6650_attach_adapter(struct i2c_adapter *adapter) -{ - if (!(adapter->class & I2C_CLASS_HWMON)) { - dev_dbg(&adapter->dev, - "FATAL: max6650_attach_adapter class HWMON not set\n"); - return 0; - } - - return i2c_probe(adapter, &addr_data, max6650_detect); -} - -/* - * The following function does more than just detection. If detection - * succeeds, it also registers the new chip. - */ - -static int max6650_detect(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct max6650_data *data; - int err = -ENODEV; - - dev_dbg(&adapter->dev, "max6650_detect called, kind = %d\n", kind); - - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { - dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support " - "byte read mode, skipping.\n"); - return 0; - } - - if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) { - dev_err(&adapter->dev, "max6650: out of memory.\n"); - return -ENOMEM; - } - - client = &data->client; - i2c_set_clientdata(client, data); - client->addr = address; - client->adapter = adapter; - client->driver = &max6650_driver; - - /* - * Now we do the remaining detection. A negative kind means that - * the driver was loaded with no force parameter (default), so we - * must both detect and identify the chip (actually there is only - * one possible kind of chip for now, max6650). A zero kind means that - * the driver was loaded with the force parameter, the detection - * step shall be skipped. A positive kind means that the driver - * was loaded with the force parameter and a given kind of chip is - * requested, so both the detection and the identification steps - * are skipped. - * - * Currently I can find no way to distinguish between a MAX6650 and - * a MAX6651. This driver has only been tried on the former. - */ - - if ((kind < 0) && - ( (i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0) - ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0) - ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0) - ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0) - ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) { - dev_dbg(&adapter->dev, - "max6650: detection failed at 0x%02x.\n", address); - goto err_free; - } - - dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address); - - strlcpy(client->name, "max6650", I2C_NAME_SIZE); - mutex_init(&data->update_lock); - - if ((err = i2c_attach_client(client))) { - dev_err(&adapter->dev, "max6650: failed to attach client.\n"); - goto err_free; - } - - /* - * Initialize the max6650 chip - */ - if (max6650_init_client(client)) - goto err_detach; - - err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp); - if (err) - goto err_detach; - - data->class_dev = hwmon_device_register(&client->dev); - if (!IS_ERR(data->class_dev)) - return 0; - - err = PTR_ERR(data->class_dev); - dev_err(&client->dev, "error registering hwmon device.\n"); - sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); -err_detach: - i2c_detach_client(client); -err_free: - kfree(data); - return err; -} - -static int max6650_detach_client(struct i2c_client *client) -{ - struct max6650_data *data = i2c_get_clientdata(client); - int err; - - sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp); - hwmon_device_unregister(data->class_dev); - err = i2c_detach_client(client); - if (!err) - kfree(data); - return err; -} - -static int max6650_init_client(struct i2c_client *client) -{ - struct max6650_data *data = i2c_get_clientdata(client); - int config; - int err = -EIO; - - config = i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG); - - if (config < 0) { - dev_err(&client->dev, "Error reading config, aborting.\n"); - return err; - } - - switch (fan_voltage) { - case 0: - break; - case 5: - config &= ~MAX6650_CFG_V12; - break; - case 12: - config |= MAX6650_CFG_V12; - break; - default: - dev_err(&client->dev, - "illegal value for fan_voltage (%d)\n", - fan_voltage); - } - - dev_info(&client->dev, "Fan voltage is set to %dV.\n", - (config & MAX6650_CFG_V12) ? 12 : 5); - - switch (prescaler) { - case 0: - break; - case 1: - config &= ~MAX6650_CFG_PRESCALER_MASK; - break; - case 2: - config = (config & ~MAX6650_CFG_PRESCALER_MASK) - | MAX6650_CFG_PRESCALER_2; - break; - case 4: - config = (config & ~MAX6650_CFG_PRESCALER_MASK) - | MAX6650_CFG_PRESCALER_4; - break; - case 8: - config = (config & ~MAX6650_CFG_PRESCALER_MASK) - | MAX6650_CFG_PRESCALER_8; - break; - case 16: - config = (config & ~MAX6650_CFG_PRESCALER_MASK) - | MAX6650_CFG_PRESCALER_16; - break; - default: - dev_err(&client->dev, - "illegal value for prescaler (%d)\n", - prescaler); - } - - dev_info(&client->dev, "Prescaler is set to %d.\n", - 1 << (config & MAX6650_CFG_PRESCALER_MASK)); - - /* If mode is set to "full off", we change it to "open loop" and - * set DAC to 255, which has the same effect. We do this because - * there's no "full off" mode defined in hwmon specifcations. - */ - - if ((config & MAX6650_CFG_MODE_MASK) == MAX6650_CFG_MODE_OFF) { - dev_dbg(&client->dev, "Change mode to open loop, full off.\n"); - config = (config & ~MAX6650_CFG_MODE_MASK) - | MAX6650_CFG_MODE_OPEN_LOOP; - if (i2c_smbus_write_byte_data(client, MAX6650_REG_DAC, 255)) { - dev_err(&client->dev, "DAC write error, aborting.\n"); - return err; - } - } - - if (i2c_smbus_write_byte_data(client, MAX6650_REG_CONFIG, config)) { - dev_err(&client->dev, "Config write error, aborting.\n"); - return err; - } - - data->config = config; - data->count = i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT); - - return 0; -} - -static const u8 tach_reg[] = { - MAX6650_REG_TACH0, - MAX6650_REG_TACH1, - MAX6650_REG_TACH2, - MAX6650_REG_TACH3, -}; - -static struct max6650_data *max6650_update_device(struct device *dev) -{ - int i; - struct i2c_client *client = to_i2c_client(dev); - struct max6650_data *data = i2c_get_clientdata(client); - - mutex_lock(&data->update_lock); - - if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { - data->speed = i2c_smbus_read_byte_data(client, - MAX6650_REG_SPEED); - data->config = i2c_smbus_read_byte_data(client, - MAX6650_REG_CONFIG); - for (i = 0; i < 4; i++) { - data->tach[i] = i2c_smbus_read_byte_data(client, - tach_reg[i]); - } - data->count = i2c_smbus_read_byte_data(client, - MAX6650_REG_COUNT); - data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); - - data->last_updated = jiffies; - data->valid = 1; - } - - mutex_unlock(&data->update_lock); - - return data; -} - -static int __init sensors_max6650_init(void) -{ - return i2c_add_driver(&max6650_driver); -} - -static void __exit sensors_max6650_exit(void) -{ - i2c_del_driver(&max6650_driver); -} - -MODULE_AUTHOR("Hans J. Koch"); -MODULE_DESCRIPTION("MAX6650 sensor driver"); -MODULE_LICENSE("GPL"); - -module_init(sensors_max6650_init); -module_exit(sensors_max6650_exit); diff --git a/trunk/drivers/hwmon/pc87427.c b/trunk/drivers/hwmon/pc87427.c index 29354fa26f81..affa21a5ccfd 100644 --- a/trunk/drivers/hwmon/pc87427.c +++ b/trunk/drivers/hwmon/pc87427.c @@ -31,7 +31,6 @@ #include #include #include -#include #include static struct platform_device *pdev; @@ -430,12 +429,6 @@ static int __devinit pc87427_probe(struct platform_device *pdev) /* This will need to be revisited when we add support for temperature and voltage monitoring. */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) { - err = -EBUSY; - dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n", - (unsigned long)res->start, (unsigned long)res->end); - goto exit_kfree; - } data->address[0] = res->start; mutex_init(&data->lock); @@ -445,7 +438,7 @@ static int __devinit pc87427_probe(struct platform_device *pdev) /* Register sysfs hooks */ if ((err = device_create_file(&pdev->dev, &dev_attr_name))) - goto exit_release_region; + goto exit_kfree; for (i = 0; i < 8; i++) { if (!(data->fan_enabled & (1 << i))) continue; @@ -469,8 +462,6 @@ static int __devinit pc87427_probe(struct platform_device *pdev) continue; sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]); } -exit_release_region: - release_region(res->start, res->end - res->start + 1); exit_kfree: platform_set_drvdata(pdev, NULL); kfree(data); @@ -481,7 +472,6 @@ static int __devinit pc87427_probe(struct platform_device *pdev) static int __devexit pc87427_remove(struct platform_device *pdev) { struct pc87427_data *data = platform_get_drvdata(pdev); - struct resource *res; int i; platform_set_drvdata(pdev, NULL); @@ -494,9 +484,6 @@ static int __devexit pc87427_remove(struct platform_device *pdev) } kfree(data); - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, res->end - res->start + 1); - return 0; } diff --git a/trunk/drivers/hwmon/smsc47b397.c b/trunk/drivers/hwmon/smsc47b397.c index 943abbd95ab5..72b0e2d8650c 100644 --- a/trunk/drivers/hwmon/smsc47b397.c +++ b/trunk/drivers/hwmon/smsc47b397.c @@ -30,17 +30,16 @@ #include #include #include -#include +#include +#include #include -#include #include #include #include #include -static struct platform_device *pdev; - -#define DRVNAME "smsc47b397" +/* Address is autodetected, there is no default value */ +static unsigned short address; /* Super-I/0 registers and commands */ @@ -92,8 +91,7 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80}; #define SMSC47B397_REG_FAN_MSB(nr) (0x29 + 2 * (nr)) struct smsc47b397_data { - unsigned short addr; - const char *name; + struct i2c_client client; struct class_device *class_dev; struct mutex lock; @@ -106,43 +104,45 @@ struct smsc47b397_data { u8 temp[4]; }; -static int smsc47b397_read_value(struct smsc47b397_data* data, u8 reg) +static int smsc47b397_read_value(struct i2c_client *client, u8 reg) { + struct smsc47b397_data *data = i2c_get_clientdata(client); int res; mutex_lock(&data->lock); - outb(reg, data->addr); - res = inb_p(data->addr + 1); + outb(reg, client->addr); + res = inb_p(client->addr + 1); mutex_unlock(&data->lock); return res; } static struct smsc47b397_data *smsc47b397_update_device(struct device *dev) { - struct smsc47b397_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct smsc47b397_data *data = i2c_get_clientdata(client); int i; mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { - dev_dbg(dev, "starting device update...\n"); + dev_dbg(&client->dev, "starting device update...\n"); /* 4 temperature inputs, 4 fan inputs */ for (i = 0; i < 4; i++) { - data->temp[i] = smsc47b397_read_value(data, + data->temp[i] = smsc47b397_read_value(client, SMSC47B397_REG_TEMP(i)); /* must read LSB first */ - data->fan[i] = smsc47b397_read_value(data, + data->fan[i] = smsc47b397_read_value(client, SMSC47B397_REG_FAN_LSB(i)); - data->fan[i] |= smsc47b397_read_value(data, + data->fan[i] |= smsc47b397_read_value(client, SMSC47B397_REG_FAN_MSB(i)) << 8; } data->last_updated = jiffies; data->valid = 1; - dev_dbg(dev, "... device update complete\n"); + dev_dbg(&client->dev, "... device update complete\n"); } mutex_unlock(&data->update_lock); @@ -157,18 +157,24 @@ static int temp_from_reg(u8 reg) return (s8)reg * 1000; } -static ssize_t show_temp(struct device *dev, struct device_attribute - *devattr, char *buf) +/* 0 <= nr <= 3 */ +static ssize_t show_temp(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47b397_data *data = smsc47b397_update_device(dev); - return sprintf(buf, "%d\n", temp_from_reg(data->temp[attr->index])); + return sprintf(buf, "%d\n", temp_from_reg(data->temp[nr])); } -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); -static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); -static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); -static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); +#define sysfs_temp(num) \ +static ssize_t show_temp##num(struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_temp(dev, buf, num-1); \ +} \ +static DEVICE_ATTR(temp##num##_input, S_IRUGO, show_temp##num, NULL) + +sysfs_temp(1); +sysfs_temp(2); +sysfs_temp(3); +sysfs_temp(4); /* FAN: 1 RPM/bit REG: count of 90kHz pulses / revolution */ @@ -177,37 +183,35 @@ static int fan_from_reg(u16 reg) return 90000 * 60 / reg; } -static ssize_t show_fan(struct device *dev, struct device_attribute - *devattr, char *buf) +/* 0 <= nr <= 3 */ +static ssize_t show_fan(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct smsc47b397_data *data = smsc47b397_update_device(dev); - return sprintf(buf, "%d\n", fan_from_reg(data->fan[attr->index])); + struct smsc47b397_data *data = smsc47b397_update_device(dev); + return sprintf(buf, "%d\n", fan_from_reg(data->fan[nr])); } -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); -static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); -static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); -static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); -static ssize_t show_name(struct device *dev, struct device_attribute - *devattr, char *buf) -{ - struct smsc47b397_data *data = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", data->name); -} -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); +#define sysfs_fan(num) \ +static ssize_t show_fan##num(struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_fan(dev, buf, num-1); \ +} \ +static DEVICE_ATTR(fan##num##_input, S_IRUGO, show_fan##num, NULL) + +sysfs_fan(1); +sysfs_fan(2); +sysfs_fan(3); +sysfs_fan(4); static struct attribute *smsc47b397_attributes[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_temp2_input.dev_attr.attr, - &sensor_dev_attr_temp3_input.dev_attr.attr, - &sensor_dev_attr_temp4_input.dev_attr.attr, - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan3_input.dev_attr.attr, - &sensor_dev_attr_fan4_input.dev_attr.attr, - - &dev_attr_name.attr, + &dev_attr_temp1_input.attr, + &dev_attr_temp2_input.attr, + &dev_attr_temp3_input.attr, + &dev_attr_temp4_input.attr, + &dev_attr_fan1_input.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan3_input.attr, + &dev_attr_fan4_input.attr, + NULL }; @@ -215,44 +219,44 @@ static const struct attribute_group smsc47b397_group = { .attrs = smsc47b397_attributes, }; -static int __devexit smsc47b397_remove(struct platform_device *pdev) +static int smsc47b397_detach_client(struct i2c_client *client) { - struct smsc47b397_data *data = platform_get_drvdata(pdev); - struct resource *res; + struct smsc47b397_data *data = i2c_get_clientdata(client); + int err; hwmon_device_unregister(data->class_dev); - sysfs_remove_group(&pdev->dev.kobj, &smsc47b397_group); - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, SMSC_EXTENT); + sysfs_remove_group(&client->dev.kobj, &smsc47b397_group); + + if ((err = i2c_detach_client(client))) + return err; + + release_region(client->addr, SMSC_EXTENT); kfree(data); return 0; } -static int smsc47b397_probe(struct platform_device *pdev); +static int smsc47b397_detect(struct i2c_adapter *adapter); -static struct platform_driver smsc47b397_driver = { +static struct i2c_driver smsc47b397_driver = { .driver = { .owner = THIS_MODULE, - .name = DRVNAME, + .name = "smsc47b397", }, - .probe = smsc47b397_probe, - .remove = __devexit_p(smsc47b397_remove), + .attach_adapter = smsc47b397_detect, + .detach_client = smsc47b397_detach_client, }; -static int __devinit smsc47b397_probe(struct platform_device *pdev) +static int smsc47b397_detect(struct i2c_adapter *adapter) { - struct device *dev = &pdev->dev; + struct i2c_client *new_client; struct smsc47b397_data *data; - struct resource *res; int err = 0; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, SMSC_EXTENT, + if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.driver.name)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - (unsigned long)res->start, - (unsigned long)res->start + SMSC_EXTENT - 1); + dev_err(&adapter->dev, "Region 0x%x already in use!\n", + address); return -EBUSY; } @@ -261,16 +265,25 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) goto error_release; } - data->addr = res->start; - data->name = "smsc47b397"; + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; mutex_init(&data->lock); + new_client->adapter = adapter; + new_client->driver = &smsc47b397_driver; + new_client->flags = 0; + + strlcpy(new_client->name, "smsc47b397", I2C_NAME_SIZE); + mutex_init(&data->update_lock); - platform_set_drvdata(pdev, data); - if ((err = sysfs_create_group(&dev->kobj, &smsc47b397_group))) + if ((err = i2c_attach_client(new_client))) goto error_free; - data->class_dev = hwmon_device_register(dev); + if ((err = sysfs_create_group(&new_client->dev.kobj, &smsc47b397_group))) + goto error_detach; + + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); goto error_remove; @@ -279,50 +292,13 @@ static int __devinit smsc47b397_probe(struct platform_device *pdev) return 0; error_remove: - sysfs_remove_group(&dev->kobj, &smsc47b397_group); + sysfs_remove_group(&new_client->dev.kobj, &smsc47b397_group); +error_detach: + i2c_detach_client(new_client); error_free: kfree(data); error_release: - release_region(res->start, SMSC_EXTENT); - return err; -} - -static int __init smsc47b397_device_add(unsigned short address) -{ - struct resource res = { - .start = address, - .end = address + SMSC_EXTENT - 1, - .name = DRVNAME, - .flags = IORESOURCE_IO, - }; - int err; - - pdev = platform_device_alloc(DRVNAME, address); - if (!pdev) { - err = -ENOMEM; - printk(KERN_ERR DRVNAME ": Device allocation failed\n"); - goto exit; - } - - err = platform_device_add_resources(pdev, &res, 1); - if (err) { - printk(KERN_ERR DRVNAME ": Device resource addition failed " - "(%d)\n", err); - goto exit_device_put; - } - - err = platform_device_add(pdev); - if (err) { - printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", - err); - goto exit_device_put; - } - - return 0; - -exit_device_put: - platform_device_put(pdev); -exit: + release_region(address, SMSC_EXTENT); return err; } @@ -344,7 +320,7 @@ static int __init smsc47b397_find(unsigned short *addr) *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); - printk(KERN_INFO DRVNAME ": found SMSC %s " + printk(KERN_INFO "smsc47b397: found SMSC %s " "(base address 0x%04x, revision %u)\n", id == 0x81 ? "SCH5307-NS" : "LPC47B397-NC", *addr, rev); @@ -354,33 +330,17 @@ static int __init smsc47b397_find(unsigned short *addr) static int __init smsc47b397_init(void) { - unsigned short address; int ret; if ((ret = smsc47b397_find(&address))) return ret; - ret = platform_driver_register(&smsc47b397_driver); - if (ret) - goto exit; - - /* Sets global pdev as a side effect */ - ret = smsc47b397_device_add(address); - if (ret) - goto exit_driver; - - return 0; - -exit_driver: - platform_driver_unregister(&smsc47b397_driver); -exit: - return ret; + return i2c_isa_add_driver(&smsc47b397_driver); } static void __exit smsc47b397_exit(void) { - platform_device_unregister(pdev); - platform_driver_unregister(&smsc47b397_driver); + i2c_isa_del_driver(&smsc47b397_driver); } MODULE_AUTHOR("Mark M. Hoffman "); diff --git a/trunk/drivers/hwmon/smsc47m1.c b/trunk/drivers/hwmon/smsc47m1.c index 1e21c8cc948f..beb881c4b2e8 100644 --- a/trunk/drivers/hwmon/smsc47m1.c +++ b/trunk/drivers/hwmon/smsc47m1.c @@ -3,11 +3,10 @@ for hardware monitoring Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x, - LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997 - Super-I/O chips. + LPC47M14x, LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips. Copyright (C) 2002 Mark D. Studebaker - Copyright (C) 2004-2007 Jean Delvare + Copyright (C) 2004 Jean Delvare Ported to Linux 2.6 by Gabriele Gorla and Jean Delvare @@ -30,19 +29,17 @@ #include #include #include -#include +#include +#include #include -#include #include #include #include #include #include -static struct platform_device *pdev; - -#define DRVNAME "smsc47m1" -enum chips { smsc47m1, smsc47m2 }; +/* Address is autodetected, there is no default value */ +static unsigned short address; /* Super-I/0 registers and commands */ @@ -90,18 +87,10 @@ superio_exit(void) #define SMSC47M1_REG_ALARM 0x04 #define SMSC47M1_REG_TPIN(nr) (0x34 - (nr)) #define SMSC47M1_REG_PPIN(nr) (0x36 - (nr)) +#define SMSC47M1_REG_PWM(nr) (0x56 + (nr)) #define SMSC47M1_REG_FANDIV 0x58 - -static const u8 SMSC47M1_REG_FAN[3] = { 0x59, 0x5a, 0x6b }; -static const u8 SMSC47M1_REG_FAN_PRELOAD[3] = { 0x5b, 0x5c, 0x6c }; -static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 }; - -#define SMSC47M2_REG_ALARM6 0x09 -#define SMSC47M2_REG_TPIN1 0x38 -#define SMSC47M2_REG_TPIN2 0x37 -#define SMSC47M2_REG_TPIN3 0x2d -#define SMSC47M2_REG_PPIN3 0x2c -#define SMSC47M2_REG_FANDIV3 0x6a +#define SMSC47M1_REG_FAN(nr) (0x59 + (nr)) +#define SMSC47M1_REG_FAN_PRELOAD(nr) (0x5B + (nr)) #define MIN_FROM_REG(reg,div) ((reg)>=192 ? 0 : \ 983040/((192-(reg))*(div))) @@ -113,57 +102,45 @@ static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 }; #define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E) struct smsc47m1_data { - unsigned short addr; - const char *name; - enum chips type; + struct i2c_client client; struct class_device *class_dev; + struct mutex lock; struct mutex update_lock; unsigned long last_updated; /* In jiffies */ - u8 fan[3]; /* Register value */ - u8 fan_preload[3]; /* Register value */ - u8 fan_div[3]; /* Register encoding, shifted right */ + u8 fan[2]; /* Register value */ + u8 fan_preload[2]; /* Register value */ + u8 fan_div[2]; /* Register encoding, shifted right */ u8 alarms; /* Register encoding */ - u8 pwm[3]; /* Register value (bit 0 is disable) */ + u8 pwm[2]; /* Register value (bit 7 is enable) */ }; -struct smsc47m1_sio_data { - enum chips type; -}; +static int smsc47m1_detect(struct i2c_adapter *adapter); +static int smsc47m1_detach_client(struct i2c_client *client); + +static int smsc47m1_read_value(struct i2c_client *client, u8 reg); +static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value); -static int smsc47m1_probe(struct platform_device *pdev); -static int smsc47m1_remove(struct platform_device *pdev); static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, int init); -static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg) -{ - return inb_p(data->addr + reg); -} -static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg, - u8 value) -{ - outb_p(value, data->addr + reg); -} - -static struct platform_driver smsc47m1_driver = { +static struct i2c_driver smsc47m1_driver = { .driver = { .owner = THIS_MODULE, - .name = DRVNAME, + .name = "smsc47m1", }, - .probe = smsc47m1_probe, - .remove = __devexit_p(smsc47m1_remove), + .attach_adapter = smsc47m1_detect, + .detach_client = smsc47m1_detach_client, }; -static ssize_t get_fan(struct device *dev, struct device_attribute - *devattr, char *buf) +/* nr is 0 or 1 in the callback functions below */ + +static ssize_t get_fan(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); - int nr = attr->index; /* This chip (stupidly) stops monitoring fan speed if PWM is enabled and duty cycle is 0%. This is fine if the monitoring and control concern the same fan, but troublesome if they are @@ -175,54 +152,43 @@ static ssize_t get_fan(struct device *dev, struct device_attribute return sprintf(buf, "%d\n", rpm); } -static ssize_t get_fan_min(struct device *dev, struct device_attribute - *devattr, char *buf) +static ssize_t get_fan_min(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); - int nr = attr->index; int rpm = MIN_FROM_REG(data->fan_preload[nr], DIV_FROM_REG(data->fan_div[nr])); return sprintf(buf, "%d\n", rpm); } -static ssize_t get_fan_div(struct device *dev, struct device_attribute - *devattr, char *buf) +static ssize_t get_fan_div(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); - return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index])); + return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); } -static ssize_t get_pwm(struct device *dev, struct device_attribute - *devattr, char *buf) +static ssize_t get_pwm(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); - return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[attr->index])); + return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr])); } -static ssize_t get_pwm_en(struct device *dev, struct device_attribute - *devattr, char *buf) +static ssize_t get_pwm_en(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); - return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[attr->index])); + return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr])); } -static ssize_t get_alarms(struct device *dev, struct device_attribute - *devattr, char *buf) +static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf) { struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); return sprintf(buf, "%d\n", data->alarms); } -static ssize_t set_fan_min(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) +static ssize_t set_fan_min(struct device *dev, const char *buf, + size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct smsc47m1_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct smsc47m1_data *data = i2c_get_clientdata(client); long rpmdiv, val = simple_strtol(buf, NULL, 10); mutex_lock(&data->update_lock); @@ -234,7 +200,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute } data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv); - smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr], + smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), data->fan_preload[nr]); mutex_unlock(&data->update_lock); @@ -245,12 +211,12 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute determined in part by the fan clock divider. This follows the principle of least surprise; the user doesn't expect the fan minimum to change just because the divider changed. */ -static ssize_t set_fan_div(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) +static ssize_t set_fan_div(struct device *dev, const char *buf, + size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct smsc47m1_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct smsc47m1_data *data = i2c_get_clientdata(client); + long new_div = simple_strtol(buf, NULL, 10), tmp; u8 old_div = DIV_FROM_REG(data->fan_div[nr]); @@ -268,38 +234,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute return -EINVAL; } - switch (nr) { - case 0: - case 1: - tmp = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV) - & ~(0x03 << (4 + 2 * nr)); - tmp |= data->fan_div[nr] << (4 + 2 * nr); - smsc47m1_write_value(data, SMSC47M1_REG_FANDIV, tmp); - break; - case 2: - tmp = smsc47m1_read_value(data, SMSC47M2_REG_FANDIV3) & 0xCF; - tmp |= data->fan_div[2] << 4; - smsc47m1_write_value(data, SMSC47M2_REG_FANDIV3, tmp); - break; - } + tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F; + tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6); + smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp); /* Preserve fan min */ tmp = 192 - (old_div * (192 - data->fan_preload[nr]) + new_div / 2) / new_div; data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191); - smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr], + smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), data->fan_preload[nr]); mutex_unlock(&data->update_lock); return count; } -static ssize_t set_pwm(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) +static ssize_t set_pwm(struct device *dev, const char *buf, + size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct smsc47m1_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct smsc47m1_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); if (val < 0 || val > 255) @@ -308,19 +263,19 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute mutex_lock(&data->update_lock); data->pwm[nr] &= 0x81; /* Preserve additional bits */ data->pwm[nr] |= PWM_TO_REG(val); - smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr], + smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), data->pwm[nr]); mutex_unlock(&data->update_lock); return count; } -static ssize_t set_pwm_en(struct device *dev, struct device_attribute - *devattr, const char *buf, size_t count) +static ssize_t set_pwm_en(struct device *dev, const char *buf, + size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); - struct smsc47m1_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct smsc47m1_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); if (val != 0 && val != 1) @@ -329,7 +284,7 @@ static ssize_t set_pwm_en(struct device *dev, struct device_attribute mutex_lock(&data->update_lock); data->pwm[nr] &= 0xFE; /* preserve the other bits */ data->pwm[nr] |= !val; - smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr], + smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), data->pwm[nr]); mutex_unlock(&data->update_lock); @@ -337,55 +292,79 @@ static ssize_t set_pwm_en(struct device *dev, struct device_attribute } #define fan_present(offset) \ -static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan, \ - NULL, offset - 1); \ -static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ - get_fan_min, set_fan_min, offset - 1); \ -static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ - get_fan_div, set_fan_div, offset - 1); \ -static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ - get_pwm, set_pwm, offset - 1); \ -static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ - get_pwm_en, set_pwm_en, offset - 1) +static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return get_fan(dev, buf, offset - 1); \ +} \ +static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return get_fan_min(dev, buf, offset - 1); \ +} \ +static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return set_fan_min(dev, buf, count, offset - 1); \ +} \ +static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return get_fan_div(dev, buf, offset - 1); \ +} \ +static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return set_fan_div(dev, buf, count, offset - 1); \ +} \ +static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return get_pwm(dev, buf, offset - 1); \ +} \ +static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return set_pwm(dev, buf, count, offset - 1); \ +} \ +static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return get_pwm_en(dev, buf, offset - 1); \ +} \ +static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return set_pwm_en(dev, buf, count, offset - 1); \ +} \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \ + NULL); \ +static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ + get_fan##offset##_min, set_fan##offset##_min); \ +static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ + get_fan##offset##_div, set_fan##offset##_div); \ +static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ + get_pwm##offset, set_pwm##offset); \ +static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ + get_pwm##offset##_en, set_pwm##offset##_en); fan_present(1); fan_present(2); -fan_present(3); static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); -static ssize_t show_name(struct device *dev, struct device_attribute - *devattr, char *buf) -{ - struct smsc47m1_data *data = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", data->name); -} -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - /* Almost all sysfs files may or may not be created depending on the chip setup so we create them individually. It is still convenient to define a group to remove them all at once. */ static struct attribute *smsc47m1_attributes[] = { - &sensor_dev_attr_fan1_input.dev_attr.attr, - &sensor_dev_attr_fan1_min.dev_attr.attr, - &sensor_dev_attr_fan1_div.dev_attr.attr, - &sensor_dev_attr_fan2_input.dev_attr.attr, - &sensor_dev_attr_fan2_min.dev_attr.attr, - &sensor_dev_attr_fan2_div.dev_attr.attr, - &sensor_dev_attr_fan3_input.dev_attr.attr, - &sensor_dev_attr_fan3_min.dev_attr.attr, - &sensor_dev_attr_fan3_div.dev_attr.attr, - - &sensor_dev_attr_pwm1.dev_attr.attr, - &sensor_dev_attr_pwm1_enable.dev_attr.attr, - &sensor_dev_attr_pwm2.dev_attr.attr, - &sensor_dev_attr_pwm2_enable.dev_attr.attr, - &sensor_dev_attr_pwm3.dev_attr.attr, - &sensor_dev_attr_pwm3_enable.dev_attr.attr, + &dev_attr_fan1_input.attr, + &dev_attr_fan1_min.attr, + &dev_attr_fan1_div.attr, + &dev_attr_fan2_input.attr, + &dev_attr_fan2_min.attr, + &dev_attr_fan2_div.attr, + + &dev_attr_pwm1.attr, + &dev_attr_pwm1_enable.attr, + &dev_attr_pwm2.attr, + &dev_attr_pwm2_enable.attr, &dev_attr_alarms.attr, - &dev_attr_name.attr, NULL }; @@ -393,8 +372,7 @@ static const struct attribute_group smsc47m1_group = { .attrs = smsc47m1_attributes, }; -static int __init smsc47m1_find(unsigned short *addr, - struct smsc47m1_sio_data *sio_data) +static int __init smsc47m1_find(unsigned short *addr) { u8 val; @@ -408,32 +386,18 @@ static int __init smsc47m1_find(unsigned short *addr, * can do much more besides (device id 0x60). * The LPC47M997 is undocumented, but seems to be compatible with * the LPC47M192, and has the same device id. - * The LPC47M292 (device id 0x6B) is somewhat compatible, but it - * supports a 3rd fan, and the pin configuration registers are - * unfortunately different. */ - switch (val) { - case 0x51: - pr_info(DRVNAME ": Found SMSC LPC47B27x\n"); - sio_data->type = smsc47m1; - break; - case 0x59: - pr_info(DRVNAME ": Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n"); - sio_data->type = smsc47m1; - break; - case 0x5F: - pr_info(DRVNAME ": Found SMSC LPC47M14x\n"); - sio_data->type = smsc47m1; - break; - case 0x60: - pr_info(DRVNAME ": Found SMSC LPC47M15x/LPC47M192/LPC47M997\n"); - sio_data->type = smsc47m1; - break; - case 0x6B: - pr_info(DRVNAME ": Found SMSC LPC47M292\n"); - sio_data->type = smsc47m2; - break; - default: + if (val == 0x51) + printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n"); + else if (val == 0x59) + printk(KERN_INFO "smsc47m1: Found SMSC " + "LPC47M10x/LPC47M112/LPC47M13x\n"); + else if (val == 0x5F) + printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n"); + else if (val == 0x60) + printk(KERN_INFO "smsc47m1: Found SMSC " + "LPC47M15x/LPC47M192/LPC47M997\n"); + else { superio_exit(); return -ENODEV; } @@ -443,7 +407,7 @@ static int __init smsc47m1_find(unsigned short *addr, | superio_inb(SUPERIO_REG_BASE + 1); val = superio_inb(SUPERIO_REG_ACT); if (*addr == 0 || (val & 0x01) == 0) { - pr_info(DRVNAME ": Device is disabled, will not use\n"); + printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n"); superio_exit(); return -ENODEV; } @@ -452,25 +416,15 @@ static int __init smsc47m1_find(unsigned short *addr, return 0; } -static int __devinit smsc47m1_probe(struct platform_device *pdev) +static int smsc47m1_detect(struct i2c_adapter *adapter) { - struct device *dev = &pdev->dev; - struct smsc47m1_sio_data *sio_data = dev->platform_data; + struct i2c_client *new_client; struct smsc47m1_data *data; - struct resource *res; int err = 0; - int fan1, fan2, fan3, pwm1, pwm2, pwm3; - - static const char *names[] = { - "smsc47m1", - "smsc47m2", - }; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, SMSC_EXTENT, DRVNAME)) { - dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", - (unsigned long)res->start, - (unsigned long)res->end); + int fan1, fan2, pwm1, pwm2; + + if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) { + dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); return -EBUSY; } @@ -479,114 +433,93 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) goto error_release; } - data->addr = res->start; - data->type = sio_data->type; - data->name = names[sio_data->type]; + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; + mutex_init(&data->lock); + new_client->adapter = adapter; + new_client->driver = &smsc47m1_driver; + new_client->flags = 0; + + strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE); mutex_init(&data->update_lock); - platform_set_drvdata(pdev, data); /* If no function is properly configured, there's no point in actually registering the chip. */ - pwm1 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(0)) & 0x05) + fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05) + == 0x05; + fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05) + == 0x05; + pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05) == 0x04; - pwm2 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(1)) & 0x05) + pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05) == 0x04; - if (data->type == smsc47m2) { - fan1 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN1) - & 0x0d) == 0x09; - fan2 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN2) - & 0x0d) == 0x09; - fan3 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN3) - & 0x0d) == 0x0d; - pwm3 = (smsc47m1_read_value(data, SMSC47M2_REG_PPIN3) - & 0x0d) == 0x08; - } else { - fan1 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(0)) - & 0x05) == 0x05; - fan2 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(1)) - & 0x05) == 0x05; - fan3 = 0; - pwm3 = 0; - } - if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) { - dev_warn(dev, "Device not configured, will not use\n"); + if (!(fan1 || fan2 || pwm1 || pwm2)) { + dev_warn(&adapter->dev, "Device at 0x%x is not configured, " + "will not use\n", new_client->addr); err = -ENODEV; goto error_free; } + if ((err = i2c_attach_client(new_client))) + goto error_free; + /* Some values (fan min, clock dividers, pwm registers) may be needed before any update is triggered, so we better read them at least once here. We don't usually do it that way, but in this particular case, manually reading 5 registers out of 8 doesn't make much sense and we're better using the existing function. */ - smsc47m1_update_device(dev, 1); + smsc47m1_update_device(&new_client->dev, 1); /* Register sysfs hooks */ if (fan1) { - if ((err = device_create_file(dev, - &sensor_dev_attr_fan1_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan1_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan1_div.dev_attr))) + if ((err = device_create_file(&new_client->dev, + &dev_attr_fan1_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan1_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan1_div))) goto error_remove_files; } else - dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n"); + dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, " + "skipping\n"); if (fan2) { - if ((err = device_create_file(dev, - &sensor_dev_attr_fan2_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan2_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan2_div.dev_attr))) + if ((err = device_create_file(&new_client->dev, + &dev_attr_fan2_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan2_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan2_div))) goto error_remove_files; } else - dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n"); - - if (fan3) { - if ((err = device_create_file(dev, - &sensor_dev_attr_fan3_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan3_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_fan3_div.dev_attr))) - goto error_remove_files; - } else - dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n"); + dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, " + "skipping\n"); if (pwm1) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm1.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm1_enable.dev_attr))) + if ((err = device_create_file(&new_client->dev, + &dev_attr_pwm1)) + || (err = device_create_file(&new_client->dev, + &dev_attr_pwm1_enable))) goto error_remove_files; } else - dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n"); - + dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, " + "skipping\n"); if (pwm2) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm2.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm2_enable.dev_attr))) - goto error_remove_files; - } else - dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n"); - - if (pwm3) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm3.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm3_enable.dev_attr))) + if ((err = device_create_file(&new_client->dev, + &dev_attr_pwm2)) + || (err = device_create_file(&new_client->dev, + &dev_attr_pwm2_enable))) goto error_remove_files; } else - dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n"); + dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, " + "skipping\n"); - if ((err = device_create_file(dev, &dev_attr_alarms))) + if ((err = device_create_file(&new_client->dev, &dev_attr_alarms))) goto error_remove_files; - data->class_dev = hwmon_device_register(dev); + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); goto error_remove_files; @@ -595,71 +528,78 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) return 0; error_remove_files: - sysfs_remove_group(&dev->kobj, &smsc47m1_group); + sysfs_remove_group(&new_client->dev.kobj, &smsc47m1_group); + i2c_detach_client(new_client); error_free: kfree(data); error_release: - release_region(res->start, SMSC_EXTENT); + release_region(address, SMSC_EXTENT); return err; } -static int __devexit smsc47m1_remove(struct platform_device *pdev) +static int smsc47m1_detach_client(struct i2c_client *client) { - struct smsc47m1_data *data = platform_get_drvdata(pdev); - struct resource *res; + struct smsc47m1_data *data = i2c_get_clientdata(client); + int err; - platform_set_drvdata(pdev, NULL); hwmon_device_unregister(data->class_dev); - sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group); + sysfs_remove_group(&client->dev.kobj, &smsc47m1_group); + + if ((err = i2c_detach_client(client))) + return err; - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, SMSC_EXTENT); + release_region(client->addr, SMSC_EXTENT); kfree(data); return 0; } +static int smsc47m1_read_value(struct i2c_client *client, u8 reg) +{ + int res; + + mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); + res = inb_p(client->addr + reg); + mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); + return res; +} + +static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value) +{ + mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); + outb_p(value, client->addr + reg); + mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); +} + static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, int init) { - struct smsc47m1_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct smsc47m1_data *data = i2c_get_clientdata(client); mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) { - int i, fan_nr; - fan_nr = data->type == smsc47m2 ? 3 : 2; - - for (i = 0; i < fan_nr; i++) { - data->fan[i] = smsc47m1_read_value(data, - SMSC47M1_REG_FAN[i]); - data->fan_preload[i] = smsc47m1_read_value(data, - SMSC47M1_REG_FAN_PRELOAD[i]); - data->pwm[i] = smsc47m1_read_value(data, - SMSC47M1_REG_PWM[i]); + int i; + + for (i = 0; i < 2; i++) { + data->fan[i] = smsc47m1_read_value(client, + SMSC47M1_REG_FAN(i)); + data->fan_preload[i] = smsc47m1_read_value(client, + SMSC47M1_REG_FAN_PRELOAD(i)); + data->pwm[i] = smsc47m1_read_value(client, + SMSC47M1_REG_PWM(i)); } - i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV); + i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV); data->fan_div[0] = (i >> 4) & 0x03; data->fan_div[1] = i >> 6; - data->alarms = smsc47m1_read_value(data, + data->alarms = smsc47m1_read_value(client, SMSC47M1_REG_ALARM) >> 6; /* Clear alarms if needed */ if (data->alarms) - smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0); - - if (fan_nr >= 3) { - data->fan_div[2] = (smsc47m1_read_value(data, - SMSC47M2_REG_FANDIV3) >> 4) & 0x03; - data->alarms |= (smsc47m1_read_value(data, - SMSC47M2_REG_ALARM6) & 0x40) >> 4; - /* Clear alarm if needed */ - if (data->alarms & 0x04) - smsc47m1_write_value(data, - SMSC47M2_REG_ALARM6, - 0x40); - } + smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0); data->last_updated = jiffies; } @@ -668,86 +608,18 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, return data; } -static int __init smsc47m1_device_add(unsigned short address, - const struct smsc47m1_sio_data *sio_data) -{ - struct resource res = { - .start = address, - .end = address + SMSC_EXTENT - 1, - .name = DRVNAME, - .flags = IORESOURCE_IO, - }; - int err; - - pdev = platform_device_alloc(DRVNAME, address); - if (!pdev) { - err = -ENOMEM; - printk(KERN_ERR DRVNAME ": Device allocation failed\n"); - goto exit; - } - - err = platform_device_add_resources(pdev, &res, 1); - if (err) { - printk(KERN_ERR DRVNAME ": Device resource addition failed " - "(%d)\n", err); - goto exit_device_put; - } - - pdev->dev.platform_data = kmalloc(sizeof(struct smsc47m1_sio_data), - GFP_KERNEL); - if (!pdev->dev.platform_data) { - err = -ENOMEM; - printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); - goto exit_device_put; - } - memcpy(pdev->dev.platform_data, sio_data, - sizeof(struct smsc47m1_sio_data)); - - err = platform_device_add(pdev); - if (err) { - printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", - err); - goto exit_device_put; - } - - return 0; - -exit_device_put: - platform_device_put(pdev); -exit: - return err; -} - static int __init sm_smsc47m1_init(void) { - int err; - unsigned short address; - struct smsc47m1_sio_data sio_data; - - if (smsc47m1_find(&address, &sio_data)) + if (smsc47m1_find(&address)) { return -ENODEV; + } - err = platform_driver_register(&smsc47m1_driver); - if (err) - goto exit; - - /* Sets global pdev as a side effect */ - err = smsc47m1_device_add(address, &sio_data); - if (err) - goto exit_driver; - - return 0; - -exit_driver: - platform_driver_unregister(&smsc47m1_driver); -exit: - return err; + return i2c_isa_add_driver(&smsc47m1_driver); } static void __exit sm_smsc47m1_exit(void) { - platform_device_unregister(pdev); - platform_driver_unregister(&smsc47m1_driver); + i2c_isa_del_driver(&smsc47m1_driver); } MODULE_AUTHOR("Mark D. Studebaker "); diff --git a/trunk/drivers/hwmon/smsc47m192.c b/trunk/drivers/hwmon/smsc47m192.c index a012f396f354..a6833f437395 100644 --- a/trunk/drivers/hwmon/smsc47m192.c +++ b/trunk/drivers/hwmon/smsc47m192.c @@ -1,6 +1,6 @@ /* smsc47m192.c - Support for hardware monitoring block of - SMSC LPC47M192 and compatible Super I/O chips + SMSC LPC47M192 and LPC47M997 Super I/O chips Copyright (C) 2006 Hartmut Rick @@ -518,7 +518,7 @@ static int smsc47m192_detect(struct i2c_adapter *adapter, int address, && (i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID4) & 0xfe) == 0x80) { dev_info(&adapter->dev, - "found SMSC47M192 or compatible, " + "found SMSC47M192 or SMSC47M997, " "version 2, stepping A%d\n", version & 0x0f); } else { dev_dbg(&adapter->dev, diff --git a/trunk/drivers/hwmon/vt1211.c b/trunk/drivers/hwmon/vt1211.c index 9f3e332c5b7f..89c23d6add7b 100644 --- a/trunk/drivers/hwmon/vt1211.c +++ b/trunk/drivers/hwmon/vt1211.c @@ -31,7 +31,6 @@ #include #include #include -#include #include static int uch_config = -1; @@ -1131,12 +1130,6 @@ static int __devinit vt1211_probe(struct platform_device *pdev) } res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) { - err = -EBUSY; - dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", - (unsigned long)res->start, (unsigned long)res->end); - goto EXIT_KFREE; - } data->addr = res->start; data->name = DRVNAME; mutex_init(&data->update_lock); @@ -1204,8 +1197,6 @@ static int __devinit vt1211_probe(struct platform_device *pdev) dev_err(dev, "Sysfs interface creation failed (%d)\n", err); EXIT_DEV_REMOVE_SILENT: vt1211_remove_sysfs(pdev); - release_region(res->start, res->end - res->start + 1); -EXIT_KFREE: platform_set_drvdata(pdev, NULL); kfree(data); EXIT: @@ -1215,16 +1206,12 @@ static int __devinit vt1211_probe(struct platform_device *pdev) static int __devexit vt1211_remove(struct platform_device *pdev) { struct vt1211_data *data = platform_get_drvdata(pdev); - struct resource *res; hwmon_device_unregister(data->class_dev); vt1211_remove_sysfs(pdev); platform_set_drvdata(pdev, NULL); kfree(data); - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, res->end - res->start + 1); - return 0; } diff --git a/trunk/drivers/hwmon/w83627hf.c b/trunk/drivers/hwmon/w83627hf.c index a5b774b07cbd..d7e240635b3b 100644 --- a/trunk/drivers/hwmon/w83627hf.c +++ b/trunk/drivers/hwmon/w83627hf.c @@ -5,7 +5,6 @@ Philip Edelbrock , and Mark Studebaker Ported to 2.6 by Bernhard C. Schrenk - Copyright (c) 2007 Jean Delvare 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 @@ -43,20 +42,15 @@ #include #include #include -#include +#include +#include #include #include #include #include -#include #include #include "lm75.h" -static struct platform_device *pdev; - -#define DRVNAME "w83627hf" -enum chips { w83627hf, w83627thf, w83697hf, w83637hf, w83687thf }; - static u16 force_addr; module_param(force_addr, ushort, 0); MODULE_PARM_DESC(force_addr, @@ -66,6 +60,12 @@ module_param(force_i2c, byte, 0); MODULE_PARM_DESC(force_i2c, "Initialize the i2c address of the sensors"); +/* The actual ISA address is read from Super-I/O configuration space */ +static unsigned short address; + +/* Insmod parameters */ +enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf, w83687thf }; + static int reset; module_param(reset, bool, 0); MODULE_PARM_DESC(reset, "Set to one to reset chip on load"); @@ -156,9 +156,9 @@ superio_exit(void) #define WINB_REGION_OFFSET 5 #define WINB_REGION_SIZE 2 -/* Where are the sensors address/data registers relative to the region offset */ -#define W83781D_ADDR_REG_OFFSET 0 -#define W83781D_DATA_REG_OFFSET 1 +/* Where are the sensors address/data registers relative to the base address */ +#define W83781D_ADDR_REG_OFFSET 5 +#define W83781D_DATA_REG_OFFSET 6 /* The W83781D registers */ /* The W83782D registers for nr=7,8 are in bank 5 */ @@ -289,8 +289,7 @@ static inline u8 DIV_TO_REG(long val) /* For each registered chip, we need to keep some data in memory. The structure is dynamically allocated. */ struct w83627hf_data { - unsigned short addr; - const char *name; + struct i2c_client client; struct class_device *class_dev; struct mutex lock; enum chips type; @@ -299,6 +298,9 @@ struct w83627hf_data { char valid; /* !=0 if following fields are valid */ unsigned long last_updated; /* In jiffies */ + struct i2c_client *lm75; /* for secondary I2C addresses */ + /* pointer to array of 2 subclients */ + u8 in[9]; /* Register value */ u8 in_max[9]; /* Register value */ u8 in_min[9]; /* Register value */ @@ -325,26 +327,22 @@ struct w83627hf_data { u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */ }; -struct w83627hf_sio_data { - enum chips type; -}; - -static int w83627hf_probe(struct platform_device *pdev); -static int w83627hf_remove(struct platform_device *pdev); +static int w83627hf_detect(struct i2c_adapter *adapter); +static int w83627hf_detach_client(struct i2c_client *client); -static int w83627hf_read_value(struct w83627hf_data *data, u16 reg); -static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value); +static int w83627hf_read_value(struct i2c_client *client, u16 reg); +static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value); static struct w83627hf_data *w83627hf_update_device(struct device *dev); -static void w83627hf_init_device(struct platform_device *pdev); +static void w83627hf_init_client(struct i2c_client *client); -static struct platform_driver w83627hf_driver = { +static struct i2c_driver w83627hf_driver = { .driver = { .owner = THIS_MODULE, - .name = DRVNAME, + .name = "w83627hf", }, - .probe = w83627hf_probe, - .remove = __devexit_p(w83627hf_remove), + .attach_adapter = w83627hf_detect, + .detach_client = w83627hf_detach_client, }; /* following are the sysfs callback functions */ @@ -362,14 +360,15 @@ show_in_reg(in_max) static ssize_t \ store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \ { \ - struct w83627hf_data *data = dev_get_drvdata(dev); \ + struct i2c_client *client = to_i2c_client(dev); \ + struct w83627hf_data *data = i2c_get_clientdata(client); \ u32 val; \ \ val = simple_strtoul(buf, NULL, 10); \ \ mutex_lock(&data->update_lock); \ data->in_##reg[nr] = IN_TO_REG(val); \ - w83627hf_write_value(data, W83781D_REG_IN_##REG(nr), \ + w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \ data->in_##reg[nr]); \ \ mutex_unlock(&data->update_lock); \ @@ -453,7 +452,8 @@ static ssize_t show_regs_in_max0(struct device *dev, struct device_attribute *at static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); @@ -472,7 +472,7 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a /* use VRM8 (standard) calculation */ data->in_min[0] = IN_TO_REG(val); - w83627hf_write_value(data, W83781D_REG_IN_MIN(0), data->in_min[0]); + w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]); mutex_unlock(&data->update_lock); return count; } @@ -480,7 +480,8 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); @@ -499,7 +500,7 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a /* use VRM8 (standard) calculation */ data->in_max[0] = IN_TO_REG(val); - w83627hf_write_value(data, W83781D_REG_IN_MAX(0), data->in_max[0]); + w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]); mutex_unlock(&data->update_lock); return count; } @@ -524,7 +525,8 @@ show_fan_reg(fan_min); static ssize_t store_fan_min(struct device *dev, const char *buf, size_t count, int nr) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); @@ -532,7 +534,7 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr) mutex_lock(&data->update_lock); data->fan_min[nr - 1] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); - w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr), + w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr), data->fan_min[nr - 1]); mutex_unlock(&data->update_lock); @@ -585,7 +587,8 @@ show_temp_reg(temp_max_hyst); static ssize_t \ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ { \ - struct w83627hf_data *data = dev_get_drvdata(dev); \ + struct i2c_client *client = to_i2c_client(dev); \ + struct w83627hf_data *data = i2c_get_clientdata(client); \ u32 val; \ \ val = simple_strtoul(buf, NULL, 10); \ @@ -594,11 +597,11 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ \ if (nr >= 2) { /* TEMP2 and TEMP3 */ \ data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ - w83627hf_write_value(data, W83781D_REG_TEMP_##REG(nr), \ + w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \ data->temp_##reg##_add[nr-2]); \ } else { /* TEMP1 */ \ data->temp_##reg = TEMP_TO_REG(val); \ - w83627hf_write_value(data, W83781D_REG_TEMP_##REG(nr), \ + w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \ data->temp_##reg); \ } \ \ @@ -656,7 +659,8 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); @@ -691,7 +695,8 @@ static ssize_t store_beep_reg(struct device *dev, const char *buf, size_t count, int update_mask) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); u32 val, val2; val = simple_strtoul(buf, NULL, 10); @@ -700,18 +705,18 @@ store_beep_reg(struct device *dev, const char *buf, size_t count, if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ data->beep_mask = BEEP_MASK_TO_REG(val); - w83627hf_write_value(data, W83781D_REG_BEEP_INTS1, + w83627hf_write_value(client, W83781D_REG_BEEP_INTS1, data->beep_mask & 0xff); - w83627hf_write_value(data, W83781D_REG_BEEP_INTS3, + w83627hf_write_value(client, W83781D_REG_BEEP_INTS3, ((data->beep_mask) >> 16) & 0xff); val2 = (data->beep_mask >> 8) & 0x7f; } else { /* We are storing beep_enable */ val2 = - w83627hf_read_value(data, W83781D_REG_BEEP_INTS2) & 0x7f; + w83627hf_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f; data->beep_enable = BEEP_ENABLE_TO_REG(val); } - w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, + w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, val2 | data->beep_enable << 7); mutex_unlock(&data->update_lock); @@ -749,7 +754,8 @@ show_fan_div_reg(struct device *dev, char *buf, int nr) static ssize_t store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); unsigned long min; u8 reg; unsigned long val = simple_strtoul(buf, NULL, 10); @@ -762,19 +768,19 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) data->fan_div[nr] = DIV_TO_REG(val); - reg = (w83627hf_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) + reg = (w83627hf_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) & (nr==0 ? 0xcf : 0x3f)) | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6)); - w83627hf_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); + w83627hf_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); - reg = (w83627hf_read_value(data, W83781D_REG_VBAT) + reg = (w83627hf_read_value(client, W83781D_REG_VBAT) & ~(1 << (5 + nr))) | ((data->fan_div[nr] & 0x04) << (3 + nr)); - w83627hf_write_value(data, W83781D_REG_VBAT, reg); + w83627hf_write_value(client, W83781D_REG_VBAT, reg); /* Restore fan_min */ data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); - w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); + w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); mutex_unlock(&data->update_lock); return count; @@ -808,7 +814,8 @@ show_pwm_reg(struct device *dev, char *buf, int nr) static ssize_t store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); @@ -818,14 +825,14 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) if (data->type == w83627thf) { /* bits 0-3 are reserved in 627THF */ data->pwm[nr - 1] = PWM_TO_REG(val) & 0xf0; - w83627hf_write_value(data, + w83627hf_write_value(client, W836X7HF_REG_PWM(data->type, nr), data->pwm[nr - 1] | - (w83627hf_read_value(data, + (w83627hf_read_value(client, W836X7HF_REG_PWM(data->type, nr)) & 0x0f)); } else { data->pwm[nr - 1] = PWM_TO_REG(val); - w83627hf_write_value(data, + w83627hf_write_value(client, W836X7HF_REG_PWM(data->type, nr), data->pwm[nr - 1]); } @@ -861,7 +868,8 @@ show_sensor_reg(struct device *dev, char *buf, int nr) static ssize_t store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); u32 val, tmp; val = simple_strtoul(buf, NULL, 10); @@ -870,31 +878,31 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) switch (val) { case 1: /* PII/Celeron diode */ - tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); - w83627hf_write_value(data, W83781D_REG_SCFG1, + tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); + w83627hf_write_value(client, W83781D_REG_SCFG1, tmp | BIT_SCFG1[nr - 1]); - tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); - w83627hf_write_value(data, W83781D_REG_SCFG2, + tmp = w83627hf_read_value(client, W83781D_REG_SCFG2); + w83627hf_write_value(client, W83781D_REG_SCFG2, tmp | BIT_SCFG2[nr - 1]); data->sens[nr - 1] = val; break; case 2: /* 3904 */ - tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); - w83627hf_write_value(data, W83781D_REG_SCFG1, + tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); + w83627hf_write_value(client, W83781D_REG_SCFG1, tmp | BIT_SCFG1[nr - 1]); - tmp = w83627hf_read_value(data, W83781D_REG_SCFG2); - w83627hf_write_value(data, W83781D_REG_SCFG2, + tmp = w83627hf_read_value(client, W83781D_REG_SCFG2); + w83627hf_write_value(client, W83781D_REG_SCFG2, tmp & ~BIT_SCFG2[nr - 1]); data->sens[nr - 1] = val; break; case W83781D_DEFAULT_BETA: /* thermistor */ - tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); - w83627hf_write_value(data, W83781D_REG_SCFG1, + tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); + w83627hf_write_value(client, W83781D_REG_SCFG1, tmp & ~BIT_SCFG1[nr - 1]); data->sens[nr - 1] = val; break; default: - dev_err(dev, + dev_err(&client->dev, "Invalid sensor type %ld; must be 1, 2, or %d\n", (long) val, W83781D_DEFAULT_BETA); break; @@ -921,85 +929,35 @@ sysfs_sensor(1); sysfs_sensor(2); sysfs_sensor(3); -static ssize_t show_name(struct device *dev, struct device_attribute - *devattr, char *buf) -{ - struct w83627hf_data *data = dev_get_drvdata(dev); - - return sprintf(buf, "%s\n", data->name); -} -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); - -static int __init w83627hf_find(int sioaddr, unsigned short *addr, - struct w83627hf_sio_data *sio_data) +static int __init w83627hf_find(int sioaddr, unsigned short *addr) { - int err = -ENODEV; u16 val; - static const __initdata char *names[] = { - "W83627HF", - "W83627THF", - "W83697HF", - "W83637HF", - "W83687THF", - }; - REG = sioaddr; VAL = sioaddr + 1; superio_enter(); val= superio_inb(DEVID); - switch (val) { - case W627_DEVID: - sio_data->type = w83627hf; - break; - case W627THF_DEVID: - sio_data->type = w83627thf; - break; - case W697_DEVID: - sio_data->type = w83697hf; - break; - case W637_DEVID: - sio_data->type = w83637hf; - break; - case W687THF_DEVID: - sio_data->type = w83687thf; - break; - default: - pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%x)\n", val); - goto exit; + if(val != W627_DEVID && + val != W627THF_DEVID && + val != W697_DEVID && + val != W637_DEVID && + val != W687THF_DEVID) { + superio_exit(); + return -ENODEV; } superio_select(W83627HF_LD_HWM); - force_addr &= WINB_ALIGNMENT; - if (force_addr) { - printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n", - force_addr); - superio_outb(WINB_BASE_REG, force_addr >> 8); - superio_outb(WINB_BASE_REG + 1, force_addr & 0xff); - } val = (superio_inb(WINB_BASE_REG) << 8) | superio_inb(WINB_BASE_REG + 1); *addr = val & WINB_ALIGNMENT; - if (*addr == 0) { - printk(KERN_WARNING DRVNAME ": Base address not set, " - "skipping\n"); - goto exit; - } - - val = superio_inb(WINB_ACT_REG); - if (!(val & 0x01)) { - printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n"); - superio_outb(WINB_ACT_REG, val | 0x01); + if (*addr == 0 && force_addr == 0) { + superio_exit(); + return -ENODEV; } - err = 0; - pr_info(DRVNAME ": Found %s chip at %#x\n", - names[sio_data->type], *addr); - - exit: superio_exit(); - return err; + return 0; } static struct attribute *w83627hf_attributes[] = { @@ -1045,7 +1003,6 @@ static struct attribute *w83627hf_attributes[] = { &dev_attr_pwm1.attr, &dev_attr_pwm2.attr, - &dev_attr_name.attr, NULL }; @@ -1082,92 +1039,161 @@ static const struct attribute_group w83627hf_group_opt = { .attrs = w83627hf_attributes_opt, }; -static int __devinit w83627hf_probe(struct platform_device *pdev) +static int w83627hf_detect(struct i2c_adapter *adapter) { - struct device *dev = &pdev->dev; - struct w83627hf_sio_data *sio_data = dev->platform_data; + int val, kind; + struct i2c_client *new_client; struct w83627hf_data *data; - struct resource *res; - int err; + int err = 0; + const char *client_name = ""; - static const char *names[] = { - "w83627hf", - "w83627thf", - "w83697hf", - "w83637hf", - "w83687thf", - }; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, WINB_REGION_SIZE, DRVNAME)) { - dev_err(dev, "Failed to request region 0x%lx-0x%lx\n", - (unsigned long)res->start, - (unsigned long)(res->start + WINB_REGION_SIZE - 1)); + if(force_addr) + address = force_addr & WINB_ALIGNMENT; + + if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE, + w83627hf_driver.driver.name)) { err = -EBUSY; goto ERROR0; } + if(force_addr) { + printk("w83627hf.o: forcing ISA address 0x%04X\n", address); + superio_enter(); + superio_select(W83627HF_LD_HWM); + superio_outb(WINB_BASE_REG, address >> 8); + superio_outb(WINB_BASE_REG+1, address & 0xff); + superio_exit(); + } + + superio_enter(); + val= superio_inb(DEVID); + if(val == W627_DEVID) + kind = w83627hf; + else if(val == W697_DEVID) + kind = w83697hf; + else if(val == W627THF_DEVID) + kind = w83627thf; + else if(val == W637_DEVID) + kind = w83637hf; + else if (val == W687THF_DEVID) + kind = w83687thf; + else { + dev_info(&adapter->dev, + "Unsupported chip (dev_id=0x%02X).\n", val); + goto ERROR1; + } + + superio_select(W83627HF_LD_HWM); + if((val = 0x01 & superio_inb(WINB_ACT_REG)) == 0) + superio_outb(WINB_ACT_REG, 1); + superio_exit(); + + /* OK. For now, we presume we have a valid client. We now create the + client structure, even though we cannot fill it completely yet. + But it allows us to access w83627hf_{read,write}_value. */ + if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR1; } - data->addr = res->start; - data->type = sio_data->type; - data->name = names[sio_data->type]; + + new_client = &data->client; + i2c_set_clientdata(new_client, data); + new_client->addr = address; mutex_init(&data->lock); + new_client->adapter = adapter; + new_client->driver = &w83627hf_driver; + new_client->flags = 0; + + + if (kind == w83627hf) { + client_name = "w83627hf"; + } else if (kind == w83627thf) { + client_name = "w83627thf"; + } else if (kind == w83697hf) { + client_name = "w83697hf"; + } else if (kind == w83637hf) { + client_name = "w83637hf"; + } else if (kind == w83687thf) { + client_name = "w83687thf"; + } + + /* Fill in the remaining client fields and put into the global list */ + strlcpy(new_client->name, client_name, I2C_NAME_SIZE); + data->type = kind; + data->valid = 0; mutex_init(&data->update_lock); - platform_set_drvdata(pdev, data); + + /* Tell the I2C layer a new client has arrived */ + if ((err = i2c_attach_client(new_client))) + goto ERROR2; + + data->lm75 = NULL; /* Initialize the chip */ - w83627hf_init_device(pdev); + w83627hf_init_client(new_client); /* A few vars need to be filled upon startup */ - data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1)); - data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2)); - data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3)); + data->fan_min[0] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(1)); + data->fan_min[1] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(2)); + data->fan_min[2] = w83627hf_read_value(new_client, W83781D_REG_FAN_MIN(3)); /* Register common device attributes */ - if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group))) + if ((err = sysfs_create_group(&new_client->dev.kobj, &w83627hf_group))) goto ERROR3; /* Register chip-specific device attributes */ - if (data->type == w83627hf || data->type == w83697hf) - if ((err = device_create_file(dev, &dev_attr_in5_input)) - || (err = device_create_file(dev, &dev_attr_in5_min)) - || (err = device_create_file(dev, &dev_attr_in5_max)) - || (err = device_create_file(dev, &dev_attr_in6_input)) - || (err = device_create_file(dev, &dev_attr_in6_min)) - || (err = device_create_file(dev, &dev_attr_in6_max))) + if (kind == w83627hf || kind == w83697hf) + if ((err = device_create_file(&new_client->dev, + &dev_attr_in5_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in5_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in5_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in6_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in6_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in6_max))) goto ERROR4; - if (data->type != w83697hf) - if ((err = device_create_file(dev, &dev_attr_in1_input)) - || (err = device_create_file(dev, &dev_attr_in1_min)) - || (err = device_create_file(dev, &dev_attr_in1_max)) - || (err = device_create_file(dev, &dev_attr_fan3_input)) - || (err = device_create_file(dev, &dev_attr_fan3_min)) - || (err = device_create_file(dev, &dev_attr_fan3_div)) - || (err = device_create_file(dev, &dev_attr_temp3_input)) - || (err = device_create_file(dev, &dev_attr_temp3_max)) - || (err = device_create_file(dev, &dev_attr_temp3_max_hyst)) - || (err = device_create_file(dev, &dev_attr_temp3_type))) + if (kind != w83697hf) + if ((err = device_create_file(&new_client->dev, + &dev_attr_in1_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in1_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_in1_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan3_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan3_min)) + || (err = device_create_file(&new_client->dev, + &dev_attr_fan3_div)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_input)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_max)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_max_hyst)) + || (err = device_create_file(&new_client->dev, + &dev_attr_temp3_type))) goto ERROR4; - if (data->type != w83697hf && data->vid != 0xff) { - /* Convert VID to voltage based on VRM */ - data->vrm = vid_which_vrm(); - - if ((err = device_create_file(dev, &dev_attr_cpu0_vid)) - || (err = device_create_file(dev, &dev_attr_vrm))) + if (kind != w83697hf && data->vid != 0xff) + if ((err = device_create_file(&new_client->dev, + &dev_attr_cpu0_vid)) + || (err = device_create_file(&new_client->dev, + &dev_attr_vrm))) goto ERROR4; - } - if (data->type == w83627thf || data->type == w83637hf - || data->type == w83687thf) - if ((err = device_create_file(dev, &dev_attr_pwm3))) + if (kind == w83627thf || kind == w83637hf || kind == w83687thf) + if ((err = device_create_file(&new_client->dev, + &dev_attr_pwm3))) goto ERROR4; - data->class_dev = hwmon_device_register(dev); + data->class_dev = hwmon_device_register(&new_client->dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); goto ERROR4; @@ -1176,37 +1202,47 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) return 0; ERROR4: - sysfs_remove_group(&dev->kobj, &w83627hf_group); - sysfs_remove_group(&dev->kobj, &w83627hf_group_opt); + sysfs_remove_group(&new_client->dev.kobj, &w83627hf_group); + sysfs_remove_group(&new_client->dev.kobj, &w83627hf_group_opt); ERROR3: + i2c_detach_client(new_client); + ERROR2: kfree(data); ERROR1: - release_region(res->start, WINB_REGION_SIZE); + release_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE); ERROR0: return err; } -static int __devexit w83627hf_remove(struct platform_device *pdev) +static int w83627hf_detach_client(struct i2c_client *client) { - struct w83627hf_data *data = platform_get_drvdata(pdev); - struct resource *res; + struct w83627hf_data *data = i2c_get_clientdata(client); + int err; - platform_set_drvdata(pdev, NULL); hwmon_device_unregister(data->class_dev); - sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group); - sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group_opt); - kfree(data); + sysfs_remove_group(&client->dev.kobj, &w83627hf_group); + sysfs_remove_group(&client->dev.kobj, &w83627hf_group_opt); - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, WINB_REGION_SIZE); + if ((err = i2c_detach_client(client))) + return err; + + release_region(client->addr + WINB_REGION_OFFSET, WINB_REGION_SIZE); + kfree(data); return 0; } -static int w83627hf_read_value(struct w83627hf_data *data, u16 reg) +/* + ISA access must always be locked explicitly! + We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, + would slow down the W83781D access and should not be necessary. + There are some ugly typecasts here, but the good news is - they should + nowhere else be necessary! */ +static int w83627hf_read_value(struct i2c_client *client, u16 reg) { + struct w83627hf_data *data = i2c_get_clientdata(client); int res, word_sized; mutex_lock(&data->lock); @@ -1217,29 +1253,29 @@ static int w83627hf_read_value(struct w83627hf_data *data, u16 reg) || ((reg & 0x00ff) == 0x55)); if (reg & 0xff00) { outb_p(W83781D_REG_BANK, - data->addr + W83781D_ADDR_REG_OFFSET); + client->addr + W83781D_ADDR_REG_OFFSET); outb_p(reg >> 8, - data->addr + W83781D_DATA_REG_OFFSET); + client->addr + W83781D_DATA_REG_OFFSET); } - outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); - res = inb_p(data->addr + W83781D_DATA_REG_OFFSET); + outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); + res = inb_p(client->addr + W83781D_DATA_REG_OFFSET); if (word_sized) { outb_p((reg & 0xff) + 1, - data->addr + W83781D_ADDR_REG_OFFSET); + client->addr + W83781D_ADDR_REG_OFFSET); res = - (res << 8) + inb_p(data->addr + + (res << 8) + inb_p(client->addr + W83781D_DATA_REG_OFFSET); } if (reg & 0xff00) { outb_p(W83781D_REG_BANK, - data->addr + W83781D_ADDR_REG_OFFSET); - outb_p(0, data->addr + W83781D_DATA_REG_OFFSET); + client->addr + W83781D_ADDR_REG_OFFSET); + outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); } mutex_unlock(&data->lock); return res; } -static int __devinit w83627thf_read_gpio5(struct platform_device *pdev) +static int w83627thf_read_gpio5(struct i2c_client *client) { int res = 0xff, sel; @@ -1248,7 +1284,7 @@ static int __devinit w83627thf_read_gpio5(struct platform_device *pdev) /* Make sure these GPIO pins are enabled */ if (!(superio_inb(W83627THF_GPIO5_EN) & (1<<3))) { - dev_dbg(&pdev->dev, "GPIO5 disabled, no VID function\n"); + dev_dbg(&client->dev, "GPIO5 disabled, no VID function\n"); goto exit; } @@ -1256,12 +1292,12 @@ static int __devinit w83627thf_read_gpio5(struct platform_device *pdev) There must be at least five (VRM 9), and possibly 6 (VRM 10) */ sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f; if ((sel & 0x1f) != 0x1f) { - dev_dbg(&pdev->dev, "GPIO5 not configured for VID " + dev_dbg(&client->dev, "GPIO5 not configured for VID " "function\n"); goto exit; } - dev_info(&pdev->dev, "Reading VID from GPIO5\n"); + dev_info(&client->dev, "Reading VID from GPIO5\n"); res = superio_inb(W83627THF_GPIO5_DR) & sel; exit: @@ -1269,7 +1305,7 @@ static int __devinit w83627thf_read_gpio5(struct platform_device *pdev) return res; } -static int __devinit w83687thf_read_vid(struct platform_device *pdev) +static int w83687thf_read_vid(struct i2c_client *client) { int res = 0xff; @@ -1278,13 +1314,13 @@ static int __devinit w83687thf_read_vid(struct platform_device *pdev) /* Make sure these GPIO pins are enabled */ if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) { - dev_dbg(&pdev->dev, "VID disabled, no VID function\n"); + dev_dbg(&client->dev, "VID disabled, no VID function\n"); goto exit; } /* Make sure the pins are configured for input */ if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) { - dev_dbg(&pdev->dev, "VID configured as output, " + dev_dbg(&client->dev, "VID configured as output, " "no VID function\n"); goto exit; } @@ -1296,8 +1332,9 @@ static int __devinit w83687thf_read_vid(struct platform_device *pdev) return res; } -static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value) +static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value) { + struct w83627hf_data *data = i2c_get_clientdata(client); int word_sized; mutex_lock(&data->lock); @@ -1307,33 +1344,33 @@ static int w83627hf_write_value(struct w83627hf_data *data, u16 reg, u16 value) || ((reg & 0x00ff) == 0x55)); if (reg & 0xff00) { outb_p(W83781D_REG_BANK, - data->addr + W83781D_ADDR_REG_OFFSET); + client->addr + W83781D_ADDR_REG_OFFSET); outb_p(reg >> 8, - data->addr + W83781D_DATA_REG_OFFSET); + client->addr + W83781D_DATA_REG_OFFSET); } - outb_p(reg & 0xff, data->addr + W83781D_ADDR_REG_OFFSET); + outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET); if (word_sized) { outb_p(value >> 8, - data->addr + W83781D_DATA_REG_OFFSET); + client->addr + W83781D_DATA_REG_OFFSET); outb_p((reg & 0xff) + 1, - data->addr + W83781D_ADDR_REG_OFFSET); + client->addr + W83781D_ADDR_REG_OFFSET); } outb_p(value & 0xff, - data->addr + W83781D_DATA_REG_OFFSET); + client->addr + W83781D_DATA_REG_OFFSET); if (reg & 0xff00) { outb_p(W83781D_REG_BANK, - data->addr + W83781D_ADDR_REG_OFFSET); - outb_p(0, data->addr + W83781D_DATA_REG_OFFSET); + client->addr + W83781D_ADDR_REG_OFFSET); + outb_p(0, client->addr + W83781D_DATA_REG_OFFSET); } mutex_unlock(&data->lock); return 0; } -static void __devinit w83627hf_init_device(struct platform_device *pdev) +static void w83627hf_init_client(struct i2c_client *client) { - struct w83627hf_data *data = platform_get_drvdata(pdev); + struct w83627hf_data *data = i2c_get_clientdata(client); int i; - enum chips type = data->type; + int type = data->type; u8 tmp; if (reset) { @@ -1342,53 +1379,57 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) speed...) so it is now optional. It might even go away if nobody reports it as being useful, as I see very little reason why this would be needed at all. */ - dev_info(&pdev->dev, "If reset=1 solved a problem you were " + dev_info(&client->dev, "If reset=1 solved a problem you were " "having, please report!\n"); /* save this register */ - i = w83627hf_read_value(data, W83781D_REG_BEEP_CONFIG); + i = w83627hf_read_value(client, W83781D_REG_BEEP_CONFIG); /* Reset all except Watchdog values and last conversion values This sets fan-divs to 2, among others */ - w83627hf_write_value(data, W83781D_REG_CONFIG, 0x80); + w83627hf_write_value(client, W83781D_REG_CONFIG, 0x80); /* Restore the register and disable power-on abnormal beep. This saves FAN 1/2/3 input/output values set by BIOS. */ - w83627hf_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); + w83627hf_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80); /* Disable master beep-enable (reset turns it on). Individual beeps should be reset to off but for some reason disabling this bit helps some people not get beeped */ - w83627hf_write_value(data, W83781D_REG_BEEP_INTS2, 0); + w83627hf_write_value(client, W83781D_REG_BEEP_INTS2, 0); } /* Minimize conflicts with other winbond i2c-only clients... */ /* disable i2c subclients... how to disable main i2c client?? */ /* force i2c address to relatively uncommon address */ - w83627hf_write_value(data, W83781D_REG_I2C_SUBADDR, 0x89); - w83627hf_write_value(data, W83781D_REG_I2C_ADDR, force_i2c); + w83627hf_write_value(client, W83781D_REG_I2C_SUBADDR, 0x89); + w83627hf_write_value(client, W83781D_REG_I2C_ADDR, force_i2c); /* Read VID only once */ - if (type == w83627hf || type == w83637hf) { - int lo = w83627hf_read_value(data, W83781D_REG_VID_FANDIV); - int hi = w83627hf_read_value(data, W83781D_REG_CHIPID); + if (w83627hf == data->type || w83637hf == data->type) { + int lo = w83627hf_read_value(client, W83781D_REG_VID_FANDIV); + int hi = w83627hf_read_value(client, W83781D_REG_CHIPID); data->vid = (lo & 0x0f) | ((hi & 0x01) << 4); - } else if (type == w83627thf) { - data->vid = w83627thf_read_gpio5(pdev); - } else if (type == w83687thf) { - data->vid = w83687thf_read_vid(pdev); + } else if (w83627thf == data->type) { + data->vid = w83627thf_read_gpio5(client); + } else if (w83687thf == data->type) { + data->vid = w83687thf_read_vid(client); } /* Read VRM & OVT Config only once */ - if (type == w83627thf || type == w83637hf || type == w83687thf) { + if (w83627thf == data->type || w83637hf == data->type + || w83687thf == data->type) { data->vrm_ovt = - w83627hf_read_value(data, W83627THF_REG_VRM_OVT_CFG); + w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG); } - tmp = w83627hf_read_value(data, W83781D_REG_SCFG1); + /* Convert VID to voltage based on VRM */ + data->vrm = vid_which_vrm(); + + tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); for (i = 1; i <= 3; i++) { if (!(tmp & BIT_SCFG1[i - 1])) { data->sens[i - 1] = W83781D_DEFAULT_BETA; } else { if (w83627hf_read_value - (data, + (client, W83781D_REG_SCFG2) & BIT_SCFG2[i - 1]) data->sens[i - 1] = 1; else @@ -1400,37 +1441,38 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) if(init) { /* Enable temp2 */ - tmp = w83627hf_read_value(data, W83781D_REG_TEMP2_CONFIG); + tmp = w83627hf_read_value(client, W83781D_REG_TEMP2_CONFIG); if (tmp & 0x01) { - dev_warn(&pdev->dev, "Enabling temp2, readings " + dev_warn(&client->dev, "Enabling temp2, readings " "might not make sense\n"); - w83627hf_write_value(data, W83781D_REG_TEMP2_CONFIG, + w83627hf_write_value(client, W83781D_REG_TEMP2_CONFIG, tmp & 0xfe); } /* Enable temp3 */ if (type != w83697hf) { - tmp = w83627hf_read_value(data, + tmp = w83627hf_read_value(client, W83781D_REG_TEMP3_CONFIG); if (tmp & 0x01) { - dev_warn(&pdev->dev, "Enabling temp3, " + dev_warn(&client->dev, "Enabling temp3, " "readings might not make sense\n"); - w83627hf_write_value(data, + w83627hf_write_value(client, W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); } } } /* Start monitoring */ - w83627hf_write_value(data, W83781D_REG_CONFIG, - (w83627hf_read_value(data, + w83627hf_write_value(client, W83781D_REG_CONFIG, + (w83627hf_read_value(client, W83781D_REG_CONFIG) & 0xf7) | 0x01); } static struct w83627hf_data *w83627hf_update_device(struct device *dev) { - struct w83627hf_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83627hf_data *data = i2c_get_clientdata(client); int i; mutex_lock(&data->update_lock); @@ -1444,23 +1486,23 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) && (i == 5 || i == 6))) continue; data->in[i] = - w83627hf_read_value(data, W83781D_REG_IN(i)); + w83627hf_read_value(client, W83781D_REG_IN(i)); data->in_min[i] = - w83627hf_read_value(data, + w83627hf_read_value(client, W83781D_REG_IN_MIN(i)); data->in_max[i] = - w83627hf_read_value(data, + w83627hf_read_value(client, W83781D_REG_IN_MAX(i)); } for (i = 1; i <= 3; i++) { data->fan[i - 1] = - w83627hf_read_value(data, W83781D_REG_FAN(i)); + w83627hf_read_value(client, W83781D_REG_FAN(i)); data->fan_min[i - 1] = - w83627hf_read_value(data, + w83627hf_read_value(client, W83781D_REG_FAN_MIN(i)); } for (i = 1; i <= 3; i++) { - u8 tmp = w83627hf_read_value(data, + u8 tmp = w83627hf_read_value(client, W836X7HF_REG_PWM(data->type, i)); /* bits 0-3 are reserved in 627THF */ if (data->type == w83627thf) @@ -1471,47 +1513,47 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) break; } - data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1)); + data->temp = w83627hf_read_value(client, W83781D_REG_TEMP(1)); data->temp_max = - w83627hf_read_value(data, W83781D_REG_TEMP_OVER(1)); + w83627hf_read_value(client, W83781D_REG_TEMP_OVER(1)); data->temp_max_hyst = - w83627hf_read_value(data, W83781D_REG_TEMP_HYST(1)); + w83627hf_read_value(client, W83781D_REG_TEMP_HYST(1)); data->temp_add[0] = - w83627hf_read_value(data, W83781D_REG_TEMP(2)); + w83627hf_read_value(client, W83781D_REG_TEMP(2)); data->temp_max_add[0] = - w83627hf_read_value(data, W83781D_REG_TEMP_OVER(2)); + w83627hf_read_value(client, W83781D_REG_TEMP_OVER(2)); data->temp_max_hyst_add[0] = - w83627hf_read_value(data, W83781D_REG_TEMP_HYST(2)); + w83627hf_read_value(client, W83781D_REG_TEMP_HYST(2)); if (data->type != w83697hf) { data->temp_add[1] = - w83627hf_read_value(data, W83781D_REG_TEMP(3)); + w83627hf_read_value(client, W83781D_REG_TEMP(3)); data->temp_max_add[1] = - w83627hf_read_value(data, W83781D_REG_TEMP_OVER(3)); + w83627hf_read_value(client, W83781D_REG_TEMP_OVER(3)); data->temp_max_hyst_add[1] = - w83627hf_read_value(data, W83781D_REG_TEMP_HYST(3)); + w83627hf_read_value(client, W83781D_REG_TEMP_HYST(3)); } - i = w83627hf_read_value(data, W83781D_REG_VID_FANDIV); + i = w83627hf_read_value(client, W83781D_REG_VID_FANDIV); data->fan_div[0] = (i >> 4) & 0x03; data->fan_div[1] = (i >> 6) & 0x03; if (data->type != w83697hf) { - data->fan_div[2] = (w83627hf_read_value(data, + data->fan_div[2] = (w83627hf_read_value(client, W83781D_REG_PIN) >> 6) & 0x03; } - i = w83627hf_read_value(data, W83781D_REG_VBAT); + i = w83627hf_read_value(client, W83781D_REG_VBAT); data->fan_div[0] |= (i >> 3) & 0x04; data->fan_div[1] |= (i >> 4) & 0x04; if (data->type != w83697hf) data->fan_div[2] |= (i >> 5) & 0x04; data->alarms = - w83627hf_read_value(data, W83781D_REG_ALARM1) | - (w83627hf_read_value(data, W83781D_REG_ALARM2) << 8) | - (w83627hf_read_value(data, W83781D_REG_ALARM3) << 16); - i = w83627hf_read_value(data, W83781D_REG_BEEP_INTS2); + w83627hf_read_value(client, W83781D_REG_ALARM1) | + (w83627hf_read_value(client, W83781D_REG_ALARM2) << 8) | + (w83627hf_read_value(client, W83781D_REG_ALARM3) << 16); + i = w83627hf_read_value(client, W83781D_REG_BEEP_INTS2); data->beep_enable = i >> 7; data->beep_mask = ((i & 0x7f) << 8) | - w83627hf_read_value(data, W83781D_REG_BEEP_INTS1) | - w83627hf_read_value(data, W83781D_REG_BEEP_INTS3) << 16; + w83627hf_read_value(client, W83781D_REG_BEEP_INTS1) | + w83627hf_read_value(client, W83781D_REG_BEEP_INTS3) << 16; data->last_updated = jiffies; data->valid = 1; } @@ -1521,87 +1563,19 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) return data; } -static int __init w83627hf_device_add(unsigned short address, - const struct w83627hf_sio_data *sio_data) -{ - struct resource res = { - .start = address + WINB_REGION_OFFSET, - .end = address + WINB_REGION_OFFSET + WINB_REGION_SIZE - 1, - .name = DRVNAME, - .flags = IORESOURCE_IO, - }; - int err; - - pdev = platform_device_alloc(DRVNAME, address); - if (!pdev) { - err = -ENOMEM; - printk(KERN_ERR DRVNAME ": Device allocation failed\n"); - goto exit; - } - - err = platform_device_add_resources(pdev, &res, 1); - if (err) { - printk(KERN_ERR DRVNAME ": Device resource addition failed " - "(%d)\n", err); - goto exit_device_put; - } - - pdev->dev.platform_data = kmalloc(sizeof(struct w83627hf_sio_data), - GFP_KERNEL); - if (!pdev->dev.platform_data) { - err = -ENOMEM; - printk(KERN_ERR DRVNAME ": Platform data allocation failed\n"); - goto exit_device_put; - } - memcpy(pdev->dev.platform_data, sio_data, - sizeof(struct w83627hf_sio_data)); - - err = platform_device_add(pdev); - if (err) { - printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", - err); - goto exit_device_put; - } - - return 0; - -exit_device_put: - platform_device_put(pdev); -exit: - return err; -} - static int __init sensors_w83627hf_init(void) { - int err; - unsigned short address; - struct w83627hf_sio_data sio_data; - - if (w83627hf_find(0x2e, &address, &sio_data) - && w83627hf_find(0x4e, &address, &sio_data)) + if (w83627hf_find(0x2e, &address) + && w83627hf_find(0x4e, &address)) { return -ENODEV; + } - err = platform_driver_register(&w83627hf_driver); - if (err) - goto exit; - - /* Sets global pdev as a side effect */ - err = w83627hf_device_add(address, &sio_data); - if (err) - goto exit_driver; - - return 0; - -exit_driver: - platform_driver_unregister(&w83627hf_driver); -exit: - return err; + return i2c_isa_add_driver(&w83627hf_driver); } static void __exit sensors_w83627hf_exit(void) { - platform_device_unregister(pdev); - platform_driver_unregister(&w83627hf_driver); + i2c_isa_del_driver(&w83627hf_driver); } MODULE_AUTHOR("Frodo Looijaard , " diff --git a/trunk/drivers/hwmon/w83781d.c b/trunk/drivers/hwmon/w83781d.c index f85b48fea1c4..a47da3ec5472 100644 --- a/trunk/drivers/hwmon/w83781d.c +++ b/trunk/drivers/hwmon/w83781d.c @@ -2,9 +2,8 @@ w83781d.c - Part of lm_sensors, Linux kernel modules for hardware monitoring Copyright (c) 1998 - 2001 Frodo Looijaard , - Philip Edelbrock , - and Mark Studebaker - Copyright (c) 2007 Jean Delvare + Philip Edelbrock , + and Mark Studebaker 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 @@ -39,20 +38,15 @@ #include #include #include -#include -#include +#include #include #include -#include #include #include #include #include #include "lm75.h" -/* ISA device, if found */ -static struct platform_device *pdev; - /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, @@ -81,8 +75,8 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); #define W83781D_ADDR_REG_OFFSET 5 #define W83781D_DATA_REG_OFFSET 6 -/* The device registers */ -/* in nr from 0 to 8 */ +/* The W83781D registers */ +/* The W83782D registers for nr=7,8 are in bank 5 */ #define W83781D_REG_IN_MAX(nr) ((nr < 7) ? (0x2b + (nr) * 2) : \ (0x554 + (((nr) - 7) * 2))) #define W83781D_REG_IN_MIN(nr) ((nr < 7) ? (0x2c + (nr) * 2) : \ @@ -90,14 +84,12 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); #define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ (0x550 + (nr) - 7)) -/* fan nr from 0 to 2 */ -#define W83781D_REG_FAN_MIN(nr) (0x3b + (nr)) -#define W83781D_REG_FAN(nr) (0x28 + (nr)) +#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr)) +#define W83781D_REG_FAN(nr) (0x27 + (nr)) #define W83781D_REG_BANK 0x4E #define W83781D_REG_TEMP2_CONFIG 0x152 #define W83781D_REG_TEMP3_CONFIG 0x252 -/* temp nr from 1 to 3 */ #define W83781D_REG_TEMP(nr) ((nr == 3) ? (0x0250) : \ ((nr == 2) ? (0x0150) : \ (0x27))) @@ -135,9 +127,19 @@ MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization"); #define W83781D_REG_VBAT 0x5D /* PWM 782D (1-4) and 783S (1-2) only */ -static const u8 W83781D_REG_PWM[] = { 0x5B, 0x5A, 0x5E, 0x5F }; +#define W83781D_REG_PWM1 0x5B /* 782d and 783s/627hf datasheets disagree */ + /* on which is which; */ +#define W83781D_REG_PWM2 0x5A /* We follow the 782d convention here, */ + /* However 782d is probably wrong. */ +#define W83781D_REG_PWM3 0x5E +#define W83781D_REG_PWM4 0x5F #define W83781D_REG_PWMCLK12 0x5C #define W83781D_REG_PWMCLK34 0x45C +static const u8 regpwm[] = { W83781D_REG_PWM1, W83781D_REG_PWM2, + W83781D_REG_PWM3, W83781D_REG_PWM4 +}; + +#define W83781D_REG_PWM(nr) (regpwm[(nr) - 1]) #define W83781D_REG_I2C_ADDR 0x48 #define W83781D_REG_I2C_SUBADDR 0x4A @@ -157,9 +159,12 @@ static const u8 BIT_SCFG2[] = { 0x10, 0x20, 0x40 }; #define W83781D_REG_RT_IDX 0x50 #define W83781D_REG_RT_VAL 0x51 -/* Conversions */ -#define IN_TO_REG(val) SENSORS_LIMIT(((val) + 8) / 16, 0, 255) -#define IN_FROM_REG(val) ((val) * 16) +/* Conversions. Rounding and limit checking is only done on the TO_REG + variants. Note that you should be a bit careful with which arguments + these macros are called: arguments may be evaluated more than once. + Fixing this is just not worth it. */ +#define IN_TO_REG(val) (SENSORS_LIMIT((((val) * 10 + 8)/16),0,255)) +#define IN_FROM_REG(val) (((val) * 16) / 10) static inline u8 FAN_TO_REG(long rpm, int div) @@ -170,24 +175,24 @@ FAN_TO_REG(long rpm, int div) return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); } -static inline long -FAN_FROM_REG(u8 val, int div) -{ - if (val == 0) - return -1; - if (val == 255) - return 0; - return 1350000 / (val * div); -} +#define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \ + ((val) == 255 ? 0 : \ + 1350000 / ((val) * (div)))) -#define TEMP_TO_REG(val) SENSORS_LIMIT((val) / 1000, -127, 128) -#define TEMP_FROM_REG(val) ((val) * 1000) +#define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \ + : (val)) / 1000, 0, 0xff)) +#define TEMP_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000) +#define PWM_FROM_REG(val) (val) +#define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) #define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ (val) ^ 0x7fff : (val)) #define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \ (~(val)) & 0x7fff : (val) & 0xffffff) +#define BEEP_ENABLE_TO_REG(val) ((val) ? 1 : 0) +#define BEEP_ENABLE_FROM_REG(val) ((val) ? 1 : 0) + #define DIV_FROM_REG(val) (1 << (val)) static inline u8 @@ -202,7 +207,7 @@ DIV_TO_REG(long val, enum chips type) break; val >>= 1; } - return i; + return ((u8) i); } /* There are some complications in a module like this. First off, W83781D chips @@ -216,8 +221,8 @@ DIV_TO_REG(long val, enum chips type) a bit - except if there could be more than one SMBus. Groan. No solution for this yet. */ -/* For ISA chips, we abuse the i2c_client addr and name fields. We also use - the driver field to differentiate between I2C and ISA chips. */ +/* For each registered chip, we need to keep some data in memory. + The structure is dynamically allocated. */ struct w83781d_data { struct i2c_client client; struct class_device *class_dev; @@ -236,9 +241,9 @@ struct w83781d_data { u8 in_min[9]; /* Register value - 8 & 9 for 782D only */ u8 fan[3]; /* Register value */ u8 fan_min[3]; /* Register value */ - s8 temp; /* Register value */ - s8 temp_max; /* Register value */ - s8 temp_max_hyst; /* Register value */ + u8 temp; + u8 temp_max; /* Register value */ + u8 temp_max_hyst; /* Register value */ u16 temp_add[2]; /* Register value */ u16 temp_max_add[2]; /* Register value */ u16 temp_max_hyst_add[2]; /* Register value */ @@ -248,7 +253,7 @@ struct w83781d_data { u32 beep_mask; /* Register encoding, combined */ u8 beep_enable; /* Boolean */ u8 pwm[4]; /* Register value */ - u8 pwm2_enable; /* Boolean */ + u8 pwmenable[4]; /* Boolean */ u16 sens[3]; /* 782D/783S only. 1 = pentium diode; 2 = 3904 diode; 3000-5000 = thermistor beta. @@ -258,16 +263,14 @@ struct w83781d_data { }; static int w83781d_attach_adapter(struct i2c_adapter *adapter); +static int w83781d_isa_attach_adapter(struct i2c_adapter *adapter); static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind); static int w83781d_detach_client(struct i2c_client *client); -static int __devinit w83781d_isa_probe(struct platform_device *pdev); -static int __devexit w83781d_isa_remove(struct platform_device *pdev); - -static int w83781d_read_value(struct w83781d_data *data, u16 reg); -static int w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value); +static int w83781d_read_value(struct i2c_client *client, u16 reg); +static int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value); static struct w83781d_data *w83781d_update_device(struct device *dev); -static void w83781d_init_device(struct device *dev); +static void w83781d_init_client(struct i2c_client *client); static struct i2c_driver w83781d_driver = { .driver = { @@ -278,44 +281,39 @@ static struct i2c_driver w83781d_driver = { .detach_client = w83781d_detach_client, }; -static struct platform_driver w83781d_isa_driver = { +static struct i2c_driver w83781d_isa_driver = { .driver = { .owner = THIS_MODULE, - .name = "w83781d", + .name = "w83781d-isa", }, - .probe = w83781d_isa_probe, - .remove = w83781d_isa_remove, + .attach_adapter = w83781d_isa_attach_adapter, + .detach_client = w83781d_detach_client, }; /* following are the sysfs callback functions */ #define show_in_reg(reg) \ -static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ - char *buf) \ +static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ { \ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ struct w83781d_data *data = w83781d_update_device(dev); \ - return sprintf(buf, "%ld\n", \ - (long)IN_FROM_REG(data->reg[attr->index])); \ + return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr] * 10)); \ } show_in_reg(in); show_in_reg(in_min); show_in_reg(in_max); #define store_in_reg(REG, reg) \ -static ssize_t store_in_##reg (struct device *dev, struct device_attribute \ - *da, const char *buf, size_t count) \ +static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \ { \ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ - struct w83781d_data *data = dev_get_drvdata(dev); \ - int nr = attr->index; \ + struct i2c_client *client = to_i2c_client(dev); \ + struct w83781d_data *data = i2c_get_clientdata(client); \ u32 val; \ \ - val = simple_strtoul(buf, NULL, 10); \ + val = simple_strtoul(buf, NULL, 10) / 10; \ \ mutex_lock(&data->update_lock); \ data->in_##reg[nr] = IN_TO_REG(val); \ - w83781d_write_value(data, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \ + w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \ \ mutex_unlock(&data->update_lock); \ return count; \ @@ -323,13 +321,29 @@ static ssize_t store_in_##reg (struct device *dev, struct device_attribute \ store_in_reg(MIN, min); store_in_reg(MAX, max); +#define sysfs_in_offset(offset) \ +static ssize_t \ +show_regs_in_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_in(dev, buf, offset); \ +} \ +static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_regs_in_##offset, NULL); + +#define sysfs_in_reg_offset(reg, offset) \ +static ssize_t show_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_in_##reg (dev, buf, offset); \ +} \ +static ssize_t store_regs_in_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + return store_in_##reg (dev, buf, count, offset); \ +} \ +static DEVICE_ATTR(in##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_in_##reg##offset, store_regs_in_##reg##offset); + #define sysfs_in_offsets(offset) \ -static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ - show_in, NULL, offset); \ -static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ - show_in_min, store_in_min, offset); \ -static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ - show_in_max, store_in_max, offset) +sysfs_in_offset(offset); \ +sysfs_in_reg_offset(min, offset); \ +sysfs_in_reg_offset(max, offset); sysfs_in_offsets(0); sysfs_in_offsets(1); @@ -342,56 +356,63 @@ sysfs_in_offsets(7); sysfs_in_offsets(8); #define show_fan_reg(reg) \ -static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ - char *buf) \ +static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ { \ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ struct w83781d_data *data = w83781d_update_device(dev); \ return sprintf(buf,"%ld\n", \ - FAN_FROM_REG(data->reg[attr->index], \ - DIV_FROM_REG(data->fan_div[attr->index]))); \ + FAN_FROM_REG(data->reg[nr-1], (long)DIV_FROM_REG(data->fan_div[nr-1]))); \ } show_fan_reg(fan); show_fan_reg(fan_min); static ssize_t -store_fan_min(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +store_fan_min(struct device *dev, const char *buf, size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct w83781d_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct w83781d_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); - data->fan_min[nr] = - FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); - w83781d_write_value(data, W83781D_REG_FAN_MIN(nr), - data->fan_min[nr]); + data->fan_min[nr - 1] = + FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); + w83781d_write_value(client, W83781D_REG_FAN_MIN(nr), + data->fan_min[nr - 1]); mutex_unlock(&data->update_lock); return count; } -static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); -static SENSOR_DEVICE_ATTR(fan1_min, S_IRUGO | S_IWUSR, - show_fan_min, store_fan_min, 0); -static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); -static SENSOR_DEVICE_ATTR(fan2_min, S_IRUGO | S_IWUSR, - show_fan_min, store_fan_min, 1); -static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); -static SENSOR_DEVICE_ATTR(fan3_min, S_IRUGO | S_IWUSR, - show_fan_min, store_fan_min, 2); +#define sysfs_fan_offset(offset) \ +static ssize_t show_regs_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_fan(dev, buf, offset); \ +} \ +static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL); + +#define sysfs_fan_min_offset(offset) \ +static ssize_t show_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_fan_min(dev, buf, offset); \ +} \ +static ssize_t store_regs_fan_min##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + return store_fan_min(dev, buf, count, offset); \ +} \ +static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, show_regs_fan_min##offset, store_regs_fan_min##offset); + +sysfs_fan_offset(1); +sysfs_fan_min_offset(1); +sysfs_fan_offset(2); +sysfs_fan_min_offset(2); +sysfs_fan_offset(3); +sysfs_fan_min_offset(3); #define show_temp_reg(reg) \ -static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \ - char *buf) \ +static ssize_t show_##reg (struct device *dev, char *buf, int nr) \ { \ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ struct w83781d_data *data = w83781d_update_device(dev); \ - int nr = attr->index; \ if (nr >= 2) { /* TEMP2 and TEMP3 */ \ return sprintf(buf,"%d\n", \ LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \ @@ -404,12 +425,10 @@ show_temp_reg(temp_max); show_temp_reg(temp_max_hyst); #define store_temp_reg(REG, reg) \ -static ssize_t store_temp_##reg (struct device *dev, \ - struct device_attribute *da, const char *buf, size_t count) \ +static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \ { \ - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); \ - struct w83781d_data *data = dev_get_drvdata(dev); \ - int nr = attr->index; \ + struct i2c_client *client = to_i2c_client(dev); \ + struct w83781d_data *data = i2c_get_clientdata(client); \ s32 val; \ \ val = simple_strtol(buf, NULL, 10); \ @@ -418,11 +437,11 @@ static ssize_t store_temp_##reg (struct device *dev, \ \ if (nr >= 2) { /* TEMP2 and TEMP3 */ \ data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ - w83781d_write_value(data, W83781D_REG_TEMP_##REG(nr), \ + w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \ data->temp_##reg##_add[nr-2]); \ } else { /* TEMP1 */ \ data->temp_##reg = TEMP_TO_REG(val); \ - w83781d_write_value(data, W83781D_REG_TEMP_##REG(nr), \ + w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \ data->temp_##reg); \ } \ \ @@ -432,13 +451,29 @@ static ssize_t store_temp_##reg (struct device *dev, \ store_temp_reg(OVER, max); store_temp_reg(HYST, max_hyst); +#define sysfs_temp_offset(offset) \ +static ssize_t \ +show_regs_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_temp(dev, buf, offset); \ +} \ +static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL); + +#define sysfs_temp_reg_offset(reg, offset) \ +static ssize_t show_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_temp_##reg (dev, buf, offset); \ +} \ +static ssize_t store_regs_temp_##reg##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + return store_temp_##reg (dev, buf, count, offset); \ +} \ +static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset); + #define sysfs_temp_offsets(offset) \ -static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ - show_temp, NULL, offset); \ -static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ - show_temp_max, store_temp_max, offset); \ -static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ - show_temp_max_hyst, store_temp_max_hyst, offset); +sysfs_temp_offset(offset); \ +sysfs_temp_reg_offset(max, offset); \ +sysfs_temp_reg_offset(max_hyst, offset); sysfs_temp_offsets(1); sysfs_temp_offsets(2); @@ -463,7 +498,8 @@ show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct w83781d_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83781d_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); @@ -492,67 +528,68 @@ static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr static ssize_t show_beep_enable (struct device *dev, struct device_attribute *attr, char *buf) { struct w83781d_data *data = w83781d_update_device(dev); - return sprintf(buf, "%ld\n", (long)data->beep_enable); + return sprintf(buf, "%ld\n", + (long)BEEP_ENABLE_FROM_REG(data->beep_enable)); } +#define BEEP_ENABLE 0 /* Store beep_enable */ +#define BEEP_MASK 1 /* Store beep_mask */ + static ssize_t -store_beep_mask(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +store_beep_reg(struct device *dev, const char *buf, size_t count, + int update_mask) { - struct w83781d_data *data = dev_get_drvdata(dev); - u32 val; + struct i2c_client *client = to_i2c_client(dev); + struct w83781d_data *data = i2c_get_clientdata(client); + u32 val, val2; val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); - data->beep_mask = BEEP_MASK_TO_REG(val, data->type); - w83781d_write_value(data, W83781D_REG_BEEP_INTS1, - data->beep_mask & 0xff); - w83781d_write_value(data, W83781D_REG_BEEP_INTS2, - ((data->beep_mask >> 8) & 0x7f) - | data->beep_enable << 7); - if (data->type != w83781d && data->type != as99127f) { - w83781d_write_value(data, W83781D_REG_BEEP_INTS3, - ((data->beep_mask) >> 16) & 0xff); - } - mutex_unlock(&data->update_lock); - return count; -} + if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ + data->beep_mask = BEEP_MASK_TO_REG(val, data->type); + w83781d_write_value(client, W83781D_REG_BEEP_INTS1, + data->beep_mask & 0xff); -static ssize_t -store_beep_enable(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct w83781d_data *data = dev_get_drvdata(dev); - u32 val; + if ((data->type != w83781d) && (data->type != as99127f)) { + w83781d_write_value(client, W83781D_REG_BEEP_INTS3, + ((data->beep_mask) >> 16) & 0xff); + } - val = simple_strtoul(buf, NULL, 10); - if (val != 0 && val != 1) - return -EINVAL; + val2 = (data->beep_mask >> 8) & 0x7f; + } else { /* We are storing beep_enable */ + val2 = w83781d_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f; + data->beep_enable = BEEP_ENABLE_TO_REG(val); + } - mutex_lock(&data->update_lock); - data->beep_enable = val; - val = w83781d_read_value(data, W83781D_REG_BEEP_INTS2) & 0x7f; - val |= data->beep_enable << 7; - w83781d_write_value(data, W83781D_REG_BEEP_INTS2, val); - mutex_unlock(&data->update_lock); + w83781d_write_value(client, W83781D_REG_BEEP_INTS2, + val2 | data->beep_enable << 7); + mutex_unlock(&data->update_lock); return count; } -static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR, - show_beep_mask, store_beep_mask); -static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR, - show_beep_enable, store_beep_enable); +#define sysfs_beep(REG, reg) \ +static ssize_t show_regs_beep_##reg (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_beep_##reg(dev, attr, buf); \ +} \ +static ssize_t store_regs_beep_##reg (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + return store_beep_reg(dev, buf, count, BEEP_##REG); \ +} \ +static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg); + +sysfs_beep(ENABLE, enable); +sysfs_beep(MASK, mask); static ssize_t -show_fan_div(struct device *dev, struct device_attribute *da, char *buf) +show_fan_div_reg(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", - (long) DIV_FROM_REG(data->fan_div[attr->index])); + (long) DIV_FROM_REG(data->fan_div[nr - 1])); } /* Note: we save and restore the fan minimum here, because its value is @@ -560,13 +597,11 @@ show_fan_div(struct device *dev, struct device_attribute *da, char *buf) least surprise; the user doesn't expect the fan minimum to change just because the divisor changed. */ static ssize_t -store_fan_div(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct w83781d_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83781d_data *data = i2c_get_clientdata(client); unsigned long min; - int nr = attr->index; u8 reg; unsigned long val = simple_strtoul(buf, NULL, 10); @@ -578,72 +613,77 @@ store_fan_div(struct device *dev, struct device_attribute *da, data->fan_div[nr] = DIV_TO_REG(val, data->type); - reg = (w83781d_read_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) + reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) & (nr==0 ? 0xcf : 0x3f)) | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6)); - w83781d_write_value(data, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); + w83781d_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); /* w83781d and as99127f don't have extended divisor bits */ if (data->type != w83781d && data->type != as99127f) { - reg = (w83781d_read_value(data, W83781D_REG_VBAT) + reg = (w83781d_read_value(client, W83781D_REG_VBAT) & ~(1 << (5 + nr))) | ((data->fan_div[nr] & 0x04) << (3 + nr)); - w83781d_write_value(data, W83781D_REG_VBAT, reg); + w83781d_write_value(client, W83781D_REG_VBAT, reg); } /* Restore fan_min */ data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); - w83781d_write_value(data, W83781D_REG_FAN_MIN(nr), data->fan_min[nr]); + w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); mutex_unlock(&data->update_lock); return count; } -static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, - show_fan_div, store_fan_div, 0); -static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR, - show_fan_div, store_fan_div, 1); -static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO | S_IWUSR, - show_fan_div, store_fan_div, 2); +#define sysfs_fan_div(offset) \ +static ssize_t show_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_fan_div_reg(dev, buf, offset); \ +} \ +static ssize_t store_regs_fan_div_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + return store_fan_div_reg(dev, buf, count, offset - 1); \ +} \ +static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset); + +sysfs_fan_div(1); +sysfs_fan_div(2); +sysfs_fan_div(3); static ssize_t -show_pwm(struct device *dev, struct device_attribute *da, char *buf) +show_pwm_reg(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct w83781d_data *data = w83781d_update_device(dev); - return sprintf(buf, "%d\n", (int)data->pwm[attr->index]); + return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1])); } static ssize_t -show_pwm2_enable(struct device *dev, struct device_attribute *da, char *buf) +show_pwmenable_reg(struct device *dev, char *buf, int nr) { struct w83781d_data *data = w83781d_update_device(dev); - return sprintf(buf, "%d\n", (int)data->pwm2_enable); + return sprintf(buf, "%ld\n", (long) data->pwmenable[nr - 1]); } static ssize_t -store_pwm(struct device *dev, struct device_attribute *da, const char *buf, - size_t count) +store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct w83781d_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct w83781d_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); - data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); - w83781d_write_value(data, W83781D_REG_PWM[nr], data->pwm[nr]); + data->pwm[nr - 1] = PWM_TO_REG(val); + w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]); mutex_unlock(&data->update_lock); return count; } static ssize_t -store_pwm2_enable(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr) { - struct w83781d_data *data = dev_get_drvdata(dev); + struct i2c_client *client = to_i2c_client(dev); + struct w83781d_data *data = i2c_get_clientdata(client); u32 val, reg; val = simple_strtoul(buf, NULL, 10); @@ -653,15 +693,15 @@ store_pwm2_enable(struct device *dev, struct device_attribute *da, switch (val) { case 0: case 1: - reg = w83781d_read_value(data, W83781D_REG_PWMCLK12); - w83781d_write_value(data, W83781D_REG_PWMCLK12, + reg = w83781d_read_value(client, W83781D_REG_PWMCLK12); + w83781d_write_value(client, W83781D_REG_PWMCLK12, (reg & 0xf7) | (val << 3)); - reg = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); - w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, + reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); + w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, (reg & 0xef) | (!val << 4)); - data->pwm2_enable = val; + data->pwmenable[nr - 1] = val; break; default: @@ -673,29 +713,50 @@ store_pwm2_enable(struct device *dev, struct device_attribute *da, return count; } -static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 0); -static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 1); -static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 2); -static SENSOR_DEVICE_ATTR(pwm4, S_IRUGO | S_IWUSR, show_pwm, store_pwm, 3); -/* only PWM2 can be enabled/disabled */ -static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, - show_pwm2_enable, store_pwm2_enable); +#define sysfs_pwm(offset) \ +static ssize_t show_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_pwm_reg(dev, buf, offset); \ +} \ +static ssize_t store_regs_pwm_##offset (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return store_pwm_reg(dev, buf, count, offset); \ +} \ +static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ + show_regs_pwm_##offset, store_regs_pwm_##offset); + +#define sysfs_pwmenable(offset) \ +static ssize_t show_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_pwmenable_reg(dev, buf, offset); \ +} \ +static ssize_t store_regs_pwmenable_##offset (struct device *dev, struct device_attribute *attr, \ + const char *buf, size_t count) \ +{ \ + return store_pwmenable_reg(dev, buf, count, offset); \ +} \ +static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ + show_regs_pwmenable_##offset, store_regs_pwmenable_##offset); + +sysfs_pwm(1); +sysfs_pwm(2); +sysfs_pwmenable(2); /* only PWM2 can be enabled/disabled */ +sysfs_pwm(3); +sysfs_pwm(4); static ssize_t -show_sensor(struct device *dev, struct device_attribute *da, char *buf) +show_sensor_reg(struct device *dev, char *buf, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct w83781d_data *data = w83781d_update_device(dev); - return sprintf(buf, "%d\n", (int)data->sens[attr->index]); + return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]); } static ssize_t -store_sensor(struct device *dev, struct device_attribute *da, - const char *buf, size_t count) +store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr) { - struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct w83781d_data *data = dev_get_drvdata(dev); - int nr = attr->index; + struct i2c_client *client = to_i2c_client(dev); + struct w83781d_data *data = i2c_get_clientdata(client); u32 val, tmp; val = simple_strtoul(buf, NULL, 10); @@ -704,28 +765,28 @@ store_sensor(struct device *dev, struct device_attribute *da, switch (val) { case 1: /* PII/Celeron diode */ - tmp = w83781d_read_value(data, W83781D_REG_SCFG1); - w83781d_write_value(data, W83781D_REG_SCFG1, - tmp | BIT_SCFG1[nr]); - tmp = w83781d_read_value(data, W83781D_REG_SCFG2); - w83781d_write_value(data, W83781D_REG_SCFG2, - tmp | BIT_SCFG2[nr]); - data->sens[nr] = val; + tmp = w83781d_read_value(client, W83781D_REG_SCFG1); + w83781d_write_value(client, W83781D_REG_SCFG1, + tmp | BIT_SCFG1[nr - 1]); + tmp = w83781d_read_value(client, W83781D_REG_SCFG2); + w83781d_write_value(client, W83781D_REG_SCFG2, + tmp | BIT_SCFG2[nr - 1]); + data->sens[nr - 1] = val; break; case 2: /* 3904 */ - tmp = w83781d_read_value(data, W83781D_REG_SCFG1); - w83781d_write_value(data, W83781D_REG_SCFG1, - tmp | BIT_SCFG1[nr]); - tmp = w83781d_read_value(data, W83781D_REG_SCFG2); - w83781d_write_value(data, W83781D_REG_SCFG2, - tmp & ~BIT_SCFG2[nr]); - data->sens[nr] = val; + tmp = w83781d_read_value(client, W83781D_REG_SCFG1); + w83781d_write_value(client, W83781D_REG_SCFG1, + tmp | BIT_SCFG1[nr - 1]); + tmp = w83781d_read_value(client, W83781D_REG_SCFG2); + w83781d_write_value(client, W83781D_REG_SCFG2, + tmp & ~BIT_SCFG2[nr - 1]); + data->sens[nr - 1] = val; break; case W83781D_DEFAULT_BETA: /* thermistor */ - tmp = w83781d_read_value(data, W83781D_REG_SCFG1); - w83781d_write_value(data, W83781D_REG_SCFG1, - tmp & ~BIT_SCFG1[nr]); - data->sens[nr] = val; + tmp = w83781d_read_value(client, W83781D_REG_SCFG1); + w83781d_write_value(client, W83781D_REG_SCFG1, + tmp & ~BIT_SCFG1[nr - 1]); + data->sens[nr - 1] = val; break; default: dev_err(dev, "Invalid sensor type %ld; must be 1, 2, or %d\n", @@ -737,22 +798,20 @@ store_sensor(struct device *dev, struct device_attribute *da, return count; } -static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); -static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); -static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); +#define sysfs_sensor(offset) \ +static ssize_t show_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show_sensor_reg(dev, buf, offset); \ +} \ +static ssize_t store_regs_sensor_##offset (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ +{ \ + return store_sensor_reg(dev, buf, count, offset); \ +} \ +static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset); -/* I2C devices get this name attribute automatically, but for ISA devices - we must create it by ourselves. */ -static ssize_t -show_name(struct device *dev, struct device_attribute *devattr, char *buf) -{ - struct w83781d_data *data = dev_get_drvdata(dev); - return sprintf(buf, "%s\n", data->client.name); -} -static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); +sysfs_sensor(1); +sysfs_sensor(2); +sysfs_sensor(3); /* This function is called when: * w83781d_driver is inserted (when this module is loaded), for each @@ -766,6 +825,12 @@ w83781d_attach_adapter(struct i2c_adapter *adapter) return i2c_probe(adapter, &addr_data, w83781d_detect); } +static int +w83781d_isa_attach_adapter(struct i2c_adapter *adapter) +{ + return w83781d_detect(adapter, isa_address, -1); +} + /* Assumes that adapter is of I2C, not ISA variety. * OTHERWISE DON'T CALL THIS */ @@ -797,12 +862,12 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, goto ERROR_SC_1; } } - w83781d_write_value(data, W83781D_REG_I2C_SUBADDR, + w83781d_write_value(new_client, W83781D_REG_I2C_SUBADDR, (force_subclients[2] & 0x07) | ((force_subclients[3] & 0x07) << 4)); data->lm75[0]->addr = force_subclients[2]; } else { - val1 = w83781d_read_value(data, W83781D_REG_I2C_SUBADDR); + val1 = w83781d_read_value(new_client, W83781D_REG_I2C_SUBADDR); data->lm75[0]->addr = 0x48 + (val1 & 0x07); } @@ -872,20 +937,20 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind, return err; } -#define IN_UNIT_ATTRS(X) \ - &sensor_dev_attr_in##X##_input.dev_attr.attr, \ - &sensor_dev_attr_in##X##_min.dev_attr.attr, \ - &sensor_dev_attr_in##X##_max.dev_attr.attr +#define IN_UNIT_ATTRS(X) \ + &dev_attr_in##X##_input.attr, \ + &dev_attr_in##X##_min.attr, \ + &dev_attr_in##X##_max.attr -#define FAN_UNIT_ATTRS(X) \ - &sensor_dev_attr_fan##X##_input.dev_attr.attr, \ - &sensor_dev_attr_fan##X##_min.dev_attr.attr, \ - &sensor_dev_attr_fan##X##_div.dev_attr.attr +#define FAN_UNIT_ATTRS(X) \ + &dev_attr_fan##X##_input.attr, \ + &dev_attr_fan##X##_min.attr, \ + &dev_attr_fan##X##_div.attr -#define TEMP_UNIT_ATTRS(X) \ - &sensor_dev_attr_temp##X##_input.dev_attr.attr, \ - &sensor_dev_attr_temp##X##_max.dev_attr.attr, \ - &sensor_dev_attr_temp##X##_max_hyst.dev_attr.attr +#define TEMP_UNIT_ATTRS(X) \ + &dev_attr_temp##X##_input.attr, \ + &dev_attr_temp##X##_max.attr, \ + &dev_attr_temp##X##_max_hyst.attr static struct attribute* w83781d_attributes[] = { IN_UNIT_ATTRS(0), @@ -915,115 +980,91 @@ static struct attribute *w83781d_attributes_opt[] = { IN_UNIT_ATTRS(7), IN_UNIT_ATTRS(8), TEMP_UNIT_ATTRS(3), - &sensor_dev_attr_pwm1.dev_attr.attr, - &sensor_dev_attr_pwm2.dev_attr.attr, - &sensor_dev_attr_pwm3.dev_attr.attr, - &sensor_dev_attr_pwm4.dev_attr.attr, + &dev_attr_pwm1.attr, + &dev_attr_pwm2.attr, &dev_attr_pwm2_enable.attr, - &sensor_dev_attr_temp1_type.dev_attr.attr, - &sensor_dev_attr_temp2_type.dev_attr.attr, - &sensor_dev_attr_temp3_type.dev_attr.attr, + &dev_attr_pwm3.attr, + &dev_attr_pwm4.attr, + &dev_attr_temp1_type.attr, + &dev_attr_temp2_type.attr, + &dev_attr_temp3_type.attr, NULL }; static const struct attribute_group w83781d_group_opt = { .attrs = w83781d_attributes_opt, }; -/* No clean up is done on error, it's up to the caller */ -static int -w83781d_create_files(struct device *dev, int kind, int is_isa) -{ - int err; - - if ((err = sysfs_create_group(&dev->kobj, &w83781d_group))) - return err; - - if (kind != w83783s) { - if ((err = device_create_file(dev, - &sensor_dev_attr_in1_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in1_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in1_max.dev_attr))) - return err; - } - if (kind != as99127f && kind != w83781d && kind != w83783s) { - if ((err = device_create_file(dev, - &sensor_dev_attr_in7_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in7_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in7_max.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in8_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in8_min.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_in8_max.dev_attr))) - return err; - } - if (kind != w83783s) { - if ((err = device_create_file(dev, - &sensor_dev_attr_temp3_input.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_temp3_max.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_temp3_max_hyst.dev_attr))) - return err; - } - - if (kind != w83781d && kind != as99127f) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm1.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm2.dev_attr)) - || (err = device_create_file(dev, &dev_attr_pwm2_enable))) - return err; - } - if (kind == w83782d && !is_isa) { - if ((err = device_create_file(dev, - &sensor_dev_attr_pwm3.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_pwm4.dev_attr))) - return err; - } - - if (kind != as99127f && kind != w83781d) { - if ((err = device_create_file(dev, - &sensor_dev_attr_temp1_type.dev_attr)) - || (err = device_create_file(dev, - &sensor_dev_attr_temp2_type.dev_attr))) - return err; - if (kind != w83783s) { - if ((err = device_create_file(dev, - &sensor_dev_attr_temp3_type.dev_attr))) - return err; - } - } - - if (is_isa) { - err = device_create_file(&pdev->dev, &dev_attr_name); - if (err) - return err; - } - - return 0; -} - static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind) { - int val1 = 0, val2; + int i = 0, val1 = 0, val2; struct i2c_client *client; struct device *dev; struct w83781d_data *data; int err; const char *client_name = ""; + int is_isa = i2c_is_isa_adapter(adapter); enum vendor { winbond, asus } vendid; - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { + if (!is_isa + && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { err = -EINVAL; - goto ERROR1; + goto ERROR0; + } + + /* Prevent users from forcing a kind for a bus it isn't supposed + to possibly be on */ + if (is_isa && (kind == as99127f || kind == w83783s)) { + dev_err(&adapter->dev, + "Cannot force I2C-only chip for ISA address 0x%02x.\n", + address); + err = -EINVAL; + goto ERROR0; + } + + if (is_isa) + if (!request_region(address, W83781D_EXTENT, + w83781d_isa_driver.driver.name)) { + dev_dbg(&adapter->dev, "Request of region " + "0x%x-0x%x for w83781d failed\n", address, + address + W83781D_EXTENT - 1); + err = -EBUSY; + goto ERROR0; + } + + /* Probe whether there is anything available on this address. Already + done for SMBus clients */ + if (kind < 0) { + if (is_isa) { + +#define REALLY_SLOW_IO + /* We need the timeouts for at least some LM78-like + chips. But only if we read 'undefined' registers. */ + i = inb_p(address + 1); + if (inb_p(address + 2) != i + || inb_p(address + 3) != i + || inb_p(address + 7) != i) { + dev_dbg(&adapter->dev, "Detection of w83781d " + "chip failed at step 1\n"); + err = -ENODEV; + goto ERROR1; + } +#undef REALLY_SLOW_IO + + /* Let's just hope nothing breaks here */ + i = inb_p(address + 5) & 0x7f; + outb_p(~i & 0x7f, address + 5); + val2 = inb_p(address + 5) & 0x7f; + if (val2 != (~i & 0x7f)) { + outb_p(i, address + 5); + dev_dbg(&adapter->dev, "Detection of w83781d " + "chip failed at step 2 (0x%x != " + "0x%x at 0x%x)\n", val2, ~i & 0x7f, + address + 5); + err = -ENODEV; + goto ERROR1; + } + } } /* OK. For now, we presume we have a valid client. We now create the @@ -1040,7 +1081,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) client->addr = address; mutex_init(&data->lock); client->adapter = adapter; - client->driver = &w83781d_driver; + client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver; + client->flags = 0; dev = &client->dev; /* Now, we do the remaining detection. */ @@ -1050,14 +1092,14 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) force_*=... parameter, and the Winbond will be reset to the right bank. */ if (kind < 0) { - if (w83781d_read_value(data, W83781D_REG_CONFIG) & 0x80) { + if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) { dev_dbg(&adapter->dev, "Detection of w83781d chip " "failed at step 3\n"); err = -ENODEV; goto ERROR2; } - val1 = w83781d_read_value(data, W83781D_REG_BANK); - val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN); + val1 = w83781d_read_value(client, W83781D_REG_BANK); + val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN); /* Check for Winbond or Asus ID if in bank 0 */ if ((!(val1 & 0x07)) && (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)) @@ -1069,10 +1111,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) } /* If Winbond SMBus, check address at 0x48. Asus doesn't support, except for as99127f rev.2 */ - if ((!(val1 & 0x80) && (val2 == 0xa3)) || - ((val1 & 0x80) && (val2 == 0x5c))) { + if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) || + ((val1 & 0x80) && (val2 == 0x5c)))) { if (w83781d_read_value - (data, W83781D_REG_I2C_ADDR) != address) { + (client, W83781D_REG_I2C_ADDR) != address) { dev_dbg(&adapter->dev, "Detection of w83781d " "chip failed at step 5\n"); err = -ENODEV; @@ -1083,14 +1125,14 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) /* We have either had a force parameter, or we have already detected the Winbond. Put it now into bank 0 and Vendor ID High Byte */ - w83781d_write_value(data, W83781D_REG_BANK, - (w83781d_read_value(data, W83781D_REG_BANK) + w83781d_write_value(client, W83781D_REG_BANK, + (w83781d_read_value(client, W83781D_REG_BANK) & 0x78) | 0x80); /* Determine the chip type. */ if (kind <= 0) { /* get vendor ID */ - val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN); + val2 = w83781d_read_value(client, W83781D_REG_CHIPMAN); if (val2 == 0x5c) vendid = winbond; else if (val2 == 0x12) @@ -1102,16 +1144,17 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) goto ERROR2; } - val1 = w83781d_read_value(data, W83781D_REG_WCHIPID); + val1 = w83781d_read_value(client, W83781D_REG_WCHIPID); if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond) kind = w83781d; else if (val1 == 0x30 && vendid == winbond) kind = w83782d; - else if (val1 == 0x40 && vendid == winbond && address == 0x2d) + else if (val1 == 0x40 && vendid == winbond && !is_isa + && address == 0x2d) kind = w83783s; else if (val1 == 0x21 && vendid == winbond) kind = w83627hf; - else if (val1 == 0x31 && address >= 0x28) + else if (val1 == 0x31 && !is_isa && address >= 0x28) kind = as99127f; else { if (kind == 0) @@ -1139,23 +1182,86 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) strlcpy(client->name, client_name, I2C_NAME_SIZE); data->type = kind; + data->valid = 0; + mutex_init(&data->update_lock); + /* Tell the I2C layer a new client has arrived */ if ((err = i2c_attach_client(client))) goto ERROR2; /* attach secondary i2c lm75-like clients */ - if ((err = w83781d_detect_subclients(adapter, address, - kind, client))) - goto ERROR3; + if (!is_isa) { + if ((err = w83781d_detect_subclients(adapter, address, + kind, client))) + goto ERROR3; + } else { + data->lm75[0] = NULL; + data->lm75[1] = NULL; + } /* Initialize the chip */ - w83781d_init_device(dev); + w83781d_init_client(client); + + /* A few vars need to be filled upon startup */ + for (i = 1; i <= 3; i++) { + data->fan_min[i - 1] = w83781d_read_value(client, + W83781D_REG_FAN_MIN(i)); + } + if (kind != w83781d && kind != as99127f) + for (i = 0; i < 4; i++) + data->pwmenable[i] = 1; /* Register sysfs hooks */ - err = w83781d_create_files(dev, kind, 0); - if (err) + if ((err = sysfs_create_group(&dev->kobj, &w83781d_group))) goto ERROR4; + if (kind != w83783s) { + if ((err = device_create_file(dev, &dev_attr_in1_input)) + || (err = device_create_file(dev, &dev_attr_in1_min)) + || (err = device_create_file(dev, &dev_attr_in1_max))) + goto ERROR4; + } + if (kind != as99127f && kind != w83781d && kind != w83783s) { + if ((err = device_create_file(dev, &dev_attr_in7_input)) + || (err = device_create_file(dev, &dev_attr_in7_min)) + || (err = device_create_file(dev, &dev_attr_in7_max)) + || (err = device_create_file(dev, &dev_attr_in8_input)) + || (err = device_create_file(dev, &dev_attr_in8_min)) + || (err = device_create_file(dev, &dev_attr_in8_max))) + goto ERROR4; + } + if (kind != w83783s) { + if ((err = device_create_file(dev, &dev_attr_temp3_input)) + || (err = device_create_file(dev, &dev_attr_temp3_max)) + || (err = device_create_file(dev, + &dev_attr_temp3_max_hyst))) + goto ERROR4; + } + + if (kind != w83781d && kind != as99127f) { + if ((err = device_create_file(dev, &dev_attr_pwm1)) + || (err = device_create_file(dev, &dev_attr_pwm2)) + || (err = device_create_file(dev, &dev_attr_pwm2_enable))) + goto ERROR4; + } + if (kind == w83782d && !is_isa) { + if ((err = device_create_file(dev, &dev_attr_pwm3)) + || (err = device_create_file(dev, &dev_attr_pwm4))) + goto ERROR4; + } + + if (kind != as99127f && kind != w83781d) { + if ((err = device_create_file(dev, &dev_attr_temp1_type)) + || (err = device_create_file(dev, + &dev_attr_temp2_type))) + goto ERROR4; + if (kind != w83783s) { + if ((err = device_create_file(dev, + &dev_attr_temp3_type))) + goto ERROR4; + } + } + data->class_dev = hwmon_device_register(dev); if (IS_ERR(data->class_dev)) { err = PTR_ERR(data->class_dev); @@ -1181,6 +1287,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind) ERROR2: kfree(data); ERROR1: + if (is_isa) + release_region(address, W83781D_EXTENT); +ERROR0: return err; } @@ -1196,6 +1305,8 @@ w83781d_detach_client(struct i2c_client *client) sysfs_remove_group(&client->dev.kobj, &w83781d_group); sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt); } + if (i2c_is_isa_client(client)) + release_region(client->addr, W83781D_EXTENT); if ((err = i2c_detach_client(client))) return err; @@ -1211,88 +1322,6 @@ w83781d_detach_client(struct i2c_client *client) return 0; } -static int __devinit -w83781d_isa_probe(struct platform_device *pdev) -{ - int err, reg; - struct w83781d_data *data; - struct resource *res; - const char *name; - - /* Reserve the ISA region */ - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, W83781D_EXTENT, "w83781d")) { - err = -EBUSY; - goto exit; - } - - if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) { - err = -ENOMEM; - goto exit_release_region; - } - mutex_init(&data->lock); - data->client.addr = res->start; - i2c_set_clientdata(&data->client, data); - platform_set_drvdata(pdev, data); - - reg = w83781d_read_value(data, W83781D_REG_WCHIPID); - switch (reg) { - case 0x21: - data->type = w83627hf; - name = "w83627hf"; - break; - case 0x30: - data->type = w83782d; - name = "w83782d"; - break; - default: - data->type = w83781d; - name = "w83781d"; - } - strlcpy(data->client.name, name, I2C_NAME_SIZE); - - /* Initialize the W83781D chip */ - w83781d_init_device(&pdev->dev); - - /* Register sysfs hooks */ - err = w83781d_create_files(&pdev->dev, data->type, 1); - if (err) - goto exit_remove_files; - - data->class_dev = hwmon_device_register(&pdev->dev); - if (IS_ERR(data->class_dev)) { - err = PTR_ERR(data->class_dev); - goto exit_remove_files; - } - - return 0; - - exit_remove_files: - sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); - sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); - device_remove_file(&pdev->dev, &dev_attr_name); - kfree(data); - exit_release_region: - release_region(res->start, W83781D_EXTENT); - exit: - return err; -} - -static int __devexit -w83781d_isa_remove(struct platform_device *pdev) -{ - struct w83781d_data *data = platform_get_drvdata(pdev); - - hwmon_device_unregister(data->class_dev); - sysfs_remove_group(&pdev->dev.kobj, &w83781d_group); - sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt); - device_remove_file(&pdev->dev, &dev_attr_name); - release_region(data->client.addr, W83781D_EXTENT); - kfree(data); - - return 0; -} - /* The SMBus locks itself, usually, but nothing may access the Winbond between bank switches. ISA access must always be locked explicitly! We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks, @@ -1300,14 +1329,14 @@ w83781d_isa_remove(struct platform_device *pdev) There are some ugly typecasts here, but the good news is - they should nowhere else be necessary! */ static int -w83781d_read_value(struct w83781d_data *data, u16 reg) +w83781d_read_value(struct i2c_client *client, u16 reg) { - struct i2c_client *client = &data->client; + struct w83781d_data *data = i2c_get_clientdata(client); int res, word_sized, bank; struct i2c_client *cl; mutex_lock(&data->lock); - if (!client->driver) { /* ISA device */ + if (i2c_is_isa_client(client)) { word_sized = (((reg & 0xff00) == 0x100) || ((reg & 0xff00) == 0x200)) && (((reg & 0x00ff) == 0x50) @@ -1369,14 +1398,14 @@ w83781d_read_value(struct w83781d_data *data, u16 reg) } static int -w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value) +w83781d_write_value(struct i2c_client *client, u16 reg, u16 value) { - struct i2c_client *client = &data->client; + struct w83781d_data *data = i2c_get_clientdata(client); int word_sized, bank; struct i2c_client *cl; mutex_lock(&data->lock); - if (!client->driver) { /* ISA device */ + if (i2c_is_isa_client(client)) { word_sized = (((reg & 0xff00) == 0x100) || ((reg & 0xff00) == 0x200)) && (((reg & 0x00ff) == 0x53) @@ -1433,18 +1462,13 @@ w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value) } static void -w83781d_init_device(struct device *dev) +w83781d_init_client(struct i2c_client *client) { - struct w83781d_data *data = dev_get_drvdata(dev); + struct w83781d_data *data = i2c_get_clientdata(client); int i, p; int type = data->type; u8 tmp; - if (type == w83627hf) - dev_info(dev, "The W83627HF chip is better supported by the " - "w83627hf driver, support will be dropped from the " - "w83781d driver soon\n"); - if (reset && type != as99127f) { /* this resets registers we don't have documentation for on the as99127f */ /* Resetting the chip has been the default for a long time, @@ -1453,42 +1477,42 @@ w83781d_init_device(struct device *dev) It might even go away if nobody reports it as being useful, as I see very little reason why this would be needed at all. */ - dev_info(dev, "If reset=1 solved a problem you were " + dev_info(&client->dev, "If reset=1 solved a problem you were " "having, please report!\n"); /* save these registers */ - i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); - p = w83781d_read_value(data, W83781D_REG_PWMCLK12); + i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); + p = w83781d_read_value(client, W83781D_REG_PWMCLK12); /* Reset all except Watchdog values and last conversion values This sets fan-divs to 2, among others */ - w83781d_write_value(data, W83781D_REG_CONFIG, 0x80); + w83781d_write_value(client, W83781D_REG_CONFIG, 0x80); /* Restore the registers and disable power-on abnormal beep. This saves FAN 1/2/3 input/output values set by BIOS. */ - w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); - w83781d_write_value(data, W83781D_REG_PWMCLK12, p); + w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80); + w83781d_write_value(client, W83781D_REG_PWMCLK12, p); /* Disable master beep-enable (reset turns it on). Individual beep_mask should be reset to off but for some reason disabling this bit helps some people not get beeped */ - w83781d_write_value(data, W83781D_REG_BEEP_INTS2, 0); + w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0); } /* Disable power-on abnormal beep, as advised by the datasheet. Already done if reset=1. */ if (init && !reset && type != as99127f) { - i = w83781d_read_value(data, W83781D_REG_BEEP_CONFIG); - w83781d_write_value(data, W83781D_REG_BEEP_CONFIG, i | 0x80); + i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); + w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80); } data->vrm = vid_which_vrm(); if ((type != w83781d) && (type != as99127f)) { - tmp = w83781d_read_value(data, W83781D_REG_SCFG1); + tmp = w83781d_read_value(client, W83781D_REG_SCFG1); for (i = 1; i <= 3; i++) { if (!(tmp & BIT_SCFG1[i - 1])) { data->sens[i - 1] = W83781D_DEFAULT_BETA; } else { if (w83781d_read_value - (data, + (client, W83781D_REG_SCFG2) & BIT_SCFG2[i - 1]) data->sens[i - 1] = 1; else @@ -1501,46 +1525,38 @@ w83781d_init_device(struct device *dev) if (init && type != as99127f) { /* Enable temp2 */ - tmp = w83781d_read_value(data, W83781D_REG_TEMP2_CONFIG); + tmp = w83781d_read_value(client, W83781D_REG_TEMP2_CONFIG); if (tmp & 0x01) { - dev_warn(dev, "Enabling temp2, readings " + dev_warn(&client->dev, "Enabling temp2, readings " "might not make sense\n"); - w83781d_write_value(data, W83781D_REG_TEMP2_CONFIG, + w83781d_write_value(client, W83781D_REG_TEMP2_CONFIG, tmp & 0xfe); } /* Enable temp3 */ if (type != w83783s) { - tmp = w83781d_read_value(data, + tmp = w83781d_read_value(client, W83781D_REG_TEMP3_CONFIG); if (tmp & 0x01) { - dev_warn(dev, "Enabling temp3, " + dev_warn(&client->dev, "Enabling temp3, " "readings might not make sense\n"); - w83781d_write_value(data, + w83781d_write_value(client, W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); } } } /* Start monitoring */ - w83781d_write_value(data, W83781D_REG_CONFIG, - (w83781d_read_value(data, + w83781d_write_value(client, W83781D_REG_CONFIG, + (w83781d_read_value(client, W83781D_REG_CONFIG) & 0xf7) | 0x01); - - /* A few vars need to be filled upon startup */ - for (i = 0; i < 3; i++) { - data->fan_min[i] = w83781d_read_value(data, - W83781D_REG_FAN_MIN(i)); - } - - mutex_init(&data->update_lock); } static struct w83781d_data *w83781d_update_device(struct device *dev) { - struct w83781d_data *data = dev_get_drvdata(dev); - struct i2c_client *client = &data->client; + struct i2c_client *client = to_i2c_client(dev); + struct w83781d_data *data = i2c_get_clientdata(client); int i; mutex_lock(&data->update_lock); @@ -1553,97 +1569,98 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) if (data->type == w83783s && i == 1) continue; /* 783S has no in1 */ data->in[i] = - w83781d_read_value(data, W83781D_REG_IN(i)); + w83781d_read_value(client, W83781D_REG_IN(i)); data->in_min[i] = - w83781d_read_value(data, W83781D_REG_IN_MIN(i)); + w83781d_read_value(client, W83781D_REG_IN_MIN(i)); data->in_max[i] = - w83781d_read_value(data, W83781D_REG_IN_MAX(i)); + w83781d_read_value(client, W83781D_REG_IN_MAX(i)); if ((data->type != w83782d) && (data->type != w83627hf) && (i == 6)) break; } - for (i = 0; i < 3; i++) { - data->fan[i] = - w83781d_read_value(data, W83781D_REG_FAN(i)); - data->fan_min[i] = - w83781d_read_value(data, W83781D_REG_FAN_MIN(i)); + for (i = 1; i <= 3; i++) { + data->fan[i - 1] = + w83781d_read_value(client, W83781D_REG_FAN(i)); + data->fan_min[i - 1] = + w83781d_read_value(client, W83781D_REG_FAN_MIN(i)); } if (data->type != w83781d && data->type != as99127f) { - for (i = 0; i < 4; i++) { - data->pwm[i] = - w83781d_read_value(data, - W83781D_REG_PWM[i]); - if ((data->type != w83782d || !client->driver) - && i == 1) + for (i = 1; i <= 4; i++) { + data->pwm[i - 1] = + w83781d_read_value(client, + W83781D_REG_PWM(i)); + if ((data->type != w83782d + || i2c_is_isa_client(client)) + && i == 2) break; } /* Only PWM2 can be disabled */ - data->pwm2_enable = (w83781d_read_value(data, + data->pwmenable[1] = (w83781d_read_value(client, W83781D_REG_PWMCLK12) & 0x08) >> 3; } - data->temp = w83781d_read_value(data, W83781D_REG_TEMP(1)); + data->temp = w83781d_read_value(client, W83781D_REG_TEMP(1)); data->temp_max = - w83781d_read_value(data, W83781D_REG_TEMP_OVER(1)); + w83781d_read_value(client, W83781D_REG_TEMP_OVER(1)); data->temp_max_hyst = - w83781d_read_value(data, W83781D_REG_TEMP_HYST(1)); + w83781d_read_value(client, W83781D_REG_TEMP_HYST(1)); data->temp_add[0] = - w83781d_read_value(data, W83781D_REG_TEMP(2)); + w83781d_read_value(client, W83781D_REG_TEMP(2)); data->temp_max_add[0] = - w83781d_read_value(data, W83781D_REG_TEMP_OVER(2)); + w83781d_read_value(client, W83781D_REG_TEMP_OVER(2)); data->temp_max_hyst_add[0] = - w83781d_read_value(data, W83781D_REG_TEMP_HYST(2)); + w83781d_read_value(client, W83781D_REG_TEMP_HYST(2)); if (data->type != w83783s) { data->temp_add[1] = - w83781d_read_value(data, W83781D_REG_TEMP(3)); + w83781d_read_value(client, W83781D_REG_TEMP(3)); data->temp_max_add[1] = - w83781d_read_value(data, + w83781d_read_value(client, W83781D_REG_TEMP_OVER(3)); data->temp_max_hyst_add[1] = - w83781d_read_value(data, + w83781d_read_value(client, W83781D_REG_TEMP_HYST(3)); } - i = w83781d_read_value(data, W83781D_REG_VID_FANDIV); + i = w83781d_read_value(client, W83781D_REG_VID_FANDIV); data->vid = i & 0x0f; - data->vid |= (w83781d_read_value(data, + data->vid |= (w83781d_read_value(client, W83781D_REG_CHIPID) & 0x01) << 4; data->fan_div[0] = (i >> 4) & 0x03; data->fan_div[1] = (i >> 6) & 0x03; - data->fan_div[2] = (w83781d_read_value(data, + data->fan_div[2] = (w83781d_read_value(client, W83781D_REG_PIN) >> 6) & 0x03; if ((data->type != w83781d) && (data->type != as99127f)) { - i = w83781d_read_value(data, W83781D_REG_VBAT); + i = w83781d_read_value(client, W83781D_REG_VBAT); data->fan_div[0] |= (i >> 3) & 0x04; data->fan_div[1] |= (i >> 4) & 0x04; data->fan_div[2] |= (i >> 5) & 0x04; } if ((data->type == w83782d) || (data->type == w83627hf)) { - data->alarms = w83781d_read_value(data, + data->alarms = w83781d_read_value(client, W83782D_REG_ALARM1) - | (w83781d_read_value(data, + | (w83781d_read_value(client, W83782D_REG_ALARM2) << 8) - | (w83781d_read_value(data, + | (w83781d_read_value(client, W83782D_REG_ALARM3) << 16); } else if (data->type == w83783s) { - data->alarms = w83781d_read_value(data, + data->alarms = w83781d_read_value(client, W83782D_REG_ALARM1) - | (w83781d_read_value(data, + | (w83781d_read_value(client, W83782D_REG_ALARM2) << 8); } else { /* No real-time status registers, fall back to interrupt status registers */ - data->alarms = w83781d_read_value(data, + data->alarms = w83781d_read_value(client, W83781D_REG_ALARM1) - | (w83781d_read_value(data, + | (w83781d_read_value(client, W83781D_REG_ALARM2) << 8); } - i = w83781d_read_value(data, W83781D_REG_BEEP_INTS2); + i = w83781d_read_value(client, W83781D_REG_BEEP_INTS2); data->beep_enable = i >> 7; data->beep_mask = ((i & 0x7f) << 8) + - w83781d_read_value(data, W83781D_REG_BEEP_INTS1); + w83781d_read_value(client, W83781D_REG_BEEP_INTS1); if ((data->type != w83781d) && (data->type != as99127f)) { data->beep_mask |= - w83781d_read_value(data, + w83781d_read_value(client, W83781D_REG_BEEP_INTS3) << 16; } data->last_updated = jiffies; @@ -1655,133 +1672,6 @@ static struct w83781d_data *w83781d_update_device(struct device *dev) return data; } -/* return 1 if a supported chip is found, 0 otherwise */ -static int __init -w83781d_isa_found(unsigned short address) -{ - int val, save, found = 0; - - if (!request_region(address, W83781D_EXTENT, "w83781d")) - return 0; - -#define REALLY_SLOW_IO - /* We need the timeouts for at least some W83781D-like - chips. But only if we read 'undefined' registers. */ - val = inb_p(address + 1); - if (inb_p(address + 2) != val - || inb_p(address + 3) != val - || inb_p(address + 7) != val) { - pr_debug("w83781d: Detection failed at step 1\n"); - goto release; - } -#undef REALLY_SLOW_IO - - /* We should be able to change the 7 LSB of the address port. The - MSB (busy flag) should be clear initially, set after the write. */ - save = inb_p(address + W83781D_ADDR_REG_OFFSET); - if (save & 0x80) { - pr_debug("w83781d: Detection failed at step 2\n"); - goto release; - } - val = ~save & 0x7f; - outb_p(val, address + W83781D_ADDR_REG_OFFSET); - if (inb_p(address + W83781D_ADDR_REG_OFFSET) != (val | 0x80)) { - outb_p(save, address + W83781D_ADDR_REG_OFFSET); - pr_debug("w83781d: Detection failed at step 3\n"); - goto release; - } - - /* We found a device, now see if it could be a W83781D */ - outb_p(W83781D_REG_CONFIG, address + W83781D_ADDR_REG_OFFSET); - val = inb_p(address + W83781D_DATA_REG_OFFSET); - if (val & 0x80) { - pr_debug("w83781d: Detection failed at step 4\n"); - goto release; - } - outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET); - save = inb_p(address + W83781D_DATA_REG_OFFSET); - outb_p(W83781D_REG_CHIPMAN, address + W83781D_ADDR_REG_OFFSET); - val = inb_p(address + W83781D_DATA_REG_OFFSET); - if ((!(save & 0x80) && (val != 0xa3)) - || ((save & 0x80) && (val != 0x5c))) { - pr_debug("w83781d: Detection failed at step 5\n"); - goto release; - } - outb_p(W83781D_REG_I2C_ADDR, address + W83781D_ADDR_REG_OFFSET); - val = inb_p(address + W83781D_DATA_REG_OFFSET); - if (val < 0x03 || val > 0x77) { /* Not a valid I2C address */ - pr_debug("w83781d: Detection failed at step 6\n"); - goto release; - } - - /* The busy flag should be clear again */ - if (inb_p(address + W83781D_ADDR_REG_OFFSET) & 0x80) { - pr_debug("w83781d: Detection failed at step 7\n"); - goto release; - } - - /* Determine the chip type */ - outb_p(W83781D_REG_BANK, address + W83781D_ADDR_REG_OFFSET); - save = inb_p(address + W83781D_DATA_REG_OFFSET); - outb_p(save & 0xf8, address + W83781D_DATA_REG_OFFSET); - outb_p(W83781D_REG_WCHIPID, address + W83781D_ADDR_REG_OFFSET); - val = inb_p(address + W83781D_DATA_REG_OFFSET); - if ((val & 0xfe) == 0x10 /* W83781D */ - || val == 0x30 /* W83782D */ - || val == 0x21) /* W83627HF */ - found = 1; - - if (found) - pr_info("w83781d: Found a %s chip at %#x\n", - val == 0x21 ? "W83627HF" : - val == 0x30 ? "W83782D" : "W83781D", (int)address); - - release: - release_region(address, W83781D_EXTENT); - return found; -} - -static int __init -w83781d_isa_device_add(unsigned short address) -{ - struct resource res = { - .start = address, - .end = address + W83781D_EXTENT, - .name = "w83781d", - .flags = IORESOURCE_IO, - }; - int err; - - pdev = platform_device_alloc("w83781d", address); - if (!pdev) { - err = -ENOMEM; - printk(KERN_ERR "w83781d: Device allocation failed\n"); - goto exit; - } - - err = platform_device_add_resources(pdev, &res, 1); - if (err) { - printk(KERN_ERR "w83781d: Device resource addition failed " - "(%d)\n", err); - goto exit_device_put; - } - - err = platform_device_add(pdev); - if (err) { - printk(KERN_ERR "w83781d: Device addition failed (%d)\n", - err); - goto exit_device_put; - } - - return 0; - - exit_device_put: - platform_device_put(pdev); - exit: - pdev = NULL; - return err; -} - static int __init sensors_w83781d_init(void) { @@ -1789,36 +1679,21 @@ sensors_w83781d_init(void) res = i2c_add_driver(&w83781d_driver); if (res) - goto exit; - - if (w83781d_isa_found(isa_address)) { - res = platform_driver_register(&w83781d_isa_driver); - if (res) - goto exit_unreg_i2c_driver; + return res; - /* Sets global pdev as a side effect */ - res = w83781d_isa_device_add(isa_address); - if (res) - goto exit_unreg_isa_driver; - } + /* Don't exit if this one fails, we still want the I2C variants + to work! */ + if (i2c_isa_add_driver(&w83781d_isa_driver)) + isa_address = 0; return 0; - - exit_unreg_isa_driver: - platform_driver_unregister(&w83781d_isa_driver); - exit_unreg_i2c_driver: - i2c_del_driver(&w83781d_driver); - exit: - return res; } static void __exit sensors_w83781d_exit(void) { - if (pdev) { - platform_device_unregister(pdev); - platform_driver_unregister(&w83781d_isa_driver); - } + if (isa_address) + i2c_isa_del_driver(&w83781d_isa_driver); i2c_del_driver(&w83781d_driver); } diff --git a/trunk/drivers/i2c/Kconfig b/trunk/drivers/i2c/Kconfig index 434a61b415a3..11935f66fcd8 100644 --- a/trunk/drivers/i2c/Kconfig +++ b/trunk/drivers/i2c/Kconfig @@ -2,7 +2,9 @@ # I2C subsystem configuration # -menuconfig I2C +menu "I2C support" + +config I2C tristate "I2C support" ---help--- I2C (pronounce: I-square-C) is a slow serial bus protocol used in @@ -20,14 +22,9 @@ menuconfig I2C This I2C support can also be built as a module. If so, the module will be called i2c-core. -if I2C - -config I2C_BOARDINFO - boolean - default y - config I2C_CHARDEV tristate "I2C device interface" + depends on I2C help Say Y here to use i2c-* device files, usually found in the /dev directory on your system. They make it possible to have user-space @@ -43,6 +40,7 @@ source drivers/i2c/chips/Kconfig config I2C_DEBUG_CORE bool "I2C Core debugging messages" + depends on I2C help Say Y here if you want the I2C core to produce a bunch of debug messages to the system log. Select this if you are having a @@ -50,6 +48,7 @@ config I2C_DEBUG_CORE config I2C_DEBUG_ALGO bool "I2C Algorithm debugging messages" + depends on I2C help Say Y here if you want the I2C algorithm drivers to produce a bunch of debug messages to the system log. Select this if you are having @@ -58,6 +57,7 @@ config I2C_DEBUG_ALGO config I2C_DEBUG_BUS bool "I2C Bus debugging messages" + depends on I2C help Say Y here if you want the I2C bus drivers to produce a bunch of debug messages to the system log. Select this if you are having @@ -66,10 +66,12 @@ config I2C_DEBUG_BUS config I2C_DEBUG_CHIP bool "I2C Chip debugging messages" + depends on I2C help Say Y here if you want the I2C chip drivers to produce a bunch of debug messages to the system log. Select this if you are having a problem with I2C support and want to see more of what is going on. -endif # I2C +endmenu + diff --git a/trunk/drivers/i2c/Makefile b/trunk/drivers/i2c/Makefile index ba26e6cbe74e..71c5a854ac5d 100644 --- a/trunk/drivers/i2c/Makefile +++ b/trunk/drivers/i2c/Makefile @@ -2,7 +2,6 @@ # Makefile for the i2c core. # -obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o obj-$(CONFIG_I2C) += i2c-core.o obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o obj-y += busses/ chips/ algos/ diff --git a/trunk/drivers/i2c/algos/Kconfig b/trunk/drivers/i2c/algos/Kconfig index 58899078810b..af0203409dd1 100644 --- a/trunk/drivers/i2c/algos/Kconfig +++ b/trunk/drivers/i2c/algos/Kconfig @@ -3,9 +3,11 @@ # menu "I2C Algorithms" + depends on I2C config I2C_ALGOBIT tristate "I2C bit-banging interfaces" + depends on I2C help This allows you to use a range of I2C adapters called bit-banging adapters. Say Y if you own an I2C adapter belonging to this class @@ -16,6 +18,7 @@ config I2C_ALGOBIT config I2C_ALGOPCF tristate "I2C PCF 8584 interfaces" + depends on I2C help This allows you to use a range of I2C adapters called PCF adapters. Say Y if you own an I2C adapter belonging to this class and then say @@ -26,6 +29,7 @@ config I2C_ALGOPCF config I2C_ALGOPCA tristate "I2C PCA 9564 interfaces" + depends on I2C help This allows you to use a range of I2C adapters called PCA adapters. Say Y if you own an I2C adapter belonging to this class and then say @@ -36,11 +40,11 @@ config I2C_ALGOPCA config I2C_ALGO8XX tristate "MPC8xx CPM I2C interface" - depends on 8xx + depends on 8xx && I2C config I2C_ALGO_SGI tristate "I2C SGI interfaces" - depends on SGI_IP22 || SGI_IP32 || X86_VISWS + depends on I2C && (SGI_IP22 || SGI_IP32 || X86_VISWS) help Supports the SGI interfaces like the ones found on SGI Indy VINO or SGI O2 MACE. diff --git a/trunk/drivers/i2c/algos/i2c-algo-bit.c b/trunk/drivers/i2c/algos/i2c-algo-bit.c index 8a5f5825bb72..95aa5395a5be 100644 --- a/trunk/drivers/i2c/algos/i2c-algo-bit.c +++ b/trunk/drivers/i2c/algos/i2c-algo-bit.c @@ -33,30 +33,19 @@ /* ----- global defines ----------------------------------------------- */ +#define DEB(x) if (i2c_debug>=1) x; +#define DEB2(x) if (i2c_debug>=2) x; +#define DEBSTAT(x) if (i2c_debug>=3) x; /* print several statistical values*/ +#define DEBPROTO(x) if (i2c_debug>=9) { x; } + /* debug the protocol by showing transferred bits */ -#ifdef DEBUG -#define bit_dbg(level, dev, format, args...) \ - do { \ - if (i2c_debug >= level) \ - dev_dbg(dev, format, ##args); \ - } while (0) -#else -#define bit_dbg(level, dev, format, args...) \ - do {} while (0) -#endif /* DEBUG */ /* ----- global variables --------------------------------------------- */ +/* module parameters: + */ +static int i2c_debug; static int bit_test; /* see if the line-setting functions work */ -module_param(bit_test, bool, 0); -MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck"); - -#ifdef DEBUG -static int i2c_debug = 1; -module_param(i2c_debug, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(i2c_debug, - "debug level - 0 off; 1 normal; 2 verbose; 3 very verbose"); -#endif /* --- setting states on the bus with the right timing: --------------- */ @@ -68,19 +57,19 @@ MODULE_PARM_DESC(i2c_debug, static inline void sdalo(struct i2c_algo_bit_data *adap) { setsda(adap,0); - udelay((adap->udelay + 1) / 2); + udelay(adap->udelay); } static inline void sdahi(struct i2c_algo_bit_data *adap) { setsda(adap,1); - udelay((adap->udelay + 1) / 2); + udelay(adap->udelay); } static inline void scllo(struct i2c_algo_bit_data *adap) { setscl(adap,0); - udelay(adap->udelay / 2); + udelay(adap->udelay); } /* @@ -109,11 +98,7 @@ static int sclhi(struct i2c_algo_bit_data *adap) } cond_resched(); } -#ifdef DEBUG - if (jiffies != start && i2c_debug >= 3) - pr_debug("i2c-algo-bit: needed %ld jiffies for SCL to go " - "high\n", jiffies - start); -#endif + DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start)); done: udelay(adap->udelay); @@ -125,29 +110,30 @@ static int sclhi(struct i2c_algo_bit_data *adap) static void i2c_start(struct i2c_algo_bit_data *adap) { /* assert: scl, sda are high */ - setsda(adap, 0); - udelay(adap->udelay); + DEBPROTO(printk("S ")); + sdalo(adap); scllo(adap); } static void i2c_repstart(struct i2c_algo_bit_data *adap) { - /* assert: scl is low */ - sdahi(adap); + /* scl, sda may not be high */ + DEBPROTO(printk(" Sr ")); + setsda(adap,1); sclhi(adap); - setsda(adap, 0); - udelay(adap->udelay); + + sdalo(adap); scllo(adap); } static void i2c_stop(struct i2c_algo_bit_data *adap) { + DEBPROTO(printk("P\n")); /* assert: scl is low */ sdalo(adap); sclhi(adap); - setsda(adap, 1); - udelay(adap->udelay); + sdahi(adap); } @@ -159,7 +145,7 @@ static void i2c_stop(struct i2c_algo_bit_data *adap) * 0 if the device did not ack * -ETIMEDOUT if an error occurred (while raising the scl line) */ -static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) +static int i2c_outb(struct i2c_adapter *i2c_adap, char c) { int i; int sb; @@ -168,32 +154,34 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) /* assert: scl is low */ for ( i=7 ; i>=0 ; i-- ) { - sb = (c >> i) & 1; + sb = c & ( 1 << i ); setsda(adap,sb); - udelay((adap->udelay + 1) / 2); + udelay(adap->udelay); + DEBPROTO(printk(KERN_DEBUG "%d",sb!=0)); if (sclhi(adap)<0) { /* timed out */ - bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " - "timeout at bit #%d\n", (int)c, i); + sdahi(adap); /* we don't want to block the net */ + DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i)); return -ETIMEDOUT; }; /* do arbitration here: * if ( sb && ! getsda(adap) ) -> ouch! Get out of here. */ - scllo(adap); + setscl(adap, 0 ); + udelay(adap->udelay); } sdahi(adap); if (sclhi(adap)<0){ /* timeout */ - bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " - "timeout at ack\n", (int)c); - return -ETIMEDOUT; + DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at ack\n", c&0xff)); + return -ETIMEDOUT; }; /* read ack: SDA should be pulled down by slave */ - ack = !getsda(adap); /* ack: sda is pulled low -> success */ - bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, - ack ? "A" : "NA"); + ack=getsda(adap); /* ack: sda is pulled low ->success. */ + DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x , getsda() = %d\n", c & 0xff, ack)); + DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) ); + DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") ); scllo(adap); - return ack; + return 0==ack; /* return 1 if device acked */ /* assert: scl is low (sda undef) */ } @@ -210,18 +198,19 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) sdahi(adap); for (i=0;i<8;i++) { if (sclhi(adap)<0) { /* timeout */ - bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " - "#%d\n", 7 - i); + DEB2(printk(KERN_DEBUG " i2c_inb: timeout at bit #%d\n", 7-i)); return -ETIMEDOUT; }; indata *= 2; if ( getsda(adap) ) indata |= 0x01; - setscl(adap, 0); - udelay(i == 7 ? adap->udelay / 2 : adap->udelay); + scllo(adap); } /* assert: scl is low */ - return indata; + DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff)); + + DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff)); + return (int) (indata & 0xff); } /* @@ -232,67 +221,73 @@ static int test_bus(struct i2c_algo_bit_data *adap, char* name) { int scl,sda; if (adap->getscl==NULL) - pr_info("%s: Testing SDA only, SCL is not readable\n", name); + printk(KERN_INFO "i2c-algo-bit.o: Testing SDA only, " + "SCL is not readable.\n"); sda=getsda(adap); scl=(adap->getscl==NULL?1:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (0) scl=%d, sda=%d\n",scl,sda); if (!scl || !sda ) { - printk(KERN_WARNING "%s: bus seems to be busy\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: %s seems to be busy.\n", name); goto bailout; } sdalo(adap); sda=getsda(adap); scl=(adap->getscl==NULL?1:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (1) scl=%d, sda=%d\n",scl,sda); if ( 0 != sda ) { - printk(KERN_WARNING "%s: SDA stuck high!\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck high!\n"); goto bailout; } if ( 0 == scl ) { - printk(KERN_WARNING "%s: SCL unexpected low " - "while pulling SDA low!\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " + "while pulling SDA low!\n"); goto bailout; } sdahi(adap); sda=getsda(adap); scl=(adap->getscl==NULL?1:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (2) scl=%d, sda=%d\n",scl,sda); if ( 0 == sda ) { - printk(KERN_WARNING "%s: SDA stuck low!\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: SDA stuck low!\n"); goto bailout; } if ( 0 == scl ) { - printk(KERN_WARNING "%s: SCL unexpected low " - "while pulling SDA high!\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: SCL unexpected low " + "while pulling SDA high!\n"); goto bailout; } scllo(adap); sda=getsda(adap); scl=(adap->getscl==NULL?0:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (3) scl=%d, sda=%d\n",scl,sda); if ( 0 != scl ) { - printk(KERN_WARNING "%s: SCL stuck high!\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck high!\n"); goto bailout; } if ( 0 == sda ) { - printk(KERN_WARNING "%s: SDA unexpected low " - "while pulling SCL low!\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " + "while pulling SCL low!\n"); goto bailout; } sclhi(adap); sda=getsda(adap); scl=(adap->getscl==NULL?1:getscl(adap)); + printk(KERN_DEBUG "i2c-algo-bit.o: (4) scl=%d, sda=%d\n",scl,sda); if ( 0 == scl ) { - printk(KERN_WARNING "%s: SCL stuck low!\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: SCL stuck low!\n"); goto bailout; } if ( 0 == sda ) { - printk(KERN_WARNING "%s: SDA unexpected low " - "while pulling SCL high!\n", name); + printk(KERN_WARNING "i2c-algo-bit.o: SDA unexpected low " + "while pulling SCL high!\n"); goto bailout; } - pr_info("%s: Test OK\n", name); + printk(KERN_INFO "i2c-algo-bit.o: %s passed test.\n",name); return 0; bailout: sdahi(adap); @@ -317,39 +312,44 @@ static int try_address(struct i2c_adapter *i2c_adap, int i,ret = -1; for (i=0;i<=retries;i++) { ret = i2c_outb(i2c_adap,addr); - if (ret == 1 || i == retries) - break; - bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); + if (ret==1) + break; /* success! */ i2c_stop(adap); - udelay(adap->udelay); - yield(); - bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); + udelay(5/*adap->udelay*/); + if (i==retries) /* no success */ + break; i2c_start(adap); + udelay(adap->udelay); } - if (i && ret) - bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at " - "0x%02x: %s\n", i + 1, - addr & 1 ? "read from" : "write to", addr >> 1, - ret == 1 ? "success" : "failed, timeout?"); + DEB2(if (i) + printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n", + i+1, addr & 1 ? "read" : "write", addr>>1, + ret==1 ? "success" : ret==0 ? "no ack" : "failed, timeout?" ) + ); return ret; } static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { - const unsigned char *temp = msg->buf; + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; + char c; + const char *temp = msg->buf; int count = msg->len; unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; int retval; int wrcount=0; while (count > 0) { - retval = i2c_outb(i2c_adap, *temp); + c = *temp; + DEB2(dev_dbg(&i2c_adap->dev, "sendbytes: writing %2.2X\n", c&0xff)); + retval = i2c_outb(i2c_adap,c); if ((retval>0) || (nak_ok && (retval==0))) { /* ok or ignored NAK */ count--; temp++; wrcount++; } else { /* arbitration or no acknowledge */ dev_err(&i2c_adap->dev, "sendbytes: error - bailout.\n"); + i2c_stop(adap); return (retval<0)? retval : -EFAULT; /* got a better one ?? */ } @@ -362,7 +362,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) int inval; int rdcount=0; /* counts bytes read */ struct i2c_algo_bit_data *adap = i2c_adap->algo_data; - unsigned char *temp = msg->buf; + char *temp = msg->buf; int count = msg->len; while (count > 0) { @@ -371,44 +371,30 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) *temp = inval; rdcount++; } else { /* read timed out */ + printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n"); break; } temp++; count--; - if (msg->flags & I2C_M_NO_RD_ACK) { - bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x\n", - inval); + if (msg->flags & I2C_M_NO_RD_ACK) continue; - } - /* assert: sda is high */ - if (count) /* send ack */ - setsda(adap, 0); - udelay((adap->udelay + 1) / 2); - bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x %s\n", inval, - count ? "A" : "NA"); + if ( count > 0 ) { /* send ack */ + sdalo(adap); + DEBPROTO(printk(" Am ")); + } else { + sdahi(adap); /* neg. ack on last byte */ + DEBPROTO(printk(" NAm ")); + } if (sclhi(adap)<0) { /* timeout */ - dev_err(&i2c_adap->dev, "readbytes: timeout at ack\n"); + sdahi(adap); + printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n"); return -ETIMEDOUT; }; scllo(adap); - - /* Some SMBus transactions require that we receive the - transaction length as the first read byte. */ - if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) { - if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { - dev_err(&i2c_adap->dev, "readbytes: invalid " - "block length (%d)\n", inval); - return -EREMOTEIO; - } - /* The original count value accounts for the extra - bytes, that is, either 1 for a regular transaction, - or 2 for a PEC transaction. */ - count += inval; - msg->len += inval; - } + sdahi(adap); } return rdcount; } @@ -435,31 +421,27 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) if ( (flags & I2C_M_TEN) ) { /* a ten bit address */ addr = 0xf0 | (( msg->addr >> 7) & 0x03); - bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); + DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); /* try extended address code...*/ ret = try_address(i2c_adap, addr, retries); if ((ret != 1) && !nak_ok) { - dev_err(&i2c_adap->dev, - "died at extended address code\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } /* the remaining 8 bit address */ ret = i2c_outb(i2c_adap,msg->addr & 0x7f); if ((ret != 1) && !nak_ok) { /* the chip did not ack / xmission error occurred */ - dev_err(&i2c_adap->dev, "died at 2nd address code\n"); + printk(KERN_ERR "died at 2nd address code.\n"); return -EREMOTEIO; } if ( flags & I2C_M_RD ) { - bit_dbg(3, &i2c_adap->dev, "emitting repeated " - "start condition\n"); i2c_repstart(adap); /* okay, now switch into reading mode */ addr |= 0x01; ret = try_address(i2c_adap, addr, retries); if ((ret!=1) && !nak_ok) { - dev_err(&i2c_adap->dev, - "died at repeated address code\n"); + printk(KERN_ERR "died at extended address code.\n"); return -EREMOTEIO; } } @@ -486,62 +468,44 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, int i,ret; unsigned short nak_ok; - bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); i2c_start(adap); for (i=0;iflags & I2C_M_IGNORE_NAK; if (!(pmsg->flags & I2C_M_NOSTART)) { if (i) { - bit_dbg(3, &i2c_adap->dev, "emitting " - "repeated start condition\n"); i2c_repstart(adap); } ret = bit_doAddress(i2c_adap, pmsg); if ((ret != 0) && !nak_ok) { - bit_dbg(1, &i2c_adap->dev, "NAK from " - "device addr 0x%02x msg #%d\n", - msgs[i].addr, i); - goto bailout; + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.2x msg #%d\n" + ,msgs[i].addr,i)); + return (ret<0) ? ret : -EREMOTEIO; } } if (pmsg->flags & I2C_M_RD ) { /* read bytes into buffer*/ ret = readbytes(i2c_adap, pmsg); - if (ret >= 1) - bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", - ret, ret == 1 ? "" : "s"); - if (ret < pmsg->len) { - if (ret >= 0) - ret = -EREMOTEIO; - goto bailout; + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: read %d bytes.\n",ret)); + if (ret < pmsg->len ) { + return (ret<0)? ret : -EREMOTEIO; } } else { /* write bytes from buffer */ ret = sendbytes(i2c_adap, pmsg); - if (ret >= 1) - bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", - ret, ret == 1 ? "" : "s"); - if (ret < pmsg->len) { - if (ret >= 0) - ret = -EREMOTEIO; - goto bailout; + DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: wrote %d bytes.\n",ret)); + if (ret < pmsg->len ) { + return (ret<0) ? ret : -EREMOTEIO; } } } - ret = i; - -bailout: - bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); i2c_stop(adap); - return ret; + return num; } static u32 bit_func(struct i2c_adapter *adap) { return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | - I2C_FUNC_SMBUS_READ_BLOCK_DATA | - I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; } @@ -556,7 +520,7 @@ static const struct i2c_algorithm i2c_bit_algo = { /* * registering functions to load algorithms at runtime */ -static int i2c_bit_prepare_bus(struct i2c_adapter *adap) +int i2c_bit_add_bus(struct i2c_adapter *adap) { struct i2c_algo_bit_data *bit_adap = adap->algo_data; @@ -566,39 +530,25 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap) return -ENODEV; } + DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); + /* register new adapter to i2c module... */ adap->algo = &i2c_bit_algo; adap->timeout = 100; /* default values, should */ adap->retries = 3; /* be replaced by defines */ - return 0; -} - -int i2c_bit_add_bus(struct i2c_adapter *adap) -{ - int err; - - err = i2c_bit_prepare_bus(adap); - if (err) - return err; - return i2c_add_adapter(adap); } EXPORT_SYMBOL(i2c_bit_add_bus); -int i2c_bit_add_numbered_bus(struct i2c_adapter *adap) -{ - int err; - - err = i2c_bit_prepare_bus(adap); - if (err) - return err; - - return i2c_add_numbered_adapter(adap); -} -EXPORT_SYMBOL(i2c_bit_add_numbered_bus); - MODULE_AUTHOR("Simon G. Vogl "); MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm"); MODULE_LICENSE("GPL"); + +module_param(bit_test, bool, 0); +module_param(i2c_debug, int, S_IRUGO | S_IWUSR); + +MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck"); +MODULE_PARM_DESC(i2c_debug, + "debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol"); diff --git a/trunk/drivers/i2c/algos/i2c-algo-sgi.c b/trunk/drivers/i2c/algos/i2c-algo-sgi.c index 6eaf145e1ada..ac2d5053078a 100644 --- a/trunk/drivers/i2c/algos/i2c-algo-sgi.c +++ b/trunk/drivers/i2c/algos/i2c-algo-sgi.c @@ -1,7 +1,6 @@ /* - * i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and - * MACE (SGI O2) chips. - * + * i2c-algo-sgi.c: i2c driver algorithms for SGI adapters. + * * This file is subject to the terms and conditions of the GNU General Public * License version 2 as published by the Free Software Foundation. * @@ -163,8 +162,8 @@ static const struct i2c_algorithm sgi_algo = { .functionality = sgi_func, }; -/* - * registering functions to load algorithms at runtime +/* + * registering functions to load algorithms at runtime */ int i2c_sgi_add_bus(struct i2c_adapter *adap) { diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index 838dc1c19d61..ece31d2c6c64 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -3,10 +3,11 @@ # menu "I2C Hardware Bus support" + depends on I2C config I2C_ALI1535 tristate "ALI 1535" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the SMB Host controller on Acer Labs Inc. (ALI) M1535 South Bridges. The SMB @@ -18,7 +19,7 @@ config I2C_ALI1535 config I2C_ALI1563 tristate "ALI 1563" - depends on PCI && EXPERIMENTAL + depends on I2C && PCI && EXPERIMENTAL help If you say yes to this option, support will be included for the SMB Host controller on Acer Labs Inc. (ALI) M1563 South Bridges. The SMB @@ -30,7 +31,7 @@ config I2C_ALI1563 config I2C_ALI15X3 tristate "ALI 15x3" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the Acer Labs Inc. (ALI) M1514 and M1543 motherboard I2C interfaces. @@ -40,7 +41,7 @@ config I2C_ALI15X3 config I2C_AMD756 tristate "AMD 756/766/768/8111 and nVidia nForce" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the AMD 756/766/768 mainboard I2C interfaces. The driver also includes @@ -65,7 +66,7 @@ config I2C_AMD756_S4882 config I2C_AMD8111 tristate "AMD 8111" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the second (SMBus 2.0) AMD 8111 mainboard I2C interface. @@ -75,14 +76,14 @@ config I2C_AMD8111 config I2C_AT91 tristate "Atmel AT91 I2C Two-Wire interface (TWI)" - depends on ARCH_AT91 && EXPERIMENTAL + depends on I2C && ARCH_AT91 && EXPERIMENTAL help This supports the use of the I2C interface on Atmel AT91 processors. config I2C_AU1550 tristate "Au1550/Au1200 SMBus interface" - depends on SOC_AU1550 || SOC_AU1200 + depends on I2C && (SOC_AU1550 || SOC_AU1200) help If you say yes to this option, support will be included for the Au1550 and Au1200 SMBus interface. @@ -90,25 +91,9 @@ config I2C_AU1550 This driver can also be built as a module. If so, the module will be called i2c-au1550. -config I2C_BLACKFIN_TWI - tristate "Blackfin TWI I2C support" - depends on BF534 || BF536 || BF537 - help - This is the TWI I2C device driver for Blackfin 534/536/537. - This driver can also be built as a module. If so, the module - will be called i2c-bfin-twi. - -config I2C_BLACKFIN_TWI_CLK_KHZ - int "Blackfin TWI I2C clock (kHz)" - depends on I2C_BLACKFIN_TWI - range 10 400 - default 50 - help - The unit of the TWI clock is kHz. - config I2C_ELEKTOR tristate "Elektor ISA card" - depends on ISA && BROKEN_ON_SMP + depends on I2C && ISA && BROKEN_ON_SMP select I2C_ALGOPCF help This supports the PCF8584 ISA bus I2C adapter. Say Y if you own @@ -117,17 +102,9 @@ config I2C_ELEKTOR This support is also available as a module. If so, the module will be called i2c-elektor. -config I2C_GPIO - tristate "GPIO-based bitbanging I2C" - depends on GENERIC_GPIO - select I2C_ALGOBIT - help - This is a very simple bitbanging I2C driver utilizing the - arch-neutral GPIO API to control the SCL and SDA lines. - config I2C_HYDRA tristate "CHRP Apple Hydra Mac I/O I2C interface" - depends on PCI && PPC_CHRP && EXPERIMENTAL + depends on I2C && PCI && PPC_CHRP && EXPERIMENTAL select I2C_ALGOBIT help This supports the use of the I2C interface in the Apple Hydra Mac @@ -139,7 +116,7 @@ config I2C_HYDRA config I2C_I801 tristate "Intel 82801 (ICH)" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the Intel 801 family of mainboard I2C interfaces. Specifically, the following @@ -162,7 +139,7 @@ config I2C_I801 config I2C_I810 tristate "Intel 810/815" - depends on PCI + depends on I2C && PCI select I2C_ALGOBIT help If you say yes to this option, support will be included for the Intel @@ -179,7 +156,7 @@ config I2C_I810 config I2C_PXA tristate "Intel PXA2XX I2C adapter (EXPERIMENTAL)" - depends on EXPERIMENTAL && ARCH_PXA + depends on I2C && EXPERIMENTAL && ARCH_PXA help If you have devices in the PXA I2C bus, say yes to this option. This driver can also be built as a module. If so, the module @@ -195,7 +172,7 @@ config I2C_PXA_SLAVE config I2C_PIIX4 tristate "Intel PIIX4 and compatible (ATI/Serverworks/Broadcom/SMSC)" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the Intel PIIX4 family of mainboard I2C interfaces. Specifically, the following @@ -218,7 +195,7 @@ config I2C_PIIX4 config I2C_IBM_IIC tristate "IBM PPC 4xx on-chip I2C interface" - depends on IBM_OCP + depends on IBM_OCP && I2C help Say Y here if you want to use IIC peripheral found on embedded IBM PPC 4xx based systems. @@ -228,7 +205,7 @@ config I2C_IBM_IIC config I2C_IOP3XX tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface" - depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX + depends on (ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || ARCH_IOP13XX) && I2C help Say Y here if you want to use the IIC bus controller on the Intel IOPx3xx I/O Processors or IXP4xx Network Processors. @@ -238,10 +215,11 @@ config I2C_IOP3XX config I2C_ISA tristate + depends on I2C config I2C_IXP4XX - tristate "IXP4xx GPIO-Based I2C Interface (DEPRECATED)" - depends on ARCH_IXP4XX + tristate "IXP4xx GPIO-Based I2C Interface" + depends on I2C && ARCH_IXP4XX select I2C_ALGOBIT help Say Y here if you have an Intel IXP4xx(420,421,422,425) based @@ -250,12 +228,9 @@ config I2C_IXP4XX This support is also available as a module. If so, the module will be called i2c-ixp4xx. - This driver is deprecated and will be dropped soon. Use i2c-gpio - instead. - config I2C_IXP2000 - tristate "IXP2000 GPIO-Based I2C Interface (DEPRECATED)" - depends on ARCH_IXP2000 + tristate "IXP2000 GPIO-Based I2C Interface" + depends on I2C && ARCH_IXP2000 select I2C_ALGOBIT help Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based @@ -264,12 +239,9 @@ config I2C_IXP2000 This support is also available as a module. If so, the module will be called i2c-ixp2000. - This driver is deprecated and will be dropped soon. Use i2c-gpio - instead. - config I2C_POWERMAC tristate "Powermac I2C interface" - depends on PPC_PMAC + depends on I2C && PPC_PMAC default y help This exposes the various PowerMac i2c interfaces to the linux i2c @@ -281,7 +253,7 @@ config I2C_POWERMAC config I2C_MPC tristate "MPC107/824x/85xx/52xx/86xx" - depends on PPC32 + depends on I2C && PPC32 help If you say yes to this option, support will be included for the built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and @@ -293,7 +265,7 @@ config I2C_MPC config I2C_NFORCE2 tristate "Nvidia nForce2, nForce3 and nForce4" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the Nvidia nForce2, nForce3 and nForce4 families of mainboard I2C interfaces. @@ -303,7 +275,7 @@ config I2C_NFORCE2 config I2C_OCORES tristate "OpenCores I2C Controller" - depends on EXPERIMENTAL + depends on I2C && EXPERIMENTAL help If you say yes to this option, support will be included for the OpenCores I2C controller. For details see @@ -314,7 +286,7 @@ config I2C_OCORES config I2C_OMAP tristate "OMAP I2C adapter" - depends on ARCH_OMAP + depends on I2C && ARCH_OMAP default y if MACH_OMAP_H3 || MACH_OMAP_OSK help If you say yes to this option, support will be included for the @@ -324,7 +296,7 @@ config I2C_OMAP config I2C_PARPORT tristate "Parallel port adapter" - depends on PARPORT + depends on I2C && PARPORT select I2C_ALGOBIT help This supports parallel port I2C adapters such as the ones made by @@ -348,6 +320,7 @@ config I2C_PARPORT config I2C_PARPORT_LIGHT tristate "Parallel port adapter (light)" + depends on I2C select I2C_ALGOBIT help This supports parallel port I2C adapters such as the ones made by @@ -371,13 +344,13 @@ config I2C_PARPORT_LIGHT config I2C_PASEMI tristate "PA Semi SMBus interface" - depends on PPC_PASEMI && PCI + depends on PPC_PASEMI && I2C && PCI help Supports the PA Semi PWRficient on-chip SMBus interfaces. config I2C_PROSAVAGE tristate "S3/VIA (Pro)Savage" - depends on PCI + depends on I2C && PCI select I2C_ALGOBIT help If you say yes to this option, support will be included for the @@ -392,19 +365,19 @@ config I2C_PROSAVAGE config I2C_RPXLITE tristate "Embedded Planet RPX Lite/Classic support" - depends on RPXLITE || RPXCLASSIC + depends on (RPXLITE || RPXCLASSIC) && I2C select I2C_ALGO8XX config I2C_S3C2410 tristate "S3C2410 I2C Driver" - depends on ARCH_S3C2410 + depends on I2C && ARCH_S3C2410 help Say Y here to include support for I2C controller in the Samsung S3C2410 based System-on-Chip devices. config I2C_SAVAGE4 tristate "S3 Savage 4" - depends on PCI && EXPERIMENTAL + depends on I2C && PCI && EXPERIMENTAL select I2C_ALGOBIT help If you say yes to this option, support will be included for the @@ -415,25 +388,13 @@ config I2C_SAVAGE4 config I2C_SIBYTE tristate "SiByte SMBus interface" - depends on SIBYTE_SB1xxx_SOC + depends on SIBYTE_SB1xxx_SOC && I2C help Supports the SiByte SOC on-chip I2C interfaces (2 channels). -config I2C_SIMTEC - tristate "Simtec Generic I2C interface" - select I2C_ALGOBIT - help - If you say yes to this option, support will be inclyded for - the Simtec Generic I2C interface. This driver is for the - simple I2C bus used on newer Simtec products for general - I2C, such as DDC on the Simtec BBD2016A. - - This driver can also be build as a module. If so, the module - will be called i2c-simtec. - config SCx200_I2C - tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)" - depends on SCx200_GPIO + tristate "NatSemi SCx200 I2C using GPIO pins" + depends on SCx200_GPIO && I2C select I2C_ALGOBIT help Enable the use of two GPIO pins of a SCx200 processor as an I2C bus. @@ -443,9 +404,6 @@ config SCx200_I2C This support is also available as a module. If so, the module will be called scx200_i2c. - This driver is deprecated and will be dropped soon. Use i2c-gpio - (or scx200_acb) instead. - config SCx200_I2C_SCL int "GPIO pin used for SCL" depends on SCx200_I2C @@ -464,7 +422,7 @@ config SCx200_I2C_SDA config SCx200_ACB tristate "Geode ACCESS.bus support" - depends on X86_32 && PCI + depends on X86_32 && I2C && PCI help Enable the use of the ACCESS.bus controllers on the Geode SCx200 and SC1100 processors and the CS5535 and CS5536 Geode companion devices. @@ -476,7 +434,7 @@ config SCx200_ACB config I2C_SIS5595 tristate "SiS 5595" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the SiS5595 SMBus (a subset of I2C) interface. @@ -486,7 +444,7 @@ config I2C_SIS5595 config I2C_SIS630 tristate "SiS 630/730" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the SiS630 and SiS730 SMBus (a subset of I2C) interface. @@ -496,7 +454,7 @@ config I2C_SIS630 config I2C_SIS96X tristate "SiS 96x" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the SiS 96x SMBus (a subset of I2C) interfaces. Specifically, the following @@ -514,7 +472,7 @@ config I2C_SIS96X config I2C_STUB tristate "I2C/SMBus Test Stub" - depends on EXPERIMENTAL && m + depends on I2C && EXPERIMENTAL && 'm' default 'n' help This module may be useful to developers of SMBus client drivers, @@ -525,20 +483,9 @@ config I2C_STUB If you don't know what to do here, definitely say N. -config I2C_TINY_USB - tristate "I2C-Tiny-USB" - depends on USB - help - If you say yes to this option, support will be included for the - i2c-tiny-usb, a simple do-it-yourself USB to I2C interface. See - http://www.harbaum.org/till/i2c_tiny_usb for hardware details. - - This driver can also be built as a module. If so, the module - will be called i2c-tiny-usb. - config I2C_VERSATILE tristate "ARM Versatile/Realview I2C bus support" - depends on ARCH_VERSATILE || ARCH_REALVIEW + depends on I2C && (ARCH_VERSATILE || ARCH_REALVIEW) select I2C_ALGOBIT help Say yes if you want to support the I2C serial bus on ARMs Versatile @@ -549,7 +496,7 @@ config I2C_VERSATILE config I2C_ACORN bool "Acorn IOC/IOMD I2C bus support" - depends on ARCH_ACORN + depends on I2C && ARCH_ACORN default y select I2C_ALGOBIT help @@ -559,7 +506,7 @@ config I2C_ACORN config I2C_VIA tristate "VIA 82C586B" - depends on PCI && EXPERIMENTAL + depends on I2C && PCI && EXPERIMENTAL select I2C_ALGOBIT help If you say yes to this option, support will be included for the VIA @@ -570,7 +517,7 @@ config I2C_VIA config I2C_VIAPRO tristate "VIA VT82C596/82C686/82xx and CX700" - depends on PCI + depends on I2C && PCI help If you say yes to this option, support will be included for the VIA VT82C596 and later SMBus interface. Specifically, the following @@ -589,7 +536,7 @@ config I2C_VIAPRO config I2C_VOODOO3 tristate "Voodoo 3" - depends on PCI + depends on I2C && PCI select I2C_ALGOBIT help If you say yes to this option, support will be included for the @@ -600,7 +547,7 @@ config I2C_VOODOO3 config I2C_PCA_ISA tristate "PCA9564 on an ISA bus" - depends on ISA + depends on I2C select I2C_ALGOPCA default n help @@ -617,7 +564,7 @@ config I2C_PCA_ISA config I2C_MV64XXX tristate "Marvell mv64xxx I2C Controller" - depends on MV64X60 && EXPERIMENTAL + depends on I2C && MV64X60 && EXPERIMENTAL help If you say yes to this option, support will be included for the built-in I2C interface on the Marvell 64xxx line of host bridges. @@ -627,7 +574,7 @@ config I2C_MV64XXX config I2C_PNX tristate "I2C bus support for Philips PNX targets" - depends on ARCH_PNX4008 + depends on ARCH_PNX4008 && I2C help This driver supports the Philips IP3204 I2C IP block master and/or slave controller diff --git a/trunk/drivers/i2c/busses/Makefile b/trunk/drivers/i2c/busses/Makefile index 14d1432f698b..290b54018354 100644 --- a/trunk/drivers/i2c/busses/Makefile +++ b/trunk/drivers/i2c/busses/Makefile @@ -10,9 +10,7 @@ obj-$(CONFIG_I2C_AMD756_S4882) += i2c-amd756-s4882.o obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o obj-$(CONFIG_I2C_AT91) += i2c-at91.o obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o -obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o -obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o obj-$(CONFIG_I2C_HYDRA) += i2c-hydra.o obj-$(CONFIG_I2C_I801) += i2c-i801.o obj-$(CONFIG_I2C_I810) += i2c-i810.o @@ -39,12 +37,10 @@ obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o obj-$(CONFIG_I2C_SIBYTE) += i2c-sibyte.o -obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o obj-$(CONFIG_I2C_STUB) += i2c-stub.o -obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o obj-$(CONFIG_I2C_VIA) += i2c-via.o diff --git a/trunk/drivers/i2c/busses/i2c-ali1535.c b/trunk/drivers/i2c/busses/i2c-ali1535.c index f14372ac2fc5..1e277ba5a9f3 100644 --- a/trunk/drivers/i2c/busses/i2c-ali1535.c +++ b/trunk/drivers/i2c/busses/i2c-ali1535.c @@ -497,7 +497,7 @@ static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_ /* set up the sysfs linkage to our parent device */ ali1535_adapter.dev.parent = &dev->dev; - snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name), + snprintf(ali1535_adapter.name, I2C_NAME_SIZE, "SMBus ALI1535 adapter at %04x", ali1535_smba); return i2c_add_adapter(&ali1535_adapter); } diff --git a/trunk/drivers/i2c/busses/i2c-ali15x3.c b/trunk/drivers/i2c/busses/i2c-ali15x3.c index 93bf87d70961..e47fe01bf42a 100644 --- a/trunk/drivers/i2c/busses/i2c-ali15x3.c +++ b/trunk/drivers/i2c/busses/i2c-ali15x3.c @@ -492,7 +492,7 @@ static int __devinit ali15x3_probe(struct pci_dev *dev, const struct pci_device_ /* set up the sysfs linkage to our parent device */ ali15x3_adapter.dev.parent = &dev->dev; - snprintf(ali15x3_adapter.name, sizeof(ali15x3_adapter.name), + snprintf(ali15x3_adapter.name, I2C_NAME_SIZE, "SMBus ALI15X3 adapter at %04x", ali15x3_smba); return i2c_add_adapter(&ali15x3_adapter); } diff --git a/trunk/drivers/i2c/busses/i2c-amd8111.c b/trunk/drivers/i2c/busses/i2c-amd8111.c index c9fca7b49267..0c70f8293341 100644 --- a/trunk/drivers/i2c/busses/i2c-amd8111.c +++ b/trunk/drivers/i2c/busses/i2c-amd8111.c @@ -365,7 +365,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, } smbus->adapter.owner = THIS_MODULE; - snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), + snprintf(smbus->adapter.name, I2C_NAME_SIZE, "SMBus2 AMD8111 adapter at %04x", smbus->base); smbus->adapter.id = I2C_HW_SMBUS_AMD8111; smbus->adapter.class = I2C_CLASS_HWMON; diff --git a/trunk/drivers/i2c/busses/i2c-at91.c b/trunk/drivers/i2c/busses/i2c-at91.c index f35156c58922..67f91bdda089 100644 --- a/trunk/drivers/i2c/busses/i2c-at91.c +++ b/trunk/drivers/i2c/busses/i2c-at91.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/i2c/busses/i2c-bfin-twi.c b/trunk/drivers/i2c/busses/i2c-bfin-twi.c deleted file mode 100644 index 6311039dfe60..000000000000 --- a/trunk/drivers/i2c/busses/i2c-bfin-twi.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * drivers/i2c/busses/i2c-bfin-twi.c - * - * Description: Driver for Blackfin Two Wire Interface - * - * Author: sonicz - * - * Copyright (c) 2005-2007 Analog Devices, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define POLL_TIMEOUT (2 * HZ) - -/* SMBus mode*/ -#define TWI_I2C_MODE_STANDARD 0x01 -#define TWI_I2C_MODE_STANDARDSUB 0x02 -#define TWI_I2C_MODE_COMBINED 0x04 - -struct bfin_twi_iface { - struct mutex twi_lock; - int irq; - spinlock_t lock; - char read_write; - u8 command; - u8 *transPtr; - int readNum; - int writeNum; - int cur_mode; - int manual_stop; - int result; - int timeout_count; - struct timer_list timeout_timer; - struct i2c_adapter adap; - struct completion complete; -}; - -static struct bfin_twi_iface twi_iface; - -static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface) -{ - unsigned short twi_int_status = bfin_read_TWI_INT_STAT(); - unsigned short mast_stat = bfin_read_TWI_MASTER_STAT(); - - if (twi_int_status & XMTSERV) { - /* Transmit next data */ - if (iface->writeNum > 0) { - bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); - iface->writeNum--; - } - /* start receive immediately after complete sending in - * combine mode. - */ - else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() - | MDIR | RSTART); - } else if (iface->manual_stop) - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() - | STOP); - SSYNC(); - /* Clear status */ - bfin_write_TWI_INT_STAT(XMTSERV); - SSYNC(); - } - if (twi_int_status & RCVSERV) { - if (iface->readNum > 0) { - /* Receive next data */ - *(iface->transPtr) = bfin_read_TWI_RCV_DATA8(); - if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { - /* Change combine mode into sub mode after - * read first data. - */ - iface->cur_mode = TWI_I2C_MODE_STANDARDSUB; - /* Get read number from first byte in block - * combine mode. - */ - if (iface->readNum == 1 && iface->manual_stop) - iface->readNum = *iface->transPtr + 1; - } - iface->transPtr++; - iface->readNum--; - } else if (iface->manual_stop) { - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() - | STOP); - SSYNC(); - } - /* Clear interrupt source */ - bfin_write_TWI_INT_STAT(RCVSERV); - SSYNC(); - } - if (twi_int_status & MERR) { - bfin_write_TWI_INT_STAT(MERR); - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_STAT(0x3e); - bfin_write_TWI_MASTER_CTL(0); - SSYNC(); - iface->result = -1; - /* if both err and complete int stats are set, return proper - * results. - */ - if (twi_int_status & MCOMP) { - bfin_write_TWI_INT_STAT(MCOMP); - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_CTL(0); - SSYNC(); - /* If it is a quick transfer, only address bug no data, - * not an err, return 1. - */ - if (iface->writeNum == 0 && (mast_stat & BUFRDERR)) - iface->result = 1; - /* If address not acknowledged return -1, - * else return 0. - */ - else if (!(mast_stat & ANAK)) - iface->result = 0; - } - complete(&iface->complete); - return; - } - if (twi_int_status & MCOMP) { - bfin_write_TWI_INT_STAT(MCOMP); - SSYNC(); - if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { - if (iface->readNum == 0) { - /* set the read number to 1 and ask for manual - * stop in block combine mode - */ - iface->readNum = 1; - iface->manual_stop = 1; - bfin_write_TWI_MASTER_CTL( - bfin_read_TWI_MASTER_CTL() - | (0xff << 6)); - } else { - /* set the readd number in other - * combine mode. - */ - bfin_write_TWI_MASTER_CTL( - (bfin_read_TWI_MASTER_CTL() & - (~(0xff << 6))) | - ( iface->readNum << 6)); - } - /* remove restart bit and enable master receive */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() & - ~RSTART); - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | - MEN | MDIR); - SSYNC(); - } else { - iface->result = 1; - bfin_write_TWI_INT_MASK(0); - bfin_write_TWI_MASTER_CTL(0); - SSYNC(); - complete(&iface->complete); - } - } -} - -/* Interrupt handler */ -static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id) -{ - struct bfin_twi_iface *iface = dev_id; - unsigned long flags; - - spin_lock_irqsave(&iface->lock, flags); - del_timer(&iface->timeout_timer); - bfin_twi_handle_interrupt(iface); - spin_unlock_irqrestore(&iface->lock, flags); - return IRQ_HANDLED; -} - -static void bfin_twi_timeout(unsigned long data) -{ - struct bfin_twi_iface *iface = (struct bfin_twi_iface *)data; - unsigned long flags; - - spin_lock_irqsave(&iface->lock, flags); - bfin_twi_handle_interrupt(iface); - if (iface->result == 0) { - iface->timeout_count--; - if (iface->timeout_count > 0) { - iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; - add_timer(&iface->timeout_timer); - } else { - iface->result = -1; - complete(&iface->complete); - } - } - spin_unlock_irqrestore(&iface->lock, flags); -} - -/* - * Generic i2c master transfer entrypoint - */ -static int bfin_twi_master_xfer(struct i2c_adapter *adap, - struct i2c_msg *msgs, int num) -{ - struct bfin_twi_iface *iface = adap->algo_data; - struct i2c_msg *pmsg; - int i, ret; - int rc = 0; - - if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) - return -ENXIO; - - mutex_lock(&iface->twi_lock); - - while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) { - mutex_unlock(&iface->twi_lock); - yield(); - mutex_lock(&iface->twi_lock); - } - - ret = 0; - for (i = 0; rc >= 0 && i < num; i++) { - pmsg = &msgs[i]; - if (pmsg->flags & I2C_M_TEN) { - dev_err(&(adap->dev), "i2c-bfin-twi: 10 bits addr " - "not supported !\n"); - rc = -EINVAL; - break; - } - - iface->cur_mode = TWI_I2C_MODE_STANDARD; - iface->manual_stop = 0; - iface->transPtr = pmsg->buf; - iface->writeNum = iface->readNum = pmsg->len; - iface->result = 0; - iface->timeout_count = 10; - /* Set Transmit device address */ - bfin_write_TWI_MASTER_ADDR(pmsg->addr); - - /* FIFO Initiation. Data in FIFO should be - * discarded before start a new operation. - */ - bfin_write_TWI_FIFO_CTL(0x3); - SSYNC(); - bfin_write_TWI_FIFO_CTL(0); - SSYNC(); - - if (pmsg->flags & I2C_M_RD) - iface->read_write = I2C_SMBUS_READ; - else { - iface->read_write = I2C_SMBUS_WRITE; - /* Transmit first data */ - if (iface->writeNum > 0) { - bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); - iface->writeNum--; - SSYNC(); - } - } - - /* clear int stat */ - bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV); - - /* Interrupt mask . Enable XMT, RCV interrupt */ - bfin_write_TWI_INT_MASK(MCOMP | MERR | - ((iface->read_write == I2C_SMBUS_READ)? - RCVSERV : XMTSERV)); - SSYNC(); - - if (pmsg->len > 0 && pmsg->len <= 255) - bfin_write_TWI_MASTER_CTL(pmsg->len << 6); - else if (pmsg->len > 255) { - bfin_write_TWI_MASTER_CTL(0xff << 6); - iface->manual_stop = 1; - } else - break; - - iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; - add_timer(&iface->timeout_timer); - - /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | - ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | - ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); - SSYNC(); - - wait_for_completion(&iface->complete); - - rc = iface->result; - if (rc == 1) - ret++; - else if (rc == -1) - break; - } - - /* Release mutex */ - mutex_unlock(&iface->twi_lock); - - return ret; -} - -/* - * SMBus type transfer entrypoint - */ - -int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr, - unsigned short flags, char read_write, - u8 command, int size, union i2c_smbus_data *data) -{ - struct bfin_twi_iface *iface = adap->algo_data; - int rc = 0; - - if (!(bfin_read_TWI_CONTROL() & TWI_ENA)) - return -ENXIO; - - mutex_lock(&iface->twi_lock); - - while (bfin_read_TWI_MASTER_STAT() & BUSBUSY) { - mutex_unlock(&iface->twi_lock); - yield(); - mutex_lock(&iface->twi_lock); - } - - iface->writeNum = 0; - iface->readNum = 0; - - /* Prepare datas & select mode */ - switch (size) { - case I2C_SMBUS_QUICK: - iface->transPtr = NULL; - iface->cur_mode = TWI_I2C_MODE_STANDARD; - break; - case I2C_SMBUS_BYTE: - if (data == NULL) - iface->transPtr = NULL; - else { - if (read_write == I2C_SMBUS_READ) - iface->readNum = 1; - else - iface->writeNum = 1; - iface->transPtr = &data->byte; - } - iface->cur_mode = TWI_I2C_MODE_STANDARD; - break; - case I2C_SMBUS_BYTE_DATA: - if (read_write == I2C_SMBUS_READ) { - iface->readNum = 1; - iface->cur_mode = TWI_I2C_MODE_COMBINED; - } else { - iface->writeNum = 1; - iface->cur_mode = TWI_I2C_MODE_STANDARDSUB; - } - iface->transPtr = &data->byte; - break; - case I2C_SMBUS_WORD_DATA: - if (read_write == I2C_SMBUS_READ) { - iface->readNum = 2; - iface->cur_mode = TWI_I2C_MODE_COMBINED; - } else { - iface->writeNum = 2; - iface->cur_mode = TWI_I2C_MODE_STANDARDSUB; - } - iface->transPtr = (u8 *)&data->word; - break; - case I2C_SMBUS_PROC_CALL: - iface->writeNum = 2; - iface->readNum = 2; - iface->cur_mode = TWI_I2C_MODE_COMBINED; - iface->transPtr = (u8 *)&data->word; - break; - case I2C_SMBUS_BLOCK_DATA: - if (read_write == I2C_SMBUS_READ) { - iface->readNum = 0; - iface->cur_mode = TWI_I2C_MODE_COMBINED; - } else { - iface->writeNum = data->block[0] + 1; - iface->cur_mode = TWI_I2C_MODE_STANDARDSUB; - } - iface->transPtr = data->block; - break; - default: - return -1; - } - - iface->result = 0; - iface->manual_stop = 0; - iface->read_write = read_write; - iface->command = command; - iface->timeout_count = 10; - - /* FIFO Initiation. Data in FIFO should be discarded before - * start a new operation. - */ - bfin_write_TWI_FIFO_CTL(0x3); - SSYNC(); - bfin_write_TWI_FIFO_CTL(0); - - /* clear int stat */ - bfin_write_TWI_INT_STAT(MERR|MCOMP|XMTSERV|RCVSERV); - - /* Set Transmit device address */ - bfin_write_TWI_MASTER_ADDR(addr); - SSYNC(); - - iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; - add_timer(&iface->timeout_timer); - - switch (iface->cur_mode) { - case TWI_I2C_MODE_STANDARDSUB: - bfin_write_TWI_XMT_DATA8(iface->command); - bfin_write_TWI_INT_MASK(MCOMP | MERR | - ((iface->read_write == I2C_SMBUS_READ) ? - RCVSERV : XMTSERV)); - SSYNC(); - - if (iface->writeNum + 1 <= 255) - bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6); - else { - bfin_write_TWI_MASTER_CTL(0xff << 6); - iface->manual_stop = 1; - } - /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | - ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); - break; - case TWI_I2C_MODE_COMBINED: - bfin_write_TWI_XMT_DATA8(iface->command); - bfin_write_TWI_INT_MASK(MCOMP | MERR | RCVSERV | XMTSERV); - SSYNC(); - - if (iface->writeNum > 0) - bfin_write_TWI_MASTER_CTL((iface->writeNum + 1) << 6); - else - bfin_write_TWI_MASTER_CTL(0x1 << 6); - /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | - ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0)); - break; - default: - bfin_write_TWI_MASTER_CTL(0); - if (size != I2C_SMBUS_QUICK) { - /* Don't access xmit data register when this is a - * read operation. - */ - if (iface->read_write != I2C_SMBUS_READ) { - if (iface->writeNum > 0) { - bfin_write_TWI_XMT_DATA8(*(iface->transPtr++)); - if (iface->writeNum <= 255) - bfin_write_TWI_MASTER_CTL(iface->writeNum << 6); - else { - bfin_write_TWI_MASTER_CTL(0xff << 6); - iface->manual_stop = 1; - } - iface->writeNum--; - } else { - bfin_write_TWI_XMT_DATA8(iface->command); - bfin_write_TWI_MASTER_CTL(1 << 6); - } - } else { - if (iface->readNum > 0 && iface->readNum <= 255) - bfin_write_TWI_MASTER_CTL(iface->readNum << 6); - else if (iface->readNum > 255) { - bfin_write_TWI_MASTER_CTL(0xff << 6); - iface->manual_stop = 1; - } else { - del_timer(&iface->timeout_timer); - break; - } - } - } - bfin_write_TWI_INT_MASK(MCOMP | MERR | - ((iface->read_write == I2C_SMBUS_READ) ? - RCVSERV : XMTSERV)); - SSYNC(); - - /* Master enable */ - bfin_write_TWI_MASTER_CTL(bfin_read_TWI_MASTER_CTL() | MEN | - ((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) | - ((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0)); - break; - } - SSYNC(); - - wait_for_completion(&iface->complete); - - rc = (iface->result >= 0) ? 0 : -1; - - /* Release mutex */ - mutex_unlock(&iface->twi_lock); - - return rc; -} - -/* - * Return what the adapter supports - */ -static u32 bfin_twi_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL | - I2C_FUNC_I2C; -} - - -static struct i2c_algorithm bfin_twi_algorithm = { - .master_xfer = bfin_twi_master_xfer, - .smbus_xfer = bfin_twi_smbus_xfer, - .functionality = bfin_twi_functionality, -}; - - -static int i2c_bfin_twi_suspend(struct platform_device *dev, pm_message_t state) -{ -/* struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/ - - /* Disable TWI */ - bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() & ~TWI_ENA); - SSYNC(); - - return 0; -} - -static int i2c_bfin_twi_resume(struct platform_device *dev) -{ -/* struct bfin_twi_iface *iface = platform_get_drvdata(dev);*/ - - /* Enable TWI */ - bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); - SSYNC(); - - return 0; -} - -static int i2c_bfin_twi_probe(struct platform_device *dev) -{ - struct bfin_twi_iface *iface = &twi_iface; - struct i2c_adapter *p_adap; - int rc; - - mutex_init(&(iface->twi_lock)); - spin_lock_init(&(iface->lock)); - init_completion(&(iface->complete)); - iface->irq = IRQ_TWI; - - init_timer(&(iface->timeout_timer)); - iface->timeout_timer.function = bfin_twi_timeout; - iface->timeout_timer.data = (unsigned long)iface; - - p_adap = &iface->adap; - p_adap->id = I2C_HW_BLACKFIN; - strlcpy(p_adap->name, dev->name, sizeof(p_adap->name)); - p_adap->algo = &bfin_twi_algorithm; - p_adap->algo_data = iface; - p_adap->class = I2C_CLASS_ALL; - p_adap->dev.parent = &dev->dev; - - rc = request_irq(iface->irq, bfin_twi_interrupt_entry, - IRQF_DISABLED, dev->name, iface); - if (rc) { - dev_err(&(p_adap->dev), "i2c-bfin-twi: can't get IRQ %d !\n", - iface->irq); - return -ENODEV; - } - - /* Set TWI internal clock as 10MHz */ - bfin_write_TWI_CONTROL(((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); - - /* Set Twi interface clock as specified */ - bfin_write_TWI_CLKDIV((( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ ) - << 8) | (( 5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ ) - & 0xFF)); - - /* Enable TWI */ - bfin_write_TWI_CONTROL(bfin_read_TWI_CONTROL() | TWI_ENA); - SSYNC(); - - rc = i2c_add_adapter(p_adap); - if (rc < 0) - free_irq(iface->irq, iface); - else - platform_set_drvdata(dev, iface); - - return rc; -} - -static int i2c_bfin_twi_remove(struct platform_device *pdev) -{ - struct bfin_twi_iface *iface = platform_get_drvdata(pdev); - - platform_set_drvdata(pdev, NULL); - - i2c_del_adapter(&(iface->adap)); - free_irq(iface->irq, iface); - - return 0; -} - -static struct platform_driver i2c_bfin_twi_driver = { - .probe = i2c_bfin_twi_probe, - .remove = i2c_bfin_twi_remove, - .suspend = i2c_bfin_twi_suspend, - .resume = i2c_bfin_twi_resume, - .driver = { - .name = "i2c-bfin-twi", - .owner = THIS_MODULE, - }, -}; - -static int __init i2c_bfin_twi_init(void) -{ - pr_info("I2C: Blackfin I2C TWI driver\n"); - - return platform_driver_register(&i2c_bfin_twi_driver); -} - -static void __exit i2c_bfin_twi_exit(void) -{ - platform_driver_unregister(&i2c_bfin_twi_driver); -} - -MODULE_AUTHOR("Sonic Zhang "); -MODULE_DESCRIPTION("I2C-Bus adapter routines for Blackfin TWI"); -MODULE_LICENSE("GPL"); - -module_init(i2c_bfin_twi_init); -module_exit(i2c_bfin_twi_exit); diff --git a/trunk/drivers/i2c/busses/i2c-elektor.c b/trunk/drivers/i2c/busses/i2c-elektor.c index 804f0a551c05..834967464814 100644 --- a/trunk/drivers/i2c/busses/i2c-elektor.c +++ b/trunk/drivers/i2c/busses/i2c-elektor.c @@ -35,7 +35,6 @@ #include #include -#include #include #include @@ -208,7 +207,7 @@ static struct i2c_adapter pcf_isa_ops = { .name = "i2c-elektor", }; -static int __devinit elektor_match(struct device *dev, unsigned int id) +static int __init i2c_pcfisa_init(void) { #ifdef __alpha__ /* check to see we have memory mapped PCF8584 connected to the @@ -223,8 +222,9 @@ static int __devinit elektor_match(struct device *dev, unsigned int id) /* yeap, we've found cypress, let's check config */ if (!pci_read_config_byte(cy693_dev, 0x47, &config)) { - dev_dbg(dev, "found cy82c693, config " - "register 0x47 = 0x%02x\n", config); + pr_debug("%s: found cy82c693, config " + "register 0x47 = 0x%02x\n", + pcf_isa_ops.name, config); /* UP2000 board has this register set to 0xe1, but the most significant bit as seems can be @@ -244,9 +244,9 @@ static int __devinit elektor_match(struct device *dev, unsigned int id) 8.25 MHz (PCI/4) clock (this can be read from cypress) */ clock = I2C_PCF_CLK | I2C_PCF_TRNS90; - dev_info(dev, "found API UP2000 like " - "board, will probe PCF8584 " - "later\n"); + pr_info("%s: found API UP2000 like " + "board, will probe PCF8584 " + "later\n", pcf_isa_ops.name); } } pci_dev_put(cy693_dev); @@ -256,27 +256,22 @@ static int __devinit elektor_match(struct device *dev, unsigned int id) /* sanity checks for mmapped I/O */ if (mmapped && base < 0xc8000) { - dev_err(dev, "incorrect base address (%#x) specified " - "for mmapped I/O\n", base); - return 0; + printk(KERN_ERR "%s: incorrect base address (%#x) specified " + "for mmapped I/O\n", pcf_isa_ops.name, base); + return -ENODEV; } if (base == 0) { base = DEFAULT_BASE; } - return 1; -} -static int __devinit elektor_probe(struct device *dev, unsigned int id) -{ init_waitqueue_head(&pcf_wait); if (pcf_isa_init()) return -ENODEV; - pcf_isa_ops.dev.parent = dev; if (i2c_pcf_add_bus(&pcf_isa_ops) < 0) goto fail; - dev_info(dev, "found device at %#x\n", base); + dev_info(&pcf_isa_ops.dev, "found device at %#x\n", base); return 0; @@ -296,7 +291,7 @@ static int __devinit elektor_probe(struct device *dev, unsigned int id) return -ENODEV; } -static int __devexit elektor_remove(struct device *dev, unsigned int id) +static void i2c_pcfisa_exit(void) { i2c_del_adapter(&pcf_isa_ops); @@ -312,28 +307,6 @@ static int __devexit elektor_remove(struct device *dev, unsigned int id) iounmap(base_iomem); release_mem_region(base, 2); } - - return 0; -} - -static struct isa_driver i2c_elektor_driver = { - .match = elektor_match, - .probe = elektor_probe, - .remove = __devexit_p(elektor_remove), - .driver = { - .owner = THIS_MODULE, - .name = "i2c-elektor", - }, -}; - -static int __init i2c_pcfisa_init(void) -{ - return isa_register_driver(&i2c_elektor_driver, 1); -} - -static void __exit i2c_pcfisa_exit(void) -{ - isa_unregister_driver(&i2c_elektor_driver); } MODULE_AUTHOR("Hans Berglund "); diff --git a/trunk/drivers/i2c/busses/i2c-gpio.c b/trunk/drivers/i2c/busses/i2c-gpio.c deleted file mode 100644 index a7dd54654a9a..000000000000 --- a/trunk/drivers/i2c/busses/i2c-gpio.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Bitbanging I2C bus driver using the GPIO API - * - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include - -#include - -/* Toggle SDA by changing the direction of the pin */ -static void i2c_gpio_setsda_dir(void *data, int state) -{ - struct i2c_gpio_platform_data *pdata = data; - - if (state) - gpio_direction_input(pdata->sda_pin); - else - gpio_direction_output(pdata->sda_pin, 0); -} - -/* - * Toggle SDA by changing the output value of the pin. This is only - * valid for pins configured as open drain (i.e. setting the value - * high effectively turns off the output driver.) - */ -static void i2c_gpio_setsda_val(void *data, int state) -{ - struct i2c_gpio_platform_data *pdata = data; - - gpio_set_value(pdata->sda_pin, state); -} - -/* Toggle SCL by changing the direction of the pin. */ -static void i2c_gpio_setscl_dir(void *data, int state) -{ - struct i2c_gpio_platform_data *pdata = data; - - if (state) - gpio_direction_input(pdata->scl_pin); - else - gpio_direction_output(pdata->scl_pin, 0); -} - -/* - * Toggle SCL by changing the output value of the pin. This is used - * for pins that are configured as open drain and for output-only - * pins. The latter case will break the i2c protocol, but it will - * often work in practice. - */ -static void i2c_gpio_setscl_val(void *data, int state) -{ - struct i2c_gpio_platform_data *pdata = data; - - gpio_set_value(pdata->scl_pin, state); -} - -int i2c_gpio_getsda(void *data) -{ - struct i2c_gpio_platform_data *pdata = data; - - return gpio_get_value(pdata->sda_pin); -} - -int i2c_gpio_getscl(void *data) -{ - struct i2c_gpio_platform_data *pdata = data; - - return gpio_get_value(pdata->scl_pin); -} - -static int __init i2c_gpio_probe(struct platform_device *pdev) -{ - struct i2c_gpio_platform_data *pdata; - struct i2c_algo_bit_data *bit_data; - struct i2c_adapter *adap; - int ret; - - pdata = pdev->dev.platform_data; - if (!pdata) - return -ENXIO; - - ret = -ENOMEM; - adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); - if (!adap) - goto err_alloc_adap; - bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL); - if (!bit_data) - goto err_alloc_bit_data; - - ret = gpio_request(pdata->sda_pin, "sda"); - if (ret) - goto err_request_sda; - ret = gpio_request(pdata->scl_pin, "scl"); - if (ret) - goto err_request_scl; - - if (pdata->sda_is_open_drain) { - gpio_direction_output(pdata->sda_pin, 1); - bit_data->setsda = i2c_gpio_setsda_val; - } else { - gpio_direction_input(pdata->sda_pin); - bit_data->setsda = i2c_gpio_setsda_dir; - } - - if (pdata->scl_is_open_drain || pdata->scl_is_output_only) { - gpio_direction_output(pdata->scl_pin, 1); - bit_data->setscl = i2c_gpio_setscl_val; - } else { - gpio_direction_input(pdata->scl_pin); - bit_data->setscl = i2c_gpio_setscl_dir; - } - - if (!pdata->scl_is_output_only) - bit_data->getscl = i2c_gpio_getscl; - bit_data->getsda = i2c_gpio_getsda; - - if (pdata->udelay) - bit_data->udelay = pdata->udelay; - else if (pdata->scl_is_output_only) - bit_data->udelay = 50; /* 10 kHz */ - else - bit_data->udelay = 5; /* 100 kHz */ - - if (pdata->timeout) - bit_data->timeout = pdata->timeout; - else - bit_data->timeout = HZ / 10; /* 100 ms */ - - bit_data->data = pdata; - - adap->owner = THIS_MODULE; - snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); - adap->algo_data = bit_data; - adap->dev.parent = &pdev->dev; - - ret = i2c_bit_add_bus(adap); - if (ret) - goto err_add_bus; - - platform_set_drvdata(pdev, adap); - - dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n", - pdata->sda_pin, pdata->scl_pin, - pdata->scl_is_output_only - ? ", no clock stretching" : ""); - - return 0; - -err_add_bus: - gpio_free(pdata->scl_pin); -err_request_scl: - gpio_free(pdata->sda_pin); -err_request_sda: - kfree(bit_data); -err_alloc_bit_data: - kfree(adap); -err_alloc_adap: - return ret; -} - -static int __exit i2c_gpio_remove(struct platform_device *pdev) -{ - struct i2c_gpio_platform_data *pdata; - struct i2c_adapter *adap; - - adap = platform_get_drvdata(pdev); - pdata = pdev->dev.platform_data; - - i2c_del_adapter(adap); - gpio_free(pdata->scl_pin); - gpio_free(pdata->sda_pin); - kfree(adap->algo_data); - kfree(adap); - - return 0; -} - -static struct platform_driver i2c_gpio_driver = { - .driver = { - .name = "i2c-gpio", - .owner = THIS_MODULE, - }, - .remove = __exit_p(i2c_gpio_remove), -}; - -static int __init i2c_gpio_init(void) -{ - int ret; - - ret = platform_driver_probe(&i2c_gpio_driver, i2c_gpio_probe); - if (ret) - printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); - - return ret; -} -module_init(i2c_gpio_init); - -static void __exit i2c_gpio_exit(void) -{ - platform_driver_unregister(&i2c_gpio_driver); -} -module_exit(i2c_gpio_exit); - -MODULE_AUTHOR("Haavard Skinnemoen "); -MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 611b57192c96..a320e7d82c1f 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -527,7 +527,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id /* set up the sysfs linkage to our parent device */ i801_adapter.dev.parent = &dev->dev; - snprintf(i801_adapter.name, sizeof(i801_adapter.name), + snprintf(i801_adapter.name, I2C_NAME_SIZE, "SMBus I801 adapter at %04lx", i801_smba); err = i2c_add_adapter(&i801_adapter); if (err) { diff --git a/trunk/drivers/i2c/busses/i2c-isa.c b/trunk/drivers/i2c/busses/i2c-isa.c index b0e1370075de..5f33bc9c1e02 100644 --- a/trunk/drivers/i2c/busses/i2c-isa.c +++ b/trunk/drivers/i2c/busses/i2c-isa.c @@ -41,10 +41,6 @@ #include #include -/* Exported by i2c-core for i2c-isa only */ -extern void i2c_adapter_dev_release(struct device *dev); -extern struct class i2c_adapter_class; - static u32 isa_func(struct i2c_adapter *adapter); /* This is the actual algorithm we define */ @@ -68,6 +64,16 @@ static u32 isa_func(struct i2c_adapter *adapter) } +/* Copied from i2c-core */ +static ssize_t show_adapter_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct i2c_adapter *adap = dev_to_i2c_adapter(dev); + return sprintf(buf, "%s\n", adap->name); +} +static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); + + /* We implement an interface which resembles i2c_{add,del}_driver, but for i2c-isa drivers. We don't have to remember and handle lists of drivers and adapters so this is much more simple, of course. */ @@ -133,18 +139,41 @@ static int __init i2c_isa_init(void) isa_adapter.nr = ANY_I2C_ISA_BUS; isa_adapter.dev.parent = &platform_bus; sprintf(isa_adapter.dev.bus_id, "i2c-%d", isa_adapter.nr); + isa_adapter.dev.driver = &i2c_adapter_driver; isa_adapter.dev.release = &i2c_adapter_dev_release; - isa_adapter.dev.class = &i2c_adapter_class; err = device_register(&isa_adapter.dev); if (err) { printk(KERN_ERR "i2c-isa: Failed to register device\n"); goto exit; } + err = device_create_file(&isa_adapter.dev, &dev_attr_name); + if (err) { + printk(KERN_ERR "i2c-isa: Failed to create name file\n"); + goto exit_unregister; + } + + /* Add this adapter to the i2c_adapter class */ + memset(&isa_adapter.class_dev, 0x00, sizeof(struct class_device)); + isa_adapter.class_dev.dev = &isa_adapter.dev; + isa_adapter.class_dev.class = &i2c_adapter_class; + strlcpy(isa_adapter.class_dev.class_id, isa_adapter.dev.bus_id, + BUS_ID_SIZE); + err = class_device_register(&isa_adapter.class_dev); + if (err) { + printk(KERN_ERR "i2c-isa: Failed to register class device\n"); + goto exit_remove_name; + } dev_dbg(&isa_adapter.dev, "%s registered\n", isa_adapter.name); return 0; +exit_remove_name: + device_remove_file(&isa_adapter.dev, &dev_attr_name); +exit_unregister: + init_completion(&isa_adapter.dev_released); /* Needed? */ + device_unregister(&isa_adapter.dev); + wait_for_completion(&isa_adapter.dev_released); exit: return err; } @@ -172,11 +201,15 @@ static void __exit i2c_isa_exit(void) /* Clean up the sysfs representation */ dev_dbg(&isa_adapter.dev, "Unregistering from sysfs\n"); init_completion(&isa_adapter.dev_released); + init_completion(&isa_adapter.class_dev_released); + class_device_unregister(&isa_adapter.class_dev); + device_remove_file(&isa_adapter.dev, &dev_attr_name); device_unregister(&isa_adapter.dev); /* Wait for sysfs to drop all references */ dev_dbg(&isa_adapter.dev, "Waiting for sysfs completion\n"); wait_for_completion(&isa_adapter.dev_released); + wait_for_completion(&isa_adapter.class_dev_released); dev_dbg(&isa_adapter.dev, "%s unregistered\n", isa_adapter.name); } diff --git a/trunk/drivers/i2c/busses/i2c-ixp2000.c b/trunk/drivers/i2c/busses/i2c-ixp2000.c index 6352121a2827..efa3ecc5522a 100644 --- a/trunk/drivers/i2c/busses/i2c-ixp2000.c +++ b/trunk/drivers/i2c/busses/i2c-ixp2000.c @@ -118,7 +118,7 @@ static int ixp2000_i2c_probe(struct platform_device *plat_dev) drv_data->adapter.id = I2C_HW_B_IXP2000, strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, - sizeof(drv_data->adapter.name)); + I2C_NAME_SIZE); drv_data->adapter.algo_data = &drv_data->algo_data, drv_data->adapter.dev.parent = &plat_dev->dev; diff --git a/trunk/drivers/i2c/busses/i2c-ixp4xx.c b/trunk/drivers/i2c/busses/i2c-ixp4xx.c index 069ed7f3b395..08e89b83984a 100644 --- a/trunk/drivers/i2c/busses/i2c-ixp4xx.c +++ b/trunk/drivers/i2c/busses/i2c-ixp4xx.c @@ -127,7 +127,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) drv_data->adapter.id = I2C_HW_B_IXP4XX; drv_data->adapter.class = I2C_CLASS_HWMON; strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, - sizeof(drv_data->adapter.name)); + I2C_NAME_SIZE); drv_data->adapter.algo_data = &drv_data->algo_data; drv_data->adapter.dev.parent = &plat_dev->dev; diff --git a/trunk/drivers/i2c/busses/i2c-mpc.c b/trunk/drivers/i2c/busses/i2c-mpc.c index c6b6898592b1..ee65aa1be13a 100644 --- a/trunk/drivers/i2c/busses/i2c-mpc.c +++ b/trunk/drivers/i2c/busses/i2c-mpc.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/i2c/busses/i2c-mv64xxx.c b/trunk/drivers/i2c/busses/i2c-mv64xxx.c index a55b3335d1be..a3283b907eb8 100644 --- a/trunk/drivers/i2c/busses/i2c-mv64xxx.c +++ b/trunk/drivers/i2c/busses/i2c-mv64xxx.c @@ -508,7 +508,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) } strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", - sizeof(drv_data->adapter.name)); + I2C_NAME_SIZE); init_waitqueue_head(&drv_data->waitq); spin_lock_init(&drv_data->lock); diff --git a/trunk/drivers/i2c/busses/i2c-nforce2.c b/trunk/drivers/i2c/busses/i2c-nforce2.c index 3cd0d63e7b50..1514ec5b77f8 100644 --- a/trunk/drivers/i2c/busses/i2c-nforce2.c +++ b/trunk/drivers/i2c/busses/i2c-nforce2.c @@ -33,8 +33,6 @@ nForce4 MCP-04 0034 nForce4 MCP51 0264 nForce4 MCP55 0368 - nForce MCP61 03EB - nForce MCP65 0446 This driver supports the 2 SMBuses that are included in the MCP of the nForce2/3/4/5xx chipsets. @@ -202,8 +200,6 @@ static struct pci_device_id nforce2_ids[] = { { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS) }, { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS) }, - { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS) }, { 0 } }; @@ -244,7 +240,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo_data = smbus; smbus->adapter.dev.parent = &dev->dev; - snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), + snprintf(smbus->adapter.name, I2C_NAME_SIZE, "SMBus nForce2 adapter at %04x", smbus->base); error = i2c_add_adapter(&smbus->adapter); diff --git a/trunk/drivers/i2c/busses/i2c-omap.c b/trunk/drivers/i2c/busses/i2c-omap.c index e471e3bfdc1e..bcd8367cede1 100644 --- a/trunk/drivers/i2c/busses/i2c-omap.c +++ b/trunk/drivers/i2c/busses/i2c-omap.c @@ -605,8 +605,7 @@ omap_i2c_probe(struct platform_device *pdev) adap->dev.parent = &pdev->dev; /* i2c device drivers may be active on return from add_adapter() */ - adap->nr = pdev->id; - r = i2c_add_numbered_adapter(adap); + r = i2c_add_adapter(adap); if (r) { dev_err(dev->dev, "failure adding adapter\n"); goto err_free_irq; diff --git a/trunk/drivers/i2c/busses/i2c-parport-light.c b/trunk/drivers/i2c/busses/i2c-parport-light.c index 49a95e2887bc..4bc42810b9aa 100644 --- a/trunk/drivers/i2c/busses/i2c-parport-light.c +++ b/trunk/drivers/i2c/busses/i2c-parport-light.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------ * - * i2c-parport-light.c I2C bus over parallel port * + * i2c-parport.c I2C bus over parallel port * * ------------------------------------------------------------------------ * - Copyright (C) 2003-2007 Jean Delvare + Copyright (C) 2003-2004 Jean Delvare Based on older i2c-velleman.c driver Copyright (C) 1995-2000 Simon G. Vogl @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -35,9 +34,6 @@ #include "i2c-parport.h" #define DEFAULT_BASE 0x378 -#define DRVNAME "i2c-parport-light" - -static struct platform_device *pdev; static u16 base; module_param(base, ushort, 0); @@ -110,7 +106,7 @@ static struct i2c_algo_bit_data parport_algo_data = { .timeout = HZ, }; -/* ----- Driver registration ---------------------------------------------- */ +/* ----- I2c structure ---------------------------------------------------- */ static struct i2c_adapter parport_adapter = { .owner = THIS_MODULE, @@ -120,141 +116,55 @@ static struct i2c_adapter parport_adapter = { .name = "Parallel port adapter (light)", }; -static int __devinit i2c_parport_probe(struct platform_device *pdev) -{ - int err; - struct resource *res; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) - return -EBUSY; - - /* Reset hardware to a sane state (SCL and SDA high) */ - parport_setsda(NULL, 1); - parport_setscl(NULL, 1); - /* Other init if needed (power on...) */ - if (adapter_parm[type].init.val) - line_set(1, &adapter_parm[type].init); - - parport_adapter.dev.parent = &pdev->dev; - err = i2c_bit_add_bus(&parport_adapter); - if (err) { - dev_err(&pdev->dev, "Unable to register with I2C\n"); - goto exit_region; - } - return 0; - -exit_region: - release_region(res->start, res->end - res->start + 1); - return err; -} - -static int __devexit i2c_parport_remove(struct platform_device *pdev) -{ - struct resource *res; - - i2c_del_adapter(&parport_adapter); - - /* Un-init if needed (power off...) */ - if (adapter_parm[type].init.val) - line_set(0, &adapter_parm[type].init); - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_region(res->start, res->end - res->start + 1); - return 0; -} - -static struct platform_driver i2c_parport_driver = { - .driver = { - .owner = THIS_MODULE, - .name = DRVNAME, - }, - .probe = i2c_parport_probe, - .remove = __devexit_p(i2c_parport_remove), -}; - -static int __init i2c_parport_device_add(u16 address) -{ - struct resource res = { - .start = address, - .end = address + 2, - .name = DRVNAME, - .flags = IORESOURCE_IO, - }; - int err; - - pdev = platform_device_alloc(DRVNAME, -1); - if (!pdev) { - err = -ENOMEM; - printk(KERN_ERR DRVNAME ": Device allocation failed\n"); - goto exit; - } - - err = platform_device_add_resources(pdev, &res, 1); - if (err) { - printk(KERN_ERR DRVNAME ": Device resource addition failed " - "(%d)\n", err); - goto exit_device_put; - } - - err = platform_device_add(pdev); - if (err) { - printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", - err); - goto exit_device_put; - } - - return 0; - -exit_device_put: - platform_device_put(pdev); -exit: - return err; -} +/* ----- Module loading, unloading and information ------------------------ */ static int __init i2c_parport_init(void) { - int err; - if (type < 0) { - printk(KERN_ERR DRVNAME ": adapter type unspecified\n"); + printk(KERN_WARNING "i2c-parport: adapter type unspecified\n"); return -ENODEV; } if (type >= ARRAY_SIZE(adapter_parm)) { - printk(KERN_ERR DRVNAME ": invalid type (%d)\n", type); + printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); return -ENODEV; } if (base == 0) { - pr_info(DRVNAME ": using default base 0x%x\n", DEFAULT_BASE); + printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); base = DEFAULT_BASE; } + if (!request_region(base, 3, "i2c-parport")) + return -ENODEV; + if (!adapter_parm[type].getscl.val) parport_algo_data.getscl = NULL; - /* Sets global pdev as a side effect */ - err = i2c_parport_device_add(base); - if (err) - goto exit; + /* Reset hardware to a sane state (SCL and SDA high) */ + parport_setsda(NULL, 1); + parport_setscl(NULL, 1); + /* Other init if needed (power on...) */ + if (adapter_parm[type].init.val) + line_set(1, &adapter_parm[type].init); - err = platform_driver_register(&i2c_parport_driver); - if (err) - goto exit_device; + if (i2c_bit_add_bus(&parport_adapter) < 0) { + printk(KERN_ERR "i2c-parport: Unable to register with I2C\n"); + release_region(base, 3); + return -ENODEV; + } return 0; - -exit_device: - platform_device_unregister(pdev); -exit: - return err; } static void __exit i2c_parport_exit(void) { - platform_driver_unregister(&i2c_parport_driver); - platform_device_unregister(pdev); + /* Un-init if needed (power off...) */ + if (adapter_parm[type].init.val) + line_set(0, &adapter_parm[type].init); + + i2c_del_adapter(&parport_adapter); + release_region(base, 3); } MODULE_AUTHOR("Jean Delvare "); diff --git a/trunk/drivers/i2c/busses/i2c-parport.c b/trunk/drivers/i2c/busses/i2c-parport.c index 039a07fde908..66696a40c7b5 100644 --- a/trunk/drivers/i2c/busses/i2c-parport.c +++ b/trunk/drivers/i2c/busses/i2c-parport.c @@ -1,7 +1,7 @@ /* ------------------------------------------------------------------------ * * i2c-parport.c I2C bus over parallel port * * ------------------------------------------------------------------------ * - Copyright (C) 2003-2007 Jean Delvare + Copyright (C) 2003-2004 Jean Delvare Based on older i2c-philips-par.c driver Copyright (C) 1995-2000 Simon G. Vogl @@ -137,12 +137,19 @@ static struct i2c_algo_bit_data parport_algo_data = { .setscl = parport_setscl, .getsda = parport_getsda, .getscl = parport_getscl, - .udelay = 10, /* ~50 kbps */ + .udelay = 60, .timeout = HZ, }; /* ----- I2c and parallel port call-back functions and structures --------- */ +static struct i2c_adapter parport_adapter = { + .owner = THIS_MODULE, + .class = I2C_CLASS_HWMON, + .id = I2C_HW_B_LP, + .name = "Parallel port adapter", +}; + static void i2c_parport_attach (struct parport *port) { struct i2c_par *adapter; @@ -162,20 +169,12 @@ static void i2c_parport_attach (struct parport *port) } /* Fill the rest of the structure */ - adapter->adapter.owner = THIS_MODULE; - adapter->adapter.class = I2C_CLASS_HWMON; - adapter->adapter.id = I2C_HW_B_LP; - strlcpy(adapter->adapter.name, "Parallel port adapter", - sizeof(adapter->adapter.name)); + adapter->adapter = parport_adapter; adapter->algo_data = parport_algo_data; - /* Slow down if we can't sense SCL */ - if (!adapter_parm[type].getscl.val) { + if (!adapter_parm[type].getscl.val) adapter->algo_data.getscl = NULL; - adapter->algo_data.udelay = 50; /* ~10 kbps */ - } adapter->algo_data.data = port; adapter->adapter.algo_data = &adapter->algo_data; - adapter->adapter.dev.parent = port->physport->dev; if (parport_claim_or_block(adapter->pdev) < 0) { printk(KERN_ERR "i2c-parport: Could not claim parallel port\n"); @@ -215,12 +214,11 @@ static void i2c_parport_detach (struct parport *port) for (prev = NULL, adapter = adapter_list; adapter; prev = adapter, adapter = adapter->next) { if (adapter->pdev->port == port) { - i2c_del_adapter(&adapter->adapter); - /* Un-init if needed (power off...) */ if (adapter_parm[type].init.val) line_set(port, 0, &adapter_parm[type].init); + i2c_del_adapter(&adapter->adapter); parport_unregister_device(adapter->pdev); if (prev) prev->next = adapter->next; diff --git a/trunk/drivers/i2c/busses/i2c-pasemi.c b/trunk/drivers/i2c/busses/i2c-pasemi.c index 58e32714afb5..bf89eeef74e9 100644 --- a/trunk/drivers/i2c/busses/i2c-pasemi.c +++ b/trunk/drivers/i2c/busses/i2c-pasemi.c @@ -358,7 +358,7 @@ static int __devinit pasemi_smb_probe(struct pci_dev *dev, } smbus->adapter.owner = THIS_MODULE; - snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), + snprintf(smbus->adapter.name, I2C_NAME_SIZE, "PA Semi SMBus adapter at 0x%lx", smbus->base); smbus->adapter.class = I2C_CLASS_HWMON; smbus->adapter.algo = &smbus_algorithm; diff --git a/trunk/drivers/i2c/busses/i2c-pca-isa.c b/trunk/drivers/i2c/busses/i2c-pca-isa.c index 5161aaf9341b..cc6536a19eca 100644 --- a/trunk/drivers/i2c/busses/i2c-pca-isa.c +++ b/trunk/drivers/i2c/busses/i2c-pca-isa.c @@ -25,9 +25,9 @@ #include #include #include +#include #include -#include #include #include @@ -119,26 +119,27 @@ static struct i2c_adapter pca_isa_ops = { .name = "PCA9564 ISA Adapter", }; -static int __devinit pca_isa_probe(struct device *dev, unsigned int id) +static int __init pca_isa_init(void) { + init_waitqueue_head(&pca_wait); - dev_info(dev, "i/o base %#08lx. irq %d\n", base, irq); + printk(KERN_INFO "i2c-pca-isa: i/o base %#08lx. irq %d\n", base, irq); if (!request_region(base, IO_SIZE, "i2c-pca-isa")) { - dev_err(dev, "I/O address %#08lx is in use\n", base); + printk(KERN_ERR "i2c-pca-isa: I/O address %#08lx is in use.\n", base); goto out; } if (irq > -1) { if (request_irq(irq, pca_handler, 0, "i2c-pca-isa", &pca_isa_ops) < 0) { - dev_err(dev, "Request irq%d failed\n", irq); + printk(KERN_ERR "i2c-pca-isa: Request irq%d failed\n", irq); goto out_region; } } if (i2c_pca_add_bus(&pca_isa_ops) < 0) { - dev_err(dev, "Failed to add i2c bus\n"); + printk(KERN_ERR "i2c-pca-isa: Failed to add i2c bus\n"); goto out_irq; } @@ -153,7 +154,7 @@ static int __devinit pca_isa_probe(struct device *dev, unsigned int id) return -ENODEV; } -static int __devexit pca_isa_remove(struct device *dev, unsigned int id) +static void pca_isa_exit(void) { i2c_del_adapter(&pca_isa_ops); @@ -162,27 +163,6 @@ static int __devexit pca_isa_remove(struct device *dev, unsigned int id) free_irq(irq, &pca_isa_ops); } release_region(base, IO_SIZE); - - return 0; -} - -static struct isa_driver pca_isa_driver = { - .probe = pca_isa_probe, - .remove = __devexit_p(pca_isa_remove), - .driver = { - .owner = THIS_MODULE, - .name = "i2c-pca-isa", - } -}; - -static int __init pca_isa_init(void) -{ - return isa_register_driver(&pca_isa_driver, 1); -} - -static void __exit pca_isa_exit(void) -{ - isa_unregister_driver(&pca_isa_driver); } MODULE_AUTHOR("Ian Campbell "); diff --git a/trunk/drivers/i2c/busses/i2c-piix4.c b/trunk/drivers/i2c/busses/i2c-piix4.c index 5a52bf5e3fb0..21b180904085 100644 --- a/trunk/drivers/i2c/busses/i2c-piix4.c +++ b/trunk/drivers/i2c/busses/i2c-piix4.c @@ -428,7 +428,7 @@ static int __devinit piix4_probe(struct pci_dev *dev, /* set up the sysfs linkage to our parent device */ piix4_adapter.dev.parent = &dev->dev; - snprintf(piix4_adapter.name, sizeof(piix4_adapter.name), + snprintf(piix4_adapter.name, I2C_NAME_SIZE, "SMBus PIIX4 adapter at %04x", piix4_smba); if ((retval = i2c_add_adapter(&piix4_adapter))) { diff --git a/trunk/drivers/i2c/busses/i2c-pxa.c b/trunk/drivers/i2c/busses/i2c-pxa.c index 873544ab598e..14e83d0aac8c 100644 --- a/trunk/drivers/i2c/busses/i2c-pxa.c +++ b/trunk/drivers/i2c/busses/i2c-pxa.c @@ -539,18 +539,6 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c) writel(icr | ICR_START | ICR_TB, _ICR(i2c)); } -static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c) -{ - u32 icr; - - /* - * Clear the STOP and ACK flags - */ - icr = readl(_ICR(i2c)); - icr &= ~(ICR_STOP | ICR_ACKNAK); - writel(icr, _IRC(i2c)); -} - /* * We are protected by the adapter bus mutex. */ @@ -593,7 +581,6 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num) * The rest of the processing occurs in the interrupt handler. */ timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); - i2c_pxa_stop_message(i2c); /* * We place the return code in i2c->msg_idx. @@ -838,7 +825,7 @@ static const struct i2c_algorithm i2c_pxa_algorithm = { }; static struct pxa_i2c i2c_pxa = { - .lock = __SPIN_LOCK_UNLOCKED(i2c_pxa.lock), + .lock = SPIN_LOCK_UNLOCKED, .adap = { .owner = THIS_MODULE, .algo = &i2c_pxa_algorithm, @@ -852,7 +839,9 @@ static int i2c_pxa_probe(struct platform_device *dev) { struct pxa_i2c *i2c = &i2c_pxa; struct resource *res; +#ifdef CONFIG_I2C_PXA_SLAVE struct i2c_pxa_platform_data *plat = dev->dev.platform_data; +#endif int ret; int irq; @@ -900,14 +889,14 @@ static int i2c_pxa_probe(struct platform_device *dev) pxa_gpio_mode(GPIO117_I2CSCL_MD); pxa_gpio_mode(GPIO118_I2CSDA_MD); #endif - pxa_set_cken(CKEN_I2C, 1); + pxa_set_cken(CKEN14_I2C, 1); break; #ifdef CONFIG_PXA27x case 1: local_irq_disable(); PCFR |= PCFR_PI2CEN; local_irq_enable(); - pxa_set_cken(CKEN_PWRI2C, 1); + pxa_set_cken(CKEN15_PWRI2C, 1); #endif } @@ -922,10 +911,6 @@ static int i2c_pxa_probe(struct platform_device *dev) i2c->adap.algo_data = i2c; i2c->adap.dev.parent = &dev->dev; - if (plat) { - i2c->adap.class = plat->class; - } - ret = i2c_add_adapter(&i2c->adap); if (ret < 0) { printk(KERN_INFO "I2C: Failed to add bus\n"); @@ -948,11 +933,11 @@ static int i2c_pxa_probe(struct platform_device *dev) ereqirq: switch (dev->id) { case 0: - pxa_set_cken(CKEN_I2C, 0); + pxa_set_cken(CKEN14_I2C, 0); break; #ifdef CONFIG_PXA27x case 1: - pxa_set_cken(CKEN_PWRI2C, 0); + pxa_set_cken(CKEN15_PWRI2C, 0); local_irq_disable(); PCFR &= ~PCFR_PI2CEN; local_irq_enable(); @@ -975,11 +960,11 @@ static int i2c_pxa_remove(struct platform_device *dev) free_irq(i2c->irq, i2c); switch (dev->id) { case 0: - pxa_set_cken(CKEN_I2C, 0); + pxa_set_cken(CKEN14_I2C, 0); break; #ifdef CONFIG_PXA27x case 1: - pxa_set_cken(CKEN_PWRI2C, 0); + pxa_set_cken(CKEN15_PWRI2C, 0); local_irq_disable(); PCFR &= ~PCFR_PI2CEN; local_irq_enable(); diff --git a/trunk/drivers/i2c/busses/i2c-s3c2410.c b/trunk/drivers/i2c/busses/i2c-s3c2410.c index e68a96f589fd..556f244aae76 100644 --- a/trunk/drivers/i2c/busses/i2c-s3c2410.c +++ b/trunk/drivers/i2c/busses/i2c-s3c2410.c @@ -61,8 +61,6 @@ struct s3c24xx_i2c { unsigned int msg_idx; unsigned int msg_ptr; - unsigned int tx_setup; - enum s3c24xx_i2c_state state; void __iomem *regs; @@ -201,11 +199,8 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c, dev_dbg(i2c->dev, "START: %08lx to IICSTAT, %02x to DS\n", stat, addr); writeb(addr, i2c->regs + S3C2410_IICDS); - /* delay here to ensure the data byte has gotten onto the bus - * before the transaction is started */ - - ndelay(i2c->tx_setup); - + // delay a bit and reset iiccon before setting start (per samsung) + udelay(1); dev_dbg(i2c->dev, "iiccon, %08lx\n", iiccon); writel(iiccon, i2c->regs + S3C2410_IICCON); @@ -327,15 +322,7 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) if (!is_msgend(i2c)) { byte = i2c->msg->buf[i2c->msg_ptr++]; writeb(byte, i2c->regs + S3C2410_IICDS); - - /* delay after writing the byte to allow the - * data setup time on the bus, as writing the - * data to the register causes the first bit - * to appear on SDA, and SCL will change as - * soon as the interrupt is acknowledged */ - - ndelay(i2c->tx_setup); - + } else if (!is_lastmsg(i2c)) { /* we need to go to the next i2c message */ @@ -583,10 +570,9 @@ static const struct i2c_algorithm s3c24xx_i2c_algorithm = { }; static struct s3c24xx_i2c s3c24xx_i2c = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_i2c.lock), - .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait), - .tx_setup = 50, - .adap = { + .lock = SPIN_LOCK_UNLOCKED, + .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s3c24xx_i2c.wait), + .adap = { .name = "s3c2410-i2c", .owner = THIS_MODULE, .algo = &s3c24xx_i2c_algorithm, @@ -745,6 +731,26 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) return 0; } +static void s3c24xx_i2c_free(struct s3c24xx_i2c *i2c) +{ + if (i2c->clk != NULL && !IS_ERR(i2c->clk)) { + clk_disable(i2c->clk); + clk_put(i2c->clk); + i2c->clk = NULL; + } + + if (i2c->regs != NULL) { + iounmap(i2c->regs); + i2c->regs = NULL; + } + + if (i2c->ioarea != NULL) { + release_resource(i2c->ioarea); + kfree(i2c->ioarea); + i2c->ioarea = NULL; + } +} + /* s3c24xx_i2c_probe * * called by the bus driver when a suitable device is found @@ -763,7 +769,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) if (IS_ERR(i2c->clk)) { dev_err(&pdev->dev, "cannot get clock\n"); ret = -ENOENT; - goto err_noclk; + goto out; } dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk); @@ -776,7 +782,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) if (res == NULL) { dev_err(&pdev->dev, "cannot find IO resource\n"); ret = -ENOENT; - goto err_clk; + goto out; } i2c->ioarea = request_mem_region(res->start, (res->end-res->start)+1, @@ -785,7 +791,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) if (i2c->ioarea == NULL) { dev_err(&pdev->dev, "cannot request IO\n"); ret = -ENXIO; - goto err_clk; + goto out; } i2c->regs = ioremap(res->start, (res->end-res->start)+1); @@ -793,7 +799,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) if (i2c->regs == NULL) { dev_err(&pdev->dev, "cannot map IO\n"); ret = -ENXIO; - goto err_ioarea; + goto out; } dev_dbg(&pdev->dev, "registers %p (%p, %p)\n", i2c->regs, i2c->ioarea, res); @@ -807,7 +813,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ret = s3c24xx_i2c_init(i2c); if (ret != 0) - goto err_iomap; + goto out; /* find the IRQ for this unit (note, this relies on the init call to * ensure no current IRQs pending @@ -817,7 +823,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) if (res == NULL) { dev_err(&pdev->dev, "cannot find IRQ\n"); ret = -ENOENT; - goto err_iomap; + goto out; } ret = request_irq(res->start, s3c24xx_i2c_irq, IRQF_DISABLED, @@ -825,7 +831,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) if (ret != 0) { dev_err(&pdev->dev, "cannot claim IRQ\n"); - goto err_iomap; + goto out; } i2c->irq = res; @@ -835,29 +841,17 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) ret = i2c_add_adapter(&i2c->adap); if (ret < 0) { dev_err(&pdev->dev, "failed to add bus to i2c core\n"); - goto err_irq; + goto out; } platform_set_drvdata(pdev, i2c); dev_info(&pdev->dev, "%s: S3C I2C adapter\n", i2c->adap.dev.bus_id); - return 0; - - err_irq: - free_irq(i2c->irq->start, i2c); - - err_iomap: - iounmap(i2c->regs); - err_ioarea: - release_resource(i2c->ioarea); - kfree(i2c->ioarea); - - err_clk: - clk_disable(i2c->clk); - clk_put(i2c->clk); + out: + if (ret < 0) + s3c24xx_i2c_free(i2c); - err_noclk: return ret; } @@ -869,17 +863,11 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) static int s3c24xx_i2c_remove(struct platform_device *pdev) { struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev); - - i2c_del_adapter(&i2c->adap); - free_irq(i2c->irq->start, i2c); - - clk_disable(i2c->clk); - clk_put(i2c->clk); - - iounmap(i2c->regs); - - release_resource(i2c->ioarea); - kfree(i2c->ioarea); + + if (i2c != NULL) { + s3c24xx_i2c_free(i2c); + platform_set_drvdata(pdev, NULL); + } return 0; } diff --git a/trunk/drivers/i2c/busses/i2c-simtec.c b/trunk/drivers/i2c/busses/i2c-simtec.c deleted file mode 100644 index 10af8d31e12a..000000000000 --- a/trunk/drivers/i2c/busses/i2c-simtec.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2005 Simtec Electronics - * Ben Dooks - * - * Simtec Generic I2C Controller - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include - -#include -#include - -#include - -struct simtec_i2c_data { - struct resource *ioarea; - void __iomem *reg; - struct i2c_adapter adap; - struct i2c_algo_bit_data bit; -}; - -#define CMD_SET_SDA (1<<2) -#define CMD_SET_SCL (1<<3) - -#define STATE_SDA (1<<0) -#define STATE_SCL (1<<1) - -/* i2c bit-bus functions */ - -static void simtec_i2c_setsda(void *pw, int state) -{ - struct simtec_i2c_data *pd = pw; - writeb(CMD_SET_SDA | (state ? STATE_SDA : 0), pd->reg); -} - -static void simtec_i2c_setscl(void *pw, int state) -{ - struct simtec_i2c_data *pd = pw; - writeb(CMD_SET_SCL | (state ? STATE_SCL : 0), pd->reg); -} - -static int simtec_i2c_getsda(void *pw) -{ - struct simtec_i2c_data *pd = pw; - return readb(pd->reg) & STATE_SDA ? 1 : 0; -} - -static int simtec_i2c_getscl(void *pw) -{ - struct simtec_i2c_data *pd = pw; - return readb(pd->reg) & STATE_SCL ? 1 : 0; -} - -/* device registration */ - -static int simtec_i2c_probe(struct platform_device *dev) -{ - struct simtec_i2c_data *pd; - struct resource *res; - int size; - int ret; - - pd = kzalloc(sizeof(struct simtec_i2c_data), GFP_KERNEL); - if (pd == NULL) { - dev_err(&dev->dev, "cannot allocate private data\n"); - return -ENOMEM; - } - - platform_set_drvdata(dev, pd); - - res = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (res == NULL) { - dev_err(&dev->dev, "cannot find IO resource\n"); - ret = -ENOENT; - goto err; - } - - size = (res->end-res->start)+1; - - pd->ioarea = request_mem_region(res->start, size, dev->name); - if (pd->ioarea == NULL) { - dev_err(&dev->dev, "cannot request IO\n"); - ret = -ENXIO; - goto err; - } - - pd->reg = ioremap(res->start, size); - if (pd->reg == NULL) { - dev_err(&dev->dev, "cannot map IO\n"); - ret = -ENXIO; - goto err_res; - } - - /* setup the private data */ - - pd->adap.owner = THIS_MODULE; - pd->adap.algo_data = &pd->bit; - pd->adap.dev.parent = &dev->dev; - - strlcpy(pd->adap.name, "Simtec I2C", sizeof(pd->adap.name)); - - pd->bit.data = pd; - pd->bit.setsda = simtec_i2c_setsda; - pd->bit.setscl = simtec_i2c_setscl; - pd->bit.getsda = simtec_i2c_getsda; - pd->bit.getscl = simtec_i2c_getscl; - pd->bit.timeout = HZ; - pd->bit.udelay = 20; - - ret = i2c_bit_add_bus(&pd->adap); - if (ret) - goto err_all; - - return 0; - - err_all: - iounmap(pd->reg); - - err_res: - release_resource(pd->ioarea); - kfree(pd->ioarea); - - err: - kfree(pd); - return ret; -} - -static int simtec_i2c_remove(struct platform_device *dev) -{ - struct simtec_i2c_data *pd = platform_get_drvdata(dev); - - i2c_del_adapter(&pd->adap); - - iounmap(pd->reg); - release_resource(pd->ioarea); - kfree(pd->ioarea); - kfree(pd); - - return 0; -} - - -/* device driver */ - -static struct platform_driver simtec_i2c_driver = { - .driver = { - .name = "simtec-i2c", - .owner = THIS_MODULE, - }, - .probe = simtec_i2c_probe, - .remove = simtec_i2c_remove, -}; - -static int __init i2c_adap_simtec_init(void) -{ - return platform_driver_register(&simtec_i2c_driver); -} - -static void __exit i2c_adap_simtec_exit(void) -{ - platform_driver_unregister(&simtec_i2c_driver); -} - -module_init(i2c_adap_simtec_init); -module_exit(i2c_adap_simtec_exit); - -MODULE_DESCRIPTION("Simtec Generic I2C Bus driver"); -MODULE_AUTHOR("Ben Dooks "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/i2c/busses/i2c-sis96x.c b/trunk/drivers/i2c/busses/i2c-sis96x.c index dc235bb8e24d..4157b0cd604c 100644 --- a/trunk/drivers/i2c/busses/i2c-sis96x.c +++ b/trunk/drivers/i2c/busses/i2c-sis96x.c @@ -300,7 +300,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev, /* set up the sysfs linkage to our parent device */ sis96x_adapter.dev.parent = &dev->dev; - snprintf(sis96x_adapter.name, sizeof(sis96x_adapter.name), + snprintf(sis96x_adapter.name, I2C_NAME_SIZE, "SiS96x SMBus adapter at 0x%04x", sis96x_smbus_base); if ((retval = i2c_add_adapter(&sis96x_adapter))) { diff --git a/trunk/drivers/i2c/busses/i2c-tiny-usb.c b/trunk/drivers/i2c/busses/i2c-tiny-usb.c deleted file mode 100644 index 907999049d50..000000000000 --- a/trunk/drivers/i2c/busses/i2c-tiny-usb.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * driver for the i2c-tiny-usb adapter - 1.0 - * http://www.harbaum.org/till/i2c_tiny_usb - * - * Copyright (C) 2006-2007 Till Harbaum (Till@Harbaum.org) - * - * 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, version 2. - * - */ - -#include -#include -#include - -/* include interfaces to usb layer */ -#include - -/* include interface to i2c layer */ -#include - -/* commands via USB, must match command ids in the firmware */ -#define CMD_ECHO 0 -#define CMD_GET_FUNC 1 -#define CMD_SET_DELAY 2 -#define CMD_GET_STATUS 3 - -#define CMD_I2C_IO 4 -#define CMD_I2C_IO_BEGIN (1<<0) -#define CMD_I2C_IO_END (1<<1) - -/* i2c bit delay, default is 10us -> 100kHz */ -static int delay = 10; -module_param(delay, int, 0); -MODULE_PARM_DESC(delay, "bit delay in microseconds, " - "e.g. 10 for 100kHz (default is 100kHz)"); - -static int usb_read(struct i2c_adapter *adapter, int cmd, - int value, int index, void *data, int len); - -static int usb_write(struct i2c_adapter *adapter, int cmd, - int value, int index, void *data, int len); - -/* ----- begin of i2c layer ---------------------------------------------- */ - -#define STATUS_IDLE 0 -#define STATUS_ADDRESS_ACK 1 -#define STATUS_ADDRESS_NAK 2 - -static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) -{ - unsigned char status; - struct i2c_msg *pmsg; - int i; - - dev_dbg(&adapter->dev, "master xfer %d messages:\n", num); - - for (i = 0 ; i < num ; i++) { - int cmd = CMD_I2C_IO; - - if (i == 0) - cmd |= CMD_I2C_IO_BEGIN; - - if (i == num-1) - cmd |= CMD_I2C_IO_END; - - pmsg = &msgs[i]; - - dev_dbg(&adapter->dev, - " %d: %s (flags %d) %d bytes to 0x%02x\n", - i, pmsg->flags & I2C_M_RD ? "read" : "write", - pmsg->flags, pmsg->len, pmsg->addr); - - /* and directly send the message */ - if (pmsg->flags & I2C_M_RD) { - /* read data */ - if (usb_read(adapter, cmd, - pmsg->flags, pmsg->addr, - pmsg->buf, pmsg->len) != pmsg->len) { - dev_err(&adapter->dev, - "failure reading data\n"); - return -EREMOTEIO; - } - } else { - /* write data */ - if (usb_write(adapter, cmd, - pmsg->flags, pmsg->addr, - pmsg->buf, pmsg->len) != pmsg->len) { - dev_err(&adapter->dev, - "failure writing data\n"); - return -EREMOTEIO; - } - } - - /* read status */ - if (usb_read(adapter, CMD_GET_STATUS, 0, 0, &status, 1) != 1) { - dev_err(&adapter->dev, "failure reading status\n"); - return -EREMOTEIO; - } - - dev_dbg(&adapter->dev, " status = %d\n", status); - if (status == STATUS_ADDRESS_NAK) - return -EREMOTEIO; - } - - return i; -} - -static u32 usb_func(struct i2c_adapter *adapter) -{ - u32 func; - - /* get functionality from adapter */ - if (usb_read(adapter, CMD_GET_FUNC, 0, 0, &func, sizeof(func)) != - sizeof(func)) { - dev_err(&adapter->dev, "failure reading functionality\n"); - return 0; - } - - return func; -} - -/* This is the actual algorithm we define */ -static const struct i2c_algorithm usb_algorithm = { - .master_xfer = usb_xfer, - .functionality = usb_func, -}; - -/* ----- end of i2c layer ------------------------------------------------ */ - -/* ----- begin of usb layer ---------------------------------------------- */ - -/* The usb i2c interface uses a vid/pid pair donated by */ -/* Future Technology Devices International Ltd. */ -static struct usb_device_id i2c_tiny_usb_table [] = { - { USB_DEVICE(0x0403, 0xc631) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, i2c_tiny_usb_table); - -/* Structure to hold all of our device specific stuff */ -struct i2c_tiny_usb { - struct usb_device *usb_dev; /* the usb device for this device */ - struct usb_interface *interface; /* the interface for this device */ - struct i2c_adapter adapter; /* i2c related things */ -}; - -static int usb_read(struct i2c_adapter *adapter, int cmd, - int value, int index, void *data, int len) -{ - struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; - - /* do control transfer */ - return usb_control_msg(dev->usb_dev, usb_rcvctrlpipe(dev->usb_dev, 0), - cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE | - USB_DIR_IN, value, index, data, len, 2000); -} - -static int usb_write(struct i2c_adapter *adapter, int cmd, - int value, int index, void *data, int len) -{ - struct i2c_tiny_usb *dev = (struct i2c_tiny_usb *)adapter->algo_data; - - /* do control transfer */ - return usb_control_msg(dev->usb_dev, usb_sndctrlpipe(dev->usb_dev, 0), - cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, index, data, len, 2000); -} - -static void i2c_tiny_usb_free(struct i2c_tiny_usb *dev) -{ - usb_put_dev(dev->usb_dev); - kfree(dev); -} - -static int i2c_tiny_usb_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct i2c_tiny_usb *dev; - int retval = -ENOMEM; - u16 version; - - dev_dbg(&interface->dev, "probing usb device\n"); - - /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - dev_err(&interface->dev, "Out of memory\n"); - goto error; - } - - dev->usb_dev = usb_get_dev(interface_to_usbdev(interface)); - dev->interface = interface; - - /* save our data pointer in this interface device */ - usb_set_intfdata(interface, dev); - - version = le16_to_cpu(dev->usb_dev->descriptor.bcdDevice); - dev_info(&interface->dev, - "version %x.%02x found at bus %03d address %03d\n", - version >> 8, version & 0xff, - dev->usb_dev->bus->busnum, dev->usb_dev->devnum); - - /* setup i2c adapter description */ - dev->adapter.owner = THIS_MODULE; - dev->adapter.class = I2C_CLASS_HWMON; - dev->adapter.algo = &usb_algorithm; - dev->adapter.algo_data = dev; - snprintf(dev->adapter.name, I2C_NAME_SIZE, - "i2c-tiny-usb at bus %03d device %03d", - dev->usb_dev->bus->busnum, dev->usb_dev->devnum); - - if (usb_write(&dev->adapter, CMD_SET_DELAY, - cpu_to_le16(delay), 0, NULL, 0) != 0) { - dev_err(&dev->adapter.dev, - "failure setting delay to %dus\n", delay); - retval = -EIO; - goto error; - } - - dev->adapter.dev.parent = &dev->interface->dev; - - /* and finally attach to i2c layer */ - i2c_add_adapter(&dev->adapter); - - /* inform user about successful attachment to i2c layer */ - dev_info(&dev->adapter.dev, "connected i2c-tiny-usb device\n"); - - return 0; - - error: - if (dev) - i2c_tiny_usb_free(dev); - - return retval; -} - -static void i2c_tiny_usb_disconnect(struct usb_interface *interface) -{ - struct i2c_tiny_usb *dev = usb_get_intfdata(interface); - - i2c_del_adapter(&dev->adapter); - usb_set_intfdata(interface, NULL); - i2c_tiny_usb_free(dev); - - dev_dbg(&interface->dev, "disconnected\n"); -} - -static struct usb_driver i2c_tiny_usb_driver = { - .name = "i2c-tiny-usb", - .probe = i2c_tiny_usb_probe, - .disconnect = i2c_tiny_usb_disconnect, - .id_table = i2c_tiny_usb_table, -}; - -static int __init usb_i2c_tiny_usb_init(void) -{ - /* register this driver with the USB subsystem */ - return usb_register(&i2c_tiny_usb_driver); -} - -static void __exit usb_i2c_tiny_usb_exit(void) -{ - /* deregister this driver with the USB subsystem */ - usb_deregister(&i2c_tiny_usb_driver); -} - -module_init(usb_i2c_tiny_usb_init); -module_exit(usb_i2c_tiny_usb_exit); - -/* ----- end of usb layer ------------------------------------------------ */ - -MODULE_AUTHOR("Till Harbaum "); -MODULE_DESCRIPTION("i2c-tiny-usb driver v1.0"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/i2c/busses/i2c-viapro.c b/trunk/drivers/i2c/busses/i2c-viapro.c index 7a2bc06304fc..03c5fc868548 100644 --- a/trunk/drivers/i2c/busses/i2c-viapro.c +++ b/trunk/drivers/i2c/busses/i2c-viapro.c @@ -404,7 +404,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, } vt596_adapter.dev.parent = &pdev->dev; - snprintf(vt596_adapter.name, sizeof(vt596_adapter.name), + snprintf(vt596_adapter.name, I2C_NAME_SIZE, "SMBus Via Pro adapter at %04x", vt596_smba); vt596_pdev = pci_dev_get(pdev); diff --git a/trunk/drivers/i2c/busses/scx200_acb.c b/trunk/drivers/i2c/busses/scx200_acb.c index 0d6bd4f7b7fa..0b082c5a0195 100644 --- a/trunk/drivers/i2c/busses/scx200_acb.c +++ b/trunk/drivers/i2c/busses/scx200_acb.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -440,7 +441,7 @@ static __init struct scx200_acb_iface *scx200_create_iface(const char *text, adapter = &iface->adapter; i2c_set_adapdata(adapter, iface); - snprintf(adapter->name, sizeof(adapter->name), "%s ACB%d", text, index); + snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index); adapter->owner = THIS_MODULE; adapter->id = I2C_HW_SMBUS_SCX200; adapter->algo = &scx200_acb_algorithm; @@ -598,7 +599,6 @@ static __init int scx200_scan_pci(void) else { int i; - pci_dev_put(pdev); for (i = 0; i < MAX_DEVICES; ++i) { if (base[i] == 0) continue; diff --git a/trunk/drivers/i2c/chips/Kconfig b/trunk/drivers/i2c/chips/Kconfig index ea085a006ead..87ee3ce58618 100644 --- a/trunk/drivers/i2c/chips/Kconfig +++ b/trunk/drivers/i2c/chips/Kconfig @@ -3,10 +3,11 @@ # menu "Miscellaneous I2C Chip support" + depends on I2C config SENSORS_DS1337 tristate "Dallas Semiconductor DS1337 and DS1339 Real Time Clock" - depends on EXPERIMENTAL + depends on I2C && EXPERIMENTAL help If you say yes here you get support for Dallas Semiconductor DS1337 and DS1339 real-time clock chips. @@ -16,7 +17,7 @@ config SENSORS_DS1337 config SENSORS_DS1374 tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock" - depends on EXPERIMENTAL + depends on I2C && EXPERIMENTAL help If you say yes here you get support for Dallas Semiconductor DS1374 real-time clock chips. @@ -26,7 +27,7 @@ config SENSORS_DS1374 config SENSORS_EEPROM tristate "EEPROM reader" - depends on EXPERIMENTAL + depends on I2C && EXPERIMENTAL help If you say yes here you get read-only access to the EEPROM data available on modern memory DIMMs and Sony Vaio laptops. Such @@ -37,7 +38,7 @@ config SENSORS_EEPROM config SENSORS_PCF8574 tristate "Philips PCF8574 and PCF8574A" - depends on EXPERIMENTAL + depends on I2C && EXPERIMENTAL default n help If you say yes here you get support for Philips PCF8574 and @@ -51,7 +52,7 @@ config SENSORS_PCF8574 config SENSORS_PCA9539 tristate "Philips PCA9539 16-bit I/O port" - depends on EXPERIMENTAL + depends on I2C && EXPERIMENTAL help If you say yes here you get support for the Philips PCA9539 16-bit I/O port. @@ -61,7 +62,7 @@ config SENSORS_PCA9539 config SENSORS_PCF8591 tristate "Philips PCF8591" - depends on EXPERIMENTAL + depends on I2C && EXPERIMENTAL default n help If you say yes here you get support for Philips PCF8591 chips. @@ -74,7 +75,7 @@ config SENSORS_PCF8591 config ISP1301_OMAP tristate "Philips ISP1301 with OMAP OTG" - depends on ARCH_OMAP_OTG + depends on I2C && ARCH_OMAP_OTG help If you say yes here you get support for the Philips ISP1301 USB-On-The-Go transceiver working with the OMAP OTG controller. @@ -89,7 +90,7 @@ config ISP1301_OMAP # and having mostly OMAP-specific board support config TPS65010 tristate "TPS6501x Power Management chips" - depends on ARCH_OMAP + depends on I2C && ARCH_OMAP default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK help If you say yes here you get support for the TPS6501x series of @@ -102,7 +103,7 @@ config TPS65010 config SENSORS_M41T00 tristate "ST M41T00 RTC chip" - depends on PPC32 + depends on I2C && PPC32 help If you say yes here you get support for the ST M41T00 RTC chip. @@ -111,7 +112,7 @@ config SENSORS_M41T00 config SENSORS_MAX6875 tristate "Maxim MAX6875 Power supply supervisor" - depends on EXPERIMENTAL + depends on I2C && EXPERIMENTAL help If you say yes here you get support for the Maxim MAX6875 EEPROM-programmable, quad power-supply sequencer/supervisor. diff --git a/trunk/drivers/i2c/chips/tps65010.c b/trunk/drivers/i2c/chips/tps65010.c index 7ed92dc3d833..214fbb1423c5 100644 --- a/trunk/drivers/i2c/chips/tps65010.c +++ b/trunk/drivers/i2c/chips/tps65010.c @@ -351,10 +351,8 @@ static void tps65010_interrupt(struct tps65010 *tps) #if 0 /* REVISIT: this might need its own workqueue * plus tweaks including deadlock avoidance ... - * also needs to get error handling and probably - * an #ifdef CONFIG_SOFTWARE_SUSPEND */ - pm_suspend(PM_SUSPEND_DISK); + software_suspend(); #endif poll = 1; } diff --git a/trunk/drivers/i2c/i2c-boardinfo.c b/trunk/drivers/i2c/i2c-boardinfo.c deleted file mode 100644 index ffb35f09df03..000000000000 --- a/trunk/drivers/i2c/i2c-boardinfo.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * i2c-boardinfo.h - collect pre-declarations of I2C devices - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -#include "i2c-core.h" - - -/* These symbols are exported ONLY FOR the i2c core. - * No other users will be supported. - */ -DEFINE_MUTEX(__i2c_board_lock); -EXPORT_SYMBOL_GPL(__i2c_board_lock); - -LIST_HEAD(__i2c_board_list); -EXPORT_SYMBOL_GPL(__i2c_board_list); - -int __i2c_first_dynamic_bus_num; -EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num); - - -/** - * i2c_register_board_info - statically declare I2C devices - * @busnum: identifies the bus to which these devices belong - * @info: vector of i2c device descriptors - * @len: how many descriptors in the vector; may be zero to reserve - * the specified bus number. - * - * Systems using the Linux I2C driver stack can declare tables of board info - * while they initialize. This should be done in board-specific init code - * near arch_initcall() time, or equivalent, before any I2C adapter driver is - * registered. For example, mainboard init code could define several devices, - * as could the init code for each daughtercard in a board stack. - * - * The I2C devices will be created later, after the adapter for the relevant - * bus has been registered. After that moment, standard driver model tools - * are used to bind "new style" I2C drivers to the devices. The bus number - * for any device declared using this routine is not available for dynamic - * allocation. - * - * The board info passed can safely be __initdata, but be careful of embedded - * pointers (for platform_data, functions, etc) since that won't be copied. - */ -int __init -i2c_register_board_info(int busnum, - struct i2c_board_info const *info, unsigned len) -{ - int status; - - mutex_lock(&__i2c_board_lock); - - /* dynamic bus numbers will be assigned after the last static one */ - if (busnum >= __i2c_first_dynamic_bus_num) - __i2c_first_dynamic_bus_num = busnum + 1; - - for (status = 0; len; len--, info++) { - struct i2c_devinfo *devinfo; - - devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); - if (!devinfo) { - pr_debug("i2c-core: can't register boardinfo!\n"); - status = -ENOMEM; - break; - } - - devinfo->busnum = busnum; - devinfo->board_info = *info; - list_add_tail(&devinfo->list, &__i2c_board_list); - } - - mutex_unlock(&__i2c_board_lock); - - return status; -} diff --git a/trunk/drivers/i2c/i2c-core.c b/trunk/drivers/i2c/i2c-core.c index 64f8e56d300e..21fe1406c8b4 100644 --- a/trunk/drivers/i2c/i2c-core.c +++ b/trunk/drivers/i2c/i2c-core.c @@ -35,92 +35,29 @@ #include #include -#include "i2c-core.h" - static LIST_HEAD(adapters); static LIST_HEAD(drivers); static DEFINE_MUTEX(core_lists); static DEFINE_IDR(i2c_adapter_idr); -#define is_newstyle_driver(d) ((d)->probe || (d)->remove) /* ------------------------------------------------------------------------- */ +/* match always succeeds, as we want the probe() to tell if we really accept this match */ static int i2c_device_match(struct device *dev, struct device_driver *drv) { - struct i2c_client *client = to_i2c_client(dev); - struct i2c_driver *driver = to_i2c_driver(drv); - - /* make legacy i2c drivers bypass driver model probing entirely; - * such drivers scan each i2c adapter/bus themselves. - */ - if (!is_newstyle_driver(driver)) - return 0; - - /* new style drivers use the same kind of driver matching policy - * as platform devices or SPI: compare device and driver IDs. - */ - return strcmp(client->driver_name, drv->name) == 0; -} - -#ifdef CONFIG_HOTPLUG - -/* uevent helps with hotplug: modprobe -q $(MODALIAS) */ -static int i2c_device_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) -{ - struct i2c_client *client = to_i2c_client(dev); - int i = 0, length = 0; - - /* by definition, legacy drivers can't hotplug */ - if (dev->driver || !client->driver_name) - return 0; - - if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, - "MODALIAS=%s", client->driver_name)) - return -ENOMEM; - envp[i] = NULL; - dev_dbg(dev, "uevent\n"); - return 0; + return 1; } -#else -#define i2c_device_uevent NULL -#endif /* CONFIG_HOTPLUG */ - static int i2c_device_probe(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct i2c_driver *driver = to_i2c_driver(dev->driver); - - if (!driver->probe) - return -ENODEV; - client->driver = driver; - dev_dbg(dev, "probe\n"); - return driver->probe(client); + return -ENODEV; } static int i2c_device_remove(struct device *dev) { - struct i2c_client *client = to_i2c_client(dev); - struct i2c_driver *driver; - int status; - - if (!dev->driver) - return 0; - - driver = to_i2c_driver(dev->driver); - if (driver->remove) { - dev_dbg(dev, "remove\n"); - status = driver->remove(client); - } else { - dev->driver = NULL; - status = 0; - } - if (status == 0) - client->driver = NULL; - return status; + return 0; } static void i2c_device_shutdown(struct device *dev) @@ -158,184 +95,122 @@ static int i2c_device_resume(struct device * dev) return driver->resume(to_i2c_client(dev)); } -static void i2c_client_release(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - complete(&client->released); -} - -static void i2c_client_dev_release(struct device *dev) -{ - kfree(to_i2c_client(dev)); -} - -static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return sprintf(buf, "%s\n", client->name); -} - -static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct i2c_client *client = to_i2c_client(dev); - return client->driver_name - ? sprintf(buf, "%s\n", client->driver_name) - : 0; -} - -static struct device_attribute i2c_dev_attrs[] = { - __ATTR(name, S_IRUGO, show_client_name, NULL), - /* modalias helps coldplug: modprobe $(cat .../modalias) */ - __ATTR(modalias, S_IRUGO, show_modalias, NULL), - { }, -}; - struct bus_type i2c_bus_type = { .name = "i2c", - .dev_attrs = i2c_dev_attrs, .match = i2c_device_match, - .uevent = i2c_device_uevent, .probe = i2c_device_probe, .remove = i2c_device_remove, .shutdown = i2c_device_shutdown, .suspend = i2c_device_suspend, .resume = i2c_device_resume, }; -EXPORT_SYMBOL_GPL(i2c_bus_type); - -/** - * i2c_new_device - instantiate an i2c device for use with a new style driver - * @adap: the adapter managing the device - * @info: describes one I2C device; bus_num is ignored - * - * Create a device to work with a new style i2c driver, where binding is - * handled through driver model probe()/remove() methods. This call is not - * appropriate for use by mainboad initialization logic, which usually runs - * during an arch_initcall() long before any i2c_adapter could exist. - * - * This returns the new i2c client, which may be saved for later use with - * i2c_unregister_device(); or NULL to indicate an error. - */ -struct i2c_client * -i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) -{ - struct i2c_client *client; - int status; - - client = kzalloc(sizeof *client, GFP_KERNEL); - if (!client) - return NULL; - - client->adapter = adap; - - client->dev.platform_data = info->platform_data; - client->flags = info->flags; - client->addr = info->addr; - client->irq = info->irq; - - strlcpy(client->driver_name, info->driver_name, - sizeof(client->driver_name)); - strlcpy(client->name, info->type, sizeof(client->name)); - - /* a new style driver may be bound to this device when we - * return from this function, or any later moment (e.g. maybe - * hotplugging will load the driver module). and the device - * refcount model is the standard driver model one. - */ - status = i2c_attach_client(client); - if (status < 0) { - kfree(client); - client = NULL; - } - return client; -} -EXPORT_SYMBOL_GPL(i2c_new_device); +/* ------------------------------------------------------------------------- */ -/** - * i2c_unregister_device - reverse effect of i2c_new_device() - * @client: value returned from i2c_new_device() - */ -void i2c_unregister_device(struct i2c_client *client) +void i2c_adapter_dev_release(struct device *dev) { - struct i2c_adapter *adapter = client->adapter; - struct i2c_driver *driver = client->driver; - - if (driver && !is_newstyle_driver(driver)) { - dev_err(&client->dev, "can't unregister devices " - "with legacy drivers\n"); - WARN_ON(1); - return; - } - - mutex_lock(&adapter->clist_lock); - list_del(&client->list); - mutex_unlock(&adapter->clist_lock); - - device_unregister(&client->dev); + struct i2c_adapter *adap = dev_to_i2c_adapter(dev); + complete(&adap->dev_released); } -EXPORT_SYMBOL_GPL(i2c_unregister_device); +struct device_driver i2c_adapter_driver = { + .owner = THIS_MODULE, + .name = "i2c_adapter", + .bus = &i2c_bus_type, +}; /* ------------------------------------------------------------------------- */ /* I2C bus adapters -- one roots each I2C or SMBUS segment */ -void i2c_adapter_dev_release(struct device *dev) +static void i2c_adapter_class_dev_release(struct class_device *dev) { - struct i2c_adapter *adap = to_i2c_adapter(dev); - complete(&adap->dev_released); + struct i2c_adapter *adap = class_dev_to_i2c_adapter(dev); + complete(&adap->class_dev_released); } -EXPORT_SYMBOL_GPL(i2c_adapter_dev_release); /* exported to i2c-isa */ -static ssize_t -show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t i2c_adapter_show_name(struct class_device *cdev, char *buf) { - struct i2c_adapter *adap = to_i2c_adapter(dev); + struct i2c_adapter *adap = class_dev_to_i2c_adapter(cdev); return sprintf(buf, "%s\n", adap->name); } -static struct device_attribute i2c_adapter_attrs[] = { - __ATTR(name, S_IRUGO, show_adapter_name, NULL), +static struct class_device_attribute i2c_adapter_attrs[] = { + __ATTR(name, S_IRUGO, i2c_adapter_show_name, NULL), { }, }; struct class i2c_adapter_class = { .owner = THIS_MODULE, .name = "i2c-adapter", - .dev_attrs = i2c_adapter_attrs, + .class_dev_attrs = i2c_adapter_attrs, + .release = &i2c_adapter_class_dev_release, }; -EXPORT_SYMBOL_GPL(i2c_adapter_class); /* exported to i2c-isa */ -static void i2c_scan_static_board_info(struct i2c_adapter *adapter) +static ssize_t show_adapter_name(struct device *dev, struct device_attribute *attr, char *buf) { - struct i2c_devinfo *devinfo; - - mutex_lock(&__i2c_board_lock); - list_for_each_entry(devinfo, &__i2c_board_list, list) { - if (devinfo->busnum == adapter->nr - && !i2c_new_device(adapter, - &devinfo->board_info)) - printk(KERN_ERR "i2c-core: can't create i2c%d-%04x\n", - i2c_adapter_id(adapter), - devinfo->board_info.addr); - } - mutex_unlock(&__i2c_board_lock); + struct i2c_adapter *adap = dev_to_i2c_adapter(dev); + return sprintf(buf, "%s\n", adap->name); } +static DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); + -static int i2c_register_adapter(struct i2c_adapter *adap) +static void i2c_client_release(struct device *dev) { - int res = 0; + struct i2c_client *client = to_i2c_client(dev); + complete(&client->released); +} + +static ssize_t show_client_name(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + return sprintf(buf, "%s\n", client->name); +} + +/* + * We can't use the DEVICE_ATTR() macro here, as we used the same name for + * an i2c adapter attribute (above). + */ +static struct device_attribute dev_attr_client_name = + __ATTR(name, S_IRUGO, &show_client_name, NULL); + + +/* --------------------------------------------------- + * registering functions + * --------------------------------------------------- + */ + +/* ----- + * i2c_add_adapter is called from within the algorithm layer, + * when a new hw adapter registers. A new device is register to be + * available for clients. + */ +int i2c_add_adapter(struct i2c_adapter *adap) +{ + int id, res = 0; struct list_head *item; struct i2c_driver *driver; + mutex_lock(&core_lists); + + if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) { + res = -ENOMEM; + goto out_unlock; + } + + res = idr_get_new(&i2c_adapter_idr, adap, &id); + if (res < 0) { + if (res == -EAGAIN) + res = -ENOMEM; + goto out_unlock; + } + + adap->nr = id & MAX_ID_MASK; mutex_init(&adap->bus_lock); mutex_init(&adap->clist_lock); + list_add_tail(&adap->list,&adapters); INIT_LIST_HEAD(&adap->clients); - mutex_lock(&core_lists); - list_add_tail(&adap->list, &adapters); - /* Add the adapter to the driver core. * If the parent pointer is not set up, * we add this adapter to the host bus. @@ -346,19 +221,27 @@ static int i2c_register_adapter(struct i2c_adapter *adap) "physical device\n", adap->name); } sprintf(adap->dev.bus_id, "i2c-%d", adap->nr); + adap->dev.driver = &i2c_adapter_driver; adap->dev.release = &i2c_adapter_dev_release; - adap->dev.class = &i2c_adapter_class; res = device_register(&adap->dev); if (res) goto out_list; + res = device_create_file(&adap->dev, &dev_attr_name); + if (res) + goto out_unregister; + + /* Add this adapter to the i2c_adapter class */ + memset(&adap->class_dev, 0x00, sizeof(struct class_device)); + adap->class_dev.dev = &adap->dev; + adap->class_dev.class = &i2c_adapter_class; + strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE); + res = class_device_register(&adap->class_dev); + if (res) + goto out_remove_name; dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); - /* create pre-declared device nodes for new-style drivers */ - if (adap->nr < __i2c_first_dynamic_bus_num) - i2c_scan_static_board_info(adap); - - /* let legacy drivers scan this bus for matching devices */ + /* inform drivers of new adapters */ list_for_each(item,&drivers) { driver = list_entry(item, struct i2c_driver, list); if (driver->attach_adapter) @@ -370,98 +253,18 @@ static int i2c_register_adapter(struct i2c_adapter *adap) mutex_unlock(&core_lists); return res; +out_remove_name: + device_remove_file(&adap->dev, &dev_attr_name); +out_unregister: + init_completion(&adap->dev_released); /* Needed? */ + device_unregister(&adap->dev); + wait_for_completion(&adap->dev_released); out_list: list_del(&adap->list); idr_remove(&i2c_adapter_idr, adap->nr); goto out_unlock; } -/** - * i2c_add_adapter - declare i2c adapter, use dynamic bus number - * @adapter: the adapter to add - * - * This routine is used to declare an I2C adapter when its bus number - * doesn't matter. Examples: for I2C adapters dynamically added by - * USB links or PCI plugin cards. - * - * When this returns zero, a new bus number was allocated and stored - * in adap->nr, and the specified adapter became available for clients. - * Otherwise, a negative errno value is returned. - */ -int i2c_add_adapter(struct i2c_adapter *adapter) -{ - int id, res = 0; - -retry: - if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) - return -ENOMEM; - - mutex_lock(&core_lists); - /* "above" here means "above or equal to", sigh */ - res = idr_get_new_above(&i2c_adapter_idr, adapter, - __i2c_first_dynamic_bus_num, &id); - mutex_unlock(&core_lists); - - if (res < 0) { - if (res == -EAGAIN) - goto retry; - return res; - } - - adapter->nr = id; - return i2c_register_adapter(adapter); -} -EXPORT_SYMBOL(i2c_add_adapter); - -/** - * i2c_add_numbered_adapter - declare i2c adapter, use static bus number - * @adap: the adapter to register (with adap->nr initialized) - * - * This routine is used to declare an I2C adapter when its bus number - * matters. Example: for I2C adapters from system-on-chip CPUs, or - * otherwise built in to the system's mainboard, and where i2c_board_info - * is used to properly configure I2C devices. - * - * If no devices have pre-been declared for this bus, then be sure to - * register the adapter before any dynamically allocated ones. Otherwise - * the required bus ID may not be available. - * - * When this returns zero, the specified adapter became available for - * clients using the bus number provided in adap->nr. Also, the table - * of I2C devices pre-declared using i2c_register_board_info() is scanned, - * and the appropriate driver model device nodes are created. Otherwise, a - * negative errno value is returned. - */ -int i2c_add_numbered_adapter(struct i2c_adapter *adap) -{ - int id; - int status; - - if (adap->nr & ~MAX_ID_MASK) - return -EINVAL; - -retry: - if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) - return -ENOMEM; - - mutex_lock(&core_lists); - /* "above" here means "above or equal to", sigh; - * we need the "equal to" result to force the result - */ - status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id); - if (status == 0 && id != adap->nr) { - status = -EBUSY; - idr_remove(&i2c_adapter_idr, id); - } - mutex_unlock(&core_lists); - if (status == -EAGAIN) - goto retry; - - if (status == 0) - status = i2c_register_adapter(adap); - return status; -} -EXPORT_SYMBOL_GPL(i2c_add_numbered_adapter); int i2c_del_adapter(struct i2c_adapter *adap) { @@ -499,19 +302,9 @@ int i2c_del_adapter(struct i2c_adapter *adap) /* detach any active clients. This must be done first, because * it can fail; in which case we give up. */ list_for_each_safe(item, _n, &adap->clients) { - struct i2c_driver *driver; - client = list_entry(item, struct i2c_client, list); - driver = client->driver; - - /* new style, follow standard driver model */ - if (!driver || is_newstyle_driver(driver)) { - i2c_unregister_device(client); - continue; - } - /* legacy drivers create and remove clients themselves */ - if ((res = driver->detach_client(client))) { + if ((res=client->driver->detach_client(client))) { dev_err(&adap->dev, "detach_client failed for client " "[%s] at address 0x%02x\n", client->name, client->addr); @@ -521,13 +314,17 @@ int i2c_del_adapter(struct i2c_adapter *adap) /* clean up the sysfs representation */ init_completion(&adap->dev_released); + init_completion(&adap->class_dev_released); + class_device_unregister(&adap->class_dev); + device_remove_file(&adap->dev, &dev_attr_name); device_unregister(&adap->dev); list_del(&adap->list); /* wait for sysfs to drop all references */ wait_for_completion(&adap->dev_released); + wait_for_completion(&adap->class_dev_released); - /* free bus id */ + /* free dynamically allocated bus id */ idr_remove(&i2c_adapter_idr, adap->nr); dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); @@ -536,42 +333,24 @@ int i2c_del_adapter(struct i2c_adapter *adap) mutex_unlock(&core_lists); return res; } -EXPORT_SYMBOL(i2c_del_adapter); - -/* ------------------------------------------------------------------------- */ -/* - * An i2c_driver is used with one or more i2c_client (device) nodes to access - * i2c slave chips, on a bus instance associated with some i2c_adapter. There - * are two models for binding the driver to its device: "new style" drivers - * follow the standard Linux driver model and just respond to probe() calls - * issued if the driver core sees they match(); "legacy" drivers create device - * nodes themselves. +/* ----- + * What follows is the "upwards" interface: commands for talking to clients, + * which implement the functions to access the physical information of the + * chips. */ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) { + struct list_head *item; + struct i2c_adapter *adapter; int res; - /* new style driver methods can't mix with legacy ones */ - if (is_newstyle_driver(driver)) { - if (driver->attach_adapter || driver->detach_adapter - || driver->detach_client) { - printk(KERN_WARNING - "i2c-core: driver [%s] is confused\n", - driver->driver.name); - return -EINVAL; - } - } - /* add the driver to the list of i2c drivers in the driver core */ driver->driver.owner = owner; driver->driver.bus = &i2c_bus_type; - /* for new style drivers, when registration returns the driver core - * will have called probe() for all matching-but-unbound devices. - */ res = driver_register(&driver->driver); if (res) return res; @@ -581,11 +360,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) list_add_tail(&driver->list,&drivers); pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); - /* legacy drivers scan i2c busses directly */ + /* now look for instances of driver on our adapters */ if (driver->attach_adapter) { - struct i2c_adapter *adapter; - - list_for_each_entry(adapter, &adapters, list) { + list_for_each(item,&adapters) { + adapter = list_entry(item, struct i2c_adapter, list); driver->attach_adapter(adapter); } } @@ -595,21 +373,15 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) } EXPORT_SYMBOL(i2c_register_driver); -/** - * i2c_del_driver - unregister I2C driver - * @driver: the driver being unregistered - */ -void i2c_del_driver(struct i2c_driver *driver) +int i2c_del_driver(struct i2c_driver *driver) { struct list_head *item1, *item2, *_n; struct i2c_client *client; struct i2c_adapter *adap; - mutex_lock(&core_lists); + int res = 0; - /* new-style driver? */ - if (is_newstyle_driver(driver)) - goto unregister; + mutex_lock(&core_lists); /* Have a look at each adapter, if clients of this driver are still * attached. If so, detach them to be able to kill the driver @@ -618,10 +390,11 @@ void i2c_del_driver(struct i2c_driver *driver) list_for_each(item1,&adapters) { adap = list_entry(item1, struct i2c_adapter, list); if (driver->detach_adapter) { - if (driver->detach_adapter(adap)) { + if ((res = driver->detach_adapter(adap))) { dev_err(&adap->dev, "detach_adapter failed " "for driver [%s]\n", driver->driver.name); + goto out_unlock; } } else { list_for_each_safe(item2, _n, &adap->clients) { @@ -631,26 +404,25 @@ void i2c_del_driver(struct i2c_driver *driver) dev_dbg(&adap->dev, "detaching client [%s] " "at 0x%02x\n", client->name, client->addr); - if (driver->detach_client(client)) { + if ((res = driver->detach_client(client))) { dev_err(&adap->dev, "detach_client " "failed for client [%s] at " "0x%02x\n", client->name, client->addr); + goto out_unlock; } } } } - unregister: driver_unregister(&driver->driver); list_del(&driver->list); pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); + out_unlock: mutex_unlock(&core_lists); + return 0; } -EXPORT_SYMBOL(i2c_del_driver); - -/* ------------------------------------------------------------------------- */ static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr) { @@ -675,7 +447,6 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr) return rval; } -EXPORT_SYMBOL(i2c_check_addr); int i2c_attach_client(struct i2c_client *client) { @@ -692,15 +463,9 @@ int i2c_attach_client(struct i2c_client *client) client->usage_count = 0; client->dev.parent = &client->adapter->dev; + client->dev.driver = &client->driver->driver; client->dev.bus = &i2c_bus_type; - - if (client->driver) - client->dev.driver = &client->driver->driver; - - if (client->driver && !is_newstyle_driver(client->driver)) - client->dev.release = i2c_client_release; - else - client->dev.release = i2c_client_dev_release; + client->dev.release = &i2c_client_release; snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id), "%d-%04x", i2c_adapter_id(adapter), client->addr); @@ -709,6 +474,9 @@ int i2c_attach_client(struct i2c_client *client) res = device_register(&client->dev); if (res) goto out_list; + res = device_create_file(&client->dev, &dev_attr_client_name); + if (res) + goto out_unregister; mutex_unlock(&adapter->clist_lock); if (adapter->client_register) { @@ -721,6 +489,10 @@ int i2c_attach_client(struct i2c_client *client) return 0; +out_unregister: + init_completion(&client->released); /* Needed? */ + device_unregister(&client->dev); + wait_for_completion(&client->released); out_list: list_del(&client->list); dev_err(&adapter->dev, "Failed to attach i2c client %s at 0x%02x " @@ -729,7 +501,7 @@ int i2c_attach_client(struct i2c_client *client) mutex_unlock(&adapter->clist_lock); return res; } -EXPORT_SYMBOL(i2c_attach_client); + int i2c_detach_client(struct i2c_client *client) { @@ -755,6 +527,7 @@ int i2c_detach_client(struct i2c_client *client) mutex_lock(&adapter->clist_lock); list_del(&client->list); init_completion(&client->released); + device_remove_file(&client->dev, &dev_attr_client_name); device_unregister(&client->dev); mutex_unlock(&adapter->clist_lock); wait_for_completion(&client->released); @@ -762,7 +535,6 @@ int i2c_detach_client(struct i2c_client *client) out: return res; } -EXPORT_SYMBOL(i2c_detach_client); static int i2c_inc_use_client(struct i2c_client *client) { @@ -795,7 +567,6 @@ int i2c_use_client(struct i2c_client *client) return 0; } -EXPORT_SYMBOL(i2c_use_client); int i2c_release_client(struct i2c_client *client) { @@ -810,7 +581,6 @@ int i2c_release_client(struct i2c_client *client) return 0; } -EXPORT_SYMBOL(i2c_release_client); void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) { @@ -831,13 +601,15 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) } mutex_unlock(&adap->clist_lock); } -EXPORT_SYMBOL(i2c_clients_command); static int __init i2c_init(void) { int retval; retval = bus_register(&i2c_bus_type); + if (retval) + return retval; + retval = driver_register(&i2c_adapter_driver); if (retval) return retval; return class_register(&i2c_adapter_class); @@ -846,6 +618,7 @@ static int __init i2c_init(void) static void __exit i2c_exit(void) { class_unregister(&i2c_adapter_class); + driver_unregister(&i2c_adapter_driver); bus_unregister(&i2c_bus_type); } @@ -865,9 +638,8 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) #ifdef DEBUG for (ret = 0; ret < num; ret++) { dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, " - "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD) - ? 'R' : 'W', msgs[ret].addr, msgs[ret].len, - (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : ""); + "len=%d\n", ret, msgs[ret].flags & I2C_M_RD ? + 'R' : 'W', msgs[ret].addr, msgs[ret].len); } #endif @@ -881,7 +653,6 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) return -ENOSYS; } } -EXPORT_SYMBOL(i2c_transfer); int i2c_master_send(struct i2c_client *client,const char *buf ,int count) { @@ -900,7 +671,6 @@ int i2c_master_send(struct i2c_client *client,const char *buf ,int count) transmitted, else error code. */ return (ret == 1) ? count : ret; } -EXPORT_SYMBOL(i2c_master_send); int i2c_master_recv(struct i2c_client *client, char *buf ,int count) { @@ -920,7 +690,7 @@ int i2c_master_recv(struct i2c_client *client, char *buf ,int count) transmitted, else error code. */ return (ret == 1) ? count : ret; } -EXPORT_SYMBOL(i2c_master_recv); + int i2c_control(struct i2c_client *client, unsigned int cmd, unsigned long arg) @@ -942,7 +712,6 @@ int i2c_control(struct i2c_client *client, } return ret; } -EXPORT_SYMBOL(i2c_control); /* ---------------------------------------------------- * the i2c address scanning function @@ -1084,70 +853,6 @@ int i2c_probe(struct i2c_adapter *adapter, return 0; } -EXPORT_SYMBOL(i2c_probe); - -struct i2c_client * -i2c_new_probed_device(struct i2c_adapter *adap, - struct i2c_board_info *info, - unsigned short const *addr_list) -{ - int i; - - /* Stop here if the bus doesn't support probing */ - if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) { - dev_err(&adap->dev, "Probing not supported\n"); - return NULL; - } - - mutex_lock(&adap->clist_lock); - for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) { - /* Check address validity */ - if (addr_list[i] < 0x03 || addr_list[i] > 0x77) { - dev_warn(&adap->dev, "Invalid 7-bit address " - "0x%02x\n", addr_list[i]); - continue; - } - - /* Check address availability */ - if (__i2c_check_addr(adap, addr_list[i])) { - dev_dbg(&adap->dev, "Address 0x%02x already in " - "use, not probing\n", addr_list[i]); - continue; - } - - /* Test address responsiveness - The default probe method is a quick write, but it is known - to corrupt the 24RF08 EEPROMs due to a state machine bug, - and could also irreversibly write-protect some EEPROMs, so - for address ranges 0x30-0x37 and 0x50-0x5f, we use a byte - read instead. Also, some bus drivers don't implement - quick write, so we fallback to a byte read it that case - too. */ - if ((addr_list[i] & ~0x07) == 0x30 - || (addr_list[i] & ~0x0f) == 0x50 - || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) { - if (i2c_smbus_xfer(adap, addr_list[i], 0, - I2C_SMBUS_READ, 0, - I2C_SMBUS_BYTE, NULL) >= 0) - break; - } else { - if (i2c_smbus_xfer(adap, addr_list[i], 0, - I2C_SMBUS_WRITE, 0, - I2C_SMBUS_QUICK, NULL) >= 0) - break; - } - } - mutex_unlock(&adap->clist_lock); - - if (addr_list[i] == I2C_CLIENT_END) { - dev_dbg(&adap->dev, "Probing failed, no device found\n"); - return NULL; - } - - info->addr = addr_list[i]; - return i2c_new_device(adap, info); -} -EXPORT_SYMBOL_GPL(i2c_new_probed_device); struct i2c_adapter* i2c_get_adapter(int id) { @@ -1161,13 +866,11 @@ struct i2c_adapter* i2c_get_adapter(int id) mutex_unlock(&core_lists); return adapter; } -EXPORT_SYMBOL(i2c_get_adapter); void i2c_put_adapter(struct i2c_adapter *adap) { module_put(adap->owner); } -EXPORT_SYMBOL(i2c_put_adapter); /* The SMBus parts */ @@ -1236,7 +939,6 @@ s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value) return i2c_smbus_xfer(client->adapter,client->addr,client->flags, value,0,I2C_SMBUS_QUICK,NULL); } -EXPORT_SYMBOL(i2c_smbus_write_quick); s32 i2c_smbus_read_byte(struct i2c_client *client) { @@ -1247,14 +949,12 @@ s32 i2c_smbus_read_byte(struct i2c_client *client) else return data.byte; } -EXPORT_SYMBOL(i2c_smbus_read_byte); s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter,client->addr,client->flags, I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); } -EXPORT_SYMBOL(i2c_smbus_write_byte); s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) { @@ -1265,7 +965,6 @@ s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) else return data.byte; } -EXPORT_SYMBOL(i2c_smbus_read_byte_data); s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) { @@ -1275,7 +974,6 @@ s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) I2C_SMBUS_WRITE,command, I2C_SMBUS_BYTE_DATA,&data); } -EXPORT_SYMBOL(i2c_smbus_write_byte_data); s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) { @@ -1286,7 +984,6 @@ s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) else return data.word; } -EXPORT_SYMBOL(i2c_smbus_read_word_data); s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) { @@ -1296,23 +993,6 @@ s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) I2C_SMBUS_WRITE,command, I2C_SMBUS_WORD_DATA,&data); } -EXPORT_SYMBOL(i2c_smbus_write_word_data); - -/* Returns the number of read bytes */ -s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command, - u8 *values) -{ - union i2c_smbus_data data; - - if (i2c_smbus_xfer(client->adapter, client->addr, client->flags, - I2C_SMBUS_READ, command, - I2C_SMBUS_BLOCK_DATA, &data)) - return -1; - - memcpy(values, &data.block[1], data.block[0]); - return data.block[0]; -} -EXPORT_SYMBOL(i2c_smbus_read_block_data); s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, u8 length, const u8 *values) @@ -1327,7 +1007,6 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, I2C_SMBUS_WRITE,command, I2C_SMBUS_BLOCK_DATA,&data); } -EXPORT_SYMBOL(i2c_smbus_write_block_data); /* Returns the number of read bytes */ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values) @@ -1342,7 +1021,6 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val memcpy(values, &data.block[1], data.block[0]); return data.block[0]; } -EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, u8 length, const u8 *values) @@ -1357,7 +1035,6 @@ s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, I2C_SMBUS_WRITE, command, I2C_SMBUS_I2C_BLOCK_DATA, &data); } -EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); /* Simulate a SMBus command using the i2c protocol No checking of parameters is done! */ @@ -1421,9 +1098,9 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, break; case I2C_SMBUS_BLOCK_DATA: if (read_write == I2C_SMBUS_READ) { - msg[1].flags |= I2C_M_RECV_LEN; - msg[1].len = 1; /* block length will be added by - the underlying bus driver */ + dev_err(&adapter->dev, "Block read not supported " + "under I2C emulation!\n"); + return -1; } else { msg[0].len = data->block[0] + 2; if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) { @@ -1437,21 +1114,9 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, } break; case I2C_SMBUS_BLOCK_PROC_CALL: - num = 2; /* Another special case */ - read_write = I2C_SMBUS_READ; - if (data->block[0] > I2C_SMBUS_BLOCK_MAX) { - dev_err(&adapter->dev, "%s called with invalid " - "block proc call size (%d)\n", __FUNCTION__, - data->block[0]); - return -1; - } - msg[0].len = data->block[0] + 2; - for (i = 1; i < msg[0].len; i++) - msgbuf0[i] = data->block[i-1]; - msg[1].flags |= I2C_M_RECV_LEN; - msg[1].len = 1; /* block length will be added by - the underlying bus driver */ - break; + dev_dbg(&adapter->dev, "Block process call not supported " + "under I2C emulation!\n"); + return -1; case I2C_SMBUS_I2C_BLOCK_DATA: if (read_write == I2C_SMBUS_READ) { msg[1].len = I2C_SMBUS_BLOCK_MAX; @@ -1515,11 +1180,6 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++) data->block[i+1] = msgbuf1[i]; break; - case I2C_SMBUS_BLOCK_DATA: - case I2C_SMBUS_BLOCK_PROC_CALL: - for (i = 0; i < msgbuf1[0] + 1; i++) - data->block[i] = msgbuf1[i]; - break; } return 0; } @@ -1544,7 +1204,43 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, return res; } + + +/* Next four are needed by i2c-isa */ +EXPORT_SYMBOL_GPL(i2c_adapter_dev_release); +EXPORT_SYMBOL_GPL(i2c_adapter_driver); +EXPORT_SYMBOL_GPL(i2c_adapter_class); +EXPORT_SYMBOL_GPL(i2c_bus_type); + +EXPORT_SYMBOL(i2c_add_adapter); +EXPORT_SYMBOL(i2c_del_adapter); +EXPORT_SYMBOL(i2c_del_driver); +EXPORT_SYMBOL(i2c_attach_client); +EXPORT_SYMBOL(i2c_detach_client); +EXPORT_SYMBOL(i2c_use_client); +EXPORT_SYMBOL(i2c_release_client); +EXPORT_SYMBOL(i2c_clients_command); +EXPORT_SYMBOL(i2c_check_addr); + +EXPORT_SYMBOL(i2c_master_send); +EXPORT_SYMBOL(i2c_master_recv); +EXPORT_SYMBOL(i2c_control); +EXPORT_SYMBOL(i2c_transfer); +EXPORT_SYMBOL(i2c_get_adapter); +EXPORT_SYMBOL(i2c_put_adapter); +EXPORT_SYMBOL(i2c_probe); + EXPORT_SYMBOL(i2c_smbus_xfer); +EXPORT_SYMBOL(i2c_smbus_write_quick); +EXPORT_SYMBOL(i2c_smbus_read_byte); +EXPORT_SYMBOL(i2c_smbus_write_byte); +EXPORT_SYMBOL(i2c_smbus_read_byte_data); +EXPORT_SYMBOL(i2c_smbus_write_byte_data); +EXPORT_SYMBOL(i2c_smbus_read_word_data); +EXPORT_SYMBOL(i2c_smbus_write_word_data); +EXPORT_SYMBOL(i2c_smbus_write_block_data); +EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); +EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); MODULE_AUTHOR("Simon G. Vogl "); MODULE_DESCRIPTION("I2C-Bus main module"); diff --git a/trunk/drivers/i2c/i2c-core.h b/trunk/drivers/i2c/i2c-core.h deleted file mode 100644 index cd5bff874855..000000000000 --- a/trunk/drivers/i2c/i2c-core.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * i2c-core.h - interfaces internal to the I2C framework - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -struct i2c_devinfo { - struct list_head list; - int busnum; - struct i2c_board_info board_info; -}; - -/* board_lock protects board_list and first_dynamic_bus_num. - * only i2c core components are allowed to use these symbols. - */ -extern struct mutex __i2c_board_lock; -extern struct list_head __i2c_board_list; -extern int __i2c_first_dynamic_bus_num; - diff --git a/trunk/drivers/i2c/i2c-dev.c b/trunk/drivers/i2c/i2c-dev.c index e7a709710592..cb4fa9bef8cd 100644 --- a/trunk/drivers/i2c/i2c-dev.c +++ b/trunk/drivers/i2c/i2c-dev.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/ide/cris/ide-cris.c b/trunk/drivers/ide/cris/ide-cris.c index 5e8efc89255a..556455fbfa2b 100644 --- a/trunk/drivers/ide/cris/ide-cris.c +++ b/trunk/drivers/ide/cris/ide-cris.c @@ -730,7 +730,7 @@ static int speed_cris_ide(ide_drive_t *drive, u8 speed) if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) { tune_cris_ide(drive, speed - XFER_PIO_0); - return ide_config_drive_speed(drive, speed); + return 0; } switch(speed) @@ -760,8 +760,7 @@ static int speed_cris_ide(ide_drive_t *drive, u8 speed) hold = ATA_DMA2_HOLD; break; default: - BUG(); - break; + return 0; } if (speed >= XFER_UDMA_0) @@ -769,7 +768,7 @@ static int speed_cris_ide(ide_drive_t *drive, u8 speed) else cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); - return ide_config_drive_speed(drive, speed); + return 0; } void __init @@ -822,6 +821,7 @@ init_e100_ide (void) hwif->udma_four = 0; hwif->ultra_mask = cris_ultra_mask; hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ + hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */ hwif->autodma = 1; hwif->drives[0].autodma = 1; hwif->drives[1].autodma = 1; @@ -1010,6 +1010,7 @@ static int cris_config_drive_for_dma (ide_drive_t *drive) return 0; speed_cris_ide(drive, speed); + ide_config_drive_speed(drive, speed); return ide_dma_enable(drive); } diff --git a/trunk/drivers/ide/legacy/ide-cs.c b/trunk/drivers/ide/legacy/ide-cs.c index c6522a64d7ec..b08c37c9f956 100644 --- a/trunk/drivers/ide/legacy/ide-cs.c +++ b/trunk/drivers/ide/legacy/ide-cs.c @@ -401,7 +401,6 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), - PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2), PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), diff --git a/trunk/drivers/ide/pci/aec62xx.c b/trunk/drivers/ide/pci/aec62xx.c index 73bdf64dbbfc..990eafe5ea11 100644 --- a/trunk/drivers/ide/pci/aec62xx.c +++ b/trunk/drivers/ide/pci/aec62xx.c @@ -1,8 +1,7 @@ /* - * linux/drivers/ide/pci/aec62xx.c Version 0.21 Apr 21, 2007 + * linux/drivers/ide/pci/aec62xx.c Version 0.11 March 27, 2002 * * Copyright (C) 1999-2002 Andre Hedrick - * Copyright (C) 2007 MontaVista Software, Inc. * */ @@ -194,8 +193,18 @@ static int config_chipset_for_dma (ide_drive_t *drive) static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio) { - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void) aec62xx_tune_chipset(drive, pio + XFER_PIO_0); + u8 speed = 0; + u8 new_pio = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); + + switch(pio) { + case 5: speed = new_pio; break; + case 4: speed = XFER_PIO_4; break; + case 3: speed = XFER_PIO_3; break; + case 2: speed = XFER_PIO_2; break; + case 1: speed = XFER_PIO_1; break; + default: speed = XFER_PIO_0; break; + } + (void) aec62xx_tune_chipset(drive, speed); } static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) @@ -204,7 +213,7 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - aec62xx_tune_drive(drive, 255); + aec62xx_tune_drive(drive, 5); return -1; } @@ -279,10 +288,11 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; hwif->ide_dma_check = &aec62xx_config_drive_xfer_rate; hwif->ide_dma_lostirq = &aec62xx_irq_timeout; - + hwif->ide_dma_timeout = &aec62xx_irq_timeout; if (!noautodma) hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; diff --git a/trunk/drivers/ide/pci/alim15x3.c b/trunk/drivers/ide/pci/alim15x3.c index 946a12746cb5..83e0aa65a431 100644 --- a/trunk/drivers/ide/pci/alim15x3.c +++ b/trunk/drivers/ide/pci/alim15x3.c @@ -534,7 +534,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive) struct hd_driveid *id = drive->id; if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) - goto ata_pio; + goto no_dma_set; drive->init_speed = 0; @@ -555,19 +555,20 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive) (id->dma_1word & hwif->swdma_mask)) { /* Force if Capable regular DMA modes */ if (!config_chipset_for_dma(drive)) - goto ata_pio; + goto no_dma_set; } } else if (__ide_dma_good_drive(drive) && (id->eide_dma_time < 150)) { /* Consult the list of known "good" drives */ if (!config_chipset_for_dma(drive)) - goto ata_pio; + goto no_dma_set; } else { goto ata_pio; } } else { ata_pio: hwif->tuneproc(drive, 255); +no_dma_set: return -1; } diff --git a/trunk/drivers/ide/pci/cmd64x.c b/trunk/drivers/ide/pci/cmd64x.c index 77f51ab6d439..561197f7b5bb 100644 --- a/trunk/drivers/ide/pci/cmd64x.c +++ b/trunk/drivers/ide/pci/cmd64x.c @@ -1,7 +1,10 @@ -/* - * linux/drivers/ide/pci/cmd64x.c Version 1.47 Mar 19, 2007 +/* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 + * + * linux/drivers/ide/pci/cmd64x.c Version 1.42 Feb 8, 2007 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. + * Note, this driver is not used at all on other systems because + * there the "BIOS" has done all of the following already. * Due to massive hardware bugs, UltraDMA is only supported * on the 646U2 and not on the 646U. * @@ -36,12 +39,11 @@ * CMD64x specific registers definition. */ #define CFR 0x50 -#define CFR_INTR_CH0 0x04 +#define CFR_INTR_CH0 0x02 #define CNTRL 0x51 -#define CNTRL_ENA_1ST 0x04 -#define CNTRL_ENA_2ND 0x08 -#define CNTRL_DIS_RA0 0x40 -#define CNTRL_DIS_RA1 0x80 +#define CNTRL_DIS_RA0 0x40 +#define CNTRL_DIS_RA1 0x80 +#define CNTRL_ENA_2ND 0x08 #define CMDTIM 0x52 #define ARTTIM0 0x53 @@ -88,67 +90,86 @@ static int n_cmd_devs; static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index) { char *p = buf; + + u8 reg53 = 0, reg54 = 0, reg55 = 0, reg56 = 0; /* primary */ + u8 reg57 = 0, reg58 = 0, reg5b; /* secondary */ u8 reg72 = 0, reg73 = 0; /* primary */ u8 reg7a = 0, reg7b = 0; /* secondary */ - u8 reg50 = 1, reg51 = 1, reg57 = 0, reg71 = 0; /* extra */ - u8 rev = 0; + u8 reg50 = 0, reg71 = 0; /* extra */ p += sprintf(p, "\nController: %d\n", index); - p += sprintf(p, "PCI-%x Chipset.\n", dev->device); - + p += sprintf(p, "CMD%x Chipset.\n", dev->device); (void) pci_read_config_byte(dev, CFR, ®50); - (void) pci_read_config_byte(dev, CNTRL, ®51); - (void) pci_read_config_byte(dev, ARTTIM23, ®57); + (void) pci_read_config_byte(dev, ARTTIM0, ®53); + (void) pci_read_config_byte(dev, DRWTIM0, ®54); + (void) pci_read_config_byte(dev, ARTTIM1, ®55); + (void) pci_read_config_byte(dev, DRWTIM1, ®56); + (void) pci_read_config_byte(dev, ARTTIM2, ®57); + (void) pci_read_config_byte(dev, DRWTIM2, ®58); + (void) pci_read_config_byte(dev, DRWTIM3, ®5b); (void) pci_read_config_byte(dev, MRDMODE, ®71); (void) pci_read_config_byte(dev, BMIDESR0, ®72); (void) pci_read_config_byte(dev, UDIDETCR0, ®73); (void) pci_read_config_byte(dev, BMIDESR1, ®7a); (void) pci_read_config_byte(dev, UDIDETCR1, ®7b); - /* PCI0643/6 originally didn't have the primary channel enable bit */ - (void) pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - if ((dev->device == PCI_DEVICE_ID_CMD_643) || - (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 3)) - reg51 |= CNTRL_ENA_1ST; - - p += sprintf(p, "---------------- Primary Channel " - "---------------- Secondary Channel ------------\n"); - p += sprintf(p, " %s %s\n", - (reg51 & CNTRL_ENA_1ST) ? "enabled " : "disabled", - (reg51 & CNTRL_ENA_2ND) ? "enabled " : "disabled"); - p += sprintf(p, "---------------- drive0 --------- drive1 " - "-------- drive0 --------- drive1 ------\n"); - p += sprintf(p, "DMA enabled: %s %s" - " %s %s\n", - (reg72 & 0x20) ? "yes" : "no ", (reg72 & 0x40) ? "yes" : "no ", - (reg7a & 0x20) ? "yes" : "no ", (reg7a & 0x40) ? "yes" : "no "); - p += sprintf(p, "UltraDMA mode: %s (%c) %s (%c)", - ( reg73 & 0x01) ? " on" : "off", - ((reg73 & 0x30) == 0x30) ? ((reg73 & 0x04) ? '3' : '0') : - ((reg73 & 0x30) == 0x20) ? ((reg73 & 0x04) ? '3' : '1') : - ((reg73 & 0x30) == 0x10) ? ((reg73 & 0x04) ? '4' : '2') : - ((reg73 & 0x30) == 0x00) ? ((reg73 & 0x04) ? '5' : '2') : '?', - ( reg73 & 0x02) ? " on" : "off", - ((reg73 & 0xC0) == 0xC0) ? ((reg73 & 0x08) ? '3' : '0') : - ((reg73 & 0xC0) == 0x80) ? ((reg73 & 0x08) ? '3' : '1') : - ((reg73 & 0xC0) == 0x40) ? ((reg73 & 0x08) ? '4' : '2') : - ((reg73 & 0xC0) == 0x00) ? ((reg73 & 0x08) ? '5' : '2') : '?'); - p += sprintf(p, " %s (%c) %s (%c)\n", - ( reg7b & 0x01) ? " on" : "off", - ((reg7b & 0x30) == 0x30) ? ((reg7b & 0x04) ? '3' : '0') : - ((reg7b & 0x30) == 0x20) ? ((reg7b & 0x04) ? '3' : '1') : - ((reg7b & 0x30) == 0x10) ? ((reg7b & 0x04) ? '4' : '2') : - ((reg7b & 0x30) == 0x00) ? ((reg7b & 0x04) ? '5' : '2') : '?', - ( reg7b & 0x02) ? " on" : "off", - ((reg7b & 0xC0) == 0xC0) ? ((reg7b & 0x08) ? '3' : '0') : - ((reg7b & 0xC0) == 0x80) ? ((reg7b & 0x08) ? '3' : '1') : - ((reg7b & 0xC0) == 0x40) ? ((reg7b & 0x08) ? '4' : '2') : - ((reg7b & 0xC0) == 0x00) ? ((reg7b & 0x08) ? '5' : '2') : '?'); - p += sprintf(p, "Interrupt: %s, %s %s, %s\n", - (reg71 & MRDMODE_BLK_CH0 ) ? "blocked" : "enabled", - (reg50 & CFR_INTR_CH0 ) ? "pending" : "clear ", - (reg71 & MRDMODE_BLK_CH1 ) ? "blocked" : "enabled", - (reg57 & ARTTIM23_INTR_CH1) ? "pending" : "clear "); + p += sprintf(p, "--------------- Primary Channel " + "---------------- Secondary Channel " + "-------------\n"); + p += sprintf(p, " %sabled " + " %sabled\n", + (reg72&0x80)?"dis":" en", + (reg7a&0x80)?"dis":" en"); + p += sprintf(p, "--------------- drive0 " + "--------- drive1 -------- drive0 " + "---------- drive1 ------\n"); + p += sprintf(p, "DMA enabled: %s %s" + " %s %s\n", + (reg72&0x20)?"yes":"no ", (reg72&0x40)?"yes":"no ", + (reg7a&0x20)?"yes":"no ", (reg7a&0x40)?"yes":"no "); + + p += sprintf(p, "DMA Mode: %s(%s) %s(%s)", + (reg72&0x20)?((reg73&0x01)?"UDMA":" DMA"):" PIO", + (reg72&0x20)?( + ((reg73&0x30)==0x30)?(((reg73&0x35)==0x35)?"3":"0"): + ((reg73&0x20)==0x20)?(((reg73&0x25)==0x25)?"3":"1"): + ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"): + ((reg73&0x00)==0x00)?(((reg73&0x05)==0x05)?"5":"2"): + "X"):"?", + (reg72&0x40)?((reg73&0x02)?"UDMA":" DMA"):" PIO", + (reg72&0x40)?( + ((reg73&0xC0)==0xC0)?(((reg73&0xC5)==0xC5)?"3":"0"): + ((reg73&0x80)==0x80)?(((reg73&0x85)==0x85)?"3":"1"): + ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"): + ((reg73&0x00)==0x00)?(((reg73&0x0A)==0x0A)?"5":"2"): + "X"):"?"); + p += sprintf(p, " %s(%s) %s(%s)\n", + (reg7a&0x20)?((reg7b&0x01)?"UDMA":" DMA"):" PIO", + (reg7a&0x20)?( + ((reg7b&0x30)==0x30)?(((reg7b&0x35)==0x35)?"3":"0"): + ((reg7b&0x20)==0x20)?(((reg7b&0x25)==0x25)?"3":"1"): + ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"): + ((reg7b&0x00)==0x00)?(((reg7b&0x05)==0x05)?"5":"2"): + "X"):"?", + (reg7a&0x40)?((reg7b&0x02)?"UDMA":" DMA"):" PIO", + (reg7a&0x40)?( + ((reg7b&0xC0)==0xC0)?(((reg7b&0xC5)==0xC5)?"3":"0"): + ((reg7b&0x80)==0x80)?(((reg7b&0x85)==0x85)?"3":"1"): + ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"): + ((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"): + "X"):"?" ); + p += sprintf(p, "PIO Mode: %s %s" + " %s %s\n", + "?", "?", "?", "?"); + p += sprintf(p, " %s %s\n", + (reg50 & CFR_INTR_CH0) ? "interrupting" : "polling ", + (reg57 & ARTTIM23_INTR_CH1) ? "interrupting" : "polling"); + p += sprintf(p, " %s %s\n", + (reg71 & MRDMODE_INTR_CH0) ? "pending" : "clear ", + (reg71 & MRDMODE_INTR_CH1) ? "pending" : "clear"); + p += sprintf(p, " %s %s\n", + (reg71 & MRDMODE_BLK_CH0) ? "blocked" : "enabled", + (reg71 & MRDMODE_BLK_CH1) ? "blocked" : "enabled"); return (char *)p; } @@ -158,6 +179,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) char *p = buffer; int i; + p += sprintf(p, "\n"); for (i = 0; i < n_cmd_devs; i++) { struct pci_dev *dev = cmd_devs[i]; p = print_cmd64x_get_info(p, dev, i); @@ -173,103 +195,116 @@ static u8 quantize_timing(int timing, int quant) } /* - * This routine calculates active/recovery counts and then writes them into - * the chipset registers. + * This routine writes the prepared setup/active/recovery counts + * for a drive into the cmd646 chipset registers to active them. */ -static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time) +static void program_drive_counts (ide_drive_t *drive, int setup_count, int active_count, int recovery_count) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int clock_time = 1000 / system_bus_clock(); - u8 cycle_count, active_count, recovery_count, drwtim; - static const u8 recovery_values[] = + unsigned long flags; + struct pci_dev *dev = HWIF(drive)->pci_dev; + ide_drive_t *drives = HWIF(drive)->drives; + u8 temp_b; + static const u8 setup_counts[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; + static const u8 recovery_counts[] = {15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}; - static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3}; - - cmdprintk("program_cycle_times parameters: total=%d, active=%d\n", - cycle_time, active_time); - - cycle_count = quantize_timing( cycle_time, clock_time); - active_count = quantize_timing(active_time, clock_time); - recovery_count = cycle_count - active_count; - + static const u8 arttim_regs[2][2] = { + { ARTTIM0, ARTTIM1 }, + { ARTTIM23, ARTTIM23 } + }; + static const u8 drwtim_regs[2][2] = { + { DRWTIM0, DRWTIM1 }, + { DRWTIM2, DRWTIM3 } + }; + int channel = (int) HWIF(drive)->channel; + int slave = (drives != drive); /* Is this really the best way to determine this?? */ + + cmdprintk("program_drive_count parameters = s(%d),a(%d),r(%d),p(%d)\n", + setup_count, active_count, recovery_count, drive->present); /* - * In case we've got too long recovery phase, try to lengthen - * the active phase + * Set up address setup count registers. + * Primary interface has individual count/timing registers for + * each drive. Secondary interface has one common set of registers, + * for address setup so we merge these timings, using the slowest + * value. */ - if (recovery_count > 16) { - active_count += recovery_count - 16; - recovery_count = 16; + if (channel) { + drive->drive_data = setup_count; + setup_count = max(drives[0].drive_data, + drives[1].drive_data); + cmdprintk("Secondary interface, setup_count = %d\n", + setup_count); } - if (active_count > 16) /* shouldn't actually happen... */ - active_count = 16; - - cmdprintk("Final counts: total=%d, active=%d, recovery=%d\n", - cycle_count, active_count, recovery_count); /* * Convert values to internal chipset representation */ - recovery_count = recovery_values[recovery_count]; - active_count &= 0x0f; + setup_count = (setup_count > 5) ? 0xc0 : (int) setup_counts[setup_count]; + active_count &= 0xf; /* Remember, max value is 16 */ + recovery_count = (int) recovery_counts[recovery_count]; - /* Program the active/recovery counts into the DRWTIM register */ - drwtim = (active_count << 4) | recovery_count; - (void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim); - cmdprintk("Write 0x%02x to reg 0x%x\n", drwtim, drwtim_regs[drive->dn]); + cmdprintk("Final values = %d,%d,%d\n", + setup_count, active_count, recovery_count); + + /* + * Now that everything is ready, program the new timings + */ + local_irq_save(flags); + /* + * Program the address_setup clocks into ARTTIM reg, + * and then the active/recovery counts into the DRWTIM reg + */ + (void) pci_read_config_byte(dev, arttim_regs[channel][slave], &temp_b); + (void) pci_write_config_byte(dev, arttim_regs[channel][slave], + ((u8) setup_count) | (temp_b & 0x3f)); + (void) pci_write_config_byte(dev, drwtim_regs[channel][slave], + (u8) ((active_count << 4) | recovery_count)); + cmdprintk ("Write %x to %x\n", + ((u8) setup_count) | (temp_b & 0x3f), + arttim_regs[channel][slave]); + cmdprintk ("Write %x to %x\n", + (u8) ((active_count << 4) | recovery_count), + drwtim_regs[channel][slave]); + local_irq_restore(flags); } /* - * This routine selects drive's best PIO mode and writes into the chipset - * registers setup/active/recovery timings. + * This routine selects drive's best PIO mode, calculates setup/active/recovery + * counts, and then writes them into the chipset registers. */ static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + int setup_time, active_time, cycle_time; + u8 cycle_count, setup_count, active_count, recovery_count; + u8 pio_mode; + int clock_time = 1000 / system_bus_clock(); ide_pio_data_t pio; - u8 pio_mode, setup_count, arttim = 0; - static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; - static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; - pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio); - - cmdprintk("%s: PIO mode wanted %d, selected %d (%d ns)%s\n", - drive->name, mode_wanted, pio_mode, pio.cycle_time, - pio.overridden ? " (overriding vendor mode)" : ""); - program_cycle_times(drive, pio.cycle_time, - ide_pio_timings[pio_mode].active_time); + pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio); + cycle_time = pio.cycle_time; - setup_count = quantize_timing(ide_pio_timings[pio_mode].setup_time, - 1000 / system_bus_clock()); + setup_time = ide_pio_timings[pio_mode].setup_time; + active_time = ide_pio_timings[pio_mode].active_time; - /* - * The primary channel has individual address setup timing registers - * for each drive and the hardware selects the slowest timing itself. - * The secondary channel has one common register and we have to select - * the slowest address setup timing ourselves. - */ - if (hwif->channel) { - ide_drive_t *drives = hwif->drives; + setup_count = quantize_timing( setup_time, clock_time); + cycle_count = quantize_timing( cycle_time, clock_time); + active_count = quantize_timing(active_time, clock_time); - drive->drive_data = setup_count; - setup_count = max(drives[0].drive_data, drives[1].drive_data); + recovery_count = cycle_count - active_count; + /* program_drive_counts() takes care of zero recovery cycles */ + if (recovery_count > 16) { + active_count += recovery_count - 16; + recovery_count = 16; } + if (active_count > 16) + active_count = 16; /* maximum allowed by cmd64x */ - if (setup_count > 5) /* shouldn't actually happen... */ - setup_count = 5; - cmdprintk("Final address setup count: %d\n", setup_count); + program_drive_counts (drive, setup_count, active_count, recovery_count); - /* - * Program the address setup clocks into the ARTTIM registers. - * Avoid clearing the secondary channel's interrupt bit. - */ - (void) pci_read_config_byte (dev, arttim_regs[drive->dn], &arttim); - if (hwif->channel) - arttim &= ~ARTTIM23_INTR_CH1; - arttim &= ~0xc0; - arttim |= setup_values[setup_count]; - (void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim); - cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]); + cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, " + "clocks=%d/%d/%d\n", + drive->name, mode_wanted, pio_mode, cycle_time, + pio.overridden ? " (overriding vendor mode)" : "", + setup_count, active_count, recovery_count); return pio_mode; } @@ -341,64 +376,61 @@ static u8 cmd64x_ratemask (ide_drive_t *drive) return mode; } -static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed) +static int cmd64x_tune_chipset (ide_drive_t *drive, u8 xferspeed) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - u8 unit = drive->dn & 0x01; - u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0; - speed = ide_rate_filter(cmd64x_ratemask(drive), speed); + u8 unit = (drive->select.b.unit & 0x01); + u8 regU = 0, pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0; + u8 regD = 0, pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0; + + u8 speed = ide_rate_filter(cmd64x_ratemask(drive), xferspeed); if (speed >= XFER_SW_DMA_0) { + (void) pci_read_config_byte(dev, pciD, ®D); (void) pci_read_config_byte(dev, pciU, ®U); + regD &= ~(unit ? 0x40 : 0x20); regU &= ~(unit ? 0xCA : 0x35); + (void) pci_write_config_byte(dev, pciD, regD); + (void) pci_write_config_byte(dev, pciU, regU); + (void) pci_read_config_byte(dev, pciD, ®D); + (void) pci_read_config_byte(dev, pciU, ®U); } switch(speed) { - case XFER_UDMA_5: - regU |= unit ? 0x0A : 0x05; - break; - case XFER_UDMA_4: - regU |= unit ? 0x4A : 0x15; - break; - case XFER_UDMA_3: - regU |= unit ? 0x8A : 0x25; - break; - case XFER_UDMA_2: - regU |= unit ? 0x42 : 0x11; - break; - case XFER_UDMA_1: - regU |= unit ? 0x82 : 0x21; - break; - case XFER_UDMA_0: - regU |= unit ? 0xC2 : 0x31; - break; - case XFER_MW_DMA_2: - program_cycle_times(drive, 120, 70); - break; - case XFER_MW_DMA_1: - program_cycle_times(drive, 150, 80); - break; - case XFER_MW_DMA_0: - program_cycle_times(drive, 480, 215); - break; - case XFER_PIO_5: - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - (void) cmd64x_tune_pio(drive, speed - XFER_PIO_0); - break; - default: - return 1; + case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; + case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; + case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break; + case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break; + case XFER_UDMA_1: regU |= (unit ? 0x82 : 0x21); break; + case XFER_UDMA_0: regU |= (unit ? 0xC2 : 0x31); break; + case XFER_MW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; + case XFER_MW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; + case XFER_MW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; + case XFER_SW_DMA_2: regD |= (unit ? 0x40 : 0x10); break; + case XFER_SW_DMA_1: regD |= (unit ? 0x80 : 0x20); break; + case XFER_SW_DMA_0: regD |= (unit ? 0xC0 : 0x30); break; + case XFER_PIO_5: + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + (void) cmd64x_tune_pio(drive, speed - XFER_PIO_0); + break; + + default: + return 1; } - if (speed >= XFER_SW_DMA_0) + if (speed >= XFER_SW_DMA_0) { (void) pci_write_config_byte(dev, pciU, regU); + regD |= (unit ? 0x40 : 0x20); + (void) pci_write_config_byte(dev, pciD, regD); + } - return ide_config_drive_speed(drive, speed); + return (ide_config_drive_speed(drive, speed)); } static int config_chipset_for_dma (ide_drive_t *drive) @@ -425,80 +457,67 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) return -1; } -static int cmd648_ide_dma_end (ide_drive_t *drive) +static int cmd64x_alt_dma_status (struct pci_dev *dev) { - ide_hwif_t *hwif = HWIF(drive); - int err = __ide_dma_end(drive); - u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : - MRDMODE_INTR_CH0; - u8 mrdmode = inb(hwif->dma_master + 0x01); - - /* clear the interrupt bit */ - outb(mrdmode | irq_mask, hwif->dma_master + 0x01); - - return err; + switch(dev->device) { + case PCI_DEVICE_ID_CMD_648: + case PCI_DEVICE_ID_CMD_649: + return 1; + default: + break; + } + return 0; } static int cmd64x_ide_dma_end (ide_drive_t *drive) { + u8 dma_stat = 0, dma_cmd = 0; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - int irq_reg = hwif->channel ? ARTTIM23 : CFR; - u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : - CFR_INTR_CH0; - u8 irq_stat = 0; - int err = __ide_dma_end(drive); - - (void) pci_read_config_byte(dev, irq_reg, &irq_stat); - /* clear the interrupt bit */ - (void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask); - - return err; -} - -static int cmd648_ide_dma_test_irq (ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : - MRDMODE_INTR_CH0; - u8 dma_stat = inb(hwif->dma_status); - u8 mrdmode = inb(hwif->dma_master + 0x01); - -#ifdef DEBUG - printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n", - drive->name, dma_stat, mrdmode, irq_mask); -#endif - if (!(mrdmode & irq_mask)) - return 0; - /* return 1 if INTR asserted */ - if (dma_stat & 4) - return 1; - - return 0; + drive->waiting_for_dma = 0; + /* read DMA command state */ + dma_cmd = inb(hwif->dma_command); + /* stop DMA */ + outb(dma_cmd & ~1, hwif->dma_command); + /* get DMA status */ + dma_stat = inb(hwif->dma_status); + /* clear the INTR & ERROR bits */ + outb(dma_stat | 6, hwif->dma_status); + if (cmd64x_alt_dma_status(dev)) { + u8 dma_intr = 0; + u8 dma_mask = (hwif->channel) ? ARTTIM23_INTR_CH1 : + CFR_INTR_CH0; + u8 dma_reg = (hwif->channel) ? ARTTIM2 : CFR; + (void) pci_read_config_byte(dev, dma_reg, &dma_intr); + /* clear the INTR bit */ + (void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask); + } + /* purge DMA mappings */ + ide_destroy_dmatable(drive); + /* verify good DMA status */ + return (dma_stat & 7) != 4; } static int cmd64x_ide_dma_test_irq (ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - int irq_reg = hwif->channel ? ARTTIM23 : CFR; - u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : - CFR_INTR_CH0; - u8 dma_stat = inb(hwif->dma_status); - u8 irq_stat = 0; - - (void) pci_read_config_byte(dev, irq_reg, &irq_stat); + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u8 dma_alt_stat = 0, mask = (hwif->channel) ? MRDMODE_INTR_CH1 : + MRDMODE_INTR_CH0; + u8 dma_stat = inb(hwif->dma_status); + (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat); #ifdef DEBUG - printk("%s: dma_stat: 0x%02x irq_stat: 0x%02x irq_mask: 0x%02x\n", - drive->name, dma_stat, irq_stat, irq_mask); + printk("%s: dma_stat: 0x%02x dma_alt_stat: " + "0x%02x mask: 0x%02x\n", drive->name, + dma_stat, dma_alt_stat, mask); #endif - if (!(irq_stat & irq_mask)) + if (!(dma_alt_stat & mask)) return 0; /* return 1 if INTR asserted */ - if (dma_stat & 4) + if ((dma_stat & 4) == 4) return 1; return 0; @@ -646,6 +665,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; if (dev->device == PCI_DEVICE_ID_CMD_643) hwif->ultra_mask = 0x80; @@ -658,25 +678,17 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) if (!(hwif->udma_four)) hwif->udma_four = ata66_cmd64x(hwif); - switch(dev->device) { - case PCI_DEVICE_ID_CMD_648: - case PCI_DEVICE_ID_CMD_649: - alt_irq_bits: - hwif->ide_dma_end = &cmd648_ide_dma_end; - hwif->ide_dma_test_irq = &cmd648_ide_dma_test_irq; - break; - case PCI_DEVICE_ID_CMD_646: + if (dev->device == PCI_DEVICE_ID_CMD_646) { hwif->chipset = ide_cmd646; if (class_rev == 0x01) { hwif->ide_dma_end = &cmd646_1_ide_dma_end; - break; - } else if (class_rev >= 0x03) - goto alt_irq_bits; - /* fall thru */ - default: - hwif->ide_dma_end = &cmd64x_ide_dma_end; - hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; - break; + } else { + hwif->ide_dma_end = &cmd64x_ide_dma_end; + hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; + } + } else { + hwif->ide_dma_end = &cmd64x_ide_dma_end; + hwif->ide_dma_test_irq = &cmd64x_ide_dma_test_irq; } @@ -686,75 +698,42 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) hwif->drives[1].autodma = hwif->autodma; } -static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d) -{ - return ide_setup_pci_device(dev, d); -} - -static int __devinit init_setup_cmd646(struct pci_dev *dev, ide_pci_device_t *d) -{ - u8 rev = 0; - - /* - * The original PCI0646 didn't have the primary channel enable bit, - * it appeared starting with PCI0646U (i.e. revision ID 3). - */ - pci_read_config_byte(dev, PCI_REVISION_ID, &rev); - if (rev < 3) - d->enablebits[0].reg = 0; - - return ide_setup_pci_device(dev, d); -} - static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { { /* 0 */ .name = "CMD643", - .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, },{ /* 1 */ .name = "CMD646", - .init_setup = init_setup_cmd646, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, + .enablebits = {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, .bootable = ON_BOARD, },{ /* 2 */ .name = "CMD648", - .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, },{ /* 3 */ .name = "CMD649", - .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, .bootable = ON_BOARD, } }; -/* - * We may have to modify enablebits for PCI0646, so we'd better pass - * a local copy of the ide_pci_device_t structure down the call chain... - */ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t d = cmd64x_chipsets[id->driver_data]; - - return d.init_setup(dev, &d); + return ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]); } static struct pci_device_id cmd64x_pci_tbl[] = { diff --git a/trunk/drivers/ide/pci/hpt366.c b/trunk/drivers/ide/pci/hpt366.c index cf9d344d19f8..ab6fa271aeb3 100644 --- a/trunk/drivers/ide/pci/hpt366.c +++ b/trunk/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.03 May 4, 2007 + * linux/drivers/ide/pci/hpt366.c Version 1.02 Apr 18, 2007 * * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -1527,12 +1527,7 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) if (rev > 2) goto init_single; - /* - * HPT36x chips are single channel and - * do not seem to have the channel enable bit... - */ d->channels = 1; - d->enablebits[0].reg = 0; if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { u8 pin1 = 0, pin2 = 0; diff --git a/trunk/drivers/ide/pci/it821x.c b/trunk/drivers/ide/pci/it821x.c index 4e1254813ee0..a132767f7d90 100644 --- a/trunk/drivers/ide/pci/it821x.c +++ b/trunk/drivers/ide/pci/it821x.c @@ -1,9 +1,8 @@ /* - * linux/drivers/ide/pci/it821x.c Version 0.10 Mar 10 2007 + * linux/drivers/ide/pci/it821x.c Version 0.09 December 2004 * * Copyright (C) 2004 Red Hat - * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public License * Based in part on the ITE vendor provided SCSI driver. @@ -105,7 +104,6 @@ static int it8212_noraid; /** * it821x_program - program the PIO/MWDMA registers * @drive: drive to tune - * @timing: timing info * * Program the PIO/MWDMA timing for this channel according to the * current clock. @@ -129,7 +127,6 @@ static void it821x_program(ide_drive_t *drive, u16 timing) /** * it821x_program_udma - program the UDMA registers * @drive: drive to tune - * @timing: timing info * * Program the UDMA timing for this drive according to the * current clock. @@ -156,9 +153,10 @@ static void it821x_program_udma(ide_drive_t *drive, u16 timing) } } + /** * it821x_clock_strategy - * @drive: drive to set up + * @hwif: hardware interface * * Select between the 50 and 66Mhz base clocks to get the best * results for this interface. @@ -184,11 +182,8 @@ static void it821x_clock_strategy(ide_drive_t *drive) altclock = itdev->want[0][1]; } - /* - * if both clocks can be used for the mode with the higher priority - * use the clock needed by the mode with the lower priority - */ - if (clock == ATA_ANY) + /* Master doesn't care does the slave ? */ + if(clock == ATA_ANY) clock = altclock; /* Nobody cares - keep the same clock */ @@ -245,56 +240,37 @@ static u8 it821x_ratemask (ide_drive_t *drive) } /** - * it821x_tunepio - tune a drive + * it821x_tuneproc - tune a drive * @drive: drive to tune - * @pio: the desired PIO mode + * @mode_wanted: the target operating mode + * + * Load the timing settings for this device mode into the + * controller. By the time we are called the mode has been + * modified as neccessary to handle the absence of seperate + * master/slave timers for MWDMA/PIO. * - * Try to tune the drive/host to the desired PIO mode taking into - * the consideration the maximum PIO mode supported by the other - * device on the cable. + * This code is only used in pass through mode. */ -static int it821x_tunepio(ide_drive_t *drive, u8 set_pio) +static void it821x_tuneproc (ide_drive_t *drive, byte mode_wanted) { ide_hwif_t *hwif = drive->hwif; struct it821x_dev *itdev = ide_get_hwifdata(hwif); int unit = drive->select.b.unit; - ide_drive_t *pair = &hwif->drives[1 - unit]; /* Spec says 89 ref driver uses 88 */ static u16 pio[] = { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 }; static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY }; - /* - * Compute the best PIO mode we can for a given device. We must - * pick a speed that does not cause problems with the other device - * on the cable. - */ - if (pair) { - u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4, NULL); - /* trim PIO to the slowest of the master/slave */ - if (pair_pio < set_pio) - set_pio = pair_pio; - } - - if (itdev->smart) - goto set_drive_speed; + if(itdev->smart) + return; /* We prefer 66Mhz clock for PIO 0-3, don't care for PIO4 */ - itdev->want[unit][1] = pio_want[set_pio]; + itdev->want[unit][1] = pio_want[mode_wanted]; itdev->want[unit][0] = 1; /* PIO is lowest priority */ - itdev->pio[unit] = pio[set_pio]; + itdev->pio[unit] = pio[mode_wanted]; it821x_clock_strategy(drive); it821x_program(drive, itdev->pio[unit]); - -set_drive_speed: - return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio); -} - -static void it821x_tuneproc(ide_drive_t *drive, u8 pio) -{ - pio = ide_get_best_pio_mode(drive, pio, 4, NULL); - (void)it821x_tunepio(drive, pio); } /** @@ -377,6 +353,40 @@ static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted) } +/** + * config_it821x_chipset_for_pio - set drive timings + * @drive: drive to tune + * @speed we want + * + * Compute the best pio mode we can for a given device. We must + * pick a speed that does not cause problems with the other device + * on the cable. + */ + +static void config_it821x_chipset_for_pio (ide_drive_t *drive, byte set_speed) +{ + u8 unit = drive->select.b.unit; + ide_hwif_t *hwif = drive->hwif; + ide_drive_t *pair = &hwif->drives[1-unit]; + u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 255, 5, NULL); + u8 pair_pio; + + /* We have to deal with this mess in pairs */ + if(pair != NULL) { + pair_pio = ide_get_best_pio_mode(pair, 255, 5, NULL); + /* Trim PIO to the slowest of the master/slave */ + if(pair_pio < set_pio) + set_pio = pair_pio; + } + it821x_tuneproc(drive, set_pio); + speed = XFER_PIO_0 + set_pio; + /* XXX - We trim to the lowest of the pair so the other drive + will always be fine at this point until we do hotplug passthru */ + + if (set_speed) + (void) ide_config_drive_speed(drive, speed); +} + /** * it821x_dma_read - DMA hook * @drive: drive for DMA @@ -440,17 +450,15 @@ static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed) struct it821x_dev *itdev = ide_get_hwifdata(hwif); u8 speed = ide_rate_filter(it821x_ratemask(drive), xferspeed); - switch (speed) { - case XFER_PIO_4: - case XFER_PIO_3: - case XFER_PIO_2: - case XFER_PIO_1: - case XFER_PIO_0: - return it821x_tunepio(drive, speed - XFER_PIO_0); - } - - if (itdev->smart == 0) { - switch (speed) { + if(!itdev->smart) { + switch(speed) { + case XFER_PIO_4: + case XFER_PIO_3: + case XFER_PIO_2: + case XFER_PIO_1: + case XFER_PIO_0: + it821x_tuneproc(drive, (speed - XFER_PIO_0)); + break; /* MWDMA tuning is really hard because our MWDMA and PIO timings are kept in the same place. We can switch in the host dma on/off callbacks */ @@ -490,12 +498,14 @@ static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, it821x_ratemask(drive)); - if (speed == 0) - return 0; + if (speed) { + config_it821x_chipset_for_pio(drive, 0); + it821x_tune_chipset(drive, speed); - it821x_tune_chipset(drive, speed); + return ide_dma_enable(drive); + } - return ide_dma_enable(drive); + return 0; } /** @@ -513,7 +523,7 @@ static int it821x_config_drive_for_dma (ide_drive_t *drive) if (ide_use_dma(drive) && config_chipset_for_dma(drive)) return 0; - it821x_tuneproc(drive, 255); + config_it821x_chipset_for_pio(drive, 1); return -1; } diff --git a/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index 2cdd629c653d..ace98929cc3d 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -255,6 +255,9 @@ static int config_chipset_for_dma(ide_drive_t *drive) printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); } + if (drive->media != ide_disk && drive->media != ide_cdrom) + return 0; + if (id->capability & 4) { /* * Set IORDY_EN & PREFETCH_EN (this seems to have @@ -395,7 +398,7 @@ static void __devinit apple_kiwi_init(struct pci_dev *pdev) unsigned int class_rev = 0; u8 conf; - if (np == NULL || !of_device_is_compatible(np, "kiwi-root")) + if (np == NULL || !device_is_compatible(np, "kiwi-root")) return; pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); diff --git a/trunk/drivers/ide/pci/siimage.c b/trunk/drivers/ide/pci/siimage.c index c0188de3cc66..71eccdf5f817 100644 --- a/trunk/drivers/ide/pci/siimage.c +++ b/trunk/drivers/ide/pci/siimage.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/siimage.c Version 1.12 Mar 10 2007 + * linux/drivers/ide/pci/siimage.c Version 1.11 Jan 27, 2007 * * Copyright (C) 2001-2002 Andre Hedrick * Copyright (C) 2003 Red Hat @@ -287,6 +287,11 @@ static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed) (void) ide_config_drive_speed(drive, speed); } +static void config_chipset_for_pio (ide_drive_t *drive, byte set_speed) +{ + config_siimage_chipset_for_pio(drive, set_speed); +} + /** * siimage_tune_chipset - set controller timings * @drive: Drive to set up @@ -391,6 +396,8 @@ static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, siimage_ratemask(drive)); + config_chipset_for_pio(drive, !speed); + if (!speed) return 0; @@ -416,7 +423,7 @@ static int siimage_config_drive_for_dma (ide_drive_t *drive) return 0; if (ide_use_fast_pio(drive)) - config_siimage_chipset_for_pio(drive, 1); + config_chipset_for_pio(drive, 1); return -1; } @@ -1008,6 +1015,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; if (!is_sata(hwif)) hwif->atapi_dma = 1; diff --git a/trunk/drivers/ide/pci/sl82c105.c b/trunk/drivers/ide/pci/sl82c105.c index fe3b4b91f854..3a8a76fc78c7 100644 --- a/trunk/drivers/ide/pci/sl82c105.c +++ b/trunk/drivers/ide/pci/sl82c105.c @@ -11,8 +11,6 @@ * Merge in Russell's HW workarounds, fix various problems * with the timing registers setup. * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org - * - * Copyright (C) 2006-2007 MontaVista Software, Inc. */ #include @@ -49,19 +47,25 @@ #define CTRL_P0EN (1 << 0) /* - * Convert a PIO mode and cycle time to the required on/off times - * for the interface. This has protection against runaway timings. + * Convert a PIO mode and cycle time to the required on/off + * times for the interface. This has protection against run-away + * timings. */ -static unsigned int get_pio_timings(ide_pio_data_t *p) +static unsigned int get_timing_sl82c105(ide_pio_data_t *p) { - unsigned int cmd_on, cmd_off; + unsigned int cmd_on; + unsigned int cmd_off; - cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; + cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30; cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30; + if (cmd_on > 32) + cmd_on = 32; if (cmd_on == 0) cmd_on = 1; + if (cmd_off > 32) + cmd_off = 32; if (cmd_off == 0) cmd_off = 1; @@ -69,59 +73,100 @@ static unsigned int get_pio_timings(ide_pio_data_t *p) } /* - * Configure the chipset for PIO mode. + * Configure the drive and chipset for PIO */ -static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio) +static void config_for_pio(ide_drive_t *drive, int pio, int report, int chipset_only) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int reg = 0x44 + drive->dn * 4; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; ide_pio_data_t p; - u16 drv_ctrl; + u16 drv_ctrl = 0x909; + unsigned int xfer_mode, reg; - DBG(("sl82c105_tune_pio(drive:%s, pio:%u)\n", drive->name, pio)); + DBG(("config_for_pio(drive:%s, pio:%d, report:%d, chipset_only:%d)\n", + drive->name, pio, report, chipset_only)); + + reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); pio = ide_get_best_pio_mode(drive, pio, 5, &p); - drive->drive_data = drv_ctrl = get_pio_timings(&p); + xfer_mode = XFER_PIO_0 + pio; + + if (chipset_only || ide_config_drive_speed(drive, xfer_mode) == 0) { + drv_ctrl = get_timing_sl82c105(&p); + drive->pio_speed = xfer_mode; + } else + drive->pio_speed = XFER_PIO_0; - if (!drive->using_dma) { + if (drive->using_dma == 0) { /* * If we are actually using MW DMA, then we can not * reprogram the interface drive control register. */ - pci_write_config_word(dev, reg, drv_ctrl); - pci_read_config_word (dev, reg, &drv_ctrl); - } + pci_write_config_word(dev, reg, drv_ctrl); + pci_read_config_word(dev, reg, &drv_ctrl); - printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, - ide_xfer_verbose(pio + XFER_PIO_0), p.cycle_time, drv_ctrl); - - return pio; + if (report) { + printk("%s: selected %s (%dns) (%04X)\n", drive->name, + ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl); + } + } } /* - * Configure the drive for DMA. - * We'll program the chipset only when DMA is actually turned on. + * Configure the drive and the chipset for DMA */ -static int config_for_dma(ide_drive_t *drive) +static int config_for_dma (ide_drive_t *drive) { + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + unsigned int reg; + DBG(("config_for_dma(drive:%s)\n", drive->name)); + reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0); + if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) - return 0; + return 1; - return ide_dma_enable(drive); + pci_write_config_word(dev, reg, 0x0240); + + return 0; } /* - * Check to see if the drive and chipset are capable of DMA mode. + * Check to see if the drive and + * chipset is capable of DMA mode */ -static int sl82c105_ide_dma_check(ide_drive_t *drive) + +static int sl82c105_check_drive (ide_drive_t *drive) { - DBG(("sl82c105_ide_dma_check(drive:%s)\n", drive->name)); + ide_hwif_t *hwif = HWIF(drive); + + DBG(("sl82c105_check_drive(drive:%s)\n", drive->name)); + + do { + struct hd_driveid *id = drive->id; + + if (!drive->autodma) + break; + + if (!id || !(id->capability & 1)) + break; - if (ide_use_dma(drive) && config_for_dma(drive)) - return 0; + /* Consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) + break; + + if (id->field_valid & 2) { + if ((id->dma_mword & hwif->mwdma_mask) || + (id->dma_1word & hwif->swdma_mask)) + return 0; + } + + if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150) + return 0; + } while (0); return -1; } @@ -150,14 +195,14 @@ static inline void sl82c105_reset_host(struct pci_dev *dev) * This function is called when the IDE timer expires, the drive * indicates that it is READY, and we were waiting for DMA to complete. */ -static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) +static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; - u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; - u8 dma_cmd; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; + u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; + unsigned long dma_base = hwif->dma_base; - printk("sl82c105: lost IRQ, resetting host\n"); + printk("sl82c105: lost IRQ: resetting host\n"); /* * Check the raw interrupt from the drive. @@ -170,15 +215,15 @@ static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) * Was DMA enabled? If so, disable it - we're resetting the * host. The IDE layer will be handling the drive for us. */ - dma_cmd = inb(hwif->dma_command); - if (dma_cmd & 1) { - outb(dma_cmd & ~1, hwif->dma_command); + val = inb(dma_base); + if (val & 1) { + outb(val & ~1, dma_base); printk("sl82c105: DMA was enabled\n"); } sl82c105_reset_host(dev); - /* __ide_dma_lostirq would return 1, so we do as well */ + /* ide_dmaproc would return 1, so we do as well */ return 1; } @@ -190,10 +235,10 @@ static int sl82c105_ide_dma_lostirq(ide_drive_t *drive) * The generic IDE core will have disabled the BMEN bit before this * function is called. */ -static void sl82c105_dma_start(ide_drive_t *drive) +static void sl82c105_ide_dma_start(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; sl82c105_reset_host(dev); ide_dma_start(drive); @@ -201,8 +246,8 @@ static void sl82c105_dma_start(ide_drive_t *drive) static int sl82c105_ide_dma_timeout(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; DBG(("sl82c105_ide_dma_timeout(drive:%s)\n", drive->name)); @@ -210,32 +255,26 @@ static int sl82c105_ide_dma_timeout(ide_drive_t *drive) return __ide_dma_timeout(drive); } -static int sl82c105_ide_dma_on(ide_drive_t *drive) +static int sl82c105_ide_dma_on (ide_drive_t *drive) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int rc, reg = 0x44 + drive->dn * 4; - DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); - rc = __ide_dma_on(drive); - if (rc == 0) { - pci_write_config_word(dev, reg, 0x0200); - - printk(KERN_INFO "%s: DMA enabled\n", drive->name); - } - return rc; + if (config_for_dma(drive)) + return 1; + printk(KERN_INFO "%s: DMA enabled\n", drive->name); + return __ide_dma_on(drive); } static void sl82c105_dma_off_quietly(ide_drive_t *drive) { - struct pci_dev *dev = HWIF(drive)->pci_dev; - int reg = 0x44 + drive->dn * 4; + u8 speed = XFER_PIO_0; DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); - pci_write_config_word(dev, reg, drive->drive_data); - ide_dma_off_quietly(drive); + if (drive->pio_speed) + speed = drive->pio_speed - XFER_PIO_0; + config_for_pio(drive, speed, 0, 1); } /* @@ -247,8 +286,8 @@ static void sl82c105_dma_off_quietly(ide_drive_t *drive) */ static void sl82c105_selectproc(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = hwif->pci_dev; + ide_hwif_t *hwif = HWIF(drive); + struct pci_dev *dev = hwif->pci_dev; u32 val, old, mask; //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name)); @@ -284,12 +323,18 @@ static void sl82c105_resetproc(ide_drive_t *drive) * We only deal with PIO mode here - DMA mode 'using_dma' is not * initialised at the point that this function is called. */ -static void sl82c105_tune_drive(ide_drive_t *drive, u8 pio) +static void tune_sl82c105(ide_drive_t *drive, u8 pio) { - DBG(("sl82c105_tune_drive(drive:%s, pio:%u)\n", drive->name, pio)); + DBG(("tune_sl82c105(drive:%s)\n", drive->name)); + + config_for_pio(drive, pio, 1, 0); - pio = sl82c105_tune_pio(drive, pio); - (void) ide_config_drive_speed(drive, XFER_PIO_0 + pio); + /* + * We support 32-bit I/O on this interface, and it + * doesn't have problems with interrupts. + */ + drive->io_32bit = 1; + drive->unmask = 1; } /* @@ -348,7 +393,7 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c } /* - * Initialise IDE channel + * Initialise the chip */ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { @@ -356,22 +401,24 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); - hwif->tuneproc = &sl82c105_tune_drive; - hwif->selectproc = &sl82c105_selectproc; - hwif->resetproc = &sl82c105_resetproc; - - /* - * We support 32-bit I/O on this interface, and - * it doesn't have problems with interrupts. - */ - hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1; - hwif->drives[0].unmask = hwif->drives[1].unmask = 1; + hwif->tuneproc = tune_sl82c105; + hwif->selectproc = sl82c105_selectproc; + hwif->resetproc = sl82c105_resetproc; /* + * Default to PIO 0 for fallback unless tuned otherwise. * We always autotune PIO, this is done before DMA is checked, * so there's no risk of accidentally disabling DMA */ - hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + hwif->drives[0].pio_speed = XFER_PIO_0; + hwif->drives[0].autotune = 1; + hwif->drives[1].pio_speed = XFER_PIO_0; + hwif->drives[1].autotune = 1; + + hwif->atapi_dma = 0; + hwif->mwdma_mask = 0; + hwif->swdma_mask = 0; + hwif->autodma = 0; if (!hwif->dma_base) return; @@ -382,27 +429,27 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) * Never ever EVER under any circumstances enable * DMA when the bridge is this old. */ - printk(" %s: Winbond W83C553 bridge revision %d, " - "BM-DMA disabled\n", hwif->name, rev); - return; + printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", + hwif->name, rev); + } else { + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; + + hwif->ide_dma_check = &sl82c105_check_drive; + hwif->ide_dma_on = &sl82c105_ide_dma_on; + hwif->dma_off_quietly = &sl82c105_dma_off_quietly; + hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; + hwif->dma_start = &sl82c105_ide_dma_start; + hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; + + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; + + if (hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; } - - hwif->atapi_dma = 1; - hwif->mwdma_mask = 0x04; - - hwif->ide_dma_check = &sl82c105_ide_dma_check; - hwif->ide_dma_on = &sl82c105_ide_dma_on; - hwif->dma_off_quietly = &sl82c105_dma_off_quietly; - hwif->ide_dma_lostirq = &sl82c105_ide_dma_lostirq; - hwif->dma_start = &sl82c105_dma_start; - hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; - - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; - - if (hwif->mate) - hwif->serialized = hwif->mate->serialized = 1; } static ide_pci_device_t sl82c105_chipset __devinitdata = { diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index a49ebe44babd..071a030ec26e 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -1157,32 +1157,32 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) pmif->cable_80 = 0; pmif->broken_dma = pmif->broken_dma_warn = 0; - if (of_device_is_compatible(np, "shasta-ata")) + if (device_is_compatible(np, "shasta-ata")) pmif->kind = controller_sh_ata6; - else if (of_device_is_compatible(np, "kauai-ata")) + else if (device_is_compatible(np, "kauai-ata")) pmif->kind = controller_un_ata6; - else if (of_device_is_compatible(np, "K2-UATA")) + else if (device_is_compatible(np, "K2-UATA")) pmif->kind = controller_k2_ata6; - else if (of_device_is_compatible(np, "keylargo-ata")) { + else if (device_is_compatible(np, "keylargo-ata")) { if (strcmp(np->name, "ata-4") == 0) pmif->kind = controller_kl_ata4; else pmif->kind = controller_kl_ata3; - } else if (of_device_is_compatible(np, "heathrow-ata")) + } else if (device_is_compatible(np, "heathrow-ata")) pmif->kind = controller_heathrow; else { pmif->kind = controller_ohare; pmif->broken_dma = 1; } - bidp = of_get_property(np, "AAPL,bus-id", NULL); + bidp = get_property(np, "AAPL,bus-id", NULL); pmif->aapl_bus_id = bidp ? *bidp : 0; /* Get cable type from device-tree */ if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6 || pmif->kind == controller_sh_ata6) { - const char* cable = of_get_property(np, "cable-type", NULL); + const char* cable = get_property(np, "cable-type", NULL); if (cable && !strncmp(cable, "80-", 3)) pmif->cable_80 = 1; } @@ -1190,8 +1190,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) * they have a 80 conductor cable, this seem to be always the case unless * the user mucked around */ - if (of_device_is_compatible(np, "K2-UATA") || - of_device_is_compatible(np, "shasta-ata")) + if (device_is_compatible(np, "K2-UATA") || + device_is_compatible(np, "shasta-ata")) pmif->cable_80 = 1; /* On Kauai-type controllers, we make sure the FCR is correct */ diff --git a/trunk/drivers/ieee1394/dv1394.c b/trunk/drivers/ieee1394/dv1394.c index 208141377612..026e38face5c 100644 --- a/trunk/drivers/ieee1394/dv1394.c +++ b/trunk/drivers/ieee1394/dv1394.c @@ -94,6 +94,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/ieee1394/hosts.c b/trunk/drivers/ieee1394/hosts.c index bd0755c789c5..6164a9a83396 100644 --- a/trunk/drivers/ieee1394/hosts.c +++ b/trunk/drivers/ieee1394/hosts.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/ieee1394/raw1394.c b/trunk/drivers/ieee1394/raw1394.c index d382500f4210..c6aefd9ad0e8 100644 --- a/trunk/drivers/ieee1394/raw1394.c +++ b/trunk/drivers/ieee1394/raw1394.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/ieee1394/video1394.c b/trunk/drivers/ieee1394/video1394.c index 87ebd0846c34..95ca26d75272 100644 --- a/trunk/drivers/ieee1394/video1394.c +++ b/trunk/drivers/ieee1394/video1394.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index eff591deeb46..842cd0b53e91 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/infiniband/core/fmr_pool.c b/trunk/drivers/infiniband/core/fmr_pool.c index a06bcc65a871..1d796e7c8199 100644 --- a/trunk/drivers/infiniband/core/fmr_pool.c +++ b/trunk/drivers/infiniband/core/fmr_pool.c @@ -43,8 +43,6 @@ #include "core_priv.h" -#define PFX "fmr_pool: " - enum { IB_FMR_MAX_REMAPS = 32, @@ -152,7 +150,7 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool) #ifdef DEBUG if (fmr->ref_count !=0) { - printk(KERN_WARNING PFX "Unmapping FMR 0x%08x with ref count %d", + printk(KERN_WARNING "Unmapping FMR 0x%08x with ref count %d", fmr, fmr->ref_count); } #endif @@ -170,7 +168,7 @@ static void ib_fmr_batch_release(struct ib_fmr_pool *pool) ret = ib_unmap_fmr(&fmr_list); if (ret) - printk(KERN_WARNING PFX "ib_unmap_fmr returned %d", ret); + printk(KERN_WARNING "ib_unmap_fmr returned %d", ret); spin_lock_irq(&pool->pool_lock); list_splice(&unmap_list, &pool->free_list); @@ -228,20 +226,20 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, device = pd->device; if (!device->alloc_fmr || !device->dealloc_fmr || !device->map_phys_fmr || !device->unmap_fmr) { - printk(KERN_INFO PFX "Device %s does not support FMRs\n", + printk(KERN_WARNING "Device %s does not support fast memory regions", device->name); return ERR_PTR(-ENOSYS); } attr = kmalloc(sizeof *attr, GFP_KERNEL); if (!attr) { - printk(KERN_WARNING PFX "couldn't allocate device attr struct"); + printk(KERN_WARNING "couldn't allocate device attr struct"); return ERR_PTR(-ENOMEM); } ret = ib_query_device(device, attr); if (ret) { - printk(KERN_WARNING PFX "couldn't query device: %d", ret); + printk(KERN_WARNING "couldn't query device"); kfree(attr); return ERR_PTR(ret); } @@ -255,7 +253,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, pool = kmalloc(sizeof *pool, GFP_KERNEL); if (!pool) { - printk(KERN_WARNING PFX "couldn't allocate pool struct"); + printk(KERN_WARNING "couldn't allocate pool struct"); return ERR_PTR(-ENOMEM); } @@ -272,7 +270,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, kmalloc(IB_FMR_HASH_SIZE * sizeof *pool->cache_bucket, GFP_KERNEL); if (!pool->cache_bucket) { - printk(KERN_WARNING PFX "Failed to allocate cache in pool"); + printk(KERN_WARNING "Failed to allocate cache in pool"); ret = -ENOMEM; goto out_free_pool; } @@ -296,7 +294,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, "ib_fmr(%s)", device->name); if (IS_ERR(pool->thread)) { - printk(KERN_WARNING PFX "couldn't start cleanup thread"); + printk(KERN_WARNING "couldn't start cleanup thread"); ret = PTR_ERR(pool->thread); goto out_free_pool; } @@ -313,8 +311,8 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, fmr = kmalloc(sizeof *fmr + params->max_pages_per_fmr * sizeof (u64), GFP_KERNEL); if (!fmr) { - printk(KERN_WARNING PFX "failed to allocate fmr " - "struct for FMR %d", i); + printk(KERN_WARNING "failed to allocate fmr struct " + "for FMR %d", i); goto out_fail; } @@ -325,8 +323,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd, fmr->fmr = ib_alloc_fmr(pd, params->access, &fmr_attr); if (IS_ERR(fmr->fmr)) { - printk(KERN_WARNING PFX "fmr_create failed " - "for FMR %d", i); + printk(KERN_WARNING "fmr_create failed for FMR %d", i); kfree(fmr); goto out_fail; } @@ -381,7 +378,7 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool) } if (i < pool->pool_size) - printk(KERN_WARNING PFX "pool still has %d regions registered", + printk(KERN_WARNING "pool still has %d regions registered", pool->pool_size - i); kfree(pool->cache_bucket); @@ -466,7 +463,8 @@ struct ib_pool_fmr *ib_fmr_pool_map_phys(struct ib_fmr_pool *pool_handle, list_add(&fmr->list, &pool->free_list); spin_unlock_irqrestore(&pool->pool_lock, flags); - printk(KERN_WARNING PFX "fmr_map returns %d\n", result); + printk(KERN_WARNING "fmr_map returns %d\n", + result); return ERR_PTR(result); } @@ -518,7 +516,7 @@ int ib_fmr_pool_unmap(struct ib_pool_fmr *fmr) #ifdef DEBUG if (fmr->ref_count < 0) - printk(KERN_WARNING PFX "FMR %p has ref count %d < 0", + printk(KERN_WARNING "FMR %p has ref count %d < 0", fmr, fmr->ref_count); #endif diff --git a/trunk/drivers/infiniband/core/iwcm.c b/trunk/drivers/infiniband/core/iwcm.c index 223b1aa7d92b..891d1fa7b2eb 100644 --- a/trunk/drivers/infiniband/core/iwcm.c +++ b/trunk/drivers/infiniband/core/iwcm.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index 85ccf13b8041..6edfecf1be72 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -2771,7 +2771,7 @@ static int ib_mad_port_open(struct ib_device *device, cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2; port_priv->cq = ib_create_cq(port_priv->device, ib_mad_thread_completion_handler, - NULL, port_priv, cq_size, 0); + NULL, port_priv, cq_size); if (IS_ERR(port_priv->cq)) { printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n"); ret = PTR_ERR(port_priv->cq); diff --git a/trunk/drivers/infiniband/core/mad_priv.h b/trunk/drivers/infiniband/core/mad_priv.h index 9be5cc00a3a9..de89717f49fe 100644 --- a/trunk/drivers/infiniband/core/mad_priv.h +++ b/trunk/drivers/infiniband/core/mad_priv.h @@ -39,6 +39,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/infiniband/core/multicast.c b/trunk/drivers/infiniband/core/multicast.c index 1e13ab42b70b..4a579b3a1c90 100644 --- a/trunk/drivers/infiniband/core/multicast.c +++ b/trunk/drivers/infiniband/core/multicast.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/infiniband/core/sa_query.c b/trunk/drivers/infiniband/core/sa_query.c index 6469406ea9d8..9a7eaadb1688 100644 --- a/trunk/drivers/infiniband/core/sa_query.c +++ b/trunk/drivers/infiniband/core/sa_query.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/infiniband/core/user_mad.c b/trunk/drivers/infiniband/core/user_mad.c index d97ded25c4ff..8199b83052a9 100644 --- a/trunk/drivers/infiniband/core/user_mad.c +++ b/trunk/drivers/infiniband/core/user_mad.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c index bab66769be14..4fd75afa6a3a 100644 --- a/trunk/drivers/infiniband/core/uverbs_cmd.c +++ b/trunk/drivers/infiniband/core/uverbs_cmd.c @@ -802,7 +802,6 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, INIT_LIST_HEAD(&obj->async_list); cq = file->device->ib_dev->create_cq(file->device->ib_dev, cmd.cqe, - cmd.comp_vector, file->ucontext, &udata); if (IS_ERR(cq)) { ret = PTR_ERR(cq); diff --git a/trunk/drivers/infiniband/core/uverbs_main.c b/trunk/drivers/infiniband/core/uverbs_main.c index d44e54799651..f8bc822a3cc3 100644 --- a/trunk/drivers/infiniband/core/uverbs_main.c +++ b/trunk/drivers/infiniband/core/uverbs_main.c @@ -752,7 +752,7 @@ static void ib_uverbs_add_one(struct ib_device *device) spin_unlock(&map_lock); uverbs_dev->ib_dev = device; - uverbs_dev->num_comp_vectors = device->num_comp_vectors; + uverbs_dev->num_comp_vectors = 1; uverbs_dev->dev = cdev_alloc(); if (!uverbs_dev->dev) diff --git a/trunk/drivers/infiniband/core/verbs.c b/trunk/drivers/infiniband/core/verbs.c index 86ed8af9c7e6..ccdf93d30b01 100644 --- a/trunk/drivers/infiniband/core/verbs.c +++ b/trunk/drivers/infiniband/core/verbs.c @@ -609,11 +609,11 @@ EXPORT_SYMBOL(ib_destroy_qp); struct ib_cq *ib_create_cq(struct ib_device *device, ib_comp_handler comp_handler, void (*event_handler)(struct ib_event *, void *), - void *cq_context, int cqe, int comp_vector) + void *cq_context, int cqe) { struct ib_cq *cq; - cq = device->create_cq(device, cqe, comp_vector, NULL, NULL); + cq = device->create_cq(device, cqe, NULL, NULL); if (!IS_ERR(cq)) { cq->device = device; diff --git a/trunk/drivers/infiniband/hw/amso1100/c2.h b/trunk/drivers/infiniband/hw/amso1100/c2.h index fa58200217a1..04a9db5de881 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2.h +++ b/trunk/drivers/infiniband/hw/amso1100/c2.h @@ -519,7 +519,7 @@ extern void c2_free_cq(struct c2_dev *c2dev, struct c2_cq *cq); extern void c2_cq_event(struct c2_dev *c2dev, u32 mq_index); extern void c2_cq_clean(struct c2_dev *c2dev, struct c2_qp *qp, u32 mq_index); extern int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); -extern int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags); +extern int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify); /* CM */ extern int c2_llp_connect(struct iw_cm_id *cm_id, diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_cq.c b/trunk/drivers/infiniband/hw/amso1100/c2_cq.c index d2b3366786d6..5175c99ee586 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_cq.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_cq.c @@ -217,19 +217,17 @@ int c2_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry) return npolled; } -int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags) +int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) { struct c2_mq_shared __iomem *shared; struct c2_cq *cq; - unsigned long flags; - int ret = 0; cq = to_c2cq(ibcq); shared = cq->mq.peer; - if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_NEXT_COMP) + if (notify == IB_CQ_NEXT_COMP) writeb(C2_CQ_NOTIFICATION_TYPE_NEXT, &shared->notification_type); - else if ((notify_flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED) + else if (notify == IB_CQ_SOLICITED) writeb(C2_CQ_NOTIFICATION_TYPE_NEXT_SE, &shared->notification_type); else return -EINVAL; @@ -243,13 +241,7 @@ int c2_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags) */ readb(&shared->armed); - if (notify_flags & IB_CQ_REPORT_MISSED_EVENTS) { - spin_lock_irqsave(&cq->lock, flags); - ret = !c2_mq_empty(&cq->mq); - spin_unlock_irqrestore(&cq->lock, flags); - } - - return ret; + return 0; } static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq) diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_provider.c b/trunk/drivers/infiniband/hw/amso1100/c2_provider.c index 109166223c09..607c09bf764c 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_provider.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_provider.c @@ -290,7 +290,7 @@ static int c2_destroy_qp(struct ib_qp *ib_qp) return 0; } -static struct ib_cq *c2_create_cq(struct ib_device *ibdev, int entries, int vector, +static struct ib_cq *c2_create_cq(struct ib_device *ibdev, int entries, struct ib_ucontext *context, struct ib_udata *udata) { @@ -795,7 +795,6 @@ int c2_register_device(struct c2_dev *dev) memset(&dev->ibdev.node_guid, 0, sizeof(dev->ibdev.node_guid)); memcpy(&dev->ibdev.node_guid, dev->pseudo_netdev->dev_addr, 6); dev->ibdev.phys_port_cnt = 1; - dev->ibdev.num_comp_vectors = 1; dev->ibdev.dma_device = &dev->pcidev->dev; dev->ibdev.query_device = c2_query_device; dev->ibdev.query_port = c2_query_port; diff --git a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c index 76049afc7655..f5e9aeec6f6e 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c +++ b/trunk/drivers/infiniband/hw/cxgb3/cxio_hal.c @@ -114,10 +114,7 @@ int cxio_hal_cq_op(struct cxio_rdev *rdev_p, struct t3_cq *cq, return -EIO; } } - - return 1; } - return 0; } diff --git a/trunk/drivers/infiniband/hw/cxgb3/cxio_wr.h b/trunk/drivers/infiniband/hw/cxgb3/cxio_wr.h index ff7290eacefb..90d7b8972cb4 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/trunk/drivers/infiniband/hw/cxgb3/cxio_wr.h @@ -38,7 +38,6 @@ #include "firmware_exports.h" #define T3_MAX_SGE 4 -#define T3_MAX_INLINE 64 #define Q_EMPTY(rptr,wptr) ((rptr)==(wptr)) #define Q_FULL(rptr,wptr,size_log2) ( (((wptr)-(rptr))>>(size_log2)) && \ diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c index b2faff5abce8..3b4b0acd707f 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -1109,15 +1109,6 @@ static int abort_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) PDBG("%s ep %p\n", __FUNCTION__, ep); - /* - * We get 2 abort replies from the HW. The first one must - * be ignored except for scribbling that we need one more. - */ - if (!(ep->flags & ABORT_REQ_IN_PROGRESS)) { - ep->flags |= ABORT_REQ_IN_PROGRESS; - return CPL_RET_BUF_DONE; - } - close_complete_upcall(ep); state_set(&ep->com, DEAD); release_ep_resources(ep); @@ -1198,7 +1189,6 @@ static int listen_stop(struct iwch_listen_ep *ep) } req = (struct cpl_close_listserv_req *) skb_put(skb, sizeof(*req)); req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); - req->cpu_idx = 0; OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); skb->priority = 1; ep->com.tdev->send(ep->com.tdev, skb); @@ -1485,15 +1475,6 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) int ret; int state; - /* - * We get 2 peer aborts from the HW. The first one must - * be ignored except for scribbling that we need one more. - */ - if (!(ep->flags & PEER_ABORT_IN_PROGRESS)) { - ep->flags |= PEER_ABORT_IN_PROGRESS; - return CPL_RET_BUF_DONE; - } - if (is_neg_adv_abort(req->status)) { PDBG("%s neg_adv_abort ep %p tid %d\n", __FUNCTION__, ep, ep->hwtid); diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h index 21a388c313cf..0c6f281bd4a0 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_cm.h @@ -143,11 +143,6 @@ enum iwch_ep_state { DEAD, }; -enum iwch_ep_flags { - PEER_ABORT_IN_PROGRESS = (1 << 0), - ABORT_REQ_IN_PROGRESS = (1 << 1), -}; - struct iwch_ep_common { struct iw_cm_id *cm_id; struct iwch_qp *qp; @@ -186,7 +181,6 @@ struct iwch_ep { u16 plen; u32 ird; u32 ord; - u32 flags; }; static inline struct iwch_ep *to_ep(struct iw_cm_id *cm_id) diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c index a891493fd340..af28a317016d 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -139,7 +139,7 @@ static int iwch_destroy_cq(struct ib_cq *ib_cq) return 0; } -static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries, int vector, +static struct ib_cq *iwch_create_cq(struct ib_device *ibdev, int entries, struct ib_ucontext *ib_context, struct ib_udata *udata) { @@ -292,7 +292,7 @@ static int iwch_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata) #endif } -static int iwch_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) +static int iwch_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) { struct iwch_dev *rhp; struct iwch_cq *chp; @@ -303,7 +303,7 @@ static int iwch_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) chp = to_iwch_cq(ibcq); rhp = chp->rhp; - if ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED) + if (notify == IB_CQ_SOLICITED) cq_op = CQ_ARM_SE; else cq_op = CQ_ARM_AN; @@ -317,11 +317,9 @@ static int iwch_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) PDBG("%s rptr 0x%x\n", __FUNCTION__, chp->cq.rptr); err = cxio_hal_cq_op(&rhp->rdev, &chp->cq, cq_op, 0); spin_unlock_irqrestore(&chp->lock, flag); - if (err < 0) + if (err) printk(KERN_ERR MOD "Error %d rearming CQID 0x%x\n", err, chp->cq.cqid); - if (err > 0 && !(flags & IB_CQ_REPORT_MISSED_EVENTS)) - err = 0; return err; } @@ -782,9 +780,6 @@ static struct ib_qp *iwch_create_qp(struct ib_pd *pd, if (rqsize > T3_MAX_RQ_SIZE) return ERR_PTR(-EINVAL); - if (attrs->cap.max_inline_data > T3_MAX_INLINE) - return ERR_PTR(-EINVAL); - /* * NOTE: The SQ and total WQ sizes don't need to be * a power of two. However, all the code assumes @@ -1112,7 +1107,6 @@ int iwch_register_device(struct iwch_dev *dev) dev->ibdev.node_type = RDMA_NODE_RNIC; memcpy(dev->ibdev.node_desc, IWCH_NODE_DESC, sizeof(IWCH_NODE_DESC)); dev->ibdev.phys_port_cnt = dev->rdev.port_info.nports; - dev->ibdev.num_comp_vectors = 1; dev->ibdev.dma_device = &(dev->rdev.rnic_info.pdev->dev); dev->ibdev.query_device = iwch_query_device; dev->ibdev.query_port = iwch_query_port; diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c index 714dddbc9a98..0a472c9b44db 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_qp.c @@ -471,62 +471,43 @@ int iwch_bind_mw(struct ib_qp *qp, return err; } -static inline void build_term_codes(struct respQ_msg_t *rsp_msg, - u8 *layer_type, u8 *ecode) +static void build_term_codes(int t3err, u8 *layer_type, u8 *ecode, int tagged) { - int status = TPT_ERR_INTERNAL_ERR; - int tagged = 0; - int opcode = -1; - int rqtype = 0; - int send_inv = 0; - - if (rsp_msg) { - status = CQE_STATUS(rsp_msg->cqe); - opcode = CQE_OPCODE(rsp_msg->cqe); - rqtype = RQ_TYPE(rsp_msg->cqe); - send_inv = (opcode == T3_SEND_WITH_INV) || - (opcode == T3_SEND_WITH_SE_INV); - tagged = (opcode == T3_RDMA_WRITE) || - (rqtype && (opcode == T3_READ_RESP)); - } - - switch (status) { + switch (t3err) { case TPT_ERR_STAG: - if (send_inv) { - *layer_type = LAYER_RDMAP|RDMAP_REMOTE_OP; - *ecode = RDMAP_CANT_INV_STAG; - } else { + if (tagged == 1) { + *layer_type = LAYER_DDP|DDP_TAGGED_ERR; + *ecode = DDPT_INV_STAG; + } else if (tagged == 2) { *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT; *ecode = RDMAP_INV_STAG; } break; case TPT_ERR_PDID: - *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT; - if ((opcode == T3_SEND_WITH_INV) || - (opcode == T3_SEND_WITH_SE_INV)) - *ecode = RDMAP_CANT_INV_STAG; - else - *ecode = RDMAP_STAG_NOT_ASSOC; - break; case TPT_ERR_QPID: - *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT; - *ecode = RDMAP_STAG_NOT_ASSOC; - break; case TPT_ERR_ACCESS: - *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT; - *ecode = RDMAP_ACC_VIOL; + if (tagged == 1) { + *layer_type = LAYER_DDP|DDP_TAGGED_ERR; + *ecode = DDPT_STAG_NOT_ASSOC; + } else if (tagged == 2) { + *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT; + *ecode = RDMAP_STAG_NOT_ASSOC; + } break; case TPT_ERR_WRAP: *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT; *ecode = RDMAP_TO_WRAP; break; case TPT_ERR_BOUND: - if (tagged) { + if (tagged == 1) { *layer_type = LAYER_DDP|DDP_TAGGED_ERR; *ecode = DDPT_BASE_BOUNDS; - } else { + } else if (tagged == 2) { *layer_type = LAYER_RDMAP|RDMAP_REMOTE_PROT; *ecode = RDMAP_BASE_BOUNDS; + } else { + *layer_type = LAYER_DDP|DDP_UNTAGGED_ERR; + *ecode = DDPU_MSG_TOOBIG; } break; case TPT_ERR_INVALIDATE_SHARED_MR: @@ -610,6 +591,8 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg) { union t3_wr *wqe; struct terminate_message *term; + int status; + int tagged = 0; struct sk_buff *skb; PDBG("%s %d\n", __FUNCTION__, __LINE__); @@ -627,7 +610,17 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg) /* immediate data starts here. */ term = (struct terminate_message *)wqe->send.sgl; - build_term_codes(rsp_msg, &term->layer_etype, &term->ecode); + if (rsp_msg) { + status = CQE_STATUS(rsp_msg->cqe); + if (CQE_OPCODE(rsp_msg->cqe) == T3_RDMA_WRITE) + tagged = 1; + if ((CQE_OPCODE(rsp_msg->cqe) == T3_READ_REQ) || + (CQE_OPCODE(rsp_msg->cqe) == T3_READ_RESP)) + tagged = 2; + } else { + status = TPT_ERR_INTERNAL_ERR; + } + build_term_codes(status, &term->layer_etype, &term->ecode, tagged); build_fw_riwrh((void *)wqe, T3_WR_SEND, T3_COMPLETION_FLAG | T3_NOTIFY_FLAG, 1, qhp->ep->hwtid, 5); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_cq.c b/trunk/drivers/infiniband/hw/ehca/ehca_cq.c index 67f0670fe3b1..e2cdc1a16fe9 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_cq.c @@ -113,7 +113,7 @@ struct ehca_qp* ehca_cq_get_qp(struct ehca_cq *cq, int real_qp_num) return ret; } -struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, +struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, struct ib_ucontext *context, struct ib_udata *udata) { diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h b/trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h index e14b029332c8..95fd59fb4528 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h @@ -123,7 +123,7 @@ int ehca_destroy_eq(struct ehca_shca *shca, struct ehca_eq *eq); void *ehca_poll_eq(struct ehca_shca *shca, struct ehca_eq *eq); -struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, +struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, struct ib_ucontext *context, struct ib_udata *udata); @@ -135,7 +135,7 @@ int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc); int ehca_peek_cq(struct ib_cq *cq, int wc_cnt); -int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags notify_flags); +int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify cq_notify); struct ib_qp *ehca_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *init_attr, diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_main.c b/trunk/drivers/infiniband/hw/ehca/ehca_main.c index fe90e7454560..4700085ba834 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_main.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_main.c @@ -313,7 +313,6 @@ int ehca_init_device(struct ehca_shca *shca) shca->ib_device.node_type = RDMA_NODE_IB_CA; shca->ib_device.phys_port_cnt = shca->num_ports; - shca->ib_device.num_comp_vectors = 1; shca->ib_device.dma_device = &shca->ibmebus_dev->ofdev.dev; shca->ib_device.query_device = ehca_query_device; shca->ib_device.query_port = ehca_query_port; @@ -376,7 +375,7 @@ static int ehca_create_aqp1(struct ehca_shca *shca, u32 port) return -EPERM; } - ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10, 0); + ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10); if (IS_ERR(ibcq)) { ehca_err(&shca->ib_device, "Cannot create AQP1 CQ."); return PTR_ERR(ibcq); @@ -570,7 +569,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev, struct ib_pd *ibpd; int ret; - handle = of_get_property(dev->ofdev.node, "ibm,hca-handle", NULL); + handle = get_property(dev->ofdev.node, "ibm,hca-handle", NULL); if (!handle) { ehca_gen_err("Cannot get eHCA handle for adapter: %s.", dev->ofdev.node->full_name); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c b/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c index caec9dee09e1..08d3f892d9f3 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -634,13 +634,11 @@ int ehca_poll_cq(struct ib_cq *cq, int num_entries, struct ib_wc *wc) return ret; } -int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags notify_flags) +int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify cq_notify) { struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq); - unsigned long spl_flags; - int ret = 0; - switch (notify_flags & IB_CQ_SOLICITED_MASK) { + switch (cq_notify) { case IB_CQ_SOLICITED: hipz_set_cqx_n0(my_cq, 1); break; @@ -651,11 +649,5 @@ int ehca_req_notify_cq(struct ib_cq *cq, enum ib_cq_notify_flags notify_flags) return -EINVAL; } - if (notify_flags & IB_CQ_REPORT_MISSED_EVENTS) { - spin_lock_irqsave(&my_cq->spinlock, spl_flags); - ret = ipz_qeit_is_valid(&my_cq->ipz_queue); - spin_unlock_irqrestore(&my_cq->spinlock, spl_flags); - } - - return ret; + return 0; } diff --git a/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.h index 57f141a36bce..8199c45768a3 100644 --- a/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.h +++ b/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.h @@ -140,14 +140,6 @@ static inline void *ipz_qeit_get_inc_valid(struct ipz_queue *queue) return cqe; } -static inline int ipz_qeit_is_valid(struct ipz_queue *queue) -{ - struct ehca_cqe *cqe = ipz_qeit_get(queue); - u32 cqe_flags = cqe->cqe_flags; - - return cqe_flags >> 7 == (queue->toggle_state & 1); -} - /* * returns and resets Queue Entry iterator * returns address (kv) of first Queue Entry diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_cq.c b/trunk/drivers/infiniband/hw/ipath/ipath_cq.c index 3e9241badba0..ea78e6dddc90 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_cq.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_cq.c @@ -204,7 +204,7 @@ static void send_complete(unsigned long data) * * Called by ib_create_cq() in the generic verbs code. */ -struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector, +struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, struct ib_ucontext *context, struct ib_udata *udata) { @@ -243,21 +243,33 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vec * See ipath_mmap() for details. */ if (udata && udata->outlen >= sizeof(__u64)) { + struct ipath_mmap_info *ip; + __u64 offset = (__u64) wc; int err; - u32 s = sizeof *wc + sizeof(struct ib_wc) * entries; - cq->ip = ipath_create_mmap_info(dev, s, context, wc); - if (!cq->ip) { - ret = ERR_PTR(-ENOMEM); + err = ib_copy_to_udata(udata, &offset, sizeof(offset)); + if (err) { + ret = ERR_PTR(err); goto bail_wc; } - err = ib_copy_to_udata(udata, &cq->ip->offset, - sizeof(cq->ip->offset)); - if (err) { - ret = ERR_PTR(err); - goto bail_ip; + /* Allocate info for ipath_mmap(). */ + ip = kmalloc(sizeof(*ip), GFP_KERNEL); + if (!ip) { + ret = ERR_PTR(-ENOMEM); + goto bail_wc; } + cq->ip = ip; + ip->context = context; + ip->obj = wc; + kref_init(&ip->ref); + ip->mmap_cnt = 0; + ip->size = PAGE_ALIGN(sizeof(*wc) + + sizeof(struct ib_wc) * entries); + spin_lock_irq(&dev->pending_lock); + ip->next = dev->pending_mmaps; + dev->pending_mmaps = ip; + spin_unlock_irq(&dev->pending_lock); } else cq->ip = NULL; @@ -265,18 +277,12 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vec if (dev->n_cqs_allocated == ib_ipath_max_cqs) { spin_unlock(&dev->n_cqs_lock); ret = ERR_PTR(-ENOMEM); - goto bail_ip; + goto bail_wc; } dev->n_cqs_allocated++; spin_unlock(&dev->n_cqs_lock); - if (cq->ip) { - spin_lock_irq(&dev->pending_lock); - list_add(&cq->ip->pending_mmaps, &dev->pending_mmaps); - spin_unlock_irq(&dev->pending_lock); - } - /* * ib_create_cq() will initialize cq->ibcq except for cq->ibcq.cqe. * The number of entries should be >= the number requested or return @@ -295,12 +301,12 @@ struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vec goto done; -bail_ip: - kfree(cq->ip); bail_wc: vfree(wc); + bail_cq: kfree(cq); + done: return ret; } @@ -334,18 +340,17 @@ int ipath_destroy_cq(struct ib_cq *ibcq) /** * ipath_req_notify_cq - change the notification type for a completion queue * @ibcq: the completion queue - * @notify_flags: the type of notification to request + * @notify: the type of notification to request * * Returns 0 for success. * * This may be called from interrupt context. Also called by * ib_req_notify_cq() in the generic verbs code. */ -int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags) +int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) { struct ipath_cq *cq = to_icq(ibcq); unsigned long flags; - int ret = 0; spin_lock_irqsave(&cq->lock, flags); /* @@ -353,15 +358,9 @@ int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags * any other transitions (see C11-31 and C11-32 in ch. 11.4.2.2). */ if (cq->notify != IB_CQ_NEXT_COMP) - cq->notify = notify_flags & IB_CQ_SOLICITED_MASK; - - if ((notify_flags & IB_CQ_REPORT_MISSED_EVENTS) && - cq->queue->head != cq->queue->tail) - ret = 1; - + cq->notify = notify; spin_unlock_irqrestore(&cq->lock, flags); - - return ret; + return 0; } /** @@ -444,12 +443,13 @@ int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata) if (cq->ip) { struct ipath_ibdev *dev = to_idev(ibcq->device); struct ipath_mmap_info *ip = cq->ip; - u32 s = sizeof *wc + sizeof(struct ib_wc) * cqe; - ipath_update_mmap_info(dev, ip, s, wc); + ip->obj = wc; + ip->size = PAGE_ALIGN(sizeof(*wc) + + sizeof(struct ib_wc) * cqe); spin_lock_irq(&dev->pending_lock); - if (list_empty(&ip->pending_mmaps)) - list_add(&ip->pending_mmaps, &dev->pending_mmaps); + ip->next = dev->pending_mmaps; + dev->pending_mmaps = ip; spin_unlock_irq(&dev->pending_lock); } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c index ebd5c7bd2cdb..ed55979bfd34 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_fs.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "ipath_kernel.h" @@ -523,7 +524,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data, int ret; static struct tree_descr files[] = { - [2] = {"atomic_stats", &atomic_stats_ops, S_IRUGO}, + [1] = {"atomic_stats", &atomic_stats_ops, S_IRUGO}, {""}, }; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_layer.c b/trunk/drivers/infiniband/hw/ipath/ipath_layer.c index 05a1d2b01d9d..e46aa4ed2a7e 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_layer.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_layer.c @@ -37,6 +37,7 @@ */ #include +#include #include #include "ipath_kernel.h" diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_mmap.c b/trunk/drivers/infiniband/hw/ipath/ipath_mmap.c index 937bc3396b53..a82157db4689 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_mmap.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_mmap.c @@ -46,11 +46,6 @@ void ipath_release_mmap_info(struct kref *ref) { struct ipath_mmap_info *ip = container_of(ref, struct ipath_mmap_info, ref); - struct ipath_ibdev *dev = to_idev(ip->context->device); - - spin_lock_irq(&dev->pending_lock); - list_del(&ip->pending_mmaps); - spin_unlock_irq(&dev->pending_lock); vfree(ip->obj); kfree(ip); @@ -65,12 +60,14 @@ static void ipath_vma_open(struct vm_area_struct *vma) struct ipath_mmap_info *ip = vma->vm_private_data; kref_get(&ip->ref); + ip->mmap_cnt++; } static void ipath_vma_close(struct vm_area_struct *vma) { struct ipath_mmap_info *ip = vma->vm_private_data; + ip->mmap_cnt--; kref_put(&ip->ref, ipath_release_mmap_info); } @@ -90,7 +87,7 @@ int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) struct ipath_ibdev *dev = to_idev(context->device); unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; unsigned long size = vma->vm_end - vma->vm_start; - struct ipath_mmap_info *ip, *pp; + struct ipath_mmap_info *ip, **pp; int ret = -EINVAL; /* @@ -99,16 +96,15 @@ int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) * CQ, QP, or SRQ is soon followed by a call to mmap(). */ spin_lock_irq(&dev->pending_lock); - list_for_each_entry_safe(ip, pp, &dev->pending_mmaps, - pending_mmaps) { + for (pp = &dev->pending_mmaps; (ip = *pp); pp = &ip->next) { /* Only the creator is allowed to mmap the object */ - if (context != ip->context || (__u64) offset != ip->offset) + if (context != ip->context || (void *) offset != ip->obj) continue; /* Don't allow a mmap larger than the object. */ if (size > ip->size) break; - list_del_init(&ip->pending_mmaps); + *pp = ip->next; spin_unlock_irq(&dev->pending_lock); ret = remap_vmalloc_range(vma, ip->obj, 0); @@ -123,51 +119,3 @@ int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma) done: return ret; } - -/* - * Allocate information for ipath_mmap - */ -struct ipath_mmap_info *ipath_create_mmap_info(struct ipath_ibdev *dev, - u32 size, - struct ib_ucontext *context, - void *obj) { - struct ipath_mmap_info *ip; - - ip = kmalloc(sizeof *ip, GFP_KERNEL); - if (!ip) - goto bail; - - size = PAGE_ALIGN(size); - - spin_lock_irq(&dev->mmap_offset_lock); - if (dev->mmap_offset == 0) - dev->mmap_offset = PAGE_SIZE; - ip->offset = dev->mmap_offset; - dev->mmap_offset += size; - spin_unlock_irq(&dev->mmap_offset_lock); - - INIT_LIST_HEAD(&ip->pending_mmaps); - ip->size = size; - ip->context = context; - ip->obj = obj; - kref_init(&ip->ref); - -bail: - return ip; -} - -void ipath_update_mmap_info(struct ipath_ibdev *dev, - struct ipath_mmap_info *ip, - u32 size, void *obj) { - size = PAGE_ALIGN(size); - - spin_lock_irq(&dev->mmap_offset_lock); - if (dev->mmap_offset == 0) - dev->mmap_offset = PAGE_SIZE; - ip->offset = dev->mmap_offset; - dev->mmap_offset += size; - spin_unlock_irq(&dev->mmap_offset_lock); - - ip->size = size; - ip->obj = obj; -} diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_qp.c b/trunk/drivers/infiniband/hw/ipath/ipath_qp.c index bfef08ecd342..16db9ac0b402 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_qp.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_qp.c @@ -844,36 +844,34 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, * See ipath_mmap() for details. */ if (udata && udata->outlen >= sizeof(__u64)) { + struct ipath_mmap_info *ip; + __u64 offset = (__u64) qp->r_rq.wq; int err; - if (!qp->r_rq.wq) { - __u64 offset = 0; + err = ib_copy_to_udata(udata, &offset, sizeof(offset)); + if (err) { + ret = ERR_PTR(err); + goto bail_rwq; + } - err = ib_copy_to_udata(udata, &offset, - sizeof(offset)); - if (err) { - ret = ERR_PTR(err); - goto bail_rwq; - } - } else { - u32 s = sizeof(struct ipath_rwq) + - qp->r_rq.size * sz; - - qp->ip = - ipath_create_mmap_info(dev, s, - ibpd->uobject->context, - qp->r_rq.wq); - if (!qp->ip) { + if (qp->r_rq.wq) { + /* Allocate info for ipath_mmap(). */ + ip = kmalloc(sizeof(*ip), GFP_KERNEL); + if (!ip) { ret = ERR_PTR(-ENOMEM); goto bail_rwq; } - - err = ib_copy_to_udata(udata, &(qp->ip->offset), - sizeof(qp->ip->offset)); - if (err) { - ret = ERR_PTR(err); - goto bail_ip; - } + qp->ip = ip; + ip->context = ibpd->uobject->context; + ip->obj = qp->r_rq.wq; + kref_init(&ip->ref); + ip->mmap_cnt = 0; + ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) + + qp->r_rq.size * sz); + spin_lock_irq(&dev->pending_lock); + ip->next = dev->pending_mmaps; + dev->pending_mmaps = ip; + spin_unlock_irq(&dev->pending_lock); } } @@ -887,12 +885,6 @@ struct ib_qp *ipath_create_qp(struct ib_pd *ibpd, dev->n_qps_allocated++; spin_unlock(&dev->n_qps_lock); - if (qp->ip) { - spin_lock_irq(&dev->pending_lock); - list_add(&qp->ip->pending_mmaps, &dev->pending_mmaps); - spin_unlock_irq(&dev->pending_lock); - } - ret = &qp->ibqp; goto bail; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_rc.c b/trunk/drivers/infiniband/hw/ipath/ipath_rc.c index 1915771fd038..b4b88d0b53f5 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_rc.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_rc.c @@ -98,21 +98,13 @@ static int ipath_make_rc_ack(struct ipath_qp *qp, case OP(RDMA_READ_RESPONSE_LAST): case OP(RDMA_READ_RESPONSE_ONLY): case OP(ATOMIC_ACKNOWLEDGE): - /* - * We can increment the tail pointer now that the last - * response has been sent instead of only being - * constructed. - */ - if (++qp->s_tail_ack_queue > IPATH_MAX_RDMA_ATOMIC) - qp->s_tail_ack_queue = 0; + qp->s_ack_state = OP(ACKNOWLEDGE); /* FALLTHROUGH */ - case OP(SEND_ONLY): case OP(ACKNOWLEDGE): /* Check for no next entry in the queue. */ if (qp->r_head_ack_queue == qp->s_tail_ack_queue) { if (qp->s_flags & IPATH_S_ACK_PENDING) goto normal; - qp->s_ack_state = OP(ACKNOWLEDGE); goto bail; } @@ -125,8 +117,12 @@ static int ipath_make_rc_ack(struct ipath_qp *qp, if (len > pmtu) { len = pmtu; qp->s_ack_state = OP(RDMA_READ_RESPONSE_FIRST); - } else + } else { qp->s_ack_state = OP(RDMA_READ_RESPONSE_ONLY); + if (++qp->s_tail_ack_queue > + IPATH_MAX_RDMA_ATOMIC) + qp->s_tail_ack_queue = 0; + } ohdr->u.aeth = ipath_compute_aeth(qp); hwords++; qp->s_ack_rdma_psn = e->psn; @@ -143,6 +139,8 @@ static int ipath_make_rc_ack(struct ipath_qp *qp, cpu_to_be32(e->atomic_data); hwords += sizeof(ohdr->u.at) / sizeof(u32); bth2 = e->psn; + if (++qp->s_tail_ack_queue > IPATH_MAX_RDMA_ATOMIC) + qp->s_tail_ack_queue = 0; } bth0 = qp->s_ack_state << 24; break; @@ -158,6 +156,8 @@ static int ipath_make_rc_ack(struct ipath_qp *qp, ohdr->u.aeth = ipath_compute_aeth(qp); hwords++; qp->s_ack_state = OP(RDMA_READ_RESPONSE_LAST); + if (++qp->s_tail_ack_queue > IPATH_MAX_RDMA_ATOMIC) + qp->s_tail_ack_queue = 0; } bth0 = qp->s_ack_state << 24; bth2 = qp->s_ack_rdma_psn++ & IPATH_PSN_MASK; @@ -171,7 +171,7 @@ static int ipath_make_rc_ack(struct ipath_qp *qp, * the ACK before setting s_ack_state to ACKNOWLEDGE * (see above). */ - qp->s_ack_state = OP(SEND_ONLY); + qp->s_ack_state = OP(ATOMIC_ACKNOWLEDGE); qp->s_flags &= ~IPATH_S_ACK_PENDING; qp->s_cur_sge = NULL; if (qp->s_nak_state) @@ -223,18 +223,23 @@ int ipath_make_rc_req(struct ipath_qp *qp, /* Sending responses has higher priority over sending requests. */ if ((qp->r_head_ack_queue != qp->s_tail_ack_queue || (qp->s_flags & IPATH_S_ACK_PENDING) || - qp->s_ack_state != OP(ACKNOWLEDGE)) && + qp->s_ack_state != IB_OPCODE_RC_ACKNOWLEDGE) && ipath_make_rc_ack(qp, ohdr, pmtu, bth0p, bth2p)) goto done; if (!(ib_ipath_state_ops[qp->state] & IPATH_PROCESS_SEND_OK) || - qp->s_rnr_timeout || qp->s_wait_credit) + qp->s_rnr_timeout) goto bail; /* Limit the number of packets sent without an ACK. */ if (ipath_cmp24(qp->s_psn, qp->s_last_psn + IPATH_PSN_CREDIT) > 0) { qp->s_wait_credit = 1; dev->n_rc_stalls++; + spin_lock(&dev->pending_lock); + if (list_empty(&qp->timerwait)) + list_add_tail(&qp->timerwait, + &dev->pending[dev->pending_index]); + spin_unlock(&dev->pending_lock); goto bail; } @@ -582,12 +587,9 @@ static void send_rc_ack(struct ipath_qp *qp) u32 hwords; struct ipath_ib_header hdr; struct ipath_other_headers *ohdr; - unsigned long flags; /* Don't send ACK or NAK if a RDMA read or atomic is pending. */ - if (qp->r_head_ack_queue != qp->s_tail_ack_queue || - (qp->s_flags & IPATH_S_ACK_PENDING) || - qp->s_ack_state != OP(ACKNOWLEDGE)) + if (qp->r_head_ack_queue != qp->s_tail_ack_queue) goto queue_ack; /* Construct the header. */ @@ -638,11 +640,11 @@ static void send_rc_ack(struct ipath_qp *qp) dev->n_rc_qacks++; queue_ack: - spin_lock_irqsave(&qp->s_lock, flags); + spin_lock_irq(&qp->s_lock); qp->s_flags |= IPATH_S_ACK_PENDING; qp->s_nak_state = qp->r_nak_state; qp->s_ack_psn = qp->r_ack_psn; - spin_unlock_irqrestore(&qp->s_lock, flags); + spin_unlock_irq(&qp->s_lock); /* Call ipath_do_rc_send() in another thread. */ tasklet_hi_schedule(&qp->s_task); @@ -1259,7 +1261,6 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev, wc.dlid_path_bits = 0; wc.port_num = 0; ipath_sqerror_qp(qp, &wc); - spin_unlock_irqrestore(&qp->s_lock, flags); bail: return; } @@ -1293,7 +1294,6 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, struct ipath_ack_entry *e; u8 i, prev; int old_req; - unsigned long flags; if (diff > 0) { /* @@ -1327,7 +1327,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, psn &= IPATH_PSN_MASK; e = NULL; old_req = 1; - spin_lock_irqsave(&qp->s_lock, flags); + spin_lock_irq(&qp->s_lock); for (i = qp->r_head_ack_queue; ; i = prev) { if (i == qp->s_tail_ack_queue) old_req = 0; @@ -1425,7 +1425,7 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, * after all the previous RDMA reads and atomics. */ if (i == qp->r_head_ack_queue) { - spin_unlock_irqrestore(&qp->s_lock, flags); + spin_unlock_irq(&qp->s_lock); qp->r_nak_state = 0; qp->r_ack_psn = qp->r_psn - 1; goto send_ack; @@ -1439,10 +1439,11 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, break; } qp->r_nak_state = 0; + spin_unlock_irq(&qp->s_lock); tasklet_hi_schedule(&qp->s_task); unlock_done: - spin_unlock_irqrestore(&qp->s_lock, flags); + spin_unlock_irq(&qp->s_lock); done: return 1; @@ -1452,12 +1453,10 @@ static inline int ipath_rc_rcv_error(struct ipath_ibdev *dev, static void ipath_rc_error(struct ipath_qp *qp, enum ib_wc_status err) { - unsigned long flags; - - spin_lock_irqsave(&qp->s_lock, flags); + spin_lock_irq(&qp->s_lock); qp->state = IB_QPS_ERR; ipath_error_qp(qp, err); - spin_unlock_irqrestore(&qp->s_lock, flags); + spin_unlock_irq(&qp->s_lock); } /** diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_srq.c b/trunk/drivers/infiniband/hw/ipath/ipath_srq.c index 03acae66ba81..94033503400c 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_srq.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_srq.c @@ -139,24 +139,33 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd, * See ipath_mmap() for details. */ if (udata && udata->outlen >= sizeof(__u64)) { + struct ipath_mmap_info *ip; + __u64 offset = (__u64) srq->rq.wq; int err; - u32 s = sizeof(struct ipath_rwq) + srq->rq.size * sz; - srq->ip = - ipath_create_mmap_info(dev, s, - ibpd->uobject->context, - srq->rq.wq); - if (!srq->ip) { - ret = ERR_PTR(-ENOMEM); + err = ib_copy_to_udata(udata, &offset, sizeof(offset)); + if (err) { + ret = ERR_PTR(err); goto bail_wq; } - err = ib_copy_to_udata(udata, &srq->ip->offset, - sizeof(srq->ip->offset)); - if (err) { - ret = ERR_PTR(err); - goto bail_ip; + /* Allocate info for ipath_mmap(). */ + ip = kmalloc(sizeof(*ip), GFP_KERNEL); + if (!ip) { + ret = ERR_PTR(-ENOMEM); + goto bail_wq; } + srq->ip = ip; + ip->context = ibpd->uobject->context; + ip->obj = srq->rq.wq; + kref_init(&ip->ref); + ip->mmap_cnt = 0; + ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) + + srq->rq.size * sz); + spin_lock_irq(&dev->pending_lock); + ip->next = dev->pending_mmaps; + dev->pending_mmaps = ip; + spin_unlock_irq(&dev->pending_lock); } else srq->ip = NULL; @@ -172,27 +181,21 @@ struct ib_srq *ipath_create_srq(struct ib_pd *ibpd, if (dev->n_srqs_allocated == ib_ipath_max_srqs) { spin_unlock(&dev->n_srqs_lock); ret = ERR_PTR(-ENOMEM); - goto bail_ip; + goto bail_wq; } dev->n_srqs_allocated++; spin_unlock(&dev->n_srqs_lock); - if (srq->ip) { - spin_lock_irq(&dev->pending_lock); - list_add(&srq->ip->pending_mmaps, &dev->pending_mmaps); - spin_unlock_irq(&dev->pending_lock); - } - ret = &srq->ibsrq; goto done; -bail_ip: - kfree(srq->ip); bail_wq: vfree(srq->rq.wq); + bail_srq: kfree(srq); + done: return ret; } @@ -309,13 +312,13 @@ int ipath_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, if (srq->ip) { struct ipath_mmap_info *ip = srq->ip; struct ipath_ibdev *dev = to_idev(srq->ibsrq.device); - u32 s = sizeof(struct ipath_rwq) + size * sz; - ipath_update_mmap_info(dev, ip, s, wq); + ip->obj = wq; + ip->size = PAGE_ALIGN(sizeof(struct ipath_rwq) + + size * sz); spin_lock_irq(&dev->pending_lock); - if (list_empty(&ip->pending_mmaps)) - list_add(&ip->pending_mmaps, - &dev->pending_mmaps); + ip->next = dev->pending_mmaps; + dev->pending_mmaps = ip; spin_unlock_irq(&dev->pending_lock); } } else if (attr_mask & IB_SRQ_LIMIT) { diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_stats.c b/trunk/drivers/infiniband/hw/ipath/ipath_stats.c index d8b5e4cefe25..9307f7187ca5 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_stats.c @@ -31,6 +31,8 @@ * SOFTWARE. */ +#include + #include "ipath_kernel.h" struct infinipath_stats ipath_stats; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_sysfs.c b/trunk/drivers/infiniband/hw/ipath/ipath_sysfs.c index 4dc398d5e011..ffa6318ad0cc 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_sysfs.c @@ -32,6 +32,7 @@ */ #include +#include #include "ipath_kernel.h" #include "ipath_common.h" diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c index 12933e77c7e9..18c6df2052c2 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -1476,10 +1476,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd) ret = -ENOMEM; goto err_lk; } - INIT_LIST_HEAD(&idev->pending_mmaps); spin_lock_init(&idev->pending_lock); - idev->mmap_offset = PAGE_SIZE; - spin_lock_init(&idev->mmap_offset_lock); INIT_LIST_HEAD(&idev->pending[0]); INIT_LIST_HEAD(&idev->pending[1]); INIT_LIST_HEAD(&idev->pending[2]); @@ -1561,7 +1558,6 @@ int ipath_register_ib_device(struct ipath_devdata *dd) (1ull << IB_USER_VERBS_CMD_POST_SRQ_RECV); dev->node_type = RDMA_NODE_IB_CA; dev->phys_port_cnt = 1; - dev->num_comp_vectors = 1; dev->dma_device = &dd->pcidev->dev; dev->query_device = ipath_query_device; dev->modify_device = ipath_modify_device; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.h b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.h index 7064fc222727..7c4929f1cb5b 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.h @@ -173,12 +173,12 @@ struct ipath_ah { * this as its vm_private_data. */ struct ipath_mmap_info { - struct list_head pending_mmaps; + struct ipath_mmap_info *next; struct ib_ucontext *context; void *obj; - __u64 offset; struct kref ref; unsigned size; + unsigned mmap_cnt; }; /* @@ -422,7 +422,7 @@ struct ipath_qp { #define IPATH_S_RDMAR_PENDING 0x04 #define IPATH_S_ACK_PENDING 0x08 -#define IPATH_PSN_CREDIT 512 +#define IPATH_PSN_CREDIT 2048 /* * Since struct ipath_swqe is not a fixed size, we can't simply index into @@ -485,10 +485,9 @@ struct ipath_opcode_stats { struct ipath_ibdev { struct ib_device ibdev; + struct list_head dev_list; struct ipath_devdata *dd; - struct list_head pending_mmaps; - spinlock_t mmap_offset_lock; - u32 mmap_offset; + struct ipath_mmap_info *pending_mmaps; int ib_unit; /* This is the device number */ u16 sm_lid; /* in host order */ u8 sm_sl; @@ -735,13 +734,13 @@ int ipath_destroy_srq(struct ib_srq *ibsrq); int ipath_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); -struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, int comp_vector, +struct ib_cq *ipath_create_cq(struct ib_device *ibdev, int entries, struct ib_ucontext *context, struct ib_udata *udata); int ipath_destroy_cq(struct ib_cq *ibcq); -int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags notify_flags); +int ipath_req_notify_cq(struct ib_cq *ibcq, enum ib_cq_notify notify); int ipath_resize_cq(struct ib_cq *ibcq, int cqe, struct ib_udata *udata); @@ -769,15 +768,6 @@ int ipath_dealloc_fmr(struct ib_fmr *ibfmr); void ipath_release_mmap_info(struct kref *ref); -struct ipath_mmap_info *ipath_create_mmap_info(struct ipath_ibdev *dev, - u32 size, - struct ib_ucontext *context, - void *obj); - -void ipath_update_mmap_info(struct ipath_ibdev *dev, - struct ipath_mmap_info *ip, - u32 size, void *obj); - int ipath_mmap(struct ib_ucontext *context, struct vm_area_struct *vma); void ipath_no_bufs_available(struct ipath_qp *qp, struct ipath_ibdev *dev); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index cf0868f6e965..efd79ef109a6 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -726,12 +726,11 @@ int mthca_poll_cq(struct ib_cq *ibcq, int num_entries, return err == 0 || err == -EAGAIN ? npolled : err; } -int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags) +int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify) { __be32 doorbell[2]; - doorbell[0] = cpu_to_be32(((flags & IB_CQ_SOLICITED_MASK) == - IB_CQ_SOLICITED ? + doorbell[0] = cpu_to_be32((notify == IB_CQ_SOLICITED ? MTHCA_TAVOR_CQ_DB_REQ_NOT_SOL : MTHCA_TAVOR_CQ_DB_REQ_NOT) | to_mcq(cq)->cqn); @@ -744,7 +743,7 @@ int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags) return 0; } -int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) +int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify notify) { struct mthca_cq *cq = to_mcq(ibcq); __be32 doorbell[2]; @@ -756,8 +755,7 @@ int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) doorbell[0] = ci; doorbell[1] = cpu_to_be32((cq->cqn << 8) | (2 << 5) | (sn << 3) | - ((flags & IB_CQ_SOLICITED_MASK) == - IB_CQ_SOLICITED ? 1 : 2)); + (notify == IB_CQ_SOLICITED ? 1 : 2)); mthca_write_db_rec(doorbell, cq->arm_db); @@ -768,7 +766,7 @@ int mthca_arbel_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags flags) wmb(); doorbell[0] = cpu_to_be32((sn << 28) | - ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED ? + (notify == IB_CQ_SOLICITED ? MTHCA_ARBEL_CQ_DB_REQ_NOT_SOL : MTHCA_ARBEL_CQ_DB_REQ_NOT) | cq->cqn); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h index 9bae3cc60603..b7e42efaf43d 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h @@ -495,8 +495,8 @@ void mthca_unmap_eq_icm(struct mthca_dev *dev); int mthca_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); -int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags); -int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify_flags flags); +int mthca_tavor_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify); +int mthca_arbel_arm_cq(struct ib_cq *cq, enum ib_cq_notify notify); int mthca_init_cq(struct mthca_dev *dev, int nent, struct mthca_ucontext *ctx, u32 pdn, struct mthca_cq *cq); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.h b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.h index a1ab06847b75..594144145f45 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.h +++ b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.h @@ -38,6 +38,7 @@ #define MTHCA_MEMFREE_H #include +#include #include #define MTHCA_ICM_CHUNK_LEN \ diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c index 1c05486c3c68..47e6fd46d9c2 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_provider.c @@ -663,7 +663,6 @@ static int mthca_destroy_qp(struct ib_qp *qp) } static struct ib_cq *mthca_create_cq(struct ib_device *ibdev, int entries, - int comp_vector, struct ib_ucontext *context, struct ib_udata *udata) { @@ -1293,7 +1292,6 @@ int mthca_register_device(struct mthca_dev *dev) (1ull << IB_USER_VERBS_CMD_DETACH_MCAST); dev->ib_dev.node_type = RDMA_NODE_IB_CA; dev->ib_dev.phys_port_cnt = dev->limits.num_ports; - dev->ib_dev.num_comp_vectors = 1; dev->ib_dev.dma_device = &dev->pdev->dev; dev->ib_dev.query_device = mthca_query_device; dev->ib_dev.query_port = mthca_query_port; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index fee60c852d14..8fe6fee7a97a 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c @@ -701,19 +701,6 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); } - if (ibqp->qp_type == IB_QPT_RC && - cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) { - u8 sched_queue = ibqp->uobject ? 0x2 : 0x1; - - if (mthca_is_memfree(dev)) - qp_context->rlkey_arbel_sched_queue |= sched_queue; - else - qp_context->tavor_sched_queue |= cpu_to_be32(sched_queue); - - qp_param->opt_param_mask |= - cpu_to_be32(MTHCA_QP_OPTPAR_SCHED_QUEUE); - } - if (attr_mask & IB_QP_TIMEOUT) { qp_context->pri_path.ackto = attr->timeout << 3; qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h index 87310eeb6df0..fd558267d1cb 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -310,7 +311,6 @@ extern struct workqueue_struct *ipoib_workqueue; /* functions */ -int ipoib_poll(struct net_device *dev, int *budget); void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr); struct ipoib_ah *ipoib_create_ah(struct net_device *dev, diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 785bc8505f2a..0c4e59b906cd 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -370,7 +370,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) if (!likely(wr_id & IPOIB_CM_RX_UPDATE_MASK)) { p = wc->qp->qp_context; - if (p && time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) { + if (time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_UPDATE_TIME)) { spin_lock_irqsave(&priv->lock, flags); p->jiffies = jiffies; /* Move this entry to list head, but do @@ -416,7 +416,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) skb->dev = dev; /* XXX get correct PACKET_ type here */ skb->pkt_type = PACKET_HOST; - netif_receive_skb(skb); + netif_rx_ni(skb); repost: if (unlikely(ipoib_cm_post_receive(dev, wr_id))) @@ -592,9 +592,7 @@ int ipoib_cm_dev_open(struct net_device *dev) priv->cm.id = ib_create_cm_id(priv->ca, ipoib_cm_rx_handler, dev); if (IS_ERR(priv->cm.id)) { printk(KERN_WARNING "%s: failed to create CM ID\n", priv->ca->name); - ret = PTR_ERR(priv->cm.id); - priv->cm.id = NULL; - return ret; + return IS_ERR(priv->cm.id); } ret = ib_cm_listen(priv->cm.id, cpu_to_be64(IPOIB_CM_IETF_ID | priv->qp->qp_num), @@ -603,7 +601,6 @@ int ipoib_cm_dev_open(struct net_device *dev) printk(KERN_WARNING "%s: failed to listen on ID 0x%llx\n", priv->ca->name, IPOIB_CM_IETF_ID | priv->qp->qp_num); ib_destroy_cm_id(priv->cm.id); - priv->cm.id = NULL; return ret; } return 0; @@ -614,11 +611,10 @@ void ipoib_cm_dev_stop(struct net_device *dev) struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_cm_rx *p; - if (!IPOIB_CM_SUPPORTED(dev->dev_addr) || !priv->cm.id) + if (!IPOIB_CM_SUPPORTED(dev->dev_addr)) return; ib_destroy_cm_id(priv->cm.id); - priv->cm.id = NULL; spin_lock_irq(&priv->lock); while (!list_empty(&priv->cm.passive_ids)) { p = list_entry(priv->cm.passive_ids.next, typeof(*p), list); @@ -793,7 +789,7 @@ static int ipoib_cm_tx_init(struct ipoib_cm_tx *p, u32 qpn, } p->cq = ib_create_cq(priv->ca, ipoib_cm_tx_completion, NULL, p, - ipoib_sendq_size + 1, 0); + ipoib_sendq_size + 1); if (IS_ERR(p->cq)) { ret = PTR_ERR(p->cq); ipoib_warn(priv, "failed to allocate tx cq: %d\n", ret); diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 68d72c6f7ffb..1bdb9101911a 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -226,7 +226,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc) skb->dev = dev; /* XXX get correct PACKET_ type here */ skb->pkt_type = PACKET_HOST; - netif_receive_skb(skb); + netif_rx_ni(skb); } else { ipoib_dbg_data(priv, "dropping loopback packet\n"); dev_kfree_skb_any(skb); @@ -280,63 +280,28 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) wc->status, wr_id, wc->vendor_err); } -int ipoib_poll(struct net_device *dev, int *budget) +static void ipoib_ib_handle_wc(struct net_device *dev, struct ib_wc *wc) { - struct ipoib_dev_priv *priv = netdev_priv(dev); - int max = min(*budget, dev->quota); - int done; - int t; - int empty; - int n, i; - - done = 0; - empty = 0; - - while (max) { - t = min(IPOIB_NUM_WC, max); - n = ib_poll_cq(priv->cq, t, priv->ibwc); - - for (i = 0; i < n; ++i) { - struct ib_wc *wc = priv->ibwc + i; - - if (wc->wr_id & IPOIB_CM_OP_SRQ) { - ++done; - --max; - ipoib_cm_handle_rx_wc(dev, wc); - } else if (wc->wr_id & IPOIB_OP_RECV) { - ++done; - --max; - ipoib_ib_handle_rx_wc(dev, wc); - } else - ipoib_ib_handle_tx_wc(dev, wc); - } - - if (n != t) { - empty = 1; - break; - } - } - - dev->quota -= done; - *budget -= done; - - if (empty) { - netif_rx_complete(dev); - if (unlikely(ib_req_notify_cq(priv->cq, - IB_CQ_NEXT_COMP | - IB_CQ_REPORT_MISSED_EVENTS)) && - netif_rx_reschedule(dev, 0)) - return 1; - - return 0; - } - - return 1; + if (wc->wr_id & IPOIB_CM_OP_SRQ) + ipoib_cm_handle_rx_wc(dev, wc); + else if (wc->wr_id & IPOIB_OP_RECV) + ipoib_ib_handle_rx_wc(dev, wc); + else + ipoib_ib_handle_tx_wc(dev, wc); } void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr) { - netif_rx_schedule(dev_ptr); + struct net_device *dev = (struct net_device *) dev_ptr; + struct ipoib_dev_priv *priv = netdev_priv(dev); + int n, i; + + ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); + do { + n = ib_poll_cq(cq, IPOIB_NUM_WC, priv->ibwc); + for (i = 0; i < n; ++i) + ipoib_ib_handle_wc(dev, priv->ibwc + i); + } while (n == IPOIB_NUM_WC); } static inline int post_send(struct ipoib_dev_priv *priv, @@ -549,10 +514,9 @@ int ipoib_ib_dev_stop(struct net_device *dev) struct ib_qp_attr qp_attr; unsigned long begin; struct ipoib_tx_buf *tx_req; - int i, n; + int i; clear_bit(IPOIB_FLAG_INITIALIZED, &priv->flags); - netif_poll_disable(dev); ipoib_cm_dev_stop(dev); @@ -604,18 +568,6 @@ int ipoib_ib_dev_stop(struct net_device *dev) goto timeout; } - do { - n = ib_poll_cq(priv->cq, IPOIB_NUM_WC, priv->ibwc); - for (i = 0; i < n; ++i) { - if (priv->ibwc[i].wr_id & IPOIB_CM_OP_SRQ) - ipoib_cm_handle_rx_wc(dev, priv->ibwc + i); - else if (priv->ibwc[i].wr_id & IPOIB_OP_RECV) - ipoib_ib_handle_rx_wc(dev, priv->ibwc + i); - else - ipoib_ib_handle_tx_wc(dev, priv->ibwc + i); - } - } while (n == IPOIB_NUM_WC); - msleep(1); } @@ -644,9 +596,6 @@ int ipoib_ib_dev_stop(struct net_device *dev) msleep(1); } - netif_poll_enable(dev); - ib_req_notify_cq(priv->cq, IB_CQ_NEXT_COMP); - return 0; } diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c index 0a428f2b05c7..b4c380c5a3ba 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -948,8 +948,6 @@ static void ipoib_setup(struct net_device *dev) dev->hard_header = ipoib_hard_header; dev->set_multicast_list = ipoib_set_mcast_list; dev->neigh_setup = ipoib_neigh_setup_dev; - dev->poll = ipoib_poll; - dev->weight = 100; dev->watchdog_timeo = HZ; diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 5c3c6a43a52b..7f3ec205e35f 100644 --- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -187,7 +187,7 @@ int ipoib_transport_dev_init(struct net_device *dev, struct ib_device *ca) if (!ret) size += ipoib_recvq_size; - priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size, 0); + priv->cq = ib_create_cq(priv->ca, ipoib_ib_completion, NULL, dev, size); if (IS_ERR(priv->cq)) { printk(KERN_WARNING "%s: failed to create CQ\n", ca->name); goto out_free_mr; diff --git a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c index 3651072f6c1f..278fcbccc2d9 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_initiator.c @@ -201,7 +201,7 @@ static int iser_post_receive_control(struct iscsi_conn *conn) * what's common for both schemes is that the connection is not started */ if (conn->c_stage != ISCSI_CONN_STARTED) - rx_data_size = ISCSI_DEF_MAX_RECV_SEG_LEN; + rx_data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; else /* FIXME till user space sets conn->max_recv_dlength correctly */ rx_data_size = 128; diff --git a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c index 3702e2375553..1fc967464a28 100644 --- a/trunk/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/trunk/drivers/infiniband/ulp/iser/iser_verbs.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -75,7 +76,7 @@ static int iser_create_device_ib_res(struct iser_device *device) iser_cq_callback, iser_cq_event_callback, (void *)device, - ISER_MAX_CQ_LEN, 0); + ISER_MAX_CQ_LEN); if (IS_ERR(device->cq)) goto cq_err; diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c index 39bf057fbc43..5e8ac577f0ad 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c @@ -197,7 +197,7 @@ static int srp_create_target_ib(struct srp_target_port *target) return -ENOMEM; target->cq = ib_create_cq(target->srp_host->dev->dev, srp_completion, - NULL, target, SRP_CQ_SIZE, 0); + NULL, target, SRP_CQ_SIZE); if (IS_ERR(target->cq)) { ret = PTR_ERR(target->cq); goto out; @@ -1468,25 +1468,6 @@ static ssize_t show_dgid(struct class_device *cdev, char *buf) be16_to_cpu(((__be16 *) target->path.dgid.raw)[7])); } -static ssize_t show_orig_dgid(struct class_device *cdev, char *buf) -{ - struct srp_target_port *target = host_to_target(class_to_shost(cdev)); - - if (target->state == SRP_TARGET_DEAD || - target->state == SRP_TARGET_REMOVED) - return -ENODEV; - - return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", - be16_to_cpu(target->orig_dgid[0]), - be16_to_cpu(target->orig_dgid[1]), - be16_to_cpu(target->orig_dgid[2]), - be16_to_cpu(target->orig_dgid[3]), - be16_to_cpu(target->orig_dgid[4]), - be16_to_cpu(target->orig_dgid[5]), - be16_to_cpu(target->orig_dgid[6]), - be16_to_cpu(target->orig_dgid[7])); -} - static ssize_t show_zero_req_lim(struct class_device *cdev, char *buf) { struct srp_target_port *target = host_to_target(class_to_shost(cdev)); @@ -1517,7 +1498,6 @@ static CLASS_DEVICE_ATTR(ioc_guid, S_IRUGO, show_ioc_guid, NULL); static CLASS_DEVICE_ATTR(service_id, S_IRUGO, show_service_id, NULL); static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL); static CLASS_DEVICE_ATTR(dgid, S_IRUGO, show_dgid, NULL); -static CLASS_DEVICE_ATTR(orig_dgid, S_IRUGO, show_orig_dgid, NULL); static CLASS_DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); static CLASS_DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); static CLASS_DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); @@ -1528,7 +1508,6 @@ static struct class_device_attribute *srp_host_attrs[] = { &class_device_attr_service_id, &class_device_attr_pkey, &class_device_attr_dgid, - &class_device_attr_orig_dgid, &class_device_attr_zero_req_lim, &class_device_attr_local_ib_port, &class_device_attr_local_ib_device, @@ -1537,8 +1516,7 @@ static struct class_device_attribute *srp_host_attrs[] = { static struct scsi_host_template srp_template = { .module = THIS_MODULE, - .name = "InfiniBand SRP initiator", - .proc_name = DRV_NAME, + .name = DRV_NAME, .info = srp_target_info, .queuecommand = srp_queuecommand, .eh_abort_handler = srp_abort, @@ -1684,7 +1662,6 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) target->path.dgid.raw[i] = simple_strtoul(dgid, NULL, 16); } kfree(p); - memcpy(target->orig_dgid, target->path.dgid.raw, 16); break; case SRP_OPT_PKEY: diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.h b/trunk/drivers/infiniband/ulp/srp/ib_srp.h index 1d53c7bc368f..2f3319c719a5 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.h +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.h @@ -129,7 +129,6 @@ struct srp_target_port { unsigned int scsi_id; struct ib_sa_path_rec path; - __be16 orig_dgid[8]; struct ib_sa_query *path_query; int path_query_id; diff --git a/trunk/drivers/input/Kconfig b/trunk/drivers/input/Kconfig index 0e9b69535ad6..96232313b1b9 100644 --- a/trunk/drivers/input/Kconfig +++ b/trunk/drivers/input/Kconfig @@ -153,8 +153,6 @@ source "drivers/input/mouse/Kconfig" source "drivers/input/joystick/Kconfig" -source "drivers/input/tablet/Kconfig" - source "drivers/input/touchscreen/Kconfig" source "drivers/input/misc/Kconfig" diff --git a/trunk/drivers/input/Makefile b/trunk/drivers/input/Makefile index 8a2dd987546c..da575deb3c7a 100644 --- a/trunk/drivers/input/Makefile +++ b/trunk/drivers/input/Makefile @@ -13,12 +13,12 @@ obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o obj-$(CONFIG_INPUT_JOYDEV) += joydev.o obj-$(CONFIG_INPUT_EVDEV) += evdev.o obj-$(CONFIG_INPUT_TSDEV) += tsdev.o +obj-$(CONFIG_INPUT_POWER) += power.o obj-$(CONFIG_INPUT_EVBUG) += evbug.o obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/ obj-$(CONFIG_INPUT_MOUSE) += mouse/ obj-$(CONFIG_INPUT_JOYSTICK) += joystick/ -obj-$(CONFIG_INPUT_TABLET) += tablet/ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ diff --git a/trunk/drivers/input/evbug.c b/trunk/drivers/input/evbug.c index c21f2f127234..5a9653c3128a 100644 --- a/trunk/drivers/input/evbug.c +++ b/trunk/drivers/input/evbug.c @@ -38,43 +38,31 @@ MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Input driver event debug module"); MODULE_LICENSE("GPL"); +static char evbug_name[] = "evbug"; + static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", handle->dev->phys, type, code, value); } -static int evbug_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct input_handle *handle; - int error; - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; + if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) + return NULL; handle->dev = dev; handle->handler = handler; - handle->name = "evbug"; - - error = input_register_handle(handle); - if (error) - goto err_free_handle; + handle->name = evbug_name; - error = input_open_device(handle); - if (error) - goto err_unregister_handle; + input_open_device(handle); printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys); - return 0; - - err_unregister_handle: - input_unregister_handle(handle); - err_free_handle: - kfree(handle); - return error; + return handle; } static void evbug_disconnect(struct input_handle *handle) @@ -82,7 +70,7 @@ static void evbug_disconnect(struct input_handle *handle) printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys); input_close_device(handle); - input_unregister_handle(handle); + kfree(handle); } diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index 55a72592704c..6439f378f6cc 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -28,11 +29,11 @@ struct evdev { char name[16]; struct input_handle handle; wait_queue_head_t wait; - struct evdev_client *grab; - struct list_head client_list; + struct evdev_list *grab; + struct list_head list; }; -struct evdev_client { +struct evdev_list { struct input_event buffer[EVDEV_BUFFER_SIZE]; int head; int tail; @@ -46,28 +47,28 @@ static struct evdev *evdev_table[EVDEV_MINORS]; static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct evdev *evdev = handle->private; - struct evdev_client *client; + struct evdev_list *list; if (evdev->grab) { - client = evdev->grab; + list = evdev->grab; - do_gettimeofday(&client->buffer[client->head].time); - client->buffer[client->head].type = type; - client->buffer[client->head].code = code; - client->buffer[client->head].value = value; - client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1); + do_gettimeofday(&list->buffer[list->head].time); + list->buffer[list->head].type = type; + list->buffer[list->head].code = code; + list->buffer[list->head].value = value; + list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); - kill_fasync(&client->fasync, SIGIO, POLL_IN); + kill_fasync(&list->fasync, SIGIO, POLL_IN); } else - list_for_each_entry(client, &evdev->client_list, node) { + list_for_each_entry(list, &evdev->list, node) { - do_gettimeofday(&client->buffer[client->head].time); - client->buffer[client->head].type = type; - client->buffer[client->head].code = code; - client->buffer[client->head].value = value; - client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1); + do_gettimeofday(&list->buffer[list->head].time); + list->buffer[list->head].type = type; + list->buffer[list->head].code = code; + list->buffer[list->head].value = value; + list->head = (list->head + 1) & (EVDEV_BUFFER_SIZE - 1); - kill_fasync(&client->fasync, SIGIO, POLL_IN); + kill_fasync(&list->fasync, SIGIO, POLL_IN); } wake_up_interruptible(&evdev->wait); @@ -75,23 +76,22 @@ static void evdev_event(struct input_handle *handle, unsigned int type, unsigned static int evdev_fasync(int fd, struct file *file, int on) { - struct evdev_client *client = file->private_data; int retval; + struct evdev_list *list = file->private_data; - retval = fasync_helper(fd, file, on, &client->fasync); + retval = fasync_helper(fd, file, on, &list->fasync); return retval < 0 ? retval : 0; } static int evdev_flush(struct file *file, fl_owner_t id) { - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; + struct evdev_list *list = file->private_data; - if (!evdev->exist) + if (!list->evdev->exist) return -ENODEV; - return input_flush_device(&evdev->handle, file); + return input_flush_device(&list->evdev->handle, file); } static void evdev_free(struct evdev *evdev) @@ -100,62 +100,48 @@ static void evdev_free(struct evdev *evdev) kfree(evdev); } -static int evdev_release(struct inode *inode, struct file *file) +static int evdev_release(struct inode * inode, struct file * file) { - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; + struct evdev_list *list = file->private_data; - if (evdev->grab == client) { - input_release_device(&evdev->handle); - evdev->grab = NULL; + if (list->evdev->grab == list) { + input_release_device(&list->evdev->handle); + list->evdev->grab = NULL; } evdev_fasync(-1, file, 0); - list_del(&client->node); - kfree(client); + list_del(&list->node); - if (!--evdev->open) { - if (evdev->exist) - input_close_device(&evdev->handle); + if (!--list->evdev->open) { + if (list->evdev->exist) + input_close_device(&list->evdev->handle); else - evdev_free(evdev); + evdev_free(list->evdev); } + kfree(list); return 0; } -static int evdev_open(struct inode *inode, struct file *file) +static int evdev_open(struct inode * inode, struct file * file) { - struct evdev_client *client; - struct evdev *evdev; + struct evdev_list *list; int i = iminor(inode) - EVDEV_MINOR_BASE; - int error; - if (i >= EVDEV_MINORS) + if (i >= EVDEV_MINORS || !evdev_table[i] || !evdev_table[i]->exist) return -ENODEV; - evdev = evdev_table[i]; - - if (!evdev || !evdev->exist) - return -ENODEV; - - client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); - if (!client) + if (!(list = kzalloc(sizeof(struct evdev_list), GFP_KERNEL))) return -ENOMEM; - client->evdev = evdev; - list_add_tail(&client->node, &evdev->client_list); + list->evdev = evdev_table[i]; + list_add_tail(&list->node, &evdev_table[i]->list); + file->private_data = list; - if (!evdev->open++ && evdev->exist) { - error = input_open_device(&evdev->handle); - if (error) { - list_del(&client->node); - kfree(client); - return error; - } - } + if (!list->evdev->open++) + if (list->evdev->exist) + input_open_device(&list->evdev->handle); - file->private_data = client; return 0; } @@ -257,55 +243,54 @@ static int evdev_event_to_user(char __user *buffer, const struct input_event *ev #endif /* CONFIG_COMPAT */ -static ssize_t evdev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) { - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; + struct evdev_list *list = file->private_data; struct input_event event; int retval = 0; - if (!evdev->exist) + if (!list->evdev->exist) return -ENODEV; while (retval < count) { if (evdev_event_from_user(buffer + retval, &event)) return -EFAULT; - input_inject_event(&evdev->handle, event.type, event.code, event.value); + input_inject_event(&list->evdev->handle, event.type, event.code, event.value); retval += evdev_event_size(); } return retval; } -static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) +static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) { - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; + struct evdev_list *list = file->private_data; int retval; if (count < evdev_event_size()) return -EINVAL; - if (client->head == client->tail && evdev->exist && (file->f_flags & O_NONBLOCK)) + if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(evdev->wait, - client->head != client->tail || !evdev->exist); + retval = wait_event_interruptible(list->evdev->wait, + list->head != list->tail || (!list->evdev->exist)); + if (retval) return retval; - if (!evdev->exist) + if (!list->evdev->exist) return -ENODEV; - while (client->head != client->tail && retval + evdev_event_size() <= count) { + while (list->head != list->tail && retval + evdev_event_size() <= count) { - struct input_event *event = (struct input_event *) client->buffer + client->tail; + struct input_event *event = (struct input_event *) list->buffer + list->tail; if (evdev_event_to_user(buffer + retval, event)) return -EFAULT; - client->tail = (client->tail + 1) & (EVDEV_BUFFER_SIZE - 1); + list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1); retval += evdev_event_size(); } @@ -315,12 +300,11 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, /* No kernel lock - fine */ static unsigned int evdev_poll(struct file *file, poll_table *wait) { - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; + struct evdev_list *list = file->private_data; - poll_wait(file, &evdev->wait, wait); - return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | - (evdev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &list->evdev->wait, wait); + return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | + (list->evdev->exist ? 0 : (POLLHUP | POLLERR)); } #ifdef CONFIG_COMPAT @@ -403,8 +387,8 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) static long evdev_ioctl_handler(struct file *file, unsigned int cmd, void __user *p, int compat_mode) { - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; + struct evdev_list *list = file->private_data; + struct evdev *evdev = list->evdev; struct input_dev *dev = evdev->handle.dev; struct input_absinfo abs; struct ff_effect effect; @@ -450,21 +434,32 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, case EVIOCGKEYCODE: if (get_user(t, ip)) return -EFAULT; - - error = dev->getkeycode(dev, t, &v); - if (error) - return error; - - if (put_user(v, ip + 1)) + if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) + return -EINVAL; + if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) return -EFAULT; - return 0; case EVIOCSKEYCODE: - if (get_user(t, ip) || get_user(v, ip + 1)) + if (get_user(t, ip)) return -EFAULT; + if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) + return -EINVAL; + if (get_user(v, ip + 1)) + return -EFAULT; + if (v < 0 || v > KEY_MAX) + return -EINVAL; + if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) + return -EINVAL; + + u = SET_INPUT_KEYCODE(dev, t, v); + clear_bit(u, dev->keybit); + set_bit(v, dev->keybit); + for (i = 0; i < dev->keycodemax; i++) + if (INPUT_KEYCODE(dev, i) == u) + set_bit(u, dev->keybit); - return dev->setkeycode(dev, t, v); + return 0; case EVIOCSFF: if (copy_from_user(&effect, p, sizeof(effect))) @@ -492,10 +487,10 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, return -EBUSY; if (input_grab_device(&evdev->handle)) return -EBUSY; - evdev->grab = client; + evdev->grab = list; return 0; } else { - if (evdev->grab != client) + if (evdev->grab != list) return -EINVAL; input_release_device(&evdev->handle); evdev->grab = NULL; @@ -511,7 +506,7 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) { - unsigned long *bits; + long *bits; int len; switch (_IOC_NR(cmd) & EV_MAX) { @@ -556,7 +551,7 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) { - t = _IOC_NR(cmd) & ABS_MAX; + int t = _IOC_NR(cmd) & ABS_MAX; abs.value = dev->abs[t]; abs.minimum = dev->absmin[t]; @@ -576,7 +571,7 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) { - t = _IOC_NR(cmd) & ABS_MAX; + int t = _IOC_NR(cmd) & ABS_MAX; if (copy_from_user(&abs, p, sizeof(struct input_absinfo))) return -EFAULT; @@ -621,26 +616,23 @@ static const struct file_operations evdev_fops = { .flush = evdev_flush }; -static int evdev_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct evdev *evdev; struct class_device *cdev; - dev_t devt; int minor; - int error; for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); if (minor == EVDEV_MINORS) { printk(KERN_ERR "evdev: no more free evdev devices\n"); - return -ENFILE; + return NULL; } - evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); - if (!evdev) - return -ENOMEM; + if (!(evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL))) + return NULL; - INIT_LIST_HEAD(&evdev->client_list); + INIT_LIST_HEAD(&evdev->list); init_waitqueue_head(&evdev->wait); evdev->exist = 1; @@ -653,45 +645,23 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, evdev_table[minor] = evdev; - devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), - - cdev = class_device_create(&input_class, &dev->cdev, devt, - dev->cdev.dev, evdev->name); - if (IS_ERR(cdev)) { - error = PTR_ERR(cdev); - goto err_free_evdev; - } + cdev = class_device_create(&input_class, &dev->cdev, + MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), + dev->cdev.dev, evdev->name); /* temporary symlink to keep userspace happy */ - error = sysfs_create_link(&input_class.subsys.kobj, - &cdev->kobj, evdev->name); - if (error) - goto err_cdev_destroy; - - error = input_register_handle(&evdev->handle); - if (error) - goto err_remove_link; + sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + evdev->name); - return 0; - - err_remove_link: - sysfs_remove_link(&input_class.subsys.kobj, evdev->name); - err_cdev_destroy: - class_device_destroy(&input_class, devt); - err_free_evdev: - kfree(evdev); - evdev_table[minor] = NULL; - return error; + return &evdev->handle; } static void evdev_disconnect(struct input_handle *handle) { struct evdev *evdev = handle->private; - struct evdev_client *client; - - input_unregister_handle(handle); + struct evdev_list *list; - sysfs_remove_link(&input_class.subsys.kobj, evdev->name); + sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); evdev->exist = 0; @@ -700,8 +670,8 @@ static void evdev_disconnect(struct input_handle *handle) input_flush_device(handle, NULL); input_close_device(handle); wake_up_interruptible(&evdev->wait); - list_for_each_entry(client, &evdev->client_list, node) - kill_fasync(&client->fasync, SIGIO, POLL_HUP); + list_for_each_entry(list, &evdev->list, node) + kill_fasync(&list->fasync, SIGIO, POLL_HUP); } else evdev_free(evdev); } diff --git a/trunk/drivers/input/ff-core.c b/trunk/drivers/input/ff-core.c index eebc72465fc9..783b3412cead 100644 --- a/trunk/drivers/input/ff-core.c +++ b/trunk/drivers/input/ff-core.c @@ -281,8 +281,7 @@ int input_ff_event(struct input_dev *dev, unsigned int type, break; default: - if (check_effect_access(ff, code, NULL) == 0) - ff->playback(dev, code, value); + ff->playback(dev, code, value); break; } diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index ccd8abafcb70..a9a706f8fff9 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -298,87 +299,12 @@ void input_close_device(struct input_handle *handle) } EXPORT_SYMBOL(input_close_device); -static int input_fetch_keycode(struct input_dev *dev, int scancode) +static void input_link_handle(struct input_handle *handle) { - switch (dev->keycodesize) { - case 1: - return ((u8 *)dev->keycode)[scancode]; - - case 2: - return ((u16 *)dev->keycode)[scancode]; - - default: - return ((u32 *)dev->keycode)[scancode]; - } -} - -static int input_default_getkeycode(struct input_dev *dev, - int scancode, int *keycode) -{ - if (!dev->keycodesize) - return -EINVAL; - - if (scancode < 0 || scancode >= dev->keycodemax) - return -EINVAL; - - *keycode = input_fetch_keycode(dev, scancode); - - return 0; -} - -static int input_default_setkeycode(struct input_dev *dev, - int scancode, int keycode) -{ - int old_keycode; - int i; - - if (scancode < 0 || scancode >= dev->keycodemax) - return -EINVAL; - - if (keycode < 0 || keycode > KEY_MAX) - return -EINVAL; - - if (!dev->keycodesize) - return -EINVAL; - - if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8))) - return -EINVAL; - - switch (dev->keycodesize) { - case 1: { - u8 *k = (u8 *)dev->keycode; - old_keycode = k[scancode]; - k[scancode] = keycode; - break; - } - case 2: { - u16 *k = (u16 *)dev->keycode; - old_keycode = k[scancode]; - k[scancode] = keycode; - break; - } - default: { - u32 *k = (u32 *)dev->keycode; - old_keycode = k[scancode]; - k[scancode] = keycode; - break; - } - } - - clear_bit(old_keycode, dev->keybit); - set_bit(keycode, dev->keybit); - - for (i = 0; i < dev->keycodemax; i++) { - if (input_fetch_keycode(dev, i) == old_keycode) { - set_bit(old_keycode, dev->keybit); - break; /* Setting the bit twice is useless, so break */ - } - } - - return 0; + list_add_tail(&handle->d_node, &handle->dev->h_list); + list_add_tail(&handle->h_node, &handle->handler->h_list); } - #define MATCH_BIT(bit, max) \ for (i = 0; i < NBITS(max); i++) \ if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ @@ -425,29 +351,6 @@ static const struct input_device_id *input_match_device(const struct input_devic return NULL; } -static int input_attach_handler(struct input_dev *dev, struct input_handler *handler) -{ - const struct input_device_id *id; - int error; - - if (handler->blacklist && input_match_device(handler->blacklist, dev)) - return -ENODEV; - - id = input_match_device(handler->id_table, dev); - if (!id) - return -ENODEV; - - error = handler->connect(handler, dev, id); - if (error && error != -ENODEV) - printk(KERN_ERR - "input: failed to attach handler %s to device %s, " - "error: %d\n", - handler->name, kobject_name(&dev->cdev.kobj), error); - - return error; -} - - #ifdef CONFIG_PROC_FS static struct proc_dir_entry *proc_bus_input_dir; @@ -536,7 +439,6 @@ static int input_devices_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : ""); seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : ""); seq_printf(seq, "S: Sysfs=%s\n", path ? path : ""); - seq_printf(seq, "U: Uniq=%s\n", dev->uniq ? dev->uniq : ""); seq_printf(seq, "H: Handlers="); list_for_each_entry(handle, &dev->h_list, d_node) @@ -851,13 +753,6 @@ static struct attribute_group input_dev_caps_attr_group = { .attrs = input_dev_caps_attrs, }; -static struct attribute_group *input_dev_attr_groups[] = { - &input_dev_attr_group, - &input_dev_id_attr_group, - &input_dev_caps_attr_group, - NULL -}; - static void input_dev_release(struct class_device *class_dev) { struct input_dev *dev = to_input_dev(class_dev); @@ -1011,7 +906,6 @@ struct input_dev *input_allocate_device(void) dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); if (dev) { dev->cdev.class = &input_class; - dev->cdev.groups = input_dev_attr_groups; class_device_initialize(&dev->cdev); mutex_init(&dev->mutex); INIT_LIST_HEAD(&dev->h_list); @@ -1040,71 +934,23 @@ EXPORT_SYMBOL(input_allocate_device); */ void input_free_device(struct input_dev *dev) { - if (dev) - input_put_device(dev); -} -EXPORT_SYMBOL(input_free_device); + if (dev) { -/** - * input_set_capability - mark device as capable of a certain event - * @dev: device that is capable of emitting or accepting event - * @type: type of the event (EV_KEY, EV_REL, etc...) - * @code: event code - * - * In addition to setting up corresponding bit in appropriate capability - * bitmap the function also adjusts dev->evbit. - */ -void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) -{ - switch (type) { - case EV_KEY: - __set_bit(code, dev->keybit); - break; - - case EV_REL: - __set_bit(code, dev->relbit); - break; - - case EV_ABS: - __set_bit(code, dev->absbit); - break; - - case EV_MSC: - __set_bit(code, dev->mscbit); - break; - - case EV_SW: - __set_bit(code, dev->swbit); - break; - - case EV_LED: - __set_bit(code, dev->ledbit); - break; - - case EV_SND: - __set_bit(code, dev->sndbit); - break; - - case EV_FF: - __set_bit(code, dev->ffbit); - break; - - default: - printk(KERN_ERR - "input_set_capability: unknown type %u (code %u)\n", - type, code); - dump_stack(); - return; - } + mutex_lock(&dev->mutex); + dev->name = dev->phys = dev->uniq = NULL; + mutex_unlock(&dev->mutex); - __set_bit(type, dev->evbit); + input_put_device(dev); + } } -EXPORT_SYMBOL(input_set_capability); +EXPORT_SYMBOL(input_free_device); int input_register_device(struct input_dev *dev) { static atomic_t input_no = ATOMIC_INIT(0); + struct input_handle *handle; struct input_handler *handler; + const struct input_device_id *id; const char *path; int error; @@ -1123,41 +969,55 @@ int input_register_device(struct input_dev *dev) dev->rep[REP_PERIOD] = 33; } - if (!dev->getkeycode) - dev->getkeycode = input_default_getkeycode; - - if (!dev->setkeycode) - dev->setkeycode = input_default_setkeycode; - list_add_tail(&dev->node, &input_dev_list); snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id), "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1); - if (!dev->cdev.dev) - dev->cdev.dev = dev->dev.parent; - error = class_device_add(&dev->cdev); if (error) return error; + error = sysfs_create_group(&dev->cdev.kobj, &input_dev_attr_group); + if (error) + goto fail1; + + error = sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group); + if (error) + goto fail2; + + error = sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group); + if (error) + goto fail3; + path = kobject_get_path(&dev->cdev.kobj, GFP_KERNEL); printk(KERN_INFO "input: %s as %s\n", dev->name ? dev->name : "Unspecified device", path ? path : "N/A"); kfree(path); list_for_each_entry(handler, &input_handler_list, node) - input_attach_handler(dev, handler); + if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) + if ((id = input_match_device(handler->id_table, dev))) + if ((handle = handler->connect(handler, dev, id))) { + input_link_handle(handle); + if (handler->start) + handler->start(handle); + } input_wakeup_procfs_readers(); return 0; + + fail3: sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); + fail2: sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); + fail1: class_device_del(&dev->cdev); + return error; } EXPORT_SYMBOL(input_register_device); void input_unregister_device(struct input_dev *dev) { - struct input_handle *handle, *next; + struct list_head *node, *next; int code; for (code = 0; code <= KEY_MAX; code++) @@ -1167,12 +1027,19 @@ void input_unregister_device(struct input_dev *dev) del_timer_sync(&dev->timer); - list_for_each_entry_safe(handle, next, &dev->h_list, d_node) + list_for_each_safe(node, next, &dev->h_list) { + struct input_handle * handle = to_handle(node); + list_del_init(&handle->d_node); + list_del_init(&handle->h_node); handle->handler->disconnect(handle); - WARN_ON(!list_empty(&dev->h_list)); + } list_del_init(&dev->node); + sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); + sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); + sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); + class_device_unregister(&dev->cdev); input_wakeup_procfs_readers(); @@ -1182,6 +1049,8 @@ EXPORT_SYMBOL(input_unregister_device); int input_register_handler(struct input_handler *handler) { struct input_dev *dev; + struct input_handle *handle; + const struct input_device_id *id; INIT_LIST_HEAD(&handler->h_list); @@ -1195,7 +1064,13 @@ int input_register_handler(struct input_handler *handler) list_add_tail(&handler->node, &input_handler_list); list_for_each_entry(dev, &input_dev_list, node) - input_attach_handler(dev, handler); + if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) + if ((id = input_match_device(handler->id_table, dev))) + if ((handle = handler->connect(handler, dev, id))) { + input_link_handle(handle); + if (handler->start) + handler->start(handle); + } input_wakeup_procfs_readers(); return 0; @@ -1204,11 +1079,14 @@ EXPORT_SYMBOL(input_register_handler); void input_unregister_handler(struct input_handler *handler) { - struct input_handle *handle, *next; + struct list_head *node, *next; - list_for_each_entry_safe(handle, next, &handler->h_list, h_node) + list_for_each_safe(node, next, &handler->h_list) { + struct input_handle * handle = to_handle_h(node); + list_del_init(&handle->h_node); + list_del_init(&handle->d_node); handler->disconnect(handle); - WARN_ON(!list_empty(&handler->h_list)); + } list_del_init(&handler->node); @@ -1219,27 +1097,6 @@ void input_unregister_handler(struct input_handler *handler) } EXPORT_SYMBOL(input_unregister_handler); -int input_register_handle(struct input_handle *handle) -{ - struct input_handler *handler = handle->handler; - - list_add_tail(&handle->d_node, &handle->dev->h_list); - list_add_tail(&handle->h_node, &handler->h_list); - - if (handler->start) - handler->start(handle); - - return 0; -} -EXPORT_SYMBOL(input_register_handle); - -void input_unregister_handle(struct input_handle *handle) -{ - list_del_init(&handle->h_node); - list_del_init(&handle->d_node); -} -EXPORT_SYMBOL(input_unregister_handle); - static int input_open_file(struct inode *inode, struct file *file) { struct input_handler *handler = input_table[iminor(inode) >> 5]; diff --git a/trunk/drivers/input/joydev.c b/trunk/drivers/input/joydev.c index 06f0541b24da..9f3529ad3fda 100644 --- a/trunk/drivers/input/joydev.c +++ b/trunk/drivers/input/joydev.c @@ -24,6 +24,7 @@ #include #include #include +#include #include MODULE_AUTHOR("Vojtech Pavlik "); @@ -42,7 +43,7 @@ struct joydev { char name[16]; struct input_handle handle; wait_queue_head_t wait; - struct list_head client_list; + struct list_head list; struct js_corr corr[ABS_MAX + 1]; struct JS_DATA_SAVE_TYPE glue; int nabs; @@ -54,7 +55,7 @@ struct joydev { __s16 abs[ABS_MAX + 1]; }; -struct joydev_client { +struct joydev_list { struct js_event buffer[JOYDEV_BUFFER_SIZE]; int head; int tail; @@ -86,7 +87,7 @@ static int joydev_correct(int value, struct js_corr *corr) static void joydev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct joydev *joydev = handle->private; - struct joydev_client *client; + struct joydev_list *list; struct js_event event; switch (type) { @@ -114,15 +115,15 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne event.time = jiffies_to_msecs(jiffies); - list_for_each_entry(client, &joydev->client_list, node) { + list_for_each_entry(list, &joydev->list, node) { - memcpy(client->buffer + client->head, &event, sizeof(struct js_event)); + memcpy(list->buffer + list->head, &event, sizeof(struct js_event)); - if (client->startup == joydev->nabs + joydev->nkey) - if (client->tail == (client->head = (client->head + 1) & (JOYDEV_BUFFER_SIZE - 1))) - client->startup = 0; + if (list->startup == joydev->nabs + joydev->nkey) + if (list->tail == (list->head = (list->head + 1) & (JOYDEV_BUFFER_SIZE - 1))) + list->startup = 0; - kill_fasync(&client->fasync, SIGIO, POLL_IN); + kill_fasync(&list->fasync, SIGIO, POLL_IN); } wake_up_interruptible(&joydev->wait); @@ -131,9 +132,9 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne static int joydev_fasync(int fd, struct file *file, int on) { int retval; - struct joydev_client *client = file->private_data; + struct joydev_list *list = file->private_data; - retval = fasync_helper(fd, file, on, &client->fasync); + retval = fasync_helper(fd, file, on, &list->fasync); return retval < 0 ? retval : 0; } @@ -144,73 +145,60 @@ static void joydev_free(struct joydev *joydev) kfree(joydev); } -static int joydev_release(struct inode *inode, struct file *file) +static int joydev_release(struct inode * inode, struct file * file) { - struct joydev_client *client = file->private_data; - struct joydev *joydev = client->joydev; + struct joydev_list *list = file->private_data; joydev_fasync(-1, file, 0); - list_del(&client->node); - kfree(client); + list_del(&list->node); - if (!--joydev->open) { - if (joydev->exist) - input_close_device(&joydev->handle); + if (!--list->joydev->open) { + if (list->joydev->exist) + input_close_device(&list->joydev->handle); else - joydev_free(joydev); + joydev_free(list->joydev); } + kfree(list); return 0; } static int joydev_open(struct inode *inode, struct file *file) { - struct joydev_client *client; - struct joydev *joydev; + struct joydev_list *list; int i = iminor(inode) - JOYDEV_MINOR_BASE; - int error; - - if (i >= JOYDEV_MINORS) - return -ENODEV; - joydev = joydev_table[i]; - if (!joydev || !joydev->exist) + if (i >= JOYDEV_MINORS || !joydev_table[i]) return -ENODEV; - client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); - if (!client) + if (!(list = kzalloc(sizeof(struct joydev_list), GFP_KERNEL))) return -ENOMEM; - client->joydev = joydev; - list_add_tail(&client->node, &joydev->client_list); + list->joydev = joydev_table[i]; + list_add_tail(&list->node, &joydev_table[i]->list); + file->private_data = list; - if (!joydev->open++ && joydev->exist) { - error = input_open_device(&joydev->handle); - if (error) { - list_del(&client->node); - kfree(client); - return error; - } - } + if (!list->joydev->open++) + if (list->joydev->exist) + input_open_device(&list->joydev->handle); - file->private_data = client; return 0; } -static ssize_t joydev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +static ssize_t joydev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) { return -EINVAL; } static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct joydev_client *client = file->private_data; - struct joydev *joydev = client->joydev; + struct joydev_list *list = file->private_data; + struct joydev *joydev = list->joydev; struct input_dev *input = joydev->handle.dev; int retval = 0; - if (!joydev->exist) + if (!list->joydev->exist) return -ENODEV; if (count < sizeof(struct js_event)) @@ -229,55 +217,56 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE))) return -EFAULT; - client->startup = 0; - client->tail = client->head; + list->startup = 0; + list->tail = list->head; return sizeof(struct JS_DATA_TYPE); } - if (client->startup == joydev->nabs + joydev->nkey && - client->head == client->tail && (file->f_flags & O_NONBLOCK)) + if (list->startup == joydev->nabs + joydev->nkey && + list->head == list->tail && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(joydev->wait, - !joydev->exist || - client->startup < joydev->nabs + joydev->nkey || - client->head != client->tail); + retval = wait_event_interruptible(list->joydev->wait, + !list->joydev->exist || + list->startup < joydev->nabs + joydev->nkey || + list->head != list->tail); + if (retval) return retval; - if (!joydev->exist) + if (!list->joydev->exist) return -ENODEV; - while (client->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) { + while (list->startup < joydev->nabs + joydev->nkey && retval + sizeof(struct js_event) <= count) { struct js_event event; event.time = jiffies_to_msecs(jiffies); - if (client->startup < joydev->nkey) { + if (list->startup < joydev->nkey) { event.type = JS_EVENT_BUTTON | JS_EVENT_INIT; - event.number = client->startup; + event.number = list->startup; event.value = !!test_bit(joydev->keypam[event.number], input->key); } else { event.type = JS_EVENT_AXIS | JS_EVENT_INIT; - event.number = client->startup - joydev->nkey; + event.number = list->startup - joydev->nkey; event.value = joydev->abs[event.number]; } if (copy_to_user(buf + retval, &event, sizeof(struct js_event))) return -EFAULT; - client->startup++; + list->startup++; retval += sizeof(struct js_event); } - while (client->head != client->tail && retval + sizeof(struct js_event) <= count) { + while (list->head != list->tail && retval + sizeof(struct js_event) <= count) { - if (copy_to_user(buf + retval, client->buffer + client->tail, sizeof(struct js_event))) + if (copy_to_user(buf + retval, list->buffer + list->tail, sizeof(struct js_event))) return -EFAULT; - client->tail = (client->tail + 1) & (JOYDEV_BUFFER_SIZE - 1); + list->tail = (list->tail + 1) & (JOYDEV_BUFFER_SIZE - 1); retval += sizeof(struct js_event); } @@ -287,12 +276,11 @@ static ssize_t joydev_read(struct file *file, char __user *buf, size_t count, lo /* No kernel lock - fine */ static unsigned int joydev_poll(struct file *file, poll_table *wait) { - struct joydev_client *client = file->private_data; - struct joydev *joydev = client->joydev; + struct joydev_list *list = file->private_data; - poll_wait(file, &joydev->wait, wait); - return ((client->head != client->tail || client->startup < joydev->nabs + joydev->nkey) ? - (POLLIN | POLLRDNORM) : 0) | (joydev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &list->joydev->wait, wait); + return ((list->head != list->tail || list->startup < list->joydev->nabs + list->joydev->nkey) ? + (POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR)); } static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp) @@ -386,8 +374,8 @@ static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __u #ifdef CONFIG_COMPAT static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct joydev_client *client = file->private_data; - struct joydev *joydev = client->joydev; + struct joydev_list *list = file->private_data; + struct joydev *joydev = list->joydev; void __user *argp = (void __user *)arg; s32 tmp32; struct JS_DATA_SAVE_TYPE_32 ds32; @@ -440,8 +428,8 @@ static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned lo static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct joydev_client *client = file->private_data; - struct joydev *joydev = client->joydev; + struct joydev_list *list = file->private_data; + struct joydev *joydev = list->joydev; void __user *argp = (void __user *)arg; if (!joydev->exist) @@ -477,26 +465,23 @@ static const struct file_operations joydev_fops = { .fasync = joydev_fasync, }; -static int joydev_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct joydev *joydev; struct class_device *cdev; - dev_t devt; int i, j, t, minor; - int error; for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); if (minor == JOYDEV_MINORS) { printk(KERN_ERR "joydev: no more free joydev devices\n"); - return -ENFILE; + return NULL; } - joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL); - if (!joydev) - return -ENOMEM; + if (!(joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL))) + return NULL; - INIT_LIST_HEAD(&joydev->client_list); + INIT_LIST_HEAD(&joydev->list); init_waitqueue_head(&joydev->wait); joydev->minor = minor; @@ -549,54 +534,31 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, joydev_table[minor] = joydev; - devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), - - cdev = class_device_create(&input_class, &dev->cdev, devt, - dev->cdev.dev, joydev->name); - if (IS_ERR(cdev)) { - error = PTR_ERR(cdev); - goto err_free_joydev; - } + cdev = class_device_create(&input_class, &dev->cdev, + MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), + dev->cdev.dev, joydev->name); /* temporary symlink to keep userspace happy */ - error = sysfs_create_link(&input_class.subsys.kobj, - &cdev->kobj, joydev->name); - if (error) - goto err_cdev_destroy; - - error = input_register_handle(&joydev->handle); - if (error) - goto err_remove_link; - - return 0; + sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + joydev->name); - err_remove_link: - sysfs_remove_link(&input_class.subsys.kobj, joydev->name); - err_cdev_destroy: - class_device_destroy(&input_class, devt); - err_free_joydev: - joydev_table[minor] = NULL; - kfree(joydev); - return error; + return &joydev->handle; } - static void joydev_disconnect(struct input_handle *handle) { struct joydev *joydev = handle->private; - struct joydev_client *client; - - input_unregister_handle(handle); + struct joydev_list *list; - sysfs_remove_link(&input_class.subsys.kobj, joydev->name); + sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); joydev->exist = 0; if (joydev->open) { input_close_device(handle); wake_up_interruptible(&joydev->wait); - list_for_each_entry(client, &joydev->client_list, node) - kill_fasync(&client->fasync, SIGIO, POLL_HUP); + list_for_each_entry(list, &joydev->list, node) + kill_fasync(&list->fasync, SIGIO, POLL_HUP); } else joydev_free(joydev); } diff --git a/trunk/drivers/input/joystick/Kconfig b/trunk/drivers/input/joystick/Kconfig index 82f563e24fdb..271263443c37 100644 --- a/trunk/drivers/input/joystick/Kconfig +++ b/trunk/drivers/input/joystick/Kconfig @@ -2,7 +2,7 @@ # Joystick driver configuration # menuconfig INPUT_JOYSTICK - bool "Joysticks/Gamepads" + bool "Joysticks" help If you have a joystick, 6dof controller, gamepad, steering wheel, weapon control system or something like that you can say Y here @@ -196,7 +196,7 @@ config JOYSTICK_TWIDJOY config JOYSTICK_DB9 tristate "Multisystem, Sega Genesis, Saturn joysticks and gamepads" depends on PARPORT - help + ---help--- Say Y here if you have a Sega Master System gamepad, Sega Genesis gamepad, Sega Saturn gamepad, or a Multisystem -- Atari, Amiga, Commodore, Amstrad CPC joystick connected to your parallel port. @@ -253,18 +253,4 @@ config JOYSTICK_JOYDUMP To compile this driver as a module, choose M here: the module will be called joydump. -config JOYSTICK_XPAD - tristate "X-Box gamepad support" - select USB - help - Say Y here if you want to use the X-Box pad with your computer. - Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV) - and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. - - For information about how to connect the X-Box pad to USB, see - . - - To compile this driver as a module, choose M here: the - module will be called xpad. - endif diff --git a/trunk/drivers/input/joystick/Makefile b/trunk/drivers/input/joystick/Makefile index e855abb0cc51..5231f6ff75b8 100644 --- a/trunk/drivers/input/joystick/Makefile +++ b/trunk/drivers/input/joystick/Makefile @@ -26,6 +26,5 @@ obj-$(CONFIG_JOYSTICK_TMDC) += tmdc.o obj-$(CONFIG_JOYSTICK_TURBOGRAFX) += turbografx.o obj-$(CONFIG_JOYSTICK_TWIDJOY) += twidjoy.o obj-$(CONFIG_JOYSTICK_WARRIOR) += warrior.o -obj-$(CONFIG_JOYSTICK_XPAD) += xpad.o obj-$(CONFIG_JOYSTICK_IFORCE) += iforce/ diff --git a/trunk/drivers/input/joystick/a3d.c b/trunk/drivers/input/joystick/a3d.c index ff701ab10d74..b11a4bbc84c4 100644 --- a/trunk/drivers/input/joystick/a3d.c +++ b/trunk/drivers/input/joystick/a3d.c @@ -241,7 +241,7 @@ static void a3d_adc_close(struct gameport *gameport) static int a3d_open(struct input_dev *dev) { - struct a3d *a3d = input_get_drvdata(dev); + struct a3d *a3d = dev->private; gameport_start_polling(a3d->gameport); return 0; @@ -253,7 +253,7 @@ static int a3d_open(struct input_dev *dev) static void a3d_close(struct input_dev *dev) { - struct a3d *a3d = input_get_drvdata(dev); + struct a3d *a3d = dev->private; gameport_stop_polling(a3d->gameport); } @@ -314,12 +314,11 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ; input_dev->id.product = a3d->mode; input_dev->id.version = 0x0100; - input_dev->dev.parent = &gameport->dev; + input_dev->cdev.dev = &gameport->dev; + input_dev->private = a3d; input_dev->open = a3d_open; input_dev->close = a3d_close; - input_set_drvdata(input_dev, a3d); - if (a3d->mode == A3D_MODE_PXL) { int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER }; diff --git a/trunk/drivers/input/joystick/adi.c b/trunk/drivers/input/joystick/adi.c index 28140c4a110d..6279ced8a35b 100644 --- a/trunk/drivers/input/joystick/adi.c +++ b/trunk/drivers/input/joystick/adi.c @@ -290,7 +290,7 @@ static void adi_poll(struct gameport *gameport) static int adi_open(struct input_dev *dev) { - struct adi_port *port = input_get_drvdata(dev); + struct adi_port *port = dev->private; gameport_start_polling(port->gameport); return 0; @@ -302,7 +302,7 @@ static int adi_open(struct input_dev *dev) static void adi_close(struct input_dev *dev) { - struct adi_port *port = input_get_drvdata(dev); + struct adi_port *port = dev->private; gameport_stop_polling(port->gameport); } @@ -424,9 +424,8 @@ static int adi_init_input(struct adi *adi, struct adi_port *port, int half) input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH; input_dev->id.product = adi->id; input_dev->id.version = 0x0100; - input_dev->dev.parent = &port->gameport->dev; - - input_set_drvdata(input_dev, port); + input_dev->cdev.dev = &port->gameport->dev; + input_dev->private = port; input_dev->open = adi_open; input_dev->close = adi_close; diff --git a/trunk/drivers/input/joystick/analog.c b/trunk/drivers/input/joystick/analog.c index bdd157c1ebf8..51f1e4bfff3e 100644 --- a/trunk/drivers/input/joystick/analog.c +++ b/trunk/drivers/input/joystick/analog.c @@ -53,7 +53,7 @@ MODULE_LICENSE("GPL"); #define ANALOG_PORTS 16 static char *js[ANALOG_PORTS]; -static unsigned int js_nargs; +static int js_nargs; static int analog_options[ANALOG_PORTS]; module_param_array_named(map, js, charp, &js_nargs, 0); MODULE_PARM_DESC(map, "Describes analog joysticks type/capabilities"); @@ -343,7 +343,7 @@ static void analog_poll(struct gameport *gameport) static int analog_open(struct input_dev *dev) { - struct analog_port *port = input_get_drvdata(dev); + struct analog_port *port = dev->private; gameport_start_polling(port->gameport); return 0; @@ -355,7 +355,7 @@ static int analog_open(struct input_dev *dev) static void analog_close(struct input_dev *dev) { - struct analog_port *port = input_get_drvdata(dev); + struct analog_port *port = dev->private; gameport_stop_polling(port->gameport); } @@ -449,13 +449,10 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG; input_dev->id.product = analog->mask >> 4; input_dev->id.version = 0x0100; - input_dev->dev.parent = &port->gameport->dev; - - input_set_drvdata(input_dev, port); input_dev->open = analog_open; input_dev->close = analog_close; - + input_dev->private = port; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = j = 0; i < 4; i++) diff --git a/trunk/drivers/input/joystick/cobra.c b/trunk/drivers/input/joystick/cobra.c index d3352a849b85..034ec39c251d 100644 --- a/trunk/drivers/input/joystick/cobra.c +++ b/trunk/drivers/input/joystick/cobra.c @@ -142,7 +142,7 @@ static void cobra_poll(struct gameport *gameport) static int cobra_open(struct input_dev *dev) { - struct cobra *cobra = input_get_drvdata(dev); + struct cobra *cobra = dev->private; gameport_start_polling(cobra->gameport); return 0; @@ -150,7 +150,7 @@ static int cobra_open(struct input_dev *dev) static void cobra_close(struct input_dev *dev) { - struct cobra *cobra = input_get_drvdata(dev); + struct cobra *cobra = dev->private; gameport_stop_polling(cobra->gameport); } @@ -211,9 +211,8 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE; input_dev->id.product = 0x0008; input_dev->id.version = 0x0100; - input_dev->dev.parent = &gameport->dev; - - input_set_drvdata(input_dev, cobra); + input_dev->cdev.dev = &gameport->dev; + input_dev->private = cobra; input_dev->open = cobra_open; input_dev->close = cobra_close; diff --git a/trunk/drivers/input/joystick/db9.c b/trunk/drivers/input/joystick/db9.c index 86ad1027e12a..b41bd2eb37dd 100644 --- a/trunk/drivers/input/joystick/db9.c +++ b/trunk/drivers/input/joystick/db9.c @@ -46,17 +46,17 @@ MODULE_LICENSE("GPL"); struct db9_config { int args[2]; - unsigned int nargs; + int nargs; }; #define DB9_MAX_PORTS 3 -static struct db9_config db9_cfg[DB9_MAX_PORTS] __initdata; +static struct db9_config db9[DB9_MAX_PORTS] __initdata; -module_param_array_named(dev, db9_cfg[0].args, int, &db9_cfg[0].nargs, 0); +module_param_array_named(dev, db9[0].args, int, &db9[0].nargs, 0); MODULE_PARM_DESC(dev, "Describes first attached device (,)"); -module_param_array_named(dev2, db9_cfg[1].args, int, &db9_cfg[0].nargs, 0); +module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0); MODULE_PARM_DESC(dev2, "Describes second attached device (,)"); -module_param_array_named(dev3, db9_cfg[2].args, int, &db9_cfg[2].nargs, 0); +module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0); MODULE_PARM_DESC(dev3, "Describes third attached device (,)"); #define DB9_ARG_PARPORT 0 @@ -518,7 +518,7 @@ static void db9_timer(unsigned long private) static int db9_open(struct input_dev *dev) { - struct db9 *db9 = input_get_drvdata(dev); + struct db9 *db9 = dev->private; struct parport *port = db9->pd->port; int err; @@ -542,7 +542,7 @@ static int db9_open(struct input_dev *dev) static void db9_close(struct input_dev *dev) { - struct db9 *db9 = input_get_drvdata(dev); + struct db9 *db9 = dev->private; struct parport *port = db9->pd->port; mutex_lock(&db9->mutex); @@ -625,8 +625,7 @@ static struct db9 __init *db9_probe(int parport, int mode) input_dev->id.vendor = 0x0002; input_dev->id.product = mode; input_dev->id.version = 0x0100; - - input_set_drvdata(input_dev, db9); + input_dev->private = db9; input_dev->open = db9_open; input_dev->close = db9_close; @@ -680,17 +679,17 @@ static int __init db9_init(void) int err = 0; for (i = 0; i < DB9_MAX_PORTS; i++) { - if (db9_cfg[i].nargs == 0 || db9_cfg[i].args[DB9_ARG_PARPORT] < 0) + if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0) continue; - if (db9_cfg[i].nargs < 2) { + if (db9[i].nargs < 2) { printk(KERN_ERR "db9.c: Device type must be specified.\n"); err = -EINVAL; break; } - db9_base[i] = db9_probe(db9_cfg[i].args[DB9_ARG_PARPORT], - db9_cfg[i].args[DB9_ARG_MODE]); + db9_base[i] = db9_probe(db9[i].args[DB9_ARG_PARPORT], + db9[i].args[DB9_ARG_MODE]); if (IS_ERR(db9_base[i])) { err = PTR_ERR(db9_base[i]); break; diff --git a/trunk/drivers/input/joystick/gamecon.c b/trunk/drivers/input/joystick/gamecon.c index 1a452e0e5f25..711e4b3e9e61 100644 --- a/trunk/drivers/input/joystick/gamecon.c +++ b/trunk/drivers/input/joystick/gamecon.c @@ -48,16 +48,16 @@ MODULE_LICENSE("GPL"); struct gc_config { int args[GC_MAX_DEVICES + 1]; - unsigned int nargs; + int nargs; }; -static struct gc_config gc_cfg[GC_MAX_PORTS] __initdata; +static struct gc_config gc[GC_MAX_PORTS] __initdata; -module_param_array_named(map, gc_cfg[0].args, int, &gc_cfg[0].nargs, 0); +module_param_array_named(map, gc[0].args, int, &gc[0].nargs, 0); MODULE_PARM_DESC(map, "Describes first set of devices (,,,..)"); -module_param_array_named(map2, gc_cfg[1].args, int, &gc_cfg[1].nargs, 0); +module_param_array_named(map2, gc[1].args, int, &gc[1].nargs, 0); MODULE_PARM_DESC(map2, "Describes second set of devices"); -module_param_array_named(map3, gc_cfg[2].args, int, &gc_cfg[2].nargs, 0); +module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0); MODULE_PARM_DESC(map3, "Describes third set of devices"); /* see also gs_psx_delay parameter in PSX support section */ @@ -591,7 +591,7 @@ static void gc_timer(unsigned long private) static int gc_open(struct input_dev *dev) { - struct gc *gc = input_get_drvdata(dev); + struct gc *gc = dev->private; int err; err = mutex_lock_interruptible(&gc->mutex); @@ -610,7 +610,7 @@ static int gc_open(struct input_dev *dev) static void gc_close(struct input_dev *dev) { - struct gc *gc = input_get_drvdata(dev); + struct gc *gc = dev->private; mutex_lock(&gc->mutex); if (!--gc->used) { @@ -646,8 +646,7 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) input_dev->id.vendor = 0x0001; input_dev->id.product = pad_type; input_dev->id.version = 0x0100; - - input_set_drvdata(input_dev, gc); + input_dev->private = gc; input_dev->open = gc_open; input_dev->close = gc_close; @@ -810,17 +809,16 @@ static int __init gc_init(void) int err = 0; for (i = 0; i < GC_MAX_PORTS; i++) { - if (gc_cfg[i].nargs == 0 || gc_cfg[i].args[0] < 0) + if (gc[i].nargs == 0 || gc[i].args[0] < 0) continue; - if (gc_cfg[i].nargs < 2) { + if (gc[i].nargs < 2) { printk(KERN_ERR "gamecon.c: at least one device must be specified\n"); err = -EINVAL; break; } - gc_base[i] = gc_probe(gc_cfg[i].args[0], - gc_cfg[i].args + 1, gc_cfg[i].nargs - 1); + gc_base[i] = gc_probe(gc[i].args[0], gc[i].args + 1, gc[i].nargs - 1); if (IS_ERR(gc_base[i])) { err = PTR_ERR(gc_base[i]); break; diff --git a/trunk/drivers/input/joystick/gf2k.c b/trunk/drivers/input/joystick/gf2k.c index d514aebf7554..bacbab5d1b6f 100644 --- a/trunk/drivers/input/joystick/gf2k.c +++ b/trunk/drivers/input/joystick/gf2k.c @@ -220,7 +220,7 @@ static void gf2k_poll(struct gameport *gameport) static int gf2k_open(struct input_dev *dev) { - struct gf2k *gf2k = input_get_drvdata(dev); + struct gf2k *gf2k = dev->private; gameport_start_polling(gf2k->gameport); return 0; @@ -228,7 +228,7 @@ static int gf2k_open(struct input_dev *dev) static void gf2k_close(struct input_dev *dev) { - struct gf2k *gf2k = input_get_drvdata(dev); + struct gf2k *gf2k = dev->private; gameport_stop_polling(gf2k->gameport); } @@ -308,13 +308,11 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS; input_dev->id.product = gf2k->id; input_dev->id.version = 0x0100; - input_dev->dev.parent = &gameport->dev; - - input_set_drvdata(input_dev, gf2k); + input_dev->cdev.dev = &gameport->dev; + input_dev->private = gf2k; input_dev->open = gf2k_open; input_dev->close = gf2k_close; - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < gf2k_axes[gf2k->id]; i++) diff --git a/trunk/drivers/input/joystick/grip.c b/trunk/drivers/input/joystick/grip.c index 73eb5ab6f140..17a90c436de8 100644 --- a/trunk/drivers/input/joystick/grip.c +++ b/trunk/drivers/input/joystick/grip.c @@ -285,7 +285,7 @@ static void grip_poll(struct gameport *gameport) static int grip_open(struct input_dev *dev) { - struct grip *grip = input_get_drvdata(dev); + struct grip *grip = dev->private; gameport_start_polling(grip->gameport); return 0; @@ -293,7 +293,7 @@ static int grip_open(struct input_dev *dev) static void grip_close(struct input_dev *dev) { - struct grip *grip = input_get_drvdata(dev); + struct grip *grip = dev->private; gameport_stop_polling(grip->gameport); } @@ -363,9 +363,8 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; input_dev->id.product = grip->mode[i]; input_dev->id.version = 0x0100; - input_dev->dev.parent = &gameport->dev; - - input_set_drvdata(input_dev, grip); + input_dev->cdev.dev = &gameport->dev; + input_dev->private = grip; input_dev->open = grip_open; input_dev->close = grip_close; diff --git a/trunk/drivers/input/joystick/grip_mp.c b/trunk/drivers/input/joystick/grip_mp.c index 555319e6378c..8120a9c40773 100644 --- a/trunk/drivers/input/joystick/grip_mp.c +++ b/trunk/drivers/input/joystick/grip_mp.c @@ -562,7 +562,7 @@ static void grip_poll(struct gameport *gameport) static int grip_open(struct input_dev *dev) { - struct grip_mp *grip = input_get_drvdata(dev); + struct grip_mp *grip = dev->private; gameport_start_polling(grip->gameport); return 0; @@ -574,9 +574,9 @@ static int grip_open(struct input_dev *dev) static void grip_close(struct input_dev *dev) { - struct grip_mp *grip = input_get_drvdata(dev); + struct grip_mp *grip = dev->private; - gameport_stop_polling(grip->gameport); + gameport_start_polling(grip->gameport); } /* @@ -599,9 +599,8 @@ static int register_slot(int slot, struct grip_mp *grip) input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS; input_dev->id.product = 0x0100 + port->mode; input_dev->id.version = 0x0100; - input_dev->dev.parent = &grip->gameport->dev; - - input_set_drvdata(input_dev, grip); + input_dev->cdev.dev = &grip->gameport->dev; + input_dev->private = grip; input_dev->open = grip_open; input_dev->close = grip_close; diff --git a/trunk/drivers/input/joystick/guillemot.c b/trunk/drivers/input/joystick/guillemot.c index d4e8073caf27..dbc5d92858b8 100644 --- a/trunk/drivers/input/joystick/guillemot.c +++ b/trunk/drivers/input/joystick/guillemot.c @@ -156,7 +156,7 @@ static void guillemot_poll(struct gameport *gameport) static int guillemot_open(struct input_dev *dev) { - struct guillemot *guillemot = input_get_drvdata(dev); + struct guillemot *guillemot = dev->private; gameport_start_polling(guillemot->gameport); return 0; @@ -168,7 +168,7 @@ static int guillemot_open(struct input_dev *dev) static void guillemot_close(struct input_dev *dev) { - struct guillemot *guillemot = input_get_drvdata(dev); + struct guillemot *guillemot = dev->private; gameport_stop_polling(guillemot->gameport); } @@ -231,9 +231,8 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT; input_dev->id.product = guillemot_type[i].id; input_dev->id.version = (int)data[14] << 8 | data[15]; - input_dev->dev.parent = &gameport->dev; - - input_set_drvdata(input_dev, guillemot); + input_dev->cdev.dev = &gameport->dev; + input_dev->private = guillemot; input_dev->open = guillemot_open; input_dev->close = guillemot_close; diff --git a/trunk/drivers/input/joystick/iforce/iforce-ff.c b/trunk/drivers/input/joystick/iforce/iforce-ff.c index f2a4381d0ab8..8fb0c19cc60e 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-ff.c +++ b/trunk/drivers/input/joystick/iforce/iforce-ff.c @@ -2,7 +2,7 @@ * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002, 2007 Johann Deneux + * Copyright (c) 2001-2002 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -205,7 +205,7 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) int i; if (new->type != FF_SPRING && new->type != FF_FRICTION) { - warn("bad effect type in need_condition_modifier"); + printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n"); return 0; } @@ -227,7 +227,7 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new) static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect) { if (effect->type != FF_CONSTANT) { - warn("bad effect type in need_envelope_modifier"); + printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); return 0; } @@ -258,7 +258,7 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec break; default: - warn("bad effect type in need_envelope_modifier"); + printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); } return 0; @@ -271,7 +271,7 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec static int need_period_modifier(struct ff_effect *old, struct ff_effect *new) { if (new->type != FF_PERIODIC) { - warn("bad effect type in need_period_modifier"); + printk(KERN_WARNING "iforce.c: bad effect type in need_period_modifier\n"); return 0; } return (old->u.periodic.period != new->u.periodic.period diff --git a/trunk/drivers/input/joystick/iforce/iforce-main.c b/trunk/drivers/input/joystick/iforce/iforce-main.c index fb129c479a66..3393a37fec39 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-main.c +++ b/trunk/drivers/input/joystick/iforce/iforce-main.c @@ -2,7 +2,7 @@ * $Id: iforce-main.c,v 1.19 2002/07/07 10:22:50 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002, 2007 Johann Deneux + * Copyright (c) 2001-2002 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -29,7 +29,7 @@ #include "iforce.h" -MODULE_AUTHOR("Vojtech Pavlik , Johann Deneux "); +MODULE_AUTHOR("Vojtech Pavlik , Johann Deneux "); MODULE_DESCRIPTION("USB/RS232 I-Force joysticks and wheels driver"); MODULE_LICENSE("GPL"); @@ -220,7 +220,7 @@ static void iforce_release(struct input_dev *dev) /* Check: no effects should be present in memory */ for (i = 0; i < dev->ff->max_effects; i++) { if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) { - warn("iforce_release: Device still owns effects"); + printk(KERN_WARNING "iforce_release: Device still owns effects\n"); break; } } @@ -232,7 +232,7 @@ static void iforce_release(struct input_dev *dev) switch (iforce->bus) { #ifdef CONFIG_JOYSTICK_IFORCE_USB case IFORCE_USB: - usb_kill_urb(iforce->irq); + usb_unlink_urb(iforce->irq); /* The device was unplugged before the file * was released */ @@ -287,13 +287,13 @@ int iforce_init_device(struct iforce *iforce) #ifdef CONFIG_JOYSTICK_IFORCE_USB case IFORCE_USB: input_dev->id.bustype = BUS_USB; - input_dev->dev.parent = &iforce->usbdev->dev; + input_dev->cdev.dev = &iforce->usbdev->dev; break; #endif #ifdef CONFIG_JOYSTICK_IFORCE_232 case IFORCE_232: input_dev->id.bustype = BUS_RS232; - input_dev->dev.parent = &iforce->serio->dev; + input_dev->cdev.dev = &iforce->serio->dev; break; #endif } @@ -324,7 +324,7 @@ int iforce_init_device(struct iforce *iforce) break; if (i == 20) { /* 5 seconds */ - err("Timeout waiting for response from device."); + printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n"); error = -ENODEV; goto fail; } @@ -336,26 +336,26 @@ int iforce_init_device(struct iforce *iforce) if (!iforce_get_id_packet(iforce, "M")) input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet M"); + printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n"); if (!iforce_get_id_packet(iforce, "P")) input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet P"); + printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n"); if (!iforce_get_id_packet(iforce, "B")) iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1]; else - warn("Device does not respond to id packet B"); + printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n"); if (!iforce_get_id_packet(iforce, "N")) ff_effects = iforce->edata[1]; else - warn("Device does not respond to id packet N"); + printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n"); /* Check if the device can store more effects than the driver can really handle */ if (ff_effects > IFORCE_EFFECTS_MAX) { - warn("Limiting number of effects to %d (device reports %d)", + printk(KERN_WARNING "iforce: Limiting number of effects to %d (device reports %d)\n", IFORCE_EFFECTS_MAX, ff_effects); ff_effects = IFORCE_EFFECTS_MAX; } @@ -457,6 +457,8 @@ int iforce_init_device(struct iforce *iforce) if (error) goto fail; + printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open); + return 0; fail: input_free_device(input_dev); diff --git a/trunk/drivers/input/joystick/iforce/iforce-packets.c b/trunk/drivers/input/joystick/iforce/iforce-packets.c index 21c4e13d3a50..808f05932a6f 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-packets.c +++ b/trunk/drivers/input/joystick/iforce/iforce-packets.c @@ -2,7 +2,7 @@ * $Id: iforce-packets.c,v 1.16 2002/07/07 10:22:50 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002, 2007 Johann Deneux + * Copyright (c) 2001-2002 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -39,10 +39,10 @@ void iforce_dump_packet(char *msg, u16 cmd, unsigned char *data) { int i; - printk(KERN_DEBUG __FILE__ ": %s cmd = %04x, data = ", msg, cmd); + printk(KERN_DEBUG "iforce.c: %s ( cmd = %04x, data = ", msg, cmd); for (i = 0; i < LO(cmd); i++) printk("%02x ", data[i]); - printk("\n"); + printk(")\n"); } /* @@ -65,9 +65,8 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data) head = iforce->xmit.head; tail = iforce->xmit.tail; - if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) { - warn("not enough space in xmit buffer to send new packet"); + printk(KERN_WARNING "iforce.c: not enough space in xmit buffer to send new packet\n"); spin_unlock_irqrestore(&iforce->xmit_lock, flags); return -1; } @@ -127,6 +126,8 @@ int iforce_control_playback(struct iforce* iforce, u16 id, unsigned int value) { unsigned char data[3]; +printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value); + data[0] = LO(id); data[1] = (value > 0) ? ((value > 1) ? 0x41 : 0x01) : 0; data[2] = LO(value); @@ -150,7 +151,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr) return 0; } } - warn("unused effect %04x updated !!!", addr); + printk(KERN_WARNING "iforce-packets.c: unused effect %04x updated !!!\n", addr); return -1; } @@ -161,7 +162,7 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data) static int being_used = 0; if (being_used) - warn("re-entrant call to iforce_process %d", being_used); + printk(KERN_WARNING "iforce-packets.c: re-entrant call to iforce_process %d\n", being_used); being_used++; #ifdef CONFIG_JOYSTICK_IFORCE_232 @@ -265,7 +266,7 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) return -1; } #else - err("iforce_get_id_packet: iforce->bus = USB!"); + printk(KERN_ERR "iforce_get_id_packet: iforce->bus = USB!\n"); #endif break; @@ -283,12 +284,13 @@ int iforce_get_id_packet(struct iforce *iforce, char *packet) return -1; } #else - err("iforce_get_id_packet: iforce->bus = SERIO!"); + printk(KERN_ERR "iforce_get_id_packet: iforce->bus = SERIO!\n"); #endif break; default: - err("iforce_get_id_packet: iforce->bus = %d", iforce->bus); + printk(KERN_ERR "iforce_get_id_packet: iforce->bus = %d\n", + iforce->bus); break; } diff --git a/trunk/drivers/input/joystick/iforce/iforce-serio.c b/trunk/drivers/input/joystick/iforce/iforce-serio.c index 7b4bc19cef27..ec4be535f483 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-serio.c +++ b/trunk/drivers/input/joystick/iforce/iforce-serio.c @@ -2,7 +2,7 @@ * $Id: iforce-serio.c,v 1.4 2002/01/28 22:45:00 jdeneux Exp $ * * Copyright (c) 2000-2001 Vojtech Pavlik - * Copyright (c) 2001, 2007 Johann Deneux + * Copyright (c) 2001 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ diff --git a/trunk/drivers/input/joystick/iforce/iforce-usb.c b/trunk/drivers/input/joystick/iforce/iforce-usb.c index 750099d8e3c6..80cdebcbcb99 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-usb.c +++ b/trunk/drivers/input/joystick/iforce/iforce-usb.c @@ -2,7 +2,7 @@ * $Id: iforce-usb.c,v 1.16 2002/06/09 11:08:04 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002, 2007 Johann Deneux + * Copyright (c) 2001-2002 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -65,7 +65,7 @@ void iforce_usb_xmit(struct iforce *iforce) XMIT_INC(iforce->xmit.tail, n); if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) { - warn("usb_submit_urb failed %d\n", n); + printk(KERN_WARNING "iforce-usb.c: iforce_usb_xmit: usb_submit_urb failed %d\n", n); } /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended. @@ -110,7 +110,7 @@ static void iforce_usb_out(struct urb *urb) struct iforce *iforce = urb->context; if (urb->status) { - dbg("urb->status %d, exiting", urb->status); + printk(KERN_DEBUG "iforce_usb_out: urb->status %d, exiting", urb->status); return; } @@ -190,9 +190,10 @@ static int iforce_usb_probe(struct usb_interface *intf, /* Called by iforce_delete() */ void iforce_usb_delete(struct iforce* iforce) { - usb_kill_urb(iforce->irq); - usb_kill_urb(iforce->out); - usb_kill_urb(iforce->ctrl); + usb_unlink_urb(iforce->irq); +/* Is it ok to unlink those ? */ + usb_unlink_urb(iforce->out); + usb_unlink_urb(iforce->ctrl); usb_free_urb(iforce->irq); usb_free_urb(iforce->out); diff --git a/trunk/drivers/input/joystick/iforce/iforce.h b/trunk/drivers/input/joystick/iforce/iforce.h index 40a853ac21c7..ffaeaefa1a42 100644 --- a/trunk/drivers/input/joystick/iforce/iforce.h +++ b/trunk/drivers/input/joystick/iforce/iforce.h @@ -2,7 +2,7 @@ * $Id: iforce.h,v 1.13 2002/07/07 10:22:50 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik - * Copyright (c) 2001-2002, 2007 Johann Deneux + * Copyright (c) 2001-2002 Johann Deneux * * USB/RS232 I-Force joysticks and wheels. */ @@ -124,7 +124,7 @@ struct iforce { /* Buffer used for asynchronous sending of bytes to the device */ struct circ_buf xmit; unsigned char xmit_data[XMIT_SIZE]; - unsigned long xmit_flags[1]; + long xmit_flags[1]; /* Force Feedback */ wait_queue_head_t wait; diff --git a/trunk/drivers/input/joystick/interact.c b/trunk/drivers/input/joystick/interact.c index 1aec1e9d7c59..fec8b3d0967d 100644 --- a/trunk/drivers/input/joystick/interact.c +++ b/trunk/drivers/input/joystick/interact.c @@ -185,7 +185,7 @@ static void interact_poll(struct gameport *gameport) static int interact_open(struct input_dev *dev) { - struct interact *interact = input_get_drvdata(dev); + struct interact *interact = dev->private; gameport_start_polling(interact->gameport); return 0; @@ -197,7 +197,7 @@ static int interact_open(struct input_dev *dev) static void interact_close(struct input_dev *dev) { - struct interact *interact = input_get_drvdata(dev); + struct interact *interact = dev->private; gameport_stop_polling(interact->gameport); } @@ -262,9 +262,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT; input_dev->id.product = interact_type[i].id; input_dev->id.version = 0x0100; - input_dev->dev.parent = &gameport->dev; - - input_set_drvdata(input_dev, interact); + input_dev->private = interact; input_dev->open = interact_open; input_dev->close = interact_close; diff --git a/trunk/drivers/input/joystick/magellan.c b/trunk/drivers/input/joystick/magellan.c index b35604ee43ae..4112789f1196 100644 --- a/trunk/drivers/input/joystick/magellan.c +++ b/trunk/drivers/input/joystick/magellan.c @@ -168,7 +168,8 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_MAGELLAN; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = magellan; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/trunk/drivers/input/joystick/sidewinder.c b/trunk/drivers/input/joystick/sidewinder.c index 2adf73f63c94..e58b22c018e4 100644 --- a/trunk/drivers/input/joystick/sidewinder.c +++ b/trunk/drivers/input/joystick/sidewinder.c @@ -509,7 +509,7 @@ static void sw_poll(struct gameport *gameport) static int sw_open(struct input_dev *dev) { - struct sw *sw = input_get_drvdata(dev); + struct sw *sw = dev->private; gameport_start_polling(sw->gameport); return 0; @@ -517,7 +517,7 @@ static int sw_open(struct input_dev *dev) static void sw_close(struct input_dev *dev) { - struct sw *sw = input_get_drvdata(dev); + struct sw *sw = dev->private; gameport_stop_polling(sw->gameport); } @@ -751,9 +751,8 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT; input_dev->id.product = sw->type; input_dev->id.version = 0x0100; - input_dev->dev.parent = &gameport->dev; - - input_set_drvdata(input_dev, sw); + input_dev->cdev.dev = &gameport->dev; + input_dev->private = sw; input_dev->open = sw_open; input_dev->close = sw_close; diff --git a/trunk/drivers/input/joystick/spaceball.c b/trunk/drivers/input/joystick/spaceball.c index abb7c4cf54ad..08bf113e62eb 100644 --- a/trunk/drivers/input/joystick/spaceball.c +++ b/trunk/drivers/input/joystick/spaceball.c @@ -226,7 +226,8 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_SPACEBALL; input_dev->id.product = id; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = spaceball; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/trunk/drivers/input/joystick/spaceorb.c b/trunk/drivers/input/joystick/spaceorb.c index c4937f1e837c..c9c79211af71 100644 --- a/trunk/drivers/input/joystick/spaceorb.c +++ b/trunk/drivers/input/joystick/spaceorb.c @@ -183,7 +183,8 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_SPACEORB; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = spaceorb; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); diff --git a/trunk/drivers/input/joystick/stinger.c b/trunk/drivers/input/joystick/stinger.c index 8581ee991d4e..ecb0916215fa 100644 --- a/trunk/drivers/input/joystick/stinger.c +++ b/trunk/drivers/input/joystick/stinger.c @@ -154,7 +154,8 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_STINGER; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = stinger; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | diff --git a/trunk/drivers/input/joystick/tmdc.c b/trunk/drivers/input/joystick/tmdc.c index 3b36ee04f726..bb23ed2a04a6 100644 --- a/trunk/drivers/input/joystick/tmdc.c +++ b/trunk/drivers/input/joystick/tmdc.c @@ -265,7 +265,7 @@ static void tmdc_poll(struct gameport *gameport) static int tmdc_open(struct input_dev *dev) { - struct tmdc *tmdc = input_get_drvdata(dev); + struct tmdc *tmdc = dev->private; gameport_start_polling(tmdc->gameport); return 0; @@ -273,7 +273,7 @@ static int tmdc_open(struct input_dev *dev) static void tmdc_close(struct input_dev *dev) { - struct tmdc *tmdc = input_get_drvdata(dev); + struct tmdc *tmdc = dev->private; gameport_stop_polling(tmdc->gameport); } @@ -326,9 +326,8 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER; input_dev->id.product = model->id; input_dev->id.version = 0x0100; - input_dev->dev.parent = &tmdc->gameport->dev; - - input_set_drvdata(input_dev, tmdc); + input_dev->cdev.dev = &tmdc->gameport->dev; + input_dev->private = tmdc; input_dev->open = tmdc_open; input_dev->close = tmdc_close; diff --git a/trunk/drivers/input/joystick/turbografx.c b/trunk/drivers/input/joystick/turbografx.c index 8381c6f14373..037d3487fcc7 100644 --- a/trunk/drivers/input/joystick/turbografx.c +++ b/trunk/drivers/input/joystick/turbografx.c @@ -48,16 +48,16 @@ MODULE_LICENSE("GPL"); struct tgfx_config { int args[TGFX_MAX_DEVICES + 1]; - unsigned int nargs; + int nargs; }; -static struct tgfx_config tgfx_cfg[TGFX_MAX_PORTS] __initdata; +static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata; -module_param_array_named(map, tgfx_cfg[0].args, int, &tgfx_cfg[0].nargs, 0); +module_param_array_named(map, tgfx[0].args, int, &tgfx[0].nargs, 0); MODULE_PARM_DESC(map, "Describes first set of devices (,,,.."); -module_param_array_named(map2, tgfx_cfg[1].args, int, &tgfx_cfg[1].nargs, 0); +module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0); MODULE_PARM_DESC(map2, "Describes second set of devices"); -module_param_array_named(map3, tgfx_cfg[2].args, int, &tgfx_cfg[2].nargs, 0); +module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0); MODULE_PARM_DESC(map3, "Describes third set of devices"); #define TGFX_REFRESH_TIME HZ/100 /* 10 ms */ @@ -122,7 +122,7 @@ static void tgfx_timer(unsigned long private) static int tgfx_open(struct input_dev *dev) { - struct tgfx *tgfx = input_get_drvdata(dev); + struct tgfx *tgfx = dev->private; int err; err = mutex_lock_interruptible(&tgfx->sem); @@ -141,7 +141,7 @@ static int tgfx_open(struct input_dev *dev) static void tgfx_close(struct input_dev *dev) { - struct tgfx *tgfx = input_get_drvdata(dev); + struct tgfx *tgfx = dev->private; mutex_lock(&tgfx->sem); if (!--tgfx->used) { @@ -224,8 +224,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) input_dev->id.product = n_buttons[i]; input_dev->id.version = 0x0100; - input_set_drvdata(input_dev, tgfx); - + input_dev->private = tgfx; input_dev->open = tgfx_open; input_dev->close = tgfx_close; @@ -283,18 +282,16 @@ static int __init tgfx_init(void) int err = 0; for (i = 0; i < TGFX_MAX_PORTS; i++) { - if (tgfx_cfg[i].nargs == 0 || tgfx_cfg[i].args[0] < 0) + if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0) continue; - if (tgfx_cfg[i].nargs < 2) { + if (tgfx[i].nargs < 2) { printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n"); err = -EINVAL; break; } - tgfx_base[i] = tgfx_probe(tgfx_cfg[i].args[0], - tgfx_cfg[i].args + 1, - tgfx_cfg[i].nargs - 1); + tgfx_base[i] = tgfx_probe(tgfx[i].args[0], tgfx[i].args + 1, tgfx[i].nargs - 1); if (IS_ERR(tgfx_base[i])) { err = PTR_ERR(tgfx_base[i]); break; diff --git a/trunk/drivers/input/joystick/twidjoy.c b/trunk/drivers/input/joystick/twidjoy.c index c91504ec38eb..9cf17d6ced82 100644 --- a/trunk/drivers/input/joystick/twidjoy.c +++ b/trunk/drivers/input/joystick/twidjoy.c @@ -205,9 +205,11 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_TWIDJOY; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = twidjoy; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4); input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4); diff --git a/trunk/drivers/input/joystick/warrior.c b/trunk/drivers/input/joystick/warrior.c index 4e85f72eefd7..29d339acf430 100644 --- a/trunk/drivers/input/joystick/warrior.c +++ b/trunk/drivers/input/joystick/warrior.c @@ -160,7 +160,8 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_WARRIOR; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = warrior; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); diff --git a/trunk/drivers/input/keyboard/Kconfig b/trunk/drivers/input/keyboard/Kconfig index bd707b86c114..f17e9c7d4b36 100644 --- a/trunk/drivers/input/keyboard/Kconfig +++ b/trunk/drivers/input/keyboard/Kconfig @@ -164,17 +164,6 @@ config KEYBOARD_AMIGA To compile this driver as a module, choose M here: the module will be called amikbd. -config KEYBOARD_ATARI - tristate "Atari keyboard" - depends on ATARI - select ATARI_KBD_CORE - help - Say Y here if you are running Linux on any Atari and have a keyboard - attached. - - To compile this driver as a module, choose M here: the - module will be called atakbd. - config KEYBOARD_HIL_OLD tristate "HP HIL keyboard support (simple driver)" depends on GSC || HP300 @@ -214,19 +203,9 @@ config KEYBOARD_OMAP To compile this driver as a module, choose M here: the module will be called omap-keypad. -config KEYBOARD_PXA27x - tristate "PXA27x keyboard support" - depends on PXA27x - help - Enable support for PXA27x matrix keyboard controller - - To compile this driver as a module, choose M here: the - module will be called pxa27x_keyboard. - config KEYBOARD_AAED2000 tristate "AAED-2000 keyboard" depends on MACH_AAED2000 - select INPUT_POLLDEV default y help Say Y here to enable the keyboard on the Agilent AAED-2000 diff --git a/trunk/drivers/input/keyboard/Makefile b/trunk/drivers/input/keyboard/Makefile index 28d211b87b14..586a0fe53be6 100644 --- a/trunk/drivers/input/keyboard/Makefile +++ b/trunk/drivers/input/keyboard/Makefile @@ -9,7 +9,6 @@ obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o -obj-$(CONFIG_KEYBOARD_ATARI) += atakbd.o obj-$(CONFIG_KEYBOARD_LOCOMO) += locomokbd.o obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o @@ -18,7 +17,6 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o -obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keyboard.o obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o diff --git a/trunk/drivers/input/keyboard/aaed2000_kbd.c b/trunk/drivers/input/keyboard/aaed2000_kbd.c index 63d6ead6b877..65fcb6af63a8 100644 --- a/trunk/drivers/input/keyboard/aaed2000_kbd.c +++ b/trunk/drivers/input/keyboard/aaed2000_kbd.c @@ -14,11 +14,12 @@ #include #include #include -#include +#include #include #include #include #include +#include #include #include @@ -45,7 +46,8 @@ static unsigned char aaedkbd_keycode[NR_SCANCODES] = { struct aaedkbd { unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)]; - struct input_polled_dev *poll_dev; + struct input_dev *input; + struct work_struct workq; int kbdscan_state[KB_COLS]; int kbdscan_count[KB_COLS]; }; @@ -62,15 +64,14 @@ static void aaedkbd_report_col(struct aaedkbd *aaedkbd, scancode = SCANCODE(row, col); pressed = rowd & KB_ROWMASK(row); - input_report_key(aaedkbd->poll_dev->input, - aaedkbd->keycode[scancode], pressed); + input_report_key(aaedkbd->input, aaedkbd->keycode[scancode], pressed); } } /* Scan the hardware keyboard and push any changes up through the input layer */ -static void aaedkbd_poll(struct input_polled_dev *dev) +static void aaedkbd_work(void *data) { - struct aaedkbd *aaedkbd = dev->private; + struct aaedkbd *aaedkbd = data; unsigned int col, rowd; col = 0; @@ -89,41 +90,59 @@ static void aaedkbd_poll(struct input_polled_dev *dev) } while (col < KB_COLS); AAEC_GPIO_KSCAN = 0x07; - input_sync(dev->input); + input_sync(aaedkbd->input); + + schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); +} + +static int aaedkbd_open(struct input_dev *indev) +{ + struct aaedkbd *aaedkbd = indev->private; + + schedule_delayed_work(&aaedkbd->workq, msecs_to_jiffies(SCAN_INTERVAL)); + + return 0; +} + +static void aaedkbd_close(struct input_dev *indev) +{ + struct aaedkbd *aaedkbd = indev->private; + + cancel_delayed_work(&aaedkbd->workq); + flush_scheduled_work(); } static int __devinit aaedkbd_probe(struct platform_device *pdev) { struct aaedkbd *aaedkbd; - struct input_polled_dev *poll_dev; struct input_dev *input_dev; int i; int error; aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL); - poll_dev = input_allocate_polled_device(); - if (!aaedkbd || !poll_dev) { + input_dev = input_allocate_device(); + if (!aaedkbd || !input_dev) { error = -ENOMEM; goto fail; } platform_set_drvdata(pdev, aaedkbd); - aaedkbd->poll_dev = poll_dev; - memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode)); + aaedkbd->input = input_dev; - poll_dev->private = aaedkbd; - poll_dev->poll = aaedkbd_poll; - poll_dev->poll_interval = SCAN_INTERVAL; + /* Init keyboard rescan workqueue */ + INIT_WORK(&aaedkbd->workq, aaedkbd_work, aaedkbd); + + memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode)); - input_dev = poll_dev->input; input_dev->name = "AAED-2000 Keyboard"; input_dev->phys = "aaedkbd/input0"; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &pdev->dev; + input_dev->cdev.dev = &pdev->dev; + input_dev->private = aaedkbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = aaedkbd->keycode; @@ -134,14 +153,17 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev) set_bit(aaedkbd->keycode[i], input_dev->keybit); clear_bit(0, input_dev->keybit); - error = input_register_polled_device(aaedkbd->poll_dev); + input_dev->open = aaedkbd_open; + input_dev->close = aaedkbd_close; + + error = input_register_device(aaedkbd->input); if (error) goto fail; return 0; fail: kfree(aaedkbd); - input_free_polled_device(poll_dev); + input_free_device(input_dev); return error; } @@ -149,8 +171,7 @@ static int __devexit aaedkbd_remove(struct platform_device *pdev) { struct aaedkbd *aaedkbd = platform_get_drvdata(pdev); - input_unregister_polled_device(aaedkbd->poll_dev); - input_free_polled_device(aaedkbd->poll_dev); + input_unregister_device(aaedkbd->input); kfree(aaedkbd); return 0; diff --git a/trunk/drivers/input/keyboard/atakbd.c b/trunk/drivers/input/keyboard/atakbd.c deleted file mode 100644 index ded1d6ac6ff3..000000000000 --- a/trunk/drivers/input/keyboard/atakbd.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * atakbd.c - * - * Copyright (c) 2005 Michael Schmitz - * - * Based on amikbd.c, which is - * - * Copyright (c) 2000-2001 Vojtech Pavlik - * - * Based on the work of: - * Hamish Macdonald - */ - -/* - * Atari keyboard driver for Linux/m68k - * - * The low level init and interrupt stuff is handled in arch/mm68k/atari/atakeyb.c - * (the keyboard ACIA also handles the mouse and joystick data, and the keyboard - * interrupt is shared with the MIDI ACIA so MIDI data also get handled there). - * This driver only deals with handing key events off to the input layer. - */ - -/* - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to , or by paper mail: - * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -MODULE_AUTHOR("Michael Schmitz "); -MODULE_DESCRIPTION("Atari keyboard driver"); -MODULE_LICENSE("GPL"); - -static unsigned char atakbd_keycode[0x72]; - -static struct input_dev *atakbd_dev; - -static void atakbd_interrupt(unsigned char scancode, char down) -{ - - if (scancode < 0x72) { /* scancodes < 0xf2 are keys */ - - // report raw events here? - - scancode = atakbd_keycode[scancode]; - - if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */ - input_report_key(atakbd_dev, scancode, 1); - input_report_key(atakbd_dev, scancode, 0); - input_sync(atakbd_dev); - } else { - input_report_key(atakbd_dev, scancode, down); - input_sync(atakbd_dev); - } - } else /* scancodes >= 0xf2 are mouse data, most likely */ - printk(KERN_INFO "atakbd: unhandled scancode %x\n", scancode); - - return; -} - -static int __init atakbd_init(void) -{ - int i; - - if (!ATARIHW_PRESENT(ST_MFP)) - return -EIO; - - // TODO: request_mem_region if not done in arch code - - if (!(atakbd_dev = input_allocate_device())) - return -ENOMEM; - - // need to init core driver if not already done so - if (atari_keyb_init()) - return -ENODEV; - - atakbd_dev->name = "Atari Keyboard"; - atakbd_dev->phys = "atakbd/input0"; - atakbd_dev->id.bustype = BUS_ATARI; - atakbd_dev->id.vendor = 0x0001; - atakbd_dev->id.product = 0x0001; - atakbd_dev->id.version = 0x0100; - - atakbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); - atakbd_dev->keycode = atakbd_keycode; - atakbd_dev->keycodesize = sizeof(unsigned char); - atakbd_dev->keycodemax = ARRAY_SIZE(atakbd_keycode); - - for (i = 1; i < 0x72; i++) { - atakbd_keycode[i] = i; - set_bit(atakbd_keycode[i], atakbd_dev->keybit); - } - - input_register_device(atakbd_dev); - - atari_input_keyboard_interrupt_hook = atakbd_interrupt; - - printk(KERN_INFO "input: %s at IKBD ACIA\n", atakbd_dev->name); - - return 0; -} - -static void __exit atakbd_exit(void) -{ - atari_input_keyboard_interrupt_hook = NULL; - input_unregister_device(atakbd_dev); -} - -module_init(atakbd_init); -module_exit(atakbd_exit); diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index be1fe46cd308..663877076bc7 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -586,7 +586,7 @@ static void atkbd_event_work(struct work_struct *work) static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct atkbd *atkbd = input_get_drvdata(dev); + struct atkbd *atkbd = dev->private; if (!atkbd->write) return -1; @@ -883,9 +883,8 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) input_dev->id.product = atkbd->translated ? 1 : atkbd->set; input_dev->id.version = atkbd->id; input_dev->event = atkbd_event; - input_dev->dev.parent = &atkbd->ps2dev.serio->dev; - - input_set_drvdata(input_dev, atkbd); + input_dev->private = atkbd; + input_dev->cdev.dev = &atkbd->ps2dev.serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); diff --git a/trunk/drivers/input/keyboard/corgikbd.c b/trunk/drivers/input/keyboard/corgikbd.c index 6578bfff644b..1016c94e65db 100644 --- a/trunk/drivers/input/keyboard/corgikbd.c +++ b/trunk/drivers/input/keyboard/corgikbd.c @@ -323,7 +323,8 @@ static int __init corgikbd_probe(struct platform_device *pdev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &pdev->dev; + input_dev->cdev.dev = &pdev->dev; + input_dev->private = corgikbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); input_dev->keycode = corgikbd->keycode; diff --git a/trunk/drivers/input/keyboard/gpio_keys.c b/trunk/drivers/input/keyboard/gpio_keys.c index 739212252b09..ccf6df387b62 100644 --- a/trunk/drivers/input/keyboard/gpio_keys.c +++ b/trunk/drivers/input/keyboard/gpio_keys.c @@ -35,14 +35,11 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id) struct input_dev *input = platform_get_drvdata(pdev); for (i = 0; i < pdata->nbuttons; i++) { - struct gpio_keys_button *button = &pdata->buttons[i]; - int gpio = button->gpio; - + int gpio = pdata->buttons[i].gpio; if (irq == gpio_to_irq(gpio)) { - unsigned int type = button->type ?: EV_KEY; - int state = (gpio_get_value(gpio) ? 1 : 0) ^ button->active_low; + int state = (gpio_get_value(gpio) ? 1 : 0) ^ (pdata->buttons[i].active_low); - input_event(input, type, button->code, !!state); + input_report_key(input, pdata->buttons[i].keycode, state); input_sync(input); } } @@ -66,7 +63,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input->name = pdev->name; input->phys = "gpio-keys/input0"; - input->dev.parent = &pdev->dev; + input->cdev.dev = &pdev->dev; + input->private = pdata; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; @@ -74,21 +72,19 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) input->id.version = 0x0100; for (i = 0; i < pdata->nbuttons; i++) { - struct gpio_keys_button *button = &pdata->buttons[i]; - int irq = gpio_to_irq(button->gpio); - unsigned int type = button->type ?: EV_KEY; + int code = pdata->buttons[i].keycode; + int irq = gpio_to_irq(pdata->buttons[i].gpio); set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM, - button->desc ? button->desc : "gpio_keys", + pdata->buttons[i].desc ? pdata->buttons[i].desc : "gpio_keys", pdev); if (error) { printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n", irq, error); goto fail; } - - input_set_capability(input, type, button->code); + set_bit(code, input->keybit); } error = input_register_device(input); diff --git a/trunk/drivers/input/keyboard/hil_kbd.c b/trunk/drivers/input/keyboard/hil_kbd.c index cdd254f2e6c7..7cc9728b04df 100644 --- a/trunk/drivers/input/keyboard/hil_kbd.c +++ b/trunk/drivers/input/keyboard/hil_kbd.c @@ -51,7 +51,7 @@ MODULE_LICENSE("Dual BSD/GPL"); #define HIL_KBD_SET1_UPBIT 0x01 #define HIL_KBD_SET1_SHIFT 1 -static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly = +static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] = { HIL_KEYCODES_SET1 }; #define HIL_KBD_SET2_UPBIT 0x01 @@ -60,10 +60,10 @@ static unsigned int hil_kbd_set1[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly = #define HIL_KBD_SET3_UPBIT 0x80 #define HIL_KBD_SET3_SHIFT 0 -static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] __read_mostly = +static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] = { HIL_KEYCODES_SET3 }; -static const char hil_language[][16] = { HIL_LOCALE_MAP }; +static char hil_language[][16] = { HIL_LOCALE_MAP }; struct hil_kbd { struct input_dev *dev; @@ -94,12 +94,10 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) idx = kbd->idx4/4; p = data[idx - 1]; - if ((p & ~HIL_CMDCT_POL) == - (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) - goto report; - if ((p & ~HIL_CMDCT_RPL) == - (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) - goto report; + if ((p & ~HIL_CMDCT_POL) == + (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; + if ((p & ~HIL_CMDCT_RPL) == + (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; /* Not a poll response. See if we are loading config records. */ switch (p & HIL_PKT_DATA_MASK) { @@ -109,32 +107,27 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) for (; i < HIL_KBD_MAX_LENGTH; i++) kbd->idd[i] = 0; break; - case HIL_CMD_RSC: for (i = 0; i < idx; i++) kbd->rsc[i] = kbd->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_KBD_MAX_LENGTH; i++) kbd->rsc[i] = 0; break; - case HIL_CMD_EXD: for (i = 0; i < idx; i++) kbd->exd[i] = kbd->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_KBD_MAX_LENGTH; i++) kbd->exd[i] = 0; break; - case HIL_CMD_RNM: for (i = 0; i < idx; i++) kbd->rnm[i] = kbd->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_KBD_MAX_LENGTH + 1; i++) kbd->rnm[i] = '\0'; break; - default: /* These occur when device isn't present */ - if (p == (HIL_ERR_INT | HIL_PKT_CMD)) - break; + if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; /* Anything else we'd like to know about. */ printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); break; @@ -146,19 +139,16 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) { case HIL_POL_CHARTYPE_NONE: break; - case HIL_POL_CHARTYPE_ASCII: while (cnt < idx - 1) input_report_key(dev, kbd->data[cnt++] & 0x7f, 1); break; - case HIL_POL_CHARTYPE_RSVD1: case HIL_POL_CHARTYPE_RSVD2: case HIL_POL_CHARTYPE_BINARY: while (cnt < idx - 1) input_report_key(dev, kbd->data[cnt++], 1); break; - case HIL_POL_CHARTYPE_SET1: while (cnt < idx - 1) { unsigned int key; @@ -171,7 +161,6 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) input_report_key(dev, key, !up); } break; - case HIL_POL_CHARTYPE_SET2: while (cnt < idx - 1) { unsigned int key; @@ -184,7 +173,6 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) input_report_key(dev, key, !up); } break; - case HIL_POL_CHARTYPE_SET3: while (cnt < idx - 1) { unsigned int key; @@ -203,43 +191,42 @@ static void hil_kbd_process_record(struct hil_kbd *kbd) up(&kbd->sem); } -static void hil_kbd_process_err(struct hil_kbd *kbd) -{ +static void hil_kbd_process_err(struct hil_kbd *kbd) { printk(KERN_WARNING PREFIX "errored HIL packet\n"); kbd->idx4 = 0; up(&kbd->sem); } -static irqreturn_t hil_kbd_interrupt(struct serio *serio, - unsigned char data, unsigned int flags) +static irqreturn_t hil_kbd_interrupt(struct serio *serio, + unsigned char data, unsigned int flags) { struct hil_kbd *kbd; hil_packet packet; int idx; kbd = serio_get_drvdata(serio); - BUG_ON(kbd == NULL); + if (kbd == NULL) { + BUG(); + return IRQ_HANDLED; + } if (kbd->idx4 >= (HIL_KBD_MAX_LENGTH * sizeof(hil_packet))) { hil_kbd_process_err(kbd); return IRQ_HANDLED; } idx = kbd->idx4/4; - if (!(kbd->idx4 % 4)) - kbd->data[idx] = 0; + if (!(kbd->idx4 % 4)) kbd->data[idx] = 0; packet = kbd->data[idx]; packet |= ((hil_packet)data) << ((3 - (kbd->idx4 % 4)) * 8); kbd->data[idx] = packet; /* Records of N 4-byte hil_packets must terminate with a command. */ - if ((++(kbd->idx4)) % 4) - return IRQ_HANDLED; + if ((++(kbd->idx4)) % 4) return IRQ_HANDLED; if ((packet & 0xffff0000) != HIL_ERR_INT) { hil_kbd_process_err(kbd); return IRQ_HANDLED; } - if (packet & HIL_PKT_CMD) - hil_kbd_process_record(kbd); + if (packet & HIL_PKT_CMD) hil_kbd_process_record(kbd); return IRQ_HANDLED; } @@ -248,7 +235,10 @@ static void hil_kbd_disconnect(struct serio *serio) struct hil_kbd *kbd; kbd = serio_get_drvdata(serio); - BUG_ON(kbd == NULL); + if (kbd == NULL) { + BUG(); + return; + } serio_close(serio); input_unregister_device(kbd->dev); @@ -269,40 +259,42 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) if (!kbd->dev) goto bail0; + kbd->dev->private = kbd; + if (serio_open(serio, drv)) goto bail1; serio_set_drvdata(serio, kbd); kbd->serio = serio; - init_MUTEX_LOCKED(&kbd->sem); + init_MUTEX_LOCKED(&(kbd->sem)); /* Get device info. MLC driver supplies devid/status/etc. */ serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_IDD); - down(&kbd->sem); + down(&(kbd->sem)); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_RSC); - down(&kbd->sem); + down(&(kbd->sem)); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_RNM); - down(&kbd->sem); + down(&(kbd->sem)); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_EXD); - down(&kbd->sem); + down(&(kbd->sem)); - up(&kbd->sem); + up(&(kbd->sem)); did = kbd->idd[0]; idd = kbd->idd + 1; @@ -318,11 +310,12 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) goto bail2; } - if (HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { + if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) { printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n"); goto bail2; } + kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; @@ -335,7 +328,7 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) kbd->dev->id.vendor = PCI_VENDOR_ID_HP; kbd->dev->id.product = 0x0001; /* TODO: get from kbd->rsc */ kbd->dev->id.version = 0x0100; /* TODO: get from kbd->rsc */ - kbd->dev->dev.parent = &serio->dev; + kbd->dev->cdev.dev = &serio->dev; for (i = 0; i < 128; i++) { set_bit(hil_kbd_set1[i], kbd->dev->keybit); @@ -351,8 +344,8 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_EK1); /* Enable Keyswitch Autorepeat 1 */ - down(&kbd->sem); - up(&kbd->sem); + down(&(kbd->sem)); + up(&(kbd->sem)); return 0; bail2: @@ -375,26 +368,26 @@ static struct serio_device_id hil_kbd_ids[] = { { 0 } }; -static struct serio_driver hil_kbd_serio_drv = { +struct serio_driver hil_kbd_serio_drv = { .driver = { .name = "hil_kbd", }, .description = "HP HIL keyboard driver", .id_table = hil_kbd_ids, - .connect = hil_kbd_connect, - .disconnect = hil_kbd_disconnect, - .interrupt = hil_kbd_interrupt + .connect = hil_kbd_connect, + .disconnect = hil_kbd_disconnect, + .interrupt = hil_kbd_interrupt }; static int __init hil_kbd_init(void) { return serio_register_driver(&hil_kbd_serio_drv); } - + static void __exit hil_kbd_exit(void) { serio_unregister_driver(&hil_kbd_serio_drv); } - + module_init(hil_kbd_init); module_exit(hil_kbd_exit); diff --git a/trunk/drivers/input/keyboard/hilkbd.c b/trunk/drivers/input/keyboard/hilkbd.c index 499b6974457f..4de4dc297d50 100644 --- a/trunk/drivers/input/keyboard/hilkbd.c +++ b/trunk/drivers/input/keyboard/hilkbd.c @@ -3,7 +3,7 @@ * * Copyright (C) 1998 Philip Blundell * Copyright (C) 1999 Matthew Wilcox - * Copyright (C) 1999-2007 Helge Deller + * Copyright (C) 1999-2006 Helge Deller * * Very basic HP Human Interface Loop (HIL) driver. * This driver handles the keyboard on HP300 (m68k) and on some @@ -52,7 +52,7 @@ MODULE_LICENSE("GPL v2"); #elif defined(CONFIG_HP300) - #define HILBASE 0xf0428000UL /* HP300 (m68k) port address */ + #define HILBASE 0xf0428000 /* HP300 (m86k) port address */ #define HIL_DATA 0x1 #define HIL_CMD 0x3 #define HIL_IRQ 2 @@ -89,7 +89,7 @@ MODULE_LICENSE("GPL v2"); #define HIL_READKBDSADR 0xF9 #define HIL_WRITEKBDSADR 0xE9 -static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly = +static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = { HIL_KEYCODES_SET1 }; /* HIL structure */ @@ -211,10 +211,10 @@ hil_keyb_init(void) return -ENODEV; /* already initialized */ } - spin_lock_init(&hil_dev.lock); hil_dev.dev = input_allocate_device(); if (!hil_dev.dev) return -ENOMEM; + hil_dev.dev->private = &hil_dev; #if defined(CONFIG_HP300) if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { diff --git a/trunk/drivers/input/keyboard/lkkbd.c b/trunk/drivers/input/keyboard/lkkbd.c index 1b08f4e79dd2..3d4d0a0ede28 100644 --- a/trunk/drivers/input/keyboard/lkkbd.c +++ b/trunk/drivers/input/keyboard/lkkbd.c @@ -515,7 +515,7 @@ static int lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct lkkbd *lk = input_get_drvdata (dev); + struct lkkbd *lk = dev->private; unsigned char leds_on = 0; unsigned char leds_off = 0; @@ -666,10 +666,9 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_LKKBD; input_dev->id.product = 0; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; input_dev->event = lkkbd_event; - - input_set_drvdata (input_dev, lk); + input_dev->private = lk; set_bit (EV_KEY, input_dev->evbit); set_bit (EV_LED, input_dev->evbit); diff --git a/trunk/drivers/input/keyboard/locomokbd.c b/trunk/drivers/input/keyboard/locomokbd.c index 7a41b271f222..2ade5186cc41 100644 --- a/trunk/drivers/input/keyboard/locomokbd.c +++ b/trunk/drivers/input/keyboard/locomokbd.c @@ -231,7 +231,7 @@ static int locomokbd_probe(struct locomo_dev *dev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &dev->dev; + input_dev->private = locomokbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = locomokbd->keycode; diff --git a/trunk/drivers/input/keyboard/newtonkbd.c b/trunk/drivers/input/keyboard/newtonkbd.c index b97a41e3ee56..aa29b50765c9 100644 --- a/trunk/drivers/input/keyboard/newtonkbd.c +++ b/trunk/drivers/input/keyboard/newtonkbd.c @@ -104,7 +104,8 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_NEWTON; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = nkbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = nkbd->keycode; diff --git a/trunk/drivers/input/keyboard/omap-keypad.c b/trunk/drivers/input/keyboard/omap-keypad.c index 3a228634f101..5680a6d95b2b 100644 --- a/trunk/drivers/input/keyboard/omap-keypad.c +++ b/trunk/drivers/input/keyboard/omap-keypad.c @@ -370,7 +370,8 @@ static int __init omap_kp_probe(struct platform_device *pdev) set_bit(keymap[i] & KEY_MAX, input_dev->keybit); input_dev->name = "omap-keypad"; input_dev->phys = "omap-keypad/input0"; - input_dev->dev.parent = &pdev->dev; + input_dev->cdev.dev = &pdev->dev; + input_dev->private = omap_kp; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; diff --git a/trunk/drivers/input/keyboard/pxa27x_keyboard.c b/trunk/drivers/input/keyboard/pxa27x_keyboard.c deleted file mode 100644 index 06eaf766d9d2..000000000000 --- a/trunk/drivers/input/keyboard/pxa27x_keyboard.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * linux/drivers/input/keyboard/pxa27x_keyboard.c - * - * Driver for the pxa27x matrix keyboard controller. - * - * Created: Feb 22, 2007 - * Author: Rodolfo Giometti - * - * Based on a previous implementations by Kevin O'Connor - * and Alex Osborne and - * on some suggestions by Nicolas Pitre . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define DRIVER_NAME "pxa27x-keyboard" - -#define KPASMKP(col) (col/2 == 0 ? KPASMKP0 : \ - col/2 == 1 ? KPASMKP1 : \ - col/2 == 2 ? KPASMKP2 : KPASMKP3) -#define KPASMKPx_MKC(row, col) (1 << (row + 16 * (col % 2))) - -static irqreturn_t pxakbd_irq_handler(int irq, void *dev_id) -{ - struct platform_device *pdev = dev_id; - struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; - struct input_dev *input_dev = platform_get_drvdata(pdev); - unsigned long kpc = KPC; - int p, row, col, rel; - - if (kpc & KPC_DI) { - unsigned long kpdk = KPDK; - - if (!(kpdk & KPDK_DKP)) { - /* better luck next time */ - } else if (kpc & KPC_REE0) { - unsigned long kprec = KPREC; - KPREC = 0x7f; - - if (kprec & KPREC_OF0) - rel = (kprec & 0xff) + 0x7f; - else if (kprec & KPREC_UF0) - rel = (kprec & 0xff) - 0x7f - 0xff; - else - rel = (kprec & 0xff) - 0x7f; - - if (rel) { - input_report_rel(input_dev, REL_WHEEL, rel); - input_sync(input_dev); - } - } - } - - if (kpc & KPC_MI) { - /* report the status of every button */ - for (row = 0; row < pdata->nr_rows; row++) { - for (col = 0; col < pdata->nr_cols; col++) { - p = KPASMKP(col) & KPASMKPx_MKC(row, col) ? - 1 : 0; - pr_debug("keycode %x - pressed %x\n", - pdata->keycodes[row][col], p); - input_report_key(input_dev, - pdata->keycodes[row][col], p); - } - } - input_sync(input_dev); - } - - return IRQ_HANDLED; -} - -static int pxakbd_open(struct input_dev *dev) -{ - /* Set keypad control register */ - KPC |= (KPC_ASACT | - KPC_MS_ALL | - (2 << 6) | KPC_REE0 | KPC_DK_DEB_SEL | - KPC_ME | KPC_MIE | KPC_DE | KPC_DIE); - - KPC &= ~KPC_AS; /* disable automatic scan */ - KPC &= ~KPC_IMKP; /* do not ignore multiple keypresses */ - - /* Set rotary count to mid-point value */ - KPREC = 0x7F; - - /* Enable unit clock */ - pxa_set_cken(CKEN19_KEYPAD, 1); - - return 0; -} - -static void pxakbd_close(struct input_dev *dev) -{ - /* Disable clock unit */ - pxa_set_cken(CKEN19_KEYPAD, 0); -} - -#ifdef CONFIG_PM -static int pxakbd_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; - - /* Save controller status */ - pdata->reg_kpc = KPC; - pdata->reg_kprec = KPREC; - - return 0; -} - -static int pxakbd_resume(struct platform_device *pdev) -{ - struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; - struct input_dev *input_dev = platform_get_drvdata(pdev); - - mutex_lock(&input_dev->mutex); - - if (input_dev->users) { - /* Restore controller status */ - KPC = pdata->reg_kpc; - KPREC = pdata->reg_kprec; - - /* Enable unit clock */ - pxa_set_cken(CKEN19_KEYPAD, 1); - } - - mutex_unlock(&input_dev->mutex); - - return 0; -} -#else -#define pxakbd_suspend NULL -#define pxakbd_resume NULL -#endif - -static int __devinit pxakbd_probe(struct platform_device *pdev) -{ - struct pxa27x_keyboard_platform_data *pdata = pdev->dev.platform_data; - struct input_dev *input_dev; - int i, row, col, error; - - /* Create and register the input driver. */ - input_dev = input_allocate_device(); - if (!input_dev) { - printk(KERN_ERR "Cannot request keypad device\n"); - return -ENOMEM; - } - - input_dev->name = DRIVER_NAME; - input_dev->id.bustype = BUS_HOST; - input_dev->open = pxakbd_open; - input_dev->close = pxakbd_close; - input_dev->dev.parent = &pdev->dev; - - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); - input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL); - for (row = 0; row < pdata->nr_rows; row++) { - for (col = 0; col < pdata->nr_cols; col++) { - int code = pdata->keycodes[row][col]; - if (code > 0) - set_bit(code, input_dev->keybit); - } - } - - error = request_irq(IRQ_KEYPAD, pxakbd_irq_handler, IRQF_DISABLED, - DRIVER_NAME, pdev); - if (error) { - printk(KERN_ERR "Cannot request keypad IRQ\n"); - pxa_set_cken(CKEN19_KEYPAD, 0); - goto err_free_dev; - } - - platform_set_drvdata(pdev, input_dev); - - /* Register the input device */ - error = input_register_device(input_dev); - if (error) - goto err_free_irq; - - /* Setup GPIOs. */ - for (i = 0; i < pdata->nr_rows + pdata->nr_cols; i++) - pxa_gpio_mode(pdata->gpio_modes[i]); - - /* - * Store rows/cols info into keyboard registers. - */ - - KPC |= (pdata->nr_rows - 1) << 26; - KPC |= (pdata->nr_cols - 1) << 23; - - for (col = 0; col < pdata->nr_cols; col++) - KPC |= KPC_MS0 << col; - - return 0; - - err_free_irq: - platform_set_drvdata(pdev, NULL); - free_irq(IRQ_KEYPAD, pdev); - err_free_dev: - input_free_device(input_dev); - return error; -} - -static int __devexit pxakbd_remove(struct platform_device *pdev) -{ - struct input_dev *input_dev = platform_get_drvdata(pdev); - - input_unregister_device(input_dev); - free_irq(IRQ_KEYPAD, pdev); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver pxakbd_driver = { - .probe = pxakbd_probe, - .remove = __devexit_p(pxakbd_remove), - .suspend = pxakbd_suspend, - .resume = pxakbd_resume, - .driver = { - .name = DRIVER_NAME, - }, -}; - -static int __init pxakbd_init(void) -{ - return platform_driver_register(&pxakbd_driver); -} - -static void __exit pxakbd_exit(void) -{ - platform_driver_unregister(&pxakbd_driver); -} - -module_init(pxakbd_init); -module_exit(pxakbd_exit); - -MODULE_DESCRIPTION("PXA27x Matrix Keyboard Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/keyboard/spitzkbd.c b/trunk/drivers/input/keyboard/spitzkbd.c index 41b80385476c..8a2166c77ff4 100644 --- a/trunk/drivers/input/keyboard/spitzkbd.c +++ b/trunk/drivers/input/keyboard/spitzkbd.c @@ -372,9 +372,10 @@ static int __init spitzkbd_probe(struct platform_device *dev) spitzkbd->input = input_dev; + input_dev->private = spitzkbd; input_dev->name = "Spitz Keyboard"; input_dev->phys = spitzkbd->phys; - input_dev->dev.parent = &dev->dev; + input_dev->cdev.dev = &dev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; diff --git a/trunk/drivers/input/keyboard/stowaway.c b/trunk/drivers/input/keyboard/stowaway.c index b44b0684d543..f7b5c5b81451 100644 --- a/trunk/drivers/input/keyboard/stowaway.c +++ b/trunk/drivers/input/keyboard/stowaway.c @@ -108,7 +108,8 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_STOWAWAY; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = skbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = skbd->keycode; diff --git a/trunk/drivers/input/keyboard/sunkbd.c b/trunk/drivers/input/keyboard/sunkbd.c index 1d4e39624cfe..cc0238366414 100644 --- a/trunk/drivers/input/keyboard/sunkbd.c +++ b/trunk/drivers/input/keyboard/sunkbd.c @@ -146,7 +146,7 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio, static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct sunkbd *sunkbd = input_get_drvdata(dev); + struct sunkbd *sunkbd = dev->private; switch (type) { @@ -271,10 +271,8 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_SUNKBD; input_dev->id.product = sunkbd->type; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; - - input_set_drvdata(input_dev, sunkbd); - + input_dev->cdev.dev = &serio->dev; + input_dev->private = sunkbd; input_dev->event = sunkbd_event; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP); diff --git a/trunk/drivers/input/keyboard/xtkbd.c b/trunk/drivers/input/keyboard/xtkbd.c index f3a56eb58ed1..a82093432138 100644 --- a/trunk/drivers/input/keyboard/xtkbd.c +++ b/trunk/drivers/input/keyboard/xtkbd.c @@ -108,7 +108,8 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = xtkbd; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = xtkbd->keycode; diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index 6013ace94d98..41b42587f5e9 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -40,28 +40,6 @@ config INPUT_M68K_BEEP tristate "M68k Beeper support" depends on M68K -config INPUT_IXP4XX_BEEPER - tristate "IXP4XX Beeper support" - depends on ARCH_IXP4XX - help - If you say yes here, you can connect a beeper to the - ixp4xx gpio pins. This is used by the LinkSys NSLU2. - - If unsure, say Y. - - To compile this driver as a module, choose M here: the - module will be called ixp4xx-beeper. - -config INPUT_COBALT_BTNS - tristate "Cobalt button interface" - depends on MIPS_COBALT - select INPUT_POLLDEV - help - Say Y here if you want to support MIPS Cobalt button interface. - - To compile this driver as a module, choose M here: the - module will be called cobalt_btns. - config INPUT_WISTRON_BTNS tristate "x86 Wistron laptop button interface" depends on X86 && !X86_64 @@ -82,79 +60,17 @@ config INPUT_ATLAS_BTNS To compile this driver as a module, choose M here: the module will be called atlas_btns. -config INPUT_ATI_REMOTE - tristate "ATI / X10 USB RF remote control" - select USB - help - Say Y here if you want to use an ATI or X10 "Lola" USB remote control. - These are RF remotes with USB receivers. - The ATI remote comes with many of ATI's All-In-Wonder video cards. - The X10 "Lola" remote is available at: - - This driver provides mouse pointer, left and right mouse buttons, - and maps all the other remote buttons to keypress events. - - To compile this driver as a module, choose M here: the module will be - called ati_remote. - -config INPUT_ATI_REMOTE2 - tristate "ATI / Philips USB RF remote control" - select USB - help - Say Y here if you want to use an ATI or Philips USB RF remote control. - These are RF remotes with USB receivers. - ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards - and is also available as a separate product. - This driver provides mouse pointer, left and right mouse buttons, - and maps all the other remote buttons to keypress events. - - To compile this driver as a module, choose M here: the module will be - called ati_remote2. - -config INPUT_KEYSPAN_REMOTE - tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" - depends on EXPERIMENTAL - select USB - help - Say Y here if you want to use a Keyspan DMR USB remote control. - Currently only the UIA-11 type of receiver has been tested. The tag - on the receiver that connects to the USB port should have a P/N that - will tell you what type of DMR you have. The UIA-10 type is not - supported at this time. This driver maps all buttons to keypress - events. - - To compile this driver as a module, choose M here: the module will - be called keyspan_remote. - -config INPUT_POWERMATE - tristate "Griffin PowerMate and Contour Jog support" - select USB +config INPUT_IXP4XX_BEEPER + tristate "IXP4XX Beeper support" + depends on ARCH_IXP4XX help - Say Y here if you want to use Griffin PowerMate or Contour Jog devices. - These are aluminum dials which can measure clockwise and anticlockwise - rotation. The dial also acts as a pushbutton. The base contains an LED - which can be instructed to pulse or to switch to a particular intensity. + If you say yes here, you can connect a beeper to the + ixp4xx gpio pins. This is used by the LinkSys NSLU2. - You can download userspace tools from - . + If unsure, say Y. To compile this driver as a module, choose M here: the - module will be called powermate. - -config INPUT_YEALINK - tristate "Yealink usb-p1k voip phone" - depends EXPERIMENTAL - select USB - help - Say Y here if you want to enable keyboard and LCD functions of the - Yealink usb-p1k usb phones. The audio part is enabled by the generic - usb sound driver, so you might want to enable that as well. - - For information about how to use these additional functions, see - . - - To compile this driver as a module, choose M here: the module will be - called yealink. + module will be called ixp4xx-beeper. config INPUT_UINPUT tristate "User level driver support" @@ -165,19 +81,8 @@ config INPUT_UINPUT To compile this driver as a module, choose M here: the module will be called uinput. -config INPUT_POLLDEV - tristate "Polled input device skeleton" - help - Say Y here if you are using a driver for an input - device that periodically polls hardware state. This - option is only useful for out-of-tree drivers since - in-tree drivers select it automatically. - - To compile this driver as a module, choose M here: the - module will be called input-polldev. - config HP_SDC_RTC - tristate "HP SDC Real Time Clock" + tristate "HP SDC Real Time Clock" depends on GSC || HP300 select HP_SDC help diff --git a/trunk/drivers/input/misc/Makefile b/trunk/drivers/input/misc/Makefile index 8b2f7799e25c..e0a8d58c9e9b 100644 --- a/trunk/drivers/input/misc/Makefile +++ b/trunk/drivers/input/misc/Makefile @@ -4,18 +4,11 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o obj-$(CONFIG_INPUT_PCSPKR) += pcspkr.o obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o -obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o -obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o +obj-$(CONFIG_INPUT_UINPUT) += uinput.o obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o -obj-$(CONFIG_INPUT_ATI_REMOTE) += ati_remote.o -obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o -obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o -obj-$(CONFIG_INPUT_POWERMATE) += powermate.o -obj-$(CONFIG_INPUT_YEALINK) += yealink.o obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o -obj-$(CONFIG_INPUT_UINPUT) += uinput.o +obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o diff --git a/trunk/drivers/input/misc/cobalt_btns.c b/trunk/drivers/input/misc/cobalt_btns.c deleted file mode 100644 index 064b07936019..000000000000 --- a/trunk/drivers/input/misc/cobalt_btns.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Cobalt button interface driver. - * - * Copyright (C) 2007 Yoichi Yuasa - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include -#include -#include -#include -#include - -#define BUTTONS_POLL_INTERVAL 30 /* msec */ -#define BUTTONS_COUNT_THRESHOLD 3 -#define BUTTONS_STATUS_MASK 0xfe000000 - -struct buttons_dev { - struct input_polled_dev *poll_dev; - void __iomem *reg; -}; - -struct buttons_map { - uint32_t mask; - int keycode; - int count; -}; - -static struct buttons_map buttons_map[] = { - { 0x02000000, KEY_RESTART, }, - { 0x04000000, KEY_LEFT, }, - { 0x08000000, KEY_UP, }, - { 0x10000000, KEY_DOWN, }, - { 0x20000000, KEY_RIGHT, }, - { 0x40000000, KEY_ENTER, }, - { 0x80000000, KEY_SELECT, }, -}; - -static void handle_buttons(struct input_polled_dev *dev) -{ - struct buttons_map *button = buttons_map; - struct buttons_dev *bdev = dev->private; - struct input_dev *input = dev->input; - uint32_t status; - int i; - - status = readl(bdev->reg); - status = ~status & BUTTONS_STATUS_MASK; - - for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { - if (status & button->mask) { - button->count++; - } else { - if (button->count >= BUTTONS_COUNT_THRESHOLD) { - input_report_key(input, button->keycode, 0); - input_sync(input); - } - button->count = 0; - } - - if (button->count == BUTTONS_COUNT_THRESHOLD) { - input_report_key(input, button->keycode, 1); - input_sync(input); - } - - button++; - } -} - -static int __devinit cobalt_buttons_probe(struct platform_device *pdev) -{ - struct buttons_dev *bdev; - struct input_polled_dev *poll_dev; - struct input_dev *input; - struct resource *res; - int error, i; - - bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); - poll_dev = input_allocate_polled_device(); - if (!bdev || !poll_dev) { - error = -ENOMEM; - goto err_free_mem; - } - - poll_dev->private = bdev; - poll_dev->poll = handle_buttons; - poll_dev->poll_interval = BUTTONS_POLL_INTERVAL; - - input = poll_dev->input; - input->name = "Cobalt buttons"; - input->phys = "cobalt/input0"; - input->id.bustype = BUS_HOST; - input->cdev.dev = &pdev->dev; - - input->evbit[0] = BIT(EV_KEY); - for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { - set_bit(buttons_map[i].keycode, input->keybit); - buttons_map[i].count = 0; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - error = -EBUSY; - goto err_free_mem; - } - - bdev->poll_dev = poll_dev; - bdev->reg = ioremap(res->start, res->end - res->start + 1); - dev_set_drvdata(&pdev->dev, bdev); - - error = input_register_polled_device(poll_dev); - if (error) - goto err_iounmap; - - return 0; - - err_iounmap: - iounmap(bdev->reg); - err_free_mem: - input_free_polled_device(poll_dev); - kfree(bdev); - dev_set_drvdata(&pdev->dev, NULL); - return error; -} - -static int __devexit cobalt_buttons_remove(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct buttons_dev *bdev = dev_get_drvdata(dev); - - input_unregister_polled_device(bdev->poll_dev); - input_free_polled_device(bdev->poll_dev); - iounmap(bdev->reg); - kfree(bdev); - dev_set_drvdata(dev, NULL); - - return 0; -} - -static struct platform_driver cobalt_buttons_driver = { - .probe = cobalt_buttons_probe, - .remove = __devexit_p(cobalt_buttons_remove), - .driver = { - .name = "Cobalt buttons", - .owner = THIS_MODULE, - }, -}; - -static int __init cobalt_buttons_init(void) -{ - return platform_driver_register(&cobalt_buttons_driver); -} - -static void __exit cobalt_buttons_exit(void) -{ - platform_driver_unregister(&cobalt_buttons_driver); -} - -module_init(cobalt_buttons_init); -module_exit(cobalt_buttons_exit); diff --git a/trunk/drivers/input/misc/input-polldev.c b/trunk/drivers/input/misc/input-polldev.c deleted file mode 100644 index 1b2b9c9c5d88..000000000000 --- a/trunk/drivers/input/misc/input-polldev.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Generic implementation of a polled input device - - * Copyright (c) 2007 Dmitry Torokhov - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include -#include -#include - -static DEFINE_MUTEX(polldev_mutex); -static int polldev_users; -static struct workqueue_struct *polldev_wq; - -static int input_polldev_start_workqueue(void) -{ - int retval; - - retval = mutex_lock_interruptible(&polldev_mutex); - if (retval) - return retval; - - if (!polldev_users) { - polldev_wq = create_singlethread_workqueue("ipolldevd"); - if (!polldev_wq) { - printk(KERN_ERR "input-polldev: failed to create " - "ipolldevd workqueue\n"); - retval = -ENOMEM; - goto out; - } - } - - polldev_users++; - - out: - mutex_unlock(&polldev_mutex); - return retval; -} - -static void input_polldev_stop_workqueue(void) -{ - mutex_lock(&polldev_mutex); - - if (!--polldev_users) - destroy_workqueue(polldev_wq); - - mutex_unlock(&polldev_mutex); -} - -static void input_polled_device_work(struct work_struct *work) -{ - struct input_polled_dev *dev = - container_of(work, struct input_polled_dev, work.work); - - dev->poll(dev); - queue_delayed_work(polldev_wq, &dev->work, - msecs_to_jiffies(dev->poll_interval)); -} - -static int input_open_polled_device(struct input_dev *input) -{ - struct input_polled_dev *dev = input->private; - int error; - - error = input_polldev_start_workqueue(); - if (error) - return error; - - if (dev->flush) - dev->flush(dev); - - queue_delayed_work(polldev_wq, &dev->work, - msecs_to_jiffies(dev->poll_interval)); - - return 0; -} - -static void input_close_polled_device(struct input_dev *input) -{ - struct input_polled_dev *dev = input->private; - - cancel_rearming_delayed_workqueue(polldev_wq, &dev->work); - input_polldev_stop_workqueue(); -} - -/** - * input_allocate_polled_device - allocated memory polled device - * - * The function allocates memory for a polled device and also - * for an input device associated with this polled device. - */ -struct input_polled_dev *input_allocate_polled_device(void) -{ - struct input_polled_dev *dev; - - dev = kzalloc(sizeof(struct input_polled_dev), GFP_KERNEL); - if (!dev) - return NULL; - - dev->input = input_allocate_device(); - if (!dev->input) { - kfree(dev); - return NULL; - } - - return dev; -} -EXPORT_SYMBOL(input_allocate_polled_device); - -/** - * input_free_polled_device - free memory allocated for polled device - * @dev: device to free - * - * The function frees memory allocated for polling device and drops - * reference to the associated input device (if present). - */ -void input_free_polled_device(struct input_polled_dev *dev) -{ - if (dev) { - input_free_device(dev->input); - kfree(dev); - } -} -EXPORT_SYMBOL(input_free_polled_device); - -/** - * input_register_polled_device - register polled device - * @dev: device to register - * - * The function registers previously initialized polled input device - * with input layer. The device should be allocated with call to - * input_allocate_polled_device(). Callers should also set up poll() - * method and set up capabilities (id, name, phys, bits) of the - * corresponing input_dev structure. - */ -int input_register_polled_device(struct input_polled_dev *dev) -{ - struct input_dev *input = dev->input; - - INIT_DELAYED_WORK(&dev->work, input_polled_device_work); - if (!dev->poll_interval) - dev->poll_interval = 500; - input->private = dev; - input->open = input_open_polled_device; - input->close = input_close_polled_device; - - return input_register_device(input); -} -EXPORT_SYMBOL(input_register_polled_device); - -/** - * input_unregister_polled_device - unregister polled device - * @dev: device to unregister - * - * The function unregisters previously registered polled input - * device from input layer. Polling is stopped and device is - * ready to be freed with call to input_free_polled_device(). - * Callers should not attempt to access dev->input pointer - * after calling this function. - */ -void input_unregister_polled_device(struct input_polled_dev *dev) -{ - input_unregister_device(dev->input); - dev->input = NULL; -} -EXPORT_SYMBOL(input_unregister_polled_device); - diff --git a/trunk/drivers/input/misc/ixp4xx-beeper.c b/trunk/drivers/input/misc/ixp4xx-beeper.c index 3d4b619dadab..105c6fc27823 100644 --- a/trunk/drivers/input/misc/ixp4xx-beeper.c +++ b/trunk/drivers/input/misc/ixp4xx-beeper.c @@ -51,7 +51,7 @@ static void ixp4xx_spkr_control(unsigned int pin, unsigned int count) static int ixp4xx_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - unsigned int pin = (unsigned int) input_get_drvdata(input_dev); + unsigned int pin = (unsigned int) dev->private; unsigned int count = 0; if (type != EV_SND) @@ -99,15 +99,14 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) if (!input_dev) return -ENOMEM; - input_set_drvdata(input_dev, (void *) dev->id); - + input_dev->private = (void *) dev->id; input_dev->name = "ixp4xx beeper", input_dev->phys = "ixp4xx/gpio"; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &dev->dev; + input_dev->cdev.dev = &dev->dev; input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); @@ -137,7 +136,7 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) { struct input_dev *input_dev = platform_get_drvdata(dev); - unsigned int pin = (unsigned int) input_get_drvdata(input_dev); + unsigned int pin = (unsigned int) input_dev->private; input_unregister_device(input_dev); platform_set_drvdata(dev, NULL); @@ -154,7 +153,7 @@ static int __devexit ixp4xx_spkr_remove(struct platform_device *dev) static void ixp4xx_spkr_shutdown(struct platform_device *dev) { struct input_dev *input_dev = platform_get_drvdata(dev); - unsigned int pin = (unsigned int) input_get_drvdata(input_dev); + unsigned int pin = (unsigned int) input_dev->private; /* turn off the speaker */ disable_irq(IRQ_IXP4XX_TIMER2); diff --git a/trunk/drivers/input/misc/m68kspkr.c b/trunk/drivers/input/misc/m68kspkr.c index e9f26e766b4d..8d6c3837badb 100644 --- a/trunk/drivers/input/misc/m68kspkr.c +++ b/trunk/drivers/input/misc/m68kspkr.c @@ -63,7 +63,7 @@ static int __devinit m68kspkr_probe(struct platform_device *dev) input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = &dev->dev; + input_dev->cdev.dev = &dev->dev; input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); diff --git a/trunk/drivers/input/misc/pcspkr.c b/trunk/drivers/input/misc/pcspkr.c index 31989dcd922c..afd322185bbf 100644 --- a/trunk/drivers/input/misc/pcspkr.c +++ b/trunk/drivers/input/misc/pcspkr.c @@ -78,7 +78,7 @@ static int __devinit pcspkr_probe(struct platform_device *dev) pcspkr_dev->id.vendor = 0x001f; pcspkr_dev->id.product = 0x0001; pcspkr_dev->id.version = 0x0100; - pcspkr_dev->dev.parent = &dev->dev; + pcspkr_dev->cdev.dev = &dev->dev; pcspkr_dev->evbit[0] = BIT(EV_SND); pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); diff --git a/trunk/drivers/input/misc/sparcspkr.c b/trunk/drivers/input/misc/sparcspkr.c index e36ec1d92be8..106c94f33b93 100644 --- a/trunk/drivers/input/misc/sparcspkr.c +++ b/trunk/drivers/input/misc/sparcspkr.c @@ -28,7 +28,7 @@ struct sparcspkr_state { static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent); + struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); unsigned int count = 0; unsigned long flags; @@ -61,7 +61,7 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct sparcspkr_state *state = dev_get_drvdata(dev->dev.parent); + struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); unsigned int count = 0; unsigned long flags; @@ -113,7 +113,7 @@ static int __devinit sparcspkr_probe(struct device *dev) input_dev->id.vendor = 0x001f; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->dev.parent = dev; + input_dev->cdev.dev = dev; input_dev->evbit[0] = BIT(EV_SND); input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); diff --git a/trunk/drivers/input/misc/uinput.c b/trunk/drivers/input/misc/uinput.c index a56ad4ba8fe2..42556232c523 100644 --- a/trunk/drivers/input/misc/uinput.c +++ b/trunk/drivers/input/misc/uinput.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -40,7 +41,9 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - struct uinput_device *udev = input_get_drvdata(dev); + struct uinput_device *udev; + + udev = dev->private; udev->buff[udev->head].type = type; udev->buff[udev->head].code = code; @@ -133,7 +136,7 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff request.u.upload.effect = effect; request.u.upload.old = old; - retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request); + retval = uinput_request_reserve_slot(dev->private, &request); if (!retval) retval = uinput_request_submit(dev, &request); @@ -153,7 +156,7 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) request.code = UI_FF_ERASE; request.u.effect_id = effect_id; - retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request); + retval = uinput_request_reserve_slot(dev->private, &request); if (!retval) retval = uinput_request_submit(dev, &request); @@ -271,7 +274,7 @@ static int uinput_allocate_device(struct uinput_device *udev) return -ENOMEM; udev->dev->event = uinput_dev_event; - input_set_drvdata(udev->dev, udev); + udev->dev->private = udev; return 0; } diff --git a/trunk/drivers/input/misc/wistron_btns.c b/trunk/drivers/input/misc/wistron_btns.c index 961aad7a0476..e1183aeb8ed5 100644 --- a/trunk/drivers/input/misc/wistron_btns.c +++ b/trunk/drivers/input/misc/wistron_btns.c @@ -50,7 +50,7 @@ MODULE_AUTHOR("Miloslav Trmac "); MODULE_DESCRIPTION("Wistron laptop button driver"); MODULE_LICENSE("GPL v2"); -MODULE_VERSION("0.2"); +MODULE_VERSION("0.1"); static int force; /* = 0; */ module_param(force, bool, 0); @@ -58,7 +58,7 @@ MODULE_PARM_DESC(force, "Load even if computer is not in database"); static char *keymap_name; /* = NULL; */ module_param_named(keymap, keymap_name, charp, 0); -MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]"); +MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected"); static struct platform_device *wistron_device; @@ -233,20 +233,10 @@ static void bios_set_state(u8 subsys, int enable) struct key_entry { char type; /* See KE_* below */ u8 code; - union { - u16 keycode; /* For KE_KEY */ - struct { /* For KE_SW */ - u8 code; - u8 value; - } sw; - }; + unsigned keycode; /* For KE_KEY */ }; -enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; - -#define FE_MAIL_LED 0x01 -#define FE_WIFI_LED 0x02 -#define FE_UNTESTED 0x80 +enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH }; static const struct key_entry *keymap; /* = NULL; Current key map */ static int have_wifi; @@ -266,341 +256,93 @@ static int __init dmi_matched(struct dmi_system_id *dmi) return 1; } -static struct key_entry keymap_empty[] __initdata = { +static struct key_entry keymap_empty[] = { { KE_END, 0 } }; -static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_WIFI, 0x30 }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, +static struct key_entry keymap_fs_amilo_pro_v2000[] = { + { KE_KEY, 0x01, KEY_HELP }, + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_WIFI, 0x30, 0 }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, { KE_END, 0 } }; -static struct key_entry keymap_fujitsu_n3510[] __initdata = { - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x71, {KEY_STOPCD} }, - { KE_KEY, 0x72, {KEY_PLAYPAUSE} }, - { KE_KEY, 0x74, {KEY_REWIND} }, - { KE_KEY, 0x78, {KEY_FORWARD} }, +static struct key_entry keymap_fujitsu_n3510[] = { + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_KEY, 0x36, KEY_WWW }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x71, KEY_STOPCD }, + { KE_KEY, 0x72, KEY_PLAYPAUSE }, + { KE_KEY, 0x74, KEY_REWIND }, + { KE_KEY, 0x78, KEY_FORWARD }, { KE_END, 0 } }; -static struct key_entry keymap_wistron_ms2111[] __initdata = { - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_PROG3} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_END, FE_MAIL_LED } -}; - -static struct key_entry keymap_wistron_md40100[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ - { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_wistron_ms2141[] __initdata = { - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_WIFI, 0x30 }, - { KE_KEY, 0x22, {KEY_REWIND} }, - { KE_KEY, 0x23, {KEY_FORWARD} }, - { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, - { KE_KEY, 0x25, {KEY_STOPCD} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, +static struct key_entry keymap_wistron_ms2111[] = { + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_KEY, 0x13, KEY_PROG3 }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, { KE_END, 0 } }; -static struct key_entry keymap_acer_aspire_1500[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x03, {KEY_POWER} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_WIFI, 0x30 }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x49, {KEY_CONFIG} }, - { KE_BLUETOOTH, 0x44 }, - { KE_END, FE_UNTESTED } -}; - -static struct key_entry keymap_acer_aspire_1600[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x03, {KEY_POWER} }, - { KE_KEY, 0x08, {KEY_MUTE} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_PROG3} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x49, {KEY_CONFIG} }, - { KE_WIFI, 0x30 }, - { KE_BLUETOOTH, 0x44 }, - { KE_END, FE_MAIL_LED | FE_UNTESTED } -}; - -/* 3020 has been tested */ -static struct key_entry keymap_acer_aspire_5020[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x03, {KEY_POWER} }, - { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x6a, {KEY_CONFIG} }, - { KE_WIFI, 0x30 }, - { KE_BLUETOOTH, 0x44 }, - { KE_END, FE_MAIL_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_acer_travelmate_2410[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x6d, {KEY_POWER} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x6a, {KEY_CONFIG} }, - { KE_WIFI, 0x30 }, - { KE_BLUETOOTH, 0x44 }, - { KE_END, FE_MAIL_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_acer_travelmate_110[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x03, {KEY_POWER} }, - { KE_KEY, 0x08, {KEY_MUTE} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x20, {KEY_VOLUMEUP} }, - { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ - { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ - { KE_WIFI, 0x30 }, - { KE_END, FE_MAIL_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_acer_travelmate_300[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x03, {KEY_POWER} }, - { KE_KEY, 0x08, {KEY_MUTE} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x20, {KEY_VOLUMEUP} }, - { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_WIFI, 0x30 }, - { KE_BLUETOOTH, 0x44 }, - { KE_END, FE_MAIL_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_acer_travelmate_380[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x03, {KEY_POWER} }, /* not 370 */ - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_PROG3} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_WIFI, 0x30 }, - { KE_END, FE_MAIL_LED | FE_UNTESTED } -}; - -/* unusual map */ -static struct key_entry keymap_acer_travelmate_220[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x11, {KEY_MAIL} }, - { KE_KEY, 0x12, {KEY_WWW} }, - { KE_KEY, 0x13, {KEY_PROG2} }, - { KE_KEY, 0x31, {KEY_PROG1} }, - { KE_END, FE_WIFI_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_acer_travelmate_230[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_END, FE_WIFI_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_acer_travelmate_240[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x03, {KEY_POWER} }, - { KE_KEY, 0x08, {KEY_MUTE} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_BLUETOOTH, 0x44 }, - { KE_WIFI, 0x30 }, - { KE_END, FE_UNTESTED } -}; - -static struct key_entry keymap_acer_travelmate_350[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_MAIL} }, - { KE_KEY, 0x14, {KEY_PROG3} }, - { KE_KEY, 0x15, {KEY_WWW} }, - { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_acer_travelmate_360[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_MAIL} }, - { KE_KEY, 0x14, {KEY_PROG3} }, - { KE_KEY, 0x15, {KEY_WWW} }, - { KE_KEY, 0x40, {KEY_WLAN} }, - { KE_END, FE_WIFI_LED | FE_UNTESTED } /* no mail led */ +static struct key_entry keymap_wistron_ms2141[] = { + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_WIFI, 0x30, 0 }, + { KE_KEY, 0x22, KEY_REWIND }, + { KE_KEY, 0x23, KEY_FORWARD }, + { KE_KEY, 0x24, KEY_PLAYPAUSE }, + { KE_KEY, 0x25, KEY_STOPCD }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, + { KE_END, 0 } }; -/* Wifi subsystem only activates the led. Therefore we need to pass - * wifi event as a normal key, then userspace can really change the wifi state. - * TODO we need to export led state to userspace (wifi and mail) */ -static struct key_entry keymap_acer_travelmate_610[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_PROG3} }, - { KE_KEY, 0x14, {KEY_MAIL} }, - { KE_KEY, 0x15, {KEY_WWW} }, - { KE_KEY, 0x40, {KEY_WLAN} }, - { KE_END, FE_MAIL_LED | FE_WIFI_LED } +static struct key_entry keymap_acer_aspire_1500[] = { + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_WIFI, 0x30, 0 }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, + { KE_BLUETOOTH, 0x44, 0 }, + { KE_END, 0 } }; -static struct key_entry keymap_acer_travelmate_630[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x03, {KEY_POWER} }, - { KE_KEY, 0x08, {KEY_MUTE} }, /* not 620 */ - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_PROG3} }, - { KE_KEY, 0x20, {KEY_VOLUMEUP} }, - { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_WIFI, 0x30 }, - { KE_END, FE_MAIL_LED | FE_UNTESTED } +static struct key_entry keymap_acer_travelmate_240[] = { + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_BLUETOOTH, 0x44, 0 }, + { KE_WIFI, 0x30, 0 }, + { KE_END, 0 } }; -static struct key_entry keymap_aopen_1559as[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x06, {KEY_PROG3} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_WIFI, 0x30 }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, +static struct key_entry keymap_aopen_1559as[] = { + { KE_KEY, 0x01, KEY_HELP }, + { KE_KEY, 0x06, KEY_PROG3 }, + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_WIFI, 0x30, 0 }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, { KE_END, 0 }, }; -static struct key_entry keymap_fs_amilo_d88x0[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x08, {KEY_MUTE} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_PROG3} }, - { KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_wistron_md2900[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_WIFI, 0x30 }, - { KE_END, FE_MAIL_LED | FE_UNTESTED } -}; - -static struct key_entry keymap_wistron_md96500[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ - { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ - { KE_KEY, 0x08, {KEY_MUTE} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x20, {KEY_VOLUMEUP} }, - { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, - { KE_KEY, 0x22, {KEY_REWIND} }, - { KE_KEY, 0x23, {KEY_FORWARD} }, - { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, - { KE_KEY, 0x25, {KEY_STOPCD} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_WIFI, 0x30 }, - { KE_BLUETOOTH, 0x44 }, - { KE_END, FE_UNTESTED } -}; - -static struct key_entry keymap_wistron_generic[] __initdata = { - { KE_KEY, 0x01, {KEY_HELP} }, - { KE_KEY, 0x02, {KEY_CONFIG} }, - { KE_KEY, 0x03, {KEY_POWER} }, - { KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ - { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ - { KE_KEY, 0x08, {KEY_MUTE} }, - { KE_KEY, 0x11, {KEY_PROG1} }, - { KE_KEY, 0x12, {KEY_PROG2} }, - { KE_KEY, 0x13, {KEY_PROG3} }, - { KE_KEY, 0x14, {KEY_MAIL} }, - { KE_KEY, 0x15, {KEY_WWW} }, - { KE_KEY, 0x20, {KEY_VOLUMEUP} }, - { KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, - { KE_KEY, 0x22, {KEY_REWIND} }, - { KE_KEY, 0x23, {KEY_FORWARD} }, - { KE_KEY, 0x24, {KEY_PLAYPAUSE} }, - { KE_KEY, 0x25, {KEY_STOPCD} }, - { KE_KEY, 0x31, {KEY_MAIL} }, - { KE_KEY, 0x36, {KEY_WWW} }, - { KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ - { KE_KEY, 0x40, {KEY_WLAN} }, - { KE_KEY, 0x49, {KEY_CONFIG} }, - { KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ - { KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ - { KE_KEY, 0x6a, {KEY_CONFIG} }, - { KE_KEY, 0x6d, {KEY_POWER} }, - { KE_KEY, 0x71, {KEY_STOPCD} }, - { KE_KEY, 0x72, {KEY_PLAYPAUSE} }, - { KE_KEY, 0x74, {KEY_REWIND} }, - { KE_KEY, 0x78, {KEY_FORWARD} }, - { KE_WIFI, 0x30 }, - { KE_BLUETOOTH, 0x44 }, +static struct key_entry keymap_fs_amilo_d88x0[] = { + { KE_KEY, 0x01, KEY_HELP }, + { KE_KEY, 0x08, KEY_MUTE }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_KEY, 0x13, KEY_PROG3 }, { KE_END, 0 } }; @@ -646,133 +388,6 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, .driver_data = keymap_acer_aspire_1500 }, - { - .callback = dmi_matched, - .ident = "Acer Aspire 1600", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), - }, - .driver_data = keymap_acer_aspire_1600 - }, - { - .callback = dmi_matched, - .ident = "Acer Aspire 3020", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), - }, - .driver_data = keymap_acer_aspire_5020 - }, - { - .callback = dmi_matched, - .ident = "Acer Aspire 5020", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), - }, - .driver_data = keymap_acer_aspire_5020 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 2100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), - }, - .driver_data = keymap_acer_aspire_5020 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 2410", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), - }, - .driver_data = keymap_acer_travelmate_2410 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate C300", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), - }, - .driver_data = keymap_acer_travelmate_300 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate C100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), - }, - .driver_data = keymap_acer_travelmate_300 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate C110", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), - }, - .driver_data = keymap_acer_travelmate_110 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 380", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), - }, - .driver_data = keymap_acer_travelmate_380 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 370", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), - }, - .driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 220", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), - }, - .driver_data = keymap_acer_travelmate_220 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 260", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), - }, - .driver_data = keymap_acer_travelmate_220 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 230", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), - /* acerhk looks for "TravelMate F4..." ?! */ - }, - .driver_data = keymap_acer_travelmate_230 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 280", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), - }, - .driver_data = keymap_acer_travelmate_230 - }, { .callback = dmi_matched, .ident = "Acer TravelMate 240", @@ -782,15 +397,6 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, .driver_data = keymap_acer_travelmate_240 }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 250", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), - }, - .driver_data = keymap_acer_travelmate_240 - }, { .callback = dmi_matched, .ident = "Acer TravelMate 2424NWXCi", @@ -800,51 +406,6 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, .driver_data = keymap_acer_travelmate_240 }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 350", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), - }, - .driver_data = keymap_acer_travelmate_350 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 360", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), - }, - .driver_data = keymap_acer_travelmate_360 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 610", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ACER"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), - }, - .driver_data = keymap_acer_travelmate_610 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 620", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), - }, - .driver_data = keymap_acer_travelmate_630 - }, - { - .callback = dmi_matched, - .ident = "Acer TravelMate 630", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), - }, - .driver_data = keymap_acer_travelmate_630 - }, { .callback = dmi_matched, .ident = "AOpen 1559AS", @@ -863,51 +424,6 @@ static struct dmi_system_id dmi_ids[] __initdata = { }, .driver_data = keymap_wistron_ms2111 }, - { - .callback = dmi_matched, - .ident = "Medion MD 40100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), - DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), - }, - .driver_data = keymap_wistron_md40100 - }, - { - .callback = dmi_matched, - .ident = "Medion MD 2900", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), - DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), - }, - .driver_data = keymap_wistron_md2900 - }, - { - .callback = dmi_matched, - .ident = "Medion MD 96500", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), - DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), - }, - .driver_data = keymap_wistron_md96500 - }, - { - .callback = dmi_matched, - .ident = "Medion MD 95400", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), - DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), - }, - .driver_data = keymap_wistron_md96500 - }, - { - .callback = dmi_matched, - .ident = "Fujitsu Siemens Amilo D7820", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ - DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), - }, - .driver_data = keymap_fs_amilo_d88x0 - }, { .callback = dmi_matched, .ident = "Fujitsu Siemens Amilo D88x0", @@ -920,39 +436,17 @@ static struct dmi_system_id dmi_ids[] __initdata = { { NULL, } }; -/* Copy the good keymap, as the original ones are free'd */ -static int __init copy_keymap(void) -{ - const struct key_entry *key; - struct key_entry *new_keymap; - unsigned int length = 1; - - for (key = keymap; key->type != KE_END; key++) - length++; - - new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL); - if (!new_keymap) - return -ENOMEM; - - memcpy(new_keymap, keymap, length * sizeof(struct key_entry)); - keymap = new_keymap; - - return 0; -} - static int __init select_keymap(void) { - dmi_check_system(dmi_ids); if (keymap_name != NULL) { if (strcmp (keymap_name, "1557/MS2141") == 0) keymap = keymap_wistron_ms2141; - else if (strcmp (keymap_name, "generic") == 0) - keymap = keymap_wistron_generic; else { printk(KERN_ERR "wistron_btns: Keymap unknown\n"); return -EINVAL; } } + dmi_check_system(dmi_ids); if (keymap == NULL) { if (!force) { printk(KERN_ERR "wistron_btns: System unknown\n"); @@ -960,8 +454,7 @@ static int __init select_keymap(void) } keymap = keymap_empty; } - - return copy_keymap(); + return 0; } /* Input layer interface */ @@ -983,28 +476,12 @@ static int __devinit setup_input_dev(void) input_dev->cdev.dev = &wistron_device->dev; for (key = keymap; key->type != KE_END; key++) { - switch (key->type) { - case KE_KEY: - set_bit(EV_KEY, input_dev->evbit); - set_bit(key->keycode, input_dev->keybit); - break; - - case KE_SW: - set_bit(EV_SW, input_dev->evbit); - set_bit(key->sw.code, input_dev->swbit); - break; - - default: - ; + if (key->type == KE_KEY) { + input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY); + set_bit(key->keycode, input_dev->keybit); } } - /* reads information flags on KE_END */ - if (key->code & FE_UNTESTED) - printk(KERN_WARNING "Untested laptop multimedia keys, " - "please report success or failure to eric.piel" - "@tremplin-utc.net\n"); - error = input_register_device(input_dev); if (error) { input_free_device(input_dev); @@ -1022,12 +499,6 @@ static void report_key(unsigned keycode) input_sync(input_dev); } -static void report_switch(unsigned code, int value) -{ - input_report_switch(input_dev, code, value); - input_sync(input_dev); -} - /* Driver core */ static int wifi_enabled; @@ -1048,10 +519,6 @@ static void handle_key(u8 code) report_key(key->keycode); break; - case KE_SW: - report_switch(key->sw.code, key->sw.value); - break; - case KE_WIFI: if (have_wifi) { wifi_enabled = !wifi_enabled; @@ -1067,7 +534,6 @@ static void handle_key(u8 code) break; case KE_END: - break; default: BUG(); } @@ -1224,7 +690,6 @@ static void __exit wb_module_exit(void) platform_device_unregister(wistron_device); platform_driver_unregister(&wistron_driver); unmap_bios(); - kfree(keymap); } module_init(wb_module_init); diff --git a/trunk/drivers/input/mouse/Kconfig b/trunk/drivers/input/mouse/Kconfig index 2ccc114b3ff6..35d998c3e578 100644 --- a/trunk/drivers/input/mouse/Kconfig +++ b/trunk/drivers/input/mouse/Kconfig @@ -2,7 +2,7 @@ # Mouse driver configuration # menuconfig INPUT_MOUSE - bool "Mice" + bool "Mouse" default y help Say Y here, and a list of supported mice will be displayed. @@ -19,7 +19,7 @@ config MOUSE_PS2 select SERIO_LIBPS2 select SERIO_I8042 if X86_PC select SERIO_GSCPS2 if GSC - help + ---help--- Say Y here if you have a PS/2 mouse connected to your system. This includes the standard 2 or 3-button PS/2 mouse, as well as PS/2 mice with wheels and extra buttons, Microsoft, Logitech or Genius @@ -37,69 +37,10 @@ config MOUSE_PS2 To compile this driver as a module, choose M here: the module will be called psmouse. -config MOUSE_PS2_ALPS - bool "ALPS PS/2 mouse protocol extension" if EMBEDDED - default y - depends on MOUSE_PS2 - help - Say Y here if you have an ALPS PS/2 touchpad connected to - your system. - - If unsure, say Y. - -config MOUSE_PS2_LOGIPS2PP - bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED - default y - depends on MOUSE_PS2 - help - Say Y here if you have a Logictech PS/2++ mouse connected to - your system. - - If unsure, say Y. - -config MOUSE_PS2_SYNAPTICS - bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED - default y - depends on MOUSE_PS2 - help - Say Y here if you have a Synaptics PS/2 TouchPad connected to - your system. - - If unsure, say Y. - -config MOUSE_PS2_LIFEBOOK - bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED - default y - depends on MOUSE_PS2 - help - Say Y here if you have a Fujitsu B-series Lifebook PS/2 - TouchScreen connected to your system. - - If unsure, say Y. - -config MOUSE_PS2_TRACKPOINT - bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED - default y - depends on MOUSE_PS2 - help - Say Y here if you have an IBM Trackpoint PS/2 mouse connected - to your system. - - If unsure, say Y. - -config MOUSE_PS2_TOUCHKIT - bool "eGalax TouchKit PS/2 protocol extension" - depends on MOUSE_PS2 - help - Say Y here if you have an eGalax TouchKit PS/2 touchscreen - connected to your system. - - If unsure, say N. - config MOUSE_SERIAL tristate "Serial mouse" select SERIO - help + ---help--- Say Y here if you have a serial (RS-232, COM port) mouse connected to your system. This includes Sun, MouseSystems, Microsoft, Logitech and all other compatible serial mice. @@ -109,26 +50,6 @@ config MOUSE_SERIAL To compile this driver as a module, choose M here: the module will be called sermouse. -config MOUSE_APPLETOUCH - tristate "Apple USB Touchpad support" - select USB - help - Say Y here if you want to use an Apple USB Touchpad. - - These are the touchpads that can be found on post-February 2005 - Apple Powerbooks (prior models have a Synaptics touchpad connected - to the ADB bus). - - This driver provides a basic mouse driver but can be interfaced - with the synaptics X11 driver to provide acceleration and - scrolling in X11. - - For further information, see - . - - To compile this driver as a module, choose M here: the - module will be called appletouch. - config MOUSE_INPORT tristate "InPort/MS/ATIXL busmouse" depends on ISA @@ -175,17 +96,6 @@ config MOUSE_AMIGA To compile this driver as a module, choose M here: the module will be called amimouse. -config MOUSE_ATARI - tristate "Atari mouse" - depends on ATARI - select ATARI_KBD_CORE - help - Say Y here if you have an Atari and want its native mouse - supported by the kernel. - - To compile this driver as a module, choose M here: the - module will be called atarimouse. - config MOUSE_RISCPC tristate "Acorn RiscPC mouse" depends on ARCH_ACORN @@ -208,7 +118,7 @@ config MOUSE_VSXXXAA digitizer (VSXXX-AB) DEC produced. config MOUSE_HIL - tristate "HIL pointers (mice etc)." + tristate "HIL pointers (mice etc)." depends on GSC || HP300 select HP_SDC select HIL_MLC diff --git a/trunk/drivers/input/mouse/Makefile b/trunk/drivers/input/mouse/Makefile index aa4ba878533f..21a1de61a79b 100644 --- a/trunk/drivers/input/mouse/Makefile +++ b/trunk/drivers/input/mouse/Makefile @@ -5,8 +5,6 @@ # Each configuration option enables a list of files. obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o -obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o -obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o obj-$(CONFIG_MOUSE_INPORT) += inport.o obj-$(CONFIG_MOUSE_LOGIBM) += logibm.o @@ -16,10 +14,4 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o -psmouse-objs := psmouse-base.o synaptics.o - -psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o -psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o -psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o -psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o -psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o +psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o trackpoint.o diff --git a/trunk/drivers/input/mouse/alps.c b/trunk/drivers/input/mouse/alps.c index cf3e4664e72b..4e71a66fc7fc 100644 --- a/trunk/drivers/input/mouse/alps.c +++ b/trunk/drivers/input/mouse/alps.c @@ -424,15 +424,14 @@ int alps_init(struct psmouse *psmouse) struct input_dev *dev1 = psmouse->dev, *dev2; int version; - priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); + psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); dev2 = input_allocate_device(); if (!priv || !dev2) goto init_fail; priv->dev2 = dev2; - priv->i = alps_get_model(psmouse, &version); - if (!priv->i) + if (!(priv->i = alps_get_model(psmouse, &version))) goto init_fail; if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) @@ -481,8 +480,7 @@ int alps_init(struct psmouse *psmouse) dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - if (input_register_device(priv->dev2)) - goto init_fail; + input_register_device(priv->dev2); psmouse->protocol_handler = alps_process_byte; psmouse->poll = alps_poll; @@ -493,11 +491,9 @@ int alps_init(struct psmouse *psmouse) /* We are having trouble resyncing ALPS touchpads so disable it for now */ psmouse->resync_time = 0; - psmouse->private = priv; return 0; init_fail: - psmouse_reset(psmouse); input_free_device(dev2); kfree(priv); return -1; @@ -508,8 +504,7 @@ int alps_detect(struct psmouse *psmouse, int set_properties) int version; const struct alps_model_info *model; - model = alps_get_model(psmouse, &version); - if (!model) + if (!(model = alps_get_model(psmouse, &version))) return -1; if (set_properties) { diff --git a/trunk/drivers/input/mouse/alps.h b/trunk/drivers/input/mouse/alps.h index 4bbddc99962b..69db7325a494 100644 --- a/trunk/drivers/input/mouse/alps.h +++ b/trunk/drivers/input/mouse/alps.h @@ -12,6 +12,9 @@ #ifndef _ALPS_H #define _ALPS_H +int alps_detect(struct psmouse *psmouse, int set_properties); +int alps_init(struct psmouse *psmouse); + struct alps_model_info { unsigned char signature[3]; unsigned char byte0, mask0; @@ -20,23 +23,10 @@ struct alps_model_info { struct alps_data { struct input_dev *dev2; /* Relative device */ + char name[32]; /* Name */ char phys[32]; /* Phys */ const struct alps_model_info *i;/* Info */ int prev_fin; /* Finger bit from previous packet */ }; -#ifdef CONFIG_MOUSE_PS2_ALPS -int alps_detect(struct psmouse *psmouse, int set_properties); -int alps_init(struct psmouse *psmouse); -#else -inline int alps_detect(struct psmouse *psmouse, int set_properties) -{ - return -ENOSYS; -} -inline int alps_init(struct psmouse *psmouse) -{ - return -ENOSYS; -} -#endif /* CONFIG_MOUSE_PS2_ALPS */ - #endif diff --git a/trunk/drivers/input/mouse/atarimouse.c b/trunk/drivers/input/mouse/atarimouse.c deleted file mode 100644 index 43ab6566fb65..000000000000 --- a/trunk/drivers/input/mouse/atarimouse.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Atari mouse driver for Linux/m68k - * - * Copyright (c) 2005 Michael Schmitz - * - * Based on: - * Amiga mouse driver for Linux/m68k - * - * Copyright (c) 2000-2002 Vojtech Pavlik - * - */ -/* - * The low level init and interrupt stuff is handled in arch/mm68k/atari/atakeyb.c - * (the keyboard ACIA also handles the mouse and joystick data, and the keyboard - * interrupt is shared with the MIDI ACIA so MIDI data also get handled there). - * This driver only deals with handing key events off to the input layer. - * - * Largely based on the old: - * - * Atari Mouse Driver for Linux - * by Robert de Vries (robert@and.nl) 19Jul93 - * - * 16 Nov 1994 Andreas Schwab - * Compatibility with busmouse - * Support for three button mouse (shamelessly stolen from MiNT) - * third button wired to one of the joystick directions on joystick 1 - * - * 1996/02/11 Andreas Schwab - * Module support - * Allow multiple open's - * - * Converted to use new generic busmouse code. 5 Apr 1998 - * Russell King - */ - - -/* - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Michael Schmitz "); -MODULE_DESCRIPTION("Atari mouse driver"); -MODULE_LICENSE("GPL"); - -static int mouse_threshold[2] = {2,2}; - -#ifdef __MODULE__ -MODULE_PARM(mouse_threshold, "2i"); -#endif -#ifdef FIXED_ATARI_JOYSTICK -extern int atari_mouse_buttons; -#endif -static int atamouse_used = 0; - -static struct input_dev *atamouse_dev; - -static void atamouse_interrupt(char *buf) -{ - int buttons, dx, dy; - -/* ikbd_mouse_disable(); */ - - buttons = (buf[0] & 1) | ((buf[0] & 2) << 1); -#ifdef FIXED_ATARI_JOYSTICK - buttons |= atari_mouse_buttons & 2; - atari_mouse_buttons = buttons; -#endif -/* ikbd_mouse_rel_pos(); */ - - /* only relative events get here */ - dx = buf[1]; - dy = -buf[2]; - - input_report_rel(atamouse_dev, REL_X, dx); - input_report_rel(atamouse_dev, REL_Y, dy); - - input_report_key(atamouse_dev, BTN_LEFT, buttons & 0x1); - input_report_key(atamouse_dev, BTN_MIDDLE, buttons & 0x2); - input_report_key(atamouse_dev, BTN_RIGHT, buttons & 0x4); - - input_sync(atamouse_dev); - - return; -} - -static int atamouse_open(struct input_dev *dev) -{ - if (atamouse_used++) - return 0; - -#ifdef FIXED_ATARI_JOYSTICK - atari_mouse_buttons = 0; -#endif - ikbd_mouse_y0_top(); - ikbd_mouse_thresh(mouse_threshold[0], mouse_threshold[1]); - ikbd_mouse_rel_pos(); - atari_input_mouse_interrupt_hook = atamouse_interrupt; - return 0; -} - -static void atamouse_close(struct input_dev *dev) -{ - if (!--atamouse_used) { - ikbd_mouse_disable(); - atari_mouse_interrupt_hook = NULL; - } -} - -static int __init atamouse_init(void) -{ - if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP)) - return -ENODEV; - - if (!(atamouse_dev = input_allocate_device())) - return -ENOMEM; - - if (!(atari_keyb_init())) - return -ENODEV; - - atamouse_dev->name = "Atari mouse"; - atamouse_dev->phys = "atamouse/input0"; - atamouse_dev->id.bustype = BUS_ATARI; - atamouse_dev->id.vendor = 0x0001; - atamouse_dev->id.product = 0x0002; - atamouse_dev->id.version = 0x0100; - - atamouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - atamouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); - atamouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - atamouse_dev->open = atamouse_open; - atamouse_dev->close = atamouse_close; - - input_register_device(atamouse_dev); - - printk(KERN_INFO "input: %s at keyboard ACIA\n", atamouse_dev->name); - return 0; -} - -static void __exit atamouse_exit(void) -{ - input_unregister_device(atamouse_dev); -} - -module_init(atamouse_init); -module_exit(atamouse_exit); diff --git a/trunk/drivers/input/mouse/hil_ptr.c b/trunk/drivers/input/mouse/hil_ptr.c index 449bf4dcbbcc..bfb174fe3230 100644 --- a/trunk/drivers/input/mouse/hil_ptr.c +++ b/trunk/drivers/input/mouse/hil_ptr.c @@ -88,12 +88,10 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) idx = ptr->idx4/4; p = data[idx - 1]; - if ((p & ~HIL_CMDCT_POL) == - (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) - goto report; - if ((p & ~HIL_CMDCT_RPL) == - (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) - goto report; + if ((p & ~HIL_CMDCT_POL) == + (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; + if ((p & ~HIL_CMDCT_RPL) == + (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; /* Not a poll response. See if we are loading config records. */ switch (p & HIL_PKT_DATA_MASK) { @@ -103,32 +101,27 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) for (; i < HIL_PTR_MAX_LENGTH; i++) ptr->idd[i] = 0; break; - case HIL_CMD_RSC: for (i = 0; i < idx; i++) ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_PTR_MAX_LENGTH; i++) ptr->rsc[i] = 0; break; - case HIL_CMD_EXD: for (i = 0; i < idx; i++) ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_PTR_MAX_LENGTH; i++) ptr->exd[i] = 0; break; - case HIL_CMD_RNM: for (i = 0; i < idx; i++) ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; for (; i < HIL_PTR_MAX_LENGTH + 1; i++) - ptr->rnm[i] = 0; + ptr->rnm[i] = '\0'; break; - default: /* These occur when device isn't present */ - if (p == (HIL_ERR_INT | HIL_PKT_CMD)) - break; + if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; /* Anything else we'd like to know about. */ printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); break; @@ -137,8 +130,7 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) report: if ((p & HIL_CMDCT_POL) != idx - 1) { - printk(KERN_WARNING PREFIX - "Malformed poll packet %x (idx = %i)\n", p, idx); + printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx); goto out; } @@ -147,7 +139,7 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) laxis += i; ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ - absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; + absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; for (cnt = 1; i < laxis; i++) { unsigned int lo,hi,val; @@ -165,8 +157,7 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) input_report_abs(dev, ABS_X + i, val); } else { val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); - if (i%3) - val *= -1; + if (i%3) val *= -1; input_report_rel(dev, REL_X + i, val); } } @@ -177,11 +168,10 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) btn = ptr->data[cnt++]; up = btn & 1; btn &= 0xfe; - if (btn == 0x8e) + if (btn == 0x8e) { continue; /* TODO: proximity == touch? */ - else - if ((btn > 0x8c) || (btn < 0x80)) - continue; + } + else if ((btn > 0x8c) || (btn < 0x80)) continue; btn = (btn - 0x80) >> 1; btn = ptr->btnmap[btn]; input_report_key(dev, btn, !up); @@ -192,14 +182,14 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) up(&ptr->sem); } -static void hil_ptr_process_err(struct hil_ptr *ptr) -{ +static void hil_ptr_process_err(struct hil_ptr *ptr) { printk(KERN_WARNING PREFIX "errored HIL packet\n"); ptr->idx4 = 0; up(&ptr->sem); + return; } -static irqreturn_t hil_ptr_interrupt(struct serio *serio, +static irqreturn_t hil_ptr_interrupt(struct serio *serio, unsigned char data, unsigned int flags) { struct hil_ptr *ptr; @@ -207,29 +197,29 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio, int idx; ptr = serio_get_drvdata(serio); - BUG_ON(ptr == NULL); + if (ptr == NULL) { + BUG(); + return IRQ_HANDLED; + } if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { hil_ptr_process_err(ptr); return IRQ_HANDLED; } idx = ptr->idx4/4; - if (!(ptr->idx4 % 4)) - ptr->data[idx] = 0; + if (!(ptr->idx4 % 4)) ptr->data[idx] = 0; packet = ptr->data[idx]; packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); ptr->data[idx] = packet; /* Records of N 4-byte hil_packets must terminate with a command. */ - if ((++(ptr->idx4)) % 4) - return IRQ_HANDLED; + if ((++(ptr->idx4)) % 4) return IRQ_HANDLED; if ((packet & 0xffff0000) != HIL_ERR_INT) { hil_ptr_process_err(ptr); return IRQ_HANDLED; } - if (packet & HIL_PKT_CMD) + if (packet & HIL_PKT_CMD) hil_ptr_process_record(ptr); - return IRQ_HANDLED; } @@ -238,7 +228,10 @@ static void hil_ptr_disconnect(struct serio *serio) struct hil_ptr *ptr; ptr = serio_get_drvdata(serio); - BUG_ON(ptr == NULL); + if (ptr == NULL) { + BUG(); + return; + } serio_close(serio); input_unregister_device(ptr->dev); @@ -248,7 +241,7 @@ static void hil_ptr_disconnect(struct serio *serio) static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) { struct hil_ptr *ptr; - const char *txt; + char *txt; unsigned int i, naxsets, btntype; uint8_t did, *idd; @@ -259,40 +252,42 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) if (!ptr->dev) goto bail0; + ptr->dev->private = ptr; + if (serio_open(serio, driver)) goto bail1; serio_set_drvdata(serio, ptr); ptr->serio = serio; - init_MUTEX_LOCKED(&ptr->sem); + init_MUTEX_LOCKED(&(ptr->sem)); /* Get device info. MLC driver supplies devid/status/etc. */ serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_IDD); - down(&ptr->sem); + down(&(ptr->sem)); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_RSC); - down(&ptr->sem); + down(&(ptr->sem)); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_RNM); - down(&ptr->sem); + down(&(ptr->sem)); serio->write(serio, 0); serio->write(serio, 0); serio->write(serio, HIL_PKT_CMD >> 8); serio->write(serio, HIL_CMD_EXD); - down(&ptr->sem); + down(&(ptr->sem)); - up(&ptr->sem); + up(&(ptr->sem)); did = ptr->idd[0]; idd = ptr->idd + 1; @@ -306,12 +301,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) ptr->dev->evbit[0] = BIT(EV_ABS); txt = "absolute"; } - if (!ptr->dev->evbit[0]) + if (!ptr->dev->evbit[0]) { goto bail2; + } ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); - if (ptr->nbtn) - ptr->dev->evbit[0] |= BIT(EV_KEY); + if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY); naxsets = HIL_IDD_NUM_AXSETS(*idd); ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); @@ -320,7 +315,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) did, txt); printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", ptr->nbtn, naxsets, ptr->naxes); - + btntype = BTN_MISC; if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) #ifdef TABLET_SIMULATES_MOUSE @@ -330,7 +325,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) #endif if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) btntype = BTN_TOUCH; - + if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) btntype = BTN_MOUSE; @@ -346,10 +341,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) } if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { - for (i = 0; i < ptr->naxes; i++) + for (i = 0; i < ptr->naxes; i++) { set_bit(REL_X + i, ptr->dev->relbit); - for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) + } + for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { set_bit(REL_X + i, ptr->dev->relbit); + } } else { for (i = 0; i < ptr->naxes; i++) { set_bit(ABS_X + i, ptr->dev->absbit); @@ -378,7 +375,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) ptr->dev->id.vendor = PCI_VENDOR_ID_HP; ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ - ptr->dev->dev.parent = &serio->dev; + ptr->dev->cdev.dev = &serio->dev; input_register_device(ptr->dev); printk(KERN_INFO "input: %s (%s), ID: %d\n", @@ -422,11 +419,11 @@ static int __init hil_ptr_init(void) { return serio_register_driver(&hil_ptr_serio_driver); } - + static void __exit hil_ptr_exit(void) { serio_unregister_driver(&hil_ptr_serio_driver); } - + module_init(hil_ptr_init); module_exit(hil_ptr_exit); diff --git a/trunk/drivers/input/mouse/lifebook.c b/trunk/drivers/input/mouse/lifebook.c index 1740cadd9594..29542f0631cb 100644 --- a/trunk/drivers/input/mouse/lifebook.c +++ b/trunk/drivers/input/mouse/lifebook.c @@ -20,27 +20,6 @@ #include "psmouse.h" #include "lifebook.h" -struct lifebook_data { - struct input_dev *dev2; /* Relative device */ - char phys[32]; -}; - -static const char *desired_serio_phys; - -static int lifebook_set_serio_phys(struct dmi_system_id *d) -{ - desired_serio_phys = d->driver_data; - return 0; -} - -static unsigned char lifebook_use_6byte_proto; - -static int lifebook_set_6byte_proto(struct dmi_system_id *d) -{ - lifebook_use_6byte_proto = 1; - return 0; -} - static struct dmi_system_id lifebook_dmi_table[] = { { .ident = "FLORA-ie 55mi", @@ -77,24 +56,6 @@ static struct dmi_system_id lifebook_dmi_table[] = { .matches = { DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), }, - .callback = lifebook_set_serio_phys, - .driver_data = "isa0060/serio3", - }, - { - .ident = "Panasonic CF-28", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), - DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"), - }, - .callback = lifebook_set_6byte_proto, - }, - { - .ident = "Panasonic CF-29", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), - DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), - }, - .callback = lifebook_set_6byte_proto, }, { .ident = "Lifebook B142", @@ -107,71 +68,31 @@ static struct dmi_system_id lifebook_dmi_table[] = { static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) { - struct lifebook_data *priv = psmouse->private; - struct input_dev *dev1 = psmouse->dev; - struct input_dev *dev2 = priv->dev2; unsigned char *packet = psmouse->packet; - int relative_packet = packet[0] & 0x08; + struct input_dev *dev = psmouse->dev; - if (relative_packet || !lifebook_use_6byte_proto) { - if (psmouse->pktcnt != 3) - return PSMOUSE_GOOD_DATA; - } else { - switch (psmouse->pktcnt) { - case 1: - return (packet[0] & 0xf8) == 0x00 ? - PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; - case 2: - return PSMOUSE_GOOD_DATA; - case 3: - return ((packet[2] & 0x30) << 2) == (packet[2] & 0xc0) ? - PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; - case 4: - return (packet[3] & 0xf8) == 0xc0 ? - PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; - case 5: - return (packet[4] & 0xc0) == (packet[2] & 0xc0) ? - PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; - case 6: - if (((packet[5] & 0x30) << 2) != (packet[5] & 0xc0)) - return PSMOUSE_BAD_DATA; - if ((packet[5] & 0xc0) != (packet[1] & 0xc0)) - return PSMOUSE_BAD_DATA; - break; /* report data */ - } - } + if (psmouse->pktcnt != 3) + return PSMOUSE_GOOD_DATA; - if (relative_packet) { - if (!dev2) - printk(KERN_WARNING "lifebook.c: got relative packet " - "but no relative device set up\n"); - } else if (lifebook_use_6byte_proto) { - input_report_abs(dev1, ABS_X, - ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f)); - input_report_abs(dev1, ABS_Y, - 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f))); - } else { - input_report_abs(dev1, ABS_X, + /* calculate X and Y */ + if ((packet[0] & 0x08) == 0x00) { + input_report_abs(dev, ABS_X, (packet[1] | ((packet[0] & 0x30) << 4))); - input_report_abs(dev1, ABS_Y, + input_report_abs(dev, ABS_Y, 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); - } - - input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04); - input_sync(dev1); - - if (dev2) { - if (relative_packet) { - input_report_rel(dev2, REL_X, + } else { + input_report_rel(dev, REL_X, ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); - input_report_rel(dev2, REL_Y, + input_report_rel(dev, REL_Y, -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); - } - input_report_key(dev2, BTN_LEFT, packet[0] & 0x01); - input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02); - input_sync(dev2); } + input_report_key(dev, BTN_LEFT, packet[0] & 0x01); + input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); + input_report_key(dev, BTN_TOUCH, packet[0] & 0x04); + + input_sync(dev); + return PSMOUSE_FULL_PACKET; } @@ -188,20 +109,12 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) you leave this call out the touchsreen will never send absolute coordinates */ - param = lifebook_use_6byte_proto ? 0x08 : 0x07; + param = 0x07; ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); return 0; } -static void lifebook_relative_mode(struct psmouse *psmouse) -{ - struct ps2dev *ps2dev = &psmouse->ps2dev; - unsigned char param = 0x06; - - ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); -} - static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) { static const unsigned char params[] = { 0, 1, 2, 2, 3 }; @@ -218,8 +131,6 @@ static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolu static void lifebook_disconnect(struct psmouse *psmouse) { psmouse_reset(psmouse); - kfree(psmouse->private); - psmouse->private = NULL; } int lifebook_detect(struct psmouse *psmouse, int set_properties) @@ -227,10 +138,6 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) if (!dmi_check_system(lifebook_dmi_table)) return -1; - if (desired_serio_phys && - strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys)) - return -1; - if (set_properties) { psmouse->vendor = "Fujitsu"; psmouse->name = "Lifebook TouchScreen"; @@ -239,78 +146,24 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) return 0; } -static int lifebook_create_relative_device(struct psmouse *psmouse) -{ - struct input_dev *dev2; - struct lifebook_data *priv; - int error = -ENOMEM; - - priv = kzalloc(sizeof(struct lifebook_data), GFP_KERNEL); - dev2 = input_allocate_device(); - if (!priv || !dev2) - goto err_out; - - priv->dev2 = dev2; - snprintf(priv->phys, sizeof(priv->phys), - "%s/input1", psmouse->ps2dev.serio->phys); - - dev2->phys = priv->phys; - dev2->name = "PS/2 Touchpad"; - dev2->id.bustype = BUS_I8042; - dev2->id.vendor = 0x0002; - dev2->id.product = PSMOUSE_LIFEBOOK; - dev2->id.version = 0x0000; - dev2->dev.parent = &psmouse->ps2dev.serio->dev; - - dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); - dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y); - dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); - - error = input_register_device(priv->dev2); - if (error) - goto err_out; - - psmouse->private = priv; - return 0; - - err_out: - input_free_device(dev2); - kfree(priv); - return error; -} - int lifebook_init(struct psmouse *psmouse) { - struct input_dev *dev1 = psmouse->dev; - int max_coord = lifebook_use_6byte_proto ? 1024 : 4096; + struct input_dev *input_dev = psmouse->dev; if (lifebook_absolute_mode(psmouse)) return -1; - dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); - dev1->relbit[0] = 0; - dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); - input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); - - if (!desired_serio_phys) { - if (lifebook_create_relative_device(psmouse)) { - lifebook_relative_mode(psmouse); - return -1; - } - } + input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0); psmouse->protocol_handler = lifebook_process_byte; psmouse->set_resolution = lifebook_set_resolution; psmouse->disconnect = lifebook_disconnect; psmouse->reconnect = lifebook_absolute_mode; - - psmouse->model = lifebook_use_6byte_proto ? 6 : 3; - - /* - * Use packet size = 3 even when using 6-byte protocol because - * that's what POLL will return on Lifebooks (according to spec). - */ psmouse->pktsize = 3; return 0; diff --git a/trunk/drivers/input/mouse/lifebook.h b/trunk/drivers/input/mouse/lifebook.h index c1647cf036c2..be1c0943825d 100644 --- a/trunk/drivers/input/mouse/lifebook.h +++ b/trunk/drivers/input/mouse/lifebook.h @@ -11,18 +11,7 @@ #ifndef _LIFEBOOK_H #define _LIFEBOOK_H -#ifdef CONFIG_MOUSE_PS2_LIFEBOOK int lifebook_detect(struct psmouse *psmouse, int set_properties); int lifebook_init(struct psmouse *psmouse); -#else -inline int lifebook_detect(struct psmouse *psmouse, int set_properties) -{ - return -ENOSYS; -} -inline int lifebook_init(struct psmouse *psmouse) -{ - return -ENOSYS; -} -#endif #endif diff --git a/trunk/drivers/input/mouse/logips2pp.c b/trunk/drivers/input/mouse/logips2pp.c index 9df74b72e6c4..d3ddea26b8ca 100644 --- a/trunk/drivers/input/mouse/logips2pp.c +++ b/trunk/drivers/input/mouse/logips2pp.c @@ -200,7 +200,6 @@ static void ps2pp_disconnect(struct psmouse *psmouse) static const struct ps2pp_info *get_model_info(unsigned char model) { static const struct ps2pp_info ps2pp_list[] = { - { 1, 0, 0 }, /* Simple 2-button mouse */ { 12, 0, PS2PP_SIDE_BTN}, { 13, 0, 0 }, { 15, PS2PP_KIND_MX, /* MX1000 */ @@ -339,12 +338,12 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) param[1] = 0; ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); + if (!param[1]) + return -1; + model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); buttons = param[1]; - if (!model || !buttons) - return -1; - if ((model_info = get_model_info(model)) != NULL) { /* diff --git a/trunk/drivers/input/mouse/logips2pp.h b/trunk/drivers/input/mouse/logips2pp.h index 6e5712525fd6..64a8ec52ea6d 100644 --- a/trunk/drivers/input/mouse/logips2pp.h +++ b/trunk/drivers/input/mouse/logips2pp.h @@ -11,13 +11,6 @@ #ifndef _LOGIPS2PP_H #define _LOGIPS2PP_H -#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP int ps2pp_init(struct psmouse *psmouse, int set_properties); -#else -inline int ps2pp_init(struct psmouse *psmouse, int set_properties) -{ - return -ENOSYS; -} -#endif /* CONFIG_MOUSE_PS2_LOGIPS2PP */ #endif diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index f15f695777f8..0fe5869d7d4c 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -28,7 +28,6 @@ #include "alps.h" #include "lifebook.h" #include "trackpoint.h" -#include "touchkit_ps2.h" #define DRIVER_DESC "PS/2 mouse driver" @@ -570,9 +569,7 @@ static int psmouse_extensions(struct psmouse *psmouse, return PSMOUSE_THINKPS; /* - * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol - * support is disabled in config - we need to know if it is synaptics so we - * can reset it properly after probing for intellimouse. + * Try Synaptics TouchPad */ if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { synaptics_hardware = 1; @@ -608,20 +605,14 @@ static int psmouse_extensions(struct psmouse *psmouse, } } - if (max_proto > PSMOUSE_IMEX) { - - if (genius_detect(psmouse, set_properties) == 0) - return PSMOUSE_GENPS; + if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse, set_properties) == 0) + return PSMOUSE_GENPS; - if (ps2pp_init(psmouse, set_properties) == 0) - return PSMOUSE_PS2PP; + if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) + return PSMOUSE_PS2PP; - if (trackpoint_detect(psmouse, set_properties) == 0) - return PSMOUSE_TRACKPOINT; - - if (touchkit_ps2_detect(psmouse, set_properties) == 0) - return PSMOUSE_TOUCHKIT_PS2; - } + if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0) + return PSMOUSE_TRACKPOINT; /* * Reset to defaults in case the device got confused by extended @@ -663,14 +654,12 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = 1, .detect = ps2bare_detect, }, -#ifdef CONFIG_MOUSE_PS2_LOGIPS2PP { .type = PSMOUSE_PS2PP, .name = "PS2++", .alias = "logitech", .detect = ps2pp_init, }, -#endif { .type = PSMOUSE_THINKPS, .name = "ThinkPS/2", @@ -697,7 +686,6 @@ static const struct psmouse_protocol psmouse_protocols[] = { .maxproto = 1, .detect = im_explorer_detect, }, -#ifdef CONFIG_MOUSE_PS2_SYNAPTICS { .type = PSMOUSE_SYNAPTICS, .name = "SynPS/2", @@ -705,8 +693,6 @@ static const struct psmouse_protocol psmouse_protocols[] = { .detect = synaptics_detect, .init = synaptics_init, }, -#endif -#ifdef CONFIG_MOUSE_PS2_ALPS { .type = PSMOUSE_ALPS, .name = "AlpsPS/2", @@ -714,31 +700,18 @@ static const struct psmouse_protocol psmouse_protocols[] = { .detect = alps_detect, .init = alps_init, }, -#endif -#ifdef CONFIG_MOUSE_PS2_LIFEBOOK { .type = PSMOUSE_LIFEBOOK, .name = "LBPS/2", .alias = "lifebook", .init = lifebook_init, }, -#endif -#ifdef CONFIG_MOUSE_PS2_TRACKPOINT { .type = PSMOUSE_TRACKPOINT, .name = "TPPS/2", .alias = "trackpoint", .detect = trackpoint_detect, }, -#endif -#ifdef CONFIG_MOUSE_PS2_TOUCHKIT - { - .type = PSMOUSE_TOUCHKIT_PS2, - .name = "touchkitPS/2", - .alias = "touchkit", - .detect = touchkit_ps2_detect, - }, -#endif { .type = PSMOUSE_AUTO, .name = "auto", @@ -849,6 +822,12 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) static void psmouse_initialize(struct psmouse *psmouse) { +/* + * We set the mouse into streaming mode. + */ + + ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM); + /* * We set the mouse report rate, resolution and scaling. */ @@ -1083,7 +1062,8 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse { struct input_dev *input_dev = psmouse->dev; - input_dev->dev.parent = &psmouse->ps2dev.serio->dev; + input_dev->private = psmouse; + input_dev->cdev.dev = &psmouse->ps2dev.serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); diff --git a/trunk/drivers/input/mouse/psmouse.h b/trunk/drivers/input/mouse/psmouse.h index 3964e8acbc54..cf1de95b6f27 100644 --- a/trunk/drivers/input/mouse/psmouse.h +++ b/trunk/drivers/input/mouse/psmouse.h @@ -87,7 +87,6 @@ enum psmouse_type { PSMOUSE_ALPS, PSMOUSE_LIFEBOOK, PSMOUSE_TRACKPOINT, - PSMOUSE_TOUCHKIT_PS2, PSMOUSE_AUTO /* This one should always be last */ }; diff --git a/trunk/drivers/input/mouse/sermouse.c b/trunk/drivers/input/mouse/sermouse.c index 77b8ee2b9651..a85d74710b44 100644 --- a/trunk/drivers/input/mouse/sermouse.c +++ b/trunk/drivers/input/mouse/sermouse.c @@ -69,8 +69,7 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data) switch (sermouse->count) { case 0: - if ((data & 0xf8) != 0x80) - return; + if ((data & 0xf8) != 0x80) return; input_report_key(dev, BTN_LEFT, !(data & 4)); input_report_key(dev, BTN_RIGHT, !(data & 1)); input_report_key(dev, BTN_MIDDLE, !(data & 2)); @@ -108,10 +107,7 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) struct input_dev *dev = sermouse->dev; signed char *buf = sermouse->buf; - if (data & 0x40) - sermouse->count = 0; - else if (sermouse->count == 0) - return; + if (data & 0x40) sermouse->count = 0; switch (sermouse->count) { @@ -173,8 +169,7 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) case 5: case 7: /* Ignore anything besides MZ++ */ - if (sermouse->type != SERIO_MZPP) - break; + if (sermouse->type != SERIO_MZPP) break; switch (buf[1]) { @@ -211,16 +206,13 @@ static irqreturn_t sermouse_interrupt(struct serio *serio, { struct sermouse *sermouse = serio_get_drvdata(serio); - if (time_after(jiffies, sermouse->last + HZ/10)) - sermouse->count = 0; - + if (time_after(jiffies, sermouse->last + HZ/10)) sermouse->count = 0; sermouse->last = jiffies; if (sermouse->type > SERIO_SUN) sermouse_process_ms(sermouse, data); else sermouse_process_msc(sermouse, data); - return IRQ_HANDLED; } @@ -266,11 +258,12 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = sermouse->type; input_dev->id.product = c; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_dev->private = sermouse; if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); diff --git a/trunk/drivers/input/mouse/synaptics.c b/trunk/drivers/input/mouse/synaptics.c index 666ad3a53fdb..f0f9413d762c 100644 --- a/trunk/drivers/input/mouse/synaptics.c +++ b/trunk/drivers/input/mouse/synaptics.c @@ -40,70 +40,33 @@ #define YMIN_NOMINAL 1408 #define YMAX_NOMINAL 4448 - /***************************************************************************** - * Stuff we need even when we do not want native Synaptics support + * Synaptics communications functions ****************************************************************************/ /* - * Set the synaptics touchpad mode byte by special commands + * Send a command to the synpatics touchpad by special commands */ -static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) +static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) { - unsigned char param[1]; - - if (psmouse_sliced_command(psmouse, mode)) + if (psmouse_sliced_command(psmouse, c)) return -1; - param[0] = SYN_PS_SET_MODE2; - if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) return -1; return 0; } -int synaptics_detect(struct psmouse *psmouse, int set_properties) -{ - struct ps2dev *ps2dev = &psmouse->ps2dev; - unsigned char param[4]; - - param[0] = 0; - - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); - ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); - - if (param[1] != 0x47) - return -ENODEV; - - if (set_properties) { - psmouse->vendor = "Synaptics"; - psmouse->name = "TouchPad"; - } - - return 0; -} - -void synaptics_reset(struct psmouse *psmouse) -{ - /* reset touchpad back to relative mode, gestures enabled */ - synaptics_mode_cmd(psmouse, 0); -} - -#ifdef CONFIG_MOUSE_PS2_SYNAPTICS - -/***************************************************************************** - * Synaptics communications functions - ****************************************************************************/ - /* - * Send a command to the synpatics touchpad by special commands + * Set the synaptics touchpad mode byte by special commands */ -static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) +static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) { - if (psmouse_sliced_command(psmouse, c)) + unsigned char param[1]; + + if (psmouse_sliced_command(psmouse, mode)) return -1; - if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) + param[0] = SYN_PS_SET_MODE2; + if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) return -1; return 0; } @@ -185,7 +148,7 @@ static int synaptics_query_hardware(struct psmouse *psmouse) int retries = 0; while ((retries++ < 3) && psmouse_reset(psmouse)) - /* empty */; + printk(KERN_ERR "synaptics reset failed\n"); if (synaptics_identify(psmouse)) return -1; @@ -566,6 +529,12 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) clear_bit(REL_Y, dev->relbit); } +void synaptics_reset(struct psmouse *psmouse) +{ + /* reset touchpad back to relative mode, gestures enabled */ + synaptics_mode_cmd(psmouse, 0); +} + static void synaptics_disconnect(struct psmouse *psmouse) { synaptics_reset(psmouse); @@ -600,6 +569,30 @@ static int synaptics_reconnect(struct psmouse *psmouse) return 0; } +int synaptics_detect(struct psmouse *psmouse, int set_properties) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param[4]; + + param[0] = 0; + + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); + ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); + + if (param[1] != 0x47) + return -1; + + if (set_properties) { + psmouse->vendor = "Synaptics"; + psmouse->name = "TouchPad"; + } + + return 0; +} + #if defined(__i386__) #include static struct dmi_system_id toshiba_dmi_table[] = { @@ -655,16 +648,6 @@ int synaptics_init(struct psmouse *psmouse) set_input_params(psmouse->dev, priv); - /* - * Encode touchpad model so that it can be used to set - * input device->id.version and be visible to userspace. - * Because version is __u16 we have to drop something. - * Hardware info bits seem to be good candidates as they - * are documented to be for Synaptics corp. internal use. - */ - psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) | - (priv->model_id & 0x000000ff); - psmouse->protocol_handler = synaptics_process_byte; psmouse->set_rate = synaptics_set_rate; psmouse->disconnect = synaptics_disconnect; @@ -697,12 +680,4 @@ int synaptics_init(struct psmouse *psmouse) return -1; } -#else /* CONFIG_MOUSE_PS2_SYNAPTICS */ - -int synaptics_init(struct psmouse *psmouse) -{ - return -ENOSYS; -} - -#endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ diff --git a/trunk/drivers/input/mouse/synaptics.h b/trunk/drivers/input/mouse/synaptics.h index 02aa4cf7bc77..68fff1dcd7de 100644 --- a/trunk/drivers/input/mouse/synaptics.h +++ b/trunk/drivers/input/mouse/synaptics.h @@ -9,6 +9,10 @@ #ifndef _SYNAPTICS_H #define _SYNAPTICS_H +extern int synaptics_detect(struct psmouse *psmouse, int set_properties); +extern int synaptics_init(struct psmouse *psmouse); +extern void synaptics_reset(struct psmouse *psmouse); + /* synaptics queries */ #define SYN_QUE_IDENTIFY 0x00 #define SYN_QUE_MODES 0x01 @@ -58,9 +62,9 @@ #define SYN_MODE_WMODE(m) ((m) & (1 << 0)) /* synaptics identify query bits */ -#define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) -#define SYN_ID_MAJOR(i) ((i) & 0x0f) -#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) +#define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) +#define SYN_ID_MAJOR(i) ((i) & 0x0f) +#define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) /* synaptics special commands */ @@ -94,8 +98,8 @@ struct synaptics_hw_state { struct synaptics_data { /* Data read from the touchpad */ unsigned long int model_id; /* Model-ID */ - unsigned long int capabilities; /* Capabilities */ - unsigned long int ext_cap; /* Extended Capabilities */ + unsigned long int capabilities; /* Capabilities */ + unsigned long int ext_cap; /* Extended Capabilities */ unsigned long int identity; /* Identification */ unsigned char pkt_type; /* packet type - old, new, etc */ @@ -103,8 +107,4 @@ struct synaptics_data { int scroll; }; -int synaptics_detect(struct psmouse *psmouse, int set_properties); -int synaptics_init(struct psmouse *psmouse); -void synaptics_reset(struct psmouse *psmouse); - #endif /* _SYNAPTICS_H */ diff --git a/trunk/drivers/input/mouse/touchkit_ps2.c b/trunk/drivers/input/mouse/touchkit_ps2.c deleted file mode 100644 index 7b977fd23571..000000000000 --- a/trunk/drivers/input/mouse/touchkit_ps2.c +++ /dev/null @@ -1,100 +0,0 @@ -/* ---------------------------------------------------------------------------- - * touchkit_ps2.c -- Driver for eGalax TouchKit PS/2 Touchscreens - * - * Copyright (C) 2005 by Stefan Lucke - * Copyright (C) 2004 by Daniel Ritz - * Copyright (C) by Todd E. Johnson (mtouchusb.c) - * - * 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Based upon touchkitusb.c - * - * Vendor documentation is available in support section of: - * http://www.egalax.com.tw/ - */ - -#include -#include - -#include -#include -#include - -#include "psmouse.h" -#include "touchkit_ps2.h" - -#define TOUCHKIT_MAX_XC 0x07ff -#define TOUCHKIT_MAX_YC 0x07ff - -#define TOUCHKIT_CMD 0x0a -#define TOUCHKIT_CMD_LENGTH 1 - -#define TOUCHKIT_CMD_ACTIVE 'A' -#define TOUCHKIT_CMD_FIRMWARE_VERSION 'D' -#define TOUCHKIT_CMD_CONTROLLER_TYPE 'E' - -#define TOUCHKIT_SEND_PARMS(s, r, c) ((s) << 12 | (r) << 8 | (c)) - -#define TOUCHKIT_GET_TOUCHED(packet) (((packet)[0]) & 0x01) -#define TOUCHKIT_GET_X(packet) (((packet)[1] << 7) | (packet)[2]) -#define TOUCHKIT_GET_Y(packet) (((packet)[3] << 7) | (packet)[4]) - -static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse) -{ - unsigned char *packet = psmouse->packet; - struct input_dev *dev = psmouse->dev; - - if (psmouse->pktcnt != 5) - return PSMOUSE_GOOD_DATA; - - input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet)); - input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet)); - input_report_key(dev, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(packet)); - input_sync(dev); - - return PSMOUSE_FULL_PACKET; -} - -int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) -{ - struct input_dev *dev = psmouse->dev; - unsigned char param[3]; - int command; - - param[0] = TOUCHKIT_CMD_LENGTH; - param[1] = TOUCHKIT_CMD_ACTIVE; - command = TOUCHKIT_SEND_PARMS(2, 3, TOUCHKIT_CMD); - - if (ps2_command(&psmouse->ps2dev, param, command)) - return -ENODEV; - - if (param[0] != TOUCHKIT_CMD || param[1] != 0x01 || - param[2] != TOUCHKIT_CMD_ACTIVE) - return -ENODEV; - - if (set_properties) { - dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - set_bit(BTN_TOUCH, dev->keybit); - input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); - input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); - - psmouse->vendor = "eGalax"; - psmouse->name = "Touchscreen"; - psmouse->protocol_handler = touchkit_ps2_process_byte; - psmouse->pktsize = 5; - } - - return 0; -} diff --git a/trunk/drivers/input/mouse/touchkit_ps2.h b/trunk/drivers/input/mouse/touchkit_ps2.h deleted file mode 100644 index 61e9dfd8419f..000000000000 --- a/trunk/drivers/input/mouse/touchkit_ps2.h +++ /dev/null @@ -1,24 +0,0 @@ -/* ---------------------------------------------------------------------------- - * touchkit_ps2.h -- Driver for eGalax TouchKit PS/2 Touchscreens - * - * Copyright (C) 2005 by Stefan Lucke - * Copyright (c) 2005 Vojtech Pavlik - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#ifndef _TOUCHKIT_PS2_H -#define _TOUCHKIT_PS2_H - -#ifdef CONFIG_MOUSE_PS2_TOUCHKIT -int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties); -#else -inline int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) -{ - return -ENOSYS; -} -#endif /* CONFIG_MOUSE_PS2_TOUCHKIT */ - -#endif diff --git a/trunk/drivers/input/mouse/trackpoint.h b/trunk/drivers/input/mouse/trackpoint.h index c10a6e7d0101..050298b1a09d 100644 --- a/trunk/drivers/input/mouse/trackpoint.h +++ b/trunk/drivers/input/mouse/trackpoint.h @@ -142,13 +142,6 @@ struct trackpoint_data unsigned char ext_dev; }; -#ifdef CONFIG_MOUSE_PS2_TRACKPOINT -int trackpoint_detect(struct psmouse *psmouse, int set_properties); -#else -inline int trackpoint_detect(struct psmouse *psmouse, int set_properties) -{ - return -ENOSYS; -} -#endif /* CONFIG_MOUSE_PS2_TRACKPOINT */ +extern int trackpoint_detect(struct psmouse *psmouse, int set_properties); #endif /* _TRACKPOINT_H */ diff --git a/trunk/drivers/input/mouse/vsxxxaa.c b/trunk/drivers/input/mouse/vsxxxaa.c index 4a321576f345..c3d64fcc858d 100644 --- a/trunk/drivers/input/mouse/vsxxxaa.c +++ b/trunk/drivers/input/mouse/vsxxxaa.c @@ -508,7 +508,8 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) input_dev->name = mouse->name; input_dev->phys = mouse->phys; input_dev->id.bustype = BUS_RS232; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; + input_dev->private = mouse; set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ set_bit (EV_REL, input_dev->evbit); diff --git a/trunk/drivers/input/mousedev.c b/trunk/drivers/input/mousedev.c index 8675f9509393..664bcc8116fc 100644 --- a/trunk/drivers/input/mousedev.c +++ b/trunk/drivers/input/mousedev.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -62,12 +63,9 @@ struct mousedev { int minor; char name[16]; wait_queue_head_t wait; - struct list_head client_list; + struct list_head list; struct input_handle handle; - struct list_head mixdev_node; - int mixdev_open; - struct mousedev_hw_data packet; unsigned int pkt_count; int old_x[4], old_y[4]; @@ -87,7 +85,7 @@ struct mousedev_motion { }; #define PACKET_QUEUE_LEN 16 -struct mousedev_client { +struct mousedev_list { struct fasync_struct *fasync; struct mousedev *mousedev; struct list_head node; @@ -113,7 +111,6 @@ static struct input_handler mousedev_handler; static struct mousedev *mousedev_table[MOUSEDEV_MINORS]; static struct mousedev mousedev_mix; -static LIST_HEAD(mousedev_mix_list); #define fx(i) (mousedev->old_x[(mousedev->pkt_count - (i)) & 03]) #define fy(i) (mousedev->old_y[(mousedev->pkt_count - (i)) & 03]) @@ -123,33 +120,32 @@ static void mousedev_touchpad_event(struct input_dev *dev, struct mousedev *mous int size, tmp; enum { FRACTION_DENOM = 128 }; - switch (code) { - case ABS_X: - fx(0) = value; - if (mousedev->touch && mousedev->pkt_count >= 2) { - size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; - if (size == 0) - size = 256 * 2; - tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size; - tmp += mousedev->frac_dx; - mousedev->packet.dx = tmp / FRACTION_DENOM; - mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM; - } - break; + if (mousedev->touch) { + size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; + if (size == 0) + size = 256 * 2; + + switch (code) { + case ABS_X: + fx(0) = value; + if (mousedev->pkt_count >= 2) { + tmp = ((value - fx(2)) * (256 * FRACTION_DENOM)) / size; + tmp += mousedev->frac_dx; + mousedev->packet.dx = tmp / FRACTION_DENOM; + mousedev->frac_dx = tmp - mousedev->packet.dx * FRACTION_DENOM; + } + break; - case ABS_Y: - fy(0) = value; - if (mousedev->touch && mousedev->pkt_count >= 2) { - /* use X size to keep the same scale */ - size = dev->absmax[ABS_X] - dev->absmin[ABS_X]; - if (size == 0) - size = 256 * 2; - tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size; - tmp += mousedev->frac_dy; - mousedev->packet.dy = tmp / FRACTION_DENOM; - mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; - } - break; + case ABS_Y: + fy(0) = value; + if (mousedev->pkt_count >= 2) { + tmp = -((value - fy(2)) * (256 * FRACTION_DENOM)) / size; + tmp += mousedev->frac_dy; + mousedev->packet.dy = tmp / FRACTION_DENOM; + mousedev->frac_dy = tmp - mousedev->packet.dy * FRACTION_DENOM; + } + break; + } } } @@ -227,47 +223,47 @@ static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_hw_data *packet) { - struct mousedev_client *client; + struct mousedev_list *list; struct mousedev_motion *p; unsigned long flags; int wake_readers = 0; - list_for_each_entry(client, &mousedev->client_list, node) { - spin_lock_irqsave(&client->packet_lock, flags); + list_for_each_entry(list, &mousedev->list, node) { + spin_lock_irqsave(&list->packet_lock, flags); - p = &client->packets[client->head]; - if (client->ready && p->buttons != mousedev->packet.buttons) { - unsigned int new_head = (client->head + 1) % PACKET_QUEUE_LEN; - if (new_head != client->tail) { - p = &client->packets[client->head = new_head]; + p = &list->packets[list->head]; + if (list->ready && p->buttons != mousedev->packet.buttons) { + unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN; + if (new_head != list->tail) { + p = &list->packets[list->head = new_head]; memset(p, 0, sizeof(struct mousedev_motion)); } } if (packet->abs_event) { - p->dx += packet->x - client->pos_x; - p->dy += packet->y - client->pos_y; - client->pos_x = packet->x; - client->pos_y = packet->y; + p->dx += packet->x - list->pos_x; + p->dy += packet->y - list->pos_y; + list->pos_x = packet->x; + list->pos_y = packet->y; } - client->pos_x += packet->dx; - client->pos_x = client->pos_x < 0 ? 0 : (client->pos_x >= xres ? xres : client->pos_x); - client->pos_y += packet->dy; - client->pos_y = client->pos_y < 0 ? 0 : (client->pos_y >= yres ? yres : client->pos_y); + list->pos_x += packet->dx; + list->pos_x = list->pos_x < 0 ? 0 : (list->pos_x >= xres ? xres : list->pos_x); + list->pos_y += packet->dy; + list->pos_y = list->pos_y < 0 ? 0 : (list->pos_y >= yres ? yres : list->pos_y); p->dx += packet->dx; p->dy += packet->dy; p->dz += packet->dz; p->buttons = mousedev->packet.buttons; - if (p->dx || p->dy || p->dz || p->buttons != client->last_buttons) - client->ready = 1; + if (p->dx || p->dy || p->dz || p->buttons != list->last_buttons) + list->ready = 1; - spin_unlock_irqrestore(&client->packet_lock, flags); + spin_unlock_irqrestore(&list->packet_lock, flags); - if (client->ready) { - kill_fasync(&client->fasync, SIGIO, POLL_IN); + if (list->ready) { + kill_fasync(&list->fasync, SIGIO, POLL_IN); wake_readers = 1; } } @@ -355,9 +351,9 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig static int mousedev_fasync(int fd, struct file *file, int on) { int retval; - struct mousedev_client *client = file->private_data; + struct mousedev_list *list = file->private_data; - retval = fasync_helper(fd, file, on, &client->fasync); + retval = fasync_helper(fd, file, on, &list->fasync); return retval < 0 ? retval : 0; } @@ -368,95 +364,50 @@ static void mousedev_free(struct mousedev *mousedev) kfree(mousedev); } -static int mixdev_add_device(struct mousedev *mousedev) -{ - int error; - - if (mousedev_mix.open) { - error = input_open_device(&mousedev->handle); - if (error) - return error; - - mousedev->open++; - mousedev->mixdev_open++; - } - - list_add_tail(&mousedev->mixdev_node, &mousedev_mix_list); - - return 0; -} - -static void mixdev_remove_device(struct mousedev *mousedev) -{ - if (mousedev->mixdev_open) { - mousedev->mixdev_open = 0; - if (!--mousedev->open && mousedev->exist) - input_close_device(&mousedev->handle); - } - - list_del_init(&mousedev->mixdev_node); -} - -static void mixdev_open_devices(void) +static void mixdev_release(void) { - struct mousedev *mousedev; - - list_for_each_entry(mousedev, &mousedev_mix_list, mixdev_node) { - if (mousedev->exist && !mousedev->open) { - if (input_open_device(&mousedev->handle)) - continue; + struct input_handle *handle; - mousedev->open++; - mousedev->mixdev_open++; - } - } -} + list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { + struct mousedev *mousedev = handle->private; -static void mixdev_close_devices(void) -{ - struct mousedev *mousedev, *next; - - list_for_each_entry_safe(mousedev, next, &mousedev_mix_list, mixdev_node) { - if (mousedev->mixdev_open) { - mousedev->mixdev_open = 0; - if (!--mousedev->open) { - if (mousedev->exist) - input_close_device(&mousedev->handle); - else - mousedev_free(mousedev); - } + if (!mousedev->open) { + if (mousedev->exist) + input_close_device(&mousedev->handle); + else + mousedev_free(mousedev); } } } -static int mousedev_release(struct inode *inode, struct file *file) +static int mousedev_release(struct inode * inode, struct file * file) { - struct mousedev_client *client = file->private_data; - struct mousedev *mousedev = client->mousedev; + struct mousedev_list *list = file->private_data; mousedev_fasync(-1, file, 0); - list_del(&client->node); - kfree(client); + list_del(&list->node); - if (!--mousedev->open) { - if (mousedev->minor == MOUSEDEV_MIX) - mixdev_close_devices(); - else if (mousedev->exist) - input_close_device(&mousedev->handle); - else - mousedev_free(mousedev); + if (!--list->mousedev->open) { + if (list->mousedev->minor == MOUSEDEV_MIX) + mixdev_release(); + else if (!mousedev_mix.open) { + if (list->mousedev->exist) + input_close_device(&list->mousedev->handle); + else + mousedev_free(list->mousedev); + } } + kfree(list); return 0; } - -static int mousedev_open(struct inode *inode, struct file *file) +static int mousedev_open(struct inode * inode, struct file * file) { - struct mousedev_client *client; + struct mousedev_list *list; + struct input_handle *handle; struct mousedev *mousedev; - int error; int i; #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX @@ -466,37 +417,31 @@ static int mousedev_open(struct inode *inode, struct file *file) #endif i = iminor(inode) - MOUSEDEV_MINOR_BASE; - if (i >= MOUSEDEV_MINORS) - return -ENODEV; - - mousedev = mousedev_table[i]; - if (!mousedev) + if (i >= MOUSEDEV_MINORS || !mousedev_table[i]) return -ENODEV; - client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); - if (!client) + if (!(list = kzalloc(sizeof(struct mousedev_list), GFP_KERNEL))) return -ENOMEM; - spin_lock_init(&client->packet_lock); - client->pos_x = xres / 2; - client->pos_y = yres / 2; - client->mousedev = mousedev; - list_add_tail(&client->node, &mousedev->client_list); - - if (!mousedev->open++) { - if (mousedev->minor == MOUSEDEV_MIX) - mixdev_open_devices(); - else if (mousedev->exist) { - error = input_open_device(&mousedev->handle); - if (error) { - list_del(&client->node); - kfree(client); - return error; + spin_lock_init(&list->packet_lock); + list->pos_x = xres / 2; + list->pos_y = yres / 2; + list->mousedev = mousedev_table[i]; + list_add_tail(&list->node, &mousedev_table[i]->list); + file->private_data = list; + + if (!list->mousedev->open++) { + if (list->mousedev->minor == MOUSEDEV_MIX) { + list_for_each_entry(handle, &mousedev_handler.h_list, h_node) { + mousedev = handle->private; + if (!mousedev->open && mousedev->exist) + input_open_device(handle); } - } + } else + if (!mousedev_mix.open && list->mousedev->exist) + input_open_device(&list->mousedev->handle); } - file->private_data = client; return 0; } @@ -505,13 +450,13 @@ static inline int mousedev_limit_delta(int delta, int limit) return delta > limit ? limit : (delta < -limit ? -limit : delta); } -static void mousedev_packet(struct mousedev_client *client, signed char *ps2_data) +static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data) { struct mousedev_motion *p; unsigned long flags; - spin_lock_irqsave(&client->packet_lock, flags); - p = &client->packets[client->tail]; + spin_lock_irqsave(&list->packet_lock, flags); + p = &list->packets[list->tail]; ps2_data[0] = 0x08 | ((p->dx < 0) << 4) | ((p->dy < 0) << 5) | (p->buttons & 0x07); ps2_data[1] = mousedev_limit_delta(p->dx, 127); @@ -519,44 +464,44 @@ static void mousedev_packet(struct mousedev_client *client, signed char *ps2_dat p->dx -= ps2_data[1]; p->dy -= ps2_data[2]; - switch (client->mode) { + switch (list->mode) { case MOUSEDEV_EMUL_EXPS: ps2_data[3] = mousedev_limit_delta(p->dz, 7); p->dz -= ps2_data[3]; ps2_data[3] = (ps2_data[3] & 0x0f) | ((p->buttons & 0x18) << 1); - client->bufsiz = 4; + list->bufsiz = 4; break; case MOUSEDEV_EMUL_IMPS: ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); ps2_data[3] = mousedev_limit_delta(p->dz, 127); p->dz -= ps2_data[3]; - client->bufsiz = 4; + list->bufsiz = 4; break; case MOUSEDEV_EMUL_PS2: default: ps2_data[0] |= ((p->buttons & 0x10) >> 3) | ((p->buttons & 0x08) >> 1); p->dz = 0; - client->bufsiz = 3; + list->bufsiz = 3; break; } if (!p->dx && !p->dy && !p->dz) { - if (client->tail == client->head) { - client->ready = 0; - client->last_buttons = p->buttons; + if (list->tail == list->head) { + list->ready = 0; + list->last_buttons = p->buttons; } else - client->tail = (client->tail + 1) % PACKET_QUEUE_LEN; + list->tail = (list->tail + 1) % PACKET_QUEUE_LEN; } - spin_unlock_irqrestore(&client->packet_lock, flags); + spin_unlock_irqrestore(&list->packet_lock, flags); } -static ssize_t mousedev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +static ssize_t mousedev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos) { - struct mousedev_client *client = file->private_data; + struct mousedev_list *list = file->private_data; unsigned char c; unsigned int i; @@ -565,95 +510,95 @@ static ssize_t mousedev_write(struct file *file, const char __user *buffer, size if (get_user(c, buffer + i)) return -EFAULT; - if (c == mousedev_imex_seq[client->imexseq]) { - if (++client->imexseq == MOUSEDEV_SEQ_LEN) { - client->imexseq = 0; - client->mode = MOUSEDEV_EMUL_EXPS; + if (c == mousedev_imex_seq[list->imexseq]) { + if (++list->imexseq == MOUSEDEV_SEQ_LEN) { + list->imexseq = 0; + list->mode = MOUSEDEV_EMUL_EXPS; } } else - client->imexseq = 0; + list->imexseq = 0; - if (c == mousedev_imps_seq[client->impsseq]) { - if (++client->impsseq == MOUSEDEV_SEQ_LEN) { - client->impsseq = 0; - client->mode = MOUSEDEV_EMUL_IMPS; + if (c == mousedev_imps_seq[list->impsseq]) { + if (++list->impsseq == MOUSEDEV_SEQ_LEN) { + list->impsseq = 0; + list->mode = MOUSEDEV_EMUL_IMPS; } } else - client->impsseq = 0; + list->impsseq = 0; - client->ps2[0] = 0xfa; + list->ps2[0] = 0xfa; switch (c) { case 0xeb: /* Poll */ - mousedev_packet(client, &client->ps2[1]); - client->bufsiz++; /* account for leading ACK */ + mousedev_packet(list, &list->ps2[1]); + list->bufsiz++; /* account for leading ACK */ break; case 0xf2: /* Get ID */ - switch (client->mode) { - case MOUSEDEV_EMUL_PS2: client->ps2[1] = 0; break; - case MOUSEDEV_EMUL_IMPS: client->ps2[1] = 3; break; - case MOUSEDEV_EMUL_EXPS: client->ps2[1] = 4; break; + switch (list->mode) { + case MOUSEDEV_EMUL_PS2: list->ps2[1] = 0; break; + case MOUSEDEV_EMUL_IMPS: list->ps2[1] = 3; break; + case MOUSEDEV_EMUL_EXPS: list->ps2[1] = 4; break; } - client->bufsiz = 2; + list->bufsiz = 2; break; case 0xe9: /* Get info */ - client->ps2[1] = 0x60; client->ps2[2] = 3; client->ps2[3] = 200; - client->bufsiz = 4; + list->ps2[1] = 0x60; list->ps2[2] = 3; list->ps2[3] = 200; + list->bufsiz = 4; break; case 0xff: /* Reset */ - client->impsseq = client->imexseq = 0; - client->mode = MOUSEDEV_EMUL_PS2; - client->ps2[1] = 0xaa; client->ps2[2] = 0x00; - client->bufsiz = 3; + list->impsseq = list->imexseq = 0; + list->mode = MOUSEDEV_EMUL_PS2; + list->ps2[1] = 0xaa; list->ps2[2] = 0x00; + list->bufsiz = 3; break; default: - client->bufsiz = 1; + list->bufsiz = 1; break; } - client->buffer = client->bufsiz; + list->buffer = list->bufsiz; } - kill_fasync(&client->fasync, SIGIO, POLL_IN); + kill_fasync(&list->fasync, SIGIO, POLL_IN); - wake_up_interruptible(&client->mousedev->wait); + wake_up_interruptible(&list->mousedev->wait); return count; } -static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) +static ssize_t mousedev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) { - struct mousedev_client *client = file->private_data; + struct mousedev_list *list = file->private_data; int retval = 0; - if (!client->ready && !client->buffer && (file->f_flags & O_NONBLOCK)) + if (!list->ready && !list->buffer && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(client->mousedev->wait, - !client->mousedev->exist || client->ready || client->buffer); + retval = wait_event_interruptible(list->mousedev->wait, + !list->mousedev->exist || list->ready || list->buffer); if (retval) return retval; - if (!client->mousedev->exist) + if (!list->mousedev->exist) return -ENODEV; - if (!client->buffer && client->ready) { - mousedev_packet(client, client->ps2); - client->buffer = client->bufsiz; + if (!list->buffer && list->ready) { + mousedev_packet(list, list->ps2); + list->buffer = list->bufsiz; } - if (count > client->buffer) - count = client->buffer; + if (count > list->buffer) + count = list->buffer; - client->buffer -= count; + list->buffer -= count; - if (copy_to_user(buffer, client->ps2 + client->bufsiz - client->buffer - count, count)) + if (copy_to_user(buffer, list->ps2 + list->bufsiz - list->buffer - count, count)) return -EFAULT; return count; @@ -662,12 +607,11 @@ static ssize_t mousedev_read(struct file *file, char __user *buffer, size_t coun /* No kernel lock - fine */ static unsigned int mousedev_poll(struct file *file, poll_table *wait) { - struct mousedev_client *client = file->private_data; - struct mousedev *mousedev = client->mousedev; + struct mousedev_list *list = file->private_data; - poll_wait(file, &mousedev->wait, wait); - return ((client->ready || client->buffer) ? (POLLIN | POLLRDNORM) : 0) | - (mousedev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &list->mousedev->wait, wait); + return ((list->ready || list->buffer) ? (POLLIN | POLLRDNORM) : 0) | + (list->mousedev->exist ? 0 : (POLLHUP | POLLERR)); } static const struct file_operations mousedev_fops = { @@ -680,27 +624,23 @@ static const struct file_operations mousedev_fops = { .fasync = mousedev_fasync, }; -static int mousedev_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, + const struct input_device_id *id) { struct mousedev *mousedev; struct class_device *cdev; - dev_t devt; - int minor; - int error; + int minor = 0; for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); if (minor == MOUSEDEV_MINORS) { printk(KERN_ERR "mousedev: no more free mousedev devices\n"); - return -ENFILE; + return NULL; } - mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); - if (!mousedev) - return -ENOMEM; + if (!(mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL))) + return NULL; - INIT_LIST_HEAD(&mousedev->client_list); - INIT_LIST_HEAD(&mousedev->mixdev_node); + INIT_LIST_HEAD(&mousedev->list); init_waitqueue_head(&mousedev->wait); mousedev->minor = minor; @@ -711,66 +651,42 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev mousedev->handle.private = mousedev; sprintf(mousedev->name, "mouse%d", minor); - mousedev_table[minor] = mousedev; + if (mousedev_mix.open) + input_open_device(&mousedev->handle); - devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), + mousedev_table[minor] = mousedev; - cdev = class_device_create(&input_class, &dev->cdev, devt, - dev->cdev.dev, mousedev->name); - if (IS_ERR(cdev)) { - error = PTR_ERR(cdev); - goto err_free_mousedev; - } + cdev = class_device_create(&input_class, &dev->cdev, + MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), + dev->cdev.dev, mousedev->name); /* temporary symlink to keep userspace happy */ - error = sysfs_create_link(&input_class.subsys.kobj, - &cdev->kobj, mousedev->name); - if (error) - goto err_cdev_destroy; - - error = input_register_handle(&mousedev->handle); - if (error) - goto err_remove_link; - - error = mixdev_add_device(mousedev); - if (error) - goto err_unregister_handle; - - return 0; + sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + mousedev->name); - err_unregister_handle: - input_unregister_handle(&mousedev->handle); - err_remove_link: - sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); - err_cdev_destroy: - class_device_destroy(&input_class, devt); - err_free_mousedev: - mousedev_table[minor] = NULL; - kfree(mousedev); - return error; + return &mousedev->handle; } static void mousedev_disconnect(struct input_handle *handle) { struct mousedev *mousedev = handle->private; - struct mousedev_client *client; + struct mousedev_list *list; - input_unregister_handle(handle); - - sysfs_remove_link(&input_class.subsys.kobj, mousedev->name); + sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); mousedev->exist = 0; - mixdev_remove_device(mousedev); - if (mousedev->open) { input_close_device(handle); wake_up_interruptible(&mousedev->wait); - list_for_each_entry(client, &mousedev->client_list, node) - kill_fasync(&client->fasync, SIGIO, POLL_HUP); - } else + list_for_each_entry(list, &mousedev->list, node) + kill_fasync(&list->fasync, SIGIO, POLL_HUP); + } else { + if (mousedev_mix.open) + input_close_device(handle); mousedev_free(mousedev); + } } static const struct input_device_id mousedev_ids[] = { @@ -798,7 +714,7 @@ static const struct input_device_id mousedev_ids[] = { .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | BIT(ABS_TOOL_WIDTH) }, }, /* A touchpad */ - { }, /* Terminating entry */ + { }, /* Terminating entry */ }; MODULE_DEVICE_TABLE(input, mousedev_ids); @@ -830,7 +746,7 @@ static int __init mousedev_init(void) return error; memset(&mousedev_mix, 0, sizeof(struct mousedev)); - INIT_LIST_HEAD(&mousedev_mix.client_list); + INIT_LIST_HEAD(&mousedev_mix.list); init_waitqueue_head(&mousedev_mix.wait); mousedev_table[MOUSEDEV_MIX] = &mousedev_mix; mousedev_mix.exist = 1; diff --git a/trunk/drivers/input/power.c b/trunk/drivers/input/power.c new file mode 100644 index 000000000000..ee82464a2fa7 --- /dev/null +++ b/trunk/drivers/input/power.c @@ -0,0 +1,166 @@ +/* + * $Id: power.c,v 1.10 2001/09/25 09:17:15 vojtech Exp $ + * + * Copyright (c) 2001 "Crazy" James Simmons + * + * Input driver Power Management. + * + * Sponsored by Transvirtual Technology. + */ + +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Should you need to contact me, the author, you can do so by + * e-mail - mail your message to . + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct input_handler power_handler; + +/* + * Power management can't be done in a interrupt context. So we have to + * use keventd. + */ +static int suspend_button_pushed = 0; +static void suspend_button_task_handler(void *data) +{ + udelay(200); /* debounce */ + suspend_button_pushed = 0; +} + +static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL); + +static void power_event(struct input_handle *handle, unsigned int type, + unsigned int code, int down) +{ + struct input_dev *dev = handle->dev; + + printk("Entering power_event\n"); + + if (type == EV_PWR) { + switch (code) { + case KEY_SUSPEND: + printk("Powering down entire device\n"); + + if (!suspend_button_pushed) { + suspend_button_pushed = 1; + schedule_work(&suspend_button_task); + } + break; + case KEY_POWER: + /* Hum power down the machine. */ + break; + default: + return; + } + } + + if (type == EV_KEY) { + switch (code) { + case KEY_SUSPEND: + printk("Powering down input device\n"); + /* This is risky. See pm.h for details. */ + if (dev->state != PM_RESUME) + dev->state = PM_RESUME; + else + dev->state = PM_SUSPEND; + pm_send(dev->pm_dev, dev->state, dev); + break; + case KEY_POWER: + /* Turn the input device off completely ? */ + break; + default: + return; + } + } + return; +} + +static struct input_handle *power_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id) +{ + struct input_handle *handle; + + if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) + return NULL; + + handle->dev = dev; + handle->handler = handler; + + input_open_device(handle); + + printk(KERN_INFO "power.c: Adding power management to input layer\n"); + return handle; +} + +static void power_disconnect(struct input_handle *handle) +{ + input_close_device(handle); + kfree(handle); +} + +static const struct input_device_id power_ids[] = { + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT(EV_KEY) }, + .keybit = { [LONG(KEY_SUSPEND)] = BIT(KEY_SUSPEND) } + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, + .evbit = { BIT(EV_KEY) }, + .keybit = { [LONG(KEY_POWER)] = BIT(KEY_POWER) } + }, + { + .flags = INPUT_DEVICE_ID_MATCH_EVBIT, + .evbit = { BIT(EV_PWR) }, + }, + { }, /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(input, power_ids); + +static struct input_handler power_handler = { + .event = power_event, + .connect = power_connect, + .disconnect = power_disconnect, + .name = "power", + .id_table = power_ids, +}; + +static int __init power_init(void) +{ + return input_register_handler(&power_handler); +} + +static void __exit power_exit(void) +{ + input_unregister_handler(&power_handler); +} + +module_init(power_init); +module_exit(power_exit); + +MODULE_AUTHOR("James Simmons "); +MODULE_DESCRIPTION("Input Power Management driver"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/serio/hil_mlc.c b/trunk/drivers/input/serio/hil_mlc.c index 93a1a6ba216a..4fa93ff30919 100644 --- a/trunk/drivers/input/serio/hil_mlc.c +++ b/trunk/drivers/input/serio/hil_mlc.c @@ -32,11 +32,11 @@ * * Driver theory of operation: * - * Some access methods and an ISR is defined by the sub-driver - * (e.g. hp_sdc_mlc.c). These methods are expected to provide a - * few bits of logic in addition to raw access to the HIL MLC, - * specifically, the ISR, which is entirely registered by the - * sub-driver and invoked directly, must check for record + * Some access methods and an ISR is defined by the sub-driver + * (e.g. hp_sdc_mlc.c). These methods are expected to provide a + * few bits of logic in addition to raw access to the HIL MLC, + * specifically, the ISR, which is entirely registered by the + * sub-driver and invoked directly, must check for record * termination or packet match, at which point a semaphore must * be cleared and then the hil_mlcs_tasklet must be scheduled. * @@ -47,7 +47,7 @@ * itself if output is pending. (This rescheduling should be replaced * at some point with a sub-driver-specific mechanism.) * - * A timer task prods the tasklet once per second to prevent + * A timer task prods the tasklet once per second to prevent * hangups when attached devices do not return expected data * and to initiate probes of the loop for new devices. */ @@ -83,85 +83,69 @@ DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0); /********************** Device info/instance management **********************/ -static void hil_mlc_clear_di_map(hil_mlc *mlc, int val) -{ +static void hil_mlc_clear_di_map (hil_mlc *mlc, int val) { int j; - - for (j = val; j < 7 ; j++) + for (j = val; j < 7 ; j++) { mlc->di_map[j] = -1; + } } -static void hil_mlc_clear_di_scratch(hil_mlc *mlc) -{ - memset(&mlc->di_scratch, 0, sizeof(mlc->di_scratch)); +static void hil_mlc_clear_di_scratch (hil_mlc *mlc) { + memset(&(mlc->di_scratch), 0, sizeof(mlc->di_scratch)); } -static void hil_mlc_copy_di_scratch(hil_mlc *mlc, int idx) -{ - memcpy(&mlc->di[idx], &mlc->di_scratch, sizeof(mlc->di_scratch)); +static void hil_mlc_copy_di_scratch (hil_mlc *mlc, int idx) { + memcpy(&(mlc->di[idx]), &(mlc->di_scratch), sizeof(mlc->di_scratch)); } -static int hil_mlc_match_di_scratch(hil_mlc *mlc) -{ +static int hil_mlc_match_di_scratch (hil_mlc *mlc) { int idx; for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { - int j, found = 0; + int j, found; /* In-use slots are not eligible. */ - for (j = 0; j < 7 ; j++) - if (mlc->di_map[j] == idx) - found++; - - if (found) - continue; - - if (!memcmp(mlc->di + idx, &mlc->di_scratch, - sizeof(mlc->di_scratch))) - break; + found = 0; + for (j = 0; j < 7 ; j++) { + if (mlc->di_map[j] == idx) found++; + } + if (found) continue; + if (!memcmp(mlc->di + idx, + &(mlc->di_scratch), + sizeof(mlc->di_scratch))) break; } - return idx >= HIL_MLC_DEVMEM ? -1 : idx; + return((idx >= HIL_MLC_DEVMEM) ? -1 : idx); } -static int hil_mlc_find_free_di(hil_mlc *mlc) -{ +static int hil_mlc_find_free_di(hil_mlc *mlc) { int idx; - - /* TODO: Pick all-zero slots first, failing that, - * randomize the slot picked among those eligible. + /* TODO: Pick all-zero slots first, failing that, + * randomize the slot picked among those eligible. */ for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { - int j, found = 0; - - for (j = 0; j < 7 ; j++) - if (mlc->di_map[j] == idx) - found++; - - if (!found) - break; + int j, found; + found = 0; + for (j = 0; j < 7 ; j++) { + if (mlc->di_map[j] == idx) found++; + } + if (!found) break; } - - return idx; /* Note: It is guaranteed at least one above will match */ + return(idx); /* Note: It is guaranteed at least one above will match */ } -static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) -{ +static inline void hil_mlc_clean_serio_map(hil_mlc *mlc) { int idx; - for (idx = 0; idx < HIL_MLC_DEVMEM; idx++) { - int j, found = 0; - - for (j = 0; j < 7 ; j++) - if (mlc->di_map[j] == idx) - found++; - - if (!found) - mlc->serio_map[idx].di_revmap = -1; + int j, found; + found = 0; + for (j = 0; j < 7 ; j++) { + if (mlc->di_map[j] == idx) found++; + } + if (!found) mlc->serio_map[idx].di_revmap = -1; } } -static void hil_mlc_send_polls(hil_mlc *mlc) -{ +static void hil_mlc_send_polls(hil_mlc *mlc) { int did, i, cnt; struct serio *serio; struct serio_driver *drv; @@ -173,31 +157,26 @@ static void hil_mlc_send_polls(hil_mlc *mlc) while (mlc->icount < 15 - i) { hil_packet p; - p = mlc->ipacket[i]; if (did != (p & HIL_PKT_ADDR_MASK) >> 8) { - if (drv && drv->interrupt) { - drv->interrupt(serio, 0, 0); - drv->interrupt(serio, HIL_ERR_INT >> 16, 0); - drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); - drv->interrupt(serio, HIL_CMD_POL + cnt, 0); - } + if (drv == NULL || drv->interrupt == NULL) goto skip; + drv->interrupt(serio, 0, 0); + drv->interrupt(serio, HIL_ERR_INT >> 16, 0); + drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); + drv->interrupt(serio, HIL_CMD_POL + cnt, 0); + skip: did = (p & HIL_PKT_ADDR_MASK) >> 8; serio = did ? mlc->serio[mlc->di_map[did-1]] : NULL; drv = (serio != NULL) ? serio->drv : NULL; cnt = 0; } - - cnt++; - i++; - - if (drv && drv->interrupt) { - drv->interrupt(serio, (p >> 24), 0); - drv->interrupt(serio, (p >> 16) & 0xff, 0); - drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); - drv->interrupt(serio, p & 0xff, 0); - } + cnt++; i++; + if (drv == NULL || drv->interrupt == NULL) continue; + drv->interrupt(serio, (p >> 24), 0); + drv->interrupt(serio, (p >> 16) & 0xff, 0); + drv->interrupt(serio, (p >> 8) & ~HIL_PKT_ADDR_MASK, 0); + drv->interrupt(serio, p & 0xff, 0); } } @@ -236,16 +215,12 @@ static void hil_mlc_send_polls(hil_mlc *mlc) #define HILSEN_DOZE (HILSEN_SAME | HILSEN_SCHED | HILSEN_BREAK) #define HILSEN_SLEEP (HILSEN_SAME | HILSEN_BREAK) -static int hilse_match(hil_mlc *mlc, int unused) -{ +static int hilse_match(hil_mlc *mlc, int unused) { int rc; - rc = hil_mlc_match_di_scratch(mlc); if (rc == -1) { rc = hil_mlc_find_free_di(mlc); - if (rc == -1) - goto err; - + if (rc == -1) goto err; #ifdef HIL_MLC_DEBUG printk(KERN_DEBUG PREFIX "new in slot %i\n", rc); #endif @@ -256,7 +231,6 @@ static int hilse_match(hil_mlc *mlc, int unused) serio_rescan(mlc->serio[rc]); return -1; } - mlc->di_map[mlc->ddi] = rc; #ifdef HIL_MLC_DEBUG printk(KERN_DEBUG PREFIX "same in slot %i\n", rc); @@ -264,177 +238,152 @@ static int hilse_match(hil_mlc *mlc, int unused) mlc->serio_map[rc].di_revmap = mlc->ddi; hil_mlc_clean_serio_map(mlc); return 0; - err: printk(KERN_ERR PREFIX "Residual device slots exhausted, close some serios!\n"); return 1; } /* An LCV used to prevent runaway loops, forces 5 second sleep when reset. */ -static int hilse_init_lcv(hil_mlc *mlc, int unused) -{ +static int hilse_init_lcv(hil_mlc *mlc, int unused) { struct timeval tv; do_gettimeofday(&tv); - if (mlc->lcv && (tv.tv_sec - mlc->lcv_tv.tv_sec) < 5) - return -1; - + if(mlc->lcv == 0) goto restart; /* First init, no need to dally */ + if(tv.tv_sec - mlc->lcv_tv.tv_sec < 5) return -1; + restart: mlc->lcv_tv = tv; mlc->lcv = 0; - return 0; } -static int hilse_inc_lcv(hil_mlc *mlc, int lim) -{ - return mlc->lcv++ >= lim ? -1 : 0; +static int hilse_inc_lcv(hil_mlc *mlc, int lim) { + if (mlc->lcv++ >= lim) return -1; + return 0; } #if 0 -static int hilse_set_lcv(hil_mlc *mlc, int val) -{ +static int hilse_set_lcv(hil_mlc *mlc, int val) { mlc->lcv = val; - return 0; } #endif /* Management of the discovered device index (zero based, -1 means no devs) */ -static int hilse_set_ddi(hil_mlc *mlc, int val) -{ +static int hilse_set_ddi(hil_mlc *mlc, int val) { mlc->ddi = val; hil_mlc_clear_di_map(mlc, val + 1); - return 0; } -static int hilse_dec_ddi(hil_mlc *mlc, int unused) -{ +static int hilse_dec_ddi(hil_mlc *mlc, int unused) { mlc->ddi--; - if (mlc->ddi <= -1) { + if (mlc->ddi <= -1) { mlc->ddi = -1; hil_mlc_clear_di_map(mlc, 0); return -1; } hil_mlc_clear_di_map(mlc, mlc->ddi + 1); - return 0; } -static int hilse_inc_ddi(hil_mlc *mlc, int unused) -{ - BUG_ON(mlc->ddi >= 6); +static int hilse_inc_ddi(hil_mlc *mlc, int unused) { + if (mlc->ddi >= 6) { + BUG(); + return -1; + } mlc->ddi++; - return 0; } -static int hilse_take_idd(hil_mlc *mlc, int unused) -{ +static int hilse_take_idd(hil_mlc *mlc, int unused) { int i; - /* Help the state engine: - * Is this a real IDD response or just an echo? + /* Help the state engine: + * Is this a real IDD response or just an echo? * - * Real IDD response does not start with a command. + * Real IDD response does not start with a command. */ - if (mlc->ipacket[0] & HIL_PKT_CMD) - goto bail; - + if (mlc->ipacket[0] & HIL_PKT_CMD) goto bail; /* Should have the command echoed further down. */ for (i = 1; i < 16; i++) { - if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == + if (((mlc->ipacket[i] & HIL_PKT_ADDR_MASK) == (mlc->ipacket[0] & HIL_PKT_ADDR_MASK)) && - (mlc->ipacket[i] & HIL_PKT_CMD) && + (mlc->ipacket[i] & HIL_PKT_CMD) && ((mlc->ipacket[i] & HIL_PKT_DATA_MASK) == HIL_CMD_IDD)) break; } - if (i > 15) - goto bail; - + if (i > 15) goto bail; /* And the rest of the packets should still be clear. */ - while (++i < 16) - if (mlc->ipacket[i]) - break; - - if (i < 16) - goto bail; - - for (i = 0; i < 16; i++) - mlc->di_scratch.idd[i] = + while (++i < 16) { + if (mlc->ipacket[i]) break; + } + if (i < 16) goto bail; + for (i = 0; i < 16; i++) { + mlc->di_scratch.idd[i] = mlc->ipacket[i] & HIL_PKT_DATA_MASK; - + } /* Next step is to see if RSC supported */ - if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) + if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_RSC) return HILSEN_NEXT; - - if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) + if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) return HILSEN_DOWN | 4; - return 0; - bail: mlc->ddi--; - return -1; /* This should send us off to ACF */ } -static int hilse_take_rsc(hil_mlc *mlc, int unused) -{ +static int hilse_take_rsc(hil_mlc *mlc, int unused) { int i; - for (i = 0; i < 16; i++) - mlc->di_scratch.rsc[i] = + for (i = 0; i < 16; i++) { + mlc->di_scratch.rsc[i] = mlc->ipacket[i] & HIL_PKT_DATA_MASK; - + } /* Next step is to see if EXD supported (IDD has already been read) */ - if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) + if (mlc->di_scratch.idd[1] & HIL_IDD_HEADER_EXD) return HILSEN_NEXT; - return 0; } -static int hilse_take_exd(hil_mlc *mlc, int unused) -{ +static int hilse_take_exd(hil_mlc *mlc, int unused) { int i; - for (i = 0; i < 16; i++) - mlc->di_scratch.exd[i] = + for (i = 0; i < 16; i++) { + mlc->di_scratch.exd[i] = mlc->ipacket[i] & HIL_PKT_DATA_MASK; - + } /* Next step is to see if RNM supported. */ - if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) + if (mlc->di_scratch.exd[0] & HIL_EXD_HEADER_RNM) return HILSEN_NEXT; - return 0; } -static int hilse_take_rnm(hil_mlc *mlc, int unused) -{ +static int hilse_take_rnm(hil_mlc *mlc, int unused) { int i; - for (i = 0; i < 16; i++) - mlc->di_scratch.rnm[i] = + for (i = 0; i < 16; i++) { + mlc->di_scratch.rnm[i] = mlc->ipacket[i] & HIL_PKT_DATA_MASK; - - printk(KERN_INFO PREFIX "Device name gotten: %16s\n", - mlc->di_scratch.rnm); - + } + do { + char nam[17]; + snprintf(nam, 16, "%s", mlc->di_scratch.rnm); + nam[16] = '\0'; + printk(KERN_INFO PREFIX "Device name gotten: %s\n", nam); + } while (0); return 0; } -static int hilse_operate(hil_mlc *mlc, int repoll) -{ +static int hilse_operate(hil_mlc *mlc, int repoll) { - if (mlc->opercnt == 0) - hil_mlcs_probe = 0; + if (mlc->opercnt == 0) hil_mlcs_probe = 0; mlc->opercnt = 1; hil_mlc_send_polls(mlc); - if (!hil_mlcs_probe) - return 0; + if (!hil_mlcs_probe) return 0; hil_mlcs_probe = 0; mlc->opercnt = 0; return 1; @@ -459,7 +408,7 @@ static int hilse_operate(hil_mlc *mlc, int repoll) #define OUT_LAST(pack) \ { HILSE_OUT_LAST, { .packet = pack }, 0, 0, 0, 0 }, -const struct hilse_node hil_mlc_se[HILSEN_END] = { +struct hilse_node hil_mlc_se[HILSEN_END] = { /* 0 HILSEN_START */ FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) @@ -479,7 +428,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { EXPECT(HIL_ERR_INT | TEST_PACKET(0xa), 2000, HILSEN_NEXT, HILSEN_RESTART, HILSEN_RESTART) OUT(HIL_CTRL_ONLY | 0) /* Disable test mode */ - + /* 9 HILSEN_DHR */ FUNC(hilse_init_lcv, 0, HILSEN_NEXT, HILSEN_SLEEP, 0) @@ -490,7 +439,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { IN(300000, HILSEN_DHR2, HILSEN_DHR2, HILSEN_NEXT) /* 14 HILSEN_IFC */ - OUT(HIL_PKT_CMD | HIL_CMD_IFC) + OUT(HIL_PKT_CMD | HIL_CMD_IFC) EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, 20000, HILSEN_DISC, HILSEN_DHR2, HILSEN_NEXT ) @@ -506,7 +455,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { /* 18 HILSEN_HEAL */ OUT_LAST(HIL_CMD_ELB) - EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, + EXPECT_LAST(HIL_CMD_ELB | HIL_ERR_INT, 20000, HILSEN_REPOLL, HILSEN_DSR, HILSEN_NEXT) FUNC(hilse_dec_ddi, 0, HILSEN_HEAL, HILSEN_NEXT, 0) @@ -554,7 +503,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { /* 44 HILSEN_PROBE */ OUT_LAST(HIL_PKT_CMD | HIL_CMD_EPT) - IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) + IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) OUT_DISC(HIL_PKT_CMD | HIL_CMD_ELB) IN(10000, HILSEN_DISC, HILSEN_DSR, HILSEN_NEXT) OUT(HIL_PKT_CMD | HIL_CMD_ACF | 1) @@ -565,7 +514,7 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { /* 52 HILSEN_DSR */ FUNC(hilse_set_ddi, -1, HILSEN_NEXT, 0, 0) OUT(HIL_PKT_CMD | HIL_CMD_DSR) - IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) + IN(20000, HILSEN_DHR, HILSEN_DHR, HILSEN_IFC) /* 55 HILSEN_REPOLL */ OUT(HIL_PKT_CMD | HIL_CMD_RPL) @@ -574,15 +523,14 @@ const struct hilse_node hil_mlc_se[HILSEN_END] = { FUNC(hilse_operate, 1, HILSEN_OPERATE, HILSEN_IFC, HILSEN_PROBE) /* 58 HILSEN_IFCACF */ - OUT(HIL_PKT_CMD | HIL_CMD_IFC) + OUT(HIL_PKT_CMD | HIL_CMD_IFC) EXPECT(HIL_PKT_CMD | HIL_CMD_IFC | HIL_ERR_INT, 20000, HILSEN_ACF2, HILSEN_DHR2, HILSEN_HEAL) /* 60 HILSEN_END */ }; -static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node) -{ +static inline void hilse_setup_input(hil_mlc *mlc, struct hilse_node *node) { switch (node->act) { case HILSE_EXPECT_DISC: @@ -607,27 +555,29 @@ static inline void hilse_setup_input(hil_mlc *mlc, const struct hilse_node *node do_gettimeofday(&(mlc->instart)); mlc->icount = 15; memset(mlc->ipacket, 0, 16 * sizeof(hil_packet)); - BUG_ON(down_trylock(&mlc->isem)); + BUG_ON(down_trylock(&(mlc->isem))); + + return; } #ifdef HIL_MLC_DEBUG -static int doze; +static int doze = 0; static int seidx; /* For debug */ +static int kick = 1; #endif -static int hilse_donode(hil_mlc *mlc) -{ - const struct hilse_node *node; +static int hilse_donode (hil_mlc *mlc) { + struct hilse_node *node; int nextidx = 0; int sched_long = 0; unsigned long flags; #ifdef HIL_MLC_DEBUG - if (mlc->seidx && mlc->seidx != seidx && - mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { - printk(KERN_DEBUG PREFIX "z%i \n {%i}", doze, mlc->seidx); + if (mlc->seidx && (mlc->seidx != seidx) && mlc->seidx != 41 && mlc->seidx != 42 && mlc->seidx != 43) { + printk(KERN_DEBUG PREFIX "z%i \n%s {%i}", doze, kick ? "K" : "", mlc->seidx); doze = 0; } + kick = 0; seidx = mlc->seidx; #endif @@ -638,61 +588,52 @@ static int hilse_donode(hil_mlc *mlc) hil_packet pack; case HILSE_FUNC: - BUG_ON(node->object.func == NULL); + if (node->object.func == NULL) break; rc = node->object.func(mlc, node->arg); - nextidx = (rc > 0) ? node->ugly : + nextidx = (rc > 0) ? node->ugly : ((rc < 0) ? node->bad : node->good); - if (nextidx == HILSEN_FOLLOW) - nextidx = rc; + if (nextidx == HILSEN_FOLLOW) nextidx = rc; break; - case HILSE_EXPECT_LAST: case HILSE_EXPECT_DISC: case HILSE_EXPECT: case HILSE_IN: /* Already set up from previous HILSE_OUT_* */ - write_lock_irqsave(&mlc->lock, flags); + write_lock_irqsave(&(mlc->lock), flags); rc = mlc->in(mlc, node->arg); if (rc == 2) { nextidx = HILSEN_DOZE; sched_long = 1; - write_unlock_irqrestore(&mlc->lock, flags); + write_unlock_irqrestore(&(mlc->lock), flags); break; } - if (rc == 1) - nextidx = node->ugly; - else if (rc == 0) - nextidx = node->good; - else - nextidx = node->bad; + if (rc == 1) nextidx = node->ugly; + else if (rc == 0) nextidx = node->good; + else nextidx = node->bad; mlc->istarted = 0; - write_unlock_irqrestore(&mlc->lock, flags); + write_unlock_irqrestore(&(mlc->lock), flags); break; - case HILSE_OUT_LAST: - write_lock_irqsave(&mlc->lock, flags); + write_lock_irqsave(&(mlc->lock), flags); pack = node->object.packet; pack |= ((mlc->ddi + 1) << HIL_PKT_ADDR_SHIFT); goto out; - case HILSE_OUT_DISC: - write_lock_irqsave(&mlc->lock, flags); + write_lock_irqsave(&(mlc->lock), flags); pack = node->object.packet; pack |= ((mlc->ddi + 2) << HIL_PKT_ADDR_SHIFT); goto out; - case HILSE_OUT: - write_lock_irqsave(&mlc->lock, flags); + write_lock_irqsave(&(mlc->lock), flags); pack = node->object.packet; out: - if (mlc->istarted) - goto out2; + if (mlc->istarted) goto out2; /* Prepare to receive input */ if ((node + 1)->act & HILSE_IN) hilse_setup_input(mlc, node + 1); out2: - write_unlock_irqrestore(&mlc->lock, flags); + write_unlock_irqrestore(&(mlc->lock), flags); if (down_trylock(&mlc->osem)) { nextidx = HILSEN_DOZE; @@ -700,71 +641,60 @@ static int hilse_donode(hil_mlc *mlc) } up(&mlc->osem); - write_lock_irqsave(&mlc->lock, flags); - if (!mlc->ostarted) { + write_lock_irqsave(&(mlc->lock), flags); + if (!(mlc->ostarted)) { mlc->ostarted = 1; mlc->opacket = pack; mlc->out(mlc); nextidx = HILSEN_DOZE; - write_unlock_irqrestore(&mlc->lock, flags); + write_unlock_irqrestore(&(mlc->lock), flags); break; } mlc->ostarted = 0; do_gettimeofday(&(mlc->instart)); - write_unlock_irqrestore(&mlc->lock, flags); + write_unlock_irqrestore(&(mlc->lock), flags); nextidx = HILSEN_NEXT; break; - case HILSE_CTS: - write_lock_irqsave(&mlc->lock, flags); nextidx = mlc->cts(mlc) ? node->bad : node->good; - write_unlock_irqrestore(&mlc->lock, flags); break; - default: BUG(); + nextidx = 0; + break; } #ifdef HIL_MLC_DEBUG - if (nextidx == HILSEN_DOZE) - doze++; + if (nextidx == HILSEN_DOZE) doze++; #endif while (nextidx & HILSEN_SCHED) { struct timeval tv; - if (!sched_long) - goto sched; + if (!sched_long) goto sched; do_gettimeofday(&tv); - tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); + tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); tv.tv_usec -= mlc->instart.tv_usec; if (tv.tv_usec >= mlc->intimeout) goto sched; - tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / USEC_PER_SEC; + tv.tv_usec = (mlc->intimeout - tv.tv_usec) * HZ / 1000000; if (!tv.tv_usec) goto sched; mod_timer(&hil_mlcs_kicker, jiffies + tv.tv_usec); break; sched: tasklet_schedule(&hil_mlcs_tasklet); break; - } - - if (nextidx & HILSEN_DOWN) - mlc->seidx += nextidx & HILSEN_MASK; - else if (nextidx & HILSEN_UP) - mlc->seidx -= nextidx & HILSEN_MASK; - else - mlc->seidx = nextidx & HILSEN_MASK; - - if (nextidx & HILSEN_BREAK) - return 1; + } + if (nextidx & HILSEN_DOWN) mlc->seidx += nextidx & HILSEN_MASK; + else if (nextidx & HILSEN_UP) mlc->seidx -= nextidx & HILSEN_MASK; + else mlc->seidx = nextidx & HILSEN_MASK; + if (nextidx & HILSEN_BREAK) return 1; return 0; } /******************** tasklet context functions **************************/ -static void hil_mlcs_process(unsigned long unused) -{ +static void hil_mlcs_process(unsigned long unused) { struct list_head *tmp; read_lock(&hil_mlcs_lock); @@ -772,20 +702,19 @@ static void hil_mlcs_process(unsigned long unused) struct hil_mlc *mlc = list_entry(tmp, hil_mlc, list); while (hilse_donode(mlc) == 0) { #ifdef HIL_MLC_DEBUG - if (mlc->seidx != 41 && - mlc->seidx != 42 && - mlc->seidx != 43) - printk(KERN_DEBUG PREFIX " + "); + if (mlc->seidx != 41 && + mlc->seidx != 42 && + mlc->seidx != 43) + printk(KERN_DEBUG PREFIX " + "); #endif - } + }; } read_unlock(&hil_mlcs_lock); } /************************* Keepalive timer task *********************/ -void hil_mlcs_timer(unsigned long data) -{ +void hil_mlcs_timer (unsigned long data) { hil_mlcs_probe = 1; tasklet_schedule(&hil_mlcs_tasklet); /* Re-insert the periodic task. */ @@ -795,25 +724,28 @@ void hil_mlcs_timer(unsigned long data) /******************** user/kernel context functions **********************/ -static int hil_mlc_serio_write(struct serio *serio, unsigned char c) -{ +static int hil_mlc_serio_write(struct serio *serio, unsigned char c) { struct hil_mlc_serio_map *map; struct hil_mlc *mlc; struct serio_driver *drv; uint8_t *idx, *last; map = serio->port_data; - BUG_ON(map == NULL); - + if (map == NULL) { + BUG(); + return -EIO; + } mlc = map->mlc; - BUG_ON(mlc == NULL); - - mlc->serio_opacket[map->didx] |= + if (mlc == NULL) { + BUG(); + return -EIO; + } + mlc->serio_opacket[map->didx] |= ((hil_packet)c) << (8 * (3 - mlc->serio_oidx[map->didx])); if (mlc->serio_oidx[map->didx] >= 3) { /* for now only commands */ - if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) + if (!(mlc->serio_opacket[map->didx] & HIL_PKT_CMD)) return -EIO; switch (mlc->serio_opacket[map->didx] & HIL_PKT_DATA_MASK) { case HIL_CMD_IDD: @@ -839,11 +771,12 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) return -EIO; emu: drv = serio->drv; - BUG_ON(drv == NULL); - + if (drv == NULL) { + BUG(); + return -EIO; + } last = idx + 15; - while ((last != idx) && (*last == 0)) - last--; + while ((last != idx) && (*last == 0)) last--; while (idx != last) { drv->interrupt(serio, 0, 0); @@ -856,15 +789,14 @@ static int hil_mlc_serio_write(struct serio *serio, unsigned char c) drv->interrupt(serio, HIL_ERR_INT >> 16, 0); drv->interrupt(serio, HIL_PKT_CMD >> 8, 0); drv->interrupt(serio, *idx, 0); - + mlc->serio_oidx[map->didx] = 0; mlc->serio_opacket[map->didx] = 0; return 0; } -static int hil_mlc_serio_open(struct serio *serio) -{ +static int hil_mlc_serio_open(struct serio *serio) { struct hil_mlc_serio_map *map; struct hil_mlc *mlc; @@ -872,57 +804,67 @@ static int hil_mlc_serio_open(struct serio *serio) return -EBUSY; map = serio->port_data; - BUG_ON(map == NULL); - + if (map == NULL) { + BUG(); + return -ENODEV; + } mlc = map->mlc; - BUG_ON(mlc == NULL); + if (mlc == NULL) { + BUG(); + return -ENODEV; + } return 0; } -static void hil_mlc_serio_close(struct serio *serio) -{ +static void hil_mlc_serio_close(struct serio *serio) { struct hil_mlc_serio_map *map; struct hil_mlc *mlc; map = serio->port_data; - BUG_ON(map == NULL); - + if (map == NULL) { + BUG(); + return; + } mlc = map->mlc; - BUG_ON(mlc == NULL); + if (mlc == NULL) { + BUG(); + return; + } serio_set_drvdata(serio, NULL); serio->drv = NULL; /* TODO wake up interruptable */ } -static const struct serio_device_id hil_mlc_serio_id = { +static struct serio_device_id hil_mlc_serio_id = { .type = SERIO_HIL_MLC, .proto = SERIO_HIL, .extra = SERIO_ANY, .id = SERIO_ANY, }; -int hil_mlc_register(hil_mlc *mlc) -{ +int hil_mlc_register(hil_mlc *mlc) { int i; - unsigned long flags; + unsigned long flags; - BUG_ON(mlc == NULL); + if (mlc == NULL) { + return -EINVAL; + } mlc->istarted = 0; - mlc->ostarted = 0; + mlc->ostarted = 0; - rwlock_init(&mlc->lock); - init_MUTEX(&mlc->osem); + rwlock_init(&mlc->lock); + init_MUTEX(&(mlc->osem)); - init_MUTEX(&mlc->isem); - mlc->icount = -1; - mlc->imatch = 0; + init_MUTEX(&(mlc->isem)); + mlc->icount = -1; + mlc->imatch = 0; mlc->opercnt = 0; - init_MUTEX_LOCKED(&(mlc->csem)); + init_MUTEX_LOCKED(&(mlc->csem)); hil_mlc_clear_di_scratch(mlc); hil_mlc_clear_di_map(mlc, 0); @@ -931,8 +873,6 @@ int hil_mlc_register(hil_mlc *mlc) hil_mlc_copy_di_scratch(mlc, i); mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); mlc->serio[i] = mlc_serio; - snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); - snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); mlc_serio->id = hil_mlc_serio_id; mlc_serio->write = hil_mlc_serio_write; mlc_serio->open = hil_mlc_serio_open; @@ -957,18 +897,19 @@ int hil_mlc_register(hil_mlc *mlc) return 0; } -int hil_mlc_unregister(hil_mlc *mlc) -{ +int hil_mlc_unregister(hil_mlc *mlc) { struct list_head *tmp; - unsigned long flags; + unsigned long flags; int i; - BUG_ON(mlc == NULL); + if (mlc == NULL) + return -EINVAL; write_lock_irqsave(&hil_mlcs_lock, flags); - list_for_each(tmp, &hil_mlcs) + list_for_each(tmp, &hil_mlcs) { if (list_entry(tmp, hil_mlc, list) == mlc) goto found; + } /* not found in list */ write_unlock_irqrestore(&hil_mlcs_lock, flags); @@ -977,7 +918,7 @@ int hil_mlc_unregister(hil_mlc *mlc) found: list_del(tmp); - write_unlock_irqrestore(&hil_mlcs_lock, flags); + write_unlock_irqrestore(&hil_mlcs_lock, flags); for (i = 0; i < HIL_MLC_DEVMEM; i++) { serio_unregister_port(mlc->serio[i]); @@ -1001,7 +942,7 @@ static int __init hil_mlc_init(void) return 0; } - + static void __exit hil_mlc_exit(void) { del_timer(&hil_mlcs_kicker); @@ -1009,6 +950,6 @@ static void __exit hil_mlc_exit(void) tasklet_disable(&hil_mlcs_tasklet); tasklet_kill(&hil_mlcs_tasklet); } - + module_init(hil_mlc_init); module_exit(hil_mlc_exit); diff --git a/trunk/drivers/input/serio/hp_sdc.c b/trunk/drivers/input/serio/hp_sdc.c index 6af199805ffc..b57370dc4e3d 100644 --- a/trunk/drivers/input/serio/hp_sdc.c +++ b/trunk/drivers/input/serio/hp_sdc.c @@ -34,27 +34,27 @@ * * Driver theory of operation: * - * hp_sdc_put does all writing to the SDC. ISR can run on a different - * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time + * hp_sdc_put does all writing to the SDC. ISR can run on a different + * CPU than hp_sdc_put, but only one CPU runs hp_sdc_put at a time * (it cannot really benefit from SMP anyway.) A tasket fit this perfectly. * - * All data coming back from the SDC is sent via interrupt and can be read - * fully in the ISR, so there are no latency/throughput problems there. - * The problem is with output, due to the slow clock speed of the SDC - * compared to the CPU. This should not be too horrible most of the time, - * but if used with HIL devices that support the multibyte transfer command, - * keeping outbound throughput flowing at the 6500KBps that the HIL is + * All data coming back from the SDC is sent via interrupt and can be read + * fully in the ISR, so there are no latency/throughput problems there. + * The problem is with output, due to the slow clock speed of the SDC + * compared to the CPU. This should not be too horrible most of the time, + * but if used with HIL devices that support the multibyte transfer command, + * keeping outbound throughput flowing at the 6500KBps that the HIL is * capable of is more than can be done at HZ=100. * - * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf - * is set to 0 when the IBF flag in the status register has cleared. ISR - * may do this, and may also access the parts of queued transactions related - * to reading data back from the SDC, but otherwise will not touch the + * Busy polling for IBF clear wastes CPU cycles and bus cycles. hp_sdc.ibf + * is set to 0 when the IBF flag in the status register has cleared. ISR + * may do this, and may also access the parts of queued transactions related + * to reading data back from the SDC, but otherwise will not touch the * hp_sdc state. Whenever a register is written hp_sdc.ibf is set to 1. * * The i8042 write index and the values in the 4-byte input buffer * starting at 0x70 are kept track of in hp_sdc.wi, and .r7[], respectively, - * to minimize the amount of IO needed to the SDC. However these values + * to minimize the amount of IO needed to the SDC. However these values * do not need to be locked since they are only ever accessed by hp_sdc_put. * * A timer task schedules the tasklet once per second just to make @@ -100,46 +100,39 @@ EXPORT_SYMBOL(hp_sdc_release_timer_irq); EXPORT_SYMBOL(hp_sdc_release_hil_irq); EXPORT_SYMBOL(hp_sdc_release_cooked_irq); -EXPORT_SYMBOL(__hp_sdc_enqueue_transaction); EXPORT_SYMBOL(hp_sdc_enqueue_transaction); EXPORT_SYMBOL(hp_sdc_dequeue_transaction); static hp_i8042_sdc hp_sdc; /* All driver state is kept in here. */ /*************** primitives for use in any context *********************/ -static inline uint8_t hp_sdc_status_in8(void) -{ +static inline uint8_t hp_sdc_status_in8 (void) { uint8_t status; unsigned long flags; write_lock_irqsave(&hp_sdc.ibf_lock, flags); status = sdc_readb(hp_sdc.status_io); - if (!(status & HP_SDC_STATUS_IBF)) - hp_sdc.ibf = 0; + if (!(status & HP_SDC_STATUS_IBF)) hp_sdc.ibf = 0; write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); return status; } -static inline uint8_t hp_sdc_data_in8(void) -{ - return sdc_readb(hp_sdc.data_io); +static inline uint8_t hp_sdc_data_in8 (void) { + return sdc_readb(hp_sdc.data_io); } -static inline void hp_sdc_status_out8(uint8_t val) -{ +static inline void hp_sdc_status_out8 (uint8_t val) { unsigned long flags; write_lock_irqsave(&hp_sdc.ibf_lock, flags); hp_sdc.ibf = 1; - if ((val & 0xf0) == 0xe0) - hp_sdc.wi = 0xff; + if ((val & 0xf0) == 0xe0) hp_sdc.wi = 0xff; sdc_writeb(val, hp_sdc.status_io); write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); } -static inline void hp_sdc_data_out8(uint8_t val) -{ +static inline void hp_sdc_data_out8 (uint8_t val) { unsigned long flags; write_lock_irqsave(&hp_sdc.ibf_lock, flags); @@ -148,12 +141,11 @@ static inline void hp_sdc_data_out8(uint8_t val) write_unlock_irqrestore(&hp_sdc.ibf_lock, flags); } -/* Care must be taken to only invoke hp_sdc_spin_ibf when - * absolutely needed, or in rarely invoked subroutines. - * Not only does it waste CPU cycles, it also wastes bus cycles. +/* Care must be taken to only invoke hp_sdc_spin_ibf when + * absolutely needed, or in rarely invoked subroutines. + * Not only does it waste CPU cycles, it also wastes bus cycles. */ -static inline void hp_sdc_spin_ibf(void) -{ +static inline void hp_sdc_spin_ibf(void) { unsigned long flags; rwlock_t *lock; @@ -166,21 +158,19 @@ static inline void hp_sdc_spin_ibf(void) } read_unlock(lock); write_lock(lock); - while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) - { } + while (sdc_readb(hp_sdc.status_io) & HP_SDC_STATUS_IBF) {}; hp_sdc.ibf = 0; write_unlock_irqrestore(lock, flags); } /************************ Interrupt context functions ************************/ -static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data) -{ +static void hp_sdc_take (int irq, void *dev_id, uint8_t status, uint8_t data) { hp_sdc_transaction *curr; read_lock(&hp_sdc.rtq_lock); if (hp_sdc.rcurr < 0) { - read_unlock(&hp_sdc.rtq_lock); + read_unlock(&hp_sdc.rtq_lock); return; } curr = hp_sdc.tq[hp_sdc.rcurr]; @@ -193,27 +183,25 @@ static void hp_sdc_take(int irq, void *dev_id, uint8_t status, uint8_t data) if (hp_sdc.rqty <= 0) { /* All data has been gathered. */ - if (curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) - if (curr->act.semaphore) - up(curr->act.semaphore); - - if (curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) + if(curr->seq[curr->actidx] & HP_SDC_ACT_SEMAPHORE) { + if (curr->act.semaphore) up(curr->act.semaphore); + } + if(curr->seq[curr->actidx] & HP_SDC_ACT_CALLBACK) { if (curr->act.irqhook) curr->act.irqhook(irq, dev_id, status, data); - + } curr->actidx = curr->idx; curr->idx++; /* Return control of this transaction */ write_lock(&hp_sdc.rtq_lock); - hp_sdc.rcurr = -1; + hp_sdc.rcurr = -1; hp_sdc.rqty = 0; write_unlock(&hp_sdc.rtq_lock); tasklet_schedule(&hp_sdc.task); } } -static irqreturn_t hp_sdc_isr(int irq, void *dev_id) -{ +static irqreturn_t hp_sdc_isr(int irq, void *dev_id) { uint8_t status, data; status = hp_sdc_status_in8(); @@ -221,74 +209,67 @@ static irqreturn_t hp_sdc_isr(int irq, void *dev_id) data = hp_sdc_data_in8(); /* For now we are ignoring these until we get the SDC to behave. */ - if (((status & 0xf1) == 0x51) && data == 0x82) - return IRQ_HANDLED; + if (((status & 0xf1) == 0x51) && data == 0x82) { + return IRQ_HANDLED; + } - switch (status & HP_SDC_STATUS_IRQMASK) { - case 0: /* This case is not documented. */ + switch(status & HP_SDC_STATUS_IRQMASK) { + case 0: /* This case is not documented. */ break; - - case HP_SDC_STATUS_USERTIMER: - case HP_SDC_STATUS_PERIODIC: - case HP_SDC_STATUS_TIMER: + case HP_SDC_STATUS_USERTIMER: + case HP_SDC_STATUS_PERIODIC: + case HP_SDC_STATUS_TIMER: read_lock(&hp_sdc.hook_lock); - if (hp_sdc.timer != NULL) + if (hp_sdc.timer != NULL) hp_sdc.timer(irq, dev_id, status, data); read_unlock(&hp_sdc.hook_lock); break; - - case HP_SDC_STATUS_REG: + case HP_SDC_STATUS_REG: hp_sdc_take(irq, dev_id, status, data); break; - - case HP_SDC_STATUS_HILCMD: - case HP_SDC_STATUS_HILDATA: + case HP_SDC_STATUS_HILCMD: + case HP_SDC_STATUS_HILDATA: read_lock(&hp_sdc.hook_lock); if (hp_sdc.hil != NULL) hp_sdc.hil(irq, dev_id, status, data); read_unlock(&hp_sdc.hook_lock); break; - - case HP_SDC_STATUS_PUP: + case HP_SDC_STATUS_PUP: read_lock(&hp_sdc.hook_lock); if (hp_sdc.pup != NULL) hp_sdc.pup(irq, dev_id, status, data); - else - printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); + else printk(KERN_INFO PREFIX "HP SDC reports successful PUP.\n"); read_unlock(&hp_sdc.hook_lock); break; - - default: + default: read_lock(&hp_sdc.hook_lock); if (hp_sdc.cooked != NULL) hp_sdc.cooked(irq, dev_id, status, data); read_unlock(&hp_sdc.hook_lock); break; } - return IRQ_HANDLED; } -static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) -{ +static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) { int status; - + status = hp_sdc_status_in8(); printk(KERN_WARNING PREFIX "NMI !\n"); -#if 0 +#if 0 if (status & HP_SDC_NMISTATUS_FHS) { read_lock(&hp_sdc.hook_lock); - if (hp_sdc.timer != NULL) + if (hp_sdc.timer != NULL) hp_sdc.timer(irq, dev_id, status, 0); read_unlock(&hp_sdc.hook_lock); - } else { + } + else { /* TODO: pass this on to the HIL handler, or do SAK here? */ printk(KERN_WARNING PREFIX "HIL NMI\n"); } #endif - return IRQ_HANDLED; } @@ -297,17 +278,13 @@ static irqreturn_t hp_sdc_nmisr(int irq, void *dev_id) unsigned long hp_sdc_put(void); -static void hp_sdc_tasklet(unsigned long foo) -{ - write_lock_irq(&hp_sdc.rtq_lock); +static void hp_sdc_tasklet(unsigned long foo) { + write_lock_irq(&hp_sdc.rtq_lock); if (hp_sdc.rcurr >= 0) { struct timeval tv; - do_gettimeofday(&tv); - if (tv.tv_sec > hp_sdc.rtv.tv_sec) - tv.tv_usec += USEC_PER_SEC; - + if (tv.tv_sec > hp_sdc.rtv.tv_sec) tv.tv_usec += 1000000; if (tv.tv_usec - hp_sdc.rtv.tv_usec > HP_SDC_MAX_REG_DELAY) { hp_sdc_transaction *curr; uint8_t tmp; @@ -323,29 +300,27 @@ static void hp_sdc_tasklet(unsigned long foo) hp_sdc.rqty = 0; tmp = curr->seq[curr->actidx]; curr->seq[curr->actidx] |= HP_SDC_ACT_DEAD; - if (tmp & HP_SDC_ACT_SEMAPHORE) - if (curr->act.semaphore) + if(tmp & HP_SDC_ACT_SEMAPHORE) { + if (curr->act.semaphore) up(curr->act.semaphore); - - if (tmp & HP_SDC_ACT_CALLBACK) { + } + if(tmp & HP_SDC_ACT_CALLBACK) { /* Note this means that irqhooks may be called * in tasklet/bh context. */ - if (curr->act.irqhook) + if (curr->act.irqhook) curr->act.irqhook(0, NULL, 0, 0); } - curr->actidx = curr->idx; curr->idx++; - hp_sdc.rcurr = -1; + hp_sdc.rcurr = -1; } } write_unlock_irq(&hp_sdc.rtq_lock); hp_sdc_put(); } -unsigned long hp_sdc_put(void) -{ +unsigned long hp_sdc_put(void) { hp_sdc_transaction *curr; uint8_t act; int idx, curridx; @@ -358,24 +333,19 @@ unsigned long hp_sdc_put(void) requires output, so we skip to the administrativa. */ if (hp_sdc.ibf) { hp_sdc_status_in8(); - if (hp_sdc.ibf) - goto finish; + if (hp_sdc.ibf) goto finish; } anew: /* See if we are in the middle of a sequence. */ - if (hp_sdc.wcurr < 0) - hp_sdc.wcurr = 0; + if (hp_sdc.wcurr < 0) hp_sdc.wcurr = 0; read_lock_irq(&hp_sdc.rtq_lock); - if (hp_sdc.rcurr == hp_sdc.wcurr) - hp_sdc.wcurr++; + if (hp_sdc.rcurr == hp_sdc.wcurr) hp_sdc.wcurr++; read_unlock_irq(&hp_sdc.rtq_lock); - if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) - hp_sdc.wcurr = 0; + if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; curridx = hp_sdc.wcurr; - if (hp_sdc.tq[curridx] != NULL) - goto start; + if (hp_sdc.tq[curridx] != NULL) goto start; while (++curridx != hp_sdc.wcurr) { if (curridx >= HP_SDC_QUEUE_LEN) { @@ -388,8 +358,7 @@ unsigned long hp_sdc_put(void) continue; } read_unlock_irq(&hp_sdc.rtq_lock); - if (hp_sdc.tq[curridx] != NULL) - break; /* Found one. */ + if (hp_sdc.tq[curridx] != NULL) break; /* Found one. */ } if (curridx == hp_sdc.wcurr) { /* There's nothing queued to do. */ curridx = -1; @@ -405,8 +374,7 @@ unsigned long hp_sdc_put(void) goto finish; } - if (hp_sdc.wcurr == -1) - goto done; + if (hp_sdc.wcurr == -1) goto done; curr = hp_sdc.tq[curridx]; idx = curr->actidx; @@ -415,23 +383,20 @@ unsigned long hp_sdc_put(void) hp_sdc.tq[curridx] = NULL; /* Interleave outbound data between the transactions. */ hp_sdc.wcurr++; - if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) - hp_sdc.wcurr = 0; - goto finish; + if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; + goto finish; } act = curr->seq[idx]; idx++; if (curr->idx >= curr->endidx) { - if (act & HP_SDC_ACT_DEALLOC) - kfree(curr); + if (act & HP_SDC_ACT_DEALLOC) kfree(curr); hp_sdc.tq[curridx] = NULL; /* Interleave outbound data between the transactions. */ hp_sdc.wcurr++; - if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) - hp_sdc.wcurr = 0; - goto finish; + if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; + goto finish; } while (act & HP_SDC_ACT_PRECMD) { @@ -444,10 +409,9 @@ unsigned long hp_sdc_put(void) curr->idx++; /* act finished? */ if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_PRECMD) - goto actdone; + goto actdone; /* skip quantity field if data-out sequence follows. */ - if (act & HP_SDC_ACT_DATAOUT) - curr->idx++; + if (act & HP_SDC_ACT_DATAOUT) curr->idx++; goto finish; } if (act & HP_SDC_ACT_DATAOUT) { @@ -459,15 +423,15 @@ unsigned long hp_sdc_put(void) hp_sdc_data_out8(curr->seq[curr->idx]); curr->idx++; /* act finished? */ - if (curr->idx - idx >= qty && - (act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT) + if ((curr->idx - idx >= qty) && + ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAOUT)) goto actdone; goto finish; } idx += qty; act &= ~HP_SDC_ACT_DATAOUT; - } else - while (act & HP_SDC_ACT_DATAREG) { + } + else while (act & HP_SDC_ACT_DATAREG) { int mask; uint8_t w7[4]; @@ -481,30 +445,26 @@ unsigned long hp_sdc_put(void) act &= ~HP_SDC_ACT_DATAREG; break; } - + w7[0] = (mask & 1) ? curr->seq[++idx] : hp_sdc.r7[0]; w7[1] = (mask & 2) ? curr->seq[++idx] : hp_sdc.r7[1]; w7[2] = (mask & 4) ? curr->seq[++idx] : hp_sdc.r7[2]; w7[3] = (mask & 8) ? curr->seq[++idx] : hp_sdc.r7[3]; - + if (hp_sdc.wi > 0x73 || hp_sdc.wi < 0x70 || - w7[hp_sdc.wi - 0x70] == hp_sdc.r7[hp_sdc.wi - 0x70]) { + w7[hp_sdc.wi-0x70] == hp_sdc.r7[hp_sdc.wi-0x70]) { int i = 0; - /* Need to point the write index register */ - while (i < 4 && w7[i] == hp_sdc.r7[i]) - i++; - + /* Need to point the write index register */ + while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; if (i < 4) { hp_sdc_status_out8(HP_SDC_CMD_SET_D0 + i); hp_sdc.wi = 0x70 + i; goto finish; } - idx++; if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) goto actdone; - curr->idx = idx; act &= ~HP_SDC_ACT_DATAREG; break; @@ -516,13 +476,12 @@ unsigned long hp_sdc_put(void) { int i = 0; - while ((i < 4) && w7[i] == hp_sdc.r7[i]) - i++; + while ((i < 4) && w7[i] == hp_sdc.r7[i]) i++; if (i >= 4) { curr->idx = idx + 1; - if ((act & HP_SDC_ACT_DURING) == + if ((act & HP_SDC_ACT_DURING) == HP_SDC_ACT_DATAREG) - goto actdone; + goto actdone; } } goto finish; @@ -538,7 +497,7 @@ unsigned long hp_sdc_put(void) if (act & HP_SDC_ACT_POSTCMD) { - uint8_t postcmd; + uint8_t postcmd; /* curr->idx should == idx at this point. */ postcmd = curr->seq[idx]; @@ -546,12 +505,12 @@ unsigned long hp_sdc_put(void) if (act & HP_SDC_ACT_DATAIN) { /* Start a new read */ - hp_sdc.rqty = curr->seq[curr->idx]; + hp_sdc.rqty = curr->seq[curr->idx]; do_gettimeofday(&hp_sdc.rtv); curr->idx++; /* Still need to lock here in case of spurious irq. */ write_lock_irq(&hp_sdc.rtq_lock); - hp_sdc.rcurr = curridx; + hp_sdc.rcurr = curridx; write_unlock_irq(&hp_sdc.rtq_lock); hp_sdc_status_out8(postcmd); goto finish; @@ -560,86 +519,75 @@ unsigned long hp_sdc_put(void) goto actdone; } - actdone: - if (act & HP_SDC_ACT_SEMAPHORE) +actdone: + if (act & HP_SDC_ACT_SEMAPHORE) { up(curr->act.semaphore); - else if (act & HP_SDC_ACT_CALLBACK) + } + else if (act & HP_SDC_ACT_CALLBACK) { curr->act.irqhook(0,NULL,0,0); - + } if (curr->idx >= curr->endidx) { /* This transaction is over. */ - if (act & HP_SDC_ACT_DEALLOC) - kfree(curr); + if (act & HP_SDC_ACT_DEALLOC) kfree(curr); hp_sdc.tq[curridx] = NULL; - } else { + } + else { curr->actidx = idx + 1; curr->idx = idx + 2; } /* Interleave outbound data between the transactions. */ hp_sdc.wcurr++; - if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) - hp_sdc.wcurr = 0; + if (hp_sdc.wcurr >= HP_SDC_QUEUE_LEN) hp_sdc.wcurr = 0; finish: - /* If by some quirk IBF has cleared and our ISR has run to + /* If by some quirk IBF has cleared and our ISR has run to see that that has happened, do it all again. */ - if (!hp_sdc.ibf && limit++ < 20) - goto anew; + if (!hp_sdc.ibf && limit++ < 20) goto anew; done: - if (hp_sdc.wcurr >= 0) - tasklet_schedule(&hp_sdc.task); + if (hp_sdc.wcurr >= 0) tasklet_schedule(&hp_sdc.task); write_unlock(&hp_sdc.lock); - return 0; } /******* Functions called in either user or kernel context ****/ -int __hp_sdc_enqueue_transaction(hp_sdc_transaction *this) -{ +int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { + unsigned long flags; int i; if (this == NULL) { - BUG(); + tasklet_schedule(&hp_sdc.task); return -EINVAL; - } + }; + + write_lock_irqsave(&hp_sdc.lock, flags); /* Can't have same transaction on queue twice */ - for (i = 0; i < HP_SDC_QUEUE_LEN; i++) - if (hp_sdc.tq[i] == this) - goto fail; + for (i=0; i < HP_SDC_QUEUE_LEN; i++) + if (hp_sdc.tq[i] == this) goto fail; this->actidx = 0; this->idx = 1; /* Search for empty slot */ - for (i = 0; i < HP_SDC_QUEUE_LEN; i++) + for (i=0; i < HP_SDC_QUEUE_LEN; i++) { if (hp_sdc.tq[i] == NULL) { hp_sdc.tq[i] = this; + write_unlock_irqrestore(&hp_sdc.lock, flags); tasklet_schedule(&hp_sdc.task); return 0; } - + } + write_unlock_irqrestore(&hp_sdc.lock, flags); printk(KERN_WARNING PREFIX "No free slot to add transaction.\n"); return -EBUSY; fail: + write_unlock_irqrestore(&hp_sdc.lock,flags); printk(KERN_WARNING PREFIX "Transaction add failed: transaction already queued?\n"); return -EINVAL; } -int hp_sdc_enqueue_transaction(hp_sdc_transaction *this) { - unsigned long flags; - int ret; - - write_lock_irqsave(&hp_sdc.lock, flags); - ret = __hp_sdc_enqueue_transaction(this); - write_unlock_irqrestore(&hp_sdc.lock,flags); - - return ret; -} - -int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) -{ +int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) { unsigned long flags; int i; @@ -647,9 +595,8 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) /* TODO: don't remove it if it's not done. */ - for (i = 0; i < HP_SDC_QUEUE_LEN; i++) - if (hp_sdc.tq[i] == this) - hp_sdc.tq[i] = NULL; + for (i=0; i < HP_SDC_QUEUE_LEN; i++) + if (hp_sdc.tq[i] == this) hp_sdc.tq[i] = NULL; write_unlock_irqrestore(&hp_sdc.lock, flags); return 0; @@ -658,11 +605,11 @@ int hp_sdc_dequeue_transaction(hp_sdc_transaction *this) /********************** User context functions **************************/ -int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) -{ - if (callback == NULL || hp_sdc.dev == NULL) - return -EINVAL; +int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) { + if (callback == NULL || hp_sdc.dev == NULL) { + return -EINVAL; + } write_lock_irq(&hp_sdc.hook_lock); if (hp_sdc.timer != NULL) { write_unlock_irq(&hp_sdc.hook_lock); @@ -682,11 +629,11 @@ int hp_sdc_request_timer_irq(hp_sdc_irqhook *callback) return 0; } -int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) -{ - if (callback == NULL || hp_sdc.dev == NULL) - return -EINVAL; +int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) { + if (callback == NULL || hp_sdc.dev == NULL) { + return -EINVAL; + } write_lock_irq(&hp_sdc.hook_lock); if (hp_sdc.hil != NULL) { write_unlock_irq(&hp_sdc.hook_lock); @@ -703,11 +650,11 @@ int hp_sdc_request_hil_irq(hp_sdc_irqhook *callback) return 0; } -int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) -{ - if (callback == NULL || hp_sdc.dev == NULL) - return -EINVAL; +int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) { + if (callback == NULL || hp_sdc.dev == NULL) { + return -EINVAL; + } write_lock_irq(&hp_sdc.hook_lock); if (hp_sdc.cooked != NULL) { write_unlock_irq(&hp_sdc.hook_lock); @@ -725,8 +672,9 @@ int hp_sdc_request_cooked_irq(hp_sdc_irqhook *callback) return 0; } -int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) -{ +int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) { + + write_lock_irq(&hp_sdc.hook_lock); if ((callback != hp_sdc.timer) || (hp_sdc.timer == NULL)) { @@ -746,8 +694,8 @@ int hp_sdc_release_timer_irq(hp_sdc_irqhook *callback) return 0; } -int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) -{ +int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) { + write_lock_irq(&hp_sdc.hook_lock); if ((callback != hp_sdc.hil) || (hp_sdc.hil == NULL)) { @@ -767,8 +715,8 @@ int hp_sdc_release_hil_irq(hp_sdc_irqhook *callback) return 0; } -int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) -{ +int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) { + write_lock_irq(&hp_sdc.hook_lock); if ((callback != hp_sdc.cooked) || (hp_sdc.cooked == NULL)) { @@ -790,8 +738,7 @@ int hp_sdc_release_cooked_irq(hp_sdc_irqhook *callback) /************************* Keepalive timer task *********************/ -void hp_sdc_kicker (unsigned long data) -{ +void hp_sdc_kicker (unsigned long data) { tasklet_schedule(&hp_sdc.task); /* Re-insert the periodic task. */ mod_timer(&hp_sdc.kicker, jiffies + HZ); @@ -801,12 +748,12 @@ void hp_sdc_kicker (unsigned long data) #if defined(__hppa__) -static const struct parisc_device_id hp_sdc_tbl[] = { +static struct parisc_device_id hp_sdc_tbl[] = { { - .hw_type = HPHW_FIO, + .hw_type = HPHW_FIO, .hversion_rev = HVERSION_REV_ANY_ID, .hversion = HVERSION_ANY_ID, - .sversion = 0x73, + .sversion = 0x73, }, { 0, } }; @@ -825,15 +772,16 @@ static struct parisc_driver hp_sdc_driver = { static int __init hp_sdc_init(void) { + int i; char *errstr; hp_sdc_transaction t_sync; uint8_t ts_sync[6]; struct semaphore s_sync; - rwlock_init(&hp_sdc.lock); - rwlock_init(&hp_sdc.ibf_lock); - rwlock_init(&hp_sdc.rtq_lock); - rwlock_init(&hp_sdc.hook_lock); + rwlock_init(&hp_sdc.lock); + rwlock_init(&hp_sdc.ibf_lock); + rwlock_init(&hp_sdc.rtq_lock); + rwlock_init(&hp_sdc.hook_lock); hp_sdc.timer = NULL; hp_sdc.hil = NULL; @@ -848,8 +796,7 @@ static int __init hp_sdc_init(void) hp_sdc.r7[3] = 0xff; hp_sdc.ibf = 1; - memset(&hp_sdc.tq, 0, sizeof(hp_sdc.tq)); - + for (i = 0; i < HP_SDC_QUEUE_LEN; i++) hp_sdc.tq[i] = NULL; hp_sdc.wcurr = -1; hp_sdc.rcurr = -1; hp_sdc.rqty = 0; @@ -857,32 +804,27 @@ static int __init hp_sdc_init(void) hp_sdc.dev_err = -ENODEV; errstr = "IO not found for"; - if (!hp_sdc.base_io) - goto err0; + if (!hp_sdc.base_io) goto err0; errstr = "IRQ not found for"; - if (!hp_sdc.irq) - goto err0; + if (!hp_sdc.irq) goto err0; hp_sdc.dev_err = -EBUSY; #if defined(__hppa__) errstr = "IO not available for"; - if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) - goto err0; -#endif + if (request_region(hp_sdc.data_io, 2, hp_sdc_driver.name)) goto err0; +#endif errstr = "IRQ not available for"; - if (request_irq(hp_sdc.irq, &hp_sdc_isr, IRQF_SHARED|IRQF_SAMPLE_RANDOM, - "HP SDC", &hp_sdc)) - goto err1; + if(request_irq(hp_sdc.irq, &hp_sdc_isr, 0, "HP SDC", + (void *) hp_sdc.base_io)) goto err1; errstr = "NMI not available for"; - if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, IRQF_SHARED, - "HP SDC NMI", &hp_sdc)) - goto err2; + if (request_irq(hp_sdc.nmi, &hp_sdc_nmisr, 0, "HP SDC NMI", + (void *) hp_sdc.base_io)) goto err2; - printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", + printk(KERN_INFO PREFIX "HP SDC at 0x%p, IRQ %d (NMI IRQ %d)\n", (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); hp_sdc_status_in8(); @@ -912,14 +854,13 @@ static int __init hp_sdc_init(void) hp_sdc.dev_err = 0; return 0; err2: - free_irq(hp_sdc.irq, &hp_sdc); + free_irq(hp_sdc.irq, NULL); err1: release_region(hp_sdc.data_io, 2); err0: - printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", + printk(KERN_WARNING PREFIX ": %s SDC IO=0x%p IRQ=0x%x NMI=0x%x\n", errstr, (void *)hp_sdc.base_io, hp_sdc.irq, hp_sdc.nmi); hp_sdc.dev = NULL; - return hp_sdc.dev_err; } @@ -927,10 +868,8 @@ static int __init hp_sdc_init(void) static int __init hp_sdc_init_hppa(struct parisc_device *d) { - if (!d) - return 1; - if (hp_sdc.dev != NULL) - return 1; /* We only expect one SDC */ + if (!d) return 1; + if (hp_sdc.dev != NULL) return 1; /* We only expect one SDC */ hp_sdc.dev = d; hp_sdc.irq = d->irq; @@ -959,16 +898,18 @@ static void hp_sdc_exit(void) /* Wait until we know this has been processed by the i8042 */ hp_sdc_spin_ibf(); - free_irq(hp_sdc.nmi, &hp_sdc); - free_irq(hp_sdc.irq, &hp_sdc); + free_irq(hp_sdc.nmi, NULL); + free_irq(hp_sdc.irq, NULL); write_unlock_irq(&hp_sdc.lock); del_timer(&hp_sdc.kicker); tasklet_kill(&hp_sdc.task); +/* release_region(hp_sdc.data_io, 2); */ + #if defined(__hppa__) - if (unregister_parisc_driver(&hp_sdc_driver)) + if (unregister_parisc_driver(&hp_sdc_driver)) printk(KERN_WARNING PREFIX "Error unregistering HP SDC"); #endif } @@ -982,7 +923,7 @@ static int __init hp_sdc_register(void) mm_segment_t fs; unsigned char i; #endif - + hp_sdc.dev = NULL; hp_sdc.dev_err = 0; #if defined(__hppa__) @@ -1019,8 +960,8 @@ static int __init hp_sdc_register(void) tq_init.seq = tq_init_seq; tq_init.act.semaphore = &tq_init_sem; - tq_init_seq[0] = - HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; + tq_init_seq[0] = + HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; tq_init_seq[1] = HP_SDC_CMD_READ_KCC; tq_init_seq[2] = 1; tq_init_seq[3] = 0; @@ -1038,13 +979,13 @@ static int __init hp_sdc_register(void) } hp_sdc.r11 = tq_init_seq[4]; if (hp_sdc.r11 & HP_SDC_CFG_NEW) { - const char *str; + char *str; printk(KERN_INFO PREFIX "New style SDC\n"); tq_init_seq[1] = HP_SDC_CMD_READ_XTD; tq_init.actidx = 0; tq_init.idx = 1; down(&tq_init_sem); - hp_sdc_enqueue_transaction(&tq_init); + hp_sdc_enqueue_transaction(&tq_init); down(&tq_init_sem); up(&tq_init_sem); if ((tq_init_seq[0] & HP_SDC_ACT_DEAD) == HP_SDC_ACT_DEAD) { @@ -1054,13 +995,15 @@ static int __init hp_sdc_register(void) hp_sdc.r7e = tq_init_seq[4]; HP_SDC_XTD_REV_STRINGS(hp_sdc.r7e & HP_SDC_XTD_REV, str) printk(KERN_INFO PREFIX "Revision: %s\n", str); - if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) + if (hp_sdc.r7e & HP_SDC_XTD_BEEPER) { printk(KERN_INFO PREFIX "TI SN76494 beeper present\n"); - if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) + } + if (hp_sdc.r7e & HP_SDC_XTD_BBRTC) { printk(KERN_INFO PREFIX "OKI MSM-58321 BBRTC present\n"); + } printk(KERN_INFO PREFIX "Spunking the self test register to force PUP " "on next firmware reset.\n"); - tq_init_seq[0] = HP_SDC_ACT_PRECMD | + tq_init_seq[0] = HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; tq_init_seq[1] = HP_SDC_CMD_SET_STR; tq_init_seq[2] = 1; @@ -1069,12 +1012,14 @@ static int __init hp_sdc_register(void) tq_init.idx = 1; tq_init.endidx = 4; down(&tq_init_sem); - hp_sdc_enqueue_transaction(&tq_init); + hp_sdc_enqueue_transaction(&tq_init); down(&tq_init_sem); up(&tq_init_sem); - } else - printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n", + } + else { + printk(KERN_INFO PREFIX "Old style SDC (1820-%s).\n", (hp_sdc.r11 & HP_SDC_CFG_REV) ? "3300" : "2564/3087"); + } return 0; } @@ -1082,13 +1027,13 @@ static int __init hp_sdc_register(void) module_init(hp_sdc_register); module_exit(hp_sdc_exit); -/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) +/* Timing notes: These measurements taken on my 64MHz 7100-LC (715/64) * cycles cycles-adj time * between two consecutive mfctl(16)'s: 4 n/a 63ns * hp_sdc_spin_ibf when idle: 119 115 1.7us * gsc_writeb status register: 83 79 1.2us * IBF to clear after sending SET_IM: 6204 6006 93us - * IBF to clear after sending LOAD_RT: 4467 4352 68us + * IBF to clear after sending LOAD_RT: 4467 4352 68us * IBF to clear after sending two LOAD_RTs: 18974 18859 295us * READ_T1, read status/data, IRQ, call handler: 35564 n/a 556us * cmd to ~IBF READ_T1 2nd time right after: 5158403 n/a 81ms diff --git a/trunk/drivers/input/serio/hp_sdc_mlc.c b/trunk/drivers/input/serio/hp_sdc_mlc.c index c45ea74d53e4..aa4a8a4ccfdb 100644 --- a/trunk/drivers/input/serio/hp_sdc_mlc.c +++ b/trunk/drivers/input/serio/hp_sdc_mlc.c @@ -58,13 +58,12 @@ struct hp_sdc_mlc_priv_s { } hp_sdc_mlc_priv; /************************* Interrupt context ******************************/ -static void hp_sdc_mlc_isr (int irq, void *dev_id, - uint8_t status, uint8_t data) -{ - int idx; +static void hp_sdc_mlc_isr (int irq, void *dev_id, + uint8_t status, uint8_t data) { + int idx; hil_mlc *mlc = &hp_sdc_mlc; - write_lock(&mlc->lock); + write_lock(&(mlc->lock)); if (mlc->icount < 0) { printk(KERN_WARNING PREFIX "HIL Overflow!\n"); up(&mlc->isem); @@ -74,232 +73,239 @@ static void hp_sdc_mlc_isr (int irq, void *dev_id, if ((status & HP_SDC_STATUS_IRQMASK) == HP_SDC_STATUS_HILDATA) { mlc->ipacket[idx] |= data | HIL_ERR_INT; mlc->icount--; - if (hp_sdc_mlc_priv.got5x || !idx) - goto check; - if ((mlc->ipacket[idx - 1] & HIL_PKT_ADDR_MASK) != + if (hp_sdc_mlc_priv.got5x) goto check; + if (!idx) goto check; + if ((mlc->ipacket[idx-1] & HIL_PKT_ADDR_MASK) != (mlc->ipacket[idx] & HIL_PKT_ADDR_MASK)) { mlc->ipacket[idx] &= ~HIL_PKT_ADDR_MASK; - mlc->ipacket[idx] |= (mlc->ipacket[idx - 1] - & HIL_PKT_ADDR_MASK); + mlc->ipacket[idx] |= (mlc->ipacket[idx-1] + & HIL_PKT_ADDR_MASK); } goto check; } /* We know status is 5X */ - if (data & HP_SDC_HIL_ISERR) - goto err; - mlc->ipacket[idx] = + if (data & HP_SDC_HIL_ISERR) goto err; + mlc->ipacket[idx] = (data & HP_SDC_HIL_R1MASK) << HIL_PKT_ADDR_SHIFT; hp_sdc_mlc_priv.got5x = 1; goto out; check: hp_sdc_mlc_priv.got5x = 0; - if (mlc->imatch == 0) - goto done; - if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) - && (mlc->ipacket[idx] == (mlc->imatch | idx))) - goto done; - if (mlc->ipacket[idx] == mlc->imatch) - goto done; + if (mlc->imatch == 0) goto done; + if ((mlc->imatch == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) + && (mlc->ipacket[idx] == (mlc->imatch | idx))) goto done; + if (mlc->ipacket[idx] == mlc->imatch) goto done; goto out; - err: + err: printk(KERN_DEBUG PREFIX "err code %x\n", data); - switch (data) { case HP_SDC_HIL_RC_DONE: printk(KERN_WARNING PREFIX "Bastard SDC reconfigured loop!\n"); break; - case HP_SDC_HIL_ERR: - mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR | - HIL_ERR_FERR | HIL_ERR_FOF; + mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_PERR | + HIL_ERR_FERR | HIL_ERR_FOF; break; - case HP_SDC_HIL_TO: mlc->ipacket[idx] |= HIL_ERR_INT | HIL_ERR_LERR; break; - case HP_SDC_HIL_RC: printk(KERN_WARNING PREFIX "Bastard SDC decided to reconfigure loop!\n"); break; - default: printk(KERN_WARNING PREFIX "Unkown HIL Error status (%x)!\n", data); break; } - /* No more data will be coming due to an error. */ done: tasklet_schedule(mlc->tasklet); - up(&mlc->isem); + up(&(mlc->isem)); out: - write_unlock(&mlc->lock); + write_unlock(&(mlc->lock)); } /******************** Tasklet or userspace context functions ****************/ -static int hp_sdc_mlc_in(hil_mlc *mlc, suseconds_t timeout) -{ +static int hp_sdc_mlc_in (hil_mlc *mlc, suseconds_t timeout) { + unsigned long flags; struct hp_sdc_mlc_priv_s *priv; int rc = 2; priv = mlc->priv; + write_lock_irqsave(&(mlc->lock), flags); + /* Try to down the semaphore */ - if (down_trylock(&mlc->isem)) { + if (down_trylock(&(mlc->isem))) { struct timeval tv; if (priv->emtestmode) { - mlc->ipacket[0] = - HIL_ERR_INT | (mlc->opacket & - (HIL_PKT_CMD | - HIL_PKT_ADDR_MASK | + mlc->ipacket[0] = + HIL_ERR_INT | (mlc->opacket & + (HIL_PKT_CMD | + HIL_PKT_ADDR_MASK | HIL_PKT_DATA_MASK)); mlc->icount = 14; /* printk(KERN_DEBUG PREFIX ">[%x]\n", mlc->ipacket[0]); */ goto wasup; } do_gettimeofday(&tv); - tv.tv_usec += USEC_PER_SEC * (tv.tv_sec - mlc->instart.tv_sec); + tv.tv_usec += 1000000 * (tv.tv_sec - mlc->instart.tv_sec); if (tv.tv_usec - mlc->instart.tv_usec > mlc->intimeout) { - /* printk("!%i %i", - tv.tv_usec - mlc->instart.tv_usec, - mlc->intimeout); - */ + /* printk("!%i %i", + tv.tv_usec - mlc->instart.tv_usec, + mlc->intimeout); + */ rc = 1; - up(&mlc->isem); + up(&(mlc->isem)); } goto done; } wasup: - up(&mlc->isem); + up(&(mlc->isem)); rc = 0; + goto done; done: + write_unlock_irqrestore(&(mlc->lock), flags); return rc; } -static int hp_sdc_mlc_cts(hil_mlc *mlc) -{ +static int hp_sdc_mlc_cts (hil_mlc *mlc) { struct hp_sdc_mlc_priv_s *priv; + unsigned long flags; - priv = mlc->priv; - - /* Try to down the semaphores -- they should be up. */ - BUG_ON(down_trylock(&mlc->isem)); - BUG_ON(down_trylock(&mlc->osem)); + priv = mlc->priv; - up(&mlc->isem); - up(&mlc->osem); + write_lock_irqsave(&(mlc->lock), flags); - if (down_trylock(&mlc->csem)) { - if (priv->trans.act.semaphore != &mlc->csem) - goto poll; - else - goto busy; + /* Try to down the semaphores -- they should be up. */ + if (down_trylock(&(mlc->isem))) { + BUG(); + goto busy; + } + if (down_trylock(&(mlc->osem))) { + BUG(); + up(&(mlc->isem)); + goto busy; } + up(&(mlc->isem)); + up(&(mlc->osem)); - if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) - goto done; + if (down_trylock(&(mlc->csem))) { + if (priv->trans.act.semaphore != &(mlc->csem)) goto poll; + goto busy; + } + if (!(priv->tseq[4] & HP_SDC_USE_LOOP)) goto done; poll: - priv->trans.act.semaphore = &mlc->csem; + priv->trans.act.semaphore = &(mlc->csem); priv->trans.actidx = 0; priv->trans.idx = 1; priv->trans.endidx = 5; - priv->tseq[0] = + priv->tseq[0] = HP_SDC_ACT_POSTCMD | HP_SDC_ACT_DATAIN | HP_SDC_ACT_SEMAPHORE; priv->tseq[1] = HP_SDC_CMD_READ_USE; priv->tseq[2] = 1; priv->tseq[3] = 0; priv->tseq[4] = 0; - __hp_sdc_enqueue_transaction(&priv->trans); + hp_sdc_enqueue_transaction(&(priv->trans)); busy: + write_unlock_irqrestore(&(mlc->lock), flags); return 1; done: - priv->trans.act.semaphore = &mlc->osem; - up(&mlc->csem); + priv->trans.act.semaphore = &(mlc->osem); + up(&(mlc->csem)); + write_unlock_irqrestore(&(mlc->lock), flags); return 0; } -static void hp_sdc_mlc_out(hil_mlc *mlc) -{ +static void hp_sdc_mlc_out (hil_mlc *mlc) { struct hp_sdc_mlc_priv_s *priv; + unsigned long flags; priv = mlc->priv; + write_lock_irqsave(&(mlc->lock), flags); + /* Try to down the semaphore -- it should be up. */ - BUG_ON(down_trylock(&mlc->osem)); + if (down_trylock(&(mlc->osem))) { + BUG(); + goto done; + } - if (mlc->opacket & HIL_DO_ALTER_CTRL) - goto do_control; + if (mlc->opacket & HIL_DO_ALTER_CTRL) goto do_control; do_data: if (priv->emtestmode) { - up(&mlc->osem); - return; + up(&(mlc->osem)); + goto done; } /* Shouldn't be sending commands when loop may be busy */ - BUG_ON(down_trylock(&mlc->csem)); - up(&mlc->csem); + if (down_trylock(&(mlc->csem))) { + BUG(); + goto done; + } + up(&(mlc->csem)); priv->trans.actidx = 0; priv->trans.idx = 1; - priv->trans.act.semaphore = &mlc->osem; + priv->trans.act.semaphore = &(mlc->osem); priv->trans.endidx = 6; - priv->tseq[0] = + priv->tseq[0] = HP_SDC_ACT_DATAREG | HP_SDC_ACT_POSTCMD | HP_SDC_ACT_SEMAPHORE; priv->tseq[1] = 0x7; - priv->tseq[2] = - (mlc->opacket & + priv->tseq[2] = + (mlc->opacket & (HIL_PKT_ADDR_MASK | HIL_PKT_CMD)) >> HIL_PKT_ADDR_SHIFT; - priv->tseq[3] = - (mlc->opacket & HIL_PKT_DATA_MASK) + priv->tseq[3] = + (mlc->opacket & HIL_PKT_DATA_MASK) >> HIL_PKT_DATA_SHIFT; priv->tseq[4] = 0; /* No timeout */ - if (priv->tseq[3] == HIL_CMD_DHR) - priv->tseq[4] = 1; + if (priv->tseq[3] == HIL_CMD_DHR) priv->tseq[4] = 1; priv->tseq[5] = HP_SDC_CMD_DO_HIL; goto enqueue; do_control: priv->emtestmode = mlc->opacket & HIL_CTRL_TEST; - + /* we cannot emulate this, it should not be used. */ BUG_ON((mlc->opacket & (HIL_CTRL_APE | HIL_CTRL_IPF)) == HIL_CTRL_APE); - - if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) - goto control_only; - - /* Should not send command/data after engaging APE */ - BUG_ON(mlc->opacket & HIL_CTRL_APE); - - /* Disengaging APE this way would not be valid either since + + if ((mlc->opacket & HIL_CTRL_ONLY) == HIL_CTRL_ONLY) goto control_only; + if (mlc->opacket & HIL_CTRL_APE) { + BUG(); /* Should not send command/data after engaging APE */ + goto done; + } + /* Disengaging APE this way would not be valid either since * the loop must be allowed to idle. * - * So, it works out that we really never actually send control - * and data when using SDC, we just send the data. + * So, it works out that we really never actually send control + * and data when using SDC, we just send the data. */ goto do_data; control_only: priv->trans.actidx = 0; priv->trans.idx = 1; - priv->trans.act.semaphore = &mlc->osem; + priv->trans.act.semaphore = &(mlc->osem); priv->trans.endidx = 4; - priv->tseq[0] = + priv->tseq[0] = HP_SDC_ACT_PRECMD | HP_SDC_ACT_DATAOUT | HP_SDC_ACT_SEMAPHORE; priv->tseq[1] = HP_SDC_CMD_SET_LPC; priv->tseq[2] = 1; - /* priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; */ + // priv->tseq[3] = (mlc->ddc + 1) | HP_SDC_LPS_ACSUCC; priv->tseq[3] = 0; if (mlc->opacket & HIL_CTRL_APE) { priv->tseq[3] |= HP_SDC_LPC_APE_IPF; - down_trylock(&mlc->csem); - } + down_trylock(&(mlc->csem)); + } enqueue: - hp_sdc_enqueue_transaction(&priv->trans); + hp_sdc_enqueue_transaction(&(priv->trans)); + done: + write_unlock_irqrestore(&(mlc->lock), flags); } static int __init hp_sdc_mlc_init(void) @@ -310,18 +316,18 @@ static int __init hp_sdc_mlc_init(void) hp_sdc_mlc_priv.emtestmode = 0; hp_sdc_mlc_priv.trans.seq = hp_sdc_mlc_priv.tseq; - hp_sdc_mlc_priv.trans.act.semaphore = &mlc->osem; + hp_sdc_mlc_priv.trans.act.semaphore = &(mlc->osem); hp_sdc_mlc_priv.got5x = 0; - mlc->cts = &hp_sdc_mlc_cts; - mlc->in = &hp_sdc_mlc_in; - mlc->out = &hp_sdc_mlc_out; - mlc->priv = &hp_sdc_mlc_priv; + mlc->cts = &hp_sdc_mlc_cts; + mlc->in = &hp_sdc_mlc_in; + mlc->out = &hp_sdc_mlc_out; if (hil_mlc_register(mlc)) { printk(KERN_WARNING PREFIX "Failed to register MLC structure with hil_mlc\n"); goto err0; } + mlc->priv = &hp_sdc_mlc_priv; if (hp_sdc_request_hil_irq(&hp_sdc_mlc_isr)) { printk(KERN_WARNING PREFIX "Request for raw HIL ISR hook denied\n"); @@ -329,9 +335,10 @@ static int __init hp_sdc_mlc_init(void) } return 0; err1: - if (hil_mlc_unregister(mlc)) + if (hil_mlc_unregister(mlc)) { printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" "This is bad. Could cause an oops.\n"); + } err0: return -EBUSY; } @@ -339,14 +346,14 @@ static int __init hp_sdc_mlc_init(void) static void __exit hp_sdc_mlc_exit(void) { hil_mlc *mlc = &hp_sdc_mlc; - - if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) + if (hp_sdc_release_hil_irq(&hp_sdc_mlc_isr)) { printk(KERN_ERR PREFIX "Failed to release the raw HIL ISR hook.\n" "This is bad. Could cause an oops.\n"); - - if (hil_mlc_unregister(mlc)) + } + if (hil_mlc_unregister(mlc)) { printk(KERN_ERR PREFIX "Failed to unregister MLC structure with hil_mlc.\n" "This is bad. Could cause an oops.\n"); + } } module_init(hp_sdc_mlc_init); diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index 6858bc58f0fd..d36bd5475b6d 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -159,28 +159,6 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), }, }, - { - /* - * No data is coming from the touchscreen unless KBC - * is in legacy mode. - */ - .ident = "Panasonic CF-29", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), - DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), - }, - }, - { - /* - * Errors on MUX ports are reported without raising AUXDATA - * causing "spurious NAK" messages. - */ - .ident = "HP Pavilion DV4017EA", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), - }, - }, { .ident = "Toshiba P10", .matches = { @@ -302,8 +280,6 @@ static struct pnp_driver i8042_pnp_kbd_driver = { }; static struct pnp_device_id pnp_aux_devids[] = { - { .id = "FJC6000", .driver_data = 0 }, - { .id = "FJC6001", .driver_data = 0 }, { .id = "PNP0f03", .driver_data = 0 }, { .id = "PNP0f0b", .driver_data = 0 }, { .id = "PNP0f0e", .driver_data = 0 }, diff --git a/trunk/drivers/input/serio/i8042.c b/trunk/drivers/input/serio/i8042.c index 3888dc307e0c..db9cca3b65e0 100644 --- a/trunk/drivers/input/serio/i8042.c +++ b/trunk/drivers/input/serio/i8042.c @@ -526,33 +526,6 @@ static irqreturn_t __devinit i8042_aux_test_irq(int irq, void *dev_id) return IRQ_HANDLED; } -/* - * i8042_toggle_aux - enables or disables AUX port on i8042 via command and - * verifies success by readinng CTR. Used when testing for presence of AUX - * port. - */ -static int __devinit i8042_toggle_aux(int on) -{ - unsigned char param; - int i; - - if (i8042_command(¶m, - on ? I8042_CMD_AUX_ENABLE : I8042_CMD_AUX_DISABLE)) - return -1; - - /* some chips need some time to set the I8042_CTR_AUXDIS bit */ - for (i = 0; i < 100; i++) { - udelay(50); - - if (i8042_command(¶m, I8042_CMD_CTL_RCTR)) - return -1; - - if (!(param & I8042_CTR_AUXDIS) == on) - return 0; - } - - return -1; -} /* * i8042_check_aux() applies as much paranoia as it can at detecting @@ -607,12 +580,16 @@ static int __devinit i8042_check_aux(void) * Bit assignment test - filters out PS/2 i8042's in AT mode */ - if (i8042_toggle_aux(0)) { + if (i8042_command(¶m, I8042_CMD_AUX_DISABLE)) + return -1; + if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (~param & I8042_CTR_AUXDIS)) { printk(KERN_WARNING "Failed to disable AUX port, but continuing anyway... Is this a SiS?\n"); printk(KERN_WARNING "If AUX port is really absent please use the 'i8042.noaux' option.\n"); } - if (i8042_toggle_aux(1)) + if (i8042_command(¶m, I8042_CMD_AUX_ENABLE)) + return -1; + if (i8042_command(¶m, I8042_CMD_CTL_RCTR) || (param & I8042_CTR_AUXDIS)) return -1; /* @@ -790,13 +767,6 @@ static void i8042_controller_reset(void) { i8042_flush(); -/* - * Disable both KBD and AUX interfaces so they don't get in the way - */ - - i8042_ctr |= I8042_CTR_KBDDIS | I8042_CTR_AUXDIS; - i8042_ctr &= ~(I8042_CTR_KBDINT | I8042_CTR_AUXINT); - /* * Disable MUX mode if present. */ diff --git a/trunk/drivers/input/tablet/Kconfig b/trunk/drivers/input/tablet/Kconfig deleted file mode 100644 index 12dfb0eb3262..000000000000 --- a/trunk/drivers/input/tablet/Kconfig +++ /dev/null @@ -1,74 +0,0 @@ -# -# Tablet driver configuration -# -menuconfig INPUT_TABLET - bool "Tablets" - help - Say Y here, and a list of supported tablets will be displayed. - This option doesn't affect the kernel. - - If unsure, say Y. - -if INPUT_TABLET - -config TABLET_USB_ACECAD - tristate "Acecad Flair tablet support (USB)" - select USB - help - Say Y here if you want to use the USB version of the Acecad Flair - tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. - - To compile this driver as a module, choose M here: the - module will be called acecad. - -config TABLET_USB_AIPTEK - tristate "Aiptek 6000U/8000U tablet support (USB)" - select USB - help - Say Y here if you want to use the USB version of the Aiptek 6000U - or Aiptek 8000U tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. - - To compile this driver as a module, choose M here: the - module will be called aiptek. - -config TABLET_USB_GTCO - tristate "GTCO CalComp/InterWrite USB Support" - depends on USB && INPUT - help - Say Y here if you want to use the USB version of the GTCO - CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. - - To compile this driver as a module, choose M here: the - module will be called gtco. - -config TABLET_USB_KBTAB - tristate "KB Gear JamStudio tablet support (USB)" - select USB - help - Say Y here if you want to use the USB version of the KB Gear - JamStudio tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. - - To compile this driver as a module, choose M here: the - module will be called kbtab. - -config TABLET_USB_WACOM - tristate "Wacom Intuos/Graphire tablet support (USB)" - select USB - help - Say Y here if you want to use the USB version of the Wacom Intuos - or Graphire tablet. Make sure to say Y to "Mouse support" - (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" - (CONFIG_INPUT_EVDEV) as well. - - To compile this driver as a module, choose M here: the - module will be called wacom. - -endif diff --git a/trunk/drivers/input/tablet/Makefile b/trunk/drivers/input/tablet/Makefile deleted file mode 100644 index ce8b9a9cfa40..000000000000 --- a/trunk/drivers/input/tablet/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# Makefile for the tablet drivers -# - -# Multipart objects. -wacom-objs := wacom_wac.o wacom_sys.o - -obj-$(CONFIG_TABLET_USB_ACECAD) += acecad.o -obj-$(CONFIG_TABLET_USB_AIPTEK) += aiptek.o -obj-$(CONFIG_TABLET_USB_GTCO) += gtco.o -obj-$(CONFIG_TABLET_USB_KBTAB) += kbtab.o -obj-$(CONFIG_TABLET_USB_WACOM) += wacom.o diff --git a/trunk/drivers/input/touchscreen/Kconfig b/trunk/drivers/input/touchscreen/Kconfig index 5e640aeb03cd..971618059a6f 100644 --- a/trunk/drivers/input/touchscreen/Kconfig +++ b/trunk/drivers/input/touchscreen/Kconfig @@ -1,5 +1,5 @@ # -# Touchscreen driver configuration +# Mouse driver configuration # menuconfig INPUT_TOUCHSCREEN bool "Touchscreens" @@ -44,9 +44,9 @@ config TOUCHSCREEN_BITSY config TOUCHSCREEN_CORGI tristate "SharpSL (Corgi and Spitz series) touchscreen driver" depends on PXA_SHARPSL - default y + default y help - Say Y here to enable the driver for the touchscreen on the + Say Y here to enable the driver for the touchscreen on the Sharp SL-C7xx and SL-Cxx00 series of PDAs. If unsure, say N. @@ -164,58 +164,4 @@ config TOUCHSCREEN_UCB1400 To compile this driver as a module, choose M here: the module will be called ucb1400_ts. -config TOUCHSCREEN_USB_COMPOSITE - tristate "USB Touchscreen Driver" - select USB - help - USB Touchscreen driver for: - - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700) - - PanJit TouchSet USB - - 3M MicroTouch USB (EX II series) - - ITM - - some other eTurboTouch - - Gunze AHL61 - - DMC TSC-10/25 - - Have a look at for - a usage description and the required user-space stuff. - - To compile this driver as a module, choose M here: the - module will be called usbtouchscreen. - -config TOUCHSCREEN_USB_EGALAX - default y - bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED - depends on TOUCHSCREEN_USB_COMPOSITE - -config TOUCHSCREEN_USB_PANJIT - default y - bool "PanJit device support" if EMBEDDED - depends on TOUCHSCREEN_USB_COMPOSITE - -config TOUCHSCREEN_USB_3M - default y - bool "3M/Microtouch EX II series device support" if EMBEDDED - depends on TOUCHSCREEN_USB_COMPOSITE - -config TOUCHSCREEN_USB_ITM - default y - bool "ITM device support" if EMBEDDED - depends on TOUCHSCREEN_USB_COMPOSITE - -config TOUCHSCREEN_USB_ETURBO - default y - bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED - depends on TOUCHSCREEN_USB_COMPOSITE - -config TOUCHSCREEN_USB_GUNZE - default y - bool "Gunze AHL61 device support" if EMBEDDED - depends on TOUCHSCREEN_USB_COMPOSITE - -config TOUCHSCREEN_USB_DMC_TSC10 - default y - bool "DMC TSC-10/25 device support" if EMBEDDED - depends on TOUCHSCREEN_USB_COMPOSITE - endif diff --git a/trunk/drivers/input/touchscreen/Makefile b/trunk/drivers/input/touchscreen/Makefile index 2f86d6ad06d3..30e6e2217a15 100644 --- a/trunk/drivers/input/touchscreen/Makefile +++ b/trunk/drivers/input/touchscreen/Makefile @@ -1,18 +1,17 @@ # -# Makefile for the touchscreen drivers. +# Makefile for the mouse drivers. # # Each configuration option enables a list of files. obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o -obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o -obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o -obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o -obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o -obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o -obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o -obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o -obj-$(CONFIG_TOUCHSCREEN_USB_COMPOSITE) += usbtouchscreen.o +obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o +obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o +obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o +obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o +obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o +obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o +obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o obj-$(CONFIG_TOUCHSCREEN_PENMOUNT) += penmount.o obj-$(CONFIG_TOUCHSCREEN_TOUCHRIGHT) += touchright.o obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index 693e3b2a65a3..0a26e0663542 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -39,8 +39,7 @@ /* * This code has been heavily tested on a Nokia 770, and lightly * tested on other ads7846 devices (OSK/Mistral, Lubbock). - * Support for ads7843 tested on Atmel at91sam926x-EK. - * Support for ads7845 has only been stubbed in. + * Support for ads7843 and ads7845 has only been stubbed in. * * IRQ handling needs a workaround because of a shortcoming in handling * edge triggered IRQs on some platforms like the OMAP1/2. These @@ -247,16 +246,18 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) /* REVISIT: take a few more samples, and compare ... */ - /* converter in low power mode & enable PENIRQ */ - req->ref_off = PWRDOWN; - req->xfer[4].tx_buf = &req->ref_off; - req->xfer[4].len = 1; - spi_message_add_tail(&req->xfer[4], &req->msg); - - req->xfer[5].rx_buf = &req->scratch; - req->xfer[5].len = 2; - CS_CHANGE(req->xfer[5]); - spi_message_add_tail(&req->xfer[5], &req->msg); + /* maybe off internal vREF */ + if (use_internal) { + req->ref_off = REF_OFF; + req->xfer[4].tx_buf = &req->ref_off; + req->xfer[4].len = 1; + spi_message_add_tail(&req->xfer[4], &req->msg); + + req->xfer[5].rx_buf = &req->scratch; + req->xfer[5].len = 2; + CS_CHANGE(req->xfer[5]); + spi_message_add_tail(&req->xfer[5], &req->msg); + } ts->irq_disabled = 1; disable_irq(spi->irq); @@ -535,9 +536,6 @@ static void ads7846_rx(void *ads) } else Rt = 0; - if (ts->model == 7843) - Rt = ts->pressure_max / 2; - /* Sample found inconsistent by debouncing or pressure is beyond * the maximum. Don't report it to user space, repeat at least * once more the measurement @@ -899,7 +897,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) input_dev->name = "ADS784x Touchscreen"; input_dev->phys = ts->phys; - input_dev->dev.parent = &spi->dev; + input_dev->cdev.dev = &spi->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/trunk/drivers/input/touchscreen/corgi_ts.c b/trunk/drivers/input/touchscreen/corgi_ts.c index e6a31d118786..e2945582828e 100644 --- a/trunk/drivers/input/touchscreen/corgi_ts.c +++ b/trunk/drivers/input/touchscreen/corgi_ts.c @@ -300,7 +300,8 @@ static int __init corgits_probe(struct platform_device *pdev) input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0002; input_dev->id.version = 0x0100; - input_dev->dev.parent = &pdev->dev; + input_dev->cdev.dev = &pdev->dev; + input_dev->private = corgi_ts; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/trunk/drivers/input/touchscreen/elo.c b/trunk/drivers/input/touchscreen/elo.c index 557d781719f1..9d61cd133d01 100644 --- a/trunk/drivers/input/touchscreen/elo.c +++ b/trunk/drivers/input/touchscreen/elo.c @@ -312,13 +312,14 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) init_completion(&elo->cmd_done); snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); + input_dev->private = elo; input_dev->name = "Elo Serial TouchScreen"; input_dev->phys = elo->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_ELO; input_dev->id.product = elo->id; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/trunk/drivers/input/touchscreen/gunze.c b/trunk/drivers/input/touchscreen/gunze.c index 39d602600d7c..9157eb148e84 100644 --- a/trunk/drivers/input/touchscreen/gunze.c +++ b/trunk/drivers/input/touchscreen/gunze.c @@ -130,13 +130,13 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) gunze->dev = input_dev; snprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys); + input_dev->private = gunze; input_dev->name = "Gunze AHL-51S TouchScreen"; input_dev->phys = gunze->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_GUNZE; input_dev->id.product = 0x0051; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0); diff --git a/trunk/drivers/input/touchscreen/h3600_ts_input.c b/trunk/drivers/input/touchscreen/h3600_ts_input.c index 09ed7803cb8f..c4116d4f64e7 100644 --- a/trunk/drivers/input/touchscreen/h3600_ts_input.c +++ b/trunk/drivers/input/touchscreen/h3600_ts_input.c @@ -147,7 +147,7 @@ enum flite_pwr { unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) { unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness; - struct h3600_dev *ts = input_get_drvdata(dev); + struct h3600_dev *ts = dev->private; /* Must be in this order */ ts->serio->write(ts->serio, 1); @@ -260,7 +260,7 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { #if 0 - struct h3600_dev *ts = input_get_drvdata(dev); + struct h3600_dev *ts = dev->private; switch (type) { case EV_LED: { @@ -367,9 +367,8 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_H3600; input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; - - input_set_drvdata(input_dev, ts); + input_dev->cdev.dev = &serio->dev; + input_dev->private = ts; input_dev->event = h3600ts_event; diff --git a/trunk/drivers/input/touchscreen/hp680_ts_input.c b/trunk/drivers/input/touchscreen/hp680_ts_input.c index 61c15024c2a0..249087472740 100644 --- a/trunk/drivers/input/touchscreen/hp680_ts_input.c +++ b/trunk/drivers/input/touchscreen/hp680_ts_input.c @@ -21,7 +21,7 @@ static void do_softint(void *data); static struct input_dev *hp680_ts_dev; -static DECLARE_WORK(work, do_softint); +static DECLARE_WORK(work, do_softint, 0); static void do_softint(void *data) { diff --git a/trunk/drivers/input/touchscreen/mtouch.c b/trunk/drivers/input/touchscreen/mtouch.c index 4ec3b1f940c8..c3c2d735d0ec 100644 --- a/trunk/drivers/input/touchscreen/mtouch.c +++ b/trunk/drivers/input/touchscreen/mtouch.c @@ -144,13 +144,13 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) mtouch->dev = input_dev; snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys); + input_dev->private = mtouch; input_dev->name = "MicroTouch Serial TouchScreen"; input_dev->phys = mtouch->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_MICROTOUCH; input_dev->id.product = 0; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); diff --git a/trunk/drivers/input/touchscreen/penmount.c b/trunk/drivers/input/touchscreen/penmount.c index f2c0d3c7149c..bd2767991ae9 100644 --- a/trunk/drivers/input/touchscreen/penmount.c +++ b/trunk/drivers/input/touchscreen/penmount.c @@ -105,13 +105,14 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) pm->dev = input_dev; snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys); + input_dev->private = pm; input_dev->name = "Penmount Serial TouchScreen"; input_dev->phys = pm->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_PENMOUNT; input_dev->id.product = 0; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; + input_dev->cdev.dev = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); diff --git a/trunk/drivers/input/touchscreen/touchright.c b/trunk/drivers/input/touchscreen/touchright.c index 3def7bb1df44..35ba46c6ad2d 100644 --- a/trunk/drivers/input/touchscreen/touchright.c +++ b/trunk/drivers/input/touchscreen/touchright.c @@ -118,13 +118,13 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv) tr->dev = input_dev; snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys); + input_dev->private = tr; input_dev->name = "Touchright Serial TouchScreen"; input_dev->phys = tr->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_TOUCHRIGHT; input_dev->id.product = 0; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0); diff --git a/trunk/drivers/input/touchscreen/touchwin.c b/trunk/drivers/input/touchscreen/touchwin.c index ac4bdcf18666..4dc073dacabb 100644 --- a/trunk/drivers/input/touchscreen/touchwin.c +++ b/trunk/drivers/input/touchscreen/touchwin.c @@ -125,13 +125,13 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv) tw->dev = input_dev; snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys); + input_dev->private = tw; input_dev->name = "Touchwindow Serial TouchScreen"; input_dev->phys = tw->phys; input_dev->id.bustype = BUS_RS232; input_dev->id.vendor = SERIO_TOUCHWIN; input_dev->id.product = 0; input_dev->id.version = 0x0100; - input_dev->dev.parent = &serio->dev; input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0); diff --git a/trunk/drivers/input/touchscreen/ucb1400_ts.c b/trunk/drivers/input/touchscreen/ucb1400_ts.c index 6582816a0477..e8606c48c9c3 100644 --- a/trunk/drivers/input/touchscreen/ucb1400_ts.c +++ b/trunk/drivers/input/touchscreen/ucb1400_ts.c @@ -97,8 +97,6 @@ struct ucb1400 { }; static int adcsync; -static int ts_delay = 55; /* us */ -static int ts_delay_pressure; /* us */ static inline u16 ucb1400_reg_read(struct ucb1400 *ucb, u16 reg) { @@ -161,7 +159,6 @@ static inline unsigned int ucb1400_ts_read_pressure(struct ucb1400 *ucb) UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND | UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA); - udelay(ts_delay_pressure); return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); } @@ -183,7 +180,7 @@ static inline unsigned int ucb1400_ts_read_xpos(struct ucb1400 *ucb) UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - udelay(ts_delay); + udelay(55); return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPY); } @@ -206,7 +203,7 @@ static inline unsigned int ucb1400_ts_read_ypos(struct ucb1400 *ucb) UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW | UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA); - udelay(ts_delay); + udelay(55); return ucb1400_adc_read(ucb, UCB_ADC_INP_TSPX); } @@ -372,7 +369,7 @@ static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid) static int ucb1400_ts_open(struct input_dev *idev) { - struct ucb1400 *ucb = input_get_drvdata(idev); + struct ucb1400 *ucb = idev->private; int ret = 0; BUG_ON(ucb->ts_task); @@ -388,7 +385,7 @@ static int ucb1400_ts_open(struct input_dev *idev) static void ucb1400_ts_close(struct input_dev *idev) { - struct ucb1400 *ucb = input_get_drvdata(idev); + struct ucb1400 *ucb = idev->private; if (ucb->ts_task) kthread_stop(ucb->ts_task); @@ -510,9 +507,8 @@ static int ucb1400_ts_probe(struct device *dev) } printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq); - input_set_drvdata(idev, ucb); - - idev->dev.parent = dev; + idev->private = ucb; + idev->cdev.dev = dev; idev->name = "UCB1400 touchscreen interface"; idev->id.vendor = ucb1400_reg_read(ucb, AC97_VENDOR_ID1); idev->id.product = id; @@ -575,15 +571,7 @@ static void __exit ucb1400_ts_exit(void) driver_unregister(&ucb1400_ts_driver); } -module_param(adcsync, bool, 0444); -MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin."); - -module_param(ts_delay, int, 0444); -MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us."); - -module_param(ts_delay_pressure, int, 0444); -MODULE_PARM_DESC(ts_delay_pressure, - "delay between panel setup and pressure read. Default = 0us."); +module_param(adcsync, int, 0444); module_init(ucb1400_ts_init); module_exit(ucb1400_ts_exit); diff --git a/trunk/drivers/input/tsdev.c b/trunk/drivers/input/tsdev.c index 8238b13874c2..0300dca8591d 100644 --- a/trunk/drivers/input/tsdev.c +++ b/trunk/drivers/input/tsdev.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -110,13 +111,13 @@ struct tsdev { int minor; char name[8]; wait_queue_head_t wait; - struct list_head client_list; + struct list_head list; struct input_handle handle; int x, y, pressure; struct ts_calibration cal; }; -struct tsdev_client { +struct tsdev_list { struct fasync_struct *fasync; struct list_head node; struct tsdev *tsdev; @@ -138,49 +139,38 @@ static struct tsdev *tsdev_table[TSDEV_MINORS/2]; static int tsdev_fasync(int fd, struct file *file, int on) { - struct tsdev_client *client = file->private_data; + struct tsdev_list *list = file->private_data; int retval; - retval = fasync_helper(fd, file, on, &client->fasync); + retval = fasync_helper(fd, file, on, &list->fasync); return retval < 0 ? retval : 0; } static int tsdev_open(struct inode *inode, struct file *file) { int i = iminor(inode) - TSDEV_MINOR_BASE; - struct tsdev_client *client; - struct tsdev *tsdev; - int error; + struct tsdev_list *list; printk(KERN_WARNING "tsdev (compaq touchscreen emulation) is scheduled " "for removal.\nSee Documentation/feature-removal-schedule.txt " "for details.\n"); - if (i >= TSDEV_MINORS) - return -ENODEV; - - tsdev = tsdev_table[i & TSDEV_MINOR_MASK]; - if (!tsdev || !tsdev->exist) + if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) return -ENODEV; - client = kzalloc(sizeof(struct tsdev_client), GFP_KERNEL); - if (!client) + if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL))) return -ENOMEM; - client->tsdev = tsdev; - client->raw = (i >= TSDEV_MINORS / 2) ? 1 : 0; - list_add_tail(&client->node, &tsdev->client_list); + list->raw = (i >= TSDEV_MINORS/2) ? 1 : 0; - if (!tsdev->open++ && tsdev->exist) { - error = input_open_device(&tsdev->handle); - if (error) { - list_del(&client->node); - kfree(client); - return error; - } - } + i &= TSDEV_MINOR_MASK; + list->tsdev = tsdev_table[i]; + list_add_tail(&list->node, &tsdev_table[i]->list); + file->private_data = list; - file->private_data = client; + if (!list->tsdev->open++) + if (list->tsdev->exist) + input_open_device(&list->tsdev->handle); return 0; } @@ -192,48 +182,45 @@ static void tsdev_free(struct tsdev *tsdev) static int tsdev_release(struct inode *inode, struct file *file) { - struct tsdev_client *client = file->private_data; - struct tsdev *tsdev = client->tsdev; + struct tsdev_list *list = file->private_data; tsdev_fasync(-1, file, 0); + list_del(&list->node); - list_del(&client->node); - kfree(client); - - if (!--tsdev->open) { - if (tsdev->exist) - input_close_device(&tsdev->handle); + if (!--list->tsdev->open) { + if (list->tsdev->exist) + input_close_device(&list->tsdev->handle); else - tsdev_free(tsdev); + tsdev_free(list->tsdev); } - + kfree(list); return 0; } static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, - loff_t *ppos) + loff_t * ppos) { - struct tsdev_client *client = file->private_data; - struct tsdev *tsdev = client->tsdev; + struct tsdev_list *list = file->private_data; int retval = 0; - if (client->head == client->tail && tsdev->exist && (file->f_flags & O_NONBLOCK)) + if (list->head == list->tail && list->tsdev->exist && (file->f_flags & O_NONBLOCK)) return -EAGAIN; - retval = wait_event_interruptible(tsdev->wait, - client->head != client->tail || !tsdev->exist); + retval = wait_event_interruptible(list->tsdev->wait, + list->head != list->tail || !list->tsdev->exist); + if (retval) return retval; - if (!tsdev->exist) + if (!list->tsdev->exist) return -ENODEV; - while (client->head != client->tail && + while (list->head != list->tail && retval + sizeof (struct ts_event) <= count) { - if (copy_to_user (buffer + retval, client->event + client->tail, + if (copy_to_user (buffer + retval, list->event + list->tail, sizeof (struct ts_event))) return -EFAULT; - client->tail = (client->tail + 1) & (TSDEV_BUFFER_SIZE - 1); + list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1); retval += sizeof (struct ts_event); } @@ -241,33 +228,32 @@ static ssize_t tsdev_read(struct file *file, char __user *buffer, size_t count, } /* No kernel lock - fine */ -static unsigned int tsdev_poll(struct file *file, poll_table *wait) +static unsigned int tsdev_poll(struct file *file, poll_table * wait) { - struct tsdev_client *client = file->private_data; - struct tsdev *tsdev = client->tsdev; + struct tsdev_list *list = file->private_data; - poll_wait(file, &tsdev->wait, wait); - return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) | - (tsdev->exist ? 0 : (POLLHUP | POLLERR)); + poll_wait(file, &list->tsdev->wait, wait); + return ((list->head == list->tail) ? 0 : (POLLIN | POLLRDNORM)) | + (list->tsdev->exist ? 0 : (POLLHUP | POLLERR)); } static int tsdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - struct tsdev_client *client = file->private_data; - struct tsdev *tsdev = client->tsdev; + struct tsdev_list *list = file->private_data; + struct tsdev *tsdev = list->tsdev; int retval = 0; switch (cmd) { case TS_GET_CAL: - if (copy_to_user((void __user *)arg, &tsdev->cal, - sizeof (struct ts_calibration))) + if (copy_to_user ((void __user *)arg, &tsdev->cal, + sizeof (struct ts_calibration))) retval = -EFAULT; break; case TS_SET_CAL: - if (copy_from_user(&tsdev->cal, (void __user *)arg, - sizeof (struct ts_calibration))) + if (copy_from_user (&tsdev->cal, (void __user *)arg, + sizeof (struct ts_calibration))) retval = -EFAULT; break; @@ -293,7 +279,7 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct tsdev *tsdev = handle->private; - struct tsdev_client *client; + struct tsdev_list *list; struct timeval time; switch (type) { @@ -357,18 +343,18 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, if (type != EV_SYN || code != SYN_REPORT) return; - list_for_each_entry(client, &tsdev->client_list, node) { + list_for_each_entry(list, &tsdev->list, node) { int x, y, tmp; do_gettimeofday(&time); - client->event[client->head].millisecs = time.tv_usec / 100; - client->event[client->head].pressure = tsdev->pressure; + list->event[list->head].millisecs = time.tv_usec / 100; + list->event[list->head].pressure = tsdev->pressure; x = tsdev->x; y = tsdev->y; /* Calibration */ - if (!client->raw) { + if (!list->raw) { x = ((x * tsdev->cal.xscale) >> 8) + tsdev->cal.xtrans; y = ((y * tsdev->cal.yscale) >> 8) + tsdev->cal.ytrans; if (tsdev->cal.xyswap) { @@ -376,35 +362,33 @@ static void tsdev_event(struct input_handle *handle, unsigned int type, } } - client->event[client->head].x = x; - client->event[client->head].y = y; - client->head = (client->head + 1) & (TSDEV_BUFFER_SIZE - 1); - kill_fasync(&client->fasync, SIGIO, POLL_IN); + list->event[list->head].x = x; + list->event[list->head].y = y; + list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1); + kill_fasync(&list->fasync, SIGIO, POLL_IN); } wake_up_interruptible(&tsdev->wait); } -static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) +static struct input_handle *tsdev_connect(struct input_handler *handler, + struct input_dev *dev, + const struct input_device_id *id) { struct tsdev *tsdev; struct class_device *cdev; - dev_t devt; int minor, delta; - int error; for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++); if (minor >= TSDEV_MINORS / 2) { printk(KERN_ERR "tsdev: You have way too many touchscreens\n"); - return -ENFILE; + return NULL; } - tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL); - if (!tsdev) - return -ENOMEM; + if (!(tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL))) + return NULL; - INIT_LIST_HEAD(&tsdev->client_list); + INIT_LIST_HEAD(&tsdev->list); init_waitqueue_head(&tsdev->wait); sprintf(tsdev->name, "ts%d", minor); @@ -431,45 +415,23 @@ static int tsdev_connect(struct input_handler *handler, struct input_dev *dev, tsdev_table[minor] = tsdev; - devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), - - cdev = class_device_create(&input_class, &dev->cdev, devt, - dev->cdev.dev, tsdev->name); - if (IS_ERR(cdev)) { - error = PTR_ERR(cdev); - goto err_free_tsdev; - } + cdev = class_device_create(&input_class, &dev->cdev, + MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), + dev->cdev.dev, tsdev->name); /* temporary symlink to keep userspace happy */ - error = sysfs_create_link(&input_class.subsys.kobj, - &cdev->kobj, tsdev->name); - if (error) - goto err_cdev_destroy; - - error = input_register_handle(&tsdev->handle); - if (error) - goto err_remove_link; + sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, + tsdev->name); - return 0; - - err_remove_link: - sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); - err_cdev_destroy: - class_device_destroy(&input_class, devt); - err_free_tsdev: - tsdev_table[minor] = NULL; - kfree(tsdev); - return error; + return &tsdev->handle; } static void tsdev_disconnect(struct input_handle *handle) { struct tsdev *tsdev = handle->private; - struct tsdev_client *client; - - input_unregister_handle(handle); + struct tsdev_list *list; - sysfs_remove_link(&input_class.subsys.kobj, tsdev->name); + sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name); class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); tsdev->exist = 0; @@ -477,8 +439,8 @@ static void tsdev_disconnect(struct input_handle *handle) if (tsdev->open) { input_close_device(handle); wake_up_interruptible(&tsdev->wait); - list_for_each_entry(client, &tsdev->client_list, node) - kill_fasync(&client->fasync, SIGIO, POLL_HUP); + list_for_each_entry(list, &tsdev->list, node) + kill_fasync(&list->fasync, SIGIO, POLL_HUP); } else tsdev_free(tsdev); } diff --git a/trunk/drivers/isdn/capi/capi.c b/trunk/drivers/isdn/capi/capi.c index 81661b8bd3a8..db1260f73f10 100644 --- a/trunk/drivers/isdn/capi/capi.c +++ b/trunk/drivers/isdn/capi/capi.c @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include #include #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE @@ -147,7 +147,7 @@ struct capidev { struct capincci *nccis; - struct mutex ncci_list_mtx; + struct semaphore ncci_list_sem; }; /* -------- global variables ---------------------------------------- */ @@ -395,7 +395,7 @@ static struct capidev *capidev_alloc(void) if (!cdev) return NULL; - mutex_init(&cdev->ncci_list_mtx); + init_MUTEX(&cdev->ncci_list_sem); skb_queue_head_init(&cdev->recvqueue); init_waitqueue_head(&cdev->recvwait); write_lock_irqsave(&capidev_list_lock, flags); @@ -414,9 +414,9 @@ static void capidev_free(struct capidev *cdev) } skb_queue_purge(&cdev->recvqueue); - mutex_lock(&cdev->ncci_list_mtx); + down(&cdev->ncci_list_sem); capincci_free(cdev, 0xffffffff); - mutex_unlock(&cdev->ncci_list_mtx); + up(&cdev->ncci_list_sem); write_lock_irqsave(&capidev_list_lock, flags); list_del(&cdev->list); @@ -603,15 +603,15 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb) if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) { u16 info = CAPIMSG_U16(skb->data, 12); // Info field if (info == 0) { - mutex_lock(&cdev->ncci_list_mtx); + down(&cdev->ncci_list_sem); capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); - mutex_unlock(&cdev->ncci_list_mtx); + up(&cdev->ncci_list_sem); } } if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) { - mutex_lock(&cdev->ncci_list_mtx); + down(&cdev->ncci_list_sem); capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); - mutex_unlock(&cdev->ncci_list_mtx); + up(&cdev->ncci_list_sem); } spin_lock_irqsave(&workaround_lock, flags); if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) { @@ -752,9 +752,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos CAPIMSG_SETAPPID(skb->data, cdev->ap.applid); if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) { - mutex_lock(&cdev->ncci_list_mtx); + down(&cdev->ncci_list_sem); capincci_free(cdev, CAPIMSG_NCCI(skb->data)); - mutex_unlock(&cdev->ncci_list_mtx); + up(&cdev->ncci_list_sem); } cdev->errcode = capi20_put_message(&cdev->ap, skb); @@ -939,9 +939,9 @@ capi_ioctl(struct inode *inode, struct file *file, if (copy_from_user(&ncci, argp, sizeof(ncci))) return -EFAULT; - mutex_lock(&cdev->ncci_list_mtx); + down(&cdev->ncci_list_sem); if ((nccip = capincci_find(cdev, (u32) ncci)) == 0) { - mutex_unlock(&cdev->ncci_list_mtx); + up(&cdev->ncci_list_sem); return 0; } #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE @@ -949,7 +949,7 @@ capi_ioctl(struct inode *inode, struct file *file, count += atomic_read(&mp->ttyopencount); } #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ - mutex_unlock(&cdev->ncci_list_mtx); + up(&cdev->ncci_list_sem); return count; } return 0; @@ -964,14 +964,14 @@ capi_ioctl(struct inode *inode, struct file *file, if (copy_from_user(&ncci, argp, sizeof(ncci))) return -EFAULT; - mutex_lock(&cdev->ncci_list_mtx); + down(&cdev->ncci_list_sem); nccip = capincci_find(cdev, (u32) ncci); if (!nccip || (mp = nccip->minorp) == 0) { - mutex_unlock(&cdev->ncci_list_mtx); + up(&cdev->ncci_list_sem); return -ESRCH; } unit = mp->minor; - mutex_unlock(&cdev->ncci_list_mtx); + up(&cdev->ncci_list_sem); return unit; } return 0; diff --git a/trunk/drivers/isdn/capi/capiutil.c b/trunk/drivers/isdn/capi/capiutil.c index 22379b94e88f..ad1e2702c2d1 100644 --- a/trunk/drivers/isdn/capi/capiutil.c +++ b/trunk/drivers/isdn/capi/capiutil.c @@ -855,7 +855,7 @@ static _cdebbuf *g_debbuf; static u_long g_debbuf_lock; static _cmsg *g_cmsg; -static _cdebbuf *cdebbuf_alloc(void) +_cdebbuf *cdebbuf_alloc(void) { _cdebbuf *cdb; @@ -989,6 +989,11 @@ _cdebbuf *capi_cmsg2str(_cmsg * cmsg) return &g_debbuf; } +_cdebbuf *cdebbuf_alloc(void) +{ + return &g_debbuf; +} + void cdebbuf_free(_cdebbuf *cdb) { } @@ -1004,6 +1009,7 @@ void __exit cdebug_exit(void) #endif +EXPORT_SYMBOL(cdebbuf_alloc); EXPORT_SYMBOL(cdebbuf_free); EXPORT_SYMBOL(capi_cmsg2message); EXPORT_SYMBOL(capi_message2cmsg); diff --git a/trunk/drivers/isdn/divert/divert_procfs.c b/trunk/drivers/isdn/divert/divert_procfs.c index be77ee625bb7..53a189003355 100644 --- a/trunk/drivers/isdn/divert/divert_procfs.c +++ b/trunk/drivers/isdn/divert/divert_procfs.c @@ -11,6 +11,7 @@ #include #include +#include #ifdef CONFIG_PROC_FS #include #else diff --git a/trunk/drivers/isdn/hardware/eicon/capimain.c b/trunk/drivers/isdn/hardware/eicon/capimain.c index 98fcdfc7ca55..7a74ed35b1bf 100644 --- a/trunk/drivers/isdn/hardware/eicon/capimain.c +++ b/trunk/drivers/isdn/hardware/eicon/capimain.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "os_capi.h" diff --git a/trunk/drivers/isdn/hardware/eicon/dbgioctl.h b/trunk/drivers/isdn/hardware/eicon/dbgioctl.h new file mode 100644 index 000000000000..0fb6f5e88b60 --- /dev/null +++ b/trunk/drivers/isdn/hardware/eicon/dbgioctl.h @@ -0,0 +1,198 @@ + +/* + * + Copyright (c) Eicon Technology Corporation, 2000. + * + This source file is supplied for the use with Eicon + Technology Corporation's range of DIVA Server Adapters. + * + 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, or (at your option) + any later version. + * + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + * + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +/*------------------------------------------------------------------*/ +/* file: dbgioctl.h */ +/*------------------------------------------------------------------*/ + +#if !defined(__DBGIOCTL_H__) + +#define __DBGIOCTL_H__ + +#ifdef NOT_YET_NEEDED +/* + * The requested operation is passed in arg0 of DbgIoctlArgs, + * additional arguments (if any) in arg1, arg2 and arg3. + */ + +typedef struct +{ ULONG arg0 ; + ULONG arg1 ; + ULONG arg2 ; + ULONG arg3 ; +} DbgIoctlArgs ; + +#define DBG_COPY_LOGS 0 /* copy debugs to user until buffer full */ + /* arg1: size threshold */ + /* arg2: timeout in milliseconds */ + +#define DBG_FLUSH_LOGS 1 /* flush pending debugs to user buffer */ + /* arg1: internal driver id */ + +#define DBG_LIST_DRVS 2 /* return the list of registered drivers */ + +#define DBG_GET_MASK 3 /* get current debug mask of driver */ + /* arg1: internal driver id */ + +#define DBG_SET_MASK 4 /* set/change debug mask of driver */ + /* arg1: internal driver id */ + /* arg2: new debug mask */ + +#define DBG_GET_BUFSIZE 5 /* get current buffer size of driver */ + /* arg1: internal driver id */ + /* arg2: new debug mask */ + +#define DBG_SET_BUFSIZE 6 /* set new buffer size of driver */ + /* arg1: new buffer size */ + +/* + * common internal debug message structure + */ + +typedef struct +{ unsigned short id ; /* virtual driver id */ + unsigned short type ; /* special message type */ + unsigned long seq ; /* sequence number of message */ + unsigned long size ; /* size of message in bytes */ + unsigned long next ; /* offset to next buffered message */ + LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */ + unsigned char data[4] ;/* message data */ +} OldDbgMessage ; + +typedef struct +{ LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */ + unsigned short size ; /* size of message in bytes */ + unsigned short ffff ; /* always 0xffff to indicate new msg */ + unsigned short id ; /* virtual driver id */ + unsigned short type ; /* special message type */ + unsigned long seq ; /* sequence number of message */ + unsigned char data[4] ;/* message data */ +} DbgMessage ; + +#endif + +#define DRV_ID_UNKNOWN 0x0C /* for messages via prtComp() */ + +#define MSG_PROC_FLAG 0x80 +#define MSG_PROC_NO_GET(x) (((x) & MSG_PROC_FLAG) ? (((x) >> 4) & 7) : -1) +#define MSG_PROC_NO_SET(x) (MSG_PROC_FLAG | (((x) & 7) << 4)) + +#define MSG_TYPE_DRV_ID 0x0001 +#define MSG_TYPE_FLAGS 0x0002 +#define MSG_TYPE_STRING 0x0003 +#define MSG_TYPE_BINARY 0x0004 + +#define MSG_HEAD_SIZE ((unsigned long)&(((DbgMessage *)0)->data[0])) +#define MSG_ALIGN(len) (((unsigned long)(len) + MSG_HEAD_SIZE + 3) & ~3) +#define MSG_SIZE(pMsg) MSG_ALIGN((pMsg)->size) +#define MSG_NEXT(pMsg) ((DbgMessage *)( ((char *)(pMsg)) + MSG_SIZE(pMsg) )) + +#define OLD_MSG_HEAD_SIZE ((unsigned long)&(((OldDbgMessage *)0)->data[0])) +#define OLD_MSG_ALIGN(len) (((unsigned long)(len)+OLD_MSG_HEAD_SIZE+3) & ~3) + +/* + * manifest constants + */ + +#define MSG_FRAME_MAX_SIZE 2150 /* maximum size of B1 frame */ +#define MSG_TEXT_MAX_SIZE 1024 /* maximum size of msg text */ +#define MSG_MAX_SIZE MSG_ALIGN(MSG_FRAME_MAX_SIZE) +#define DBG_MIN_BUFFER_SIZE 0x00008000 /* minimal total buffer size 32 KB */ +#define DBG_DEF_BUFFER_SIZE 0x00020000 /* default total buffer size 128 KB */ +#define DBG_MAX_BUFFER_SIZE 0x00400000 /* maximal total buffer size 4 MB */ + +#define DBGDRV_NAME "Diehl_DIMAINT" +#define UNIDBG_DRIVER L"\\Device\\Diehl_DIMAINT" /* UNICODE name for kernel */ +#define DEBUG_DRIVER "\\\\.\\" DBGDRV_NAME /* traditional string for apps */ +#define DBGVXD_NAME "DIMAINT" +#define DEBUG_VXD "\\\\.\\" DBGVXD_NAME /* traditional string for apps */ + +/* + * Special IDI interface debug construction + */ + +#define DBG_IDI_SIG_REQ (unsigned long)0xF479C402 +#define DBG_IDI_SIG_IND (unsigned long)0xF479C403 +#define DBG_IDI_NL_REQ (unsigned long)0xF479C404 +#define DBG_IDI_NL_IND (unsigned long)0xF479C405 + +typedef struct +{ unsigned long magic_type ; + unsigned short data_len ; + unsigned char layer_ID ; + unsigned char entity_ID ; + unsigned char request ; + unsigned char ret_code ; + unsigned char indication ; + unsigned char complete ; + unsigned char data[4] ; +} DbgIdiAct, *DbgIdiAction ; + +/* + * We want to use the same IOCTL codes in Win95 and WinNT. + * The official constructor for IOCTL codes is the CTL_CODE macro + * from ( in WinNT DDK environment). + * The problem here is that we don't know how to get + * working in a Win95 DDK environment! + */ + +# ifdef CTL_CODE /*{*/ + +/* Assert that we have the same idea of the CTL_CODE macro. */ + +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) + +# else /* !CTL_CODE */ /*}{*/ + +/* Use the definitions stolen from . */ + +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) + +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe +#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe + +# endif /* CTL_CODE */ /*}*/ + +/* + * Now we can define WinNT/Win95 DeviceIoControl codes. + * + * These codes are defined in di_defs.h too, a possible mismatch will be + * detected when the dbgtool is compiled. + */ + +#define IOCTL_DRIVER_LNK \ + CTL_CODE(0x8001U,0x701,METHOD_OUT_DIRECT,FILE_ANY_ACCESS) +#define IOCTL_DRIVER_DBG \ + CTL_CODE(0x8001U,0x702,METHOD_OUT_DIRECT,FILE_ANY_ACCESS) + +#endif /* __DBGIOCTL_H__ */ diff --git a/trunk/drivers/isdn/hardware/eicon/divamnt.c b/trunk/drivers/isdn/hardware/eicon/divamnt.c index c90928974249..4aba5c502d8e 100644 --- a/trunk/drivers/isdn/hardware/eicon/divamnt.c +++ b/trunk/drivers/isdn/hardware/eicon/divamnt.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/isdn/hardware/eicon/divasi.c b/trunk/drivers/isdn/hardware/eicon/divasi.c index 78f141e77466..556b19615bc7 100644 --- a/trunk/drivers/isdn/hardware/eicon/divasi.c +++ b/trunk/drivers/isdn/hardware/eicon/divasi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/isdn/hardware/eicon/divasmain.c b/trunk/drivers/isdn/hardware/eicon/divasmain.c index 6d39f9360766..5e862e244117 100644 --- a/trunk/drivers/isdn/hardware/eicon/divasmain.c +++ b/trunk/drivers/isdn/hardware/eicon/divasmain.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/isdn/hardware/eicon/main_if.h b/trunk/drivers/isdn/hardware/eicon/main_if.h new file mode 100644 index 000000000000..0ea339afd424 --- /dev/null +++ b/trunk/drivers/isdn/hardware/eicon/main_if.h @@ -0,0 +1,50 @@ +/* + * + Copyright (c) Eicon Technology Corporation, 2000. + * + This source file is supplied for the use with Eicon + Technology Corporation's range of DIVA Server Adapters. + * + 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, or (at your option) + any later version. + * + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + * + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +/*------------------------------------------------------------------*/ +/* file: main_if.h */ +/*------------------------------------------------------------------*/ +# ifndef MAIN_IF___H +# define MAIN_IF___H + +# include "debug_if.h" + +void DI_lock (void) ; +void DI_unlock (void) ; + +#ifdef NOT_YET_NEEDED +void DI_nttime (LARGE_INTEGER *NTtime) ; +void DI_ntlcltime(LARGE_INTEGER *NTtime, LARGE_INTEGER *lclNTtime) ; +void DI_nttimefields(LARGE_INTEGER *NTtime, TIME_FIELDS *TimeFields); +unsigned long DI_wintime(LARGE_INTEGER *NTtime) ; + +unsigned short DiInsertProcessorNumber (int type) ; +void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap); + +void StartIoctlTimer (void (*Handler)(void), unsigned long msec) ; +void StopIoctlTimer (void) ; +void UnpendIoctl (DbgRequest *pDbgReq) ; +#endif + +void add_to_q(int, char* , unsigned int); +# endif /* MAIN_IF___H */ + diff --git a/trunk/drivers/isdn/hardware/eicon/platform.h b/trunk/drivers/isdn/hardware/eicon/platform.h index 15d4942de53b..ff09f07f440a 100644 --- a/trunk/drivers/isdn/hardware/eicon/platform.h +++ b/trunk/drivers/isdn/hardware/eicon/platform.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/isdn/hisax/hfc_usb.c b/trunk/drivers/isdn/hisax/hfc_usb.c index 99e70d4103b6..9f44d3e69fb0 100644 --- a/trunk/drivers/isdn/hisax/hfc_usb.c +++ b/trunk/drivers/isdn/hisax/hfc_usb.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "hisax.h" #include "hisax_if.h" #include "hfc_usb.h" diff --git a/trunk/drivers/isdn/hisax/netjet.c b/trunk/drivers/isdn/hisax/netjet.c index 02c6fbaeccf8..38f648f9b0ed 100644 --- a/trunk/drivers/isdn/hisax/netjet.c +++ b/trunk/drivers/isdn/hisax/netjet.c @@ -19,6 +19,7 @@ #include "isac.h" #include "hscx.h" #include "isdnl1.h" +#include #include #include #include diff --git a/trunk/drivers/isdn/hysdn/boardergo.c b/trunk/drivers/isdn/hysdn/boardergo.c index 6cdbad3a9926..84dccd526ac0 100644 --- a/trunk/drivers/isdn/hysdn/boardergo.c +++ b/trunk/drivers/isdn/hysdn/boardergo.c @@ -443,7 +443,7 @@ ergo_inithardware(hysdn_card * card) card->waitpofready = ergo_waitpofready; card->set_errlog_state = ergo_set_errlog_state; INIT_WORK(&card->irq_queue, ergo_irq_bh); - spin_lock_init(&card->hysdn_lock); + card->hysdn_lock = SPIN_LOCK_UNLOCKED; return (0); } /* ergo_inithardware */ diff --git a/trunk/drivers/isdn/hysdn/hysdn_proclog.c b/trunk/drivers/isdn/hysdn/hysdn_proclog.c index 27b3991fb0ec..f7e83a86f444 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_proclog.c +++ b/trunk/drivers/isdn/hysdn/hysdn_proclog.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "hysdn_defs.h" @@ -297,6 +298,8 @@ hysdn_log_close(struct inode *ino, struct file *filep) struct procdata *pd; hysdn_card *card; int retval = 0; + unsigned long flags; + spinlock_t hysdn_lock = SPIN_LOCK_UNLOCKED; lock_kernel(); if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { @@ -306,6 +309,7 @@ hysdn_log_close(struct inode *ino, struct file *filep) /* read access -> log/debug read, mark one further file as closed */ pd = NULL; + spin_lock_irqsave(&hysdn_lock, flags); inf = *((struct log_data **) filep->private_data); /* get first log entry */ if (inf) pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ @@ -328,6 +332,7 @@ hysdn_log_close(struct inode *ino, struct file *filep) inf->usage_cnt--; /* decrement usage count for buffers */ inf = inf->next; } + spin_unlock_irqrestore(&hysdn_lock, flags); if (pd) if (pd->if_used <= 0) /* delete buffers if last file closed */ diff --git a/trunk/drivers/isdn/isdnloop/isdnloop.c b/trunk/drivers/isdn/isdnloop/isdnloop.c index bb92e3cd9334..e93ad59f60bf 100644 --- a/trunk/drivers/isdn/isdnloop/isdnloop.c +++ b/trunk/drivers/isdn/isdnloop/isdnloop.c @@ -1462,7 +1462,7 @@ isdnloop_initcard(char *id) skb_queue_head_init(&card->bqueue[i]); } skb_queue_head_init(&card->dqueue); - spin_lock_init(&card->isdnloop_lock); + card->isdnloop_lock = SPIN_LOCK_UNLOCKED; card->next = cards; cards = card; if (!register_isdn(&card->interface)) { diff --git a/trunk/drivers/kvm/kvm.h b/trunk/drivers/kvm/kvm.h index 41634fde8e13..0d122bf889db 100644 --- a/trunk/drivers/kvm/kvm.h +++ b/trunk/drivers/kvm/kvm.h @@ -51,19 +51,16 @@ #define UNMAPPED_GVA (~(gpa_t)0) #define KVM_MAX_VCPUS 1 -#define KVM_ALIAS_SLOTS 4 #define KVM_MEMORY_SLOTS 4 #define KVM_NUM_MMU_PAGES 256 #define KVM_MIN_FREE_MMU_PAGES 5 #define KVM_REFILL_PAGES 25 -#define KVM_MAX_CPUID_ENTRIES 40 #define FX_IMAGE_SIZE 512 #define FX_IMAGE_ALIGN 16 #define FX_BUF_SIZE (2 * FX_IMAGE_SIZE + FX_IMAGE_ALIGN) #define DE_VECTOR 0 -#define NM_VECTOR 7 #define DF_VECTOR 8 #define TS_VECTOR 10 #define NP_VECTOR 11 @@ -76,8 +73,6 @@ #define IOPL_SHIFT 12 -#define KVM_PIO_PAGE_OFFSET 1 - /* * Address types: * @@ -111,7 +106,6 @@ struct kvm_pte_chain { * bits 4:7 - page table level for this shadow (1-4) * bits 8:9 - page table quadrant for 2-level guests * bit 16 - "metaphysical" - gfn is not a real page (huge page/real mode) - * bits 17:18 - "access" - the user and writable bits of a huge page pde */ union kvm_mmu_page_role { unsigned word; @@ -121,7 +115,6 @@ union kvm_mmu_page_role { unsigned quadrant : 2; unsigned pad_for_nice_hex_output : 6; unsigned metaphysical : 1; - unsigned hugepage_access : 2; }; }; @@ -140,6 +133,7 @@ struct kvm_mmu_page { unsigned long slot_bitmap; /* One bit set per slot which has memory * in this shadow page. */ + int global; /* Set if all ptes in this page are global */ int multimapped; /* More than one parent_pte? */ int root_count; /* Currently serving as active root */ union { @@ -225,34 +219,6 @@ enum { VCPU_SREG_LDTR, }; -struct kvm_pio_request { - unsigned long count; - int cur_count; - struct page *guest_pages[2]; - unsigned guest_page_offset; - int in; - int size; - int string; - int down; - int rep; -}; - -struct kvm_stat { - u32 pf_fixed; - u32 pf_guest; - u32 tlb_flush; - u32 invlpg; - - u32 exits; - u32 io_exits; - u32 mmio_exits; - u32 signal_exits; - u32 irq_window_exits; - u32 halt_exits; - u32 request_irq_exits; - u32 irq_exits; -}; - struct kvm_vcpu { struct kvm *kvm; union { @@ -262,8 +228,6 @@ struct kvm_vcpu { struct mutex mutex; int cpu; int launched; - u64 host_tsc; - struct kvm_run *run; int interrupt_window_open; unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */ #define NR_IRQ_WORDS KVM_IRQ_BITMAP_SIZE(unsigned long) @@ -302,7 +266,6 @@ struct kvm_vcpu { char fx_buf[FX_BUF_SIZE]; char *host_fx_image; char *guest_fx_image; - int fpu_active; int mmio_needed; int mmio_read_completed; @@ -310,14 +273,6 @@ struct kvm_vcpu { int mmio_size; unsigned char mmio_data[8]; gpa_t mmio_phys_addr; - gva_t mmio_fault_cr2; - struct kvm_pio_request pio; - void *pio_data; - - int sigset_active; - sigset_t sigset; - - struct kvm_stat stat; struct { int active; @@ -329,15 +284,6 @@ struct kvm_vcpu { u32 ar; } tr, es, ds, fs, gs; } rmode; - - int cpuid_nent; - struct kvm_cpuid_entry cpuid_entries[KVM_MAX_CPUID_ENTRIES]; -}; - -struct kvm_mem_alias { - gfn_t base_gfn; - unsigned long npages; - gfn_t target_gfn; }; struct kvm_memory_slot { @@ -350,8 +296,6 @@ struct kvm_memory_slot { struct kvm { spinlock_t lock; /* protects everything except vcpus */ - int naliases; - struct kvm_mem_alias aliases[KVM_ALIAS_SLOTS]; int nmemslots; struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS]; /* @@ -368,6 +312,22 @@ struct kvm { struct file *filp; }; +struct kvm_stat { + u32 pf_fixed; + u32 pf_guest; + u32 tlb_flush; + u32 invlpg; + + u32 exits; + u32 io_exits; + u32 mmio_exits; + u32 signal_exits; + u32 irq_window_exits; + u32 halt_exits; + u32 request_irq_exits; + u32 irq_exits; +}; + struct descriptor_table { u16 limit; unsigned long base; @@ -398,8 +358,10 @@ struct kvm_arch_ops { void (*set_segment)(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); - void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu); + void (*decache_cr0_cr4_guest_bits)(struct kvm_vcpu *vcpu); void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); + void (*set_cr0_no_modeswitch)(struct kvm_vcpu *vcpu, + unsigned long cr0); void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); void (*set_cr4)(struct kvm_vcpu *vcpu, unsigned long cr4); void (*set_efer)(struct kvm_vcpu *vcpu, u64 efer); @@ -429,6 +391,7 @@ struct kvm_arch_ops { unsigned char *hypercall_addr); }; +extern struct kvm_stat kvm_stat; extern struct kvm_arch_ops *kvm_arch_ops; #define kvm_printf(kvm, fmt ...) printk(KERN_DEBUG fmt) @@ -437,29 +400,28 @@ extern struct kvm_arch_ops *kvm_arch_ops; int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module); void kvm_exit_arch(void); -int kvm_mmu_module_init(void); -void kvm_mmu_module_exit(void); - void kvm_mmu_destroy(struct kvm_vcpu *vcpu); int kvm_mmu_create(struct kvm_vcpu *vcpu); int kvm_mmu_setup(struct kvm_vcpu *vcpu); int kvm_mmu_reset_context(struct kvm_vcpu *vcpu); void kvm_mmu_slot_remove_write_access(struct kvm_vcpu *vcpu, int slot); -void kvm_mmu_zap_all(struct kvm_vcpu *vcpu); hpa_t gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa); #define HPA_MSB ((sizeof(hpa_t) * 8) - 1) #define HPA_ERR_MASK ((hpa_t)1 << HPA_MSB) static inline int is_error_hpa(hpa_t hpa) { return hpa >> HPA_MSB; } hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva); -struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva); void kvm_emulator_want_group7_invlpg(void); extern hpa_t bad_page_address; -struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn); +static inline struct page *gfn_to_page(struct kvm_memory_slot *slot, gfn_t gfn) +{ + return slot->phys_mem[gfn - slot->base_gfn]; +} + struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); void mark_page_dirty(struct kvm *kvm, gfn_t gfn); @@ -482,10 +444,6 @@ void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value, struct x86_emulate_ctxt; -int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, - int size, unsigned long count, int string, int down, - gva_t address, int rep, unsigned port); -void kvm_emulate_cpuid(struct kvm_vcpu *vcpu); int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address); int emulate_clts(struct kvm_vcpu *vcpu); int emulator_get_dr(struct x86_emulate_ctxt* ctxt, int dr, @@ -535,6 +493,12 @@ static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, return vcpu->mmu.page_fault(vcpu, gva, error_code); } +static inline struct page *_gfn_to_page(struct kvm *kvm, gfn_t gfn) +{ + struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn); + return (slot) ? slot->phys_mem[gfn - slot->base_gfn] : NULL; +} + static inline int is_long_mode(struct kvm_vcpu *vcpu) { #ifdef CONFIG_X86_64 diff --git a/trunk/drivers/kvm/kvm_main.c b/trunk/drivers/kvm/kvm_main.c index c8b8cfa332bb..dc7a8c78cbf9 100644 --- a/trunk/drivers/kvm/kvm_main.c +++ b/trunk/drivers/kvm/kvm_main.c @@ -51,27 +51,27 @@ static DEFINE_SPINLOCK(kvm_lock); static LIST_HEAD(vm_list); struct kvm_arch_ops *kvm_arch_ops; - -#define STAT_OFFSET(x) offsetof(struct kvm_vcpu, stat.x) +struct kvm_stat kvm_stat; +EXPORT_SYMBOL_GPL(kvm_stat); static struct kvm_stats_debugfs_item { const char *name; - int offset; + u32 *data; struct dentry *dentry; } debugfs_entries[] = { - { "pf_fixed", STAT_OFFSET(pf_fixed) }, - { "pf_guest", STAT_OFFSET(pf_guest) }, - { "tlb_flush", STAT_OFFSET(tlb_flush) }, - { "invlpg", STAT_OFFSET(invlpg) }, - { "exits", STAT_OFFSET(exits) }, - { "io_exits", STAT_OFFSET(io_exits) }, - { "mmio_exits", STAT_OFFSET(mmio_exits) }, - { "signal_exits", STAT_OFFSET(signal_exits) }, - { "irq_window", STAT_OFFSET(irq_window_exits) }, - { "halt_exits", STAT_OFFSET(halt_exits) }, - { "request_irq", STAT_OFFSET(request_irq_exits) }, - { "irq_exits", STAT_OFFSET(irq_exits) }, - { NULL } + { "pf_fixed", &kvm_stat.pf_fixed }, + { "pf_guest", &kvm_stat.pf_guest }, + { "tlb_flush", &kvm_stat.tlb_flush }, + { "invlpg", &kvm_stat.invlpg }, + { "exits", &kvm_stat.exits }, + { "io_exits", &kvm_stat.io_exits }, + { "mmio_exits", &kvm_stat.mmio_exits }, + { "signal_exits", &kvm_stat.signal_exits }, + { "irq_window", &kvm_stat.irq_window_exits }, + { "halt_exits", &kvm_stat.halt_exits }, + { "request_irq", &kvm_stat.request_irq_exits }, + { "irq_exits", &kvm_stat.irq_exits }, + { NULL, NULL } }; static struct dentry *debugfs_dir; @@ -346,17 +346,6 @@ static void kvm_free_physmem(struct kvm *kvm) kvm_free_physmem_slot(&kvm->memslots[i], NULL); } -static void free_pio_guest_pages(struct kvm_vcpu *vcpu) -{ - int i; - - for (i = 0; i < 2; ++i) - if (vcpu->pio.guest_pages[i]) { - __free_page(vcpu->pio.guest_pages[i]); - vcpu->pio.guest_pages[i] = NULL; - } -} - static void kvm_free_vcpu(struct kvm_vcpu *vcpu) { if (!vcpu->vmcs) @@ -366,11 +355,6 @@ static void kvm_free_vcpu(struct kvm_vcpu *vcpu) kvm_mmu_destroy(vcpu); vcpu_put(vcpu); kvm_arch_ops->vcpu_free(vcpu); - free_page((unsigned long)vcpu->run); - vcpu->run = NULL; - free_page((unsigned long)vcpu->pio_data); - vcpu->pio_data = NULL; - free_pio_guest_pages(vcpu); } static void kvm_free_vcpus(struct kvm *kvm) @@ -420,12 +404,12 @@ static int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3) u64 pdpte; u64 *pdpt; int ret; - struct page *page; + struct kvm_memory_slot *memslot; spin_lock(&vcpu->kvm->lock); - page = gfn_to_page(vcpu->kvm, pdpt_gfn); - /* FIXME: !page - emulate? 0xff? */ - pdpt = kmap_atomic(page, KM_USER0); + memslot = gfn_to_memslot(vcpu->kvm, pdpt_gfn); + /* FIXME: !memslot - emulate? 0xff? */ + pdpt = kmap_atomic(gfn_to_page(memslot, pdpt_gfn), KM_USER0); ret = 1; for (i = 0; i < 4; ++i) { @@ -510,6 +494,7 @@ EXPORT_SYMBOL_GPL(set_cr0); void lmsw(struct kvm_vcpu *vcpu, unsigned long msw) { + kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); set_cr0(vcpu, (vcpu->cr0 & ~0x0ful) | (msw & 0x0f)); } EXPORT_SYMBOL_GPL(lmsw); @@ -845,73 +830,7 @@ static int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, return r; } -/* - * Set a new alias region. Aliases map a portion of physical memory into - * another portion. This is useful for memory windows, for example the PC - * VGA region. - */ -static int kvm_vm_ioctl_set_memory_alias(struct kvm *kvm, - struct kvm_memory_alias *alias) -{ - int r, n; - struct kvm_mem_alias *p; - - r = -EINVAL; - /* General sanity checks */ - if (alias->memory_size & (PAGE_SIZE - 1)) - goto out; - if (alias->guest_phys_addr & (PAGE_SIZE - 1)) - goto out; - if (alias->slot >= KVM_ALIAS_SLOTS) - goto out; - if (alias->guest_phys_addr + alias->memory_size - < alias->guest_phys_addr) - goto out; - if (alias->target_phys_addr + alias->memory_size - < alias->target_phys_addr) - goto out; - - spin_lock(&kvm->lock); - - p = &kvm->aliases[alias->slot]; - p->base_gfn = alias->guest_phys_addr >> PAGE_SHIFT; - p->npages = alias->memory_size >> PAGE_SHIFT; - p->target_gfn = alias->target_phys_addr >> PAGE_SHIFT; - - for (n = KVM_ALIAS_SLOTS; n > 0; --n) - if (kvm->aliases[n - 1].npages) - break; - kvm->naliases = n; - - spin_unlock(&kvm->lock); - - vcpu_load(&kvm->vcpus[0]); - spin_lock(&kvm->lock); - kvm_mmu_zap_all(&kvm->vcpus[0]); - spin_unlock(&kvm->lock); - vcpu_put(&kvm->vcpus[0]); - - return 0; - -out: - return r; -} - -static gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) -{ - int i; - struct kvm_mem_alias *alias; - - for (i = 0; i < kvm->naliases; ++i) { - alias = &kvm->aliases[i]; - if (gfn >= alias->base_gfn - && gfn < alias->base_gfn + alias->npages) - return alias->target_gfn + gfn - alias->base_gfn; - } - return gfn; -} - -static struct kvm_memory_slot *__gfn_to_memslot(struct kvm *kvm, gfn_t gfn) +struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) { int i; @@ -924,24 +843,7 @@ static struct kvm_memory_slot *__gfn_to_memslot(struct kvm *kvm, gfn_t gfn) } return NULL; } - -struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn) -{ - gfn = unalias_gfn(kvm, gfn); - return __gfn_to_memslot(kvm, gfn); -} - -struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn) -{ - struct kvm_memory_slot *slot; - - gfn = unalias_gfn(kvm, gfn); - slot = __gfn_to_memslot(kvm, gfn); - if (!slot) - return NULL; - return slot->phys_mem[gfn - slot->base_gfn]; -} -EXPORT_SYMBOL_GPL(gfn_to_page); +EXPORT_SYMBOL_GPL(gfn_to_memslot); void mark_page_dirty(struct kvm *kvm, gfn_t gfn) { @@ -969,7 +871,7 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn) } static int emulator_read_std(unsigned long addr, - void *val, + unsigned long *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { @@ -981,20 +883,20 @@ static int emulator_read_std(unsigned long addr, unsigned offset = addr & (PAGE_SIZE-1); unsigned tocopy = min(bytes, (unsigned)PAGE_SIZE - offset); unsigned long pfn; - struct page *page; - void *page_virt; + struct kvm_memory_slot *memslot; + void *page; if (gpa == UNMAPPED_GVA) return X86EMUL_PROPAGATE_FAULT; pfn = gpa >> PAGE_SHIFT; - page = gfn_to_page(vcpu->kvm, pfn); - if (!page) + memslot = gfn_to_memslot(vcpu->kvm, pfn); + if (!memslot) return X86EMUL_UNHANDLEABLE; - page_virt = kmap_atomic(page, KM_USER0); + page = kmap_atomic(gfn_to_page(memslot, pfn), KM_USER0); - memcpy(data, page_virt + offset, tocopy); + memcpy(data, page + offset, tocopy); - kunmap_atomic(page_virt, KM_USER0); + kunmap_atomic(page, KM_USER0); bytes -= tocopy; data += tocopy; @@ -1005,7 +907,7 @@ static int emulator_read_std(unsigned long addr, } static int emulator_write_std(unsigned long addr, - const void *val, + unsigned long val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { @@ -1015,7 +917,7 @@ static int emulator_write_std(unsigned long addr, } static int emulator_read_emulated(unsigned long addr, - void *val, + unsigned long *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { @@ -1043,37 +945,37 @@ static int emulator_read_emulated(unsigned long addr, } static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, - const void *val, int bytes) + unsigned long val, int bytes) { + struct kvm_memory_slot *m; struct page *page; void *virt; if (((gpa + bytes - 1) >> PAGE_SHIFT) != (gpa >> PAGE_SHIFT)) return 0; - page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); - if (!page) + m = gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT); + if (!m) return 0; + page = gfn_to_page(m, gpa >> PAGE_SHIFT); kvm_mmu_pre_write(vcpu, gpa, bytes); mark_page_dirty(vcpu->kvm, gpa >> PAGE_SHIFT); virt = kmap_atomic(page, KM_USER0); - memcpy(virt + offset_in_page(gpa), val, bytes); + memcpy(virt + offset_in_page(gpa), &val, bytes); kunmap_atomic(virt, KM_USER0); kvm_mmu_post_write(vcpu, gpa, bytes); return 1; } static int emulator_write_emulated(unsigned long addr, - const void *val, + unsigned long val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { struct kvm_vcpu *vcpu = ctxt->vcpu; gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr); - if (gpa == UNMAPPED_GVA) { - kvm_arch_ops->inject_page_fault(vcpu, addr, 2); + if (gpa == UNMAPPED_GVA) return X86EMUL_PROPAGATE_FAULT; - } if (emulator_write_phys(vcpu, gpa, val, bytes)) return X86EMUL_CONTINUE; @@ -1082,14 +984,14 @@ static int emulator_write_emulated(unsigned long addr, vcpu->mmio_phys_addr = gpa; vcpu->mmio_size = bytes; vcpu->mmio_is_write = 1; - memcpy(vcpu->mmio_data, val, bytes); + memcpy(vcpu->mmio_data, &val, bytes); return X86EMUL_CONTINUE; } static int emulator_cmpxchg_emulated(unsigned long addr, - const void *old, - const void *new, + unsigned long old, + unsigned long new, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { @@ -1102,6 +1004,30 @@ static int emulator_cmpxchg_emulated(unsigned long addr, return emulator_write_emulated(addr, new, bytes, ctxt); } +#ifdef CONFIG_X86_32 + +static int emulator_cmpxchg8b_emulated(unsigned long addr, + unsigned long old_lo, + unsigned long old_hi, + unsigned long new_lo, + unsigned long new_hi, + struct x86_emulate_ctxt *ctxt) +{ + static int reported; + int r; + + if (!reported) { + reported = 1; + printk(KERN_WARNING "kvm: emulating exchange8b as write\n"); + } + r = emulator_write_emulated(addr, new_lo, 4, ctxt); + if (r != X86EMUL_CONTINUE) + return r; + return emulator_write_emulated(addr+4, new_hi, 4, ctxt); +} + +#endif + static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) { return kvm_arch_ops->get_segment_base(vcpu, seg); @@ -1116,6 +1042,7 @@ int emulate_clts(struct kvm_vcpu *vcpu) { unsigned long cr0; + kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); cr0 = vcpu->cr0 & ~CR0_TS_MASK; kvm_arch_ops->set_cr0(vcpu, cr0); return X86EMUL_CONTINUE; @@ -1175,6 +1102,9 @@ struct x86_emulate_ops emulate_ops = { .read_emulated = emulator_read_emulated, .write_emulated = emulator_write_emulated, .cmpxchg_emulated = emulator_cmpxchg_emulated, +#ifdef CONFIG_X86_32 + .cmpxchg8b_emulated = emulator_cmpxchg8b_emulated, +#endif }; int emulate_instruction(struct kvm_vcpu *vcpu, @@ -1186,7 +1116,6 @@ int emulate_instruction(struct kvm_vcpu *vcpu, int r; int cs_db, cs_l; - vcpu->mmio_fault_cr2 = cr2; kvm_arch_ops->cache_regs(vcpu); kvm_arch_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l); @@ -1237,10 +1166,8 @@ int emulate_instruction(struct kvm_vcpu *vcpu, kvm_arch_ops->decache_regs(vcpu); kvm_arch_ops->set_rflags(vcpu, emulate_ctxt.eflags); - if (vcpu->mmio_is_write) { - vcpu->mmio_needed = 0; + if (vcpu->mmio_is_write) return EMULATE_DO_MMIO; - } return EMULATE_DONE; } @@ -1250,7 +1177,7 @@ int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run) { unsigned long nr, a0, a1, a2, a3, a4, a5, ret; - kvm_arch_ops->cache_regs(vcpu); + kvm_arch_ops->decache_regs(vcpu); ret = -KVM_EINVAL; #ifdef CONFIG_X86_64 if (is_long_mode(vcpu)) { @@ -1274,19 +1201,10 @@ int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run) } switch (nr) { default: - run->hypercall.args[0] = a0; - run->hypercall.args[1] = a1; - run->hypercall.args[2] = a2; - run->hypercall.args[3] = a3; - run->hypercall.args[4] = a4; - run->hypercall.args[5] = a5; - run->hypercall.ret = ret; - run->hypercall.longmode = is_long_mode(vcpu); - kvm_arch_ops->decache_regs(vcpu); - return 0; + ; } vcpu->regs[VCPU_REGS_RAX] = ret; - kvm_arch_ops->decache_regs(vcpu); + kvm_arch_ops->cache_regs(vcpu); return 1; } EXPORT_SYMBOL_GPL(kvm_hypercall); @@ -1319,7 +1237,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr) { - kvm_arch_ops->decache_cr4_guest_bits(vcpu); + kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); switch (cr) { case 0: return vcpu->cr0; @@ -1524,10 +1442,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n", __FUNCTION__, data); break; - case MSR_IA32_MCG_STATUS: - printk(KERN_WARNING "%s: MSR_IA32_MCG_STATUS 0x%llx, nop\n", - __FUNCTION__, data); - break; case MSR_IA32_UCODE_REV: case MSR_IA32_UCODE_WRITE: case 0x200 ... 0x2ff: /* MTRRs */ @@ -1564,8 +1478,6 @@ static int set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) void kvm_resched(struct kvm_vcpu *vcpu) { - if (!need_resched()) - return; vcpu_put(vcpu); cond_resched(); vcpu_load(vcpu); @@ -1590,250 +1502,29 @@ void save_msrs(struct vmx_msr_entry *e, int n) } EXPORT_SYMBOL_GPL(save_msrs); -void kvm_emulate_cpuid(struct kvm_vcpu *vcpu) -{ - int i; - u32 function; - struct kvm_cpuid_entry *e, *best; - - kvm_arch_ops->cache_regs(vcpu); - function = vcpu->regs[VCPU_REGS_RAX]; - vcpu->regs[VCPU_REGS_RAX] = 0; - vcpu->regs[VCPU_REGS_RBX] = 0; - vcpu->regs[VCPU_REGS_RCX] = 0; - vcpu->regs[VCPU_REGS_RDX] = 0; - best = NULL; - for (i = 0; i < vcpu->cpuid_nent; ++i) { - e = &vcpu->cpuid_entries[i]; - if (e->function == function) { - best = e; - break; - } - /* - * Both basic or both extended? - */ - if (((e->function ^ function) & 0x80000000) == 0) - if (!best || e->function > best->function) - best = e; - } - if (best) { - vcpu->regs[VCPU_REGS_RAX] = best->eax; - vcpu->regs[VCPU_REGS_RBX] = best->ebx; - vcpu->regs[VCPU_REGS_RCX] = best->ecx; - vcpu->regs[VCPU_REGS_RDX] = best->edx; - } - kvm_arch_ops->decache_regs(vcpu); - kvm_arch_ops->skip_emulated_instruction(vcpu); -} -EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); - -static int pio_copy_data(struct kvm_vcpu *vcpu) -{ - void *p = vcpu->pio_data; - void *q; - unsigned bytes; - int nr_pages = vcpu->pio.guest_pages[1] ? 2 : 1; - - kvm_arch_ops->vcpu_put(vcpu); - q = vmap(vcpu->pio.guest_pages, nr_pages, VM_READ|VM_WRITE, - PAGE_KERNEL); - if (!q) { - kvm_arch_ops->vcpu_load(vcpu); - free_pio_guest_pages(vcpu); - return -ENOMEM; - } - q += vcpu->pio.guest_page_offset; - bytes = vcpu->pio.size * vcpu->pio.cur_count; - if (vcpu->pio.in) - memcpy(q, p, bytes); - else - memcpy(p, q, bytes); - q -= vcpu->pio.guest_page_offset; - vunmap(q); - kvm_arch_ops->vcpu_load(vcpu); - free_pio_guest_pages(vcpu); - return 0; -} - -static int complete_pio(struct kvm_vcpu *vcpu) -{ - struct kvm_pio_request *io = &vcpu->pio; - long delta; - int r; - - kvm_arch_ops->cache_regs(vcpu); - - if (!io->string) { - if (io->in) - memcpy(&vcpu->regs[VCPU_REGS_RAX], vcpu->pio_data, - io->size); - } else { - if (io->in) { - r = pio_copy_data(vcpu); - if (r) { - kvm_arch_ops->cache_regs(vcpu); - return r; - } - } - - delta = 1; - if (io->rep) { - delta *= io->cur_count; - /* - * The size of the register should really depend on - * current address size. - */ - vcpu->regs[VCPU_REGS_RCX] -= delta; - } - if (io->down) - delta = -delta; - delta *= io->size; - if (io->in) - vcpu->regs[VCPU_REGS_RDI] += delta; - else - vcpu->regs[VCPU_REGS_RSI] += delta; - } - - kvm_arch_ops->decache_regs(vcpu); - - io->count -= io->cur_count; - io->cur_count = 0; - - if (!io->count) - kvm_arch_ops->skip_emulated_instruction(vcpu); - return 0; -} - -int kvm_setup_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, - int size, unsigned long count, int string, int down, - gva_t address, int rep, unsigned port) -{ - unsigned now, in_page; - int i; - int nr_pages = 1; - struct page *page; - - vcpu->run->exit_reason = KVM_EXIT_IO; - vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; - vcpu->run->io.size = size; - vcpu->run->io.data_offset = KVM_PIO_PAGE_OFFSET * PAGE_SIZE; - vcpu->run->io.count = count; - vcpu->run->io.port = port; - vcpu->pio.count = count; - vcpu->pio.cur_count = count; - vcpu->pio.size = size; - vcpu->pio.in = in; - vcpu->pio.string = string; - vcpu->pio.down = down; - vcpu->pio.guest_page_offset = offset_in_page(address); - vcpu->pio.rep = rep; - - if (!string) { - kvm_arch_ops->cache_regs(vcpu); - memcpy(vcpu->pio_data, &vcpu->regs[VCPU_REGS_RAX], 4); - kvm_arch_ops->decache_regs(vcpu); - return 0; - } - - if (!count) { - kvm_arch_ops->skip_emulated_instruction(vcpu); - return 1; - } - - now = min(count, PAGE_SIZE / size); - - if (!down) - in_page = PAGE_SIZE - offset_in_page(address); - else - in_page = offset_in_page(address) + size; - now = min(count, (unsigned long)in_page / size); - if (!now) { - /* - * String I/O straddles page boundary. Pin two guest pages - * so that we satisfy atomicity constraints. Do just one - * transaction to avoid complexity. - */ - nr_pages = 2; - now = 1; - } - if (down) { - /* - * String I/O in reverse. Yuck. Kill the guest, fix later. - */ - printk(KERN_ERR "kvm: guest string pio down\n"); - inject_gp(vcpu); - return 1; - } - vcpu->run->io.count = now; - vcpu->pio.cur_count = now; - - for (i = 0; i < nr_pages; ++i) { - spin_lock(&vcpu->kvm->lock); - page = gva_to_page(vcpu, address + i * PAGE_SIZE); - if (page) - get_page(page); - vcpu->pio.guest_pages[i] = page; - spin_unlock(&vcpu->kvm->lock); - if (!page) { - inject_gp(vcpu); - free_pio_guest_pages(vcpu); - return 1; - } - } - - if (!vcpu->pio.in) - return pio_copy_data(vcpu); - return 0; -} -EXPORT_SYMBOL_GPL(kvm_setup_pio); - static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { int r; - sigset_t sigsaved; vcpu_load(vcpu); - if (vcpu->sigset_active) - sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved); - /* re-sync apic's tpr */ vcpu->cr8 = kvm_run->cr8; - if (vcpu->pio.cur_count) { - r = complete_pio(vcpu); - if (r) - goto out; + if (kvm_run->emulated) { + kvm_arch_ops->skip_emulated_instruction(vcpu); + kvm_run->emulated = 0; } - if (vcpu->mmio_needed) { + if (kvm_run->mmio_completed) { memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8); vcpu->mmio_read_completed = 1; - vcpu->mmio_needed = 0; - r = emulate_instruction(vcpu, kvm_run, - vcpu->mmio_fault_cr2, 0); - if (r == EMULATE_DO_MMIO) { - /* - * Read-modify-write. Back to userspace. - */ - kvm_run->exit_reason = KVM_EXIT_MMIO; - r = 0; - goto out; - } } - if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) { - kvm_arch_ops->cache_regs(vcpu); - vcpu->regs[VCPU_REGS_RAX] = kvm_run->hypercall.ret; - kvm_arch_ops->decache_regs(vcpu); - } + vcpu->mmio_needed = 0; r = kvm_arch_ops->run(vcpu, kvm_run); -out: - if (vcpu->sigset_active) - sigprocmask(SIG_SETMASK, &sigsaved, NULL); - vcpu_put(vcpu); return r; } @@ -1942,7 +1633,7 @@ static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, sregs->gdt.limit = dt.limit; sregs->gdt.base = dt.base; - kvm_arch_ops->decache_cr4_guest_bits(vcpu); + kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); sregs->cr0 = vcpu->cr0; sregs->cr2 = vcpu->cr2; sregs->cr3 = vcpu->cr3; @@ -1974,6 +1665,16 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, vcpu_load(vcpu); + set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); + set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); + set_segment(vcpu, &sregs->es, VCPU_SREG_ES); + set_segment(vcpu, &sregs->fs, VCPU_SREG_FS); + set_segment(vcpu, &sregs->gs, VCPU_SREG_GS); + set_segment(vcpu, &sregs->ss, VCPU_SREG_SS); + + set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); + set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); + dt.limit = sregs->idt.limit; dt.base = sregs->idt.base; kvm_arch_ops->set_idt(vcpu, &dt); @@ -1993,10 +1694,10 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, #endif vcpu->apic_base = sregs->apic_base; - kvm_arch_ops->decache_cr4_guest_bits(vcpu); + kvm_arch_ops->decache_cr0_cr4_guest_bits(vcpu); mmu_reset_needed |= vcpu->cr0 != sregs->cr0; - kvm_arch_ops->set_cr0(vcpu, sregs->cr0); + kvm_arch_ops->set_cr0_no_modeswitch(vcpu, sregs->cr0); mmu_reset_needed |= vcpu->cr4 != sregs->cr4; kvm_arch_ops->set_cr4(vcpu, sregs->cr4); @@ -2013,16 +1714,6 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, if (vcpu->irq_pending[i]) __set_bit(i, &vcpu->irq_summary); - set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); - set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); - set_segment(vcpu, &sregs->es, VCPU_SREG_ES); - set_segment(vcpu, &sregs->fs, VCPU_SREG_FS); - set_segment(vcpu, &sregs->gs, VCPU_SREG_GS); - set_segment(vcpu, &sregs->ss, VCPU_SREG_SS); - - set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); - set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); - vcpu_put(vcpu); return 0; @@ -2196,36 +1887,6 @@ static int kvm_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, return r; } -static struct page *kvm_vcpu_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type) -{ - struct kvm_vcpu *vcpu = vma->vm_file->private_data; - unsigned long pgoff; - struct page *page; - - *type = VM_FAULT_MINOR; - pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; - if (pgoff == 0) - page = virt_to_page(vcpu->run); - else if (pgoff == KVM_PIO_PAGE_OFFSET) - page = virt_to_page(vcpu->pio_data); - else - return NOPAGE_SIGBUS; - get_page(page); - return page; -} - -static struct vm_operations_struct kvm_vcpu_vm_ops = { - .nopage = kvm_vcpu_nopage, -}; - -static int kvm_vcpu_mmap(struct file *file, struct vm_area_struct *vma) -{ - vma->vm_ops = &kvm_vcpu_vm_ops; - return 0; -} - static int kvm_vcpu_release(struct inode *inode, struct file *filp) { struct kvm_vcpu *vcpu = filp->private_data; @@ -2238,7 +1899,6 @@ static struct file_operations kvm_vcpu_fops = { .release = kvm_vcpu_release, .unlocked_ioctl = kvm_vcpu_ioctl, .compat_ioctl = kvm_vcpu_ioctl, - .mmap = kvm_vcpu_mmap, }; /* @@ -2287,7 +1947,6 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n) { int r; struct kvm_vcpu *vcpu; - struct page *page; r = -EINVAL; if (!valid_vcpu(n)) @@ -2302,22 +1961,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n) return -EEXIST; } - page = alloc_page(GFP_KERNEL | __GFP_ZERO); - r = -ENOMEM; - if (!page) - goto out_unlock; - vcpu->run = page_address(page); - - page = alloc_page(GFP_KERNEL | __GFP_ZERO); - r = -ENOMEM; - if (!page) - goto out_free_run; - vcpu->pio_data = page_address(page); - vcpu->host_fx_image = (char*)ALIGN((hva_t)vcpu->fx_buf, FX_IMAGE_ALIGN); vcpu->guest_fx_image = vcpu->host_fx_image + FX_IMAGE_SIZE; - vcpu->cr0 = 0x10; r = kvm_arch_ops->vcpu_create(vcpu); if (r < 0) @@ -2344,107 +1990,11 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n) out_free_vcpus: kvm_free_vcpu(vcpu); -out_free_run: - free_page((unsigned long)vcpu->run); - vcpu->run = NULL; -out_unlock: mutex_unlock(&vcpu->mutex); out: return r; } -static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, - struct kvm_cpuid *cpuid, - struct kvm_cpuid_entry __user *entries) -{ - int r; - - r = -E2BIG; - if (cpuid->nent > KVM_MAX_CPUID_ENTRIES) - goto out; - r = -EFAULT; - if (copy_from_user(&vcpu->cpuid_entries, entries, - cpuid->nent * sizeof(struct kvm_cpuid_entry))) - goto out; - vcpu->cpuid_nent = cpuid->nent; - return 0; - -out: - return r; -} - -static int kvm_vcpu_ioctl_set_sigmask(struct kvm_vcpu *vcpu, sigset_t *sigset) -{ - if (sigset) { - sigdelsetmask(sigset, sigmask(SIGKILL)|sigmask(SIGSTOP)); - vcpu->sigset_active = 1; - vcpu->sigset = *sigset; - } else - vcpu->sigset_active = 0; - return 0; -} - -/* - * fxsave fpu state. Taken from x86_64/processor.h. To be killed when - * we have asm/x86/processor.h - */ -struct fxsave { - u16 cwd; - u16 swd; - u16 twd; - u16 fop; - u64 rip; - u64 rdp; - u32 mxcsr; - u32 mxcsr_mask; - u32 st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ -#ifdef CONFIG_X86_64 - u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg = 256 bytes */ -#else - u32 xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ -#endif -}; - -static int kvm_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) -{ - struct fxsave *fxsave = (struct fxsave *)vcpu->guest_fx_image; - - vcpu_load(vcpu); - - memcpy(fpu->fpr, fxsave->st_space, 128); - fpu->fcw = fxsave->cwd; - fpu->fsw = fxsave->swd; - fpu->ftwx = fxsave->twd; - fpu->last_opcode = fxsave->fop; - fpu->last_ip = fxsave->rip; - fpu->last_dp = fxsave->rdp; - memcpy(fpu->xmm, fxsave->xmm_space, sizeof fxsave->xmm_space); - - vcpu_put(vcpu); - - return 0; -} - -static int kvm_vcpu_ioctl_set_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) -{ - struct fxsave *fxsave = (struct fxsave *)vcpu->guest_fx_image; - - vcpu_load(vcpu); - - memcpy(fxsave->st_space, fpu->fpr, 128); - fxsave->cwd = fpu->fcw; - fxsave->swd = fpu->fsw; - fxsave->twd = fpu->ftwx; - fxsave->fop = fpu->last_opcode; - fxsave->rip = fpu->last_ip; - fxsave->rdp = fpu->last_dp; - memcpy(fxsave->xmm_space, fpu->xmm, sizeof fxsave->xmm_space); - - vcpu_put(vcpu); - - return 0; -} - static long kvm_vcpu_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -2453,12 +2003,21 @@ static long kvm_vcpu_ioctl(struct file *filp, int r = -EINVAL; switch (ioctl) { - case KVM_RUN: - r = -EINVAL; - if (arg) + case KVM_RUN: { + struct kvm_run kvm_run; + + r = -EFAULT; + if (copy_from_user(&kvm_run, argp, sizeof kvm_run)) goto out; - r = kvm_vcpu_ioctl_run(vcpu, vcpu->run); + r = kvm_vcpu_ioctl_run(vcpu, &kvm_run); + if (r < 0 && r != -EINTR) + goto out; + if (copy_to_user(argp, &kvm_run, sizeof kvm_run)) { + r = -EFAULT; + goto out; + } break; + } case KVM_GET_REGS: { struct kvm_regs kvm_regs; @@ -2554,66 +2113,6 @@ static long kvm_vcpu_ioctl(struct file *filp, case KVM_SET_MSRS: r = msr_io(vcpu, argp, do_set_msr, 0); break; - case KVM_SET_CPUID: { - struct kvm_cpuid __user *cpuid_arg = argp; - struct kvm_cpuid cpuid; - - r = -EFAULT; - if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid)) - goto out; - r = kvm_vcpu_ioctl_set_cpuid(vcpu, &cpuid, cpuid_arg->entries); - if (r) - goto out; - break; - } - case KVM_SET_SIGNAL_MASK: { - struct kvm_signal_mask __user *sigmask_arg = argp; - struct kvm_signal_mask kvm_sigmask; - sigset_t sigset, *p; - - p = NULL; - if (argp) { - r = -EFAULT; - if (copy_from_user(&kvm_sigmask, argp, - sizeof kvm_sigmask)) - goto out; - r = -EINVAL; - if (kvm_sigmask.len != sizeof sigset) - goto out; - r = -EFAULT; - if (copy_from_user(&sigset, sigmask_arg->sigset, - sizeof sigset)) - goto out; - p = &sigset; - } - r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); - break; - } - case KVM_GET_FPU: { - struct kvm_fpu fpu; - - memset(&fpu, 0, sizeof fpu); - r = kvm_vcpu_ioctl_get_fpu(vcpu, &fpu); - if (r) - goto out; - r = -EFAULT; - if (copy_to_user(argp, &fpu, sizeof fpu)) - goto out; - r = 0; - break; - } - case KVM_SET_FPU: { - struct kvm_fpu fpu; - - r = -EFAULT; - if (copy_from_user(&fpu, argp, sizeof fpu)) - goto out; - r = kvm_vcpu_ioctl_set_fpu(vcpu, &fpu); - if (r) - goto out; - r = 0; - break; - } default: ; } @@ -2656,17 +2155,6 @@ static long kvm_vm_ioctl(struct file *filp, goto out; break; } - case KVM_SET_MEMORY_ALIAS: { - struct kvm_memory_alias alias; - - r = -EFAULT; - if (copy_from_user(&alias, argp, sizeof alias)) - goto out; - r = kvm_vm_ioctl_set_memory_alias(kvm, &alias); - if (r) - goto out; - break; - } default: ; } @@ -2680,11 +2168,15 @@ static struct page *kvm_vm_nopage(struct vm_area_struct *vma, { struct kvm *kvm = vma->vm_file->private_data; unsigned long pgoff; + struct kvm_memory_slot *slot; struct page *page; *type = VM_FAULT_MINOR; pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; - page = gfn_to_page(kvm, pgoff); + slot = gfn_to_memslot(kvm, pgoff); + if (!slot) + return NOPAGE_SIGBUS; + page = gfn_to_page(slot, pgoff); if (!page) return NOPAGE_SIGBUS; get_page(page); @@ -2756,19 +2248,13 @@ static long kvm_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { void __user *argp = (void __user *)arg; - long r = -EINVAL; + int r = -EINVAL; switch (ioctl) { case KVM_GET_API_VERSION: - r = -EINVAL; - if (arg) - goto out; r = KVM_API_VERSION; break; case KVM_CREATE_VM: - r = -EINVAL; - if (arg) - goto out; r = kvm_dev_ioctl_create_vm(); break; case KVM_GET_MSR_INDEX_LIST: { @@ -2798,18 +2284,6 @@ static long kvm_dev_ioctl(struct file *filp, r = 0; break; } - case KVM_CHECK_EXTENSION: - /* - * No extensions defined at present. - */ - r = 0; - break; - case KVM_GET_VCPU_MMAP_SIZE: - r = -EINVAL; - if (arg) - goto out; - r = 2 * PAGE_SIZE; - break; default: ; } @@ -2825,7 +2299,7 @@ static struct file_operations kvm_chardev_ops = { }; static struct miscdevice kvm_dev = { - KVM_MINOR, + MISC_DYNAMIC_MINOR, "kvm", &kvm_chardev_ops, }; @@ -2911,39 +2385,14 @@ static struct notifier_block kvm_cpu_notifier = { .priority = 20, /* must be > scheduler priority */ }; -static u64 stat_get(void *_offset) -{ - unsigned offset = (long)_offset; - u64 total = 0; - struct kvm *kvm; - struct kvm_vcpu *vcpu; - int i; - - spin_lock(&kvm_lock); - list_for_each_entry(kvm, &vm_list, vm_list) - for (i = 0; i < KVM_MAX_VCPUS; ++i) { - vcpu = &kvm->vcpus[i]; - total += *(u32 *)((void *)vcpu + offset); - } - spin_unlock(&kvm_lock); - return total; -} - -static void stat_set(void *offset, u64 val) -{ -} - -DEFINE_SIMPLE_ATTRIBUTE(stat_fops, stat_get, stat_set, "%llu\n"); - static __init void kvm_init_debug(void) { struct kvm_stats_debugfs_item *p; debugfs_dir = debugfs_create_dir("kvm", NULL); for (p = debugfs_entries; p->name; ++p) - p->dentry = debugfs_create_file(p->name, 0444, debugfs_dir, - (void *)(long)p->offset, - &stat_fops); + p->dentry = debugfs_create_u32(p->name, 0444, debugfs_dir, + p->data); } static void kvm_exit_debug(void) @@ -3073,10 +2522,6 @@ static __init int kvm_init(void) static struct page *bad_page; int r; - r = kvm_mmu_module_init(); - if (r) - goto out4; - r = register_filesystem(&kvm_fs_type); if (r) goto out3; @@ -3105,8 +2550,6 @@ static __init int kvm_init(void) out2: unregister_filesystem(&kvm_fs_type); out3: - kvm_mmu_module_exit(); -out4: return r; } @@ -3116,7 +2559,6 @@ static __exit void kvm_exit(void) __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT)); mntput(kvmfs_mnt); unregister_filesystem(&kvm_fs_type); - kvm_mmu_module_exit(); } module_init(kvm_init) diff --git a/trunk/drivers/kvm/kvm_svm.h b/trunk/drivers/kvm/kvm_svm.h index a869983d683d..624f1ca48657 100644 --- a/trunk/drivers/kvm/kvm_svm.h +++ b/trunk/drivers/kvm/kvm_svm.h @@ -9,15 +9,17 @@ #include "svm.h" #include "kvm.h" -static const u32 host_save_user_msrs[] = { +static const u32 host_save_msrs[] = { #ifdef CONFIG_X86_64 MSR_STAR, MSR_LSTAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_KERNEL_GS_BASE, - MSR_FS_BASE, + MSR_FS_BASE, MSR_GS_BASE, #endif MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, + MSR_IA32_DEBUGCTLMSR, /*MSR_IA32_LASTBRANCHFROMIP, + MSR_IA32_LASTBRANCHTOIP, MSR_IA32_LASTINTFROMIP,MSR_IA32_LASTINTTOIP,*/ }; -#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs) +#define NR_HOST_SAVE_MSRS ARRAY_SIZE(host_save_msrs) #define NUM_DB_REGS 4 struct vcpu_svm { @@ -26,12 +28,13 @@ struct vcpu_svm { struct svm_cpu_data *svm_data; uint64_t asid_generation; + unsigned long cr0; + unsigned long cr4; unsigned long db_regs[NUM_DB_REGS]; u64 next_rip; - u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS]; - u64 host_gs_base; + u64 host_msrs[NR_HOST_SAVE_MSRS]; unsigned long host_cr2; unsigned long host_db_regs[NUM_DB_REGS]; unsigned long host_dr6; diff --git a/trunk/drivers/kvm/kvm_vmx.h b/trunk/drivers/kvm/kvm_vmx.h new file mode 100644 index 000000000000..d139f73fb6e1 --- /dev/null +++ b/trunk/drivers/kvm/kvm_vmx.h @@ -0,0 +1,14 @@ +#ifndef __KVM_VMX_H +#define __KVM_VMX_H + +#ifdef CONFIG_X86_64 +/* + * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt + * mechanism (cpu bug AA24) + */ +#define NR_BAD_MSRS 2 +#else +#define NR_BAD_MSRS 0 +#endif + +#endif diff --git a/trunk/drivers/kvm/mmu.c b/trunk/drivers/kvm/mmu.c index e8e228118de9..cab26f301eab 100644 --- a/trunk/drivers/kvm/mmu.c +++ b/trunk/drivers/kvm/mmu.c @@ -52,15 +52,11 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, const char *msg) {} static int dbg = 1; #endif -#ifndef MMU_DEBUG -#define ASSERT(x) do { } while (0) -#else #define ASSERT(x) \ if (!(x)) { \ printk(KERN_WARNING "assertion failed %s:%d: %s\n", \ __FILE__, __LINE__, #x); \ } -#endif #define PT64_PT_BITS 9 #define PT64_ENT_PER_PAGE (1 << PT64_PT_BITS) @@ -163,9 +159,6 @@ struct kvm_rmap_desc { struct kvm_rmap_desc *more; }; -static struct kmem_cache *pte_chain_cache; -static struct kmem_cache *rmap_desc_cache; - static int is_write_protection(struct kvm_vcpu *vcpu) { return vcpu->cr0 & CR0_WP_MASK; @@ -203,15 +196,14 @@ static int is_rmap_pte(u64 pte) } static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, - struct kmem_cache *base_cache, int min, - gfp_t gfp_flags) + size_t objsize, int min) { void *obj; if (cache->nobjs >= min) return 0; while (cache->nobjs < ARRAY_SIZE(cache->objects)) { - obj = kmem_cache_zalloc(base_cache, gfp_flags); + obj = kzalloc(objsize, GFP_NOWAIT); if (!obj) return -ENOMEM; cache->objects[cache->nobjs++] = obj; @@ -225,35 +217,20 @@ static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc) kfree(mc->objects[--mc->nobjs]); } -static int __mmu_topup_memory_caches(struct kvm_vcpu *vcpu, gfp_t gfp_flags) +static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) { int r; r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, - pte_chain_cache, 4, gfp_flags); + sizeof(struct kvm_pte_chain), 4); if (r) goto out; r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, - rmap_desc_cache, 1, gfp_flags); + sizeof(struct kvm_rmap_desc), 1); out: return r; } -static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) -{ - int r; - - r = __mmu_topup_memory_caches(vcpu, GFP_NOWAIT); - if (r < 0) { - spin_unlock(&vcpu->kvm->lock); - kvm_arch_ops->vcpu_put(vcpu); - r = __mmu_topup_memory_caches(vcpu, GFP_KERNEL); - kvm_arch_ops->vcpu_load(vcpu); - spin_lock(&vcpu->kvm->lock); - } - return r; -} - static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) { mmu_free_memory_cache(&vcpu->mmu_pte_chain_cache); @@ -413,11 +390,13 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) { struct kvm *kvm = vcpu->kvm; struct page *page; + struct kvm_memory_slot *slot; struct kvm_rmap_desc *desc; u64 *spte; - page = gfn_to_page(kvm, gfn); - BUG_ON(!page); + slot = gfn_to_memslot(kvm, gfn); + BUG_ON(!slot); + page = gfn_to_page(slot, gfn); while (page_private(page)) { if (!(page_private(page) & 1)) @@ -438,7 +417,6 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) } } -#ifdef MMU_DEBUG static int is_empty_shadow_page(hpa_t page_hpa) { u64 *pos; @@ -453,15 +431,15 @@ static int is_empty_shadow_page(hpa_t page_hpa) } return 1; } -#endif static void kvm_mmu_free_page(struct kvm_vcpu *vcpu, hpa_t page_hpa) { struct kvm_mmu_page *page_head = page_header(page_hpa); ASSERT(is_empty_shadow_page(page_hpa)); + list_del(&page_head->link); page_head->page_hpa = page_hpa; - list_move(&page_head->link, &vcpu->free_pages); + list_add(&page_head->link, &vcpu->free_pages); ++vcpu->kvm->n_free_mmu_pages; } @@ -479,9 +457,11 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, return NULL; page = list_entry(vcpu->free_pages.next, struct kvm_mmu_page, link); - list_move(&page->link, &vcpu->kvm->active_mmu_pages); + list_del(&page->link); + list_add(&page->link, &vcpu->kvm->active_mmu_pages); ASSERT(is_empty_shadow_page(page->page_hpa)); page->slot_bitmap = 0; + page->global = 1; page->multimapped = 0; page->parent_pte = parent_pte; --vcpu->kvm->n_free_mmu_pages; @@ -589,7 +569,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, gva_t gaddr, unsigned level, int metaphysical, - unsigned hugepage_access, u64 *parent_pte) { union kvm_mmu_page_role role; @@ -603,7 +582,6 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, role.glevels = vcpu->mmu.root_level; role.level = level; role.metaphysical = metaphysical; - role.hugepage_access = hugepage_access; if (vcpu->mmu.root_level <= PT32_ROOT_LEVEL) { quadrant = gaddr >> (PAGE_SHIFT + (PT64_PT_BITS * level)); quadrant &= (1 << ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; @@ -691,8 +669,10 @@ static void kvm_mmu_zap_page(struct kvm_vcpu *vcpu, if (!page->root_count) { hlist_del(&page->hash_link); kvm_mmu_free_page(vcpu, page->page_hpa); - } else - list_move(&page->link, &vcpu->kvm->active_mmu_pages); + } else { + list_del(&page->link); + list_add(&page->link, &vcpu->kvm->active_mmu_pages); + } } static int kvm_mmu_unprotect_page(struct kvm_vcpu *vcpu, gfn_t gfn) @@ -734,12 +714,14 @@ hpa_t safe_gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa) hpa_t gpa_to_hpa(struct kvm_vcpu *vcpu, gpa_t gpa) { + struct kvm_memory_slot *slot; struct page *page; ASSERT((gpa & HPA_ERR_MASK) == 0); - page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT); - if (!page) + slot = gfn_to_memslot(vcpu->kvm, gpa >> PAGE_SHIFT); + if (!slot) return gpa | HPA_ERR_MASK; + page = gfn_to_page(slot, gpa >> PAGE_SHIFT); return ((hpa_t)page_to_pfn(page) << PAGE_SHIFT) | (gpa & (PAGE_SIZE-1)); } @@ -753,15 +735,6 @@ hpa_t gva_to_hpa(struct kvm_vcpu *vcpu, gva_t gva) return gpa_to_hpa(vcpu, gpa); } -struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva) -{ - gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, gva); - - if (gpa == UNMAPPED_GVA) - return NULL; - return pfn_to_page(gpa_to_hpa(vcpu, gpa) >> PAGE_SHIFT); -} - static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) { } @@ -799,7 +772,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, hpa_t p) >> PAGE_SHIFT; new_table = kvm_mmu_get_page(vcpu, pseudo_gfn, v, level - 1, - 1, 0, &table[index]); + 1, &table[index]); if (!new_table) { pgprintk("nonpaging_map: ENOMEM\n"); return -ENOMEM; @@ -831,12 +804,10 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu) for (i = 0; i < 4; ++i) { hpa_t root = vcpu->mmu.pae_root[i]; - if (root) { - ASSERT(VALID_PAGE(root)); - root &= PT64_BASE_ADDR_MASK; - page = page_header(root); - --page->root_count; - } + ASSERT(VALID_PAGE(root)); + root &= PT64_BASE_ADDR_MASK; + page = page_header(root); + --page->root_count; vcpu->mmu.pae_root[i] = INVALID_PAGE; } vcpu->mmu.root_hpa = INVALID_PAGE; @@ -856,7 +827,7 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu) ASSERT(!VALID_PAGE(root)); page = kvm_mmu_get_page(vcpu, root_gfn, 0, - PT64_ROOT_LEVEL, 0, 0, NULL); + PT64_ROOT_LEVEL, 0, NULL); root = page->page_hpa; ++page->root_count; vcpu->mmu.root_hpa = root; @@ -867,17 +838,13 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu) hpa_t root = vcpu->mmu.pae_root[i]; ASSERT(!VALID_PAGE(root)); - if (vcpu->mmu.root_level == PT32E_ROOT_LEVEL) { - if (!is_present_pte(vcpu->pdptrs[i])) { - vcpu->mmu.pae_root[i] = 0; - continue; - } + if (vcpu->mmu.root_level == PT32E_ROOT_LEVEL) root_gfn = vcpu->pdptrs[i] >> PAGE_SHIFT; - } else if (vcpu->mmu.root_level == 0) + else if (vcpu->mmu.root_level == 0) root_gfn = 0; page = kvm_mmu_get_page(vcpu, root_gfn, i << 30, PT32_ROOT_LEVEL, !is_paging(vcpu), - 0, NULL); + NULL); root = page->page_hpa; ++page->root_count; vcpu->mmu.pae_root[i] = root | PT_PRESENT_MASK; @@ -936,7 +903,7 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu) static void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) { - ++vcpu->stat.tlb_flush; + ++kvm_stat.tlb_flush; kvm_arch_ops->tlb_flush(vcpu); } @@ -951,6 +918,11 @@ static void paging_new_cr3(struct kvm_vcpu *vcpu) kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa); } +static void mark_pagetable_nonglobal(void *shadow_pte) +{ + page_header(__pa(shadow_pte))->global = 0; +} + static inline void set_pte_common(struct kvm_vcpu *vcpu, u64 *shadow_pte, gpa_t gaddr, @@ -968,6 +940,9 @@ static inline void set_pte_common(struct kvm_vcpu *vcpu, *shadow_pte |= access_bits; + if (!(*shadow_pte & PT_GLOBAL_MASK)) + mark_pagetable_nonglobal(shadow_pte); + if (is_error_hpa(paddr)) { *shadow_pte |= gaddr; *shadow_pte |= PT_SHADOW_IO_MARK; @@ -1341,51 +1316,6 @@ void kvm_mmu_slot_remove_write_access(struct kvm_vcpu *vcpu, int slot) } } -void kvm_mmu_zap_all(struct kvm_vcpu *vcpu) -{ - destroy_kvm_mmu(vcpu); - - while (!list_empty(&vcpu->kvm->active_mmu_pages)) { - struct kvm_mmu_page *page; - - page = container_of(vcpu->kvm->active_mmu_pages.next, - struct kvm_mmu_page, link); - kvm_mmu_zap_page(vcpu, page); - } - - mmu_free_memory_caches(vcpu); - kvm_arch_ops->tlb_flush(vcpu); - init_kvm_mmu(vcpu); -} - -void kvm_mmu_module_exit(void) -{ - if (pte_chain_cache) - kmem_cache_destroy(pte_chain_cache); - if (rmap_desc_cache) - kmem_cache_destroy(rmap_desc_cache); -} - -int kvm_mmu_module_init(void) -{ - pte_chain_cache = kmem_cache_create("kvm_pte_chain", - sizeof(struct kvm_pte_chain), - 0, 0, NULL, NULL); - if (!pte_chain_cache) - goto nomem; - rmap_desc_cache = kmem_cache_create("kvm_rmap_desc", - sizeof(struct kvm_rmap_desc), - 0, 0, NULL, NULL); - if (!rmap_desc_cache) - goto nomem; - - return 0; - -nomem: - kvm_mmu_module_exit(); - return -ENOMEM; -} - #ifdef AUDIT static const char *audit_msg; @@ -1408,7 +1338,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, for (i = 0; i < PT64_ENT_PER_PAGE; ++i, va += va_delta) { u64 ent = pt[i]; - if (!(ent & PT_PRESENT_MASK)) + if (!ent & PT_PRESENT_MASK) continue; va = canonicalize(va); @@ -1430,7 +1360,7 @@ static void audit_mappings_page(struct kvm_vcpu *vcpu, u64 page_pte, static void audit_mappings(struct kvm_vcpu *vcpu) { - unsigned i; + int i; if (vcpu->mmu.root_level == 4) audit_mappings_page(vcpu, vcpu->mmu.root_hpa, 0, 4); diff --git a/trunk/drivers/kvm/paging_tmpl.h b/trunk/drivers/kvm/paging_tmpl.h index 73ffbffb1097..f3bcee904651 100644 --- a/trunk/drivers/kvm/paging_tmpl.h +++ b/trunk/drivers/kvm/paging_tmpl.h @@ -148,7 +148,8 @@ static int FNAME(walk_addr)(struct guest_walker *walker, break; } - walker->inherited_ar &= walker->table[index]; + if (walker->level != 3 || is_long_mode(vcpu)) + walker->inherited_ar &= walker->table[index]; table_gfn = (*ptep & PT_BASE_ADDR_MASK) >> PAGE_SHIFT; paddr = safe_gpa_to_hpa(vcpu, *ptep & PT_BASE_ADDR_MASK); kunmap_atomic(walker->table, KM_USER0); @@ -247,7 +248,6 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, u64 shadow_pte; int metaphysical; gfn_t table_gfn; - unsigned hugepage_access = 0; if (is_present_pte(*shadow_ent) || is_io_pte(*shadow_ent)) { if (level == PT_PAGE_TABLE_LEVEL) @@ -277,9 +277,6 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, if (level - 1 == PT_PAGE_TABLE_LEVEL && walker->level == PT_DIRECTORY_LEVEL) { metaphysical = 1; - hugepage_access = *guest_ent; - hugepage_access &= PT_USER_MASK | PT_WRITABLE_MASK; - hugepage_access >>= PT_WRITABLE_SHIFT; table_gfn = (*guest_ent & PT_BASE_ADDR_MASK) >> PAGE_SHIFT; } else { @@ -287,8 +284,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, table_gfn = walker->table_gfn[level - 2]; } shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1, - metaphysical, hugepage_access, - shadow_ent); + metaphysical, shadow_ent); shadow_addr = shadow_page->page_hpa; shadow_pte = shadow_addr | PT_PRESENT_MASK | PT_ACCESSED_MASK | PT_WRITABLE_MASK | PT_USER_MASK; @@ -448,7 +444,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, if (is_io_pte(*shadow_pte)) return 1; - ++vcpu->stat.pf_fixed; + ++kvm_stat.pf_fixed; kvm_mmu_audit(vcpu, "post page fault (fixed)"); return write_pt; diff --git a/trunk/drivers/kvm/svm.c b/trunk/drivers/kvm/svm.c index 9c15f32eea18..3d8ea7ac2ecc 100644 --- a/trunk/drivers/kvm/svm.c +++ b/trunk/drivers/kvm/svm.c @@ -44,10 +44,6 @@ MODULE_LICENSE("GPL"); #define KVM_EFER_LMA (1 << 10) #define KVM_EFER_LME (1 << 8) -#define SVM_FEATURE_NPT (1 << 0) -#define SVM_FEATURE_LBRV (1 << 1) -#define SVM_DEATURE_SVML (1 << 2) - unsigned long iopm_base; unsigned long msrpm_base; @@ -63,16 +59,15 @@ struct kvm_ldttss_desc { struct svm_cpu_data { int cpu; - u64 asid_generation; - u32 max_asid; - u32 next_asid; + uint64_t asid_generation; + uint32_t max_asid; + uint32_t next_asid; struct kvm_ldttss_desc *tss_desc; struct page *save_area; }; static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data); -static uint32_t svm_features; struct svm_init_data { int cpu; @@ -87,11 +82,6 @@ static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000}; #define MAX_INST_SIZE 15 -static inline u32 svm_has(u32 feat) -{ - return svm_features & feat; -} - static unsigned get_addr_size(struct kvm_vcpu *vcpu) { struct vmcb_save_area *sa = &vcpu->svm->vmcb->save; @@ -213,6 +203,13 @@ static void inject_ud(struct kvm_vcpu *vcpu) UD_VECTOR; } +static void inject_db(struct kvm_vcpu *vcpu) +{ + vcpu->svm->vmcb->control.event_inj = SVM_EVTINJ_VALID | + SVM_EVTINJ_TYPE_EXEPT | + DB_VECTOR; +} + static int is_page_fault(uint32_t info) { info &= SVM_EVTINJ_VEC_MASK | SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; @@ -312,7 +309,6 @@ static void svm_hardware_enable(void *garbage) svm_data->asid_generation = 1; svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; svm_data->next_asid = svm_data->max_asid + 1; - svm_features = cpuid_edx(SVM_CPUID_FUNC); asm volatile ( "sgdt %0" : "=m"(gdt_descr) ); gdt = (struct desc_struct *)gdt_descr.address; @@ -463,6 +459,7 @@ static void init_vmcb(struct vmcb *vmcb) { struct vmcb_control_area *control = &vmcb->control; struct vmcb_save_area *save = &vmcb->save; + u64 tsc; control->intercept_cr_read = INTERCEPT_CR0_MASK | INTERCEPT_CR3_MASK | @@ -514,13 +511,12 @@ static void init_vmcb(struct vmcb *vmcb) (1ULL << INTERCEPT_VMSAVE) | (1ULL << INTERCEPT_STGI) | (1ULL << INTERCEPT_CLGI) | - (1ULL << INTERCEPT_SKINIT) | - (1ULL << INTERCEPT_MONITOR) | - (1ULL << INTERCEPT_MWAIT); + (1ULL << INTERCEPT_SKINIT); control->iopm_base_pa = iopm_base; control->msrpm_base_pa = msrpm_base; - control->tsc_offset = 0; + rdtscll(tsc); + control->tsc_offset = -tsc; control->int_ctl = V_INTR_MASKING_MASK; init_seg(&save->es); @@ -580,15 +576,12 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu) vcpu->svm->vmcb = page_address(page); memset(vcpu->svm->vmcb, 0, PAGE_SIZE); vcpu->svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; + vcpu->svm->cr0 = 0x00000010; vcpu->svm->asid_generation = 0; memset(vcpu->svm->db_regs, 0, sizeof(vcpu->svm->db_regs)); init_vmcb(vcpu->svm->vmcb); fx_init(vcpu); - vcpu->fpu_active = 1; - vcpu->apic_base = 0xfee00000 | - /*for vcpu 0*/ MSR_IA32_APICBASE_BSP | - MSR_IA32_APICBASE_ENABLE; return 0; @@ -609,34 +602,11 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu) static void svm_vcpu_load(struct kvm_vcpu *vcpu) { - int cpu, i; - - cpu = get_cpu(); - if (unlikely(cpu != vcpu->cpu)) { - u64 tsc_this, delta; - - /* - * Make sure that the guest sees a monotonically - * increasing TSC. - */ - rdtscll(tsc_this); - delta = vcpu->host_tsc - tsc_this; - vcpu->svm->vmcb->control.tsc_offset += delta; - vcpu->cpu = cpu; - } - - for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) - rdmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]); + get_cpu(); } static void svm_vcpu_put(struct kvm_vcpu *vcpu) { - int i; - - for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) - wrmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]); - - rdtscll(vcpu->host_tsc); put_cpu(); } @@ -744,7 +714,7 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) vcpu->svm->vmcb->save.gdtr.base = dt->base ; } -static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) +static void svm_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu) { } @@ -763,15 +733,9 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) } } #endif - if ((vcpu->cr0 & CR0_TS_MASK) && !(cr0 & CR0_TS_MASK)) { - vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); - vcpu->fpu_active = 1; - } - + vcpu->svm->cr0 = cr0; + vcpu->svm->vmcb->save.cr0 = cr0 | CR0_PG_MASK | CR0_WP_MASK; vcpu->cr0 = cr0; - cr0 |= CR0_PG_MASK | CR0_WP_MASK; - cr0 &= ~(CR0_CD_MASK | CR0_NW_MASK); - vcpu->svm->vmcb->save.cr0 = cr0; } static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) @@ -821,16 +785,18 @@ static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) static void load_host_msrs(struct kvm_vcpu *vcpu) { -#ifdef CONFIG_X86_64 - wrmsrl(MSR_GS_BASE, vcpu->svm->host_gs_base); -#endif + int i; + + for ( i = 0; i < NR_HOST_SAVE_MSRS; i++) + wrmsrl(host_save_msrs[i], vcpu->svm->host_msrs[i]); } static void save_host_msrs(struct kvm_vcpu *vcpu) { -#ifdef CONFIG_X86_64 - rdmsrl(MSR_GS_BASE, vcpu->svm->host_gs_base); -#endif + int i; + + for ( i = 0; i < NR_HOST_SAVE_MSRS; i++) + rdmsrl(host_save_msrs[i], vcpu->svm->host_msrs[i]); } static void new_asid(struct kvm_vcpu *vcpu, struct svm_cpu_data *svm_data) @@ -924,7 +890,7 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) case EMULATE_DONE: return 1; case EMULATE_DO_MMIO: - ++vcpu->stat.mmio_exits; + ++kvm_stat.mmio_exits; kvm_run->exit_reason = KVM_EXIT_MMIO; return 0; case EMULATE_FAIL: @@ -938,16 +904,6 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 0; } -static int nm_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) -{ - vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); - if (!(vcpu->cr0 & CR0_TS_MASK)) - vcpu->svm->vmcb->save.cr0 &= ~CR0_TS_MASK; - vcpu->fpu_active = 1; - - return 1; -} - static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { /* @@ -1025,7 +981,7 @@ static int io_get_override(struct kvm_vcpu *vcpu, return 0; } -static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, gva_t *address) +static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, u64 *address) { unsigned long addr_mask; unsigned long *reg; @@ -1069,38 +1025,38 @@ static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, gva_t *address) static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { u32 io_info = vcpu->svm->vmcb->control.exit_info_1; //address size bug? - int size, down, in, string, rep; - unsigned port; - unsigned long count; - gva_t address = 0; + int _in = io_info & SVM_IOIO_TYPE_MASK; - ++vcpu->stat.io_exits; + ++kvm_stat.io_exits; vcpu->svm->next_rip = vcpu->svm->vmcb->control.exit_info_2; - in = (io_info & SVM_IOIO_TYPE_MASK) != 0; - port = io_info >> 16; - size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; - string = (io_info & SVM_IOIO_STR_MASK) != 0; - rep = (io_info & SVM_IOIO_REP_MASK) != 0; - count = 1; - down = (vcpu->svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0; + kvm_run->exit_reason = KVM_EXIT_IO; + kvm_run->io.port = io_info >> 16; + kvm_run->io.direction = (_in) ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; + kvm_run->io.size = ((io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT); + kvm_run->io.string = (io_info & SVM_IOIO_STR_MASK) != 0; + kvm_run->io.rep = (io_info & SVM_IOIO_REP_MASK) != 0; - if (string) { + if (kvm_run->io.string) { unsigned addr_mask; - addr_mask = io_adress(vcpu, in, &address); + addr_mask = io_adress(vcpu, _in, &kvm_run->io.address); if (!addr_mask) { printk(KERN_DEBUG "%s: get io address failed\n", __FUNCTION__); return 1; } - if (rep) - count = vcpu->regs[VCPU_REGS_RCX] & addr_mask; - } - return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down, - address, rep, port); + if (kvm_run->io.rep) { + kvm_run->io.count + = vcpu->regs[VCPU_REGS_RCX] & addr_mask; + kvm_run->io.string_down = (vcpu->svm->vmcb->save.rflags + & X86_EFLAGS_DF) != 0; + } + } else + kvm_run->io.value = vcpu->svm->vmcb->save.rax; + return 0; } static int nop_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) @@ -1116,14 +1072,13 @@ static int halt_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 1; kvm_run->exit_reason = KVM_EXIT_HLT; - ++vcpu->stat.halt_exits; + ++kvm_stat.halt_exits; return 0; } static int vmmcall_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { - vcpu->svm->next_rip = vcpu->svm->vmcb->save.rip + 3; - skip_emulated_instruction(vcpu); + vcpu->svm->vmcb->save.rip += 3; return kvm_hypercall(vcpu, kvm_run); } @@ -1143,8 +1098,8 @@ static int task_switch_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_r static int cpuid_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { vcpu->svm->next_rip = vcpu->svm->vmcb->save.rip + 2; - kvm_emulate_cpuid(vcpu); - return 1; + kvm_run->exit_reason = KVM_EXIT_CPUID; + return 0; } static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) @@ -1284,7 +1239,7 @@ static int interrupt_window_interception(struct kvm_vcpu *vcpu, */ if (kvm_run->request_interrupt_window && !vcpu->irq_summary) { - ++vcpu->stat.irq_window_exits; + ++kvm_stat.irq_window_exits; kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; return 0; } @@ -1312,7 +1267,6 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu, [SVM_EXIT_WRITE_DR5] = emulate_on_interception, [SVM_EXIT_WRITE_DR7] = emulate_on_interception, [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, - [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception, [SVM_EXIT_INTR] = nop_on_interception, [SVM_EXIT_NMI] = nop_on_interception, [SVM_EXIT_SMI] = nop_on_interception, @@ -1334,8 +1288,6 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu, [SVM_EXIT_STGI] = invalid_op_interception, [SVM_EXIT_CLGI] = invalid_op_interception, [SVM_EXIT_SKINIT] = invalid_op_interception, - [SVM_EXIT_MONITOR] = invalid_op_interception, - [SVM_EXIT_MWAIT] = invalid_op_interception, }; @@ -1343,6 +1295,8 @@ static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { u32 exit_code = vcpu->svm->vmcb->control.exit_code; + kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT; + if (is_external_interrupt(vcpu->svm->vmcb->control.exit_int_info) && exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR) printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x " @@ -1353,7 +1307,12 @@ static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (exit_code >= ARRAY_SIZE(svm_exit_handlers) || svm_exit_handlers[exit_code] == 0) { kvm_run->exit_reason = KVM_EXIT_UNKNOWN; - kvm_run->hw.hardware_exit_reason = exit_code; + printk(KERN_ERR "%s: 0x%x @ 0x%llx cr0 0x%lx rflags 0x%llx\n", + __FUNCTION__, + exit_code, + vcpu->svm->vmcb->save.rip, + vcpu->cr0, + vcpu->svm->vmcb->save.rflags); return 0; } @@ -1502,10 +1461,8 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) load_db_regs(vcpu->svm->db_regs); } - if (vcpu->fpu_active) { - fx_save(vcpu->host_fx_image); - fx_restore(vcpu->guest_fx_image); - } + fx_save(vcpu->host_fx_image); + fx_restore(vcpu->guest_fx_image); asm volatile ( #ifdef CONFIG_X86_64 @@ -1616,10 +1573,8 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) #endif : "cc", "memory" ); - if (vcpu->fpu_active) { - fx_save(vcpu->guest_fx_image); - fx_restore(vcpu->host_fx_image); - } + fx_save(vcpu->guest_fx_image); + fx_restore(vcpu->host_fx_image); if ((vcpu->svm->vmcb->save.dr7 & 0xff)) load_db_regs(vcpu->svm->host_db_regs); @@ -1651,9 +1606,8 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) vcpu->svm->next_rip = 0; if (vcpu->svm->vmcb->control.exit_code == SVM_EXIT_ERR) { - kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; - kvm_run->fail_entry.hardware_entry_failure_reason - = vcpu->svm->vmcb->control.exit_code; + kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY; + kvm_run->exit_reason = vcpu->svm->vmcb->control.exit_code; post_kvm_run_save(vcpu, kvm_run); return 0; } @@ -1661,16 +1615,14 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) r = handle_exit(vcpu, kvm_run); if (r > 0) { if (signal_pending(current)) { - ++vcpu->stat.signal_exits; + ++kvm_stat.signal_exits; post_kvm_run_save(vcpu, kvm_run); - kvm_run->exit_reason = KVM_EXIT_INTR; return -EINTR; } if (dm_request_for_irq_injection(vcpu, kvm_run)) { - ++vcpu->stat.request_irq_exits; + ++kvm_stat.request_irq_exits; post_kvm_run_save(vcpu, kvm_run); - kvm_run->exit_reason = KVM_EXIT_INTR; return -EINTR; } kvm_resched(vcpu); @@ -1689,12 +1641,6 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root) { vcpu->svm->vmcb->save.cr3 = root; force_new_asid(vcpu); - - if (vcpu->fpu_active) { - vcpu->svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR); - vcpu->svm->vmcb->save.cr0 |= CR0_TS_MASK; - vcpu->fpu_active = 0; - } } static void svm_inject_page_fault(struct kvm_vcpu *vcpu, @@ -1703,7 +1649,7 @@ static void svm_inject_page_fault(struct kvm_vcpu *vcpu, { uint32_t exit_int_info = vcpu->svm->vmcb->control.exit_int_info; - ++vcpu->stat.pf_guest; + ++kvm_stat.pf_guest; if (is_page_fault(exit_int_info)) { @@ -1763,8 +1709,9 @@ static struct kvm_arch_ops svm_arch_ops = { .get_segment = svm_get_segment, .set_segment = svm_set_segment, .get_cs_db_l_bits = svm_get_cs_db_l_bits, - .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, + .decache_cr0_cr4_guest_bits = svm_decache_cr0_cr4_guest_bits, .set_cr0 = svm_set_cr0, + .set_cr0_no_modeswitch = svm_set_cr0, .set_cr3 = svm_set_cr3, .set_cr4 = svm_set_cr4, .set_efer = svm_set_efer, diff --git a/trunk/drivers/kvm/svm.h b/trunk/drivers/kvm/svm.h index 5e93814400ce..df731c3fb588 100644 --- a/trunk/drivers/kvm/svm.h +++ b/trunk/drivers/kvm/svm.h @@ -44,9 +44,6 @@ enum { INTERCEPT_RDTSCP, INTERCEPT_ICEBP, INTERCEPT_WBINVD, - INTERCEPT_MONITOR, - INTERCEPT_MWAIT, - INTERCEPT_MWAIT_COND, }; @@ -301,9 +298,6 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_EXIT_RDTSCP 0x087 #define SVM_EXIT_ICEBP 0x088 #define SVM_EXIT_WBINVD 0x089 -#define SVM_EXIT_MONITOR 0x08a -#define SVM_EXIT_MWAIT 0x08b -#define SVM_EXIT_MWAIT_COND 0x08c #define SVM_EXIT_NPF 0x400 #define SVM_EXIT_ERR -1 diff --git a/trunk/drivers/kvm/vmx.c b/trunk/drivers/kvm/vmx.c index 724db0027f00..fbbf9d6b299f 100644 --- a/trunk/drivers/kvm/vmx.c +++ b/trunk/drivers/kvm/vmx.c @@ -17,6 +17,7 @@ #include "kvm.h" #include "vmx.h" +#include "kvm_vmx.h" #include #include #include @@ -69,10 +70,6 @@ static struct kvm_vmx_segment_field { VMX_SEGMENT_FIELD(LDTR), }; -/* - * Keep MSR_K6_STAR at the end, as setup_msrs() will try to optimize it - * away by decrementing the array size. - */ static const u32 vmx_msr_index[] = { #ifdef CONFIG_X86_64 MSR_SYSCALL_MASK, MSR_LSTAR, MSR_CSTAR, MSR_KERNEL_GS_BASE, @@ -81,19 +78,6 @@ static const u32 vmx_msr_index[] = { }; #define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index) -#ifdef CONFIG_X86_64 -static unsigned msr_offset_kernel_gs_base; -#define NR_64BIT_MSRS 4 -/* - * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt - * mechanism (cpu bug AA24) - */ -#define NR_BAD_MSRS 2 -#else -#define NR_64BIT_MSRS 0 -#define NR_BAD_MSRS 0 -#endif - static inline int is_page_fault(u32 intr_info) { return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | @@ -101,13 +85,6 @@ static inline int is_page_fault(u32 intr_info) (INTR_TYPE_EXCEPTION | PF_VECTOR | INTR_INFO_VALID_MASK); } -static inline int is_no_device(u32 intr_info) -{ - return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VECTOR_MASK | - INTR_INFO_VALID_MASK)) == - (INTR_TYPE_EXCEPTION | NM_VECTOR | INTR_INFO_VALID_MASK); -} - static inline int is_external_interrupt(u32 intr_info) { return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK)) @@ -223,16 +200,6 @@ static void vmcs_write64(unsigned long field, u64 value) #endif } -static void vmcs_clear_bits(unsigned long field, u32 mask) -{ - vmcs_writel(field, vmcs_readl(field) & ~mask); -} - -static void vmcs_set_bits(unsigned long field, u32 mask) -{ - vmcs_writel(field, vmcs_readl(field) | mask); -} - /* * Switches to specified vcpu, until a matching vcpu_put(), but assumes * vcpu mutex is already taken. @@ -329,44 +296,6 @@ static void vmx_inject_gp(struct kvm_vcpu *vcpu, unsigned error_code) INTR_INFO_VALID_MASK); } -/* - * Set up the vmcs to automatically save and restore system - * msrs. Don't touch the 64-bit msrs if the guest is in legacy - * mode, as fiddling with msrs is very expensive. - */ -static void setup_msrs(struct kvm_vcpu *vcpu) -{ - int nr_skip, nr_good_msrs; - - if (is_long_mode(vcpu)) - nr_skip = NR_BAD_MSRS; - else - nr_skip = NR_64BIT_MSRS; - nr_good_msrs = vcpu->nmsrs - nr_skip; - - /* - * MSR_K6_STAR is only needed on long mode guests, and only - * if efer.sce is enabled. - */ - if (find_msr_entry(vcpu, MSR_K6_STAR)) { - --nr_good_msrs; -#ifdef CONFIG_X86_64 - if (is_long_mode(vcpu) && (vcpu->shadow_efer & EFER_SCE)) - ++nr_good_msrs; -#endif - } - - vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR, - virt_to_phys(vcpu->guest_msrs + nr_skip)); - vmcs_writel(VM_EXIT_MSR_STORE_ADDR, - virt_to_phys(vcpu->guest_msrs + nr_skip)); - vmcs_writel(VM_EXIT_MSR_LOAD_ADDR, - virt_to_phys(vcpu->host_msrs + nr_skip)); - vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs); /* 22.2.2 */ - vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */ - vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */ -} - /* * reads and returns guest's timestamp counter "register" * guest_tsc = host_tsc + tsc_offset -- 21.3 @@ -783,8 +712,6 @@ static void enter_rmode(struct kvm_vcpu *vcpu) vmcs_write32(GUEST_CS_AR_BYTES, 0xf3); vmcs_write32(GUEST_CS_LIMIT, 0xffff); - if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000) - vmcs_writel(GUEST_CS_BASE, 0xf0000); vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4); fix_rmode_seg(VCPU_SREG_ES, &vcpu->rmode.es); @@ -827,8 +754,11 @@ static void exit_lmode(struct kvm_vcpu *vcpu) #endif -static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) +static void vmx_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu) { + vcpu->cr0 &= KVM_GUEST_CR0_MASK; + vcpu->cr0 |= vmcs_readl(GUEST_CR0) & ~KVM_GUEST_CR0_MASK; + vcpu->cr4 &= KVM_GUEST_CR4_MASK; vcpu->cr4 |= vmcs_readl(GUEST_CR4) & ~KVM_GUEST_CR4_MASK; } @@ -850,11 +780,22 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) } #endif - if (!(cr0 & CR0_TS_MASK)) { - vcpu->fpu_active = 1; - vmcs_clear_bits(EXCEPTION_BITMAP, CR0_TS_MASK); - } + vmcs_writel(CR0_READ_SHADOW, cr0); + vmcs_writel(GUEST_CR0, + (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON); + vcpu->cr0 = cr0; +} + +/* + * Used when restoring the VM to avoid corrupting segment registers + */ +static void vmx_set_cr0_no_modeswitch(struct kvm_vcpu *vcpu, unsigned long cr0) +{ + if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK)) + enter_rmode(vcpu); + vcpu->rmode.active = ((cr0 & CR0_PE_MASK) == 0); + update_exception_bitmap(vcpu); vmcs_writel(CR0_READ_SHADOW, cr0); vmcs_writel(GUEST_CR0, (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON); @@ -864,12 +805,6 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { vmcs_writel(GUEST_CR3, cr3); - - if (!(vcpu->cr0 & CR0_TS_MASK)) { - vcpu->fpu_active = 0; - vmcs_set_bits(GUEST_CR0, CR0_TS_MASK); - vmcs_set_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR); - } } static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) @@ -900,7 +835,6 @@ static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) msr->data = efer & ~EFER_LME; } - setup_msrs(vcpu); } #endif @@ -944,14 +878,7 @@ static void vmx_set_segment(struct kvm_vcpu *vcpu, vmcs_writel(sf->base, var->base); vmcs_write32(sf->limit, var->limit); vmcs_write16(sf->selector, var->selector); - if (vcpu->rmode.active && var->s) { - /* - * Hack real-mode segments into vm86 compatibility. - */ - if (var->base == 0xffff0000 && var->selector == 0xf000) - vmcs_writel(sf->base, 0xf0000); - ar = 0xf3; - } else if (var->unusable) + if (var->unusable) ar = 1 << 16; else { ar = var->type & 15; @@ -1006,9 +933,9 @@ static int init_rmode_tss(struct kvm* kvm) gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT; char *page; - p1 = gfn_to_page(kvm, fn++); - p2 = gfn_to_page(kvm, fn++); - p3 = gfn_to_page(kvm, fn); + p1 = _gfn_to_page(kvm, fn++); + p2 = _gfn_to_page(kvm, fn++); + p3 = _gfn_to_page(kvm, fn); if (!p1 || !p2 || !p3) { kvm_printf(kvm,"%s: gfn_to_page failed\n", __FUNCTION__); @@ -1064,6 +991,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) struct descriptor_table dt; int i; int ret = 0; + int nr_good_msrs; extern asmlinkage void kvm_vmx_return(void); if (!init_rmode_tss(vcpu->kvm)) { @@ -1208,17 +1136,23 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) vcpu->host_msrs[j].reserved = 0; vcpu->host_msrs[j].data = data; vcpu->guest_msrs[j] = vcpu->host_msrs[j]; -#ifdef CONFIG_X86_64 - if (index == MSR_KERNEL_GS_BASE) - msr_offset_kernel_gs_base = j; -#endif ++vcpu->nmsrs; } + printk(KERN_DEBUG "kvm: msrs: %d\n", vcpu->nmsrs); - setup_msrs(vcpu); - + nr_good_msrs = vcpu->nmsrs - NR_BAD_MSRS; + vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR, + virt_to_phys(vcpu->guest_msrs + NR_BAD_MSRS)); + vmcs_writel(VM_EXIT_MSR_STORE_ADDR, + virt_to_phys(vcpu->guest_msrs + NR_BAD_MSRS)); + vmcs_writel(VM_EXIT_MSR_LOAD_ADDR, + virt_to_phys(vcpu->host_msrs + NR_BAD_MSRS)); vmcs_write32_fixedbits(MSR_IA32_VMX_EXIT_CTLS, VM_EXIT_CONTROLS, (HOST_IS_64 << 9)); /* 22.2,1, 20.7.1 */ + vmcs_write32(VM_EXIT_MSR_STORE_COUNT, nr_good_msrs); /* 22.2.2 */ + vmcs_write32(VM_EXIT_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */ + vmcs_write32(VM_ENTRY_MSR_LOAD_COUNT, nr_good_msrs); /* 22.2.2 */ + /* 22.2.1, 20.8.1 */ vmcs_write32_fixedbits(MSR_IA32_VMX_ENTRY_CTLS, @@ -1230,7 +1164,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) vmcs_writel(TPR_THRESHOLD, 0); #endif - vmcs_writel(CR0_GUEST_HOST_MASK, ~0UL); + vmcs_writel(CR0_GUEST_HOST_MASK, KVM_GUEST_CR0_MASK); vmcs_writel(CR4_GUEST_HOST_MASK, KVM_GUEST_CR4_MASK); vcpu->cr0 = 0x60000010; @@ -1256,7 +1190,7 @@ static void inject_rmode_irq(struct kvm_vcpu *vcpu, int irq) u16 sp = vmcs_readl(GUEST_RSP); u32 ss_limit = vmcs_read32(GUEST_SS_LIMIT); - if (sp > ss_limit || sp < 6 ) { + if (sp > ss_limit || sp - 6 > sp) { vcpu_printf(vcpu, "%s: #SS, rsp 0x%lx ss 0x%lx limit 0x%x\n", __FUNCTION__, vmcs_readl(GUEST_RSP), @@ -1396,15 +1330,6 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) asm ("int $2"); return 1; } - - if (is_no_device(intr_info)) { - vcpu->fpu_active = 1; - vmcs_clear_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR); - if (!(vcpu->cr0 & CR0_TS_MASK)) - vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK); - return 1; - } - error_code = 0; rip = vmcs_readl(GUEST_RIP); if (intr_info & INTR_INFO_DELIEVER_CODE_MASK) @@ -1430,7 +1355,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) case EMULATE_DONE: return 1; case EMULATE_DO_MMIO: - ++vcpu->stat.mmio_exits; + ++kvm_stat.mmio_exits; kvm_run->exit_reason = KVM_EXIT_MMIO; return 0; case EMULATE_FAIL: @@ -1459,7 +1384,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) static int handle_external_interrupt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { - ++vcpu->stat.irq_exits; + ++kvm_stat.irq_exits; return 1; } @@ -1469,7 +1394,7 @@ static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 0; } -static int get_io_count(struct kvm_vcpu *vcpu, unsigned long *count) +static int get_io_count(struct kvm_vcpu *vcpu, u64 *count) { u64 inst; gva_t rip; @@ -1514,35 +1439,33 @@ static int get_io_count(struct kvm_vcpu *vcpu, unsigned long *count) done: countr_size *= 8; *count = vcpu->regs[VCPU_REGS_RCX] & (~0ULL >> (64 - countr_size)); - //printk("cx: %lx\n", vcpu->regs[VCPU_REGS_RCX]); return 1; } static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { u64 exit_qualification; - int size, down, in, string, rep; - unsigned port; - unsigned long count; - gva_t address; - ++vcpu->stat.io_exits; + ++kvm_stat.io_exits; exit_qualification = vmcs_read64(EXIT_QUALIFICATION); - in = (exit_qualification & 8) != 0; - size = (exit_qualification & 7) + 1; - string = (exit_qualification & 16) != 0; - down = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0; - count = 1; - rep = (exit_qualification & 32) != 0; - port = exit_qualification >> 16; - address = 0; - if (string) { - if (rep && !get_io_count(vcpu, &count)) + kvm_run->exit_reason = KVM_EXIT_IO; + if (exit_qualification & 8) + kvm_run->io.direction = KVM_EXIT_IO_IN; + else + kvm_run->io.direction = KVM_EXIT_IO_OUT; + kvm_run->io.size = (exit_qualification & 7) + 1; + kvm_run->io.string = (exit_qualification & 16) != 0; + kvm_run->io.string_down + = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0; + kvm_run->io.rep = (exit_qualification & 32) != 0; + kvm_run->io.port = exit_qualification >> 16; + if (kvm_run->io.string) { + if (!get_io_count(vcpu, &kvm_run->io.count)) return 1; - address = vmcs_readl(GUEST_LINEAR_ADDRESS); - } - return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down, - address, rep, port); + kvm_run->io.address = vmcs_readl(GUEST_LINEAR_ADDRESS); + } else + kvm_run->io.value = vcpu->regs[VCPU_REGS_RAX]; /* rax */ + return 0; } static void @@ -1591,15 +1514,6 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 1; }; break; - case 2: /* clts */ - vcpu_load_rsp_rip(vcpu); - vcpu->fpu_active = 1; - vmcs_clear_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR); - vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK); - vcpu->cr0 &= ~CR0_TS_MASK; - vmcs_writel(CR0_READ_SHADOW, vcpu->cr0); - skip_emulated_instruction(vcpu); - return 1; case 1: /*mov from cr*/ switch (cr) { case 3: @@ -1609,6 +1523,8 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) skip_emulated_instruction(vcpu); return 1; case 8: + printk(KERN_DEBUG "handle_cr: read CR8 " + "cpu erratum AA15\n"); vcpu_load_rsp_rip(vcpu); vcpu->regs[reg] = vcpu->cr8; vcpu_put_rsp_rip(vcpu); @@ -1667,8 +1583,8 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) static int handle_cpuid(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { - kvm_emulate_cpuid(vcpu); - return 1; + kvm_run->exit_reason = KVM_EXIT_CPUID; + return 0; } static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) @@ -1723,7 +1639,7 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu, if (kvm_run->request_interrupt_window && !vcpu->irq_summary) { kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; - ++vcpu->stat.irq_window_exits; + ++kvm_stat.irq_window_exits; return 0; } return 1; @@ -1736,13 +1652,13 @@ static int handle_halt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 1; kvm_run->exit_reason = KVM_EXIT_HLT; - ++vcpu->stat.halt_exits; + ++kvm_stat.halt_exits; return 0; } static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { - skip_emulated_instruction(vcpu); + vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP)+3); return kvm_hypercall(vcpu, kvm_run); } @@ -1783,6 +1699,7 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) exit_reason != EXIT_REASON_EXCEPTION_NMI ) printk(KERN_WARNING "%s: unexpected, valid vectoring info and " "exit reason is 0x%x\n", __FUNCTION__, exit_reason); + kvm_run->instruction_length = vmcs_read32(VM_EXIT_INSTRUCTION_LEN); if (exit_reason < kvm_vmx_max_exit_handlers && kvm_vmx_exit_handlers[exit_reason]) return kvm_vmx_exit_handlers[exit_reason](vcpu, kvm_run); @@ -1846,21 +1763,11 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (vcpu->guest_debug.enabled) kvm_guest_debug_pre(vcpu); - if (vcpu->fpu_active) { - fx_save(vcpu->host_fx_image); - fx_restore(vcpu->guest_fx_image); - } - /* - * Loading guest fpu may have cleared host cr0.ts - */ - vmcs_writel(HOST_CR0, read_cr0()); + fx_save(vcpu->host_fx_image); + fx_restore(vcpu->guest_fx_image); -#ifdef CONFIG_X86_64 - if (is_long_mode(vcpu)) { - save_msrs(vcpu->host_msrs + msr_offset_kernel_gs_base, 1); - load_msrs(vcpu->guest_msrs, NR_BAD_MSRS); - } -#endif + save_msrs(vcpu->host_msrs, vcpu->nmsrs); + load_msrs(vcpu->guest_msrs, NR_BAD_MSRS); asm ( /* Store host registers */ @@ -2002,28 +1909,21 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) reload_tss(); } - ++vcpu->stat.exits; + ++kvm_stat.exits; -#ifdef CONFIG_X86_64 - if (is_long_mode(vcpu)) { - save_msrs(vcpu->guest_msrs, NR_BAD_MSRS); - load_msrs(vcpu->host_msrs, NR_BAD_MSRS); - } -#endif - - if (vcpu->fpu_active) { - fx_save(vcpu->guest_fx_image); - fx_restore(vcpu->host_fx_image); - } + save_msrs(vcpu->guest_msrs, NR_BAD_MSRS); + load_msrs(vcpu->host_msrs, NR_BAD_MSRS); + fx_save(vcpu->guest_fx_image); + fx_restore(vcpu->host_fx_image); vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); + kvm_run->exit_type = 0; if (fail) { - kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; - kvm_run->fail_entry.hardware_entry_failure_reason - = vmcs_read32(VM_INSTRUCTION_ERROR); + kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY; + kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR); r = 0; } else { /* @@ -2033,20 +1933,19 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) profile_hit(KVM_PROFILING, (void *)vmcs_readl(GUEST_RIP)); vcpu->launched = 1; + kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT; r = kvm_handle_exit(kvm_run, vcpu); if (r > 0) { /* Give scheduler a change to reschedule. */ if (signal_pending(current)) { - ++vcpu->stat.signal_exits; + ++kvm_stat.signal_exits; post_kvm_run_save(vcpu, kvm_run); - kvm_run->exit_reason = KVM_EXIT_INTR; return -EINTR; } if (dm_request_for_irq_injection(vcpu, kvm_run)) { - ++vcpu->stat.request_irq_exits; + ++kvm_stat.request_irq_exits; post_kvm_run_save(vcpu, kvm_run); - kvm_run->exit_reason = KVM_EXIT_INTR; return -EINTR; } @@ -2070,7 +1969,7 @@ static void vmx_inject_page_fault(struct kvm_vcpu *vcpu, { u32 vect_info = vmcs_read32(IDT_VECTORING_INFO_FIELD); - ++vcpu->stat.pf_guest; + ++kvm_stat.pf_guest; if (is_page_fault(vect_info)) { printk(KERN_DEBUG "inject_page_fault: " @@ -2127,7 +2026,6 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) vmcs_clear(vmcs); vcpu->vmcs = vmcs; vcpu->launched = 0; - vcpu->fpu_active = 1; return 0; @@ -2164,8 +2062,9 @@ static struct kvm_arch_ops vmx_arch_ops = { .get_segment = vmx_get_segment, .set_segment = vmx_set_segment, .get_cs_db_l_bits = vmx_get_cs_db_l_bits, - .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits, + .decache_cr0_cr4_guest_bits = vmx_decache_cr0_cr4_guest_bits, .set_cr0 = vmx_set_cr0, + .set_cr0_no_modeswitch = vmx_set_cr0_no_modeswitch, .set_cr3 = vmx_set_cr3, .set_cr4 = vmx_set_cr4, #ifdef CONFIG_X86_64 diff --git a/trunk/drivers/kvm/x86_emulate.c b/trunk/drivers/kvm/x86_emulate.c index 7ade09086aa5..7513cddb929f 100644 --- a/trunk/drivers/kvm/x86_emulate.c +++ b/trunk/drivers/kvm/x86_emulate.c @@ -833,9 +833,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) dst.ptr = (unsigned long *)cr2; dst.bytes = (d & ByteOp) ? 1 : op_bytes; if (d & BitOp) { - unsigned long mask = ~(dst.bytes * 8 - 1); - - dst.ptr = (void *)dst.ptr + (src.val & mask) / 8; + dst.ptr += src.val / BITS_PER_LONG; + dst.bytes = sizeof(long); } if (!(d & Mov) && /* optimisation - avoid slow emulated read */ ((rc = ops->read_emulated((unsigned long)dst.ptr, @@ -1045,7 +1044,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) if ((rc = ops->write_std( register_address(ctxt->ss_base, _regs[VCPU_REGS_RSP]), - &dst.val, dst.bytes, ctxt)) != 0) + dst.val, dst.bytes, ctxt)) != 0) goto done; dst.val = dst.orig_val; /* skanky: disable writeback */ break; @@ -1078,12 +1077,12 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) case OP_MEM: if (lock_prefix) rc = ops->cmpxchg_emulated((unsigned long)dst. - ptr, &dst.orig_val, - &dst.val, dst.bytes, + ptr, dst.orig_val, + dst.val, dst.bytes, ctxt); else rc = ops->write_emulated((unsigned long)dst.ptr, - &dst.val, dst.bytes, + dst.val, dst.bytes, ctxt); if (rc != 0) goto done; @@ -1321,8 +1320,36 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); break; case 0xc7: /* Grp9 (cmpxchg8b) */ +#if defined(__i386__) + { + unsigned long old_lo, old_hi; + if (((rc = ops->read_emulated(cr2 + 0, &old_lo, 4, + ctxt)) != 0) + || ((rc = ops->read_emulated(cr2 + 4, &old_hi, 4, + ctxt)) != 0)) + goto done; + if ((old_lo != _regs[VCPU_REGS_RAX]) + || (old_hi != _regs[VCPU_REGS_RDX])) { + _regs[VCPU_REGS_RAX] = old_lo; + _regs[VCPU_REGS_RDX] = old_hi; + _eflags &= ~EFLG_ZF; + } else if (ops->cmpxchg8b_emulated == NULL) { + rc = X86EMUL_UNHANDLEABLE; + goto done; + } else { + if ((rc = ops->cmpxchg8b_emulated(cr2, old_lo, + old_hi, + _regs[VCPU_REGS_RBX], + _regs[VCPU_REGS_RCX], + ctxt)) != 0) + goto done; + _eflags |= EFLG_ZF; + } + break; + } +#elif defined(CONFIG_X86_64) { - u64 old, new; + unsigned long old, new; if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0) goto done; if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || @@ -1331,15 +1358,15 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) _regs[VCPU_REGS_RDX] = (u32) (old >> 32); _eflags &= ~EFLG_ZF; } else { - new = ((u64)_regs[VCPU_REGS_RCX] << 32) - | (u32) _regs[VCPU_REGS_RBX]; - if ((rc = ops->cmpxchg_emulated(cr2, &old, - &new, 8, ctxt)) != 0) + new = (_regs[VCPU_REGS_RCX] << 32) | (u32) _regs[VCPU_REGS_RBX]; + if ((rc = ops->cmpxchg_emulated(cr2, old, + new, 8, ctxt)) != 0) goto done; _eflags |= EFLG_ZF; } break; } +#endif } goto writeback; diff --git a/trunk/drivers/kvm/x86_emulate.h b/trunk/drivers/kvm/x86_emulate.h index ea3407d7feee..5d41bd55125e 100644 --- a/trunk/drivers/kvm/x86_emulate.h +++ b/trunk/drivers/kvm/x86_emulate.h @@ -59,7 +59,8 @@ struct x86_emulate_ops { * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory. */ - int (*read_std)(unsigned long addr, void *val, + int (*read_std)(unsigned long addr, + unsigned long *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); /* @@ -70,7 +71,8 @@ struct x86_emulate_ops { * required). * @bytes: [IN ] Number of bytes to write to memory. */ - int (*write_std)(unsigned long addr, const void *val, + int (*write_std)(unsigned long addr, + unsigned long val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); /* @@ -80,7 +82,7 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to read from memory. */ int (*read_emulated) (unsigned long addr, - void *val, + unsigned long *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); @@ -92,7 +94,7 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to write to memory. */ int (*write_emulated) (unsigned long addr, - const void *val, + unsigned long val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); @@ -105,11 +107,29 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to access using CMPXCHG. */ int (*cmpxchg_emulated) (unsigned long addr, - const void *old, - const void *new, + unsigned long old, + unsigned long new, unsigned int bytes, struct x86_emulate_ctxt * ctxt); + /* + * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an + * emulated/special memory area. + * @addr: [IN ] Linear address to access. + * @old: [IN ] Value expected to be current at @addr. + * @new: [IN ] Value to write to @addr. + * NOTES: + * 1. This function is only ever called when emulating a real CMPXCHG8B. + * 2. This function is *never* called on x86/64 systems. + * 2. Not defining this function (i.e., specifying NULL) is equivalent + * to defining a function that always returns X86EMUL_UNHANDLEABLE. + */ + int (*cmpxchg8b_emulated) (unsigned long addr, + unsigned long old_lo, + unsigned long old_hi, + unsigned long new_lo, + unsigned long new_hi, + struct x86_emulate_ctxt * ctxt); }; struct cpu_user_regs; diff --git a/trunk/drivers/macintosh/Kconfig b/trunk/drivers/macintosh/Kconfig index a32c91e27b3c..1a86387e23be 100644 --- a/trunk/drivers/macintosh/Kconfig +++ b/trunk/drivers/macintosh/Kconfig @@ -1,10 +1,6 @@ -menuconfig MACINTOSH_DRIVERS - bool "Macintosh device drivers" +menu "Macintosh device drivers" depends on PPC || MAC || X86 - default y - -if MACINTOSH_DRIVERS config ADB bool "Apple Desktop Bus (ADB) support" @@ -113,9 +109,7 @@ config PMAC_SMU config PMAC_APM_EMU tristate "APM emulation" - select SYS_SUPPORTS_APM_EMULATION - select APM_EMULATION - depends on ADB_PMU && PM + depends on PPC_PMAC && PPC32 && PM && ADB_PMU config PMAC_MEDIABAY bool "Support PowerBook hotswap media bay" @@ -240,4 +234,4 @@ config PMAC_RACKMETER This driver procides some support to control the front panel blue LEDs "vu-meter" of the XServer macs. -endif # MACINTOSH_DRIVERS +endmenu diff --git a/trunk/drivers/macintosh/apm_emu.c b/trunk/drivers/macintosh/apm_emu.c index 9821e6361e60..cdb0bead9917 100644 --- a/trunk/drivers/macintosh/apm_emu.c +++ b/trunk/drivers/macintosh/apm_emu.c @@ -1,8 +1,10 @@ -/* - * APM emulation for PMU-based machines - * +/* APM emulation layer for PowerMac + * * Copyright 2001 Benjamin Herrenschmidt (benh@kernel.crashing.org) * + * Lots of code inherited from apm.c, see appropriate notice in + * arch/i386/kernel/apm.c + * * 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, or (at your option) any @@ -16,39 +18,429 @@ * */ -#include #include -#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include +#include +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(args...) printk(KERN_DEBUG args) +//#define DBG(args...) xmon_printf(args) +#else +#define DBG(args...) do { } while (0) +#endif + +/* + * The apm_bios device is one of the misc char devices. + * This is its minor number. + */ +#define APM_MINOR_DEV 134 + +/* + * Maximum number of events stored + */ +#define APM_MAX_EVENTS 20 + +#define FAKE_APM_BIOS_VERSION 0x0101 + +#define APM_USER_NOTIFY_TIMEOUT (5*HZ) + +/* + * The per-file APM data + */ +struct apm_user { + int magic; + struct apm_user * next; + int suser: 1; + int suspend_waiting: 1; + int suspends_pending; + int suspends_read; + int event_head; + int event_tail; + apm_event_t events[APM_MAX_EVENTS]; +}; + +/* + * The magic number in apm_user + */ +#define APM_BIOS_MAGIC 0x4101 + +/* + * Local variables + */ +static int suspends_pending; + +static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); +static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); +static struct apm_user * user_list; + +static void apm_notify_sleep(struct pmu_sleep_notifier *self, int when); +static struct pmu_sleep_notifier apm_sleep_notifier = { + apm_notify_sleep, + SLEEP_LEVEL_USERLAND, +}; + +static const char driver_version[] = "0.5"; /* no spaces */ + +#ifdef DEBUG +static char * apm_event_name[] = { + "system standby", + "system suspend", + "normal resume", + "critical resume", + "low battery", + "power status change", + "update time", + "critical suspend", + "user standby", + "user suspend", + "system standby resume", + "capabilities change" +}; +#define NR_APM_EVENT_NAME \ + (sizeof(apm_event_name) / sizeof(apm_event_name[0])) + +#endif + +static int queue_empty(struct apm_user *as) +{ + return as->event_head == as->event_tail; +} + +static apm_event_t get_queued_event(struct apm_user *as) +{ + as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; + return as->events[as->event_tail]; +} + +static void queue_event(apm_event_t event, struct apm_user *sender) +{ + struct apm_user * as; + + DBG("apm_emu: queue_event(%s)\n", apm_event_name[event-1]); + if (user_list == NULL) + return; + for (as = user_list; as != NULL; as = as->next) { + if (as == sender) + continue; + as->event_head = (as->event_head + 1) % APM_MAX_EVENTS; + if (as->event_head == as->event_tail) { + static int notified; + + if (notified++ == 0) + printk(KERN_ERR "apm_emu: an event queue overflowed\n"); + as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS; + } + as->events[as->event_head] = event; + if (!as->suser) + continue; + switch (event) { + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + as->suspends_pending++; + suspends_pending++; + break; + case APM_NORMAL_RESUME: + as->suspend_waiting = 0; + break; + } + } + wake_up_interruptible(&apm_waitqueue); +} + +static int check_apm_user(struct apm_user *as, const char *func) +{ + if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) { + printk(KERN_ERR "apm_emu: %s passed bad filp\n", func); + return 1; + } + return 0; +} + +static ssize_t do_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) +{ + struct apm_user * as; + size_t i; + apm_event_t event; + DECLARE_WAITQUEUE(wait, current); + + as = fp->private_data; + if (check_apm_user(as, "read")) + return -EIO; + if (count < sizeof(apm_event_t)) + return -EINVAL; + if (queue_empty(as)) { + if (fp->f_flags & O_NONBLOCK) + return -EAGAIN; + add_wait_queue(&apm_waitqueue, &wait); +repeat: + set_current_state(TASK_INTERRUPTIBLE); + if (queue_empty(as) && !signal_pending(current)) { + schedule(); + goto repeat; + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&apm_waitqueue, &wait); + } + i = count; + while ((i >= sizeof(event)) && !queue_empty(as)) { + event = get_queued_event(as); + DBG("apm_emu: do_read, returning: %s\n", apm_event_name[event-1]); + if (copy_to_user(buf, &event, sizeof(event))) { + if (i < count) + break; + return -EFAULT; + } + switch (event) { + case APM_SYS_SUSPEND: + case APM_USER_SUSPEND: + as->suspends_read++; + break; + } + buf += sizeof(event); + i -= sizeof(event); + } + if (i < count) + return count - i; + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +static unsigned int do_poll(struct file *fp, poll_table * wait) +{ + struct apm_user * as; + + as = fp->private_data; + if (check_apm_user(as, "poll")) + return 0; + poll_wait(fp, &apm_waitqueue, wait); + if (!queue_empty(as)) + return POLLIN | POLLRDNORM; + return 0; +} + +static int do_ioctl(struct inode * inode, struct file *filp, + u_int cmd, u_long arg) +{ + struct apm_user * as; + DECLARE_WAITQUEUE(wait, current); + + as = filp->private_data; + if (check_apm_user(as, "ioctl")) + return -EIO; + if (!as->suser) + return -EPERM; + switch (cmd) { + case APM_IOC_SUSPEND: + /* If a suspend message was sent to userland, we + * consider this as a confirmation message + */ + if (as->suspends_read > 0) { + as->suspends_read--; + as->suspends_pending--; + suspends_pending--; + } else { + // Route to PMU suspend ? + break; + } + as->suspend_waiting = 1; + add_wait_queue(&apm_waitqueue, &wait); + DBG("apm_emu: ioctl waking up sleep waiter !\n"); + wake_up(&apm_suspend_waitqueue); + mb(); + while(as->suspend_waiting && !signal_pending(current)) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&apm_waitqueue, &wait); + break; + default: + return -EINVAL; + } + return 0; +} + +static int do_release(struct inode * inode, struct file * filp) +{ + struct apm_user * as; + + as = filp->private_data; + if (check_apm_user(as, "release")) + return 0; + filp->private_data = NULL; + lock_kernel(); + if (as->suspends_pending > 0) { + suspends_pending -= as->suspends_pending; + if (suspends_pending <= 0) + wake_up(&apm_suspend_waitqueue); + } + if (user_list == as) + user_list = as->next; + else { + struct apm_user * as1; + + for (as1 = user_list; + (as1 != NULL) && (as1->next != as); + as1 = as1->next) + ; + if (as1 == NULL) + printk(KERN_ERR "apm: filp not in user list\n"); + else + as1->next = as->next; + } + unlock_kernel(); + kfree(as); + return 0; +} + +static int do_open(struct inode * inode, struct file * filp) +{ + struct apm_user * as; + + as = kmalloc(sizeof(*as), GFP_KERNEL); + if (as == NULL) { + printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n", + sizeof(*as)); + return -ENOMEM; + } + as->magic = APM_BIOS_MAGIC; + as->event_tail = as->event_head = 0; + as->suspends_pending = 0; + as->suspends_read = 0; + /* + * XXX - this is a tiny bit broken, when we consider BSD + * process accounting. If the device is opened by root, we + * instantly flag that we used superuser privs. Who knows, + * we might close the device immediately without doing a + * privileged operation -- cevans + */ + as->suser = capable(CAP_SYS_ADMIN); + as->next = user_list; + user_list = as; + filp->private_data = as; + + DBG("apm_emu: opened by %s, suser: %d\n", current->comm, (int)as->suser); + + return 0; +} + +/* Wait for all clients to ack the suspend request. APM API + * doesn't provide a way to NAK, but this could be added + * here. + */ +static void wait_all_suspend(void) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&apm_suspend_waitqueue, &wait); + DBG("apm_emu: wait_all_suspend(), suspends_pending: %d\n", suspends_pending); + while(suspends_pending > 0) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule(); + } + set_current_state(TASK_RUNNING); + remove_wait_queue(&apm_suspend_waitqueue, &wait); + + DBG("apm_emu: wait_all_suspend() - complete !\n"); +} + +static void apm_notify_sleep(struct pmu_sleep_notifier *self, int when) +{ + switch(when) { + case PBOOK_SLEEP_REQUEST: + queue_event(APM_SYS_SUSPEND, NULL); + wait_all_suspend(); + break; + case PBOOK_WAKE: + queue_event(APM_NORMAL_RESUME, NULL); + break; + } +} + #define APM_CRITICAL 10 #define APM_LOW 30 -static void pmu_apm_get_power_status(struct apm_power_info *info) +static int apm_emu_get_info(char *buf, char **start, off_t fpos, int length) { - int percentage = -1; - int batteries = 0; - int time_units = -1; - int real_count = 0; - int i; - char charging = 0; - long charge = -1; - long amperage = 0; - unsigned long btype = 0; - - info->battery_status = APM_BATTERY_STATUS_UNKNOWN; - info->battery_flag = APM_BATTERY_FLAG_UNKNOWN; - info->units = APM_UNITS_MINS; - - if (pmu_power_flags & PMU_PWR_AC_PRESENT) - info->ac_line_status = APM_AC_ONLINE; - else - info->ac_line_status = APM_AC_OFFLINE; + /* Arguments, with symbols from linux/apm_bios.h. Information is + from the Get Power Status (0x0a) call unless otherwise noted. + 0) Linux driver version (this will change if format changes) + 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2. + 2) APM flags from APM Installation Check (0x00): + bit 0: APM_16_BIT_SUPPORT + bit 1: APM_32_BIT_SUPPORT + bit 2: APM_IDLE_SLOWS_CLOCK + bit 3: APM_BIOS_DISABLED + bit 4: APM_BIOS_DISENGAGED + 3) AC line status + 0x00: Off-line + 0x01: On-line + 0x02: On backup power (BIOS >= 1.1 only) + 0xff: Unknown + 4) Battery status + 0x00: High + 0x01: Low + 0x02: Critical + 0x03: Charging + 0x04: Selected battery not present (BIOS >= 1.2 only) + 0xff: Unknown + 5) Battery flag + bit 0: High + bit 1: Low + bit 2: Critical + bit 3: Charging + bit 7: No system battery + 0xff: Unknown + 6) Remaining battery life (percentage of charge): + 0-100: valid + -1: Unknown + 7) Remaining battery life (time units): + Number of remaining minutes or seconds + -1: Unknown + 8) min = minutes; sec = seconds */ + + unsigned short ac_line_status; + unsigned short battery_status = 0; + unsigned short battery_flag = 0xff; + int percentage = -1; + int time_units = -1; + int real_count = 0; + int i; + char * p = buf; + char charging = 0; + long charge = -1; + long amperage = 0; + unsigned long btype = 0; + + ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0); for (i=0; iac_line_status = APM_AC_ONLINE; - + if (0 == battery_status) + ac_line_status = 1; + battery_status = 0xff; if (real_count) { if (amperage < 0) { if (btype == PMU_BATT_TYPE_SMART) @@ -76,44 +468,85 @@ static void pmu_apm_get_power_status(struct apm_power_info *info) } percentage /= real_count; if (charging > 0) { - info->battery_status = APM_BATTERY_STATUS_CHARGING; - info->battery_flag = APM_BATTERY_FLAG_CHARGING; + battery_status = 0x03; + battery_flag = 0x08; } else if (percentage <= APM_CRITICAL) { - info->battery_status = APM_BATTERY_STATUS_CRITICAL; - info->battery_flag = APM_BATTERY_FLAG_CRITICAL; + battery_status = 0x02; + battery_flag = 0x04; } else if (percentage <= APM_LOW) { - info->battery_status = APM_BATTERY_STATUS_LOW; - info->battery_flag = APM_BATTERY_FLAG_LOW; + battery_status = 0x01; + battery_flag = 0x02; } else { - info->battery_status = APM_BATTERY_STATUS_HIGH; - info->battery_flag = APM_BATTERY_FLAG_HIGH; + battery_status = 0x00; + battery_flag = 0x01; } } + p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", + driver_version, + (FAKE_APM_BIOS_VERSION >> 8) & 0xff, + FAKE_APM_BIOS_VERSION & 0xff, + 0, + ac_line_status, + battery_status, + battery_flag, + percentage, + time_units, + "min"); - info->battery_life = percentage; - info->time = time_units; + return p - buf; } +static const struct file_operations apm_bios_fops = { + .owner = THIS_MODULE, + .read = do_read, + .poll = do_poll, + .ioctl = do_ioctl, + .open = do_open, + .release = do_release, +}; + +static struct miscdevice apm_device = { + APM_MINOR_DEV, + "apm_bios", + &apm_bios_fops +}; + static int __init apm_emu_init(void) { - apm_get_power_status = pmu_apm_get_power_status; + struct proc_dir_entry *apm_proc; + + if (sys_ctrler != SYS_CTRLER_PMU) { + printk(KERN_INFO "apm_emu: Requires a machine with a PMU.\n"); + return -ENODEV; + } + + apm_proc = create_proc_info_entry("apm", 0, NULL, apm_emu_get_info); + if (apm_proc) + apm_proc->owner = THIS_MODULE; - printk(KERN_INFO "apm_emu: PMU APM Emulation initialized.\n"); + if (misc_register(&apm_device) != 0) + printk(KERN_INFO "Could not create misc. device for apm\n"); + + pmu_register_sleep_notifier(&apm_sleep_notifier); + + printk(KERN_INFO "apm_emu: APM Emulation %s initialized.\n", driver_version); return 0; } static void __exit apm_emu_exit(void) { - if (apm_get_power_status == pmu_apm_get_power_status) - apm_get_power_status = NULL; + pmu_unregister_sleep_notifier(&apm_sleep_notifier); + misc_deregister(&apm_device); + remove_proc_entry("apm", NULL); - printk(KERN_INFO "apm_emu: PMU APM Emulation removed.\n"); + printk(KERN_INFO "apm_emu: APM Emulation removed.\n"); } module_init(apm_emu_init); module_exit(apm_emu_exit); MODULE_AUTHOR("Benjamin Herrenschmidt"); -MODULE_DESCRIPTION("APM emulation for PowerMac"); +MODULE_DESCRIPTION("APM emulation layer for PowerMac"); MODULE_LICENSE("GPL"); + diff --git a/trunk/drivers/macintosh/mac_hid.c b/trunk/drivers/macintosh/mac_hid.c index 76c1e8e4a487..1599dc34f15f 100644 --- a/trunk/drivers/macintosh/mac_hid.c +++ b/trunk/drivers/macintosh/mac_hid.c @@ -24,7 +24,7 @@ static int mouse_last_keycode; #if defined(CONFIG_SYSCTL) /* file(s) in /proc/sys/dev/mac_hid */ -static ctl_table mac_hid_files[] = { +ctl_table mac_hid_files[] = { { .ctl_name = DEV_MAC_HID_MOUSE_BUTTON_EMULATION, .procname = "mouse_button_emulation", @@ -53,7 +53,7 @@ static ctl_table mac_hid_files[] = { }; /* dir in /proc/sys/dev */ -static ctl_table mac_hid_dir[] = { +ctl_table mac_hid_dir[] = { { .ctl_name = DEV_MAC_HID, .procname = "mac_hid", @@ -65,7 +65,7 @@ static ctl_table mac_hid_dir[] = { }; /* /proc/sys/dev itself, in case that is not there yet */ -static ctl_table mac_hid_root_dir[] = { +ctl_table mac_hid_root_dir[] = { { .ctl_name = CTL_DEV, .procname = "dev", @@ -127,7 +127,7 @@ static int emumousebtn_input_register(void) return ret; } -static int __init mac_hid_init(void) +int __init mac_hid_init(void) { int err; diff --git a/trunk/drivers/macintosh/macio_sysfs.c b/trunk/drivers/macintosh/macio_sysfs.c index 112e5ef728f1..cc8267912656 100644 --- a/trunk/drivers/macintosh/macio_sysfs.c +++ b/trunk/drivers/macintosh/macio_sysfs.c @@ -41,15 +41,28 @@ compatible_show (struct device *dev, struct device_attribute *attr, char *buf) static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, char *buf) { - struct of_device *ofdev = to_of_device(dev); - int len; - - len = of_device_get_modalias(ofdev, buf, PAGE_SIZE); + struct of_device *of; + const char *compat; + int cplen; + int length; - buf[len] = '\n'; - buf[len+1] = 0; + of = &to_macio_device (dev)->ofdev; + compat = of_get_property(of->node, "compatible", &cplen); + if (!compat) compat = "", cplen = 1; + length = sprintf (buf, "of:N%sT%s", of->node->name, of->node->type); + buf += length; + while (cplen > 0) { + int l; + l = sprintf (buf, "C%s", compat); + length += l; + buf += l; + l = strlen (compat) + 1; + compat += l; + cplen -= l; + } + length += sprintf(buf, "\n"); - return len+1; + return length; } macio_config_of_attr (name, "%s\n"); diff --git a/trunk/drivers/macintosh/smu.c b/trunk/drivers/macintosh/smu.c index f8e1a135bf9d..a98a328b1cfc 100644 --- a/trunk/drivers/macintosh/smu.c +++ b/trunk/drivers/macintosh/smu.c @@ -606,7 +606,7 @@ static void smu_expose_childs(struct work_struct *unused) struct device_node *np; for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) - if (of_device_is_compatible(np, "smu-sensors")) + if (device_is_compatible(np, "smu-sensors")) of_platform_device_create(np, "smu-sensors", &smu->of_dev->dev); } diff --git a/trunk/drivers/macintosh/therm_adt746x.c b/trunk/drivers/macintosh/therm_adt746x.c index bd55e6ab99fc..228903403cfc 100644 --- a/trunk/drivers/macintosh/therm_adt746x.c +++ b/trunk/drivers/macintosh/therm_adt746x.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -559,9 +560,9 @@ thermostat_init(void) np = of_find_node_by_name(NULL, "fan"); if (!np) return -ENODEV; - if (of_device_is_compatible(np, "adt7460")) + if (device_is_compatible(np, "adt7460")) therm_type = ADT7460; - else if (of_device_is_compatible(np, "adt7467")) + else if (device_is_compatible(np, "adt7467")) therm_type = ADT7467; else return -ENODEV; diff --git a/trunk/drivers/macintosh/therm_pm72.c b/trunk/drivers/macintosh/therm_pm72.c index dbb22403979f..78ff18617139 100644 --- a/trunk/drivers/macintosh/therm_pm72.c +++ b/trunk/drivers/macintosh/therm_pm72.c @@ -117,6 +117,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/macintosh/therm_windtunnel.c b/trunk/drivers/macintosh/therm_windtunnel.c index 3d0354e96a97..35233de460ad 100644 --- a/trunk/drivers/macintosh/therm_windtunnel.c +++ b/trunk/drivers/macintosh/therm_windtunnel.c @@ -459,8 +459,7 @@ therm_of_probe( struct of_device *dev, const struct of_device_id *match ) static int therm_of_remove( struct of_device *dev ) { - i2c_del_driver( &g4fan_driver ); - return 0; + return i2c_del_driver( &g4fan_driver ); } static struct of_device_id therm_of_match[] = {{ diff --git a/trunk/drivers/macintosh/via-cuda.c b/trunk/drivers/macintosh/via-cuda.c index 741a93a3eb61..76d21775fc35 100644 --- a/trunk/drivers/macintosh/via-cuda.c +++ b/trunk/drivers/macintosh/via-cuda.c @@ -82,7 +82,6 @@ static unsigned char cuda_rbuf[16]; static unsigned char *reply_ptr; static int reading_reply; static int data_index; -static int cuda_irq; #ifdef CONFIG_PPC static struct device_node *vias; #endif @@ -161,8 +160,10 @@ int __init find_via_cuda(void) /* Clear and enable interrupts, but only on PPC. On 68K it's done */ /* for us by the main VIA driver in arch/m68k/mac/via.c */ +#ifndef CONFIG_MAC out_8(&via[IFR], 0x7f); /* clear interrupts by writing 1s */ out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */ +#endif /* enable autopoll */ cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1); @@ -180,22 +181,24 @@ int __init find_via_cuda(void) static int __init via_cuda_start(void) { + unsigned int irq; + if (via == NULL) return -ENODEV; #ifdef CONFIG_MAC - cuda_irq = IRQ_MAC_ADB; + irq = IRQ_MAC_ADB; #else /* CONFIG_MAC */ - cuda_irq = irq_of_parse_and_map(vias, 0); - if (cuda_irq == NO_IRQ) { + irq = irq_of_parse_and_map(vias, 0); + if (irq == NO_IRQ) { printk(KERN_ERR "via-cuda: can't map interrupts for %s\n", vias->full_name); return -ENODEV; } -#endif /* CONFIG_MAC */ +#endif /* CONFIG_MAP */ - if (request_irq(cuda_irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) { - printk(KERN_ERR "via-cuda: can't request irq %d\n", cuda_irq); + if (request_irq(irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) { + printk(KERN_ERR "via-cuda: can't request irq %d\n", irq); return -EAGAIN; } @@ -235,7 +238,6 @@ cuda_init(void) printk(KERN_ERR "cuda_init_via() failed\n"); return -ENODEV; } - out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */ return via_cuda_start(); #endif @@ -261,17 +263,15 @@ cuda_init_via(void) out_8(&via[B], in_8(&via[B]) | TACK | TIP); /* negate them */ out_8(&via[ACR] ,(in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT); /* SR data in */ (void)in_8(&via[SR]); /* clear any left-over data */ -#ifdef CONFIG_PPC +#ifndef CONFIG_MAC out_8(&via[IER], 0x7f); /* disable interrupts from VIA */ (void)in_8(&via[IER]); -#else - out_8(&via[IER], SR_INT); /* disable SR interrupt from VIA */ #endif /* delay 4ms and then clear any pending interrupt */ mdelay(4); (void)in_8(&via[SR]); - out_8(&via[IFR], SR_INT); + out_8(&via[IFR], in_8(&via[IFR]) & 0x7f); /* sync with the CUDA - assert TACK without TIP */ out_8(&via[B], in_8(&via[B]) & ~TACK); @@ -282,7 +282,7 @@ cuda_init_via(void) /* wait for the interrupt and then clear it */ WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)"); (void)in_8(&via[SR]); - out_8(&via[IFR], SR_INT); + out_8(&via[IFR], in_8(&via[IFR]) & 0x7f); /* finish the sync by negating TACK */ out_8(&via[B], in_8(&via[B]) | TACK); @@ -291,7 +291,7 @@ cuda_init_via(void) WAIT_FOR(in_8(&via[B]) & TREQ, "CUDA response to sync (3)"); WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)"); (void)in_8(&via[SR]); - out_8(&via[IFR], SR_INT); + out_8(&via[IFR], in_8(&via[IFR]) & 0x7f); out_8(&via[B], in_8(&via[B]) | TIP); /* should be unnecessary */ return 0; @@ -428,12 +428,16 @@ cuda_start(void) void cuda_poll(void) { + unsigned long flags; + /* cuda_interrupt only takes a normal lock, we disable * interrupts here to avoid re-entering and thus deadlocking. + * An option would be to disable only the IRQ source with + * disable_irq(), would that work on m68k ? --BenH */ - disable_irq(cuda_irq); + local_irq_save(flags); cuda_interrupt(0, NULL); - enable_irq(cuda_irq); + local_irq_restore(flags); } static irqreturn_t @@ -444,25 +448,15 @@ cuda_interrupt(int irq, void *arg) unsigned char ibuf[16]; int ibuf_len = 0; int complete = 0; + unsigned char virq; spin_lock(&cuda_lock); - /* On powermacs, this handler is registered for the VIA IRQ. But it uses - * just the shift register IRQ -- other VIA interrupt sources are disabled. - * On m68k macs, the VIA IRQ sources are dispatched individually. Unless - * we are polling, the shift register IRQ flag has already been cleared. - */ - -#ifdef CONFIG_MAC - if (!arg) -#endif - { - if ((in_8(&via[IFR]) & SR_INT) == 0) { - spin_unlock(&cuda_lock); - return IRQ_NONE; - } else { - out_8(&via[IFR], SR_INT); - } + virq = in_8(&via[IFR]) & 0x7f; + out_8(&via[IFR], virq); + if ((virq & SR_INT) == 0) { + spin_unlock(&cuda_lock); + return IRQ_NONE; } status = (~in_8(&via[B]) & (TIP|TREQ)) | (in_8(&via[ACR]) & SR_OUT); diff --git a/trunk/drivers/macintosh/via-macii.c b/trunk/drivers/macintosh/via-macii.c index 01b8eca7ccd5..1b3bad62a1be 100644 --- a/trunk/drivers/macintosh/via-macii.c +++ b/trunk/drivers/macintosh/via-macii.c @@ -12,15 +12,6 @@ * 1999-08-02 (jmt) - Initial rewrite for Unified ADB. * 2000-03-29 Tony Mantler * - Big overhaul, should actually work now. - * 2006-12-31 Finn Thain - Another overhaul. - * - * Suggested reading: - * Inside Macintosh, ch. 5 ADB Manager - * Guide to the Macinstosh Family Hardware, ch. 8 Apple Desktop Bus - * Rockwell R6522 VIA datasheet - * - * Apple's "ADB Analyzer" bus sniffer is invaluable: - * ftp://ftp.apple.com/developer/Tool_Chest/Devices_-_Hardware/Apple_Desktop_Bus/ */ #include @@ -35,6 +26,7 @@ #include #include #include +#include #include static volatile unsigned char *via; @@ -59,7 +51,9 @@ static volatile unsigned char *via; #define ANH (15*RS) /* A-side data, no handshake */ /* Bits in B data register: all active low */ -#define CTLR_IRQ 0x08 /* Controller rcv status (input) */ +#define TREQ 0x08 /* Transfer request (input) */ +#define TACK 0x10 /* Transfer acknowledge (output) */ +#define TIP 0x20 /* Transfer in progress (output) */ #define ST_MASK 0x30 /* mask for selecting ADB state bits */ /* Bits in ACR */ @@ -71,6 +65,8 @@ static volatile unsigned char *via; #define IER_SET 0x80 /* set bits in IER */ #define IER_CLR 0 /* clear bits in IER */ #define SR_INT 0x04 /* Shift register full/empty */ +#define SR_DATA 0x08 /* Shift register data */ +#define SR_CLOCK 0x10 /* Shift register clock */ /* ADB transaction states according to GMHW */ #define ST_CMD 0x00 /* ADB state: command byte */ @@ -81,6 +77,7 @@ static volatile unsigned char *via; static int macii_init_via(void); static void macii_start(void); static irqreturn_t macii_interrupt(int irq, void *arg); +static void macii_retransmit(int); static void macii_queue_poll(void); static int macii_probe(void); @@ -106,37 +103,29 @@ static enum macii_state { sending, reading, read_done, + awaiting_reply } macii_state; -static struct adb_request *current_req; /* first request struct in the queue */ -static struct adb_request *last_req; /* last request struct in the queue */ -static unsigned char reply_buf[16]; /* storage for autopolled replies */ -static unsigned char *reply_ptr; /* next byte in req->data or reply_buf */ -static int reading_reply; /* store reply in reply_buf else req->reply */ -static int data_index; /* index of the next byte to send from req->data */ -static int reply_len; /* number of bytes received in reply_buf or req->reply */ -static int status; /* VIA's ADB status bits captured upon interrupt */ -static int last_status; /* status bits as at previous interrupt */ -static int srq_asserted; /* have to poll for the device that asserted it */ -static int command_byte; /* the most recent command byte transmitted */ -static int autopoll_devs; /* bits set are device addresses to be polled */ - -/* Sanity check for request queue. Doesn't check for cycles. */ -static int request_is_queued(struct adb_request *req) { - struct adb_request *cur; - unsigned long flags; - local_irq_save(flags); - cur = current_req; - while (cur) { - if (cur == req) { - local_irq_restore(flags); - return 1; - } - cur = cur->next; - } - local_irq_restore(flags); - return 0; -} +static int need_poll; +static int command_byte; +static int last_reply; +static int last_active; + +static struct adb_request *current_req; +static struct adb_request *last_req; +static struct adb_request *retry_req; +static unsigned char reply_buf[16]; +static unsigned char *reply_ptr; +static int reply_len; +static int reading_reply; +static int data_index; +static int first_byte; +static int prefix_len; +static int status = ST_IDLE|TREQ; +static int last_status; +static int driver_running; + +/* debug level 10 required for ADB logging (should be && debug_adb, ideally) */ /* Check for MacII style ADB */ static int macii_probe(void) @@ -158,16 +147,15 @@ int macii_init(void) local_irq_save(flags); err = macii_init_via(); - if (err) goto out; + if (err) return err; err = request_irq(IRQ_MAC_ADB, macii_interrupt, IRQ_FLG_LOCK, "ADB", macii_interrupt); - if (err) goto out; + if (err) return err; macii_state = idle; -out: local_irq_restore(flags); - return err; + return 0; } /* initialize the hardware */ @@ -175,12 +163,12 @@ static int macii_init_via(void) { unsigned char x; - /* We want CTLR_IRQ as input and ST_EVEN | ST_ODD as output lines. */ - via[DIRB] = (via[DIRB] | ST_EVEN | ST_ODD) & ~CTLR_IRQ; + /* Set the lines up. We want TREQ as input TACK|TIP as output */ + via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ; /* Set up state: idle */ via[B] |= ST_IDLE; - last_status = via[B] & (ST_MASK|CTLR_IRQ); + last_status = via[B] & (ST_MASK|TREQ); /* Shift register on input */ via[ACR] = (via[ACR] & ~SR_CTRL) | SR_EXT; @@ -191,72 +179,81 @@ static int macii_init_via(void) return 0; } -/* Send an ADB poll (Talk Register 0 command prepended to the request queue) */ +/* Send an ADB poll (Talk Register 0 command, tagged on the front of the request queue) */ static void macii_queue_poll(void) { - /* No point polling the active device as it will never assert SRQ, so - * poll the next device in the autopoll list. This could leave us - * stuck in a polling loop if an unprobed device is asserting SRQ. - * In theory, that could only happen if a device was plugged in after - * probing started. Unplugging it again will break the cycle. - * (Simply polling the next higher device often ends up polling almost - * every device (after wrapping around), which takes too long.) - */ - int device_mask; - int next_device; + static int device = 0; + static int in_poll=0; static struct adb_request req; + unsigned long flags; + + if (in_poll) printk("macii_queue_poll: double poll!\n"); - if (!autopoll_devs) return; - - device_mask = (1 << (((command_byte & 0xF0) >> 4) + 1)) - 1; - if (autopoll_devs & ~device_mask) - next_device = ffs(autopoll_devs & ~device_mask) - 1; - else - next_device = ffs(autopoll_devs) - 1; + in_poll++; + if (++device > 15) device = 1; - BUG_ON(request_is_queued(&req)); + adb_request(&req, NULL, ADBREQ_REPLY|ADBREQ_NOSEND, 1, + ADB_READREG(device, 0)); - adb_request(&req, NULL, ADBREQ_NOSEND, 1, - ADB_READREG(next_device, 0)); + local_irq_save(flags); - req.sent = 0; - req.complete = 0; - req.reply_len = 0; req.next = current_req; + current_req = &req; + + local_irq_restore(flags); + macii_start(); + in_poll--; +} + +/* Send an ADB retransmit (Talk, appended to the request queue) */ +static void macii_retransmit(int device) +{ + static int in_retransmit = 0; + static struct adb_request rt; + unsigned long flags; + + if (in_retransmit) printk("macii_retransmit: double retransmit!\n"); + + in_retransmit++; + + adb_request(&rt, NULL, ADBREQ_REPLY|ADBREQ_NOSEND, 1, + ADB_READREG(device, 0)); + + local_irq_save(flags); if (current_req != NULL) { - current_req = &req; + last_req->next = &rt; + last_req = &rt; } else { - current_req = &req; - last_req = &req; + current_req = &rt; + last_req = &rt; } + + if (macii_state == idle) macii_start(); + + local_irq_restore(flags); + in_retransmit--; } /* Send an ADB request; if sync, poll out the reply 'till it's done */ static int macii_send_request(struct adb_request *req, int sync) { - int err; - unsigned long flags; + int i; - BUG_ON(request_is_queued(req)); + i = macii_write(req); + if (i) return i; - local_irq_save(flags); - err = macii_write(req); - local_irq_restore(flags); - - if (!err && sync) { - while (!req->complete) { - macii_poll(); - } - BUG_ON(request_is_queued(req)); + if (sync) { + while (!req->complete) macii_poll(); } - - return err; + return 0; } -/* Send an ADB request (append to request queue) */ +/* Send an ADB request */ static int macii_write(struct adb_request *req) { + unsigned long flags; + if (req->nbytes < 2 || req->data[0] != ADB_PACKET || req->nbytes > 15) { req->complete = 1; return -EINVAL; @@ -267,6 +264,8 @@ static int macii_write(struct adb_request *req) req->complete = 0; req->reply_len = 0; + local_irq_save(flags); + if (current_req != NULL) { last_req->next = req; last_req = req; @@ -275,52 +274,28 @@ static int macii_write(struct adb_request *req) last_req = req; if (macii_state == idle) macii_start(); } + + local_irq_restore(flags); return 0; } /* Start auto-polling */ static int macii_autopoll(int devs) { - static struct adb_request req; - unsigned long flags; - int err = 0; - - /* bit 1 == device 1, and so on. */ - autopoll_devs = devs & 0xFFFE; - - if (!autopoll_devs) return 0; - - local_irq_save(flags); - - if (current_req == NULL) { - /* Send a Talk Reg 0. The controller will repeatedly transmit - * this as long as it is idle. - */ - adb_request(&req, NULL, ADBREQ_NOSEND, 1, - ADB_READREG(ffs(autopoll_devs) - 1, 0)); - err = macii_write(&req); - } - - local_irq_restore(flags); - return err; -} - -static inline int need_autopoll(void) { - /* Was the last command Talk Reg 0 - * and is the target on the autopoll list? - */ - if ((command_byte & 0x0F) == 0x0C && - ((1 << ((command_byte & 0xF0) >> 4)) & autopoll_devs)) - return 0; - return 1; + /* Just ping a random default address */ + if (!(current_req || retry_req)) + macii_retransmit( (last_active < 16 && last_active > 0) ? last_active : 3); + return 0; } /* Prod the chip without interrupts */ static void macii_poll(void) { - disable_irq(IRQ_MAC_ADB); - macii_interrupt(0, NULL); - enable_irq(IRQ_MAC_ADB); + unsigned long flags; + + local_irq_save(flags); + if (via[IFR] & SR_INT) macii_interrupt(0, NULL); + local_irq_restore(flags); } /* Reset the bus */ @@ -328,34 +303,73 @@ static int macii_reset_bus(void) { static struct adb_request req; - if (request_is_queued(&req)) - return 0; - /* Command = 0, Address = ignored */ adb_request(&req, NULL, 0, 1, ADB_BUSRESET); - /* Don't want any more requests during the Global Reset low time. */ - udelay(3000); - return 0; } /* Start sending ADB packet */ static void macii_start(void) { + unsigned long flags; struct adb_request *req; req = current_req; + if (!req) return; + + /* assert macii_state == idle */ + if (macii_state != idle) { + printk("macii_start: called while driver busy (%p %x %x)!\n", + req, macii_state, (uint) via1[B] & (ST_MASK|TREQ)); + return; + } - BUG_ON(req == NULL); - - BUG_ON(macii_state != idle); - - /* Now send it. Be careful though, that first byte of the request - * is actually ADB_PACKET; the real data begins at index 1! - * And req->nbytes is the number of bytes of real data plus one. + local_irq_save(flags); + + /* + * IRQ signaled ?? (means ADB controller wants to send, or might + * be end of packet if we were reading) + */ +#if 0 /* FIXME: This is broke broke broke, for some reason */ + if ((via[B] & TREQ) == 0) { + printk("macii_start: weird poll stuff. huh?\n"); + /* + * FIXME - we need to restart this on a timer + * or a collision at boot hangs us. + * Never set macii_state to idle here, or macii_start + * won't be called again from send_request! + * (need to re-check other cases ...) + */ + /* + * if the interrupt handler set the need_poll + * flag, it's hopefully a SRQ poll or re-Talk + * so we try to send here anyway + */ + if (!need_poll) { + if (console_loglevel == 10) + printk("macii_start: device busy - retry %p state %d status %x!\n", + req, macii_state, + (uint) via[B] & (ST_MASK|TREQ)); + retry_req = req; + /* set ADB status here ? */ + local_irq_restore(flags); + return; + } else { + need_poll = 0; + } + } +#endif + /* + * Another retry pending? (sanity check) */ + if (retry_req) { + retry_req = NULL; + } + /* Now send it. Be careful though, that first byte of the request */ + /* is actually ADB_PACKET; the real data begins at index 1! */ + /* store command byte */ command_byte = req->data[1]; /* Output mode */ @@ -367,97 +381,115 @@ static void macii_start(void) macii_state = sending; data_index = 2; + + local_irq_restore(flags); } /* - * The notorious ADB interrupt handler - does all of the protocol handling. - * Relies on the ADB controller sending and receiving data, thereby - * generating shift register interrupts (SR_INT) for us. This means there has - * to be activity on the ADB bus. The chip will poll to achieve this. + * The notorious ADB interrupt handler - does all of the protocol handling, + * except for starting new send operations. Relies heavily on the ADB + * controller sending and receiving data, thereby generating SR interrupts + * for us. This means there has to be always activity on the ADB bus, otherwise + * the whole process dies and has to be re-kicked by sending TALK requests ... + * CUDA-based Macs seem to solve this with the autopoll option, for MacII-type + * ADB the problem isn't solved yet (retransmit of the latest active TALK seems + * a good choice; either on timeout or on a timer interrupt). * * The basic ADB state machine was left unchanged from the original MacII code * by Alan Cox, which was based on the CUDA driver for PowerMac. - * The syntax of the ADB status lines is totally different on MacII, - * though. MacII uses the states Command -> Even -> Odd -> Even ->...-> Idle - * for sending and Idle -> Even -> Odd -> Even ->...-> Idle for receiving. - * Start and end of a receive packet are signalled by asserting /IRQ on the - * interrupt line (/IRQ means the CTLR_IRQ bit in port B; not to be confused - * with the VIA shift register interrupt. /IRQ never actually interrupts the - * processor, it's just an ordinary input.) + * The syntax of the ADB status lines seems to be totally different on MacII, + * though. MacII uses the states Command -> Even -> Odd -> Even ->...-> Idle for + * sending, and Idle -> Even -> Odd -> Even ->...-> Idle for receiving. Start + * and end of a receive packet are signaled by asserting /IRQ on the interrupt + * line. Timeouts are signaled by a sequence of 4 0xFF, with /IRQ asserted on + * every other byte. SRQ is probably signaled by 3 or more 0xFF tacked on the + * end of a packet. (Thanks to Guido Koerber for eavesdropping on the ADB + * protocol with a logic analyzer!!) + * + * Note: As of 21/10/97, the MacII ADB part works including timeout detection + * and retransmit (Talk to the last active device). */ static irqreturn_t macii_interrupt(int irq, void *arg) { - int x; - static int entered; + int x, adbdir; + unsigned long flags; struct adb_request *req; - if (!arg) { - /* Clear the SR IRQ flag when polling. */ - if (via[IFR] & SR_INT) - via[IFR] = SR_INT; - else - return IRQ_NONE; - } + last_status = status; - BUG_ON(entered++); + /* prevent races due to SCSI enabling ints */ + local_irq_save(flags); - last_status = status; - status = via[B] & (ST_MASK|CTLR_IRQ); + if (driver_running) { + local_irq_restore(flags); + return IRQ_NONE; + } + + driver_running = 1; + + status = via[B] & (ST_MASK|TREQ); + adbdir = via[ACR] & SR_OUT; switch (macii_state) { case idle: - if (reading_reply) { - reply_ptr = current_req->reply; - } else { - BUG_ON(current_req != NULL); - reply_ptr = reply_buf; - } - x = via[SR]; + first_byte = x; + /* set ADB state = even for first data byte */ + via[B] = (via[B] & ~ST_MASK) | ST_EVEN; - if ((status & CTLR_IRQ) && (x == 0xFF)) { - /* Bus timeout without SRQ sequence: - * data is "FF" while CTLR_IRQ is "H" - */ - reply_len = 0; - srq_asserted = 0; - macii_state = read_done; - } else { - macii_state = reading; - *reply_ptr = x; - reply_len = 1; - } + reply_buf[0] = first_byte; /* was command_byte?? */ + reply_ptr = reply_buf + 1; + reply_len = 1; + prefix_len = 1; + reading_reply = 0; + + macii_state = reading; + break; + case awaiting_reply: + /* handshake etc. for II ?? */ + x = via[SR]; + first_byte = x; /* set ADB state = even for first data byte */ via[B] = (via[B] & ~ST_MASK) | ST_EVEN; + + current_req->reply[0] = first_byte; + reply_ptr = current_req->reply + 1; + reply_len = 1; + prefix_len = 1; + reading_reply = 1; + + macii_state = reading; break; case sending: req = current_req; if (data_index >= req->nbytes) { + /* print an error message if a listen command has no data */ + if (((command_byte & 0x0C) == 0x08) + /* && (console_loglevel == 10) */ + && (data_index == 2)) + printk("MacII ADB: listen command with no data: %x!\n", + command_byte); + /* reset to shift in */ + via[ACR] &= ~SR_OUT; + x = via[SR]; + /* set ADB state idle - might get SRQ */ + via[B] = (via[B] & ~ST_MASK) | ST_IDLE; + req->sent = 1; - macii_state = idle; if (req->reply_expected) { - reading_reply = 1; + macii_state = awaiting_reply; } else { req->complete = 1; current_req = req->next; if (req->done) (*req->done)(req); - - if (current_req) + macii_state = idle; + if (current_req || retry_req) macii_start(); else - if (need_autopoll()) - macii_autopoll(autopoll_devs); - } - - if (macii_state == idle) { - /* reset to shift in */ - via[ACR] &= ~SR_OUT; - x = via[SR]; - /* set ADB state idle - might get SRQ */ - via[B] = (via[B] & ~ST_MASK) | ST_IDLE; + macii_retransmit((command_byte & 0xF0) >> 4); } } else { via[SR] = req->data[data_index++]; @@ -473,79 +505,147 @@ static irqreturn_t macii_interrupt(int irq, void *arg) break; case reading: - x = via[SR]; - BUG_ON((status & ST_MASK) == ST_CMD || - (status & ST_MASK) == ST_IDLE); - - /* Bus timeout with SRQ sequence: - * data is "XX FF" while CTLR_IRQ is "L L" - * End of packet without SRQ sequence: - * data is "XX...YY 00" while CTLR_IRQ is "L...H L" - * End of packet SRQ sequence: - * data is "XX...YY 00" while CTLR_IRQ is "L...L L" - * (where XX is the first response byte and - * YY is the last byte of valid response data.) - */ - srq_asserted = 0; - if (!(status & CTLR_IRQ)) { - if (x == 0xFF) { - if (!(last_status & CTLR_IRQ)) { - macii_state = read_done; - reply_len = 0; - srq_asserted = 1; - } - } else if (x == 0x00) { - macii_state = read_done; - if (!(last_status & CTLR_IRQ)) - srq_asserted = 1; - } - } + /* timeout / SRQ handling for II hw */ + if( (first_byte == 0xFF && (reply_len-prefix_len)==2 + && memcmp(reply_ptr-2,"\xFF\xFF",2)==0) || + ((reply_len-prefix_len)==3 + && memcmp(reply_ptr-3,"\xFF\xFF\xFF",3)==0)) + { + /* + * possible timeout (in fact, most probably a + * timeout, since SRQ can't be signaled without + * transfer on the bus). + * The last three bytes seen were FF, together + * with the starting byte (in case we started + * on 'idle' or 'awaiting_reply') this probably + * makes four. So this is mostl likely #5! + * The timeout signal is a pattern 1 0 1 0 0.. + * on /INT, meaning we missed it :-( + */ + x = via[SR]; + if (x != 0xFF) printk("MacII ADB: mistaken timeout/SRQ!\n"); - if (macii_state == reading) { - BUG_ON(reply_len > 15); - reply_ptr++; + if ((status & TREQ) == (last_status & TREQ)) { + /* Not a timeout. Unsolicited SRQ? weird. */ + /* Terminate the SRQ packet and poll */ + need_poll = 1; + } + /* There's no packet to get, so reply is blank */ + via[B] ^= ST_MASK; + reply_ptr -= (reply_len-prefix_len); + reply_len = prefix_len; + macii_state = read_done; + break; + } /* end timeout / SRQ handling for II hw. */ + + if((reply_len-prefix_len)>3 + && memcmp(reply_ptr-3,"\xFF\xFF\xFF",3)==0) + { + /* SRQ tacked on data packet */ + /* Terminate the packet (SRQ never ends) */ + x = via[SR]; + macii_state = read_done; + reply_len -= 3; + reply_ptr -= 3; + need_poll = 1; + /* need to continue; next byte not seen else */ + } else { + /* Sanity check */ + if (reply_len > 15) reply_len = 0; + /* read byte */ + x = via[SR]; *reply_ptr = x; + reply_ptr++; reply_len++; } + /* The usual handshake ... */ + + /* + * NetBSD hints that the next to last byte + * is sent with IRQ !! + * Guido found out it's the last one (0x0), + * but IRQ should be asserted already. + * Problem with timeout detection: First + * transition to /IRQ might be second + * byte of timeout packet! + * Timeouts are signaled by 4x FF. + */ + if (((status & TREQ) == 0) && (x == 0x00)) { /* != 0xFF */ + /* invert state bits, toggle ODD/EVEN */ + via[B] ^= ST_MASK; - /* invert state bits, toggle ODD/EVEN */ - via[B] ^= ST_MASK; + /* adjust packet length */ + reply_len--; + reply_ptr--; + macii_state = read_done; + } else { + /* not caught: ST_CMD */ + /* required for re-entry 'reading'! */ + if ((status & ST_MASK) == ST_IDLE) { + /* (in)sanity check - set even */ + via[B] = (via[B] & ~ST_MASK) | ST_EVEN; + } else { + /* invert state bits */ + via[B] ^= ST_MASK; + } + } break; case read_done: x = via[SR]; - if (reading_reply) { - reading_reply = 0; req = current_req; - req->reply_len = reply_len; + req->reply_len = reply_ptr - req->reply; req->complete = 1; current_req = req->next; if (req->done) (*req->done)(req); - } else if (reply_len && autopoll_devs) - adb_input(reply_buf, reply_len, 0); + } else { + adb_input(reply_buf, reply_ptr - reply_buf, 0); + } - macii_state = idle; + /* + * remember this device ID; it's the latest we got a + * reply from! + */ + last_reply = command_byte; + last_active = (command_byte & 0xF0) >> 4; /* SRQ seen before, initiate poll now */ - if (srq_asserted) + if (need_poll) { + macii_state = idle; macii_queue_poll(); + need_poll = 0; + break; + } + + /* set ADB state to idle */ + via[B] = (via[B] & ~ST_MASK) | ST_IDLE; + + /* /IRQ seen, so the ADB controller has data for us */ + if ((via[B] & TREQ) != 0) { + macii_state = reading; - if (current_req) - macii_start(); - else - if (need_autopoll()) - macii_autopoll(autopoll_devs); - - if (macii_state == idle) - via[B] = (via[B] & ~ST_MASK) | ST_IDLE; + reply_buf[0] = command_byte; + reply_ptr = reply_buf + 1; + reply_len = 1; + prefix_len = 1; + reading_reply = 0; + } else { + /* no IRQ, send next packet or wait */ + macii_state = idle; + if (current_req) + macii_start(); + else + macii_retransmit(last_active); + } break; default: break; } - - entered--; + /* reset mutex and interrupts */ + driver_running = 0; + local_irq_restore(flags); return IRQ_HANDLED; } diff --git a/trunk/drivers/macintosh/via-pmu-led.c b/trunk/drivers/macintosh/via-pmu-led.c index 55ad95671387..fc89a7047cd0 100644 --- a/trunk/drivers/macintosh/via-pmu-led.c +++ b/trunk/drivers/macintosh/via-pmu-led.c @@ -31,6 +31,7 @@ static spinlock_t pmu_blink_lock; static struct adb_request pmu_blink_req; /* -1: no change, 0: request off, 1: request on */ static int requested_change; +static int sleeping; static void pmu_req_done(struct adb_request * req) { @@ -40,7 +41,7 @@ static void pmu_req_done(struct adb_request * req) /* if someone requested a change in the meantime * (we only see the last one which is fine) * then apply it now */ - if (requested_change != -1 && !pmu_sys_suspended) + if (requested_change != -1 && !sleeping) pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change); /* reset requested change */ requested_change = -1; @@ -65,7 +66,7 @@ static void pmu_led_set(struct led_classdev *led_cdev, break; } /* if request isn't done, then don't do anything */ - if (pmu_blink_req.complete && !pmu_sys_suspended) + if (pmu_blink_req.complete && !sleeping) pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change); out: spin_unlock_irqrestore(&pmu_blink_lock, flags); @@ -79,6 +80,32 @@ static struct led_classdev pmu_led = { .brightness_set = pmu_led_set, }; +#ifdef CONFIG_PM +static void pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when) +{ + unsigned long flags; + + spin_lock_irqsave(&pmu_blink_lock, flags); + + switch (when) { + case PBOOK_SLEEP_REQUEST: + sleeping = 1; + break; + case PBOOK_WAKE: + sleeping = 0; + break; + default: + /* do nothing */ + break; + } + spin_unlock_irqrestore(&pmu_blink_lock, flags); +} + +static struct pmu_sleep_notifier via_pmu_led_sleep_notif = { + .notifier_call = pmu_led_sleep_call, +}; +#endif + static int __init via_pmu_led_init(void) { struct device_node *dt; @@ -108,7 +135,9 @@ static int __init via_pmu_led_init(void) /* no outstanding req */ pmu_blink_req.complete = 1; pmu_blink_req.done = pmu_req_done; - +#ifdef CONFIG_PM + pmu_register_sleep_notifier(&via_pmu_led_sleep_notif); +#endif return led_classdev_register(NULL, &pmu_led); } diff --git a/trunk/drivers/macintosh/via-pmu.c b/trunk/drivers/macintosh/via-pmu.c index 157080b3b468..1729d3fd7a11 100644 --- a/trunk/drivers/macintosh/via-pmu.c +++ b/trunk/drivers/macintosh/via-pmu.c @@ -310,14 +310,14 @@ int __init find_via_pmu(void) PMU_INT_TICK; if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0) - || of_device_is_compatible(vias->parent, "ohare"))) + || device_is_compatible(vias->parent, "ohare"))) pmu_kind = PMU_OHARE_BASED; - else if (of_device_is_compatible(vias->parent, "paddington")) + else if (device_is_compatible(vias->parent, "paddington")) pmu_kind = PMU_PADDINGTON_BASED; - else if (of_device_is_compatible(vias->parent, "heathrow")) + else if (device_is_compatible(vias->parent, "heathrow")) pmu_kind = PMU_HEATHROW_BASED; - else if (of_device_is_compatible(vias->parent, "Keylargo") - || of_device_is_compatible(vias->parent, "K2-Keylargo")) { + else if (device_is_compatible(vias->parent, "Keylargo") + || device_is_compatible(vias->parent, "K2-Keylargo")) { struct device_node *gpiop; struct device_node *adbp; u64 gaddr = OF_BAD_ADDR; @@ -2759,7 +2759,7 @@ pmu_polled_request(struct adb_request *req) #if defined(CONFIG_PM) && defined(CONFIG_PPC32) -int pmu_sys_suspended; +static int pmu_sys_suspended; static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state) { diff --git a/trunk/drivers/macintosh/via-pmu68k.c b/trunk/drivers/macintosh/via-pmu68k.c index dfdf11c1eec4..356c7216a179 100644 --- a/trunk/drivers/macintosh/via-pmu68k.c +++ b/trunk/drivers/macintosh/via-pmu68k.c @@ -111,6 +111,7 @@ static int pmu_send_request(struct adb_request *req, int sync); static int pmu_autopoll(int devs); void pmu_poll(void); static int pmu_reset_bus(void); +static int pmu_queue_request(struct adb_request *req); static void pmu_start(void); static void send_byte(int x); @@ -474,7 +475,7 @@ pmu_request(struct adb_request *req, void (*done)(struct adb_request *), return pmu_queue_request(req); } -int +static int pmu_queue_request(struct adb_request *req) { unsigned long flags; diff --git a/trunk/drivers/macintosh/windfarm_core.c b/trunk/drivers/macintosh/windfarm_core.c index 192b26e97777..94c117ef20c1 100644 --- a/trunk/drivers/macintosh/windfarm_core.c +++ b/trunk/drivers/macintosh/windfarm_core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/macintosh/windfarm_lm75_sensor.c b/trunk/drivers/macintosh/windfarm_lm75_sensor.c index a0fabf3c2008..ab4d1b63f63e 100644 --- a/trunk/drivers/macintosh/windfarm_lm75_sensor.c +++ b/trunk/drivers/macintosh/windfarm_lm75_sensor.c @@ -188,10 +188,10 @@ static int wf_lm75_attach(struct i2c_adapter *adapter) if (loc == NULL || addr == 0) continue; /* real lm75 */ - if (of_device_is_compatible(dev, "lm75")) + if (device_is_compatible(dev, "lm75")) wf_lm75_create(adapter, addr, 0, loc); /* ds1775 (compatible, better resolution */ - else if (of_device_is_compatible(dev, "ds1775")) + else if (device_is_compatible(dev, "ds1775")) wf_lm75_create(adapter, addr, 1, loc); } return 0; diff --git a/trunk/drivers/macintosh/windfarm_max6690_sensor.c b/trunk/drivers/macintosh/windfarm_max6690_sensor.c index 5f03aab9fb5d..eaa74afa175b 100644 --- a/trunk/drivers/macintosh/windfarm_max6690_sensor.c +++ b/trunk/drivers/macintosh/windfarm_max6690_sensor.c @@ -131,7 +131,7 @@ static int wf_max6690_attach(struct i2c_adapter *adapter) */ if (!pmac_i2c_match_adapter(dev, adapter)) continue; - if (!of_device_is_compatible(dev, "max6690")) + if (!device_is_compatible(dev, "max6690")) continue; addr = pmac_i2c_get_dev_addr(dev); loc = of_get_property(dev, "hwsensor-location", NULL); diff --git a/trunk/drivers/macintosh/windfarm_smu_controls.c b/trunk/drivers/macintosh/windfarm_smu_controls.c index 58c2590f05ec..ff398adc0283 100644 --- a/trunk/drivers/macintosh/windfarm_smu_controls.c +++ b/trunk/drivers/macintosh/windfarm_smu_controls.c @@ -263,7 +263,7 @@ static int __init smu_controls_init(void) /* Look for RPM fans */ for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) if (!strcmp(fans->name, "rpm-fans") || - of_device_is_compatible(fans, "smu-rpm-fans")) + device_is_compatible(fans, "smu-rpm-fans")) break; for (fan = NULL; fans && (fan = of_get_next_child(fans, fan)) != NULL;) { diff --git a/trunk/drivers/macintosh/windfarm_smu_sat.c b/trunk/drivers/macintosh/windfarm_smu_sat.c index 1043b39aa123..9a6c2cf8fd0e 100644 --- a/trunk/drivers/macintosh/windfarm_smu_sat.c +++ b/trunk/drivers/macintosh/windfarm_smu_sat.c @@ -380,7 +380,7 @@ static int wf_sat_attach(struct i2c_adapter *adapter) busnode = pmac_i2c_get_bus_node(bus); while ((dev = of_get_next_child(busnode, dev)) != NULL) - if (of_device_is_compatible(dev, "smu-sat")) + if (device_is_compatible(dev, "smu-sat")) wf_sat_create(adapter, dev); return 0; } diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 5a4a74c1097c..e61e0efe9ec7 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -1456,10 +1456,10 @@ int bitmap_create(mddev_t *mddev) bitmap->offset = mddev->bitmap_offset; if (file) { get_file(file); - do_sync_mapping_range(file->f_mapping, 0, LLONG_MAX, - SYNC_FILE_RANGE_WAIT_BEFORE | - SYNC_FILE_RANGE_WRITE | - SYNC_FILE_RANGE_WAIT_AFTER); + do_sync_file_range(file, 0, LLONG_MAX, + SYNC_FILE_RANGE_WAIT_BEFORE | + SYNC_FILE_RANGE_WRITE | + SYNC_FILE_RANGE_WAIT_AFTER); } /* read superblock from bitmap file (this sets bitmap->chunksize) */ err = bitmap_read_sb(bitmap); diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 2b4315d7e5d6..509171ca7fa8 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -3080,7 +3080,7 @@ static int do_md_run(mddev_t * mddev) if (test_bit(Faulty, &rdev->flags)) continue; sync_blockdev(rdev->bdev); - invalidate_bdev(rdev->bdev); + invalidate_bdev(rdev->bdev, 0); } md_probe(mddev->unit, NULL, NULL); diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-i2c.c b/trunk/drivers/media/dvb/b2c2/flexcop-i2c.c index 02a0ea6e1c17..5347a406fff7 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -183,8 +183,7 @@ int flexcop_i2c_init(struct flexcop_device *fc) mutex_init(&fc->i2c_mutex); memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter)); - strncpy(fc->i2c_adap.name, "B2C2 FlexCop device", - sizeof(fc->i2c_adap.name)); + strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE); i2c_set_adapdata(&fc->i2c_adap,fc); diff --git a/trunk/drivers/media/dvb/bt8xx/dst_common.h b/trunk/drivers/media/dvb/bt8xx/dst_common.h index 87623d203a89..3bf084f2e522 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst_common.h +++ b/trunk/drivers/media/dvb/bt8xx/dst_common.h @@ -22,6 +22,7 @@ #ifndef DST_COMMON_H #define DST_COMMON_H +#include #include #include #include diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index 34d7abc900d7..a6cbbdd262d6 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -26,11 +26,11 @@ #include #include #include +#include #include #include #include #include -#include #include "dmxdev.h" #include "dvb_demux.h" diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 088b6dee3a7f..70df31b0a8a9 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c @@ -19,7 +19,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d) return -EINVAL; } - strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); + strncpy(d->i2c_adap.name,d->desc->name,I2C_NAME_SIZE); #ifdef I2C_ADAP_CLASS_TV_DIGITAL d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, #else diff --git a/trunk/drivers/media/dvb/frontends/dibx000_common.c b/trunk/drivers/media/dvb/frontends/dibx000_common.c index 315e09e95b0c..a18c8f45a2ee 100644 --- a/trunk/drivers/media/dvb/frontends/dibx000_common.c +++ b/trunk/drivers/media/dvb/frontends/dibx000_common.c @@ -105,9 +105,9 @@ struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enu } EXPORT_SYMBOL(dibx000_get_i2c_adapter); -static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst) +static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char name[I2C_NAME_SIZE], struct dibx000_i2c_master *mst) { - strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); + strncpy(i2c_adap->name, name, I2C_NAME_SIZE); i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo; i2c_adap->algo_data = NULL; diff --git a/trunk/drivers/media/dvb/ttpci/av7110_av.c b/trunk/drivers/media/dvb/ttpci/av7110_av.c index 58678c05aa53..654c9e919e04 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_av.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_av.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "av7110.h" diff --git a/trunk/drivers/media/dvb/ttpci/av7110_ca.c b/trunk/drivers/media/dvb/ttpci/av7110_ca.c index e1c1294bb767..e9b4e88e7932 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_ca.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_ca.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "av7110.h" #include "av7110_hw.h" diff --git a/trunk/drivers/media/dvb/ttpci/av7110_hw.c b/trunk/drivers/media/dvb/ttpci/av7110_hw.c index 70aee4eb5da4..4d7150e15d1e 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_hw.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_hw.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "av7110.h" diff --git a/trunk/drivers/media/dvb/ttpci/av7110_v4l.c b/trunk/drivers/media/dvb/ttpci/av7110_v4l.c index fcd9994058d0..cde5d3ae7ec7 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_v4l.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "av7110.h" #include "av7110_hw.h" diff --git a/trunk/drivers/media/radio/dsbr100.c b/trunk/drivers/media/radio/dsbr100.c index 449df1bb00d3..df8d0520d1d1 100644 --- a/trunk/drivers/media/radio/dsbr100.c +++ b/trunk/drivers/media/radio/dsbr100.c @@ -79,6 +79,7 @@ #include #include #include +#include /* * Version Information diff --git a/trunk/drivers/media/video/adv7170.c b/trunk/drivers/media/video/adv7170.c index 823cd6cc471e..2aa9ce920607 100644 --- a/trunk/drivers/media/video/adv7170.c +++ b/trunk/drivers/media/video/adv7170.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/adv7175.c b/trunk/drivers/media/video/adv7175.c index 05c7820fe53e..a3246a283aa4 100644 --- a/trunk/drivers/media/video/adv7175.c +++ b/trunk/drivers/media/video/adv7175.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/bt819.c b/trunk/drivers/media/video/bt819.c index 59a43603b5cb..68673863d5c9 100644 --- a/trunk/drivers/media/video/bt819.c +++ b/trunk/drivers/media/video/bt819.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/bt856.c b/trunk/drivers/media/video/bt856.c index 853b1a3d6a1d..42e2299dcb22 100644 --- a/trunk/drivers/media/video/bt856.c +++ b/trunk/drivers/media/video/bt856.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/bt866.c b/trunk/drivers/media/video/bt866.c index 2e4cf1efdd21..772fd52d551a 100644 --- a/trunk/drivers/media/video/bt866.c +++ b/trunk/drivers/media/video/bt866.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/cpia.h b/trunk/drivers/media/video/cpia.h index 78392fb6f94e..6eaa692021c5 100644 --- a/trunk/drivers/media/video/cpia.h +++ b/trunk/drivers/media/video/cpia.h @@ -47,6 +47,7 @@ #include #include #include +#include #include struct cpia_camera_ops diff --git a/trunk/drivers/media/video/cpia_pp.c b/trunk/drivers/media/video/cpia_pp.c index c431df8248d6..19711aaf9a3e 100644 --- a/trunk/drivers/media/video/cpia_pp.c +++ b/trunk/drivers/media/video/cpia_pp.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/media/video/cx2341x.c b/trunk/drivers/media/video/cx2341x.c index d73c86aeeaac..88dbdddeec42 100644 --- a/trunk/drivers/media/video/cx2341x.c +++ b/trunk/drivers/media/video/cx2341x.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/media/video/cx88/cx88-alsa.c b/trunk/drivers/media/video/cx88/cx88-alsa.c index 2d666b56020c..3956c257556c 100644 --- a/trunk/drivers/media/video/cx88/cx88-alsa.c +++ b/trunk/drivers/media/video/cx88/cx88-alsa.c @@ -27,8 +27,6 @@ #include #include #include -#include - #include #include #include diff --git a/trunk/drivers/media/video/cx88/cx88-mpeg.c b/trunk/drivers/media/video/cx88/cx88-mpeg.c index 2ebde2fdbcbe..b2eb32e01aee 100644 --- a/trunk/drivers/media/video/cx88/cx88-mpeg.c +++ b/trunk/drivers/media/video/cx88/cx88-mpeg.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/media/video/cx88/cx88-tvaudio.c b/trunk/drivers/media/video/cx88/cx88-tvaudio.c index 259ea08e784f..97ef421dd093 100644 --- a/trunk/drivers/media/video/cx88/cx88-tvaudio.c +++ b/trunk/drivers/media/video/cx88/cx88-tvaudio.c @@ -43,12 +43,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index b94ef8ab28c1..fbce1d50578b 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -1,3 +1,4 @@ + /* * * device driver for Conexant 2388x based TV cards @@ -33,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/dabusb.c b/trunk/drivers/media/video/dabusb.c index a5731f90be0f..ff4b238090ac 100644 --- a/trunk/drivers/media/video/dabusb.c +++ b/trunk/drivers/media/video/dabusb.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "dabusb.h" diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index 418ea8b7f85a..ed882ebc7b95 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/ov511.h b/trunk/drivers/media/video/ov511.h index 18c64222dd11..68b082bcee1d 100644 --- a/trunk/drivers/media/video/ov511.h +++ b/trunk/drivers/media/video/ov511.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h b/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h index 50c7763d44b3..1231335a9f4a 100644 --- a/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h +++ b/trunk/drivers/media/video/ovcamchip/ovcamchip_priv.h @@ -15,7 +15,6 @@ #ifndef __LINUX_OVCAMCHIP_PRIV_H #define __LINUX_OVCAMCHIP_PRIV_H -#include #include #ifdef DEBUG diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c index 9ea41c6699bb..e976c484c058 100644 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/media/video/saa7111.c b/trunk/drivers/media/video/saa7111.c index 74839f98b7c4..44dc7479119c 100644 --- a/trunk/drivers/media/video/saa7111.c +++ b/trunk/drivers/media/video/saa7111.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/saa7114.c b/trunk/drivers/media/video/saa7114.c index 87c3144ec7fc..2ce3321ab995 100644 --- a/trunk/drivers/media/video/saa7114.c +++ b/trunk/drivers/media/video/saa7114.c @@ -39,6 +39,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/saa711x.c b/trunk/drivers/media/video/saa711x.c index 80bf91187856..269d7114a93a 100644 --- a/trunk/drivers/media/video/saa711x.c +++ b/trunk/drivers/media/video/saa711x.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/saa7134/saa7134-tvaudio.c b/trunk/drivers/media/video/saa7134/saa7134-tvaudio.c index 7b56041186dc..dd759d6d8d25 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/trunk/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "saa7134-reg.h" diff --git a/trunk/drivers/media/video/saa7185.c b/trunk/drivers/media/video/saa7185.c index 339592e7722d..e0fdb1ab7580 100644 --- a/trunk/drivers/media/video/saa7185.c +++ b/trunk/drivers/media/video/saa7185.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/se401.h b/trunk/drivers/media/video/se401.h index 835ef872e803..c0891b3e0018 100644 --- a/trunk/drivers/media/video/se401.h +++ b/trunk/drivers/media/video/se401.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #define se401_DEBUG /* Turn on debug messages */ diff --git a/trunk/drivers/media/video/tvaudio.c b/trunk/drivers/media/video/tvaudio.c index c9bf9dbc2ea3..a2da5d2affff 100644 --- a/trunk/drivers/media/video/tvaudio.c +++ b/trunk/drivers/media/video/tvaudio.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/media/video/usbvideo/usbvideo.c b/trunk/drivers/media/video/usbvideo/usbvideo.c index 37ce36b9e587..687f026753b2 100644 --- a/trunk/drivers/media/video/usbvideo/usbvideo.c +++ b/trunk/drivers/media/video/usbvideo/usbvideo.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/usbvision/usbvision-cards.c b/trunk/drivers/media/video/usbvision/usbvision-cards.c index 51ab265d566a..13f69fe6360d 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-cards.c +++ b/trunk/drivers/media/video/usbvision/usbvision-cards.c @@ -24,6 +24,7 @@ #include +#include #include #include #include "usbvision.h" diff --git a/trunk/drivers/media/video/usbvision/usbvision-core.c b/trunk/drivers/media/video/usbvision/usbvision-core.c index 9118a6227ea6..bcb551adb7e6 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-core.c +++ b/trunk/drivers/media/video/usbvision/usbvision-core.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/usbvision/usbvision-video.c b/trunk/drivers/media/video/usbvision/usbvision-video.c index aa3258bbb4af..216704170a4c 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-video.c +++ b/trunk/drivers/media/video/usbvision/usbvision-video.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/v4l1-compat.c b/trunk/drivers/media/video/v4l1-compat.c index a861e150865e..d2c1ae0dbfba 100644 --- a/trunk/drivers/media/video/v4l1-compat.c +++ b/trunk/drivers/media/video/v4l1-compat.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c index 13ee550d3215..49f1df74aa21 100644 --- a/trunk/drivers/media/video/v4l2-common.c +++ b/trunk/drivers/media/video/v4l2-common.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/videodev.c b/trunk/drivers/media/video/videodev.c index 5263b50463e1..80ac5f86d9e5 100644 --- a/trunk/drivers/media/video/videodev.c +++ b/trunk/drivers/media/video/videodev.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/zoran_driver.c b/trunk/drivers/media/video/zoran_driver.c index cf0ed6cbb0e3..074323733352 100644 --- a/trunk/drivers/media/video/zoran_driver.c +++ b/trunk/drivers/media/video/zoran_driver.c @@ -2034,7 +2034,7 @@ zoran_do_ioctl (struct inode *inode, * but moving the free code outside the munmap() handler fixes * all this... If someone knows why, please explain me (Ronald) */ - if (mutex_trylock(&zr->resource_lock)) { + if (!!mutex_trylock(&zr->resource_lock)) { /* we obtained it! Let's try to free some things */ if (fh->jpg_buffers.ready_to_be_freed) jpg_fbuffer_free(file); diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c index 97471af4309c..083acfd91d8b 100644 --- a/trunk/drivers/message/fusion/mptbase.c +++ b/trunk/drivers/message/fusion/mptbase.c @@ -1531,7 +1531,6 @@ mpt_resume(struct pci_dev *pdev) MPT_ADAPTER *ioc = pci_get_drvdata(pdev); u32 device_state = pdev->current_state; int recovery_state; - int err; printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", @@ -1539,9 +1538,7 @@ mpt_resume(struct pci_dev *pdev) pci_set_power_state(pdev, 0); pci_restore_state(pdev); - err = pci_enable_device(pdev); - if (err) - return err; + pci_enable_device(pdev); /* enable interrupts */ CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); @@ -4742,8 +4739,12 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) } /** - * mpt_inactive_raid_list_free - This clears this link list. - * @ioc : pointer to per adapter structure + * mpt_inactive_raid_list_free + * + * This clears this link list. + * + * @ioc - pointer to per adapter structure + * **/ static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) @@ -4763,11 +4764,15 @@ mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) } /** - * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume + * mpt_inactive_raid_volumes + * + * This sets up link list of phy_disk_nums for devices belonging in an inactive volume + * + * @ioc - pointer to per adapter structure + * @channel - volume channel + * @id - volume target id + * * - * @ioc : pointer to per adapter structure - * @channel : volume channel - * @id : volume target id **/ static void mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) @@ -6658,7 +6663,7 @@ union loginfo_type { /** * mpt_iocstatus_info_config - IOCSTATUS information for config pages * @ioc: Pointer to MPT_ADAPTER structure - * @ioc_status: U32 IOCStatus word from IOC + * ioc_status: U32 IOCStatus word from IOC * @mf: Pointer to MPT request frame * * Refer to lsi/mpi.h. diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h index d25d3be8fcd2..e3a39272aad6 100644 --- a/trunk/drivers/message/fusion/mptbase.h +++ b/trunk/drivers/message/fusion/mptbase.h @@ -994,7 +994,6 @@ typedef struct _MPT_SCSI_HOST { int scandv_wait_done; long last_queue_full; u16 tm_iocstatus; - u16 spi_pending; struct list_head target_reset_list; } MPT_SCSI_HOST; diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c index fa0f7761652a..2a3e9e66d4ef 100644 --- a/trunk/drivers/message/fusion/mptscsih.c +++ b/trunk/drivers/message/fusion/mptscsih.c @@ -819,7 +819,10 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) sc->resid=0; case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ - sc->result = (DID_OK << 16) | scsi_status; + if (scsi_status == MPI_SCSI_STATUS_BUSY) + sc->result = (DID_BUS_BUSY << 16) | scsi_status; + else + sc->result = (DID_OK << 16) | scsi_status; if (scsi_state == 0) { ; } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { @@ -1185,7 +1188,20 @@ mptscsih_suspend(struct pci_dev *pdev, pm_message_t state) int mptscsih_resume(struct pci_dev *pdev) { - return mpt_resume(pdev); + MPT_ADAPTER *ioc = pci_get_drvdata(pdev); + struct Scsi_Host *host = ioc->sh; + MPT_SCSI_HOST *hd; + + mpt_resume(pdev); + + if(!host) + return 0; + + hd = (MPT_SCSI_HOST *)host->hostdata; + if(!hd) + return 0; + + return 0; } #endif @@ -1521,23 +1537,21 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptscsih_TMHandler - Generic handler for SCSI Task Management. - * @hd: Pointer to MPT SCSI HOST structure + * Fall through to mpt_HardResetHandler if: not operational, too many + * failed TM requests or handshake failure. + * + * @ioc: Pointer to MPT_ADAPTER structure * @type: Task Management type - * @channel: channel number for task management * @id: Logical Target ID for reset (if appropriate) * @lun: Logical Unit for reset (if appropriate) * @ctx2abort: Context for the task to be aborted (if appropriate) - * @timeout: timeout for task management control - * - * Fall through to mpt_HardResetHandler if: not operational, too many - * failed TM requests or handshake failure. * * Remark: Currently invoked from a non-interrupt thread (_bh). * * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC * will be active. * - * Returns 0 for SUCCESS, or %FAILED. + * Returns 0 for SUCCESS, or FAILED. **/ int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout) @@ -1636,11 +1650,9 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c * mptscsih_IssueTaskMgmt - Generic send Task Management function. * @hd: Pointer to MPT_SCSI_HOST structure * @type: Task Management type - * @channel: channel number for task management * @id: Logical Target ID for reset (if appropriate) * @lun: Logical Unit for reset (if appropriate) * @ctx2abort: Context for the task to be aborted (if appropriate) - * @timeout: timeout for task management control * * Remark: _HardResetHandler can be invoked from an interrupt thread (timer) * or a non-interrupt thread. In the former, must not call schedule(). @@ -2010,7 +2022,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) /** * mptscsih_tm_wait_for_completion - wait for completion of TM task * @hd: Pointer to MPT host structure. - * @timeout: timeout value * * Returns {SUCCESS,FAILED}. */ diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c index d75f7ffbb02e..85f21b54cb7d 100644 --- a/trunk/drivers/message/fusion/mptspi.c +++ b/trunk/drivers/message/fusion/mptspi.c @@ -96,13 +96,14 @@ static int mptspiTaskCtx = -1; static int mptspiInternalCtx = -1; /* Used only for internal commands */ /** - * mptspi_setTargetNegoParms - Update the target negotiation parameters + * mptspi_setTargetNegoParms - Update the target negotiation + * parameters based on the the Inquiry data, adapter capabilities, + * and NVRAM settings + * * @hd: Pointer to a SCSI Host Structure - * @target: per target private data + * @vtarget: per target private data * @sdev: SCSI device * - * Update the target negotiation parameters based on the the Inquiry - * data, adapter capabilities, and NVRAM settings. **/ static void mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, @@ -233,7 +234,7 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, /** * mptspi_writeIOCPage4 - write IOC Page 4 * @hd: Pointer to a SCSI Host Structure - * @channel: channel number + * @channel: * @id: write IOC Page4 for this ID & Bus * * Return: -EAGAIN if unable to obtain a Message Frame @@ -445,7 +446,7 @@ static int mptspi_target_alloc(struct scsi_target *starget) return 0; } -static void +void mptspi_target_destroy(struct scsi_target *starget) { if (starget->hostdata) @@ -676,9 +677,7 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd, return; } - hd->spi_pending |= (1 << sdev->id); spi_dv_device(sdev); - hd->spi_pending &= ~(1 << sdev->id); if (sdev->channel == 1 && mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0) @@ -1204,27 +1203,11 @@ mptspi_dv_renegotiate_work(struct work_struct *work) container_of(work, struct work_queue_wrapper, work); struct _MPT_SCSI_HOST *hd = wqw->hd; struct scsi_device *sdev; - struct scsi_target *starget; - struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1; - u32 nego; kfree(wqw); - if (hd->spi_pending) { - shost_for_each_device(sdev, hd->ioc->sh) { - if (hd->spi_pending & (1 << sdev->id)) - continue; - starget = scsi_target(sdev); - nego = mptspi_getRP(starget); - pg1.RequestedParameters = cpu_to_le32(nego); - pg1.Reserved = 0; - pg1.Configuration = 0; - mptspi_write_spi_device_pg1(starget, &pg1); - } - } else { - shost_for_each_device(sdev, hd->ioc->sh) - mptspi_dv_device(hd, sdev); - } + shost_for_each_device(sdev, hd->ioc->sh) + mptspi_dv_device(hd, sdev); } static void @@ -1470,7 +1453,6 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) init_waitqueue_head(&hd->scandv_waitq); hd->scandv_wait_done = 0; hd->last_queue_full = 0; - hd->spi_pending = 0; /* Some versions of the firmware don't support page 0; without * that we can't get the parameters */ diff --git a/trunk/drivers/message/i2o/i2o_lan.h b/trunk/drivers/message/i2o/i2o_lan.h new file mode 100644 index 000000000000..6502b817df58 --- /dev/null +++ b/trunk/drivers/message/i2o/i2o_lan.h @@ -0,0 +1,159 @@ +/* + * i2o_lan.h I2O LAN Class definitions + * + * I2O LAN CLASS OSM May 26th 2000 + * + * (C) Copyright 1999, 2000 University of Helsinki, + * Department of Computer Science + * + * This code is still under development / test. + * + * Author: Auvo Häkkinen + * Juha Sievänen + * Taneli Vähäkangas + */ + +#ifndef _I2O_LAN_H +#define _I2O_LAN_H + +/* Default values for tunable parameters first */ + +#define I2O_LAN_MAX_BUCKETS_OUT 96 +#define I2O_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */ +#define I2O_LAN_RX_COPYBREAK 200 +#define I2O_LAN_TX_TIMEOUT (1*HZ) +#define I2O_LAN_TX_BATCH_MODE 2 /* 2=automatic, 1=on, 0=off */ +#define I2O_LAN_EVENT_MASK 0 /* 0=None, 0xFFC00002=All */ + +/* LAN types */ +#define I2O_LAN_ETHERNET 0x0030 +#define I2O_LAN_100VG 0x0040 +#define I2O_LAN_TR 0x0050 +#define I2O_LAN_FDDI 0x0060 +#define I2O_LAN_FIBRE_CHANNEL 0x0070 +#define I2O_LAN_UNKNOWN 0x00000000 + +/* Connector types */ + +/* Ethernet */ +#define I2O_LAN_AUI (I2O_LAN_ETHERNET << 4) + 0x00000001 +#define I2O_LAN_10BASE5 (I2O_LAN_ETHERNET << 4) + 0x00000002 +#define I2O_LAN_FIORL (I2O_LAN_ETHERNET << 4) + 0x00000003 +#define I2O_LAN_10BASE2 (I2O_LAN_ETHERNET << 4) + 0x00000004 +#define I2O_LAN_10BROAD36 (I2O_LAN_ETHERNET << 4) + 0x00000005 +#define I2O_LAN_10BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000006 +#define I2O_LAN_10BASE_FP (I2O_LAN_ETHERNET << 4) + 0x00000007 +#define I2O_LAN_10BASE_FB (I2O_LAN_ETHERNET << 4) + 0x00000008 +#define I2O_LAN_10BASE_FL (I2O_LAN_ETHERNET << 4) + 0x00000009 +#define I2O_LAN_100BASE_TX (I2O_LAN_ETHERNET << 4) + 0x0000000A +#define I2O_LAN_100BASE_FX (I2O_LAN_ETHERNET << 4) + 0x0000000B +#define I2O_LAN_100BASE_T4 (I2O_LAN_ETHERNET << 4) + 0x0000000C +#define I2O_LAN_1000BASE_SX (I2O_LAN_ETHERNET << 4) + 0x0000000D +#define I2O_LAN_1000BASE_LX (I2O_LAN_ETHERNET << 4) + 0x0000000E +#define I2O_LAN_1000BASE_CX (I2O_LAN_ETHERNET << 4) + 0x0000000F +#define I2O_LAN_1000BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000010 + +/* AnyLAN */ +#define I2O_LAN_100VG_ETHERNET (I2O_LAN_100VG << 4) + 0x00000001 +#define I2O_LAN_100VG_TR (I2O_LAN_100VG << 4) + 0x00000002 + +/* Token Ring */ +#define I2O_LAN_4MBIT (I2O_LAN_TR << 4) + 0x00000001 +#define I2O_LAN_16MBIT (I2O_LAN_TR << 4) + 0x00000002 + +/* FDDI */ +#define I2O_LAN_125MBAUD (I2O_LAN_FDDI << 4) + 0x00000001 + +/* Fibre Channel */ +#define I2O_LAN_POINT_POINT (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000001 +#define I2O_LAN_ARB_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000002 +#define I2O_LAN_PUBLIC_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000003 +#define I2O_LAN_FABRIC (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000004 + +#define I2O_LAN_EMULATION 0x00000F00 +#define I2O_LAN_OTHER 0x00000F01 +#define I2O_LAN_DEFAULT 0xFFFFFFFF + +/* LAN class functions */ + +#define LAN_PACKET_SEND 0x3B +#define LAN_SDU_SEND 0x3D +#define LAN_RECEIVE_POST 0x3E +#define LAN_RESET 0x35 +#define LAN_SUSPEND 0x37 + +/* LAN DetailedStatusCode defines */ +#define I2O_LAN_DSC_SUCCESS 0x00 +#define I2O_LAN_DSC_DEVICE_FAILURE 0x01 +#define I2O_LAN_DSC_DESTINATION_NOT_FOUND 0x02 +#define I2O_LAN_DSC_TRANSMIT_ERROR 0x03 +#define I2O_LAN_DSC_TRANSMIT_ABORTED 0x04 +#define I2O_LAN_DSC_RECEIVE_ERROR 0x05 +#define I2O_LAN_DSC_RECEIVE_ABORTED 0x06 +#define I2O_LAN_DSC_DMA_ERROR 0x07 +#define I2O_LAN_DSC_BAD_PACKET_DETECTED 0x08 +#define I2O_LAN_DSC_OUT_OF_MEMORY 0x09 +#define I2O_LAN_DSC_BUCKET_OVERRUN 0x0A +#define I2O_LAN_DSC_IOP_INTERNAL_ERROR 0x0B +#define I2O_LAN_DSC_CANCELED 0x0C +#define I2O_LAN_DSC_INVALID_TRANSACTION_CONTEXT 0x0D +#define I2O_LAN_DSC_DEST_ADDRESS_DETECTED 0x0E +#define I2O_LAN_DSC_DEST_ADDRESS_OMITTED 0x0F +#define I2O_LAN_DSC_PARTIAL_PACKET_RETURNED 0x10 +#define I2O_LAN_DSC_SUSPENDED 0x11 + +struct i2o_packet_info { + u32 offset:24; + u32 flags:8; + u32 len:24; + u32 status:8; +}; + +struct i2o_bucket_descriptor { + u32 context; /* FIXME: 64bit support */ + struct i2o_packet_info packet_info[1]; +}; + +/* Event Indicator Mask Flags for LAN OSM */ + +#define I2O_LAN_EVT_LINK_DOWN 0x01 +#define I2O_LAN_EVT_LINK_UP 0x02 +#define I2O_LAN_EVT_MEDIA_CHANGE 0x04 + +#include +#include + +struct i2o_lan_local { + u8 unit; + struct i2o_device *i2o_dev; + + struct fddi_statistics stats; /* see also struct net_device_stats */ + unsigned short (*type_trans) (struct sk_buff *, struct net_device *); + atomic_t buckets_out; /* nbr of unused buckets on DDM */ + atomic_t tx_out; /* outstanding TXes */ + u8 tx_count; /* packets in one TX message frame */ + u16 tx_max_out; /* DDM's Tx queue len */ + u8 sgl_max; /* max SGLs in one message frame */ + u32 m; /* IOP address of the batch msg frame */ + + struct work_struct i2o_batch_send_task; + int send_active; + struct sk_buff **i2o_fbl; /* Free bucket list (to reuse skbs) */ + int i2o_fbl_tail; + spinlock_t fbl_lock; + + spinlock_t tx_lock; + + u32 max_size_mc_table; /* max number of multicast addresses */ + + /* LAN OSM configurable parameters are here: */ + + u16 max_buckets_out; /* max nbr of buckets to send to DDM */ + u16 bucket_thresh; /* send more when this many used */ + u16 rx_copybreak; + + u8 tx_batch_mode; /* Set when using batch mode sends */ + u32 i2o_event_mask; /* To turn on interesting event flags */ +}; + +#endif /* _I2O_LAN_H */ diff --git a/trunk/drivers/mfd/ucb1x00-ts.c b/trunk/drivers/mfd/ucb1x00-ts.c index cb8c264eaff0..ce1a48108210 100644 --- a/trunk/drivers/mfd/ucb1x00-ts.c +++ b/trunk/drivers/mfd/ucb1x00-ts.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index 877e7909a0e5..a3c525b2616a 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -25,15 +25,6 @@ config IBM_ASM information on the specific driver level and support statement for your IBM server. -config PHANTOM - tristate "Sensable PHANToM" - depends on PCI - help - Say Y here if you want to build a driver for Sensable PHANToM device. - - If you choose to build module, its name will be phantom. If unsure, - say N here. - If unsure, say N. @@ -187,13 +178,4 @@ config THINKPAD_ACPI_BAY If you are not sure, say Y here. -config BLINK - tristate "Keyboard blink driver" - help - Driver that when loaded will blink the keyboard LEDs continuously. - This is useful for debugging and for kernels that cannot necessarily - output something to the screen like kexec kernels to give the user - a visual indication that the kernel is doing something. - - endmenu diff --git a/trunk/drivers/misc/Makefile b/trunk/drivers/misc/Makefile index 5b6d46de005c..e32516459138 100644 --- a/trunk/drivers/misc/Makefile +++ b/trunk/drivers/misc/Makefile @@ -7,11 +7,9 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/ obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o -obj-$(CONFIG_BLINK) += blink.o obj-$(CONFIG_LKDTM) += lkdtm.o obj-$(CONFIG_TIFM_CORE) += tifm_core.o obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o -obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o diff --git a/trunk/drivers/misc/blink.c b/trunk/drivers/misc/blink.c deleted file mode 100644 index 634431ce1184..000000000000 --- a/trunk/drivers/misc/blink.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include -#include - -static void do_blink(unsigned long data); - -static DEFINE_TIMER(blink_timer, do_blink, 0 ,0); - -static void do_blink(unsigned long data) -{ - static long count; - if (panic_blink) - panic_blink(count++); - blink_timer.expires = jiffies + msecs_to_jiffies(1); - add_timer(&blink_timer); -} - -static int blink_init(void) -{ - printk(KERN_INFO "Enabling keyboard blinking\n"); - do_blink(0); - return 0; -} - -module_init(blink_init); - diff --git a/trunk/drivers/misc/hdpuftrs/hdpu_cpustate.c b/trunk/drivers/misc/hdpuftrs/hdpu_cpustate.c index 276ba3c5143f..ca86f113f36a 100644 --- a/trunk/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/trunk/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/misc/hdpuftrs/hdpu_nexus.c b/trunk/drivers/misc/hdpuftrs/hdpu_nexus.c index 60c8b26f0678..6a51e99a8079 100644 --- a/trunk/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/trunk/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -18,6 +18,7 @@ #include #include #include +#include #include diff --git a/trunk/drivers/misc/phantom.c b/trunk/drivers/misc/phantom.c deleted file mode 100644 index 35b139b0e5f2..000000000000 --- a/trunk/drivers/misc/phantom.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (C) 2005-2007 Jiri Slaby - * - * 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. - * - * You need an userspace library to cooperate with this driver. It (and other - * info) may be obtained here: - * http://www.fi.muni.cz/~xslaby/phantom.html - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define PHANTOM_VERSION "n0.9.5" - -#define PHANTOM_MAX_MINORS 8 - -#define PHN_IRQCTL 0x4c /* irq control in caddr space */ - -#define PHB_RUNNING 1 - -static struct class *phantom_class; -static int phantom_major; - -struct phantom_device { - unsigned int opened; - void __iomem *caddr; - u32 __iomem *iaddr; - u32 __iomem *oaddr; - unsigned long status; - atomic_t counter; - - wait_queue_head_t wait; - struct cdev cdev; - - struct mutex open_lock; -}; - -static unsigned char phantom_devices[PHANTOM_MAX_MINORS]; - -static int phantom_status(struct phantom_device *dev, unsigned long newstat) -{ - pr_debug("phantom_status %lx %lx\n", dev->status, newstat); - - if (!(dev->status & PHB_RUNNING) && (newstat & PHB_RUNNING)) { - atomic_set(&dev->counter, 0); - iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL); - iowrite32(0x43, dev->caddr + PHN_IRQCTL); - } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING)) - iowrite32(0, dev->caddr + PHN_IRQCTL); - - dev->status = newstat; - - return 0; -} - -/* - * File ops - */ - -static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd, - u_long arg) -{ - struct phantom_device *dev = file->private_data; - struct phm_regs rs; - struct phm_reg r; - void __user *argp = (void __user *)arg; - unsigned int i; - - if (_IOC_TYPE(cmd) != PH_IOC_MAGIC || - _IOC_NR(cmd) > PH_IOC_MAXNR) - return -ENOTTY; - - switch (cmd) { - case PHN_SET_REG: - if (copy_from_user(&r, argp, sizeof(r))) - return -EFAULT; - - if (r.reg > 7) - return -EINVAL; - - if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) && - phantom_status(dev, dev->status | PHB_RUNNING)) - return -ENODEV; - - pr_debug("phantom: writing %x to %u\n", r.value, r.reg); - iowrite32(r.value, dev->iaddr + r.reg); - - if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ)) - phantom_status(dev, dev->status & ~PHB_RUNNING); - break; - case PHN_SET_REGS: - if (copy_from_user(&rs, argp, sizeof(rs))) - return -EFAULT; - - pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask); - for (i = 0; i < min(rs.count, 8U); i++) - if ((1 << i) & rs.mask) - iowrite32(rs.values[i], dev->oaddr + i); - break; - case PHN_GET_REG: - if (copy_from_user(&r, argp, sizeof(r))) - return -EFAULT; - - if (r.reg > 7) - return -EINVAL; - - r.value = ioread32(dev->iaddr + r.reg); - - if (copy_to_user(argp, &r, sizeof(r))) - return -EFAULT; - break; - case PHN_GET_REGS: - if (copy_from_user(&rs, argp, sizeof(rs))) - return -EFAULT; - - pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask); - for (i = 0; i < min(rs.count, 8U); i++) - if ((1 << i) & rs.mask) - rs.values[i] = ioread32(dev->iaddr + i); - - if (copy_to_user(argp, &rs, sizeof(rs))) - return -EFAULT; - break; - default: - return -ENOTTY; - } - - return 0; -} - -static int phantom_open(struct inode *inode, struct file *file) -{ - struct phantom_device *dev = container_of(inode->i_cdev, - struct phantom_device, cdev); - - nonseekable_open(inode, file); - - if (mutex_lock_interruptible(&dev->open_lock)) - return -ERESTARTSYS; - - if (dev->opened) { - mutex_unlock(&dev->open_lock); - return -EINVAL; - } - - file->private_data = dev; - - dev->opened++; - mutex_unlock(&dev->open_lock); - - return 0; -} - -static int phantom_release(struct inode *inode, struct file *file) -{ - struct phantom_device *dev = file->private_data; - - mutex_lock(&dev->open_lock); - - dev->opened = 0; - phantom_status(dev, dev->status & ~PHB_RUNNING); - - mutex_unlock(&dev->open_lock); - - return 0; -} - -static unsigned int phantom_poll(struct file *file, poll_table *wait) -{ - struct phantom_device *dev = file->private_data; - unsigned int mask = 0; - - pr_debug("phantom_poll: %d\n", atomic_read(&dev->counter)); - poll_wait(file, &dev->wait, wait); - if (atomic_read(&dev->counter)) { - mask = POLLIN | POLLRDNORM; - atomic_dec(&dev->counter); - } else if ((dev->status & PHB_RUNNING) == 0) - mask = POLLIN | POLLRDNORM | POLLERR; - pr_debug("phantom_poll end: %x/%d\n", mask, atomic_read(&dev->counter)); - - return mask; -} - -static struct file_operations phantom_file_ops = { - .open = phantom_open, - .release = phantom_release, - .ioctl = phantom_ioctl, - .poll = phantom_poll, -}; - -static irqreturn_t phantom_isr(int irq, void *data) -{ - struct phantom_device *dev = data; - - if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ)) - return IRQ_NONE; - - iowrite32(0, dev->iaddr); - iowrite32(0xc0, dev->iaddr); - - atomic_inc(&dev->counter); - wake_up_interruptible(&dev->wait); - - return IRQ_HANDLED; -} - -/* - * Init and deinit driver - */ - -static unsigned int __devinit phantom_get_free(void) -{ - unsigned int i; - - for (i = 0; i < PHANTOM_MAX_MINORS; i++) - if (phantom_devices[i] == 0) - break; - - return i; -} - -static int __devinit phantom_probe(struct pci_dev *pdev, - const struct pci_device_id *pci_id) -{ - struct phantom_device *pht; - unsigned int minor; - int retval; - - retval = pci_enable_device(pdev); - if (retval) - goto err; - - minor = phantom_get_free(); - if (minor == PHANTOM_MAX_MINORS) { - dev_err(&pdev->dev, "too many devices found!\n"); - retval = -EIO; - goto err_dis; - } - - phantom_devices[minor] = 1; - - retval = pci_request_regions(pdev, "phantom"); - if (retval) - goto err_null; - - retval = -ENOMEM; - pht = kzalloc(sizeof(*pht), GFP_KERNEL); - if (pht == NULL) { - dev_err(&pdev->dev, "unable to allocate device\n"); - goto err_reg; - } - - pht->caddr = pci_iomap(pdev, 0, 0); - if (pht->caddr == NULL) { - dev_err(&pdev->dev, "can't remap conf space\n"); - goto err_fr; - } - pht->iaddr = pci_iomap(pdev, 2, 0); - if (pht->iaddr == NULL) { - dev_err(&pdev->dev, "can't remap input space\n"); - goto err_unmc; - } - pht->oaddr = pci_iomap(pdev, 3, 0); - if (pht->oaddr == NULL) { - dev_err(&pdev->dev, "can't remap output space\n"); - goto err_unmi; - } - - mutex_init(&pht->open_lock); - init_waitqueue_head(&pht->wait); - cdev_init(&pht->cdev, &phantom_file_ops); - pht->cdev.owner = THIS_MODULE; - - iowrite32(0, pht->caddr + PHN_IRQCTL); - retval = request_irq(pdev->irq, phantom_isr, - IRQF_SHARED | IRQF_DISABLED, "phantom", pht); - if (retval) { - dev_err(&pdev->dev, "can't establish ISR\n"); - goto err_unmo; - } - - retval = cdev_add(&pht->cdev, MKDEV(phantom_major, minor), 1); - if (retval) { - dev_err(&pdev->dev, "chardev registration failed\n"); - goto err_irq; - } - - if (IS_ERR(device_create(phantom_class, &pdev->dev, MKDEV(phantom_major, - minor), "phantom%u", minor))) - dev_err(&pdev->dev, "can't create device\n"); - - pci_set_drvdata(pdev, pht); - - return 0; -err_irq: - free_irq(pdev->irq, pht); -err_unmo: - pci_iounmap(pdev, pht->oaddr); -err_unmi: - pci_iounmap(pdev, pht->iaddr); -err_unmc: - pci_iounmap(pdev, pht->caddr); -err_fr: - kfree(pht); -err_reg: - pci_release_regions(pdev); -err_null: - phantom_devices[minor] = 0; -err_dis: - pci_disable_device(pdev); -err: - return retval; -} - -static void __devexit phantom_remove(struct pci_dev *pdev) -{ - struct phantom_device *pht = pci_get_drvdata(pdev); - unsigned int minor = MINOR(pht->cdev.dev); - - device_destroy(phantom_class, MKDEV(phantom_major, minor)); - - cdev_del(&pht->cdev); - - iowrite32(0, pht->caddr + PHN_IRQCTL); - free_irq(pdev->irq, pht); - - pci_iounmap(pdev, pht->oaddr); - pci_iounmap(pdev, pht->iaddr); - pci_iounmap(pdev, pht->caddr); - - kfree(pht); - - pci_release_regions(pdev); - - phantom_devices[minor] = 0; - - pci_disable_device(pdev); -} - -#ifdef CONFIG_PM -static int phantom_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct phantom_device *dev = pci_get_drvdata(pdev); - - iowrite32(0, dev->caddr + PHN_IRQCTL); - - return 0; -} - -static int phantom_resume(struct pci_dev *pdev) -{ - struct phantom_device *dev = pci_get_drvdata(pdev); - - iowrite32(0, dev->caddr + PHN_IRQCTL); - - return 0; -} -#else -#define phantom_suspend NULL -#define phantom_resume NULL -#endif - -static struct pci_device_id phantom_pci_tbl[] __devinitdata = { - { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050), - .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 }, - { 0, } -}; -MODULE_DEVICE_TABLE(pci, phantom_pci_tbl); - -static struct pci_driver phantom_pci_driver = { - .name = "phantom", - .id_table = phantom_pci_tbl, - .probe = phantom_probe, - .remove = __devexit_p(phantom_remove), - .suspend = phantom_suspend, - .resume = phantom_resume -}; - -static ssize_t phantom_show_version(struct class *cls, char *buf) -{ - return sprintf(buf, PHANTOM_VERSION "\n"); -} - -static CLASS_ATTR(version, 0444, phantom_show_version, NULL); - -static int __init phantom_init(void) -{ - int retval; - dev_t dev; - - phantom_class = class_create(THIS_MODULE, "phantom"); - if (IS_ERR(phantom_class)) { - retval = PTR_ERR(phantom_class); - printk(KERN_ERR "phantom: can't register phantom class\n"); - goto err; - } - retval = class_create_file(phantom_class, &class_attr_version); - if (retval) { - printk(KERN_ERR "phantom: can't create sysfs version file\n"); - goto err_class; - } - - retval = alloc_chrdev_region(&dev, 0, PHANTOM_MAX_MINORS, "phantom"); - if (retval) { - printk(KERN_ERR "phantom: can't register character device\n"); - goto err_attr; - } - phantom_major = MAJOR(dev); - - retval = pci_register_driver(&phantom_pci_driver); - if (retval) { - printk(KERN_ERR "phantom: can't register pci driver\n"); - goto err_unchr; - } - - printk(KERN_INFO "Phantom Linux Driver, version " PHANTOM_VERSION ", " - "init OK\n"); - - return 0; -err_unchr: - unregister_chrdev_region(dev, PHANTOM_MAX_MINORS); -err_attr: - class_remove_file(phantom_class, &class_attr_version); -err_class: - class_destroy(phantom_class); -err: - return retval; -} - -static void __exit phantom_exit(void) -{ - pci_unregister_driver(&phantom_pci_driver); - - unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS); - - class_remove_file(phantom_class, &class_attr_version); - class_destroy(phantom_class); - - pr_debug("phantom: module successfully removed\n"); -} - -module_init(phantom_init); -module_exit(phantom_exit); - -MODULE_AUTHOR("Jiri Slaby "); -MODULE_DESCRIPTION("Sensable Phantom driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(PHANTOM_VERSION); diff --git a/trunk/drivers/misc/tifm_7xx1.c b/trunk/drivers/misc/tifm_7xx1.c index c08ad8f823d2..bc60e2fc3c2c 100644 --- a/trunk/drivers/misc/tifm_7xx1.c +++ b/trunk/drivers/misc/tifm_7xx1.c @@ -11,20 +11,10 @@ #include #include +#include #define DRIVER_NAME "tifm_7xx1" -#define DRIVER_VERSION "0.8" - -#define TIFM_IRQ_ENABLE 0x80000000 -#define TIFM_IRQ_SOCKMASK(x) (x) -#define TIFM_IRQ_CARDMASK(x) ((x) << 8) -#define TIFM_IRQ_FIFOMASK(x) ((x) << 16) -#define TIFM_IRQ_SETALL 0xffffffff - -static void tifm_7xx1_dummy_eject(struct tifm_adapter *fm, - struct tifm_dev *sock) -{ -} +#define DRIVER_VERSION "0.7" static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) { @@ -32,7 +22,7 @@ static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) spin_lock_irqsave(&fm->lock, flags); fm->socket_change_set |= 1 << sock->socket_id; - tifm_queue_work(&fm->media_switcher); + wake_up_all(&fm->change_set_notify); spin_unlock_irqrestore(&fm->lock, flags); } @@ -40,7 +30,8 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) { struct tifm_adapter *fm = dev_id; struct tifm_dev *sock; - unsigned int irq_status, cnt; + unsigned int irq_status; + unsigned int sock_irq_status, cnt; spin_lock(&fm->lock); irq_status = readl(fm->addr + FM_INTERRUPT_STATUS); @@ -54,12 +45,12 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) for (cnt = 0; cnt < fm->num_sockets; cnt++) { sock = fm->sockets[cnt]; - if (sock) { - if ((irq_status >> cnt) & TIFM_IRQ_FIFOMASK(1)) - sock->data_event(sock); - if ((irq_status >> cnt) & TIFM_IRQ_CARDMASK(1)) - sock->card_event(sock); - } + sock_irq_status = (irq_status >> cnt) + & (TIFM_IRQ_FIFOMASK(1) + | TIFM_IRQ_CARDMASK(1)); + + if (sock && sock_irq_status) + sock->signal_irq(sock, sock_irq_status); } fm->socket_change_set |= irq_status @@ -67,163 +58,196 @@ static irqreturn_t tifm_7xx1_isr(int irq, void *dev_id) } writel(irq_status, fm->addr + FM_INTERRUPT_STATUS); - if (fm->finish_me) - complete_all(fm->finish_me); - else if (!fm->socket_change_set) + if (!fm->socket_change_set) writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE); else - tifm_queue_work(&fm->media_switcher); + wake_up_all(&fm->change_set_notify); spin_unlock(&fm->lock); return IRQ_HANDLED; } -static unsigned char tifm_7xx1_toggle_sock_power(char __iomem *sock_addr) +static tifm_media_id tifm_7xx1_toggle_sock_power(char __iomem *sock_addr, + int is_x2) { unsigned int s_state; int cnt; writel(0x0e00, sock_addr + SOCK_CONTROL); - for (cnt = 16; cnt <= 256; cnt <<= 1) { + for (cnt = 0; cnt < 100; cnt++) { if (!(TIFM_SOCK_STATE_POWERED & readl(sock_addr + SOCK_PRESENT_STATE))) break; - - msleep(cnt); + msleep(10); } s_state = readl(sock_addr + SOCK_PRESENT_STATE); if (!(TIFM_SOCK_STATE_OCCUPIED & s_state)) - return 0; - - writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED, - sock_addr + SOCK_CONTROL); - - /* xd needs some extra time before power on */ - if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) - == TIFM_TYPE_XD) - msleep(40); + return FM_NULL; + + if (is_x2) { + writel((s_state & 7) | 0x0c00, sock_addr + SOCK_CONTROL); + } else { + // SmartMedia cards need extra 40 msec + if (((readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7) == 1) + msleep(40); + writel(readl(sock_addr + SOCK_CONTROL) | TIFM_CTRL_LED, + sock_addr + SOCK_CONTROL); + msleep(10); + writel((s_state & 0x7) | 0x0c00 | TIFM_CTRL_LED, + sock_addr + SOCK_CONTROL); + } - writel((s_state & TIFM_CTRL_POWER_MASK) | 0x0c00, - sock_addr + SOCK_CONTROL); - /* wait for power to stabilize */ - msleep(20); - for (cnt = 16; cnt <= 256; cnt <<= 1) { + for (cnt = 0; cnt < 100; cnt++) { if ((TIFM_SOCK_STATE_POWERED & readl(sock_addr + SOCK_PRESENT_STATE))) break; - - msleep(cnt); + msleep(10); } - writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED), - sock_addr + SOCK_CONTROL); + if (!is_x2) + writel(readl(sock_addr + SOCK_CONTROL) & (~TIFM_CTRL_LED), + sock_addr + SOCK_CONTROL); return (readl(sock_addr + SOCK_PRESENT_STATE) >> 4) & 7; } -inline static void tifm_7xx1_sock_power_off(char __iomem *sock_addr) -{ - writel((~TIFM_CTRL_POWER_MASK) & readl(sock_addr + SOCK_CONTROL), - sock_addr + SOCK_CONTROL); -} - inline static char __iomem * tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num) { return base_addr + ((sock_num + 1) << 10); } -static void tifm_7xx1_switch_media(struct work_struct *work) +static int tifm_7xx1_switch_media(void *data) { - struct tifm_adapter *fm = container_of(work, struct tifm_adapter, - media_switcher); - struct tifm_dev *sock; - char __iomem *sock_addr; + struct tifm_adapter *fm = data; unsigned long flags; - unsigned char media_id; - unsigned int socket_change_set, cnt; - - spin_lock_irqsave(&fm->lock, flags); - socket_change_set = fm->socket_change_set; - fm->socket_change_set = 0; + tifm_media_id media_id; + char *card_name = "xx"; + int cnt, rc; + struct tifm_dev *sock; + unsigned int socket_change_set; - dev_dbg(fm->cdev.dev, "checking media set %x\n", - socket_change_set); + while (1) { + rc = wait_event_interruptible(fm->change_set_notify, + fm->socket_change_set); + if (rc == -ERESTARTSYS) + try_to_freeze(); - if (!socket_change_set) { - spin_unlock_irqrestore(&fm->lock, flags); - return; - } + spin_lock_irqsave(&fm->lock, flags); + socket_change_set = fm->socket_change_set; + fm->socket_change_set = 0; - for (cnt = 0; cnt < fm->num_sockets; cnt++) { - if (!(socket_change_set & (1 << cnt))) - continue; - sock = fm->sockets[cnt]; - if (sock) { - printk(KERN_INFO - "%s : demand removing card from socket %u:%u\n", - fm->cdev.class_id, fm->id, cnt); - fm->sockets[cnt] = NULL; - sock_addr = sock->addr; - spin_unlock_irqrestore(&fm->lock, flags); - device_unregister(&sock->dev); - spin_lock_irqsave(&fm->lock, flags); - tifm_7xx1_sock_power_off(sock_addr); - writel(0x0e00, sock_addr + SOCK_CONTROL); - } + dev_dbg(fm->dev, "checking media set %x\n", + socket_change_set); + if (kthread_should_stop()) + socket_change_set = (1 << fm->num_sockets) - 1; spin_unlock_irqrestore(&fm->lock, flags); - media_id = tifm_7xx1_toggle_sock_power( - tifm_7xx1_sock_addr(fm->addr, cnt)); - - // tifm_alloc_device will check if media_id is valid - sock = tifm_alloc_device(fm, cnt, media_id); - if (sock) { - sock->addr = tifm_7xx1_sock_addr(fm->addr, cnt); + if (!socket_change_set) + continue; - if (!device_register(&sock->dev)) { + spin_lock_irqsave(&fm->lock, flags); + for (cnt = 0; cnt < fm->num_sockets; cnt++) { + if (!(socket_change_set & (1 << cnt))) + continue; + sock = fm->sockets[cnt]; + if (sock) { + printk(KERN_INFO DRIVER_NAME + ": demand removing card from socket %d\n", + cnt); + fm->sockets[cnt] = NULL; + spin_unlock_irqrestore(&fm->lock, flags); + device_unregister(&sock->dev); spin_lock_irqsave(&fm->lock, flags); - if (!fm->sockets[cnt]) { - fm->sockets[cnt] = sock; - sock = NULL; + writel(0x0e00, + tifm_7xx1_sock_addr(fm->addr, cnt) + + SOCK_CONTROL); + } + if (kthread_should_stop()) + continue; + + spin_unlock_irqrestore(&fm->lock, flags); + media_id = tifm_7xx1_toggle_sock_power( + tifm_7xx1_sock_addr(fm->addr, cnt), + fm->num_sockets == 2); + if (media_id) { + sock = tifm_alloc_device(fm); + if (sock) { + sock->addr = tifm_7xx1_sock_addr(fm->addr, + cnt); + sock->media_id = media_id; + sock->socket_id = cnt; + switch (media_id) { + case 1: + card_name = "xd"; + break; + case 2: + card_name = "ms"; + break; + case 3: + card_name = "sd"; + break; + default: + tifm_free_device(&sock->dev); + spin_lock_irqsave(&fm->lock, flags); + continue; + } + snprintf(sock->dev.bus_id, BUS_ID_SIZE, + "tifm_%s%u:%u", card_name, + fm->id, cnt); + printk(KERN_INFO DRIVER_NAME + ": %s card detected in socket %d\n", + card_name, cnt); + if (!device_register(&sock->dev)) { + spin_lock_irqsave(&fm->lock, flags); + if (!fm->sockets[cnt]) { + fm->sockets[cnt] = sock; + sock = NULL; + } + spin_unlock_irqrestore(&fm->lock, flags); + } + if (sock) + tifm_free_device(&sock->dev); } + spin_lock_irqsave(&fm->lock, flags); + } + } + + if (!kthread_should_stop()) { + writel(TIFM_IRQ_FIFOMASK(socket_change_set) + | TIFM_IRQ_CARDMASK(socket_change_set), + fm->addr + FM_CLEAR_INTERRUPT_ENABLE); + writel(TIFM_IRQ_FIFOMASK(socket_change_set) + | TIFM_IRQ_CARDMASK(socket_change_set), + fm->addr + FM_SET_INTERRUPT_ENABLE); + writel(TIFM_IRQ_ENABLE, + fm->addr + FM_SET_INTERRUPT_ENABLE); + spin_unlock_irqrestore(&fm->lock, flags); + } else { + for (cnt = 0; cnt < fm->num_sockets; cnt++) { + if (fm->sockets[cnt]) + fm->socket_change_set |= 1 << cnt; + } + if (!fm->socket_change_set) { + spin_unlock_irqrestore(&fm->lock, flags); + return 0; + } else { spin_unlock_irqrestore(&fm->lock, flags); } - if (sock) - tifm_free_device(&sock->dev); } - spin_lock_irqsave(&fm->lock, flags); } - - writel(TIFM_IRQ_FIFOMASK(socket_change_set) - | TIFM_IRQ_CARDMASK(socket_change_set), - fm->addr + FM_CLEAR_INTERRUPT_ENABLE); - - writel(TIFM_IRQ_FIFOMASK(socket_change_set) - | TIFM_IRQ_CARDMASK(socket_change_set), - fm->addr + FM_SET_INTERRUPT_ENABLE); - - writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&fm->lock, flags); + return 0; } #ifdef CONFIG_PM static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) { - struct tifm_adapter *fm = pci_get_drvdata(dev); - int cnt; - dev_dbg(&dev->dev, "suspending host\n"); - for (cnt = 0; cnt < fm->num_sockets; cnt++) { - if (fm->sockets[cnt]) - tifm_7xx1_sock_power_off(fm->sockets[cnt]->addr); - } - pci_save_state(dev); pci_enable_wake(dev, pci_choose_state(dev, state), 0); pci_disable_device(dev); @@ -234,11 +258,9 @@ static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) static int tifm_7xx1_resume(struct pci_dev *dev) { struct tifm_adapter *fm = pci_get_drvdata(dev); - int rc; - unsigned int good_sockets = 0, bad_sockets = 0; + int cnt, rc; unsigned long flags; - unsigned char new_ids[fm->num_sockets]; - DECLARE_COMPLETION_ONSTACK(finish_resume); + tifm_media_id new_ids[fm->num_sockets]; pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); @@ -249,49 +271,45 @@ static int tifm_7xx1_resume(struct pci_dev *dev) dev_dbg(&dev->dev, "resuming host\n"); - for (rc = 0; rc < fm->num_sockets; rc++) - new_ids[rc] = tifm_7xx1_toggle_sock_power( - tifm_7xx1_sock_addr(fm->addr, rc)); + for (cnt = 0; cnt < fm->num_sockets; cnt++) + new_ids[cnt] = tifm_7xx1_toggle_sock_power( + tifm_7xx1_sock_addr(fm->addr, cnt), + fm->num_sockets == 2); spin_lock_irqsave(&fm->lock, flags); - for (rc = 0; rc < fm->num_sockets; rc++) { - if (fm->sockets[rc]) { - if (fm->sockets[rc]->type == new_ids[rc]) - good_sockets |= 1 << rc; - else - bad_sockets |= 1 << rc; + fm->socket_change_set = 0; + for (cnt = 0; cnt < fm->num_sockets; cnt++) { + if (fm->sockets[cnt]) { + if (fm->sockets[cnt]->media_id == new_ids[cnt]) + fm->socket_change_set |= 1 << cnt; + + fm->sockets[cnt]->media_id = new_ids[cnt]; } } writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), fm->addr + FM_SET_INTERRUPT_ENABLE); - dev_dbg(&dev->dev, "change sets on resume: good %x, bad %x\n", - good_sockets, bad_sockets); - - fm->socket_change_set = 0; - if (good_sockets) { - fm->finish_me = &finish_resume; + if (!fm->socket_change_set) { + spin_unlock_irqrestore(&fm->lock, flags); + return 0; + } else { + fm->socket_change_set = 0; spin_unlock_irqrestore(&fm->lock, flags); - rc = wait_for_completion_timeout(&finish_resume, HZ); - dev_dbg(&dev->dev, "wait returned %d\n", rc); - writel(TIFM_IRQ_FIFOMASK(good_sockets) - | TIFM_IRQ_CARDMASK(good_sockets), - fm->addr + FM_CLEAR_INTERRUPT_ENABLE); - writel(TIFM_IRQ_FIFOMASK(good_sockets) - | TIFM_IRQ_CARDMASK(good_sockets), - fm->addr + FM_SET_INTERRUPT_ENABLE); - spin_lock_irqsave(&fm->lock, flags); - fm->finish_me = NULL; - fm->socket_change_set ^= good_sockets & fm->socket_change_set; } - fm->socket_change_set |= bad_sockets; - if (fm->socket_change_set) - tifm_queue_work(&fm->media_switcher); + wait_event_timeout(fm->change_set_notify, fm->socket_change_set, HZ); - spin_unlock_irqrestore(&fm->lock, flags); + spin_lock_irqsave(&fm->lock, flags); + writel(TIFM_IRQ_FIFOMASK(fm->socket_change_set) + | TIFM_IRQ_CARDMASK(fm->socket_change_set), + fm->addr + FM_CLEAR_INTERRUPT_ENABLE); + writel(TIFM_IRQ_FIFOMASK(fm->socket_change_set) + | TIFM_IRQ_CARDMASK(fm->socket_change_set), + fm->addr + FM_SET_INTERRUPT_ENABLE); writel(TIFM_IRQ_ENABLE, fm->addr + FM_SET_INTERRUPT_ENABLE); + fm->socket_change_set = 0; + spin_unlock_irqrestore(&fm->lock, flags); return 0; } @@ -327,14 +345,20 @@ static int tifm_7xx1_probe(struct pci_dev *dev, pci_intx(dev, 1); - fm = tifm_alloc_adapter(dev->device == PCI_DEVICE_ID_TI_XX21_XX11_FM - ? 4 : 2, &dev->dev); + fm = tifm_alloc_adapter(); if (!fm) { rc = -ENOMEM; goto err_out_int; } - INIT_WORK(&fm->media_switcher, tifm_7xx1_switch_media); + fm->dev = &dev->dev; + fm->num_sockets = (dev->device == PCI_DEVICE_ID_TI_XX21_XX11_FM) + ? 4 : 2; + fm->sockets = kzalloc(sizeof(struct tifm_dev*) * fm->num_sockets, + GFP_KERNEL); + if (!fm->sockets) + goto err_out_free; + fm->eject = tifm_7xx1_eject; pci_set_drvdata(dev, fm); @@ -343,16 +367,19 @@ static int tifm_7xx1_probe(struct pci_dev *dev, if (!fm->addr) goto err_out_free; - rc = request_irq(dev->irq, tifm_7xx1_isr, SA_SHIRQ, DRIVER_NAME, fm); + rc = request_irq(dev->irq, tifm_7xx1_isr, IRQF_SHARED, DRIVER_NAME, fm); if (rc) goto err_out_unmap; - rc = tifm_add_adapter(fm); + init_waitqueue_head(&fm->change_set_notify); + rc = tifm_add_adapter(fm, tifm_7xx1_switch_media); if (rc) goto err_out_irq; + writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); writel(TIFM_IRQ_ENABLE | TIFM_IRQ_SOCKMASK((1 << fm->num_sockets) - 1), fm->addr + FM_SET_INTERRUPT_ENABLE); + wake_up_process(fm->media_switcher); return 0; err_out_irq: @@ -374,17 +401,19 @@ static int tifm_7xx1_probe(struct pci_dev *dev, static void tifm_7xx1_remove(struct pci_dev *dev) { struct tifm_adapter *fm = pci_get_drvdata(dev); - int cnt; + unsigned long flags; - fm->eject = tifm_7xx1_dummy_eject; writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); mmiowb(); free_irq(dev->irq, fm); - tifm_remove_adapter(fm); + spin_lock_irqsave(&fm->lock, flags); + fm->socket_change_set = (1 << fm->num_sockets) - 1; + spin_unlock_irqrestore(&fm->lock, flags); - for (cnt = 0; cnt < fm->num_sockets; cnt++) - tifm_7xx1_sock_power_off(tifm_7xx1_sock_addr(fm->addr, cnt)); + kthread_stop(fm->media_switcher); + + tifm_remove_adapter(fm); pci_set_drvdata(dev, NULL); diff --git a/trunk/drivers/misc/tifm_core.c b/trunk/drivers/misc/tifm_core.c index d195fb088f4a..6b10ebe9d936 100644 --- a/trunk/drivers/misc/tifm_core.c +++ b/trunk/drivers/misc/tifm_core.c @@ -14,124 +14,71 @@ #include #define DRIVER_NAME "tifm_core" -#define DRIVER_VERSION "0.8" +#define DRIVER_VERSION "0.7" -static struct workqueue_struct *workqueue; static DEFINE_IDR(tifm_adapter_idr); static DEFINE_SPINLOCK(tifm_adapter_lock); -static const char *tifm_media_type_name(unsigned char type, unsigned char nt) +static tifm_media_id *tifm_device_match(tifm_media_id *ids, + struct tifm_dev *dev) { - const char *card_type_name[3][3] = { - { "SmartMedia/xD", "MemoryStick", "MMC/SD" }, - { "XD", "MS", "SD"}, - { "xd", "ms", "sd"} - }; - - if (nt > 2 || type < 1 || type > 3) - return NULL; - return card_type_name[nt][type - 1]; + while (*ids) { + if (dev->media_id == *ids) + return ids; + ids++; + } + return NULL; } -static int tifm_dev_match(struct tifm_dev *sock, struct tifm_device_id *id) +static int tifm_match(struct device *dev, struct device_driver *drv) { - if (sock->type == id->type) - return 1; - return 0; -} + struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); + struct tifm_driver *fm_drv; -static int tifm_bus_match(struct device *dev, struct device_driver *drv) -{ - struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); - struct tifm_driver *fm_drv = container_of(drv, struct tifm_driver, - driver); - struct tifm_device_id *ids = fm_drv->id_table; - - if (ids) { - while (ids->type) { - if (tifm_dev_match(sock, ids)) - return 1; - ++ids; - } - } - return 0; + fm_drv = container_of(drv, struct tifm_driver, driver); + if (!fm_drv->id_table) + return -EINVAL; + if (tifm_device_match(fm_drv->id_table, fm_dev)) + return 1; + return -ENODEV; } static int tifm_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { - struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); + struct tifm_dev *fm_dev; int i = 0; int length = 0; + const char *card_type_name[] = {"INV", "SM", "MS", "SD"}; + if (!dev || !(fm_dev = container_of(dev, struct tifm_dev, dev))) + return -ENODEV; if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, - "TIFM_CARD_TYPE=%s", - tifm_media_type_name(sock->type, 1))) + "TIFM_CARD_TYPE=%s", card_type_name[fm_dev->media_id])) return -ENOMEM; return 0; } -static int tifm_device_probe(struct device *dev) -{ - struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); - struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, - driver); - int rc = -ENODEV; - - get_device(dev); - if (dev->driver && drv->probe) { - rc = drv->probe(sock); - if (!rc) - return 0; - } - put_device(dev); - return rc; -} - -static void tifm_dummy_event(struct tifm_dev *sock) -{ - return; -} - -static int tifm_device_remove(struct device *dev) -{ - struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); - struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, - driver); - - if (dev->driver && drv->remove) { - sock->card_event = tifm_dummy_event; - sock->data_event = tifm_dummy_event; - drv->remove(sock); - sock->dev.driver = NULL; - } - - put_device(dev); - return 0; -} - #ifdef CONFIG_PM static int tifm_device_suspend(struct device *dev, pm_message_t state) { - struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); - struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, - driver); + struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); + struct tifm_driver *drv = fm_dev->drv; - if (dev->driver && drv->suspend) - return drv->suspend(sock, state); + if (drv && drv->suspend) + return drv->suspend(fm_dev, state); return 0; } static int tifm_device_resume(struct device *dev) { - struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); - struct tifm_driver *drv = container_of(dev->driver, struct tifm_driver, - driver); + struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); + struct tifm_driver *drv = fm_dev->drv; - if (dev->driver && drv->resume) - return drv->resume(sock); + if (drv && drv->resume) + return drv->resume(fm_dev); return 0; } @@ -142,33 +89,19 @@ static int tifm_device_resume(struct device *dev) #endif /* CONFIG_PM */ -static ssize_t type_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); - return sprintf(buf, "%x", sock->type); -} - -static struct device_attribute tifm_dev_attrs[] = { - __ATTR(type, S_IRUGO, type_show, NULL), - __ATTR_NULL -}; - static struct bus_type tifm_bus_type = { - .name = "tifm", - .dev_attrs = tifm_dev_attrs, - .match = tifm_bus_match, - .uevent = tifm_uevent, - .probe = tifm_device_probe, - .remove = tifm_device_remove, - .suspend = tifm_device_suspend, - .resume = tifm_device_resume + .name = "tifm", + .match = tifm_match, + .uevent = tifm_uevent, + .suspend = tifm_device_suspend, + .resume = tifm_device_resume }; static void tifm_free(struct class_device *cdev) { struct tifm_adapter *fm = container_of(cdev, struct tifm_adapter, cdev); + kfree(fm->sockets); kfree(fm); } @@ -177,25 +110,28 @@ static struct class tifm_adapter_class = { .release = tifm_free }; -struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, - struct device *dev) +struct tifm_adapter *tifm_alloc_adapter(void) { struct tifm_adapter *fm; - fm = kzalloc(sizeof(struct tifm_adapter) - + sizeof(struct tifm_dev*) * num_sockets, GFP_KERNEL); + fm = kzalloc(sizeof(struct tifm_adapter), GFP_KERNEL); if (fm) { fm->cdev.class = &tifm_adapter_class; - fm->cdev.dev = dev; - class_device_initialize(&fm->cdev); spin_lock_init(&fm->lock); - fm->num_sockets = num_sockets; + class_device_initialize(&fm->cdev); } return fm; } EXPORT_SYMBOL(tifm_alloc_adapter); -int tifm_add_adapter(struct tifm_adapter *fm) +void tifm_free_adapter(struct tifm_adapter *fm) +{ + class_device_put(&fm->cdev); +} +EXPORT_SYMBOL(tifm_free_adapter); + +int tifm_add_adapter(struct tifm_adapter *fm, + int (*mediathreadfn)(void *data)) { int rc; @@ -205,80 +141,59 @@ int tifm_add_adapter(struct tifm_adapter *fm) spin_lock(&tifm_adapter_lock); rc = idr_get_new(&tifm_adapter_idr, fm, &fm->id); spin_unlock(&tifm_adapter_lock); - if (rc) - return rc; + if (!rc) { + snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id); + fm->media_switcher = kthread_create(mediathreadfn, + fm, "tifm/%u", fm->id); + + if (!IS_ERR(fm->media_switcher)) + return class_device_add(&fm->cdev); - snprintf(fm->cdev.class_id, BUS_ID_SIZE, "tifm%u", fm->id); - rc = class_device_add(&fm->cdev); - if (rc) { spin_lock(&tifm_adapter_lock); idr_remove(&tifm_adapter_idr, fm->id); spin_unlock(&tifm_adapter_lock); + rc = -ENOMEM; } - return rc; } EXPORT_SYMBOL(tifm_add_adapter); void tifm_remove_adapter(struct tifm_adapter *fm) { - unsigned int cnt; - - flush_workqueue(workqueue); - for (cnt = 0; cnt < fm->num_sockets; ++cnt) { - if (fm->sockets[cnt]) - device_unregister(&fm->sockets[cnt]->dev); - } + class_device_del(&fm->cdev); spin_lock(&tifm_adapter_lock); idr_remove(&tifm_adapter_idr, fm->id); spin_unlock(&tifm_adapter_lock); - class_device_del(&fm->cdev); } EXPORT_SYMBOL(tifm_remove_adapter); -void tifm_free_adapter(struct tifm_adapter *fm) +void tifm_free_device(struct device *dev) { - class_device_put(&fm->cdev); + struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); + kfree(fm_dev); } -EXPORT_SYMBOL(tifm_free_adapter); +EXPORT_SYMBOL(tifm_free_device); -void tifm_free_device(struct device *dev) +static void tifm_dummy_signal_irq(struct tifm_dev *sock, + unsigned int sock_irq_status) { - struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); - kfree(sock); + return; } -EXPORT_SYMBOL(tifm_free_device); -struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id, - unsigned char type) +struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm) { - struct tifm_dev *sock = NULL; - - if (!tifm_media_type_name(type, 0)) - return sock; - - sock = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); - if (sock) { - spin_lock_init(&sock->lock); - sock->type = type; - sock->socket_id = id; - sock->card_event = tifm_dummy_event; - sock->data_event = tifm_dummy_event; - - sock->dev.parent = fm->cdev.dev; - sock->dev.bus = &tifm_bus_type; - sock->dev.dma_mask = fm->cdev.dev->dma_mask; - sock->dev.release = tifm_free_device; - - snprintf(sock->dev.bus_id, BUS_ID_SIZE, - "tifm_%s%u:%u", tifm_media_type_name(type, 2), - fm->id, id); - printk(KERN_INFO DRIVER_NAME - ": %s card detected in socket %u:%u\n", - tifm_media_type_name(type, 0), fm->id, id); + struct tifm_dev *dev = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); + + if (dev) { + spin_lock_init(&dev->lock); + + dev->dev.parent = fm->dev; + dev->dev.bus = &tifm_bus_type; + dev->dev.release = tifm_free_device; + dev->signal_irq = tifm_dummy_signal_irq; } - return sock; + return dev; } EXPORT_SYMBOL(tifm_alloc_device); @@ -303,15 +218,54 @@ void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, } EXPORT_SYMBOL(tifm_unmap_sg); -void tifm_queue_work(struct work_struct *work) +static int tifm_device_probe(struct device *dev) +{ + struct tifm_driver *drv; + struct tifm_dev *fm_dev; + int rc = 0; + const tifm_media_id *id; + + drv = container_of(dev->driver, struct tifm_driver, driver); + fm_dev = container_of(dev, struct tifm_dev, dev); + get_device(dev); + if (!fm_dev->drv && drv->probe && drv->id_table) { + rc = -ENODEV; + id = tifm_device_match(drv->id_table, fm_dev); + if (id) + rc = drv->probe(fm_dev); + if (rc >= 0) { + rc = 0; + fm_dev->drv = drv; + } + } + if (rc) + put_device(dev); + return rc; +} + +static int tifm_device_remove(struct device *dev) { - queue_work(workqueue, work); + struct tifm_dev *fm_dev = container_of(dev, struct tifm_dev, dev); + struct tifm_driver *drv = fm_dev->drv; + + if (drv) { + fm_dev->signal_irq = tifm_dummy_signal_irq; + if (drv->remove) + drv->remove(fm_dev); + fm_dev->drv = NULL; + } + + put_device(dev); + return 0; } -EXPORT_SYMBOL(tifm_queue_work); int tifm_register_driver(struct tifm_driver *drv) { drv->driver.bus = &tifm_bus_type; + drv->driver.probe = tifm_device_probe; + drv->driver.remove = tifm_device_remove; + drv->driver.suspend = tifm_device_suspend; + drv->driver.resume = tifm_device_resume; return driver_register(&drv->driver); } @@ -325,25 +279,13 @@ EXPORT_SYMBOL(tifm_unregister_driver); static int __init tifm_init(void) { - int rc; - - workqueue = create_freezeable_workqueue("tifm"); - if (!workqueue) - return -ENOMEM; - - rc = bus_register(&tifm_bus_type); - - if (rc) - goto err_out_wq; - - rc = class_register(&tifm_adapter_class); - if (!rc) - return 0; + int rc = bus_register(&tifm_bus_type); - bus_unregister(&tifm_bus_type); - -err_out_wq: - destroy_workqueue(workqueue); + if (!rc) { + rc = class_register(&tifm_adapter_class); + if (rc) + bus_unregister(&tifm_bus_type); + } return rc; } @@ -352,7 +294,6 @@ static void __exit tifm_exit(void) { class_unregister(&tifm_adapter_class); bus_unregister(&tifm_bus_type); - destroy_workqueue(workqueue); } subsys_initcall(tifm_init); diff --git a/trunk/drivers/mmc/Kconfig b/trunk/drivers/mmc/Kconfig index 45b7d53b949c..12af9c718764 100644 --- a/trunk/drivers/mmc/Kconfig +++ b/trunk/drivers/mmc/Kconfig @@ -2,8 +2,10 @@ # MMC subsystem configuration # -menuconfig MMC - tristate "MMC/SD card support" +menu "MMC/SD Card support" + +config MMC + tristate "MMC support" help MMC is the "multi-media card" bus protocol. @@ -17,12 +19,110 @@ config MMC_DEBUG This is an option for use by developers; most people should say N here. This enables MMC core and driver debugging. -if MMC +config MMC_BLOCK + tristate "MMC block device driver" + depends on MMC && BLOCK + default y + help + Say Y here to enable the MMC block device driver support. + This provides a block device driver, which you can use to + mount the filesystem. Almost everyone wishing MMC support + should say Y or M here. + +config MMC_ARMMMCI + tristate "ARM AMBA Multimedia Card Interface support" + depends on ARM_AMBA && MMC + help + This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card + Interface (PL180 and PL181) support. If you have an ARM(R) + platform with a Multimedia Card slot, say Y or M here. + + If unsure, say N. + +config MMC_PXA + tristate "Intel PXA25x/26x/27x Multimedia Card Interface support" + depends on ARCH_PXA && MMC + help + This selects the Intel(R) PXA(R) Multimedia card Interface. + If you have a PXA(R) platform with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + +config MMC_SDHCI + tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" + depends on PCI && MMC && EXPERIMENTAL + help + This select the generic Secure Digital Host Controller Interface. + It is used by manufacturers such as Texas Instruments(R), Ricoh(R) + and Toshiba(R). Most controllers found in laptops are of this type. + If you have a controller with this interface, say Y or M here. + + If unsure, say N. + +config MMC_OMAP + tristate "TI OMAP Multimedia Card Interface support" + depends on ARCH_OMAP && MMC + select TPS65010 if MACH_OMAP_H2 + help + This selects the TI OMAP Multimedia card Interface. + If you have an OMAP board with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + +config MMC_WBSD + tristate "Winbond W83L51xD SD/MMC Card Interface support" + depends on MMC && ISA_DMA_API + help + This selects the Winbond(R) W83L51xD Secure digital and + Multimedia card Interface. + If you have a machine with a integrated W83L518D or W83L519D + SD/MMC card reader, say Y or M here. -source "drivers/mmc/core/Kconfig" + If unsure, say N. -source "drivers/mmc/card/Kconfig" +config MMC_AU1X + tristate "Alchemy AU1XX0 MMC Card Interface support" + depends on MMC && SOC_AU1200 + help + This selects the AMD Alchemy(R) Multimedia card interface. + If you have a Alchemy platform with a MMC slot, say Y or M here. + + If unsure, say N. + +config MMC_AT91 + tristate "AT91 SD/MMC Card Interface support" + depends on ARCH_AT91 && MMC + help + This selects the AT91 MCI controller. + + If unsure, say N. + +config MMC_IMX + tristate "Motorola i.MX Multimedia Card Interface support" + depends on ARCH_IMX && MMC + help + This selects the Motorola i.MX Multimedia card Interface. + If you have a i.MX platform with a Multimedia Card slot, + say Y or M here. + + If unsure, say N. + +config MMC_TIFM_SD + tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" + depends on MMC && EXPERIMENTAL && PCI + select TIFM_CORE + help + Say Y here if you want to be able to access MMC/SD cards with + the Texas Instruments(R) Flash Media card reader, found in many + laptops. + This option 'selects' (turns on, enables) 'TIFM_CORE', but you + probably also need appropriate card reader host adapter, such as + 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support + (TIFM_7XX1)'. -source "drivers/mmc/host/Kconfig" + To compile this driver as a module, choose M here: the + module will be called tifm_sd. -endif # MMC +endmenu diff --git a/trunk/drivers/mmc/Makefile b/trunk/drivers/mmc/Makefile index 9979f5e9765b..83ffb9326a54 100644 --- a/trunk/drivers/mmc/Makefile +++ b/trunk/drivers/mmc/Makefile @@ -2,11 +2,32 @@ # Makefile for the kernel mmc device drivers. # -ifeq ($(CONFIG_MMC_DEBUG),y) - EXTRA_CFLAGS += -DDEBUG -endif +# +# Core +# +obj-$(CONFIG_MMC) += mmc_core.o + +# +# Media drivers +# +obj-$(CONFIG_MMC_BLOCK) += mmc_block.o + +# +# Host drivers +# +obj-$(CONFIG_MMC_ARMMMCI) += mmci.o +obj-$(CONFIG_MMC_PXA) += pxamci.o +obj-$(CONFIG_MMC_IMX) += imxmmc.o +obj-$(CONFIG_MMC_SDHCI) += sdhci.o +obj-$(CONFIG_MMC_WBSD) += wbsd.o +obj-$(CONFIG_MMC_AU1X) += au1xmmc.o +obj-$(CONFIG_MMC_OMAP) += omap.o +obj-$(CONFIG_MMC_AT91) += at91_mci.o +obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o -obj-$(CONFIG_MMC) += core/ -obj-$(CONFIG_MMC) += card/ -obj-$(CONFIG_MMC) += host/ +mmc_core-y := mmc.o mmc_sysfs.o +mmc_core-$(CONFIG_BLOCK) += mmc_queue.o +ifeq ($(CONFIG_MMC_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif diff --git a/trunk/drivers/mmc/host/at91_mci.c b/trunk/drivers/mmc/at91_mci.c similarity index 99% rename from trunk/drivers/mmc/host/at91_mci.c rename to trunk/drivers/mmc/at91_mci.c index e37943c314cb..459f4b4feded 100644 --- a/trunk/drivers/mmc/host/at91_mci.c +++ b/trunk/drivers/mmc/at91_mci.c @@ -67,6 +67,7 @@ #include #include +#include #include #include diff --git a/trunk/drivers/mmc/host/au1xmmc.c b/trunk/drivers/mmc/au1xmmc.c similarity index 99% rename from trunk/drivers/mmc/host/au1xmmc.c rename to trunk/drivers/mmc/au1xmmc.c index b7156a4555b5..b834be261ab7 100644 --- a/trunk/drivers/mmc/host/au1xmmc.c +++ b/trunk/drivers/mmc/au1xmmc.c @@ -42,6 +42,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/mmc/host/au1xmmc.h b/trunk/drivers/mmc/au1xmmc.h similarity index 100% rename from trunk/drivers/mmc/host/au1xmmc.h rename to trunk/drivers/mmc/au1xmmc.h diff --git a/trunk/drivers/mmc/card/Kconfig b/trunk/drivers/mmc/card/Kconfig deleted file mode 100644 index 9320a8c73239..000000000000 --- a/trunk/drivers/mmc/card/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# -# MMC/SD card drivers -# - -comment "MMC/SD Card Drivers" - -config MMC_BLOCK - tristate "MMC block device driver" - depends on BLOCK - default y - help - Say Y here to enable the MMC block device driver support. - This provides a block device driver, which you can use to - mount the filesystem. Almost everyone wishing MMC support - should say Y or M here. - diff --git a/trunk/drivers/mmc/card/Makefile b/trunk/drivers/mmc/card/Makefile deleted file mode 100644 index cf8c939867f5..000000000000 --- a/trunk/drivers/mmc/card/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for MMC/SD card drivers -# - -ifeq ($(CONFIG_MMC_DEBUG),y) - EXTRA_CFLAGS += -DDEBUG -endif - -obj-$(CONFIG_MMC_BLOCK) += mmc_block.o -mmc_block-objs := block.o queue.o - diff --git a/trunk/drivers/mmc/core/Kconfig b/trunk/drivers/mmc/core/Kconfig deleted file mode 100644 index ab37a6d9d32a..000000000000 --- a/trunk/drivers/mmc/core/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# -# MMC core configuration -# - -config MMC_UNSAFE_RESUME - bool "Allow unsafe resume (DANGEROUS)" - help - If you say Y here, the MMC layer will assume that all cards - stayed in their respective slots during the suspend. The - normal behaviour is to remove them at suspend and - redetecting them at resume. Breaking this assumption will - in most cases result in data corruption. - - This option is usually just for embedded systems which use - a MMC/SD card for rootfs. Most people should say N here. - diff --git a/trunk/drivers/mmc/core/Makefile b/trunk/drivers/mmc/core/Makefile deleted file mode 100644 index 1075b02ae754..000000000000 --- a/trunk/drivers/mmc/core/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the kernel mmc core. -# - -ifeq ($(CONFIG_MMC_DEBUG),y) - EXTRA_CFLAGS += -DDEBUG -endif - -obj-$(CONFIG_MMC) += mmc_core.o -mmc_core-y := core.o sysfs.o mmc.o mmc_ops.o sd.o sd_ops.o - diff --git a/trunk/drivers/mmc/core/core.c b/trunk/drivers/mmc/core/core.c deleted file mode 100644 index b6c16704aaab..000000000000 --- a/trunk/drivers/mmc/core/core.c +++ /dev/null @@ -1,729 +0,0 @@ -/* - * linux/drivers/mmc/core/core.c - * - * Copyright (C) 2003-2004 Russell King, All Rights Reserved. - * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. - * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. - * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "core.h" -#include "sysfs.h" - -#include "mmc_ops.h" -#include "sd_ops.h" - -extern int mmc_attach_mmc(struct mmc_host *host, u32 ocr); -extern int mmc_attach_sd(struct mmc_host *host, u32 ocr); - -/** - * mmc_request_done - finish processing an MMC request - * @host: MMC host which completed request - * @mrq: MMC request which request - * - * MMC drivers should call this function when they have completed - * their processing of a request. - */ -void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) -{ - struct mmc_command *cmd = mrq->cmd; - int err = cmd->error; - - pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", - mmc_hostname(host), cmd->opcode, err, - mrq->data ? mrq->data->error : 0, - mrq->stop ? mrq->stop->error : 0, - cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); - - if (err && cmd->retries) { - cmd->retries--; - cmd->error = 0; - host->ops->request(host, mrq); - } else if (mrq->done) { - mrq->done(mrq); - } -} - -EXPORT_SYMBOL(mmc_request_done); - -/** - * mmc_start_request - start a command on a host - * @host: MMC host to start command on - * @mrq: MMC request to start - * - * Queue a command on the specified host. We expect the - * caller to be holding the host lock with interrupts disabled. - */ -void -mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) -{ -#ifdef CONFIG_MMC_DEBUG - unsigned int i, sz; -#endif - - pr_debug("%s: starting CMD%u arg %08x flags %08x\n", - mmc_hostname(host), mrq->cmd->opcode, - mrq->cmd->arg, mrq->cmd->flags); - - WARN_ON(!host->claimed); - - mrq->cmd->error = 0; - mrq->cmd->mrq = mrq; - if (mrq->data) { - BUG_ON(mrq->data->blksz > host->max_blk_size); - BUG_ON(mrq->data->blocks > host->max_blk_count); - BUG_ON(mrq->data->blocks * mrq->data->blksz > - host->max_req_size); - -#ifdef CONFIG_MMC_DEBUG - sz = 0; - for (i = 0;i < mrq->data->sg_len;i++) - sz += mrq->data->sg[i].length; - BUG_ON(sz != mrq->data->blocks * mrq->data->blksz); -#endif - - mrq->cmd->data = mrq->data; - mrq->data->error = 0; - mrq->data->mrq = mrq; - if (mrq->stop) { - mrq->data->stop = mrq->stop; - mrq->stop->error = 0; - mrq->stop->mrq = mrq; - } - } - host->ops->request(host, mrq); -} - -EXPORT_SYMBOL(mmc_start_request); - -static void mmc_wait_done(struct mmc_request *mrq) -{ - complete(mrq->done_data); -} - -int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) -{ - DECLARE_COMPLETION_ONSTACK(complete); - - mrq->done_data = &complete; - mrq->done = mmc_wait_done; - - mmc_start_request(host, mrq); - - wait_for_completion(&complete); - - return 0; -} - -EXPORT_SYMBOL(mmc_wait_for_req); - -/** - * mmc_wait_for_cmd - start a command and wait for completion - * @host: MMC host to start command - * @cmd: MMC command to start - * @retries: maximum number of retries - * - * Start a new MMC command for a host, and wait for the command - * to complete. Return any error that occurred while the command - * was executing. Do not attempt to parse the response. - */ -int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) -{ - struct mmc_request mrq; - - BUG_ON(!host->claimed); - - memset(&mrq, 0, sizeof(struct mmc_request)); - - memset(cmd->resp, 0, sizeof(cmd->resp)); - cmd->retries = retries; - - mrq.cmd = cmd; - cmd->data = NULL; - - mmc_wait_for_req(host, &mrq); - - return cmd->error; -} - -EXPORT_SYMBOL(mmc_wait_for_cmd); - -/** - * mmc_set_data_timeout - set the timeout for a data command - * @data: data phase for command - * @card: the MMC card associated with the data transfer - * @write: flag to differentiate reads from writes - */ -void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, - int write) -{ - unsigned int mult; - - /* - * SD cards use a 100 multiplier rather than 10 - */ - mult = mmc_card_sd(card) ? 100 : 10; - - /* - * Scale up the multiplier (and therefore the timeout) by - * the r2w factor for writes. - */ - if (write) - mult <<= card->csd.r2w_factor; - - data->timeout_ns = card->csd.tacc_ns * mult; - data->timeout_clks = card->csd.tacc_clks * mult; - - /* - * SD cards also have an upper limit on the timeout. - */ - if (mmc_card_sd(card)) { - unsigned int timeout_us, limit_us; - - timeout_us = data->timeout_ns / 1000; - timeout_us += data->timeout_clks * 1000 / - (card->host->ios.clock / 1000); - - if (write) - limit_us = 250000; - else - limit_us = 100000; - - /* - * SDHC cards always use these fixed values. - */ - if (timeout_us > limit_us || mmc_card_blockaddr(card)) { - data->timeout_ns = limit_us * 1000; - data->timeout_clks = 0; - } - } -} -EXPORT_SYMBOL(mmc_set_data_timeout); - -/** - * __mmc_claim_host - exclusively claim a host - * @host: mmc host to claim - * @card: mmc card to claim host for - * - * Claim a host for a set of operations. If a valid card - * is passed and this wasn't the last card selected, select - * the card before returning. - * - * Note: you should use mmc_card_claim_host or mmc_claim_host. - */ -void mmc_claim_host(struct mmc_host *host) -{ - DECLARE_WAITQUEUE(wait, current); - unsigned long flags; - - add_wait_queue(&host->wq, &wait); - spin_lock_irqsave(&host->lock, flags); - while (1) { - set_current_state(TASK_UNINTERRUPTIBLE); - if (!host->claimed) - break; - spin_unlock_irqrestore(&host->lock, flags); - schedule(); - spin_lock_irqsave(&host->lock, flags); - } - set_current_state(TASK_RUNNING); - host->claimed = 1; - spin_unlock_irqrestore(&host->lock, flags); - remove_wait_queue(&host->wq, &wait); -} - -EXPORT_SYMBOL(mmc_claim_host); - -/** - * mmc_release_host - release a host - * @host: mmc host to release - * - * Release a MMC host, allowing others to claim the host - * for their operations. - */ -void mmc_release_host(struct mmc_host *host) -{ - unsigned long flags; - - BUG_ON(!host->claimed); - - spin_lock_irqsave(&host->lock, flags); - host->claimed = 0; - spin_unlock_irqrestore(&host->lock, flags); - - wake_up(&host->wq); -} - -EXPORT_SYMBOL(mmc_release_host); - -/* - * Internal function that does the actual ios call to the host driver, - * optionally printing some debug output. - */ -static inline void mmc_set_ios(struct mmc_host *host) -{ - struct mmc_ios *ios = &host->ios; - - pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " - "width %u timing %u\n", - mmc_hostname(host), ios->clock, ios->bus_mode, - ios->power_mode, ios->chip_select, ios->vdd, - ios->bus_width, ios->timing); - - host->ops->set_ios(host, ios); -} - -/* - * Control chip select pin on a host. - */ -void mmc_set_chip_select(struct mmc_host *host, int mode) -{ - host->ios.chip_select = mode; - mmc_set_ios(host); -} - -/* - * Sets the host clock to the highest possible frequency that - * is below "hz". - */ -void mmc_set_clock(struct mmc_host *host, unsigned int hz) -{ - WARN_ON(hz < host->f_min); - - if (hz > host->f_max) - hz = host->f_max; - - host->ios.clock = hz; - mmc_set_ios(host); -} - -/* - * Change the bus mode (open drain/push-pull) of a host. - */ -void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode) -{ - host->ios.bus_mode = mode; - mmc_set_ios(host); -} - -/* - * Change data bus width of a host. - */ -void mmc_set_bus_width(struct mmc_host *host, unsigned int width) -{ - host->ios.bus_width = width; - mmc_set_ios(host); -} - -/* - * Mask off any voltages we don't support and select - * the lowest voltage - */ -u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) -{ - int bit; - - ocr &= host->ocr_avail; - - bit = ffs(ocr); - if (bit) { - bit -= 1; - - ocr &= 3 << bit; - - host->ios.vdd = bit; - mmc_set_ios(host); - } else { - ocr = 0; - } - - return ocr; -} - -/* - * Select timing parameters for host. - */ -void mmc_set_timing(struct mmc_host *host, unsigned int timing) -{ - host->ios.timing = timing; - mmc_set_ios(host); -} - -/* - * Allocate a new MMC card - */ -struct mmc_card *mmc_alloc_card(struct mmc_host *host) -{ - struct mmc_card *card; - - card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); - if (!card) - return ERR_PTR(-ENOMEM); - - mmc_init_card(card, host); - - return card; -} - -/* - * Apply power to the MMC stack. This is a two-stage process. - * First, we enable power to the card without the clock running. - * We then wait a bit for the power to stabilise. Finally, - * enable the bus drivers and clock to the card. - * - * We must _NOT_ enable the clock prior to power stablising. - * - * If a host does all the power sequencing itself, ignore the - * initial MMC_POWER_UP stage. - */ -static void mmc_power_up(struct mmc_host *host) -{ - int bit = fls(host->ocr_avail) - 1; - - host->ios.vdd = bit; - host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; - host->ios.chip_select = MMC_CS_DONTCARE; - host->ios.power_mode = MMC_POWER_UP; - host->ios.bus_width = MMC_BUS_WIDTH_1; - host->ios.timing = MMC_TIMING_LEGACY; - mmc_set_ios(host); - - mmc_delay(1); - - host->ios.clock = host->f_min; - host->ios.power_mode = MMC_POWER_ON; - mmc_set_ios(host); - - mmc_delay(2); -} - -static void mmc_power_off(struct mmc_host *host) -{ - host->ios.clock = 0; - host->ios.vdd = 0; - host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; - host->ios.chip_select = MMC_CS_DONTCARE; - host->ios.power_mode = MMC_POWER_OFF; - host->ios.bus_width = MMC_BUS_WIDTH_1; - host->ios.timing = MMC_TIMING_LEGACY; - mmc_set_ios(host); -} - -/* - * Assign a mmc bus handler to a host. Only one bus handler may control a - * host at any given time. - */ -void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops) -{ - unsigned long flags; - - BUG_ON(!host); - BUG_ON(!ops); - - BUG_ON(!host->claimed); - - spin_lock_irqsave(&host->lock, flags); - - BUG_ON(host->bus_ops); - BUG_ON(host->bus_refs); - - host->bus_ops = ops; - host->bus_refs = 1; - host->bus_dead = 0; - - spin_unlock_irqrestore(&host->lock, flags); -} - -/* - * Remove the current bus handler from a host. Assumes that there are - * no interesting cards left, so the bus is powered down. - */ -void mmc_detach_bus(struct mmc_host *host) -{ - unsigned long flags; - - BUG_ON(!host); - - BUG_ON(!host->claimed); - BUG_ON(!host->bus_ops); - - spin_lock_irqsave(&host->lock, flags); - - host->bus_dead = 1; - - spin_unlock_irqrestore(&host->lock, flags); - - mmc_power_off(host); - - mmc_bus_put(host); -} - -/* - * Cleanup when the last reference to the bus operator is dropped. - */ -void __mmc_release_bus(struct mmc_host *host) -{ - BUG_ON(!host); - BUG_ON(host->bus_refs); - BUG_ON(!host->bus_dead); - - host->bus_ops = NULL; -} - -/** - * mmc_detect_change - process change of state on a MMC socket - * @host: host which changed state. - * @delay: optional delay to wait before detection (jiffies) - * - * All we know is that card(s) have been inserted or removed - * from the socket(s). We don't know which socket or cards. - */ -void mmc_detect_change(struct mmc_host *host, unsigned long delay) -{ -#ifdef CONFIG_MMC_DEBUG - unsigned long flags; - spin_lock_irqsave(host->lock, flags); - BUG_ON(host->removed); - spin_unlock_irqrestore(host->lock, flags); -#endif - - mmc_schedule_delayed_work(&host->detect, delay); -} - -EXPORT_SYMBOL(mmc_detect_change); - - -static void mmc_rescan(struct work_struct *work) -{ - struct mmc_host *host = - container_of(work, struct mmc_host, detect.work); - u32 ocr; - int err; - - mmc_bus_get(host); - - if (host->bus_ops == NULL) { - /* - * Only we can add a new handler, so it's safe to - * release the lock here. - */ - mmc_bus_put(host); - - mmc_claim_host(host); - - mmc_power_up(host); - mmc_go_idle(host); - - mmc_send_if_cond(host, host->ocr_avail); - - err = mmc_send_app_op_cond(host, 0, &ocr); - if (err == MMC_ERR_NONE) { - if (mmc_attach_sd(host, ocr)) - mmc_power_off(host); - } else { - /* - * If we fail to detect any SD cards then try - * searching for MMC cards. - */ - err = mmc_send_op_cond(host, 0, &ocr); - if (err == MMC_ERR_NONE) { - if (mmc_attach_mmc(host, ocr)) - mmc_power_off(host); - } else { - mmc_power_off(host); - mmc_release_host(host); - } - } - } else { - if (host->bus_ops->detect && !host->bus_dead) - host->bus_ops->detect(host); - - mmc_bus_put(host); - } -} - - -/** - * mmc_alloc_host - initialise the per-host structure. - * @extra: sizeof private data structure - * @dev: pointer to host device model structure - * - * Initialise the per-host structure. - */ -struct mmc_host *mmc_alloc_host(int extra, struct device *dev) -{ - struct mmc_host *host; - - host = mmc_alloc_host_sysfs(extra, dev); - if (host) { - spin_lock_init(&host->lock); - init_waitqueue_head(&host->wq); - INIT_DELAYED_WORK(&host->detect, mmc_rescan); - - /* - * By default, hosts do not support SGIO or large requests. - * They have to set these according to their abilities. - */ - host->max_hw_segs = 1; - host->max_phys_segs = 1; - host->max_seg_size = PAGE_CACHE_SIZE; - - host->max_req_size = PAGE_CACHE_SIZE; - host->max_blk_size = 512; - host->max_blk_count = PAGE_CACHE_SIZE / 512; - } - - return host; -} - -EXPORT_SYMBOL(mmc_alloc_host); - -/** - * mmc_add_host - initialise host hardware - * @host: mmc host - */ -int mmc_add_host(struct mmc_host *host) -{ - int ret; - - ret = mmc_add_host_sysfs(host); - if (ret == 0) { - mmc_power_off(host); - mmc_detect_change(host, 0); - } - - return ret; -} - -EXPORT_SYMBOL(mmc_add_host); - -/** - * mmc_remove_host - remove host hardware - * @host: mmc host - * - * Unregister and remove all cards associated with this host, - * and power down the MMC bus. - */ -void mmc_remove_host(struct mmc_host *host) -{ -#ifdef CONFIG_MMC_DEBUG - unsigned long flags; - spin_lock_irqsave(&host->lock, flags); - host->removed = 1; - spin_unlock_irqrestore(&host->lock, flags); -#endif - - mmc_flush_scheduled_work(); - - mmc_bus_get(host); - if (host->bus_ops && !host->bus_dead) { - if (host->bus_ops->remove) - host->bus_ops->remove(host); - - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_release_host(host); - } - mmc_bus_put(host); - - BUG_ON(host->card); - - mmc_power_off(host); - mmc_remove_host_sysfs(host); -} - -EXPORT_SYMBOL(mmc_remove_host); - -/** - * mmc_free_host - free the host structure - * @host: mmc host - * - * Free the host once all references to it have been dropped. - */ -void mmc_free_host(struct mmc_host *host) -{ - mmc_free_host_sysfs(host); -} - -EXPORT_SYMBOL(mmc_free_host); - -#ifdef CONFIG_PM - -/** - * mmc_suspend_host - suspend a host - * @host: mmc host - * @state: suspend mode (PM_SUSPEND_xxx) - */ -int mmc_suspend_host(struct mmc_host *host, pm_message_t state) -{ - mmc_flush_scheduled_work(); - - mmc_bus_get(host); - if (host->bus_ops && !host->bus_dead) { - if (host->bus_ops->suspend) - host->bus_ops->suspend(host); - if (!host->bus_ops->resume) { - if (host->bus_ops->remove) - host->bus_ops->remove(host); - - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_release_host(host); - } - } - mmc_bus_put(host); - - mmc_power_off(host); - - return 0; -} - -EXPORT_SYMBOL(mmc_suspend_host); - -/** - * mmc_resume_host - resume a previously suspended host - * @host: mmc host - */ -int mmc_resume_host(struct mmc_host *host) -{ - mmc_bus_get(host); - if (host->bus_ops && !host->bus_dead) { - mmc_power_up(host); - BUG_ON(!host->bus_ops->resume); - host->bus_ops->resume(host); - } - mmc_bus_put(host); - - /* - * We add a slight delay here so that resume can progress - * in parallel. - */ - mmc_detect_change(host, 1); - - return 0; -} - -EXPORT_SYMBOL(mmc_resume_host); - -#endif - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mmc/core/core.h b/trunk/drivers/mmc/core/core.h deleted file mode 100644 index 177264d090ac..000000000000 --- a/trunk/drivers/mmc/core/core.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * linux/drivers/mmc/core/core.h - * - * Copyright (C) 2003 Russell King, All Rights Reserved. - * Copyright 2007 Pierre Ossman - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#ifndef _MMC_CORE_CORE_H -#define _MMC_CORE_CORE_H - -#include - -#define MMC_CMD_RETRIES 3 - -struct mmc_bus_ops { - void (*remove)(struct mmc_host *); - void (*detect)(struct mmc_host *); - void (*suspend)(struct mmc_host *); - void (*resume)(struct mmc_host *); -}; - -void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); -void mmc_detach_bus(struct mmc_host *host); - -void __mmc_release_bus(struct mmc_host *host); - -static inline void mmc_bus_get(struct mmc_host *host) -{ - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - host->bus_refs++; - spin_unlock_irqrestore(&host->lock, flags); -} - -static inline void mmc_bus_put(struct mmc_host *host) -{ - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - host->bus_refs--; - if ((host->bus_refs == 0) && host->bus_ops) - __mmc_release_bus(host); - spin_unlock_irqrestore(&host->lock, flags); -} - -void mmc_set_chip_select(struct mmc_host *host, int mode); -void mmc_set_clock(struct mmc_host *host, unsigned int hz); -void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); -void mmc_set_bus_width(struct mmc_host *host, unsigned int width); -u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); -void mmc_set_timing(struct mmc_host *host, unsigned int timing); - -struct mmc_card *mmc_alloc_card(struct mmc_host *host); - -static inline void mmc_delay(unsigned int ms) -{ - if (ms < 1000 / HZ) { - cond_resched(); - mdelay(ms); - } else { - msleep(ms); - } -} - -#endif - diff --git a/trunk/drivers/mmc/core/mmc.c b/trunk/drivers/mmc/core/mmc.c deleted file mode 100644 index 42cc2867ed7d..000000000000 --- a/trunk/drivers/mmc/core/mmc.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * linux/drivers/mmc/mmc.c - * - * Copyright (C) 2003-2004 Russell King, All Rights Reserved. - * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. - * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include - -#include -#include -#include - -#include "core.h" -#include "sysfs.h" -#include "mmc_ops.h" - -static const unsigned int tran_exp[] = { - 10000, 100000, 1000000, 10000000, - 0, 0, 0, 0 -}; - -static const unsigned char tran_mant[] = { - 0, 10, 12, 13, 15, 20, 25, 30, - 35, 40, 45, 50, 55, 60, 70, 80, -}; - -static const unsigned int tacc_exp[] = { - 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, -}; - -static const unsigned int tacc_mant[] = { - 0, 10, 12, 13, 15, 20, 25, 30, - 35, 40, 45, 50, 55, 60, 70, 80, -}; - -#define UNSTUFF_BITS(resp,start,size) \ - ({ \ - const int __size = size; \ - const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ - const int __off = 3 - ((start) / 32); \ - const int __shft = (start) & 31; \ - u32 __res; \ - \ - __res = resp[__off] >> __shft; \ - if (__size + __shft > 32) \ - __res |= resp[__off-1] << ((32 - __shft) % 32); \ - __res & __mask; \ - }) - -/* - * Given the decoded CSD structure, decode the raw CID to our CID structure. - */ -static int mmc_decode_cid(struct mmc_card *card) -{ - u32 *resp = card->raw_cid; - - /* - * The selection of the format here is based upon published - * specs from sandisk and from what people have reported. - */ - switch (card->csd.mmca_vsn) { - case 0: /* MMC v1.0 - v1.2 */ - case 1: /* MMC v1.4 */ - card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); - card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); - card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); - card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); - card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); - card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); - card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); - card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); - card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); - card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); - card->cid.serial = UNSTUFF_BITS(resp, 16, 24); - card->cid.month = UNSTUFF_BITS(resp, 12, 4); - card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; - break; - - case 2: /* MMC v2.0 - v2.2 */ - case 3: /* MMC v3.1 - v3.3 */ - case 4: /* MMC v4 */ - card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); - card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); - card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); - card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); - card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); - card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); - card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); - card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); - card->cid.serial = UNSTUFF_BITS(resp, 16, 32); - card->cid.month = UNSTUFF_BITS(resp, 12, 4); - card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; - break; - - default: - printk("%s: card has unknown MMCA version %d\n", - mmc_hostname(card->host), card->csd.mmca_vsn); - return -EINVAL; - } - - return 0; -} - -/* - * Given a 128-bit response, decode to our card CSD structure. - */ -static int mmc_decode_csd(struct mmc_card *card) -{ - struct mmc_csd *csd = &card->csd; - unsigned int e, m, csd_struct; - u32 *resp = card->raw_csd; - - /* - * We only understand CSD structure v1.1 and v1.2. - * v1.2 has extra information in bits 15, 11 and 10. - */ - csd_struct = UNSTUFF_BITS(resp, 126, 2); - if (csd_struct != 1 && csd_struct != 2) { - printk("%s: unrecognised CSD structure version %d\n", - mmc_hostname(card->host), csd_struct); - return -EINVAL; - } - - csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); - m = UNSTUFF_BITS(resp, 115, 4); - e = UNSTUFF_BITS(resp, 112, 3); - csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; - csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; - - m = UNSTUFF_BITS(resp, 99, 4); - e = UNSTUFF_BITS(resp, 96, 3); - csd->max_dtr = tran_exp[e] * tran_mant[m]; - csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); - - e = UNSTUFF_BITS(resp, 47, 3); - m = UNSTUFF_BITS(resp, 62, 12); - csd->capacity = (1 + m) << (e + 2); - - csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); - csd->read_partial = UNSTUFF_BITS(resp, 79, 1); - csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); - csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); - csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); - csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); - csd->write_partial = UNSTUFF_BITS(resp, 21, 1); - - return 0; -} - -/* - * Read and decode extended CSD. - */ -static int mmc_read_ext_csd(struct mmc_card *card) -{ - int err; - u8 *ext_csd; - - BUG_ON(!card); - - err = MMC_ERR_FAILED; - - if (card->csd.mmca_vsn < CSD_SPEC_VER_4) - return MMC_ERR_NONE; - - /* - * As the ext_csd is so large and mostly unused, we don't store the - * raw block in mmc_card. - */ - ext_csd = kmalloc(512, GFP_KERNEL); - if (!ext_csd) { - printk(KERN_ERR "%s: could not allocate a buffer to " - "receive the ext_csd. mmc v4 cards will be " - "treated as v3.\n", mmc_hostname(card->host)); - return MMC_ERR_FAILED; - } - - err = mmc_send_ext_csd(card, ext_csd); - if (err != MMC_ERR_NONE) { - /* - * High capacity cards should have this "magic" size - * stored in their CSD. - */ - if (card->csd.capacity == (4096 * 512)) { - printk(KERN_ERR "%s: unable to read EXT_CSD " - "on a possible high capacity card. " - "Card will be ignored.\n", - mmc_hostname(card->host)); - } else { - printk(KERN_WARNING "%s: unable to read " - "EXT_CSD, performance might " - "suffer.\n", - mmc_hostname(card->host)); - err = MMC_ERR_NONE; - } - goto out; - } - - card->ext_csd.sectors = - ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | - ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | - ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | - ext_csd[EXT_CSD_SEC_CNT + 3] << 24; - if (card->ext_csd.sectors) - mmc_card_set_blockaddr(card); - - switch (ext_csd[EXT_CSD_CARD_TYPE]) { - case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: - card->ext_csd.hs_max_dtr = 52000000; - break; - case EXT_CSD_CARD_TYPE_26: - card->ext_csd.hs_max_dtr = 26000000; - break; - default: - /* MMC v4 spec says this cannot happen */ - printk(KERN_WARNING "%s: card is mmc v4 but doesn't " - "support any high-speed modes.\n", - mmc_hostname(card->host)); - goto out; - } - -out: - kfree(ext_csd); - - return err; -} - -/* - * Handle the detection and initialisation of a card. - * - * In the case of a resume, "curcard" will contain the card - * we're trying to reinitialise. - */ -static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, - struct mmc_card *oldcard) -{ - struct mmc_card *card; - int err; - u32 cid[4]; - unsigned int max_dtr; - - BUG_ON(!host); - BUG_ON(!host->claimed); - - /* - * Since we're changing the OCR value, we seem to - * need to tell some cards to go back to the idle - * state. We wait 1ms to give cards time to - * respond. - */ - mmc_go_idle(host); - - /* The extra bit indicates that we support high capacity */ - err = mmc_send_op_cond(host, ocr | (1 << 30), NULL); - if (err != MMC_ERR_NONE) - goto err; - - /* - * Fetch CID from card. - */ - err = mmc_all_send_cid(host, cid); - if (err != MMC_ERR_NONE) - goto err; - - if (oldcard) { - if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) - goto err; - - card = oldcard; - } else { - /* - * Allocate card structure. - */ - card = mmc_alloc_card(host); - if (IS_ERR(card)) - goto err; - - card->type = MMC_TYPE_MMC; - card->rca = 1; - memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); - } - - /* - * Set card RCA. - */ - err = mmc_set_relative_addr(card); - if (err != MMC_ERR_NONE) - goto free_card; - - mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); - - if (!oldcard) { - /* - * Fetch CSD from card. - */ - err = mmc_send_csd(card, card->raw_csd); - if (err != MMC_ERR_NONE) - goto free_card; - - err = mmc_decode_csd(card); - if (err < 0) - goto free_card; - err = mmc_decode_cid(card); - if (err < 0) - goto free_card; - } - - /* - * Select card, as all following commands rely on that. - */ - err = mmc_select_card(card); - if (err != MMC_ERR_NONE) - goto free_card; - - if (!oldcard) { - /* - * Fetch and process extened CSD. - */ - err = mmc_read_ext_csd(card); - if (err != MMC_ERR_NONE) - goto free_card; - } - - /* - * Activate high speed (if supported) - */ - if ((card->ext_csd.hs_max_dtr != 0) && - (host->caps & MMC_CAP_MMC_HIGHSPEED)) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, 1); - if (err != MMC_ERR_NONE) - goto free_card; - - mmc_card_set_highspeed(card); - - mmc_set_timing(card->host, MMC_TIMING_MMC_HS); - } - - /* - * Compute bus speed. - */ - max_dtr = (unsigned int)-1; - - if (mmc_card_highspeed(card)) { - if (max_dtr > card->ext_csd.hs_max_dtr) - max_dtr = card->ext_csd.hs_max_dtr; - } else if (max_dtr > card->csd.max_dtr) { - max_dtr = card->csd.max_dtr; - } - - mmc_set_clock(host, max_dtr); - - /* - * Activate wide bus (if supported). - */ - if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && - (host->caps & MMC_CAP_4_BIT_DATA)) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_4); - if (err != MMC_ERR_NONE) - goto free_card; - - mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); - } - - if (!oldcard) - host->card = card; - - return MMC_ERR_NONE; - -free_card: - if (!oldcard) - mmc_remove_card(card); -err: - - return MMC_ERR_FAILED; -} - -/* - * Host is being removed. Free up the current card. - */ -static void mmc_remove(struct mmc_host *host) -{ - BUG_ON(!host); - BUG_ON(!host->card); - - mmc_remove_card(host->card); - host->card = NULL; -} - -/* - * Card detection callback from host. - */ -static void mmc_detect(struct mmc_host *host) -{ - int err; - - BUG_ON(!host); - BUG_ON(!host->card); - - mmc_claim_host(host); - - /* - * Just check if our card has been removed. - */ - err = mmc_send_status(host->card, NULL); - - mmc_release_host(host); - - if (err != MMC_ERR_NONE) { - mmc_remove_card(host->card); - host->card = NULL; - - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_release_host(host); - } -} - -#ifdef CONFIG_MMC_UNSAFE_RESUME - -/* - * Suspend callback from host. - */ -static void mmc_suspend(struct mmc_host *host) -{ - BUG_ON(!host); - BUG_ON(!host->card); - - mmc_claim_host(host); - mmc_deselect_cards(host); - host->card->state &= ~MMC_STATE_HIGHSPEED; - mmc_release_host(host); -} - -/* - * Resume callback from host. - * - * This function tries to determine if the same card is still present - * and, if so, restore all state to it. - */ -static void mmc_resume(struct mmc_host *host) -{ - int err; - - BUG_ON(!host); - BUG_ON(!host->card); - - mmc_claim_host(host); - - err = mmc_sd_init_card(host, host->ocr, host->card); - if (err != MMC_ERR_NONE) { - mmc_remove_card(host->card); - host->card = NULL; - - mmc_detach_bus(host); - } - - mmc_release_host(host); -} - -#else - -#define mmc_suspend NULL -#define mmc_resume NULL - -#endif - -static const struct mmc_bus_ops mmc_ops = { - .remove = mmc_remove, - .detect = mmc_detect, - .suspend = mmc_suspend, - .resume = mmc_resume, -}; - -/* - * Starting point for MMC card init. - */ -int mmc_attach_mmc(struct mmc_host *host, u32 ocr) -{ - int err; - - BUG_ON(!host); - BUG_ON(!host->claimed); - - mmc_attach_bus(host, &mmc_ops); - - /* - * Sanity check the voltages that the card claims to - * support. - */ - if (ocr & 0x7F) { - printk(KERN_WARNING "%s: card claims to support voltages " - "below the defined range. These will be ignored.\n", - mmc_hostname(host)); - ocr &= ~0x7F; - } - - host->ocr = mmc_select_voltage(host, ocr); - - /* - * Can we support the voltage of the card? - */ - if (!host->ocr) - goto err; - - /* - * Detect and init the card. - */ - err = mmc_sd_init_card(host, host->ocr, NULL); - if (err != MMC_ERR_NONE) - goto err; - - mmc_release_host(host); - - err = mmc_register_card(host->card); - if (err) - goto reclaim_host; - - return 0; - -reclaim_host: - mmc_claim_host(host); - mmc_remove_card(host->card); - host->card = NULL; -err: - mmc_detach_bus(host); - mmc_release_host(host); - - return 0; -} - diff --git a/trunk/drivers/mmc/core/mmc_ops.c b/trunk/drivers/mmc/core/mmc_ops.c deleted file mode 100644 index 7dd720fa5895..000000000000 --- a/trunk/drivers/mmc/core/mmc_ops.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * linux/drivers/mmc/mmc_ops.h - * - * Copyright 2006-2007 Pierre Ossman - * - * 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 "core.h" -#include "mmc_ops.h" - -static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!host); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SELECT_CARD; - - if (card) { - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - } else { - cmd.arg = 0; - cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; - } - - err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - return err; - - return MMC_ERR_NONE; -} - -int mmc_select_card(struct mmc_card *card) -{ - BUG_ON(!card); - - return _mmc_select_card(card->host, card); -} - -int mmc_deselect_cards(struct mmc_host *host) -{ - return _mmc_select_card(host, NULL); -} - -int mmc_go_idle(struct mmc_host *host) -{ - int err; - struct mmc_command cmd; - - mmc_set_chip_select(host, MMC_CS_HIGH); - - mmc_delay(1); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_GO_IDLE_STATE; - cmd.arg = 0; - cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; - - err = mmc_wait_for_cmd(host, &cmd, 0); - - mmc_delay(1); - - mmc_set_chip_select(host, MMC_CS_DONTCARE); - - mmc_delay(1); - - return err; -} - -int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) -{ - struct mmc_command cmd; - int i, err = 0; - - BUG_ON(!host); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SEND_OP_COND; - cmd.arg = ocr; - cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; - - for (i = 100; i; i--) { - err = mmc_wait_for_cmd(host, &cmd, 0); - if (err != MMC_ERR_NONE) - break; - - if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) - break; - - err = MMC_ERR_TIMEOUT; - - mmc_delay(10); - } - - if (rocr) - *rocr = cmd.resp[0]; - - return err; -} - -int mmc_all_send_cid(struct mmc_host *host, u32 *cid) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!host); - BUG_ON(!cid); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_ALL_SEND_CID; - cmd.arg = 0; - cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; - - err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - return err; - - memcpy(cid, cmd.resp, sizeof(u32) * 4); - - return MMC_ERR_NONE; -} - -int mmc_set_relative_addr(struct mmc_card *card) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!card); - BUG_ON(!card->host); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SET_RELATIVE_ADDR; - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - return err; - - return MMC_ERR_NONE; -} - -int mmc_send_csd(struct mmc_card *card, u32 *csd) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!card); - BUG_ON(!card->host); - BUG_ON(!csd); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SEND_CSD; - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - return err; - - memcpy(csd, cmd.resp, sizeof(u32) * 4); - - return MMC_ERR_NONE; -} - -int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) -{ - struct mmc_request mrq; - struct mmc_command cmd; - struct mmc_data data; - struct scatterlist sg; - - BUG_ON(!card); - BUG_ON(!card->host); - BUG_ON(!ext_csd); - - memset(&mrq, 0, sizeof(struct mmc_request)); - memset(&cmd, 0, sizeof(struct mmc_command)); - memset(&data, 0, sizeof(struct mmc_data)); - - mrq.cmd = &cmd; - mrq.data = &data; - - cmd.opcode = MMC_SEND_EXT_CSD; - cmd.arg = 0; - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; - - data.blksz = 512; - data.blocks = 1; - data.flags = MMC_DATA_READ; - data.sg = &sg; - data.sg_len = 1; - - sg_init_one(&sg, ext_csd, 512); - - mmc_set_data_timeout(&data, card, 0); - - mmc_wait_for_req(card->host, &mrq); - - if (cmd.error != MMC_ERR_NONE) - return cmd.error; - if (data.error != MMC_ERR_NONE) - return data.error; - - return MMC_ERR_NONE; -} - -int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!card); - BUG_ON(!card->host); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SWITCH; - cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | - (index << 16) | - (value << 8) | - set; - cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - return err; - - return MMC_ERR_NONE; -} - -int mmc_send_status(struct mmc_card *card, u32 *status) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!card); - BUG_ON(!card->host); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = MMC_SEND_STATUS; - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - return err; - - if (status) - *status = cmd.resp[0]; - - return MMC_ERR_NONE; -} - diff --git a/trunk/drivers/mmc/core/mmc_ops.h b/trunk/drivers/mmc/core/mmc_ops.h deleted file mode 100644 index 7a481e8ca5ea..000000000000 --- a/trunk/drivers/mmc/core/mmc_ops.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/drivers/mmc/mmc_ops.h - * - * Copyright 2006-2007 Pierre Ossman - * - * 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. - */ - -#ifndef _MMC_MMC_OPS_H -#define _MMC_MMC_OPS_H - -int mmc_select_card(struct mmc_card *card); -int mmc_deselect_cards(struct mmc_host *host); -int mmc_go_idle(struct mmc_host *host); -int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); -int mmc_all_send_cid(struct mmc_host *host, u32 *cid); -int mmc_set_relative_addr(struct mmc_card *card); -int mmc_send_csd(struct mmc_card *card, u32 *csd); -int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd); -int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value); -int mmc_send_status(struct mmc_card *card, u32 *status); - -#endif - diff --git a/trunk/drivers/mmc/core/sd.c b/trunk/drivers/mmc/core/sd.c deleted file mode 100644 index c1dfd03d559a..000000000000 --- a/trunk/drivers/mmc/core/sd.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * linux/drivers/mmc/sd.c - * - * Copyright (C) 2003-2004 Russell King, All Rights Reserved. - * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. - * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include - -#include -#include -#include - -#include "core.h" -#include "sysfs.h" -#include "mmc_ops.h" -#include "sd_ops.h" - -#include "core.h" - -static const unsigned int tran_exp[] = { - 10000, 100000, 1000000, 10000000, - 0, 0, 0, 0 -}; - -static const unsigned char tran_mant[] = { - 0, 10, 12, 13, 15, 20, 25, 30, - 35, 40, 45, 50, 55, 60, 70, 80, -}; - -static const unsigned int tacc_exp[] = { - 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, -}; - -static const unsigned int tacc_mant[] = { - 0, 10, 12, 13, 15, 20, 25, 30, - 35, 40, 45, 50, 55, 60, 70, 80, -}; - -#define UNSTUFF_BITS(resp,start,size) \ - ({ \ - const int __size = size; \ - const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ - const int __off = 3 - ((start) / 32); \ - const int __shft = (start) & 31; \ - u32 __res; \ - \ - __res = resp[__off] >> __shft; \ - if (__size + __shft > 32) \ - __res |= resp[__off-1] << ((32 - __shft) % 32); \ - __res & __mask; \ - }) - -/* - * Given the decoded CSD structure, decode the raw CID to our CID structure. - */ -static void mmc_decode_cid(struct mmc_card *card) -{ - u32 *resp = card->raw_cid; - - memset(&card->cid, 0, sizeof(struct mmc_cid)); - - /* - * SD doesn't currently have a version field so we will - * have to assume we can parse this. - */ - card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); - card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); - card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); - card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); - card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); - card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); - card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); - card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4); - card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4); - card->cid.serial = UNSTUFF_BITS(resp, 24, 32); - card->cid.year = UNSTUFF_BITS(resp, 12, 8); - card->cid.month = UNSTUFF_BITS(resp, 8, 4); - - card->cid.year += 2000; /* SD cards year offset */ -} - -/* - * Given a 128-bit response, decode to our card CSD structure. - */ -static int mmc_decode_csd(struct mmc_card *card) -{ - struct mmc_csd *csd = &card->csd; - unsigned int e, m, csd_struct; - u32 *resp = card->raw_csd; - - csd_struct = UNSTUFF_BITS(resp, 126, 2); - - switch (csd_struct) { - case 0: - m = UNSTUFF_BITS(resp, 115, 4); - e = UNSTUFF_BITS(resp, 112, 3); - csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; - csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; - - m = UNSTUFF_BITS(resp, 99, 4); - e = UNSTUFF_BITS(resp, 96, 3); - csd->max_dtr = tran_exp[e] * tran_mant[m]; - csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); - - e = UNSTUFF_BITS(resp, 47, 3); - m = UNSTUFF_BITS(resp, 62, 12); - csd->capacity = (1 + m) << (e + 2); - - csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); - csd->read_partial = UNSTUFF_BITS(resp, 79, 1); - csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); - csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); - csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); - csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); - csd->write_partial = UNSTUFF_BITS(resp, 21, 1); - break; - case 1: - /* - * This is a block-addressed SDHC card. Most - * interesting fields are unused and have fixed - * values. To avoid getting tripped by buggy cards, - * we assume those fixed values ourselves. - */ - mmc_card_set_blockaddr(card); - - csd->tacc_ns = 0; /* Unused */ - csd->tacc_clks = 0; /* Unused */ - - m = UNSTUFF_BITS(resp, 99, 4); - e = UNSTUFF_BITS(resp, 96, 3); - csd->max_dtr = tran_exp[e] * tran_mant[m]; - csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); - - m = UNSTUFF_BITS(resp, 48, 22); - csd->capacity = (1 + m) << 10; - - csd->read_blkbits = 9; - csd->read_partial = 0; - csd->write_misalign = 0; - csd->read_misalign = 0; - csd->r2w_factor = 4; /* Unused */ - csd->write_blkbits = 9; - csd->write_partial = 0; - break; - default: - printk("%s: unrecognised CSD structure version %d\n", - mmc_hostname(card->host), csd_struct); - return -EINVAL; - } - - return 0; -} - -/* - * Given a 64-bit response, decode to our card SCR structure. - */ -static int mmc_decode_scr(struct mmc_card *card) -{ - struct sd_scr *scr = &card->scr; - unsigned int scr_struct; - u32 resp[4]; - - BUG_ON(!mmc_card_sd(card)); - - resp[3] = card->raw_scr[1]; - resp[2] = card->raw_scr[0]; - - scr_struct = UNSTUFF_BITS(resp, 60, 4); - if (scr_struct != 0) { - printk("%s: unrecognised SCR structure version %d\n", - mmc_hostname(card->host), scr_struct); - return -EINVAL; - } - - scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); - scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); - - return 0; -} - -/* - * Fetches and decodes switch information - */ -static int mmc_read_switch(struct mmc_card *card) -{ - int err; - u8 *status; - - err = MMC_ERR_FAILED; - - status = kmalloc(64, GFP_KERNEL); - if (!status) { - printk("%s: could not allocate a buffer for switch " - "capabilities.\n", - mmc_hostname(card->host)); - return err; - } - - err = mmc_sd_switch(card, 0, 0, 1, status); - if (err != MMC_ERR_NONE) { - /* - * Card not supporting high-speed will ignore the - * command. - */ - err = MMC_ERR_NONE; - goto out; - } - - if (status[13] & 0x02) - card->sw_caps.hs_max_dtr = 50000000; - -out: - kfree(status); - - return err; -} - -/* - * Test if the card supports high-speed mode and, if so, switch to it. - */ -static int mmc_switch_hs(struct mmc_card *card) -{ - int err; - u8 *status; - - if (!(card->host->caps & MMC_CAP_SD_HIGHSPEED)) - return MMC_ERR_NONE; - - if (card->sw_caps.hs_max_dtr == 0) - return MMC_ERR_NONE; - - err = MMC_ERR_FAILED; - - status = kmalloc(64, GFP_KERNEL); - if (!status) { - printk("%s: could not allocate a buffer for switch " - "capabilities.\n", - mmc_hostname(card->host)); - return err; - } - - err = mmc_sd_switch(card, 1, 0, 1, status); - if (err != MMC_ERR_NONE) - goto out; - - if ((status[16] & 0xF) != 1) { - printk(KERN_WARNING "%s: Problem switching card " - "into high-speed mode!\n", - mmc_hostname(card->host)); - } else { - mmc_card_set_highspeed(card); - mmc_set_timing(card->host, MMC_TIMING_SD_HS); - } - -out: - kfree(status); - - return err; -} - -/* - * Handle the detection and initialisation of a card. - * - * In the case of a resume, "curcard" will contain the card - * we're trying to reinitialise. - */ -static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, - struct mmc_card *oldcard) -{ - struct mmc_card *card; - int err; - u32 cid[4]; - unsigned int max_dtr; - - BUG_ON(!host); - BUG_ON(!host->claimed); - - /* - * Since we're changing the OCR value, we seem to - * need to tell some cards to go back to the idle - * state. We wait 1ms to give cards time to - * respond. - */ - mmc_go_idle(host); - - /* - * If SD_SEND_IF_COND indicates an SD 2.0 - * compliant card and we should set bit 30 - * of the ocr to indicate that we can handle - * block-addressed SDHC cards. - */ - err = mmc_send_if_cond(host, ocr); - if (err == MMC_ERR_NONE) - ocr |= 1 << 30; - - err = mmc_send_app_op_cond(host, ocr, NULL); - if (err != MMC_ERR_NONE) - goto err; - - /* - * Fetch CID from card. - */ - err = mmc_all_send_cid(host, cid); - if (err != MMC_ERR_NONE) - goto err; - - if (oldcard) { - if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) - goto err; - - card = oldcard; - } else { - /* - * Allocate card structure. - */ - card = mmc_alloc_card(host); - if (IS_ERR(card)) - goto err; - - card->type = MMC_TYPE_SD; - memcpy(card->raw_cid, cid, sizeof(card->raw_cid)); - } - - /* - * Set card RCA. - */ - err = mmc_send_relative_addr(host, &card->rca); - if (err != MMC_ERR_NONE) - goto free_card; - - mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); - - if (!oldcard) { - /* - * Fetch CSD from card. - */ - err = mmc_send_csd(card, card->raw_csd); - if (err != MMC_ERR_NONE) - goto free_card; - - err = mmc_decode_csd(card); - if (err < 0) - goto free_card; - - mmc_decode_cid(card); - } - - /* - * Select card, as all following commands rely on that. - */ - err = mmc_select_card(card); - if (err != MMC_ERR_NONE) - goto free_card; - - if (!oldcard) { - /* - * Fetch SCR from card. - */ - err = mmc_app_send_scr(card, card->raw_scr); - if (err != MMC_ERR_NONE) - goto free_card; - - err = mmc_decode_scr(card); - if (err < 0) - goto free_card; - - /* - * Fetch switch information from card. - */ - err = mmc_read_switch(card); - if (err != MMC_ERR_NONE) - goto free_card; - } - - /* - * Attempt to change to high-speed (if supported) - */ - err = mmc_switch_hs(card); - if (err != MMC_ERR_NONE) - goto free_card; - - /* - * Compute bus speed. - */ - max_dtr = (unsigned int)-1; - - if (mmc_card_highspeed(card)) { - if (max_dtr > card->sw_caps.hs_max_dtr) - max_dtr = card->sw_caps.hs_max_dtr; - } else if (max_dtr > card->csd.max_dtr) { - max_dtr = card->csd.max_dtr; - } - - mmc_set_clock(host, max_dtr); - - /* - * Switch to wider bus (if supported). - */ - if ((host->caps && MMC_CAP_4_BIT_DATA) && - (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { - err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4); - if (err != MMC_ERR_NONE) - goto free_card; - - mmc_set_bus_width(host, MMC_BUS_WIDTH_4); - } - - if (!oldcard) - host->card = card; - - return MMC_ERR_NONE; - -free_card: - if (!oldcard) - mmc_remove_card(card); -err: - - return MMC_ERR_FAILED; -} - -/* - * Host is being removed. Free up the current card. - */ -static void mmc_sd_remove(struct mmc_host *host) -{ - BUG_ON(!host); - BUG_ON(!host->card); - - mmc_remove_card(host->card); - host->card = NULL; -} - -/* - * Card detection callback from host. - */ -static void mmc_sd_detect(struct mmc_host *host) -{ - int err; - - BUG_ON(!host); - BUG_ON(!host->card); - - mmc_claim_host(host); - - /* - * Just check if our card has been removed. - */ - err = mmc_send_status(host->card, NULL); - - mmc_release_host(host); - - if (err != MMC_ERR_NONE) { - mmc_remove_card(host->card); - host->card = NULL; - - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_release_host(host); - } -} - -#ifdef CONFIG_MMC_UNSAFE_RESUME - -/* - * Suspend callback from host. - */ -static void mmc_sd_suspend(struct mmc_host *host) -{ - BUG_ON(!host); - BUG_ON(!host->card); - - mmc_claim_host(host); - mmc_deselect_cards(host); - host->card->state &= ~MMC_STATE_HIGHSPEED; - mmc_release_host(host); -} - -/* - * Resume callback from host. - * - * This function tries to determine if the same card is still present - * and, if so, restore all state to it. - */ -static void mmc_sd_resume(struct mmc_host *host) -{ - int err; - - BUG_ON(!host); - BUG_ON(!host->card); - - mmc_claim_host(host); - - err = mmc_sd_init_card(host, host->ocr, host->card); - if (err != MMC_ERR_NONE) { - mmc_remove_card(host->card); - host->card = NULL; - - mmc_detach_bus(host); - } - - mmc_release_host(host); -} - -#else - -#define mmc_sd_suspend NULL -#define mmc_sd_resume NULL - -#endif - -static const struct mmc_bus_ops mmc_sd_ops = { - .remove = mmc_sd_remove, - .detect = mmc_sd_detect, - .suspend = mmc_sd_suspend, - .resume = mmc_sd_resume, -}; - -/* - * Starting point for SD card init. - */ -int mmc_attach_sd(struct mmc_host *host, u32 ocr) -{ - int err; - - BUG_ON(!host); - BUG_ON(!host->claimed); - - mmc_attach_bus(host, &mmc_sd_ops); - - /* - * Sanity check the voltages that the card claims to - * support. - */ - if (ocr & 0x7F) { - printk(KERN_WARNING "%s: card claims to support voltages " - "below the defined range. These will be ignored.\n", - mmc_hostname(host)); - ocr &= ~0x7F; - } - - if (ocr & MMC_VDD_165_195) { - printk(KERN_WARNING "%s: SD card claims to support the " - "incompletely defined 'low voltage range'. This " - "will be ignored.\n", mmc_hostname(host)); - ocr &= ~MMC_VDD_165_195; - } - - host->ocr = mmc_select_voltage(host, ocr); - - /* - * Can we support the voltage(s) of the card(s)? - */ - if (!host->ocr) - goto err; - - /* - * Detect and init the card. - */ - err = mmc_sd_init_card(host, host->ocr, NULL); - if (err != MMC_ERR_NONE) - goto err; - - mmc_release_host(host); - - err = mmc_register_card(host->card); - if (err) - goto reclaim_host; - - return 0; - -reclaim_host: - mmc_claim_host(host); - mmc_remove_card(host->card); - host->card = NULL; -err: - mmc_detach_bus(host); - mmc_release_host(host); - - return 0; -} - diff --git a/trunk/drivers/mmc/core/sd_ops.c b/trunk/drivers/mmc/core/sd_ops.c deleted file mode 100644 index 9697ce581101..000000000000 --- a/trunk/drivers/mmc/core/sd_ops.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * linux/drivers/mmc/sd_ops.h - * - * Copyright 2006-2007 Pierre Ossman - * - * 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 "core.h" -#include "sd_ops.h" - -/** - * mmc_wait_for_app_cmd - start an application command and wait for - completion - * @host: MMC host to start command - * @rca: RCA to send MMC_APP_CMD to - * @cmd: MMC command to start - * @retries: maximum number of retries - * - * Sends a MMC_APP_CMD, checks the card response, sends the command - * in the parameter and waits for it to complete. Return any error - * that occurred while the command was executing. Do not attempt to - * parse the response. - */ -int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card, - struct mmc_command *cmd, int retries) -{ - struct mmc_request mrq; - - int i, err; - - BUG_ON(!cmd); - BUG_ON(retries < 0); - - err = MMC_ERR_INVALID; - - /* - * We have to resend MMC_APP_CMD for each attempt so - * we cannot use the retries field in mmc_command. - */ - for (i = 0;i <= retries;i++) { - memset(&mrq, 0, sizeof(struct mmc_request)); - - err = mmc_app_cmd(host, card); - if (err != MMC_ERR_NONE) - continue; - - memset(&mrq, 0, sizeof(struct mmc_request)); - - memset(cmd->resp, 0, sizeof(cmd->resp)); - cmd->retries = 0; - - mrq.cmd = cmd; - cmd->data = NULL; - - mmc_wait_for_req(host, &mrq); - - err = cmd->error; - if (cmd->error == MMC_ERR_NONE) - break; - } - - return err; -} - -EXPORT_SYMBOL(mmc_wait_for_app_cmd); - -int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!host); - BUG_ON(card && (card->host != host)); - - cmd.opcode = MMC_APP_CMD; - - if (card) { - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - } else { - cmd.arg = 0; - cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR; - } - - err = mmc_wait_for_cmd(host, &cmd, 0); - if (err != MMC_ERR_NONE) - return err; - - /* Check that card supported application commands */ - if (!(cmd.resp[0] & R1_APP_CMD)) - return MMC_ERR_FAILED; - - return MMC_ERR_NONE; -} - -int mmc_app_set_bus_width(struct mmc_card *card, int width) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!card); - BUG_ON(!card->host); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = SD_APP_SET_BUS_WIDTH; - cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; - - switch (width) { - case MMC_BUS_WIDTH_1: - cmd.arg = SD_BUS_WIDTH_1; - break; - case MMC_BUS_WIDTH_4: - cmd.arg = SD_BUS_WIDTH_4; - break; - default: - return MMC_ERR_INVALID; - } - - err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - return err; - - return MMC_ERR_NONE; -} - -int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) -{ - struct mmc_command cmd; - int i, err = 0; - - BUG_ON(!host); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = SD_APP_OP_COND; - cmd.arg = ocr; - cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; - - for (i = 100; i; i--) { - err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - break; - - if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) - break; - - err = MMC_ERR_TIMEOUT; - - mmc_delay(10); - } - - if (rocr) - *rocr = cmd.resp[0]; - - return err; -} - -int mmc_send_if_cond(struct mmc_host *host, u32 ocr) -{ - struct mmc_command cmd; - int err; - static const u8 test_pattern = 0xAA; - - /* - * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND - * before SD_APP_OP_COND. This command will harmlessly fail for - * SD 1.0 cards. - */ - cmd.opcode = SD_SEND_IF_COND; - cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; - cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; - - err = mmc_wait_for_cmd(host, &cmd, 0); - if (err != MMC_ERR_NONE) - return err; - - if ((cmd.resp[0] & 0xFF) != test_pattern) - return MMC_ERR_FAILED; - - return MMC_ERR_NONE; -} - -int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca) -{ - int err; - struct mmc_command cmd; - - BUG_ON(!host); - BUG_ON(!rca); - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = SD_SEND_RELATIVE_ADDR; - cmd.arg = 0; - cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; - - err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); - if (err != MMC_ERR_NONE) - return err; - - *rca = cmd.resp[0] >> 16; - - return MMC_ERR_NONE; -} - -int mmc_app_send_scr(struct mmc_card *card, u32 *scr) -{ - int err; - struct mmc_request mrq; - struct mmc_command cmd; - struct mmc_data data; - struct scatterlist sg; - - BUG_ON(!card); - BUG_ON(!card->host); - BUG_ON(!scr); - - err = mmc_app_cmd(card->host, card); - if (err != MMC_ERR_NONE) - return err; - - memset(&mrq, 0, sizeof(struct mmc_request)); - memset(&cmd, 0, sizeof(struct mmc_command)); - memset(&data, 0, sizeof(struct mmc_data)); - - mrq.cmd = &cmd; - mrq.data = &data; - - cmd.opcode = SD_APP_SEND_SCR; - cmd.arg = 0; - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; - - data.blksz = 8; - data.blocks = 1; - data.flags = MMC_DATA_READ; - data.sg = &sg; - data.sg_len = 1; - - sg_init_one(&sg, scr, 8); - - mmc_set_data_timeout(&data, card, 0); - - mmc_wait_for_req(card->host, &mrq); - - if (cmd.error != MMC_ERR_NONE) - return cmd.error; - if (data.error != MMC_ERR_NONE) - return data.error; - - scr[0] = ntohl(scr[0]); - scr[1] = ntohl(scr[1]); - - return MMC_ERR_NONE; -} - -int mmc_sd_switch(struct mmc_card *card, int mode, int group, - u8 value, u8 *resp) -{ - struct mmc_request mrq; - struct mmc_command cmd; - struct mmc_data data; - struct scatterlist sg; - - BUG_ON(!card); - BUG_ON(!card->host); - - mode = !!mode; - value &= 0xF; - - memset(&mrq, 0, sizeof(struct mmc_request)); - memset(&cmd, 0, sizeof(struct mmc_command)); - memset(&data, 0, sizeof(struct mmc_data)); - - mrq.cmd = &cmd; - mrq.data = &data; - - cmd.opcode = SD_SWITCH; - cmd.arg = mode << 31 | 0x00FFFFFF; - cmd.arg &= ~(0xF << (group * 4)); - cmd.arg |= value << (group * 4); - cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; - - data.blksz = 64; - data.blocks = 1; - data.flags = MMC_DATA_READ; - data.sg = &sg; - data.sg_len = 1; - - sg_init_one(&sg, resp, 64); - - mmc_set_data_timeout(&data, card, 0); - - mmc_wait_for_req(card->host, &mrq); - - if (cmd.error != MMC_ERR_NONE) - return cmd.error; - if (data.error != MMC_ERR_NONE) - return data.error; - - return MMC_ERR_NONE; -} - diff --git a/trunk/drivers/mmc/core/sd_ops.h b/trunk/drivers/mmc/core/sd_ops.h deleted file mode 100644 index 1240fddba5e3..000000000000 --- a/trunk/drivers/mmc/core/sd_ops.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * linux/drivers/mmc/sd_ops.h - * - * Copyright 2006-2007 Pierre Ossman - * - * 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. - */ - -#ifndef _MMC_SD_OPS_H -#define _MMC_SD_OPS_H - -int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card); -int mmc_app_set_bus_width(struct mmc_card *card, int width); -int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr); -int mmc_send_if_cond(struct mmc_host *host, u32 ocr); -int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca); -int mmc_app_send_scr(struct mmc_card *card, u32 *scr); -int mmc_sd_switch(struct mmc_card *card, int mode, int group, - u8 value, u8 *resp); - -#endif - diff --git a/trunk/drivers/mmc/host/Kconfig b/trunk/drivers/mmc/host/Kconfig deleted file mode 100644 index e23082fe88d0..000000000000 --- a/trunk/drivers/mmc/host/Kconfig +++ /dev/null @@ -1,102 +0,0 @@ -# -# MMC/SD host controller drivers -# - -comment "MMC/SD Host Controller Drivers" - -config MMC_ARMMMCI - tristate "ARM AMBA Multimedia Card Interface support" - depends on ARM_AMBA - help - This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card - Interface (PL180 and PL181) support. If you have an ARM(R) - platform with a Multimedia Card slot, say Y or M here. - - If unsure, say N. - -config MMC_PXA - tristate "Intel PXA25x/26x/27x Multimedia Card Interface support" - depends on ARCH_PXA - help - This selects the Intel(R) PXA(R) Multimedia card Interface. - If you have a PXA(R) platform with a Multimedia Card slot, - say Y or M here. - - If unsure, say N. - -config MMC_SDHCI - tristate "Secure Digital Host Controller Interface support (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL - help - This select the generic Secure Digital Host Controller Interface. - It is used by manufacturers such as Texas Instruments(R), Ricoh(R) - and Toshiba(R). Most controllers found in laptops are of this type. - If you have a controller with this interface, say Y or M here. - - If unsure, say N. - -config MMC_OMAP - tristate "TI OMAP Multimedia Card Interface support" - depends on ARCH_OMAP - select TPS65010 if MACH_OMAP_H2 - help - This selects the TI OMAP Multimedia card Interface. - If you have an OMAP board with a Multimedia Card slot, - say Y or M here. - - If unsure, say N. - -config MMC_WBSD - tristate "Winbond W83L51xD SD/MMC Card Interface support" - depends on ISA_DMA_API - help - This selects the Winbond(R) W83L51xD Secure digital and - Multimedia card Interface. - If you have a machine with a integrated W83L518D or W83L519D - SD/MMC card reader, say Y or M here. - - If unsure, say N. - -config MMC_AU1X - tristate "Alchemy AU1XX0 MMC Card Interface support" - depends on SOC_AU1200 - help - This selects the AMD Alchemy(R) Multimedia card interface. - If you have a Alchemy platform with a MMC slot, say Y or M here. - - If unsure, say N. - -config MMC_AT91 - tristate "AT91 SD/MMC Card Interface support" - depends on ARCH_AT91 - help - This selects the AT91 MCI controller. - - If unsure, say N. - -config MMC_IMX - tristate "Motorola i.MX Multimedia Card Interface support" - depends on ARCH_IMX - help - This selects the Motorola i.MX Multimedia card Interface. - If you have a i.MX platform with a Multimedia Card slot, - say Y or M here. - - If unsure, say N. - -config MMC_TIFM_SD - tristate "TI Flash Media MMC/SD Interface support (EXPERIMENTAL)" - depends on EXPERIMENTAL && PCI - select TIFM_CORE - help - Say Y here if you want to be able to access MMC/SD cards with - the Texas Instruments(R) Flash Media card reader, found in many - laptops. - This option 'selects' (turns on, enables) 'TIFM_CORE', but you - probably also need appropriate card reader host adapter, such as - 'Misc devices: TI Flash Media PCI74xx/PCI76xx host adapter support - (TIFM_7XX1)'. - - To compile this driver as a module, choose M here: the - module will be called tifm_sd. - diff --git a/trunk/drivers/mmc/host/Makefile b/trunk/drivers/mmc/host/Makefile deleted file mode 100644 index 6685f64345b4..000000000000 --- a/trunk/drivers/mmc/host/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# Makefile for MMC/SD host controller drivers -# - -ifeq ($(CONFIG_MMC_DEBUG),y) - EXTRA_CFLAGS += -DDEBUG -endif - -obj-$(CONFIG_MMC_ARMMMCI) += mmci.o -obj-$(CONFIG_MMC_PXA) += pxamci.o -obj-$(CONFIG_MMC_IMX) += imxmmc.o -obj-$(CONFIG_MMC_SDHCI) += sdhci.o -obj-$(CONFIG_MMC_WBSD) += wbsd.o -obj-$(CONFIG_MMC_AU1X) += au1xmmc.o -obj-$(CONFIG_MMC_OMAP) += omap.o -obj-$(CONFIG_MMC_AT91) += at91_mci.o -obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o - diff --git a/trunk/drivers/mmc/host/tifm_sd.c b/trunk/drivers/mmc/host/tifm_sd.c deleted file mode 100644 index 8b736e968447..000000000000 --- a/trunk/drivers/mmc/host/tifm_sd.c +++ /dev/null @@ -1,1091 +0,0 @@ -/* - * tifm_sd.c - TI FlashMedia driver - * - * Copyright (C) 2006 Alex Dubov - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Special thanks to Brad Campbell for extensive testing of this driver. - * - */ - - -#include -#include -#include -#include -#include - -#define DRIVER_NAME "tifm_sd" -#define DRIVER_VERSION "0.8" - -static int no_dma = 0; -static int fixed_timeout = 0; -module_param(no_dma, bool, 0644); -module_param(fixed_timeout, bool, 0644); - -/* Constants here are mostly from OMAP5912 datasheet */ -#define TIFM_MMCSD_RESET 0x0002 -#define TIFM_MMCSD_CLKMASK 0x03ff -#define TIFM_MMCSD_POWER 0x0800 -#define TIFM_MMCSD_4BBUS 0x8000 -#define TIFM_MMCSD_RXDE 0x8000 /* rx dma enable */ -#define TIFM_MMCSD_TXDE 0x0080 /* tx dma enable */ -#define TIFM_MMCSD_BUFINT 0x0c00 /* set bits: AE, AF */ -#define TIFM_MMCSD_DPE 0x0020 /* data timeout counted in kilocycles */ -#define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */ -#define TIFM_MMCSD_READ 0x8000 - -#define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */ -#define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ -#define TIFM_MMCSD_CD 0x0002 /* card detect */ -#define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ -#define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ -#define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */ -#define TIFM_MMCSD_DTO 0x0020 /* data time-out */ -#define TIFM_MMCSD_DCRC 0x0040 /* data crc error */ -#define TIFM_MMCSD_CTO 0x0080 /* command time-out */ -#define TIFM_MMCSD_CCRC 0x0100 /* command crc error */ -#define TIFM_MMCSD_AF 0x0400 /* fifo almost full */ -#define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */ -#define TIFM_MMCSD_OCRB 0x1000 /* OCR busy */ -#define TIFM_MMCSD_CIRQ 0x2000 /* card irq (cmd40/sdio) */ -#define TIFM_MMCSD_CERR 0x4000 /* card status error */ - -#define TIFM_MMCSD_ODTO 0x0040 /* open drain / extended timeout */ -#define TIFM_MMCSD_CARD_RO 0x0200 /* card is read-only */ - -#define TIFM_MMCSD_FIFO_SIZE 0x0020 - -#define TIFM_MMCSD_RSP_R0 0x0000 -#define TIFM_MMCSD_RSP_R1 0x0100 -#define TIFM_MMCSD_RSP_R2 0x0200 -#define TIFM_MMCSD_RSP_R3 0x0300 -#define TIFM_MMCSD_RSP_R4 0x0400 -#define TIFM_MMCSD_RSP_R5 0x0500 -#define TIFM_MMCSD_RSP_R6 0x0600 - -#define TIFM_MMCSD_RSP_BUSY 0x0800 - -#define TIFM_MMCSD_CMD_BC 0x0000 -#define TIFM_MMCSD_CMD_BCR 0x1000 -#define TIFM_MMCSD_CMD_AC 0x2000 -#define TIFM_MMCSD_CMD_ADTC 0x3000 - -#define TIFM_MMCSD_MAX_BLOCK_SIZE 0x0800UL - -enum { - CMD_READY = 0x0001, - FIFO_READY = 0x0002, - BRS_READY = 0x0004, - SCMD_ACTIVE = 0x0008, - SCMD_READY = 0x0010, - CARD_BUSY = 0x0020, - DATA_CARRY = 0x0040 -}; - -struct tifm_sd { - struct tifm_dev *dev; - - unsigned short eject:1, - open_drain:1, - no_dma:1; - unsigned short cmd_flags; - - unsigned int clk_freq; - unsigned int clk_div; - unsigned long timeout_jiffies; - - struct tasklet_struct finish_tasklet; - struct timer_list timer; - struct mmc_request *req; - - int sg_len; - int sg_pos; - unsigned int block_pos; - struct scatterlist bounce_buf; - unsigned char bounce_buf_data[TIFM_MMCSD_MAX_BLOCK_SIZE]; -}; - -/* for some reason, host won't respond correctly to readw/writew */ -static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, - unsigned int off, unsigned int cnt) -{ - struct tifm_dev *sock = host->dev; - unsigned char *buf; - unsigned int pos = 0, val; - - buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + off; - if (host->cmd_flags & DATA_CARRY) { - buf[pos++] = host->bounce_buf_data[0]; - host->cmd_flags &= ~DATA_CARRY; - } - - while (pos < cnt) { - val = readl(sock->addr + SOCK_MMCSD_DATA); - buf[pos++] = val & 0xff; - if (pos == cnt) { - host->bounce_buf_data[0] = (val >> 8) & 0xff; - host->cmd_flags |= DATA_CARRY; - break; - } - buf[pos++] = (val >> 8) & 0xff; - } - kunmap_atomic(buf - off, KM_BIO_DST_IRQ); -} - -static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, - unsigned int off, unsigned int cnt) -{ - struct tifm_dev *sock = host->dev; - unsigned char *buf; - unsigned int pos = 0, val; - - buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + off; - if (host->cmd_flags & DATA_CARRY) { - val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00); - writel(val, sock->addr + SOCK_MMCSD_DATA); - host->cmd_flags &= ~DATA_CARRY; - } - - while (pos < cnt) { - val = buf[pos++]; - if (pos == cnt) { - host->bounce_buf_data[0] = val & 0xff; - host->cmd_flags |= DATA_CARRY; - break; - } - val |= (buf[pos++] << 8) & 0xff00; - writel(val, sock->addr + SOCK_MMCSD_DATA); - } - kunmap_atomic(buf - off, KM_BIO_SRC_IRQ); -} - -static void tifm_sd_transfer_data(struct tifm_sd *host) -{ - struct mmc_data *r_data = host->req->cmd->data; - struct scatterlist *sg = r_data->sg; - unsigned int off, cnt, t_size = TIFM_MMCSD_FIFO_SIZE * 2; - unsigned int p_off, p_cnt; - struct page *pg; - - if (host->sg_pos == host->sg_len) - return; - while (t_size) { - cnt = sg[host->sg_pos].length - host->block_pos; - if (!cnt) { - host->block_pos = 0; - host->sg_pos++; - if (host->sg_pos == host->sg_len) { - if ((r_data->flags & MMC_DATA_WRITE) - && DATA_CARRY) - writel(host->bounce_buf_data[0], - host->dev->addr - + SOCK_MMCSD_DATA); - - return; - } - cnt = sg[host->sg_pos].length; - } - off = sg[host->sg_pos].offset + host->block_pos; - - pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT); - p_off = offset_in_page(off); - p_cnt = PAGE_SIZE - p_off; - p_cnt = min(p_cnt, cnt); - p_cnt = min(p_cnt, t_size); - - if (r_data->flags & MMC_DATA_READ) - tifm_sd_read_fifo(host, pg, p_off, p_cnt); - else if (r_data->flags & MMC_DATA_WRITE) - tifm_sd_write_fifo(host, pg, p_off, p_cnt); - - t_size -= p_cnt; - host->block_pos += p_cnt; - } -} - -static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off, - struct page *src, unsigned int src_off, - unsigned int count) -{ - unsigned char *src_buf = kmap_atomic(src, KM_BIO_SRC_IRQ) + src_off; - unsigned char *dst_buf = kmap_atomic(dst, KM_BIO_DST_IRQ) + dst_off; - - memcpy(dst_buf, src_buf, count); - - kunmap_atomic(dst_buf - dst_off, KM_BIO_DST_IRQ); - kunmap_atomic(src_buf - src_off, KM_BIO_SRC_IRQ); -} - -static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data) -{ - struct scatterlist *sg = r_data->sg; - unsigned int t_size = r_data->blksz; - unsigned int off, cnt; - unsigned int p_off, p_cnt; - struct page *pg; - - dev_dbg(&host->dev->dev, "bouncing block\n"); - while (t_size) { - cnt = sg[host->sg_pos].length - host->block_pos; - if (!cnt) { - host->block_pos = 0; - host->sg_pos++; - if (host->sg_pos == host->sg_len) - return; - cnt = sg[host->sg_pos].length; - } - off = sg[host->sg_pos].offset + host->block_pos; - - pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT); - p_off = offset_in_page(off); - p_cnt = PAGE_SIZE - p_off; - p_cnt = min(p_cnt, cnt); - p_cnt = min(p_cnt, t_size); - - if (r_data->flags & MMC_DATA_WRITE) - tifm_sd_copy_page(host->bounce_buf.page, - r_data->blksz - t_size, - pg, p_off, p_cnt); - else if (r_data->flags & MMC_DATA_READ) - tifm_sd_copy_page(pg, p_off, host->bounce_buf.page, - r_data->blksz - t_size, p_cnt); - - t_size -= p_cnt; - host->block_pos += p_cnt; - } -} - -static int tifm_sd_set_dma_data(struct tifm_sd *host, struct mmc_data *r_data) -{ - struct tifm_dev *sock = host->dev; - unsigned int t_size = TIFM_DMA_TSIZE * r_data->blksz; - unsigned int dma_len, dma_blk_cnt, dma_off; - struct scatterlist *sg = NULL; - unsigned long flags; - - if (host->sg_pos == host->sg_len) - return 1; - - if (host->cmd_flags & DATA_CARRY) { - host->cmd_flags &= ~DATA_CARRY; - local_irq_save(flags); - tifm_sd_bounce_block(host, r_data); - local_irq_restore(flags); - if (host->sg_pos == host->sg_len) - return 1; - } - - dma_len = sg_dma_len(&r_data->sg[host->sg_pos]) - host->block_pos; - if (!dma_len) { - host->block_pos = 0; - host->sg_pos++; - if (host->sg_pos == host->sg_len) - return 1; - dma_len = sg_dma_len(&r_data->sg[host->sg_pos]); - } - - if (dma_len < t_size) { - dma_blk_cnt = dma_len / r_data->blksz; - dma_off = host->block_pos; - host->block_pos += dma_blk_cnt * r_data->blksz; - } else { - dma_blk_cnt = TIFM_DMA_TSIZE; - dma_off = host->block_pos; - host->block_pos += t_size; - } - - if (dma_blk_cnt) - sg = &r_data->sg[host->sg_pos]; - else if (dma_len) { - if (r_data->flags & MMC_DATA_WRITE) { - local_irq_save(flags); - tifm_sd_bounce_block(host, r_data); - local_irq_restore(flags); - } else - host->cmd_flags |= DATA_CARRY; - - sg = &host->bounce_buf; - dma_off = 0; - dma_blk_cnt = 1; - } else - return 1; - - dev_dbg(&sock->dev, "setting dma for %d blocks\n", dma_blk_cnt); - writel(sg_dma_address(sg) + dma_off, sock->addr + SOCK_DMA_ADDRESS); - if (r_data->flags & MMC_DATA_WRITE) - writel((dma_blk_cnt << 8) | TIFM_DMA_TX | TIFM_DMA_EN, - sock->addr + SOCK_DMA_CONTROL); - else - writel((dma_blk_cnt << 8) | TIFM_DMA_EN, - sock->addr + SOCK_DMA_CONTROL); - - return 0; -} - -static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) -{ - unsigned int rc = 0; - - switch (mmc_resp_type(cmd)) { - case MMC_RSP_NONE: - rc |= TIFM_MMCSD_RSP_R0; - break; - case MMC_RSP_R1B: - rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through - case MMC_RSP_R1: - rc |= TIFM_MMCSD_RSP_R1; - break; - case MMC_RSP_R2: - rc |= TIFM_MMCSD_RSP_R2; - break; - case MMC_RSP_R3: - rc |= TIFM_MMCSD_RSP_R3; - break; - default: - BUG(); - } - - switch (mmc_cmd_type(cmd)) { - case MMC_CMD_BC: - rc |= TIFM_MMCSD_CMD_BC; - break; - case MMC_CMD_BCR: - rc |= TIFM_MMCSD_CMD_BCR; - break; - case MMC_CMD_AC: - rc |= TIFM_MMCSD_CMD_AC; - break; - case MMC_CMD_ADTC: - rc |= TIFM_MMCSD_CMD_ADTC; - break; - default: - BUG(); - } - return rc; -} - -static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) -{ - struct tifm_dev *sock = host->dev; - unsigned int cmd_mask = tifm_sd_op_flags(cmd); - - if (host->open_drain) - cmd_mask |= TIFM_MMCSD_ODTO; - - if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) - cmd_mask |= TIFM_MMCSD_READ; - - dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", - cmd->opcode, cmd->arg, cmd_mask); - - writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); - writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); - writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND); -} - -static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock) -{ - cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16) - | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18); - cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16) - | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10); - cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16) - | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08); - cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16) - | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00); -} - -static void tifm_sd_check_status(struct tifm_sd *host) -{ - struct tifm_dev *sock = host->dev; - struct mmc_command *cmd = host->req->cmd; - - if (cmd->error != MMC_ERR_NONE) - goto finish_request; - - if (!(host->cmd_flags & CMD_READY)) - return; - - if (cmd->data) { - if (cmd->data->error != MMC_ERR_NONE) { - if ((host->cmd_flags & SCMD_ACTIVE) - && !(host->cmd_flags & SCMD_READY)) - return; - - goto finish_request; - } - - if (!(host->cmd_flags & BRS_READY)) - return; - - if (!(host->no_dma || (host->cmd_flags & FIFO_READY))) - return; - - if (cmd->data->flags & MMC_DATA_WRITE) { - if (host->req->stop) { - if (!(host->cmd_flags & SCMD_ACTIVE)) { - host->cmd_flags |= SCMD_ACTIVE; - writel(TIFM_MMCSD_EOFB - | readl(sock->addr - + SOCK_MMCSD_INT_ENABLE), - sock->addr - + SOCK_MMCSD_INT_ENABLE); - tifm_sd_exec(host, host->req->stop); - return; - } else { - if (!(host->cmd_flags & SCMD_READY) - || (host->cmd_flags & CARD_BUSY)) - return; - writel((~TIFM_MMCSD_EOFB) - & readl(sock->addr - + SOCK_MMCSD_INT_ENABLE), - sock->addr - + SOCK_MMCSD_INT_ENABLE); - } - } else { - if (host->cmd_flags & CARD_BUSY) - return; - writel((~TIFM_MMCSD_EOFB) - & readl(sock->addr - + SOCK_MMCSD_INT_ENABLE), - sock->addr + SOCK_MMCSD_INT_ENABLE); - } - } else { - if (host->req->stop) { - if (!(host->cmd_flags & SCMD_ACTIVE)) { - host->cmd_flags |= SCMD_ACTIVE; - tifm_sd_exec(host, host->req->stop); - return; - } else { - if (!(host->cmd_flags & SCMD_READY)) - return; - } - } - } - } -finish_request: - tasklet_schedule(&host->finish_tasklet); -} - -/* Called from interrupt handler */ -static void tifm_sd_data_event(struct tifm_dev *sock) -{ - struct tifm_sd *host; - unsigned int fifo_status = 0; - struct mmc_data *r_data = NULL; - - spin_lock(&sock->lock); - host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); - fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); - dev_dbg(&sock->dev, "data event: fifo_status %x, flags %x\n", - fifo_status, host->cmd_flags); - - if (host->req) { - r_data = host->req->cmd->data; - - if (r_data && (fifo_status & TIFM_FIFO_READY)) { - if (tifm_sd_set_dma_data(host, r_data)) { - host->cmd_flags |= FIFO_READY; - tifm_sd_check_status(host); - } - } - } - - writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS); - spin_unlock(&sock->lock); -} - -/* Called from interrupt handler */ -static void tifm_sd_card_event(struct tifm_dev *sock) -{ - struct tifm_sd *host; - unsigned int host_status = 0; - int cmd_error = MMC_ERR_NONE; - struct mmc_command *cmd = NULL; - unsigned long flags; - - spin_lock(&sock->lock); - host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); - host_status = readl(sock->addr + SOCK_MMCSD_STATUS); - dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n", - host_status, host->cmd_flags); - - if (host->req) { - cmd = host->req->cmd; - - if (host_status & TIFM_MMCSD_ERRMASK) { - writel(host_status & TIFM_MMCSD_ERRMASK, - sock->addr + SOCK_MMCSD_STATUS); - if (host_status & TIFM_MMCSD_CTO) - cmd_error = MMC_ERR_TIMEOUT; - else if (host_status & TIFM_MMCSD_CCRC) - cmd_error = MMC_ERR_BADCRC; - - if (cmd->data) { - if (host_status & TIFM_MMCSD_DTO) - cmd->data->error = MMC_ERR_TIMEOUT; - else if (host_status & TIFM_MMCSD_DCRC) - cmd->data->error = MMC_ERR_BADCRC; - } - - writel(TIFM_FIFO_INT_SETALL, - sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); - writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); - - if (host->req->stop) { - if (host->cmd_flags & SCMD_ACTIVE) { - host->req->stop->error = cmd_error; - host->cmd_flags |= SCMD_READY; - } else { - cmd->error = cmd_error; - host->cmd_flags |= SCMD_ACTIVE; - tifm_sd_exec(host, host->req->stop); - goto done; - } - } else - cmd->error = cmd_error; - } else { - if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) { - if (!(host->cmd_flags & CMD_READY)) { - host->cmd_flags |= CMD_READY; - tifm_sd_fetch_resp(cmd, sock); - } else if (host->cmd_flags & SCMD_ACTIVE) { - host->cmd_flags |= SCMD_READY; - tifm_sd_fetch_resp(host->req->stop, - sock); - } - } - if (host_status & TIFM_MMCSD_BRS) - host->cmd_flags |= BRS_READY; - } - - if (host->no_dma && cmd->data) { - if (host_status & TIFM_MMCSD_AE) - writel(host_status & TIFM_MMCSD_AE, - sock->addr + SOCK_MMCSD_STATUS); - - if (host_status & (TIFM_MMCSD_AE | TIFM_MMCSD_AF - | TIFM_MMCSD_BRS)) { - local_irq_save(flags); - tifm_sd_transfer_data(host); - local_irq_restore(flags); - host_status &= ~TIFM_MMCSD_AE; - } - } - - if (host_status & TIFM_MMCSD_EOFB) - host->cmd_flags &= ~CARD_BUSY; - else if (host_status & TIFM_MMCSD_CB) - host->cmd_flags |= CARD_BUSY; - - tifm_sd_check_status(host); - } -done: - writel(host_status, sock->addr + SOCK_MMCSD_STATUS); - spin_unlock(&sock->lock); -} - -static void tifm_sd_set_data_timeout(struct tifm_sd *host, - struct mmc_data *data) -{ - struct tifm_dev *sock = host->dev; - unsigned int data_timeout = data->timeout_clks; - - if (fixed_timeout) - return; - - data_timeout += data->timeout_ns / - ((1000000000UL / host->clk_freq) * host->clk_div); - - if (data_timeout < 0xffff) { - writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); - writel((~TIFM_MMCSD_DPE) - & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), - sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); - } else { - data_timeout = (data_timeout >> 10) + 1; - if (data_timeout > 0xffff) - data_timeout = 0; /* set to unlimited */ - writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); - writel(TIFM_MMCSD_DPE - | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), - sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); - } -} - -static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) -{ - struct tifm_sd *host = mmc_priv(mmc); - struct tifm_dev *sock = host->dev; - unsigned long flags; - struct mmc_data *r_data = mrq->cmd->data; - - spin_lock_irqsave(&sock->lock, flags); - if (host->eject) { - spin_unlock_irqrestore(&sock->lock, flags); - goto err_out; - } - - if (host->req) { - printk(KERN_ERR "%s : unfinished request detected\n", - sock->dev.bus_id); - spin_unlock_irqrestore(&sock->lock, flags); - goto err_out; - } - - host->cmd_flags = 0; - host->block_pos = 0; - host->sg_pos = 0; - - if (r_data) { - tifm_sd_set_data_timeout(host, r_data); - - if ((r_data->flags & MMC_DATA_WRITE) && !mrq->stop) - writel(TIFM_MMCSD_EOFB - | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), - sock->addr + SOCK_MMCSD_INT_ENABLE); - - if (host->no_dma) { - writel(TIFM_MMCSD_BUFINT - | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), - sock->addr + SOCK_MMCSD_INT_ENABLE); - writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) - | (TIFM_MMCSD_FIFO_SIZE - 1), - sock->addr + SOCK_MMCSD_BUFFER_CONFIG); - - host->sg_len = r_data->sg_len; - } else { - sg_init_one(&host->bounce_buf, host->bounce_buf_data, - r_data->blksz); - - if(1 != tifm_map_sg(sock, &host->bounce_buf, 1, - r_data->flags & MMC_DATA_WRITE - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE)) { - printk(KERN_ERR "%s : scatterlist map failed\n", - sock->dev.bus_id); - spin_unlock_irqrestore(&sock->lock, flags); - goto err_out; - } - host->sg_len = tifm_map_sg(sock, r_data->sg, - r_data->sg_len, - r_data->flags - & MMC_DATA_WRITE - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); - if (host->sg_len < 1) { - printk(KERN_ERR "%s : scatterlist map failed\n", - sock->dev.bus_id); - tifm_unmap_sg(sock, &host->bounce_buf, 1, - r_data->flags & MMC_DATA_WRITE - ? PCI_DMA_TODEVICE - : PCI_DMA_FROMDEVICE); - spin_unlock_irqrestore(&sock->lock, flags); - goto err_out; - } - - writel(TIFM_FIFO_INT_SETALL, - sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); - writel(ilog2(r_data->blksz) - 2, - sock->addr + SOCK_FIFO_PAGE_SIZE); - writel(TIFM_FIFO_ENABLE, - sock->addr + SOCK_FIFO_CONTROL); - writel(TIFM_FIFO_INTMASK, - sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); - - if (r_data->flags & MMC_DATA_WRITE) - writel(TIFM_MMCSD_TXDE, - sock->addr + SOCK_MMCSD_BUFFER_CONFIG); - else - writel(TIFM_MMCSD_RXDE, - sock->addr + SOCK_MMCSD_BUFFER_CONFIG); - - tifm_sd_set_dma_data(host, r_data); - } - - writel(r_data->blocks - 1, - sock->addr + SOCK_MMCSD_NUM_BLOCKS); - writel(r_data->blksz - 1, - sock->addr + SOCK_MMCSD_BLOCK_LEN); - } - - host->req = mrq; - mod_timer(&host->timer, jiffies + host->timeout_jiffies); - writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), - sock->addr + SOCK_CONTROL); - tifm_sd_exec(host, mrq->cmd); - spin_unlock_irqrestore(&sock->lock, flags); - return; - -err_out: - mrq->cmd->error = MMC_ERR_TIMEOUT; - mmc_request_done(mmc, mrq); -} - -static void tifm_sd_end_cmd(unsigned long data) -{ - struct tifm_sd *host = (struct tifm_sd*)data; - struct tifm_dev *sock = host->dev; - struct mmc_host *mmc = tifm_get_drvdata(sock); - struct mmc_request *mrq; - struct mmc_data *r_data = NULL; - unsigned long flags; - - spin_lock_irqsave(&sock->lock, flags); - - del_timer(&host->timer); - mrq = host->req; - host->req = NULL; - - if (!mrq) { - printk(KERN_ERR " %s : no request to complete?\n", - sock->dev.bus_id); - spin_unlock_irqrestore(&sock->lock, flags); - return; - } - - r_data = mrq->cmd->data; - if (r_data) { - if (host->no_dma) { - writel((~TIFM_MMCSD_BUFINT) - & readl(sock->addr + SOCK_MMCSD_INT_ENABLE), - sock->addr + SOCK_MMCSD_INT_ENABLE); - } else { - tifm_unmap_sg(sock, &host->bounce_buf, 1, - (r_data->flags & MMC_DATA_WRITE) - ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); - tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, - (r_data->flags & MMC_DATA_WRITE) - ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); - } - - r_data->bytes_xfered = r_data->blocks - - readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; - r_data->bytes_xfered *= r_data->blksz; - r_data->bytes_xfered += r_data->blksz - - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; - } - - writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), - sock->addr + SOCK_CONTROL); - - spin_unlock_irqrestore(&sock->lock, flags); - mmc_request_done(mmc, mrq); -} - -static void tifm_sd_abort(unsigned long data) -{ - struct tifm_sd *host = (struct tifm_sd*)data; - - printk(KERN_ERR - "%s : card failed to respond for a long period of time " - "(%x, %x)\n", - host->dev->dev.bus_id, host->req->cmd->opcode, host->cmd_flags); - - tifm_eject(host->dev); -} - -static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct tifm_sd *host = mmc_priv(mmc); - struct tifm_dev *sock = host->dev; - unsigned int clk_div1, clk_div2; - unsigned long flags; - - spin_lock_irqsave(&sock->lock, flags); - - dev_dbg(&sock->dev, "ios: clock = %u, vdd = %x, bus_mode = %x, " - "chip_select = %x, power_mode = %x, bus_width = %x\n", - ios->clock, ios->vdd, ios->bus_mode, ios->chip_select, - ios->power_mode, ios->bus_width); - - if (ios->bus_width == MMC_BUS_WIDTH_4) { - writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), - sock->addr + SOCK_MMCSD_CONFIG); - } else { - writel((~TIFM_MMCSD_4BBUS) - & readl(sock->addr + SOCK_MMCSD_CONFIG), - sock->addr + SOCK_MMCSD_CONFIG); - } - - if (ios->clock) { - clk_div1 = 20000000 / ios->clock; - if (!clk_div1) - clk_div1 = 1; - - clk_div2 = 24000000 / ios->clock; - if (!clk_div2) - clk_div2 = 1; - - if ((20000000 / clk_div1) > ios->clock) - clk_div1++; - if ((24000000 / clk_div2) > ios->clock) - clk_div2++; - if ((20000000 / clk_div1) > (24000000 / clk_div2)) { - host->clk_freq = 20000000; - host->clk_div = clk_div1; - writel((~TIFM_CTRL_FAST_CLK) - & readl(sock->addr + SOCK_CONTROL), - sock->addr + SOCK_CONTROL); - } else { - host->clk_freq = 24000000; - host->clk_div = clk_div2; - writel(TIFM_CTRL_FAST_CLK - | readl(sock->addr + SOCK_CONTROL), - sock->addr + SOCK_CONTROL); - } - } else { - host->clk_div = 0; - } - host->clk_div &= TIFM_MMCSD_CLKMASK; - writel(host->clk_div - | ((~TIFM_MMCSD_CLKMASK) - & readl(sock->addr + SOCK_MMCSD_CONFIG)), - sock->addr + SOCK_MMCSD_CONFIG); - - host->open_drain = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN); - - /* chip_select : maybe later */ - //vdd - //power is set before probe / after remove - - spin_unlock_irqrestore(&sock->lock, flags); -} - -static int tifm_sd_ro(struct mmc_host *mmc) -{ - int rc = 0; - struct tifm_sd *host = mmc_priv(mmc); - struct tifm_dev *sock = host->dev; - unsigned long flags; - - spin_lock_irqsave(&sock->lock, flags); - if (TIFM_MMCSD_CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE)) - rc = 1; - spin_unlock_irqrestore(&sock->lock, flags); - return rc; -} - -static const struct mmc_host_ops tifm_sd_ops = { - .request = tifm_sd_request, - .set_ios = tifm_sd_ios, - .get_ro = tifm_sd_ro -}; - -static int tifm_sd_initialize_host(struct tifm_sd *host) -{ - int rc; - unsigned int host_status = 0; - struct tifm_dev *sock = host->dev; - - writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); - mmiowb(); - host->clk_div = 61; - host->clk_freq = 20000000; - writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); - writel(host->clk_div | TIFM_MMCSD_POWER, - sock->addr + SOCK_MMCSD_CONFIG); - - /* wait up to 0.51 sec for reset */ - for (rc = 32; rc <= 256; rc <<= 1) { - if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) { - rc = 0; - break; - } - msleep(rc); - } - - if (rc) { - printk(KERN_ERR "%s : controller failed to reset\n", - sock->dev.bus_id); - return -ENODEV; - } - - writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS); - writel(host->clk_div | TIFM_MMCSD_POWER, - sock->addr + SOCK_MMCSD_CONFIG); - writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); - - // command timeout fixed to 64 clocks for now - writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); - writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND); - - for (rc = 16; rc <= 64; rc <<= 1) { - host_status = readl(sock->addr + SOCK_MMCSD_STATUS); - writel(host_status, sock->addr + SOCK_MMCSD_STATUS); - if (!(host_status & TIFM_MMCSD_ERRMASK) - && (host_status & TIFM_MMCSD_EOC)) { - rc = 0; - break; - } - msleep(rc); - } - - if (rc) { - printk(KERN_ERR - "%s : card not ready - probe failed on initialization\n", - sock->dev.bus_id); - return -ENODEV; - } - - writel(TIFM_MMCSD_CERR | TIFM_MMCSD_BRS | TIFM_MMCSD_EOC - | TIFM_MMCSD_ERRMASK, - sock->addr + SOCK_MMCSD_INT_ENABLE); - mmiowb(); - - return 0; -} - -static int tifm_sd_probe(struct tifm_dev *sock) -{ - struct mmc_host *mmc; - struct tifm_sd *host; - int rc = -EIO; - - if (!(TIFM_SOCK_STATE_OCCUPIED - & readl(sock->addr + SOCK_PRESENT_STATE))) { - printk(KERN_WARNING "%s : card gone, unexpectedly\n", - sock->dev.bus_id); - return rc; - } - - mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev); - if (!mmc) - return -ENOMEM; - - host = mmc_priv(mmc); - host->no_dma = no_dma; - tifm_set_drvdata(sock, mmc); - host->dev = sock; - host->timeout_jiffies = msecs_to_jiffies(1000); - - tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd, - (unsigned long)host); - setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); - - mmc->ops = &tifm_sd_ops; - mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; - mmc->f_min = 20000000 / 60; - mmc->f_max = 24000000; - - mmc->max_blk_count = 2048; - mmc->max_hw_segs = mmc->max_blk_count; - mmc->max_blk_size = min(TIFM_MMCSD_MAX_BLOCK_SIZE, PAGE_SIZE); - mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size; - mmc->max_req_size = mmc->max_seg_size; - mmc->max_phys_segs = mmc->max_hw_segs; - - sock->card_event = tifm_sd_card_event; - sock->data_event = tifm_sd_data_event; - rc = tifm_sd_initialize_host(host); - - if (!rc) - rc = mmc_add_host(mmc); - if (!rc) - return 0; - - mmc_free_host(mmc); - return rc; -} - -static void tifm_sd_remove(struct tifm_dev *sock) -{ - struct mmc_host *mmc = tifm_get_drvdata(sock); - struct tifm_sd *host = mmc_priv(mmc); - unsigned long flags; - - spin_lock_irqsave(&sock->lock, flags); - host->eject = 1; - writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); - mmiowb(); - spin_unlock_irqrestore(&sock->lock, flags); - - tasklet_kill(&host->finish_tasklet); - - spin_lock_irqsave(&sock->lock, flags); - if (host->req) { - writel(TIFM_FIFO_INT_SETALL, - sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); - writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); - host->req->cmd->error = MMC_ERR_TIMEOUT; - if (host->req->stop) - host->req->stop->error = MMC_ERR_TIMEOUT; - tasklet_schedule(&host->finish_tasklet); - } - spin_unlock_irqrestore(&sock->lock, flags); - mmc_remove_host(mmc); - dev_dbg(&sock->dev, "after remove\n"); - - mmc_free_host(mmc); -} - -#ifdef CONFIG_PM - -static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state) -{ - return mmc_suspend_host(tifm_get_drvdata(sock), state); -} - -static int tifm_sd_resume(struct tifm_dev *sock) -{ - struct mmc_host *mmc = tifm_get_drvdata(sock); - struct tifm_sd *host = mmc_priv(mmc); - int rc; - - rc = tifm_sd_initialize_host(host); - dev_dbg(&sock->dev, "resume initialize %d\n", rc); - - if (rc) - host->eject = 1; - else - rc = mmc_resume_host(mmc); - - return rc; -} - -#else - -#define tifm_sd_suspend NULL -#define tifm_sd_resume NULL - -#endif /* CONFIG_PM */ - -static struct tifm_device_id tifm_sd_id_tbl[] = { - { TIFM_TYPE_SD }, { } -}; - -static struct tifm_driver tifm_sd_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE - }, - .id_table = tifm_sd_id_tbl, - .probe = tifm_sd_probe, - .remove = tifm_sd_remove, - .suspend = tifm_sd_suspend, - .resume = tifm_sd_resume -}; - -static int __init tifm_sd_init(void) -{ - return tifm_register_driver(&tifm_sd_driver); -} - -static void __exit tifm_sd_exit(void) -{ - tifm_unregister_driver(&tifm_sd_driver); -} - -MODULE_AUTHOR("Alex Dubov"); -MODULE_DESCRIPTION("TI FlashMedia SD driver"); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl); -MODULE_VERSION(DRIVER_VERSION); - -module_init(tifm_sd_init); -module_exit(tifm_sd_exit); diff --git a/trunk/drivers/mmc/host/imxmmc.c b/trunk/drivers/mmc/imxmmc.c similarity index 99% rename from trunk/drivers/mmc/host/imxmmc.c rename to trunk/drivers/mmc/imxmmc.c index 7ee2045acbef..0de5c9e94e74 100644 --- a/trunk/drivers/mmc/host/imxmmc.c +++ b/trunk/drivers/mmc/imxmmc.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/mmc/host/imxmmc.h b/trunk/drivers/mmc/imxmmc.h similarity index 100% rename from trunk/drivers/mmc/host/imxmmc.h rename to trunk/drivers/mmc/imxmmc.h diff --git a/trunk/drivers/mmc/mmc.c b/trunk/drivers/mmc/mmc.c new file mode 100644 index 000000000000..4a73e8b2428d --- /dev/null +++ b/trunk/drivers/mmc/mmc.c @@ -0,0 +1,1724 @@ +/* + * linux/drivers/mmc/mmc.c + * + * Copyright (C) 2003-2004 Russell King, All Rights Reserved. + * SD support Copyright (C) 2004 Ian Molton, All Rights Reserved. + * SD support Copyright (C) 2005 Pierre Ossman, All Rights Reserved. + * MMCv4 support Copyright (C) 2006 Philip Langdale, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mmc.h" + +#define CMD_RETRIES 3 + +/* + * OCR Bit positions to 10s of Vdd mV. + */ +static const unsigned short mmc_ocr_bit_to_vdd[] = { + 150, 155, 160, 165, 170, 180, 190, 200, + 210, 220, 230, 240, 250, 260, 270, 280, + 290, 300, 310, 320, 330, 340, 350, 360 +}; + +static const unsigned int tran_exp[] = { + 10000, 100000, 1000000, 10000000, + 0, 0, 0, 0 +}; + +static const unsigned char tran_mant[] = { + 0, 10, 12, 13, 15, 20, 25, 30, + 35, 40, 45, 50, 55, 60, 70, 80, +}; + +static const unsigned int tacc_exp[] = { + 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, +}; + +static const unsigned int tacc_mant[] = { + 0, 10, 12, 13, 15, 20, 25, 30, + 35, 40, 45, 50, 55, 60, 70, 80, +}; + + +/** + * mmc_request_done - finish processing an MMC request + * @host: MMC host which completed request + * @mrq: MMC request which request + * + * MMC drivers should call this function when they have completed + * their processing of a request. + */ +void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) +{ + struct mmc_command *cmd = mrq->cmd; + int err = cmd->error; + + pr_debug("%s: req done (CMD%u): %d/%d/%d: %08x %08x %08x %08x\n", + mmc_hostname(host), cmd->opcode, err, + mrq->data ? mrq->data->error : 0, + mrq->stop ? mrq->stop->error : 0, + cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]); + + if (err && cmd->retries) { + cmd->retries--; + cmd->error = 0; + host->ops->request(host, mrq); + } else if (mrq->done) { + mrq->done(mrq); + } +} + +EXPORT_SYMBOL(mmc_request_done); + +/** + * mmc_start_request - start a command on a host + * @host: MMC host to start command on + * @mrq: MMC request to start + * + * Queue a command on the specified host. We expect the + * caller to be holding the host lock with interrupts disabled. + */ +void +mmc_start_request(struct mmc_host *host, struct mmc_request *mrq) +{ + pr_debug("%s: starting CMD%u arg %08x flags %08x\n", + mmc_hostname(host), mrq->cmd->opcode, + mrq->cmd->arg, mrq->cmd->flags); + + WARN_ON(!host->claimed); + + mrq->cmd->error = 0; + mrq->cmd->mrq = mrq; + if (mrq->data) { + BUG_ON(mrq->data->blksz > host->max_blk_size); + BUG_ON(mrq->data->blocks > host->max_blk_count); + BUG_ON(mrq->data->blocks * mrq->data->blksz > + host->max_req_size); + + mrq->cmd->data = mrq->data; + mrq->data->error = 0; + mrq->data->mrq = mrq; + if (mrq->stop) { + mrq->data->stop = mrq->stop; + mrq->stop->error = 0; + mrq->stop->mrq = mrq; + } + } + host->ops->request(host, mrq); +} + +EXPORT_SYMBOL(mmc_start_request); + +static void mmc_wait_done(struct mmc_request *mrq) +{ + complete(mrq->done_data); +} + +int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) +{ + DECLARE_COMPLETION_ONSTACK(complete); + + mrq->done_data = &complete; + mrq->done = mmc_wait_done; + + mmc_start_request(host, mrq); + + wait_for_completion(&complete); + + return 0; +} + +EXPORT_SYMBOL(mmc_wait_for_req); + +/** + * mmc_wait_for_cmd - start a command and wait for completion + * @host: MMC host to start command + * @cmd: MMC command to start + * @retries: maximum number of retries + * + * Start a new MMC command for a host, and wait for the command + * to complete. Return any error that occurred while the command + * was executing. Do not attempt to parse the response. + */ +int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries) +{ + struct mmc_request mrq; + + BUG_ON(!host->claimed); + + memset(&mrq, 0, sizeof(struct mmc_request)); + + memset(cmd->resp, 0, sizeof(cmd->resp)); + cmd->retries = retries; + + mrq.cmd = cmd; + cmd->data = NULL; + + mmc_wait_for_req(host, &mrq); + + return cmd->error; +} + +EXPORT_SYMBOL(mmc_wait_for_cmd); + +/** + * mmc_wait_for_app_cmd - start an application command and wait for + completion + * @host: MMC host to start command + * @rca: RCA to send MMC_APP_CMD to + * @cmd: MMC command to start + * @retries: maximum number of retries + * + * Sends a MMC_APP_CMD, checks the card response, sends the command + * in the parameter and waits for it to complete. Return any error + * that occurred while the command was executing. Do not attempt to + * parse the response. + */ +int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, + struct mmc_command *cmd, int retries) +{ + struct mmc_request mrq; + struct mmc_command appcmd; + + int i, err; + + BUG_ON(!host->claimed); + BUG_ON(retries < 0); + + err = MMC_ERR_INVALID; + + /* + * We have to resend MMC_APP_CMD for each attempt so + * we cannot use the retries field in mmc_command. + */ + for (i = 0;i <= retries;i++) { + memset(&mrq, 0, sizeof(struct mmc_request)); + + appcmd.opcode = MMC_APP_CMD; + appcmd.arg = rca << 16; + appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + appcmd.retries = 0; + memset(appcmd.resp, 0, sizeof(appcmd.resp)); + appcmd.data = NULL; + + mrq.cmd = &appcmd; + appcmd.data = NULL; + + mmc_wait_for_req(host, &mrq); + + if (appcmd.error) { + err = appcmd.error; + continue; + } + + /* Check that card supported application commands */ + if (!(appcmd.resp[0] & R1_APP_CMD)) + return MMC_ERR_FAILED; + + memset(&mrq, 0, sizeof(struct mmc_request)); + + memset(cmd->resp, 0, sizeof(cmd->resp)); + cmd->retries = 0; + + mrq.cmd = cmd; + cmd->data = NULL; + + mmc_wait_for_req(host, &mrq); + + err = cmd->error; + if (cmd->error == MMC_ERR_NONE) + break; + } + + return err; +} + +EXPORT_SYMBOL(mmc_wait_for_app_cmd); + +/** + * mmc_set_data_timeout - set the timeout for a data command + * @data: data phase for command + * @card: the MMC card associated with the data transfer + * @write: flag to differentiate reads from writes + */ +void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card, + int write) +{ + unsigned int mult; + + /* + * SD cards use a 100 multiplier rather than 10 + */ + mult = mmc_card_sd(card) ? 100 : 10; + + /* + * Scale up the multiplier (and therefore the timeout) by + * the r2w factor for writes. + */ + if (write) + mult <<= card->csd.r2w_factor; + + data->timeout_ns = card->csd.tacc_ns * mult; + data->timeout_clks = card->csd.tacc_clks * mult; + + /* + * SD cards also have an upper limit on the timeout. + */ + if (mmc_card_sd(card)) { + unsigned int timeout_us, limit_us; + + timeout_us = data->timeout_ns / 1000; + timeout_us += data->timeout_clks * 1000 / + (card->host->ios.clock / 1000); + + if (write) + limit_us = 250000; + else + limit_us = 100000; + + /* + * SDHC cards always use these fixed values. + */ + if (timeout_us > limit_us || mmc_card_blockaddr(card)) { + data->timeout_ns = limit_us * 1000; + data->timeout_clks = 0; + } + } +} +EXPORT_SYMBOL(mmc_set_data_timeout); + +static int mmc_select_card(struct mmc_host *host, struct mmc_card *card); + +/** + * __mmc_claim_host - exclusively claim a host + * @host: mmc host to claim + * @card: mmc card to claim host for + * + * Claim a host for a set of operations. If a valid card + * is passed and this wasn't the last card selected, select + * the card before returning. + * + * Note: you should use mmc_card_claim_host or mmc_claim_host. + */ +int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int err = 0; + + add_wait_queue(&host->wq, &wait); + spin_lock_irqsave(&host->lock, flags); + while (1) { + set_current_state(TASK_UNINTERRUPTIBLE); + if (!host->claimed) + break; + spin_unlock_irqrestore(&host->lock, flags); + schedule(); + spin_lock_irqsave(&host->lock, flags); + } + set_current_state(TASK_RUNNING); + host->claimed = 1; + spin_unlock_irqrestore(&host->lock, flags); + remove_wait_queue(&host->wq, &wait); + + if (card != (void *)-1) { + err = mmc_select_card(host, card); + if (err != MMC_ERR_NONE) + return err; + } + + return err; +} + +EXPORT_SYMBOL(__mmc_claim_host); + +/** + * mmc_release_host - release a host + * @host: mmc host to release + * + * Release a MMC host, allowing others to claim the host + * for their operations. + */ +void mmc_release_host(struct mmc_host *host) +{ + unsigned long flags; + + BUG_ON(!host->claimed); + + spin_lock_irqsave(&host->lock, flags); + host->claimed = 0; + spin_unlock_irqrestore(&host->lock, flags); + + wake_up(&host->wq); +} + +EXPORT_SYMBOL(mmc_release_host); + +static inline void mmc_set_ios(struct mmc_host *host) +{ + struct mmc_ios *ios = &host->ios; + + pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u " + "width %u timing %u\n", + mmc_hostname(host), ios->clock, ios->bus_mode, + ios->power_mode, ios->chip_select, ios->vdd, + ios->bus_width, ios->timing); + + host->ops->set_ios(host, ios); +} + +static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) +{ + int err; + struct mmc_command cmd; + + BUG_ON(!host->claimed); + + if (host->card_selected == card) + return MMC_ERR_NONE; + + host->card_selected = card; + + cmd.opcode = MMC_SELECT_CARD; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) + return err; + + /* + * We can only change the bus width of SD cards when + * they are selected so we have to put the handling + * here. + * + * The card is in 1 bit mode by default so + * we only need to change if it supports the + * wider version. + */ + if (mmc_card_sd(card) && + (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) { + + /* + * Default bus width is 1 bit. + */ + host->ios.bus_width = MMC_BUS_WIDTH_1; + + if (host->caps & MMC_CAP_4_BIT_DATA) { + struct mmc_command cmd; + cmd.opcode = SD_APP_SET_BUS_WIDTH; + cmd.arg = SD_BUS_WIDTH_4; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + err = mmc_wait_for_app_cmd(host, card->rca, &cmd, + CMD_RETRIES); + if (err != MMC_ERR_NONE) + return err; + + host->ios.bus_width = MMC_BUS_WIDTH_4; + } + } + + mmc_set_ios(host); + + return MMC_ERR_NONE; +} + +/* + * Ensure that no card is selected. + */ +static void mmc_deselect_cards(struct mmc_host *host) +{ + struct mmc_command cmd; + + if (host->card_selected) { + host->card_selected = NULL; + + cmd.opcode = MMC_SELECT_CARD; + cmd.arg = 0; + cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; + + mmc_wait_for_cmd(host, &cmd, 0); + } +} + + +static inline void mmc_delay(unsigned int ms) +{ + if (ms < 1000 / HZ) { + cond_resched(); + mdelay(ms); + } else { + msleep(ms); + } +} + +/* + * Mask off any voltages we don't support and select + * the lowest voltage + */ +static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) +{ + int bit; + + ocr &= host->ocr_avail; + + bit = ffs(ocr); + if (bit) { + bit -= 1; + + ocr &= 3 << bit; + + host->ios.vdd = bit; + mmc_set_ios(host); + } else { + ocr = 0; + } + + return ocr; +} + +#define UNSTUFF_BITS(resp,start,size) \ + ({ \ + const int __size = size; \ + const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \ + const int __off = 3 - ((start) / 32); \ + const int __shft = (start) & 31; \ + u32 __res; \ + \ + __res = resp[__off] >> __shft; \ + if (__size + __shft > 32) \ + __res |= resp[__off-1] << ((32 - __shft) % 32); \ + __res & __mask; \ + }) + +/* + * Given the decoded CSD structure, decode the raw CID to our CID structure. + */ +static void mmc_decode_cid(struct mmc_card *card) +{ + u32 *resp = card->raw_cid; + + memset(&card->cid, 0, sizeof(struct mmc_cid)); + + if (mmc_card_sd(card)) { + /* + * SD doesn't currently have a version field so we will + * have to assume we can parse this. + */ + card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); + card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); + card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); + card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); + card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); + card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); + card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); + card->cid.hwrev = UNSTUFF_BITS(resp, 60, 4); + card->cid.fwrev = UNSTUFF_BITS(resp, 56, 4); + card->cid.serial = UNSTUFF_BITS(resp, 24, 32); + card->cid.year = UNSTUFF_BITS(resp, 12, 8); + card->cid.month = UNSTUFF_BITS(resp, 8, 4); + + card->cid.year += 2000; /* SD cards year offset */ + } else { + /* + * The selection of the format here is based upon published + * specs from sandisk and from what people have reported. + */ + switch (card->csd.mmca_vsn) { + case 0: /* MMC v1.0 - v1.2 */ + case 1: /* MMC v1.4 */ + card->cid.manfid = UNSTUFF_BITS(resp, 104, 24); + card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); + card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); + card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); + card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); + card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); + card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); + card->cid.prod_name[6] = UNSTUFF_BITS(resp, 48, 8); + card->cid.hwrev = UNSTUFF_BITS(resp, 44, 4); + card->cid.fwrev = UNSTUFF_BITS(resp, 40, 4); + card->cid.serial = UNSTUFF_BITS(resp, 16, 24); + card->cid.month = UNSTUFF_BITS(resp, 12, 4); + card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; + break; + + case 2: /* MMC v2.0 - v2.2 */ + case 3: /* MMC v3.1 - v3.3 */ + case 4: /* MMC v4 */ + card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); + card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); + card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); + card->cid.prod_name[1] = UNSTUFF_BITS(resp, 88, 8); + card->cid.prod_name[2] = UNSTUFF_BITS(resp, 80, 8); + card->cid.prod_name[3] = UNSTUFF_BITS(resp, 72, 8); + card->cid.prod_name[4] = UNSTUFF_BITS(resp, 64, 8); + card->cid.prod_name[5] = UNSTUFF_BITS(resp, 56, 8); + card->cid.serial = UNSTUFF_BITS(resp, 16, 32); + card->cid.month = UNSTUFF_BITS(resp, 12, 4); + card->cid.year = UNSTUFF_BITS(resp, 8, 4) + 1997; + break; + + default: + printk("%s: card has unknown MMCA version %d\n", + mmc_hostname(card->host), card->csd.mmca_vsn); + mmc_card_set_bad(card); + break; + } + } +} + +/* + * Given a 128-bit response, decode to our card CSD structure. + */ +static void mmc_decode_csd(struct mmc_card *card) +{ + struct mmc_csd *csd = &card->csd; + unsigned int e, m, csd_struct; + u32 *resp = card->raw_csd; + + if (mmc_card_sd(card)) { + csd_struct = UNSTUFF_BITS(resp, 126, 2); + + switch (csd_struct) { + case 0: + m = UNSTUFF_BITS(resp, 115, 4); + e = UNSTUFF_BITS(resp, 112, 3); + csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; + csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; + + m = UNSTUFF_BITS(resp, 99, 4); + e = UNSTUFF_BITS(resp, 96, 3); + csd->max_dtr = tran_exp[e] * tran_mant[m]; + csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); + + e = UNSTUFF_BITS(resp, 47, 3); + m = UNSTUFF_BITS(resp, 62, 12); + csd->capacity = (1 + m) << (e + 2); + + csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); + csd->read_partial = UNSTUFF_BITS(resp, 79, 1); + csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); + csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); + csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); + csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); + csd->write_partial = UNSTUFF_BITS(resp, 21, 1); + break; + case 1: + /* + * This is a block-addressed SDHC card. Most + * interesting fields are unused and have fixed + * values. To avoid getting tripped by buggy cards, + * we assume those fixed values ourselves. + */ + mmc_card_set_blockaddr(card); + + csd->tacc_ns = 0; /* Unused */ + csd->tacc_clks = 0; /* Unused */ + + m = UNSTUFF_BITS(resp, 99, 4); + e = UNSTUFF_BITS(resp, 96, 3); + csd->max_dtr = tran_exp[e] * tran_mant[m]; + csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); + + m = UNSTUFF_BITS(resp, 48, 22); + csd->capacity = (1 + m) << 10; + + csd->read_blkbits = 9; + csd->read_partial = 0; + csd->write_misalign = 0; + csd->read_misalign = 0; + csd->r2w_factor = 4; /* Unused */ + csd->write_blkbits = 9; + csd->write_partial = 0; + break; + default: + printk("%s: unrecognised CSD structure version %d\n", + mmc_hostname(card->host), csd_struct); + mmc_card_set_bad(card); + return; + } + } else { + /* + * We only understand CSD structure v1.1 and v1.2. + * v1.2 has extra information in bits 15, 11 and 10. + */ + csd_struct = UNSTUFF_BITS(resp, 126, 2); + if (csd_struct != 1 && csd_struct != 2) { + printk("%s: unrecognised CSD structure version %d\n", + mmc_hostname(card->host), csd_struct); + mmc_card_set_bad(card); + return; + } + + csd->mmca_vsn = UNSTUFF_BITS(resp, 122, 4); + m = UNSTUFF_BITS(resp, 115, 4); + e = UNSTUFF_BITS(resp, 112, 3); + csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10; + csd->tacc_clks = UNSTUFF_BITS(resp, 104, 8) * 100; + + m = UNSTUFF_BITS(resp, 99, 4); + e = UNSTUFF_BITS(resp, 96, 3); + csd->max_dtr = tran_exp[e] * tran_mant[m]; + csd->cmdclass = UNSTUFF_BITS(resp, 84, 12); + + e = UNSTUFF_BITS(resp, 47, 3); + m = UNSTUFF_BITS(resp, 62, 12); + csd->capacity = (1 + m) << (e + 2); + + csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4); + csd->read_partial = UNSTUFF_BITS(resp, 79, 1); + csd->write_misalign = UNSTUFF_BITS(resp, 78, 1); + csd->read_misalign = UNSTUFF_BITS(resp, 77, 1); + csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3); + csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4); + csd->write_partial = UNSTUFF_BITS(resp, 21, 1); + } +} + +/* + * Given a 64-bit response, decode to our card SCR structure. + */ +static void mmc_decode_scr(struct mmc_card *card) +{ + struct sd_scr *scr = &card->scr; + unsigned int scr_struct; + u32 resp[4]; + + BUG_ON(!mmc_card_sd(card)); + + resp[3] = card->raw_scr[1]; + resp[2] = card->raw_scr[0]; + + scr_struct = UNSTUFF_BITS(resp, 60, 4); + if (scr_struct != 0) { + printk("%s: unrecognised SCR structure version %d\n", + mmc_hostname(card->host), scr_struct); + mmc_card_set_bad(card); + return; + } + + scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4); + scr->bus_widths = UNSTUFF_BITS(resp, 48, 4); +} + +/* + * Locate a MMC card on this MMC host given a raw CID. + */ +static struct mmc_card *mmc_find_card(struct mmc_host *host, u32 *raw_cid) +{ + struct mmc_card *card; + + list_for_each_entry(card, &host->cards, node) { + if (memcmp(card->raw_cid, raw_cid, sizeof(card->raw_cid)) == 0) + return card; + } + return NULL; +} + +/* + * Allocate a new MMC card, and assign a unique RCA. + */ +static struct mmc_card * +mmc_alloc_card(struct mmc_host *host, u32 *raw_cid, unsigned int *frca) +{ + struct mmc_card *card, *c; + unsigned int rca = *frca; + + card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); + if (!card) + return ERR_PTR(-ENOMEM); + + mmc_init_card(card, host); + memcpy(card->raw_cid, raw_cid, sizeof(card->raw_cid)); + + again: + list_for_each_entry(c, &host->cards, node) + if (c->rca == rca) { + rca++; + goto again; + } + + card->rca = rca; + + *frca = rca; + + return card; +} + +/* + * Tell attached cards to go to IDLE state + */ +static void mmc_idle_cards(struct mmc_host *host) +{ + struct mmc_command cmd; + + host->ios.chip_select = MMC_CS_HIGH; + mmc_set_ios(host); + + mmc_delay(1); + + cmd.opcode = MMC_GO_IDLE_STATE; + cmd.arg = 0; + cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; + + mmc_wait_for_cmd(host, &cmd, 0); + + mmc_delay(1); + + host->ios.chip_select = MMC_CS_DONTCARE; + mmc_set_ios(host); + + mmc_delay(1); +} + +/* + * Apply power to the MMC stack. This is a two-stage process. + * First, we enable power to the card without the clock running. + * We then wait a bit for the power to stabilise. Finally, + * enable the bus drivers and clock to the card. + * + * We must _NOT_ enable the clock prior to power stablising. + * + * If a host does all the power sequencing itself, ignore the + * initial MMC_POWER_UP stage. + */ +static void mmc_power_up(struct mmc_host *host) +{ + int bit = fls(host->ocr_avail) - 1; + + host->ios.vdd = bit; + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; + host->ios.chip_select = MMC_CS_DONTCARE; + host->ios.power_mode = MMC_POWER_UP; + host->ios.bus_width = MMC_BUS_WIDTH_1; + host->ios.timing = MMC_TIMING_LEGACY; + mmc_set_ios(host); + + mmc_delay(1); + + host->ios.clock = host->f_min; + host->ios.power_mode = MMC_POWER_ON; + mmc_set_ios(host); + + mmc_delay(2); +} + +static void mmc_power_off(struct mmc_host *host) +{ + host->ios.clock = 0; + host->ios.vdd = 0; + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; + host->ios.chip_select = MMC_CS_DONTCARE; + host->ios.power_mode = MMC_POWER_OFF; + host->ios.bus_width = MMC_BUS_WIDTH_1; + host->ios.timing = MMC_TIMING_LEGACY; + mmc_set_ios(host); +} + +static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) +{ + struct mmc_command cmd; + int i, err = 0; + + cmd.opcode = MMC_SEND_OP_COND; + cmd.arg = ocr; + cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; + + for (i = 100; i; i--) { + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err != MMC_ERR_NONE) + break; + + if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) + break; + + err = MMC_ERR_TIMEOUT; + + mmc_delay(10); + } + + if (rocr) + *rocr = cmd.resp[0]; + + return err; +} + +static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) +{ + struct mmc_command cmd; + int i, err = 0; + + cmd.opcode = SD_APP_OP_COND; + cmd.arg = ocr; + cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; + + for (i = 100; i; i--) { + err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) + break; + + if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) + break; + + err = MMC_ERR_TIMEOUT; + + mmc_delay(10); + } + + if (rocr) + *rocr = cmd.resp[0]; + + return err; +} + +static int mmc_send_if_cond(struct mmc_host *host, u32 ocr, int *rsd2) +{ + struct mmc_command cmd; + int err, sd2; + static const u8 test_pattern = 0xAA; + + /* + * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND + * before SD_APP_OP_COND. This command will harmlessly fail for + * SD 1.0 cards. + */ + cmd.opcode = SD_SEND_IF_COND; + cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern; + cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR; + + err = mmc_wait_for_cmd(host, &cmd, 0); + if (err == MMC_ERR_NONE) { + if ((cmd.resp[0] & 0xFF) == test_pattern) { + sd2 = 1; + } else { + sd2 = 0; + err = MMC_ERR_FAILED; + } + } else { + /* + * Treat errors as SD 1.0 card. + */ + sd2 = 0; + err = MMC_ERR_NONE; + } + if (rsd2) + *rsd2 = sd2; + return err; +} + +/* + * Discover cards by requesting their CID. If this command + * times out, it is not an error; there are no further cards + * to be discovered. Add new cards to the list. + * + * Create a mmc_card entry for each discovered card, assigning + * it an RCA, and save the raw CID for decoding later. + */ +static void mmc_discover_cards(struct mmc_host *host) +{ + struct mmc_card *card; + unsigned int first_rca = 1, err; + + while (1) { + struct mmc_command cmd; + + cmd.opcode = MMC_ALL_SEND_CID; + cmd.arg = 0; + cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err == MMC_ERR_TIMEOUT) { + err = MMC_ERR_NONE; + break; + } + if (err != MMC_ERR_NONE) { + printk(KERN_ERR "%s: error requesting CID: %d\n", + mmc_hostname(host), err); + break; + } + + card = mmc_find_card(host, cmd.resp); + if (!card) { + card = mmc_alloc_card(host, cmd.resp, &first_rca); + if (IS_ERR(card)) { + err = PTR_ERR(card); + break; + } + list_add(&card->node, &host->cards); + } + + card->state &= ~MMC_STATE_DEAD; + + if (host->mode == MMC_MODE_SD) { + mmc_card_set_sd(card); + + cmd.opcode = SD_SEND_RELATIVE_ADDR; + cmd.arg = 0; + cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) + mmc_card_set_dead(card); + else { + card->rca = cmd.resp[0] >> 16; + + if (!host->ops->get_ro) { + printk(KERN_WARNING "%s: host does not " + "support reading read-only " + "switch. assuming write-enable.\n", + mmc_hostname(host)); + } else { + if (host->ops->get_ro(host)) + mmc_card_set_readonly(card); + } + } + } else { + cmd.opcode = MMC_SET_RELATIVE_ADDR; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) + mmc_card_set_dead(card); + } + } +} + +static void mmc_read_csds(struct mmc_host *host) +{ + struct mmc_card *card; + + list_for_each_entry(card, &host->cards, node) { + struct mmc_command cmd; + int err; + + if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) + continue; + + cmd.opcode = MMC_SEND_CSD; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) { + mmc_card_set_dead(card); + continue; + } + + memcpy(card->raw_csd, cmd.resp, sizeof(card->raw_csd)); + + mmc_decode_csd(card); + mmc_decode_cid(card); + } +} + +static void mmc_process_ext_csds(struct mmc_host *host) +{ + int err; + struct mmc_card *card; + + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_data data; + + struct scatterlist sg; + + /* + * As the ext_csd is so large and mostly unused, we don't store the + * raw block in mmc_card. + */ + u8 *ext_csd; + ext_csd = kmalloc(512, GFP_KERNEL); + if (!ext_csd) { + printk("%s: could not allocate a buffer to receive the ext_csd." + "mmc v4 cards will be treated as v3.\n", + mmc_hostname(host)); + return; + } + + list_for_each_entry(card, &host->cards, node) { + if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) + continue; + if (mmc_card_sd(card)) + continue; + if (card->csd.mmca_vsn < CSD_SPEC_VER_4) + continue; + + err = mmc_select_card(host, card); + if (err != MMC_ERR_NONE) { + mmc_card_set_dead(card); + continue; + } + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = MMC_SEND_EXT_CSD; + cmd.arg = 0; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + memset(&data, 0, sizeof(struct mmc_data)); + + mmc_set_data_timeout(&data, card, 0); + + data.blksz = 512; + data.blocks = 1; + data.flags = MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; + + memset(&mrq, 0, sizeof(struct mmc_request)); + + mrq.cmd = &cmd; + mrq.data = &data; + + sg_init_one(&sg, ext_csd, 512); + + mmc_wait_for_req(host, &mrq); + + if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { + printk("%s: unable to read EXT_CSD, performance " + "might suffer.\n", mmc_hostname(card->host)); + continue; + } + + switch (ext_csd[EXT_CSD_CARD_TYPE]) { + case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 52000000; + break; + case EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 26000000; + break; + default: + /* MMC v4 spec says this cannot happen */ + printk("%s: card is mmc v4 but doesn't support " + "any high-speed modes.\n", + mmc_hostname(card->host)); + continue; + } + + if (host->caps & MMC_CAP_MMC_HIGHSPEED) { + /* Activate highspeed support. */ + cmd.opcode = MMC_SWITCH; + cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (EXT_CSD_HS_TIMING << 16) | + (1 << 8) | + EXT_CSD_CMD_SET_NORMAL; + cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) { + printk("%s: failed to switch card to mmc v4 " + "high-speed mode.\n", + mmc_hostname(card->host)); + continue; + } + + mmc_card_set_highspeed(card); + + host->ios.timing = MMC_TIMING_SD_HS; + mmc_set_ios(host); + } + + /* Check for host support for wide-bus modes. */ + if (host->caps & MMC_CAP_4_BIT_DATA) { + /* Activate 4-bit support. */ + cmd.opcode = MMC_SWITCH; + cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + (EXT_CSD_BUS_WIDTH << 16) | + (EXT_CSD_BUS_WIDTH_4 << 8) | + EXT_CSD_CMD_SET_NORMAL; + cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err != MMC_ERR_NONE) { + printk("%s: failed to switch card to " + "mmc v4 4-bit bus mode.\n", + mmc_hostname(card->host)); + continue; + } + + host->ios.bus_width = MMC_BUS_WIDTH_4; + mmc_set_ios(host); + } + } + + kfree(ext_csd); + + mmc_deselect_cards(host); +} + +static void mmc_read_scrs(struct mmc_host *host) +{ + int err; + struct mmc_card *card; + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_data data; + struct scatterlist sg; + + list_for_each_entry(card, &host->cards, node) { + if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) + continue; + if (!mmc_card_sd(card)) + continue; + + err = mmc_select_card(host, card); + if (err != MMC_ERR_NONE) { + mmc_card_set_dead(card); + continue; + } + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = MMC_APP_CMD; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, 0); + if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { + mmc_card_set_dead(card); + continue; + } + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_APP_SEND_SCR; + cmd.arg = 0; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + memset(&data, 0, sizeof(struct mmc_data)); + + mmc_set_data_timeout(&data, card, 0); + + data.blksz = 1 << 3; + data.blocks = 1; + data.flags = MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; + + memset(&mrq, 0, sizeof(struct mmc_request)); + + mrq.cmd = &cmd; + mrq.data = &data; + + sg_init_one(&sg, (u8*)card->raw_scr, 8); + + mmc_wait_for_req(host, &mrq); + + if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { + mmc_card_set_dead(card); + continue; + } + + card->raw_scr[0] = ntohl(card->raw_scr[0]); + card->raw_scr[1] = ntohl(card->raw_scr[1]); + + mmc_decode_scr(card); + } + + mmc_deselect_cards(host); +} + +static void mmc_read_switch_caps(struct mmc_host *host) +{ + int err; + struct mmc_card *card; + struct mmc_request mrq; + struct mmc_command cmd; + struct mmc_data data; + unsigned char *status; + struct scatterlist sg; + + if (!(host->caps & MMC_CAP_SD_HIGHSPEED)) + return; + + status = kmalloc(64, GFP_KERNEL); + if (!status) { + printk(KERN_WARNING "%s: Unable to allocate buffer for " + "reading switch capabilities.\n", + mmc_hostname(host)); + return; + } + + list_for_each_entry(card, &host->cards, node) { + if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT)) + continue; + if (!mmc_card_sd(card)) + continue; + if (card->scr.sda_vsn < SCR_SPEC_VER_1) + continue; + + err = mmc_select_card(host, card); + if (err != MMC_ERR_NONE) { + mmc_card_set_dead(card); + continue; + } + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_SWITCH; + cmd.arg = 0x00FFFFF1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + memset(&data, 0, sizeof(struct mmc_data)); + + mmc_set_data_timeout(&data, card, 0); + + data.blksz = 64; + data.blocks = 1; + data.flags = MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; + + memset(&mrq, 0, sizeof(struct mmc_request)); + + mrq.cmd = &cmd; + mrq.data = &data; + + sg_init_one(&sg, status, 64); + + mmc_wait_for_req(host, &mrq); + + if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) { + printk("%s: unable to read switch capabilities, " + "performance might suffer.\n", + mmc_hostname(card->host)); + continue; + } + + if (status[13] & 0x02) + card->sw_caps.hs_max_dtr = 50000000; + + memset(&cmd, 0, sizeof(struct mmc_command)); + + cmd.opcode = SD_SWITCH; + cmd.arg = 0x80FFFFF1; + cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; + + memset(&data, 0, sizeof(struct mmc_data)); + + mmc_set_data_timeout(&data, card, 0); + + data.blksz = 64; + data.blocks = 1; + data.flags = MMC_DATA_READ; + data.sg = &sg; + data.sg_len = 1; + + memset(&mrq, 0, sizeof(struct mmc_request)); + + mrq.cmd = &cmd; + mrq.data = &data; + + sg_init_one(&sg, status, 64); + + mmc_wait_for_req(host, &mrq); + + if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE || + (status[16] & 0xF) != 1) { + printk(KERN_WARNING "%s: Problem switching card " + "into high-speed mode!\n", + mmc_hostname(host)); + continue; + } + + mmc_card_set_highspeed(card); + + host->ios.timing = MMC_TIMING_SD_HS; + mmc_set_ios(host); + } + + kfree(status); + + mmc_deselect_cards(host); +} + +static unsigned int mmc_calculate_clock(struct mmc_host *host) +{ + struct mmc_card *card; + unsigned int max_dtr = host->f_max; + + list_for_each_entry(card, &host->cards, node) + if (!mmc_card_dead(card)) { + if (mmc_card_highspeed(card) && mmc_card_sd(card)) { + if (max_dtr > card->sw_caps.hs_max_dtr) + max_dtr = card->sw_caps.hs_max_dtr; + } else if (mmc_card_highspeed(card) && !mmc_card_sd(card)) { + if (max_dtr > card->ext_csd.hs_max_dtr) + max_dtr = card->ext_csd.hs_max_dtr; + } else if (max_dtr > card->csd.max_dtr) { + max_dtr = card->csd.max_dtr; + } + } + + pr_debug("%s: selected %d.%03dMHz transfer rate\n", + mmc_hostname(host), + max_dtr / 1000000, (max_dtr / 1000) % 1000); + + return max_dtr; +} + +/* + * Check whether cards we already know about are still present. + * We do this by requesting status, and checking whether a card + * responds. + * + * A request for status does not cause a state change in data + * transfer mode. + */ +static void mmc_check_cards(struct mmc_host *host) +{ + struct list_head *l, *n; + + mmc_deselect_cards(host); + + list_for_each_safe(l, n, &host->cards) { + struct mmc_card *card = mmc_list_to_card(l); + struct mmc_command cmd; + int err; + + cmd.opcode = MMC_SEND_STATUS; + cmd.arg = card->rca << 16; + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; + + err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); + if (err == MMC_ERR_NONE) + continue; + + mmc_card_set_dead(card); + } +} + +static void mmc_setup(struct mmc_host *host) +{ + if (host->ios.power_mode != MMC_POWER_ON) { + int err; + u32 ocr; + + host->mode = MMC_MODE_SD; + + mmc_power_up(host); + mmc_idle_cards(host); + + err = mmc_send_if_cond(host, host->ocr_avail, NULL); + if (err != MMC_ERR_NONE) { + return; + } + err = mmc_send_app_op_cond(host, 0, &ocr); + + /* + * If we fail to detect any SD cards then try + * searching for MMC cards. + */ + if (err != MMC_ERR_NONE) { + host->mode = MMC_MODE_MMC; + + err = mmc_send_op_cond(host, 0, &ocr); + if (err != MMC_ERR_NONE) + return; + } + + host->ocr = mmc_select_voltage(host, ocr); + + /* + * Since we're changing the OCR value, we seem to + * need to tell some cards to go back to the idle + * state. We wait 1ms to give cards time to + * respond. + */ + if (host->ocr) + mmc_idle_cards(host); + } else { + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; + host->ios.clock = host->f_min; + mmc_set_ios(host); + + /* + * We should remember the OCR mask from the existing + * cards, and detect the new cards OCR mask, combine + * the two and re-select the VDD. However, if we do + * change VDD, we should do an idle, and then do a + * full re-initialisation. We would need to notify + * drivers so that they can re-setup the cards as + * well, while keeping their queues at bay. + * + * For the moment, we take the easy way out - if the + * new cards don't like our currently selected VDD, + * they drop off the bus. + */ + } + + if (host->ocr == 0) + return; + + /* + * Send the selected OCR multiple times... until the cards + * all get the idea that they should be ready for CMD2. + * (My SanDisk card seems to need this.) + */ + if (host->mode == MMC_MODE_SD) { + int err, sd2; + err = mmc_send_if_cond(host, host->ocr, &sd2); + if (err == MMC_ERR_NONE) { + /* + * If SD_SEND_IF_COND indicates an SD 2.0 + * compliant card and we should set bit 30 + * of the ocr to indicate that we can handle + * block-addressed SDHC cards. + */ + mmc_send_app_op_cond(host, host->ocr | (sd2 << 30), NULL); + } + } else { + mmc_send_op_cond(host, host->ocr, NULL); + } + + mmc_discover_cards(host); + + /* + * Ok, now switch to push-pull mode. + */ + host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; + mmc_set_ios(host); + + mmc_read_csds(host); + + if (host->mode == MMC_MODE_SD) { + mmc_read_scrs(host); + mmc_read_switch_caps(host); + } else + mmc_process_ext_csds(host); +} + + +/** + * mmc_detect_change - process change of state on a MMC socket + * @host: host which changed state. + * @delay: optional delay to wait before detection (jiffies) + * + * All we know is that card(s) have been inserted or removed + * from the socket(s). We don't know which socket or cards. + */ +void mmc_detect_change(struct mmc_host *host, unsigned long delay) +{ + mmc_schedule_delayed_work(&host->detect, delay); +} + +EXPORT_SYMBOL(mmc_detect_change); + + +static void mmc_rescan(struct work_struct *work) +{ + struct mmc_host *host = + container_of(work, struct mmc_host, detect.work); + struct list_head *l, *n; + unsigned char power_mode; + + mmc_claim_host(host); + + /* + * Check for removed cards and newly inserted ones. We check for + * removed cards first so we can intelligently re-select the VDD. + */ + power_mode = host->ios.power_mode; + if (power_mode == MMC_POWER_ON) + mmc_check_cards(host); + + mmc_setup(host); + + /* + * Some broken cards process CMD1 even in stand-by state. There is + * no reply, but an ILLEGAL_COMMAND error is cached and returned + * after next command. We poll for card status here to clear any + * possibly pending error. + */ + if (power_mode == MMC_POWER_ON) + mmc_check_cards(host); + + if (!list_empty(&host->cards)) { + /* + * (Re-)calculate the fastest clock rate which the + * attached cards and the host support. + */ + host->ios.clock = mmc_calculate_clock(host); + mmc_set_ios(host); + } + + mmc_release_host(host); + + list_for_each_safe(l, n, &host->cards) { + struct mmc_card *card = mmc_list_to_card(l); + + /* + * If this is a new and good card, register it. + */ + if (!mmc_card_present(card) && !mmc_card_dead(card)) { + if (mmc_register_card(card)) + mmc_card_set_dead(card); + else + mmc_card_set_present(card); + } + + /* + * If this card is dead, destroy it. + */ + if (mmc_card_dead(card)) { + list_del(&card->node); + mmc_remove_card(card); + } + } + + /* + * If we discover that there are no cards on the + * bus, turn off the clock and power down. + */ + if (list_empty(&host->cards)) + mmc_power_off(host); +} + + +/** + * mmc_alloc_host - initialise the per-host structure. + * @extra: sizeof private data structure + * @dev: pointer to host device model structure + * + * Initialise the per-host structure. + */ +struct mmc_host *mmc_alloc_host(int extra, struct device *dev) +{ + struct mmc_host *host; + + host = mmc_alloc_host_sysfs(extra, dev); + if (host) { + spin_lock_init(&host->lock); + init_waitqueue_head(&host->wq); + INIT_LIST_HEAD(&host->cards); + INIT_DELAYED_WORK(&host->detect, mmc_rescan); + + /* + * By default, hosts do not support SGIO or large requests. + * They have to set these according to their abilities. + */ + host->max_hw_segs = 1; + host->max_phys_segs = 1; + host->max_seg_size = PAGE_CACHE_SIZE; + + host->max_req_size = PAGE_CACHE_SIZE; + host->max_blk_size = 512; + host->max_blk_count = PAGE_CACHE_SIZE / 512; + } + + return host; +} + +EXPORT_SYMBOL(mmc_alloc_host); + +/** + * mmc_add_host - initialise host hardware + * @host: mmc host + */ +int mmc_add_host(struct mmc_host *host) +{ + int ret; + + ret = mmc_add_host_sysfs(host); + if (ret == 0) { + mmc_power_off(host); + mmc_detect_change(host, 0); + } + + return ret; +} + +EXPORT_SYMBOL(mmc_add_host); + +/** + * mmc_remove_host - remove host hardware + * @host: mmc host + * + * Unregister and remove all cards associated with this host, + * and power down the MMC bus. + */ +void mmc_remove_host(struct mmc_host *host) +{ + struct list_head *l, *n; + + list_for_each_safe(l, n, &host->cards) { + struct mmc_card *card = mmc_list_to_card(l); + + mmc_remove_card(card); + } + + mmc_power_off(host); + mmc_remove_host_sysfs(host); +} + +EXPORT_SYMBOL(mmc_remove_host); + +/** + * mmc_free_host - free the host structure + * @host: mmc host + * + * Free the host once all references to it have been dropped. + */ +void mmc_free_host(struct mmc_host *host) +{ + mmc_flush_scheduled_work(); + mmc_free_host_sysfs(host); +} + +EXPORT_SYMBOL(mmc_free_host); + +#ifdef CONFIG_PM + +/** + * mmc_suspend_host - suspend a host + * @host: mmc host + * @state: suspend mode (PM_SUSPEND_xxx) + */ +int mmc_suspend_host(struct mmc_host *host, pm_message_t state) +{ + mmc_claim_host(host); + mmc_deselect_cards(host); + mmc_power_off(host); + mmc_release_host(host); + + return 0; +} + +EXPORT_SYMBOL(mmc_suspend_host); + +/** + * mmc_resume_host - resume a previously suspended host + * @host: mmc host + */ +int mmc_resume_host(struct mmc_host *host) +{ + mmc_rescan(&host->detect.work); + + return 0; +} + +EXPORT_SYMBOL(mmc_resume_host); + +#endif + +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mmc/core/sysfs.h b/trunk/drivers/mmc/mmc.h similarity index 86% rename from trunk/drivers/mmc/core/sysfs.h rename to trunk/drivers/mmc/mmc.h index 80e29b358282..149affe0b686 100644 --- a/trunk/drivers/mmc/core/sysfs.h +++ b/trunk/drivers/mmc/mmc.h @@ -1,16 +1,15 @@ /* - * linux/drivers/mmc/core/sysfs.h + * linux/drivers/mmc/mmc.h * * Copyright (C) 2003 Russell King, All Rights Reserved. - * Copyright 2007 Pierre Ossman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifndef _MMC_CORE_SYSFS_H -#define _MMC_CORE_SYSFS_H - +#ifndef _MMC_H +#define _MMC_H +/* core-internal functions */ void mmc_init_card(struct mmc_card *card, struct mmc_host *host); int mmc_register_card(struct mmc_card *card); void mmc_remove_card(struct mmc_card *card); @@ -23,5 +22,4 @@ void mmc_free_host_sysfs(struct mmc_host *host); int mmc_schedule_work(struct work_struct *work); int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); void mmc_flush_scheduled_work(void); - #endif diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/mmc_block.c similarity index 93% rename from trunk/drivers/mmc/card/block.c rename to trunk/drivers/mmc/mmc_block.c index d24ab234394c..86439a0bb271 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/mmc_block.c @@ -2,7 +2,6 @@ * Block driver for media (i.e., flash cards) * * Copyright 2002 Hewlett-Packard Company - * Copyright 2005-2007 Pierre Ossman * * Use consistent with the GNU GPL is permitted, * provided that this copyright notice is @@ -32,13 +31,13 @@ #include #include -#include -#include +#include +#include #include #include -#include "queue.h" +#include "mmc_queue.h" /* * max 8 partitions per card @@ -224,9 +223,10 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; struct mmc_blk_request brq; - int ret = 1, sg_pos, data_size; + int ret = 1; - mmc_claim_host(card->host); + if (mmc_card_claim_host(card)) + goto flush_queue; do { struct mmc_command cmd; @@ -283,20 +283,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.data.sg = mq->sg; brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); - if (brq.data.blocks != - (req->nr_sectors >> (md->block_bits - 9))) { - data_size = brq.data.blocks * brq.data.blksz; - for (sg_pos = 0; sg_pos < brq.data.sg_len; sg_pos++) { - data_size -= mq->sg[sg_pos].length; - if (data_size <= 0) { - mq->sg[sg_pos].length += data_size; - sg_pos++; - break; - } - } - brq.data.sg_len = sg_pos; - } - mmc_wait_for_req(card->host, &brq.mrq); if (brq.cmd.error) { printk(KERN_ERR "%s: error %d sending read/write command\n", @@ -356,7 +342,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) spin_unlock_irq(&md->lock); } while (ret); - mmc_release_host(card->host); + mmc_card_release_host(card); return 1; @@ -392,7 +378,9 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) spin_unlock_irq(&md->lock); } - mmc_release_host(card->host); +flush_queue: + + mmc_card_release_host(card); spin_lock_irq(&md->lock); while (ret) { @@ -489,20 +477,11 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits); - if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { - /* - * The EXT_CSD sector count is in number or 512 byte - * sectors. - */ - set_capacity(md->disk, card->ext_csd.sectors); - } else { - /* - * The CSD capacity field is in units of read_blkbits. - * set_capacity takes units of 512 bytes. - */ - set_capacity(md->disk, - card->csd.capacity << (card->csd.read_blkbits - 9)); - } + /* + * The CSD capacity field is in units of read_blkbits. + * set_capacity takes units of 512 bytes. + */ + set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9)); return md; err_putdisk: @@ -523,12 +502,12 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) if (mmc_card_blockaddr(card)) return 0; - mmc_claim_host(card->host); + mmc_card_claim_host(card); cmd.opcode = MMC_SET_BLOCKLEN; cmd.arg = 1 << md->block_bits; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 5); - mmc_release_host(card->host); + mmc_card_release_host(card); if (err) { printk(KERN_ERR "%s: unable to set block size to %d: %d\n", diff --git a/trunk/drivers/mmc/card/queue.c b/trunk/drivers/mmc/mmc_queue.c similarity index 96% rename from trunk/drivers/mmc/card/queue.c rename to trunk/drivers/mmc/mmc_queue.c index 2e77963db334..c27e42645cdb 100644 --- a/trunk/drivers/mmc/card/queue.c +++ b/trunk/drivers/mmc/mmc_queue.c @@ -1,8 +1,7 @@ /* - * linux/drivers/mmc/queue.c + * linux/drivers/mmc/mmc_queue.c * * Copyright (C) 2003 Russell King, All Rights Reserved. - * Copyright 2006-2007 Pierre Ossman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -15,7 +14,7 @@ #include #include -#include "queue.h" +#include "mmc_queue.h" #define MMC_QUEUE_SUSPENDED (1 << 0) @@ -180,6 +179,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock blk_cleanup_queue(mq->queue); return ret; } +EXPORT_SYMBOL(mmc_init_queue); void mmc_cleanup_queue(struct mmc_queue *mq) { @@ -191,9 +191,6 @@ void mmc_cleanup_queue(struct mmc_queue *mq) q->queuedata = NULL; spin_unlock_irqrestore(q->queue_lock, flags); - /* Make sure the queue isn't suspended, as that will deadlock */ - mmc_queue_resume(mq); - /* Then terminate our worker thread */ kthread_stop(mq->thread); @@ -229,6 +226,7 @@ void mmc_queue_suspend(struct mmc_queue *mq) down(&mq->thread_sem); } } +EXPORT_SYMBOL(mmc_queue_suspend); /** * mmc_queue_resume - resume a previously suspended MMC request queue @@ -249,4 +247,4 @@ void mmc_queue_resume(struct mmc_queue *mq) spin_unlock_irqrestore(q->queue_lock, flags); } } - +EXPORT_SYMBOL(mmc_queue_resume); diff --git a/trunk/drivers/mmc/card/queue.h b/trunk/drivers/mmc/mmc_queue.h similarity index 100% rename from trunk/drivers/mmc/card/queue.h rename to trunk/drivers/mmc/mmc_queue.h diff --git a/trunk/drivers/mmc/core/sysfs.c b/trunk/drivers/mmc/mmc_sysfs.c similarity index 97% rename from trunk/drivers/mmc/core/sysfs.c rename to trunk/drivers/mmc/mmc_sysfs.c index 843b1fbba557..e0e82d849d5f 100644 --- a/trunk/drivers/mmc/core/sysfs.c +++ b/trunk/drivers/mmc/mmc_sysfs.c @@ -1,5 +1,5 @@ /* - * linux/drivers/mmc/core/sysfs.c + * linux/drivers/mmc/mmc_sysfs.c * * Copyright (C) 2003 Russell King, All Rights Reserved. * @@ -18,7 +18,7 @@ #include #include -#include "sysfs.h" +#include "mmc.h" #define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev) #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) @@ -72,11 +72,12 @@ static void mmc_release_card(struct device *dev) /* * This currently matches any MMC driver to any MMC card - drivers * themselves make the decision whether to drive this card in their - * probe method. + * probe method. However, we force "bad" cards to fail. */ static int mmc_bus_match(struct device *dev, struct device_driver *drv) { - return 1; + struct mmc_card *card = dev_to_mmc_card(dev); + return !mmc_card_bad(card); } static int @@ -216,8 +217,6 @@ int mmc_register_card(struct mmc_card *card) device_del(&card->dev); } } - if (ret == 0) - mmc_card_set_present(card); return ret; } diff --git a/trunk/drivers/mmc/host/mmci.c b/trunk/drivers/mmc/mmci.c similarity index 99% rename from trunk/drivers/mmc/host/mmci.c rename to trunk/drivers/mmc/mmci.c index d11c2d23ceea..5941dd951e82 100644 --- a/trunk/drivers/mmc/host/mmci.c +++ b/trunk/drivers/mmc/mmci.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/mmc/host/mmci.h b/trunk/drivers/mmc/mmci.h similarity index 100% rename from trunk/drivers/mmc/host/mmci.h rename to trunk/drivers/mmc/mmci.h diff --git a/trunk/drivers/mmc/host/omap.c b/trunk/drivers/mmc/omap.c similarity index 98% rename from trunk/drivers/mmc/host/omap.c rename to trunk/drivers/mmc/omap.c index 1914e65d4db1..1e96a2f65022 100644 --- a/trunk/drivers/mmc/host/omap.c +++ b/trunk/drivers/mmc/omap.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -604,7 +605,7 @@ static void mmc_omap_switch_handler(struct work_struct *work) } if (mmc_omap_cover_is_open(host)) { if (!complained) { - dev_info(mmc_dev(host->mmc), "cover is open\n"); + dev_info(mmc_dev(host->mmc), "cover is open"); complained = 1; } if (mmc_omap_enable_poll) @@ -936,55 +937,48 @@ static void mmc_omap_power(struct mmc_omap_host *host, int on) } } -static int mmc_omap_calc_divisor(struct mmc_host *mmc, struct mmc_ios *ios) +static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct mmc_omap_host *host = mmc_priv(mmc); - int func_clk_rate = clk_get_rate(host->fclk); int dsor; + int realclock, i; - if (ios->clock == 0) - return 0; - - dsor = func_clk_rate / ios->clock; - if (dsor < 1) - dsor = 1; - - if (func_clk_rate / dsor > ios->clock) - dsor++; + realclock = ios->clock; - if (dsor > 250) - dsor = 250; - dsor++; + if (ios->clock == 0) + dsor = 0; + else { + int func_clk_rate = clk_get_rate(host->fclk); - if (ios->bus_width == MMC_BUS_WIDTH_4) - dsor |= 1 << 15; + dsor = func_clk_rate / realclock; + if (dsor < 1) + dsor = 1; - return dsor; -} + if (func_clk_rate / dsor > realclock) + dsor++; -static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ - struct mmc_omap_host *host = mmc_priv(mmc); - int dsor; - int i; + if (dsor > 250) + dsor = 250; + dsor++; - dsor = mmc_omap_calc_divisor(mmc, ios); - host->bus_mode = ios->bus_mode; - host->hw_bus_mode = host->bus_mode; + if (ios->bus_width == MMC_BUS_WIDTH_4) + dsor |= 1 << 15; + } switch (ios->power_mode) { case MMC_POWER_OFF: mmc_omap_power(host, 0); break; case MMC_POWER_UP: - /* Cannot touch dsor yet, just power up MMC */ - mmc_omap_power(host, 1); - return; case MMC_POWER_ON: + mmc_omap_power(host, 1); dsor |= 1 << 11; break; } + host->bus_mode = ios->bus_mode; + host->hw_bus_mode = host->bus_mode; + clk_enable(host->fclk); /* On insanely high arm_per frequencies something sometimes @@ -993,7 +987,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * Writing to the CON register twice seems to do the trick. */ for (i = 0; i < 2; i++) OMAP_MMC_WRITE(host, CON, dsor); - if (ios->power_mode == MMC_POWER_ON) { + if (ios->power_mode == MMC_POWER_UP) { /* Send clock cycles, poll completion */ OMAP_MMC_WRITE(host, IE, 0); OMAP_MMC_WRITE(host, STAT, 0xffff); diff --git a/trunk/drivers/mmc/host/pxamci.c b/trunk/drivers/mmc/pxamci.c similarity index 99% rename from trunk/drivers/mmc/host/pxamci.c rename to trunk/drivers/mmc/pxamci.c index d97d3864b57f..9774fc68b61a 100644 --- a/trunk/drivers/mmc/host/pxamci.c +++ b/trunk/drivers/mmc/pxamci.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -368,14 +369,14 @@ static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (CLOCKRATE / clk > ios->clock) clk <<= 1; host->clkrt = fls(clk) - 1; - pxa_set_cken(CKEN_MMC, 1); + pxa_set_cken(CKEN12_MMC, 1); /* * we write clkrt on the next command */ } else { pxamci_stop_clock(host); - pxa_set_cken(CKEN_MMC, 0); + pxa_set_cken(CKEN12_MMC, 0); } if (host->power_mode != ios->power_mode) { diff --git a/trunk/drivers/mmc/host/pxamci.h b/trunk/drivers/mmc/pxamci.h similarity index 100% rename from trunk/drivers/mmc/host/pxamci.h rename to trunk/drivers/mmc/pxamci.h diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/sdhci.c similarity index 97% rename from trunk/drivers/mmc/host/sdhci.c rename to trunk/drivers/mmc/sdhci.c index ff5bf73cdd25..d749f08601b8 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/sdhci.c @@ -1,7 +1,7 @@ /* * linux/drivers/mmc/sdhci.c - Secure Digital Host Controller Interface driver * - * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. + * Copyright (C) 2005-2006 Pierre Ossman, All Rights Reserved. * * 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 @@ -15,6 +15,7 @@ #include #include +#include #include @@ -246,13 +247,14 @@ static void sdhci_read_block_pio(struct sdhci_host *host) chunk_remain = min(blksize, 4); } - size = min(host->remain, chunk_remain); + size = min(host->size, host->remain); + size = min(size, chunk_remain); chunk_remain -= size; blksize -= size; host->offset += size; host->remain -= size; - + host->size -= size; while (size) { *buffer = data & 0xFF; buffer++; @@ -287,13 +289,14 @@ static void sdhci_write_block_pio(struct sdhci_host *host) buffer = sdhci_sg_to_buffer(host) + host->offset; while (blksize) { - size = min(host->remain, chunk_remain); + size = min(host->size, host->remain); + size = min(size, chunk_remain); chunk_remain -= size; blksize -= size; host->offset += size; host->remain -= size; - + host->size -= size; while (size) { data >>= 8; data |= (u32)*buffer << 24; @@ -322,7 +325,7 @@ static void sdhci_transfer_pio(struct sdhci_host *host) BUG_ON(!host->data); - if (host->num_sg == 0) + if (host->size == 0) return; if (host->data->flags & MMC_DATA_READ) @@ -336,8 +339,10 @@ static void sdhci_transfer_pio(struct sdhci_host *host) else sdhci_write_block_pio(host); - if (host->num_sg == 0) + if (host->size == 0) break; + + BUG_ON(host->num_sg == 0); } DBG("PIO transfer complete.\n"); @@ -403,6 +408,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) writel(sg_dma_address(data->sg), host->ioaddr + SDHCI_DMA_ADDRESS); } else { + host->size = data->blksz * data->blocks; + host->cur_sg = data->sg; host->num_sg = data->sg_len; @@ -466,6 +473,10 @@ static void sdhci_finish_data(struct sdhci_host *host) "though there were blocks left.\n", mmc_hostname(host->mmc)); data->error = MMC_ERR_FAILED; + } else if (host->size != 0) { + printk(KERN_ERR "%s: %d bytes were left untransferred.\n", + mmc_hostname(host->mmc), host->size); + data->error = MMC_ERR_FAILED; } DBG("Ending data transfer (%d bytes)\n", data->bytes_xfered); @@ -658,16 +669,20 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) pwr = SDHCI_POWER_ON; - switch (1 << power) { - case MMC_VDD_165_195: + switch (power) { + case MMC_VDD_170: + case MMC_VDD_180: + case MMC_VDD_190: pwr |= SDHCI_POWER_180; break; - case MMC_VDD_29_30: - case MMC_VDD_30_31: + case MMC_VDD_290: + case MMC_VDD_300: + case MMC_VDD_310: pwr |= SDHCI_POWER_300; break; - case MMC_VDD_32_33: - case MMC_VDD_33_34: + case MMC_VDD_320: + case MMC_VDD_330: + case MMC_VDD_340: pwr |= SDHCI_POWER_330; break; default: @@ -1279,7 +1294,7 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) if (caps & SDHCI_CAN_VDD_300) mmc->ocr_avail |= MMC_VDD_29_30|MMC_VDD_30_31; if (caps & SDHCI_CAN_VDD_180) - mmc->ocr_avail |= MMC_VDD_165_195; + mmc->ocr_avail |= MMC_VDD_17_18|MMC_VDD_18_19; if (mmc->ocr_avail == 0) { printk(KERN_ERR "%s: Hardware doesn't report any " diff --git a/trunk/drivers/mmc/host/sdhci.h b/trunk/drivers/mmc/sdhci.h similarity index 98% rename from trunk/drivers/mmc/host/sdhci.h rename to trunk/drivers/mmc/sdhci.h index 7400f4bc114f..e324f0a623dc 100644 --- a/trunk/drivers/mmc/host/sdhci.h +++ b/trunk/drivers/mmc/sdhci.h @@ -1,7 +1,7 @@ /* * linux/drivers/mmc/sdhci.h - Secure Digital Host Controller Interface driver * - * Copyright (C) 2005-2007 Pierre Ossman, All Rights Reserved. + * Copyright (C) 2005 Pierre Ossman, All Rights Reserved. * * 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 @@ -187,6 +187,8 @@ struct sdhci_host { int offset; /* Offset into current sg */ int remain; /* Bytes left in current */ + int size; /* Remaining bytes in transfer */ + char slot_descr[20]; /* Name for reservations */ int irq; /* Device IRQ */ diff --git a/trunk/drivers/mmc/tifm_sd.c b/trunk/drivers/mmc/tifm_sd.c new file mode 100644 index 000000000000..0581d09c58fc --- /dev/null +++ b/trunk/drivers/mmc/tifm_sd.c @@ -0,0 +1,987 @@ +/* + * tifm_sd.c - TI FlashMedia driver + * + * Copyright (C) 2006 Alex Dubov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + + +#include +#include +#include +#include +#include + +#define DRIVER_NAME "tifm_sd" +#define DRIVER_VERSION "0.7" + +static int no_dma = 0; +static int fixed_timeout = 0; +module_param(no_dma, bool, 0644); +module_param(fixed_timeout, bool, 0644); + +/* Constants here are mostly from OMAP5912 datasheet */ +#define TIFM_MMCSD_RESET 0x0002 +#define TIFM_MMCSD_CLKMASK 0x03ff +#define TIFM_MMCSD_POWER 0x0800 +#define TIFM_MMCSD_4BBUS 0x8000 +#define TIFM_MMCSD_RXDE 0x8000 /* rx dma enable */ +#define TIFM_MMCSD_TXDE 0x0080 /* tx dma enable */ +#define TIFM_MMCSD_BUFINT 0x0c00 /* set bits: AE, AF */ +#define TIFM_MMCSD_DPE 0x0020 /* data timeout counted in kilocycles */ +#define TIFM_MMCSD_INAB 0x0080 /* abort / initialize command */ +#define TIFM_MMCSD_READ 0x8000 + +#define TIFM_MMCSD_DATAMASK 0x401d /* set bits: CERR, EOFB, BRS, CB, EOC */ +#define TIFM_MMCSD_ERRMASK 0x01e0 /* set bits: CCRC, CTO, DCRC, DTO */ +#define TIFM_MMCSD_EOC 0x0001 /* end of command phase */ +#define TIFM_MMCSD_CB 0x0004 /* card enter busy state */ +#define TIFM_MMCSD_BRS 0x0008 /* block received/sent */ +#define TIFM_MMCSD_EOFB 0x0010 /* card exit busy state */ +#define TIFM_MMCSD_DTO 0x0020 /* data time-out */ +#define TIFM_MMCSD_DCRC 0x0040 /* data crc error */ +#define TIFM_MMCSD_CTO 0x0080 /* command time-out */ +#define TIFM_MMCSD_CCRC 0x0100 /* command crc error */ +#define TIFM_MMCSD_AF 0x0400 /* fifo almost full */ +#define TIFM_MMCSD_AE 0x0800 /* fifo almost empty */ +#define TIFM_MMCSD_CERR 0x4000 /* card status error */ + +#define TIFM_MMCSD_FIFO_SIZE 0x0020 + +#define TIFM_MMCSD_RSP_R0 0x0000 +#define TIFM_MMCSD_RSP_R1 0x0100 +#define TIFM_MMCSD_RSP_R2 0x0200 +#define TIFM_MMCSD_RSP_R3 0x0300 +#define TIFM_MMCSD_RSP_R4 0x0400 +#define TIFM_MMCSD_RSP_R5 0x0500 +#define TIFM_MMCSD_RSP_R6 0x0600 + +#define TIFM_MMCSD_RSP_BUSY 0x0800 + +#define TIFM_MMCSD_CMD_BC 0x0000 +#define TIFM_MMCSD_CMD_BCR 0x1000 +#define TIFM_MMCSD_CMD_AC 0x2000 +#define TIFM_MMCSD_CMD_ADTC 0x3000 + +typedef enum { + IDLE = 0, + CMD, /* main command ended */ + BRS, /* block transfer finished */ + SCMD, /* stop command ended */ + CARD, /* card left busy state */ + FIFO, /* FIFO operation completed (uncertain) */ + READY +} card_state_t; + +enum { + FIFO_RDY = 0x0001, /* hardware dependent value */ + EJECT = 0x0004, + EJECT_DONE = 0x0008, + CARD_BUSY = 0x0010, + OPENDRAIN = 0x0040, /* hardware dependent value */ + CARD_EVENT = 0x0100, /* hardware dependent value */ + CARD_RO = 0x0200, /* hardware dependent value */ + FIFO_EVENT = 0x10000 }; /* hardware dependent value */ + +struct tifm_sd { + struct tifm_dev *dev; + + unsigned int flags; + card_state_t state; + unsigned int clk_freq; + unsigned int clk_div; + unsigned long timeout_jiffies; + + struct tasklet_struct finish_tasklet; + struct timer_list timer; + struct mmc_request *req; + wait_queue_head_t notify; + + size_t written_blocks; + size_t buffer_size; + size_t buffer_pos; + +}; + +static char* tifm_sd_data_buffer(struct mmc_data *data) +{ + return page_address(data->sg->page) + data->sg->offset; +} + +static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, + unsigned int host_status) +{ + struct mmc_command *cmd = host->req->cmd; + unsigned int t_val = 0, cnt = 0; + char *buffer; + + if (host_status & TIFM_MMCSD_BRS) { + /* in non-dma rx mode BRS fires when fifo is still not empty */ + if (no_dma && (cmd->data->flags & MMC_DATA_READ)) { + buffer = tifm_sd_data_buffer(host->req->data); + while (host->buffer_size > host->buffer_pos) { + t_val = readl(sock->addr + SOCK_MMCSD_DATA); + buffer[host->buffer_pos++] = t_val & 0xff; + buffer[host->buffer_pos++] = + (t_val >> 8) & 0xff; + } + } + return 1; + } else if (no_dma) { + buffer = tifm_sd_data_buffer(host->req->data); + if ((cmd->data->flags & MMC_DATA_READ) && + (host_status & TIFM_MMCSD_AF)) { + for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { + t_val = readl(sock->addr + SOCK_MMCSD_DATA); + if (host->buffer_size > host->buffer_pos) { + buffer[host->buffer_pos++] = + t_val & 0xff; + buffer[host->buffer_pos++] = + (t_val >> 8) & 0xff; + } + } + } else if ((cmd->data->flags & MMC_DATA_WRITE) + && (host_status & TIFM_MMCSD_AE)) { + for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { + if (host->buffer_size > host->buffer_pos) { + t_val = buffer[host->buffer_pos++] + & 0x00ff; + t_val |= ((buffer[host->buffer_pos++]) + << 8) & 0xff00; + writel(t_val, + sock->addr + SOCK_MMCSD_DATA); + } + } + } + } + return 0; +} + +static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) +{ + unsigned int rc = 0; + + switch (mmc_resp_type(cmd)) { + case MMC_RSP_NONE: + rc |= TIFM_MMCSD_RSP_R0; + break; + case MMC_RSP_R1B: + rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through + case MMC_RSP_R1: + rc |= TIFM_MMCSD_RSP_R1; + break; + case MMC_RSP_R2: + rc |= TIFM_MMCSD_RSP_R2; + break; + case MMC_RSP_R3: + rc |= TIFM_MMCSD_RSP_R3; + break; + default: + BUG(); + } + + switch (mmc_cmd_type(cmd)) { + case MMC_CMD_BC: + rc |= TIFM_MMCSD_CMD_BC; + break; + case MMC_CMD_BCR: + rc |= TIFM_MMCSD_CMD_BCR; + break; + case MMC_CMD_AC: + rc |= TIFM_MMCSD_CMD_AC; + break; + case MMC_CMD_ADTC: + rc |= TIFM_MMCSD_CMD_ADTC; + break; + default: + BUG(); + } + return rc; +} + +static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd) +{ + struct tifm_dev *sock = host->dev; + unsigned int cmd_mask = tifm_sd_op_flags(cmd) | + (host->flags & OPENDRAIN); + + if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) + cmd_mask |= TIFM_MMCSD_READ; + + dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n", + cmd->opcode, cmd->arg, cmd_mask); + + writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH); + writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW); + writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND); +} + +static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock) +{ + cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16) + | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18); + cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16) + | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10); + cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16) + | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08); + cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16) + | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00); +} + +static void tifm_sd_process_cmd(struct tifm_dev *sock, struct tifm_sd *host, + unsigned int host_status) +{ + struct mmc_command *cmd = host->req->cmd; + +change_state: + switch (host->state) { + case IDLE: + return; + case CMD: + if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) { + tifm_sd_fetch_resp(cmd, sock); + if (cmd->data) { + host->state = BRS; + } else { + host->state = READY; + } + goto change_state; + } + break; + case BRS: + if (tifm_sd_transfer_data(sock, host, host_status)) { + if (cmd->data->flags & MMC_DATA_WRITE) { + host->state = CARD; + } else { + if (no_dma) { + if (host->req->stop) { + tifm_sd_exec(host, host->req->stop); + host->state = SCMD; + } else { + host->state = READY; + } + } else { + host->state = FIFO; + } + } + goto change_state; + } + break; + case SCMD: + if (host_status & TIFM_MMCSD_EOC) { + tifm_sd_fetch_resp(host->req->stop, sock); + host->state = READY; + goto change_state; + } + break; + case CARD: + dev_dbg(&sock->dev, "waiting for CARD, have %zd blocks\n", + host->written_blocks); + if (!(host->flags & CARD_BUSY) + && (host->written_blocks == cmd->data->blocks)) { + if (no_dma) { + if (host->req->stop) { + tifm_sd_exec(host, host->req->stop); + host->state = SCMD; + } else { + host->state = READY; + } + } else { + host->state = FIFO; + } + goto change_state; + } + break; + case FIFO: + if (host->flags & FIFO_RDY) { + host->flags &= ~FIFO_RDY; + if (host->req->stop) { + tifm_sd_exec(host, host->req->stop); + host->state = SCMD; + } else { + host->state = READY; + } + goto change_state; + } + break; + case READY: + tasklet_schedule(&host->finish_tasklet); + return; + } + +} + +/* Called from interrupt handler */ +static void tifm_sd_signal_irq(struct tifm_dev *sock, + unsigned int sock_irq_status) +{ + struct tifm_sd *host; + unsigned int host_status = 0, fifo_status = 0; + int error_code = 0; + + spin_lock(&sock->lock); + host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock)); + + if (sock_irq_status & FIFO_EVENT) { + fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS); + writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS); + + host->flags |= fifo_status & FIFO_RDY; + } + + if (sock_irq_status & CARD_EVENT) { + host_status = readl(sock->addr + SOCK_MMCSD_STATUS); + writel(host_status, sock->addr + SOCK_MMCSD_STATUS); + + if (!host->req) + goto done; + + if (host_status & TIFM_MMCSD_ERRMASK) { + if (host_status & (TIFM_MMCSD_CTO | TIFM_MMCSD_DTO)) + error_code = MMC_ERR_TIMEOUT; + else if (host_status + & (TIFM_MMCSD_CCRC | TIFM_MMCSD_DCRC)) + error_code = MMC_ERR_BADCRC; + + writel(TIFM_FIFO_INT_SETALL, + sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); + writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL); + + if (host->req->stop) { + if (host->state == SCMD) { + host->req->stop->error = error_code; + } else if (host->state == BRS + || host->state == CARD + || host->state == FIFO) { + host->req->cmd->error = error_code; + tifm_sd_exec(host, host->req->stop); + host->state = SCMD; + goto done; + } else { + host->req->cmd->error = error_code; + } + } else { + host->req->cmd->error = error_code; + } + host->state = READY; + } + + if (host_status & TIFM_MMCSD_CB) + host->flags |= CARD_BUSY; + if ((host_status & TIFM_MMCSD_EOFB) + && (host->flags & CARD_BUSY)) { + host->written_blocks++; + host->flags &= ~CARD_BUSY; + } + } + + if (host->req) + tifm_sd_process_cmd(sock, host, host_status); +done: + dev_dbg(&sock->dev, "host_status %x, fifo_status %x\n", + host_status, fifo_status); + spin_unlock(&sock->lock); +} + +static void tifm_sd_prepare_data(struct tifm_sd *host, struct mmc_command *cmd) +{ + struct tifm_dev *sock = host->dev; + unsigned int dest_cnt; + + /* DMA style IO */ + dev_dbg(&sock->dev, "setting dma for %d blocks\n", + cmd->data->blocks); + writel(TIFM_FIFO_INT_SETALL, + sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); + writel(ilog2(cmd->data->blksz) - 2, + sock->addr + SOCK_FIFO_PAGE_SIZE); + writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL); + writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); + + dest_cnt = (cmd->data->blocks) << 8; + + writel(sg_dma_address(cmd->data->sg), sock->addr + SOCK_DMA_ADDRESS); + + writel(cmd->data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS); + writel(cmd->data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN); + + if (cmd->data->flags & MMC_DATA_WRITE) { + writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); + writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN, + sock->addr + SOCK_DMA_CONTROL); + } else { + writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); + writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL); + } +} + +static void tifm_sd_set_data_timeout(struct tifm_sd *host, + struct mmc_data *data) +{ + struct tifm_dev *sock = host->dev; + unsigned int data_timeout = data->timeout_clks; + + if (fixed_timeout) + return; + + data_timeout += data->timeout_ns / + ((1000000000UL / host->clk_freq) * host->clk_div); + + if (data_timeout < 0xffff) { + writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); + writel((~TIFM_MMCSD_DPE) + & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), + sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); + } else { + data_timeout = (data_timeout >> 10) + 1; + if (data_timeout > 0xffff) + data_timeout = 0; /* set to unlimited */ + writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO); + writel(TIFM_MMCSD_DPE + | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG), + sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG); + } +} + +static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct tifm_sd *host = mmc_priv(mmc); + struct tifm_dev *sock = host->dev; + unsigned long flags; + int sg_count = 0; + struct mmc_data *r_data = mrq->cmd->data; + + spin_lock_irqsave(&sock->lock, flags); + if (host->flags & EJECT) { + spin_unlock_irqrestore(&sock->lock, flags); + goto err_out; + } + + if (host->req) { + printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); + spin_unlock_irqrestore(&sock->lock, flags); + goto err_out; + } + + if (r_data) { + tifm_sd_set_data_timeout(host, r_data); + + sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len, + mrq->cmd->flags & MMC_DATA_WRITE + ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + if (sg_count != 1) { + printk(KERN_ERR DRIVER_NAME + ": scatterlist map failed\n"); + spin_unlock_irqrestore(&sock->lock, flags); + goto err_out; + } + + host->written_blocks = 0; + host->flags &= ~CARD_BUSY; + tifm_sd_prepare_data(host, mrq->cmd); + } + + host->req = mrq; + mod_timer(&host->timer, jiffies + host->timeout_jiffies); + host->state = CMD; + writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), + sock->addr + SOCK_CONTROL); + tifm_sd_exec(host, mrq->cmd); + spin_unlock_irqrestore(&sock->lock, flags); + return; + +err_out: + if (sg_count > 0) + tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, + (r_data->flags & MMC_DATA_WRITE) + ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + + mrq->cmd->error = MMC_ERR_TIMEOUT; + mmc_request_done(mmc, mrq); +} + +static void tifm_sd_end_cmd(unsigned long data) +{ + struct tifm_sd *host = (struct tifm_sd*)data; + struct tifm_dev *sock = host->dev; + struct mmc_host *mmc = tifm_get_drvdata(sock); + struct mmc_request *mrq; + struct mmc_data *r_data = NULL; + unsigned long flags; + + spin_lock_irqsave(&sock->lock, flags); + + del_timer(&host->timer); + mrq = host->req; + host->req = NULL; + host->state = IDLE; + + if (!mrq) { + printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); + spin_unlock_irqrestore(&sock->lock, flags); + return; + } + + r_data = mrq->cmd->data; + if (r_data) { + if (r_data->flags & MMC_DATA_WRITE) { + r_data->bytes_xfered = host->written_blocks + * r_data->blksz; + } else { + r_data->bytes_xfered = r_data->blocks - + readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; + r_data->bytes_xfered *= r_data->blksz; + r_data->bytes_xfered += r_data->blksz - + readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; + } + tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, + (r_data->flags & MMC_DATA_WRITE) + ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); + } + + writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), + sock->addr + SOCK_CONTROL); + + spin_unlock_irqrestore(&sock->lock, flags); + mmc_request_done(mmc, mrq); +} + +static void tifm_sd_request_nodma(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct tifm_sd *host = mmc_priv(mmc); + struct tifm_dev *sock = host->dev; + unsigned long flags; + struct mmc_data *r_data = mrq->cmd->data; + + spin_lock_irqsave(&sock->lock, flags); + if (host->flags & EJECT) { + spin_unlock_irqrestore(&sock->lock, flags); + goto err_out; + } + + if (host->req) { + printk(KERN_ERR DRIVER_NAME ": unfinished request detected\n"); + spin_unlock_irqrestore(&sock->lock, flags); + goto err_out; + } + + if (r_data) { + tifm_sd_set_data_timeout(host, r_data); + + host->buffer_size = mrq->cmd->data->blocks + * mrq->cmd->data->blksz; + + writel(TIFM_MMCSD_BUFINT + | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), + sock->addr + SOCK_MMCSD_INT_ENABLE); + writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8) + | (TIFM_MMCSD_FIFO_SIZE - 1), + sock->addr + SOCK_MMCSD_BUFFER_CONFIG); + + host->written_blocks = 0; + host->flags &= ~CARD_BUSY; + host->buffer_pos = 0; + writel(r_data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS); + writel(r_data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN); + } + + host->req = mrq; + mod_timer(&host->timer, jiffies + host->timeout_jiffies); + host->state = CMD; + writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), + sock->addr + SOCK_CONTROL); + tifm_sd_exec(host, mrq->cmd); + spin_unlock_irqrestore(&sock->lock, flags); + return; + +err_out: + mrq->cmd->error = MMC_ERR_TIMEOUT; + mmc_request_done(mmc, mrq); +} + +static void tifm_sd_end_cmd_nodma(unsigned long data) +{ + struct tifm_sd *host = (struct tifm_sd*)data; + struct tifm_dev *sock = host->dev; + struct mmc_host *mmc = tifm_get_drvdata(sock); + struct mmc_request *mrq; + struct mmc_data *r_data = NULL; + unsigned long flags; + + spin_lock_irqsave(&sock->lock, flags); + + del_timer(&host->timer); + mrq = host->req; + host->req = NULL; + host->state = IDLE; + + if (!mrq) { + printk(KERN_ERR DRIVER_NAME ": no request to complete?\n"); + spin_unlock_irqrestore(&sock->lock, flags); + return; + } + + r_data = mrq->cmd->data; + if (r_data) { + writel((~TIFM_MMCSD_BUFINT) & + readl(sock->addr + SOCK_MMCSD_INT_ENABLE), + sock->addr + SOCK_MMCSD_INT_ENABLE); + + if (r_data->flags & MMC_DATA_WRITE) { + r_data->bytes_xfered = host->written_blocks + * r_data->blksz; + } else { + r_data->bytes_xfered = r_data->blocks - + readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1; + r_data->bytes_xfered *= r_data->blksz; + r_data->bytes_xfered += r_data->blksz - + readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1; + } + host->buffer_pos = 0; + host->buffer_size = 0; + } + + writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), + sock->addr + SOCK_CONTROL); + + spin_unlock_irqrestore(&sock->lock, flags); + + mmc_request_done(mmc, mrq); +} + +static void tifm_sd_terminate(struct tifm_sd *host) +{ + struct tifm_dev *sock = host->dev; + unsigned long flags; + + writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); + mmiowb(); + spin_lock_irqsave(&sock->lock, flags); + host->flags |= EJECT; + if (host->req) { + writel(TIFM_FIFO_INT_SETALL, + sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR); + writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET); + tasklet_schedule(&host->finish_tasklet); + } + spin_unlock_irqrestore(&sock->lock, flags); +} + +static void tifm_sd_abort(unsigned long data) +{ + struct tifm_sd *host = (struct tifm_sd*)data; + + printk(KERN_ERR DRIVER_NAME + ": card failed to respond for a long period of time"); + + tifm_sd_terminate(host); + tifm_eject(host->dev); +} + +static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct tifm_sd *host = mmc_priv(mmc); + struct tifm_dev *sock = host->dev; + unsigned int clk_div1, clk_div2; + unsigned long flags; + + spin_lock_irqsave(&sock->lock, flags); + + dev_dbg(&sock->dev, "Setting bus width %d, power %d\n", ios->bus_width, + ios->power_mode); + if (ios->bus_width == MMC_BUS_WIDTH_4) { + writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG), + sock->addr + SOCK_MMCSD_CONFIG); + } else { + writel((~TIFM_MMCSD_4BBUS) + & readl(sock->addr + SOCK_MMCSD_CONFIG), + sock->addr + SOCK_MMCSD_CONFIG); + } + + if (ios->clock) { + clk_div1 = 20000000 / ios->clock; + if (!clk_div1) + clk_div1 = 1; + + clk_div2 = 24000000 / ios->clock; + if (!clk_div2) + clk_div2 = 1; + + if ((20000000 / clk_div1) > ios->clock) + clk_div1++; + if ((24000000 / clk_div2) > ios->clock) + clk_div2++; + if ((20000000 / clk_div1) > (24000000 / clk_div2)) { + host->clk_freq = 20000000; + host->clk_div = clk_div1; + writel((~TIFM_CTRL_FAST_CLK) + & readl(sock->addr + SOCK_CONTROL), + sock->addr + SOCK_CONTROL); + } else { + host->clk_freq = 24000000; + host->clk_div = clk_div2; + writel(TIFM_CTRL_FAST_CLK + | readl(sock->addr + SOCK_CONTROL), + sock->addr + SOCK_CONTROL); + } + } else { + host->clk_div = 0; + } + host->clk_div &= TIFM_MMCSD_CLKMASK; + writel(host->clk_div + | ((~TIFM_MMCSD_CLKMASK) + & readl(sock->addr + SOCK_MMCSD_CONFIG)), + sock->addr + SOCK_MMCSD_CONFIG); + + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) + host->flags |= OPENDRAIN; + else + host->flags &= ~OPENDRAIN; + + /* chip_select : maybe later */ + //vdd + //power is set before probe / after remove + //I believe, power_off when already marked for eject is sufficient to + // allow removal. + if ((host->flags & EJECT) && ios->power_mode == MMC_POWER_OFF) { + host->flags |= EJECT_DONE; + wake_up_all(&host->notify); + } + + spin_unlock_irqrestore(&sock->lock, flags); +} + +static int tifm_sd_ro(struct mmc_host *mmc) +{ + int rc; + struct tifm_sd *host = mmc_priv(mmc); + struct tifm_dev *sock = host->dev; + unsigned long flags; + + spin_lock_irqsave(&sock->lock, flags); + + host->flags |= (CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE)); + rc = (host->flags & CARD_RO) ? 1 : 0; + + spin_unlock_irqrestore(&sock->lock, flags); + return rc; +} + +static struct mmc_host_ops tifm_sd_ops = { + .request = tifm_sd_request, + .set_ios = tifm_sd_ios, + .get_ro = tifm_sd_ro +}; + +static int tifm_sd_initialize_host(struct tifm_sd *host) +{ + int rc; + unsigned int host_status = 0; + struct tifm_dev *sock = host->dev; + + writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE); + mmiowb(); + host->clk_div = 61; + host->clk_freq = 20000000; + writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL); + writel(host->clk_div | TIFM_MMCSD_POWER, + sock->addr + SOCK_MMCSD_CONFIG); + + /* wait up to 0.51 sec for reset */ + for (rc = 2; rc <= 256; rc <<= 1) { + if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) { + rc = 0; + break; + } + msleep(rc); + } + + if (rc) { + printk(KERN_ERR DRIVER_NAME + ": controller failed to reset\n"); + return -ENODEV; + } + + writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS); + writel(host->clk_div | TIFM_MMCSD_POWER, + sock->addr + SOCK_MMCSD_CONFIG); + writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG); + + // command timeout fixed to 64 clocks for now + writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO); + writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND); + + /* INAB should take much less than reset */ + for (rc = 1; rc <= 16; rc <<= 1) { + host_status = readl(sock->addr + SOCK_MMCSD_STATUS); + writel(host_status, sock->addr + SOCK_MMCSD_STATUS); + if (!(host_status & TIFM_MMCSD_ERRMASK) + && (host_status & TIFM_MMCSD_EOC)) { + rc = 0; + break; + } + msleep(rc); + } + + if (rc) { + printk(KERN_ERR DRIVER_NAME + ": card not ready - probe failed on initialization\n"); + return -ENODEV; + } + + writel(TIFM_MMCSD_DATAMASK | TIFM_MMCSD_ERRMASK, + sock->addr + SOCK_MMCSD_INT_ENABLE); + mmiowb(); + + return 0; +} + +static int tifm_sd_probe(struct tifm_dev *sock) +{ + struct mmc_host *mmc; + struct tifm_sd *host; + int rc = -EIO; + + if (!(TIFM_SOCK_STATE_OCCUPIED + & readl(sock->addr + SOCK_PRESENT_STATE))) { + printk(KERN_WARNING DRIVER_NAME ": card gone, unexpectedly\n"); + return rc; + } + + mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev); + if (!mmc) + return -ENOMEM; + + host = mmc_priv(mmc); + tifm_set_drvdata(sock, mmc); + host->dev = sock; + host->timeout_jiffies = msecs_to_jiffies(1000); + + init_waitqueue_head(&host->notify); + tasklet_init(&host->finish_tasklet, + no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd, + (unsigned long)host); + setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host); + + tifm_sd_ops.request = no_dma ? tifm_sd_request_nodma : tifm_sd_request; + mmc->ops = &tifm_sd_ops; + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; + mmc->f_min = 20000000 / 60; + mmc->f_max = 24000000; + mmc->max_hw_segs = 1; + mmc->max_phys_segs = 1; + // limited by DMA counter - it's safer to stick with + // block counter has 11 bits though + mmc->max_blk_count = 256; + // 2k maximum hw block length + mmc->max_blk_size = 2048; + mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; + mmc->max_seg_size = mmc->max_req_size; + sock->signal_irq = tifm_sd_signal_irq; + rc = tifm_sd_initialize_host(host); + + if (!rc) + rc = mmc_add_host(mmc); + if (rc) + goto out_free_mmc; + + return 0; +out_free_mmc: + mmc_free_host(mmc); + return rc; +} + +static void tifm_sd_remove(struct tifm_dev *sock) +{ + struct mmc_host *mmc = tifm_get_drvdata(sock); + struct tifm_sd *host = mmc_priv(mmc); + + del_timer_sync(&host->timer); + tifm_sd_terminate(host); + wait_event_timeout(host->notify, host->flags & EJECT_DONE, + host->timeout_jiffies); + tasklet_kill(&host->finish_tasklet); + mmc_remove_host(mmc); + + /* The meaning of the bit majority in this constant is unknown. */ + writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), + sock->addr + SOCK_CONTROL); + + tifm_set_drvdata(sock, NULL); + mmc_free_host(mmc); +} + +#ifdef CONFIG_PM + +static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state) +{ + struct mmc_host *mmc = tifm_get_drvdata(sock); + int rc; + + rc = mmc_suspend_host(mmc, state); + /* The meaning of the bit majority in this constant is unknown. */ + writel(0xfff8 & readl(sock->addr + SOCK_CONTROL), + sock->addr + SOCK_CONTROL); + return rc; +} + +static int tifm_sd_resume(struct tifm_dev *sock) +{ + struct mmc_host *mmc = tifm_get_drvdata(sock); + struct tifm_sd *host = mmc_priv(mmc); + + if (sock->media_id != FM_SD + || tifm_sd_initialize_host(host)) { + tifm_eject(sock); + return 0; + } else { + return mmc_resume_host(mmc); + } +} + +#else + +#define tifm_sd_suspend NULL +#define tifm_sd_resume NULL + +#endif /* CONFIG_PM */ + +static tifm_media_id tifm_sd_id_tbl[] = { + FM_SD, 0 +}; + +static struct tifm_driver tifm_sd_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE + }, + .id_table = tifm_sd_id_tbl, + .probe = tifm_sd_probe, + .remove = tifm_sd_remove, + .suspend = tifm_sd_suspend, + .resume = tifm_sd_resume +}; + +static int __init tifm_sd_init(void) +{ + return tifm_register_driver(&tifm_sd_driver); +} + +static void __exit tifm_sd_exit(void) +{ + tifm_unregister_driver(&tifm_sd_driver); +} + +MODULE_AUTHOR("Alex Dubov"); +MODULE_DESCRIPTION("TI FlashMedia SD driver"); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl); +MODULE_VERSION(DRIVER_VERSION); + +module_init(tifm_sd_init); +module_exit(tifm_sd_exit); diff --git a/trunk/drivers/mmc/host/wbsd.c b/trunk/drivers/mmc/wbsd.c similarity index 93% rename from trunk/drivers/mmc/host/wbsd.c rename to trunk/drivers/mmc/wbsd.c index 867ca6a69298..05ccfc43168f 100644 --- a/trunk/drivers/mmc/host/wbsd.c +++ b/trunk/drivers/mmc/wbsd.c @@ -1,7 +1,7 @@ /* * linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver * - * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. + * Copyright (C) 2004-2006 Pierre Ossman, All Rights Reserved. * * 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 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -177,8 +178,9 @@ static void wbsd_init_device(struct wbsd_host *host) ier = 0; ier |= WBSD_EINT_CARD; ier |= WBSD_EINT_FIFO_THRE; - ier |= WBSD_EINT_CRC; + ier |= WBSD_EINT_CCRC; ier |= WBSD_EINT_TIMEOUT; + ier |= WBSD_EINT_CRC; ier |= WBSD_EINT_TC; outb(ier, host->base + WBSD_EIR); @@ -276,36 +278,90 @@ static inline char *wbsd_sg_to_buffer(struct wbsd_host *host) static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) { - unsigned int len, i; + unsigned int len, i, size; struct scatterlist *sg; char *dmabuf = host->dma_buffer; char *sgbuf; + size = host->size; + sg = data->sg; len = data->sg_len; + /* + * Just loop through all entries. Size might not + * be the entire list though so make sure that + * we do not transfer too much. + */ for (i = 0; i < len; i++) { sgbuf = page_address(sg[i].page) + sg[i].offset; - memcpy(dmabuf, sgbuf, sg[i].length); + if (size < sg[i].length) + memcpy(dmabuf, sgbuf, size); + else + memcpy(dmabuf, sgbuf, sg[i].length); dmabuf += sg[i].length; + + if (size < sg[i].length) + size = 0; + else + size -= sg[i].length; + + if (size == 0) + break; } + + /* + * Check that we didn't get a request to transfer + * more data than can fit into the SG list. + */ + + BUG_ON(size != 0); + + host->size -= size; } static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) { - unsigned int len, i; + unsigned int len, i, size; struct scatterlist *sg; char *dmabuf = host->dma_buffer; char *sgbuf; + size = host->size; + sg = data->sg; len = data->sg_len; + /* + * Just loop through all entries. Size might not + * be the entire list though so make sure that + * we do not transfer too much. + */ for (i = 0; i < len; i++) { sgbuf = page_address(sg[i].page) + sg[i].offset; - memcpy(sgbuf, dmabuf, sg[i].length); + if (size < sg[i].length) + memcpy(sgbuf, dmabuf, size); + else + memcpy(sgbuf, dmabuf, sg[i].length); dmabuf += sg[i].length; + + if (size < sg[i].length) + size = 0; + else + size -= sg[i].length; + + if (size == 0) + break; } + + /* + * Check that we didn't get a request to transfer + * more data than can fit into the SG list. + */ + + BUG_ON(size != 0); + + host->size -= size; } /* @@ -428,7 +484,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) /* * Handle excessive data. */ - if (host->num_sg == 0) + if (data->bytes_xfered == host->size) return; buffer = wbsd_sg_to_buffer(host) + host->offset; @@ -457,6 +513,12 @@ static void wbsd_empty_fifo(struct wbsd_host *host) data->bytes_xfered++; + /* + * Transfer done? + */ + if (data->bytes_xfered == host->size) + return; + /* * End of scatter list entry? */ @@ -464,8 +526,19 @@ static void wbsd_empty_fifo(struct wbsd_host *host) /* * Get next entry. Check if last. */ - if (!wbsd_next_sg(host)) + if (!wbsd_next_sg(host)) { + /* + * We should never reach this point. + * It means that we're trying to + * transfer more blocks than can fit + * into the scatter list. + */ + BUG_ON(1); + + host->size = data->bytes_xfered; + return; + } buffer = wbsd_sg_to_buffer(host); } @@ -477,7 +550,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host) * hardware problem. The chip doesn't trigger * FIFO threshold interrupts properly. */ - if ((data->blocks * data->blksz - data->bytes_xfered) < 16) + if ((host->size - data->bytes_xfered) < 16) tasklet_schedule(&host->fifo_tasklet); } @@ -491,7 +564,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) * Check that we aren't being called after the * entire buffer has been transfered. */ - if (host->num_sg == 0) + if (data->bytes_xfered == host->size) return; buffer = wbsd_sg_to_buffer(host) + host->offset; @@ -520,6 +593,12 @@ static void wbsd_fill_fifo(struct wbsd_host *host) data->bytes_xfered++; + /* + * Transfer done? + */ + if (data->bytes_xfered == host->size) + return; + /* * End of scatter list entry? */ @@ -527,8 +606,19 @@ static void wbsd_fill_fifo(struct wbsd_host *host) /* * Get next entry. Check if last. */ - if (!wbsd_next_sg(host)) + if (!wbsd_next_sg(host)) { + /* + * We should never reach this point. + * It means that we're trying to + * transfer more blocks than can fit + * into the scatter list. + */ + BUG_ON(1); + + host->size = data->bytes_xfered; + return; + } buffer = wbsd_sg_to_buffer(host); } @@ -548,7 +638,6 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) u16 blksize; u8 setup; unsigned long dmaflags; - unsigned int size; DBGF("blksz %04x blks %04x flags %08x\n", data->blksz, data->blocks, data->flags); @@ -558,7 +647,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) /* * Calculate size. */ - size = data->blocks * data->blksz; + host->size = data->blocks * data->blksz; /* * Check timeout values for overflow. @@ -616,8 +705,8 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) /* * The buffer for DMA is only 64 kB. */ - BUG_ON(size > 0x10000); - if (size > 0x10000) { + BUG_ON(host->size > 0x10000); + if (host->size > 0x10000) { data->error = MMC_ERR_INVALID; return; } @@ -640,7 +729,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) else set_dma_mode(host->dma, DMA_MODE_WRITE & ~0x40); set_dma_addr(host->dma, host->dma_addr); - set_dma_count(host->dma, size); + set_dma_count(host->dma, host->size); enable_dma(host->dma); release_dma_lock(dmaflags); @@ -723,10 +812,6 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) count = get_dma_residue(host->dma); release_dma_lock(dmaflags); - data->bytes_xfered = host->mrq->data->blocks * - host->mrq->data->blksz - count; - data->bytes_xfered -= data->bytes_xfered % data->blksz; - /* * Any leftover data? */ @@ -735,8 +820,7 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) "%d bytes left.\n", mmc_hostname(host->mmc), count); - if (data->error == MMC_ERR_NONE) - data->error = MMC_ERR_FAILED; + data->error = MMC_ERR_FAILED; } else { /* * Transfer data from DMA buffer to @@ -744,11 +828,8 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) */ if (data->flags & MMC_DATA_READ) wbsd_dma_to_sg(host, data); - } - if (data->error != MMC_ERR_NONE) { - if (data->bytes_xfered) - data->bytes_xfered -= data->blksz; + data->bytes_xfered = host->size; } } @@ -788,7 +869,24 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) goto done; } + /* + * Does the request include data? + */ if (cmd->data) { + wbsd_prepare_data(host, cmd->data); + + if (cmd->data->error != MMC_ERR_NONE) + goto done; + } + + wbsd_send_command(host, cmd); + + /* + * If this is a data transfer the request + * will be finished after the data has + * transfered. + */ + if (cmd->data && (cmd->error == MMC_ERR_NONE)) { /* * The hardware is so delightfully stupid that it has a list * of "data" commands. If a command isn't on this list, it'll @@ -820,30 +918,14 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) "supported by this controller.\n", mmc_hostname(host->mmc), cmd->opcode); #endif - cmd->error = MMC_ERR_INVALID; - - goto done; - }; - } + cmd->data->error = MMC_ERR_INVALID; - /* - * Does the request include data? - */ - if (cmd->data) { - wbsd_prepare_data(host, cmd->data); + if (cmd->data->stop) + wbsd_send_command(host, cmd->data->stop); - if (cmd->data->error != MMC_ERR_NONE) goto done; - } - - wbsd_send_command(host, cmd); + }; - /* - * If this is a data transfer the request - * will be finished after the data has - * transfered. - */ - if (cmd->data && (cmd->error == MMC_ERR_NONE)) { /* * Dirty fix for hardware bug. */ @@ -1085,7 +1167,7 @@ static void wbsd_tasklet_fifo(unsigned long param) /* * Done? */ - if (host->num_sg == 0) { + if (host->size == data->bytes_xfered) { wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); tasklet_schedule(&host->finish_tasklet); } @@ -1163,6 +1245,30 @@ static void wbsd_tasklet_finish(unsigned long param) spin_unlock(&host->lock); } +static void wbsd_tasklet_block(unsigned long param) +{ + struct wbsd_host *host = (struct wbsd_host *)param; + struct mmc_data *data; + + spin_lock(&host->lock); + + if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != + WBSD_CRC_OK) { + data = wbsd_get_data(host); + if (!data) + goto end; + + DBGF("CRC error\n"); + + data->error = MMC_ERR_BADCRC; + + tasklet_schedule(&host->finish_tasklet); + } + +end: + spin_unlock(&host->lock); +} + /* * Interrupt handling */ @@ -1193,6 +1299,8 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id) tasklet_hi_schedule(&host->crc_tasklet); if (isr & WBSD_INT_TIMEOUT) tasklet_hi_schedule(&host->timeout_tasklet); + if (isr & WBSD_INT_BUSYEND) + tasklet_hi_schedule(&host->block_tasklet); if (isr & WBSD_INT_TC) tasklet_schedule(&host->finish_tasklet); @@ -1493,6 +1601,8 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) (unsigned long)host); tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); + tasklet_init(&host->block_tasklet, wbsd_tasklet_block, + (unsigned long)host); return 0; } @@ -1511,6 +1621,7 @@ static void __devexit wbsd_release_irq(struct wbsd_host *host) tasklet_kill(&host->crc_tasklet); tasklet_kill(&host->timeout_tasklet); tasklet_kill(&host->finish_tasklet); + tasklet_kill(&host->block_tasklet); } /* diff --git a/trunk/drivers/mmc/host/wbsd.h b/trunk/drivers/mmc/wbsd.h similarity index 95% rename from trunk/drivers/mmc/host/wbsd.h rename to trunk/drivers/mmc/wbsd.h index 873bda1e59b4..d06718b0e2ab 100644 --- a/trunk/drivers/mmc/host/wbsd.h +++ b/trunk/drivers/mmc/wbsd.h @@ -1,7 +1,7 @@ /* * linux/drivers/mmc/wbsd.h - Winbond W83L51xD SD/MMC driver * - * Copyright (C) 2004-2007 Pierre Ossman, All Rights Reserved. + * Copyright (C) 2004-2005 Pierre Ossman, All Rights Reserved. * * 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 @@ -46,10 +46,10 @@ #define WBSD_EINT_CARD 0x40 #define WBSD_EINT_FIFO_THRE 0x20 -#define WBSD_EINT_CRC 0x10 +#define WBSD_EINT_CCRC 0x10 #define WBSD_EINT_TIMEOUT 0x08 #define WBSD_EINT_PROGEND 0x04 -#define WBSD_EINT_BUSYEND 0x02 +#define WBSD_EINT_CRC 0x02 #define WBSD_EINT_TC 0x01 #define WBSD_INT_PENDING 0x80 @@ -158,6 +158,8 @@ struct wbsd_host unsigned int offset; /* Offset into current entry */ unsigned int remain; /* Data left in curren entry */ + int size; /* Total size of transfer */ + char* dma_buffer; /* ISA DMA buffer */ dma_addr_t dma_addr; /* Physical address for same */ @@ -180,6 +182,7 @@ struct wbsd_host struct tasklet_struct crc_tasklet; struct tasklet_struct timeout_tasklet; struct tasklet_struct finish_tasklet; + struct tasklet_struct block_tasklet; struct timer_list ignore_timer; /* Ignore detection timer */ }; diff --git a/trunk/drivers/mtd/devices/Kconfig b/trunk/drivers/mtd/devices/Kconfig index ff642f8fbee7..690c94236d7f 100644 --- a/trunk/drivers/mtd/devices/Kconfig +++ b/trunk/drivers/mtd/devices/Kconfig @@ -49,8 +49,8 @@ config MTD_MS02NV If you want to compile this driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), - say M here and read . - The module will be called ms02-nv.ko. + say M here and read . The module will + be called ms02-nv.o. config MTD_DATAFLASH tristate "Support for AT45xxx DataFlash" diff --git a/trunk/drivers/mtd/devices/block2mtd.c b/trunk/drivers/mtd/devices/block2mtd.c index fc4cc8ba9e29..ce47544dc120 100644 --- a/trunk/drivers/mtd/devices/block2mtd.c +++ b/trunk/drivers/mtd/devices/block2mtd.c @@ -40,11 +40,13 @@ struct block2mtd_dev { static LIST_HEAD(blkmtd_device_list); -static struct page *page_read(struct address_space *mapping, int index) +static struct page* page_read(struct address_space *mapping, int index) { - return read_mapping_page(mapping, index, NULL); + filler_t *filler = (filler_t*)mapping->a_ops->readpage; + return read_cache_page(mapping, index, filler, NULL); } + /* erase a specified part of the device */ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len) { diff --git a/trunk/drivers/mtd/devices/doc2000.c b/trunk/drivers/mtd/devices/doc2000.c index c73e96bfafc6..8a0c4dec6351 100644 --- a/trunk/drivers/mtd/devices/doc2000.c +++ b/trunk/drivers/mtd/devices/doc2000.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/mtd/devices/doc2001.c b/trunk/drivers/mtd/devices/doc2001.c index 6413efc045e0..6f368aec5d5d 100644 --- a/trunk/drivers/mtd/devices/doc2001.c +++ b/trunk/drivers/mtd/devices/doc2001.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/mtd/devices/doc2001plus.c b/trunk/drivers/mtd/devices/doc2001plus.c index 2b30b587c6e8..88ba82df0fbb 100644 --- a/trunk/drivers/mtd/devices/doc2001plus.c +++ b/trunk/drivers/mtd/devices/doc2001plus.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/mtd/devices/docecc.c b/trunk/drivers/mtd/devices/docecc.c index fd8a8daba3a8..52b5d638077f 100644 --- a/trunk/drivers/mtd/devices/docecc.c +++ b/trunk/drivers/mtd/devices/docecc.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/mtd/inftlmount.c b/trunk/drivers/mtd/inftlmount.c index ecac0e438f49..acf3ba223298 100644 --- a/trunk/drivers/mtd/inftlmount.c +++ b/trunk/drivers/mtd/inftlmount.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/mtd/maps/physmap_of.c b/trunk/drivers/mtd/maps/physmap_of.c index 72107dc06d67..7efe744ad31e 100644 --- a/trunk/drivers/mtd/maps/physmap_of.c +++ b/trunk/drivers/mtd/maps/physmap_of.c @@ -48,7 +48,7 @@ static int parse_flash_partitions(struct device_node *node, const u32 *part; const char *name; - part = of_get_property(node, "partitions", &plen); + part = get_property(node, "partitions", &plen); if (part == NULL) goto err; @@ -59,7 +59,7 @@ static int parse_flash_partitions(struct device_node *node, goto err; } - name = of_get_property(node, "partition-names", &plen); + name = get_property(node, "partition-names", &plen); for (i = 0; i < retval; i++) { (*parts)[i].offset = *part++; @@ -153,7 +153,7 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev goto err_out; } - width = of_get_property(dp, "bank-width", NULL); + width = get_property(dp, "bank-width", NULL); if (width == NULL) { dev_err(&dev->dev, "Can't get the flash bank width!\n"); err = -EINVAL; @@ -174,7 +174,7 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev simple_map_init(&info->map); - of_probe = of_get_property(dp, "probe-type", NULL); + of_probe = get_property(dp, "probe-type", NULL); if (of_probe == NULL) { probe_type = rom_probe_types; for (; info->mtd == NULL && *probe_type != NULL; probe_type++) diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index 51bc7e2f1f22..524b83b5ebf5 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -216,7 +216,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int last_devnum = -1; struct gendisk *gd; - if (mutex_trylock(&mtd_table_mutex)) { + if (!!mutex_trylock(&mtd_table_mutex)) { mutex_unlock(&mtd_table_mutex); BUG(); } @@ -294,7 +294,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) { - if (mutex_trylock(&mtd_table_mutex)) { + if (!!mutex_trylock(&mtd_table_mutex)) { mutex_unlock(&mtd_table_mutex); BUG(); } diff --git a/trunk/drivers/mtd/nand/cs553x_nand.c b/trunk/drivers/mtd/nand/cs553x_nand.c index 89deff007116..8296305c8297 100644 --- a/trunk/drivers/mtd/nand/cs553x_nand.c +++ b/trunk/drivers/mtd/nand/cs553x_nand.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/mtd/nftlcore.c b/trunk/drivers/mtd/nftlcore.c index 0c9ce19ea27a..e6ef7d7f9f14 100644 --- a/trunk/drivers/mtd/nftlcore.c +++ b/trunk/drivers/mtd/nftlcore.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/mtd/ubi/eba.c b/trunk/drivers/mtd/ubi/eba.c index 3dba5733ed1f..d847ee1da3d9 100644 --- a/trunk/drivers/mtd/ubi/eba.c +++ b/trunk/drivers/mtd/ubi/eba.c @@ -940,7 +940,8 @@ static void ltree_entry_ctor(void *obj, struct kmem_cache *cache, { struct ltree_entry *le = obj; - if (flags & SLAB_CTOR_CONSTRUCTOR) + if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) != + SLAB_CTOR_CONSTRUCTOR) return; le->users = 0; diff --git a/trunk/drivers/net/7990.c b/trunk/drivers/net/7990.c index 0877fc372f4b..d396f996af57 100644 --- a/trunk/drivers/net/7990.c +++ b/trunk/drivers/net/7990.c @@ -565,9 +565,9 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) ib->btx_ring [entry].length = (-len) | 0xf000; ib->btx_ring [entry].misc = 0; - if (skb->len < ETH_ZLEN) - memset((void *)&ib->tx_buf[entry][0], 0, ETH_ZLEN); - skb_copy_from_linear_data(skb, (void *)&ib->tx_buf[entry][0], skblen); + if (skb->len < ETH_ZLEN) + memset((char *)&ib->tx_buf[entry][0], 0, ETH_ZLEN); + skb_copy_from_linear_data(skb, &ib->tx_buf[entry][0], skblen); /* Now, give the packet to the lance */ ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN); diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index b86ccd2ecd5b..dcdad217df51 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -311,7 +311,7 @@ config MAC8390 config MAC89x0 tristate "Macintosh CS89x0 based ethernet cards" - depends on NET_ETHERNET && MAC + depends on NET_ETHERNET && MAC && BROKEN ---help--- Support for CS89x0 chipset based Ethernet cards. If you have a Nubus or LC-PDS network (Ethernet) card of this type, say Y and @@ -337,8 +337,8 @@ config MACSONIC be called macsonic. config MACMACE - bool "Macintosh (AV) onboard MACE ethernet" - depends on NET_ETHERNET && MAC + bool "Macintosh (AV) onboard MACE ethernet (EXPERIMENTAL)" + depends on NET_ETHERNET && MAC && EXPERIMENTAL select CRC32 help Support for the onboard AMD 79C940 MACE Ethernet controller used in @@ -822,7 +822,7 @@ config SMC91X tristate "SMC 91C9x/91C1xxx support" select CRC32 select MII - depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00 || BFIN) + depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || SOC_AU1X00) help This is a driver for SMC's 91x series of Ethernet chipsets, including the SMC91C94 and the SMC91C111. Say Y if you want it @@ -833,8 +833,8 @@ config SMC91X This driver is also available as a module ( = code which can be inserted in and removed from the running kernel whenever you want). The module will be called smc91x. If you want to compile it as a - module, say M here and read - as well as . + module, say M here and read as well + as . config SMC9194 tristate "SMC 9194 support" @@ -889,7 +889,7 @@ config SMC911X This driver is also available as a module. The module will be called smc911x. If you want to compile it as a module, say M - here and read + here and read config NET_VENDOR_RACAL bool "Racal-Interlan (Micom) NI cards" @@ -1104,7 +1104,7 @@ config ETH16I config NE2000 tristate "NE2000/NE1000 support" - depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938 + depends on NET_ISA || (Q40 && m) || M32R select CRC32 ---help--- If you have a network (Ethernet) card of this type, say Y and read @@ -2488,7 +2488,6 @@ config NETXEN_NIC config PASEMI_MAC tristate "PA Semi 1/10Gbit MAC" depends on PPC64 && PCI - select PHYLIB help This driver supports the on-chip 1/10Gbit Ethernet controller on PA Semi's PWRficient line of chips. diff --git a/trunk/drivers/net/Space.c b/trunk/drivers/net/Space.c index 1c3e293fbaf7..dd8ed456c8b2 100644 --- a/trunk/drivers/net/Space.c +++ b/trunk/drivers/net/Space.c @@ -83,6 +83,7 @@ extern struct net_device *bagetlance_probe(int unit); extern struct net_device *mvme147lance_probe(int unit); extern struct net_device *tc515_probe(int unit); extern struct net_device *lance_probe(int unit); +extern struct net_device *mace_probe(int unit); extern struct net_device *mac8390_probe(int unit); extern struct net_device *mac89x0_probe(int unit); extern struct net_device *mc32_probe(int unit); @@ -273,6 +274,9 @@ static struct devprobe2 m68k_probes[] __initdata = { #ifdef CONFIG_MVME147_NET /* MVME147 internal Ethernet */ {mvme147lance_probe, 0}, #endif +#ifdef CONFIG_MACMACE /* Mac 68k Quadra AV builtin Ethernet */ + {mace_probe, 0}, +#endif #ifdef CONFIG_MAC8390 /* NuBus NS8390-based cards */ {mac8390_probe, 0}, #endif diff --git a/trunk/drivers/net/a2065.c b/trunk/drivers/net/a2065.c index 81d5a374042a..1226cbba0450 100644 --- a/trunk/drivers/net/a2065.c +++ b/trunk/drivers/net/a2065.c @@ -562,6 +562,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) volatile struct lance_init_block *ib = lp->init_block; int entry, skblen, len; int status = 0; + static int outs; unsigned long flags; skblen = skb->len; @@ -597,16 +598,17 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) ib->btx_ring [entry].length = (-len) | 0xf000; ib->btx_ring [entry].misc = 0; - skb_copy_from_linear_data(skb, (void *)&ib->tx_buf [entry][0], skblen); + skb_copy_from_linear_data(skb, &ib->tx_buf [entry][0], skblen); /* Clear the slack of the packet, do I need this? */ if (len != skblen) - memset ((void *) &ib->tx_buf [entry][skblen], 0, len - skblen); + memset ((char *) &ib->tx_buf [entry][skblen], 0, len - skblen); /* Now, give the packet to the lance */ ib->btx_ring [entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN); lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask; - lp->stats.tx_bytes += skblen; + + outs++; if (TX_BUFFS_AVAIL <= 0) netif_stop_queue(dev); diff --git a/trunk/drivers/net/ariadne.c b/trunk/drivers/net/ariadne.c index a241ae7855a3..a0e68e718531 100644 --- a/trunk/drivers/net/ariadne.c +++ b/trunk/drivers/net/ariadne.c @@ -677,7 +677,6 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct net_device *dev) priv->cur_tx -= TX_RING_SIZE; priv->dirty_tx -= TX_RING_SIZE; } - priv->stats.tx_bytes += len; /* Trigger an immediate send poll. */ lance->RAP = CSR0; /* PCnet-ISA Controller Status */ diff --git a/trunk/drivers/net/arm/at91_ether.c b/trunk/drivers/net/arm/at91_ether.c index ef2cc80256a3..152fa7a042b8 100644 --- a/trunk/drivers/net/arm/at91_ether.c +++ b/trunk/drivers/net/arm/at91_ether.c @@ -225,16 +225,6 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id) if (!(phy & ((1 << 2) | 1))) goto done; } - else if (lp->phy_type == MII_T78Q21x3_ID) { /* ack interrupt in Teridian PHY */ - read_phy(lp->phy_address, MII_T78Q21INT_REG, &phy); - if (!(phy & ((1 << 2) | 1))) - goto done; - } - else if (lp->phy_type == MII_DP83848_ID) { - read_phy(lp->phy_address, MII_DPPHYSTS_REG, &phy); /* ack interrupt in DP83848 PHY */ - if (!(phy & (1 << 7))) - goto done; - } update_linkspeed(dev, 0); @@ -290,19 +280,6 @@ static void enable_phyirq(struct net_device *dev) dsintr = (1 << 10) | ( 1 << 8); write_phy(lp->phy_address, MII_TPISTATUS, dsintr); } - else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */ - read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr); - dsintr = dsintr | 0x500; /* set bits 8, 10 */ - write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr); - } - else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */ - read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr); - dsintr = dsintr | 0x3c; /* set bits 2..5 */ - write_phy(lp->phy_address, MII_DPMISR_REG, dsintr); - read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr); - dsintr = dsintr | 0x3; /* set bits 0,1 */ - write_phy(lp->phy_address, MII_DPMICR_REG, dsintr); - } disable_mdi(); spin_unlock_irq(&lp->lock); @@ -346,19 +323,6 @@ static void disable_phyirq(struct net_device *dev) dsintr = ~((1 << 10) | (1 << 8)); write_phy(lp->phy_address, MII_TPISTATUS, dsintr); } - else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */ - read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr); - dsintr = dsintr & ~0x500; /* clear bits 8, 10 */ - write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr); - } - else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */ - read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr); - dsintr = dsintr & ~0x3; /* clear bits 0, 1 */ - write_phy(lp->phy_address, MII_DPMICR_REG, dsintr); - read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr); - dsintr = dsintr & ~0x3c; /* clear bits 2..5 */ - write_phy(lp->phy_address, MII_DPMISR_REG, dsintr); - } disable_mdi(); spin_unlock_irq(&lp->lock); @@ -571,8 +535,8 @@ static void at91ether_sethashtable(struct net_device *dev) mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); } - at91_emac_write(AT91_EMAC_HSL, mc_filter[0]); - at91_emac_write(AT91_EMAC_HSH, mc_filter[1]); + at91_emac_write(AT91_EMAC_HSH, mc_filter[0]); + at91_emac_write(AT91_EMAC_HSL, mc_filter[1]); } /* @@ -1098,16 +1062,10 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name); else if (phy_type == MII_DP83847_ID) printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name); - else if (phy_type == MII_DP83848_ID) - printk(KERN_INFO "%s: National Semiconductor DP83848 PHY\n", dev->name); else if (phy_type == MII_AC101L_ID) printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name); else if (phy_type == MII_KS8721_ID) printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name); - else if (phy_type == MII_T78Q21x3_ID) - printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name); - else if (phy_type == MII_LAN83C185_ID) - printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name); return 0; } @@ -1145,11 +1103,8 @@ static int __init at91ether_probe(struct platform_device *pdev) case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */ case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */ case MII_DP83847_ID: /* National Semiconductor DP83847: */ - case MII_DP83848_ID: /* National Semiconductor DP83848: */ case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ - case MII_T78Q21x3_ID: /* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */ - case MII_LAN83C185_ID: /* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */ detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk); break; } diff --git a/trunk/drivers/net/arm/at91_ether.h b/trunk/drivers/net/arm/at91_ether.h index a38fd2d053a6..b6b665de2ea0 100644 --- a/trunk/drivers/net/arm/at91_ether.h +++ b/trunk/drivers/net/arm/at91_ether.h @@ -17,46 +17,39 @@ /* Davicom 9161 PHY */ -#define MII_DM9161_ID 0x0181b880 -#define MII_DM9161A_ID 0x0181b8a0 -#define MII_DSCR_REG 16 -#define MII_DSCSR_REG 17 -#define MII_DSINTR_REG 21 +#define MII_DM9161_ID 0x0181b880 +#define MII_DM9161A_ID 0x0181b8a0 + +/* Davicom specific registers */ +#define MII_DSCR_REG 16 +#define MII_DSCSR_REG 17 +#define MII_DSINTR_REG 21 /* Intel LXT971A PHY */ -#define MII_LXT971A_ID 0x001378E0 -#define MII_ISINTE_REG 18 -#define MII_ISINTS_REG 19 -#define MII_LEDCTRL_REG 20 +#define MII_LXT971A_ID 0x001378E0 + +/* Intel specific registers */ +#define MII_ISINTE_REG 18 +#define MII_ISINTS_REG 19 +#define MII_LEDCTRL_REG 20 /* Realtek RTL8201 PHY */ -#define MII_RTL8201_ID 0x00008200 +#define MII_RTL8201_ID 0x00008200 /* Broadcom BCM5221 PHY */ -#define MII_BCM5221_ID 0x004061e0 -#define MII_BCMINTR_REG 26 +#define MII_BCM5221_ID 0x004061e0 -/* National Semiconductor DP83847 */ -#define MII_DP83847_ID 0x20005c30 +/* Broadcom specific registers */ +#define MII_BCMINTR_REG 26 -/* National Semiconductor DP83848 */ -#define MII_DP83848_ID 0x20005c90 -#define MII_DPPHYSTS_REG 16 -#define MII_DPMICR_REG 17 -#define MII_DPMISR_REG 18 +/* National Semiconductor DP83847 */ +#define MII_DP83847_ID 0x20005c30 /* Altima AC101L PHY */ -#define MII_AC101L_ID 0x00225520 +#define MII_AC101L_ID 0x00225520 /* Micrel KS8721 PHY */ -#define MII_KS8721_ID 0x00221610 - -/* Teridian 78Q2123/78Q2133 */ -#define MII_T78Q21x3_ID 0x000e7230 -#define MII_T78Q21INT_REG 17 - -/* SMSC LAN83C185 */ -#define MII_LAN83C185_ID 0x0007C0A0 +#define MII_KS8721_ID 0x00221610 /* ........................................................................ */ diff --git a/trunk/drivers/net/atl1/atl1_ethtool.c b/trunk/drivers/net/atl1/atl1_ethtool.c index 1f616c5c1473..c11c27798e5c 100644 --- a/trunk/drivers/net/atl1/atl1_ethtool.c +++ b/trunk/drivers/net/atl1/atl1_ethtool.c @@ -156,7 +156,8 @@ static int atl1_set_settings(struct net_device *netdev, u16 old_media_type = hw->media_type; if (netif_running(adapter->netdev)) { - dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n"); + printk(KERN_DEBUG "%s: ethtool shutting down adapter\n", + atl1_driver_name); atl1_down(adapter); } @@ -165,8 +166,9 @@ static int atl1_set_settings(struct net_device *netdev, else { if (ecmd->speed == SPEED_1000) { if (ecmd->duplex != DUPLEX_FULL) { - dev_warn(&adapter->pdev->dev, - "can't force to 1000M half duplex\n"); + printk(KERN_WARNING + "%s: can't force to 1000M half duplex\n", + atl1_driver_name); ret_val = -EINVAL; goto exit_sset; } @@ -204,8 +206,9 @@ static int atl1_set_settings(struct net_device *netdev, } if (atl1_phy_setup_autoneg_adv(hw)) { ret_val = -EINVAL; - dev_warn(&adapter->pdev->dev, - "invalid ethtool speed/duplex setting\n"); + printk(KERN_WARNING + "%s: invalid ethtool speed/duplex setting\n", + atl1_driver_name); goto exit_sset; } if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || @@ -236,10 +239,12 @@ static int atl1_set_settings(struct net_device *netdev, hw->media_type = old_media_type; if (netif_running(adapter->netdev)) { - dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n"); + printk(KERN_DEBUG "%s: ethtool starting adapter\n", + atl1_driver_name); atl1_up(adapter); } else if (!ret_val) { - dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n"); + printk(KERN_DEBUG "%s: ethtool resetting adapter\n", + atl1_driver_name); atl1_reset(adapter); } return ret_val; diff --git a/trunk/drivers/net/atl1/atl1_hw.c b/trunk/drivers/net/atl1/atl1_hw.c index ef886bdeac13..69482e0d849b 100644 --- a/trunk/drivers/net/atl1/atl1_hw.c +++ b/trunk/drivers/net/atl1/atl1_hw.c @@ -2,20 +2,20 @@ * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. * Copyright(c) 2006 Chris Snook * Copyright(c) 2006 Jay Cliburn - * + * * Derived from Intel e1000 driver * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * + * * 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. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. - * + * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -38,13 +38,12 @@ */ s32 atl1_reset_hw(struct atl1_hw *hw) { - struct pci_dev *pdev = hw->back->pdev; u32 icr; int i; - /* + /* * Clear Interrupt mask to stop board from generating - * interrupts & Clear any pending interrupt events + * interrupts & Clear any pending interrupt events */ /* * iowrite32(0, hw->hw_addr + REG_IMR); @@ -75,7 +74,7 @@ s32 atl1_reset_hw(struct atl1_hw *hw) } if (icr) { - dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr); + printk (KERN_DEBUG "icr = %x\n", icr); return icr; } @@ -137,8 +136,8 @@ s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data) int i; val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | - MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 << - MDIO_CLK_SEL_SHIFT; + MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 << + MDIO_CLK_SEL_SHIFT; iowrite32(val, hw->hw_addr + REG_MDIO_CTRL); ioread32(hw->hw_addr + REG_MDIO_CTRL); @@ -205,7 +204,7 @@ static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf) /* * get_permanent_address - * return 0 if get valid mac address, + * return 0 if get valid mac address, */ static int atl1_get_permanent_address(struct atl1_hw *hw) { @@ -302,7 +301,7 @@ static int atl1_get_permanent_address(struct atl1_hw *hw) } /* - * Reads the adapter's MAC address from the EEPROM + * Reads the adapter's MAC address from the EEPROM * hw - Struct containing variables accessed by shared code */ s32 atl1_read_mac_addr(struct atl1_hw *hw) @@ -438,7 +437,6 @@ s32 atl1_phy_enter_power_saving(struct atl1_hw *hw) */ static s32 atl1_phy_reset(struct atl1_hw *hw) { - struct pci_dev *pdev = hw->back->pdev; s32 ret_val; u16 phy_data; @@ -470,7 +468,8 @@ static s32 atl1_phy_reset(struct atl1_hw *hw) u32 val; int i; /* pcie serdes link may be down! */ - dev_dbg(&pdev->dev, "pcie phy link down\n"); + printk(KERN_DEBUG "%s: autoneg caused pcie phy link down\n", + atl1_driver_name); for (i = 0; i < 25; i++) { msleep(1); @@ -480,7 +479,9 @@ static s32 atl1_phy_reset(struct atl1_hw *hw) } if ((val & (MDIO_START | MDIO_BUSY)) != 0) { - dev_warn(&pdev->dev, "pcie link down at least 25ms\n"); + printk(KERN_WARNING + "%s: pcie link down at least for 25ms\n", + atl1_driver_name); return ret_val; } } @@ -570,7 +571,6 @@ s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw) */ static s32 atl1_setup_link(struct atl1_hw *hw) { - struct pci_dev *pdev = hw->back->pdev; s32 ret_val; /* @@ -581,13 +581,15 @@ static s32 atl1_setup_link(struct atl1_hw *hw) */ ret_val = atl1_phy_setup_autoneg_adv(hw); if (ret_val) { - dev_dbg(&pdev->dev, "error setting up autonegotiation\n"); + printk(KERN_DEBUG "%s: error setting up autonegotiation\n", + atl1_driver_name); return ret_val; } /* SW.Reset , En-Auto-Neg if needed */ ret_val = atl1_phy_reset(hw); if (ret_val) { - dev_dbg(&pdev->dev, "error resetting phy\n"); + printk(KERN_DEBUG "%s: error resetting the phy\n", + atl1_driver_name); return ret_val; } hw->phy_configured = true; @@ -629,7 +631,7 @@ static void atl1_init_flash_opcode(struct atl1_hw *hw) * Performs basic configuration of the adapter. * hw - Struct containing variables accessed by shared code * Assumes that the controller has previously been reset and is in a - * post-reset uninitialized state. Initializes multicast table, + * post-reset uninitialized state. Initializes multicast table, * and Calls routines to setup link * Leaves the transmit and receive units disabled and uninitialized. */ @@ -667,7 +669,6 @@ s32 atl1_init_hw(struct atl1_hw *hw) */ s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex) { - struct pci_dev *pdev = hw->back->pdev; s32 ret_val; u16 phy_data; @@ -690,7 +691,8 @@ s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex) *speed = SPEED_10; break; default: - dev_dbg(&pdev->dev, "error getting speed\n"); + printk(KERN_DEBUG "%s: error getting speed\n", + atl1_driver_name); return ATL1_ERR_PHY_SPEED; break; } diff --git a/trunk/drivers/net/atl1/atl1_main.c b/trunk/drivers/net/atl1/atl1_main.c index d28f88bbdd5f..4b1d4d153ecf 100644 --- a/trunk/drivers/net/atl1/atl1_main.c +++ b/trunk/drivers/net/atl1/atl1_main.c @@ -188,7 +188,8 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count); tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL); if (unlikely(!tpd_ring->buffer_info)) { - dev_err(&pdev->dev, "kzalloc failed , size = D%d\n", size); + printk(KERN_WARNING "%s: kzalloc failed , size = D%d\n", + atl1_driver_name, size); goto err_nomem; } rfd_ring->buffer_info = @@ -206,7 +207,9 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, &ring_header->dma); if (unlikely(!ring_header->desc)) { - dev_err(&pdev->dev, "pci_alloc_consistent failed\n"); + printk(KERN_WARNING + "%s: pci_alloc_consistent failed, size = D%d\n", + atl1_driver_name, size); goto err_nomem; } @@ -370,7 +373,8 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC | ERR_FLAG_CODE | ERR_FLAG_OV)) { adapter->hw_csum_err++; - dev_dbg(&adapter->pdev->dev, "rx checksum error\n"); + printk(KERN_DEBUG "%s: rx checksum error\n", + atl1_driver_name); return; } } @@ -389,9 +393,8 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, } /* IPv4, but hardware thinks its checksum is wrong */ - dev_dbg(&adapter->pdev->dev, - "hw csum wrong, pkt_flag:%x, err_flag:%x\n", - rrd->pkt_flg, rrd->err_flg); + printk(KERN_DEBUG "%s: hw csum wrong pkt_flag:%x, err_flag:%x\n", + atl1_driver_name, rrd->pkt_flg, rrd->err_flg); skb->ip_summed = CHECKSUM_COMPLETE; skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum); adapter->hw_csum_err++; @@ -504,13 +507,14 @@ static void atl1_intr_rx(struct atl1_adapter *adapter) /* rrd seems to be bad */ if (unlikely(i-- > 0)) { /* rrd may not be DMAed completely */ - dev_dbg(&adapter->pdev->dev, - "incomplete RRD DMA transfer\n"); + printk(KERN_DEBUG + "%s: RRD may not be DMAed completely\n", + atl1_driver_name); udelay(1); goto chk_rrd; } /* bad rrd */ - dev_dbg(&adapter->pdev->dev, "bad RRD\n"); + printk(KERN_DEBUG "%s: bad RRD\n", atl1_driver_name); /* see if update RFD index */ if (rrd->num_buf > 1) { u16 num_buf; @@ -681,8 +685,8 @@ static void atl1_check_for_link(struct atl1_adapter *adapter) /* notify upper layer link down ASAP */ if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */ if (netif_carrier_ok(netdev)) { /* old link state: Up */ - dev_info(&adapter->pdev->dev, "%s link is down\n", - netdev->name); + printk(KERN_INFO "%s: %s link is down\n", + atl1_driver_name, netdev->name); adapter->link_speed = SPEED_0; netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -727,8 +731,8 @@ static irqreturn_t atl1_intr(int irq, void *data) /* check if PCIE PHY Link down */ if (status & ISR_PHY_LINKDOWN) { - dev_dbg(&adapter->pdev->dev, "pcie phy link down %x\n", - status); + printk(KERN_DEBUG "%s: pcie phy link down %x\n", + atl1_driver_name, status); if (netif_running(adapter->netdev)) { /* reset MAC */ iowrite32(0, adapter->hw.hw_addr + REG_IMR); schedule_work(&adapter->pcie_dma_to_rst_task); @@ -738,9 +742,9 @@ static irqreturn_t atl1_intr(int irq, void *data) /* check if DMA read/write error ? */ if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) { - dev_dbg(&adapter->pdev->dev, - "pcie DMA r/w error (status = 0x%x)\n", - status); + printk(KERN_DEBUG + "%s: pcie DMA r/w error (status = 0x%x)\n", + atl1_driver_name, status); iowrite32(0, adapter->hw.hw_addr + REG_IMR); schedule_work(&adapter->pcie_dma_to_rst_task); return IRQ_HANDLED; @@ -758,13 +762,14 @@ static irqreturn_t atl1_intr(int irq, void *data) /* rx exception */ if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | - ISR_RRD_OV | ISR_HOST_RFD_UNRUN | - ISR_HOST_RRD_OV | ISR_CMB_RX))) { - if (status & (ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV | ISR_HOST_RFD_UNRUN | - ISR_HOST_RRD_OV)) - dev_dbg(&adapter->pdev->dev, - "rx exception, ISR = 0x%x\n", status); + ISR_HOST_RRD_OV | ISR_CMB_RX))) { + if (status & + (ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV | + ISR_HOST_RFD_UNRUN | ISR_HOST_RRD_OV)) + printk(KERN_INFO + "%s: rx exception: status = 0x%x\n", + atl1_driver_name, status); atl1_intr_rx(adapter); } @@ -869,7 +874,8 @@ static u32 atl1_check_link(struct atl1_adapter *adapter) atl1_read_phy_reg(hw, MII_BMSR, &phy_data); if (!(phy_data & BMSR_LSTATUS)) { /* link down */ if (netif_carrier_ok(netdev)) { /* old link state: Up */ - dev_info(&adapter->pdev->dev, "link is down\n"); + printk(KERN_INFO "%s: link is down\n", + atl1_driver_name); adapter->link_speed = SPEED_0; netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -912,11 +918,11 @@ static u32 atl1_check_link(struct atl1_adapter *adapter) adapter->link_speed = speed; adapter->link_duplex = duplex; atl1_setup_mac_ctrl(adapter); - dev_info(&adapter->pdev->dev, - "%s link is up %d Mbps %s\n", - netdev->name, adapter->link_speed, - adapter->link_duplex == FULL_DUPLEX ? - "full duplex" : "half duplex"); + printk(KERN_INFO "%s: %s link is up %d Mbps %s\n", + atl1_driver_name, netdev->name, + adapter->link_speed, + adapter->link_duplex == + FULL_DUPLEX ? "full duplex" : "half duplex"); } if (!netif_carrier_ok(netdev)) { /* Link down -> Up */ netif_carrier_on(netdev); @@ -1324,8 +1330,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, cso = skb_transport_offset(skb); css = cso + skb->csum_offset; if (unlikely(cso & 0x1)) { - dev_dbg(&adapter->pdev->dev, - "payload offset not an even number\n"); + printk(KERN_DEBUG "%s: payload offset != even number\n", + atl1_driver_name); return -1; } csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) << @@ -1573,7 +1579,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (!spin_trylock(&adapter->lock)) { /* Can't get lock - tell upper layer to requeue */ local_irq_restore(flags); - dev_dbg(&adapter->pdev->dev, "tx locked\n"); + printk(KERN_DEBUG "%s: TX locked\n", atl1_driver_name); return NETDEV_TX_LOCKED; } @@ -1581,7 +1587,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* not enough descriptors */ netif_stop_queue(netdev); spin_unlock_irqrestore(&adapter->lock, flags); - dev_dbg(&adapter->pdev->dev, "tx busy\n"); + printk(KERN_DEBUG "%s: TX busy\n", atl1_driver_name); return NETDEV_TX_BUSY; } @@ -1835,7 +1841,8 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu) if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || (max_frame > MAX_JUMBO_FRAME_SIZE)) { - dev_warn(&adapter->pdev->dev, "invalid MTU setting\n"); + printk(KERN_WARNING "%s: invalid MTU setting\n", + atl1_driver_name); return -EINVAL; } @@ -2129,7 +2136,9 @@ static int __devinit atl1_probe(struct pci_dev *pdev, if (err) { err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (err) { - dev_err(&pdev->dev, "no usable DMA configuration\n"); + printk(KERN_DEBUG + "%s: no usable DMA configuration, aborting\n", + atl1_driver_name); goto err_dma; } pci_using_64 = false; @@ -2166,9 +2175,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev, goto err_pci_iomap; } /* get device revision number */ - adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + - (REG_MASTER_CTRL + 2)); - dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); + adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + (REG_MASTER_CTRL + 2)); /* set default ring resource counts */ adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD; @@ -2459,6 +2466,8 @@ static void __exit atl1_exit_module(void) */ static int __init atl1_init_module(void) { + printk(KERN_INFO "%s - version %s\n", atl1_driver_string, DRIVER_VERSION); + printk(KERN_INFO "%s\n", atl1_copyright); return pci_register_driver(&atl1_driver); } diff --git a/trunk/drivers/net/atl1/atl1_param.c b/trunk/drivers/net/atl1/atl1_param.c index 4246bb9bd50e..c407214339f6 100644 --- a/trunk/drivers/net/atl1/atl1_param.c +++ b/trunk/drivers/net/atl1/atl1_param.c @@ -22,8 +22,8 @@ */ #include -#include #include +#include #include "atl1.h" /* @@ -94,7 +94,7 @@ struct atl1_option { } arg; }; -static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, struct pci_dev *pdev) +static int __devinit atl1_validate_option(int *value, struct atl1_option *opt) { if (*value == OPTION_UNSET) { *value = opt->def; @@ -105,17 +105,19 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, s case enable_option: switch (*value) { case OPTION_ENABLED: - dev_info(&pdev->dev, "%s enabled\n", opt->name); + printk(KERN_INFO "%s: %s Enabled\n", atl1_driver_name, + opt->name); return 0; case OPTION_DISABLED: - dev_info(&pdev->dev, "%s disabled\n", opt->name); + printk(KERN_INFO "%s: %s Disabled\n", atl1_driver_name, + opt->name); return 0; } break; case range_option: if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { - dev_info(&pdev->dev, "%s set to %i\n", opt->name, - *value); + printk(KERN_INFO "%s: %s set to %i\n", + atl1_driver_name, opt->name, *value); return 0; } break; @@ -127,8 +129,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, s ent = &opt->arg.l.p[i]; if (*value == ent->i) { if (ent->str[0] != '\0') - dev_info(&pdev->dev, "%s\n", - ent->str); + printk(KERN_INFO "%s: %s\n", + atl1_driver_name, ent->str); return 0; } } @@ -139,8 +141,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, s break; } - dev_info(&pdev->dev, "invalid %s specified (%i) %s\n", - opt->name, *value, opt->err); + printk(KERN_INFO "%s: invalid %s specified (%i) %s\n", + atl1_driver_name, opt->name, *value, opt->err); *value = opt->def; return -1; } @@ -156,11 +158,12 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, s */ void __devinit atl1_check_options(struct atl1_adapter *adapter) { - struct pci_dev *pdev = adapter->pdev; int bd = adapter->bd_number; if (bd >= ATL1_MAX_NIC) { - dev_notice(&pdev->dev, "no configuration for board#%i\n", bd); - dev_notice(&pdev->dev, "using defaults for all values\n"); + printk(KERN_NOTICE "%s: warning: no configuration for board #%i\n", + atl1_driver_name, bd); + printk(KERN_NOTICE "%s: using defaults for all values\n", + atl1_driver_name); } { /* Interrupt Moderate Timer */ struct atl1_option opt = { @@ -175,7 +178,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter) int val; if (num_int_mod_timer > bd) { val = int_mod_timer[bd]; - atl1_validate_option(&val, &opt, pdev); + atl1_validate_option(&val, &opt); adapter->imt = (u16) val; } else adapter->imt = (u16) (opt.def); @@ -195,7 +198,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter) int val; if (num_flash_vendor > bd) { val = flash_vendor[bd]; - atl1_validate_option(&val, &opt, pdev); + atl1_validate_option(&val, &opt); adapter->hw.flash_vendor = (u8) val; } else adapter->hw.flash_vendor = (u8) (opt.def); diff --git a/trunk/drivers/net/au1000_eth.c b/trunk/drivers/net/au1000_eth.c index c39ab803c5d8..d10fb80e9a63 100644 --- a/trunk/drivers/net/au1000_eth.c +++ b/trunk/drivers/net/au1000_eth.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/bmac.c b/trunk/drivers/net/bmac.c index 9b8d7d9dbe86..4612725965df 100644 --- a/trunk/drivers/net/bmac.c +++ b/trunk/drivers/net/bmac.c @@ -1260,10 +1260,9 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i printk(KERN_ERR "BMAC: can't use, need 3 addrs and 3 intrs\n"); return -ENODEV; } - prop_addr = of_get_property(macio_get_of_node(mdev), - "mac-address", NULL); + prop_addr = get_property(macio_get_of_node(mdev), "mac-address", NULL); if (prop_addr == NULL) { - prop_addr = of_get_property(macio_get_of_node(mdev), + prop_addr = get_property(macio_get_of_node(mdev), "local-mac-address", NULL); if (prop_addr == NULL) { printk(KERN_ERR "BMAC: Can't get mac-address\n"); diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 88b33c6ddda8..f98a2205a090 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -1,6 +1,6 @@ /* bnx2.c: Broadcom NX2 network driver. * - * Copyright (c) 2004-2007 Broadcom Corporation + * Copyright (c) 2004, 2005, 2006 Broadcom Corporation * * 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 @@ -54,8 +54,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.5.10" -#define DRV_MODULE_RELDATE "May 1, 2007" +#define DRV_MODULE_VERSION "1.5.8" +#define DRV_MODULE_RELDATE "April 24, 2007" #define RUN_AT(x) (jiffies + (x)) @@ -84,7 +84,6 @@ typedef enum { BCM5708, BCM5708S, BCM5709, - BCM5709S, } board_t; /* indexed by board_t, above */ @@ -99,7 +98,6 @@ static const struct { { "Broadcom NetXtreme II BCM5708 1000Base-T" }, { "Broadcom NetXtreme II BCM5708 1000Base-SX" }, { "Broadcom NetXtreme II BCM5709 1000Base-T" }, - { "Broadcom NetXtreme II BCM5709 1000Base-SX" }, }; static struct pci_device_id bnx2_pci_tbl[] = { @@ -119,8 +117,6 @@ static struct pci_device_id bnx2_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709 }, - { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5709S, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5709S }, { 0, } }; @@ -234,29 +230,21 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp) static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) { - u32 val; - - spin_lock_bh(&bp->indirect_lock); REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); - val = REG_RD(bp, BNX2_PCICFG_REG_WINDOW); - spin_unlock_bh(&bp->indirect_lock); - return val; + return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW)); } static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val) { - spin_lock_bh(&bp->indirect_lock); REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val); - spin_unlock_bh(&bp->indirect_lock); } static void bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) { offset += cid_addr; - spin_lock_bh(&bp->indirect_lock); if (CHIP_NUM(bp) == CHIP_NUM_5709) { int i; @@ -274,7 +262,6 @@ bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) REG_WR(bp, BNX2_CTX_DATA_ADR, offset); REG_WR(bp, BNX2_CTX_DATA, val); } - spin_unlock_bh(&bp->indirect_lock); } static int @@ -585,8 +572,8 @@ bnx2_report_fw_link(struct bnx2 *bp) if (bp->autoneg) { fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED; - bnx2_read_phy(bp, bp->mii_bmsr, &bmsr); - bnx2_read_phy(bp, bp->mii_bmsr, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); if (!(bmsr & BMSR_ANEGCOMPLETE) || bp->phy_flags & PHY_PARALLEL_DETECT_FLAG) @@ -667,8 +654,8 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp) return; } - bnx2_read_phy(bp, bp->mii_adv, &local_adv); - bnx2_read_phy(bp, bp->mii_lpa, &remote_adv); + bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); + bnx2_read_phy(bp, MII_LPA, &remote_adv); if (bp->phy_flags & PHY_SERDES_FLAG) { u32 new_local_adv = 0; @@ -712,45 +699,6 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp) } } -static int -bnx2_5709s_linkup(struct bnx2 *bp) -{ - u32 val, speed; - - bp->link_up = 1; - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_GP_STATUS); - bnx2_read_phy(bp, MII_BNX2_GP_TOP_AN_STATUS1, &val); - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_COMBO_IEEEB0); - - if ((bp->autoneg & AUTONEG_SPEED) == 0) { - bp->line_speed = bp->req_line_speed; - bp->duplex = bp->req_duplex; - return 0; - } - speed = val & MII_BNX2_GP_TOP_AN_SPEED_MSK; - switch (speed) { - case MII_BNX2_GP_TOP_AN_SPEED_10: - bp->line_speed = SPEED_10; - break; - case MII_BNX2_GP_TOP_AN_SPEED_100: - bp->line_speed = SPEED_100; - break; - case MII_BNX2_GP_TOP_AN_SPEED_1G: - case MII_BNX2_GP_TOP_AN_SPEED_1GKV: - bp->line_speed = SPEED_1000; - break; - case MII_BNX2_GP_TOP_AN_SPEED_2_5G: - bp->line_speed = SPEED_2500; - break; - } - if (val & MII_BNX2_GP_TOP_AN_FD) - bp->duplex = DUPLEX_FULL; - else - bp->duplex = DUPLEX_HALF; - return 0; -} - static int bnx2_5708s_linkup(struct bnx2 *bp) { @@ -788,7 +736,7 @@ bnx2_5706s_linkup(struct bnx2 *bp) bp->link_up = 1; bp->line_speed = SPEED_1000; - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bmcr & BMCR_FULLDPLX) { bp->duplex = DUPLEX_FULL; } @@ -800,8 +748,8 @@ bnx2_5706s_linkup(struct bnx2 *bp) return 0; } - bnx2_read_phy(bp, bp->mii_adv, &local_adv); - bnx2_read_phy(bp, bp->mii_lpa, &remote_adv); + bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); + bnx2_read_phy(bp, MII_LPA, &remote_adv); common = local_adv & remote_adv; if (common & (ADVERTISE_1000XHALF | ADVERTISE_1000XFULL)) { @@ -822,7 +770,7 @@ bnx2_copper_linkup(struct bnx2 *bp) { u32 bmcr; - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bmcr & BMCR_ANENABLE) { u32 local_adv, remote_adv, common; @@ -839,8 +787,8 @@ bnx2_copper_linkup(struct bnx2 *bp) bp->duplex = DUPLEX_HALF; } else { - bnx2_read_phy(bp, bp->mii_adv, &local_adv); - bnx2_read_phy(bp, bp->mii_lpa, &remote_adv); + bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); + bnx2_read_phy(bp, MII_LPA, &remote_adv); common = local_adv & remote_adv; if (common & ADVERTISE_100FULL) { @@ -950,145 +898,6 @@ bnx2_set_mac_link(struct bnx2 *bp) return 0; } -static void -bnx2_enable_bmsr1(struct bnx2 *bp) -{ - if ((bp->phy_flags & PHY_SERDES_FLAG) && - (CHIP_NUM(bp) == CHIP_NUM_5709)) - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, - MII_BNX2_BLK_ADDR_GP_STATUS); -} - -static void -bnx2_disable_bmsr1(struct bnx2 *bp) -{ - if ((bp->phy_flags & PHY_SERDES_FLAG) && - (CHIP_NUM(bp) == CHIP_NUM_5709)) - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, - MII_BNX2_BLK_ADDR_COMBO_IEEEB0); -} - -static int -bnx2_test_and_enable_2g5(struct bnx2 *bp) -{ - u32 up1; - int ret = 1; - - if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)) - return 0; - - if (bp->autoneg & AUTONEG_SPEED) - bp->advertising |= ADVERTISED_2500baseX_Full; - - if (CHIP_NUM(bp) == CHIP_NUM_5709) - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_OVER1G); - - bnx2_read_phy(bp, bp->mii_up1, &up1); - if (!(up1 & BCM5708S_UP1_2G5)) { - up1 |= BCM5708S_UP1_2G5; - bnx2_write_phy(bp, bp->mii_up1, up1); - ret = 0; - } - - if (CHIP_NUM(bp) == CHIP_NUM_5709) - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, - MII_BNX2_BLK_ADDR_COMBO_IEEEB0); - - return ret; -} - -static int -bnx2_test_and_disable_2g5(struct bnx2 *bp) -{ - u32 up1; - int ret = 0; - - if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)) - return 0; - - if (CHIP_NUM(bp) == CHIP_NUM_5709) - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_OVER1G); - - bnx2_read_phy(bp, bp->mii_up1, &up1); - if (up1 & BCM5708S_UP1_2G5) { - up1 &= ~BCM5708S_UP1_2G5; - bnx2_write_phy(bp, bp->mii_up1, up1); - ret = 1; - } - - if (CHIP_NUM(bp) == CHIP_NUM_5709) - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, - MII_BNX2_BLK_ADDR_COMBO_IEEEB0); - - return ret; -} - -static void -bnx2_enable_forced_2g5(struct bnx2 *bp) -{ - u32 bmcr; - - if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)) - return; - - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - u32 val; - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, - MII_BNX2_BLK_ADDR_SERDES_DIG); - bnx2_read_phy(bp, MII_BNX2_SERDES_DIG_MISC1, &val); - val &= ~MII_BNX2_SD_MISC1_FORCE_MSK; - val |= MII_BNX2_SD_MISC1_FORCE | MII_BNX2_SD_MISC1_FORCE_2_5G; - bnx2_write_phy(bp, MII_BNX2_SERDES_DIG_MISC1, val); - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, - MII_BNX2_BLK_ADDR_COMBO_IEEEB0); - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); - - } else if (CHIP_NUM(bp) == CHIP_NUM_5708) { - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); - bmcr |= BCM5708S_BMCR_FORCE_2500; - } - - if (bp->autoneg & AUTONEG_SPEED) { - bmcr &= ~BMCR_ANENABLE; - if (bp->req_duplex == DUPLEX_FULL) - bmcr |= BMCR_FULLDPLX; - } - bnx2_write_phy(bp, bp->mii_bmcr, bmcr); -} - -static void -bnx2_disable_forced_2g5(struct bnx2 *bp) -{ - u32 bmcr; - - if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)) - return; - - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - u32 val; - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, - MII_BNX2_BLK_ADDR_SERDES_DIG); - bnx2_read_phy(bp, MII_BNX2_SERDES_DIG_MISC1, &val); - val &= ~MII_BNX2_SD_MISC1_FORCE; - bnx2_write_phy(bp, MII_BNX2_SERDES_DIG_MISC1, val); - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, - MII_BNX2_BLK_ADDR_COMBO_IEEEB0); - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); - - } else if (CHIP_NUM(bp) == CHIP_NUM_5708) { - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); - bmcr &= ~BCM5708S_BMCR_FORCE_2500; - } - - if (bp->autoneg & AUTONEG_SPEED) - bmcr |= BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_ANRESTART; - bnx2_write_phy(bp, bp->mii_bmcr, bmcr); -} - static int bnx2_set_link(struct bnx2 *bp) { @@ -1102,10 +911,8 @@ bnx2_set_link(struct bnx2 *bp) link_up = bp->link_up; - bnx2_enable_bmsr1(bp); - bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr); - bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr); - bnx2_disable_bmsr1(bp); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); if ((bp->phy_flags & PHY_SERDES_FLAG) && (CHIP_NUM(bp) == CHIP_NUM_5706)) { @@ -1126,8 +933,6 @@ bnx2_set_link(struct bnx2 *bp) bnx2_5706s_linkup(bp); else if (CHIP_NUM(bp) == CHIP_NUM_5708) bnx2_5708s_linkup(bp); - else if (CHIP_NUM(bp) == CHIP_NUM_5709) - bnx2_5709s_linkup(bp); } else { bnx2_copper_linkup(bp); @@ -1136,9 +941,17 @@ bnx2_set_link(struct bnx2 *bp) } else { if ((bp->phy_flags & PHY_SERDES_FLAG) && - (bp->autoneg & AUTONEG_SPEED)) - bnx2_disable_forced_2g5(bp); + (bp->autoneg & AUTONEG_SPEED)) { + u32 bmcr; + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + bmcr &= ~BCM5708S_BMCR_FORCE_2500; + if (!(bmcr & BMCR_ANENABLE)) { + bnx2_write_phy(bp, MII_BMCR, bmcr | + BMCR_ANENABLE); + } + } bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; bp->link_up = 0; } @@ -1158,13 +971,13 @@ bnx2_reset_phy(struct bnx2 *bp) int i; u32 reg; - bnx2_write_phy(bp, bp->mii_bmcr, BMCR_RESET); + bnx2_write_phy(bp, MII_BMCR, BMCR_RESET); #define PHY_RESET_MAX_WAIT 100 for (i = 0; i < PHY_RESET_MAX_WAIT; i++) { udelay(10); - bnx2_read_phy(bp, bp->mii_bmcr, ®); + bnx2_read_phy(bp, MII_BMCR, ®); if (!(reg & BMCR_RESET)) { udelay(20); break; @@ -1213,40 +1026,34 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp) static int bnx2_setup_serdes_phy(struct bnx2 *bp) { - u32 adv, bmcr; + u32 adv, bmcr, up1; u32 new_adv = 0; if (!(bp->autoneg & AUTONEG_SPEED)) { u32 new_bmcr; int force_link_down = 0; - if (bp->req_line_speed == SPEED_2500) { - if (!bnx2_test_and_enable_2g5(bp)) - force_link_down = 1; - } else if (bp->req_line_speed == SPEED_1000) { - if (bnx2_test_and_disable_2g5(bp)) - force_link_down = 1; - } - bnx2_read_phy(bp, bp->mii_adv, &adv); + bnx2_read_phy(bp, MII_ADVERTISE, &adv); adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF); - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); - new_bmcr = bmcr & ~BMCR_ANENABLE; + bnx2_read_phy(bp, MII_BMCR, &bmcr); + new_bmcr = bmcr & ~(BMCR_ANENABLE | BCM5708S_BMCR_FORCE_2500); new_bmcr |= BMCR_SPEED1000; - - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - if (bp->req_line_speed == SPEED_2500) - bnx2_enable_forced_2g5(bp); - else if (bp->req_line_speed == SPEED_1000) { - bnx2_disable_forced_2g5(bp); - new_bmcr &= ~0x2000; + if (bp->req_line_speed == SPEED_2500) { + new_bmcr |= BCM5708S_BMCR_FORCE_2500; + bnx2_read_phy(bp, BCM5708S_UP1, &up1); + if (!(up1 & BCM5708S_UP1_2G5)) { + up1 |= BCM5708S_UP1_2G5; + bnx2_write_phy(bp, BCM5708S_UP1, up1); + force_link_down = 1; } - } else if (CHIP_NUM(bp) == CHIP_NUM_5708) { - if (bp->req_line_speed == SPEED_2500) - new_bmcr |= BCM5708S_BMCR_FORCE_2500; - else - new_bmcr = bmcr & ~BCM5708S_BMCR_FORCE_2500; + bnx2_read_phy(bp, BCM5708S_UP1, &up1); + if (up1 & BCM5708S_UP1_2G5) { + up1 &= ~BCM5708S_UP1_2G5; + bnx2_write_phy(bp, BCM5708S_UP1, up1); + force_link_down = 1; + } } if (bp->req_duplex == DUPLEX_FULL) { @@ -1260,48 +1067,49 @@ bnx2_setup_serdes_phy(struct bnx2 *bp) if ((new_bmcr != bmcr) || (force_link_down)) { /* Force a link down visible on the other side */ if (bp->link_up) { - bnx2_write_phy(bp, bp->mii_adv, adv & + bnx2_write_phy(bp, MII_ADVERTISE, adv & ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF)); - bnx2_write_phy(bp, bp->mii_bmcr, bmcr | + bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); bp->link_up = 0; netif_carrier_off(bp->dev); - bnx2_write_phy(bp, bp->mii_bmcr, new_bmcr); + bnx2_write_phy(bp, MII_BMCR, new_bmcr); bnx2_report_link(bp); } - bnx2_write_phy(bp, bp->mii_adv, adv); - bnx2_write_phy(bp, bp->mii_bmcr, new_bmcr); - } else { - bnx2_resolve_flow_ctrl(bp); - bnx2_set_mac_link(bp); + bnx2_write_phy(bp, MII_ADVERTISE, adv); + bnx2_write_phy(bp, MII_BMCR, new_bmcr); } return 0; } - bnx2_test_and_enable_2g5(bp); + if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) { + bnx2_read_phy(bp, BCM5708S_UP1, &up1); + up1 |= BCM5708S_UP1_2G5; + bnx2_write_phy(bp, BCM5708S_UP1, up1); + } if (bp->advertising & ADVERTISED_1000baseT_Full) new_adv |= ADVERTISE_1000XFULL; new_adv |= bnx2_phy_get_pause_adv(bp); - bnx2_read_phy(bp, bp->mii_adv, &adv); - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, MII_ADVERTISE, &adv); + bnx2_read_phy(bp, MII_BMCR, &bmcr); bp->serdes_an_pending = 0; if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) { /* Force a link down visible on the other side */ if (bp->link_up) { - bnx2_write_phy(bp, bp->mii_bmcr, BMCR_LOOPBACK); + bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); spin_unlock_bh(&bp->phy_lock); msleep(20); spin_lock_bh(&bp->phy_lock); } - bnx2_write_phy(bp, bp->mii_adv, new_adv); - bnx2_write_phy(bp, bp->mii_bmcr, bmcr | BMCR_ANRESTART | + bnx2_write_phy(bp, MII_ADVERTISE, new_adv); + bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); /* Speed up link-up time when the link partner * does not autonegotiate which is very common @@ -1314,9 +1122,6 @@ bnx2_setup_serdes_phy(struct bnx2 *bp) bp->current_interval = SERDES_AN_TIMEOUT; bp->serdes_an_pending = 1; mod_timer(&bp->timer, jiffies + bp->current_interval); - } else { - bnx2_resolve_flow_ctrl(bp); - bnx2_set_mac_link(bp); } return 0; @@ -1341,14 +1146,14 @@ bnx2_setup_copper_phy(struct bnx2 *bp) u32 bmcr; u32 new_bmcr; - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bp->autoneg & AUTONEG_SPEED) { u32 adv_reg, adv1000_reg; u32 new_adv_reg = 0; u32 new_adv1000_reg = 0; - bnx2_read_phy(bp, bp->mii_adv, &adv_reg); + bnx2_read_phy(bp, MII_ADVERTISE, &adv_reg); adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); @@ -1374,9 +1179,9 @@ bnx2_setup_copper_phy(struct bnx2 *bp) (adv_reg != new_adv_reg) || ((bmcr & BMCR_ANENABLE) == 0)) { - bnx2_write_phy(bp, bp->mii_adv, new_adv_reg); + bnx2_write_phy(bp, MII_ADVERTISE, new_adv_reg); bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg); - bnx2_write_phy(bp, bp->mii_bmcr, BMCR_ANRESTART | + bnx2_write_phy(bp, MII_BMCR, BMCR_ANRESTART | BMCR_ANENABLE); } else if (bp->link_up) { @@ -1399,21 +1204,21 @@ bnx2_setup_copper_phy(struct bnx2 *bp) if (new_bmcr != bmcr) { u32 bmsr; - bnx2_read_phy(bp, bp->mii_bmsr, &bmsr); - bnx2_read_phy(bp, bp->mii_bmsr, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); if (bmsr & BMSR_LSTATUS) { /* Force link down */ - bnx2_write_phy(bp, bp->mii_bmcr, BMCR_LOOPBACK); + bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); spin_unlock_bh(&bp->phy_lock); msleep(50); spin_lock_bh(&bp->phy_lock); - bnx2_read_phy(bp, bp->mii_bmsr, &bmsr); - bnx2_read_phy(bp, bp->mii_bmsr, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); } - bnx2_write_phy(bp, bp->mii_bmcr, new_bmcr); + bnx2_write_phy(bp, MII_BMCR, new_bmcr); /* Normally, the new speed is setup after the link has * gone down and up again. In some cases, link will not go @@ -1425,9 +1230,6 @@ bnx2_setup_copper_phy(struct bnx2 *bp) bnx2_resolve_flow_ctrl(bp); bnx2_set_mac_link(bp); } - } else { - bnx2_resolve_flow_ctrl(bp); - bnx2_set_mac_link(bp); } return 0; } @@ -1446,64 +1248,11 @@ bnx2_setup_phy(struct bnx2 *bp) } } -static int -bnx2_init_5709s_phy(struct bnx2 *bp) -{ - u32 val; - - bp->mii_bmcr = MII_BMCR + 0x10; - bp->mii_bmsr = MII_BMSR + 0x10; - bp->mii_bmsr1 = MII_BNX2_GP_TOP_AN_STATUS1; - bp->mii_adv = MII_ADVERTISE + 0x10; - bp->mii_lpa = MII_LPA + 0x10; - bp->mii_up1 = MII_BNX2_OVER1G_UP1; - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_AER); - bnx2_write_phy(bp, MII_BNX2_AER_AER, MII_BNX2_AER_AER_AN_MMD); - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_COMBO_IEEEB0); - bnx2_reset_phy(bp); - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_SERDES_DIG); - - bnx2_read_phy(bp, MII_BNX2_SERDES_DIG_1000XCTL1, &val); - val &= ~MII_BNX2_SD_1000XCTL1_AUTODET; - val |= MII_BNX2_SD_1000XCTL1_FIBER; - bnx2_write_phy(bp, MII_BNX2_SERDES_DIG_1000XCTL1, val); - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_OVER1G); - bnx2_read_phy(bp, MII_BNX2_OVER1G_UP1, &val); - if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) - val |= BCM5708S_UP1_2G5; - else - val &= ~BCM5708S_UP1_2G5; - bnx2_write_phy(bp, MII_BNX2_OVER1G_UP1, val); - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_BAM_NXTPG); - bnx2_read_phy(bp, MII_BNX2_BAM_NXTPG_CTL, &val); - val |= MII_BNX2_NXTPG_CTL_T2 | MII_BNX2_NXTPG_CTL_BAM; - bnx2_write_phy(bp, MII_BNX2_BAM_NXTPG_CTL, val); - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_CL73_USERB0); - - val = MII_BNX2_CL73_BAM_EN | MII_BNX2_CL73_BAM_STA_MGR_EN | - MII_BNX2_CL73_BAM_NP_AFT_BP_EN; - bnx2_write_phy(bp, MII_BNX2_CL73_BAM_CTL1, val); - - bnx2_write_phy(bp, MII_BNX2_BLK_ADDR, MII_BNX2_BLK_ADDR_COMBO_IEEEB0); - - return 0; -} - static int bnx2_init_5708s_phy(struct bnx2 *bp) { u32 val; - bnx2_reset_phy(bp); - - bp->mii_up1 = BCM5708S_UP1; - bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3); bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE); bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); @@ -1556,8 +1305,6 @@ bnx2_init_5708s_phy(struct bnx2 *bp) static int bnx2_init_5706s_phy(struct bnx2 *bp) { - bnx2_reset_phy(bp); - bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; if (CHIP_NUM(bp) == CHIP_NUM_5706) @@ -1595,8 +1342,6 @@ bnx2_init_copper_phy(struct bnx2 *bp) { u32 val; - bnx2_reset_phy(bp); - if (bp->phy_flags & PHY_CRC_FIX_FLAG) { bnx2_write_phy(bp, 0x18, 0x0c00); bnx2_write_phy(bp, 0x17, 0x000a); @@ -1651,14 +1396,10 @@ bnx2_init_phy(struct bnx2 *bp) bp->phy_flags &= ~PHY_INT_MODE_MASK_FLAG; bp->phy_flags |= PHY_INT_MODE_LINK_READY_FLAG; - bp->mii_bmcr = MII_BMCR; - bp->mii_bmsr = MII_BMSR; - bp->mii_bmsr1 = MII_BMSR; - bp->mii_adv = MII_ADVERTISE; - bp->mii_lpa = MII_LPA; - REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); + bnx2_reset_phy(bp); + bnx2_read_phy(bp, MII_PHYSID1, &val); bp->phy_id = val << 16; bnx2_read_phy(bp, MII_PHYSID2, &val); @@ -1669,8 +1410,6 @@ bnx2_init_phy(struct bnx2 *bp) rc = bnx2_init_5706s_phy(bp); else if (CHIP_NUM(bp) == CHIP_NUM_5708) rc = bnx2_init_5708s_phy(bp); - else if (CHIP_NUM(bp) == CHIP_NUM_5709) - rc = bnx2_init_5709s_phy(bp); } else { rc = bnx2_init_copper_phy(bp); @@ -1703,7 +1442,7 @@ bnx2_set_phy_loopback(struct bnx2 *bp) int rc, i; spin_lock_bh(&bp->phy_lock); - rc = bnx2_write_phy(bp, bp->mii_bmcr, BMCR_LOOPBACK | BMCR_FULLDPLX | + rc = bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000); spin_unlock_bh(&bp->phy_lock); if (rc) @@ -1942,33 +1681,25 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index) return 0; } -static int -bnx2_phy_event_is_set(struct bnx2 *bp, u32 event) +static void +bnx2_phy_int(struct bnx2 *bp) { - struct status_block *sblk = bp->status_blk; u32 new_link_state, old_link_state; - int is_set = 1; - new_link_state = sblk->status_attn_bits & event; - old_link_state = sblk->status_attn_bits_ack & event; + new_link_state = bp->status_blk->status_attn_bits & + STATUS_ATTN_BITS_LINK_STATE; + old_link_state = bp->status_blk->status_attn_bits_ack & + STATUS_ATTN_BITS_LINK_STATE; if (new_link_state != old_link_state) { - if (new_link_state) - REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD, event); - else - REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, event); - } else - is_set = 0; - - return is_set; -} - -static void -bnx2_phy_int(struct bnx2 *bp) -{ - if (bnx2_phy_event_is_set(bp, STATUS_ATTN_BITS_LINK_STATE)) { - spin_lock(&bp->phy_lock); + if (new_link_state) { + REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD, + STATUS_ATTN_BITS_LINK_STATE); + } + else { + REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, + STATUS_ATTN_BITS_LINK_STATE); + } bnx2_set_link(bp); - spin_unlock(&bp->phy_lock); } } @@ -2261,23 +1992,6 @@ bnx2_msi(int irq, void *dev_instance) return IRQ_HANDLED; } -static irqreturn_t -bnx2_msi_1shot(int irq, void *dev_instance) -{ - struct net_device *dev = dev_instance; - struct bnx2 *bp = netdev_priv(dev); - - prefetch(bp->status_blk); - - /* Return here if interrupt is disabled. */ - if (unlikely(atomic_read(&bp->intr_sem) != 0)) - return IRQ_HANDLED; - - netif_rx_schedule(dev); - - return IRQ_HANDLED; -} - static irqreturn_t bnx2_interrupt(int irq, void *dev_instance) { @@ -2308,8 +2022,6 @@ bnx2_interrupt(int irq, void *dev_instance) return IRQ_HANDLED; } -#define STATUS_ATTN_EVENTS STATUS_ATTN_BITS_LINK_STATE - static inline int bnx2_has_work(struct bnx2 *bp) { @@ -2319,8 +2031,8 @@ bnx2_has_work(struct bnx2 *bp) (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)) return 1; - if ((sblk->status_attn_bits & STATUS_ATTN_EVENTS) != - (sblk->status_attn_bits_ack & STATUS_ATTN_EVENTS)) + if ((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != + (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) return 1; return 0; @@ -2330,14 +2042,15 @@ static int bnx2_poll(struct net_device *dev, int *budget) { struct bnx2 *bp = netdev_priv(dev); - struct status_block *sblk = bp->status_blk; - u32 status_attn_bits = sblk->status_attn_bits; - u32 status_attn_bits_ack = sblk->status_attn_bits_ack; - if ((status_attn_bits & STATUS_ATTN_EVENTS) != - (status_attn_bits_ack & STATUS_ATTN_EVENTS)) { + if ((bp->status_blk->status_attn_bits & + STATUS_ATTN_BITS_LINK_STATE) != + (bp->status_blk->status_attn_bits_ack & + STATUS_ATTN_BITS_LINK_STATE)) { + spin_lock(&bp->phy_lock); bnx2_phy_int(bp); + spin_unlock(&bp->phy_lock); /* This is needed to take care of transient status * during link changes. @@ -3776,21 +3489,17 @@ bnx2_init_chip(struct bnx2 *bp) REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ if (CHIP_ID(bp) == CHIP_ID_5706_A1) - val = BNX2_HC_CONFIG_COLLECT_STATS; + REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS); else { - val = BNX2_HC_CONFIG_RX_TMR_MODE | BNX2_HC_CONFIG_TX_TMR_MODE | - BNX2_HC_CONFIG_COLLECT_STATS; + REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_RX_TMR_MODE | + BNX2_HC_CONFIG_TX_TMR_MODE | + BNX2_HC_CONFIG_COLLECT_STATS); } - if (bp->flags & ONE_SHOT_MSI_FLAG) - val |= BNX2_HC_CONFIG_ONE_SHOT; - - REG_WR(bp, BNX2_HC_CONFIG, val); - /* Clear internal stats counters. */ REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW); - REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_EVENTS); + REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE); if (REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_FEATURE) & BNX2_PORT_FEATURE_ASF_ENABLED) @@ -4054,11 +3763,10 @@ static int bnx2_test_registers(struct bnx2 *bp) { int ret; - int i, is_5709; + int i; static const struct { u16 offset; u16 flags; -#define BNX2_FL_NOT_5709 1 u32 rw_mask; u32 ro_mask; } reg_tbl[] = { @@ -4066,26 +3774,26 @@ bnx2_test_registers(struct bnx2 *bp) { 0x0090, 0, 0xffffffff, 0x00000000 }, { 0x0094, 0, 0x00000000, 0x00000000 }, - { 0x0404, BNX2_FL_NOT_5709, 0x00003f00, 0x00000000 }, - { 0x0418, BNX2_FL_NOT_5709, 0x00000000, 0xffffffff }, - { 0x041c, BNX2_FL_NOT_5709, 0x00000000, 0xffffffff }, - { 0x0420, BNX2_FL_NOT_5709, 0x00000000, 0x80ffffff }, - { 0x0424, BNX2_FL_NOT_5709, 0x00000000, 0x00000000 }, - { 0x0428, BNX2_FL_NOT_5709, 0x00000000, 0x00000001 }, - { 0x0450, BNX2_FL_NOT_5709, 0x00000000, 0x0000ffff }, - { 0x0454, BNX2_FL_NOT_5709, 0x00000000, 0xffffffff }, - { 0x0458, BNX2_FL_NOT_5709, 0x00000000, 0xffffffff }, - - { 0x0808, BNX2_FL_NOT_5709, 0x00000000, 0xffffffff }, - { 0x0854, BNX2_FL_NOT_5709, 0x00000000, 0xffffffff }, - { 0x0868, BNX2_FL_NOT_5709, 0x00000000, 0x77777777 }, - { 0x086c, BNX2_FL_NOT_5709, 0x00000000, 0x77777777 }, - { 0x0870, BNX2_FL_NOT_5709, 0x00000000, 0x77777777 }, - { 0x0874, BNX2_FL_NOT_5709, 0x00000000, 0x77777777 }, - - { 0x0c00, BNX2_FL_NOT_5709, 0x00000000, 0x00000001 }, - { 0x0c04, BNX2_FL_NOT_5709, 0x00000000, 0x03ff0001 }, - { 0x0c08, BNX2_FL_NOT_5709, 0x0f0ff073, 0x00000000 }, + { 0x0404, 0, 0x00003f00, 0x00000000 }, + { 0x0418, 0, 0x00000000, 0xffffffff }, + { 0x041c, 0, 0x00000000, 0xffffffff }, + { 0x0420, 0, 0x00000000, 0x80ffffff }, + { 0x0424, 0, 0x00000000, 0x00000000 }, + { 0x0428, 0, 0x00000000, 0x00000001 }, + { 0x0450, 0, 0x00000000, 0x0000ffff }, + { 0x0454, 0, 0x00000000, 0xffffffff }, + { 0x0458, 0, 0x00000000, 0xffffffff }, + + { 0x0808, 0, 0x00000000, 0xffffffff }, + { 0x0854, 0, 0x00000000, 0xffffffff }, + { 0x0868, 0, 0x00000000, 0x77777777 }, + { 0x086c, 0, 0x00000000, 0x77777777 }, + { 0x0870, 0, 0x00000000, 0x77777777 }, + { 0x0874, 0, 0x00000000, 0x77777777 }, + + { 0x0c00, 0, 0x00000000, 0x00000001 }, + { 0x0c04, 0, 0x00000000, 0x03ff0001 }, + { 0x0c08, 0, 0x0f0ff073, 0x00000000 }, { 0x1000, 0, 0x00000000, 0x00000001 }, { 0x1004, 0, 0x00000000, 0x000f0001 }, @@ -4132,6 +3840,7 @@ bnx2_test_registers(struct bnx2 *bp) { 0x5004, 0, 0x00000000, 0x0000007f }, { 0x5008, 0, 0x0f0007ff, 0x00000000 }, + { 0x500c, 0, 0xf800f800, 0x07ff07ff }, { 0x5c00, 0, 0x00000000, 0x00000001 }, { 0x5c04, 0, 0x00000000, 0x0003000f }, @@ -4171,16 +3880,8 @@ bnx2_test_registers(struct bnx2 *bp) }; ret = 0; - is_5709 = 0; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - is_5709 = 1; - for (i = 0; reg_tbl[i].offset != 0xffff; i++) { u32 offset, rw_mask, ro_mask, save_val, val; - u16 flags = reg_tbl[i].flags; - - if (is_5709 && (flags & BNX2_FL_NOT_5709)) - continue; offset = (u32) reg_tbl[i].offset; rw_mask = reg_tbl[i].rw_mask; @@ -4249,10 +3950,10 @@ bnx2_test_memory(struct bnx2 *bp) { int ret = 0; int i; - static struct mem_entry { + static const struct { u32 offset; u32 len; - } mem_tbl_5706[] = { + } mem_tbl[] = { { 0x60000, 0x4000 }, { 0xa0000, 0x3000 }, { 0xe0000, 0x4000 }, @@ -4260,21 +3961,7 @@ bnx2_test_memory(struct bnx2 *bp) { 0x1a0000, 0x4000 }, { 0x160000, 0x4000 }, { 0xffffffff, 0 }, - }, - mem_tbl_5709[] = { - { 0x60000, 0x4000 }, - { 0xa0000, 0x3000 }, - { 0xe0000, 0x4000 }, - { 0x120000, 0x4000 }, - { 0x1a0000, 0x4000 }, - { 0xffffffff, 0 }, }; - struct mem_entry *mem_tbl; - - if (CHIP_NUM(bp) == CHIP_NUM_5709) - mem_tbl = mem_tbl_5709; - else - mem_tbl = mem_tbl_5706; for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { if ((ret = bnx2_do_mem_test(bp, mem_tbl[i].offset, @@ -4476,10 +4163,8 @@ bnx2_test_link(struct bnx2 *bp) u32 bmsr; spin_lock_bh(&bp->phy_lock); - bnx2_enable_bmsr1(bp); - bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr); - bnx2_read_phy(bp, bp->mii_bmsr1, &bmsr); - bnx2_disable_bmsr1(bp); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); spin_unlock_bh(&bp->phy_lock); if (bmsr & BMSR_LSTATUS) { @@ -4529,7 +4214,7 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) bp->current_interval = bp->timer_interval; - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, MII_BMCR, &bmcr); if (bmcr & BMCR_ANENABLE) { u32 phy1, phy2; @@ -4547,7 +4232,7 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) bmcr &= ~BMCR_ANENABLE; bmcr |= BMCR_SPEED1000 | BMCR_FULLDPLX; - bnx2_write_phy(bp, bp->mii_bmcr, bmcr); + bnx2_write_phy(bp, MII_BMCR, bmcr); bp->phy_flags |= PHY_PARALLEL_DETECT_FLAG; } } @@ -4561,9 +4246,9 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) if (phy2 & 0x20) { u32 bmcr; - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, MII_BMCR, &bmcr); bmcr |= BMCR_ANENABLE; - bnx2_write_phy(bp, bp->mii_bmcr, bmcr); + bnx2_write_phy(bp, MII_BMCR, bmcr); bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; } @@ -4587,12 +4272,17 @@ bnx2_5708_serdes_timer(struct bnx2 *bp) else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { u32 bmcr; - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, MII_BMCR, &bmcr); + if (bmcr & BMCR_ANENABLE) { - bnx2_enable_forced_2g5(bp); + bmcr &= ~BMCR_ANENABLE; + bmcr |= BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500; + bnx2_write_phy(bp, MII_BMCR, bmcr); bp->current_interval = SERDES_FORCED_TIMEOUT; } else { - bnx2_disable_forced_2g5(bp); + bmcr &= ~(BMCR_FULLDPLX | BCM5708S_BMCR_FORCE_2500); + bmcr |= BMCR_ANENABLE; + bnx2_write_phy(bp, MII_BMCR, bmcr); bp->serdes_an_pending = 2; bp->current_interval = bp->timer_interval; } @@ -4623,7 +4313,7 @@ bnx2_timer(unsigned long data) if (bp->phy_flags & PHY_SERDES_FLAG) { if (CHIP_NUM(bp) == CHIP_NUM_5706) bnx2_5706_serdes_timer(bp); - else + else if (CHIP_NUM(bp) == CHIP_NUM_5708) bnx2_5708_serdes_timer(bp); } @@ -4631,38 +4321,6 @@ bnx2_timer(unsigned long data) mod_timer(&bp->timer, jiffies + bp->current_interval); } -static int -bnx2_request_irq(struct bnx2 *bp) -{ - struct net_device *dev = bp->dev; - int rc = 0; - - if (bp->flags & USING_MSI_FLAG) { - irq_handler_t fn = bnx2_msi; - - if (bp->flags & ONE_SHOT_MSI_FLAG) - fn = bnx2_msi_1shot; - - rc = request_irq(bp->pdev->irq, fn, 0, dev->name, dev); - } else - rc = request_irq(bp->pdev->irq, bnx2_interrupt, - IRQF_SHARED, dev->name, dev); - return rc; -} - -static void -bnx2_free_irq(struct bnx2 *bp) -{ - struct net_device *dev = bp->dev; - - if (bp->flags & USING_MSI_FLAG) { - free_irq(bp->pdev->irq, dev); - pci_disable_msi(bp->pdev); - bp->flags &= ~(USING_MSI_FLAG | ONE_SHOT_MSI_FLAG); - } else - free_irq(bp->pdev->irq, dev); -} - /* Called with rtnl_lock */ static int bnx2_open(struct net_device *dev) @@ -4670,8 +4328,6 @@ bnx2_open(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); int rc; - netif_carrier_off(dev); - bnx2_set_power_state(bp, PCI_D0); bnx2_disable_int(bp); @@ -4679,15 +4335,24 @@ bnx2_open(struct net_device *dev) if (rc) return rc; - if ((bp->flags & MSI_CAP_FLAG) && !disable_msi) { + if ((CHIP_ID(bp) != CHIP_ID_5706_A0) && + (CHIP_ID(bp) != CHIP_ID_5706_A1) && + !disable_msi) { + if (pci_enable_msi(bp->pdev) == 0) { bp->flags |= USING_MSI_FLAG; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - bp->flags |= ONE_SHOT_MSI_FLAG; + rc = request_irq(bp->pdev->irq, bnx2_msi, 0, dev->name, + dev); + } + else { + rc = request_irq(bp->pdev->irq, bnx2_interrupt, + IRQF_SHARED, dev->name, dev); } } - rc = bnx2_request_irq(bp); - + else { + rc = request_irq(bp->pdev->irq, bnx2_interrupt, IRQF_SHARED, + dev->name, dev); + } if (rc) { bnx2_free_mem(bp); return rc; @@ -4696,7 +4361,11 @@ bnx2_open(struct net_device *dev) rc = bnx2_init_nic(bp); if (rc) { - bnx2_free_irq(bp); + free_irq(bp->pdev->irq, dev); + if (bp->flags & USING_MSI_FLAG) { + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + } bnx2_free_skbs(bp); bnx2_free_mem(bp); return rc; @@ -4720,13 +4389,16 @@ bnx2_open(struct net_device *dev) bp->dev->name); bnx2_disable_int(bp); - bnx2_free_irq(bp); + free_irq(bp->pdev->irq, dev); + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; rc = bnx2_init_nic(bp); - if (!rc) - rc = bnx2_request_irq(bp); - + if (!rc) { + rc = request_irq(bp->pdev->irq, bnx2_interrupt, + IRQF_SHARED, dev->name, dev); + } if (rc) { bnx2_free_skbs(bp); bnx2_free_mem(bp); @@ -4836,53 +4508,40 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } - if ((mss = skb_shinfo(skb)->gso_size)) { + if ((mss = skb_shinfo(skb)->gso_size) && + (skb->len > (bp->dev->mtu + ETH_HLEN))) { u32 tcp_opt_len, ip_tcp_len; struct iphdr *iph; - vlan_tag_flags |= TX_BD_FLAGS_SW_LSO; + if (skb_header_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } - tcp_opt_len = tcp_optlen(skb); + vlan_tag_flags |= TX_BD_FLAGS_SW_LSO; - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { - u32 tcp_off = skb_transport_offset(skb) - - sizeof(struct ipv6hdr) - ETH_HLEN; + tcp_opt_len = 0; + if (tcp_hdr(skb)->doff > 5) + tcp_opt_len = tcp_optlen(skb); - vlan_tag_flags |= ((tcp_opt_len >> 2) << 8) | - TX_BD_FLAGS_SW_FLAGS; - if (likely(tcp_off == 0)) - vlan_tag_flags &= ~TX_BD_FLAGS_TCP6_OFF0_MSK; - else { - tcp_off >>= 3; - vlan_tag_flags |= ((tcp_off & 0x3) << - TX_BD_FLAGS_TCP6_OFF0_SHL) | - ((tcp_off & 0x10) << - TX_BD_FLAGS_TCP6_OFF4_SHL); - mss |= (tcp_off & 0xc) << TX_BD_TCP6_OFF2_SHL; - } - } else { - if (skb_header_cloned(skb) && - pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } + ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); - ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr); - - iph = ip_hdr(skb); - iph->check = 0; - iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); - tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, - iph->daddr, 0, - IPPROTO_TCP, - 0); - if (tcp_opt_len || (iph->ihl > 5)) { - vlan_tag_flags |= ((iph->ihl - 5) + - (tcp_opt_len >> 2)) << 8; - } + iph = ip_hdr(skb); + iph->check = 0; + iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len); + tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, + iph->daddr, 0, + IPPROTO_TCP, 0); + if (tcp_opt_len || (iph->ihl > 5)) { + vlan_tag_flags |= ((iph->ihl - 5) + + (tcp_opt_len >> 2)) << 8; } - } else + } + else + { mss = 0; + } mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); @@ -4963,7 +4622,11 @@ bnx2_close(struct net_device *dev) else reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; bnx2_reset_chip(bp, reset_code); - bnx2_free_irq(bp); + free_irq(bp->pdev->irq, dev); + if (bp->flags & USING_MSI_FLAG) { + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + } bnx2_free_skbs(bp); bnx2_free_mem(bp); bp->link_up = 0; @@ -5072,8 +4735,6 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) if (bp->phy_flags & PHY_SERDES_FLAG) { cmd->supported |= SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE; - if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) - cmd->supported |= SUPPORTED_2500baseX_Full; cmd->port = PORT_FIBRE; } @@ -5137,10 +4798,8 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) advertising = cmd->advertising; - } else if (cmd->advertising == ADVERTISED_2500baseX_Full) { - if (!(bp->phy_flags & PHY_2_5G_CAPABLE_FLAG)) - return -EINVAL; - } else if (cmd->advertising == ADVERTISED_1000baseT_Full) { + } + else if (cmd->advertising == ADVERTISED_1000baseT_Full) { advertising = cmd->advertising; } else if (cmd->advertising == ADVERTISED_1000baseT_Half) { @@ -5316,7 +4975,7 @@ bnx2_nway_reset(struct net_device *dev) /* Force a link down visible on the other side */ if (bp->phy_flags & PHY_SERDES_FLAG) { - bnx2_write_phy(bp, bp->mii_bmcr, BMCR_LOOPBACK); + bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); spin_unlock_bh(&bp->phy_lock); msleep(20); @@ -5328,9 +4987,9 @@ bnx2_nway_reset(struct net_device *dev) mod_timer(&bp->timer, jiffies + bp->current_interval); } - bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, MII_BMCR, &bmcr); bmcr &= ~BMCR_LOOPBACK; - bnx2_write_phy(bp, bp->mii_bmcr, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); + bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); spin_unlock_bh(&bp->phy_lock); @@ -5550,15 +5209,10 @@ bnx2_set_rx_csum(struct net_device *dev, u32 data) static int bnx2_set_tso(struct net_device *dev, u32 data) { - struct bnx2 *bp = netdev_priv(dev); - - if (data) { + if (data) dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - dev->features |= NETIF_F_TSO6; - } else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 | - NETIF_F_TSO_ECN); + else + dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN); return 0; } @@ -5856,17 +5510,6 @@ bnx2_phys_id(struct net_device *dev, u32 data) return 0; } -static int -bnx2_set_tx_csum(struct net_device *dev, u32 data) -{ - struct bnx2 *bp = netdev_priv(dev); - - if (CHIP_NUM(bp) == CHIP_NUM_5709) - return (ethtool_op_set_tx_hw_csum(dev, data)); - else - return (ethtool_op_set_tx_csum(dev, data)); -} - static const struct ethtool_ops bnx2_ethtool_ops = { .get_settings = bnx2_get_settings, .set_settings = bnx2_set_settings, @@ -5889,7 +5532,7 @@ static const struct ethtool_ops bnx2_ethtool_ops = { .get_rx_csum = bnx2_get_rx_csum, .set_rx_csum = bnx2_set_rx_csum, .get_tx_csum = ethtool_op_get_tx_csum, - .set_tx_csum = bnx2_set_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, .get_tso = ethtool_op_get_tso, @@ -5919,9 +5562,6 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case SIOCGMIIREG: { u32 mii_regval; - if (!netif_running(dev)) - return -EAGAIN; - spin_lock_bh(&bp->phy_lock); err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval); spin_unlock_bh(&bp->phy_lock); @@ -5935,9 +5575,6 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (!netif_running(dev)) - return -EAGAIN; - spin_lock_bh(&bp->phy_lock); err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in); spin_unlock_bh(&bp->phy_lock); @@ -6039,58 +5676,6 @@ bnx2_get_5709_media(struct bnx2 *bp) } } -static void __devinit -bnx2_get_pci_speed(struct bnx2 *bp) -{ - u32 reg; - - reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); - if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { - u32 clkreg; - - bp->flags |= PCIX_FLAG; - - clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS); - - clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET; - switch (clkreg) { - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ: - bp->bus_speed_mhz = 133; - break; - - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ: - bp->bus_speed_mhz = 100; - break; - - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ: - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ: - bp->bus_speed_mhz = 66; - break; - - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ: - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ: - bp->bus_speed_mhz = 50; - break; - - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW: - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ: - case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ: - bp->bus_speed_mhz = 33; - break; - } - } - else { - if (reg & BNX2_PCICFG_MISC_STATUS_M66EN) - bp->bus_speed_mhz = 66; - else - bp->bus_speed_mhz = 33; - } - - if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET) - bp->flags |= PCI_32BIT_FLAG; - -} - static int __devinit bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) { @@ -6098,7 +5683,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) unsigned long mem_len; int rc; u32 reg; - u64 dma_mask, persist_dma_mask; SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); @@ -6137,11 +5721,25 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) goto err_out_release; } + if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) { + bp->flags |= USING_DAC_FLAG; + if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) { + dev_err(&pdev->dev, + "pci_set_consistent_dma_mask failed, aborting.\n"); + rc = -EIO; + goto err_out_release; + } + } + else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) { + dev_err(&pdev->dev, "System does not support DMA, aborting.\n"); + rc = -EIO; + goto err_out_release; + } + bp->dev = dev; bp->pdev = pdev; spin_lock_init(&bp->phy_lock); - spin_lock_init(&bp->indirect_lock); INIT_WORK(&bp->reset_task, bnx2_reset_task); dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); @@ -6169,15 +5767,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->chip_id = REG_RD(bp, BNX2_MISC_ID); - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - if (pci_find_capability(pdev, PCI_CAP_ID_EXP) == 0) { - dev_err(&pdev->dev, - "Cannot find PCIE capability, aborting.\n"); - rc = -EIO; - goto err_out_unmap; - } - bp->flags |= PCIE_FLAG; - } else { + if (CHIP_NUM(bp) != CHIP_NUM_5709) { bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); if (bp->pcix_cap == 0) { dev_err(&pdev->dev, @@ -6187,33 +5777,51 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) } } - if (CHIP_ID(bp) != CHIP_ID_5706_A0 && CHIP_ID(bp) != CHIP_ID_5706_A1) { - if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) - bp->flags |= MSI_CAP_FLAG; - } + /* Get bus information. */ + reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); + if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { + u32 clkreg; - /* 5708 cannot support DMA addresses > 40-bit. */ - if (CHIP_NUM(bp) == CHIP_NUM_5708) - persist_dma_mask = dma_mask = DMA_40BIT_MASK; - else - persist_dma_mask = dma_mask = DMA_64BIT_MASK; + bp->flags |= PCIX_FLAG; - /* Configure DMA attributes. */ - if (pci_set_dma_mask(pdev, dma_mask) == 0) { - dev->features |= NETIF_F_HIGHDMA; - rc = pci_set_consistent_dma_mask(pdev, persist_dma_mask); - if (rc) { - dev_err(&pdev->dev, - "pci_set_consistent_dma_mask failed, aborting.\n"); - goto err_out_unmap; + clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS); + + clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET; + switch (clkreg) { + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ: + bp->bus_speed_mhz = 133; + break; + + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ: + bp->bus_speed_mhz = 100; + break; + + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ: + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ: + bp->bus_speed_mhz = 66; + break; + + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ: + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ: + bp->bus_speed_mhz = 50; + break; + + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW: + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ: + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ: + bp->bus_speed_mhz = 33; + break; } - } else if ((rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) { - dev_err(&pdev->dev, "System does not support DMA, aborting.\n"); - goto err_out_unmap; + } + else { + if (reg & BNX2_PCICFG_MISC_STATUS_M66EN) + bp->bus_speed_mhz = 66; + else + bp->bus_speed_mhz = 33; } - if (!(bp->flags & PCIE_FLAG)) - bnx2_get_pci_speed(bp); + if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET) + bp->flags |= PCI_32BIT_FLAG; /* 5706A0 may falsely detect SERR and PERR. */ if (CHIP_ID(bp) == CHIP_ID_5706_A0) { @@ -6397,26 +6005,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) return rc; } -static char * __devinit -bnx2_bus_string(struct bnx2 *bp, char *str) -{ - char *s = str; - - if (bp->flags & PCIE_FLAG) { - s += sprintf(s, "PCI Express"); - } else { - s += sprintf(s, "PCI"); - if (bp->flags & PCIX_FLAG) - s += sprintf(s, "-X"); - if (bp->flags & PCI_32BIT_FLAG) - s += sprintf(s, " 32-bit"); - else - s += sprintf(s, " 64-bit"); - s += sprintf(s, " %dMHz", bp->bus_speed_mhz); - } - return str; -} - static int __devinit bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -6424,7 +6012,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) struct net_device *dev = NULL; struct bnx2 *bp; int rc, i; - char str[40]; if (version_printed++ == 0) printk(KERN_INFO "%s", version); @@ -6465,23 +6052,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->poll_controller = poll_bnx2; #endif - pci_set_drvdata(pdev, dev); - - memcpy(dev->dev_addr, bp->mac_addr, 6); - memcpy(dev->perm_addr, bp->mac_addr, 6); - bp->name = board_info[ent->driver_data].name; - - if (CHIP_NUM(bp) == CHIP_NUM_5709) - dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; - else - dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; -#ifdef BCM_VLAN - dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif - dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; - if (CHIP_NUM(bp) == CHIP_NUM_5709) - dev->features |= NETIF_F_TSO6; - if ((rc = register_netdev(dev))) { dev_err(&pdev->dev, "Cannot register net device\n"); if (bp->regview) @@ -6493,13 +6063,20 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return rc; } - printk(KERN_INFO "%s: %s (%c%d) %s found at mem %lx, " + pci_set_drvdata(pdev, dev); + + memcpy(dev->dev_addr, bp->mac_addr, 6); + memcpy(dev->perm_addr, bp->mac_addr, 6); + bp->name = board_info[ent->driver_data].name, + printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz found at mem %lx, " "IRQ %d, ", dev->name, bp->name, ((CHIP_ID(bp) & 0xf000) >> 12) + 'A', ((CHIP_ID(bp) & 0x0ff0) >> 4), - bnx2_bus_string(bp, str), + ((bp->flags & PCIX_FLAG) ? "-X" : ""), + ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"), + bp->bus_speed_mhz, dev->base_addr, bp->pdev->irq); @@ -6508,6 +6085,17 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) printk("%2.2x", dev->dev_addr[i]); printk("\n"); + dev->features |= NETIF_F_SG; + if (bp->flags & USING_DAC_FLAG) + dev->features |= NETIF_F_HIGHDMA; + dev->features |= NETIF_F_IP_CSUM; +#ifdef BCM_VLAN + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; +#endif + dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; + + netif_carrier_off(bp->dev); + return 0; } @@ -6552,7 +6140,6 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; bnx2_reset_chip(bp, reset_code); bnx2_free_skbs(bp); - pci_save_state(pdev); bnx2_set_power_state(bp, pci_choose_state(pdev, state)); return 0; } @@ -6566,7 +6153,6 @@ bnx2_resume(struct pci_dev *pdev) if (!netif_running(dev)) return 0; - pci_restore_state(pdev); bnx2_set_power_state(bp, PCI_D0); netif_device_attach(dev); bnx2_init_nic(bp); diff --git a/trunk/drivers/net/bnx2.h b/trunk/drivers/net/bnx2.h index bd6288d6350f..878eee58f12a 100644 --- a/trunk/drivers/net/bnx2.h +++ b/trunk/drivers/net/bnx2.h @@ -1,6 +1,6 @@ /* bnx2.h: Broadcom NX2 network driver. * - * Copyright (c) 2004-2007 Broadcom Corporation + * Copyright (c) 2004, 2005, 2006 Broadcom Corporation * * 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 @@ -24,11 +24,8 @@ struct tx_bd { u32 tx_bd_haddr_hi; u32 tx_bd_haddr_lo; u32 tx_bd_mss_nbytes; - #define TX_BD_TCP6_OFF2_SHL (14) u32 tx_bd_vlan_tag_flags; #define TX_BD_FLAGS_CONN_FAULT (1<<0) - #define TX_BD_FLAGS_TCP6_OFF0_MSK (3<<1) - #define TX_BD_FLAGS_TCP6_OFF0_SHL (1) #define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1) #define TX_BD_FLAGS_IP_CKSUM (1<<2) #define TX_BD_FLAGS_VLAN_TAG (1<<3) @@ -37,7 +34,6 @@ struct tx_bd { #define TX_BD_FLAGS_END (1<<6) #define TX_BD_FLAGS_START (1<<7) #define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8) - #define TX_BD_FLAGS_TCP6_OFF4_SHL (12) #define TX_BD_FLAGS_SW_FLAGS (1<<13) #define TX_BD_FLAGS_SW_SNAP (1<<14) #define TX_BD_FLAGS_SW_LSO (1<<15) @@ -6296,41 +6292,6 @@ struct l2_fhdr { #define MII_BNX2_DSP_ADDRESS 0x17 #define MII_BNX2_DSP_EXPAND_REG 0x0f00 -#define MII_BNX2_BLK_ADDR 0x1f -#define MII_BNX2_BLK_ADDR_IEEE0 0x0000 -#define MII_BNX2_BLK_ADDR_GP_STATUS 0x8120 -#define MII_BNX2_GP_TOP_AN_STATUS1 0x1b -#define MII_BNX2_GP_TOP_AN_SPEED_MSK 0x3f00 -#define MII_BNX2_GP_TOP_AN_SPEED_10 0x0000 -#define MII_BNX2_GP_TOP_AN_SPEED_100 0x0100 -#define MII_BNX2_GP_TOP_AN_SPEED_1G 0x0200 -#define MII_BNX2_GP_TOP_AN_SPEED_2_5G 0x0300 -#define MII_BNX2_GP_TOP_AN_SPEED_1GKV 0x0d00 -#define MII_BNX2_GP_TOP_AN_FD 0x8 -#define MII_BNX2_BLK_ADDR_SERDES_DIG 0x8300 -#define MII_BNX2_SERDES_DIG_1000XCTL1 0x10 -#define MII_BNX2_SD_1000XCTL1_FIBER 0x01 -#define MII_BNX2_SD_1000XCTL1_AUTODET 0x10 -#define MII_BNX2_SERDES_DIG_MISC1 0x18 -#define MII_BNX2_SD_MISC1_FORCE_MSK 0xf -#define MII_BNX2_SD_MISC1_FORCE_2_5G 0x0 -#define MII_BNX2_SD_MISC1_FORCE 0x10 -#define MII_BNX2_BLK_ADDR_OVER1G 0x8320 -#define MII_BNX2_OVER1G_UP1 0x19 -#define MII_BNX2_BLK_ADDR_BAM_NXTPG 0x8350 -#define MII_BNX2_BAM_NXTPG_CTL 0x10 -#define MII_BNX2_NXTPG_CTL_BAM 0x1 -#define MII_BNX2_NXTPG_CTL_T2 0x2 -#define MII_BNX2_BLK_ADDR_CL73_USERB0 0x8370 -#define MII_BNX2_CL73_BAM_CTL1 0x12 -#define MII_BNX2_CL73_BAM_EN 0x8000 -#define MII_BNX2_CL73_BAM_STA_MGR_EN 0x4000 -#define MII_BNX2_CL73_BAM_NP_AFT_BP_EN 0x2000 -#define MII_BNX2_BLK_ADDR_AER 0xffd0 -#define MII_BNX2_AER_AER 0x1e -#define MII_BNX2_AER_AER_AN_MMD 0x3800 -#define MII_BNX2_BLK_ADDR_COMBO_IEEEB0 0xffe0 - #define MIN_ETHERNET_PACKET_SIZE 60 #define MAX_ETHERNET_PACKET_SIZE 1514 #define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014 @@ -6468,15 +6429,13 @@ struct bnx2 { u32 last_status_idx; u32 flags; -#define PCIX_FLAG 0x00000001 -#define PCI_32BIT_FLAG 0x00000002 -#define ONE_TDMA_FLAG 0x00000004 /* no longer used */ -#define NO_WOL_FLAG 0x00000008 -#define USING_MSI_FLAG 0x00000020 -#define ASF_ENABLE_FLAG 0x00000040 -#define MSI_CAP_FLAG 0x00000080 -#define ONE_SHOT_MSI_FLAG 0x00000100 -#define PCIE_FLAG 0x00000200 +#define PCIX_FLAG 1 +#define PCI_32BIT_FLAG 2 +#define ONE_TDMA_FLAG 4 /* no longer used */ +#define NO_WOL_FLAG 8 +#define USING_DAC_FLAG 0x10 +#define USING_MSI_FLAG 0x20 +#define ASF_ENABLE_FLAG 0x40 /* Put tx producer and consumer fields in separate cache lines. */ @@ -6525,7 +6484,6 @@ struct bnx2 { /* Used to synchronize phy accesses. */ spinlock_t phy_lock; - spinlock_t indirect_lock; u32 phy_flags; #define PHY_SERDES_FLAG 1 @@ -6537,13 +6495,6 @@ struct bnx2 { #define PHY_INT_MODE_LINK_READY_FLAG 0x200 #define PHY_DIS_EARLY_DAC_FLAG 0x400 - u32 mii_bmcr; - u32 mii_bmsr; - u32 mii_bmsr1; - u32 mii_adv; - u32 mii_lpa; - u32 mii_up1; - u32 chip_id; /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ #define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000) diff --git a/trunk/drivers/net/bnx2_fw.h b/trunk/drivers/net/bnx2_fw.h index b49f439e0f67..21d368ff424d 100644 --- a/trunk/drivers/net/bnx2_fw.h +++ b/trunk/drivers/net/bnx2_fw.h @@ -15,1071 +15,680 @@ */ static u8 bnx2_COM_b06FwText[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x45, 0x30, 0xe7, 0x45, 0x00, 0x03, 0xdc, 0x5a, - 0x6b, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x4b, 0xae, 0xc8, 0x15, - 0x35, 0xa2, 0xc6, 0xf4, 0x5a, 0xa2, 0xed, 0x5d, 0x72, 0x28, 0x12, 0x96, - 0xec, 0x6e, 0x68, 0xda, 0x62, 0x8c, 0x8d, 0xb4, 0xd9, 0xa5, 0x0c, 0xa1, - 0x65, 0x6b, 0x4a, 0xa2, 0x6d, 0x05, 0x11, 0x02, 0x62, 0x49, 0xa9, 0x46, - 0x50, 0xb7, 0x92, 0xab, 0xb6, 0x81, 0x6b, 0x4b, 0x6b, 0x92, 0x6a, 0x09, - 0x84, 0xe6, 0x08, 0x11, 0x43, 0x19, 0xa9, 0x11, 0x10, 0xa4, 0x1c, 0xbb, - 0xc0, 0xb6, 0x2b, 0xbf, 0x05, 0x34, 0x2e, 0x15, 0x4a, 0x6e, 0xd4, 0x34, - 0x30, 0xfc, 0xa7, 0xa8, 0x51, 0x38, 0xad, 0xe1, 0x04, 0xa8, 0x9b, 0x16, - 0x45, 0xd0, 0xfc, 0x88, 0x0a, 0xdb, 0xd9, 0x7e, 0xdf, 0x9d, 0x3b, 0xcb, - 0xe1, 0x92, 0xd4, 0xc3, 0x8f, 0xfe, 0x28, 0x81, 0xe5, 0xcc, 0xbd, 0x73, - 0xe7, 0xde, 0x73, 0xcf, 0xe3, 0x3b, 0x8f, 0xb9, 0x77, 0x8a, 0x34, 0x88, - 0xfe, 0x5b, 0x8f, 0x5f, 0xf2, 0xd1, 0x3f, 0x18, 0xbe, 0xab, 0xe7, 0xae, - 0xbb, 0x71, 0x7b, 0xb7, 0x19, 0xb1, 0x22, 0xec, 0xe7, 0x3f, 0x07, 0xbf, - 0x6e, 0x7d, 0xbf, 0xda, 0x9f, 0x8d, 0xdf, 0x65, 0xfc, 0x86, 0x7e, 0x2e, - 0x62, 0xac, 0x31, 0x26, 0xfc, 0x57, 0xa9, 0x5c, 0xfd, 0xb9, 0x49, 0x5a, - 0xae, 0xf2, 0x3c, 0xe2, 0x2f, 0xa9, 0x68, 0xe6, 0x4f, 0x62, 0x66, 0x46, - 0x8e, 0xe7, 0x5c, 0x89, 0x45, 0x32, 0x1f, 0x1c, 0x1f, 0x76, 0x45, 0xb2, - 0xa5, 0x6d, 0xc9, 0xbc, 0x7c, 0x5c, 0x29, 0x3a, 0x96, 0xb0, 0xff, 0xd6, - 0xcc, 0x47, 0x27, 0xde, 0xd8, 0x91, 0xfa, 0xc5, 0x6c, 0x44, 0x62, 0x76, - 0xe6, 0x15, 0xb1, 0xb7, 0x4a, 0xac, 0x15, 0xef, 0x3c, 0xdb, 0x99, 0x33, - 0xa4, 0x29, 0x98, 0xeb, 0x83, 0xca, 0x1b, 0x9d, 0x52, 0xdc, 0x9c, 0x89, - 0x89, 0x99, 0xe9, 0x78, 0x27, 0x17, 0xb1, 0x87, 0x22, 0x19, 0x5b, 0x16, - 0xca, 0x32, 0x30, 0x32, 0x29, 0xb1, 0x58, 0x66, 0x22, 0x56, 0xdf, 0x21, - 0xb1, 0x68, 0x66, 0xe8, 0xf8, 0xf7, 0xdc, 0x13, 0x15, 0xd3, 0x75, 0x93, - 0xa3, 0x12, 0xef, 0x1d, 0xef, 0xc1, 0xf3, 0x52, 0x0a, 0x04, 0xef, 0x10, - 0xd3, 0x2d, 0xc6, 0x23, 0x6e, 0x4c, 0x72, 0x65, 0x57, 0xf2, 0x65, 0x91, - 0x1f, 0x96, 0x0c, 0x19, 0x77, 0x5b, 0x64, 0x74, 0xfb, 0x47, 0x95, 0x2c, - 0x68, 0xf9, 0x3b, 0x77, 0xe8, 0xf8, 0x73, 0x2e, 0xe9, 0x9d, 0x8e, 0xf9, - 0xf4, 0x8e, 0xd7, 0x0f, 0xbb, 0x96, 0xcc, 0x95, 0xd8, 0x77, 0xd0, 0x64, - 0x9f, 0x95, 0xf9, 0x7e, 0xc3, 0xb8, 0x1b, 0xd7, 0x7d, 0x13, 0xd9, 0x1c, - 0xe6, 0x9b, 0x2f, 0x71, 0xec, 0xbb, 0x5f, 0x18, 0x76, 0x1d, 0xdd, 0x9f, - 0xdd, 0x91, 0x73, 0x13, 0xe8, 0x6f, 0xd5, 0xcf, 0x9e, 0x79, 0x74, 0xd8, - 0x75, 0xf5, 0x33, 0xcb, 0xca, 0xb9, 0x5d, 0xba, 0xbf, 0xb4, 0x6b, 0xd8, - 0xdd, 0xae, 0xfb, 0x7f, 0xbc, 0x2b, 0xe7, 0xa6, 0x75, 0x7f, 0xef, 0x57, - 0x86, 0xdd, 0x1e, 0xdd, 0xff, 0xf6, 0xce, 0x9c, 0xdb, 0xab, 0xfb, 0x4f, - 0xf5, 0x0e, 0xbb, 0xb6, 0x9c, 0x2d, 0x25, 0xf1, 0x9b, 0x88, 0x59, 0x1d, - 0x19, 0x3d, 0xe6, 0x59, 0xd0, 0x9b, 0xc5, 0x98, 0x3e, 0xf4, 0xef, 0xc1, - 0xaf, 0x1f, 0xbf, 0xf2, 0x06, 0x69, 0x1a, 0xc0, 0xf3, 0x0f, 0xb7, 0xf8, - 0x3c, 0x04, 0xaf, 0xbc, 0x98, 0xbc, 0x17, 0x49, 0xc8, 0x1b, 0x9d, 0xef, - 0x81, 0x97, 0xb6, 0x9c, 0x2b, 0x8b, 0x31, 0xd0, 0x99, 0x00, 0x0f, 0x1d, - 0x79, 0xb1, 0xdc, 0x28, 0x91, 0x6f, 0x45, 0xc0, 0xa3, 0xaf, 0x4a, 0xc1, - 0x89, 0xc9, 0xc6, 0x19, 0x43, 0xda, 0xba, 0xd7, 0x49, 0xd6, 0x2e, 0x4a, - 0xbe, 0x13, 0x52, 0x9f, 0x72, 0xc4, 0x9a, 0x59, 0xdc, 0x68, 0xa2, 0xc7, - 0x94, 0x54, 0xa2, 0x80, 0x19, 0x47, 0xce, 0xbe, 0x4b, 0x1d, 0xa5, 0x7c, - 0xf1, 0x4b, 0x4a, 0x7e, 0xf2, 0x0e, 0x19, 0xb2, 0x49, 0xe7, 0x9f, 0xdd, - 0xea, 0xaf, 0x19, 0x33, 0x72, 0x67, 0x06, 0xe5, 0xa4, 0x17, 0x37, 0xf2, - 0x67, 0x76, 0x4a, 0x2e, 0x2d, 0x8e, 0x29, 0x1d, 0xea, 0xdd, 0xf9, 0xd2, - 0xa0, 0x8c, 0x7b, 0x62, 0xe4, 0x3c, 0x4b, 0x46, 0x4b, 0x2d, 0x78, 0xde, - 0xa4, 0xc6, 0xa2, 0xaf, 0x35, 0x22, 0x1d, 0x76, 0x5e, 0x62, 0xe8, 0xb7, - 0xd1, 0xdf, 0x6c, 0xf4, 0xa9, 0x39, 0x54, 0x7f, 0x72, 0x4c, 0xe2, 0xd8, - 0x9b, 0xa3, 0xc7, 0x56, 0x2a, 0xb9, 0xb4, 0x8d, 0x71, 0x83, 0x32, 0xe6, - 0x39, 0x32, 0x84, 0xeb, 0xa8, 0xc7, 0xf5, 0x13, 0xd0, 0xb1, 0xb7, 0x8e, - 0x17, 0xa6, 0xd5, 0x7c, 0xc9, 0x48, 0x86, 0xf3, 0xb5, 0x62, 0xdc, 0x05, - 0xd0, 0x65, 0x88, 0xa5, 0x64, 0x9b, 0x95, 0xc2, 0xa4, 0x21, 0xe4, 0x5b, - 0x41, 0xf1, 0xb0, 0x0f, 0xf4, 0x5b, 0xe2, 0x76, 0x1b, 0x32, 0xec, 0xde, - 0x2c, 0x45, 0x1b, 0xed, 0xd2, 0x79, 0x33, 0xe7, 0xd5, 0x4b, 0xde, 0x4a, - 0x62, 0xff, 0x94, 0xfd, 0x90, 0x8c, 0xe1, 0x1d, 0xd3, 0xe5, 0x98, 0x8f, - 0xb0, 0x77, 0xb4, 0xf1, 0x6e, 0x5d, 0xe6, 0xa0, 0x5c, 0x9a, 0x2c, 0x9a, - 0xb9, 0x72, 0x8b, 0x44, 0x66, 0x52, 0xd0, 0xfe, 0x71, 0x33, 0xff, 0xbc, - 0x25, 0xd1, 0x29, 0xea, 0x97, 0xd8, 0x91, 0xcc, 0x84, 0xb9, 0xbb, 0x7c, - 0xde, 0xcc, 0x97, 0xf9, 0x0e, 0xc6, 0x96, 0x4c, 0xf0, 0x96, 0xf7, 0xdb, - 0xc0, 0x4b, 0xea, 0x36, 0xdf, 0x81, 0x1c, 0xb0, 0x87, 0x17, 0x3d, 0xc8, - 0x45, 0xc9, 0x29, 0x09, 0x39, 0x89, 0xd1, 0xd7, 0x19, 0x93, 0xb1, 0x69, - 0x4b, 0x0a, 0xe9, 0x9b, 0x15, 0xe7, 0x0b, 0xe9, 0x25, 0x9a, 0x46, 0x27, - 0x6b, 0x69, 0xe2, 0x7b, 0xa4, 0xc9, 0xa7, 0x65, 0x6c, 0x9a, 0xb4, 0xf9, - 0xb4, 0x9c, 0x9c, 0x24, 0x8d, 0x5c, 0x87, 0xf4, 0x90, 0xae, 0x80, 0x26, - 0xbe, 0x43, 0x9a, 0x36, 0x61, 0x7e, 0x65, 0xc0, 0x46, 0x1f, 0x68, 0x18, - 0xf3, 0x2c, 0xc8, 0x26, 0x2e, 0x05, 0xbb, 0x68, 0x8c, 0xf5, 0x6e, 0x4b, - 0xc0, 0xaa, 0x8d, 0xd1, 0x5e, 0xd2, 0xeb, 0x42, 0x7e, 0x75, 0x4a, 0xce, - 0x66, 0x66, 0x9c, 0x3c, 0xc3, 0x78, 0xae, 0x8d, 0xfb, 0x92, 0x2d, 0xe3, - 0x6a, 0x3e, 0xd2, 0xf3, 0x59, 0xcc, 0x43, 0x7a, 0x2f, 0x43, 0x57, 0x7b, - 0xa0, 0xa3, 0x69, 0xf9, 0xdb, 0xf2, 0x76, 0x79, 0xbd, 0xdc, 0x25, 0xaf, - 0xc1, 0x7e, 0x5f, 0x2d, 0x27, 0xe5, 0x95, 0x72, 0xab, 0xbc, 0x5c, 0x4e, - 0xc8, 0x4b, 0x4a, 0x7f, 0xfb, 0x44, 0x9a, 0x94, 0x4e, 0xc7, 0x6e, 0x86, - 0x3e, 0xb6, 0x40, 0x1f, 0x9b, 0x61, 0x4f, 0x1b, 0x61, 0xab, 0xdf, 0x06, - 0x0f, 0xa7, 0x3b, 0x25, 0xbb, 0x09, 0xfd, 0xb7, 0x65, 0x2c, 0xa5, 0x23, - 0x16, 0x9e, 0x8f, 0x4d, 0x46, 0x25, 0x6f, 0x9f, 0x95, 0xf7, 0xa7, 0x2c, - 0x19, 0x2b, 0x3f, 0x79, 0x9b, 0xaf, 0xb3, 0x6c, 0xcf, 0xca, 0x45, 0xf4, - 0xe5, 0xed, 0x59, 0xb9, 0xb4, 0xd5, 0x94, 0xd1, 0xe9, 0xef, 0x4a, 0xee, - 0xf9, 0xb3, 0xf2, 0xd3, 0xbf, 0x16, 0x19, 0x00, 0xef, 0xcd, 0xee, 0xff, - 0xaa, 0x64, 0x6d, 0xec, 0xb1, 0x7b, 0xbb, 0x92, 0x89, 0xd9, 0x4d, 0x3d, - 0x4e, 0x02, 0x57, 0x2c, 0x23, 0xef, 0xbd, 0x00, 0x6c, 0x69, 0x34, 0x72, - 0xa7, 0x45, 0x86, 0x4f, 0x57, 0x64, 0x38, 0x1d, 0x95, 0xc7, 0xec, 0x8a, - 0xf4, 0xa5, 0xeb, 0xe4, 0xa8, 0x4d, 0xac, 0x39, 0x6e, 0x04, 0xb8, 0xfe, - 0xed, 0xf2, 0x09, 0xdc, 0xb3, 0x4f, 0x64, 0x5a, 0xdd, 0xfb, 0xfd, 0xc5, - 0x72, 0x54, 0xb2, 0x4e, 0x31, 0x61, 0x49, 0x9b, 0xe9, 0xd3, 0xf4, 0xcd, - 0xe0, 0x19, 0x78, 0x35, 0x04, 0x2c, 0xf5, 0xed, 0xaf, 0x30, 0xb9, 0xee, - 0x4a, 0x56, 0x75, 0x47, 0x29, 0x3b, 0xe8, 0x34, 0x79, 0x9d, 0x1c, 0x32, - 0x32, 0x8e, 0xb4, 0x29, 0xbc, 0xe8, 0xc1, 0x98, 0x5e, 0x63, 0x7f, 0x99, - 0x7a, 0x8e, 0xfb, 0x12, 0x69, 0xdd, 0x8c, 0xb1, 0x16, 0xae, 0x59, 0x4d, - 0x73, 0x98, 0x4e, 0xce, 0x45, 0x3a, 0x79, 0x7d, 0x21, 0x44, 0xe7, 0x5f, - 0x56, 0xef, 0xa7, 0x43, 0xf7, 0xc5, 0xf2, 0x0f, 0x1a, 0x7c, 0xfa, 0xc8, - 0xcf, 0x5e, 0xe8, 0xe3, 0x37, 0xf4, 0x5a, 0xb8, 0x2f, 0x71, 0x8d, 0xb3, - 0x15, 0x5f, 0xa7, 0x8a, 0xd7, 0x58, 0xeb, 0x62, 0x68, 0xad, 0x4b, 0xa1, - 0xb5, 0x2e, 0x85, 0xd6, 0x2a, 0x82, 0xb7, 0xb2, 0xc1, 0x74, 0xa3, 0xc0, - 0x27, 0xf6, 0x4c, 0x60, 0xce, 0x67, 0x21, 0x97, 0x9f, 0x60, 0x4c, 0x46, - 0x16, 0x3d, 0xf0, 0xe3, 0x74, 0x54, 0xf6, 0xa9, 0x67, 0xbd, 0x9a, 0xae, - 0xf0, 0xb3, 0x98, 0xec, 0x75, 0x78, 0x1f, 0x3c, 0xb3, 0xc0, 0x63, 0xb6, - 0xff, 0xe1, 0x16, 0xbf, 0xcd, 0xfb, 0xf3, 0x9a, 0xfe, 0x87, 0xfc, 0xf7, - 0xca, 0x1f, 0x28, 0x9c, 0x5c, 0x28, 0x13, 0xc7, 0x24, 0x1d, 0x71, 0xe5, - 0x48, 0x5f, 0x1a, 0x76, 0x65, 0x1b, 0xe9, 0xd1, 0xae, 0x7a, 0xf2, 0x3c, - 0x6b, 0xba, 0x8d, 0xc0, 0x0a, 0x49, 0x9a, 0xd0, 0xb3, 0x51, 0xb5, 0x97, - 0x75, 0xa6, 0x4f, 0xb3, 0xcd, 0xf6, 0x80, 0xe9, 0x36, 0xd7, 0xf4, 0xd3, - 0xde, 0x1b, 0x71, 0x4f, 0xdd, 0x7e, 0x4c, 0xcb, 0x37, 0x8e, 0x36, 0xf1, - 0xb9, 0x5f, 0xb7, 0x83, 0xe7, 0x39, 0x6b, 0x79, 0xfb, 0xed, 0x2d, 0xcb, - 0xdb, 0x01, 0x76, 0x84, 0xb1, 0x9d, 0x7b, 0x4d, 0x4a, 0xc4, 0xa5, 0xce, - 0x45, 0x41, 0x6b, 0x1a, 0xb6, 0x58, 0xaf, 0x69, 0xb8, 0x5d, 0xd3, 0x00, - 0x5a, 0x31, 0x6e, 0x54, 0xd9, 0x98, 0x12, 0x5f, 0x4d, 0x9b, 0xfc, 0x0e, - 0xee, 0xd7, 0xab, 0xe7, 0xbe, 0x2d, 0x06, 0x57, 0x31, 0x76, 0x77, 0x52, - 0xe6, 0x13, 0x90, 0x79, 0x5c, 0xe6, 0xa7, 0xc9, 0xb3, 0x54, 0xe2, 0x71, - 0x41, 0xbb, 0x94, 0x90, 0xb3, 0x93, 0x92, 0x3d, 0x7c, 0xaa, 0x57, 0xfa, - 0x60, 0x9f, 0x73, 0x93, 0x57, 0x2a, 0xe0, 0xdb, 0xbd, 0x75, 0xe2, 0x02, - 0x83, 0xe1, 0xef, 0x7b, 0xa2, 0x12, 0xc9, 0x64, 0xa0, 0x0b, 0x69, 0xe5, - 0x83, 0x97, 0xfe, 0x2c, 0xeb, 0xfe, 0x65, 0xed, 0x3a, 0xf8, 0x79, 0xcc, - 0xdb, 0x93, 0x56, 0x7a, 0x13, 0xfe, 0xcb, 0x01, 0x57, 0x72, 0xe9, 0x8f, - 0xa1, 0x5b, 0x01, 0x4d, 0x81, 0x6d, 0xd0, 0x07, 0x7d, 0x10, 0xf2, 0x6d, - 0xad, 0xc0, 0x17, 0x07, 0xf2, 0x0b, 0xfc, 0x11, 0xfd, 0x44, 0x82, 0x58, - 0x0e, 0x5b, 0xa0, 0x6f, 0x88, 0x8b, 0x39, 0x63, 0x69, 0xff, 0x11, 0xd3, - 0xfe, 0x23, 0x0e, 0xdf, 0xc1, 0xb6, 0xad, 0xdb, 0x8e, 0x6e, 0x27, 0xd0, - 0x46, 0xec, 0x31, 0x43, 0xbb, 0x7a, 0xeb, 0xf8, 0xc8, 0xb4, 0xf2, 0x49, - 0xf4, 0x67, 0xf0, 0x14, 0xf4, 0x29, 0xf4, 0x2d, 0xd8, 0x6f, 0x09, 0xeb, - 0x55, 0x31, 0x9c, 0xf2, 0x08, 0xd3, 0x43, 0x5a, 0xd6, 0x89, 0x09, 0x3f, - 0x9b, 0x75, 0x48, 0xef, 0x77, 0x20, 0x0f, 0x62, 0x25, 0xe9, 0xbe, 0x15, - 0xb4, 0x72, 0x3f, 0xff, 0x97, 0xb4, 0x72, 0xbd, 0x5a, 0x7a, 0x3f, 0x2d, - 0x66, 0x2b, 0xec, 0xc0, 0x9e, 0x33, 0xc0, 0x66, 0x31, 0xf6, 0x77, 0x0e, - 0x62, 0xcf, 0x03, 0xc0, 0xee, 0x7e, 0x60, 0xf7, 0x1e, 0x60, 0x77, 0x1f, - 0xb0, 0x3b, 0x0b, 0xec, 0xee, 0x05, 0x6e, 0xf7, 0x00, 0xb7, 0xd3, 0xe0, - 0x8d, 0x23, 0xb3, 0xc0, 0xf1, 0x59, 0xe8, 0xcb, 0x2c, 0xe6, 0x28, 0xcc, - 0x88, 0xf1, 0x35, 0xec, 0xe1, 0xe8, 0x54, 0x6a, 0x16, 0xfa, 0x9d, 0x18, - 0x32, 0xa1, 0x07, 0xe9, 0xbb, 0x61, 0x6f, 0x88, 0x9b, 0xca, 0x83, 0x32, - 0x0c, 0xbf, 0xdf, 0xb6, 0xb5, 0x1d, 0xfa, 0x84, 0x68, 0x24, 0x11, 0xe8, - 0x68, 0xbf, 0x14, 0xbc, 0x76, 0xbb, 0xcd, 0xec, 0x42, 0x5f, 0x2a, 0x89, - 0x18, 0xd5, 0x38, 0x74, 0x3a, 0x65, 0x8c, 0x9c, 0x26, 0x0f, 0x26, 0x81, - 0x83, 0x15, 0x19, 0x4f, 0x53, 0x4f, 0x2b, 0xf2, 0x5c, 0x3a, 0xd5, 0x5b, - 0x94, 0x46, 0x39, 0xe9, 0x4c, 0x2a, 0xdf, 0x6f, 0x65, 0x4e, 0x29, 0x1f, - 0x3a, 0xec, 0xe2, 0x5a, 0x6a, 0x33, 0x0a, 0xa7, 0xb9, 0xd7, 0x76, 0xfc, - 0xa2, 0x58, 0xf7, 0x57, 0x90, 0x91, 0x25, 0x7d, 0x3d, 0x62, 0x1c, 0xee, - 0x2c, 0x02, 0x39, 0x53, 0xf6, 0x22, 0x56, 0xcb, 0x4f, 0xb6, 0x27, 0xda, - 0x4d, 0x4b, 0x86, 0x2c, 0x43, 0x46, 0x61, 0x5f, 0x7d, 0xe9, 0xff, 0xa9, - 0x9c, 0x74, 0xf8, 0xbc, 0x5e, 0xfe, 0x5c, 0x61, 0x31, 0xd6, 0x9e, 0x9f, - 0xc6, 0xba, 0x51, 0xf0, 0x9b, 0xeb, 0x72, 0x1e, 0xb4, 0x81, 0x8b, 0x96, - 0x9b, 0x9a, 0x2d, 0xca, 0x2e, 0xd8, 0xe9, 0x06, 0xc9, 0x6d, 0xaf, 0x93, - 0xec, 0x40, 0x52, 0x0a, 0x53, 0xbb, 0x80, 0x8d, 0x31, 0x65, 0xab, 0x85, - 0xc1, 0xa4, 0x3c, 0x36, 0xc5, 0xbe, 0x2c, 0xf6, 0x9a, 0x3a, 0x95, 0x15, - 0xee, 0xd5, 0x90, 0xec, 0xc1, 0xac, 0x3c, 0xe6, 0x65, 0x65, 0x04, 0xf2, - 0x3a, 0x0b, 0x5e, 0x1e, 0xf2, 0x5c, 0x79, 0x0e, 0xbe, 0x26, 0x7f, 0x1a, - 0x58, 0xeb, 0xae, 0x07, 0x2e, 0xa6, 0xce, 0x31, 0xc6, 0x37, 0x19, 0x87, - 0x82, 0x97, 0x7f, 0x34, 0x45, 0x5e, 0x9a, 0x32, 0x7d, 0xaf, 0x01, 0x3c, - 0x48, 0x82, 0x77, 0xae, 0xfc, 0xb1, 0x97, 0x3a, 0x9f, 0x35, 0x81, 0xc5, - 0xe9, 0xde, 0x88, 0x34, 0x24, 0x30, 0xce, 0x1f, 0x93, 0x4f, 0x47, 0x20, - 0xd7, 0x22, 0xc6, 0xa6, 0xd0, 0xcf, 0x77, 0x1d, 0xfc, 0xb2, 0x18, 0x07, - 0x5d, 0xb5, 0x53, 0xe7, 0x67, 0x4d, 0x8e, 0x4f, 0x42, 0x3e, 0x36, 0xc6, - 0x03, 0xf8, 0x6c, 0xde, 0xa7, 0x8d, 0x02, 0x69, 0xf0, 0xa8, 0x53, 0x88, - 0x49, 0xcb, 0xc4, 0xd4, 0xf6, 0x73, 0xaf, 0x0b, 0xd7, 0xf9, 0x22, 0xc6, - 0x7f, 0x88, 0x38, 0xdc, 0x96, 0x79, 0xc8, 0xe5, 0xa7, 0xe0, 0x55, 0x36, - 0xe1, 0xb7, 0x0b, 0x33, 0xa9, 0x73, 0x8b, 0x26, 0xef, 0xdd, 0xe2, 0xa8, - 0xd9, 0x23, 0xd2, 0x4c, 0x7e, 0xa5, 0xc1, 0x2b, 0xd7, 0x36, 0xcd, 0xb4, - 0xf2, 0x65, 0xbe, 0x2d, 0xdf, 0x05, 0x9a, 0xa0, 0xf3, 0xdd, 0x61, 0x9b, - 0xa0, 0xaf, 0x0d, 0x6c, 0x22, 0x95, 0x98, 0x35, 0xe1, 0x9f, 0xbb, 0x2d, - 0x39, 0xa5, 0xda, 0xe0, 0xd1, 0x60, 0x2a, 0x91, 0x35, 0x11, 0x33, 0x95, - 0xba, 0xe4, 0xac, 0xc7, 0xf1, 0x49, 0x85, 0x51, 0xfe, 0x78, 0xc4, 0x7a, - 0x1e, 0xe3, 0xc5, 0x2e, 0xd0, 0xec, 0xdb, 0xc9, 0xdc, 0xa4, 0xa3, 0x9e, - 0x9d, 0xf4, 0xfc, 0xb8, 0xd0, 0x44, 0xec, 0x38, 0x8b, 0xd8, 0x31, 0xaf, - 0x6c, 0xc6, 0xce, 0x22, 0xd7, 0x80, 0xce, 0xfb, 0xf6, 0x32, 0x5f, 0xba, - 0x4f, 0x86, 0xcf, 0x7c, 0x3f, 0x6e, 0x22, 0xce, 0x2a, 0x38, 0xa4, 0x8b, - 0xe3, 0xcf, 0x81, 0x4e, 0xf2, 0x4e, 0x86, 0x18, 0x57, 0x21, 0x16, 0x7e, - 0x84, 0x32, 0x1e, 0xed, 0x7e, 0x88, 0x7c, 0x2b, 0x82, 0xe8, 0x53, 0x3e, - 0x8e, 0x49, 0x91, 0x71, 0xe8, 0x62, 0xe4, 0x09, 0x19, 0x9a, 0xa7, 0x2f, - 0xc4, 0xcf, 0x23, 0x26, 0x02, 0xc7, 0x94, 0xcf, 0x6a, 0x87, 0x3e, 0x14, - 0xc1, 0xef, 0x8d, 0x3a, 0x0e, 0x3b, 0x08, 0xf9, 0xf6, 0x43, 0xfe, 0x19, - 0x19, 0x39, 0x33, 0x42, 0xdd, 0xee, 0x9a, 0x97, 0x54, 0xd7, 0x49, 0xd9, - 0x66, 0xcf, 0xc1, 0x06, 0xb3, 0x83, 0x95, 0x5d, 0x66, 0x86, 0xef, 0x9c, - 0xc0, 0x3b, 0xb8, 0xce, 0x8f, 0xc8, 0xd1, 0x32, 0xfb, 0x9e, 0x05, 0xdf, - 0x11, 0x17, 0xf7, 0x1c, 0xd4, 0xf6, 0x80, 0xf9, 0xac, 0x60, 0xbe, 0x11, - 0x3d, 0x1f, 0xc7, 0x71, 0x0c, 0xdf, 0x59, 0x9a, 0x77, 0x37, 0x7d, 0x22, - 0x30, 0xa8, 0xc3, 0xac, 0xec, 0x8a, 0xe2, 0xf9, 0x73, 0x3d, 0xbc, 0xc7, - 0x3c, 0xf0, 0x89, 0xb6, 0xdb, 0x8f, 0xb1, 0x83, 0x98, 0x73, 0x9d, 0xb4, - 0xb5, 0x04, 0xf4, 0x52, 0x3f, 0x18, 0xab, 0xb0, 0x3d, 0xb2, 0xc9, 0x97, - 0xd1, 0xab, 0x11, 0xdf, 0xc7, 0xcc, 0xa2, 0x4d, 0x3b, 0x3c, 0x26, 0x79, - 0x2f, 0x85, 0x7d, 0x42, 0x06, 0xe5, 0x51, 0xbd, 0x47, 0xc8, 0x69, 0xe0, - 0x29, 0xf0, 0x41, 0x8a, 0x3e, 0x6f, 0xc8, 0x17, 0xf2, 0xe4, 0x38, 0x6c, - 0xe0, 0x71, 0x8c, 0x41, 0xbc, 0xab, 0x78, 0x60, 0x6f, 0xf2, 0xe3, 0xf5, - 0x54, 0x31, 0xcb, 0xbc, 0xb3, 0x99, 0xba, 0x0d, 0xdc, 0x2a, 0x0f, 0xd8, - 0x9c, 0x7b, 0xd6, 0x64, 0x7e, 0x92, 0x4a, 0x5e, 0x88, 0xec, 0x67, 0xbb, - 0x6b, 0xd6, 0x84, 0x8c, 0x20, 0xc7, 0xdc, 0xf6, 0x76, 0x8d, 0x55, 0xef, - 0x28, 0x5d, 0xa6, 0xde, 0x17, 0xbc, 0x6d, 0xf6, 0x43, 0x42, 0x5d, 0x76, - 0xa0, 0x17, 0xc4, 0x0b, 0x5e, 0x2d, 0xf8, 0xee, 0x04, 0x74, 0x61, 0xbd, - 0xa6, 0x9d, 0xf7, 0x96, 0xcc, 0xda, 0x58, 0xc3, 0xfb, 0x8f, 0x0d, 0x7e, - 0x1f, 0xef, 0x19, 0x33, 0x05, 0x72, 0x0c, 0x68, 0xa5, 0x3c, 0x6b, 0x65, - 0xf8, 0x24, 0x68, 0x67, 0x3f, 0xae, 0xf3, 0xc7, 0x60, 0xa7, 0xc0, 0x94, - 0x9e, 0x8e, 0xc4, 0x45, 0x8c, 0xcf, 0x03, 0xf7, 0x8b, 0x16, 0x9f, 0x5d, - 0x31, 0x96, 0xde, 0x31, 0x19, 0x27, 0x23, 0x1e, 0xbf, 0x60, 0x7c, 0x0d, - 0xb1, 0x4e, 0x6e, 0xfe, 0x8a, 0x91, 0x87, 0x5e, 0xcc, 0x7b, 0x77, 0x43, - 0x9f, 0x68, 0x57, 0x36, 0xd6, 0x4e, 0x25, 0xfe, 0xc9, 0x6c, 0x4f, 0xce, - 0x01, 0x03, 0x0e, 0x81, 0xb1, 0xbe, 0x2c, 0x5d, 0x25, 0xdb, 0x45, 0x33, - 0xaa, 0xf1, 0x8f, 0xed, 0x94, 0xfd, 0xb0, 0xc0, 0x58, 0x1a, 0xf6, 0x80, - 0xcf, 0x7b, 0x64, 0xb8, 0x9c, 0x91, 0xc2, 0x99, 0x6d, 0xf6, 0x28, 0x72, - 0xf5, 0x25, 0xda, 0x89, 0x75, 0x45, 0x60, 0x1d, 0xfc, 0xb7, 0x27, 0xc5, - 0xba, 0x0c, 0x31, 0xaf, 0x03, 0xfa, 0x84, 0xbe, 0xd2, 0x92, 0x4e, 0xde, - 0xbf, 0x62, 0x3f, 0xf4, 0xdb, 0xcb, 0xf7, 0x34, 0x2f, 0xd7, 0xde, 0xd3, - 0xee, 0xea, 0x9e, 0x88, 0x31, 0xf0, 0x03, 0x1e, 0xfc, 0x00, 0x74, 0xfa, - 0x75, 0x0f, 0x7e, 0xc0, 0x83, 0x1f, 0x80, 0x3d, 0xbe, 0x02, 0x7d, 0x7c, - 0xd9, 0x83, 0x2f, 0xf0, 0xe0, 0x0b, 0x3c, 0xf8, 0x02, 0x2f, 0x07, 0xd9, - 0x11, 0xef, 0xe9, 0x4b, 0x0e, 0x54, 0xfd, 0xa7, 0x1f, 0x83, 0xdd, 0xa2, - 0xe3, 0x1a, 0xd8, 0xae, 0xbd, 0x59, 0x46, 0xbb, 0x98, 0x13, 0x35, 0xe0, - 0xda, 0x88, 0x2b, 0x62, 0x98, 0xae, 0x2f, 0x69, 0xdb, 0x79, 0x1c, 0x74, - 0x01, 0x17, 0xba, 0xbe, 0x08, 0xdd, 0x44, 0x1c, 0xe1, 0xfe, 0x86, 0x8e, - 0x7f, 0x7e, 0x64, 0xf9, 0xba, 0xd9, 0x88, 0xbe, 0xfb, 0xd0, 0xd7, 0x88, - 0x31, 0x47, 0x31, 0x86, 0xf1, 0x53, 0x93, 0xee, 0x0b, 0x8f, 0x63, 0x1c, - 0xf5, 0x00, 0xd6, 0x4a, 0x61, 0x5c, 0x13, 0xe6, 0x6e, 0xc5, 0x98, 0x9d, - 0x18, 0x73, 0x2b, 0xda, 0x8c, 0xb9, 0xb7, 0xa0, 0x7d, 0x4f, 0xcd, 0x3b, - 0xb7, 0xa3, 0xef, 0x4b, 0x35, 0x7d, 0x8b, 0xe8, 0xeb, 0x41, 0xdf, 0x45, - 0xfd, 0x5e, 0x11, 0xed, 0x96, 0x9a, 0x31, 0x97, 0xd1, 0x87, 0xb8, 0xd9, - 0xfe, 0x7b, 0x5c, 0xfb, 0x71, 0x25, 0x4d, 0xc1, 0x33, 0xc6, 0xcd, 0xc8, - 0x41, 0xab, 0xb1, 0xef, 0x5b, 0x8c, 0x0b, 0xe1, 0x7b, 0x7f, 0x6c, 0xf9, - 0x71, 0xe3, 0x77, 0x6d, 0x5f, 0x57, 0x83, 0xf6, 0x8f, 0x6a, 0xda, 0x1c, - 0xfb, 0xdf, 0x35, 0x7d, 0x3b, 0x36, 0x2e, 0x6f, 0xdf, 0x59, 0xb7, 0xf2, - 0x9d, 0x89, 0x9a, 0x31, 0x2f, 0x37, 0x2f, 0x6f, 0xff, 0xe9, 0x2a, 0xef, - 0xec, 0xd9, 0xb0, 0xbc, 0xef, 0xd1, 0x4d, 0x35, 0x63, 0xa0, 0x53, 0x0e, - 0x72, 0xab, 0x60, 0xfc, 0x03, 0x37, 0xf9, 0xcf, 0xc9, 0xdf, 0x5a, 0x5d, - 0x52, 0x5b, 0x47, 0xdb, 0x84, 0x1c, 0x2e, 0x18, 0xb0, 0x39, 0xdb, 0xcc, - 0x5c, 0x32, 0xf2, 0xd0, 0xa9, 0x5c, 0x39, 0x98, 0x8f, 0xb6, 0x5c, 0x5b, - 0xdb, 0x08, 0x6a, 0x1a, 0x8c, 0xbb, 0xe2, 0xd0, 0x9b, 0xfd, 0x90, 0x71, - 0x6a, 0xa2, 0x28, 0x4b, 0x36, 0xdc, 0x66, 0xae, 0x65, 0xc3, 0x4f, 0x6b, - 0xdc, 0x7a, 0x0a, 0x74, 0x56, 0x64, 0x20, 0x5d, 0x4f, 0xff, 0xa4, 0xf1, - 0x8c, 0x58, 0x54, 0xa9, 0x44, 0xb6, 0x56, 0xe4, 0x48, 0xfa, 0xc3, 0x8a, - 0x28, 0x1c, 0x9c, 0x50, 0x58, 0x94, 0x34, 0xdb, 0x21, 0x23, 0x1b, 0xb9, - 0x8d, 0x23, 0x43, 0x0e, 0xfd, 0xd9, 0x31, 0xc6, 0x29, 0x27, 0x7c, 0x9c, - 0x25, 0x16, 0xa1, 0x8d, 0xbc, 0xae, 0x70, 0xda, 0x50, 0x31, 0x70, 0x61, - 0x9e, 0xd8, 0x4e, 0x3c, 0x85, 0xdf, 0xb6, 0x39, 0xef, 0x6a, 0x78, 0x19, - 0x8b, 0x32, 0x3e, 0xb4, 0xdc, 0x17, 0xe0, 0x1b, 0xf9, 0x8c, 0x71, 0x04, - 0xee, 0x4b, 0xaa, 0xae, 0x56, 0x5c, 0xbe, 0x97, 0xcd, 0xcc, 0x43, 0xae, - 0x63, 0x7f, 0xab, 0x63, 0x54, 0xbb, 0x79, 0x6d, 0x7b, 0xde, 0x5b, 0xb5, - 0xe7, 0x40, 0xdf, 0x56, 0xab, 0x59, 0xbc, 0xa3, 0xf8, 0xff, 0x52, 0x39, - 0x75, 0xaa, 0x08, 0xfb, 0x59, 0x50, 0x39, 0x7a, 0x20, 0x0b, 0xc6, 0x3c, - 0xa9, 0x67, 0x66, 0xe9, 0x2d, 0x54, 0x8e, 0xc2, 0xfc, 0xa4, 0x22, 0xbb, - 0xd3, 0xff, 0xa6, 0xf6, 0x9e, 0x35, 0x3b, 0xeb, 0x18, 0x63, 0x2c, 0x78, - 0xe4, 0x53, 0x1a, 0xcf, 0x11, 0xfb, 0xa7, 0x7f, 0x26, 0x79, 0x87, 0x7d, - 0xbf, 0xac, 0xcc, 0x21, 0x36, 0x52, 0xf1, 0x92, 0x8a, 0x0f, 0x18, 0xef, - 0x1d, 0x01, 0x8f, 0xc8, 0xc7, 0x01, 0xf0, 0x36, 0x88, 0x19, 0xfe, 0x91, - 0xbe, 0x58, 0x96, 0xc7, 0xd1, 0xc8, 0xb4, 0x4a, 0x97, 0x30, 0xa7, 0x89, - 0xf9, 0xe8, 0xe3, 0xe8, 0x47, 0xd8, 0x5f, 0x88, 0x32, 0xb6, 0xf3, 0x63, - 0x83, 0x08, 0xd6, 0xb3, 0x80, 0x83, 0xef, 0x0a, 0x63, 0x9a, 0x61, 0x25, - 0x03, 0x62, 0x29, 0x9f, 0xb1, 0x2f, 0xa6, 0x63, 0xef, 0xb8, 0x8e, 0xb5, - 0x6d, 0x1d, 0x6b, 0x93, 0x0e, 0xd6, 0x2d, 0x83, 0x38, 0x82, 0x72, 0xba, - 0x70, 0xdc, 0xdc, 0xca, 0x38, 0xa2, 0x49, 0x56, 0x8f, 0x23, 0x02, 0x9a, - 0x76, 0x82, 0x26, 0xc6, 0x7d, 0xaa, 0x4e, 0xd5, 0xec, 0xd7, 0xc6, 0x48, - 0x43, 0xe0, 0x27, 0x95, 0x3f, 0x9e, 0x80, 0xeb, 0xc3, 0xde, 0x10, 0x48, - 0x02, 0xdb, 0x73, 0x93, 0x3b, 0xb5, 0xdf, 0x65, 0x0e, 0xc1, 0xf8, 0xdd, - 0xd7, 0xd3, 0x5c, 0x7a, 0x34, 0x98, 0xa7, 0x05, 0x9e, 0x32, 0x54, 0x43, - 0xe3, 0x5a, 0x8c, 0x7b, 0x82, 0x18, 0x68, 0x8f, 0x8e, 0x81, 0xfa, 0xe5, - 0x88, 0xe7, 0xe7, 0x0c, 0x03, 0xa5, 0x01, 0xf4, 0x29, 0xda, 0x13, 0x8c, - 0x35, 0x4d, 0x93, 0xb1, 0x66, 0x0a, 0xc9, 0x87, 0xbf, 0x97, 0xb6, 0xad, - 0xac, 0x65, 0x06, 0x7b, 0x69, 0xbc, 0xb0, 0x7c, 0x2f, 0xbb, 0x94, 0xde, - 0x9b, 0xe0, 0x9d, 0x8f, 0x4d, 0x9c, 0xf3, 0x7c, 0x94, 0xb8, 0x35, 0x50, - 0x1a, 0x54, 0xf3, 0x8e, 0xaf, 0x98, 0x57, 0xb0, 0xc7, 0x03, 0x6b, 0x3c, - 0xe3, 0xfe, 0x19, 0x5b, 0xd8, 0x7a, 0xff, 0x81, 0x0c, 0x2f, 0x63, 0xce, - 0x2e, 0xa3, 0xa0, 0xe2, 0xb6, 0x83, 0x4a, 0x1e, 0x85, 0xd2, 0x10, 0xae, - 0xb4, 0x17, 0x35, 0x8f, 0xb2, 0x99, 0x51, 0x25, 0x83, 0x11, 0xb5, 0xc7, - 0xb9, 0xd2, 0x23, 0x88, 0xd7, 0xbe, 0x0e, 0x3f, 0x18, 0xae, 0x2b, 0x3a, - 0x18, 0x43, 0x5e, 0x15, 0x43, 0x78, 0x4a, 0x9a, 0x59, 0x33, 0xbc, 0x82, - 0x35, 0xb8, 0xe7, 0x38, 0xe4, 0x6f, 0xf8, 0xcf, 0xd5, 0xfa, 0x01, 0xcf, - 0xeb, 0x42, 0xf4, 0x54, 0x10, 0xbf, 0x26, 0x40, 0x43, 0xf8, 0x9d, 0x63, - 0xd2, 0xe7, 0x51, 0x56, 0xed, 0x89, 0x11, 0xe4, 0xbb, 0x05, 0x09, 0x62, - 0x11, 0xae, 0x4f, 0x0c, 0xc8, 0x23, 0x97, 0x4a, 0x60, 0x7f, 0x01, 0x5f, - 0x03, 0x9e, 0xc6, 0x2f, 0xd4, 0xea, 0xc7, 0x38, 0xe8, 0x19, 0xf6, 0xc8, - 0xa7, 0x40, 0x6f, 0x83, 0xb5, 0x2f, 0xab, 0xfd, 0x8c, 0xa9, 0xda, 0xe7, - 0xfa, 0xba, 0x40, 0x7f, 0x47, 0x11, 0xb7, 0xf8, 0xfa, 0xf8, 0x7b, 0x9a, - 0x37, 0x81, 0xde, 0xc6, 0xb5, 0x0e, 0x30, 0x47, 0xa4, 0x5d, 0x05, 0x3a, - 0xd2, 0x61, 0xef, 0x57, 0xbc, 0xe0, 0x33, 0x95, 0x13, 0x2a, 0x39, 0x0f, - 0x55, 0xe5, 0xbc, 0xbe, 0x46, 0x67, 0x3b, 0x6d, 0xdf, 0x46, 0x69, 0x8b, - 0xb0, 0x69, 0xd0, 0xf7, 0xd2, 0x32, 0xdb, 0xef, 0x5a, 0xa3, 0xae, 0x1c, - 0x97, 0xc8, 0xcc, 0x0f, 0xc0, 0xcb, 0xdb, 0x91, 0xd7, 0x20, 0xcb, 0x9f, - 0x22, 0x46, 0x31, 0xfe, 0x58, 0x8a, 0x89, 0xe7, 0x64, 0xb5, 0x78, 0xf8, - 0x5a, 0xb1, 0xc7, 0x9d, 0xd7, 0x19, 0x7b, 0xfc, 0x49, 0x1d, 0xf3, 0x9c, - 0x05, 0xd8, 0xe9, 0x21, 0xbc, 0x5f, 0xe7, 0xfe, 0x10, 0x3e, 0xed, 0xaf, - 0xac, 0x7a, 0x37, 0xc0, 0x8b, 0xb8, 0x6c, 0x9c, 0xd9, 0xac, 0x30, 0xc3, - 0x9e, 0x5a, 0xc2, 0x8c, 0x51, 0xcf, 0xd7, 0x5f, 0xf0, 0xca, 0xd9, 0x28, - 0xd7, 0x9b, 0x77, 0x2f, 0xe5, 0x10, 0x43, 0xd5, 0x1c, 0xe2, 0x96, 0x1a, - 0x3e, 0xae, 0x86, 0x99, 0xe7, 0x54, 0xbe, 0xfc, 0x6a, 0x39, 0xf5, 0x82, - 0x48, 0x1f, 0xf2, 0xe4, 0xd4, 0x79, 0x91, 0x2c, 0x72, 0x65, 0xe6, 0x73, - 0x7b, 0x90, 0x3b, 0xa7, 0x7e, 0x21, 0xd2, 0x8b, 0x9c, 0x99, 0xf9, 0x70, - 0x3f, 0xf8, 0xda, 0x03, 0x4c, 0x4d, 0x03, 0x63, 0xb7, 0x83, 0xbf, 0x5d, - 0x0a, 0x57, 0x0f, 0x9d, 0x46, 0xae, 0xad, 0xea, 0xec, 0xb4, 0x75, 0x07, - 0x7e, 0xb5, 0x52, 0x79, 0x2c, 0xdd, 0x8e, 0x7c, 0x3f, 0x29, 0x5f, 0xb6, - 0x98, 0xf3, 0x1a, 0x56, 0xae, 0x7b, 0x26, 0x12, 0x8e, 0x63, 0x0b, 0xd7, - 0xf4, 0x11, 0x2b, 0x79, 0x3f, 0xac, 0xfc, 0xc4, 0x78, 0xe4, 0x6a, 0xbc, - 0xdf, 0x5f, 0xe5, 0xfd, 0x9d, 0x0d, 0xd2, 0xd0, 0xaf, 0xea, 0x0b, 0xb9, - 0xee, 0xaf, 0x13, 0xcb, 0xd2, 0xf0, 0xf3, 0xf0, 0xc7, 0x15, 0xb9, 0x3f, - 0x7d, 0xa5, 0x72, 0xd1, 0xdd, 0x20, 0x85, 0xed, 0x07, 0x34, 0x9e, 0x1f, - 0x78, 0x32, 0xe7, 0x16, 0x61, 0x1f, 0xfa, 0xdb, 0xc2, 0x64, 0x0c, 0x51, - 0x29, 0xff, 0x9a, 0x65, 0xae, 0xf7, 0xf6, 0x7a, 0x69, 0xd8, 0xf6, 0x02, - 0x8b, 0x63, 0xc4, 0x99, 0x39, 0x27, 0xae, 0xea, 0xdd, 0x37, 0xb9, 0xec, - 0xb7, 0x21, 0xd3, 0xdf, 0x92, 0x39, 0xc4, 0x13, 0xf3, 0xbd, 0xa0, 0x71, - 0x7b, 0x0b, 0xc6, 0xd3, 0xee, 0xc8, 0xf3, 0xdf, 0x96, 0xa1, 0x41, 0xf2, - 0xd4, 0xc1, 0xf8, 0xfb, 0x31, 0xa6, 0x19, 0xd7, 0x07, 0x23, 0x73, 0x76, - 0xcc, 0x6f, 0x0f, 0x70, 0x0e, 0xfa, 0x52, 0xce, 0xc3, 0xb5, 0x5a, 0x94, - 0xcd, 0x2f, 0xcd, 0xcf, 0xb9, 0xf9, 0xec, 0xe3, 0xca, 0xbe, 0xee, 0xee, - 0xd0, 0x1a, 0x4d, 0xa1, 0x35, 0x7a, 0x42, 0x6b, 0x90, 0xb6, 0xe6, 0x10, - 0x6d, 0xcd, 0x78, 0xff, 0x3e, 0xac, 0xd7, 0xaf, 0xe3, 0x94, 0x60, 0x9d, - 0x60, 0x1f, 0x2d, 0xa1, 0xb1, 0x1f, 0x62, 0x0d, 0xf6, 0x39, 0xa1, 0x3e, - 0xae, 0x0b, 0x1c, 0x73, 0xd8, 0x6e, 0x0e, 0xd1, 0x42, 0xfa, 0x1a, 0xd0, - 0xaf, 0xe6, 0x02, 0x3f, 0x1b, 0xe0, 0xbb, 0x4c, 0xf8, 0x8f, 0x08, 0xe2, - 0xaa, 0x60, 0x4f, 0xc1, 0x1c, 0x0e, 0xde, 0xe3, 0x18, 0xff, 0xb9, 0xff, - 0x0e, 0xfb, 0xf9, 0x3c, 0x22, 0xdf, 0x53, 0xf4, 0xb2, 0xcd, 0x3d, 0x34, - 0x81, 0x56, 0x5e, 0x53, 0x32, 0xdb, 0x0c, 0xd9, 0x77, 0x33, 0x9f, 0x36, - 0xe4, 0x36, 0xd7, 0x34, 0xf2, 0xdd, 0x94, 0xef, 0x06, 0x8d, 0x97, 0x0d, - 0x46, 0xee, 0x34, 0x6b, 0x08, 0x8d, 0x3a, 0xf7, 0x43, 0xbe, 0xa1, 0x7c, - 0x4c, 0xe0, 0x03, 0xe8, 0x63, 0x18, 0xab, 0xd0, 0x7f, 0x66, 0xf5, 0x3d, - 0xae, 0xd0, 0xd3, 0xc3, 0xf3, 0xcd, 0x72, 0x51, 0xf1, 0xd0, 0x96, 0xc5, - 0x2a, 0x0f, 0xa3, 0xfa, 0xbb, 0xd1, 0x31, 0xfd, 0x4d, 0x66, 0x3f, 0xe2, - 0x01, 0xdc, 0x97, 0x80, 0xb9, 0xdd, 0xd0, 0xb7, 0x6e, 0xe6, 0x70, 0x45, - 0x5c, 0x59, 0xc3, 0x30, 0x70, 0x75, 0x70, 0x8d, 0xe1, 0x0a, 0xbf, 0x04, - 0xac, 0xc9, 0x77, 0xbf, 0x0d, 0x1d, 0x82, 0x6c, 0xca, 0xb6, 0x71, 0xbf, - 0xe7, 0xd7, 0x87, 0x16, 0xdd, 0xd5, 0xeb, 0x43, 0x8b, 0xa2, 0xea, 0x43, - 0x13, 0xd7, 0xa8, 0x0f, 0x65, 0xaf, 0xbf, 0x3e, 0x74, 0xa2, 0x9e, 0x18, - 0xbc, 0xb7, 0x47, 0x8c, 0xdf, 0xd5, 0xf5, 0xa1, 0xf7, 0xc5, 0xaf, 0x0f, - 0x5d, 0x94, 0xd5, 0xeb, 0x43, 0x13, 0x35, 0xf5, 0xa1, 0x8d, 0xaa, 0x3e, - 0xc4, 0x79, 0xfc, 0xfa, 0x10, 0xdb, 0x6d, 0xdd, 0xbd, 0xa1, 0x3a, 0x08, - 0xf0, 0x54, 0xe5, 0x84, 0xb6, 0x31, 0xe8, 0x05, 0x18, 0x45, 0x2c, 0xbf, - 0xb9, 0xea, 0x8f, 0x96, 0xf0, 0xca, 0x50, 0xba, 0x75, 0x2d, 0xbc, 0x1a, - 0xf4, 0x63, 0x90, 0x65, 0x58, 0x35, 0x5e, 0x8d, 0x53, 0x5e, 0xab, 0x67, - 0xde, 0x3c, 0x56, 0x5a, 0x9a, 0x77, 0x0c, 0xb2, 0x1d, 0xaa, 0xd6, 0x50, - 0xd6, 0x8a, 0x85, 0x1c, 0x39, 0xb6, 0xea, 0x37, 0xb8, 0x44, 0x76, 0xe5, - 0x37, 0x38, 0x43, 0x1c, 0xd0, 0xd9, 0xd6, 0x5d, 0x50, 0x79, 0xd5, 0x9c, - 0xf7, 0x55, 0xb9, 0xf0, 0xb0, 0x0d, 0x3c, 0x09, 0x6a, 0x26, 0x94, 0xe5, - 0x92, 0x8f, 0x28, 0x98, 0x9f, 0x5f, 0xdd, 0xe4, 0xb0, 0xaa, 0x9b, 0xfc, - 0xbc, 0x3e, 0x5c, 0x37, 0x59, 0x94, 0xab, 0xd7, 0x4d, 0x0e, 0xaf, 0x52, - 0x37, 0x79, 0x53, 0x96, 0xea, 0x26, 0x6f, 0x4a, 0x50, 0x37, 0x89, 0xc8, - 0x85, 0x4d, 0x9c, 0xe7, 0x08, 0xde, 0x19, 0xc0, 0xaf, 0x1f, 0x3f, 0xbf, - 0x8e, 0xb2, 0x58, 0xa5, 0x7f, 0xb5, 0x3a, 0x4a, 0x7d, 0xec, 0x93, 0xd4, - 0x51, 0x7c, 0x4c, 0x0f, 0xea, 0x28, 0x0d, 0x88, 0x5f, 0xe0, 0x43, 0xcc, - 0x70, 0x1d, 0xa5, 0x15, 0xf3, 0xb2, 0x8f, 0x6d, 0xf6, 0xc3, 0x2e, 0xe0, - 0x67, 0xb2, 0xaa, 0xce, 0xf1, 0x9b, 0x9a, 0x87, 0x07, 0xb0, 0xe7, 0x24, - 0x64, 0x41, 0x3e, 0xb6, 0xab, 0x38, 0x32, 0x6b, 0x25, 0x8c, 0x5c, 0x27, - 0xbc, 0xd3, 0x24, 0xbf, 0xd9, 0x27, 0x64, 0xa4, 0x4c, 0x1d, 0x6f, 0x45, - 0xdc, 0x6d, 0xa1, 0xef, 0x00, 0xda, 0x41, 0x8c, 0xd4, 0x5d, 0x9d, 0x83, - 0x76, 0x38, 0xc7, 0x7a, 0x9f, 0x73, 0x3d, 0x3e, 0x67, 0x27, 0x68, 0x0e, - 0xef, 0xa3, 0x08, 0x7f, 0x83, 0x3e, 0x25, 0x73, 0xc6, 0x8a, 0x01, 0x2d, - 0x49, 0xda, 0xf4, 0x75, 0xcc, 0xc7, 0xbe, 0x9d, 0x2a, 0xdf, 0x1a, 0xee, - 0xe1, 0x5e, 0xe9, 0xbb, 0x16, 0x40, 0x1f, 0xfa, 0xe6, 0x99, 0xe3, 0xd1, - 0x8f, 0x05, 0x39, 0x58, 0x5c, 0xe5, 0x60, 0x2d, 0x8a, 0x1f, 0xe4, 0xf5, - 0x23, 0x31, 0xe2, 0x63, 0x8b, 0xcb, 0x3d, 0xf4, 0x6b, 0x5c, 0x63, 0xdb, - 0xcf, 0xf5, 0x58, 0x8f, 0x6e, 0x71, 0x9f, 0x80, 0x5c, 0x59, 0xab, 0x09, - 0xe4, 0xf7, 0x0d, 0xbd, 0xef, 0x5e, 0x29, 0xb6, 0x48, 0x6c, 0x23, 0xe8, - 0x69, 0x9b, 0x62, 0x8c, 0x7d, 0x8f, 0xca, 0x37, 0x1c, 0x77, 0x6d, 0xbb, - 0xdd, 0x7f, 0x03, 0x76, 0x3b, 0x70, 0x55, 0xbb, 0x3d, 0x1b, 0x0b, 0xdb, - 0xed, 0xfe, 0x1b, 0xb0, 0xdb, 0x23, 0x37, 0x64, 0xb7, 0xdc, 0x1b, 0x31, - 0x29, 0xa8, 0x8b, 0xad, 0x8c, 0x9b, 0x82, 0x75, 0x47, 0xb1, 0x66, 0x76, - 0x8d, 0x35, 0x87, 0xd6, 0xac, 0xbb, 0xd6, 0xc6, 0x4c, 0xd7, 0x23, 0x6f, - 0xe6, 0x21, 0xf4, 0xab, 0x71, 0xed, 0x83, 0x9e, 0xd6, 0x3a, 0x1f, 0xe4, - 0xed, 0x61, 0xfb, 0xa1, 0x5e, 0x50, 0x17, 0x7e, 0x02, 0x7e, 0x51, 0x1f, - 0x02, 0x9b, 0x6b, 0xaf, 0xd1, 0xc1, 0x05, 0xe4, 0xf3, 0xed, 0x5a, 0x07, - 0x29, 0xeb, 0x4e, 0xf5, 0x3d, 0x69, 0xde, 0x7b, 0xc2, 0xcf, 0xe3, 0xa1, - 0x03, 0x85, 0xf9, 0xc0, 0xd6, 0x92, 0x58, 0x37, 0x78, 0x46, 0x3e, 0xba, - 0x88, 0x61, 0xb6, 0x21, 0xfe, 0x02, 0x8f, 0x54, 0xff, 0xf2, 0x3a, 0xf0, - 0xd5, 0xf1, 0x4c, 0x8a, 0x51, 0x8c, 0x7d, 0xae, 0x07, 0x36, 0xde, 0x43, - 0x8c, 0xca, 0x20, 0x8f, 0xa1, 0x1e, 0x52, 0x37, 0x3b, 0xba, 0x0e, 0x99, - 0x8c, 0x91, 0x0e, 0xc2, 0xf6, 0x6c, 0xa5, 0xc7, 0xbb, 0xcb, 0x1d, 0xe7, - 0x16, 0x4d, 0xae, 0x51, 0xa9, 0x14, 0x54, 0xbd, 0x5e, 0xcc, 0x5c, 0xf7, - 0x4d, 0xeb, 0xe8, 0x97, 0x6e, 0x76, 0x23, 0x5a, 0xd7, 0xb2, 0xb8, 0xa7, - 0xde, 0xfe, 0x2b, 0x7c, 0x3b, 0xf2, 0x89, 0xee, 0x7f, 0x41, 0x7f, 0x02, - 0x36, 0x4f, 0x5f, 0xce, 0xfc, 0x62, 0x87, 0x1e, 0xd7, 0xae, 0xbe, 0x95, - 0xaa, 0xef, 0x2d, 0x4e, 0xe0, 0x7f, 0x52, 0xf4, 0xcf, 0xcb, 0xe4, 0xcc, - 0xb3, 0x1b, 0x79, 0x95, 0x9f, 0xf0, 0x7d, 0xa5, 0x93, 0xc8, 0x29, 0xac, - 0x50, 0x9d, 0x3d, 0xa6, 0x73, 0x31, 0xda, 0x58, 0x5c, 0xe5, 0x89, 0x7e, - 0xee, 0xc1, 0x5c, 0x75, 0xf9, 0x99, 0x8d, 0xd5, 0x75, 0x60, 0xf3, 0x27, - 0xd0, 0x81, 0x5a, 0xf9, 0xc5, 0x60, 0xfb, 0x81, 0xfc, 0x82, 0x98, 0x65, - 0x56, 0xef, 0xbb, 0xdd, 0x97, 0xe1, 0xff, 0x8b, 0x7d, 0x1a, 0xa1, 0x7d, - 0x06, 0x78, 0x74, 0x58, 0xef, 0x73, 0x47, 0x0d, 0x1e, 0x0d, 0xd4, 0xd8, - 0xec, 0xe7, 0x89, 0x47, 0x97, 0xd7, 0x7d, 0xfe, 0x78, 0xc4, 0x7d, 0x6d, - 0x59, 0x15, 0x87, 0xfc, 0x7d, 0x3c, 0x2d, 0x66, 0xe6, 0xb3, 0xcc, 0xdf, - 0x3e, 0x89, 0x7c, 0xc2, 0x38, 0x42, 0x99, 0x34, 0xa9, 0x78, 0xd5, 0xb7, - 0x3d, 0xf8, 0xf2, 0xf9, 0xa8, 0xbc, 0xf7, 0x50, 0x4c, 0x7e, 0x75, 0x2f, - 0xbf, 0x95, 0x59, 0xba, 0x7e, 0xc5, 0x76, 0xb4, 0xc1, 0xf7, 0x43, 0x48, - 0x24, 0x94, 0xdf, 0xe1, 0x3b, 0x81, 0x3d, 0xdb, 0x78, 0xce, 0x67, 0x5b, - 0xe4, 0x42, 0xf3, 0x8d, 0xe4, 0x74, 0x1d, 0xf6, 0xfb, 0xe6, 0x6a, 0x39, - 0xdd, 0xd5, 0x6b, 0x7f, 0x4b, 0x39, 0x1d, 0x71, 0xb6, 0x59, 0xd7, 0x7b, - 0x98, 0xd7, 0xec, 0xd7, 0xd8, 0xc9, 0x7b, 0xe4, 0xaa, 0x1e, 0xf2, 0x57, - 0xc8, 0xf6, 0x35, 0xc4, 0x4b, 0xaf, 0x7a, 0xc8, 0x59, 0x3d, 0xe4, 0xaa, - 0x1e, 0x72, 0x55, 0x0f, 0xb9, 0xaa, 0xd7, 0xa5, 0x73, 0xde, 0x01, 0x5d, - 0xd7, 0xe7, 0xf7, 0x70, 0xd6, 0x0b, 0x8a, 0xf0, 0x25, 0xe3, 0x3c, 0x63, - 0x61, 0xe6, 0xd2, 0xeb, 0x82, 0x73, 0x48, 0xba, 0xe6, 0xdd, 0xaa, 0x6b, - 0x30, 0x75, 0x37, 0x29, 0xdf, 0x6c, 0xbe, 0xd1, 0xe0, 0x7f, 0x33, 0xe7, - 0xf9, 0x8f, 0x3f, 0x44, 0x5c, 0xc2, 0x1a, 0xd8, 0x04, 0x6d, 0xb4, 0x62, - 0x66, 0x58, 0x63, 0x11, 0xd3, 0xcc, 0x7c, 0x01, 0xef, 0x6c, 0xc3, 0x1e, - 0xea, 0x69, 0xdb, 0x11, 0x33, 0xd3, 0x48, 0x9e, 0x1a, 0x66, 0x66, 0xbd, - 0x9e, 0xeb, 0x6f, 0x1a, 0xfc, 0xd8, 0xaa, 0x93, 0x6d, 0xcb, 0x64, 0x9c, - 0xa0, 0x62, 0xed, 0xa0, 0x7f, 0x4f, 0xf3, 0xf2, 0xb5, 0xa2, 0x0a, 0xdf, - 0x73, 0xe9, 0x87, 0x31, 0x9f, 0x3a, 0xdb, 0x54, 0xe5, 0xb7, 0xb9, 0x26, - 0xbf, 0xa3, 0x9a, 0xdf, 0x3e, 0x8f, 0x23, 0x1c, 0xa7, 0xea, 0xbe, 0xe4, - 0x75, 0x30, 0x9f, 0xaa, 0xe1, 0x61, 0x1d, 0x75, 0x8e, 0x03, 0xd7, 0xbb, - 0xa2, 0xd2, 0x34, 0x78, 0x20, 0xea, 0x86, 0xd7, 0x25, 0x46, 0xf5, 0x2e, - 0xfb, 0xfe, 0xb4, 0xf6, 0x9a, 0xed, 0xea, 0xdb, 0x99, 0xef, 0x33, 0xa2, - 0x4a, 0x07, 0x2d, 0x75, 0x36, 0xef, 0xd7, 0xea, 0xcc, 0x0d, 0xf5, 0x2f, - 0x8f, 0x3c, 0x66, 0xbc, 0xa7, 0x23, 0x69, 0x99, 0x7f, 0xd1, 0xc0, 0x5a, - 0x6b, 0x5f, 0x39, 0xc0, 0x3d, 0xae, 0x57, 0xeb, 0xc7, 0x59, 0x27, 0x0b, - 0xf0, 0x4c, 0x36, 0xfb, 0xf5, 0xb3, 0x4f, 0x63, 0x4b, 0x0d, 0x35, 0xb6, - 0x14, 0xec, 0xd3, 0xcf, 0x57, 0xf9, 0xdd, 0x7a, 0xb5, 0xb3, 0x13, 0x0b, - 0xe5, 0xd0, 0xf7, 0x8f, 0xaa, 0x6e, 0xf0, 0x5c, 0xcb, 0x83, 0xd0, 0x41, - 0xd6, 0xfe, 0xf7, 0xc0, 0x8e, 0x2a, 0x95, 0x3e, 0xd6, 0x93, 0xb7, 0x3f, - 0xa0, 0xcf, 0x27, 0x3c, 0xa3, 0xea, 0x09, 0xd6, 0x8a, 0x7a, 0x42, 0x1f, - 0x74, 0x05, 0x31, 0x00, 0x6c, 0xb0, 0xa0, 0x64, 0xc9, 0x78, 0xa0, 0xf6, - 0xfb, 0xca, 0xf9, 0x46, 0x9f, 0x0f, 0xb7, 0x37, 0xfa, 0xdf, 0x18, 0x7e, - 0xe9, 0x2c, 0x6f, 0xf3, 0xfd, 0x44, 0x63, 0x70, 0xce, 0x67, 0xf8, 0x4c, - 0x1f, 0x74, 0xb1, 0x4e, 0xf2, 0x6a, 0x3e, 0xc4, 0xbb, 0xcf, 0xff, 0xac, - 0x79, 0xf9, 0x78, 0xf4, 0x9d, 0x09, 0xc6, 0x37, 0xd7, 0x8c, 0x6f, 0xc6, - 0xf8, 0x7f, 0xaf, 0x19, 0xdf, 0x1c, 0x1a, 0xef, 0xd4, 0x8c, 0x77, 0x30, - 0xbe, 0x7e, 0xd3, 0xf2, 0xf1, 0x4e, 0x68, 0x7c, 0x4b, 0xcd, 0xf8, 0x16, - 0x8c, 0x6f, 0xa8, 0x19, 0x8f, 0xbe, 0x33, 0x75, 0xfa, 0xbb, 0x17, 0x31, - 0xf6, 0x88, 0xce, 0xbb, 0x71, 0x2d, 0xd5, 0x7e, 0x4b, 0xa1, 0xde, 0xb5, - 0x42, 0x06, 0xc1, 0x39, 0x3b, 0xda, 0x6b, 0x16, 0xf6, 0xba, 0x14, 0xcb, - 0xf8, 0xfa, 0x18, 0xd6, 0x45, 0xe2, 0x43, 0x51, 0x22, 0x2e, 0x74, 0x67, - 0x1e, 0x3a, 0x34, 0x1f, 0xf8, 0x24, 0x9e, 0x99, 0x4a, 0x75, 0xf9, 0x7a, - 0x6a, 0x48, 0xd4, 0x5d, 0xd0, 0x39, 0xd8, 0x4e, 0xd2, 0x0e, 0xbc, 0x0c, - 0x30, 0x53, 0x4e, 0xf9, 0x76, 0x43, 0xfd, 0xe5, 0xfc, 0xda, 0x7e, 0xa8, - 0xab, 0x7a, 0x9d, 0xbe, 0x15, 0xb8, 0x96, 0x5c, 0x51, 0xab, 0x8a, 0x5c, - 0x07, 0xae, 0x0d, 0x54, 0x71, 0xed, 0x41, 0x99, 0xad, 0xe6, 0xdb, 0xfd, - 0x72, 0xd4, 0xdb, 0xcb, 0xf3, 0x38, 0xa7, 0xb2, 0xf2, 0xd9, 0xe4, 0xdb, - 0x7b, 0xab, 0x7e, 0x32, 0x35, 0x91, 0x95, 0x0b, 0xc7, 0x99, 0x43, 0x05, - 0xb5, 0xd6, 0x71, 0xef, 0x5b, 0x94, 0x0b, 0x6c, 0xe3, 0x46, 0xf3, 0x6d, - 0xce, 0xe7, 0xc8, 0x51, 0xff, 0x2c, 0x44, 0x75, 0xde, 0x62, 0x75, 0xde, - 0x84, 0xb6, 0x37, 0xfa, 0xe0, 0x25, 0x7f, 0x99, 0x87, 0xbf, 0x1c, 0x42, - 0xce, 0xbd, 0xe0, 0xad, 0x56, 0xef, 0xbc, 0x51, 0x7f, 0x59, 0x5b, 0x37, - 0xae, 0xf5, 0x97, 0x5c, 0xa7, 0xb6, 0x56, 0x9c, 0xac, 0xc1, 0x7f, 0xea, - 0xd3, 0x53, 0x3a, 0xa6, 0xc6, 0x75, 0xfe, 0x29, 0xd8, 0xa3, 0x29, 0x43, - 0x4a, 0x7f, 0xd9, 0x0e, 0x72, 0xcb, 0x03, 0xd5, 0xdc, 0x72, 0x29, 0x1f, - 0x44, 0xec, 0xda, 0x75, 0x9f, 0xc6, 0x47, 0xc6, 0xc8, 0xe3, 0xe8, 0x3f, - 0x05, 0x1d, 0xe0, 0x33, 0xd6, 0x3f, 0xef, 0x90, 0x2f, 0x5b, 0xbe, 0x7f, - 0xf2, 0xeb, 0x50, 0x07, 0x54, 0xfc, 0xcf, 0xfa, 0xff, 0x70, 0x7a, 0xa3, - 0x8e, 0xf7, 0xae, 0x85, 0xab, 0xcb, 0x73, 0x53, 0xd3, 0x3c, 0x81, 0x77, - 0x99, 0x9b, 0x3e, 0x10, 0x27, 0x86, 0xe6, 0xca, 0x57, 0x7d, 0xbf, 0x48, - 0xff, 0x32, 0xac, 0xbe, 0xfb, 0xa9, 0x3c, 0x14, 0xe3, 0x16, 0xf4, 0xfb, - 0x7e, 0x1e, 0x9a, 0x2b, 0x6f, 0x89, 0xfb, 0x38, 0x78, 0xb5, 0x9c, 0xe5, - 0x58, 0x9c, 0xb5, 0xbc, 0x05, 0xef, 0x5a, 0xb4, 0xae, 0xcc, 0x7b, 0x23, - 0x2b, 0xf2, 0xde, 0x41, 0x9d, 0xd7, 0x7e, 0x45, 0xe5, 0xbd, 0x3e, 0x8f, - 0xb9, 0x97, 0x70, 0x1e, 0xe5, 0x02, 0x0b, 0xf9, 0x8d, 0x84, 0xf8, 0x30, - 0xaa, 0xfc, 0x56, 0x61, 0xf2, 0x77, 0xd4, 0xf9, 0x89, 0x95, 0x7a, 0xf3, - 0x79, 0xfb, 0x89, 0x60, 0xef, 0x4f, 0x89, 0x5f, 0xaf, 0xdb, 0x03, 0x5a, - 0x98, 0x5b, 0x45, 0xb5, 0x3e, 0xa4, 0x34, 0x5e, 0x07, 0xe3, 0x82, 0x3c, - 0xbe, 0xfa, 0x5d, 0xb5, 0x98, 0x5d, 0x56, 0x3f, 0xd9, 0x42, 0x18, 0x86, - 0xdc, 0xb3, 0x37, 0xf0, 0x1d, 0xe2, 0xd3, 0x9c, 0x7f, 0xa8, 0xf5, 0x6b, - 0xfc, 0x46, 0xda, 0xaa, 0xcf, 0xc7, 0xb9, 0xb0, 0x01, 0x9e, 0x65, 0x0e, - 0xe3, 0xab, 0x3a, 0x03, 0x17, 0x73, 0x32, 0x62, 0xec, 0x23, 0x7d, 0xe9, - 0x7f, 0xd6, 0xfb, 0x4c, 0xc8, 0x91, 0x29, 0xbf, 0xbe, 0x69, 0xae, 0x71, - 0xfe, 0xcd, 0x34, 0xaf, 0xab, 0xbe, 0x79, 0x03, 0xe7, 0xdf, 0x5e, 0x8f, - 0x07, 0xf5, 0xcd, 0xda, 0xf3, 0x6f, 0x91, 0xeb, 0x3c, 0xff, 0xe6, 0xd7, - 0x37, 0x39, 0x4f, 0xb8, 0xbe, 0x79, 0x8f, 0x3a, 0x43, 0x36, 0x3a, 0xd5, - 0xa3, 0xce, 0x23, 0xb7, 0x75, 0xaf, 0x8d, 0xb3, 0xfb, 0x3e, 0xb3, 0x7c, - 0xe4, 0x3f, 0xe3, 0xe1, 0x7c, 0x64, 0xdf, 0xe7, 0x92, 0x8f, 0x70, 0x2f, - 0xbf, 0xef, 0x7f, 0xb7, 0xad, 0x39, 0xfb, 0x95, 0xfb, 0x1c, 0x6b, 0x98, - 0x47, 0x54, 0x0d, 0x73, 0xcb, 0xfa, 0x70, 0x0d, 0xd3, 0xbc, 0xc6, 0xd9, - 0xaf, 0x23, 0xab, 0xd4, 0x30, 0xa3, 0xa1, 0xb3, 0x5f, 0x51, 0x7d, 0xf6, - 0x6b, 0xa3, 0x8b, 0xbc, 0x51, 0xd7, 0x2c, 0xcd, 0xab, 0x9e, 0xfd, 0xea, - 0x59, 0xff, 0x49, 0x6a, 0x96, 0xb9, 0x65, 0x35, 0xcb, 0x15, 0x67, 0xbf, - 0xe0, 0xd7, 0x36, 0x4b, 0x32, 0x94, 0xe3, 0xe4, 0x6e, 0xf0, 0x6c, 0x43, - 0xfe, 0x3a, 0xe2, 0x80, 0x7d, 0x55, 0x5b, 0xe5, 0xd9, 0xfd, 0x3a, 0xec, - 0x39, 0x2a, 0x7b, 0x1d, 0xea, 0x27, 0xcf, 0x38, 0x76, 0xc2, 0x16, 0x70, - 0x2d, 0xb3, 0xdd, 0x45, 0x19, 0x19, 0x03, 0x9d, 0xcb, 0xcf, 0x17, 0x2c, - 0x9d, 0xd3, 0x8d, 0x55, 0xcf, 0xe9, 0x9e, 0x84, 0xde, 0x98, 0x53, 0x31, - 0x99, 0x0b, 0xe9, 0xd4, 0x38, 0x62, 0x3b, 0x73, 0xc6, 0xd6, 0xcf, 0x93, - 0x12, 0x99, 0x72, 0x80, 0x6f, 0x3c, 0xdb, 0xdb, 0x24, 0x91, 0x19, 0xff, - 0x7b, 0xa3, 0xa9, 0xf0, 0x33, 0x81, 0x31, 0x3c, 0xdb, 0x19, 0x95, 0xa3, - 0xaa, 0x3e, 0x11, 0xe8, 0xf2, 0x37, 0xc1, 0xe3, 0x4d, 0xd9, 0xa5, 0xb6, - 0xb3, 0x8a, 0x8f, 0x47, 0xcc, 0x38, 0x45, 0x7d, 0xbe, 0x5b, 0xf2, 0xba, - 0xf6, 0x33, 0x5c, 0xde, 0xa9, 0x73, 0x09, 0xf5, 0xcd, 0x06, 0xbc, 0x6c, - 0xd3, 0xfe, 0x16, 0xd7, 0xf9, 0x36, 0xfa, 0x37, 0xc6, 0xcc, 0xd2, 0x37, - 0xb9, 0x2d, 0x31, 0x02, 0x6c, 0x1b, 0x52, 0x6b, 0xde, 0x08, 0xcf, 0x8d, - 0x15, 0xf1, 0xd7, 0x8d, 0xf1, 0x3d, 0x88, 0x85, 0xdf, 0xc4, 0xfe, 0xda, - 0xa0, 0x1f, 0x8f, 0x4b, 0xfe, 0xcc, 0x1d, 0xd2, 0x37, 0x9d, 0x02, 0x3d, - 0xbf, 0xae, 0x0c, 0xa7, 0x11, 0x37, 0x3f, 0xcf, 0x33, 0x60, 0xc0, 0x4b, - 0xf0, 0xed, 0x95, 0x15, 0xdf, 0xa0, 0xc3, 0xe7, 0xc6, 0xba, 0xaa, 0xe7, - 0x80, 0x5e, 0x2a, 0x4b, 0xac, 0x99, 0x34, 0x4f, 0x2d, 0x9d, 0x09, 0x5f, - 0x28, 0xef, 0x56, 0x7e, 0xec, 0xc5, 0xf2, 0xff, 0x52, 0x77, 0x6d, 0xb1, - 0x6d, 0x9d, 0xf7, 0xfd, 0xcf, 0x43, 0xea, 0x12, 0xdd, 0x7c, 0x24, 0xd3, - 0x32, 0x2d, 0xd1, 0xf2, 0x39, 0xd2, 0xb1, 0xc5, 0xd8, 0x5a, 0xc7, 0x6a, - 0xca, 0x26, 0xac, 0x5a, 0xc2, 0x52, 0xf4, 0x65, 0x59, 0x36, 0xd0, 0x97, - 0x76, 0x1e, 0x16, 0xa0, 0x0e, 0x65, 0x3b, 0x1d, 0xd0, 0x07, 0xb7, 0xd9, - 0x80, 0xa4, 0x03, 0x6c, 0x96, 0xb2, 0x1c, 0xaf, 0x53, 0x4d, 0x36, 0x66, - 0xd5, 0xac, 0x1b, 0x50, 0x4e, 0x92, 0x9d, 0xb4, 0x50, 0xc0, 0x64, 0xbd, - 0x60, 0xd8, 0x43, 0xad, 0xc9, 0xf6, 0xf6, 0xb2, 0x87, 0x6c, 0xd8, 0x83, - 0x81, 0x0d, 0x98, 0x63, 0x05, 0x68, 0x96, 0x02, 0x49, 0x87, 0x15, 0x43, - 0x1e, 0x36, 0x70, 0xff, 0xdf, 0x77, 0x21, 0x0f, 0x0f, 0x0f, 0x75, 0x89, - 0x9d, 0x01, 0x33, 0x60, 0x88, 0xe7, 0x9c, 0xef, 0x9c, 0xf3, 0x7d, 0xff, - 0xef, 0x7f, 0xbf, 0x9d, 0x3a, 0x3f, 0x8f, 0xd8, 0xc3, 0xdc, 0xca, 0x5b, - 0x0c, 0x8b, 0xbb, 0x42, 0x96, 0xcd, 0xe5, 0x69, 0x28, 0x48, 0xd8, 0x0f, - 0x0a, 0x30, 0x0c, 0x44, 0x6e, 0x86, 0x8c, 0xcd, 0x47, 0xc5, 0xbe, 0x4a, - 0x5e, 0x71, 0xcc, 0x95, 0x5b, 0x51, 0xdb, 0x5b, 0x99, 0x73, 0x21, 0xf7, - 0x42, 0xe6, 0x85, 0x00, 0x9e, 0xab, 0x17, 0x8f, 0x3b, 0x32, 0x2f, 0x64, - 0x64, 0x01, 0xe7, 0xfa, 0x3d, 0x72, 0xae, 0x9d, 0x71, 0x00, 0x39, 0x44, - 0xc8, 0x05, 0xc7, 0x9c, 0x85, 0x5f, 0xc3, 0x37, 0x2e, 0xbd, 0x3d, 0xff, - 0xaa, 0x7c, 0xe7, 0xb0, 0x78, 0xe7, 0x2e, 0xc5, 0xb3, 0x74, 0x0e, 0x78, - 0x3c, 0x30, 0x93, 0x1f, 0x8d, 0x04, 0x19, 0xbf, 0x67, 0xca, 0xb0, 0xa5, - 0x9b, 0xe9, 0x6b, 0x1b, 0xc1, 0x33, 0xd1, 0x00, 0xcf, 0x7a, 0x9a, 0x60, - 0xdb, 0xbb, 0xca, 0xbb, 0x25, 0xec, 0xe4, 0x79, 0xe4, 0xb7, 0xeb, 0xfc, - 0x04, 0x09, 0xbb, 0x2a, 0x0d, 0x5d, 0x73, 0xe7, 0x26, 0xd4, 0x60, 0x77, - 0xa6, 0x0a, 0xbb, 0xdd, 0xff, 0x8f, 0x60, 0x77, 0x4f, 0xe8, 0xba, 0x6f, - 0x95, 0x91, 0x83, 0xa6, 0xe5, 0xbd, 0xae, 0x5d, 0x02, 0x1c, 0xc1, 0x4f, - 0xed, 0xd2, 0x2a, 0x81, 0xa7, 0x22, 0x6f, 0xb8, 0x52, 0xf9, 0x41, 0xbc, - 0xea, 0x93, 0x64, 0x1b, 0x04, 0xb6, 0x08, 0x7c, 0x77, 0xcd, 0x65, 0xe4, - 0xf1, 0x8f, 0x25, 0x23, 0xa1, 0x17, 0x79, 0x6d, 0x91, 0x1f, 0xf5, 0xb8, - 0x6d, 0x91, 0xe3, 0xdb, 0xb4, 0x45, 0x2e, 0x48, 0x5b, 0x24, 0xbb, 0x75, - 0x5b, 0x64, 0xa0, 0x21, 0x5f, 0xab, 0xb6, 0x9e, 0xed, 0xdb, 0x22, 0xc6, - 0x86, 0xb6, 0xc8, 0x88, 0xcb, 0xef, 0x82, 0xf9, 0xfe, 0x2e, 0x65, 0x4f, - 0x80, 0xc7, 0x69, 0x38, 0x03, 0xc6, 0x27, 0x3c, 0x3e, 0xe0, 0x4f, 0x12, - 0xd6, 0xe6, 0x8e, 0xff, 0x5b, 0x58, 0x0f, 0x36, 0xf8, 0xb7, 0x6b, 0xeb, - 0xa1, 0xf0, 0xce, 0x6d, 0xe9, 0xec, 0x5e, 0x58, 0x0f, 0x36, 0xf5, 0x93, - 0x36, 0xcf, 0x45, 0xac, 0xf7, 0x93, 0x0e, 0x1b, 0xcd, 0x78, 0xfb, 0x77, - 0x5d, 0xfe, 0x53, 0x37, 0x7f, 0x07, 0x4d, 0x51, 0xe0, 0xf8, 0xa8, 0x7e, - 0x17, 0x68, 0xc9, 0xce, 0x66, 0x09, 0xf6, 0x11, 0xde, 0x17, 0x11, 0xb4, - 0xe6, 0xd1, 0xb7, 0xf8, 0x7d, 0xbc, 0xbe, 0xd7, 0x9e, 0x15, 0x72, 0x4a, - 0xfa, 0x1a, 0x30, 0x3e, 0x16, 0x38, 0x2b, 0xc6, 0xca, 0xdc, 0x24, 0xe5, - 0x7b, 0x50, 0x7a, 0x7e, 0x33, 0x9f, 0x43, 0xa3, 0xcc, 0xdb, 0x9e, 0x5d, - 0xa0, 0x69, 0x7c, 0x1f, 0xef, 0x4b, 0xa4, 0xce, 0xae, 0x02, 0xff, 0xbc, - 0xc0, 0x7a, 0xc1, 0x70, 0x55, 0x27, 0xa8, 0xdf, 0x9b, 0xcb, 0xc2, 0x7e, - 0xd3, 0xbc, 0x33, 0x2d, 0xf2, 0xdd, 0x24, 0xef, 0x84, 0x9e, 0xa6, 0x79, - 0xa7, 0x57, 0x0f, 0xde, 0xe7, 0x83, 0x17, 0xbe, 0x75, 0xa7, 0x7a, 0xef, - 0x2c, 0xe4, 0x8f, 0xa7, 0x7c, 0xf7, 0xae, 0x5a, 0x77, 0x95, 0xad, 0x8d, - 0x95, 0xf7, 0xa7, 0xc4, 0xba, 0xa2, 0x4f, 0x27, 0x51, 0x13, 0x57, 0xad, - 0x09, 0xf2, 0xd6, 0x41, 0x41, 0x0e, 0x68, 0x3a, 0xd4, 0x75, 0xe2, 0x80, - 0x45, 0xcc, 0xa7, 0x0e, 0xca, 0x2d, 0x4b, 0x70, 0x9f, 0x17, 0x16, 0x35, - 0x39, 0x32, 0xa7, 0xe4, 0xc8, 0xa2, 0x8b, 0x8f, 0x37, 0xea, 0xed, 0x7d, - 0x3e, 0x7a, 0xbb, 0xbb, 0xb6, 0x43, 0xd4, 0xb8, 0x35, 0xa9, 0xed, 0xf0, - 0xab, 0x99, 0xc2, 0xd8, 0x17, 0x59, 0x5f, 0xf9, 0x14, 0xf4, 0x15, 0x13, - 0x35, 0x4b, 0x52, 0x67, 0xc1, 0x75, 0x96, 0x49, 0xaf, 0x45, 0x18, 0xa7, - 0x8e, 0xd1, 0x79, 0xd6, 0xc9, 0x6f, 0xd2, 0xe3, 0xca, 0x66, 0x4b, 0xb8, - 0xf2, 0x4c, 0x91, 0xdf, 0x1f, 0xa0, 0xec, 0xb3, 0x76, 0x2c, 0x41, 0xc7, - 0xe8, 0x9c, 0xc8, 0x99, 0x41, 0xcc, 0x0f, 0x79, 0x08, 0x07, 0xc5, 0x3c, - 0xa5, 0x7f, 0xe3, 0x51, 0xe4, 0xcd, 0x6d, 0x3d, 0x67, 0x5f, 0xd7, 0xfa, - 0x25, 0xc5, 0x3b, 0x97, 0x15, 0xed, 0x89, 0x73, 0x7c, 0xff, 0x8b, 0x46, - 0xe3, 0xfd, 0x09, 0x23, 0x55, 0x4e, 0x19, 0xc9, 0x25, 0x8c, 0x7b, 0xd1, - 0x98, 0x2e, 0xc3, 0xd6, 0xd4, 0xb8, 0x64, 0xc7, 0x41, 0x97, 0x6b, 0xb4, - 0x79, 0x7c, 0x62, 0x91, 0x3c, 0xf5, 0x13, 0x5b, 0x98, 0xf7, 0x91, 0xba, - 0x79, 0x6b, 0xf8, 0xe2, 0x37, 0x7c, 0x40, 0x09, 0x86, 0xa9, 0xd6, 0x7f, - 0x3b, 0xe0, 0x73, 0x8f, 0x65, 0x69, 0x23, 0xfd, 0xd7, 0x6e, 0xd0, 0x7f, - 0x17, 0x37, 0x9d, 0xf7, 0xc3, 0xf2, 0x02, 0x59, 0xc3, 0x1d, 0x74, 0x84, - 0x9e, 0xcb, 0xf3, 0xae, 0xd3, 0x81, 0x3d, 0x38, 0x85, 0x31, 0xda, 0x37, - 0xae, 0x7d, 0x63, 0x3d, 0x2a, 0x1f, 0x58, 0xe7, 0x2c, 0x74, 0x28, 0x3c, - 0xc6, 0x75, 0xd8, 0x62, 0xab, 0x3c, 0x3f, 0xd8, 0x65, 0x4f, 0x8a, 0x39, - 0xb2, 0x5d, 0x66, 0x4d, 0x93, 0xf4, 0x7f, 0x9f, 0x2d, 0xd7, 0xd5, 0x8f, - 0xfa, 0xd4, 0x51, 0x0e, 0xfb, 0xd4, 0x51, 0xba, 0x69, 0x32, 0xe4, 0xa2, - 0xc9, 0x88, 0x4b, 0xbf, 0x8b, 0xb2, 0x7d, 0xd3, 0xc5, 0xbc, 0x06, 0xf6, - 0x4d, 0x07, 0x05, 0x5f, 0x71, 0xdb, 0x37, 0xde, 0xba, 0x7d, 0xd0, 0x27, - 0x74, 0x38, 0x69, 0xeb, 0xa4, 0x8a, 0xd5, 0x9a, 0x7f, 0x5e, 0x77, 0xad, - 0x66, 0x71, 0xa9, 0xa1, 0xbe, 0xd2, 0x6f, 0xbe, 0x43, 0x0d, 0xf3, 0x85, - 0x9c, 0x4b, 0x34, 0xd5, 0xfd, 0xfc, 0xec, 0xaf, 0x47, 0x35, 0x3f, 0x2f, - 0xdf, 0xc3, 0xbb, 0x86, 0x85, 0x1f, 0x3c, 0x5b, 0xe5, 0x79, 0x93, 0x72, - 0xbe, 0xf9, 0x7a, 0x7b, 0x24, 0x78, 0x8d, 0x14, 0xec, 0xfc, 0x65, 0xc0, - 0xf6, 0x7c, 0x6a, 0x9d, 0x1e, 0xf9, 0x3c, 0xd1, 0x2b, 0x7d, 0x65, 0x2d, - 0x2a, 0xd7, 0x7a, 0x97, 0xb2, 0x0b, 0x37, 0xc3, 0x77, 0x9c, 0x6b, 0x51, - 0xfe, 0x45, 0xdb, 0x2a, 0x11, 0xf0, 0xfc, 0xc4, 0xe9, 0x16, 0xc7, 0x54, - 0xf1, 0x2d, 0xc4, 0xb0, 0x80, 0xf7, 0xfa, 0xf9, 0xb2, 0xd6, 0x6a, 0xf3, - 0x3d, 0xb3, 0x1a, 0xf6, 0x4c, 0xe2, 0x15, 0x6c, 0x32, 0xe4, 0x10, 0x8f, - 0x79, 0xf2, 0xb8, 0x1f, 0x06, 0x16, 0x3d, 0x3e, 0xb9, 0xcd, 0xc8, 0x4d, - 0x6e, 0x36, 0xcf, 0xfb, 0x2e, 0xfd, 0x1d, 0xf3, 0xad, 0x54, 0xde, 0x8c, - 0x0f, 0x48, 0x99, 0x5d, 0xf6, 0xd7, 0xa5, 0xcc, 0x2d, 0xcf, 0xcf, 0x2b, - 0xa3, 0xf7, 0x6c, 0x51, 0x46, 0x8b, 0x7e, 0x28, 0x81, 0xc3, 0x82, 0x07, - 0xa0, 0x06, 0x1b, 0x39, 0xd6, 0x9f, 0x06, 0xcd, 0x33, 0x9f, 0x75, 0xd5, - 0xaa, 0xf9, 0xef, 0x63, 0x35, 0xce, 0x12, 0x42, 0x2f, 0x88, 0x09, 0xe4, - 0x9b, 0xf4, 0x31, 0xef, 0xc1, 0xf8, 0xfd, 0xd6, 0x1d, 0xf8, 0x80, 0x95, - 0x9f, 0x2a, 0xa5, 0xe4, 0xcb, 0xe1, 0x2d, 0xc4, 0x5b, 0xb6, 0xc7, 0xa7, - 0x6d, 0x6b, 0x95, 0x10, 0x0b, 0x42, 0x4e, 0xf0, 0x0b, 0x3d, 0xd4, 0x73, - 0xaa, 0xad, 0xcd, 0xb9, 0xdb, 0x2b, 0xe3, 0x53, 0xb8, 0xd6, 0x45, 0x37, - 0x8a, 0xc8, 0xd7, 0xc6, 0xb5, 0xdf, 0xe3, 0x6b, 0x7e, 0x3c, 0x4a, 0xe7, - 0x9b, 0x43, 0xe7, 0x93, 0xfb, 0x53, 0x22, 0xd8, 0x54, 0x15, 0xfa, 0xa7, - 0xf8, 0xaf, 0xc8, 0x18, 0x47, 0xf9, 0x51, 0xc7, 0x6f, 0xfc, 0xfc, 0x8a, - 0x46, 0xdf, 0xc7, 0xcd, 0x97, 0xfc, 0xf2, 0x96, 0xfc, 0x8a, 0xc8, 0xbb, - 0xdf, 0x4a, 0x1c, 0x45, 0xc7, 0x8b, 0x27, 0x44, 0xed, 0xa9, 0x1b, 0x0f, - 0x1e, 0x4d, 0xcc, 0x18, 0xf8, 0x30, 0xd4, 0xc0, 0xab, 0x1e, 0x3e, 0x06, - 0xe0, 0x85, 0x6b, 0x87, 0xaf, 0x4f, 0xcb, 0x3f, 0x36, 0x8c, 0x3c, 0x00, - 0xf8, 0xb3, 0x9f, 0xa2, 0xb3, 0xd7, 0x81, 0xc3, 0x06, 0x63, 0xdb, 0x08, - 0xcd, 0x86, 0x51, 0x57, 0x24, 0x6a, 0x73, 0x54, 0x2c, 0x51, 0xd6, 0x0a, - 0x9d, 0x15, 0x75, 0x8f, 0xfb, 0x23, 0xeb, 0x94, 0x66, 0xb9, 0x97, 0xa5, - 0x73, 0x2c, 0x63, 0xcf, 0x2d, 0xd5, 0x74, 0xfc, 0xc6, 0xda, 0xc7, 0x7a, - 0x1c, 0x5f, 0x17, 0x38, 0x1e, 0xdd, 0x10, 0xc7, 0x8f, 0x56, 0x71, 0x7c, - 0xae, 0x4f, 0xe2, 0xf3, 0x45, 0x7e, 0x56, 0x0f, 0x1d, 0x16, 0xcf, 0xcd, - 0xf2, 0xef, 0x4e, 0x3a, 0x2c, 0xfb, 0x62, 0xf0, 0xbb, 0x99, 0xc7, 0xe7, - 0xb3, 0x74, 0xfe, 0x7a, 0x36, 0x90, 0x12, 0x35, 0x0a, 0xee, 0xbe, 0x1e, - 0xfa, 0x7e, 0x8c, 0x6b, 0x86, 0xff, 0x9a, 0x2f, 0xc9, 0x9a, 0xab, 0x92, - 0xe4, 0x4f, 0xf4, 0x76, 0x7c, 0xd0, 0x83, 0xff, 0xf5, 0x36, 0xe6, 0x05, - 0x25, 0x03, 0x4f, 0x6c, 0xe0, 0xff, 0x68, 0xc4, 0xcb, 0x5e, 0x1f, 0xbd, - 0xf9, 0x8d, 0x3e, 0x19, 0xbb, 0xda, 0xc8, 0xff, 0xe1, 0xc6, 0xd1, 0xba, - 0x58, 0x3e, 0xf3, 0xfd, 0x84, 0xaa, 0xff, 0x7b, 0xa7, 0x4f, 0xca, 0x0b, - 0xd4, 0x04, 0xa6, 0x19, 0x0e, 0x6f, 0xb2, 0xae, 0x32, 0x48, 0xad, 0xaf, - 0xe8, 0xb5, 0x0e, 0x0a, 0x7e, 0xeb, 0xf6, 0xe7, 0x5c, 0x56, 0xb5, 0xe0, - 0x39, 0xd7, 0x9a, 0x2e, 0x0b, 0x5b, 0xa8, 0x39, 0xbd, 0x35, 0xcf, 0xc3, - 0x8a, 0x7a, 0x64, 0x82, 0x17, 0xdf, 0xd0, 0x2f, 0x05, 0xfb, 0x4b, 0x86, - 0xd4, 0x83, 0x27, 0x59, 0xbf, 0xdd, 0x6e, 0x0c, 0xe9, 0x61, 0x75, 0x44, - 0x6f, 0x4f, 0x0e, 0xef, 0x6f, 0xec, 0x83, 0xb4, 0x39, 0x32, 0xaf, 0x3d, - 0x25, 0x78, 0xc1, 0xe5, 0xb1, 0x0a, 0x4d, 0xc7, 0xbb, 0x29, 0x33, 0xc6, - 0xef, 0x9e, 0x44, 0x4f, 0xac, 0x20, 0x65, 0x99, 0x7e, 0x33, 0x63, 0x8f, - 0x29, 0x7d, 0x51, 0xfb, 0xdd, 0xdb, 0x54, 0xee, 0xc3, 0x45, 0x11, 0xab, - 0x94, 0xfd, 0x84, 0xf8, 0xf7, 0x92, 0x7e, 0xf6, 0x45, 0x11, 0x33, 0xcd, - 0x5c, 0x6f, 0x55, 0xe3, 0x3a, 0x5d, 0xe3, 0x30, 0xa6, 0x53, 0x8d, 0xc5, - 0x33, 0xb5, 0x4e, 0xd1, 0xae, 0xf8, 0x2d, 0xe8, 0x30, 0xad, 0x6a, 0xf5, - 0x70, 0xfd, 0x02, 0xcd, 0x54, 0xd7, 0xd2, 0xc9, 0x63, 0xff, 0x5b, 0xf5, - 0xf2, 0xe8, 0x64, 0x9d, 0x17, 0xf3, 0x6e, 0x9c, 0x13, 0xd6, 0x12, 0x14, - 0x71, 0x24, 0xfe, 0xad, 0xde, 0x73, 0xa6, 0x3a, 0x27, 0xe4, 0x6d, 0xd8, - 0x11, 0xf9, 0x2c, 0x3d, 0xae, 0xd3, 0x35, 0x4e, 0xf3, 0x0a, 0x1d, 0xa7, - 0xf8, 0x57, 0x9e, 0xc7, 0x3f, 0xa8, 0xbc, 0x5e, 0x53, 0xc4, 0x54, 0x65, - 0xde, 0x86, 0xfe, 0x0d, 0x3f, 0x34, 0xf2, 0x2c, 0x90, 0x3b, 0xe1, 0xe6, - 0x37, 0x72, 0xbd, 0x21, 0xc8, 0xa2, 0x32, 0x62, 0xa9, 0x88, 0x6b, 0x34, - 0xd3, 0x9d, 0xf7, 0x20, 0x5f, 0x7f, 0x1b, 0x3a, 0xe8, 0x56, 0xe8, 0xcf, - 0xf2, 0xa1, 0x3f, 0xf7, 0xfb, 0x51, 0xeb, 0x86, 0x9a, 0xb7, 0x6c, 0xcc, - 0xa0, 0x0a, 0xdb, 0x0a, 0x06, 0x95, 0xcc, 0x00, 0x9d, 0x77, 0xec, 0xf8, - 0x12, 0xc9, 0x9a, 0xc9, 0xe9, 0x79, 0x3b, 0xb6, 0x4a, 0x87, 0xcc, 0x73, - 0x24, 0x7b, 0x25, 0x94, 0x58, 0x06, 0x9f, 0xa1, 0x18, 0xdb, 0x47, 0x6c, - 0x7f, 0x9e, 0x42, 0x5c, 0x46, 0xef, 0x0b, 0x6a, 0xe3, 0xf1, 0x37, 0xc6, - 0x70, 0xba, 0xb9, 0x93, 0x3a, 0x12, 0xfc, 0xcc, 0x18, 0xf8, 0x13, 0x3f, - 0x27, 0x4d, 0x49, 0xb6, 0x93, 0x60, 0xb3, 0x9e, 0x39, 0x65, 0x9b, 0x25, - 0x32, 0x78, 0x2c, 0x6c, 0x57, 0x3c, 0x07, 0xf7, 0x27, 0xcc, 0x16, 0xf2, - 0xd6, 0xe1, 0x5e, 0x14, 0x75, 0x8a, 0x6f, 0xc7, 0x0f, 0x92, 0xd1, 0x0f, - 0x7e, 0x85, 0x7d, 0x1b, 0x55, 0xf1, 0xa4, 0x4b, 0xfc, 0xdb, 0x51, 0xbf, - 0xbf, 0x2a, 0xea, 0xdd, 0xe4, 0x6f, 0xe0, 0xf6, 0x2f, 0xab, 0x3d, 0xab, - 0xcb, 0x09, 0x89, 0x8c, 0x18, 0x5f, 0xa5, 0x0b, 0x4b, 0x1b, 0xf9, 0x66, - 0xfc, 0xea, 0x5b, 0xbb, 0xb6, 0x58, 0xdf, 0xba, 0xbe, 0x53, 0xd6, 0x8c, - 0xe1, 0xfd, 0x7e, 0xba, 0x97, 0x77, 0x6d, 0xee, 0x7a, 0xd5, 0xef, 0xd0, - 0xb4, 0xac, 0x35, 0x56, 0xb8, 0x70, 0xbd, 0x89, 0x7f, 0xf3, 0x49, 0x21, - 0x2f, 0xcf, 0xca, 0x38, 0xc3, 0x80, 0xec, 0x6d, 0x16, 0xa2, 0xe5, 0x6a, - 0xed, 0x67, 0x50, 0xd5, 0x7f, 0x30, 0x53, 0x7c, 0xa4, 0x75, 0x9f, 0x3a, - 0x57, 0x15, 0x71, 0xa7, 0xb4, 0x2b, 0x8f, 0x22, 0xa4, 0xf2, 0x24, 0x70, - 0xdf, 0x48, 0x18, 0x75, 0x5b, 0xb2, 0xd6, 0x12, 0x63, 0x50, 0xe7, 0x08, - 0x1b, 0x12, 0x75, 0xae, 0xf0, 0xfb, 0x35, 0xab, 0x05, 0xc5, 0x78, 0xf8, - 0x9f, 0xb4, 0x5d, 0x78, 0x5a, 0xd0, 0x98, 0x7c, 0xa7, 0xac, 0xd9, 0x5c, - 0x5c, 0x39, 0x23, 0xea, 0x24, 0x93, 0xaa, 0xf6, 0x33, 0x43, 0x5d, 0x42, - 0x6f, 0xfa, 0xf8, 0x35, 0x9b, 0xe7, 0xc2, 0xdb, 0xaf, 0xd9, 0x74, 0xdf, - 0xb3, 0xbd, 0x9a, 0x4d, 0x93, 0xd7, 0x6e, 0x2c, 0xc8, 0x9a, 0xcd, 0xfa, - 0x58, 0x80, 0xf4, 0x43, 0x65, 0x5c, 0xf2, 0x48, 0xea, 0x7f, 0x5f, 0x72, - 0xe5, 0x08, 0xcb, 0x7a, 0xcc, 0xc5, 0xaa, 0x0e, 0x24, 0xeb, 0x31, 0x65, - 0x4e, 0xb1, 0xbb, 0x0f, 0x89, 0x8c, 0x39, 0xc8, 0xf7, 0x74, 0x7b, 0x62, - 0x0e, 0x2d, 0x4c, 0xa3, 0xa3, 0xaa, 0xe6, 0xbc, 0x19, 0x6e, 0xd6, 0xd9, - 0x2a, 0x4c, 0x73, 0x15, 0xfa, 0x69, 0xfc, 0xd3, 0x74, 0x3f, 0x1c, 0x51, - 0xb9, 0x74, 0xc8, 0x9d, 0x3b, 0xa8, 0xe0, 0xa8, 0xf5, 0x0f, 0xf2, 0xd1, - 0x3f, 0x7e, 0x5b, 0xe4, 0x10, 0x4b, 0xfd, 0x65, 0x50, 0xd1, 0x24, 0xe8, - 0x36, 0xe2, 0xa2, 0xdb, 0x5d, 0x4d, 0xe8, 0x16, 0xf4, 0xf9, 0xdd, 0x1d, - 0xb2, 0x4f, 0x01, 0xe2, 0xde, 0xdf, 0x57, 0xbf, 0x37, 0xa3, 0xbf, 0xf7, - 0x78, 0x6f, 0x40, 0x83, 0x78, 0xc6, 0x87, 0xe1, 0x1a, 0x1d, 0xea, 0xdf, - 0x98, 0xcb, 0x7e, 0xd7, 0x5c, 0x86, 0x5d, 0x73, 0xd9, 0xd7, 0x64, 0x2e, - 0xac, 0x4f, 0x94, 0x2f, 0xf0, 0xff, 0x8f, 0x3b, 0x27, 0xe1, 0xab, 0x65, - 0x5a, 0x8d, 0x0b, 0xf9, 0x9a, 0x03, 0x1c, 0x85, 0x9e, 0x32, 0xaa, 0xea, - 0xe0, 0xdd, 0xf3, 0x6c, 0x66, 0xab, 0x41, 0x16, 0xa0, 0xd7, 0x41, 0x82, - 0xef, 0xeb, 0x6c, 0xd2, 0xeb, 0x00, 0x3a, 0x86, 0x5f, 0xaf, 0x03, 0x37, - 0x8f, 0x77, 0xeb, 0x52, 0xd0, 0x7d, 0x21, 0x03, 0xa1, 0xf3, 0xa2, 0x57, - 0xc1, 0x2f, 0xd1, 0x85, 0xaa, 0x8e, 0x79, 0x90, 0xd2, 0x4a, 0xc7, 0xbc, - 0xb0, 0xa4, 0xf7, 0x7c, 0xd8, 0xb3, 0xe7, 0x7e, 0x3a, 0xe7, 0x90, 0xca, - 0xf1, 0xd1, 0xb0, 0xca, 0xba, 0x60, 0x95, 0xf5, 0x81, 0x95, 0x78, 0x47, - 0x93, 0x79, 0x03, 0x3e, 0xb8, 0x07, 0xff, 0xbf, 0x13, 0x41, 0x8f, 0x16, - 0xa2, 0xdf, 0xd8, 0x55, 0xf3, 0x0b, 0xe8, 0xdf, 0x98, 0x63, 0xd3, 0xdc, - 0x4f, 0xa5, 0x0f, 0x0e, 0x06, 0x8e, 0x5c, 0x67, 0x03, 0x9d, 0x65, 0x5e, - 0xbd, 0x2d, 0xa8, 0x75, 0x85, 0x03, 0x82, 0xef, 0xdd, 0x0f, 0x22, 0x77, - 0x45, 0x9f, 0xeb, 0xd6, 0xbe, 0x5c, 0xb5, 0xfe, 0xd6, 0x3a, 0x7d, 0xa2, - 0xa6, 0x4b, 0xe8, 0x1c, 0x54, 0xfd, 0x5b, 0xcb, 0xc0, 0x7b, 0x75, 0xfe, - 0x89, 0x5b, 0x75, 0xfd, 0x06, 0xe1, 0x0b, 0xea, 0x4e, 0x1b, 0x4e, 0x4a, - 0xe4, 0x91, 0xf6, 0x3a, 0xf0, 0x7b, 0x25, 0x99, 0x37, 0xf7, 0xa6, 0x91, - 0xb3, 0xdc, 0x7b, 0xcd, 0xa2, 0x93, 0xf9, 0x2f, 0xed, 0x95, 0x74, 0x7a, - 0x89, 0x86, 0xc7, 0x79, 0xfc, 0x14, 0x7c, 0xbd, 0x76, 0x2c, 0xc9, 0x4a, - 0xe4, 0x5c, 0xb9, 0x8d, 0x16, 0x59, 0x5b, 0x0f, 0x3a, 0x25, 0xe1, 0xbb, - 0x63, 0x99, 0x51, 0x40, 0x6f, 0x55, 0x63, 0xa1, 0x95, 0x9f, 0xdb, 0x4f, - 0xcb, 0x45, 0xd0, 0x7c, 0x8b, 0xea, 0x11, 0x82, 0xb1, 0x01, 0xea, 0x73, - 0xfe, 0x84, 0xe1, 0xf5, 0x05, 0x91, 0x47, 0xb9, 0x58, 0xb8, 0x24, 0xff, - 0x96, 0x5e, 0x52, 0xef, 0xe0, 0xf7, 0x95, 0xff, 0x86, 0x12, 0x7d, 0x96, - 0xcb, 0x36, 0x73, 0xff, 0xf3, 0xd7, 0x3f, 0x8e, 0x6f, 0x4b, 0xff, 0xc8, - 0xa6, 0x6b, 0xfa, 0x87, 0xfb, 0xd9, 0x5a, 0x17, 0x39, 0xd6, 0x2f, 0xfb, - 0x37, 0x00, 0x06, 0x9d, 0xd0, 0xad, 0xd2, 0x80, 0xa5, 0x31, 0x65, 0x47, - 0x92, 0xc1, 0x49, 0x9a, 0x2d, 0x47, 0x8d, 0x4c, 0x01, 0x3a, 0x30, 0xff, - 0x2d, 0x5d, 0xd9, 0x2d, 0x7d, 0x2e, 0xfa, 0x1e, 0xf0, 0xf5, 0x9d, 0x3c, - 0xfe, 0x3f, 0xfa, 0x65, 0xee, 0xb5, 0xfb, 0x7c, 0x0f, 0x9f, 0x7f, 0x2e, - 0x52, 0x7f, 0xfe, 0x31, 0x3e, 0xdf, 0xc7, 0xe7, 0xe1, 0x87, 0x84, 0x9f, - 0x31, 0x46, 0x39, 0xde, 0x9f, 0xd9, 0x32, 0xf3, 0xa9, 0x57, 0x58, 0x5e, - 0x2c, 0xe9, 0x71, 0xbb, 0x50, 0x97, 0x23, 0xf6, 0xc4, 0xe0, 0x31, 0x97, - 0xf3, 0x63, 0x3c, 0x6e, 0x90, 0x82, 0xaf, 0x58, 0x34, 0xbb, 0xa4, 0x71, - 0x52, 0xe7, 0xd4, 0xbf, 0xc3, 0xf0, 0x45, 0xde, 0xce, 0x47, 0xbb, 0x25, - 0xfc, 0x62, 0xc2, 0x87, 0x89, 0x3c, 0x8e, 0x2b, 0x02, 0xf7, 0xec, 0x49, - 0xab, 0xfa, 0x7e, 0xe0, 0x96, 0x88, 0x73, 0xf0, 0x1a, 0x58, 0x2e, 0x4d, - 0x39, 0x66, 0xae, 0x9a, 0x8f, 0xf6, 0xe7, 0x03, 0xf2, 0xfe, 0xff, 0xda, - 0x25, 0xfb, 0xa3, 0xbe, 0x3f, 0xa0, 0xfb, 0x24, 0x4a, 0x9d, 0x00, 0x39, - 0xca, 0x01, 0x01, 0x9b, 0xe0, 0x02, 0xe4, 0x95, 0xc1, 0xbf, 0x79, 0x3d, - 0x69, 0xcc, 0xb1, 0xad, 0x5f, 0xf7, 0x7c, 0x91, 0xeb, 0x3a, 0xc6, 0xf3, - 0x4d, 0xf1, 0xba, 0xf4, 0xf9, 0x04, 0x1f, 0xfb, 0xed, 0x2f, 0x9e, 0xd5, - 0x91, 0x46, 0x5d, 0x70, 0xe6, 0x54, 0x47, 0x3a, 0x13, 0x93, 0xfb, 0x5c, - 0xf3, 0xd1, 0x46, 0xaa, 0x3e, 0xda, 0xb9, 0xfc, 0x78, 0x3f, 0xfc, 0x15, - 0xc6, 0x35, 0xde, 0xef, 0xf0, 0x15, 0x1e, 0x8b, 0x7a, 0x84, 0x1c, 0xff, - 0xed, 0x52, 0xf9, 0x3c, 0x8d, 0xb8, 0x22, 0xf3, 0x23, 0xb4, 0x5e, 0x81, - 0x7b, 0x9f, 0xe0, 0x67, 0x48, 0xdd, 0xa2, 0xf9, 0x7b, 0xa8, 0x21, 0xff, - 0xa5, 0x11, 0xc7, 0x36, 0xf2, 0xab, 0x8a, 0x38, 0xa2, 0x0f, 0x9e, 0x6d, - 0xd4, 0x83, 0xe0, 0x9e, 0xf0, 0x8b, 0x4d, 0x37, 0xd0, 0x2b, 0xe8, 0x38, - 0x44, 0x2f, 0xcc, 0x67, 0xe9, 0x31, 0xde, 0xab, 0x3f, 0x30, 0x3e, 0x83, - 0x38, 0x3b, 0xc9, 0x5c, 0x27, 0x86, 0x71, 0xde, 0x89, 0x9d, 0x33, 0x52, - 0xe0, 0x8b, 0x95, 0x90, 0xd3, 0x45, 0xad, 0x4c, 0xab, 0xbf, 0x49, 0x23, - 0x6c, 0xcf, 0x81, 0x66, 0x9d, 0x48, 0x8a, 0x40, 0x6f, 0xb6, 0x79, 0x84, - 0x71, 0x62, 0xba, 0x0c, 0x7c, 0x36, 0xe8, 0x8b, 0x45, 0xa2, 0xe7, 0x8b, - 0x23, 0xe6, 0xf7, 0xc8, 0xb1, 0x6a, 0xd7, 0x6d, 0x33, 0xc9, 0xf3, 0x48, - 0x95, 0x5f, 0xa2, 0xf7, 0x44, 0xdf, 0x12, 0xc0, 0x51, 0xef, 0xfb, 0x1f, - 0xd1, 0x99, 0x34, 0xe6, 0xbd, 0x75, 0xfa, 0x3c, 0xb9, 0x2d, 0xfa, 0xec, - 0xf0, 0xa1, 0xcf, 0x7f, 0x54, 0x78, 0x53, 0x61, 0x1c, 0xed, 0xa0, 0x99, - 0x02, 0x72, 0xbf, 0x3e, 0x8b, 0xfe, 0x52, 0x85, 0x0c, 0xf3, 0xa5, 0x4c, - 0x8d, 0x2f, 0x5d, 0x4d, 0x06, 0x13, 0xa0, 0x71, 0xf4, 0x65, 0x53, 0xf9, - 0x3e, 0x58, 0xc7, 0x00, 0x8d, 0x2c, 0x74, 0x22, 0xf6, 0xb5, 0x9a, 0x9c, - 0x48, 0xa8, 0xfa, 0x7c, 0xdb, 0x9a, 0x66, 0xfe, 0x38, 0xc7, 0xb4, 0x9c, - 0x2b, 0x1c, 0xa4, 0xc5, 0x70, 0x94, 0x86, 0x17, 0x74, 0xbf, 0x12, 0x11, - 0x37, 0x89, 0x4a, 0x9e, 0xa4, 0xd7, 0xfd, 0x84, 0xf0, 0x45, 0x58, 0x37, - 0x3f, 0xa9, 0x75, 0x77, 0x6e, 0xc2, 0x97, 0xde, 0x57, 0x34, 0x5b, 0xb9, - 0x95, 0x8c, 0x53, 0x36, 0x39, 0xf1, 0xef, 0x02, 0xff, 0x87, 0x6f, 0xc2, - 0xaf, 0x06, 0x1e, 0x6d, 0x51, 0x3a, 0xef, 0x85, 0x45, 0x94, 0xd7, 0x8d, - 0xeb, 0x95, 0x0f, 0x67, 0xe2, 0x2f, 0x09, 0xdd, 0x6b, 0xe4, 0x26, 0x8f, - 0x13, 0xf2, 0x48, 0xf3, 0x0d, 0x3f, 0x3c, 0xd4, 0x3d, 0x29, 0x35, 0x2e, - 0xca, 0x7c, 0x4e, 0x93, 0x9f, 0x9b, 0x0e, 0x7a, 0x71, 0xf2, 0x5e, 0xe0, - 0xf8, 0xbc, 0x45, 0x27, 0xf2, 0xf6, 0xab, 0x59, 0x9a, 0x64, 0xba, 0x76, - 0xcb, 0x0b, 0x1e, 0x4f, 0xc0, 0xb3, 0x29, 0xd0, 0x3e, 0x65, 0x0a, 0x96, - 0xcc, 0xb7, 0x13, 0x3d, 0xe5, 0x70, 0x8c, 0xda, 0xe2, 0xee, 0xdd, 0x5a, - 0x1e, 0x64, 0x0a, 0xa8, 0x15, 0xe4, 0xbf, 0x25, 0x1e, 0x8f, 0xfc, 0xfe, - 0x22, 0x9e, 0x03, 0x19, 0x87, 0xb9, 0xf3, 0xf1, 0xb2, 0xdc, 0xd7, 0x61, - 0x7e, 0xf6, 0xc8, 0x38, 0xbf, 0xb3, 0x3c, 0xc6, 0xfb, 0xdb, 0x23, 0x78, - 0xb3, 0xdc, 0xcf, 0x29, 0xba, 0xec, 0xcb, 0x57, 0xe4, 0xbe, 0x64, 0x5c, - 0xf4, 0x9d, 0x11, 0xf4, 0x3d, 0x25, 0xf6, 0x23, 0x53, 0x34, 0x58, 0x5f, - 0xd6, 0xbe, 0x04, 0xb6, 0x9b, 0x8b, 0x21, 0xc5, 0x43, 0x70, 0xed, 0x89, - 0xdd, 0x22, 0x1f, 0x11, 0xf6, 0x74, 0x11, 0x7f, 0xa7, 0xe8, 0x0a, 0xeb, - 0xfd, 0x2f, 0xe7, 0xdb, 0xe8, 0x4e, 0xa1, 0x8d, 0xee, 0x16, 0xa2, 0x74, - 0x7b, 0x7e, 0x07, 0x5d, 0x66, 0x9b, 0xe6, 0xb2, 0x13, 0xb2, 0x72, 0xb4, - 0x03, 0xf1, 0x42, 0xe4, 0x0a, 0x31, 0xdd, 0x61, 0x3c, 0xf4, 0xef, 0xe4, - 0x1e, 0xc6, 0x39, 0xb6, 0x8d, 0xda, 0xe9, 0x5d, 0x7e, 0x67, 0x2e, 0xaf, - 0x73, 0x1c, 0xe0, 0x63, 0xdf, 0x5f, 0xb5, 0x1f, 0x36, 0xc7, 0x11, 0x73, - 0x13, 0x1c, 0x99, 0x12, 0xbc, 0x7e, 0x76, 0x3e, 0x8a, 0xbe, 0xca, 0xd9, - 0x16, 0xf8, 0x49, 0x99, 0x3f, 0x3f, 0x17, 0xc2, 0x78, 0x9c, 0x73, 0x64, - 0x8e, 0xa4, 0x58, 0x5b, 0x84, 0x8f, 0x03, 0xa2, 0x0e, 0x5a, 0xc2, 0xa1, - 0x9d, 0xd7, 0x17, 0x10, 0xe3, 0x33, 0xcb, 0xed, 0x74, 0xb6, 0x68, 0xf2, - 0x71, 0x90, 0xf5, 0x44, 0x8c, 0xed, 0xdd, 0xa7, 0xfb, 0xcb, 0x5e, 0xe6, - 0xb9, 0xe7, 0xc4, 0x38, 0xfe, 0xbb, 0xdc, 0x43, 0xb3, 0xc5, 0x2e, 0x75, - 0x7c, 0x50, 0xe6, 0xf2, 0x8a, 0x5c, 0x6c, 0x5c, 0xdb, 0x88, 0xbf, 0xbd, - 0xcd, 0x38, 0x05, 0x99, 0x2a, 0x75, 0x7c, 0xf0, 0x9a, 0x5b, 0x0d, 0xfd, - 0x90, 0x81, 0x73, 0x93, 0xf4, 0x4d, 0x96, 0xb7, 0xc3, 0xaf, 0xc0, 0x1f, - 0xfc, 0xfb, 0xc0, 0x9b, 0x52, 0x96, 0x06, 0xf9, 0x18, 0x7d, 0x8e, 0x82, - 0xa2, 0x96, 0x69, 0x3a, 0x1c, 0x13, 0xf5, 0x1f, 0x92, 0x46, 0x4f, 0x89, - 0x9e, 0x73, 0x3f, 0x12, 0xbc, 0xc9, 0xce, 0x5a, 0x06, 0xf4, 0x11, 0xf8, - 0x54, 0x64, 0xee, 0xd5, 0x49, 0xa7, 0xf7, 0xed, 0x5d, 0x53, 0xa3, 0x94, - 0xe8, 0x07, 0xde, 0x4b, 0x9a, 0x55, 0x3d, 0x04, 0x04, 0xbf, 0x37, 0x0f, - 0xe8, 0x9a, 0x48, 0x7d, 0xac, 0x65, 0x85, 0x3e, 0xee, 0xf2, 0x5c, 0x37, - 0x3d, 0xd7, 0xab, 0x79, 0x72, 0x2c, 0xf3, 0x58, 0xce, 0x93, 0xec, 0x39, - 0x84, 0xbe, 0x71, 0xc0, 0x3f, 0xf3, 0xc0, 0x7e, 0xf3, 0x73, 0xca, 0x06, - 0xca, 0xac, 0x8c, 0x44, 0x7a, 0x8d, 0x98, 0x91, 0x19, 0xfb, 0x97, 0x4a, - 0x22, 0x0d, 0xbd, 0xe8, 0xc6, 0x6e, 0xc9, 0xe3, 0x30, 0xaf, 0x6c, 0x1c, - 0xaa, 0xdb, 0xa9, 0x95, 0x2e, 0x5a, 0x15, 0x7d, 0xb5, 0xa0, 0x63, 0xe0, - 0x7e, 0x3c, 0x27, 0x6b, 0xb6, 0xb0, 0x7d, 0x77, 0xc3, 0x01, 0x8d, 0x1f, - 0x8a, 0xdc, 0xe4, 0xfd, 0x4c, 0xad, 0x7c, 0x54, 0x39, 0x23, 0xfa, 0xd2, - 0x60, 0x6c, 0x0f, 0xcd, 0x08, 0x9b, 0x8b, 0xf5, 0x97, 0x3a, 0xbb, 0x76, - 0x12, 0xf3, 0xcc, 0x22, 0x56, 0x62, 0x38, 0xdf, 0x0e, 0x64, 0x4a, 0x32, - 0xf6, 0x9d, 0xf2, 0xc4, 0xbe, 0x4f, 0x89, 0xd8, 0x37, 0xe2, 0xde, 0x80, - 0x2b, 0x60, 0xe9, 0x97, 0xcb, 0x82, 0x7d, 0x8c, 0xf3, 0x3e, 0x5a, 0x34, - 0x77, 0x5d, 0xf0, 0x9b, 0xc9, 0xe9, 0x60, 0xa2, 0xb7, 0x85, 0xac, 0x40, - 0xd2, 0xb1, 0xe3, 0x0f, 0x58, 0x87, 0xb8, 0x5d, 0xc0, 0x3c, 0x5f, 0xa2, - 0xf5, 0x52, 0x0b, 0xd3, 0x89, 0xcd, 0x78, 0xb7, 0xca, 0x3a, 0xed, 0x2c, - 0xbd, 0x5b, 0x22, 0xba, 0x5d, 0xbc, 0x8a, 0x5e, 0xbb, 0xb1, 0x07, 0x4c, - 0x2b, 0x88, 0x05, 0x67, 0x62, 0xf0, 0xb1, 0xb1, 0x5e, 0x1b, 0x6b, 0x55, - 0xb8, 0xd9, 0xc5, 0xb6, 0xa3, 0xc9, 0xff, 0x1d, 0xfe, 0x1f, 0x89, 0x00, - 0x2e, 0x6b, 0xc5, 0x31, 0xc1, 0x4b, 0x97, 0xf8, 0xfc, 0x12, 0x9f, 0x87, - 0x4c, 0x5d, 0x2b, 0x56, 0xde, 0x49, 0xc6, 0x13, 0x56, 0x72, 0xe2, 0xa4, - 0x1c, 0xc3, 0x38, 0x77, 0xf9, 0x7a, 0x62, 0x4f, 0x88, 0xe7, 0x31, 0xc3, - 0xf3, 0x58, 0x27, 0x99, 0xeb, 0x9d, 0x12, 0xef, 0x26, 0xba, 0x23, 0xde, - 0xcb, 0x3a, 0x53, 0xfc, 0x71, 0x3a, 0x13, 0x96, 0xef, 0xcf, 0xc5, 0x51, - 0x73, 0xd5, 0x49, 0xb3, 0x63, 0xa3, 0xaa, 0xe6, 0xea, 0xcd, 0x26, 0x35, - 0x57, 0xed, 0xb4, 0x36, 0x0f, 0xbb, 0xb7, 0x9d, 0xe9, 0xdd, 0x14, 0xb9, - 0x7a, 0x6b, 0xf3, 0xa2, 0x1f, 0x3e, 0xaf, 0xa7, 0xb2, 0x3e, 0xc3, 0xaa, - 0x79, 0x26, 0xde, 0x2d, 0x74, 0xa7, 0xdb, 0xcb, 0xbf, 0xc5, 0xf3, 0x49, - 0x58, 0x99, 0x09, 0xf7, 0x3a, 0xc4, 0x7c, 0xd7, 0xa7, 0xc5, 0xb8, 0xa0, - 0x67, 0x5c, 0x82, 0x32, 0x13, 0x98, 0xbf, 0x18, 0xf3, 0x3f, 0xc9, 0xb8, - 0x5e, 0x8f, 0xfb, 0x7e, 0x8b, 0x72, 0x42, 0xdf, 0xe7, 0xbf, 0x4b, 0x3d, - 0x81, 0xf5, 0x02, 0xfc, 0x26, 0x06, 0xe3, 0x3f, 0xe6, 0x66, 0x51, 0x76, - 0x89, 0xd7, 0x75, 0xbd, 0x2b, 0xf0, 0xa0, 0xf0, 0x93, 0x4a, 0xa6, 0x2e, - 0xb7, 0xa5, 0xde, 0xbf, 0x2e, 0x6d, 0xae, 0x28, 0x39, 0xd7, 0x20, 0x4b, - 0x21, 0x47, 0xb3, 0x95, 0xa0, 0x03, 0xbd, 0x0f, 0xb6, 0xd0, 0x25, 0xe6, - 0x63, 0x32, 0x3f, 0x89, 0x79, 0x2a, 0xf3, 0x32, 0x49, 0x47, 0xa9, 0xba, - 0xcf, 0x32, 0x48, 0x5c, 0x1e, 0xae, 0xe5, 0x45, 0xba, 0xe2, 0xe6, 0x21, - 0x57, 0xdc, 0xdc, 0x74, 0xe5, 0x45, 0x86, 0x85, 0x9e, 0x56, 0xd3, 0xad, - 0xc2, 0x4a, 0xb7, 0x8a, 0x8a, 0x9e, 0xf4, 0xe0, 0x71, 0x8b, 0x55, 0x1e, - 0xb7, 0x73, 0x13, 0x1e, 0xe7, 0x67, 0x9b, 0xae, 0x2a, 0x7e, 0x62, 0xc7, - 0x21, 0x6b, 0x6e, 0x31, 0xdf, 0xf8, 0x71, 0x79, 0x82, 0xf9, 0x49, 0x9c, - 0xf9, 0xc9, 0x18, 0xf3, 0x93, 0x18, 0xf3, 0x13, 0x87, 0x61, 0x60, 0xf1, - 0xda, 0xef, 0x05, 0x6e, 0xcf, 0x43, 0x8e, 0x4c, 0xd2, 0x95, 0x32, 0x78, - 0xf3, 0x18, 0xeb, 0x42, 0xf7, 0x02, 0x6b, 0xf3, 0x3d, 0x8c, 0xc7, 0x52, - 0xff, 0xa9, 0xb7, 0x6f, 0xec, 0x57, 0x51, 0x1f, 0x97, 0x8c, 0xaf, 0x81, - 0xff, 0xbc, 0x99, 0xa5, 0xee, 0xc0, 0xed, 0x42, 0x57, 0x60, 0xad, 0xf0, - 0x13, 0xf4, 0xa5, 0x78, 0x1d, 0x34, 0x8e, 0xbe, 0xbf, 0x3f, 0x1c, 0x9d, - 0xe4, 0xb9, 0x77, 0x07, 0x66, 0x79, 0x5f, 0xbe, 0x12, 0x4f, 0xf4, 0xf6, - 0x49, 0x5a, 0xc8, 0xe6, 0xc0, 0x3d, 0x17, 0x76, 0xd0, 0xfe, 0xf1, 0xe4, - 0x9e, 0x5e, 0xa6, 0x5b, 0xe0, 0x7b, 0xad, 0xef, 0x4e, 0x90, 0xf1, 0xb0, - 0x43, 0xf5, 0xeb, 0xb1, 0x58, 0x5e, 0x7e, 0xc8, 0xf7, 0x7f, 0x10, 0xc8, - 0x15, 0x5e, 0xe3, 0x67, 0xe3, 0xf8, 0x4f, 0xe1, 0xdf, 0x64, 0x7b, 0x01, - 0xbd, 0x7e, 0x3a, 0x79, 0x0c, 0xc6, 0xe2, 0xd8, 0x8e, 0x31, 0x6f, 0x8b, - 0xaf, 0x1a, 0xf6, 0x64, 0xc2, 0x78, 0x3e, 0x8a, 0x9e, 0xf1, 0x3f, 0x2c, - 0x3f, 0x15, 0x95, 0x31, 0xb6, 0xe7, 0xf6, 0x48, 0x3e, 0xc2, 0xb8, 0x19, - 0x4e, 0x08, 0x9b, 0xad, 0xe5, 0x9a, 0x94, 0x9b, 0x8b, 0xbc, 0xbf, 0x4b, - 0xf1, 0x18, 0xef, 0x6f, 0x97, 0x92, 0x99, 0x59, 0xbe, 0x2e, 0xe4, 0x31, - 0xcb, 0x4e, 0x86, 0x77, 0x91, 0x4c, 0xd1, 0x03, 0xe2, 0x14, 0xfa, 0xea, - 0x3c, 0x83, 0xe7, 0x31, 0xb6, 0x82, 0x6f, 0x7c, 0x18, 0xc8, 0x14, 0xf0, - 0x5e, 0xe0, 0x1f, 0xff, 0x2e, 0x4d, 0xd2, 0xd5, 0xbc, 0x9e, 0xc3, 0x80, - 0x61, 0x7c, 0x13, 0xf3, 0x08, 0xd0, 0x4e, 0xe7, 0xdf, 0x18, 0x4e, 0x7c, - 0xfc, 0x97, 0xde, 0x39, 0x9d, 0x57, 0x73, 0x42, 0x9f, 0xca, 0x36, 0x5e, - 0xc3, 0x4e, 0x42, 0xff, 0xa2, 0x45, 0xd1, 0x47, 0xb2, 0x55, 0xd8, 0xaa, - 0x8b, 0xc2, 0xe6, 0x38, 0xba, 0xa7, 0xd6, 0xdb, 0xf2, 0x71, 0xcf, 0xb9, - 0x9f, 0x07, 0x72, 0xf3, 0x87, 0x85, 0x6e, 0x36, 0x3c, 0xbe, 0x47, 0xd5, - 0x9c, 0x7e, 0x5e, 0x5c, 0x33, 0x16, 0x70, 0xed, 0x49, 0x75, 0xed, 0xd7, - 0x84, 0x4e, 0x8c, 0xfc, 0xb8, 0xd0, 0x35, 0x81, 0xdf, 0xbc, 0xaf, 0x4e, - 0x8c, 0xf1, 0x3b, 0xb2, 0x04, 0xdf, 0xbc, 0x80, 0xa7, 0x86, 0x07, 0x60, - 0x01, 0x9c, 0xef, 0x52, 0xf8, 0x6e, 0x5b, 0xa9, 0xa0, 0x5e, 0x77, 0x33, - 0x38, 0xb3, 0x8e, 0x93, 0xc7, 0x5a, 0xb1, 0xa6, 0xdd, 0x81, 0x44, 0xc9, - 0x32, 0x72, 0xf3, 0xb0, 0x71, 0xe0, 0x7f, 0xdc, 0x8b, 0xbc, 0x28, 0x9e, - 0xc3, 0x6e, 0x4a, 0xa4, 0x31, 0x2f, 0x8c, 0xd3, 0x30, 0x18, 0xf7, 0xc0, - 0xc2, 0x7d, 0xdf, 0x0e, 0x75, 0x5f, 0xbb, 0xd8, 0x0b, 0x32, 0xf0, 0x1e, - 0xfd, 0x6e, 0xbc, 0x17, 0xef, 0xc7, 0x7d, 0x78, 0x9e, 0x7c, 0xee, 0x2e, - 0xe6, 0xd7, 0xc9, 0x09, 0xf9, 0x2c, 0xe3, 0xa6, 0xbc, 0xb6, 0xcb, 0xf1, - 0x9f, 0xaf, 0xdc, 0x3f, 0xdc, 0xab, 0xf7, 0x6f, 0x07, 0x95, 0x84, 0x5f, - 0x09, 0xd7, 0xba, 0xc5, 0xb5, 0xa4, 0xd3, 0x2d, 0xf6, 0x75, 0x8e, 0x8f, - 0xcf, 0x16, 0x7a, 0x02, 0xb0, 0xd5, 0x73, 0xe9, 0xee, 0x40, 0xa9, 0x84, - 0xf5, 0x76, 0x07, 0x52, 0x8c, 0xf3, 0xd3, 0x85, 0x23, 0x95, 0x59, 0xc1, - 0x5b, 0x58, 0xc7, 0xed, 0xb3, 0xcd, 0x33, 0xc6, 0xcf, 0xc4, 0x9a, 0xf8, - 0x7d, 0xfc, 0x9b, 0xe9, 0x2e, 0xcf, 0x74, 0x97, 0x67, 0xba, 0xcb, 0x33, - 0xdd, 0xb1, 0x8d, 0xfa, 0x83, 0x3c, 0xd3, 0x1d, 0xcb, 0x90, 0xb7, 0x58, - 0x86, 0x48, 0x5a, 0x4d, 0x28, 0xdf, 0x9e, 0xa6, 0x55, 0x6f, 0x4d, 0xa6, - 0xa6, 0x4d, 0xc8, 0x6d, 0x0a, 0x1c, 0x1d, 0xad, 0xa7, 0xd1, 0x3b, 0x4c, - 0xa3, 0x2d, 0x53, 0xfd, 0xf4, 0xa0, 0x88, 0x3d, 0xb3, 0xad, 0x39, 0xe6, - 0xd1, 0xa9, 0x20, 0x74, 0xac, 0x10, 0xd3, 0x13, 0x74, 0x4c, 0x9b, 0xe1, - 0xde, 0x4f, 0xeb, 0xc5, 0x76, 0x1e, 0x03, 0x9a, 0xdd, 0xab, 0x8e, 0xf3, - 0x4c, 0xb3, 0x90, 0x7b, 0xd7, 0x02, 0x77, 0x0a, 0x06, 0xeb, 0x62, 0x21, - 0x33, 0x43, 0xe0, 0x9f, 0x42, 0x3f, 0xe3, 0x7d, 0x5f, 0x65, 0x7e, 0x0f, - 0xdf, 0x29, 0x7a, 0x77, 0x95, 0x20, 0x3b, 0x22, 0xb7, 0x99, 0x7f, 0x5e, - 0x28, 0x5e, 0x63, 0x3a, 0xef, 0xa3, 0x2f, 0x17, 0x21, 0x9f, 0x01, 0x23, - 0x3e, 0x2e, 0x91, 0xf0, 0x7d, 0x19, 0x53, 0x58, 0xfb, 0xfe, 0xac, 0x21, - 0xf0, 0xe4, 0xaf, 0x01, 0x07, 0x86, 0xfd, 0xdd, 0x3d, 0xe8, 0x69, 0x9f, - 0x30, 0x5a, 0x95, 0x8f, 0x17, 0xbf, 0x31, 0x1e, 0x63, 0x01, 0x37, 0x1c, - 0x37, 0x8b, 0x2f, 0xe2, 0x1b, 0x11, 0x71, 0x86, 0x87, 0x97, 0x5f, 0x5d, - 0xe5, 0xfb, 0x05, 0xbc, 0x26, 0x93, 0x41, 0xd4, 0x87, 0xd3, 0xd7, 0x82, - 0x53, 0x93, 0xf4, 0x72, 0x19, 0xf3, 0xbe, 0x42, 0xb3, 0x61, 0xf0, 0x1f, - 0x3b, 0x7e, 0x9f, 0x24, 0xec, 0xda, 0x59, 0xdf, 0xfc, 0xa2, 0x3f, 0x4f, - 0xb3, 0x92, 0x42, 0x3f, 0x6e, 0x63, 0x7b, 0x07, 0xb0, 0x79, 0x83, 0x71, - 0x2d, 0x0e, 0x1f, 0x80, 0xe2, 0x67, 0xdf, 0x67, 0x9e, 0x83, 0x3d, 0xc3, - 0x71, 0x3d, 0x0f, 0x5b, 0x53, 0x3c, 0xcc, 0x71, 0xf1, 0xb0, 0x5c, 0x95, - 0x87, 0x31, 0x2e, 0x08, 0xde, 0x05, 0xde, 0x74, 0x82, 0xf5, 0x45, 0xf9, - 0x1b, 0x7a, 0xe0, 0x4e, 0xc1, 0xab, 0x98, 0xb7, 0xb3, 0xfd, 0xb0, 0x58, - 0xce, 0x06, 0x8e, 0x08, 0x9e, 0xa1, 0xf1, 0xf9, 0xa9, 0x01, 0x49, 0x07, - 0xed, 0xd2, 0x1f, 0x79, 0x0a, 0x7c, 0xca, 0x6f, 0xfc, 0x67, 0x78, 0x1c, - 0xc6, 0x3b, 0x91, 0xd7, 0x99, 0x7f, 0x2d, 0xc6, 0x63, 0x22, 0x06, 0x22, - 0x6d, 0x9c, 0x2c, 0xdb, 0x01, 0xbb, 0x90, 0x6b, 0x69, 0x25, 0xab, 0xfc, - 0x4b, 0xd7, 0x1f, 0xc1, 0xaf, 0x88, 0x3d, 0x4e, 0xf4, 0x1a, 0x72, 0x1d, - 0x16, 0xd6, 0x31, 0x5b, 0xa4, 0xd0, 0x4c, 0x1c, 0xb9, 0x71, 0xe0, 0xeb, - 0x1f, 0xf0, 0xba, 0xb1, 0xaf, 0x1f, 0x60, 0x5f, 0xe5, 0xb5, 0x89, 0x63, - 0x62, 0x5e, 0xb3, 0xcb, 0x35, 0xfe, 0x37, 0x97, 0x1f, 0x30, 0x16, 0x0b, - 0x72, 0x6e, 0x4b, 0xa3, 0x92, 0xc7, 0x2d, 0x96, 0xd0, 0xab, 0x4b, 0xcc, - 0x91, 0xe7, 0xa6, 0xd7, 0x85, 0xf7, 0x6a, 0x7a, 0xdf, 0x0a, 0x6d, 0x3d, - 0xc3, 0x74, 0x84, 0x3d, 0xc8, 0xba, 0x70, 0xe4, 0x5b, 0xfc, 0x7e, 0x9c, - 0x6b, 0x9c, 0xff, 0x83, 0xea, 0xfc, 0x9f, 0xe4, 0xf9, 0x63, 0xcc, 0x07, - 0x2c, 0xef, 0xe5, 0xfc, 0x1f, 0x54, 0xe7, 0x5f, 0x54, 0xf3, 0xa7, 0x9c, - 0x31, 0xd5, 0xab, 0xf4, 0xf7, 0xa6, 0xcf, 0x6a, 0x9f, 0x99, 0x10, 0x63, - 0xcd, 0x19, 0xe8, 0x44, 0xa6, 0x9e, 0x8b, 0xb6, 0x0d, 0xdd, 0x73, 0xb1, - 0x63, 0xf7, 0xe9, 0x8f, 0x49, 0xea, 0x1d, 0x43, 0xac, 0x77, 0xe0, 0x3c, - 0xcd, 0x82, 0xcf, 0xe6, 0xc2, 0xe8, 0x11, 0x3b, 0xc8, 0x30, 0x62, 0x3b, - 0x6a, 0x82, 0xff, 0x0a, 0xbf, 0x18, 0x9e, 0xa3, 0xef, 0xff, 0x43, 0x5a, - 0x9f, 0x07, 0x2f, 0x86, 0xfe, 0x29, 0xfb, 0xc8, 0xae, 0xaf, 0x48, 0xff, - 0x6b, 0xca, 0xd7, 0xff, 0x0a, 0xdf, 0xeb, 0x04, 0xf4, 0x73, 0x13, 0x7e, - 0xda, 0x69, 0xf5, 0xed, 0x8f, 0x5c, 0x19, 0xcf, 0xf2, 0xe3, 0x2b, 0x93, - 0xae, 0x1c, 0x35, 0xe4, 0x8c, 0x64, 0x99, 0x4f, 0x38, 0x66, 0x8b, 0x21, - 0x6b, 0x64, 0x6e, 0x95, 0xb5, 0xae, 0x73, 0x8c, 0xf7, 0xc4, 0x89, 0x1b, - 0x46, 0x4a, 0xf8, 0x08, 0xda, 0x9d, 0x2e, 0x6a, 0x63, 0x39, 0x78, 0x8e, - 0xd0, 0xe7, 0xcc, 0xb6, 0x10, 0x3b, 0xb9, 0xca, 0x38, 0x36, 0x1b, 0xb7, - 0x23, 0xcf, 0x0b, 0x7b, 0x12, 0xf2, 0x01, 0xdf, 0x4e, 0x01, 0xac, 0x30, - 0x07, 0xfe, 0xbd, 0x8c, 0x9e, 0x95, 0x71, 0x5e, 0x3f, 0x7c, 0xbd, 0x23, - 0xd6, 0x5d, 0x96, 0x2b, 0x57, 0x85, 0x3f, 0xe5, 0x12, 0xeb, 0x92, 0xb6, - 0x79, 0x54, 0xd0, 0x99, 0x31, 0xc4, 0x54, 0xc1, 0x74, 0x82, 0x1c, 0x81, - 0xfd, 0xa2, 0xa7, 0x8e, 0xb4, 0x51, 0x78, 0x95, 0x2b, 0xaa, 0x57, 0x41, - 0x1a, 0xb4, 0xbf, 0x75, 0x5f, 0x42, 0xfa, 0xa1, 0x7d, 0x28, 0x6e, 0x1d, - 0xca, 0xeb, 0xa7, 0x86, 0x3d, 0x66, 0x89, 0xde, 0x8c, 0x80, 0x9d, 0xf0, - 0x03, 0x1a, 0x63, 0x0c, 0x37, 0xfd, 0x9d, 0x1a, 0xb7, 0xbd, 0x7f, 0x5e, - 0xd4, 0xdc, 0xbf, 0x59, 0x96, 0x32, 0x34, 0xc7, 0xb6, 0xf8, 0xec, 0xb8, - 0x5b, 0xa7, 0xb0, 0x0b, 0xd3, 0xc2, 0x07, 0x33, 0x40, 0xc9, 0x85, 0x31, - 0xfa, 0x7c, 0x1e, 0x3c, 0x88, 0xee, 0x27, 0x1d, 0xf1, 0xcd, 0x25, 0x9e, - 0xd3, 0x18, 0xa5, 0xca, 0x80, 0x51, 0x80, 0x66, 0x99, 0xcb, 0xe7, 0x0a, - 0x88, 0xbd, 0xf3, 0xef, 0x12, 0xbe, 0xa9, 0xf2, 0x3b, 0xca, 0xb7, 0x1d, - 0xa5, 0xe9, 0x05, 0xca, 0x66, 0xe2, 0x4f, 0x8b, 0x3e, 0xd3, 0x99, 0xf8, - 0xa8, 0xf2, 0xc9, 0x44, 0xf8, 0x3c, 0xfc, 0x5c, 0x16, 0x7d, 0x2e, 0x6f, - 0x67, 0x33, 0x24, 0x7d, 0x0d, 0xc4, 0x73, 0x30, 0x58, 0x76, 0xee, 0x64, - 0x9e, 0x70, 0x52, 0xf8, 0x1b, 0x58, 0xd3, 0x98, 0xc7, 0x78, 0xf8, 0x0a, - 0xfa, 0x08, 0xf6, 0x55, 0xa6, 0xf0, 0x92, 0x1a, 0x5b, 0x21, 0x93, 0x71, - 0xc1, 0xfc, 0x55, 0x27, 0x1b, 0x37, 0x6a, 0xf7, 0xc3, 0x57, 0x71, 0x52, - 0xe8, 0x7d, 0x43, 0xb4, 0x24, 0x68, 0xbd, 0x52, 0x99, 0x11, 0x7e, 0x07, - 0x3e, 0x2e, 0x4d, 0x0e, 0x4a, 0x5e, 0x25, 0xcf, 0x4b, 0x7f, 0x04, 0x3f, - 0xb3, 0xc4, 0xf3, 0xa8, 0xcb, 0x7f, 0x8f, 0x52, 0x62, 0x1b, 0xfe, 0xa1, - 0x53, 0x8f, 0xd4, 0x3f, 0xc4, 0xb0, 0x66, 0xd9, 0x71, 0x8b, 0x69, 0xe3, - 0xc7, 0x9b, 0xda, 0x6d, 0xef, 0x69, 0x19, 0xcc, 0xb0, 0x32, 0xc5, 0xb7, - 0x2b, 0xa0, 0x33, 0xcf, 0x96, 0xe7, 0xf0, 0x1d, 0x99, 0x40, 0x5a, 0xe8, - 0xb2, 0x11, 0xd6, 0x4d, 0xa0, 0xa3, 0x8c, 0x88, 0x78, 0x62, 0xe2, 0x59, - 0xcb, 0x98, 0x5d, 0xc1, 0xb7, 0xa1, 0xa0, 0x9b, 0xe9, 0x9c, 0x86, 0x76, - 0x91, 0xa7, 0x2e, 0xe3, 0xbc, 0x90, 0xaf, 0xe0, 0x79, 0x3f, 0x0f, 0x64, - 0x56, 0x9e, 0xde, 0xa5, 0xf3, 0xd5, 0x12, 0x61, 0x9d, 0x0f, 0xa3, 0x79, - 0x8a, 0xc6, 0x3d, 0x1d, 0xa3, 0x70, 0x7f, 0xcb, 0x0b, 0xb4, 0xeb, 0xd6, - 0x09, 0xe0, 0x57, 0x12, 0x7b, 0x74, 0x15, 0xb1, 0x31, 0xa3, 0x2e, 0xfe, - 0xd0, 0xc6, 0xfb, 0x64, 0x31, 0x6e, 0xc0, 0x5f, 0xf7, 0x05, 0xfe, 0x8b, - 0x38, 0x42, 0x69, 0x10, 0x7a, 0x50, 0xaf, 0xc3, 0x38, 0x33, 0x81, 0xe3, - 0x7e, 0x5a, 0x2c, 0x6a, 0xbd, 0x55, 0xfa, 0x90, 0x16, 0x97, 0xf5, 0x7e, - 0xc1, 0x7f, 0x34, 0xac, 0x7a, 0x08, 0xd8, 0x64, 0xf5, 0x01, 0x4e, 0x9f, - 0x14, 0x3d, 0x6e, 0x16, 0x73, 0xd8, 0x4a, 0xce, 0x11, 0xbe, 0x2f, 0x86, - 0x9e, 0x99, 0xfb, 0x00, 0x7b, 0xde, 0x23, 0x77, 0x4c, 0x62, 0x4e, 0x7d, - 0xff, 0xe7, 0x51, 0xed, 0xdb, 0x63, 0x3e, 0xfb, 0xf6, 0xd1, 0xa0, 0x8c, - 0x73, 0x3d, 0xa7, 0xc6, 0xf8, 0xe5, 0x99, 0xfe, 0xf3, 0x0b, 0xf0, 0x1f, - 0xd5, 0xea, 0x25, 0xee, 0x09, 0xbe, 0xd2, 0xe8, 0xc3, 0x8e, 0x30, 0x3f, - 0x95, 0x74, 0x7c, 0xd2, 0x87, 0x8e, 0xfb, 0x78, 0x8f, 0x4f, 0x3c, 0x04, - 0x1d, 0x9f, 0x68, 0x4a, 0xc7, 0x87, 0xa2, 0xd2, 0x87, 0xda, 0x48, 0xc7, - 0xa8, 0xd9, 0x39, 0x59, 0x6e, 0xe6, 0xaf, 0xc2, 0x3e, 0xa0, 0xf6, 0x1c, - 0xfe, 0x04, 0xc0, 0x4a, 0xfb, 0x14, 0x10, 0xdb, 0x03, 0x3e, 0x22, 0x56, - 0xf2, 0x17, 0x94, 0x9a, 0xf7, 0xc6, 0x38, 0x37, 0xba, 0xe7, 0x7d, 0x9f, - 0x7b, 0xa0, 0x6b, 0x83, 0x16, 0xec, 0x88, 0xb4, 0xd5, 0x35, 0xbc, 0xde, - 0x0d, 0x1c, 0x29, 0xda, 0xd9, 0x12, 0x18, 0x63, 0x4f, 0x98, 0xce, 0x23, - 0x8e, 0xaf, 0x7c, 0xbe, 0xc7, 0xf3, 0x72, 0xdd, 0xe6, 0xb8, 0xc0, 0x07, - 0xe8, 0xa3, 0x91, 0x74, 0x30, 0xcd, 0x7b, 0x2a, 0xfd, 0xbd, 0x99, 0xe5, - 0x88, 0xda, 0x27, 0x1e, 0x8b, 0xe7, 0xf9, 0xd6, 0xf3, 0x61, 0x7f, 0xec, - 0x57, 0x57, 0xab, 0x79, 0xc1, 0x90, 0x05, 0x15, 0xfa, 0x05, 0xcb, 0xb9, - 0xe0, 0xb8, 0x29, 0xfa, 0x28, 0xdc, 0x2a, 0x8f, 0xb3, 0x7e, 0x88, 0x3d, - 0x84, 0xaf, 0x50, 0xfb, 0x72, 0x7f, 0x31, 0x44, 0x3d, 0x87, 0x58, 0xea, - 0x1b, 0xe4, 0xb0, 0x7e, 0x68, 0x8c, 0x23, 0xbf, 0xdb, 0xe2, 0x7b, 0xd0, - 0xff, 0x69, 0xbf, 0x95, 0xa2, 0x2e, 0xf8, 0x09, 0xd0, 0xa7, 0xd9, 0xca, - 0xd5, 0xd1, 0xd4, 0x69, 0x41, 0x53, 0xa9, 0x95, 0xd3, 0x8a, 0xa6, 0x4e, - 0x2b, 0x7f, 0xf9, 0x69, 0x45, 0x53, 0xa7, 0x15, 0x4d, 0x9d, 0x56, 0x34, - 0x75, 0x9a, 0xf1, 0x7a, 0xc4, 0xec, 0x13, 0x3a, 0xbb, 0xf6, 0x57, 0xf6, - 0x50, 0xa6, 0x88, 0xf3, 0x90, 0xc7, 0x5e, 0xba, 0x7a, 0x75, 0x48, 0xd2, - 0xd5, 0x24, 0x2d, 0xca, 0x3c, 0x39, 0x7e, 0x17, 0xf6, 0xe0, 0xeb, 0x83, - 0xd4, 0x73, 0x2f, 0x70, 0x76, 0x1e, 0x73, 0x0d, 0xd0, 0xb4, 0xe8, 0xe1, - 0xda, 0x42, 0x49, 0xb7, 0x2e, 0x6b, 0xa2, 0x7e, 0x4b, 0xda, 0x6a, 0xd9, - 0xa6, 0xb5, 0x5c, 0x1a, 0x2f, 0xa6, 0xd4, 0x7e, 0x79, 0xed, 0x98, 0x36, - 0x4a, 0x17, 0x00, 0x57, 0xe4, 0x32, 0x5a, 0xbc, 0x37, 0x02, 0x4e, 0x59, - 0xd3, 0x07, 0x06, 0xc7, 0x15, 0x0c, 0xbe, 0x22, 0xd6, 0x88, 0x5c, 0x40, - 0xf8, 0x1c, 0x9b, 0xc3, 0x21, 0x97, 0x1f, 0xe1, 0xe7, 0x30, 0xee, 0x8f, - 0x47, 0x98, 0x07, 0x6d, 0x1d, 0x0e, 0xb5, 0xb5, 0x37, 0xe3, 0x35, 0x5b, - 0xad, 0x87, 0xb9, 0xef, 0x92, 0x1d, 0x11, 0x25, 0x37, 0xa4, 0x9e, 0xfb, - 0x98, 0x63, 0xa7, 0xb3, 0x3c, 0xb7, 0xbf, 0x8f, 0xb7, 0xef, 0xa5, 0x8e, - 0x0a, 0x1d, 0x8b, 0x03, 0x9f, 0x7b, 0xd8, 0x6e, 0xe4, 0x39, 0xec, 0xaf, - 0xd0, 0xd5, 0xf8, 0x01, 0xb6, 0x4d, 0xf0, 0x2d, 0xa6, 0x11, 0xfe, 0xef, - 0x24, 0x82, 0x01, 0xcc, 0xab, 0x8b, 0xef, 0x0d, 0x93, 0xd1, 0x9b, 0xe8, - 0x6d, 0x57, 0xba, 0x29, 0xfc, 0x6e, 0xac, 0x9b, 0x1a, 0x33, 0xf1, 0x1d, - 0xaa, 0xa6, 0x0c, 0xbe, 0x6a, 0xc4, 0xb1, 0x7e, 0x56, 0x91, 0xbd, 0x00, - 0xa2, 0xea, 0xf8, 0xa7, 0x95, 0x44, 0x14, 0xc7, 0x26, 0xdd, 0x60, 0x7b, - 0x39, 0x11, 0x18, 0xd9, 0x2b, 0x74, 0xf6, 0x80, 0x7d, 0x4c, 0xe6, 0x30, - 0xd8, 0xa6, 0x15, 0xf0, 0xc3, 0x77, 0xa9, 0xeb, 0xd4, 0xf2, 0x4c, 0x81, - 0xff, 0x15, 0xfa, 0x4f, 0xa6, 0x55, 0x93, 0x10, 0xb3, 0x98, 0x14, 0xb5, - 0xce, 0xc8, 0x33, 0x3e, 0x3b, 0x0f, 0x9a, 0x85, 0xdf, 0xd0, 0x51, 0x7b, - 0xfc, 0x29, 0xe4, 0x89, 0x15, 0x16, 0x69, 0x63, 0x59, 0x01, 0xbf, 0xd8, - 0xc8, 0xc2, 0x5a, 0x6f, 0x58, 0xd4, 0x5e, 0xc3, 0xcf, 0xa9, 0xf3, 0x89, - 0xf7, 0xf3, 0xf3, 0x43, 0xe2, 0xdb, 0x72, 0xd3, 0xd7, 0x30, 0xae, 0x95, - 0x86, 0x17, 0x2a, 0x4f, 0xf1, 0x75, 0x11, 0x2f, 0xcc, 0x50, 0xbb, 0x8a, - 0x05, 0x74, 0xa9, 0xf8, 0x51, 0x84, 0x69, 0xa8, 0x56, 0x53, 0x3c, 0x5c, - 0xf5, 0x9d, 0x01, 0xb7, 0xbd, 0xbe, 0xb3, 0xaf, 0x6d, 0x22, 0x67, 0x36, - 0xc3, 0x67, 0xe4, 0x82, 0xb6, 0x91, 0xf2, 0x09, 0x5a, 0xb3, 0xb4, 0xd5, - 0xda, 0xb9, 0x6d, 0xdf, 0xd3, 0xde, 0x3a, 0xb5, 0x7a, 0xf1, 0xae, 0xd3, - 0xa1, 0xf0, 0xa8, 0x95, 0xce, 0x16, 0x3b, 0x58, 0x56, 0xa3, 0xce, 0x09, - 0xf0, 0x0a, 0x46, 0x51, 0x27, 0xf2, 0x5c, 0xa8, 0x95, 0x96, 0x97, 0x91, - 0xd3, 0xf0, 0x67, 0x7b, 0x65, 0x7e, 0x6e, 0x9a, 0xe1, 0x72, 0x88, 0xe5, - 0x9a, 0xa1, 0x62, 0x35, 0x38, 0x07, 0x9e, 0x20, 0x7a, 0x78, 0x86, 0x9e, - 0x1e, 0xed, 0x60, 0x7d, 0x5e, 0xfa, 0xfa, 0x0f, 0xf3, 0xb3, 0xbf, 0x57, - 0x4c, 0xc3, 0x4f, 0x65, 0x1e, 0xe5, 0xe7, 0x4f, 0xb3, 0x1e, 0x90, 0xa0, - 0x56, 0x5a, 0x5a, 0x6e, 0x65, 0x7d, 0xbe, 0x95, 0xf5, 0x80, 0x11, 0x73, - 0x38, 0x20, 0xde, 0x25, 0x6a, 0x52, 0x3e, 0x1b, 0x3a, 0x64, 0x1e, 0x13, - 0x79, 0x36, 0x7f, 0xa5, 0xde, 0xe5, 0x7d, 0xc7, 0x07, 0x15, 0x1c, 0x1f, - 0x0d, 0xae, 0x5e, 0xbc, 0xe3, 0x98, 0x8c, 0x7f, 0x93, 0xac, 0xf3, 0x86, - 0xc5, 0xf7, 0x17, 0x8d, 0xa9, 0x29, 0xd6, 0xff, 0xf1, 0x8d, 0xb7, 0x67, - 0x28, 0x5b, 0x3e, 0x45, 0x5f, 0x2f, 0xbb, 0x7d, 0xaf, 0xcf, 0xf0, 0x9c, - 0x65, 0xed, 0x7c, 0x1b, 0xcf, 0xeb, 0x3d, 0xc7, 0xcb, 0x2b, 0x3a, 0x28, - 0xf8, 0xad, 0x30, 0xb5, 0x7e, 0x03, 0x3e, 0x8f, 0x0a, 0x15, 0xe2, 0xf6, - 0xd5, 0xfb, 0x24, 0xfd, 0xbc, 0x37, 0x44, 0x5e, 0x2a, 0xdf, 0xcf, 0xcf, - 0x9c, 0xc3, 0xb8, 0x1b, 0x16, 0xdd, 0x76, 0x24, 0xbc, 0xff, 0x36, 0x14, - 0xa6, 0xe0, 0x1b, 0xc8, 0xf5, 0x82, 0x8e, 0xb5, 0x7a, 0xd1, 0x39, 0xc0, - 0x7c, 0xfa, 0x1b, 0xb8, 0x8f, 0xff, 0xbe, 0x81, 0xe3, 0x0e, 0x5e, 0x27, - 0xe4, 0x2c, 0x72, 0x4a, 0xc0, 0xdf, 0x0e, 0x45, 0x4c, 0x81, 0x7f, 0xcf, - 0x30, 0x4e, 0xb5, 0x08, 0x1f, 0x5f, 0x1f, 0xc6, 0x3a, 0x83, 0xac, 0x13, - 0xac, 0x5e, 0x1c, 0x3d, 0x80, 0xe3, 0x44, 0x6f, 0x90, 0x61, 0x24, 0x71, - 0xa8, 0xe1, 0x9b, 0x75, 0xa1, 0xc3, 0xa3, 0xe4, 0xfa, 0x6e, 0x1d, 0x7a, - 0x26, 0x75, 0x50, 0x8a, 0xdf, 0x31, 0x5d, 0x94, 0xeb, 0x9e, 0x2b, 0x07, - 0x49, 0xfa, 0x87, 0x52, 0x43, 0xfa, 0xfb, 0x84, 0xd4, 0x8f, 0x67, 0x6b, - 0x5a, 0xc1, 0xef, 0x1e, 0x7a, 0x50, 0xec, 0xa2, 0x75, 0x15, 0x43, 0x7a, - 0x20, 0xec, 0x29, 0xe6, 0xc5, 0xe9, 0x1e, 0xba, 0xbf, 0xdc, 0x42, 0xd4, - 0xd7, 0x21, 0x62, 0xbc, 0x0f, 0x8a, 0x8b, 0x94, 0x7c, 0xed, 0xc9, 0x21, - 0xe9, 0x4f, 0xa9, 0xe1, 0xc8, 0x03, 0x1f, 0x1c, 0x79, 0x57, 0xe0, 0xc8, - 0xf0, 0xd0, 0xc6, 0x38, 0xb2, 0x47, 0xe7, 0x22, 0x52, 0xab, 0xc2, 0x8f, - 0xd7, 0x19, 0x3f, 0x5e, 0x66, 0xfc, 0x38, 0xd2, 0x04, 0x3f, 0x0c, 0x0f, - 0x7e, 0x1c, 0x15, 0xf8, 0xf1, 0xeb, 0x43, 0x1b, 0xe1, 0xc7, 0x91, 0xe0, - 0x46, 0x3e, 0x1e, 0x8d, 0x9b, 0x03, 0xb4, 0x54, 0x74, 0x68, 0x79, 0xde, - 0x8e, 0x27, 0x68, 0x35, 0x22, 0x63, 0x83, 0x53, 0xa2, 0x4e, 0x65, 0x51, - 0xe0, 0x55, 0x5a, 0xf8, 0x2f, 0xfd, 0xbf, 0x1b, 0x68, 0x29, 0xf8, 0xcb, - 0x3d, 0x99, 0xce, 0xaf, 0x5e, 0xfc, 0x3b, 0xde, 0xc7, 0xdb, 0x2b, 0xa1, - 0x10, 0xae, 0x05, 0xa7, 0xc2, 0xb4, 0xb6, 0x82, 0xef, 0x12, 0x46, 0xe8, - 0x4e, 0x31, 0x4a, 0xb7, 0x8b, 0x03, 0xb4, 0x56, 0x1c, 0xa2, 0xbb, 0x45, - 0xbc, 0x03, 0x30, 0xe7, 0x63, 0x01, 0x73, 0x83, 0x0e, 0x87, 0x79, 0xcc, - 0xf2, 0x00, 0xad, 0x2e, 0x6b, 0x7c, 0x05, 0xae, 0x62, 0xff, 0xe1, 0x27, - 0xf0, 0xc7, 0x81, 0xe9, 0x3a, 0x1c, 0x90, 0xf7, 0x60, 0xef, 0x67, 0x1b, - 0x6b, 0x64, 0x45, 0x9e, 0xa5, 0xc9, 0x38, 0xd2, 0x32, 0x65, 0x0b, 0x5f, - 0xea, 0xe1, 0x20, 0x74, 0xd9, 0xc4, 0x3e, 0xea, 0xe1, 0x3d, 0x70, 0x90, - 0x27, 0x34, 0xc4, 0x7a, 0xe9, 0x0e, 0xa1, 0x87, 0x26, 0x9d, 0x50, 0x64, - 0x9a, 0x2a, 0x97, 0x0c, 0x07, 0x3d, 0x0f, 0xd3, 0xfc, 0x3c, 0x43, 0xf9, - 0x71, 0xba, 0x5d, 0xf8, 0xe4, 0xd5, 0x39, 0x11, 0x8b, 0x7d, 0x96, 0xe7, - 0x0c, 0xf9, 0x58, 0x8b, 0x73, 0x50, 0x35, 0xce, 0xd1, 0xce, 0xeb, 0x96, - 0xb4, 0x34, 0xe3, 0xf0, 0xb8, 0x32, 0x8f, 0x2b, 0x23, 0x76, 0xc6, 0xe7, - 0x97, 0x11, 0xb7, 0x8d, 0xd2, 0xda, 0x3c, 0x68, 0x0e, 0x7e, 0x89, 0x5a, - 0xac, 0x74, 0x6d, 0x05, 0xe7, 0xe1, 0x9b, 0xa8, 0xc5, 0x4a, 0xd7, 0x54, - 0xac, 0x74, 0x6d, 0x65, 0x4a, 0xf0, 0xe1, 0xd9, 0xff, 0xdd, 0x14, 0x60, - 0x19, 0x30, 0x85, 0x19, 0xba, 0x4e, 0x53, 0x0d, 0x7a, 0xbf, 0x4e, 0x0c, - 0x78, 0x6c, 0x58, 0x50, 0x05, 0x7f, 0x18, 0xba, 0x62, 0x84, 0xa1, 0x0d, - 0xb8, 0xfd, 0xe3, 0x02, 0x34, 0xd3, 0x79, 0x4a, 0x0c, 0x30, 0x3c, 0x23, - 0x80, 0x79, 0x49, 0x18, 0x9a, 0x97, 0x60, 0x73, 0xaf, 0xfc, 0x0c, 0x90, - 0xbb, 0x7a, 0x6c, 0xc0, 0x6d, 0x7c, 0x48, 0xf9, 0x23, 0x83, 0x56, 0xfe, - 0x30, 0xb0, 0x38, 0xa9, 0x43, 0xf4, 0x37, 0xad, 0x7f, 0x2c, 0x07, 0x1b, - 0x5f, 0x6b, 0x02, 0x9a, 0xdb, 0x3c, 0x85, 0x94, 0xb9, 0x5b, 0x60, 0xbd, - 0x89, 0x75, 0x5d, 0x26, 0xb1, 0x76, 0xc3, 0xd2, 0x42, 0x0c, 0x19, 0xe9, - 0x09, 0x62, 0x06, 0x22, 0x3d, 0xd9, 0x00, 0xcb, 0x4e, 0x16, 0x60, 0x5e, - 0x11, 0x02, 0xd6, 0x0f, 0x0c, 0xd0, 0x3a, 0xe6, 0x00, 0x78, 0x2c, 0xa1, - 0x89, 0x01, 0x74, 0x07, 0x27, 0xd0, 0xfe, 0x7e, 0x65, 0xf0, 0xba, 0xe3, - 0x06, 0x09, 0x88, 0xa1, 0x8b, 0x7a, 0x14, 0xe5, 0x41, 0x79, 0xd4, 0x49, - 0x85, 0x81, 0xc4, 0xfc, 0x04, 0xf2, 0x1f, 0xd0, 0x1f, 0x20, 0x3f, 0x02, - 0xf3, 0x93, 0x33, 0x50, 0x0e, 0xb4, 0x36, 0xaa, 0x79, 0x0d, 0x48, 0x1f, - 0x28, 0x0c, 0x41, 0x65, 0x2a, 0x68, 0x8c, 0x03, 0xc8, 0x5e, 0x22, 0x04, - 0x0d, 0x3b, 0x20, 0x0d, 0x64, 0x37, 0x4f, 0x11, 0x01, 0xf3, 0x93, 0x02, - 0x84, 0x18, 0x1a, 0xe0, 0xf9, 0x89, 0x1d, 0xe8, 0x52, 0x98, 0x9b, 0xfe, - 0xff, 0x3f, 0xa6, 0xc2, 0x02, 0x4c, 0x7b, 0xa0, 0xb5, 0xb5, 0xbf, 0xff, - 0x1f, 0x10, 0x61, 0x61, 0x68, 0x81, 0xaf, 0xd1, 0x0b, 0x94, 0x07, 0x95, - 0x73, 0x0b, 0x80, 0xac, 0x36, 0x78, 0xbd, 0x0d, 0x92, 0x07, 0x89, 0xfd, - 0x02, 0x96, 0x2b, 0xff, 0xff, 0x2f, 0x85, 0xab, 0x05, 0x01, 0x00, 0xb3, - 0x28, 0x79, 0xae, 0x58, 0x7d, 0x00, 0x00, 0x00 }; + 0x1f, 0x8b, 0x08, 0x08, 0x09, 0x83, 0x41, 0x44, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xec, 0x5b, 0x7d, 0x6c, + 0x5b, 0xd7, 0x75, 0x3f, 0xef, 0xf1, 0x51, 0x7a, 0x96, 0x68, 0xf9, 0x99, + 0x7e, 0x96, 0x59, 0x4f, 0xb1, 0x49, 0xf1, 0xc9, 0xd2, 0x62, 0x2d, 0x63, + 0x34, 0x35, 0xd1, 0x3a, 0x26, 0x66, 0x48, 0xda, 0x71, 0x36, 0x67, 0xa0, + 0x1d, 0x05, 0x51, 0x51, 0xaf, 0xd0, 0x48, 0xd9, 0xcd, 0xb2, 0x0c, 0x73, + 0x96, 0xb4, 0x70, 0xbc, 0xb4, 0xa1, 0x25, 0x79, 0xf5, 0x06, 0x45, 0xcf, + 0xb3, 0x34, 0x39, 0xc0, 0x82, 0x41, 0x10, 0x9d, 0x3a, 0x7f, 0x30, 0xa5, + 0xed, 0x7c, 0x19, 0xe8, 0x12, 0x29, 0xb2, 0x93, 0xb5, 0x43, 0xd0, 0xa6, + 0x68, 0xff, 0xe8, 0x8a, 0x6e, 0x30, 0x52, 0x0c, 0xf3, 0x3a, 0xa0, 0x30, + 0xfa, 0xc7, 0xe6, 0x2d, 0x1f, 0xdc, 0xef, 0xdc, 0x77, 0x1f, 0xf9, 0x48, + 0x51, 0x96, 0x1c, 0x34, 0x5d, 0xb7, 0x99, 0x80, 0xf0, 0xde, 0xbd, 0xf7, + 0xbc, 0x7b, 0xcf, 0x3d, 0xdf, 0xe7, 0xdc, 0xab, 0x5f, 0x53, 0xa9, 0x85, + 0xe4, 0x6f, 0x2d, 0xfe, 0xc2, 0x7f, 0xf4, 0xc7, 0xb9, 0xdb, 0x3e, 0x7d, + 0x5b, 0x1f, 0x5e, 0x07, 0x54, 0xdd, 0xaf, 0x72, 0xbf, 0x0f, 0x7f, 0x26, + 0xfe, 0xfa, 0xe4, 0x7b, 0xa3, 0x9f, 0x81, 0xbf, 0x2b, 0x18, 0x1c, 0xfe, + 0x09, 0x91, 0xb2, 0x0c, 0x8c, 0xf7, 0x57, 0x2e, 0x5f, 0x7f, 0x9c, 0x17, + 0x0e, 0xaf, 0x62, 0x9e, 0x9b, 0xbf, 0x9b, 0xbf, 0x9b, 0xbf, 0x9b, 0xbf, + 0x9b, 0xbf, 0x9b, 0xbf, 0x9b, 0xbf, 0xff, 0x3f, 0x3f, 0x9f, 0x13, 0x72, + 0x88, 0x98, 0x85, 0xff, 0x48, 0x57, 0xe3, 0x89, 0xa1, 0xa4, 0x45, 0xba, + 0x2f, 0x7e, 0x65, 0x28, 0x67, 0x11, 0x25, 0x8a, 0xdb, 0xc3, 0x29, 0xfa, + 0xb0, 0x9c, 0x37, 0x35, 0xe2, 0xfe, 0x5b, 0xe2, 0x1f, 0x3c, 0xfd, 0xfa, + 0x9d, 0x91, 0xab, 0xb3, 0x3e, 0xd2, 0x8d, 0xf8, 0xcb, 0xba, 0xb1, 0x8d, + 0xf4, 0x0e, 0x7c, 0xf3, 0x5c, 0xf7, 0x7f, 0xa8, 0xd4, 0xe6, 0xce, 0x75, + 0xa5, 0xfc, 0x7a, 0x37, 0xe5, 0x37, 0xc7, 0x75, 0x52, 0xe3, 0x5d, 0x3f, + 0x48, 0xfa, 0x8c, 0x61, 0x5f, 0xdc, 0xa0, 0xf9, 0x12, 0x65, 0x0e, 0x4c, + 0xf0, 0x1a, 0xb1, 0x75, 0xf7, 0x62, 0x2e, 0x2d, 0x3e, 0x3c, 0xf4, 0x67, + 0xd6, 0xd3, 0x65, 0xd5, 0xb2, 0x7a, 0xe6, 0x28, 0x30, 0xf0, 0x7c, 0x3f, + 0xc6, 0x8b, 0x91, 0x1e, 0xa2, 0x3b, 0x49, 0xb5, 0xf2, 0x01, 0x9f, 0xa5, + 0x53, 0xb2, 0x64, 0x51, 0xaa, 0x44, 0xf4, 0x77, 0x45, 0x85, 0x9e, 0xb7, + 0xda, 0x69, 0xae, 0xf7, 0x83, 0x72, 0x02, 0xb8, 0xbc, 0x6d, 0x0d, 0x0f, + 0x8d, 0x5b, 0x3c, 0x57, 0x7c, 0x9d, 0x83, 0x6f, 0x6f, 0x5b, 0xce, 0xd2, + 0x68, 0xb4, 0xc8, 0x7d, 0xbd, 0x2d, 0xdc, 0xe7, 0x8f, 0x3f, 0x1c, 0x7c, + 0xde, 0x0a, 0xc8, 0xbe, 0x1f, 0xa5, 0x92, 0x98, 0x6f, 0xac, 0xc8, 0xb0, + 0xcf, 0xde, 0x91, 0xb3, 0x4c, 0xd9, 0x6f, 0xc5, 0x93, 0x56, 0x08, 0xfd, + 0x1d, 0x72, 0x2c, 0xbd, 0x2e, 0x67, 0x59, 0x72, 0xac, 0x88, 0x6f, 0x7a, + 0x65, 0xff, 0x3b, 0xa9, 0x9c, 0x15, 0x93, 0xfd, 0x57, 0x93, 0x49, 0xab, + 0x5f, 0xf6, 0x1f, 0xbe, 0x2b, 0x67, 0xc5, 0x65, 0xff, 0xf7, 0x81, 0x8b, + 0x41, 0xc7, 0x8a, 0x61, 0xfc, 0x25, 0x30, 0xfe, 0x9a, 0x41, 0x6d, 0x19, + 0x8c, 0x61, 0xef, 0xb6, 0x4e, 0x97, 0x7d, 0x21, 0x7a, 0xbd, 0xfb, 0x32, + 0x68, 0x63, 0xd0, 0xd9, 0x12, 0x29, 0x99, 0xee, 0x10, 0x68, 0x62, 0xd2, + 0xb9, 0x52, 0x2b, 0xf9, 0x4e, 0xfa, 0xb0, 0xe7, 0xcf, 0x51, 0xd6, 0xd4, + 0x69, 0xfd, 0x8c, 0x42, 0x9d, 0x7d, 0x6b, 0x28, 0x61, 0xe4, 0x29, 0xd5, + 0x8d, 0x28, 0x6e, 0xd2, 0x24, 0x6d, 0x66, 0x71, 0xbd, 0x8a, 0x1e, 0x95, + 0x22, 0xa1, 0x2c, 0x28, 0x3c, 0x72, 0xfa, 0x5d, 0x8e, 0x39, 0xb1, 0x26, + 0xff, 0x85, 0x29, 0x35, 0x71, 0x2b, 0x0d, 0x1b, 0x8c, 0x0f, 0x80, 0x05, + 0x1f, 0x74, 0x25, 0x79, 0x2a, 0x44, 0xc7, 0xec, 0x80, 0x92, 0x3a, 0x75, + 0x37, 0x25, 0x63, 0x64, 0xaa, 0xd4, 0x25, 0xbe, 0x2d, 0x14, 0x43, 0x34, + 0x6e, 0x93, 0x92, 0xb4, 0x99, 0x5e, 0xed, 0x18, 0x6f, 0x13, 0xb0, 0xe8, + 0xeb, 0xf0, 0x51, 0x97, 0x91, 0x22, 0x9d, 0x71, 0x46, 0x7f, 0x50, 0x49, + 0x8b, 0x39, 0x44, 0x7f, 0x78, 0x8c, 0x02, 0x74, 0xba, 0x68, 0x4a, 0xd8, + 0x72, 0x39, 0x19, 0x33, 0x00, 0x07, 0xda, 0xd9, 0x26, 0x0d, 0xe3, 0x39, + 0x6a, 0xf3, 0xfa, 0x21, 0xc8, 0xcc, 0xb7, 0x87, 0xb2, 0xd3, 0x62, 0xbe, + 0xb0, 0x2f, 0xce, 0xf3, 0x75, 0x00, 0xee, 0x1d, 0xe0, 0xa5, 0x90, 0x26, + 0x78, 0x95, 0xa0, 0xec, 0x84, 0x02, 0x79, 0xc2, 0x53, 0xd0, 0x2d, 0x0d, + 0xfc, 0x35, 0xb2, 0xfa, 0x14, 0xca, 0x59, 0x9b, 0x28, 0x6f, 0xa0, 0x5d, + 0xbc, 0xa0, 0x26, 0xed, 0x66, 0x4a, 0x69, 0x61, 0xec, 0x5f, 0xc8, 0x0a, + 0x8d, 0xe1, 0x1b, 0xd5, 0x62, 0x98, 0x9f, 0x61, 0xef, 0xc3, 0x82, 0xfe, + 0x4d, 0xf1, 0xfd, 0x74, 0x69, 0x22, 0xaf, 0x26, 0x4b, 0xed, 0xe4, 0x9b, + 0x89, 0x40, 0x9a, 0xc7, 0xd5, 0xd4, 0x19, 0x8d, 0xfc, 0x93, 0x0a, 0x41, + 0x3e, 0x0c, 0x5f, 0xfc, 0xb8, 0xba, 0xb3, 0x74, 0x41, 0x4d, 0x95, 0xf8, + 0x1b, 0xc0, 0x16, 0x55, 0xd0, 0x96, 0xdf, 0xb7, 0x83, 0x96, 0x34, 0xac, + 0xc6, 0x75, 0x3d, 0x51, 0x64, 0x99, 0xe5, 0x6f, 0xc1, 0x0f, 0xec, 0xe5, + 0x9c, 0x0d, 0xfe, 0x08, 0x7e, 0x85, 0xc1, 0xaf, 0x6f, 0x82, 0x5f, 0xfd, + 0xe0, 0x53, 0x8c, 0xde, 0x28, 0xf5, 0xd2, 0x6b, 0xa5, 0x1e, 0x7a, 0x15, + 0x32, 0xf9, 0x4a, 0x29, 0x4c, 0x2f, 0x97, 0x3a, 0xe8, 0xa5, 0x52, 0x88, + 0xce, 0x0b, 0x1e, 0xa6, 0x21, 0xff, 0x82, 0xaf, 0xfa, 0x26, 0xf0, 0xa4, + 0x1d, 0x3c, 0x59, 0x0f, 0x79, 0xd9, 0x08, 0xf9, 0x9b, 0xee, 0xd6, 0x69, + 0xaa, 0x9b, 0x12, 0x41, 0xf4, 0x6f, 0x89, 0x6b, 0x82, 0x4e, 0x1a, 0xc6, + 0xc7, 0x26, 0xfc, 0x94, 0x32, 0x4e, 0xd3, 0x7b, 0x93, 0x1a, 0x8d, 0x95, + 0xa6, 0x36, 0x3a, 0x7c, 0xe3, 0xf6, 0x2c, 0x5d, 0x44, 0x5f, 0xca, 0x98, + 0xa5, 0x4b, 0xdb, 0x54, 0x1a, 0x9d, 0xfe, 0x1b, 0x4a, 0x9e, 0x39, 0x4d, + 0x3f, 0xfe, 0x3a, 0x51, 0x06, 0x34, 0x51, 0xfb, 0x7e, 0x5a, 0x4e, 0x18, + 0xa0, 0x45, 0x5f, 0xaf, 0x90, 0x08, 0xb5, 0x8f, 0x79, 0x19, 0x86, 0xae, + 0x68, 0x4a, 0xca, 0x7e, 0x01, 0xfa, 0xd2, 0xaa, 0x24, 0xa7, 0x88, 0x72, + 0x53, 0x65, 0xca, 0xc5, 0xfc, 0xf4, 0x98, 0x51, 0xa6, 0x74, 0xac, 0x89, + 0xbe, 0x68, 0xb4, 0xd3, 0x68, 0xef, 0x6f, 0xf8, 0xdc, 0x5c, 0x65, 0xba, + 0xd4, 0x8f, 0x77, 0xee, 0x23, 0x9a, 0x12, 0xef, 0x4e, 0x7f, 0xbe, 0xe4, + 0xa7, 0x84, 0x99, 0x0f, 0x69, 0xf4, 0x8e, 0xcf, 0xc1, 0x29, 0xe1, 0x8e, + 0x81, 0x57, 0xc3, 0xb0, 0x0f, 0x8e, 0x0c, 0x66, 0x27, 0xd6, 0x5c, 0x4b, + 0x88, 0x6e, 0xc0, 0x0b, 0xd9, 0xd3, 0x18, 0x8f, 0x61, 0x25, 0x6e, 0x52, + 0xa7, 0xd0, 0x8d, 0x7e, 0xc0, 0x0c, 0x28, 0xfb, 0x4a, 0xcc, 0x6b, 0xbc, + 0x17, 0x19, 0xd7, 0xcd, 0x80, 0xd5, 0xf0, 0x4c, 0x48, 0x9c, 0xbd, 0x78, + 0xf2, 0x5c, 0x8c, 0x27, 0x3f, 0x7f, 0xcf, 0x83, 0xe7, 0xe7, 0x2b, 0xef, + 0x53, 0x9e, 0xf7, 0x7c, 0xe9, 0x4f, 0x03, 0x0e, 0x7e, 0x4c, 0xcf, 0x01, + 0x1a, 0x9d, 0x38, 0x2c, 0xd7, 0xc2, 0x7b, 0x91, 0xd7, 0x38, 0x0d, 0x3a, + 0x09, 0xc8, 0x15, 0xd6, 0x3a, 0xec, 0x59, 0xeb, 0x49, 0xcf, 0x5a, 0x4f, + 0x7a, 0xd6, 0xca, 0x83, 0xb6, 0xb4, 0x4e, 0xb5, 0xfc, 0xd0, 0x51, 0xee, + 0x39, 0x8e, 0x39, 0x9f, 0x03, 0x5f, 0xbe, 0x0a, 0x98, 0x38, 0x2d, 0xda, + 0xa0, 0xc7, 0x94, 0x46, 0x7b, 0x4d, 0x7e, 0x7f, 0xb1, 0xd5, 0xc1, 0x8b, + 0xdf, 0x2f, 0x48, 0x9c, 0x5a, 0x1d, 0xb8, 0xd2, 0x15, 0xa1, 0xff, 0xf3, + 0x25, 0xd6, 0x4f, 0x8a, 0xf9, 0x2c, 0x3a, 0x94, 0x8e, 0xb5, 0xd3, 0x98, + 0xa1, 0xc4, 0x46, 0x7b, 0x9a, 0x99, 0x8e, 0x09, 0xd5, 0x6a, 0x85, 0x0e, + 0x50, 0x58, 0x65, 0xdb, 0x25, 0xf0, 0x7b, 0x49, 0xe2, 0x61, 0x70, 0x3b, + 0xa3, 0x5a, 0xc1, 0xba, 0x7e, 0x96, 0xdf, 0x57, 0xf0, 0xce, 0x32, 0x9c, + 0xd4, 0x9c, 0xb5, 0x5f, 0x45, 0x9b, 0xed, 0xce, 0x66, 0xd9, 0x76, 0xc7, + 0xff, 0xa0, 0xa9, 0xb6, 0xfd, 0x05, 0xb3, 0xb6, 0xed, 0xea, 0x82, 0xd7, + 0x66, 0xf1, 0xde, 0xc2, 0xe4, 0xb3, 0x58, 0x8e, 0xfc, 0xc0, 0x35, 0x06, + 0x3d, 0x6c, 0x96, 0x38, 0x7c, 0x4b, 0xe2, 0x00, 0x5c, 0x01, 0x37, 0x5a, + 0xe2, 0x6f, 0x04, 0x4b, 0xea, 0xda, 0x4c, 0x43, 0xf7, 0x7d, 0xad, 0x18, + 0xbf, 0xec, 0xe3, 0x75, 0xdc, 0x27, 0x29, 0x69, 0xe8, 0xc9, 0xd8, 0xb4, + 0x46, 0xd9, 0xd8, 0x26, 0x21, 0xd7, 0xd9, 0x58, 0xd5, 0x06, 0x8c, 0x4e, + 0xd4, 0xdb, 0x00, 0xfe, 0x8e, 0x6d, 0x80, 0xa3, 0xfb, 0x63, 0xd3, 0x6c, + 0x0b, 0x1c, 0xdd, 0x3f, 0x36, 0xc1, 0x36, 0x41, 0xcc, 0x09, 0xfd, 0x67, + 0x3b, 0xe0, 0xda, 0x00, 0xfe, 0x86, 0x6d, 0x80, 0x0f, 0xf2, 0xcd, 0xf3, + 0xb9, 0x6b, 0x8f, 0xd7, 0xcd, 0x3b, 0xce, 0xb6, 0x45, 0xd9, 0xd9, 0xcd, + 0x30, 0xc7, 0xb1, 0x76, 0x80, 0x0a, 0xd3, 0xcc, 0xc3, 0x48, 0xe8, 0x08, + 0x1d, 0x17, 0x36, 0xef, 0xf4, 0x04, 0x25, 0x0e, 0x9e, 0x18, 0xa0, 0x34, + 0x6c, 0xc0, 0xdc, 0xc4, 0xb5, 0x32, 0xf8, 0x78, 0x47, 0x13, 0x59, 0xb0, + 0x75, 0xf0, 0x93, 0xfd, 0x7e, 0xf2, 0xc5, 0xe3, 0x90, 0xb7, 0x98, 0xf0, + 0x5d, 0xd5, 0x9f, 0xa6, 0xed, 0xaa, 0x69, 0x37, 0xc1, 0x3f, 0x62, 0xde, + 0xfe, 0x98, 0x90, 0x4d, 0xef, 0x2f, 0x09, 0x1b, 0x94, 0x8c, 0x7d, 0x08, + 0xf9, 0x75, 0x69, 0xe4, 0xea, 0x1f, 0xdb, 0xfa, 0x2b, 0x1e, 0x1f, 0xb2, + 0x05, 0x76, 0xdf, 0x84, 0x3c, 0xb9, 0x76, 0x9f, 0xed, 0x71, 0x88, 0x6d, + 0x26, 0xf4, 0x8d, 0x6d, 0x70, 0x80, 0xd4, 0x19, 0x4d, 0xda, 0x69, 0x5d, + 0xda, 0xe9, 0x00, 0x6c, 0x34, 0xb7, 0x0d, 0xd9, 0x36, 0x45, 0x1b, 0xf6, + 0x1a, 0xf6, 0x70, 0x77, 0x3a, 0x35, 0xc1, 0xfe, 0x10, 0xbe, 0x7b, 0x86, + 0x75, 0xf8, 0xdb, 0x43, 0x23, 0xd3, 0xc2, 0x07, 0xb0, 0xff, 0x80, 0x65, + 0x66, 0x1b, 0xce, 0xb6, 0x1c, 0xfb, 0x2e, 0x62, 0xdd, 0x8a, 0xad, 0x64, + 0x39, 0xf1, 0xe2, 0xc5, 0x38, 0xad, 0x21, 0xf5, 0xa4, 0x43, 0x6b, 0x35, + 0xfe, 0xa8, 0x46, 0x2d, 0x4c, 0x63, 0xc6, 0x7f, 0x2b, 0x70, 0xe6, 0x7d, + 0xfd, 0x4f, 0xe0, 0xcc, 0xeb, 0xd6, 0xe3, 0x4d, 0x7a, 0x6b, 0xfc, 0xac, + 0xfe, 0xf0, 0x33, 0xa4, 0x37, 0xc7, 0xcf, 0xd2, 0xbf, 0x58, 0x74, 0x9f, + 0x0e, 0x3f, 0xdb, 0xad, 0xc0, 0xcf, 0x16, 0xa1, 0xef, 0x53, 0x3a, 0x1d, + 0x3c, 0x15, 0xc9, 0xfc, 0x2b, 0x45, 0x61, 0x3f, 0x76, 0xd0, 0xc8, 0x94, + 0x42, 0x7a, 0x17, 0xb5, 0xc3, 0x7f, 0xf4, 0x37, 0x61, 0xfe, 0x5d, 0x44, + 0x9b, 0x1d, 0xbf, 0xd9, 0x15, 0x1e, 0x05, 0xff, 0xd3, 0x2f, 0x7e, 0x05, + 0xdf, 0x3c, 0x4d, 0x07, 0xa7, 0x0e, 0x2b, 0x39, 0xfb, 0x08, 0xe0, 0x97, + 0x83, 0xd5, 0x01, 0x9b, 0x07, 0xec, 0x97, 0x31, 0xef, 0xd3, 0xa4, 0xdf, + 0x1e, 0x19, 0x48, 0x28, 0xc0, 0xe3, 0x45, 0x01, 0x2f, 0x7d, 0x71, 0x97, + 0xb1, 0x53, 0xf0, 0x3f, 0x40, 0xef, 0x15, 0x2f, 0x80, 0xbe, 0xbd, 0xf0, + 0x39, 0x91, 0x67, 0x61, 0x93, 0xe1, 0x8f, 0x22, 0x57, 0x31, 0x2d, 0x7c, + 0x11, 0x29, 0x0f, 0x76, 0xa7, 0x41, 0xef, 0x38, 0xfc, 0xd3, 0x00, 0xfc, + 0x53, 0x0c, 0xbe, 0xa9, 0x07, 0x7e, 0xc9, 0x82, 0x5f, 0x0a, 0x83, 0x1f, + 0x06, 0xcd, 0xc2, 0x47, 0xcd, 0x42, 0xfe, 0xe7, 0x66, 0x48, 0x19, 0x04, + 0xad, 0xcf, 0xc1, 0x3f, 0x26, 0x63, 0x77, 0x42, 0xcf, 0x22, 0x17, 0x66, + 0xd5, 0x41, 0xca, 0xc1, 0x9f, 0x77, 0x6e, 0x8b, 0x62, 0xbd, 0x26, 0x4a, + 0x84, 0x5c, 0x1d, 0xe5, 0xdf, 0x7e, 0x85, 0xac, 0x7f, 0x06, 0xef, 0x22, + 0x61, 0xa2, 0x3d, 0x94, 0xb5, 0xa3, 0x46, 0xa7, 0xda, 0x03, 0x18, 0x6e, + 0x87, 0x95, 0x03, 0x53, 0x11, 0x05, 0xfb, 0x03, 0xcd, 0x27, 0x60, 0xeb, + 0xcb, 0x34, 0x1e, 0x63, 0x3d, 0x29, 0xd3, 0xf3, 0xb1, 0xc8, 0x40, 0x9e, + 0x5a, 0xe9, 0x98, 0x39, 0x21, 0x7c, 0xbc, 0x16, 0x3f, 0x21, 0x74, 0x2c, + 0x67, 0xe1, 0x59, 0xec, 0x54, 0xb2, 0x53, 0xbc, 0x7e, 0x14, 0x5a, 0xee, + 0xc7, 0x93, 0xe7, 0x07, 0xdd, 0xfa, 0x49, 0x39, 0xd8, 0x9d, 0x87, 0x77, + 0x88, 0x18, 0x8b, 0x58, 0x39, 0x35, 0x11, 0x0d, 0x45, 0x55, 0x8d, 0x86, + 0x35, 0x85, 0x46, 0x61, 0x6f, 0xd2, 0xb1, 0xff, 0x2c, 0x1f, 0x33, 0x79, + 0xbc, 0x99, 0xbe, 0x2a, 0xfc, 0x0d, 0xd6, 0x2e, 0x4c, 0x63, 0x5d, 0x3f, + 0xf8, 0xcb, 0xeb, 0xf2, 0x3c, 0x68, 0xc3, 0xf6, 0x6b, 0x56, 0xe4, 0xd9, + 0x3c, 0xed, 0x00, 0x6d, 0xd9, 0x66, 0xc1, 0x3e, 0x0c, 0x60, 0xed, 0x5e, + 0xd8, 0x4f, 0x3c, 0x93, 0xbd, 0x1c, 0x07, 0x05, 0x68, 0xd8, 0x64, 0x79, + 0xd4, 0xe5, 0x98, 0xe9, 0x19, 0xf3, 0xcb, 0xb1, 0x20, 0xfe, 0xe0, 0x7f, + 0x4d, 0x96, 0x19, 0x6e, 0x73, 0x4c, 0xc6, 0x34, 0x09, 0xd3, 0xdc, 0x64, + 0x02, 0x34, 0x8b, 0x9c, 0x4d, 0x10, 0xd3, 0x0c, 0x46, 0x7b, 0x7f, 0x82, + 0xbe, 0x64, 0xaf, 0xf7, 0x3b, 0xb6, 0xb0, 0x55, 0x49, 0xc1, 0x17, 0xa8, + 0x56, 0x0b, 0x7c, 0x45, 0x98, 0x5e, 0x15, 0xb0, 0x64, 0xa8, 0xf1, 0x68, + 0xe8, 0x4b, 0x74, 0xab, 0xb0, 0x11, 0x09, 0xc3, 0x4b, 0xe3, 0xff, 0x52, + 0xc9, 0x72, 0xbf, 0x69, 0xa5, 0xec, 0x20, 0xf3, 0x89, 0xd7, 0x33, 0x68, + 0xae, 0xe4, 0xbc, 0xfb, 0x10, 0xa3, 0x16, 0x60, 0x6b, 0xce, 0x4f, 0xaa, + 0xf4, 0xf8, 0x1d, 0xf0, 0x65, 0xb1, 0x6d, 0x58, 0xcb, 0xc4, 0x78, 0x1e, + 0x6d, 0x15, 0x6d, 0xe8, 0x99, 0x11, 0x02, 0x8f, 0xb9, 0x9f, 0xe1, 0x4c, + 0xfc, 0xbd, 0xcf, 0xb1, 0x75, 0x3e, 0xab, 0xde, 0x4a, 0x14, 0x64, 0x7a, + 0xc5, 0x40, 0x2b, 0xcb, 0x50, 0xd5, 0x6d, 0xc2, 0x5f, 0x3b, 0xb6, 0xc4, + 0x82, 0x2e, 0xc2, 0xe6, 0xf6, 0x79, 0x75, 0x91, 0xe3, 0x09, 0x57, 0x17, + 0x23, 0xa1, 0x84, 0x0a, 0x5b, 0xdc, 0xa7, 0xd1, 0x09, 0xd1, 0x56, 0x28, + 0x31, 0x18, 0x09, 0x2d, 0xa8, 0x1c, 0x4b, 0x33, 0x6c, 0x18, 0xf1, 0x4a, + 0x40, 0xc2, 0x22, 0x9e, 0xb3, 0xdd, 0x98, 0x30, 0x84, 0x7e, 0x53, 0xf4, + 0x1f, 0xab, 0xe8, 0xa8, 0x13, 0xff, 0xa9, 0x88, 0x11, 0x0b, 0x88, 0x11, + 0x53, 0x42, 0x47, 0x8d, 0x04, 0x72, 0x04, 0xd0, 0xdc, 0xd1, 0xcf, 0x42, + 0x91, 0x71, 0xc9, 0xb1, 0x5c, 0x0e, 0x00, 0x99, 0x13, 0x8e, 0x7d, 0xa4, + 0x3c, 0xc7, 0x91, 0xa3, 0xea, 0x53, 0x34, 0x5c, 0x60, 0x3f, 0x8e, 0x3f, + 0x9b, 0x6d, 0x2d, 0xec, 0xa3, 0xf0, 0xc5, 0x51, 0xf0, 0x39, 0x0f, 0x1a, + 0xac, 0x97, 0x74, 0xdd, 0x4f, 0x07, 0xec, 0x3d, 0xa0, 0x79, 0x9c, 0x46, + 0x4e, 0x8d, 0xb0, 0xcc, 0xf6, 0x14, 0x28, 0xd2, 0x73, 0x8c, 0xb6, 0x1b, + 0x73, 0x2c, 0xdf, 0x83, 0xe5, 0x1d, 0xe0, 0x85, 0xd0, 0x51, 0xc8, 0x20, + 0x65, 0x0b, 0x23, 0xf4, 0x58, 0x89, 0xfb, 0xf2, 0xa0, 0x1d, 0xe2, 0xda, + 0xfe, 0xfd, 0x52, 0xce, 0x31, 0x9f, 0xe6, 0xce, 0x37, 0x22, 0xe7, 0x63, + 0x38, 0x86, 0xe1, 0x6f, 0xaa, 0xf3, 0xee, 0x14, 0x3c, 0x8d, 0x18, 0x5d, + 0x6a, 0x79, 0x87, 0x1f, 0xe3, 0xcf, 0xf7, 0xf3, 0x3b, 0xe6, 0x81, 0xef, + 0x6f, 0xb6, 0xf6, 0x00, 0x76, 0x10, 0x73, 0xfa, 0xa9, 0xb3, 0xdd, 0xc5, + 0x37, 0x81, 0xb5, 0xd9, 0xcf, 0x31, 0x9f, 0x1f, 0xa1, 0xec, 0xa9, 0x7c, + 0x8f, 0x0a, 0x19, 0x9b, 0xcd, 0x28, 0xe4, 0xb7, 0x1e, 0xa6, 0xdc, 0xa9, + 0xa3, 0x6c, 0x37, 0x40, 0xab, 0x3d, 0xb4, 0x6b, 0x22, 0xd2, 0x73, 0x80, + 0x34, 0xb1, 0xce, 0x5b, 0x24, 0xe8, 0x1f, 0x9b, 0x15, 0xbe, 0x20, 0x43, + 0xe9, 0x89, 0xed, 0xa1, 0x4b, 0xe8, 0x1b, 0x1e, 0x8c, 0x84, 0x17, 0xe8, + 0x09, 0xd0, 0xe5, 0x23, 0xf8, 0x22, 0xab, 0x67, 0x0c, 0x3a, 0x84, 0x9c, + 0x0a, 0xeb, 0x8f, 0x4a, 0xda, 0xe0, 0xbb, 0xcc, 0x51, 0xd0, 0x8f, 0xf2, + 0x0e, 0x4d, 0x99, 0x9e, 0x4c, 0xcb, 0xaf, 0xc0, 0xf6, 0x1c, 0x11, 0xb1, + 0x4b, 0x56, 0xd0, 0xee, 0xd2, 0x06, 0x47, 0x0e, 0x60, 0x8b, 0x30, 0xef, + 0xe5, 0x41, 0x85, 0xb6, 0x20, 0x4e, 0x3f, 0x24, 0x78, 0xeb, 0xa3, 0x7d, + 0x66, 0xd4, 0xd8, 0x47, 0xf3, 0x7e, 0x27, 0x56, 0xc0, 0x3c, 0x3d, 0xf7, + 0x60, 0x0f, 0x90, 0x53, 0xfb, 0xeb, 0xeb, 0xa8, 0x2d, 0x12, 0x4e, 0xa8, + 0x09, 0xfa, 0x93, 0xd2, 0xdd, 0xe4, 0xe8, 0x77, 0x2b, 0xdb, 0x7e, 0xf0, + 0xb0, 0xd3, 0x69, 0x5b, 0x78, 0x16, 0x3a, 0xb1, 0x1e, 0xe3, 0xfe, 0xac, + 0xc0, 0x7d, 0x84, 0xba, 0xa1, 0x6b, 0x22, 0x8f, 0x39, 0x51, 0x8b, 0x17, + 0xf3, 0xbc, 0x9e, 0xcf, 0x5f, 0xc6, 0x3c, 0xdc, 0xcf, 0x70, 0x78, 0x2f, + 0x3c, 0x41, 0x23, 0x90, 0xc7, 0x5c, 0x7f, 0x57, 0x68, 0x0c, 0xdf, 0xa4, + 0x4a, 0x4d, 0x74, 0x54, 0xe3, 0xf1, 0x48, 0x38, 0xaf, 0x1e, 0x42, 0xdc, + 0xf3, 0xb8, 0xea, 0xb7, 0x7e, 0xe6, 0x67, 0xbf, 0xe3, 0xb7, 0xae, 0x29, + 0xd5, 0xb9, 0x10, 0x87, 0x8a, 0xdc, 0x60, 0x41, 0x19, 0x2c, 0x5d, 0x52, + 0x92, 0x85, 0x6b, 0x4a, 0xaa, 0xc4, 0x30, 0x8e, 0xce, 0x67, 0xcf, 0x74, + 0x82, 0x4e, 0x1f, 0x89, 0xef, 0xe6, 0x7a, 0x8f, 0x50, 0xea, 0xd4, 0xad, + 0x94, 0x9e, 0xe6, 0xbc, 0x34, 0x02, 0x7c, 0x3f, 0x2a, 0xe7, 0x62, 0x41, + 0xca, 0x9d, 0xe1, 0x31, 0xb6, 0x5f, 0xd6, 0xd5, 0x45, 0x1f, 0xef, 0x9f, + 0xf9, 0x6f, 0x52, 0xc1, 0x7e, 0x53, 0xd2, 0x8f, 0xdf, 0x7d, 0x9c, 0x93, + 0xe1, 0xf7, 0x6f, 0x86, 0xd3, 0xb7, 0x95, 0x16, 0x36, 0xdc, 0xc8, 0x3e, + 0x57, 0xb3, 0xc7, 0x47, 0x7d, 0x7e, 0x6b, 0x7b, 0x13, 0xb5, 0x84, 0x80, + 0xc3, 0x4a, 0x7b, 0x64, 0x98, 0x5f, 0x87, 0x1c, 0xb0, 0x4d, 0xd9, 0x0d, + 0x7e, 0x5a, 0x6c, 0xc3, 0x60, 0x93, 0x76, 0x53, 0xae, 0xc4, 0xb2, 0x1d, + 0x35, 0x32, 0x90, 0xb1, 0x34, 0x75, 0xb1, 0x1e, 0xb9, 0xba, 0x07, 0xdb, + 0x9d, 0x87, 0xed, 0x46, 0x3c, 0x64, 0x53, 0xbe, 0x29, 0xce, 0x36, 0xbc, + 0x0b, 0xb2, 0x85, 0xbe, 0x62, 0x55, 0x17, 0x77, 0x2d, 0xc1, 0x5d, 0x5b, + 0xc2, 0xa3, 0x02, 0xd5, 0xe2, 0x3f, 0x4b, 0x8c, 0xff, 0x5f, 0x00, 0xff, + 0xcf, 0x01, 0x7f, 0xc6, 0xa9, 0x31, 0xfe, 0x3b, 0x2b, 0xf8, 0x33, 0x0c, + 0xfc, 0x1c, 0x64, 0xf1, 0x0d, 0xe8, 0xe2, 0x6b, 0x36, 0x7c, 0x9d, 0x0d, + 0xff, 0x67, 0xc3, 0xdf, 0xd9, 0xf0, 0x8b, 0x36, 0x7c, 0x1e, 0xf6, 0x74, + 0x0e, 0x36, 0xe9, 0xac, 0x9d, 0x34, 0x58, 0x9f, 0x92, 0x31, 0xf6, 0x9d, + 0xbb, 0x65, 0xde, 0x1d, 0x92, 0x71, 0xf7, 0xa7, 0x64, 0x2c, 0x7b, 0x00, + 0xb1, 0xec, 0x66, 0x1a, 0xed, 0xe1, 0x9c, 0xa4, 0x05, 0xcf, 0x75, 0x78, + 0x22, 0x6e, 0xed, 0x49, 0x48, 0xbd, 0xfc, 0x0c, 0x62, 0x5c, 0xd8, 0xff, + 0x1e, 0xe4, 0x37, 0x19, 0xc4, 0x6a, 0x56, 0x1f, 0xc7, 0xe5, 0xb0, 0x65, + 0xef, 0x37, 0x39, 0x76, 0xfe, 0x2e, 0x19, 0x03, 0xbb, 0xed, 0x56, 0xc0, + 0xa4, 0xd1, 0xd7, 0x8a, 0x6f, 0x7e, 0x07, 0xb2, 0xdf, 0x86, 0xf6, 0xce, + 0x3a, 0x18, 0xe4, 0xb3, 0x56, 0x16, 0x7d, 0x11, 0xc0, 0xb4, 0x61, 0x9d, + 0x0e, 0xb4, 0xf7, 0xa0, 0x7d, 0x8b, 0xb3, 0x8e, 0xf1, 0x2b, 0x68, 0xa7, + 0xea, 0xbe, 0xd9, 0x8a, 0xbe, 0x4c, 0x5d, 0xdf, 0x9b, 0xe8, 0x4b, 0xa2, + 0x6f, 0x51, 0x7e, 0x97, 0x47, 0x3b, 0x52, 0x07, 0xb3, 0x88, 0x3e, 0xc6, + 0xf1, 0x5b, 0x78, 0xde, 0x47, 0xa3, 0x19, 0x8e, 0x03, 0xdc, 0xb1, 0xdc, + 0x7a, 0x6a, 0xe3, 0xdc, 0xf7, 0x43, 0x21, 0x3b, 0xf3, 0xd2, 0x46, 0xa7, + 0x27, 0xd8, 0x4f, 0x8c, 0x20, 0xee, 0xe1, 0x71, 0xe1, 0x9c, 0x3c, 0xfd, + 0x1f, 0x00, 0xf6, 0x61, 0x8c, 0x21, 0x56, 0xb7, 0xcb, 0x4d, 0x8d, 0xc7, + 0x1f, 0xc5, 0xf8, 0x5f, 0xca, 0x6f, 0x2b, 0x73, 0x03, 0xfe, 0x1b, 0x75, + 0x7d, 0x6a, 0xb0, 0xb6, 0xbd, 0xd6, 0xf3, 0xbe, 0x4d, 0x5f, 0xfa, 0xfd, + 0x48, 0x1d, 0xfc, 0xef, 0x6e, 0xa8, 0x6d, 0x3f, 0xc5, 0xdf, 0x20, 0x87, + 0x70, 0xdb, 0x09, 0xc8, 0x1d, 0xdb, 0xa4, 0xfa, 0x79, 0x3e, 0x6b, 0xd4, + 0xf6, 0x6d, 0x32, 0x6b, 0xdb, 0x1c, 0x27, 0x31, 0x5c, 0x08, 0xf2, 0xde, + 0xa1, 0xec, 0xb2, 0x7f, 0x13, 0xe3, 0x61, 0xe5, 0x5e, 0xdb, 0x8b, 0x67, + 0x48, 0xe6, 0x46, 0xe1, 0x4a, 0xcc, 0x3b, 0x5f, 0x0a, 0x40, 0xae, 0x3e, + 0x0f, 0x9e, 0x73, 0xdc, 0x53, 0xd5, 0xf1, 0xf7, 0x68, 0x39, 0x1d, 0x67, + 0x1f, 0xc0, 0x31, 0xfe, 0x36, 0x11, 0x1f, 0xfb, 0xe2, 0x4f, 0x70, 0x0c, + 0xf6, 0xb4, 0xe3, 0x5b, 0x2c, 0xf8, 0x43, 0xb4, 0x4b, 0x7e, 0xc7, 0x6e, + 0x22, 0x9f, 0xc8, 0x16, 0xd8, 0x9f, 0xb1, 0x0f, 0x89, 0xc0, 0x4e, 0xb3, + 0x1f, 0xfd, 0x24, 0x7d, 0xc6, 0x5d, 0xcd, 0x6c, 0xfb, 0x34, 0xeb, 0x05, + 0xc4, 0x0b, 0x1c, 0xe7, 0xb1, 0xed, 0xc6, 0x7b, 0xd1, 0x8d, 0x57, 0xee, + 0xd7, 0xc8, 0xaa, 0xfa, 0x11, 0x67, 0x8f, 0x5b, 0x59, 0x37, 0x56, 0xb1, + 0xef, 0xc6, 0xb6, 0xed, 0xc7, 0x75, 0xb6, 0xe1, 0xb2, 0xb0, 0x0d, 0x0f, + 0x6a, 0x7e, 0xeb, 0xf7, 0x9b, 0x1d, 0x79, 0x6d, 0x6c, 0x1b, 0xee, 0xad, + 0xd8, 0x06, 0x57, 0x5e, 0xbd, 0x79, 0xeb, 0x0f, 0xc0, 0x1b, 0x0b, 0xbc, + 0xa9, 0xaf, 0xd5, 0x70, 0x8e, 0xe2, 0x87, 0x1f, 0xe2, 0x18, 0x91, 0x73, + 0xd9, 0x18, 0xe5, 0x62, 0x45, 0xc4, 0x6a, 0x91, 0xd9, 0xd9, 0x4a, 0x8e, + 0xf5, 0x35, 0x69, 0xbb, 0x6b, 0xe2, 0x22, 0x7a, 0xbc, 0x78, 0x09, 0xf8, + 0x73, 0xbc, 0xa5, 0x49, 0x1b, 0xc1, 0xfd, 0xe3, 0x12, 0x47, 0x7e, 0xe7, + 0x3a, 0x1e, 0x7c, 0x69, 0xf1, 0x47, 0xe0, 0x15, 0xc7, 0x7d, 0x51, 0x27, + 0xde, 0xab, 0x89, 0xa9, 0xd7, 0xf8, 0xc9, 0xe2, 0x78, 0x89, 0x61, 0x74, + 0x19, 0x2f, 0x05, 0x64, 0x5e, 0x63, 0xc8, 0x3c, 0x87, 0x63, 0x6d, 0xae, + 0xb1, 0xd6, 0xc7, 0x50, 0x0b, 0x43, 0xc1, 0x6d, 0xcc, 0x13, 0x8e, 0xa1, + 0xda, 0x28, 0x39, 0xe3, 0xc4, 0x50, 0x4e, 0x9d, 0xcd, 0xcd, 0x71, 0x5c, + 0x5c, 0xd9, 0x0f, 0xef, 0xc0, 0x3e, 0x45, 0x9e, 0x14, 0x74, 0xea, 0x7f, + 0x1a, 0xec, 0xf6, 0x51, 0xf4, 0x8f, 0xba, 0xfd, 0x9e, 0x5c, 0xc3, 0xc5, + 0x85, 0x7d, 0xbd, 0x1b, 0xd3, 0xed, 0x96, 0x31, 0x1d, 0x62, 0x18, 0xdb, + 0xc9, 0xbb, 0xf6, 0x16, 0x33, 0xe8, 0xe3, 0x75, 0x11, 0x1b, 0x12, 0xc7, + 0x49, 0x90, 0xaf, 0xfd, 0x91, 0x50, 0x58, 0xad, 0xc7, 0xab, 0x75, 0xa1, + 0x16, 0xaf, 0x41, 0xf1, 0xdd, 0xf8, 0x92, 0xef, 0x48, 0xc4, 0x92, 0xe3, + 0xf6, 0x10, 0xe8, 0xc5, 0xf8, 0xb9, 0xba, 0xe1, 0xc6, 0xc9, 0x8c, 0xd3, + 0x3f, 0x82, 0xc6, 0xbb, 0x15, 0xfe, 0x7e, 0xcc, 0xde, 0x2f, 0xe8, 0x96, + 0x15, 0xb8, 0x0e, 0x7b, 0x70, 0x1d, 0x91, 0xb8, 0xb2, 0x2e, 0xb0, 0x7e, + 0x78, 0x6b, 0x9a, 0xa6, 0xd8, 0x1b, 0x70, 0x0e, 0xf3, 0xb9, 0xb9, 0x6a, + 0x2d, 0x0c, 0xf9, 0xb6, 0xc1, 0x1f, 0x02, 0xd7, 0xac, 0x88, 0x43, 0x03, + 0x0b, 0xf5, 0x34, 0x1c, 0xc7, 0x5a, 0x88, 0xdb, 0x81, 0x8f, 0xcb, 0xf3, + 0x26, 0x89, 0xcf, 0x37, 0xc5, 0xdc, 0x63, 0xa2, 0x06, 0xea, 0xd3, 0x39, + 0x77, 0xc9, 0x0a, 0xde, 0x69, 0x92, 0x77, 0x8f, 0x56, 0xf0, 0x73, 0x78, + 0x1c, 0x90, 0x74, 0xe5, 0xdc, 0x95, 0x75, 0x5a, 0xf0, 0xa7, 0x9d, 0x73, + 0xd3, 0x41, 0x6a, 0x14, 0x23, 0x2f, 0x0c, 0xa9, 0xdb, 0x1c, 0x3a, 0x3a, + 0x31, 0xf2, 0xda, 0xba, 0x18, 0xf9, 0xb6, 0x20, 0xc7, 0x5a, 0xc3, 0x50, + 0x82, 0x79, 0xf8, 0xba, 0x97, 0x6d, 0xc8, 0x36, 0x70, 0x3d, 0x5f, 0x53, + 0xbb, 0xec, 0x59, 0xa6, 0xd6, 0x1c, 0x20, 0xdf, 0x0c, 0xfb, 0x0e, 0x0b, + 0x79, 0x06, 0x91, 0x36, 0xc9, 0x3a, 0xcb, 0xbe, 0xbd, 0x1a, 0x67, 0xcf, + 0x51, 0xa3, 0x18, 0xfb, 0x46, 0xfd, 0xfa, 0x79, 0xbf, 0xdf, 0x3a, 0xac, + 0x3b, 0x36, 0x73, 0x25, 0xbf, 0xee, 0xc2, 0xed, 0x41, 0x9c, 0xad, 0x50, + 0x93, 0x55, 0xc0, 0xfe, 0xde, 0xf0, 0x37, 0x5b, 0xae, 0x2e, 0x06, 0x68, + 0xfd, 0xcc, 0x2d, 0x42, 0x1f, 0x8d, 0xc9, 0xaa, 0x3e, 0x8e, 0x82, 0x37, + 0x19, 0xa7, 0x06, 0x60, 0xae, 0xa7, 0xeb, 0xd7, 0x0b, 0xc6, 0xed, 0x37, + 0xfd, 0xaa, 0xe5, 0xca, 0xc0, 0xf5, 0xf2, 0x91, 0x4f, 0xd5, 0xd1, 0xba, + 0x51, 0x4d, 0xf8, 0x2c, 0xe8, 0x1a, 0x47, 0xde, 0x1d, 0x79, 0x81, 0x10, + 0x3b, 0x39, 0x79, 0x78, 0x1a, 0xb9, 0x77, 0xe4, 0x02, 0xe7, 0xe3, 0x6e, + 0x7e, 0xfe, 0x6a, 0x29, 0x72, 0x36, 0x8f, 0x9c, 0x79, 0x1e, 0x39, 0xf9, + 0xcb, 0xc8, 0xc9, 0xcf, 0x97, 0x7a, 0x41, 0xff, 0x1e, 0x99, 0x8f, 0xb3, + 0x8e, 0x99, 0x74, 0x11, 0xb9, 0xd3, 0x77, 0x67, 0xd8, 0x46, 0x74, 0xd1, + 0x3d, 0xc8, 0x35, 0xbe, 0x3f, 0xa9, 0x68, 0x9d, 0x7d, 0x01, 0x5f, 0xc2, + 0xb8, 0x91, 0x38, 0x71, 0x29, 0x4f, 0x1a, 0xc7, 0x8a, 0x23, 0x4d, 0x7e, + 0x6b, 0xae, 0x95, 0x5a, 0xf6, 0x2c, 0xcb, 0x93, 0x6a, 0xac, 0xe8, 0xc2, + 0x19, 0xd4, 0xd9, 0xf7, 0x87, 0x9c, 0xdb, 0xc4, 0x48, 0xe4, 0xd3, 0xeb, + 0xe8, 0xed, 0x93, 0x65, 0xda, 0x19, 0xbb, 0x56, 0xbe, 0x68, 0xad, 0xa3, + 0x6c, 0xef, 0x43, 0x32, 0x97, 0x5c, 0x78, 0x28, 0x69, 0xe5, 0x43, 0x3e, + 0xf7, 0x7c, 0x62, 0x42, 0x47, 0x84, 0xc8, 0xbf, 0x20, 0xcd, 0x0d, 0x20, + 0x71, 0x6e, 0xd9, 0xfe, 0x02, 0x1f, 0x10, 0xb1, 0x6d, 0x9c, 0x33, 0x03, + 0xa2, 0xd6, 0xb6, 0xd1, 0xe2, 0x7e, 0x03, 0xfc, 0xbe, 0x8f, 0xe6, 0x90, + 0x43, 0x14, 0x44, 0x1e, 0xde, 0x0e, 0x78, 0x37, 0x0f, 0xbf, 0x1f, 0xb9, + 0x01, 0xd3, 0xd8, 0x04, 0xfc, 0x6f, 0x03, 0xc6, 0x6b, 0x43, 0x9f, 0x6b, + 0x22, 0xf1, 0x3d, 0x8f, 0xb7, 0x13, 0xd7, 0x65, 0xab, 0xf3, 0xf2, 0x9c, + 0x3c, 0xf6, 0x61, 0xf9, 0xf6, 0xbe, 0x3e, 0xcf, 0xdc, 0x6d, 0x9e, 0xb9, + 0xef, 0xf0, 0xcc, 0xed, 0xc3, 0xb7, 0x2e, 0x3e, 0x41, 0x7c, 0xeb, 0xae, + 0xf1, 0xb7, 0x9e, 0x35, 0x5c, 0xdc, 0xdb, 0x3d, 0xb8, 0xbf, 0x8f, 0xf9, + 0xb9, 0xcf, 0xf4, 0xf4, 0xf1, 0x9a, 0x1b, 0x68, 0x6e, 0xb0, 0x8d, 0x16, + 0x4f, 0x72, 0x5f, 0xd0, 0x83, 0x0b, 0xe3, 0x17, 0x90, 0x63, 0x6d, 0x74, + 0xf1, 0x64, 0x8b, 0xc0, 0x9b, 0xfd, 0xf9, 0xc6, 0xca, 0x9a, 0x57, 0xb0, + 0xa6, 0x3b, 0x97, 0x89, 0x6f, 0x19, 0x96, 0xf1, 0xe3, 0x31, 0xee, 0xe3, + 0xb1, 0x37, 0xcb, 0x5f, 0x33, 0x82, 0xce, 0x9e, 0x0d, 0xc6, 0xcd, 0xfd, + 0x56, 0x6b, 0x26, 0x8b, 0xdb, 0x9d, 0x34, 0x1b, 0xd4, 0xc0, 0x37, 0x55, + 0xfa, 0x28, 0xae, 0x23, 0xa8, 0x4a, 0xb4, 0x8f, 0xf9, 0xbc, 0x4e, 0xd6, + 0xaf, 0x5b, 0x30, 0x6f, 0xd8, 0xcd, 0xd1, 0x88, 0xe5, 0x38, 0x27, 0xec, + 0xbe, 0x26, 0xc7, 0xd9, 0xee, 0xb3, 0xdf, 0xc7, 0x53, 0xc8, 0xaa, 0x3c, + 0xaf, 0x29, 0xed, 0xa0, 0x83, 0x50, 0xcf, 0x8b, 0xb2, 0x9e, 0xb2, 0xe8, + 0xad, 0x99, 0x18, 0x4e, 0x1c, 0xe3, 0x9c, 0xed, 0xac, 0x85, 0xfe, 0xe0, + 0xbd, 0x98, 0x00, 0x1e, 0x61, 0x8a, 0xe2, 0xaf, 0x50, 0xca, 0xe3, 0x69, + 0xe1, 0xa9, 0xe0, 0xc9, 0xf5, 0x0c, 0x1d, 0x4f, 0xe8, 0x18, 0xec, 0x53, + 0xb4, 0xef, 0x92, 0x93, 0x3f, 0x41, 0x37, 0xde, 0x9e, 0x74, 0xea, 0x51, + 0x8b, 0xd6, 0x72, 0xf5, 0xa8, 0x3f, 0x67, 0x9e, 0x9c, 0x70, 0xeb, 0x51, + 0x8b, 0x24, 0xea, 0x51, 0x27, 0x56, 0xa8, 0x47, 0x25, 0x56, 0x5f, 0x8f, + 0xe2, 0xf9, 0x35, 0xda, 0xd7, 0x4f, 0xca, 0x17, 0x64, 0x3d, 0xea, 0x3d, + 0x72, 0xea, 0x51, 0x17, 0xa9, 0x71, 0x3d, 0xea, 0x78, 0x5d, 0x3d, 0x2a, + 0x28, 0xea, 0x51, 0x3c, 0x8f, 0x53, 0x8f, 0x12, 0xed, 0xbe, 0x88, 0xa7, + 0xee, 0x42, 0xf4, 0xee, 0x64, 0x07, 0x68, 0x66, 0xd0, 0xf7, 0x1a, 0xda, + 0x34, 0x45, 0xc8, 0xdb, 0x4a, 0x35, 0xd0, 0x07, 0x6e, 0xb8, 0xbe, 0xa2, + 0xd0, 0x06, 0xcc, 0x9b, 0xec, 0x7b, 0xd8, 0x53, 0x63, 0x61, 0x9a, 0xff, + 0x62, 0xea, 0x2c, 0x07, 0x45, 0x9d, 0xe5, 0x87, 0x6b, 0xbc, 0x75, 0x96, + 0x45, 0xba, 0x7e, 0x9d, 0xe5, 0x60, 0x83, 0x3a, 0xcb, 0x5b, 0x54, 0xad, + 0xb3, 0xbc, 0x45, 0xd5, 0x3a, 0xcb, 0xc1, 0x12, 0xe7, 0xe2, 0x3e, 0x89, + 0x5f, 0x06, 0xed, 0x41, 0xf1, 0xc7, 0xb5, 0x97, 0xc5, 0xca, 0x1e, 0x7e, + 0xd9, 0x6a, 0x2f, 0x6c, 0x03, 0x22, 0x17, 0x2e, 0xd7, 0xd4, 0x5e, 0xb8, + 0x0d, 0x9d, 0xb1, 0xd7, 0x08, 0x19, 0x99, 0x83, 0x7f, 0x5f, 0x9c, 0x0c, + 0x61, 0xce, 0x0e, 0xf8, 0x8c, 0x0e, 0xe4, 0x06, 0x61, 0xb4, 0x15, 0xda, + 0x64, 0x0d, 0xa1, 0x8f, 0xc7, 0xd9, 0x0e, 0x43, 0xb7, 0x6c, 0x77, 0x7f, + 0x0f, 0x48, 0x1a, 0x44, 0x68, 0xb8, 0x9d, 0xf4, 0x20, 0xfb, 0x8e, 0xc9, + 0x3d, 0x74, 0xc8, 0xde, 0x22, 0xf6, 0xbd, 0xc1, 0xaa, 0x95, 0xb9, 0xc1, + 0x1b, 0x90, 0xb9, 0xcc, 0xaa, 0x65, 0x8e, 0xe5, 0xcd, 0x39, 0xf7, 0xdd, + 0x60, 0xf1, 0xfa, 0x1d, 0x02, 0xa7, 0x77, 0x1b, 0xc8, 0xfb, 0x18, 0xec, + 0x8e, 0x33, 0xbf, 0x2e, 0xd7, 0xab, 0x8f, 0x87, 0x9f, 0x6d, 0x66, 0xff, + 0xbd, 0x72, 0x3d, 0xb1, 0xde, 0x7f, 0xaf, 0xe4, 0x47, 0x15, 0x61, 0x93, + 0xb3, 0x25, 0xae, 0xed, 0x7b, 0xf9, 0x33, 0x8f, 0x9c, 0x00, 0x7d, 0x42, + 0x0f, 0x98, 0xae, 0x41, 0xf0, 0x01, 0xeb, 0xd8, 0x4f, 0xc9, 0x5a, 0x16, + 0x9e, 0x05, 0x97, 0x7f, 0xad, 0xb0, 0x99, 0xee, 0x18, 0xdb, 0x01, 0x0b, + 0xfe, 0x8f, 0xeb, 0x28, 0x7c, 0x8e, 0xca, 0xfd, 0x2e, 0x5f, 0xbb, 0x2e, + 0xbc, 0xa7, 0x72, 0xbb, 0x5c, 0xce, 0x8a, 0x7a, 0x2d, 0xa9, 0x9d, 0x7d, + 0xd3, 0x2d, 0x6c, 0x6b, 0xb6, 0x58, 0xae, 0xcc, 0x26, 0xf0, 0xce, 0x7c, + 0x7d, 0x17, 0x36, 0x9c, 0xcf, 0xaa, 0xbf, 0x23, 0x6a, 0x04, 0x73, 0x36, + 0xdb, 0x6b, 0x8e, 0x41, 0x7f, 0x0b, 0xb2, 0xc4, 0xef, 0x51, 0x71, 0x2e, + 0x21, 0x6a, 0xf8, 0x83, 0xdc, 0x76, 0xed, 0x4a, 0x94, 0xed, 0x30, 0xf6, + 0x5c, 0xa5, 0x31, 0xe2, 0x23, 0xc8, 0x0c, 0xc7, 0xb1, 0x0c, 0xe7, 0xc6, + 0x9e, 0x9a, 0xa7, 0x66, 0xab, 0xcb, 0xb8, 0x88, 0x75, 0x39, 0x00, 0x9a, + 0xed, 0x10, 0x31, 0xea, 0xb8, 0x5d, 0xa6, 0xea, 0x19, 0x3f, 0xd3, 0xdc, + 0x39, 0xe7, 0x3f, 0x66, 0x2f, 0x47, 0xfb, 0xcd, 0x37, 0x48, 0x7b, 0x47, + 0x1f, 0x6b, 0xe9, 0xae, 0x23, 0x7e, 0x71, 0xe9, 0xee, 0xfa, 0xa8, 0x49, + 0x49, 0x83, 0xa8, 0xac, 0x2b, 0x7e, 0x5a, 0x9e, 0x29, 0xfd, 0x5f, 0xd8, + 0xaf, 0xe2, 0xd9, 0xaf, 0xab, 0xbb, 0xfb, 0xe4, 0x7e, 0xc3, 0x75, 0xba, + 0x1b, 0x97, 0x75, 0xb9, 0x5f, 0x84, 0xee, 0xba, 0x7b, 0xe2, 0xb5, 0xb7, + 0x5c, 0x67, 0xdd, 0x67, 0x48, 0x8d, 0xaf, 0x14, 0x7b, 0xff, 0xb4, 0xf9, + 0xe3, 0xc5, 0xde, 0x1f, 0x87, 0x9e, 0x5e, 0xbd, 0x65, 0x1a, 0xb6, 0x89, + 0xb8, 0xc2, 0xd1, 0x1f, 0xd8, 0xe3, 0x82, 0x9f, 0x16, 0x1e, 0xd2, 0xe9, + 0x9f, 0xee, 0xe4, 0xfa, 0xac, 0x26, 0x73, 0x7c, 0x6e, 0x7f, 0xb1, 0x95, + 0x63, 0xab, 0x4d, 0xd6, 0x77, 0x44, 0x6e, 0x95, 0x57, 0x4d, 0x8f, 0x1f, + 0x31, 0x30, 0xce, 0x63, 0x61, 0xba, 0x1c, 0xbc, 0x91, 0xb8, 0xbc, 0xcb, + 0x58, 0xf4, 0xad, 0x26, 0x2e, 0xbf, 0x55, 0xf7, 0x5b, 0x7f, 0xdd, 0x7a, + 0xbd, 0x3a, 0x47, 0x35, 0x2e, 0xe7, 0x7c, 0x3e, 0xe8, 0xd4, 0x18, 0x4c, + 0x8e, 0xcf, 0xd7, 0x4a, 0x9e, 0xf0, 0x3b, 0x72, 0x11, 0x1b, 0x79, 0x08, + 0x64, 0xfc, 0x55, 0xc8, 0xca, 0x2b, 0x36, 0xf2, 0x0e, 0x1b, 0xf9, 0x88, + 0x8d, 0xdc, 0xc3, 0x46, 0xee, 0x61, 0xf7, 0xc8, 0x1c, 0x26, 0x23, 0xeb, + 0x56, 0x7c, 0x46, 0xcb, 0xf9, 0x61, 0x5e, 0xc9, 0xd8, 0xe3, 0x7c, 0x1f, + 0x41, 0x4d, 0xc6, 0x36, 0xca, 0x78, 0xf0, 0x38, 0xdf, 0x77, 0x28, 0xab, + 0x71, 0xae, 0x45, 0x91, 0xaa, 0xc6, 0x6f, 0x87, 0x8f, 0xda, 0x0e, 0xbc, + 0x9a, 0x79, 0xdc, 0xa7, 0xc6, 0x5b, 0x99, 0x76, 0x8a, 0x1a, 0x5f, 0x2b, + 0xcf, 0x0d, 0x7a, 0x03, 0x0e, 0xfe, 0xdd, 0xdc, 0xd6, 0xd4, 0xf8, 0xdd, + 0xec, 0xd3, 0xc2, 0xa4, 0xba, 0xfd, 0xb7, 0x07, 0x98, 0xae, 0xa4, 0xde, + 0x16, 0xe0, 0xb8, 0x76, 0xde, 0xf6, 0x8b, 0x3b, 0x05, 0xc9, 0x18, 0xd7, + 0xcc, 0xb8, 0x5d, 0xa5, 0xab, 0xba, 0x2c, 0x5d, 0xfd, 0x95, 0xfa, 0x3f, + 0xd3, 0xd2, 0xc7, 0x70, 0xa2, 0x36, 0xc6, 0x34, 0x75, 0xe7, 0xe3, 0xf3, + 0x66, 0x5e, 0x47, 0xdc, 0x63, 0xc0, 0xf3, 0x60, 0x33, 0xb5, 0x0d, 0x0e, + 0xf9, 0x2d, 0xef, 0xba, 0x6c, 0x43, 0x76, 0x90, 0x37, 0xc7, 0x5a, 0x7e, + 0xcd, 0xa8, 0x38, 0x1b, 0x49, 0xf6, 0x47, 0x85, 0xec, 0xb0, 0xac, 0x69, + 0xe2, 0xce, 0xd5, 0x47, 0xe2, 0x1e, 0x09, 0xcb, 0x19, 0xcb, 0xf2, 0x78, + 0x7f, 0x57, 0x58, 0x53, 0x5b, 0xb0, 0x46, 0x98, 0xd2, 0x25, 0x71, 0x56, + 0x80, 0x7c, 0xe9, 0xdc, 0x3a, 0x6a, 0xfb, 0x07, 0xbd, 0x9a, 0xc7, 0x46, + 0x9d, 0xb3, 0x7a, 0xbb, 0xde, 0xff, 0x8d, 0x8a, 0x73, 0x65, 0xc7, 0x06, + 0xb9, 0xe7, 0xc3, 0xab, 0x3b, 0xff, 0xbe, 0xbe, 0x3e, 0xb5, 0xd4, 0xd7, + 0x0d, 0x24, 0x0d, 0x98, 0x36, 0x8d, 0xcf, 0xee, 0xe7, 0x4b, 0x7c, 0xaf, + 0x25, 0x12, 0xe3, 0xdc, 0x6d, 0x44, 0xdc, 0xf9, 0x50, 0x21, 0x85, 0x3a, + 0x8d, 0x19, 0x9c, 0xf3, 0x85, 0x86, 0x7d, 0x71, 0xca, 0x64, 0x27, 0x48, + 0x43, 0xac, 0x98, 0xa9, 0xd6, 0x03, 0x1f, 0x5c, 0x43, 0x96, 0x2b, 0x97, + 0x51, 0xce, 0x1f, 0x6a, 0xce, 0xed, 0x16, 0xe9, 0xb0, 0x72, 0xa0, 0x74, + 0x84, 0x0e, 0x34, 0x8c, 0x29, 0x1b, 0xd7, 0x03, 0x2f, 0xd6, 0xd5, 0x14, + 0x16, 0x44, 0x4d, 0x21, 0xb7, 0xc6, 0x6f, 0x3d, 0x19, 0x70, 0xee, 0xb5, + 0x34, 0xd6, 0x93, 0x5d, 0x15, 0x3d, 0x71, 0xe1, 0xf8, 0x2c, 0xbe, 0x8d, + 0x76, 0x8a, 0xb5, 0x0e, 0x2b, 0x59, 0xbb, 0x95, 0x76, 0x1a, 0x0e, 0xd6, + 0xa3, 0x36, 0xe3, 0x75, 0x58, 0x39, 0x68, 0xe7, 0x95, 0xb4, 0xa8, 0x3d, + 0x70, 0x8c, 0xbf, 0xe6, 0xda, 0x30, 0x95, 0xe9, 0xed, 0x98, 0xfb, 0x3d, + 0xc3, 0x78, 0x6b, 0x8a, 0x2e, 0x9d, 0xf8, 0x2e, 0x51, 0x58, 0xe6, 0x6f, + 0xce, 0x7c, 0xb9, 0x29, 0xae, 0x25, 0xde, 0x8f, 0xfd, 0x33, 0xfc, 0x6e, + 0x25, 0x39, 0x55, 0x2e, 0xa7, 0x31, 0x3e, 0xd6, 0x7b, 0xaf, 0xc8, 0x8d, + 0xd4, 0x38, 0x0d, 0x71, 0x8e, 0xac, 0x2d, 0xc9, 0x91, 0xd3, 0xd0, 0x35, + 0xc4, 0x20, 0x76, 0x13, 0xbe, 0x75, 0xe3, 0x91, 0xcf, 0xae, 0x75, 0x64, + 0xe4, 0xbb, 0x12, 0x0f, 0x1e, 0xff, 0xfb, 0x80, 0x7b, 0x0f, 0x28, 0x77, + 0x2a, 0x8d, 0xfd, 0x37, 0x51, 0xca, 0x74, 0xf2, 0xbb, 0xec, 0x99, 0x23, + 0x1b, 0x6a, 0xe1, 0xd1, 0x77, 0xca, 0x85, 0x0f, 0xd6, 0xc1, 0xf3, 0x19, + 0xd7, 0x5f, 0xd5, 0xc1, 0x07, 0x3d, 0xf0, 0x66, 0x1d, 0x3c, 0xe2, 0xae, + 0x33, 0xdf, 0xa8, 0x83, 0x37, 0x3d, 0xf0, 0xed, 0x75, 0xf0, 0xed, 0x80, + 0x7f, 0xa3, 0x0e, 0x1e, 0x7d, 0xa7, 0x90, 0x13, 0x08, 0xda, 0x70, 0x8c, + 0x74, 0x48, 0xe6, 0x89, 0x78, 0x2e, 0xb9, 0x1f, 0xc9, 0xf2, 0xd3, 0x01, + 0x1a, 0x7b, 0xeb, 0xb5, 0x09, 0xd8, 0xa8, 0xaa, 0x4c, 0x39, 0xfa, 0xea, + 0x95, 0x25, 0x96, 0xbd, 0x3c, 0xe4, 0x15, 0x7a, 0x54, 0x80, 0x3e, 0x15, + 0x5c, 0x5f, 0xca, 0x77, 0xaa, 0x22, 0xc7, 0x1d, 0x3d, 0x56, 0x68, 0xbd, + 0x35, 0x2f, 0x73, 0x91, 0xab, 0x8c, 0x3b, 0xfc, 0x86, 0xeb, 0x3b, 0xe8, + 0x84, 0x63, 0x57, 0x58, 0xbf, 0x79, 0x7e, 0x69, 0x5f, 0x4a, 0x2c, 0x87, + 0xce, 0x3a, 0xe9, 0x25, 0x32, 0x1b, 0x5e, 0x52, 0x77, 0xf1, 0xd5, 0xd9, + 0x77, 0x12, 0xf6, 0x3d, 0xd7, 0xe2, 0xb7, 0x36, 0xac, 0xbd, 0x9e, 0x7d, + 0xcf, 0x78, 0xec, 0x7b, 0x38, 0x58, 0xf5, 0xf9, 0x8f, 0x09, 0x9f, 0xdf, + 0xd1, 0xc0, 0x66, 0xac, 0xde, 0xe7, 0xef, 0xfd, 0xd8, 0x3e, 0x7f, 0xb9, + 0x75, 0x57, 0xe3, 0xf3, 0x1f, 0x69, 0xf9, 0x78, 0x3e, 0x9f, 0xd7, 0xac, + 0xaf, 0x65, 0x7a, 0xcf, 0x59, 0x8e, 0xca, 0x18, 0x7b, 0xb7, 0x27, 0xc6, + 0x66, 0xfc, 0xbe, 0x27, 0xef, 0x02, 0x9e, 0x5e, 0xeb, 0xc8, 0xdb, 0x51, + 0x19, 0xa7, 0x73, 0xec, 0x8d, 0xf7, 0xc2, 0x23, 0x90, 0xd1, 0x7c, 0x8f, + 0x8f, 0x54, 0x9a, 0x35, 0x9d, 0xb3, 0xed, 0x9f, 0x6f, 0xae, 0x17, 0xa1, + 0xcb, 0xc2, 0x9f, 0x24, 0x3e, 0x81, 0x5a, 0xea, 0x49, 0xc8, 0x8f, 0xbb, + 0xaf, 0x95, 0x6a, 0xa9, 0xf5, 0xe7, 0x1f, 0x7c, 0xee, 0x41, 0xca, 0x03, + 0x95, 0x73, 0x10, 0xaf, 0x4e, 0xe9, 0x94, 0x9d, 0x21, 0xdd, 0x8c, 0x93, + 0xb2, 0x8f, 0x71, 0x8e, 0xfd, 0xb0, 0x52, 0x6f, 0x3f, 0x24, 0x6b, 0x30, + 0xea, 0xb2, 0x77, 0x82, 0x7e, 0x02, 0x7c, 0x58, 0xaf, 0x9c, 0x1a, 0x8c, + 0xea, 0xdc, 0x09, 0x3a, 0xfe, 0xf3, 0xbb, 0x13, 0xc4, 0xf3, 0x6b, 0xb4, + 0xb7, 0xc1, 0x9d, 0x20, 0xdf, 0x2a, 0xef, 0x04, 0xad, 0x17, 0x35, 0x18, + 0x9e, 0xc7, 0xa9, 0xc1, 0x70, 0xbb, 0xb3, 0x8f, 0xe5, 0x3a, 0x4c, 0xa3, + 0x93, 0xb7, 0x88, 0x7b, 0xa8, 0x9d, 0x7d, 0xb5, 0xf2, 0xbd, 0xef, 0x13, + 0x8d, 0xa5, 0x79, 0xbd, 0xa3, 0x0d, 0xef, 0xb6, 0x24, 0x3f, 0xc1, 0x9a, + 0xcb, 0x21, 0x51, 0x73, 0xb9, 0xb3, 0xcd, 0x5b, 0x73, 0x51, 0x57, 0xb8, + 0xdb, 0x72, 0xa8, 0x41, 0xcd, 0xc5, 0xef, 0xb9, 0xdb, 0xe2, 0xf7, 0xdc, + 0x6d, 0x39, 0x24, 0xeb, 0x2b, 0xea, 0x2f, 0xd1, 0xdd, 0x96, 0xe4, 0x8a, + 0x77, 0x5b, 0xb6, 0x4a, 0x7d, 0xf5, 0xc2, 0xaf, 0xfe, 0xbc, 0x32, 0x55, + 0x67, 0xe7, 0x13, 0xc2, 0xce, 0xdf, 0xd5, 0xea, 0xb7, 0x9e, 0x69, 0xbb, + 0x9e, 0x9d, 0xdf, 0x57, 0xd1, 0x53, 0xbe, 0xa3, 0xcd, 0x77, 0xbe, 0x58, + 0x16, 0xf9, 0x7c, 0xa6, 0x89, 0x72, 0x03, 0xbf, 0x2a, 0x68, 0xf6, 0x58, + 0x6f, 0xed, 0x99, 0x63, 0xf5, 0x5e, 0xa4, 0xee, 0xb9, 0x17, 0x69, 0xa2, + 0x5f, 0xaf, 0xab, 0x87, 0x04, 0xe4, 0xdd, 0x7e, 0xf8, 0xc2, 0x19, 0x43, + 0xda, 0x5e, 0xc4, 0x70, 0x98, 0xae, 0x50, 0xe4, 0x3b, 0x95, 0x6d, 0xe4, + 0x9b, 0x71, 0xce, 0x4b, 0x54, 0x11, 0x63, 0x42, 0x8e, 0x8b, 0x7e, 0xe1, + 0x6f, 0xd4, 0xb8, 0x23, 0xb3, 0xe3, 0xf6, 0x05, 0xe0, 0xbf, 0x21, 0x51, + 0x6d, 0x9b, 0x95, 0x5a, 0xce, 0x58, 0xe5, 0x0e, 0xbf, 0x09, 0xfb, 0xe0, + 0xdc, 0x07, 0xca, 0x98, 0x7c, 0x67, 0xe4, 0x62, 0x5b, 0xf5, 0x3e, 0xd0, + 0x67, 0xa4, 0x9c, 0x3a, 0xf7, 0x81, 0x48, 0x4d, 0x40, 0x3e, 0x6e, 0xe4, + 0x3e, 0x50, 0xd7, 0x92, 0xfb, 0x40, 0x2b, 0xf3, 0x66, 0xe9, 0x7d, 0xa0, + 0xc6, 0xfc, 0xe1, 0xfb, 0x40, 0xff, 0xde, 0xe6, 0xdc, 0x43, 0x5d, 0x89, + 0x3f, 0x6e, 0x9c, 0xf4, 0x11, 0xe0, 0xf9, 0x3e, 0x50, 0xe5, 0x1e, 0x90, + 0xe7, 0x0e, 0x10, 0xdf, 0x25, 0x59, 0xee, 0x0c, 0xce, 0x7b, 0xff, 0xa4, + 0xa7, 0x72, 0xff, 0xe4, 0x7c, 0xc9, 0xf5, 0xed, 0xee, 0xb9, 0x1c, 0xc7, + 0x39, 0xbb, 0x44, 0x8e, 0x7a, 0xae, 0x54, 0x5b, 0xc3, 0x60, 0xbe, 0x8f, + 0x16, 0xcf, 0x81, 0x3e, 0x6f, 0x89, 0xdc, 0x00, 0x7c, 0xde, 0xe2, 0x23, + 0xe6, 0x1d, 0x29, 0xa0, 0x8b, 0x38, 0xcb, 0x75, 0xf8, 0xdd, 0x21, 0x64, + 0xc1, 0x91, 0x8b, 0xdd, 0x9e, 0xf3, 0xd0, 0xaa, 0x1c, 0x38, 0x67, 0xba, + 0x0e, 0xef, 0x6a, 0x65, 0x46, 0x9c, 0xdd, 0x0c, 0xed, 0xb5, 0x9c, 0xf3, + 0xc6, 0xa8, 0x38, 0xb7, 0x6d, 0xaf, 0xb3, 0x5b, 0x3a, 0xe4, 0x06, 0x31, + 0x67, 0x8c, 0xeb, 0xd5, 0x8c, 0xfb, 0x66, 0xc1, 0xe3, 0x46, 0x67, 0x71, + 0x2b, 0xd7, 0xf1, 0xdc, 0x9a, 0x0a, 0x21, 0x97, 0xd8, 0x9d, 0xce, 0x09, + 0xbb, 0xe9, 0xac, 0xdd, 0x29, 0xd6, 0xde, 0x58, 0x77, 0x96, 0xcd, 0x72, + 0xb5, 0x5c, 0x4c, 0x70, 0x3d, 0x9a, 0xde, 0xb3, 0x84, 0xa6, 0xb5, 0xba, + 0x84, 0xdc, 0xb5, 0x62, 0xe3, 0x3b, 0x2a, 0xba, 0x34, 0x2e, 0xee, 0x21, + 0xbb, 0xe7, 0xb5, 0x0e, 0xfd, 0xaa, 0xba, 0xb7, 0x5c, 0x3c, 0x53, 0x4f, + 0xbf, 0x4d, 0xff, 0x4b, 0xe8, 0x77, 0x15, 0xf4, 0xe3, 0x77, 0x03, 0xef, + 0xef, 0x8a, 0x7a, 0xc0, 0xb9, 0x52, 0xe4, 0x78, 0x9e, 0x38, 0x4e, 0x88, + 0xcc, 0x2e, 0x50, 0x0f, 0xe8, 0xc8, 0xff, 0xeb, 0xe2, 0xde, 0x9d, 0x60, + 0xfa, 0xb2, 0x7d, 0x8f, 0xbc, 0x70, 0x99, 0xd8, 0xc6, 0xdf, 0x8d, 0x7d, + 0x94, 0xcb, 0x2f, 0xc5, 0x5c, 0xfa, 0xb3, 0xee, 0x73, 0x9d, 0xaa, 0x76, + 0x5f, 0x7b, 0x57, 0xed, 0x53, 0x1d, 0xf9, 0xcc, 0x34, 0x90, 0xcf, 0x8c, + 0xdc, 0xa3, 0x6f, 0xa6, 0x71, 0xbc, 0x9a, 0x9a, 0xfc, 0xef, 0x5e, 0xae, + 0x26, 0xb6, 0x8d, 0x22, 0x0a, 0xbf, 0xac, 0xd7, 0x4e, 0xe3, 0xa4, 0x61, + 0x93, 0x3a, 0xad, 0x69, 0xd2, 0x60, 0xc7, 0x4b, 0x12, 0x29, 0xa5, 0xa4, + 0x52, 0x55, 0x45, 0x60, 0xa9, 0x21, 0x4e, 0xda, 0x0a, 0x71, 0x70, 0x0b, + 0x48, 0x51, 0xc5, 0x21, 0x4d, 0xd3, 0x7b, 0x85, 0x84, 0x54, 0xa1, 0x8a, + 0x46, 0x4e, 0x02, 0x15, 0x4a, 0xe5, 0x0a, 0x96, 0x72, 0x41, 0xa2, 0xd8, + 0x8e, 0x02, 0x52, 0x2a, 0xf7, 0xca, 0x85, 0xba, 0xbf, 0x08, 0x89, 0x03, + 0x70, 0x06, 0x29, 0x2a, 0x3f, 0xe2, 0xc0, 0x8d, 0x1b, 0x54, 0x5d, 0xde, + 0x37, 0xb3, 0x63, 0xaf, 0x77, 0xd7, 0x8e, 0x03, 0x11, 0x07, 0x27, 0xbb, + 0xf6, 0xcc, 0xce, 0xec, 0xcc, 0x37, 0x6f, 0xbe, 0xf7, 0x37, 0xfd, 0xbe, + 0x78, 0x8d, 0x5a, 0xdb, 0x5b, 0xf3, 0x55, 0xec, 0xe7, 0xaf, 0x37, 0x18, + 0x57, 0xed, 0xba, 0xe4, 0xa9, 0xf5, 0xe3, 0x9a, 0x72, 0xd9, 0x1b, 0xf0, + 0xfe, 0xc7, 0x68, 0x51, 0xd8, 0x86, 0x94, 0xad, 0xee, 0xc5, 0x40, 0x9b, + 0xd9, 0xff, 0x33, 0x16, 0x03, 0x3e, 0x9b, 0x68, 0xad, 0x6d, 0x8a, 0xed, + 0x71, 0xd9, 0x16, 0xde, 0xda, 0xc2, 0xb6, 0x10, 0x3c, 0x16, 0xfd, 0x9e, + 0xb1, 0xa8, 0xc9, 0xea, 0xa1, 0x16, 0xed, 0x74, 0x88, 0x21, 0xbf, 0x9d, + 0x67, 0x6c, 0x05, 0xca, 0xce, 0x4f, 0x5d, 0x36, 0x3c, 0xe0, 0x73, 0xdc, + 0x59, 0xeb, 0xc0, 0x27, 0xb5, 0x9d, 0x1a, 0x51, 0xed, 0x01, 0x8f, 0xc9, + 0xc5, 0x45, 0x82, 0xbe, 0x86, 0x36, 0xe3, 0x82, 0xe3, 0xfa, 0x39, 0x14, + 0x8f, 0xf1, 0xfa, 0x1b, 0x88, 0xe5, 0x70, 0xda, 0x3f, 0xd9, 0x76, 0xae, + 0x9c, 0xe5, 0xbd, 0x42, 0xd4, 0x63, 0xbd, 0xef, 0x52, 0xdb, 0x82, 0xa8, + 0x27, 0xe3, 0x20, 0x1c, 0x1d, 0xd0, 0xe1, 0xe2, 0x8d, 0x74, 0x3f, 0xff, + 0x9e, 0x13, 0xcc, 0xdd, 0x7f, 0xdd, 0x1d, 0x36, 0x3f, 0x34, 0x64, 0xae, + 0xde, 0x56, 0xdc, 0x5d, 0xd9, 0x89, 0x06, 0x85, 0xaf, 0xc1, 0xad, 0x7b, + 0x41, 0x76, 0x5d, 0xe0, 0x3d, 0x7c, 0xa8, 0xba, 0x7f, 0xef, 0x84, 0x7d, + 0xe8, 0x99, 0x16, 0x62, 0x1d, 0x44, 0x8e, 0xe5, 0x2b, 0x53, 0xc8, 0x45, + 0xaa, 0xe6, 0xef, 0x78, 0xf3, 0x3c, 0x20, 0x3f, 0x55, 0x9e, 0x87, 0xca, + 0x23, 0xc5, 0x7b, 0x24, 0x02, 0xf2, 0x3c, 0xdc, 0x32, 0x18, 0xf5, 0xea, + 0xdf, 0xc3, 0x2d, 0x7f, 0x57, 0x1c, 0xf9, 0x5b, 0xf0, 0xd8, 0xe3, 0x97, + 0xf3, 0x6a, 0x2d, 0x20, 0xe7, 0x43, 0xf1, 0x94, 0xde, 0x00, 0x9e, 0x12, + 0x9c, 0xeb, 0xa1, 0xa5, 0x2f, 0xf2, 0x5e, 0x7e, 0x08, 0x7b, 0xb9, 0x51, + 0x8b, 0xe9, 0x95, 0x72, 0xf0, 0xdc, 0x3a, 0x64, 0xa2, 0xca, 0xb9, 0x81, + 0x5c, 0x44, 0x2c, 0x3c, 0xe6, 0xba, 0xe4, 0x60, 0x11, 0xbf, 0xa9, 0x58, + 0x52, 0xa5, 0x47, 0xbd, 0x23, 0xf2, 0x0c, 0xbe, 0x1b, 0x3f, 0xcc, 0x1c, + 0x18, 0xf2, 0x13, 0x76, 0xa6, 0x43, 0x0e, 0x1f, 0xbe, 0xcc, 0xbf, 0x8d, + 0x39, 0xd7, 0x92, 0x8b, 0xca, 0x6b, 0xa5, 0x4b, 0xfd, 0xd0, 0x41, 0xe6, + 0x6f, 0x0e, 0x2f, 0xad, 0xb3, 0x41, 0xc4, 0x53, 0xda, 0xdb, 0x74, 0xa1, + 0xd8, 0x0c, 0x83, 0xf5, 0xf8, 0x4b, 0x79, 0x38, 0x4f, 0x42, 0x70, 0x9e, + 0x9f, 0x3a, 0xc2, 0xe6, 0x44, 0x4f, 0xb3, 0x38, 0x9c, 0x53, 0x55, 0xfc, + 0xa9, 0x72, 0xaa, 0x6f, 0x8f, 0x3a, 0x10, 0xa7, 0xe6, 0xc7, 0x04, 0xe6, + 0x1f, 0xfa, 0x9c, 0x5a, 0x87, 0xd0, 0xeb, 0x10, 0xf3, 0x87, 0x76, 0x8d, + 0x06, 0x6b, 0xb0, 0x66, 0x13, 0x2f, 0x50, 0x2b, 0xb1, 0x7f, 0xc9, 0xd1, + 0x0a, 0x9d, 0xed, 0x69, 0xa6, 0xf3, 0x9e, 0x08, 0xd4, 0x79, 0x83, 0x72, + 0xa4, 0xcc, 0x80, 0x1c, 0x29, 0x37, 0x0e, 0x75, 0x17, 0x0e, 0xe3, 0x2e, + 0x2e, 0x30, 0xc0, 0xdc, 0xb9, 0x8b, 0xf1, 0x04, 0xee, 0x1c, 0xa5, 0xd0, + 0x07, 0x6e, 0xee, 0xec, 0xf7, 0x13, 0x49, 0x5c, 0xfe, 0xdb, 0xdc, 0xa9, + 0xa0, 0x7e, 0x27, 0x7c, 0xfd, 0x86, 0x1c, 0x9f, 0x6c, 0xc8, 0x13, 0x82, + 0x38, 0xfe, 0x4e, 0xf7, 0xd3, 0xbb, 0xf6, 0xd1, 0xa6, 0x09, 0xfd, 0x70, + 0x74, 0xb1, 0xba, 0xee, 0x5f, 0xf0, 0xd9, 0xb9, 0xc1, 0x67, 0x43, 0xc2, + 0x27, 0xd7, 0x25, 0xf6, 0x90, 0x9d, 0x93, 0x61, 0x9d, 0x1e, 0x19, 0x66, + 0xf7, 0xd4, 0xec, 0xfc, 0x88, 0x21, 0xec, 0x73, 0x74, 0x0e, 0xb9, 0xef, + 0x14, 0x1a, 0xc6, 0xa5, 0xe2, 0x3b, 0xe9, 0x1b, 0x38, 0x77, 0x04, 0xb2, + 0x1b, 0xf2, 0xfc, 0xf4, 0x6c, 0xd8, 0x34, 0x1c, 0x1f, 0x03, 0xfc, 0x08, + 0xc0, 0xa9, 0x7a, 0x7e, 0x90, 0x0d, 0x3d, 0x68, 0x0e, 0x87, 0x7c, 0x73, + 0x28, 0xf1, 0x06, 0x6e, 0x8f, 0x58, 0xbc, 0x83, 0x9e, 0x38, 0xc5, 0x9d, + 0x18, 0x93, 0xee, 0x80, 0x78, 0x41, 0xc4, 0xfa, 0xf9, 0xfa, 0xcb, 0xef, + 0x7c, 0x51, 0xf3, 0xaf, 0xad, 0x49, 0x6d, 0xba, 0x3c, 0xad, 0x4d, 0x15, + 0x51, 0xee, 0xa2, 0x56, 0xdb, 0x97, 0x36, 0x5d, 0x1c, 0x11, 0x7c, 0x30, + 0x79, 0xad, 0x42, 0x78, 0x4f, 0xdb, 0xbe, 0x25, 0xb8, 0xed, 0x80, 0x0f, + 0xab, 0x8a, 0x73, 0x18, 0x2d, 0xbc, 0x97, 0xb4, 0xbd, 0xb8, 0xb9, 0x8e, + 0x5b, 0xbe, 0x3f, 0x1d, 0x20, 0xdf, 0x9b, 0xd9, 0x0a, 0x91, 0xbf, 0x29, + 0xe2, 0xb2, 0xa9, 0x68, 0x21, 0xde, 0xf1, 0x30, 0xe2, 0x7b, 0xe1, 0xd7, + 0xa8, 0x62, 0xe1, 0x6e, 0x30, 0x16, 0xaa, 0xf6, 0x60, 0x1d, 0xb9, 0xa3, + 0x2c, 0x8b, 0xc3, 0xe9, 0x5e, 0x0a, 0x99, 0x28, 0xff, 0x6c, 0xe2, 0x3e, + 0x1d, 0x73, 0x78, 0x09, 0xfc, 0x3c, 0xb2, 0xde, 0x4c, 0x0b, 0x76, 0xe1, + 0x60, 0x7f, 0x46, 0x84, 0x65, 0xf3, 0x67, 0xbd, 0xad, 0xf9, 0x33, 0x54, + 0x39, 0xd4, 0xed, 0xa2, 0x35, 0x0b, 0x71, 0x92, 0xf0, 0x2f, 0x75, 0x77, + 0xb4, 0x9b, 0x41, 0xf2, 0x4f, 0xc5, 0x7e, 0x82, 0x1f, 0xc9, 0xb9, 0xba, + 0x41, 0x98, 0x3b, 0x9b, 0xbe, 0x6f, 0x30, 0x57, 0xdb, 0xb1, 0x29, 0x37, + 0x9f, 0x2b, 0xc3, 0x33, 0x57, 0xd8, 0x8b, 0x9a, 0xcd, 0x95, 0xf2, 0x43, + 0x2a, 0xdf, 0xdc, 0x51, 0xc8, 0x93, 0x45, 0xf7, 0x5c, 0xed, 0x8c, 0x7f, + 0x4e, 0xce, 0xd9, 0x4e, 0xfb, 0xe0, 0x1a, 0x8f, 0x43, 0x34, 0xd0, 0x76, + 0x12, 0x2c, 0x33, 0xfc, 0x6b, 0xeb, 0x86, 0x5c, 0x5b, 0xcc, 0x2b, 0x9e, + 0x6f, 0xb8, 0xb6, 0xb0, 0x0f, 0x5c, 0x70, 0xf6, 0x81, 0xd3, 0x3e, 0x7d, + 0x51, 0xd9, 0xbc, 0xff, 0xab, 0xed, 0x0d, 0xcf, 0x7d, 0x22, 0xce, 0xe9, + 0xc8, 0x91, 0xdc, 0x47, 0xce, 0x37, 0xe4, 0x61, 0x3d, 0xdb, 0x5c, 0xa7, + 0x6a, 0xee, 0x91, 0x73, 0x01, 0x79, 0x99, 0xa5, 0xf3, 0xf9, 0xc7, 0x06, + 0x75, 0xf7, 0x53, 0xa4, 0x1a, 0xd3, 0x72, 0x40, 0xf0, 0x61, 0xb7, 0xbe, + 0xbc, 0xec, 0xe4, 0x28, 0xe6, 0x5c, 0x63, 0xb0, 0x9c, 0xcf, 0x36, 0x89, + 0xa7, 0x6f, 0x25, 0x9e, 0x63, 0xc0, 0x23, 0x37, 0xbd, 0x73, 0x35, 0xa1, + 0x65, 0xf2, 0xa8, 0xb3, 0x87, 0xce, 0xea, 0x9f, 0xf0, 0x18, 0x3d, 0xb1, + 0x23, 0xe2, 0x9c, 0x11, 0xe0, 0xd2, 0xb6, 0x97, 0xcd, 0x0e, 0x5a, 0x94, + 0x7e, 0x46, 0x9a, 0xfa, 0xf8, 0x12, 0x15, 0x85, 0x7f, 0x0b, 0xb9, 0x51, + 0xb0, 0x71, 0xc3, 0x47, 0x87, 0xe7, 0xf0, 0xf7, 0x1b, 0x13, 0x8e, 0xcc, + 0xfd, 0x93, 0x31, 0x8c, 0x7a, 0x38, 0x0b, 0x01, 0xeb, 0x9d, 0x34, 0xc9, + 0x31, 0xb9, 0x1d, 0x71, 0x4e, 0x80, 0x8c, 0xcd, 0xbb, 0x5d, 0xde, 0x8e, + 0x4f, 0xa1, 0x55, 0xbd, 0xe4, 0xeb, 0x68, 0xd8, 0xfc, 0x72, 0xcf, 0xf6, + 0x7d, 0x0a, 0x2a, 0x77, 0x5f, 0x71, 0x58, 0x75, 0x2d, 0x73, 0x69, 0xc1, + 0x99, 0xe7, 0xd7, 0x55, 0xde, 0x6d, 0x77, 0x40, 0xde, 0x6d, 0x88, 0xe6, + 0x84, 0xaf, 0x2e, 0x44, 0x39, 0x47, 0x37, 0x93, 0x9c, 0x5a, 0xd9, 0x6a, + 0x23, 0x4e, 0xfc, 0x29, 0xee, 0xdd, 0x39, 0xf9, 0x7c, 0x5f, 0x04, 0xcf, + 0x46, 0x4e, 0xb5, 0x2d, 0x62, 0xf1, 0x33, 0xa2, 0x5c, 0xa7, 0xa7, 0x1c, + 0xdf, 0x17, 0xd5, 0x33, 0x3b, 0xb9, 0x7c, 0x8a, 0x64, 0x0e, 0x7d, 0x27, + 0xcd, 0x15, 0x9b, 0xf5, 0x6b, 0x1f, 0xe2, 0x81, 0xe3, 0xf0, 0x95, 0x0a, + 0xbf, 0x95, 0xa1, 0xfa, 0x80, 0x3e, 0xb5, 0x57, 0xfb, 0x04, 0xf9, 0x14, + 0x12, 0x7e, 0x05, 0xbe, 0x76, 0xda, 0x99, 0x23, 0x77, 0xbf, 0xc2, 0xdc, + 0x2f, 0x3c, 0xa7, 0xd3, 0x55, 0xb6, 0xd3, 0x55, 0xb6, 0x36, 0x5e, 0x3a, + 0xeb, 0x54, 0x0b, 0xe5, 0x1f, 0x59, 0x2f, 0xfd, 0x56, 0xd8, 0xe6, 0xe6, + 0xb3, 0x06, 0x2d, 0xac, 0xf7, 0xf2, 0x27, 0xc6, 0x1f, 0x94, 0xdb, 0xcb, + 0xff, 0xdd, 0x9c, 0xa2, 0x5f, 0xc4, 0x02, 0xb6, 0xce, 0x07, 0x83, 0xf1, + 0x1f, 0xbc, 0x6e, 0x13, 0x01, 0xeb, 0xb6, 0xf9, 0xbe, 0x22, 0xf7, 0x93, + 0xe4, 0x95, 0x8a, 0x23, 0xaf, 0x36, 0x69, 0xd0, 0x27, 0xa7, 0x82, 0xd6, + 0x29, 0xfa, 0x78, 0xca, 0xe9, 0xe3, 0x9b, 0xa2, 0x3f, 0xe3, 0x54, 0xa8, + 0xe6, 0x0d, 0x1f, 0xe1, 0xeb, 0x98, 0xb2, 0xd1, 0x35, 0x90, 0xab, 0xdf, + 0x6c, 0x43, 0xc6, 0x04, 0x71, 0xb2, 0x03, 0x01, 0xfa, 0x80, 0xee, 0xd2, + 0x07, 0xe2, 0x55, 0x7d, 0x60, 0x45, 0xe8, 0x09, 0xbb, 0x1c, 0x1d, 0x34, + 0xd8, 0x16, 0x97, 0xcb, 0xe3, 0xcc, 0x1b, 0xd8, 0xf8, 0xa4, 0x1d, 0x7d, + 0xda, 0xaa, 0x9e, 0x99, 0xc3, 0xba, 0x65, 0x8d, 0x4b, 0xfb, 0xe5, 0x09, + 0xce, 0xac, 0xa8, 0xcc, 0x3e, 0x30, 0xa3, 0xa4, 0xa5, 0x93, 0xf1, 0xa9, + 0x50, 0x84, 0x16, 0xac, 0x28, 0x15, 0xac, 0x14, 0x73, 0x70, 0xf0, 0xe3, + 0xd0, 0x80, 0x46, 0x11, 0x96, 0x35, 0x11, 0x2a, 0x95, 0x94, 0x4e, 0x76, + 0x86, 0xc8, 0x2c, 0xc6, 0xa4, 0x0d, 0x9b, 0x71, 0x9a, 0x1f, 0x33, 0xe6, + 0x49, 0x43, 0xcc, 0x8b, 0x93, 0xa3, 0x0e, 0x0c, 0x8a, 0x38, 0x4b, 0xfd, + 0xe5, 0x91, 0x28, 0xb5, 0xa7, 0xa5, 0xcd, 0x68, 0x86, 0xdb, 0xf8, 0xc2, + 0x8a, 0xd1, 0x95, 0x7c, 0xd2, 0x38, 0xc1, 0xed, 0x64, 0xac, 0x64, 0x62, + 0x92, 0x9f, 0x5d, 0x2c, 0x45, 0x28, 0x67, 0x45, 0xa8, 0x50, 0x4a, 0x19, + 0x43, 0x6d, 0xa2, 0xcd, 0x18, 0xda, 0x7c, 0x49, 0x1f, 0x33, 0x4e, 0x92, + 0xbb, 0xcd, 0xaf, 0x9c, 0x36, 0xbd, 0x6d, 0xfd, 0x61, 0xe3, 0xfe, 0x44, + 0xa8, 0x32, 0x7b, 0x9f, 0xf1, 0x92, 0x5b, 0x9d, 0x60, 0xd9, 0x14, 0x13, + 0x67, 0xdb, 0x68, 0xe9, 0x34, 0xcb, 0x1d, 0x9c, 0x6d, 0x61, 0xd0, 0x62, + 0x39, 0x4e, 0xef, 0x57, 0xed, 0x07, 0x12, 0x43, 0x39, 0x91, 0x43, 0x84, + 0x33, 0x17, 0x2a, 0xb3, 0xbf, 0x9b, 0x5e, 0x7f, 0x3f, 0xeb, 0x5b, 0x1f, + 0xc5, 0x28, 0x72, 0x15, 0x71, 0xdd, 0x36, 0x5d, 0x1b, 0x4f, 0x5e, 0xd9, + 0x14, 0x79, 0x68, 0x09, 0x5a, 0x33, 0xa5, 0x3c, 0xcd, 0x71, 0xf9, 0x15, + 0x94, 0x5b, 0x4b, 0xd0, 0x3d, 0x91, 0x8f, 0xd6, 0x4e, 0x77, 0xf4, 0x18, + 0x85, 0x6e, 0x9a, 0xc6, 0xbc, 0xf0, 0x0b, 0x57, 0x66, 0x87, 0x86, 0x0d, + 0xd2, 0xae, 0xa2, 0x1e, 0xff, 0xbf, 0x89, 0xfb, 0x28, 0x61, 0x7e, 0x66, + 0xac, 0x31, 0x5e, 0x49, 0xc3, 0xf1, 0x12, 0x64, 0xf3, 0x41, 0x89, 0xa5, + 0x39, 0x23, 0x42, 0xd0, 0x5f, 0x61, 0x7b, 0xeb, 0x35, 0x27, 0x7b, 0xa4, + 0xfe, 0xe4, 0x3b, 0x9b, 0x43, 0x9f, 0x19, 0x71, 0x9f, 0xcf, 0x51, 0x7b, + 0x66, 0xc6, 0x92, 0xef, 0xb9, 0x52, 0xee, 0xa5, 0x25, 0x6e, 0x7b, 0x64, + 0xf8, 0x8c, 0x73, 0xa6, 0x0f, 0xff, 0xd9, 0x8b, 0x7b, 0x85, 0xb7, 0x7d, + 0x7d, 0x14, 0xc5, 0x3d, 0x0d, 0xe8, 0x3c, 0xc7, 0xb0, 0xe9, 0x87, 0xc5, + 0xb8, 0xa7, 0xe2, 0x98, 0xcb, 0xb9, 0xb8, 0x3a, 0x97, 0x08, 0x65, 0xba, + 0xe9, 0x91, 0xd5, 0x45, 0x3f, 0x8b, 0xf3, 0x47, 0xf8, 0xba, 0x84, 0x9c, + 0xa3, 0x36, 0xca, 0x64, 0xbb, 0x69, 0xb3, 0x14, 0x66, 0x71, 0x05, 0xec, + 0x44, 0xb9, 0x4c, 0x81, 0xa6, 0xd6, 0x5f, 0xeb, 0x83, 0x1f, 0x66, 0x52, + 0xab, 0x61, 0xe9, 0x51, 0x00, 0x96, 0x7e, 0xa9, 0xc3, 0xd2, 0xd1, 0xbe, + 0xe6, 0x58, 0xea, 0x77, 0x62, 0xd6, 0xa3, 0x14, 0x71, 0x70, 0xf4, 0x39, + 0xe3, 0xe8, 0x3d, 0xc6, 0xd1, 0xf1, 0x06, 0x38, 0xd2, 0x3c, 0x38, 0x3a, + 0x51, 0x87, 0xa3, 0x6c, 0x5f, 0x33, 0x1c, 0x1d, 0x0f, 0xa1, 0xff, 0xcd, + 0xd6, 0x32, 0xfa, 0xb0, 0x9f, 0x39, 0xbd, 0x49, 0xa5, 0xd5, 0xe4, 0xf8, + 0x24, 0x55, 0x90, 0x73, 0x92, 0x58, 0xa2, 0xb4, 0xe0, 0x76, 0x05, 0x81, + 0xbf, 0x2c, 0x8f, 0xc9, 0xae, 0x06, 0xe7, 0xaa, 0x24, 0x9c, 0x79, 0x93, + 0x73, 0x99, 0xc9, 0x57, 0x66, 0x1f, 0x32, 0x36, 0xee, 0x6d, 0xe8, 0x3a, + 0x7e, 0x0b, 0xb1, 0x8c, 0xbc, 0xbb, 0x81, 0x73, 0x5b, 0xe2, 0x74, 0xdf, + 0x1a, 0xa0, 0x7b, 0xd6, 0x7e, 0xba, 0x6b, 0x0d, 0xd2, 0x03, 0x0b, 0x6d, + 0x60, 0x0e, 0xf8, 0x5e, 0xcc, 0x81, 0x46, 0x33, 0x31, 0x2e, 0x53, 0xda, + 0x4f, 0x95, 0x92, 0xc2, 0x35, 0xb0, 0x03, 0x0c, 0x35, 0xc6, 0x4e, 0xa6, + 0x0e, 0x3b, 0xb2, 0x0e, 0x30, 0xb3, 0xe4, 0xb7, 0xad, 0xed, 0x32, 0xf8, + 0x5d, 0x0d, 0xc6, 0x56, 0x58, 0xc4, 0x91, 0x24, 0x47, 0x67, 0x42, 0x90, + 0x59, 0xb7, 0x18, 0x53, 0x3c, 0x17, 0x3c, 0x7e, 0xda, 0xf5, 0x41, 0x96, + 0x39, 0x4f, 0x09, 0x1b, 0xf4, 0x94, 0xa9, 0xc7, 0x33, 0x64, 0x5f, 0xd6, + 0xcc, 0x31, 0x91, 0xeb, 0xb6, 0x54, 0xf6, 0x9e, 0x31, 0x91, 0xe1, 0xb1, + 0x57, 0x78, 0xf4, 0xca, 0xa1, 0x76, 0xaa, 0x38, 0x31, 0x4c, 0x85, 0x55, + 0xdb, 0x7e, 0xc8, 0xfc, 0x7f, 0xcd, 0x84, 0xcc, 0xfe, 0xdb, 0xae, 0xc4, + 0x74, 0x5a, 0x36, 0x55, 0xdf, 0xee, 0x08, 0x7c, 0x31, 0x47, 0xa4, 0x77, + 0x37, 0xaa, 0xaf, 0xc4, 0xbf, 0xe3, 0xbb, 0xbf, 0x04, 0x97, 0x59, 0xab, + 0x96, 0x85, 0xed, 0xf8, 0xd2, 0xd8, 0xc2, 0x2a, 0xce, 0x7e, 0x7b, 0xfc, + 0xea, 0xf9, 0xd5, 0x5c, 0x1f, 0x4b, 0xd8, 0x94, 0x4e, 0x76, 0x68, 0x79, + 0x3c, 0xf7, 0x5c, 0x98, 0x86, 0x19, 0x97, 0x38, 0x83, 0x6b, 0x6c, 0x34, + 0x2c, 0xce, 0x38, 0xd9, 0xcd, 0x78, 0xc8, 0x0a, 0x3b, 0xfd, 0xd4, 0x91, + 0x09, 0x9a, 0x2c, 0xa7, 0xf9, 0x53, 0x3f, 0x7e, 0xb5, 0xb9, 0xe3, 0xe1, + 0x48, 0xe3, 0x37, 0x37, 0xff, 0xa8, 0xd5, 0x9d, 0xe6, 0xba, 0x33, 0x5b, + 0xd6, 0x55, 0xe7, 0x12, 0xfd, 0x03, 0x69, 0xae, 0x1b, 0xa3, 0xbc, 0x57, + 0x00, 0x00, 0x00 }; -static const u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 }; -static const u32 bnx2_COM_b06FwRodata[(0x88/4) + 1] = { - 0x08001c1c, 0x08001c4c, 0x08001c4c, 0x08001c4c, 0x08001c4c, 0x08001c4c, - 0x08001b74, 0x08001c4c, 0x08001bdc, 0x08001c4c, 0x08001b08, 0x08001c4c, - 0x08001c4c, 0x08001c4c, 0x08001b14, 0x00000000, 0x08002b58, 0x08002ba8, - 0x08002bd8, 0x08002c08, 0x08002c38, 0x00000000, 0x080060cc, 0x080060cc, - 0x080060cc, 0x080060cc, 0x080060cc, 0x08006100, 0x08006100, 0x08006140, - 0x0800614c, 0x0800614c, 0x080060cc, 0x00000000, 0x00000000 }; -static const u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x0 }; -static const u32 bnx2_COM_b06FwSbss[(0x60/4) + 1] = { 0x0 }; +static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x0 }; +static u32 bnx2_COM_b06FwRodata[(0x58/4) + 1] = { + 0x08002428, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c, 0x0800245c, + 0x08002380, 0x0800245c, 0x080023e4, 0x0800245c, 0x0800231c, 0x0800245c, + 0x0800245c, 0x0800245c, 0x08002328, 0x00000000, 0x08003240, 0x08003270, + 0x080032a0, 0x080032d0, 0x08003300, 0x00000000, 0x00000000 }; +static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x0 }; +static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x0 }; static struct fw_info bnx2_com_fw_06 = { - .ver_major = 0x3, - .ver_minor = 0x4, - .ver_fix = 0x3, + .ver_major = 0x1, + .ver_minor = 0x0, + .ver_fix = 0x0, - .start_addr = 0x080000b4, + .start_addr = 0x080008b4, .text_addr = 0x08000000, - .text_len = 0x7d54, + .text_len = 0x57bc, .text_index = 0x0, .gz_text = bnx2_COM_b06FwText, .gz_text_len = sizeof(bnx2_COM_b06FwText), - .data_addr = 0x08007e00, + .data_addr = 0x08005840, .data_len = 0x0, .data_index = 0x0, .data = bnx2_COM_b06FwData, - .sbss_addr = 0x08007e00, - .sbss_len = 0x60, + .sbss_addr = 0x08005840, + .sbss_len = 0x1c, .sbss_index = 0x0, .sbss = bnx2_COM_b06FwSbss, - .bss_addr = 0x08007e60, + .bss_addr = 0x08005860, .bss_len = 0x88, .bss_index = 0x0, .bss = bnx2_COM_b06FwBss, - .rodata_addr = 0x08007d58, - .rodata_len = 0x88, + .rodata_addr = 0x080057c0, + .rodata_len = 0x58, .rodata_index = 0x0, .rodata = bnx2_COM_b06FwRodata, }; diff --git a/trunk/drivers/net/bnx2_fw2.h b/trunk/drivers/net/bnx2_fw2.h index 2c067531f031..680c769a3fc0 100644 --- a/trunk/drivers/net/bnx2_fw2.h +++ b/trunk/drivers/net/bnx2_fw2.h @@ -1,13 +1,13 @@ /* bnx2_fw2.h: Broadcom NX2 network driver. * - * Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation + * Copyright (c) 2006 Broadcom Corporation * * 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, except as noted below. * * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004, 2005, 2006, 2007 Broadcom Corporation. + * source code, Copyright (c) 2006 Broadcom Corporation. * * Permission is hereby granted for the distribution of this firmware data * in hexadecimal or equivalent format, provided this copyright notice is @@ -15,3260 +15,3289 @@ */ static u8 bnx2_COM_b09FwText[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xdc, 0x5b, - 0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xef, 0xd9, 0xbb, 0xf2, 0x5a, 0x92, - 0xe5, 0x6b, 0x79, 0x23, 0x16, 0x4b, 0xc0, 0xae, 0x75, 0x6d, 0x69, 0xb0, - 0x43, 0x16, 0xa1, 0x80, 0x9a, 0xd9, 0xc0, 0xb2, 0x2b, 0x33, 0x9e, 0x0c, - 0x69, 0x64, 0x50, 0x80, 0xb6, 0x4c, 0x46, 0xec, 0x1a, 0x9a, 0x4e, 0x87, - 0xd6, 0xa6, 0x6e, 0x9b, 0xc9, 0x34, 0x78, 0x47, 0x1f, 0x8d, 0xa7, 0x15, - 0xba, 0x06, 0x1b, 0xd9, 0xd3, 0xd0, 0xa0, 0x6a, 0x71, 0xf1, 0x8f, 0x8d, - 0xaf, 0xf9, 0x48, 0xaa, 0x4c, 0x4d, 0xa5, 0x18, 0x48, 0x69, 0xa7, 0x4d, - 0xfb, 0xa3, 0x9e, 0xa1, 0x5f, 0x84, 0x32, 0xfd, 0xc1, 0x74, 0xda, 0x4e, - 0x3a, 0x24, 0x53, 0x08, 0x84, 0xed, 0xf3, 0x9c, 0x7b, 0xee, 0xea, 0x6a, - 0x25, 0x7f, 0xf1, 0x91, 0x1f, 0xd5, 0xcc, 0xfa, 0xde, 0xf3, 0xfd, 0x9e, - 0xf7, 0xbc, 0xef, 0xf3, 0x7e, 0xdc, 0xe3, 0x4f, 0x8a, 0xb4, 0x8a, 0xf9, - 0xdb, 0x80, 0x5f, 0xfa, 0xc1, 0xdf, 0x2c, 0x5f, 0x37, 0x78, 0xdd, 0x0d, - 0x78, 0xbd, 0x41, 0xc5, 0xec, 0x18, 0xeb, 0xf9, 0x4f, 0x12, 0xbf, 0x01, - 0xf3, 0xbe, 0xd6, 0x9f, 0x83, 0xdf, 0x9b, 0x68, 0x1c, 0xfb, 0x0f, 0x11, - 0xeb, 0x3c, 0x7d, 0xa2, 0x7f, 0xf5, 0xfa, 0x85, 0xdb, 0x15, 0x69, 0xb9, - 0x40, 0x7b, 0x2c, 0x58, 0x52, 0xd3, 0xcc, 0x9f, 0x24, 0x54, 0x6e, 0xec, - 0xe1, 0x82, 0x2b, 0x89, 0x58, 0x6e, 0xf7, 0xc1, 0xb2, 0x2b, 0x92, 0xaf, - 0xed, 0x48, 0x17, 0xe5, 0x67, 0xf5, 0x4a, 0xd2, 0x16, 0xd6, 0x5f, 0x95, - 0x7b, 0xef, 0xc9, 0x17, 0x6e, 0xca, 0xfc, 0x68, 0x2e, 0x26, 0x09, 0x27, - 0xf7, 0xbc, 0x38, 0xdb, 0x25, 0xd1, 0x83, 0x31, 0x4f, 0xf4, 0xe5, 0x2d, - 0xe9, 0x08, 0xe7, 0x7a, 0xb3, 0xfe, 0x42, 0x9f, 0x54, 0xb6, 0xe4, 0x12, - 0xa2, 0x72, 0xdb, 0x5e, 0x2d, 0xc4, 0x9c, 0xb1, 0x58, 0xce, 0x91, 0x45, - 0x5f, 0x46, 0xee, 0x9f, 0x96, 0x44, 0x22, 0xf7, 0xe5, 0xc4, 0xba, 0x6d, - 0x92, 0xb0, 0x73, 0x4b, 0x0f, 0xff, 0xbe, 0x7b, 0xb0, 0xae, 0x5c, 0xb7, - 0x7f, 0x5e, 0xda, 0x87, 0x4e, 0x0c, 0xa2, 0xbd, 0x96, 0xe9, 0x17, 0xb9, - 0x49, 0x94, 0x5b, 0x69, 0x8f, 0xb9, 0x09, 0x29, 0xf8, 0xae, 0x14, 0x7d, - 0x91, 0xbf, 0xac, 0x59, 0x72, 0xc2, 0xed, 0x92, 0xf9, 0x9d, 0xef, 0xd5, - 0xf3, 0xa0, 0xe5, 0xfb, 0xee, 0xd2, 0xc3, 0x93, 0x2e, 0xe9, 0x3d, 0x90, - 0x08, 0xe8, 0xdd, 0xbb, 0xae, 0xec, 0xda, 0x32, 0x5e, 0x63, 0xdd, 0xa8, - 0x62, 0x5d, 0x3c, 0x97, 0x68, 0x3d, 0xe1, 0xb6, 0x9b, 0xba, 0x57, 0x6f, - 0x29, 0x60, 0xbe, 0x89, 0x1a, 0xfb, 0xe6, 0xaf, 0x2f, 0xbb, 0x49, 0x53, - 0xbf, 0x70, 0x63, 0xc1, 0x4d, 0xa1, 0xbe, 0xc7, 0xb4, 0x8d, 0x3d, 0x58, - 0x76, 0x5d, 0xd3, 0xf6, 0x76, 0xac, 0xe0, 0xf6, 0x9b, 0xfa, 0xf7, 0x6e, - 0x2e, 0xbb, 0x3b, 0x4d, 0x7d, 0x0f, 0xe6, 0xca, 0x9a, 0xfa, 0x85, 0x7b, - 0xca, 0xee, 0xa0, 0xa9, 0xdf, 0x7d, 0x73, 0xc1, 0x1d, 0x32, 0xf5, 0x89, - 0xa1, 0xb2, 0x9b, 0x43, 0xfd, 0x97, 0x13, 0x6a, 0x9b, 0x23, 0x53, 0xb5, - 0x34, 0x7e, 0x79, 0xb4, 0x0d, 0xa3, 0x6e, 0x37, 0x7e, 0xb7, 0xe3, 0xf7, - 0xc8, 0x46, 0xe9, 0x18, 0xc1, 0xf3, 0xbf, 0xba, 0x03, 0xde, 0x81, 0x47, - 0x5e, 0x42, 0x5e, 0x8f, 0xa5, 0xe4, 0x85, 0xbe, 0xd7, 0xc1, 0x43, 0x47, - 0x4e, 0xfb, 0x62, 0x8d, 0xf4, 0xa5, 0xc0, 0xbb, 0xa4, 0x3c, 0xe3, 0xb7, - 0x49, 0xec, 0xb1, 0x18, 0x78, 0xf3, 0xcb, 0x52, 0x4a, 0x26, 0x64, 0xd3, - 0xac, 0x25, 0x5b, 0x07, 0x12, 0x92, 0x77, 0xb8, 0x36, 0x4e, 0x7b, 0x26, - 0x29, 0xb1, 0xd9, 0xfc, 0x66, 0x25, 0xdb, 0x9c, 0xa2, 0x54, 0xc0, 0xbb, - 0x57, 0x29, 0x97, 0x68, 0x4b, 0x4b, 0x71, 0xfa, 0x5a, 0x19, 0x73, 0x48, - 0xd7, 0x1f, 0x5c, 0x15, 0xac, 0x95, 0xb0, 0x0a, 0xc7, 0x46, 0x65, 0xca, - 0x6b, 0xb7, 0x8a, 0xc7, 0x6e, 0x96, 0x42, 0x56, 0x92, 0x18, 0x97, 0x2a, - 0xa1, 0xa5, 0x5a, 0x1b, 0x95, 0x49, 0x4f, 0xac, 0x82, 0x47, 0x7e, 0x76, - 0xa1, 0xbd, 0x43, 0xf7, 0x45, 0x5d, 0x4f, 0x4c, 0xcf, 0x9d, 0x40, 0xbd, - 0x83, 0xfa, 0x4e, 0x6b, 0x58, 0xcf, 0xa1, 0xeb, 0xd3, 0x13, 0xd2, 0x2e, - 0x4f, 0xd5, 0x92, 0xa6, 0x6f, 0xbd, 0x5e, 0xc8, 0x3a, 0xe8, 0x37, 0x2a, - 0x13, 0x5e, 0x52, 0xc6, 0xf0, 0x1c, 0xf7, 0xb8, 0x7e, 0x0a, 0x32, 0x75, - 0xdd, 0xc1, 0xd2, 0x51, 0x3d, 0x5f, 0x3a, 0x96, 0xe3, 0x7c, 0x3d, 0xe8, - 0xf7, 0x12, 0xe8, 0xb2, 0xc4, 0xd6, 0x67, 0x99, 0x97, 0xd2, 0xb4, 0x05, - 0x79, 0xc3, 0x53, 0xf3, 0x75, 0x18, 0xf4, 0xdb, 0xe2, 0x0e, 0x58, 0x52, - 0xc6, 0x59, 0x55, 0x1c, 0x94, 0x6b, 0x0b, 0xaa, 0xe0, 0xad, 0x93, 0xa2, - 0x9d, 0x96, 0xd8, 0x0c, 0x65, 0x69, 0x4c, 0x26, 0x30, 0x46, 0xb9, 0xec, - 0xf3, 0x0e, 0xf6, 0x3d, 0xa6, 0xcf, 0xa1, 0x25, 0x57, 0x51, 0x45, 0xbf, - 0x4b, 0xd4, 0xec, 0xbd, 0xf2, 0xd2, 0xb4, 0x38, 0x38, 0xc7, 0x7a, 0xc1, - 0x9d, 0x54, 0x85, 0xa7, 0x6d, 0x89, 0xcf, 0x58, 0x32, 0xe9, 0x66, 0xa0, - 0x01, 0x87, 0xd4, 0x2e, 0x7f, 0x01, 0xfd, 0x38, 0x0e, 0xfd, 0x6a, 0x0a, - 0x7c, 0xe5, 0xfb, 0x0e, 0x47, 0x69, 0x79, 0x66, 0x1f, 0x9c, 0x01, 0xf6, - 0xf1, 0x8c, 0x87, 0x33, 0xd1, 0x67, 0x94, 0xc6, 0x19, 0x89, 0x35, 0xdc, - 0x07, 0x99, 0x3a, 0x6a, 0x4b, 0x29, 0x8b, 0x7d, 0xa1, 0x77, 0x29, 0xbb, - 0x4c, 0xd7, 0xc4, 0x74, 0x33, 0x5d, 0x1c, 0x47, 0xba, 0x02, 0x9a, 0xc6, - 0x8f, 0x92, 0xbe, 0x65, 0x7a, 0xa6, 0xa6, 0x43, 0x1a, 0xb9, 0x1e, 0x69, - 0x0b, 0xe9, 0xe2, 0x38, 0xd2, 0xb5, 0x99, 0x67, 0xcd, 0x3f, 0x6b, 0x18, - 0x74, 0x4c, 0x78, 0x36, 0xce, 0xa8, 0x5d, 0x4a, 0x4e, 0xc5, 0x9a, 0x18, - 0xda, 0x91, 0x82, 0x36, 0x5b, 0xe3, 0x43, 0xa4, 0xd9, 0xc5, 0x39, 0xb6, - 0xe8, 0xf3, 0x56, 0xb9, 0x49, 0xf2, 0x0e, 0xfd, 0xb9, 0x3e, 0xde, 0x6b, - 0x8e, 0x4c, 0xea, 0xf9, 0x48, 0xd3, 0x47, 0x31, 0x0f, 0x69, 0x7d, 0x05, - 0xb2, 0x3a, 0x08, 0x19, 0xcd, 0xca, 0x5f, 0xf8, 0x3b, 0xe5, 0xcf, 0xfc, - 0x7e, 0xf9, 0x0e, 0xf4, 0xf6, 0xdb, 0x7e, 0x5a, 0x9e, 0xf7, 0x7b, 0xe4, - 0x39, 0x3f, 0x25, 0xcf, 0x6a, 0xf9, 0x1d, 0x16, 0xe9, 0xa0, 0x4c, 0xa7, - 0xa5, 0x13, 0xfa, 0xb3, 0x09, 0xba, 0xf9, 0x38, 0xf8, 0x77, 0xb4, 0x4f, - 0xf2, 0x9b, 0x73, 0x92, 0xb8, 0x1a, 0xbf, 0x2b, 0xf0, 0xeb, 0xca, 0xd9, - 0x5a, 0x56, 0xec, 0x1c, 0x79, 0x68, 0x4b, 0x51, 0xef, 0xd9, 0x96, 0x09, - 0xff, 0x91, 0xab, 0x03, 0xd9, 0x15, 0x19, 0x01, 0x8f, 0xd5, 0xc0, 0x4f, - 0xea, 0x79, 0x07, 0xfb, 0x18, 0xd8, 0xa1, 0x79, 0xaf, 0x06, 0x28, 0xb3, - 0x69, 0xc8, 0xbd, 0x6d, 0x15, 0xbd, 0x93, 0xc0, 0x8d, 0x36, 0xab, 0x70, - 0xa4, 0x22, 0xe5, 0x23, 0x75, 0x29, 0x67, 0xe3, 0xf2, 0x90, 0x53, 0x97, - 0xe1, 0x6c, 0x8b, 0xec, 0x77, 0xc0, 0xfb, 0x9d, 0xbf, 0x6d, 0x85, 0x98, - 0xfd, 0xb8, 0xff, 0x3b, 0x78, 0x67, 0x9d, 0xc8, 0x51, 0xfd, 0x1e, 0xd4, - 0x57, 0xfc, 0xb8, 0xe4, 0x93, 0x95, 0x94, 0x2d, 0x5b, 0x54, 0xb0, 0xee, - 0x78, 0xd8, 0x06, 0x7e, 0x2c, 0x01, 0x27, 0x33, 0x5a, 0x5f, 0x4a, 0xd3, - 0xeb, 0xdf, 0xce, 0xeb, 0x6a, 0xf4, 0x77, 0x06, 0xe5, 0xac, 0xe6, 0x67, - 0x7a, 0xcc, 0xca, 0x25, 0x65, 0x6b, 0x8d, 0xe5, 0x21, 0xeb, 0x4e, 0x9f, - 0xf2, 0x8c, 0x77, 0x9f, 0x74, 0x5e, 0x89, 0x7e, 0x36, 0x9e, 0x79, 0x43, - 0x6f, 0x94, 0x46, 0xce, 0x43, 0x1a, 0xf9, 0xfc, 0x66, 0x84, 0xc6, 0x27, - 0x1b, 0xef, 0x47, 0x23, 0xef, 0x15, 0xff, 0x8f, 0x5a, 0x03, 0xda, 0x86, - 0xe4, 0x8d, 0x99, 0xaf, 0x98, 0x75, 0xf0, 0x7e, 0x8a, 0xf3, 0x7f, 0xab, - 0x1e, 0xc8, 0x4b, 0xe5, 0x22, 0xeb, 0x2c, 0x44, 0xd6, 0xf9, 0x6e, 0x64, - 0x9d, 0xef, 0x46, 0xd6, 0xa9, 0x80, 0xa7, 0xb2, 0x51, 0x41, 0x86, 0x4b, - 0x34, 0x63, 0x72, 0x08, 0x73, 0xbe, 0x2e, 0xb1, 0x1c, 0xf5, 0x3c, 0xc4, - 0x9b, 0x73, 0xe8, 0x9f, 0x93, 0xb3, 0x33, 0x15, 0x29, 0x1d, 0x89, 0xcb, - 0x1d, 0xba, 0xdf, 0x26, 0x43, 0x5f, 0xb4, 0x2d, 0x21, 0x7b, 0x92, 0x7c, - 0x0f, 0xdb, 0x6c, 0xf0, 0x99, 0xe5, 0x6f, 0x5d, 0x19, 0x94, 0xf9, 0xbe, - 0x60, 0xf6, 0x32, 0x1a, 0x8c, 0x3b, 0xf5, 0xa6, 0xc6, 0xc3, 0x45, 0x9f, - 0xb8, 0x25, 0xd9, 0x98, 0x2b, 0xfb, 0x86, 0xb3, 0x5d, 0x32, 0xe1, 0x58, - 0xd9, 0xf1, 0xfe, 0x75, 0xd4, 0x8b, 0xbc, 0x72, 0xdb, 0x80, 0x0d, 0x92, - 0x56, 0xc4, 0x7c, 0xbd, 0x2f, 0x4b, 0x05, 0xf4, 0x3b, 0x2c, 0x8f, 0x28, - 0xb7, 0xb3, 0xa9, 0x9e, 0xba, 0x1d, 0xc3, 0x3b, 0x65, 0x78, 0x97, 0x39, - 0x63, 0x1b, 0x65, 0xe2, 0xf0, 0x35, 0xa6, 0x1c, 0xb6, 0x6f, 0xb6, 0x57, - 0x96, 0xcf, 0x76, 0xaf, 0x2c, 0x87, 0x38, 0x11, 0xc5, 0x70, 0xee, 0x15, - 0xf8, 0xe4, 0x52, 0xee, 0xe2, 0xa0, 0x35, 0x0b, 0x9d, 0x5b, 0x67, 0x68, - 0xb8, 0xc2, 0xd0, 0x00, 0x5a, 0xfb, 0x20, 0x59, 0x5a, 0x97, 0xb4, 0x68, - 0x35, 0x95, 0xc9, 0xfb, 0xf0, 0x7d, 0x83, 0x6e, 0x0f, 0x74, 0x2e, 0x7c, - 0x86, 0xf8, 0xfe, 0x66, 0xc4, 0x5e, 0xf4, 0x40, 0x67, 0x93, 0xe0, 0x55, - 0x88, 0xf5, 0xc4, 0xe0, 0x14, 0xec, 0x03, 0x64, 0x55, 0x63, 0x7b, 0x3b, - 0xf0, 0xd0, 0x36, 0xd8, 0x9c, 0x30, 0xd8, 0xdc, 0x0e, 0x5c, 0x66, 0xd9, - 0x31, 0xe5, 0xa4, 0x29, 0xa7, 0x50, 0x86, 0x1d, 0x9f, 0x25, 0x2e, 0x5f, - 0x77, 0x70, 0xef, 0x51, 0x8d, 0xf7, 0xb4, 0x15, 0x40, 0x61, 0xe2, 0x35, - 0x71, 0xbb, 0x47, 0xe6, 0x6b, 0x58, 0xaf, 0x81, 0x8d, 0xdc, 0x7b, 0x94, - 0x1e, 0xd2, 0xb2, 0x5e, 0x14, 0x6c, 0x57, 0x3e, 0x49, 0x7a, 0x1f, 0xc4, - 0xde, 0x89, 0x3f, 0xa4, 0xfb, 0x2a, 0xd0, 0xca, 0x7d, 0xfc, 0x3c, 0x69, - 0xe5, 0x7a, 0xcd, 0xf4, 0x7e, 0x58, 0x1c, 0x24, 0xed, 0x27, 0xb1, 0xe7, - 0x3c, 0x30, 0x4f, 0xac, 0xd1, 0xbe, 0x51, 0xec, 0x79, 0x04, 0x78, 0x78, - 0x3b, 0xf0, 0x70, 0x37, 0xf0, 0x70, 0x18, 0x78, 0x98, 0x03, 0x16, 0x0e, - 0x01, 0x0b, 0x07, 0x81, 0x85, 0x59, 0xf0, 0x26, 0x29, 0x73, 0xc0, 0xc6, - 0x39, 0x60, 0xe4, 0x1c, 0xe6, 0x18, 0x9f, 0x15, 0xeb, 0x4b, 0xd8, 0xc3, - 0x63, 0x33, 0x99, 0x93, 0x90, 0xa5, 0x54, 0x45, 0x41, 0xfe, 0xb3, 0x43, - 0x90, 0xed, 0x7e, 0xa9, 0xfa, 0xb6, 0x94, 0x69, 0x53, 0xb7, 0xf7, 0x42, - 0xd7, 0x20, 0xef, 0x29, 0x31, 0x7f, 0x1b, 0xcc, 0xf3, 0x1f, 0x45, 0xdc, - 0xbf, 0xa3, 0x2c, 0xa6, 0x45, 0xce, 0x48, 0xc9, 0xeb, 0x75, 0x0a, 0xaa, - 0x1f, 0xfd, 0x58, 0xce, 0xaa, 0xfb, 0x8f, 0x5c, 0xaf, 0xf6, 0x1e, 0x21, - 0x5f, 0xa6, 0x81, 0x57, 0x75, 0x99, 0xcc, 0x52, 0xb7, 0xea, 0x72, 0x22, - 0x9b, 0x19, 0xaa, 0x48, 0x9b, 0x4c, 0x25, 0xa7, 0xb5, 0xad, 0xb5, 0x73, - 0x87, 0xb5, 0xbd, 0x2a, 0xbb, 0x78, 0xd6, 0x06, 0x54, 0xe9, 0x08, 0xf7, - 0xdf, 0x8b, 0x5f, 0x1c, 0xb4, 0x70, 0x7e, 0x5b, 0x86, 0x07, 0x1d, 0xf5, - 0x40, 0x5f, 0x05, 0x08, 0x96, 0x71, 0xce, 0x62, 0xe5, 0xe2, 0x74, 0x6f, - 0xaa, 0xa8, 0x6c, 0x19, 0xb3, 0x2d, 0x19, 0x87, 0x7c, 0x0f, 0x67, 0xdf, - 0xa9, 0x4f, 0x25, 0xd9, 0xbe, 0x4e, 0xbe, 0xae, 0x7d, 0x0e, 0xac, 0x5d, - 0x3d, 0x8a, 0x75, 0xe3, 0x38, 0x03, 0xae, 0xcb, 0x79, 0x50, 0xae, 0xd9, - 0x28, 0x67, 0x4e, 0x56, 0xc4, 0x87, 0x9e, 0x6c, 0x94, 0xc2, 0xce, 0x16, - 0xc9, 0x8f, 0xa4, 0x65, 0x7c, 0xc6, 0x07, 0x4e, 0xe1, 0x1c, 0xdd, 0x56, - 0x29, 0x8d, 0xa6, 0xe5, 0xd1, 0x19, 0xd6, 0x9d, 0xc6, 0xfe, 0x33, 0x87, - 0xf2, 0xc2, 0xfd, 0xc7, 0xf5, 0xbe, 0xd2, 0xea, 0xb4, 0xec, 0xf7, 0xde, - 0x30, 0x7a, 0x14, 0x94, 0xef, 0xc7, 0x99, 0x9e, 0xf0, 0x17, 0xb0, 0x7f, - 0x57, 0xe6, 0x81, 0xff, 0xc5, 0x23, 0xc0, 0x41, 0xb7, 0x03, 0x98, 0x95, - 0x59, 0xa0, 0x4d, 0x8d, 0xc1, 0xef, 0xab, 0x6a, 0x5e, 0xf7, 0xc8, 0x91, - 0x19, 0x25, 0xdf, 0xbe, 0x31, 0x8d, 0x32, 0xb0, 0x31, 0x9b, 0x39, 0x3d, - 0xa6, 0x7a, 0xe4, 0x86, 0xce, 0x14, 0xc6, 0xe5, 0x54, 0xc9, 0xdb, 0x18, - 0x03, 0x2f, 0x8f, 0xa7, 0x15, 0xfb, 0x2a, 0x29, 0x66, 0x63, 0x38, 0xff, - 0x0a, 0xfa, 0xbf, 0x8f, 0xf5, 0x7a, 0x64, 0x16, 0xbe, 0xd6, 0xec, 0x4c, - 0x1e, 0xe3, 0x88, 0x5d, 0x99, 0xe3, 0x4b, 0x0a, 0x18, 0x33, 0x0b, 0xf9, - 0x1e, 0x85, 0x2f, 0x33, 0x03, 0xd1, 0x69, 0x4d, 0xe3, 0x4c, 0x7b, 0x9d, - 0x71, 0xe0, 0x41, 0xbe, 0x87, 0xef, 0x9c, 0xd3, 0x95, 0x13, 0x1e, 0xe5, - 0x30, 0x2d, 0x4f, 0xf9, 0x1c, 0xd7, 0xbb, 0xf0, 0x1c, 0x7c, 0x9f, 0xdf, - 0xf5, 0xae, 0x44, 0xff, 0x77, 0xe1, 0x07, 0x3b, 0x52, 0xc5, 0xb9, 0x95, - 0xc1, 0xcb, 0x7c, 0x2a, 0x28, 0x8f, 0xcf, 0x66, 0x16, 0xde, 0x50, 0x7c, - 0x77, 0x2b, 0xf3, 0xea, 0x5a, 0x91, 0x4e, 0xf2, 0x33, 0x0b, 0x5e, 0xba, - 0x8e, 0x52, 0xdb, 0x8d, 0xef, 0x47, 0x3d, 0x72, 0x41, 0x9f, 0x2d, 0xf3, - 0x03, 0x51, 0x3d, 0xa2, 0x3d, 0x0c, 0xf5, 0x28, 0x93, 0x5a, 0x52, 0x0a, - 0xed, 0xb6, 0x1c, 0xd6, 0x65, 0x0b, 0xb4, 0x66, 0x52, 0xdc, 0xdf, 0x44, - 0xad, 0x5f, 0x9e, 0xf2, 0xd8, 0x1f, 0x7c, 0x9e, 0x6e, 0x37, 0xfd, 0x4f, - 0x83, 0x87, 0xf4, 0xdf, 0xfa, 0x41, 0x73, 0xa0, 0x5b, 0xf3, 0xd3, 0x49, - 0xdd, 0x36, 0xe5, 0x05, 0x7e, 0x9a, 0x82, 0x2f, 0x37, 0x07, 0x5f, 0xae, - 0xa8, 0xf5, 0xcc, 0xc9, 0xc3, 0xd7, 0x87, 0x9e, 0x04, 0x3a, 0x56, 0xad, - 0x91, 0x96, 0xbb, 0x40, 0x5f, 0xa6, 0x02, 0x62, 0x0e, 0xab, 0x1c, 0xce, - 0x7d, 0x50, 0x2a, 0xf4, 0xf7, 0xce, 0xc6, 0x9e, 0x92, 0xb1, 0x2a, 0xed, - 0x11, 0x7e, 0x9e, 0xeb, 0x30, 0xbe, 0xc8, 0x6b, 0x5b, 0xd1, 0x0d, 0x39, - 0x80, 0x1d, 0xc9, 0x6e, 0x32, 0x7e, 0xce, 0x13, 0x38, 0xcf, 0x33, 0x38, - 0xf7, 0x9a, 0xec, 0x3d, 0xf6, 0x0a, 0x65, 0xba, 0xbf, 0x2a, 0x99, 0xfe, - 0x29, 0xd9, 0xe1, 0xcc, 0x43, 0x1f, 0xf3, 0xa3, 0xf5, 0x5b, 0x54, 0x8e, - 0x63, 0x0e, 0x62, 0x0c, 0x9e, 0xd5, 0x57, 0xe4, 0x21, 0x9f, 0x75, 0x0f, - 0x81, 0x9f, 0xd0, 0x95, 0xc1, 0x27, 0x8c, 0x1e, 0x60, 0x3e, 0x3b, 0x9c, - 0xef, 0x15, 0x33, 0x1f, 0xfb, 0xb1, 0x0f, 0xc7, 0x2c, 0xcf, 0xbb, 0x8b, - 0xb6, 0x08, 0x78, 0xb4, 0x4b, 0xd5, 0x6f, 0x89, 0xa3, 0xfd, 0xc4, 0x20, - 0xdf, 0x31, 0x0f, 0x6c, 0x91, 0xe3, 0x9e, 0x41, 0x5f, 0xf8, 0x7a, 0xde, - 0x7a, 0x29, 0x74, 0x85, 0xf4, 0x52, 0x06, 0xe8, 0x27, 0x68, 0x1b, 0xbc, - 0x39, 0xe0, 0xfd, 0x1f, 0xc6, 0x02, 0x99, 0x3c, 0x80, 0x32, 0xf5, 0xef, - 0x80, 0x14, 0xbd, 0x0c, 0xf6, 0x09, 0x1d, 0xf3, 0x3b, 0xac, 0x60, 0x8f, - 0xe0, 0xff, 0xc8, 0x39, 0xf0, 0x41, 0x2a, 0x01, 0x6f, 0xc8, 0x17, 0xf2, - 0xa4, 0x03, 0xb2, 0x0f, 0xb9, 0x87, 0xdc, 0x96, 0x34, 0x0f, 0xfe, 0xbd, - 0x33, 0xf0, 0x8b, 0x33, 0x95, 0x3c, 0xe3, 0xb9, 0x4e, 0xe2, 0x26, 0x30, - 0xcc, 0x87, 0x70, 0x60, 0xee, 0x25, 0xb5, 0x9e, 0xf4, 0xa6, 0x97, 0x62, - 0x7d, 0x2c, 0xf7, 0x2f, 0x41, 0x86, 0xab, 0x38, 0x9f, 0xc2, 0xce, 0x5e, - 0x83, 0x5b, 0xcf, 0xc6, 0x28, 0xaf, 0x55, 0x60, 0x4c, 0xc9, 0xdb, 0xe1, - 0xdc, 0x4d, 0xbe, 0x39, 0x8e, 0x3c, 0xe7, 0x45, 0xb1, 0x03, 0xb6, 0xcf, - 0xa5, 0x1c, 0x26, 0x21, 0x07, 0x36, 0x6c, 0x68, 0x0a, 0x67, 0xfe, 0x6f, - 0x9d, 0xc1, 0x5e, 0xf8, 0x6e, 0xcb, 0x9c, 0x83, 0x35, 0xbd, 0xc5, 0x8d, - 0x41, 0x1d, 0xdf, 0xb7, 0xf0, 0x8c, 0x0e, 0xaf, 0xa4, 0x9d, 0xe7, 0xdb, - 0x7c, 0xa6, 0x27, 0xb0, 0x17, 0xd6, 0xe3, 0x59, 0x3d, 0x2e, 0x7b, 0x89, - 0x9b, 0x83, 0xdb, 0x52, 0x2f, 0xa2, 0x7f, 0x11, 0x36, 0xa1, 0x62, 0xb3, - 0xed, 0x6d, 0x6b, 0x79, 0x8c, 0xa2, 0x5f, 0x0a, 0x1f, 0x78, 0xc9, 0xfa, - 0x92, 0xff, 0x92, 0x55, 0xa8, 0xbe, 0x6d, 0x15, 0x21, 0x27, 0x55, 0x8f, - 0xf1, 0x0b, 0xf5, 0xc7, 0xc1, 0xda, 0x99, 0xd4, 0x5b, 0xaa, 0x37, 0x3d, - 0x0f, 0x2c, 0xb8, 0x1f, 0x3a, 0x5d, 0xb4, 0x17, 0xa4, 0xec, 0xd7, 0xa4, - 0x74, 0x6c, 0x07, 0xf4, 0x2d, 0x1d, 0xa1, 0x8b, 0x78, 0x56, 0xa1, 0x1f, - 0x6e, 0xed, 0xf2, 0xa4, 0xd2, 0x92, 0x23, 0xae, 0x6d, 0x83, 0xec, 0xa0, - 0xae, 0xb6, 0x2c, 0x7f, 0xb7, 0xad, 0xa2, 0x15, 0xb1, 0xee, 0xe0, 0x4a, - 0x7a, 0xab, 0x72, 0x71, 0x7a, 0x77, 0x35, 0xe8, 0x25, 0x66, 0x00, 0xff, - 0x3d, 0xe0, 0xbf, 0x07, 0xfc, 0xf7, 0x80, 0xff, 0x1e, 0xf0, 0xdf, 0x83, - 0x6d, 0xf0, 0x60, 0x03, 0x3c, 0xd8, 0x00, 0x0f, 0x36, 0xc0, 0x83, 0x0d, - 0xf0, 0x0a, 0x38, 0x27, 0xe2, 0x3c, 0x6d, 0xc8, 0x3d, 0x0d, 0xbb, 0x19, - 0xf8, 0x39, 0x57, 0x1a, 0xdf, 0x01, 0xfa, 0xe7, 0x6c, 0x91, 0xf1, 0xfe, - 0x2b, 0xb0, 0xb7, 0x56, 0x3c, 0xdb, 0xf0, 0xc4, 0x1a, 0xfd, 0x9f, 0x35, - 0x7a, 0xf2, 0x55, 0xd0, 0xa5, 0x50, 0xfe, 0x05, 0xc8, 0x61, 0x0b, 0xe8, - 0xf9, 0x94, 0xf1, 0x31, 0xbe, 0x61, 0x07, 0x72, 0xd8, 0x86, 0xba, 0xcf, - 0xa0, 0xae, 0x0d, 0x7d, 0xf6, 0xa3, 0x0f, 0x7d, 0x94, 0x0e, 0x53, 0x17, - 0xed, 0x47, 0x5f, 0xe5, 0x0b, 0x58, 0x2b, 0x83, 0x7e, 0x1d, 0x98, 0xbb, - 0x07, 0x7d, 0x6e, 0x46, 0x9f, 0xab, 0x50, 0xa6, 0x6f, 0xdb, 0x8d, 0xf2, - 0xa7, 0x9b, 0xc6, 0x5c, 0x83, 0xba, 0xcf, 0x36, 0xd5, 0x9d, 0x45, 0x1d, - 0x62, 0x62, 0xe7, 0x45, 0x33, 0xae, 0x82, 0x72, 0x57, 0x53, 0x9f, 0x57, - 0x50, 0x37, 0x84, 0xba, 0xbf, 0xc2, 0x13, 0xb1, 0xb0, 0x43, 0x9a, 0xc2, - 0x36, 0xfa, 0xa9, 0x69, 0xd4, 0xc7, 0x8d, 0xaf, 0xf9, 0x24, 0x7d, 0x2f, - 0xd8, 0xdc, 0x3f, 0xb6, 0x03, 0xdf, 0x0c, 0xde, 0xab, 0x96, 0xc3, 0xb0, - 0xfc, 0xcd, 0xa6, 0x32, 0xfb, 0x7e, 0xbf, 0xa9, 0xae, 0x6d, 0xd3, 0xca, - 0xf2, 0x4f, 0xe3, 0xab, 0xc7, 0xdc, 0xdb, 0xd4, 0xe7, 0xeb, 0x9d, 0x2b, - 0xcb, 0xbb, 0x5b, 0x56, 0x8f, 0xd9, 0xbe, 0x71, 0x65, 0xdd, 0xad, 0x9b, - 0x57, 0x96, 0xe9, 0x03, 0x26, 0x11, 0xc3, 0x84, 0xfd, 0x77, 0x7e, 0x22, - 0x68, 0x27, 0x7f, 0x9b, 0x65, 0x49, 0x2b, 0x23, 0xca, 0x0a, 0xe7, 0xb0, - 0x64, 0x41, 0x9f, 0x1c, 0x95, 0x7b, 0xc9, 0x2a, 0x42, 0xa6, 0x0a, 0x7e, - 0x38, 0x1f, 0x75, 0xb6, 0x39, 0x4f, 0x10, 0xe6, 0x07, 0xe8, 0x6f, 0xb5, - 0x43, 0x6e, 0xee, 0xa2, 0x4d, 0x3a, 0x54, 0x91, 0x65, 0xfd, 0xdc, 0xaa, - 0xce, 0xa7, 0x9f, 0xf7, 0x19, 0x8c, 0x3a, 0x07, 0x3a, 0xeb, 0x32, 0x92, - 0x5d, 0x47, 0x1b, 0x63, 0xb0, 0x8b, 0xb8, 0x53, 0xaf, 0xc7, 0xb6, 0xd7, - 0x65, 0x5f, 0xf6, 0xdd, 0xba, 0x68, 0xcc, 0xbb, 0x57, 0xe3, 0x4e, 0x5a, - 0x75, 0xe3, 0x8c, 0x1c, 0xc4, 0x12, 0x88, 0xed, 0x93, 0xb4, 0x49, 0xc7, - 0xe9, 0x9f, 0x1c, 0x0c, 0x30, 0x95, 0xb8, 0x83, 0xb2, 0x3f, 0x85, 0x39, - 0xb9, 0x3e, 0x9e, 0x55, 0xe2, 0xb8, 0xad, 0x6d, 0x4a, 0xc9, 0xe1, 0xbc, - 0x6b, 0x61, 0xe3, 0xbf, 0xd8, 0xf4, 0x0b, 0x6d, 0xf7, 0x24, 0xec, 0x1b, - 0xdb, 0xe8, 0x2b, 0x9c, 0xa4, 0x5f, 0x12, 0xc1, 0xaa, 0x9b, 0x62, 0xe2, - 0x2e, 0x63, 0x66, 0xb0, 0xaf, 0x2d, 0xf4, 0xfb, 0x2f, 0x61, 0xaf, 0x6b, - 0x63, 0x51, 0xaf, 0xba, 0xb8, 0x6e, 0xef, 0x69, 0xe8, 0x76, 0x28, 0x7b, - 0x6b, 0xe5, 0x03, 0x5e, 0xd5, 0x67, 0xf1, 0xac, 0x9f, 0x39, 0x5c, 0x81, - 0x2e, 0x2d, 0xea, 0xd8, 0x37, 0x3c, 0x17, 0xfa, 0x38, 0x99, 0xe3, 0x73, - 0x90, 0xed, 0xbd, 0x3a, 0x26, 0x60, 0x3c, 0x50, 0x97, 0x5d, 0xd9, 0x4f, - 0x25, 0xc9, 0x87, 0xbc, 0xfa, 0x71, 0x9c, 0x3e, 0xc3, 0xa2, 0x47, 0x9e, - 0x65, 0xd1, 0x9e, 0x05, 0x26, 0xfc, 0xab, 0x14, 0x93, 0xac, 0x7b, 0xab, - 0x3e, 0x0f, 0xbf, 0x4a, 0xfb, 0x47, 0xda, 0xde, 0xd3, 0xbf, 0x83, 0x5d, - 0xf7, 0xc9, 0xd3, 0x25, 0xf0, 0x39, 0xf4, 0x01, 0x7e, 0x40, 0x1f, 0x55, - 0x56, 0xfa, 0xd2, 0x22, 0x0f, 0xd5, 0xfe, 0x01, 0x36, 0x47, 0x05, 0xbe, - 0x0a, 0xe3, 0x65, 0x97, 0xf5, 0x37, 0xc6, 0xe9, 0xcb, 0x05, 0xb6, 0x3e, - 0x86, 0xf5, 0x10, 0x5f, 0xd7, 0xfe, 0xd3, 0x2a, 0x79, 0x3d, 0xf4, 0xb3, - 0xb0, 0x7f, 0xf8, 0x50, 0x3e, 0xdb, 0x58, 0x97, 0x30, 0xfe, 0x77, 0xbb, - 0xf1, 0xb7, 0x1d, 0xe3, 0x6f, 0x6b, 0x3a, 0x12, 0x4e, 0x2e, 0xf4, 0x0b, - 0x78, 0x66, 0xe9, 0x83, 0x6a, 0x3b, 0xfd, 0x82, 0x0e, 0x59, 0xdb, 0x2f, - 0x08, 0x69, 0x3a, 0x85, 0x7d, 0xd2, 0xcf, 0xd3, 0x79, 0xa0, 0xce, 0x20, - 0xf7, 0x44, 0x1a, 0x42, 0xfb, 0xa8, 0xed, 0xf0, 0x21, 0x98, 0x3c, 0xe6, - 0x24, 0x41, 0xeb, 0x6e, 0x29, 0x4c, 0x9f, 0x32, 0xf6, 0x96, 0x71, 0x04, - 0x7d, 0xf8, 0x40, 0x66, 0x0b, 0xd9, 0x0e, 0xcb, 0xcc, 0xd3, 0x05, 0x0b, - 0x19, 0xc9, 0x51, 0x71, 0x2d, 0xfa, 0x31, 0xa1, 0x4f, 0xb3, 0x60, 0x7c, - 0x9a, 0x33, 0xb2, 0xcf, 0x0b, 0xe2, 0x86, 0x91, 0xda, 0x12, 0xea, 0x34, - 0xed, 0x29, 0xfa, 0x96, 0x0a, 0x3e, 0x77, 0xfe, 0xde, 0x0c, 0x02, 0x90, - 0x60, 0x2f, 0x5b, 0xb1, 0x97, 0x6a, 0x63, 0x2f, 0x6d, 0x4b, 0xcd, 0x3e, - 0x0e, 0xc7, 0x4e, 0xae, 0x1a, 0x2b, 0xd8, 0xc7, 0xdc, 0x79, 0xda, 0xb8, - 0x47, 0xfa, 0x0d, 0x8e, 0xd9, 0x63, 0x78, 0x4e, 0x8f, 0x63, 0x8f, 0x49, - 0xab, 0xa4, 0x7d, 0x2d, 0xfa, 0x2d, 0x88, 0xb3, 0x6b, 0x2f, 0xe1, 0x49, - 0xfd, 0xd0, 0xf3, 0x60, 0x4f, 0xed, 0x7a, 0x4f, 0x53, 0xde, 0x2b, 0x7a, - 0x1f, 0xf3, 0xb5, 0xbf, 0x91, 0xf2, 0xb1, 0x1f, 0xc0, 0xee, 0x45, 0x73, - 0x73, 0xcc, 0x6b, 0x92, 0x1f, 0x95, 0x08, 0x7e, 0x72, 0xaf, 0xcc, 0xbb, - 0xbd, 0x1c, 0x0f, 0xe2, 0x83, 0x69, 0x9c, 0xb1, 0x15, 0xb4, 0xeb, 0xf5, - 0x43, 0xbe, 0xb6, 0x44, 0xe8, 0xa9, 0xc3, 0xe7, 0x4c, 0x81, 0x86, 0xe8, - 0x98, 0x03, 0x32, 0xec, 0xf1, 0x3c, 0x7a, 0x53, 0x7b, 0xc5, 0x75, 0x4a, - 0x12, 0xfa, 0x19, 0x5c, 0x9f, 0x3a, 0x5f, 0x84, 0xe3, 0xcb, 0x5c, 0x6a, - 0xc8, 0xbb, 0x90, 0x6f, 0xed, 0x4b, 0xcd, 0x32, 0x30, 0x89, 0x58, 0xab, - 0xec, 0x91, 0x4f, 0xa1, 0x6c, 0x86, 0x6b, 0xbf, 0x6a, 0x71, 0x3f, 0x13, - 0x3a, 0x7f, 0xf8, 0x4f, 0x0d, 0x19, 0x1d, 0x07, 0x76, 0x04, 0x32, 0xf7, - 0xf7, 0x86, 0x37, 0xa1, 0x6c, 0xb6, 0x9b, 0x73, 0x66, 0x2c, 0x48, 0xdd, - 0x09, 0xe5, 0x60, 0x9b, 0x73, 0xa7, 0xe6, 0x05, 0xdb, 0xb4, 0xcf, 0xad, - 0xcf, 0x72, 0xac, 0x71, 0x96, 0x1b, 0x9a, 0xe4, 0xf2, 0xdd, 0x8d, 0x81, - 0x1e, 0x52, 0xdf, 0xa0, 0xb7, 0xe0, 0xd7, 0xb3, 0x2b, 0xf4, 0xbb, 0xff, - 0x3c, 0x39, 0xd9, 0x76, 0x89, 0xcd, 0x7e, 0x0f, 0xbc, 0xbc, 0x06, 0xb1, - 0x8a, 0x88, 0x3d, 0x43, 0x1c, 0xa2, 0xbf, 0xb1, 0xec, 0xef, 0xce, 0xcb, - 0x5a, 0xbe, 0xee, 0xc5, 0x7c, 0x8d, 0x4f, 0x5e, 0xa2, 0xaf, 0x31, 0xdc, - 0x22, 0xad, 0xc4, 0xa2, 0x33, 0xf0, 0x6d, 0x2d, 0x69, 0x71, 0xbf, 0x01, - 0x1b, 0x76, 0xda, 0x5e, 0xe7, 0x86, 0x98, 0xd0, 0x2e, 0x9b, 0x66, 0xb7, - 0x68, 0x5c, 0x70, 0x66, 0x96, 0x71, 0x61, 0x1c, 0xbc, 0x1f, 0x09, 0xf2, - 0xbc, 0xc9, 0x4d, 0x72, 0xa9, 0xf1, 0xf5, 0xb2, 0xdf, 0x3f, 0xd6, 0xf0, - 0xfb, 0xaf, 0x6c, 0xe2, 0xe3, 0x5a, 0xb8, 0x78, 0x1a, 0x7c, 0xcb, 0x21, - 0xfe, 0x65, 0x5c, 0x3b, 0x8c, 0x78, 0x98, 0xb1, 0x58, 0x1e, 0x31, 0x71, - 0xe6, 0xb4, 0xc8, 0x6e, 0xc4, 0xc8, 0x99, 0x1f, 0x31, 0x7f, 0xf5, 0xbc, - 0x9f, 0x99, 0x13, 0xb9, 0x1d, 0x7c, 0x1d, 0x04, 0x6e, 0x66, 0x81, 0xa3, - 0x3b, 0xc1, 0xdf, 0x7e, 0x8d, 0x9d, 0xf7, 0x1f, 0x11, 0xeb, 0x0e, 0x9d, - 0xab, 0xa6, 0x3e, 0x27, 0x61, 0x47, 0xeb, 0xf5, 0xfd, 0xd9, 0x5e, 0xc4, - 0xf5, 0x69, 0xb9, 0xd5, 0x66, 0x1c, 0x6b, 0xd9, 0x5b, 0x07, 0xe6, 0x63, - 0x51, 0x9f, 0xb4, 0x70, 0x51, 0x3b, 0xb0, 0x9a, 0xf7, 0x45, 0x6d, 0x0b, - 0x0e, 0xc7, 0x2e, 0xc4, 0xfb, 0x3b, 0x1a, 0xbc, 0x6f, 0x69, 0x95, 0xd6, - 0xdb, 0x75, 0x1e, 0x61, 0xeb, 0xc0, 0x7e, 0xe2, 0x55, 0x16, 0x76, 0x1d, - 0xf6, 0xb7, 0x2e, 0xb7, 0x65, 0xdf, 0xae, 0xbf, 0xe8, 0x6e, 0x94, 0xd2, - 0xce, 0xfb, 0x0c, 0x66, 0x2f, 0x7d, 0xad, 0xe0, 0x56, 0xa0, 0x1f, 0x41, - 0xce, 0x70, 0xef, 0x74, 0x02, 0x96, 0x80, 0x7f, 0x9d, 0x32, 0x3f, 0xf4, - 0x16, 0xce, 0x70, 0xc7, 0x49, 0x26, 0x9c, 0x14, 0x70, 0x78, 0x3e, 0xd9, - 0xae, 0xf3, 0xc5, 0x9f, 0x70, 0x59, 0xef, 0xe0, 0x4c, 0x47, 0x65, 0x1e, - 0xfe, 0x43, 0x75, 0x08, 0x34, 0xee, 0xec, 0x42, 0x7f, 0xea, 0x1d, 0x79, - 0x3e, 0x0a, 0xdb, 0x4b, 0x9e, 0x26, 0xd1, 0x7f, 0x0f, 0xfa, 0x74, 0xe2, - 0x79, 0x5f, 0x6c, 0xde, 0x61, 0xec, 0xfc, 0x79, 0x94, 0x39, 0x47, 0xd4, - 0x76, 0x7e, 0x2e, 0x2e, 0x7a, 0x4e, 0x8e, 0xe9, 0xd2, 0xfa, 0xbf, 0xbc, - 0x16, 0xd7, 0x61, 0xdb, 0xcf, 0xea, 0xd7, 0x0f, 0x0c, 0x45, 0xd6, 0xeb, - 0x88, 0xac, 0x37, 0x14, 0x59, 0x8f, 0x74, 0x76, 0x46, 0xe8, 0xec, 0xc4, - 0xf8, 0x22, 0xd6, 0x26, 0x3f, 0xa2, 0x6b, 0x3e, 0x18, 0x59, 0x33, 0xdc, - 0x5f, 0x57, 0x64, 0xdc, 0xbb, 0x58, 0x8f, 0x75, 0xc9, 0x48, 0x1d, 0x69, - 0xd8, 0x8c, 0x3a, 0x96, 0x3b, 0x23, 0x74, 0x91, 0xd6, 0x0d, 0xa8, 0xd7, - 0xfe, 0x13, 0xf8, 0xdc, 0x0a, 0xbb, 0xa5, 0x60, 0x3b, 0x5a, 0xe0, 0x5f, - 0x35, 0xef, 0xf5, 0x51, 0xac, 0x1b, 0xce, 0x97, 0xc4, 0x1c, 0xec, 0xcf, - 0xbe, 0x31, 0x33, 0x9e, 0xf5, 0x6c, 0xff, 0xf3, 0xfa, 0x9f, 0x6a, 0xbe, - 0x6d, 0x06, 0xed, 0x3a, 0xef, 0x22, 0x73, 0x9d, 0x36, 0xce, 0x93, 0xf1, - 0xb1, 0x25, 0x57, 0xbb, 0xca, 0xea, 0x1d, 0xe0, 0xd9, 0x6f, 0x34, 0x58, - 0xda, 0x6a, 0x15, 0x8e, 0x30, 0x5f, 0xd0, 0x66, 0x62, 0x3e, 0xc4, 0x1e, - 0xda, 0xc6, 0xd8, 0xa6, 0x9d, 0x36, 0x86, 0x7e, 0x0b, 0xed, 0xe7, 0x69, - 0xf3, 0x8e, 0x27, 0x64, 0xf8, 0x81, 0x6a, 0xa7, 0xbc, 0xa8, 0x79, 0xea, - 0xc8, 0xd9, 0x06, 0x4f, 0xe3, 0xe6, 0xbb, 0xcc, 0x01, 0xf3, 0xcd, 0xa3, - 0x0f, 0x7e, 0x11, 0xde, 0x6b, 0x79, 0xd0, 0x90, 0x96, 0xde, 0x01, 0xc6, - 0x6e, 0x15, 0x3c, 0x99, 0xa7, 0xb0, 0xf0, 0x0c, 0xf2, 0x17, 0xbd, 0x03, - 0xb0, 0x4b, 0xc0, 0xa1, 0xde, 0x81, 0x73, 0x3a, 0x9e, 0xab, 0xfa, 0x8e, - 0x75, 0x9b, 0x17, 0xe4, 0x88, 0xce, 0xba, 0x17, 0xca, 0x11, 0xdd, 0xb3, - 0x8e, 0x79, 0x8d, 0x30, 0x47, 0x74, 0x56, 0x74, 0x8e, 0xe8, 0xf8, 0x45, - 0x72, 0x44, 0xf9, 0x4b, 0xcf, 0x11, 0x71, 0x7e, 0x5b, 0xee, 0x1c, 0x74, - 0xd4, 0xaf, 0x9a, 0x1c, 0xd1, 0x1b, 0x12, 0xe4, 0x88, 0x5e, 0x94, 0xb5, - 0x73, 0x44, 0x87, 0x9a, 0x72, 0x44, 0x9b, 0x75, 0x8e, 0x88, 0xf3, 0x04, - 0x39, 0x22, 0x96, 0x4b, 0x03, 0x43, 0x91, 0x5c, 0x07, 0xf0, 0xd7, 0xbb, - 0x01, 0x7c, 0x73, 0xac, 0x51, 0x2f, 0xc4, 0x34, 0x62, 0xff, 0x15, 0x0d, - 0xfb, 0xb5, 0x8c, 0x6f, 0x96, 0x96, 0xb9, 0x8b, 0xe1, 0xdb, 0x68, 0xe0, - 0x97, 0xac, 0xc0, 0xb6, 0xc9, 0x86, 0xef, 0xe2, 0xad, 0x63, 0x0c, 0x3d, - 0x51, 0x5b, 0x9e, 0x77, 0x02, 0xbc, 0x1e, 0x6b, 0xe4, 0x49, 0xce, 0xe7, - 0x1f, 0x25, 0xe5, 0xc0, 0x9a, 0xdf, 0xbd, 0x52, 0xf9, 0xd5, 0xdf, 0xbd, - 0x2c, 0x49, 0x82, 0xce, 0xd2, 0x40, 0x49, 0xc7, 0x5d, 0xf3, 0xde, 0xaf, - 0xc8, 0xd2, 0xdd, 0x0e, 0xf0, 0x27, 0xcc, 0x9f, 0xf0, 0x7c, 0x97, 0x6d, - 0x4a, 0x41, 0x7d, 0x7c, 0x39, 0x94, 0x07, 0x74, 0x0e, 0xe5, 0xc5, 0x75, - 0xd1, 0x1c, 0xca, 0x59, 0xb9, 0x70, 0x0e, 0xe5, 0x81, 0x35, 0x72, 0x28, - 0x2f, 0xcb, 0x72, 0x0e, 0xe5, 0x65, 0x09, 0x73, 0x28, 0x31, 0x59, 0xda, - 0x1c, 0x48, 0xe3, 0x03, 0xfe, 0x12, 0x7e, 0x67, 0xf0, 0x0b, 0x72, 0x2a, - 0x67, 0x1b, 0xf4, 0xaf, 0x95, 0x53, 0x79, 0x7d, 0xdd, 0x07, 0xc9, 0xa9, - 0x04, 0x36, 0x20, 0xcc, 0xa9, 0xe0, 0xe7, 0xc0, 0xe6, 0xa8, 0x68, 0x4e, - 0xe5, 0x27, 0xd4, 0x07, 0xd4, 0xb1, 0xcc, 0x7a, 0xe8, 0x05, 0xec, 0x52, - 0x5e, 0xe7, 0x38, 0x3e, 0x67, 0x78, 0x38, 0x87, 0x3d, 0xa7, 0x71, 0x16, - 0xe4, 0x63, 0xaf, 0xf6, 0x2d, 0xf3, 0x76, 0xca, 0x2a, 0xf4, 0xc1, 0x9a, - 0x4d, 0xf3, 0xbb, 0xb8, 0x6d, 0xed, 0xf5, 0x29, 0xe3, 0x09, 0xab, 0x8c, - 0xbd, 0x0c, 0x4f, 0xcf, 0xc9, 0x5e, 0x3f, 0xf4, 0xa9, 0x06, 0x1a, 0x73, - 0x50, 0x37, 0xe7, 0x81, 0xb3, 0xc0, 0x89, 0x4b, 0xb0, 0x51, 0xa7, 0x40, - 0x73, 0x74, 0x1f, 0x88, 0x89, 0x07, 0x51, 0xa7, 0xcf, 0x9c, 0xbe, 0x65, - 0x48, 0x4b, 0x9a, 0x7a, 0x7e, 0x09, 0xf3, 0xb1, 0xee, 0x94, 0x8e, 0xc7, - 0xca, 0x83, 0xdc, 0x2b, 0x6d, 0xdd, 0x22, 0xe8, 0x43, 0x5d, 0x95, 0x31, - 0x20, 0xed, 0x5e, 0x18, 0xa3, 0xb5, 0xeb, 0x18, 0xad, 0x4b, 0xf3, 0x83, - 0xbc, 0xbe, 0x35, 0x41, 0xac, 0xec, 0x72, 0xb9, 0x87, 0x33, 0x06, 0xeb, - 0x58, 0x0e, 0x62, 0xc1, 0xbc, 0xe2, 0xfb, 0xef, 0xe1, 0x5c, 0x99, 0xa7, - 0x09, 0xcf, 0xef, 0x2b, 0x66, 0xdf, 0x43, 0x52, 0xe9, 0x92, 0xc4, 0x66, - 0xd0, 0x53, 0x9a, 0xa1, 0xdf, 0xfd, 0x69, 0x1d, 0x83, 0x24, 0xdd, 0xf3, - 0xeb, 0xed, 0x1d, 0x97, 0xa1, 0xb7, 0x23, 0x17, 0xd4, 0xdb, 0xaf, 0x25, - 0xa2, 0x7a, 0x7b, 0xc7, 0x65, 0xe8, 0xed, 0xbe, 0xcb, 0xd2, 0x5b, 0xee, - 0x8d, 0x98, 0x14, 0xe6, 0xc4, 0x56, 0xfb, 0x59, 0xe1, 0xba, 0xe3, 0x58, - 0x33, 0x7f, 0x9e, 0x35, 0xc7, 0xce, 0x9b, 0x5b, 0x6d, 0xf6, 0xb1, 0x2e, - 0xe5, 0xbc, 0x19, 0x5b, 0xd1, 0xde, 0xb6, 0x1b, 0xbb, 0x74, 0x9f, 0x89, - 0xe7, 0xc3, 0xb8, 0x3e, 0xaa, 0x3f, 0x94, 0x0b, 0xca, 0xc2, 0x77, 0xc0, - 0x2f, 0xca, 0x43, 0xa8, 0x73, 0xdd, 0x4d, 0x32, 0xb8, 0x88, 0x78, 0xbf, - 0xdb, 0xc8, 0x20, 0xcf, 0xba, 0x4f, 0x7f, 0x67, 0xaa, 0x7a, 0x4f, 0x05, - 0x71, 0xbe, 0x8b, 0x67, 0x35, 0xd4, 0x35, 0xf0, 0x24, 0x19, 0xb6, 0x91, - 0x8f, 0x2e, 0x7c, 0x9e, 0x1d, 0xf0, 0xd7, 0xc0, 0x23, 0x5d, 0xbf, 0x32, - 0x27, 0x7c, 0x61, 0x3c, 0x93, 0x4a, 0x1c, 0x7d, 0x4f, 0x0c, 0x42, 0xc7, - 0x07, 0x89, 0x51, 0x35, 0xc4, 0x3d, 0x94, 0x43, 0xca, 0xe6, 0xb6, 0xfe, - 0x5d, 0x8a, 0x3e, 0xd5, 0x13, 0x88, 0x83, 0x29, 0xaf, 0x69, 0xd9, 0xe5, - 0x6f, 0x3b, 0x7d, 0x56, 0x71, 0x8d, 0x7a, 0xbd, 0xc4, 0x58, 0xd1, 0x11, - 0xb5, 0x75, 0xe0, 0xbf, 0x13, 0xb4, 0x4b, 0x57, 0xb8, 0x31, 0x23, 0x6b, - 0x79, 0xbc, 0x53, 0x6e, 0x7f, 0x08, 0x7b, 0xcf, 0xef, 0xfd, 0xaf, 0xa1, - 0x3e, 0x05, 0x9d, 0xa7, 0x7d, 0x67, 0x3c, 0x72, 0x93, 0xe9, 0xd7, 0xad, - 0xbf, 0x57, 0x16, 0xb2, 0x37, 0x98, 0x6f, 0x57, 0xb4, 0x3f, 0x19, 0xda, - 0xec, 0x15, 0xe7, 0xcc, 0xfb, 0x12, 0x45, 0x1d, 0xcf, 0x70, 0xbc, 0x96, - 0x49, 0xc4, 0x20, 0x76, 0x24, 0x97, 0x9e, 0x30, 0xb1, 0x1b, 0x75, 0xac, - 0x1d, 0x67, 0xe8, 0x9b, 0x58, 0x85, 0xf1, 0xeb, 0xca, 0x7b, 0x12, 0x6b, - 0xcb, 0xc0, 0x96, 0x0f, 0x20, 0x03, 0xcd, 0xe7, 0x97, 0x80, 0xee, 0x87, - 0xe7, 0x17, 0xfa, 0x31, 0x73, 0x66, 0xdf, 0xdd, 0xc1, 0x19, 0xfe, 0xbf, - 0xd8, 0xa7, 0x15, 0xd9, 0x67, 0x88, 0x47, 0x0f, 0x98, 0x7d, 0xde, 0xd4, - 0x84, 0x47, 0x23, 0x4d, 0x3a, 0xfb, 0x71, 0xe2, 0xd1, 0x9f, 0xac, 0xff, - 0xf8, 0xf1, 0x88, 0xfb, 0xea, 0x5e, 0x13, 0x87, 0x82, 0x7d, 0x3c, 0x22, - 0x2a, 0xf7, 0x51, 0xc6, 0x7b, 0x1f, 0xe4, 0x7c, 0xa2, 0x38, 0xc2, 0x33, - 0xe9, 0xd0, 0x3e, 0x6c, 0xa0, 0x7b, 0xb0, 0xe5, 0xd5, 0xb8, 0xbc, 0x7e, - 0x57, 0x42, 0xfe, 0xf7, 0x46, 0x7e, 0x0f, 0xb3, 0x4d, 0x4e, 0x8b, 0xe5, - 0xd7, 0xd6, 0x07, 0x76, 0xe8, 0xb5, 0x4d, 0x81, 0xdd, 0xe1, 0x98, 0x50, - 0x9f, 0x1d, 0xb4, 0xb3, 0xad, 0x5b, 0x96, 0x3a, 0x2f, 0x27, 0x06, 0xdc, - 0xe6, 0xbc, 0xa1, 0xd6, 0x8a, 0x01, 0x2f, 0x9c, 0x0f, 0x5c, 0x8e, 0x01, - 0x89, 0xb3, 0x9d, 0x5a, 0x36, 0x4a, 0x49, 0xc6, 0x3e, 0x7d, 0x06, 0x3b, - 0xf9, 0x8e, 0xd8, 0xd6, 0x43, 0xbc, 0xeb, 0x21, 0xd6, 0xf5, 0x10, 0xff, - 0x7a, 0x88, 0x71, 0x3d, 0xc4, 0xb6, 0x1e, 0x62, 0x5b, 0x0f, 0xb1, 0xad, - 0xd7, 0x6f, 0x62, 0xe4, 0x11, 0x93, 0xf7, 0xe7, 0x77, 0x72, 0xe6, 0x17, - 0x2a, 0xb0, 0x25, 0x93, 0xbc, 0xe7, 0xa0, 0x0a, 0xd9, 0xf5, 0x66, 0x7f, - 0x61, 0x4e, 0xbc, 0xc7, 0xe4, 0x6c, 0x5e, 0xd7, 0x79, 0x43, 0x51, 0xb3, - 0xad, 0xc1, 0xb7, 0x74, 0xde, 0xc7, 0xf8, 0x2d, 0xf8, 0x25, 0xfa, 0x3e, - 0x13, 0x75, 0xb4, 0xae, 0x72, 0xcc, 0xc9, 0x88, 0x52, 0xb9, 0xeb, 0x31, - 0x66, 0x47, 0x10, 0x13, 0x24, 0x25, 0xa6, 0x72, 0x6d, 0xe4, 0xa9, 0xa5, - 0x72, 0x1b, 0xcc, 0x5c, 0x47, 0x5b, 0x03, 0xdf, 0xaa, 0x8f, 0x65, 0x5b, - 0xe5, 0x6e, 0xe6, 0x13, 0xe7, 0x1e, 0xd6, 0xf7, 0x74, 0xae, 0x5c, 0x6b, - 0x4a, 0xe3, 0x7b, 0x21, 0x7b, 0x37, 0xe6, 0xd3, 0xf7, 0x88, 0x1a, 0xfc, - 0x56, 0xe7, 0xe5, 0xf7, 0x94, 0xe1, 0x77, 0xc0, 0xe3, 0x18, 0xfb, 0xe9, - 0xbc, 0x30, 0x79, 0x1d, 0xce, 0xa7, 0xf3, 0x7a, 0x58, 0x47, 0xdf, 0xa5, - 0xc0, 0x53, 0xc5, 0xa5, 0x63, 0xf4, 0x9e, 0xb8, 0x1b, 0x5d, 0x37, 0xfc, - 0x26, 0x7e, 0x29, 0x6b, 0x76, 0xeb, 0xef, 0x68, 0x81, 0xcd, 0x98, 0xd2, - 0x32, 0x68, 0xe7, 0xb8, 0xaf, 0xf7, 0x21, 0x7f, 0x53, 0x5a, 0xfe, 0x8a, - 0x88, 0x63, 0x26, 0x07, 0xb7, 0xa5, 0x6d, 0x75, 0xa0, 0x95, 0xf9, 0xd7, - 0x61, 0x3f, 0xc4, 0x3d, 0xae, 0xd7, 0x6c, 0xc7, 0x99, 0x57, 0x0b, 0xf1, - 0x4c, 0xb6, 0x04, 0xf9, 0xb6, 0x0f, 0xa3, 0x4b, 0xad, 0x4d, 0xba, 0x14, - 0xee, 0x93, 0xfb, 0xe7, 0x73, 0xed, 0x3b, 0x15, 0x8b, 0x7e, 0xe4, 0xfb, - 0x48, 0x43, 0x36, 0x78, 0xb7, 0xe4, 0x8b, 0x90, 0x41, 0xfd, 0x9d, 0x02, - 0x7a, 0x54, 0xaf, 0x0f, 0x33, 0xc7, 0xbc, 0xf3, 0x0b, 0xe6, 0xde, 0x82, - 0x3c, 0xcc, 0xfc, 0x83, 0xbd, 0x2a, 0xff, 0x30, 0x0c, 0x59, 0x81, 0x0f, - 0xe0, 0x75, 0x68, 0x9f, 0x4e, 0xb9, 0xf4, 0x07, 0x9a, 0xbf, 0xbf, 0x3c, - 0xda, 0x16, 0xf0, 0xe1, 0xed, 0xd6, 0xe0, 0x1b, 0xc4, 0xdf, 0x26, 0x57, - 0x96, 0x39, 0xfe, 0x7f, 0x8c, 0xac, 0x1c, 0x86, 0x6d, 0x1e, 0x86, 0x2c, - 0x22, 0x26, 0xd7, 0xf3, 0x1d, 0x96, 0xd2, 0xd3, 0x0b, 0x9d, 0x2b, 0xfb, - 0xa3, 0xee, 0x58, 0xd8, 0xff, 0xb1, 0xa6, 0xfe, 0x8f, 0xa1, 0xff, 0x0b, - 0x4d, 0xfd, 0x1f, 0x8b, 0xf4, 0x3f, 0xda, 0xd4, 0x1f, 0x31, 0xe2, 0xd3, - 0xff, 0xdc, 0xd4, 0xff, 0x68, 0xa4, 0xff, 0x6c, 0x53, 0xff, 0x59, 0xf4, - 0x7f, 0xad, 0xa9, 0x3f, 0xea, 0x8e, 0xb5, 0x98, 0xef, 0x62, 0xc4, 0xd8, - 0x7d, 0x26, 0x16, 0xc7, 0xb3, 0xd6, 0xfc, 0xad, 0x85, 0x72, 0xd7, 0x83, - 0x33, 0x08, 0xef, 0xb4, 0x51, 0x5f, 0xf3, 0xd0, 0xd7, 0x65, 0x5f, 0x26, - 0x90, 0xc7, 0xa8, 0x2c, 0x12, 0x1f, 0x2a, 0x12, 0x73, 0x7d, 0xfa, 0x47, - 0x56, 0xb9, 0x1a, 0xda, 0x24, 0xde, 0x5b, 0xe2, 0x7d, 0xd7, 0xc0, 0xf6, - 0xc6, 0xdd, 0x45, 0x13, 0x83, 0x5d, 0xd1, 0x06, 0xda, 0x81, 0x97, 0x21, - 0x66, 0xca, 0xe1, 0x40, 0x6f, 0x28, 0xbf, 0x9c, 0xdf, 0xe8, 0x0f, 0x65, - 0xd5, 0xac, 0x33, 0xbc, 0x0a, 0xd7, 0xd2, 0xab, 0x72, 0x5b, 0xb1, 0x4b, - 0xc0, 0xb5, 0x91, 0x06, 0xae, 0x7d, 0x51, 0xe6, 0x1a, 0xf1, 0xf6, 0x19, - 0xd9, 0xef, 0xed, 0xe1, 0x3d, 0x9d, 0xc3, 0x79, 0xf9, 0x68, 0xe2, 0xed, - 0x3d, 0x0d, 0x3b, 0xc9, 0x3b, 0x1d, 0xe9, 0x83, 0xbc, 0x83, 0x1b, 0xe6, - 0x66, 0x27, 0xbd, 0x5f, 0xc7, 0xfe, 0x69, 0x33, 0x2f, 0x37, 0xde, 0xe6, - 0x7c, 0x49, 0xd9, 0x1f, 0xdc, 0x77, 0x68, 0xcc, 0x5b, 0x69, 0xcc, 0x9b, - 0x32, 0xfa, 0x46, 0x1b, 0xbc, 0x6c, 0x2f, 0x8b, 0xb0, 0x97, 0x63, 0x88, - 0xb9, 0x17, 0xbd, 0xb5, 0xf2, 0xa3, 0x97, 0x6b, 0x2f, 0x9b, 0xf3, 0xcc, - 0xcd, 0xf6, 0x92, 0xeb, 0x34, 0xe7, 0x96, 0xd3, 0x4d, 0xf8, 0x4f, 0x79, - 0x3a, 0x67, 0x7c, 0x6a, 0x3c, 0xab, 0xe7, 0xa0, 0x8f, 0x4a, 0xc6, 0xb4, - 0xfc, 0xb2, 0x1c, 0xc6, 0x96, 0xf7, 0x34, 0x62, 0xcb, 0xe5, 0x78, 0x10, - 0xbe, 0x6b, 0xff, 0x67, 0x0c, 0x3e, 0xd2, 0x47, 0x76, 0xac, 0xb2, 0xb7, - 0x5b, 0xed, 0xd5, 0x6d, 0xcc, 0x97, 0x5e, 0x2b, 0xb7, 0xea, 0x38, 0xfe, - 0x8c, 0xc9, 0x4d, 0xcd, 0x69, 0xff, 0x9f, 0xdf, 0x0b, 0xca, 0xd9, 0x4d, - 0xc6, 0xdf, 0xbb, 0x18, 0xae, 0xae, 0x8c, 0x4d, 0x95, 0x3a, 0x88, 0xb1, - 0x8c, 0x4d, 0xfb, 0xdb, 0x89, 0xa1, 0x05, 0xff, 0x82, 0xe3, 0x31, 0x8e, - 0xe3, 0xd9, 0x47, 0xc7, 0xa1, 0xe8, 0xb7, 0x68, 0xc6, 0x07, 0x71, 0x68, - 0xc1, 0xff, 0x71, 0x5b, 0x80, 0x83, 0x17, 0x8a, 0x59, 0x3e, 0xdf, 0xce, - 0xbc, 0xde, 0xa2, 0x77, 0x31, 0x5a, 0x57, 0xc7, 0xbd, 0xb1, 0x55, 0x71, - 0xaf, 0x6d, 0xe2, 0xda, 0x5f, 0xd2, 0x71, 0x6f, 0xc0, 0x63, 0xee, 0x25, - 0x1a, 0x47, 0xb9, 0xc0, 0x42, 0x7e, 0x53, 0x21, 0x3e, 0xd0, 0x47, 0x81, - 0x9f, 0x35, 0xfd, 0x8b, 0xe0, 0x73, 0x72, 0x0d, 0xb9, 0xf9, 0xb8, 0xed, - 0x44, 0xb8, 0xf7, 0x73, 0x12, 0xe4, 0xeb, 0x76, 0x83, 0x16, 0xc6, 0x56, - 0x71, 0x23, 0x0f, 0x3f, 0x35, 0xf7, 0x2a, 0xc3, 0x7e, 0x61, 0x1c, 0xdf, - 0xf8, 0xee, 0x5a, 0xc9, 0xaf, 0xc8, 0x9f, 0x74, 0x33, 0x0d, 0x8d, 0x73, - 0xcf, 0x5f, 0xc6, 0x77, 0x8b, 0x0f, 0x73, 0x3f, 0xa2, 0xd9, 0xae, 0xf1, - 0xbb, 0x29, 0xbf, 0x95, 0x8a, 0x75, 0x67, 0x9f, 0x0b, 0x1d, 0xe0, 0xbd, - 0xe1, 0x28, 0xbe, 0x26, 0xa4, 0x34, 0x2b, 0x89, 0x64, 0x8e, 0xdf, 0x00, - 0x68, 0xff, 0x7f, 0x68, 0xf6, 0x99, 0x92, 0x7d, 0x33, 0x41, 0xce, 0x53, - 0x5d, 0xf0, 0x5e, 0xdc, 0xe3, 0xe0, 0x43, 0xe6, 0x50, 0x98, 0xf3, 0x54, - 0xc1, 0xbd, 0xb8, 0x43, 0x1f, 0xdd, 0xbd, 0x38, 0xce, 0x6f, 0xcb, 0x9e, - 0x35, 0xee, 0xc5, 0xc5, 0x2e, 0xf1, 0x5e, 0xdc, 0x26, 0x9d, 0xf3, 0xe4, - 0x3c, 0x41, 0xce, 0x93, 0xe5, 0xad, 0x03, 0xcc, 0x95, 0xf0, 0xee, 0xdb, - 0xa0, 0xbe, 0x2f, 0xbc, 0x75, 0xe0, 0xe7, 0x11, 0xa3, 0xfc, 0x75, 0xfb, - 0xc7, 0x1f, 0xa3, 0x70, 0x2f, 0xbf, 0x11, 0x7c, 0xdf, 0x95, 0xcb, 0xc9, - 0x03, 0x7c, 0xb8, 0xbc, 0xe6, 0x3e, 0x9d, 0xd7, 0x7c, 0xa7, 0x3d, 0x9a, - 0xd7, 0x54, 0x17, 0xb9, 0x1b, 0xb6, 0x6f, 0x8d, 0xbc, 0x66, 0x3c, 0x72, - 0x37, 0x2c, 0x6e, 0xee, 0x86, 0x6d, 0x72, 0x11, 0x4b, 0x9a, 0x3c, 0xa6, - 0xba, 0xe0, 0xdd, 0xb0, 0xce, 0x0d, 0x1f, 0x3e, 0x8f, 0xb9, 0xea, 0x6e, - 0x18, 0x6c, 0xdd, 0x16, 0x49, 0x5f, 0x56, 0xdc, 0xf3, 0x61, 0x62, 0x1e, - 0xde, 0xab, 0x6f, 0xc1, 0x9e, 0xe3, 0xb2, 0x27, 0x49, 0xf9, 0xe4, 0xdd, - 0xc6, 0x3e, 0xe8, 0x02, 0x9e, 0x3e, 0xcb, 0xfd, 0x3c, 0x23, 0x6b, 0xa4, - 0x6f, 0xe5, 0x3d, 0x84, 0xe5, 0x3b, 0xbd, 0x89, 0xc6, 0x9d, 0xde, 0x29, - 0xc8, 0x8d, 0x9a, 0x49, 0xc8, 0x7c, 0x44, 0xa6, 0x26, 0x3d, 0xf8, 0x4b, - 0xb3, 0x8e, 0x69, 0xe7, 0xff, 0xef, 0x48, 0x02, 0xf3, 0x78, 0x0f, 0xb8, - 0x43, 0x62, 0xb3, 0xc1, 0x37, 0xcb, 0xe0, 0xff, 0xb8, 0xa4, 0xd0, 0x87, - 0x77, 0x3c, 0xe3, 0xb2, 0x5f, 0xe7, 0x2c, 0x42, 0x59, 0xfe, 0x35, 0xf0, - 0x78, 0x73, 0x7e, 0xb9, 0x9c, 0x5c, 0xc3, 0xee, 0x27, 0xa5, 0x3c, 0x43, - 0x79, 0xbe, 0xc1, 0xfc, 0xff, 0x82, 0xd3, 0x52, 0xf6, 0x4f, 0x99, 0xf8, - 0x42, 0x7f, 0xdb, 0x01, 0x2f, 0xb7, 0x18, 0x1b, 0x8c, 0x67, 0x75, 0x0b, - 0x6d, 0x1e, 0xd6, 0x38, 0x2e, 0xc3, 0xd3, 0x3b, 0x52, 0x7b, 0x81, 0x77, - 0x63, 0x7a, 0xcd, 0xcb, 0xe1, 0xb9, 0x75, 0x9e, 0xef, 0x8d, 0x97, 0xca, - 0xf7, 0xd0, 0x3f, 0xae, 0x62, 0x7f, 0x5b, 0x20, 0x1f, 0x5f, 0x95, 0xe2, - 0xb1, 0x6b, 0x65, 0xf8, 0x68, 0x06, 0xf4, 0xbc, 0x5f, 0x2f, 0x67, 0xe1, - 0x4b, 0x3f, 0xcd, 0x7b, 0x63, 0xc0, 0x50, 0xf0, 0xed, 0xf9, 0x55, 0xdf, - 0xb1, 0xa3, 0x77, 0xcd, 0xfa, 0x1b, 0x77, 0x87, 0x9e, 0xf5, 0x25, 0xd1, - 0x49, 0x9a, 0x67, 0x96, 0xef, 0x8f, 0x2f, 0xfa, 0xbb, 0xb4, 0x6d, 0x7b, - 0xc6, 0x5f, 0x91, 0xfb, 0xd1, 0x67, 0x38, 0x5e, 0xfb, 0x1e, 0xec, 0xdb, - 0x39, 0x8b, 0xf6, 0x6d, 0xca, 0x93, 0xab, 0x63, 0xc2, 0xf3, 0x10, 0x0b, - 0x3c, 0xd0, 0x77, 0x38, 0x82, 0xef, 0xfb, 0x3d, 0xfa, 0x5c, 0x03, 0xac, - 0x58, 0x88, 0xdc, 0xc1, 0x58, 0x3e, 0xdb, 0xe0, 0x6e, 0x46, 0x70, 0x16, - 0xc1, 0xfd, 0x11, 0xed, 0x6f, 0x1e, 0xdc, 0xe3, 0x06, 0xf7, 0x47, 0x7a, - 0x67, 0x59, 0xd7, 0xd5, 0x64, 0xfb, 0x12, 0x90, 0x01, 0xde, 0x3b, 0xe2, - 0xbd, 0x71, 0xd2, 0xac, 0x73, 0x1d, 0xff, 0x47, 0xdd, 0xd5, 0xc7, 0xb6, - 0x75, 0x5d, 0xf7, 0xc3, 0x47, 0xea, 0xc3, 0xb4, 0x2c, 0x53, 0x32, 0x25, - 0xd3, 0x96, 0x2c, 0xbf, 0x27, 0x3d, 0x59, 0x72, 0xac, 0x14, 0xac, 0xab, - 0xad, 0x02, 0x46, 0xa4, 0x0c, 0x49, 0x7f, 0xb4, 0x08, 0x06, 0xfa, 0xa3, - 0x99, 0x8b, 0x66, 0xab, 0x4b, 0xd9, 0x4e, 0x0a, 0xf4, 0x0f, 0xb7, 0xc5, - 0x80, 0x6c, 0x58, 0x60, 0x86, 0xb4, 0x12, 0x63, 0x56, 0x4c, 0xd6, 0x66, - 0x85, 0x0c, 0xd8, 0x30, 0x4e, 0x54, 0x9c, 0x14, 0x50, 0xc6, 0x04, 0x69, - 0x83, 0xa2, 0x58, 0x61, 0x45, 0x76, 0x36, 0x6c, 0x7f, 0x65, 0x43, 0xd0, - 0x05, 0x9b, 0xb3, 0x38, 0x76, 0xb0, 0x06, 0x45, 0xd6, 0x7d, 0x62, 0x18, - 0xd0, 0x0d, 0xdc, 0xf9, 0xdd, 0x0f, 0xf2, 0xf1, 0xf1, 0x51, 0x1f, 0x89, - 0x33, 0x60, 0x02, 0x04, 0xbe, 0xf7, 0x78, 0xdf, 0x7b, 0xf7, 0x9e, 0x7b, - 0xce, 0xb9, 0xbf, 0x73, 0xee, 0x39, 0x87, 0x9e, 0x7b, 0xdb, 0x9b, 0xf3, - 0xb9, 0xca, 0x77, 0x8e, 0x8a, 0x77, 0x0e, 0x28, 0x9d, 0xa5, 0xe3, 0xc5, - 0x63, 0xc6, 0x6c, 0x61, 0x22, 0xe2, 0x67, 0xfe, 0x9e, 0xad, 0xc2, 0xbe, - 0x6e, 0x87, 0xe1, 0xd6, 0xa2, 0x67, 0xbc, 0x85, 0x9e, 0xcd, 0x32, 0xc1, - 0xf6, 0x78, 0x5d, 0x77, 0x4b, 0xda, 0xc9, 0xeb, 0x88, 0x85, 0xd7, 0x31, - 0x0e, 0x92, 0x76, 0x75, 0x19, 0xba, 0xe2, 0x8c, 0x6f, 0x68, 0xd0, 0xee, - 0x74, 0x9d, 0x76, 0x3b, 0xff, 0x1f, 0xd1, 0xee, 0x1d, 0x81, 0x7f, 0x5f, - 0xad, 0x22, 0x6e, 0x4d, 0x63, 0x00, 0x9d, 0x3b, 0x04, 0x3a, 0x42, 0x9f, - 0x5a, 0xe5, 0x15, 0x82, 0x4e, 0x45, 0x5c, 0x71, 0xad, 0xf6, 0x5a, 0xb4, - 0xee, 0xa7, 0x64, 0xbb, 0x04, 0xf6, 0x09, 0xfc, 0x79, 0xed, 0xd7, 0xc8, - 0x63, 0x1f, 0x6b, 0x8d, 0x04, 0x56, 0x72, 0xdb, 0x27, 0x0c, 0x08, 0x1d, - 0xf6, 0xc9, 0xb1, 0x4d, 0xda, 0x27, 0xe7, 0xa5, 0x7d, 0x92, 0xdd, 0xb8, - 0x7d, 0xb2, 0xbb, 0x25, 0xae, 0xab, 0x31, 0x9e, 0xcd, 0xdb, 0x27, 0xc6, - 0x9a, 0xf6, 0xc9, 0x90, 0xc3, 0x17, 0x83, 0xfe, 0xfe, 0x06, 0x65, 0x8f, - 0x43, 0xc7, 0x69, 0x3a, 0x83, 0xc6, 0xc7, 0x5d, 0x7e, 0xe1, 0x4f, 0x93, - 0xd6, 0xbf, 0xf8, 0x3f, 0xa6, 0xf5, 0x50, 0x8b, 0xcf, 0xbb, 0x31, 0x1e, - 0x0a, 0xef, 0xd8, 0x14, 0x8e, 0x77, 0xd3, 0x7a, 0xa8, 0xad, 0xef, 0xb4, - 0x7d, 0xcc, 0x62, 0xb3, 0xef, 0x74, 0xd4, 0x68, 0xa7, 0xdb, 0xff, 0xd8, - 0xe1, 0x53, 0x75, 0xea, 0x77, 0xc8, 0x14, 0xf9, 0x8e, 0x4d, 0xe8, 0x77, - 0x41, 0x96, 0xac, 0x6c, 0x96, 0x60, 0x33, 0xe1, 0x7d, 0x11, 0x21, 0x6b, - 0x2e, 0xbc, 0xc5, 0xef, 0x63, 0x7a, 0xbe, 0xf8, 0x87, 0x62, 0x9d, 0x92, - 0xfe, 0x07, 0xb4, 0x0f, 0xfb, 0xce, 0x88, 0xb6, 0x32, 0xbe, 0x49, 0xf9, - 0x23, 0x14, 0xf6, 0x6f, 0xe7, 0x87, 0x68, 0x5d, 0xf3, 0x36, 0x67, 0x2b, - 0x68, 0x19, 0xdf, 0xcb, 0xf3, 0x12, 0x69, 0xb2, 0xb5, 0xa0, 0x3f, 0xcf, - 0x33, 0x2e, 0x18, 0xad, 0x63, 0x82, 0xe6, 0xb9, 0xb9, 0x28, 0x6c, 0x3a, - 0xad, 0x3b, 0x57, 0x64, 0xec, 0xa9, 0xb8, 0x0e, 0x9c, 0xa6, 0x75, 0xa7, - 0x1b, 0x07, 0xef, 0xf5, 0xe0, 0x0b, 0xcf, 0xdc, 0x4f, 0x3d, 0x77, 0x26, - 0x62, 0xce, 0x53, 0x9e, 0x73, 0x57, 0xcf, 0xe1, 0xca, 0x36, 0xda, 0xca, - 0xfb, 0x53, 0x62, 0x5c, 0xdf, 0xfc, 0x62, 0x02, 0xb9, 0x6a, 0xf5, 0xfc, - 0x21, 0x77, 0xce, 0x14, 0xd6, 0x01, 0x2d, 0x87, 0x3a, 0x3f, 0x1b, 0xb4, - 0x18, 0xf1, 0xc8, 0x99, 0x72, 0xae, 0x25, 0xb8, 0xcf, 0x4d, 0x8b, 0xc6, - 0x3a, 0x32, 0xa7, 0xd6, 0x91, 0x45, 0x87, 0x1e, 0x6f, 0xc5, 0xed, 0xfd, - 0x1e, 0xb8, 0xdd, 0x2b, 0x6f, 0x0a, 0x7d, 0x7a, 0x92, 0x71, 0xc8, 0x67, - 0x80, 0x43, 0x42, 0xc8, 0x5b, 0x92, 0x58, 0x04, 0xdf, 0x17, 0x19, 0x8f, - 0x44, 0x98, 0x57, 0x7e, 0x44, 0xe7, 0x18, 0x6b, 0x5f, 0xa7, 0xfd, 0xca, - 0x3e, 0x83, 0xdc, 0xea, 0x38, 0x53, 0xc4, 0xf1, 0xfb, 0x28, 0xfb, 0x98, - 0x35, 0x19, 0xa7, 0x1f, 0xd1, 0x59, 0x11, 0x33, 0x83, 0xfd, 0x3d, 0xc4, - 0x1c, 0x3c, 0x20, 0xde, 0x2f, 0x7d, 0x19, 0xf7, 0x23, 0xa6, 0x6e, 0xe3, - 0xf1, 0xfb, 0x2a, 0xb7, 0x8e, 0xdb, 0xe1, 0x9d, 0x4b, 0x4a, 0xa6, 0xc4, - 0x35, 0xbe, 0xff, 0x49, 0xa3, 0xf5, 0xfe, 0xb8, 0x91, 0xaa, 0xa6, 0x8c, - 0x44, 0x05, 0xed, 0x9e, 0x34, 0x92, 0x55, 0xd8, 0x90, 0x9a, 0x47, 0xac, - 0x28, 0xe4, 0x6d, 0x95, 0xd6, 0xdf, 0x8b, 0x58, 0x24, 0x57, 0x9e, 0xc4, - 0x06, 0xfa, 0x7d, 0xb8, 0xa9, 0xdf, 0x9a, 0xbe, 0x38, 0x86, 0xbf, 0xe7, - 0x15, 0xa6, 0xa9, 0xc6, 0xb5, 0x41, 0xf8, 0xd7, 0x27, 0xb3, 0xb4, 0x16, - 0xae, 0xb5, 0x5a, 0x70, 0xed, 0xe2, 0xba, 0xfd, 0xfe, 0xa4, 0x32, 0x2e, - 0xf3, 0xa3, 0xfd, 0xb6, 0xc0, 0xaf, 0xdc, 0xef, 0x26, 0x6c, 0xeb, 0xe2, - 0x29, 0xb4, 0xd1, 0x7e, 0x70, 0xed, 0x07, 0xeb, 0x55, 0xf1, 0xc0, 0x3a, - 0x3e, 0x21, 0x88, 0x7c, 0xaf, 0x90, 0x8c, 0x6b, 0x85, 0x8d, 0xb5, 0xc2, - 0xfd, 0x83, 0xbd, 0x05, 0x9f, 0x8f, 0xb0, 0xb7, 0xcc, 0x24, 0x49, 0x5f, - 0xf7, 0x99, 0xaa, 0xd3, 0xbf, 0xeb, 0x95, 0x4b, 0x39, 0xea, 0x91, 0x4b, - 0xe9, 0x94, 0xb5, 0x80, 0x43, 0xd6, 0x22, 0x0e, 0xdc, 0x36, 0xcc, 0x76, - 0x4b, 0x0f, 0xeb, 0x90, 0x1e, 0xb1, 0x6d, 0xe2, 0xbf, 0xea, 0xb4, 0x5b, - 0xdc, 0x79, 0xf1, 0x90, 0x3b, 0x60, 0x33, 0x69, 0xc3, 0xa4, 0x4a, 0xf5, - 0x9c, 0x7a, 0x1e, 0x77, 0x23, 0x6f, 0xb1, 0xd2, 0x92, 0x63, 0xe9, 0xd5, - 0xdf, 0x91, 0x96, 0xfe, 0x62, 0xfd, 0x8a, 0xb7, 0xc5, 0x74, 0x5e, 0x76, - 0xd5, 0xfd, 0xea, 0x9f, 0x5b, 0x9f, 0xe1, 0x5d, 0xa3, 0xc2, 0xe7, 0x9d, - 0xad, 0xeb, 0xb2, 0x19, 0xd9, 0xdf, 0x42, 0xb3, 0x9d, 0xe1, 0xbf, 0x42, - 0x8a, 0x76, 0xde, 0xba, 0x7d, 0x73, 0xfe, 0xb3, 0xad, 0x6e, 0x1c, 0xdc, - 0x27, 0xfd, 0x62, 0x73, 0x2a, 0x0e, 0x7b, 0x40, 0xd9, 0x7b, 0xeb, 0xf1, - 0x3b, 0xae, 0xcd, 0x29, 0x5f, 0xa2, 0x65, 0x96, 0x09, 0x7c, 0x7e, 0xfc, - 0x54, 0x87, 0x1d, 0x52, 0x7b, 0x59, 0xd8, 0xaf, 0x02, 0xdf, 0xeb, 0xe7, - 0x43, 0x67, 0x6f, 0x64, 0xce, 0xcc, 0x96, 0x39, 0x93, 0x7c, 0x05, 0x5b, - 0x0b, 0xf1, 0xc5, 0x53, 0xae, 0x18, 0xef, 0x4f, 0x42, 0x8b, 0x5e, 0x8f, - 0xb8, 0x67, 0xc4, 0x2d, 0xb7, 0xeb, 0xe7, 0x1d, 0x07, 0x2e, 0x47, 0x7f, - 0x6b, 0xb5, 0x57, 0xa2, 0xbb, 0xe5, 0x5a, 0x5c, 0xf5, 0xc6, 0x48, 0xa1, - 0x0d, 0xf7, 0xcf, 0xbd, 0xf6, 0xee, 0xda, 0xe0, 0xda, 0x2b, 0xea, 0x8b, - 0xf8, 0x0e, 0x09, 0x1d, 0xd0, 0x43, 0x95, 0x12, 0xe2, 0xaf, 0x3f, 0x0b, - 0x99, 0x67, 0x3d, 0xeb, 0xc8, 0x49, 0xf3, 0x9e, 0xc7, 0xfa, 0x9e, 0x4a, - 0x20, 0x86, 0xbd, 0x3f, 0xc4, 0x96, 0xf4, 0xb3, 0xee, 0x41, 0xfb, 0x71, - 0xf3, 0x16, 0xfc, 0xbd, 0xca, 0xff, 0x94, 0x52, 0xeb, 0xcb, 0xa1, 0x0d, - 0xec, 0xad, 0x6c, 0x4e, 0x4f, 0x5b, 0xe6, 0x0a, 0x61, 0xdf, 0x07, 0xf1, - 0xc2, 0xc7, 0x7a, 0xa9, 0xf7, 0x2b, 0x5d, 0x5d, 0xf6, 0x1f, 0xf4, 0xc9, - 0xbd, 0x28, 0x7c, 0xd7, 0x43, 0x2f, 0x94, 0x10, 0xcb, 0x8d, 0xef, 0x7e, - 0x8b, 0xbf, 0xf3, 0xd2, 0x51, 0x3a, 0x16, 0x1d, 0x58, 0x4e, 0xce, 0x4f, - 0x99, 0x60, 0x2b, 0xd5, 0xe8, 0x6f, 0xa2, 0x9f, 0x93, 0xfb, 0x19, 0xd5, - 0xfb, 0xbd, 0x57, 0xe3, 0xe5, 0x2f, 0xfc, 0x69, 0xdf, 0xc7, 0x8d, 0x8d, - 0xfc, 0xd6, 0x86, 0xfc, 0x85, 0xd8, 0xe7, 0xdf, 0xc8, 0x9e, 0x89, 0xde, - 0x1b, 0x9e, 0x16, 0x39, 0xa7, 0x4e, 0x3e, 0xb8, 0x3f, 0xfb, 0xc3, 0xe0, - 0x87, 0x91, 0x16, 0x5d, 0xf5, 0xc9, 0xfd, 0xfd, 0x6e, 0xba, 0x06, 0x3d, - 0x7d, 0x55, 0xde, 0xfb, 0xc0, 0xd8, 0xf3, 0x87, 0x9f, 0xba, 0x4a, 0x67, - 0xae, 0x81, 0x87, 0x0d, 0xe6, 0xb6, 0x31, 0xca, 0x87, 0x91, 0x57, 0x24, - 0x72, 0x73, 0xf4, 0xbe, 0xa1, 0xc8, 0x15, 0x3a, 0x23, 0x72, 0x20, 0xc7, - 0x23, 0xf7, 0x78, 0x3d, 0x3c, 0x53, 0x7d, 0x9b, 0xce, 0x56, 0x82, 0xfc, - 0xdf, 0xc0, 0xee, 0xad, 0x79, 0x90, 0xcd, 0x3c, 0x7e, 0x4f, 0xf0, 0xf8, - 0xf0, 0x9a, 0x3c, 0x7e, 0xa4, 0xce, 0xe3, 0x5f, 0xe9, 0x97, 0xfc, 0xdc, - 0xcb, 0xcf, 0xea, 0xa5, 0x43, 0xe2, 0xb9, 0x6f, 0xf3, 0xf1, 0x56, 0x3a, - 0x14, 0x92, 0xc7, 0x67, 0x2b, 0xac, 0xe3, 0x0b, 0x6f, 0xd3, 0xb9, 0x6b, - 0x59, 0x5f, 0x4a, 0xe4, 0x2f, 0x38, 0x6b, 0x69, 0xe8, 0xfb, 0xd1, 0xae, - 0x1d, 0xff, 0x6b, 0xbd, 0x24, 0x73, 0xae, 0xca, 0x52, 0x3f, 0xd1, 0x5b, - 0xd1, 0x21, 0x17, 0xff, 0x37, 0xdb, 0x8e, 0xe7, 0xd5, 0x1a, 0x78, 0x7c, - 0x0d, 0xbf, 0x46, 0x2b, 0x5f, 0xf6, 0x79, 0xe0, 0xe1, 0xa7, 0xfb, 0xe5, - 0x3e, 0xd5, 0x5a, 0x7e, 0x8d, 0xa6, 0xb8, 0x0e, 0xe7, 0xbe, 0x3d, 0xeb, - 0xfd, 0x3d, 0x2a, 0x17, 0xf0, 0x87, 0xfd, 0x72, 0xbd, 0x40, 0x7e, 0xe0, - 0x0a, 0xd3, 0xe1, 0x22, 0x63, 0x95, 0x21, 0xea, 0xbc, 0xaa, 0xc7, 0x3a, - 0x24, 0xf4, 0xad, 0xd3, 0x4f, 0x73, 0x51, 0xe5, 0x76, 0xe7, 0x1c, 0x63, - 0xba, 0x28, 0x6c, 0x9c, 0xf6, 0xf2, 0xd6, 0x3e, 0xe6, 0x6a, 0xd8, 0xb5, - 0x26, 0xb8, 0xf9, 0x0d, 0x75, 0x4a, 0x30, 0xbf, 0x64, 0x48, 0x1c, 0x3c, - 0xc3, 0xf8, 0x76, 0xb3, 0xfb, 0x45, 0x9f, 0x14, 0x23, 0xba, 0x6b, 0x60, - 0xb8, 0x8f, 0x31, 0x0f, 0xd2, 0xe6, 0xc8, 0xbc, 0x58, 0x15, 0xba, 0xe0, - 0xe2, 0x54, 0x8d, 0x92, 0xd1, 0x6d, 0x94, 0x99, 0xe2, 0x77, 0xcf, 0xd8, - 0x6c, 0x7b, 0xf9, 0x29, 0xcb, 0xf2, 0x9b, 0x99, 0xda, 0xa2, 0xf0, 0xa2, - 0xf6, 0xa7, 0x77, 0xa9, 0x38, 0x87, 0x5e, 0xb1, 0x2f, 0x29, 0x6b, 0xf5, - 0xf0, 0x71, 0x45, 0x3f, 0x1b, 0xd7, 0xc1, 0xbb, 0x9d, 0xaa, 0xdd, 0x65, - 0x47, 0x3b, 0xb4, 0xb9, 0xac, 0xda, 0xe2, 0x99, 0x1a, 0x53, 0x74, 0x2b, - 0x7d, 0x0b, 0x39, 0x5c, 0x51, 0xb9, 0x7a, 0xc2, 0x7e, 0xa0, 0xd9, 0xfa, - 0x58, 0x2e, 0x73, 0xdb, 0xff, 0xae, 0xc5, 0x85, 0x2d, 0x77, 0x99, 0x31, - 0x6f, 0x55, 0xc8, 0x8a, 0xbb, 0x4f, 0x18, 0x8b, 0x5f, 0xec, 0x0f, 0xf1, - 0xb1, 0x7a, 0xcf, 0xe9, 0x7a, 0x9f, 0x10, 0xa3, 0x61, 0x45, 0xe4, 0xb3, - 0x74, 0xbb, 0xcb, 0x8e, 0x76, 0x5a, 0x57, 0xe8, 0xfd, 0x87, 0x8f, 0x7c, - 0xb3, 0x85, 0xdb, 0x3e, 0x19, 0xc3, 0x1b, 0x12, 0xfb, 0xa7, 0x32, 0x46, - 0x43, 0x1f, 0xc3, 0xbf, 0x8c, 0x98, 0x0a, 0xc4, 0x49, 0x38, 0xf5, 0x8d, - 0x1c, 0x6f, 0x00, 0x6b, 0x51, 0x15, 0xfb, 0xa6, 0xd8, 0xaf, 0x68, 0x87, - 0x9d, 0x77, 0x21, 0x36, 0x7f, 0x13, 0x18, 0x74, 0x23, 0xf2, 0x67, 0x7a, - 0xc8, 0x9f, 0xf3, 0xfd, 0xc8, 0x83, 0x43, 0x3e, 0x5c, 0x76, 0xd2, 0xa0, - 0x1a, 0xdb, 0x0a, 0x06, 0x95, 0x43, 0x3e, 0x3a, 0x67, 0x5b, 0xd1, 0x8a, - 0xc0, 0x9a, 0x8f, 0xc0, 0x7f, 0x35, 0xb9, 0x42, 0x07, 0x44, 0xce, 0x38, - 0x6a, 0x1f, 0x94, 0x79, 0x0d, 0x3e, 0xcd, 0x3c, 0x78, 0x96, 0xed, 0x8f, - 0xec, 0x49, 0xec, 0xb7, 0xe8, 0x79, 0x41, 0x0e, 0x3c, 0x3e, 0x4d, 0x9e, - 0xbb, 0xdf, 0xdd, 0x41, 0xc1, 0x38, 0x3f, 0xd3, 0x84, 0x7e, 0xe2, 0xe7, - 0xa4, 0x29, 0xc1, 0x76, 0x12, 0x6c, 0xd6, 0xd3, 0x27, 0xad, 0x50, 0x99, - 0x0c, 0x6e, 0x0b, 0xdb, 0x15, 0xcf, 0xc1, 0xfd, 0xf1, 0x50, 0x07, 0xb9, - 0x73, 0x72, 0x7b, 0x45, 0x9e, 0xe2, 0x5b, 0xd1, 0x07, 0xc9, 0x18, 0x84, - 0xbe, 0xc2, 0xbc, 0x3d, 0xa0, 0xf6, 0x89, 0xb6, 0xf3, 0xf1, 0x84, 0x3a, - 0x0e, 0x8a, 0xf9, 0x94, 0xc7, 0x9a, 0xbf, 0xf1, 0xf7, 0xf3, 0x2e, 0xb2, - 0xfd, 0x6a, 0xfe, 0x9a, 0x62, 0x41, 0x22, 0x63, 0x46, 0x90, 0xce, 0x57, - 0xd6, 0xf2, 0xbf, 0x78, 0xe5, 0xba, 0x6e, 0xdf, 0x60, 0xae, 0xeb, 0x4f, - 0x76, 0xc8, 0xdc, 0x32, 0x67, 0x5f, 0xfe, 0x93, 0xfb, 0xe2, 0x85, 0xc9, - 0x5a, 0x70, 0x22, 0x8f, 0xb7, 0x46, 0x3f, 0x8b, 0x7e, 0x9e, 0xee, 0x84, - 0x23, 0x2a, 0x66, 0x09, 0x31, 0x4a, 0x0f, 0x2a, 0xbe, 0xd6, 0xba, 0x9f, - 0x3c, 0x74, 0xff, 0xa3, 0x22, 0x56, 0x53, 0xae, 0x1d, 0x43, 0x8a, 0x1e, - 0xa0, 0x59, 0xc4, 0x41, 0xb3, 0x01, 0x07, 0xcd, 0x0c, 0x75, 0xbc, 0x4d, - 0x9c, 0x9f, 0xaf, 0x3c, 0xb5, 0x5d, 0xe6, 0x8b, 0x63, 0x2f, 0xf1, 0x92, - 0x3a, 0x5e, 0x6f, 0xbc, 0x56, 0x98, 0x82, 0xc2, 0xdf, 0xe4, 0x18, 0xeb, - 0xcb, 0x44, 0xf6, 0x81, 0x70, 0x2b, 0x0d, 0x5e, 0x73, 0x5c, 0x47, 0x1f, - 0xc7, 0x1d, 0x7d, 0x1c, 0x75, 0xf4, 0x71, 0x6f, 0x9b, 0x3e, 0xb2, 0x8e, - 0xe7, 0xf7, 0x9c, 0xad, 0x7e, 0xdc, 0xbe, 0xa2, 0x9f, 0xc8, 0x23, 0x06, - 0x3d, 0xb7, 0x52, 0x2e, 0x1c, 0x51, 0x6b, 0xc7, 0x2f, 0x55, 0x2e, 0xba, - 0x57, 0x9f, 0xff, 0x8e, 0xda, 0xcf, 0x9b, 0x93, 0x57, 0x9d, 0xf9, 0xc7, - 0xdf, 0xa5, 0xa4, 0xcc, 0x23, 0x57, 0xb2, 0x7d, 0xb9, 0x8d, 0x1f, 0x1a, - 0xf1, 0x1c, 0xc0, 0x20, 0xc2, 0x2e, 0xdc, 0x2d, 0x6b, 0xc1, 0x05, 0x68, - 0xa9, 0x9e, 0xcb, 0xeb, 0x57, 0xb9, 0x3b, 0xc7, 0xc3, 0xf7, 0x37, 0x8f, - 0x17, 0xd7, 0xff, 0x4c, 0xf8, 0xf2, 0xe4, 0xfe, 0xd1, 0x8a, 0xca, 0x47, - 0xb6, 0x4c, 0xc4, 0x06, 0x2c, 0x2e, 0xc3, 0xff, 0xda, 0x2e, 0x77, 0x57, - 0xea, 0xa2, 0x4c, 0xbd, 0x3e, 0x4a, 0x59, 0xe4, 0x35, 0x48, 0xff, 0x98, - 0xcc, 0xbf, 0x5d, 0x5c, 0xbe, 0x25, 0x72, 0x5e, 0x13, 0x2a, 0x8f, 0x37, - 0x43, 0x3d, 0x02, 0xe7, 0x7e, 0xfc, 0xfc, 0xdb, 0x17, 0xc2, 0x9b, 0xcf, - 0xbf, 0x75, 0xde, 0xb3, 0xb9, 0xfc, 0xdb, 0x10, 0x8f, 0xdd, 0x58, 0x90, - 0xf9, 0xb7, 0xcd, 0x7b, 0x32, 0x32, 0xff, 0x36, 0xe3, 0xc0, 0x0f, 0x12, - 0xaf, 0xbf, 0xe5, 0x88, 0xdf, 0x96, 0xb9, 0xb5, 0x8b, 0x75, 0xcc, 0x2a, - 0x73, 0x6b, 0x65, 0xbc, 0xb7, 0xb3, 0x0e, 0x8c, 0xdc, 0xfb, 0x91, 0xef, - 0xd9, 0xe6, 0xda, 0xfb, 0x91, 0x39, 0xb5, 0xa6, 0xd1, 0xce, 0x86, 0xc3, - 0x1a, 0x81, 0x7a, 0x08, 0x71, 0xe6, 0xdd, 0xad, 0x6d, 0xea, 0x21, 0xc4, - 0xdb, 0xd4, 0x43, 0x70, 0xea, 0x7e, 0x27, 0xc6, 0x02, 0x26, 0xc6, 0xda, - 0x08, 0x2c, 0x8c, 0x7a, 0x06, 0x51, 0x3a, 0x5f, 0xc7, 0x9e, 0x0f, 0x52, - 0x5a, 0x61, 0xcf, 0xf3, 0x15, 0xad, 0x8f, 0x46, 0x5d, 0xfa, 0xc8, 0x0b, - 0x8b, 0x5a, 0x2a, 0xce, 0x47, 0xcb, 0x6b, 0xd6, 0x21, 0xaf, 0x59, 0x0f, - 0x79, 0xc5, 0x3d, 0xd9, 0x36, 0xfd, 0xfe, 0xa5, 0xba, 0x07, 0xff, 0x4f, - 0x46, 0x50, 0xb3, 0x85, 0x68, 0xf7, 0x80, 0xc2, 0x7f, 0x0e, 0x79, 0x3d, - 0xcb, 0xf2, 0xaa, 0xaf, 0xa3, 0xbf, 0xed, 0x6c, 0x00, 0x8d, 0x19, 0x87, - 0x7c, 0x87, 0xaf, 0xbd, 0x21, 0xe2, 0xa4, 0x9a, 0xed, 0x45, 0x8d, 0x27, - 0xf6, 0x09, 0x59, 0xba, 0xe3, 0x47, 0xdc, 0x8a, 0xbe, 0x16, 0x52, 0x7e, - 0x32, 0x4d, 0x8b, 0xce, 0x26, 0xcc, 0xd1, 0xc0, 0x1b, 0x22, 0xc6, 0xd7, - 0xd1, 0xb7, 0x7f, 0xe5, 0xbe, 0xe9, 0xeb, 0x7a, 0xcd, 0x7c, 0xa7, 0xc9, - 0x9f, 0x71, 0xa3, 0xa9, 0xee, 0x1f, 0x7c, 0x47, 0xdb, 0xd2, 0x86, 0x9d, - 0x12, 0x31, 0xa6, 0x7d, 0x36, 0xfc, 0x64, 0x09, 0x96, 0xfd, 0xbe, 0x34, - 0xe2, 0x99, 0xfb, 0xae, 0x98, 0x74, 0xa2, 0x70, 0x7e, 0x8f, 0xe4, 0x95, - 0x0b, 0xa2, 0xa6, 0x25, 0x6a, 0x20, 0x26, 0x79, 0x7d, 0x4e, 0x30, 0xe8, - 0x9c, 0xab, 0x76, 0xd1, 0x22, 0xa3, 0x7b, 0xbf, 0x5d, 0x16, 0xbe, 0x3e, - 0xd6, 0x49, 0x45, 0xd4, 0x36, 0x35, 0x16, 0x3a, 0xf9, 0xb9, 0x83, 0xb4, - 0x54, 0x1a, 0x17, 0x35, 0xa1, 0x64, 0x7d, 0x11, 0xb4, 0xf5, 0x51, 0xbf, - 0xfd, 0x0d, 0xa6, 0xdd, 0xd7, 0x44, 0x8c, 0xe5, 0x62, 0xf1, 0x82, 0xfc, - 0x2c, 0x3f, 0xa5, 0xde, 0xc1, 0xef, 0xab, 0xfe, 0x98, 0xe2, 0xfd, 0xa6, - 0xc3, 0x96, 0x73, 0xfe, 0x79, 0xe3, 0x95, 0x63, 0x9b, 0xc2, 0x2b, 0xd9, - 0x74, 0x03, 0xaf, 0x38, 0x9f, 0xad, 0xb1, 0xcb, 0xe4, 0xa0, 0xac, 0xf7, - 0x00, 0x1a, 0x6c, 0x05, 0x16, 0x4b, 0x83, 0x96, 0x46, 0xcc, 0x8a, 0x24, - 0xfc, 0x33, 0x94, 0xaf, 0x5e, 0xa7, 0x4c, 0x11, 0x98, 0x99, 0x3f, 0xcb, - 0xe7, 0x76, 0x4a, 0x1f, 0x8d, 0xbe, 0x07, 0x7a, 0x65, 0x07, 0xb7, 0xff, - 0xeb, 0x41, 0x19, 0x97, 0xed, 0xbc, 0xde, 0xcb, 0xd7, 0xbf, 0x10, 0x69, - 0xbe, 0xbe, 0x85, 0xaf, 0xf7, 0xa7, 0x31, 0x87, 0xc6, 0x15, 0xf8, 0x25, - 0x27, 0x29, 0xc7, 0xf3, 0x93, 0xaf, 0xf2, 0xda, 0x7a, 0x95, 0xf5, 0x55, - 0x45, 0xb7, 0x1b, 0x40, 0xce, 0x8e, 0x98, 0x13, 0x83, 0xdb, 0x5c, 0x2c, - 0x4c, 0x71, 0xbb, 0x21, 0xf2, 0x5f, 0x35, 0x29, 0x5f, 0xd1, 0xbc, 0xaa, - 0xe3, 0xed, 0xdf, 0x18, 0x90, 0x31, 0x55, 0xef, 0xec, 0x94, 0xf4, 0x9b, - 0x14, 0x3e, 0x4f, 0xc4, 0x73, 0x3c, 0x23, 0xf8, 0xd0, 0x9a, 0x31, 0xeb, - 0xef, 0xdf, 0x06, 0xbe, 0x42, 0xdd, 0x54, 0x1e, 0x03, 0xeb, 0xc5, 0x98, - 0x1d, 0xca, 0xd5, 0x63, 0xd5, 0x9e, 0xdb, 0x2d, 0xef, 0xff, 0xe9, 0x80, - 0xac, 0x55, 0x7a, 0x5b, 0x9d, 0xeb, 0x35, 0x07, 0xf1, 0xcb, 0x3e, 0x41, - 0x1b, 0xff, 0x02, 0xf4, 0xa5, 0xc1, 0xc7, 0x3c, 0x9e, 0x34, 0xfa, 0xf8, - 0xb3, 0x01, 0x5d, 0x9f, 0x50, 0x8e, 0xeb, 0x28, 0xf7, 0x37, 0xc5, 0xe3, - 0xd2, 0xd7, 0xe3, 0x7c, 0xee, 0x35, 0xbf, 0x78, 0x56, 0x30, 0x2d, 0xeb, - 0x8b, 0x05, 0xd3, 0x99, 0x49, 0x39, 0xcf, 0x0d, 0x9f, 0x6e, 0xa4, 0xee, - 0xd3, 0x9d, 0x2b, 0xf4, 0x0f, 0xc2, 0xbf, 0x61, 0x5c, 0xe1, 0xf9, 0x0e, - 0x3f, 0xc3, 0x6d, 0x91, 0xab, 0x90, 0xe3, 0xcf, 0x1e, 0x15, 0xd7, 0xd3, - 0xca, 0x2b, 0x32, 0x4e, 0x42, 0xaf, 0x5b, 0xb8, 0x77, 0x80, 0x9f, 0x21, - 0xd7, 0xae, 0xf6, 0xef, 0xa1, 0x96, 0x38, 0x98, 0x56, 0x1e, 0x5b, 0xcb, - 0x0f, 0x2b, 0xf6, 0x13, 0x3d, 0xf8, 0x6c, 0xad, 0x7a, 0x06, 0xef, 0x08, - 0x3f, 0x5a, 0xb2, 0x45, 0x5e, 0x21, 0xc7, 0x01, 0xfa, 0xce, 0x7c, 0x96, - 0xb6, 0xf0, 0x5c, 0x7d, 0xc3, 0xf8, 0x35, 0xec, 0xb7, 0x93, 0x8c, 0x79, - 0x62, 0x1a, 0x17, 0xec, 0xc9, 0xb3, 0x06, 0xd3, 0xb9, 0x90, 0xad, 0x05, - 0xec, 0x1e, 0xea, 0x64, 0x59, 0xfd, 0x22, 0x8d, 0xb1, 0xfd, 0x07, 0x99, - 0xb5, 0x23, 0x29, 0x82, 0xbc, 0x59, 0xa1, 0xc3, 0xcc, 0x13, 0xc9, 0x2a, - 0xf8, 0xd9, 0xa0, 0x27, 0x4a, 0x44, 0x8f, 0x97, 0xc6, 0x42, 0xdf, 0x27, - 0xdb, 0x6c, 0x7c, 0x6f, 0x85, 0x12, 0xdc, 0x8f, 0x54, 0xf5, 0x77, 0xe8, - 0x43, 0x51, 0xe7, 0x04, 0x74, 0xd4, 0xf3, 0xfe, 0xdb, 0x74, 0x3a, 0x8d, - 0x7e, 0x6f, 0x5c, 0x3e, 0x4f, 0x6c, 0x4a, 0x3e, 0x83, 0x1e, 0xf2, 0xf9, - 0xea, 0xa0, 0xe4, 0x9b, 0x1a, 0xf3, 0x68, 0x90, 0x66, 0x8b, 0x88, 0x01, - 0x7b, 0x18, 0x75, 0xa7, 0x8a, 0x19, 0xd6, 0x4b, 0x99, 0x86, 0x5e, 0xba, - 0x94, 0xf0, 0xc7, 0x21, 0xe3, 0xa8, 0xcb, 0xa6, 0xe2, 0x7e, 0x30, 0x8e, - 0xdd, 0x34, 0xb6, 0xb0, 0x95, 0xef, 0xa5, 0x95, 0xc4, 0x74, 0x5c, 0xe5, - 0xfa, 0x5b, 0x66, 0x92, 0xf5, 0xe3, 0x1c, 0xcb, 0x72, 0xae, 0xf8, 0x00, - 0x2d, 0x86, 0x87, 0x69, 0x74, 0x41, 0xd7, 0x37, 0xc1, 0x58, 0xff, 0x6d, - 0x48, 0xea, 0x24, 0x3d, 0xee, 0x5f, 0x11, 0xbe, 0x0b, 0xf3, 0xfa, 0xa7, - 0x35, 0xee, 0xad, 0xeb, 0xe8, 0xa5, 0xbf, 0x52, 0x32, 0x5b, 0xbb, 0x91, - 0x88, 0x52, 0x36, 0x31, 0xfd, 0x97, 0x82, 0xff, 0x47, 0xaf, 0xc3, 0x0f, - 0x07, 0x1d, 0x6d, 0x52, 0xba, 0xe0, 0xa6, 0xc5, 0x30, 0x8f, 0x1b, 0xdf, - 0xd7, 0xfe, 0x79, 0x36, 0xfa, 0x94, 0x58, 0xfb, 0xc7, 0xae, 0x73, 0x3b, - 0xb1, 0x36, 0x69, 0xbd, 0xe1, 0xc5, 0x87, 0xba, 0x8e, 0xa5, 0xe6, 0x45, - 0x19, 0xeb, 0xc9, 0xf8, 0x2d, 0x94, 0xf6, 0xbb, 0x79, 0xf2, 0x23, 0x3a, - 0x36, 0x6f, 0xd2, 0xf1, 0x82, 0xf5, 0x7c, 0x96, 0x66, 0x58, 0xae, 0x9d, - 0xeb, 0x05, 0xb7, 0x27, 0xf0, 0x59, 0x8c, 0x65, 0x9f, 0xed, 0xe6, 0xa2, - 0x29, 0xe3, 0xee, 0x44, 0xed, 0xb9, 0x2e, 0xa1, 0x47, 0x43, 0xf6, 0x3f, - 0x0d, 0xea, 0xf5, 0x20, 0x53, 0x44, 0x1e, 0x21, 0x7f, 0x96, 0xb9, 0x7d, - 0x61, 0x90, 0x32, 0x25, 0x3c, 0x07, 0xeb, 0x1d, 0xfa, 0xce, 0xe7, 0x4b, - 0x72, 0x5e, 0x47, 0xf9, 0xd9, 0xc8, 0xbb, 0x3f, 0x5e, 0x9d, 0x12, 0xb1, - 0x77, 0xd0, 0xcd, 0x72, 0x3e, 0x63, 0x74, 0xd1, 0x53, 0xaf, 0x28, 0x4c, - 0xe9, 0x90, 0xef, 0x8c, 0x90, 0xef, 0x98, 0x98, 0x8f, 0x4c, 0xc9, 0x60, - 0xbc, 0xa6, 0x7d, 0x0f, 0xfd, 0x7c, 0x1e, 0x50, 0x3a, 0x04, 0xdf, 0x0d, - 0xec, 0x14, 0x71, 0x89, 0x36, 0xae, 0xe3, 0x33, 0x46, 0xcf, 0x30, 0xee, - 0x7c, 0xb6, 0xd0, 0x45, 0xb7, 0x8a, 0x5d, 0xf4, 0x66, 0x71, 0x98, 0x6e, - 0xce, 0x6f, 0xa7, 0x8b, 0x8c, 0x99, 0x2f, 0xda, 0x01, 0x33, 0xc7, 0xf6, - 0xc5, 0x0b, 0x51, 0x11, 0x33, 0xc4, 0x72, 0x87, 0xf6, 0xc0, 0x7f, 0x89, - 0x5d, 0xcc, 0x73, 0x8c, 0xbd, 0xbb, 0xe9, 0x03, 0x7e, 0x67, 0xae, 0xa0, - 0x63, 0x1d, 0xe0, 0x93, 0x1f, 0xaf, 0xe3, 0xd7, 0xf5, 0x79, 0x24, 0xb4, - 0x0e, 0x8f, 0xc4, 0x84, 0xae, 0xcf, 0xcf, 0xf3, 0xf7, 0xf3, 0xf0, 0x9f, - 0x33, 0xbd, 0x59, 0x3f, 0x7f, 0x3d, 0x80, 0xf6, 0xb8, 0x66, 0xcb, 0x58, - 0x49, 0x31, 0xb6, 0x08, 0x9f, 0x83, 0xb6, 0x11, 0x45, 0x87, 0x6e, 0x1e, - 0x9f, 0x4f, 0xb4, 0xcf, 0x2c, 0x75, 0xd3, 0x99, 0x12, 0x63, 0x90, 0x92, - 0x9f, 0x6d, 0x18, 0xb4, 0x0d, 0xec, 0xd5, 0xf5, 0x5f, 0x2f, 0x72, 0xdf, - 0x73, 0x25, 0x89, 0x41, 0x72, 0x4b, 0xbd, 0x94, 0x2f, 0xf5, 0xa8, 0xf3, - 0x07, 0x44, 0x8c, 0xbb, 0xac, 0x63, 0x84, 0xef, 0xd6, 0xd2, 0x6f, 0x6f, - 0x31, 0x4f, 0x61, 0x4d, 0x95, 0x76, 0x29, 0x74, 0xcd, 0x8d, 0x96, 0xba, - 0xc4, 0xe0, 0xb9, 0x19, 0xfa, 0x2e, 0xaf, 0xb7, 0xa3, 0x57, 0xe1, 0x3f, - 0xfe, 0x2a, 0xf8, 0xa6, 0x0c, 0x1e, 0x1b, 0xbd, 0x8a, 0xba, 0x48, 0x7e, - 0x91, 0xe7, 0x94, 0x0c, 0x4f, 0x8a, 0xdc, 0x10, 0x29, 0xa3, 0x27, 0x45, - 0x2d, 0xba, 0x1f, 0x0a, 0xdd, 0x64, 0x65, 0x4d, 0x03, 0x78, 0x04, 0x3e, - 0x18, 0x19, 0x83, 0x75, 0xc2, 0xee, 0x7b, 0x6b, 0x20, 0x36, 0x41, 0xf1, - 0x41, 0xf0, 0xbd, 0x94, 0x59, 0x55, 0x5f, 0x40, 0xe8, 0xfb, 0xd0, 0x3e, - 0x9d, 0x2f, 0xa9, 0xcf, 0xf5, 0x5a, 0xa1, 0xcf, 0x7b, 0x5c, 0xdf, 0x87, - 0x5c, 0xdf, 0xd7, 0xe3, 0xe5, 0x78, 0xcd, 0xe3, 0x75, 0x9e, 0x64, 0x8d, - 0xa2, 0xcc, 0x82, 0xe4, 0xbf, 0xd0, 0xbe, 0xf1, 0xd0, 0x97, 0x15, 0x06, - 0xcf, 0x2c, 0x8f, 0x45, 0xfa, 0x8c, 0x1e, 0x7f, 0x66, 0xea, 0xef, 0x6b, - 0xf1, 0x34, 0x70, 0xd1, 0xdc, 0x4e, 0xa9, 0xe3, 0xd0, 0xaf, 0x6c, 0x14, - 0xd0, 0xed, 0xe4, 0x72, 0x0f, 0xad, 0x88, 0x9a, 0x5c, 0xc0, 0x18, 0xb8, - 0x1f, 0xcf, 0xc9, 0x86, 0x3a, 0x08, 0x35, 0xd7, 0x21, 0xe3, 0x07, 0x22, - 0xd7, 0x79, 0x3e, 0x53, 0xcb, 0xff, 0x55, 0x3b, 0x2d, 0x6a, 0xdc, 0xa0, - 0x2d, 0x63, 0x48, 0x81, 0xf9, 0x19, 0xbf, 0x34, 0xd9, 0x55, 0x33, 0xe8, - 0x67, 0x16, 0x7b, 0x2b, 0x86, 0xfd, 0x22, 0xcb, 0x98, 0xdc, 0x2b, 0x4f, - 0xb9, 0xf6, 0xca, 0x4f, 0x8a, 0xbd, 0x72, 0xec, 0x93, 0x83, 0xae, 0xa0, - 0xa5, 0x57, 0x4c, 0x0b, 0xe6, 0x31, 0xca, 0xf3, 0x68, 0xd2, 0xc5, 0x6b, - 0x42, 0xdf, 0x44, 0x93, 0x7e, 0x19, 0x5f, 0x9d, 0xa2, 0xac, 0x88, 0xbf, - 0x96, 0x9f, 0x71, 0x23, 0x61, 0x5b, 0x93, 0xab, 0x8c, 0x29, 0x2a, 0xc5, - 0x2d, 0x74, 0xb3, 0xdc, 0xc1, 0x98, 0xef, 0x6f, 0x69, 0xb5, 0x4c, 0x8c, - 0x0d, 0xb7, 0x53, 0x3e, 0xca, 0xbc, 0x36, 0x19, 0xe4, 0x79, 0x65, 0x7c, - 0x3b, 0xc9, 0xf2, 0xc7, 0x63, 0xa8, 0x94, 0x6a, 0xef, 0xe7, 0xa2, 0x71, - 0x33, 0x31, 0xdd, 0xc3, 0xf6, 0x4b, 0x88, 0xff, 0x6d, 0xfe, 0xff, 0x6c, - 0x04, 0xb4, 0x59, 0x5c, 0xc2, 0xf7, 0x8c, 0x7d, 0x0a, 0xb5, 0xf7, 0x67, - 0xb9, 0xcd, 0xec, 0x34, 0xec, 0x20, 0xd8, 0x7b, 0x36, 0xff, 0xcb, 0x36, - 0x15, 0xe6, 0xbb, 0xdc, 0xb5, 0x6c, 0xc4, 0x10, 0x3a, 0x1e, 0x75, 0x5d, - 0xc6, 0xd4, 0x67, 0xdc, 0x98, 0xe5, 0xbe, 0xdc, 0x24, 0x3c, 0xc3, 0xa4, - 0x4c, 0x74, 0x1f, 0xcb, 0xc1, 0x76, 0xfe, 0x44, 0x3e, 0xd6, 0x56, 0xca, - 0x4f, 0x8d, 0xab, 0x7c, 0xac, 0x48, 0x9b, 0x7c, 0x2c, 0xdc, 0xc7, 0x38, - 0x60, 0xbe, 0x76, 0x6f, 0x36, 0xea, 0x7c, 0x2f, 0x19, 0x99, 0xe8, 0x36, - 0x81, 0x99, 0x2a, 0x4b, 0xfb, 0xb9, 0x0f, 0x71, 0x33, 0x33, 0xcd, 0x7d, - 0x2d, 0x39, 0xfb, 0x5f, 0xbb, 0x97, 0x8c, 0xa2, 0x9d, 0xdf, 0xd5, 0x2e, - 0x4e, 0xa2, 0xed, 0x12, 0xda, 0xd7, 0xfe, 0x27, 0x11, 0xd5, 0xe3, 0x74, - 0xde, 0x8b, 0xf1, 0x40, 0xbe, 0xf8, 0xb3, 0x72, 0x9b, 0x6e, 0x16, 0x61, - 0x8f, 0x1b, 0xcc, 0xf7, 0xe8, 0x91, 0x49, 0xd9, 0x0a, 0x63, 0xc0, 0x6b, - 0x7b, 0x7d, 0xab, 0xc5, 0x37, 0x6a, 0x99, 0xa6, 0xd8, 0x96, 0x66, 0x3f, - 0xbc, 0xb4, 0xc1, 0x86, 0xc9, 0xbe, 0x82, 0x35, 0x14, 0xeb, 0x67, 0xb6, - 0xe6, 0xb7, 0x81, 0xf7, 0x60, 0x1b, 0x5d, 0x60, 0xfd, 0x25, 0xe3, 0x93, - 0x58, 0x97, 0xb2, 0x0e, 0x93, 0xf2, 0x93, 0x6a, 0xfa, 0x39, 0x04, 0xc9, - 0xc3, 0xa3, 0x8d, 0xb8, 0x48, 0xc7, 0xfe, 0x7a, 0xc0, 0xb1, 0xbf, 0x1e, - 0x72, 0xc4, 0x45, 0x86, 0x05, 0x3e, 0x6b, 0x60, 0xaa, 0xb0, 0xc2, 0x54, - 0xc0, 0x5e, 0x52, 0xb7, 0x2d, 0xd6, 0x75, 0xdb, 0x8e, 0x75, 0x74, 0x9b, - 0x97, 0xad, 0xba, 0xa2, 0xf4, 0x88, 0x15, 0xc5, 0x1a, 0x73, 0x83, 0xf5, - 0xc5, 0xeb, 0xd5, 0x69, 0xd6, 0x23, 0x51, 0xd6, 0x23, 0x53, 0xac, 0x47, - 0x26, 0x59, 0x8f, 0xd8, 0x4c, 0x03, 0x93, 0xc7, 0xfe, 0x11, 0xeb, 0x69, - 0xac, 0x1f, 0x33, 0xf4, 0x4c, 0x15, 0x3a, 0x79, 0x8a, 0x31, 0xd0, 0x47, - 0xb4, 0x3a, 0xdf, 0xcb, 0xfc, 0x2b, 0x71, 0x4f, 0xb3, 0x5d, 0x83, 0xda, - 0x2b, 0xf0, 0x17, 0xff, 0x39, 0xf4, 0xce, 0x2b, 0x59, 0x1a, 0xf1, 0xdd, - 0x2c, 0x82, 0xce, 0xab, 0xa8, 0x55, 0xf1, 0x12, 0x64, 0x1b, 0x35, 0x82, - 0x7f, 0x30, 0x31, 0xc3, 0x7d, 0x1f, 0xf1, 0xe5, 0x79, 0x5e, 0xbe, 0x1d, - 0xcd, 0x86, 0xfa, 0x59, 0x06, 0x8e, 0x2b, 0x19, 0x38, 0xde, 0x90, 0x81, - 0x6c, 0x8e, 0x47, 0xd2, 0xb7, 0xb0, 0x9d, 0xc6, 0x0f, 0x26, 0x76, 0xf5, - 0xb1, 0xfc, 0x22, 0x66, 0xa2, 0x51, 0xbf, 0xc7, 0x4f, 0xa7, 0xc3, 0x41, - 0x55, 0xf7, 0xc7, 0x14, 0x39, 0xef, 0xf9, 0xe2, 0xbb, 0x8c, 0x4b, 0x58, - 0x4e, 0x43, 0x38, 0xbf, 0x0c, 0xbf, 0x28, 0xdb, 0x0d, 0xdd, 0xc2, 0xaf, - 0xb4, 0x28, 0xda, 0xe2, 0xdc, 0x9a, 0x64, 0x1d, 0x17, 0x5d, 0x31, 0xac, - 0x99, 0xb8, 0xf1, 0x9b, 0xc3, 0xa8, 0xe1, 0xfe, 0x83, 0xea, 0xe7, 0x86, - 0xe5, 0xde, 0x5c, 0x72, 0x97, 0xd4, 0x27, 0xcc, 0xa3, 0xe1, 0xb8, 0xb0, - 0xdd, 0x3a, 0xae, 0xc8, 0xf5, 0x73, 0x91, 0xe7, 0xbb, 0x12, 0x9d, 0xe4, - 0xf9, 0xee, 0x51, 0x6b, 0x67, 0x96, 0xbf, 0x17, 0xeb, 0x32, 0xaf, 0xa1, - 0xc3, 0xa8, 0x7f, 0x1f, 0x12, 0x75, 0x22, 0x4e, 0xa2, 0x0e, 0x4f, 0x02, - 0xcf, 0x63, 0xee, 0x85, 0xfe, 0xf8, 0x07, 0x5e, 0xa3, 0xf1, 0x5e, 0xf0, - 0x23, 0x1f, 0x97, 0x67, 0xe8, 0x52, 0x41, 0xf7, 0xe1, 0x3d, 0x32, 0xbe, - 0x8b, 0x7e, 0xf8, 0x68, 0x87, 0xfd, 0x9e, 0xc8, 0x05, 0x31, 0xfe, 0xc4, - 0xdd, 0xa7, 0xa3, 0xaa, 0x4f, 0xa8, 0x75, 0xd9, 0x85, 0xda, 0x3e, 0x84, - 0x9a, 0x48, 0x8b, 0xa2, 0x16, 0x65, 0xa7, 0xb0, 0x59, 0x17, 0x85, 0xed, - 0xb1, 0x7f, 0x57, 0xa3, 0x3e, 0xe6, 0x7e, 0xd7, 0xb5, 0x3b, 0xbc, 0x6e, - 0x1d, 0x12, 0x18, 0x6d, 0x14, 0xf5, 0xda, 0x45, 0x5e, 0xea, 0x8c, 0xf8, - 0xce, 0x58, 0xc0, 0x77, 0x0f, 0xa9, 0xef, 0x3e, 0x2f, 0xb0, 0xb1, 0x11, - 0xeb, 0x66, 0xbd, 0x28, 0xf8, 0x9d, 0xe7, 0xd9, 0x9e, 0x64, 0x7e, 0x8f, - 0x54, 0xf8, 0xb9, 0xa7, 0x05, 0x3d, 0x35, 0x3d, 0x40, 0x0b, 0xc8, 0x40, - 0x8f, 0xe2, 0x7f, 0xcb, 0x4c, 0xf9, 0xf5, 0xb8, 0xdb, 0xd1, 0x99, 0xb1, - 0x4e, 0x01, 0x63, 0xc5, 0x98, 0x4c, 0x5f, 0xbc, 0x1c, 0xf1, 0xe5, 0xe6, - 0x61, 0xeb, 0x20, 0xdf, 0x65, 0x0f, 0xe2, 0xa9, 0xb8, 0x0f, 0x3b, 0x29, - 0x9e, 0x46, 0xbf, 0xd0, 0x4e, 0xd3, 0xc0, 0x76, 0xd1, 0xc2, 0x79, 0xdf, - 0x76, 0x75, 0x5f, 0xb7, 0x98, 0x0b, 0x32, 0xf0, 0x1e, 0xfd, 0x6e, 0xbc, - 0x17, 0xef, 0xc7, 0x7d, 0x78, 0x9e, 0x7c, 0xee, 0x00, 0xeb, 0xed, 0xc4, - 0xb4, 0x7c, 0x96, 0x71, 0x5d, 0x7e, 0x37, 0x60, 0x7b, 0xf7, 0x57, 0xce, - 0x9f, 0x4f, 0xd5, 0xf1, 0xc1, 0xfc, 0x6d, 0xa7, 0xb2, 0xf0, 0x7d, 0xe2, - 0xbb, 0x11, 0x9f, 0xb0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xf3, - 0x33, 0xc5, 0xdb, 0xc2, 0x66, 0xcf, 0xa5, 0x47, 0x7c, 0xe5, 0x32, 0xc6, - 0x3b, 0xe2, 0x4b, 0xb1, 0x0c, 0x24, 0x8b, 0x89, 0x5a, 0x5e, 0xe2, 0x02, - 0x3a, 0xdd, 0x6f, 0x85, 0x4e, 0x1b, 0xef, 0x0f, 0xcb, 0x9a, 0xb7, 0x38, - 0x66, 0x39, 0x2c, 0xb0, 0x1c, 0x16, 0x58, 0x0e, 0x0b, 0x2c, 0x87, 0x6c, - 0xab, 0xbe, 0x56, 0x60, 0x39, 0xe4, 0xb5, 0xe4, 0x55, 0x5e, 0x4b, 0xa4, - 0xec, 0xc6, 0x95, 0x7f, 0x53, 0xcb, 0xae, 0x3b, 0x6f, 0x53, 0xcb, 0x2a, - 0xd6, 0x6f, 0xf2, 0x1d, 0x99, 0x68, 0x96, 0xd9, 0x5b, 0x2c, 0xb3, 0x1d, - 0xb1, 0x41, 0xba, 0x5b, 0xc2, 0x9c, 0x59, 0xe6, 0x1c, 0xeb, 0xea, 0x94, - 0x1f, 0x58, 0x2b, 0xc0, 0xf2, 0x04, 0xac, 0x69, 0x31, 0xdd, 0x07, 0xe9, - 0x1e, 0xeb, 0xeb, 0xbb, 0x25, 0xc8, 0xf0, 0x1e, 0x75, 0x6e, 0xb1, 0x0c, - 0x63, 0xfd, 0xb3, 0x7d, 0xb7, 0x8a, 0x06, 0x63, 0xb2, 0x40, 0x28, 0x43, - 0xd0, 0xa7, 0x02, 0xa7, 0xf1, 0xbc, 0xaf, 0xb0, 0xde, 0x87, 0x0f, 0x0f, - 0xeb, 0xc5, 0x19, 0x1f, 0xaf, 0x17, 0x91, 0x9b, 0xac, 0x4f, 0xcf, 0x97, - 0x6c, 0x96, 0xfb, 0x7e, 0xfa, 0x56, 0x09, 0xeb, 0x34, 0x68, 0xc4, 0xe7, - 0x65, 0x12, 0xbe, 0x31, 0x23, 0x86, 0xb1, 0x8f, 0x67, 0x0d, 0xc1, 0x27, - 0x7f, 0x0a, 0x3a, 0x30, 0xed, 0x5f, 0xdc, 0x85, 0xda, 0xf3, 0x71, 0xa3, - 0x53, 0xf9, 0x1a, 0x71, 0x8c, 0xf6, 0x68, 0x0b, 0xba, 0xe1, 0xbc, 0xdd, - 0xbe, 0x24, 0x7e, 0xb3, 0x21, 0x0a, 0xff, 0x9b, 0x4b, 0x7f, 0x5d, 0xe2, - 0xfb, 0x05, 0xbd, 0x66, 0x12, 0x7e, 0xe4, 0x90, 0xd3, 0xd3, 0xfe, 0xd8, - 0x0c, 0x3d, 0x5b, 0x45, 0xbf, 0xaf, 0x52, 0x3e, 0x0c, 0x7d, 0x64, 0x45, - 0xef, 0x90, 0xa4, 0x5d, 0x37, 0xe3, 0xce, 0x27, 0xbc, 0x75, 0x9c, 0x99, - 0x10, 0x38, 0xb9, 0x8b, 0xf5, 0x0b, 0x68, 0xf3, 0x13, 0xe6, 0x35, 0x7e, - 0x5f, 0x41, 0xeb, 0xb7, 0x1f, 0xb3, 0xce, 0xc1, 0x9c, 0xe1, 0x7c, 0x6d, - 0x9d, 0xb6, 0xaa, 0x74, 0x9a, 0xed, 0xd0, 0x69, 0xb9, 0xba, 0x4e, 0x63, - 0xde, 0x10, 0xba, 0x0c, 0xba, 0xea, 0x51, 0xc6, 0x91, 0xf2, 0x18, 0xf8, - 0x70, 0x87, 0xd0, 0x5d, 0xac, 0xfb, 0xd9, 0xae, 0x58, 0xac, 0x66, 0x7d, - 0x87, 0x85, 0x0e, 0xd1, 0xfc, 0xbd, 0x7f, 0xb7, 0x94, 0x8b, 0x6e, 0xa1, - 0x0f, 0x72, 0x27, 0xa1, 0xb7, 0xbc, 0xda, 0x8f, 0x73, 0x3b, 0xb4, 0xb7, - 0x23, 0x2f, 0xb1, 0x3e, 0x5b, 0x8c, 0xc2, 0xa6, 0xed, 0x51, 0xb6, 0x0f, - 0xea, 0x72, 0x61, 0xaf, 0x0b, 0x63, 0xd5, 0xfa, 0x6c, 0x40, 0xf9, 0x35, - 0xe0, 0x87, 0xc4, 0x9c, 0xb7, 0xc5, 0x08, 0x26, 0x30, 0x02, 0xdf, 0x13, - 0x60, 0x7a, 0x89, 0x1a, 0xe2, 0x44, 0xef, 0xd2, 0xaa, 0x90, 0x8d, 0x77, - 0x05, 0x76, 0xc9, 0xf3, 0x77, 0xb3, 0xd3, 0x07, 0x45, 0x3f, 0xf3, 0x4b, - 0x0d, 0xfd, 0x38, 0x57, 0x78, 0x0f, 0xeb, 0x86, 0xe8, 0x6b, 0x65, 0x42, - 0xea, 0xc0, 0xc5, 0x32, 0x6a, 0x80, 0x89, 0x3e, 0x73, 0x5f, 0xf5, 0x38, - 0xd1, 0x0f, 0xad, 0x0f, 0x36, 0x22, 0x7b, 0x8c, 0x6b, 0xfb, 0x31, 0x47, - 0x59, 0x07, 0x0f, 0x3d, 0xcb, 0xef, 0xc7, 0xb5, 0xf5, 0xc7, 0x73, 0xaf, - 0x3e, 0x1e, 0xf8, 0xf6, 0x70, 0xcf, 0xbb, 0x74, 0x57, 0x8d, 0xe7, 0x6e, - 0x7d, 0x3c, 0xcf, 0xa8, 0xf1, 0x50, 0xce, 0x88, 0x0d, 0x28, 0xdc, 0xbf, - 0xe1, 0x67, 0x77, 0x27, 0x18, 0xc7, 0xe4, 0x96, 0x40, 0xe7, 0xfd, 0x8a, - 0x9f, 0x9c, 0x7e, 0x54, 0x67, 0x5f, 0xad, 0xc9, 0x3b, 0xac, 0x7f, 0xef, - 0x09, 0x1c, 0x33, 0xc2, 0x38, 0x06, 0xd7, 0x29, 0x0f, 0x3d, 0x9d, 0x0b, - 0xa3, 0x4e, 0xed, 0x0c, 0x8f, 0x9b, 0xed, 0xb1, 0x69, 0xfe, 0x14, 0xfe, - 0x35, 0x3c, 0x47, 0xdf, 0xff, 0x3c, 0xdd, 0x9b, 0x87, 0x2e, 0x07, 0x8e, - 0x95, 0xb5, 0x6c, 0xef, 0x2d, 0x4b, 0xff, 0x6e, 0xca, 0xd3, 0xbf, 0x0b, - 0xdf, 0xee, 0x34, 0x70, 0x7e, 0x08, 0x7e, 0xe0, 0xa4, 0xfa, 0xad, 0x8f, - 0x5c, 0x15, 0xcf, 0xf2, 0xd2, 0x4b, 0x33, 0x8e, 0xd8, 0x38, 0xc4, 0xaa, - 0x64, 0x59, 0xcf, 0xd8, 0xa1, 0x0e, 0x43, 0xe6, 0xdc, 0xdc, 0xa8, 0x6a, - 0xec, 0x74, 0x94, 0xe7, 0xcc, 0x8e, 0x1a, 0x46, 0x4a, 0xf8, 0x1a, 0xba, - 0xed, 0x1e, 0xea, 0xe2, 0x75, 0xf4, 0x2c, 0xa1, 0x96, 0x9a, 0x65, 0x62, - 0x0f, 0xe0, 0x12, 0xf3, 0x64, 0x3e, 0x6a, 0x45, 0x1e, 0x17, 0x76, 0x29, - 0xd6, 0x17, 0x03, 0x74, 0x62, 0x5a, 0xa3, 0x0f, 0x7c, 0xbc, 0x84, 0x3a, - 0x9a, 0x51, 0x1e, 0x3f, 0xfc, 0xc7, 0x63, 0xe6, 0x9b, 0xbc, 0x2e, 0x5d, - 0x12, 0x7e, 0x99, 0x0b, 0x94, 0x63, 0x39, 0x3d, 0x22, 0xe4, 0xd4, 0x18, - 0x61, 0x29, 0x62, 0xb9, 0x42, 0x6c, 0xc2, 0xb8, 0xa8, 0xdb, 0x23, 0x6d, - 0x1d, 0x1e, 0xe5, 0xb2, 0xaa, 0x87, 0x90, 0x86, 0xee, 0xd8, 0xb8, 0x4f, - 0x22, 0xfd, 0x89, 0x7d, 0x31, 0x4e, 0x4c, 0xe6, 0xf6, 0x7d, 0xc3, 0xae, - 0x33, 0x45, 0xbd, 0x48, 0xd0, 0x4e, 0xf8, 0x13, 0x8d, 0x29, 0xa6, 0x9b, - 0xfe, 0xdd, 0x19, 0xa7, 0xdf, 0xe0, 0x9c, 0xc8, 0xeb, 0x7f, 0xa5, 0x2a, - 0xd7, 0xe0, 0x1c, 0xdb, 0xf4, 0xf9, 0x83, 0x4e, 0x4c, 0x62, 0x15, 0x93, - 0xc2, 0x97, 0xb3, 0x9b, 0x12, 0x0b, 0x53, 0xf4, 0x68, 0x01, 0x3a, 0x8c, - 0xee, 0x24, 0x6c, 0xfc, 0xa2, 0x0c, 0x64, 0x7c, 0x8a, 0x52, 0x55, 0xd0, - 0xc8, 0xc7, 0x58, 0x89, 0x79, 0xaf, 0x88, 0x3d, 0x7f, 0x3e, 0x2e, 0xe3, - 0x77, 0x54, 0x7e, 0x5d, 0xf9, 0xcb, 0x87, 0x29, 0xb9, 0x40, 0xd9, 0x4c, - 0xf4, 0x4b, 0xa2, 0xd6, 0x75, 0x26, 0x3a, 0xa1, 0x7c, 0x3b, 0x11, 0xbe, - 0x0e, 0x7f, 0x99, 0x49, 0x5f, 0x2e, 0x58, 0xd9, 0x0c, 0x49, 0x9f, 0x05, - 0x71, 0x1f, 0x0c, 0x5e, 0x7b, 0x77, 0xb0, 0x0e, 0x39, 0x21, 0xfc, 0x16, - 0x8c, 0x54, 0xe6, 0xd1, 0x1e, 0x3e, 0x87, 0x7e, 0x82, 0x9d, 0x96, 0x29, - 0x3e, 0xa5, 0xda, 0xd6, 0x28, 0xc4, 0xbc, 0x10, 0xfa, 0x55, 0x3b, 0x1b, - 0x35, 0x1a, 0xf7, 0xc3, 0xe7, 0x71, 0x42, 0xe0, 0xc8, 0x11, 0xb6, 0x79, - 0x44, 0xbb, 0xda, 0xac, 0xf0, 0x5f, 0xf0, 0x79, 0xf9, 0x81, 0x21, 0xfd, - 0x9b, 0x08, 0xb8, 0x2e, 0xfd, 0x1a, 0xfc, 0xcc, 0x32, 0xf7, 0xa3, 0x29, - 0x9e, 0x7e, 0x98, 0xe2, 0x9b, 0xf0, 0x33, 0x9d, 0xbc, 0xaf, 0x7e, 0x26, - 0xa6, 0x35, 0xaf, 0x3d, 0x37, 0x58, 0x36, 0x5e, 0x5f, 0xd7, 0xfe, 0xfb, - 0x50, 0xaf, 0xe1, 0x4c, 0xab, 0x90, 0xf8, 0xdd, 0x0c, 0x60, 0xf0, 0x7c, - 0xf5, 0x71, 0xfc, 0x5e, 0x8c, 0x2f, 0x2d, 0xb0, 0x71, 0x84, 0xb1, 0x0d, - 0x30, 0xce, 0x98, 0xd8, 0x17, 0x8b, 0x3f, 0x16, 0xf1, 0xe5, 0x97, 0x07, - 0xc9, 0x0f, 0x7f, 0x9c, 0xad, 0x63, 0x29, 0xba, 0x45, 0xdc, 0xbb, 0xdc, - 0x8f, 0xc4, 0xfa, 0x0c, 0x9d, 0x78, 0x87, 0xed, 0x86, 0x09, 0x15, 0x87, - 0xd3, 0x21, 0x6a, 0x53, 0xc9, 0xbd, 0x54, 0xad, 0x53, 0x34, 0xef, 0xe9, - 0xbd, 0x0e, 0xe7, 0x6f, 0x73, 0x41, 0x76, 0x9d, 0x98, 0x02, 0xfe, 0x29, - 0x31, 0x47, 0x97, 0x88, 0xe4, 0x1c, 0x37, 0xf6, 0x31, 0xba, 0x78, 0x9e, - 0x60, 0x0f, 0xc2, 0xef, 0xf7, 0x35, 0xfe, 0xc4, 0x7e, 0xc4, 0xd5, 0x21, - 0xe0, 0xa8, 0x3e, 0x9b, 0x79, 0x66, 0x1a, 0xe7, 0x83, 0x6c, 0x9f, 0x69, - 0xdc, 0x2b, 0x7d, 0x51, 0x6c, 0xb3, 0xa9, 0xf9, 0x82, 0x1f, 0x6a, 0x54, - 0xd5, 0x29, 0xb0, 0xc8, 0xec, 0x07, 0x9d, 0x3e, 0x2d, 0x79, 0x5c, 0x6f, - 0xef, 0x62, 0x23, 0xb1, 0x4e, 0xf8, 0xdd, 0x30, 0xd4, 0xeb, 0xdc, 0x0b, - 0xda, 0xf3, 0x1c, 0x39, 0xf7, 0x36, 0x1e, 0xdf, 0xa5, 0x7f, 0xb3, 0xe8, - 0xfe, 0xcc, 0xdb, 0x16, 0x8f, 0x79, 0xfb, 0xf9, 0x90, 0xdc, 0x3b, 0x7b, - 0x58, 0xb5, 0xf1, 0x8a, 0x6f, 0x5d, 0xfe, 0x0e, 0xfc, 0x50, 0x8d, 0xfc, - 0x8b, 0x77, 0x84, 0x5e, 0x69, 0xf5, 0x85, 0x47, 0x58, 0x9f, 0x4a, 0x39, - 0x3e, 0xe1, 0x21, 0xc7, 0xfd, 0x31, 0xe0, 0x96, 0x8f, 0x2f, 0xc7, 0xc7, - 0xdb, 0xca, 0xf1, 0x9e, 0x61, 0xe9, 0x8b, 0x6d, 0x95, 0x63, 0xe4, 0x00, - 0x9d, 0xa8, 0xb6, 0xf3, 0x7b, 0x61, 0x1e, 0x90, 0xcb, 0xee, 0xf4, 0x95, - 0x80, 0x66, 0xda, 0x5f, 0x82, 0x7d, 0x43, 0xf0, 0x25, 0xf6, 0x5e, 0x4e, - 0x1a, 0xa9, 0x79, 0xf7, 0x5e, 0xea, 0x46, 0xee, 0xbd, 0xed, 0x71, 0x2f, - 0xb0, 0x3b, 0x64, 0xc3, 0x8a, 0x48, 0x5f, 0x80, 0xa6, 0xdf, 0xb0, 0xef, - 0x70, 0xc9, 0xca, 0x96, 0x09, 0xbe, 0xee, 0x30, 0x9d, 0xc3, 0xfe, 0xb4, - 0xf2, 0x25, 0x1f, 0x2b, 0x48, 0x3a, 0x84, 0x0e, 0x0a, 0xfe, 0x00, 0xbe, - 0x8d, 0xa4, 0xfd, 0x69, 0x9e, 0x63, 0xe9, 0x47, 0xce, 0x2c, 0x45, 0xd4, - 0xbc, 0x71, 0x5b, 0x3c, 0xcf, 0x33, 0x5f, 0x10, 0xf3, 0x65, 0x3d, 0xbf, - 0x52, 0x8f, 0x4f, 0xc6, 0xda, 0x50, 0xa3, 0xff, 0xe0, 0x75, 0xcf, 0x7f, - 0x30, 0x24, 0x6a, 0x37, 0xdc, 0xa8, 0x1e, 0x64, 0xbc, 0x89, 0x39, 0x85, - 0x0f, 0x52, 0xfb, 0x88, 0x1f, 0xda, 0x4b, 0xbd, 0x07, 0x18, 0x05, 0x18, - 0x64, 0x33, 0xbe, 0x34, 0x0e, 0x22, 0xce, 0xdc, 0xe4, 0x7b, 0x50, 0x73, - 0x6a, 0xdc, 0x4c, 0x51, 0x0f, 0xfc, 0x10, 0xa8, 0x25, 0x6d, 0xe6, 0x9a, - 0x64, 0xec, 0x94, 0x90, 0xb1, 0xd4, 0xf2, 0x29, 0x25, 0x63, 0xa7, 0x94, - 0x1f, 0xfe, 0x94, 0x92, 0xb1, 0x53, 0x4a, 0xc6, 0x4e, 0x29, 0x19, 0x3b, - 0xc5, 0x7c, 0x3e, 0xc6, 0xf8, 0x16, 0x58, 0x44, 0xfb, 0x41, 0x7b, 0x29, - 0x53, 0xc2, 0x75, 0xac, 0xcf, 0x6e, 0x39, 0x7b, 0x69, 0x44, 0xca, 0x19, - 0x63, 0x13, 0x19, 0xaf, 0xc7, 0xef, 0xc2, 0x1c, 0xfc, 0x1e, 0xd3, 0xef, - 0x23, 0x3a, 0x33, 0x8f, 0xbe, 0xfa, 0x28, 0x29, 0x6a, 0xc9, 0x76, 0x50, - 0xc2, 0x89, 0x85, 0x43, 0xc8, 0x0f, 0x93, 0xb6, 0x5f, 0xb6, 0x6d, 0xae, - 0x98, 0xe6, 0x93, 0x98, 0x9a, 0x2f, 0xb7, 0x5d, 0xd4, 0x45, 0xe9, 0x22, - 0xe8, 0x8a, 0x98, 0x4a, 0x93, 0xe7, 0x46, 0xd0, 0x49, 0x86, 0x44, 0xb9, - 0x68, 0x70, 0x4c, 0xd1, 0xe0, 0xdb, 0x62, 0x8c, 0x88, 0x49, 0x84, 0x2f, - 0xb3, 0x3d, 0x1d, 0x72, 0x85, 0x31, 0x7e, 0x0e, 0xcb, 0xc2, 0xc1, 0x08, - 0xeb, 0xa4, 0x8d, 0xd3, 0xa1, 0x31, 0xf6, 0x76, 0xba, 0x67, 0xa3, 0x79, - 0x39, 0x77, 0x1c, 0x6b, 0x49, 0x44, 0xad, 0x23, 0x12, 0x17, 0x6f, 0xb1, - 0x6b, 0x74, 0x34, 0xba, 0x97, 0x8f, 0xad, 0x74, 0x96, 0x0e, 0x90, 0xd1, - 0x57, 0xa3, 0xbf, 0x60, 0x39, 0xe8, 0x66, 0x39, 0x38, 0xaa, 0xec, 0x92, - 0xa3, 0x75, 0xbb, 0x64, 0xcf, 0x1e, 0xc4, 0x65, 0x64, 0xc4, 0xbe, 0xd7, - 0x56, 0x55, 0x43, 0x00, 0xbe, 0x6f, 0x9c, 0x77, 0x51, 0x7c, 0x18, 0xe7, - 0xf8, 0x2d, 0x22, 0x6b, 0x32, 0xee, 0x1b, 0xdf, 0x23, 0xb0, 0xbb, 0xcf, - 0xc2, 0x3d, 0x47, 0xa5, 0xde, 0xf3, 0x91, 0x7f, 0xfc, 0x36, 0xe3, 0x89, - 0x1a, 0x3d, 0xc1, 0xef, 0xcc, 0x17, 0xf7, 0xf1, 0xb3, 0x75, 0x4d, 0x09, - 0x3b, 0x6e, 0xf8, 0xb6, 0x92, 0xbf, 0xaf, 0xdd, 0xbb, 0x2d, 0xc1, 0x8f, - 0x8c, 0xa7, 0x8d, 0xd9, 0xe8, 0x7b, 0xb5, 0xd3, 0x27, 0xe1, 0x63, 0x87, - 0x9c, 0x58, 0x21, 0xd3, 0xe7, 0x25, 0x1f, 0x12, 0x2b, 0x35, 0xe2, 0x63, - 0x21, 0x2f, 0x35, 0xfa, 0x77, 0x1e, 0x5b, 0x88, 0xb0, 0x77, 0x22, 0x9f, - 0x9f, 0xa6, 0x19, 0x91, 0x83, 0x8d, 0x38, 0xe9, 0x33, 0xf3, 0xfa, 0x5d, - 0xb6, 0xe2, 0x8d, 0xcf, 0x20, 0xce, 0xad, 0xb8, 0x48, 0x6b, 0xaf, 0x39, - 0xf0, 0xd7, 0x8d, 0x2d, 0xac, 0xf6, 0x85, 0x45, 0x4e, 0xf8, 0x76, 0xc6, - 0x48, 0x3a, 0x1e, 0x7a, 0x9c, 0x9f, 0x0f, 0x3f, 0x5e, 0x80, 0x92, 0x57, - 0xd0, 0xae, 0x93, 0x46, 0x17, 0x6a, 0x5f, 0xe0, 0xef, 0xc5, 0xfe, 0x65, - 0x86, 0xba, 0xd5, 0xde, 0x44, 0x8f, 0xda, 0xcf, 0x8a, 0xb0, 0xec, 0x35, - 0x72, 0x9d, 0x47, 0xeb, 0x3e, 0x3d, 0xc8, 0x84, 0xdb, 0xa7, 0xf7, 0xf4, - 0x3a, 0xeb, 0xd5, 0x7a, 0x72, 0x80, 0x58, 0xd6, 0x2e, 0x52, 0xbe, 0x4a, - 0x33, 0x4f, 0x1b, 0xcd, 0xe9, 0xdb, 0xf4, 0x3d, 0xdd, 0x9d, 0x31, 0xf3, - 0xc2, 0x9b, 0x76, 0x50, 0xf1, 0x5f, 0x27, 0x9d, 0x29, 0x05, 0x79, 0xcd, - 0x87, 0x6e, 0x05, 0xbd, 0xfc, 0xc3, 0xc8, 0x73, 0xf9, 0x7a, 0xa0, 0x93, - 0x96, 0x96, 0x10, 0x6b, 0xf1, 0x47, 0x7b, 0x64, 0x7c, 0x71, 0x9a, 0xe9, - 0x72, 0x80, 0xd7, 0x47, 0x43, 0xed, 0x1d, 0xe1, 0x1a, 0x74, 0x89, 0xa8, - 0x37, 0x1a, 0xf8, 0xd2, 0x44, 0x90, 0xed, 0x02, 0xb9, 0xf7, 0x70, 0x88, - 0x9f, 0xfd, 0xfd, 0x52, 0x1a, 0xfe, 0xb2, 0xd0, 0x11, 0x7e, 0x7e, 0x92, - 0xf1, 0x44, 0x9c, 0x3a, 0xa9, 0xb2, 0xd4, 0xc9, 0x76, 0x41, 0x27, 0xe3, - 0x89, 0xb1, 0xd0, 0xa8, 0x4f, 0xbc, 0x4b, 0xe4, 0xd4, 0x3c, 0x1c, 0x38, - 0xc0, 0x7c, 0x85, 0x77, 0xbd, 0xae, 0xde, 0xe5, 0x7e, 0xc7, 0x2f, 0x6a, - 0x38, 0x3f, 0xe2, 0x37, 0x2f, 0xdc, 0xc2, 0xef, 0x51, 0xcd, 0xcf, 0x30, - 0x76, 0x0e, 0x53, 0x7e, 0xbe, 0x83, 0xc7, 0x10, 0x63, 0x3b, 0x22, 0xca, - 0xe7, 0x8f, 0x50, 0xb6, 0x7a, 0x92, 0x7e, 0xbf, 0xea, 0xf4, 0x09, 0x3f, - 0xc2, 0x7d, 0x96, 0x39, 0xfd, 0x5d, 0xdc, 0xaf, 0x0f, 0x6d, 0xb7, 0x8e, - 0x09, 0x92, 0xff, 0x7b, 0x61, 0xea, 0x7c, 0x0e, 0xbe, 0x97, 0x1a, 0x15, - 0xa3, 0xd6, 0xa5, 0x3b, 0x24, 0xfd, 0xcf, 0x2f, 0x88, 0xb8, 0x5a, 0xbe, - 0x9f, 0x9f, 0x39, 0x87, 0x76, 0x2f, 0x98, 0x74, 0xd3, 0x96, 0xf4, 0x7e, - 0x23, 0x10, 0x26, 0xff, 0xcb, 0x88, 0x7d, 0x02, 0x56, 0x33, 0x2f, 0xd8, - 0xfb, 0x58, 0xbf, 0x3f, 0x87, 0xfb, 0xf8, 0xf3, 0x65, 0x9c, 0x07, 0x79, - 0x9c, 0x58, 0xaf, 0x11, 0xef, 0x02, 0xbd, 0x78, 0x20, 0x12, 0x12, 0xfc, - 0xf7, 0x08, 0xf3, 0x54, 0x87, 0xf0, 0x35, 0xf6, 0xa3, 0xad, 0x3d, 0xc4, - 0xd8, 0xc2, 0xbc, 0x30, 0xb1, 0x0f, 0xe7, 0xf1, 0x3e, 0x3f, 0xd3, 0x48, - 0xf2, 0x10, 0xc6, 0xd3, 0xc4, 0xdc, 0x81, 0x43, 0x13, 0xc4, 0xf3, 0x09, - 0xfc, 0xc1, 0xf3, 0x19, 0x42, 0x7d, 0xa7, 0x20, 0xa5, 0xf8, 0x1d, 0xc9, - 0x92, 0x1c, 0xf7, 0x5c, 0xd5, 0x4f, 0xd2, 0x4f, 0x75, 0x74, 0x44, 0xff, - 0x9e, 0x21, 0x0d, 0xe2, 0xd9, 0x5a, 0x56, 0x70, 0xdc, 0x4b, 0x77, 0x4b, - 0x3d, 0x74, 0x4f, 0xed, 0x69, 0xdd, 0x15, 0x76, 0x19, 0xeb, 0xf0, 0x74, - 0x2f, 0xdd, 0x59, 0xea, 0x20, 0xea, 0x0f, 0x8a, 0x3d, 0xe7, 0xbb, 0xa5, - 0x32, 0xbf, 0x3f, 0x31, 0x22, 0xfd, 0x3a, 0x0d, 0x1e, 0xb9, 0xeb, 0xc1, - 0x23, 0x1f, 0x08, 0x1e, 0xd9, 0x37, 0xb2, 0x36, 0x8f, 0xec, 0x52, 0xb6, - 0x48, 0x90, 0x3a, 0x15, 0x7f, 0xbc, 0xc4, 0xfc, 0xf1, 0x2c, 0xf3, 0xc7, - 0xe1, 0x36, 0xfc, 0x61, 0xb8, 0xf8, 0xe3, 0x88, 0xe0, 0x8f, 0x87, 0x46, - 0xd6, 0xe2, 0x8f, 0xc3, 0xfe, 0xb5, 0x7c, 0x4d, 0xe2, 0xb7, 0x3c, 0x2f, - 0xcc, 0xd9, 0xbb, 0x99, 0xd7, 0x6d, 0xaa, 0xcc, 0x23, 0x67, 0x61, 0x25, - 0x6a, 0xd0, 0xbf, 0x08, 0x9b, 0x6c, 0x55, 0xd8, 0xfc, 0x31, 0x11, 0xc3, - 0xba, 0x28, 0xf8, 0x8b, 0xd7, 0xff, 0x18, 0x72, 0xaa, 0xdc, 0x73, 0xd1, - 0x4d, 0x37, 0xa3, 0x98, 0x0b, 0x53, 0xcd, 0x05, 0xae, 0x75, 0xe9, 0xfa, - 0x90, 0x01, 0xbe, 0x7e, 0xe1, 0x03, 0xf0, 0xe8, 0x72, 0x4f, 0x20, 0x59, - 0xf8, 0xe6, 0x08, 0xf0, 0x5f, 0x7e, 0x99, 0x1c, 0xd7, 0x03, 0x7c, 0x3d, - 0x2c, 0x7e, 0xfb, 0x09, 0xb2, 0xf2, 0x8f, 0x88, 0x71, 0x64, 0x9e, 0xbc, - 0x59, 0x1a, 0xa6, 0x5b, 0xa5, 0xdd, 0xb4, 0x5a, 0x1a, 0xa1, 0x37, 0x45, - 0x2d, 0x0d, 0x99, 0x1b, 0xb9, 0x2a, 0xe6, 0xc8, 0xa0, 0x43, 0x61, 0x6e, - 0xb3, 0xb4, 0x9b, 0x56, 0x96, 0x34, 0x7f, 0x83, 0xb7, 0xc1, 0x2f, 0xf1, - 0x3e, 0x99, 0x2f, 0xd7, 0xca, 0x33, 0xc9, 0x26, 0x9e, 0x91, 0xf7, 0x80, - 0x57, 0xf2, 0xad, 0xb9, 0xbe, 0xdd, 0xa1, 0x18, 0x62, 0xf5, 0x82, 0xd4, - 0x81, 0xb8, 0x45, 0xc3, 0x9a, 0x3c, 0xe4, 0x07, 0x86, 0xfe, 0x2a, 0xaf, - 0xb9, 0x3c, 0x67, 0x36, 0xe2, 0x9c, 0x46, 0x18, 0x0f, 0x6f, 0x17, 0xf8, - 0x37, 0x61, 0x07, 0x22, 0x49, 0xaa, 0x5d, 0x30, 0x6c, 0xd4, 0x73, 0x4c, - 0xf3, 0xf3, 0x0c, 0xe5, 0x6f, 0xda, 0xe6, 0xe0, 0x3f, 0x37, 0xd6, 0xc5, - 0x5e, 0xf2, 0x63, 0xdc, 0x67, 0xac, 0xc3, 0x8d, 0xfd, 0x1a, 0xaa, 0xef, - 0xd7, 0x74, 0xf3, 0xb8, 0xa5, 0xec, 0xcd, 0xda, 0xdc, 0xae, 0xca, 0xed, - 0xaa, 0xd8, 0xfb, 0xe3, 0xeb, 0x4b, 0xd8, 0x77, 0x1e, 0xa6, 0xd5, 0x79, - 0xc8, 0x28, 0xfc, 0x21, 0x8d, 0xbd, 0xde, 0xd5, 0x65, 0x5c, 0x87, 0x4f, - 0xa4, 0xb1, 0xd7, 0xbb, 0xaa, 0xf6, 0x7a, 0x57, 0x97, 0x63, 0x42, 0x6f, - 0xe7, 0x4b, 0x4c, 0xf7, 0x92, 0x5f, 0xc5, 0x39, 0xee, 0x53, 0xbf, 0x2d, - 0xf4, 0x98, 0xf0, 0x69, 0xf7, 0xd9, 0x6b, 0xd3, 0xf0, 0x50, 0x0b, 0x0d, - 0x63, 0x02, 0x67, 0xa5, 0xf8, 0x99, 0xc9, 0xd2, 0x63, 0xff, 0x3b, 0x60, - 0x78, 0x46, 0x00, 0xf3, 0x9e, 0x30, 0x34, 0xef, 0xc1, 0xe6, 0x8e, 0xf9, - 0x19, 0x20, 0xf7, 0x14, 0xd9, 0x80, 0xfb, 0x16, 0x90, 0xf2, 0x4a, 0x06, - 0xad, 0xbc, 0x02, 0xa6, 0x09, 0x75, 0x88, 0xfe, 0xa6, 0xf5, 0x9f, 0xe5, - 0x60, 0xe3, 0x80, 0x4d, 0x40, 0x73, 0x9b, 0xa7, 0x90, 0x32, 0xf7, 0x0c, - 0xac, 0x6f, 0xb1, 0xae, 0x6d, 0xb4, 0x01, 0xef, 0xb1, 0x5e, 0x34, 0x85, - 0x85, 0x61, 0x49, 0x0f, 0x03, 0xb0, 0x7e, 0x00, 0xa5, 0x75, 0x50, 0x1d, - 0x01, 0x4f, 0xef, 0x02, 0x4d, 0x40, 0xf7, 0x39, 0x01, 0xdb, 0xa2, 0xce, - 0xfd, 0xca, 0xe0, 0xb5, 0xb2, 0x0d, 0xd0, 0x73, 0xab, 0x16, 0xf5, 0x88, - 0xc9, 0x83, 0xf2, 0x99, 0x93, 0x0a, 0x03, 0x19, 0x79, 0x81, 0x0d, 0x9a, - 0x17, 0xc0, 0xe1, 0x04, 0x4c, 0xeb, 0xc0, 0x32, 0x6a, 0x8d, 0x2e, 0xd0, - 0x3c, 0x1e, 0x16, 0x97, 0x7e, 0x90, 0x18, 0x03, 0x54, 0x8c, 0x05, 0xc8, - 0x97, 0x01, 0xb6, 0x29, 0x41, 0x7e, 0x05, 0xe5, 0x05, 0x90, 0xd9, 0x20, - 0xbf, 0x83, 0xca, 0x4e, 0x50, 0x5e, 0x04, 0xb2, 0x97, 0x08, 0x41, 0xfd, - 0x0c, 0xa4, 0x81, 0xec, 0xe6, 0x29, 0x22, 0x60, 0x7e, 0x52, 0x80, 0x10, - 0x43, 0x03, 0x3c, 0x1f, 0x10, 0x1b, 0xc6, 0x30, 0xf5, 0x31, 0x64, 0xe4, - 0x1b, 0x88, 0x19, 0x88, 0x7c, 0xc3, 0xce, 0x70, 0x40, 0x00, 0x16, 0x56, - 0xff, 0xff, 0x1f, 0x53, 0x61, 0x01, 0xa6, 0x53, 0xd0, 0x3a, 0xd6, 0xdf, - 0xff, 0x0f, 0x88, 0xb0, 0x30, 0xb4, 0xc0, 0xd7, 0x23, 0xe6, 0xc8, 0x83, - 0xca, 0xd0, 0x05, 0x40, 0x56, 0x1b, 0xbc, 0x4d, 0xc0, 0x02, 0xbe, 0xef, - 0x79, 0x01, 0xc3, 0x2f, 0x60, 0x99, 0xf5, 0xff, 0xff, 0x52, 0xb8, 0x5a, - 0x10, 0x00, 0x00, 0x19, 0x3f, 0x16, 0x21, 0xc4, 0x7d, 0x00, 0x00, 0x00 }; - -static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 }; -static const u32 bnx2_COM_b09FwRodata[(0x88/4) + 1] = { - 0x08001b68, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4, - 0x08001ab4, 0x08001ba4, 0x08001b28, 0x08001ba4, 0x08001a3c, 0x08001ba4, - 0x08001ba4, 0x08001ba4, 0x08001a48, 0x00000000, 0x08002abc, 0x08002b0c, - 0x08002b3c, 0x08002b6c, 0x08002b9c, 0x00000000, 0x0800604c, 0x0800604c, - 0x0800604c, 0x0800604c, 0x0800604c, 0x08006078, 0x08006078, 0x080060b8, - 0x080060c4, 0x080060c4, 0x0800604c, 0x00000000, 0x00000000 }; -static const u32 bnx2_COM_b09FwBss[(0x88/4) + 1] = { 0x0 }; -static const u32 bnx2_COM_b09FwSbss[(0x60/4) + 1] = { 0x0 }; + 0x1f, 0x8b, 0x08, 0x08, 0xac, 0xfb, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xdc, 0x5b, 0x6b, 0x70, + 0x1b, 0xd7, 0x75, 0x3e, 0xfb, 0x00, 0x09, 0x91, 0x10, 0xb5, 0xa4, 0x60, + 0x1a, 0x96, 0x68, 0x07, 0x20, 0x57, 0x22, 0x6a, 0xb1, 0x29, 0x4c, 0x33, + 0x16, 0x9b, 0xc2, 0x12, 0x02, 0x50, 0xae, 0x26, 0xc3, 0x3a, 0x94, 0xcd, + 0xd8, 0x4a, 0xaa, 0xc9, 0x30, 0x00, 0xa5, 0xf4, 0x61, 0xb7, 0x92, 0xab, + 0xa9, 0x5d, 0xd7, 0xaa, 0x21, 0x92, 0x6a, 0xf5, 0x83, 0xe5, 0x2a, 0x16, + 0x43, 0xa9, 0xd3, 0x74, 0xc2, 0x12, 0x56, 0xac, 0x4e, 0x31, 0x85, 0xfc, + 0xd6, 0x38, 0xb1, 0xc9, 0x4a, 0x76, 0xeb, 0xf4, 0xe1, 0xa6, 0x33, 0xcd, + 0xa3, 0x9d, 0x36, 0xf6, 0xa8, 0x3f, 0xea, 0xe9, 0xd3, 0x33, 0x6e, 0xa7, + 0xea, 0xd8, 0x0e, 0xfa, 0x7d, 0x77, 0x77, 0x81, 0x25, 0x48, 0xbd, 0xfc, + 0xc8, 0x8f, 0x70, 0x06, 0xb3, 0x7b, 0xef, 0xde, 0xbd, 0xf7, 0xdc, 0xf3, + 0xf8, 0xce, 0x63, 0x2f, 0xfb, 0x44, 0x5a, 0xc4, 0xfb, 0x5b, 0x8b, 0x5f, + 0xfc, 0xfe, 0x5f, 0x2d, 0x7c, 0x7c, 0xf0, 0xe3, 0xfd, 0x22, 0xb7, 0xdc, + 0xa2, 0xb7, 0x86, 0x75, 0xf6, 0x1b, 0xf8, 0x45, 0xf1, 0xeb, 0xf7, 0xee, + 0x57, 0xfb, 0xb3, 0xf0, 0x7b, 0x13, 0x0f, 0xc7, 0xfe, 0x55, 0x44, 0xbb, + 0xc4, 0x98, 0xe0, 0x5f, 0xb5, 0x7a, 0xf9, 0xe7, 0x5c, 0x38, 0x7e, 0x89, + 0x67, 0x86, 0xbb, 0x9c, 0xa2, 0x97, 0x3f, 0x09, 0xeb, 0x69, 0x39, 0x94, + 0xb5, 0x25, 0x6c, 0xa4, 0xdf, 0x3c, 0x54, 0xb0, 0x45, 0x32, 0xe5, 0x2d, + 0xf1, 0x9c, 0xbc, 0x57, 0x2d, 0x46, 0x4d, 0x61, 0xff, 0x8d, 0xe9, 0x77, + 0xbf, 0xf6, 0xe2, 0xd6, 0xc4, 0x5b, 0xf3, 0x86, 0x84, 0xad, 0xf4, 0x19, + 0xb1, 0x36, 0x4b, 0xb8, 0x0b, 0xef, 0x7c, 0xb5, 0xf7, 0x3d, 0x91, 0x36, + 0x7f, 0xae, 0x37, 0xab, 0x2f, 0xf6, 0x4a, 0x71, 0x43, 0x3a, 0x2c, 0x7a, + 0x7a, 0xd3, 0xf7, 0xb3, 0x86, 0x35, 0x66, 0xa4, 0x2d, 0x59, 0xac, 0xc8, + 0xc8, 0xde, 0x69, 0x09, 0x87, 0xd3, 0x47, 0x9b, 0x9b, 0x37, 0x49, 0xd8, + 0x4c, 0x8f, 0x1d, 0xfa, 0x6d, 0xfb, 0xd1, 0xaa, 0x6e, 0xdb, 0xc9, 0x05, + 0x89, 0x0c, 0x9e, 0x1a, 0xc0, 0xf3, 0x72, 0x22, 0x29, 0xb2, 0x55, 0x74, + 0xbb, 0x18, 0x31, 0xec, 0xb0, 0x64, 0x2b, 0xb6, 0xe4, 0x2a, 0x22, 0x7f, + 0x5e, 0xd6, 0xe4, 0x94, 0xdd, 0x29, 0x0b, 0x7d, 0xef, 0x56, 0x33, 0xa0, + 0xe5, 0xcf, 0xec, 0xb1, 0x43, 0x53, 0x36, 0xe9, 0x9d, 0x6d, 0x76, 0xe9, + 0x9d, 0x6a, 0x2a, 0xd8, 0xa6, 0x4c, 0x94, 0xd9, 0x37, 0xa2, 0xb3, 0x2f, + 0x94, 0x7e, 0x68, 0xcd, 0x29, 0x3b, 0xe2, 0xf5, 0xed, 0xdc, 0x9e, 0xc5, + 0x7c, 0x93, 0x65, 0x8e, 0x3d, 0x93, 0x2a, 0xd8, 0x51, 0xaf, 0x3f, 0x79, + 0x5b, 0xd6, 0x8e, 0xa1, 0xbf, 0xcb, 0x7b, 0x76, 0xf2, 0xbe, 0x82, 0x6d, + 0x7b, 0xcf, 0xbe, 0x8a, 0xb9, 0x93, 0x5e, 0xff, 0x7d, 0xdb, 0x0a, 0x76, + 0x9f, 0xd7, 0x3f, 0xbd, 0x2d, 0x6b, 0xa7, 0xbc, 0xfe, 0xe4, 0xee, 0x82, + 0x3d, 0xe0, 0xf5, 0x9f, 0xbd, 0x3d, 0x6b, 0x0f, 0x7a, 0xfd, 0x0f, 0x6d, + 0x2d, 0xd8, 0x69, 0xf4, 0x1f, 0x6d, 0xd6, 0x37, 0x59, 0x72, 0xa4, 0x1c, + 0xc7, 0x2f, 0x83, 0x67, 0x43, 0xe8, 0xdb, 0x89, 0xdf, 0x30, 0x7e, 0xbf, + 0xb8, 0x4e, 0xda, 0x46, 0x70, 0xfd, 0xc6, 0x46, 0x97, 0x77, 0xe0, 0x91, + 0x13, 0x96, 0x37, 0x8c, 0x98, 0xbc, 0xd8, 0xfb, 0x06, 0x78, 0x68, 0xc9, + 0x99, 0x8a, 0x68, 0x23, 0xbd, 0x31, 0xf0, 0x2e, 0x2a, 0x4f, 0x56, 0x5a, + 0xc5, 0x78, 0xcc, 0x00, 0x6f, 0x3e, 0x2f, 0xf9, 0x68, 0x58, 0xda, 0xe7, + 0x34, 0xe9, 0xee, 0x0f, 0x4b, 0xc6, 0x52, 0x72, 0x13, 0x7d, 0x26, 0x2a, + 0xc6, 0x5c, 0x66, 0xbd, 0x2e, 0x9b, 0xac, 0x9c, 0x14, 0xc1, 0xbb, 0xef, + 0x51, 0x27, 0xf1, 0x2c, 0x2e, 0xb9, 0xe9, 0x9b, 0x65, 0xcc, 0x22, 0x5d, + 0x3b, 0x6f, 0x74, 0xd7, 0x0a, 0x6b, 0xd9, 0x13, 0x23, 0x72, 0xc4, 0x89, + 0x68, 0xb9, 0x13, 0xdb, 0x24, 0x9b, 0x92, 0x28, 0xde, 0x8b, 0xe5, 0xf1, + 0xa4, 0x54, 0x1e, 0x91, 0x29, 0x47, 0xb4, 0xac, 0x43, 0x7e, 0x76, 0xe2, + 0x79, 0x9b, 0x1a, 0x8b, 0xbe, 0x2e, 0x43, 0xcd, 0x1d, 0x46, 0xbf, 0x85, + 0xfe, 0x0e, 0x6d, 0x48, 0xcd, 0xa1, 0xfa, 0xe3, 0x93, 0x12, 0x91, 0xc7, + 0xcb, 0x51, 0x6f, 0x6c, 0xb5, 0x9a, 0x4d, 0x59, 0x18, 0x37, 0x22, 0x93, + 0x4e, 0x54, 0xc6, 0x70, 0x9d, 0x70, 0xb8, 0x7e, 0x0c, 0x3a, 0xf5, 0xda, + 0xa1, 0xfc, 0xac, 0x9a, 0x2f, 0x6e, 0xa4, 0x39, 0x5f, 0x17, 0xc6, 0x4d, + 0x80, 0x2e, 0x4d, 0x4c, 0x25, 0xcb, 0x8c, 0xe4, 0xa7, 0x35, 0xe8, 0x1b, + 0xae, 0x8a, 0xaf, 0x43, 0xa0, 0xdf, 0x14, 0xbb, 0x5f, 0x93, 0x02, 0x64, + 0x55, 0xb4, 0xd0, 0x2e, 0x9f, 0xd5, 0xb3, 0x4e, 0xb3, 0xe4, 0xcc, 0xb8, + 0x18, 0x33, 0x4a, 0x97, 0x64, 0x12, 0xef, 0xe8, 0x36, 0xc7, 0x5c, 0xc4, + 0xbe, 0xc7, 0x94, 0x1c, 0x9a, 0xd2, 0x45, 0x3d, 0x57, 0xe9, 0x14, 0x7d, + 0x6e, 0x8f, 0xbc, 0x3c, 0x2d, 0x96, 0x91, 0x7e, 0xb7, 0x9a, 0xb5, 0xa7, + 0xf4, 0xec, 0x13, 0xa6, 0x84, 0x66, 0x34, 0x99, 0xb2, 0x13, 0xb0, 0x80, + 0xa3, 0xfa, 0x8e, 0xca, 0x59, 0x8c, 0xe3, 0x7b, 0x18, 0x57, 0xd6, 0xc1, + 0x57, 0xde, 0x6f, 0xb1, 0x74, 0xa5, 0xcf, 0x1c, 0x03, 0x19, 0x60, 0x1f, + 0x4f, 0x3a, 0x90, 0x89, 0x92, 0x51, 0x1c, 0x32, 0x7a, 0x15, 0x32, 0x1a, + 0x80, 0x6c, 0x52, 0xf2, 0x52, 0xa5, 0x4f, 0x9e, 0xaf, 0x24, 0xe5, 0x39, + 0xe8, 0xeb, 0xb3, 0x95, 0xb8, 0x3c, 0x53, 0xe9, 0x92, 0xa7, 0x2b, 0x31, + 0x79, 0x4a, 0xc9, 0x2d, 0x07, 0xdb, 0x50, 0xb2, 0x0c, 0x5f, 0x9f, 0x96, + 0x70, 0x27, 0xe4, 0xd1, 0x01, 0xfd, 0x69, 0x87, 0x6e, 0x7e, 0xa5, 0x37, + 0x2c, 0xb3, 0xbd, 0x92, 0x59, 0x8f, 0xfe, 0x9b, 0xd2, 0xa6, 0xe2, 0x91, + 0x89, 0xe7, 0x93, 0xd3, 0x21, 0xc9, 0x59, 0x8f, 0xcb, 0x85, 0x19, 0x53, + 0x26, 0x2b, 0xdb, 0x6f, 0x72, 0x65, 0xc6, 0xf6, 0xbc, 0x9c, 0x9f, 0x69, + 0xc2, 0xb3, 0x79, 0x79, 0x79, 0xb3, 0x2e, 0x13, 0xb3, 0x6f, 0x89, 0x09, + 0x1e, 0x0e, 0x29, 0x79, 0x3f, 0x2e, 0xff, 0xfc, 0x27, 0x22, 0x23, 0xe0, + 0x8b, 0xde, 0xff, 0xef, 0xd5, 0x8c, 0x05, 0x7e, 0xf4, 0xf7, 0x41, 0x3f, + 0x74, 0x5c, 0x29, 0xcf, 0x38, 0xc6, 0x98, 0x5a, 0xce, 0x39, 0x0d, 0x9b, + 0x6a, 0xd5, 0xb2, 0xc7, 0x45, 0x0a, 0xc7, 0xab, 0x52, 0x48, 0x85, 0xe4, + 0x01, 0xab, 0x2a, 0x43, 0xa9, 0x26, 0x39, 0x60, 0x75, 0xca, 0x44, 0xdf, + 0xcf, 0x68, 0x3e, 0x96, 0x7d, 0xa5, 0x92, 0xc6, 0x3d, 0xfb, 0x44, 0x66, + 0xd5, 0xbd, 0xdb, 0x5f, 0xac, 0x84, 0x24, 0x13, 0x2d, 0xc6, 0x4c, 0xb9, + 0xa0, 0xb9, 0xb4, 0xed, 0xf4, 0x9f, 0x41, 0x5e, 0x63, 0xc0, 0x90, 0x84, + 0xd2, 0xa5, 0xfc, 0xf4, 0x9a, 0x8b, 0x19, 0xd5, 0x1d, 0x52, 0x7a, 0x6a, + 0xa4, 0x4d, 0xd2, 0x31, 0xa6, 0xa5, 0xa3, 0xd2, 0xad, 0xec, 0x64, 0x00, + 0x63, 0x06, 0xb5, 0xbb, 0x2b, 0x94, 0x37, 0xee, 0xcb, 0xa4, 0x75, 0x03, + 0xc6, 0x9a, 0xb8, 0x66, 0x3c, 0x9a, 0x83, 0x74, 0x72, 0x2e, 0xd2, 0xc9, + 0xeb, 0xde, 0x00, 0x9d, 0xfb, 0x6a, 0xf7, 0xb3, 0x81, 0xfb, 0x62, 0xe5, + 0xd7, 0x5b, 0x5c, 0xfa, 0xc8, 0xd7, 0x41, 0x99, 0x98, 0x7e, 0xc8, 0x5b, + 0x0b, 0xf7, 0x65, 0xae, 0xb1, 0x00, 0x3e, 0xa9, 0x91, 0x57, 0x58, 0xab, + 0x18, 0x58, 0xeb, 0x70, 0x60, 0xad, 0xc3, 0x81, 0xb5, 0x8a, 0xe0, 0xad, + 0xac, 0xd3, 0x81, 0x33, 0x79, 0xc2, 0xbc, 0x1c, 0xc5, 0x9c, 0x6f, 0x88, + 0x91, 0xa6, 0x2d, 0xf8, 0x36, 0xf9, 0x07, 0x18, 0x9f, 0x96, 0x73, 0x0e, + 0x78, 0x73, 0x3c, 0x24, 0x77, 0xa9, 0x71, 0xff, 0xb1, 0xc6, 0xa5, 0x31, + 0xf8, 0x2c, 0x2c, 0xbb, 0xa2, 0xbc, 0xf7, 0x9f, 0x99, 0xe0, 0x37, 0xdb, + 0x93, 0x37, 0xb8, 0x6d, 0xde, 0x9f, 0xf5, 0xf6, 0xd2, 0xee, 0xbe, 0x57, + 0x79, 0x53, 0x61, 0xc6, 0x62, 0x85, 0xb6, 0x2d, 0x29, 0xc3, 0x96, 0xfd, + 0x43, 0xa9, 0x4e, 0x99, 0xb4, 0xb4, 0xd4, 0x44, 0xb2, 0x99, 0xfc, 0xcf, + 0xe8, 0x76, 0x2b, 0xec, 0x47, 0xe2, 0x3a, 0x71, 0x51, 0xed, 0xeb, 0x5b, + 0x1e, 0xfd, 0x16, 0xdb, 0x23, 0xba, 0xdd, 0xd1, 0xd0, 0x4f, 0xfd, 0xff, + 0x4b, 0xdc, 0xd3, 0x06, 0xfa, 0x75, 0x77, 0xed, 0xbf, 0x42, 0x9b, 0x58, + 0x15, 0xf1, 0xda, 0xfe, 0xf3, 0xff, 0x32, 0x96, 0xb7, 0x8f, 0x6d, 0x5c, + 0xde, 0xf6, 0x6d, 0x29, 0x88, 0x73, 0xdc, 0x2b, 0x6c, 0xd8, 0xa6, 0xfe, + 0x85, 0x40, 0x6b, 0x0a, 0x36, 0xdc, 0xec, 0xd1, 0xf0, 0xba, 0x47, 0x03, + 0x68, 0xc5, 0xb8, 0x89, 0x0a, 0xdf, 0x51, 0xa2, 0x6c, 0x68, 0x93, 0xf7, + 0xfe, 0xfd, 0x5a, 0xf5, 0xfc, 0x0d, 0x83, 0xeb, 0xf8, 0x57, 0xd1, 0x86, + 0x60, 0x67, 0x93, 0xb3, 0xa6, 0xe4, 0x53, 0x31, 0x65, 0x0f, 0xf9, 0x54, + 0x1d, 0x3f, 0x26, 0xa7, 0x1b, 0xf1, 0x83, 0xef, 0x11, 0x3f, 0x5c, 0xec, + 0x98, 0x98, 0x25, 0x8e, 0xd4, 0x71, 0xe3, 0xc8, 0xb4, 0x8f, 0x25, 0x9c, + 0x9b, 0x18, 0xe2, 0xe3, 0x07, 0xdf, 0x23, 0x7e, 0x18, 0x90, 0x15, 0xe7, + 0xf4, 0xd7, 0x9f, 0x6a, 0x98, 0x7b, 0x4a, 0x61, 0x93, 0x8b, 0xcb, 0x6f, + 0x06, 0x70, 0xbe, 0x0b, 0x18, 0x1d, 0x85, 0xfc, 0x7c, 0x8c, 0x26, 0x76, + 0xc6, 0x80, 0xeb, 0xe0, 0x91, 0xc2, 0xe4, 0x08, 0x70, 0xcc, 0xf4, 0x30, + 0x35, 0xec, 0x61, 0x6a, 0x04, 0x78, 0xca, 0xb6, 0xe5, 0xb5, 0xa3, 0x5e, + 0x3b, 0x86, 0x36, 0xfc, 0xef, 0x1c, 0x6d, 0xec, 0xb5, 0x43, 0xe3, 0xb3, + 0x0a, 0xa7, 0x89, 0xf1, 0xc0, 0x0a, 0xe2, 0x2c, 0xf1, 0xb6, 0x4b, 0x16, + 0xca, 0x58, 0xaf, 0x86, 0x69, 0x94, 0x47, 0x90, 0x1e, 0xd2, 0xb2, 0x46, + 0xf4, 0xc7, 0xdc, 0xfd, 0xe8, 0xe9, 0xcf, 0xeb, 0xd2, 0xc2, 0x7d, 0x90, + 0xee, 0x1b, 0x41, 0x2b, 0xf7, 0xf6, 0xa3, 0xa4, 0x95, 0xeb, 0x35, 0xd2, + 0x7b, 0x1a, 0xf4, 0x66, 0x80, 0xb7, 0xa2, 0x8d, 0xf6, 0x8e, 0x82, 0xde, + 0x11, 0x60, 0xf1, 0x30, 0xb0, 0x78, 0x27, 0xb0, 0x78, 0x08, 0x58, 0x9c, + 0x06, 0x0e, 0x0f, 0x02, 0x87, 0x07, 0x80, 0xc3, 0x29, 0xec, 0x2b, 0x2a, + 0xf3, 0xc0, 0xe5, 0x79, 0xe0, 0xf3, 0x3c, 0xe4, 0x35, 0x31, 0x27, 0xda, + 0x17, 0xb0, 0xfe, 0x63, 0x33, 0x89, 0xd3, 0xd0, 0xcd, 0x58, 0x51, 0x87, + 0x3d, 0xa5, 0x06, 0xa1, 0x23, 0x49, 0x29, 0x55, 0x46, 0xa5, 0x40, 0x3f, + 0xb6, 0xb9, 0x07, 0xb6, 0x0b, 0xfb, 0x89, 0xf9, 0x71, 0xd3, 0x5a, 0xef, + 0xfa, 0xf7, 0x22, 0xf6, 0x1f, 0x83, 0x27, 0x89, 0xb8, 0xc8, 0xb0, 0xe4, + 0x9d, 0x1e, 0x2b, 0xab, 0x27, 0x31, 0x8e, 0xed, 0xb8, 0xb6, 0xf7, 0x78, + 0x42, 0x1b, 0x3f, 0xce, 0x3d, 0x4d, 0x03, 0xe3, 0xaa, 0x32, 0x95, 0xa2, + 0xad, 0x56, 0xe5, 0x54, 0x2a, 0x31, 0x58, 0x94, 0x56, 0x39, 0x12, 0x9d, + 0x56, 0xfe, 0xcd, 0x4c, 0x1f, 0x53, 0xfa, 0x51, 0xb0, 0x71, 0x2d, 0x77, + 0x6b, 0xf9, 0xe3, 0xf4, 0x3b, 0x3d, 0xf8, 0x85, 0x40, 0x0b, 0xe7, 0x37, + 0x65, 0x68, 0x40, 0xb4, 0x7d, 0xbd, 0x45, 0xa0, 0x62, 0xc2, 0x3a, 0x87, + 0x95, 0x73, 0xd3, 0x3d, 0xb1, 0x9c, 0x6e, 0xca, 0x98, 0xa9, 0xc9, 0x04, + 0xec, 0x65, 0x28, 0xf5, 0x7f, 0xd5, 0x23, 0x51, 0x3e, 0x6f, 0x96, 0xdf, + 0x51, 0x38, 0x8b, 0xb5, 0x4b, 0xb3, 0x58, 0x37, 0x04, 0xfe, 0x71, 0x5d, + 0xce, 0x83, 0x36, 0x30, 0xcf, 0xb4, 0x13, 0xa7, 0x8b, 0xb2, 0x1d, 0x76, + 0xb7, 0x4e, 0xb2, 0x7d, 0x4d, 0x92, 0x19, 0x89, 0xcb, 0xc4, 0xcc, 0x76, + 0xe0, 0x1e, 0x64, 0x60, 0xb7, 0x48, 0x7e, 0x34, 0x2e, 0x5f, 0x9e, 0x61, + 0x5f, 0x06, 0xfb, 0x4f, 0x1c, 0xcd, 0x08, 0xf7, 0x1f, 0x52, 0xfb, 0x8a, + 0xeb, 0x19, 0x39, 0xe0, 0xbc, 0xa4, 0xbb, 0x76, 0xe9, 0xb6, 0xf7, 0x42, + 0x1e, 0xa7, 0xc0, 0xef, 0xbc, 0x63, 0xcb, 0x02, 0xfc, 0x4a, 0xee, 0x38, + 0x70, 0xd5, 0x6e, 0x03, 0x06, 0x26, 0xce, 0xd2, 0x3e, 0x0c, 0xc4, 0x5a, + 0x25, 0xc5, 0xeb, 0x2e, 0x39, 0x3e, 0xa3, 0xcb, 0xb3, 0xb7, 0xc5, 0xd1, + 0x06, 0xd6, 0xa6, 0x12, 0x67, 0xc6, 0xf4, 0x2e, 0xb9, 0xb5, 0x23, 0x86, + 0xf7, 0x52, 0x5a, 0xde, 0xf9, 0x37, 0xf2, 0xf2, 0x64, 0x5c, 0xe7, 0x58, + 0x5d, 0x72, 0x29, 0x03, 0x3a, 0x56, 0xc4, 0xf8, 0x7f, 0x40, 0x7f, 0x97, + 0xcc, 0x21, 0xbe, 0x99, 0x03, 0x4d, 0xd9, 0x14, 0xb1, 0x30, 0x71, 0x72, + 0x49, 0x07, 0x66, 0xcd, 0x41, 0x37, 0x47, 0x11, 0x3f, 0xcc, 0xfc, 0x37, + 0xc6, 0xc4, 0x21, 0xd3, 0x1e, 0x6b, 0x02, 0xf8, 0x92, 0xe9, 0xe2, 0x3d, + 0xe7, 0xb4, 0xe5, 0x94, 0x43, 0x1d, 0x8a, 0xcb, 0xe3, 0x15, 0xbe, 0xd7, + 0x73, 0xf6, 0x69, 0xb1, 0xe5, 0x41, 0xe7, 0x7f, 0x30, 0xfe, 0x1d, 0xc4, + 0x9e, 0x96, 0x94, 0x20, 0xb7, 0x02, 0x78, 0x99, 0x89, 0xb9, 0xed, 0x89, + 0xb9, 0xc4, 0xd9, 0x0b, 0x3a, 0xef, 0xed, 0xe2, 0x82, 0x7e, 0xb3, 0x48, + 0x07, 0xf9, 0x99, 0x02, 0x2f, 0x6d, 0x4b, 0xd7, 0x37, 0x7b, 0xf1, 0x16, + 0x6d, 0xc0, 0x06, 0x7d, 0xa6, 0x2c, 0xf4, 0x07, 0x6d, 0x80, 0x7e, 0xd6, + 0xb7, 0x81, 0x44, 0x6c, 0x49, 0xd7, 0xf1, 0xdc, 0x94, 0x63, 0xaa, 0xad, + 0x81, 0xd6, 0x44, 0x8c, 0xfb, 0x9b, 0x2c, 0x27, 0xe5, 0x71, 0x87, 0xe3, + 0xc1, 0xe7, 0xe9, 0x88, 0x37, 0x1e, 0xf1, 0x8e, 0xc3, 0x98, 0x29, 0x09, + 0x9a, 0x5d, 0xbb, 0x58, 0x98, 0x8e, 0xaa, 0x67, 0x47, 0x1c, 0x37, 0x36, + 0xd2, 0x11, 0x3f, 0xcd, 0x23, 0x7e, 0xca, 0x29, 0x1b, 0xb1, 0x32, 0x88, + 0xaf, 0xe1, 0x67, 0x5d, 0xfb, 0x28, 0x95, 0x49, 0xcb, 0x3d, 0xa0, 0x2f, + 0x51, 0x04, 0x31, 0xc7, 0x74, 0xb8, 0xeb, 0xec, 0x80, 0x14, 0x19, 0x63, + 0x9d, 0x33, 0x1e, 0x91, 0xb1, 0x12, 0xfd, 0x1b, 0x7e, 0x8e, 0x6d, 0x31, + 0xa6, 0xcf, 0x28, 0xdf, 0xd3, 0x03, 0x3d, 0x80, 0x5f, 0x4a, 0xb5, 0x8b, + 0xeb, 0x07, 0xf7, 0x40, 0x9e, 0xc3, 0x90, 0x7b, 0x5a, 0xc6, 0x4f, 0x8c, + 0x53, 0xa7, 0x93, 0x25, 0x49, 0x24, 0x8f, 0xc8, 0x16, 0x6b, 0x01, 0xbe, + 0x30, 0x33, 0x5a, 0xdd, 0xae, 0xa7, 0xf9, 0xce, 0xa3, 0x78, 0x07, 0xd7, + 0xd2, 0xb8, 0x3c, 0x50, 0x61, 0xdf, 0x9d, 0x86, 0xb4, 0xc0, 0x56, 0x06, + 0xf6, 0x78, 0x76, 0x80, 0xf9, 0x4c, 0x7f, 0xbe, 0x71, 0x6f, 0x3e, 0x8e, + 0xe3, 0x18, 0xbe, 0x53, 0x9f, 0x77, 0x07, 0x7d, 0x1b, 0xb0, 0x64, 0x87, + 0x5e, 0xdd, 0x1e, 0xc2, 0xf3, 0x53, 0x03, 0xbc, 0xc7, 0x3c, 0xf0, 0x6d, + 0x96, 0x3d, 0x8c, 0xb1, 0xa3, 0x98, 0x73, 0x8d, 0x64, 0x3b, 0x7d, 0x7a, + 0xa9, 0x03, 0x8c, 0x3f, 0xd8, 0x8e, 0xae, 0x77, 0x79, 0xff, 0x25, 0xc3, + 0xd5, 0xc9, 0x11, 0xb4, 0x69, 0x7f, 0x07, 0x25, 0xe7, 0x24, 0xb0, 0x4f, + 0xf0, 0xb6, 0x32, 0xe1, 0xed, 0x11, 0xfc, 0x1f, 0x39, 0x0c, 0x3e, 0x48, + 0xd1, 0xe5, 0x0d, 0xf9, 0x42, 0x9e, 0xfc, 0x16, 0x74, 0xff, 0x61, 0x8c, + 0x81, 0x7f, 0x50, 0x3c, 0x58, 0xea, 0x70, 0x63, 0xd1, 0x44, 0x31, 0xc3, + 0xfc, 0xa9, 0x83, 0x98, 0x07, 0xfc, 0xa9, 0x40, 0xb1, 0x30, 0xf7, 0x92, + 0xbe, 0x86, 0xf4, 0xc6, 0x97, 0x0c, 0x83, 0xed, 0xe4, 0x12, 0x74, 0xb8, + 0x04, 0xf9, 0x64, 0xfb, 0x68, 0xb3, 0x36, 0xe4, 0x31, 0x63, 0x50, 0x5f, + 0x4b, 0x88, 0x05, 0xf3, 0xce, 0x16, 0xeb, 0x5e, 0xf2, 0xcd, 0xb2, 0xe4, + 0x69, 0x27, 0x88, 0x1d, 0x3b, 0x30, 0x94, 0x7a, 0x18, 0x85, 0x1e, 0x98, + 0xf0, 0xc9, 0x31, 0xc8, 0xfc, 0xc5, 0x0e, 0x77, 0x2f, 0xbc, 0x37, 0x65, + 0xde, 0xc2, 0x9a, 0xce, 0xef, 0xaf, 0x73, 0xfb, 0x78, 0xcf, 0xb8, 0xc8, + 0x97, 0xab, 0x4f, 0x3b, 0xe5, 0xdb, 0x28, 0xd3, 0x43, 0xd8, 0x0b, 0xfb, + 0x71, 0x2d, 0x1d, 0x94, 0x71, 0xd0, 0x56, 0x18, 0xd8, 0x14, 0x3b, 0x8f, + 0xf1, 0x39, 0xe0, 0x79, 0xd1, 0xe4, 0xb3, 0x8b, 0x5a, 0xfd, 0x1d, 0xc4, + 0x5c, 0x36, 0xfd, 0xd9, 0x92, 0xf6, 0x85, 0xca, 0xcb, 0x5a, 0xb6, 0x74, + 0x51, 0xcb, 0x41, 0x4f, 0x4a, 0x0e, 0x73, 0x06, 0xda, 0x8f, 0x85, 0xb5, + 0x13, 0xb1, 0xb7, 0xf5, 0x9e, 0xf8, 0x02, 0xb0, 0x60, 0x2f, 0x6c, 0x3a, + 0x67, 0xee, 0x94, 0x02, 0xb0, 0x35, 0x7f, 0x62, 0x0b, 0xec, 0x2d, 0x1e, + 0xa0, 0x8b, 0x78, 0x56, 0xa4, 0x4f, 0xd5, 0x76, 0x38, 0x52, 0x6c, 0x4a, + 0x13, 0xd7, 0x36, 0x41, 0x77, 0xd0, 0x57, 0xae, 0xeb, 0xdf, 0x1d, 0x2b, + 0x68, 0x45, 0x7e, 0x39, 0xb0, 0x9c, 0xde, 0x92, 0x5c, 0x99, 0xde, 0x1d, + 0x35, 0x7a, 0x89, 0x19, 0xc0, 0x7f, 0xd8, 0xcd, 0x4b, 0xd0, 0xdf, 0xe7, + 0x1d, 0xe0, 0xbf, 0x03, 0xfc, 0x87, 0x4d, 0x3d, 0x03, 0xdd, 0x7b, 0xda, + 0x81, 0x0f, 0x70, 0xe0, 0x03, 0x1c, 0xf8, 0x00, 0x27, 0x0b, 0x39, 0x11, + 0xe7, 0xe9, 0x43, 0x76, 0xd7, 0x7c, 0x9e, 0x1b, 0x37, 0xdd, 0xe0, 0xc5, + 0x22, 0xa3, 0x88, 0x45, 0x36, 0xc8, 0x44, 0xf2, 0x7a, 0xec, 0xad, 0x05, + 0xd7, 0x56, 0x5c, 0xb1, 0x46, 0xf2, 0x76, 0xcf, 0x4e, 0x1e, 0x06, 0x5d, + 0x88, 0xbf, 0x93, 0x3f, 0x0d, 0x3d, 0x6c, 0x02, 0x3d, 0x3f, 0xe5, 0xc5, + 0x2c, 0x0f, 0x9a, 0xae, 0x1e, 0xb6, 0xa2, 0xef, 0x93, 0xe8, 0x6b, 0xc5, + 0x98, 0x03, 0x18, 0xc3, 0x98, 0xa7, 0xcd, 0xeb, 0x0b, 0x8e, 0x63, 0xec, + 0xf3, 0x19, 0xac, 0x95, 0xc0, 0xb8, 0x36, 0xcc, 0xdd, 0x85, 0x31, 0xdb, + 0x30, 0xe6, 0x46, 0xb4, 0x19, 0x33, 0x6f, 0x44, 0xfb, 0x13, 0x0d, 0xef, + 0x7c, 0x0c, 0x7d, 0xb7, 0x37, 0xf4, 0x9d, 0x43, 0x1f, 0xf2, 0x50, 0xeb, + 0xbc, 0xf7, 0x5e, 0x11, 0xed, 0xce, 0x86, 0x31, 0xaf, 0xa2, 0x0f, 0x71, + 0xaf, 0xf5, 0x2d, 0x5c, 0x91, 0x7f, 0x5a, 0xa4, 0xc9, 0x7f, 0xc6, 0xb8, + 0x37, 0x8e, 0xfe, 0x90, 0x17, 0xbb, 0xfe, 0xa6, 0x09, 0xbd, 0xd3, 0x86, + 0x9c, 0xdf, 0x30, 0xdd, 0x58, 0xef, 0x4e, 0xcb, 0xd5, 0x43, 0xbf, 0xfd, + 0x70, 0x43, 0x9b, 0x63, 0x17, 0x1a, 0xfa, 0xfe, 0xa5, 0xa1, 0xfd, 0xdd, + 0xd0, 0xca, 0x77, 0x06, 0xdb, 0x97, 0xf7, 0x15, 0x3a, 0x96, 0xb7, 0xed, + 0xa6, 0x95, 0xef, 0xe8, 0xeb, 0x96, 0xf7, 0xdd, 0xb8, 0xbe, 0x61, 0x0c, + 0x74, 0x2a, 0x8a, 0x1c, 0xc9, 0x1f, 0x1f, 0xbe, 0xce, 0x7d, 0x4e, 0xfe, + 0x36, 0xea, 0x92, 0xda, 0x3a, 0xda, 0x3a, 0xe4, 0xb0, 0xa4, 0xc1, 0x9e, + 0x2c, 0x3d, 0xfd, 0xb2, 0x96, 0x83, 0x4e, 0x65, 0x2b, 0xfe, 0x7c, 0xb4, + 0xd9, 0xc6, 0xdc, 0xdc, 0xcf, 0xc9, 0x19, 0x2b, 0x45, 0xa0, 0x37, 0xf7, + 0xd0, 0x27, 0x1d, 0x2d, 0x4a, 0xdd, 0x3e, 0xbb, 0xf5, 0x4b, 0xd9, 0xe7, + 0xed, 0x1e, 0x46, 0x1d, 0x06, 0x9d, 0x55, 0x19, 0x49, 0x35, 0xd3, 0xc7, + 0x78, 0xd8, 0x45, 0xdc, 0xa9, 0x56, 0x8d, 0xcd, 0x55, 0xd9, 0x9f, 0x7a, + 0xa7, 0x2a, 0x0a, 0xf3, 0x06, 0x15, 0xee, 0xc4, 0xf5, 0x1e, 0xc8, 0xc8, + 0x42, 0x6e, 0x82, 0x7c, 0x3a, 0x4a, 0x9f, 0x74, 0x90, 0xf1, 0xc9, 0xa3, + 0x2e, 0xa6, 0x12, 0x77, 0xd0, 0x46, 0x5e, 0x96, 0x3f, 0xce, 0xf5, 0x71, + 0x2d, 0x11, 0xc7, 0x47, 0x95, 0x4f, 0xc9, 0x5b, 0x9c, 0x77, 0x35, 0x6c, + 0x3c, 0x6b, 0x32, 0xa6, 0x33, 0xed, 0xd3, 0xf0, 0x6f, 0x7c, 0xc6, 0x58, + 0xe1, 0x34, 0xe3, 0x92, 0x00, 0x56, 0x6d, 0x35, 0xe0, 0x32, 0x8b, 0xcb, + 0xf7, 0xb5, 0x81, 0x79, 0xc4, 0x55, 0xec, 0x75, 0x75, 0x2c, 0xea, 0xd1, + 0xaf, 0x6c, 0xdb, 0xbb, 0x6a, 0xb6, 0xed, 0xeb, 0xde, 0x6a, 0x39, 0xf8, + 0xf7, 0x95, 0x2c, 0x9e, 0xaa, 0x24, 0x8e, 0x15, 0x61, 0x4b, 0x8b, 0x2a, + 0xef, 0xf6, 0xe5, 0xc2, 0x18, 0x27, 0x71, 0x72, 0x1e, 0x6f, 0x8e, 0xab, + 0x1c, 0x83, 0xf9, 0x45, 0x55, 0x76, 0xa4, 0x5a, 0xa3, 0xe4, 0x43, 0x46, + 0xff, 0x76, 0x88, 0x31, 0xc3, 0xa2, 0x43, 0x9e, 0xa5, 0xf0, 0x3c, 0x05, + 0x4c, 0xf8, 0x27, 0xc9, 0x45, 0xd9, 0xf7, 0x76, 0x75, 0x01, 0x71, 0x95, + 0x8a, 0x8f, 0x94, 0xbf, 0x67, 0x7c, 0xb7, 0x1f, 0xfc, 0x22, 0x4f, 0x47, + 0xc0, 0x67, 0x3f, 0x06, 0x78, 0x8d, 0x75, 0x15, 0x59, 0x1e, 0x07, 0x8b, + 0x3c, 0x50, 0x7e, 0x19, 0x73, 0xea, 0x6e, 0xac, 0xc2, 0x3c, 0xdc, 0x66, + 0x7f, 0x47, 0x88, 0xb1, 0x9c, 0xeb, 0xeb, 0x0d, 0xac, 0x87, 0xdc, 0xbe, + 0xfc, 0x8f, 0x2a, 0x6e, 0x2a, 0x28, 0x79, 0x20, 0x86, 0xaa, 0xf0, 0x19, + 0xfb, 0xc2, 0x5e, 0xec, 0x1c, 0xf1, 0x62, 0x65, 0xcb, 0x8b, 0x95, 0x49, + 0x07, 0x6b, 0x6f, 0x7e, 0x5c, 0x40, 0x99, 0x2d, 0x1d, 0xd2, 0x37, 0x33, + 0x2e, 0x68, 0x93, 0xd5, 0xe3, 0x02, 0x9f, 0xa6, 0x6d, 0xa0, 0x89, 0x71, + 0x9e, 0xaa, 0xbd, 0x74, 0xb8, 0xf5, 0x1e, 0xd2, 0xe0, 0xfb, 0x47, 0xe5, + 0x87, 0x8f, 0xc2, 0xe5, 0x61, 0x6f, 0x69, 0xd0, 0xba, 0x53, 0xb2, 0xd3, + 0xdb, 0x3c, 0x7f, 0xcb, 0x1c, 0x80, 0xf1, 0xb7, 0xab, 0xb3, 0xd9, 0xd4, + 0x84, 0x3f, 0x4f, 0x27, 0x3c, 0x64, 0xa0, 0x2e, 0xc4, 0xb5, 0x18, 0xc7, + 0xf8, 0x31, 0xcd, 0x4e, 0x2f, 0xa6, 0x19, 0x96, 0xfd, 0x8e, 0x1b, 0xf3, + 0x8f, 0xa0, 0x3f, 0xef, 0x28, 0xda, 0x63, 0x8c, 0x2d, 0x75, 0xc4, 0xdc, + 0x99, 0x3d, 0x09, 0x24, 0x0f, 0xee, 0x5e, 0xba, 0xb1, 0x97, 0x52, 0x6d, + 0x2f, 0xad, 0x4b, 0xcb, 0xf7, 0x32, 0xaa, 0xde, 0x9d, 0x5a, 0xf1, 0xae, + 0x60, 0x1f, 0xbb, 0x2f, 0xf1, 0x8c, 0x7b, 0x64, 0xdc, 0x60, 0x79, 0x7b, + 0xf4, 0xe5, 0x74, 0x00, 0x7b, 0x4c, 0x6a, 0x79, 0x15, 0x6b, 0xed, 0x51, + 0x3c, 0xcf, 0x97, 0xc7, 0x70, 0xa5, 0x7d, 0xa8, 0x79, 0x94, 0x8d, 0x4c, + 0x28, 0x3e, 0x8f, 0xab, 0x7d, 0x2c, 0x94, 0x7f, 0x41, 0x0a, 0x27, 0x7e, + 0x09, 0x7e, 0x2f, 0x58, 0x0f, 0x63, 0x2d, 0x91, 0xfc, 0x28, 0x06, 0xf0, + 0x93, 0x7b, 0x65, 0xad, 0xeb, 0x0f, 0x43, 0x6e, 0x7e, 0x10, 0x81, 0x8c, + 0x35, 0xf7, 0xb9, 0x5a, 0xdf, 0xe7, 0x6b, 0x53, 0x80, 0x9e, 0x2a, 0x62, + 0xce, 0x18, 0x68, 0x08, 0xbe, 0x73, 0x50, 0x86, 0x1c, 0xca, 0xa3, 0x27, + 0x36, 0x2e, 0xb6, 0x95, 0x17, 0x3f, 0xce, 0xe0, 0xfa, 0xb4, 0xf9, 0x5c, + 0xcc, 0x10, 0xd6, 0x2f, 0x7d, 0xde, 0xf9, 0x7c, 0x8b, 0x2c, 0x35, 0xea, + 0xc0, 0x14, 0xe8, 0x29, 0x38, 0xe4, 0x93, 0xaf, 0x9b, 0xfe, 0xda, 0xaf, + 0xaa, 0xfd, 0x4c, 0xaa, 0x9a, 0xdd, 0x73, 0x35, 0x1d, 0x9d, 0x40, 0x0c, + 0xe2, 0xea, 0xdc, 0x7d, 0x1e, 0x6f, 0x7c, 0xdd, 0x8c, 0x78, 0x72, 0x66, + 0x1e, 0x47, 0xdb, 0xf1, 0xf5, 0x60, 0x93, 0x75, 0xb7, 0xe2, 0x05, 0x9f, + 0x11, 0x53, 0x5c, 0x59, 0x8e, 0xd5, 0x64, 0xb9, 0xb6, 0x41, 0x2f, 0xbf, + 0xb7, 0xce, 0xb5, 0x43, 0xda, 0x1b, 0xec, 0x16, 0xf4, 0x3d, 0xb5, 0xcc, + 0xbe, 0x93, 0x97, 0xa8, 0x83, 0x46, 0xc4, 0x98, 0xfb, 0x53, 0xf0, 0xf2, + 0x63, 0xc8, 0x55, 0x44, 0xcc, 0x19, 0xe2, 0x10, 0xe3, 0x8d, 0x7a, 0xbc, + 0xbb, 0x20, 0xab, 0xc5, 0xba, 0x57, 0x8a, 0x35, 0x7e, 0xf2, 0x2a, 0x63, + 0x8d, 0x78, 0x93, 0xb4, 0x10, 0x8b, 0x86, 0x11, 0xdb, 0x6a, 0xd2, 0x64, + 0x3f, 0x08, 0x1f, 0x76, 0xc6, 0x6c, 0xb6, 0x7d, 0x4c, 0x88, 0x48, 0xfb, + 0xdc, 0x06, 0x85, 0x0b, 0xd6, 0x4c, 0x1d, 0x17, 0x26, 0xc0, 0xfb, 0x11, + 0xb7, 0xb6, 0x1a, 0x6d, 0x97, 0xab, 0xcd, 0x8d, 0xeb, 0x71, 0xff, 0x58, + 0x2d, 0xee, 0xbf, 0xa1, 0x81, 0x8f, 0xab, 0xe1, 0xe2, 0x19, 0xf0, 0x2d, + 0x8d, 0xfc, 0x97, 0x79, 0xed, 0x10, 0xf2, 0x61, 0xe6, 0x62, 0x19, 0xe4, + 0xc4, 0x89, 0x33, 0xc0, 0x2a, 0xe4, 0xc8, 0x89, 0xb7, 0xe0, 0x57, 0x90, + 0x37, 0x27, 0xe6, 0x99, 0xbb, 0x2e, 0x22, 0x3f, 0x7e, 0x1a, 0xf9, 0xf1, + 0x53, 0x95, 0x3e, 0xf0, 0x37, 0xa9, 0xb0, 0x73, 0xef, 0x71, 0xd1, 0xee, + 0x52, 0xf5, 0x61, 0xda, 0x73, 0x14, 0x7e, 0xb4, 0x5a, 0x3d, 0x90, 0xea, + 0x41, 0x4e, 0x1e, 0x97, 0x4f, 0x99, 0xcc, 0x63, 0x35, 0xb3, 0xbb, 0x7f, + 0xc1, 0x08, 0xc6, 0xa4, 0xd9, 0x2b, 0xfa, 0x81, 0x95, 0xbc, 0xcf, 0x29, + 0x5f, 0x70, 0xcc, 0xb8, 0x1c, 0xef, 0xef, 0xaa, 0xf1, 0xfe, 0xc2, 0x1a, + 0x69, 0x19, 0x56, 0x35, 0x80, 0xee, 0xfe, 0x03, 0xc4, 0xab, 0x14, 0xfc, + 0x3a, 0xfc, 0x6f, 0x55, 0xee, 0x48, 0x5d, 0xac, 0x9e, 0xb7, 0xd7, 0x49, + 0xbe, 0xef, 0x8b, 0x1e, 0x66, 0x8f, 0x3d, 0x92, 0xb5, 0x8b, 0xb0, 0x0f, + 0xb7, 0x16, 0x39, 0x3e, 0x1d, 0x46, 0x14, 0xca, 0xbf, 0x0e, 0x59, 0x18, + 0xfc, 0x1b, 0xc8, 0x70, 0xcb, 0x69, 0x16, 0xb0, 0x74, 0xe0, 0xf0, 0x42, + 0x34, 0xa2, 0xea, 0x33, 0xd7, 0xd9, 0xec, 0xb7, 0x20, 0xd3, 0x51, 0x59, + 0x40, 0xfc, 0x50, 0x1a, 0x04, 0x8d, 0x7d, 0x9d, 0x18, 0x4f, 0xbb, 0x23, + 0xcf, 0x47, 0xe1, 0x7b, 0xc9, 0xd3, 0x28, 0xc6, 0xef, 0xc2, 0x98, 0x0e, + 0x5c, 0xbf, 0x68, 0x2c, 0x58, 0xcc, 0x9d, 0x7f, 0x0e, 0x6d, 0xce, 0x11, + 0xf4, 0x9d, 0x9f, 0x0e, 0x89, 0x9a, 0x93, 0xef, 0x74, 0x2a, 0xfb, 0xaf, + 0xaf, 0xc5, 0x75, 0xf8, 0xec, 0xbd, 0xea, 0x2d, 0xfd, 0x83, 0x81, 0xf5, + 0xda, 0x02, 0xeb, 0x0d, 0x06, 0xd6, 0x23, 0x9d, 0x1d, 0x01, 0x3a, 0x3b, + 0xf0, 0x7e, 0x0e, 0x6b, 0x0f, 0xab, 0x98, 0xa7, 0xbe, 0xe6, 0xfd, 0x81, + 0x35, 0xfd, 0xfd, 0x75, 0x06, 0xde, 0x7b, 0x07, 0xeb, 0xb1, 0x2f, 0x1a, + 0xe8, 0x23, 0x0d, 0xeb, 0xd1, 0xc7, 0x76, 0x47, 0x80, 0x2e, 0xd2, 0xba, + 0x16, 0xfd, 0x2a, 0x7e, 0x02, 0x9f, 0x5b, 0xe0, 0xb7, 0x74, 0xf8, 0x0e, + 0xd6, 0xa0, 0x1b, 0xf7, 0xfa, 0x65, 0xac, 0xeb, 0xcf, 0x17, 0xc5, 0x1c, + 0x1c, 0xcf, 0xb1, 0x86, 0xf7, 0x3e, 0xfb, 0xf9, 0xfc, 0x1b, 0xd5, 0xaf, + 0x2b, 0xbe, 0xad, 0x07, 0xed, 0xaa, 0xee, 0x22, 0xf3, 0x1d, 0x26, 0xe4, + 0xc9, 0xfc, 0x58, 0x93, 0x9b, 0x6c, 0x5d, 0xeb, 0xe9, 0xa7, 0xec, 0xd7, + 0x79, 0x58, 0xda, 0xa2, 0x65, 0x8f, 0xb3, 0x5e, 0xd0, 0xea, 0xe5, 0x7c, + 0xc8, 0x3d, 0x94, 0x8f, 0x31, 0xbd, 0xe7, 0xf4, 0x31, 0x8c, 0x5b, 0xe8, + 0x3f, 0x33, 0xde, 0x3d, 0xae, 0xd0, 0xe1, 0x7d, 0xa5, 0x0e, 0x39, 0xaf, + 0x78, 0x6a, 0xc9, 0xb9, 0x1a, 0x4f, 0x43, 0xde, 0xb7, 0x90, 0x83, 0xde, + 0x77, 0x06, 0x03, 0x71, 0x11, 0xee, 0xcb, 0x19, 0xd0, 0x10, 0x97, 0x9e, + 0x7e, 0xe6, 0x6e, 0x45, 0x5c, 0x59, 0xa7, 0xd0, 0x70, 0x75, 0xeb, 0x17, + 0x3d, 0xfd, 0xf0, 0x4b, 0xc0, 0xa1, 0x9e, 0xfe, 0xef, 0xa8, 0x7c, 0xae, + 0x54, 0xb1, 0xb4, 0x3b, 0x1c, 0xb7, 0x46, 0x74, 0xce, 0xbe, 0x5c, 0x8d, + 0x68, 0xa0, 0x99, 0x75, 0x0d, 0xbf, 0x46, 0x74, 0x4e, 0x54, 0x8d, 0xe8, + 0xe4, 0x15, 0x6a, 0x44, 0x99, 0xab, 0xaf, 0x11, 0x71, 0x7e, 0x53, 0xee, + 0x1e, 0x10, 0xed, 0x4b, 0x5e, 0x8d, 0xe8, 0x82, 0xb8, 0x35, 0xa2, 0xf3, + 0xb2, 0x7a, 0x8d, 0xe8, 0x68, 0x43, 0x8d, 0x68, 0xbd, 0xaa, 0x11, 0x71, + 0x1e, 0xb7, 0x46, 0xc4, 0x76, 0xbe, 0x7f, 0x30, 0x50, 0xeb, 0x00, 0xfe, + 0x3a, 0xb7, 0x82, 0x6f, 0x96, 0x36, 0xea, 0xf8, 0x98, 0x46, 0xec, 0xbf, + 0xbe, 0xe6, 0xbf, 0xea, 0xf8, 0xa6, 0x29, 0x9d, 0xbb, 0x12, 0xbe, 0x8d, + 0xba, 0x71, 0xc9, 0x32, 0x6c, 0x9b, 0xaa, 0xc5, 0x2e, 0xbf, 0xdc, 0xcc, + 0x1c, 0x7a, 0xb2, 0x5c, 0x9f, 0x77, 0x12, 0xf2, 0x1e, 0xab, 0xd5, 0x49, + 0x2e, 0x15, 0x1f, 0x45, 0xe5, 0xe0, 0xaa, 0xdf, 0x9a, 0x62, 0x99, 0x95, + 0xdf, 0x9a, 0x34, 0x89, 0x82, 0xce, 0x7c, 0x7f, 0x5e, 0xe5, 0x5d, 0x0b, + 0xce, 0xcf, 0xcb, 0xd2, 0xbd, 0x16, 0xf0, 0xc7, 0xaf, 0x9f, 0x50, 0xbe, + 0x75, 0x9f, 0x92, 0xd5, 0x3f, 0xba, 0x1a, 0xca, 0x3e, 0x55, 0x43, 0xf9, + 0x5a, 0x73, 0xb0, 0x86, 0x72, 0x4e, 0x2e, 0x5f, 0x43, 0xd9, 0xb7, 0x4a, + 0x0d, 0xe5, 0x15, 0xa9, 0xd7, 0x50, 0x5e, 0x11, 0xbf, 0x86, 0x62, 0xc8, + 0xd2, 0x7a, 0xce, 0xb3, 0x1f, 0xef, 0x8c, 0xe0, 0x37, 0x8c, 0x9f, 0x5b, + 0x53, 0x39, 0x57, 0xa3, 0x7f, 0xb5, 0x9a, 0xca, 0x37, 0x9b, 0xdf, 0x4f, + 0x4d, 0xc5, 0xf5, 0x01, 0x7e, 0x4d, 0xa5, 0x05, 0xf1, 0x0e, 0x7c, 0x8e, + 0x1e, 0xac, 0xa9, 0xfc, 0x2d, 0xed, 0x01, 0x7d, 0x2a, 0x46, 0x40, 0x3f, + 0xec, 0x02, 0x7e, 0x29, 0xa3, 0x6a, 0x1c, 0x9f, 0xf6, 0x78, 0xb8, 0x1b, + 0x7b, 0x8e, 0x43, 0x16, 0xe4, 0x63, 0x8f, 0x8a, 0x2d, 0x33, 0x66, 0x4c, + 0xcb, 0xf6, 0xc2, 0x9b, 0x4d, 0xf3, 0x5b, 0x74, 0x4c, 0xc6, 0x2b, 0xd4, + 0xf1, 0x2e, 0xc4, 0xe2, 0x26, 0xfa, 0x76, 0xa3, 0xed, 0xc7, 0x54, 0xfd, + 0xb5, 0x39, 0x68, 0x9b, 0x0b, 0xc0, 0x59, 0xe0, 0xc4, 0x55, 0xf8, 0xa8, + 0x6d, 0xa0, 0x39, 0xb8, 0x8f, 0x22, 0xfc, 0x13, 0xfa, 0x94, 0xcc, 0x19, + 0x5b, 0xfa, 0xb4, 0xc4, 0x69, 0xe7, 0x57, 0x31, 0x1f, 0xfb, 0xb6, 0xa9, + 0x7c, 0xac, 0x30, 0xc0, 0xbd, 0xd2, 0xd7, 0x2d, 0x82, 0x3e, 0xf4, 0x95, + 0x98, 0x03, 0xd2, 0xef, 0xf9, 0x39, 0x5a, 0x44, 0xe5, 0x68, 0x9d, 0x8a, + 0x1f, 0xe4, 0xf5, 0x8d, 0x61, 0x62, 0x65, 0xa7, 0xcd, 0x3d, 0x0c, 0x7b, + 0x58, 0xc7, 0xb6, 0x9b, 0x0b, 0x66, 0x74, 0xde, 0x3f, 0x02, 0xb9, 0xb2, + 0x4e, 0xe3, 0xcb, 0xef, 0x21, 0x6f, 0xdf, 0x83, 0x52, 0xec, 0x94, 0xf0, + 0x7a, 0xd0, 0x93, 0x9f, 0x61, 0xdc, 0xfd, 0x09, 0x95, 0x83, 0x44, 0xed, + 0x4b, 0xdb, 0xed, 0x5d, 0xd7, 0x60, 0xb7, 0x23, 0x97, 0xb5, 0xdb, 0xcf, + 0x85, 0x83, 0x76, 0x7b, 0xd7, 0x35, 0xd8, 0xed, 0xfe, 0x6b, 0xb2, 0x5b, + 0xee, 0x8d, 0x98, 0xe4, 0xd7, 0xc4, 0x56, 0xc6, 0x59, 0xfe, 0xba, 0x13, + 0x58, 0x33, 0x73, 0x89, 0x35, 0xc7, 0x2e, 0x59, 0x5b, 0x6d, 0x8c, 0xb1, + 0xae, 0x46, 0xde, 0xcc, 0xad, 0xe8, 0x6f, 0x23, 0x9e, 0x5f, 0xba, 0xdd, + 0xcb, 0xe7, 0xfd, 0xbc, 0x3e, 0x68, 0x3f, 0xd4, 0x0b, 0xea, 0xc2, 0x63, + 0xe0, 0x17, 0xf5, 0xc1, 0xb7, 0xb9, 0x9e, 0x06, 0x1d, 0x5c, 0x44, 0xbe, + 0xdf, 0xe3, 0xe9, 0x20, 0x65, 0xdd, 0xab, 0xbe, 0x11, 0x95, 0x9c, 0x47, + 0xdc, 0x3c, 0x1f, 0x3a, 0x90, 0x2f, 0xf9, 0xb6, 0x06, 0x9e, 0x44, 0xfd, + 0x67, 0xe4, 0xa3, 0x8d, 0x98, 0x67, 0x0b, 0xe2, 0x35, 0xf0, 0x48, 0xf5, + 0x2f, 0xaf, 0x09, 0x5f, 0x1e, 0xcf, 0xa4, 0x18, 0xc2, 0xd8, 0x53, 0x03, + 0xb0, 0xf1, 0x01, 0x62, 0x54, 0x1a, 0x79, 0x0f, 0xf5, 0x90, 0xba, 0xb9, + 0x29, 0xb9, 0x43, 0x67, 0x4c, 0xb5, 0x07, 0xb6, 0x47, 0x7d, 0x8d, 0xcb, + 0x8e, 0xca, 0xa6, 0x33, 0xe7, 0x74, 0xae, 0x51, 0xad, 0xe6, 0x99, 0x2b, + 0x5a, 0xa2, 0x77, 0xf7, 0xff, 0x45, 0x98, 0x7e, 0xe9, 0x7a, 0xdb, 0xf0, + 0x74, 0x2d, 0x83, 0x7b, 0xea, 0xed, 0xeb, 0xf0, 0xf7, 0xfc, 0xc6, 0xfe, + 0x03, 0xf4, 0xc7, 0x60, 0xf3, 0xf4, 0xef, 0xcc, 0x47, 0xb6, 0x7a, 0xe3, + 0x7a, 0xd4, 0xf7, 0xcf, 0x6c, 0xea, 0x56, 0xef, 0xbb, 0x13, 0xfd, 0x4f, + 0x82, 0x3e, 0x7b, 0x99, 0x9c, 0x79, 0x46, 0x21, 0xa7, 0xf2, 0x19, 0xbe, + 0xaf, 0x74, 0x12, 0x39, 0x88, 0x19, 0xa8, 0xa5, 0x87, 0xbd, 0xdc, 0x8d, + 0x36, 0x16, 0x81, 0x0c, 0xb7, 0x7b, 0xb9, 0x0a, 0xf3, 0xd7, 0xe5, 0x67, + 0x13, 0x56, 0xd7, 0x81, 0x0d, 0xef, 0x43, 0x07, 0x1a, 0xe5, 0x17, 0x86, + 0xed, 0xfb, 0xf2, 0xf3, 0xe3, 0x98, 0x79, 0x6f, 0xdf, 0x3d, 0xae, 0x0c, + 0x7f, 0x2c, 0xf6, 0xa9, 0x05, 0xf6, 0xe9, 0xe3, 0xd1, 0x3e, 0x6f, 0x9f, + 0x5b, 0x1b, 0xf0, 0x68, 0xa4, 0xc1, 0x66, 0x3f, 0x4a, 0x3c, 0x3a, 0xb4, + 0xe6, 0xa3, 0xc7, 0x23, 0xee, 0x6b, 0xe3, 0xaa, 0x38, 0xe4, 0xee, 0xe3, + 0x77, 0x45, 0x4f, 0x7f, 0x98, 0xf9, 0xde, 0xfb, 0x91, 0x4f, 0x10, 0x47, + 0x28, 0x93, 0x36, 0x15, 0xc3, 0xba, 0xb6, 0x07, 0x5f, 0x5e, 0x0a, 0xc9, + 0x1b, 0xf7, 0x84, 0xe5, 0x7f, 0x6f, 0xe3, 0xf7, 0x30, 0xd3, 0xab, 0x69, + 0xb1, 0xfd, 0xc2, 0x1a, 0xd7, 0x0f, 0xbd, 0xd0, 0xee, 0xfa, 0x1d, 0xbe, + 0xe3, 0xdb, 0xb3, 0x85, 0xe7, 0x7c, 0xb6, 0x91, 0x5f, 0x4c, 0xae, 0x21, + 0x07, 0xdc, 0x64, 0x5d, 0xd0, 0x57, 0xcb, 0x01, 0x2f, 0x5f, 0x0f, 0xac, + 0xe7, 0x80, 0xc4, 0xd9, 0x0e, 0xa5, 0x1b, 0xf9, 0x28, 0x73, 0x1f, 0xc3, + 0xc3, 0x4e, 0xde, 0x23, 0xb7, 0x75, 0x90, 0xef, 0x42, 0xb6, 0xcf, 0x21, + 0x5e, 0x7a, 0xd6, 0x41, 0x8e, 0xeb, 0x20, 0xb7, 0x75, 0x90, 0xdb, 0x3a, + 0xc8, 0x6d, 0x9d, 0xa4, 0x97, 0x23, 0x8f, 0x78, 0x75, 0x7f, 0x7e, 0xe3, + 0x66, 0x7d, 0xa1, 0x08, 0x5f, 0x32, 0xc5, 0x73, 0x13, 0x7a, 0x36, 0xb5, + 0xc6, 0xdb, 0x9f, 0x5f, 0x13, 0xef, 0xf2, 0x6a, 0x36, 0xdf, 0x54, 0x75, + 0x43, 0xd1, 0x1f, 0x68, 0x71, 0xbf, 0x83, 0xf3, 0x7c, 0xc7, 0xaf, 0x21, + 0x2e, 0x51, 0x67, 0x88, 0x68, 0xa3, 0x55, 0x3d, 0xcd, 0x9a, 0x8c, 0xe8, + 0x7a, 0xfa, 0x16, 0xbc, 0xb3, 0xc5, 0xcd, 0x09, 0xa2, 0x62, 0xe8, 0xe9, + 0x56, 0xf2, 0x54, 0xd3, 0xd3, 0x6b, 0xbd, 0xb9, 0xf6, 0xb7, 0xb8, 0xb1, + 0x55, 0x2f, 0xdb, 0xa6, 0xce, 0x38, 0x41, 0xc5, 0xda, 0x7e, 0xff, 0xc5, + 0xf6, 0xe5, 0x6b, 0x85, 0x14, 0xbe, 0x67, 0x53, 0xf7, 0x62, 0x3e, 0xb6, + 0xeb, 0xfc, 0xd6, 0x2f, 0xc9, 0xef, 0x90, 0xc7, 0x6f, 0x97, 0xc7, 0x06, + 0xc7, 0xa9, 0xba, 0x30, 0x79, 0xed, 0xcf, 0xa7, 0xea, 0x7a, 0x58, 0x47, + 0x9d, 0xcd, 0xc0, 0xf5, 0x07, 0xa6, 0xb4, 0x8d, 0xee, 0x0e, 0xd9, 0xc1, + 0x75, 0xfd, 0x6f, 0xe2, 0x57, 0xb3, 0x66, 0x8f, 0xfa, 0x8e, 0xe6, 0xfa, + 0x8c, 0x90, 0xd2, 0x41, 0x33, 0xcd, 0x7d, 0xfd, 0x50, 0x9d, 0xa9, 0xa1, + 0xfe, 0xe5, 0x90, 0xc7, 0x4c, 0x0d, 0x6c, 0x8a, 0x9b, 0xfa, 0x48, 0x0b, + 0xeb, 0xaf, 0x43, 0x15, 0x1f, 0xf7, 0xb8, 0x5e, 0xa3, 0x1f, 0x67, 0x5d, + 0xcd, 0xc7, 0x33, 0xd9, 0xe0, 0xd6, 0xdb, 0x3e, 0x88, 0x2d, 0xb5, 0x34, + 0xd8, 0x92, 0xbf, 0x4f, 0xee, 0x9f, 0xd7, 0xd5, 0xcf, 0x43, 0x2c, 0x56, + 0x02, 0xdf, 0x47, 0x6a, 0xba, 0xc1, 0xb3, 0x2a, 0x9f, 0x85, 0x0e, 0xf2, + 0xdb, 0xc0, 0x4e, 0xd8, 0x51, 0xb5, 0x3a, 0xc4, 0x1a, 0x73, 0xdf, 0x67, + 0x54, 0x7e, 0xa9, 0xa7, 0xe7, 0x55, 0xfd, 0xc1, 0x5c, 0x51, 0x7f, 0x18, + 0x82, 0xae, 0x20, 0x06, 0x70, 0xda, 0x54, 0x4c, 0xa7, 0xe2, 0x85, 0x4a, + 0xe3, 0xf7, 0x97, 0xfb, 0x5b, 0x5d, 0x3e, 0xfc, 0x5d, 0x8b, 0xfb, 0x0d, + 0xe2, 0x8f, 0xa2, 0xcb, 0xdb, 0x7c, 0xff, 0xaf, 0x5b, 0xfc, 0xb3, 0x3b, + 0x85, 0x13, 0x43, 0xd0, 0x45, 0xe4, 0xe4, 0x6a, 0x3e, 0xc4, 0xbb, 0x4f, + 0xcc, 0x76, 0x2c, 0x1f, 0x8f, 0xbe, 0x13, 0xfe, 0xf8, 0x8e, 0x86, 0xf1, + 0x1d, 0x18, 0xff, 0x7b, 0x0d, 0xe3, 0x3b, 0x02, 0xe3, 0xa3, 0x0d, 0xe3, + 0xa3, 0x18, 0xff, 0x7c, 0xc3, 0xf8, 0x68, 0x60, 0x7c, 0x67, 0xc3, 0xf8, + 0x4e, 0x8c, 0x7f, 0xa1, 0x61, 0x3c, 0xfa, 0x4e, 0x34, 0x79, 0xdf, 0xc5, + 0x88, 0xb1, 0xfb, 0xbd, 0x5c, 0x1c, 0xd7, 0x72, 0xe3, 0xb7, 0x16, 0xea, + 0x5d, 0x17, 0x64, 0xe0, 0x9f, 0xa7, 0xa3, 0xbd, 0x66, 0x60, 0xaf, 0xf5, + 0x58, 0xc6, 0xd5, 0xc7, 0xa0, 0x2e, 0x12, 0x1f, 0x8a, 0x62, 0xd8, 0xd0, + 0x9d, 0x12, 0x74, 0xa8, 0xe4, 0xfb, 0x24, 0x9e, 0x83, 0xe2, 0x19, 0x53, + 0xd7, 0xf7, 0x86, 0xec, 0x45, 0x2f, 0x07, 0x7b, 0x9b, 0xb4, 0x03, 0x2f, + 0x7d, 0xcc, 0x94, 0x63, 0xae, 0xdd, 0x50, 0x7f, 0x39, 0xbf, 0x67, 0x3f, + 0xd4, 0x55, 0x6f, 0x9d, 0xa1, 0x15, 0xb8, 0x16, 0x5f, 0x51, 0xdb, 0x32, + 0xae, 0x02, 0xd7, 0x46, 0x6a, 0xb8, 0xf6, 0x59, 0x99, 0xaf, 0xe5, 0xdb, + 0xc3, 0x72, 0xc0, 0xd9, 0xc5, 0x33, 0x36, 0xc7, 0x32, 0xf2, 0xe1, 0xe4, + 0xdb, 0xbb, 0x6a, 0x7e, 0x92, 0x67, 0x3a, 0x96, 0x0e, 0x31, 0x87, 0xf2, + 0x6b, 0xb3, 0x53, 0xce, 0xcf, 0xb6, 0x42, 0x2e, 0xb0, 0x8d, 0x6b, 0xcd, + 0xb7, 0x39, 0x5f, 0x54, 0x0e, 0xb8, 0xe7, 0x1d, 0x6a, 0xf3, 0x16, 0x6b, + 0xf3, 0xc6, 0x3c, 0x7b, 0xa3, 0x0f, 0xae, 0xfb, 0xcb, 0x1c, 0xfc, 0xe5, + 0x18, 0x72, 0xee, 0x45, 0x67, 0xb5, 0xfa, 0xe8, 0xb5, 0xfa, 0xcb, 0xc6, + 0x3a, 0x73, 0xa3, 0xbf, 0xe4, 0x3a, 0x8d, 0xb5, 0xe5, 0x78, 0x03, 0xfe, + 0x53, 0x9f, 0x0e, 0x7b, 0x31, 0x35, 0xae, 0xa5, 0xc3, 0xb0, 0x47, 0x5d, + 0xc6, 0x94, 0xfe, 0xb2, 0xed, 0xe7, 0x96, 0xbb, 0x6b, 0xb9, 0x65, 0x3d, + 0x1f, 0x44, 0xec, 0x9a, 0xfc, 0xa4, 0x87, 0x8f, 0x8c, 0x91, 0xa7, 0xd0, + 0x7f, 0x0c, 0x3a, 0xc0, 0x67, 0xac, 0x97, 0xde, 0x2c, 0x9f, 0x32, 0x5d, + 0xff, 0xe4, 0xd6, 0xa6, 0x76, 0xab, 0xf8, 0x9f, 0xdf, 0x0b, 0x0a, 0xa9, + 0x76, 0x2f, 0xde, 0xbb, 0x12, 0xae, 0x2e, 0xcf, 0x4d, 0x75, 0xfd, 0x51, + 0xbc, 0xcb, 0xdc, 0xd4, 0x8c, 0x10, 0x43, 0xb3, 0x95, 0xcb, 0xbe, 0x5f, + 0xa4, 0x7f, 0x29, 0xa8, 0xef, 0x82, 0x2a, 0x0f, 0xc5, 0xb8, 0x45, 0xef, + 0x7d, 0x37, 0x0f, 0xcd, 0x56, 0xbe, 0xdd, 0xea, 0xe2, 0xe0, 0xe5, 0x72, + 0x96, 0x9f, 0x88, 0xb0, 0xae, 0xb7, 0xe8, 0x5c, 0x89, 0xd6, 0x95, 0x79, + 0xaf, 0xb1, 0x22, 0xef, 0x1d, 0xf5, 0xf2, 0xda, 0xcf, 0xa9, 0xbc, 0xd7, + 0xe5, 0x31, 0xf7, 0x12, 0xcc, 0xa3, 0x6c, 0x60, 0x21, 0xbf, 0xa9, 0x10, + 0x1f, 0x26, 0x94, 0xdf, 0xca, 0x4f, 0xdf, 0x09, 0x3e, 0x47, 0x57, 0xd1, + 0x9b, 0x8f, 0xda, 0x4f, 0xf8, 0x7b, 0x3f, 0x2c, 0x6e, 0xbd, 0x6e, 0x27, + 0x68, 0x61, 0x6e, 0x15, 0xf2, 0xf4, 0xe1, 0xbb, 0xde, 0x39, 0x53, 0x7f, + 0x9c, 0x9f, 0xc7, 0xd7, 0xbe, 0xbb, 0x16, 0x33, 0xcb, 0xea, 0x27, 0x1b, + 0x09, 0xc3, 0x90, 0x7b, 0xe6, 0x1a, 0xbe, 0x5b, 0x7c, 0x90, 0xf3, 0x11, + 0x8d, 0x7e, 0x8d, 0xdf, 0x4d, 0xf9, 0xad, 0x54, 0xb4, 0xbb, 0x7b, 0x6d, + 0xd8, 0x00, 0xcf, 0x2c, 0x07, 0xf1, 0x35, 0x2c, 0xf9, 0x39, 0x09, 0x47, + 0xd3, 0xfc, 0x06, 0x40, 0xff, 0xff, 0xba, 0xb7, 0xcf, 0x98, 0xec, 0x9f, + 0x71, 0x6b, 0x9e, 0xfa, 0x65, 0xcf, 0xc5, 0x1d, 0x00, 0x1f, 0x12, 0x47, + 0xfd, 0x9a, 0xa7, 0xee, 0x9e, 0x8b, 0x3b, 0xfa, 0xe1, 0x9d, 0x8b, 0xe3, + 0xfc, 0xa6, 0xec, 0x5a, 0xe5, 0x5c, 0x9c, 0x71, 0x95, 0xe7, 0xe2, 0xda, + 0x55, 0xcd, 0x93, 0xf3, 0xb8, 0x35, 0x4f, 0xb6, 0xbb, 0xfb, 0x59, 0x2b, + 0xe1, 0xd9, 0xb7, 0x01, 0x75, 0x06, 0xb9, 0xbb, 0xff, 0x47, 0x91, 0xa3, + 0x7c, 0x3d, 0xf2, 0xd1, 0xe7, 0x28, 0xdc, 0xcb, 0xaf, 0xb8, 0xdf, 0x77, + 0xe5, 0x5a, 0xea, 0x00, 0x1f, 0xac, 0xae, 0xb9, 0x5f, 0xd5, 0x35, 0xbf, + 0x13, 0x09, 0xd6, 0x35, 0xf5, 0x2b, 0x9c, 0x0d, 0xdb, 0xbf, 0x4a, 0x5d, + 0x33, 0x14, 0x38, 0x1b, 0x16, 0xf2, 0xce, 0x86, 0xb5, 0xdb, 0xc8, 0x25, + 0xbd, 0x3a, 0xa6, 0x7e, 0xd9, 0xb3, 0x61, 0xff, 0x19, 0xf9, 0xe0, 0x75, + 0xcc, 0x15, 0x67, 0xc3, 0xe0, 0xeb, 0x36, 0x48, 0xfc, 0x9a, 0xf2, 0x9e, + 0x0f, 0x92, 0xf3, 0xf0, 0xbc, 0x7e, 0x13, 0xf6, 0x1c, 0x92, 0x5d, 0x51, + 0xea, 0x27, 0xcf, 0x36, 0xf6, 0xc2, 0x16, 0x70, 0xad, 0xb0, 0x9d, 0xa4, + 0x8c, 0xb4, 0x91, 0xde, 0xe5, 0xe7, 0x10, 0xea, 0xe7, 0x71, 0xc3, 0xb5, + 0xf3, 0xb8, 0x47, 0xa0, 0x37, 0xfa, 0x4c, 0x58, 0x16, 0x02, 0x3a, 0x35, + 0x85, 0x78, 0x4f, 0x9f, 0xb3, 0xbc, 0xe7, 0xfc, 0x9f, 0x8a, 0x28, 0x30, + 0x8f, 0x67, 0x78, 0xdb, 0xc4, 0x98, 0x73, 0xbf, 0x59, 0xba, 0xff, 0x57, + 0x12, 0xc3, 0x18, 0x9e, 0xf1, 0x0c, 0xc9, 0x01, 0x55, 0xb3, 0xf0, 0x75, + 0x79, 0xc7, 0x5a, 0x69, 0x59, 0x9f, 0xa9, 0xb7, 0xa3, 0xab, 0xf8, 0x7d, + 0xc4, 0x91, 0x33, 0xd4, 0xe7, 0x5b, 0x25, 0xe7, 0xd5, 0x83, 0x0a, 0x95, + 0x6d, 0x5e, 0x7e, 0xa1, 0xbe, 0xed, 0x80, 0x97, 0xdd, 0x9e, 0x0f, 0xc6, + 0xb5, 0xd4, 0x4d, 0x9f, 0x87, 0x35, 0x4e, 0xca, 0xd0, 0xf4, 0x96, 0xd8, + 0x38, 0xf0, 0x6e, 0x4c, 0xad, 0x79, 0x2d, 0x3c, 0xd7, 0x2e, 0xf1, 0xbd, + 0xf1, 0x6a, 0xf9, 0xee, 0xc7, 0xc7, 0x8f, 0x62, 0x7f, 0xdd, 0xd0, 0x8f, + 0x87, 0x25, 0x77, 0xe2, 0x66, 0x19, 0x9a, 0x4d, 0x80, 0x9e, 0x1f, 0x56, + 0x0b, 0x29, 0xc4, 0xd2, 0x4f, 0xf0, 0xdc, 0x18, 0x30, 0x14, 0x7c, 0x7b, + 0x66, 0xc5, 0x77, 0xec, 0xe0, 0x59, 0xb3, 0x64, 0xed, 0xec, 0xd0, 0x53, + 0x15, 0x09, 0x77, 0x90, 0xe6, 0x99, 0xfa, 0xd9, 0xef, 0xc5, 0xca, 0x0e, + 0xe5, 0xdb, 0x9e, 0xac, 0x2c, 0xab, 0xfd, 0x28, 0x19, 0x4e, 0x94, 0x9f, + 0x04, 0x2f, 0x5e, 0x51, 0xfe, 0xed, 0x88, 0x23, 0x37, 0x19, 0x42, 0x79, + 0x88, 0x06, 0x1e, 0xa8, 0x33, 0x1c, 0xee, 0xf7, 0xfd, 0x2e, 0x25, 0x57, + 0x17, 0x2b, 0x76, 0x06, 0xce, 0x60, 0xd4, 0x65, 0xeb, 0x9e, 0xcd, 0x70, + 0x65, 0xe1, 0x9e, 0x1f, 0x21, 0x3f, 0x97, 0x0e, 0xed, 0xb2, 0xdd, 0xf3, + 0x23, 0x3d, 0x73, 0xec, 0xeb, 0x6c, 0xf0, 0x7d, 0x61, 0xe8, 0x00, 0xcf, + 0x1d, 0xf1, 0xcc, 0x37, 0x69, 0x56, 0xb5, 0x8e, 0x55, 0xbf, 0x6d, 0x5f, + 0x5b, 0xcd, 0xd5, 0x5d, 0xb3, 0x5b, 0xad, 0x79, 0x9d, 0x87, 0x59, 0xfe, + 0x59, 0xef, 0x94, 0xf6, 0xff, 0xd4, 0x5d, 0x7b, 0x6c, 0x1b, 0xf7, 0x7d, + 0xff, 0xf2, 0x48, 0x3d, 0xac, 0xe7, 0x49, 0xa6, 0x64, 0x5a, 0x52, 0x94, + 0x3b, 0xe9, 0x64, 0x29, 0xb1, 0x12, 0x70, 0x9e, 0xba, 0x0a, 0x88, 0x9a, + 0xb0, 0x24, 0xfd, 0x58, 0x10, 0x0c, 0xb4, 0xad, 0x64, 0xee, 0x92, 0xad, + 0x0e, 0x25, 0xa7, 0x1d, 0x30, 0x60, 0x6e, 0xd6, 0x02, 0x69, 0x07, 0xc7, + 0x0c, 0x65, 0x27, 0xc6, 0xaa, 0x88, 0x4c, 0xcc, 0x6a, 0x1d, 0xb0, 0x62, + 0x1c, 0xa5, 0x38, 0x69, 0xa7, 0x80, 0x69, 0xda, 0x04, 0xc5, 0xfe, 0xb1, + 0x26, 0x3b, 0x7b, 0x61, 0x7f, 0x04, 0xdb, 0x80, 0x1a, 0x5b, 0x81, 0xba, + 0x76, 0x8a, 0x65, 0x1b, 0xe0, 0x34, 0xdb, 0xb0, 0x75, 0x58, 0x0b, 0xee, + 0xfb, 0xf9, 0x3d, 0xc8, 0x23, 0x79, 0xd4, 0xc3, 0x71, 0x06, 0x4c, 0x80, + 0x40, 0xde, 0xf1, 0x77, 0x77, 0xbf, 0xdf, 0xf7, 0xf7, 0x7d, 0xbf, 0x6e, + 0x2e, 0x33, 0x1e, 0xf2, 0x33, 0x7e, 0xcf, 0x15, 0x61, 0x5f, 0x37, 0xd2, + 0xe1, 0x36, 0x83, 0x67, 0xa4, 0x0e, 0x9e, 0xd5, 0x34, 0xc1, 0xf6, 0x78, + 0x99, 0x77, 0x4b, 0xd8, 0xc9, 0xf3, 0xc8, 0x63, 0xd7, 0x39, 0x0e, 0x12, + 0x76, 0x65, 0x1a, 0x5a, 0x72, 0xe7, 0x37, 0x54, 0x60, 0x77, 0xb2, 0x0c, + 0xbb, 0x3d, 0xff, 0x8f, 0x60, 0x77, 0x4d, 0xe8, 0xbf, 0xdf, 0x2e, 0x22, + 0x6f, 0x4d, 0xeb, 0x00, 0xba, 0x6e, 0x09, 0x70, 0x04, 0x3f, 0xb5, 0xf3, + 0xeb, 0x04, 0x9e, 0x8a, 0xbc, 0xe2, 0x52, 0xe9, 0x3b, 0xe1, 0xb2, 0x9f, + 0x92, 0xed, 0x12, 0xd8, 0x27, 0xf0, 0xe7, 0x35, 0x96, 0x91, 0x47, 0x6f, + 0x4b, 0x46, 0x42, 0x57, 0xaa, 0xb5, 0x4f, 0x7e, 0xbb, 0xcb, 0x6d, 0x9f, + 0x1c, 0xdd, 0xa1, 0x7d, 0x72, 0x5a, 0xda, 0x27, 0xa9, 0xed, 0xdb, 0x27, + 0x03, 0x75, 0x79, 0x5d, 0x95, 0xf5, 0xec, 0xdc, 0x3e, 0x31, 0x36, 0xb5, + 0x4f, 0x46, 0x5d, 0xbe, 0x18, 0xcc, 0xf7, 0x57, 0x29, 0x75, 0x0c, 0x3c, + 0x4e, 0xc3, 0x19, 0x30, 0x3e, 0x56, 0xe3, 0x17, 0xfe, 0x38, 0x61, 0xfd, + 0xd7, 0xff, 0xc7, 0xb0, 0x1e, 0xac, 0xf3, 0x79, 0x57, 0xd6, 0x03, 0x21, + 0xfe, 0x51, 0x60, 0x3d, 0xd8, 0xd0, 0x77, 0xda, 0x38, 0x67, 0xb1, 0xda, + 0x77, 0x3a, 0x62, 0x34, 0xe2, 0xed, 0x7f, 0xe4, 0xf2, 0xa9, 0xba, 0xf9, + 0x3b, 0x68, 0x8a, 0x7c, 0x47, 0xc7, 0xf5, 0xb3, 0x40, 0x4b, 0x76, 0x2a, + 0x45, 0xb0, 0x99, 0xf0, 0xbc, 0x90, 0xa0, 0xb5, 0x1a, 0x7d, 0x8b, 0x9f, + 0xc7, 0xeb, 0x7b, 0xf5, 0x09, 0x21, 0xa7, 0xa4, 0xff, 0x01, 0xe3, 0x27, + 0x7c, 0xf3, 0x62, 0xac, 0xcc, 0x6f, 0x52, 0xfe, 0x08, 0xa5, 0xfb, 0x37, + 0xf2, 0x43, 0xd4, 0xcb, 0xbc, 0x9d, 0xd9, 0x0a, 0x9a, 0xc6, 0xef, 0xe6, + 0x7d, 0x09, 0x55, 0xd9, 0x5a, 0xe0, 0x9f, 0xa7, 0x59, 0x2f, 0x18, 0x29, + 0xeb, 0x04, 0xd5, 0x7b, 0x73, 0x4e, 0xd8, 0x74, 0x9a, 0x77, 0x26, 0x64, + 0xee, 0xa9, 0x38, 0x0f, 0x3d, 0x4d, 0xf3, 0xce, 0x5a, 0x3d, 0xf8, 0x6e, + 0x0f, 0xbc, 0xf0, 0xca, 0x69, 0x2a, 0xef, 0x9d, 0x85, 0x9c, 0xf3, 0xb8, + 0xe7, 0xde, 0x95, 0x6b, 0xc2, 0x52, 0x95, 0xb1, 0xf2, 0xfa, 0xb8, 0x58, + 0xd7, 0x0f, 0x8e, 0x44, 0x51, 0xfb, 0x56, 0xae, 0x17, 0xab, 0xad, 0x77, + 0x82, 0x1c, 0xd0, 0x74, 0xa8, 0x6b, 0xa2, 0x01, 0x8b, 0x61, 0x8f, 0x7a, + 0x27, 0xb7, 0x2c, 0xc1, 0x75, 0xb5, 0xb0, 0xa8, 0xc8, 0x91, 0xf3, 0x4a, + 0x8e, 0x14, 0x5c, 0x7c, 0xbc, 0x5e, 0x6f, 0xef, 0xf5, 0xd0, 0xdb, 0xbd, + 0x6a, 0x9e, 0x30, 0xa7, 0x67, 0x58, 0x0f, 0xb9, 0x1f, 0x7a, 0x88, 0x89, + 0xba, 0x25, 0xa9, 0x8b, 0xe0, 0x77, 0x96, 0x35, 0xaf, 0x86, 0x18, 0x57, + 0x8e, 0xd0, 0x53, 0xac, 0x6b, 0x5f, 0xa2, 0x7b, 0x94, 0x7d, 0x16, 0x71, + 0xe5, 0x99, 0x22, 0x8f, 0xdf, 0x47, 0xa9, 0x27, 0xec, 0x89, 0x08, 0x1d, + 0xa1, 0x53, 0x22, 0x67, 0x06, 0xf1, 0x3d, 0xe4, 0x1c, 0xdc, 0x2b, 0x9e, + 0x2f, 0x7d, 0x19, 0x77, 0x22, 0xa7, 0x6e, 0xfb, 0xf9, 0xfb, 0xba, 0x56, + 0x2f, 0x2a, 0x9e, 0xb9, 0xaa, 0x68, 0x4a, 0x9c, 0xe3, 0xeb, 0x9f, 0x31, + 0xea, 0xaf, 0x8f, 0x18, 0xf1, 0x62, 0xdc, 0x88, 0xae, 0x60, 0xdc, 0x33, + 0x46, 0xac, 0x08, 0x1b, 0x52, 0xe3, 0x88, 0x1d, 0x06, 0xbd, 0x6d, 0xd0, + 0xd6, 0xb1, 0x88, 0x02, 0xd5, 0xd4, 0x49, 0x6c, 0x63, 0xde, 0x87, 0xaa, + 0xe6, 0xad, 0xe1, 0x8b, 0xef, 0xf0, 0xf7, 0x44, 0x18, 0xa6, 0x5a, 0xaf, + 0x6d, 0x83, 0x7f, 0x7d, 0x22, 0x45, 0x9b, 0xe9, 0xb5, 0x76, 0x9d, 0x5e, + 0x5b, 0xd8, 0x72, 0xde, 0x1f, 0x95, 0xc6, 0x65, 0x3d, 0xa2, 0xdf, 0x11, + 0xfa, 0x2b, 0xcf, 0xbb, 0x4a, 0xb7, 0xad, 0xc1, 0x29, 0x8c, 0xd1, 0x7e, + 0x70, 0xed, 0x07, 0xeb, 0x52, 0xf9, 0xc0, 0x3a, 0x3f, 0xa1, 0x0d, 0xf5, + 0x5e, 0xa6, 0xcc, 0x6b, 0x85, 0x8d, 0xb5, 0xce, 0xf3, 0x83, 0xbd, 0xf5, + 0xa0, 0x98, 0x23, 0xdb, 0x5b, 0x56, 0x8c, 0xa4, 0xaf, 0x7b, 0xbe, 0x58, + 0x55, 0xff, 0xe9, 0x51, 0x07, 0x39, 0xe2, 0x51, 0x07, 0xe9, 0xa6, 0xb5, + 0x80, 0x8b, 0xd6, 0x42, 0x2e, 0xbd, 0x6d, 0x88, 0xed, 0x96, 0x0e, 0xe6, + 0x21, 0xb0, 0x5b, 0xda, 0xc8, 0xff, 0xb2, 0xdb, 0x6e, 0xa9, 0xad, 0x45, + 0x07, 0xdd, 0x41, 0x37, 0x93, 0x36, 0x4c, 0x3c, 0x57, 0xae, 0x63, 0xe7, + 0x75, 0x57, 0x6a, 0x0e, 0x57, 0xea, 0xea, 0x23, 0xbd, 0xe6, 0x3b, 0x5c, + 0x37, 0x5f, 0xc8, 0xaf, 0x48, 0x43, 0x9d, 0xce, 0xcb, 0xae, 0xba, 0x53, + 0xf3, 0xab, 0xe5, 0x67, 0x78, 0xd6, 0x88, 0xf0, 0x79, 0xa7, 0xca, 0xbc, + 0x6c, 0x5a, 0xce, 0x37, 0x53, 0x6d, 0x67, 0xf8, 0x97, 0x48, 0xc1, 0xce, + 0x9b, 0xb7, 0xef, 0xcc, 0x7f, 0xd6, 0x5e, 0x23, 0x77, 0xdf, 0x33, 0xa5, + 0x5f, 0xac, 0x49, 0xe5, 0x61, 0xf7, 0x29, 0x7b, 0x6f, 0x2b, 0x7c, 0xc7, + 0xb9, 0x26, 0xe5, 0x4b, 0xb4, 0xad, 0x3c, 0x01, 0xcf, 0x8f, 0x9d, 0x68, + 0x72, 0x4c, 0x15, 0xcb, 0x42, 0xbc, 0x0a, 0x78, 0xaf, 0xef, 0x0f, 0x9e, + 0xbd, 0x9d, 0x3d, 0xb3, 0xea, 0xf6, 0x4c, 0xe2, 0x15, 0x6c, 0x2d, 0xe4, + 0x17, 0x4f, 0xd6, 0xe4, 0x78, 0x7f, 0x14, 0x58, 0x74, 0x79, 0xe4, 0x3d, + 0x23, 0x6f, 0xb9, 0xd1, 0x3c, 0xaf, 0xbb, 0xf4, 0x72, 0xcc, 0xb7, 0x54, + 0x7a, 0x23, 0x3c, 0x20, 0x65, 0x71, 0xd1, 0x5b, 0x47, 0x32, 0xb7, 0x3d, + 0xbf, 0x5a, 0xd9, 0xbb, 0x77, 0x9b, 0xb2, 0x57, 0xf4, 0xf4, 0xf0, 0x1d, + 0x14, 0x3c, 0xa0, 0x83, 0x56, 0x72, 0xc8, 0xbf, 0xfe, 0x05, 0xd0, 0x3c, + 0xf3, 0x59, 0x57, 0x4d, 0x9a, 0xf7, 0x3e, 0x96, 0x63, 0x2a, 0x81, 0x19, + 0xc4, 0xfe, 0x90, 0x5b, 0xd2, 0xcb, 0xbc, 0x07, 0xe3, 0xc7, 0xac, 0xab, + 0xf0, 0xf7, 0x2a, 0xff, 0x53, 0x5c, 0xc9, 0x97, 0x83, 0xdb, 0x88, 0xad, + 0xec, 0x8c, 0x4f, 0xdb, 0xd6, 0x3a, 0x21, 0xee, 0x83, 0x7c, 0xe1, 0xfb, + 0xba, 0xa8, 0xeb, 0x33, 0x2d, 0x2d, 0xce, 0x97, 0x7a, 0x64, 0x2c, 0x0a, + 0xbf, 0x75, 0xd0, 0x2b, 0x39, 0xe4, 0x72, 0xe3, 0xb7, 0xdf, 0xe0, 0xdf, + 0xbc, 0x78, 0x94, 0xce, 0x45, 0x87, 0x2e, 0x27, 0xf7, 0x27, 0x4f, 0xb0, + 0x95, 0x4a, 0xf4, 0xb7, 0xe1, 0x5f, 0x94, 0xf1, 0x8c, 0xe2, 0x9d, 0x8e, + 0xd5, 0x78, 0xf9, 0x0b, 0xdf, 0xec, 0xb9, 0xdd, 0xdc, 0xc8, 0x2f, 0x6c, + 0xcb, 0x5f, 0x88, 0x38, 0xff, 0x76, 0x62, 0x26, 0x3a, 0x36, 0x3c, 0x25, + 0x6a, 0x4e, 0xdd, 0x78, 0x70, 0x67, 0xe2, 0xc3, 0xc0, 0x87, 0xe1, 0x3a, + 0x5e, 0xf5, 0xd1, 0xfd, 0xfd, 0xb5, 0x70, 0x6d, 0xf3, 0xf4, 0x55, 0x79, + 0xc7, 0x81, 0x11, 0xf3, 0x87, 0x9f, 0xfa, 0x21, 0x9a, 0xbf, 0x08, 0x1c, + 0x36, 0x18, 0xdb, 0x46, 0x69, 0x21, 0x88, 0xba, 0x22, 0x51, 0x9b, 0xa3, + 0xe2, 0x86, 0xb2, 0x56, 0x68, 0x5e, 0xd4, 0x40, 0x8e, 0x85, 0x6e, 0xf2, + 0xbc, 0xe7, 0x8b, 0x29, 0x3a, 0xc5, 0x32, 0xf6, 0xd4, 0x4a, 0x45, 0x77, + 0xaf, 0xaf, 0x83, 0xac, 0xc6, 0xf1, 0x9b, 0x02, 0xc7, 0x87, 0x36, 0xc5, + 0xf1, 0xc3, 0x65, 0x1c, 0xff, 0x44, 0xaf, 0xc4, 0xe7, 0x67, 0xf9, 0x5e, + 0x5d, 0x74, 0x50, 0xdc, 0x37, 0xc5, 0xdf, 0xdb, 0xe9, 0xa0, 0xec, 0x61, + 0xc1, 0xcf, 0x66, 0x1e, 0x9f, 0x49, 0xd1, 0x53, 0x17, 0x53, 0xbe, 0xb8, + 0xa8, 0x5f, 0x70, 0xf7, 0xe8, 0xd0, 0xd7, 0x63, 0x5c, 0x23, 0xfc, 0xd7, + 0x7c, 0x49, 0xd6, 0x5c, 0xe5, 0x25, 0x7f, 0xa2, 0x77, 0xc3, 0x83, 0x35, + 0xf8, 0x5f, 0x6d, 0x3b, 0x9e, 0x56, 0x32, 0xf0, 0xd8, 0x26, 0x7e, 0x8d, + 0x7a, 0xbc, 0xec, 0xf1, 0xd0, 0x87, 0x7f, 0xbd, 0x57, 0xc6, 0xa9, 0x36, + 0xf3, 0x6b, 0xb8, 0x71, 0xb4, 0x2a, 0x6e, 0xcf, 0x7c, 0xff, 0xbf, 0x55, + 0x1c, 0xfd, 0xa5, 0x5e, 0x29, 0x2f, 0x50, 0x1f, 0x98, 0x60, 0x38, 0x9c, + 0x64, 0x5d, 0x65, 0x90, 0x9a, 0x5f, 0xd6, 0x6b, 0x1d, 0x14, 0xfc, 0xd6, + 0xed, 0xa7, 0x39, 0xa7, 0x6a, 0xbb, 0xd3, 0xae, 0x35, 0x9d, 0x13, 0x36, + 0x4e, 0x63, 0x7a, 0x6b, 0x9c, 0x73, 0x35, 0x54, 0x23, 0x13, 0x6a, 0xf1, + 0x0d, 0xbd, 0x4f, 0xb0, 0xbf, 0x64, 0x48, 0x3d, 0x78, 0x9a, 0xf5, 0xdb, + 0x9d, 0xc6, 0x8b, 0x3e, 0xaa, 0x8e, 0x58, 0xdb, 0x53, 0xa3, 0xf6, 0x3b, + 0xf6, 0x41, 0xda, 0x1c, 0xc9, 0x57, 0x1f, 0x12, 0xbc, 0xe0, 0xdc, 0x64, + 0x89, 0x62, 0xe1, 0x4e, 0x4a, 0x4e, 0xf2, 0xb3, 0xa7, 0x1d, 0xb6, 0xbd, + 0xfc, 0x94, 0x62, 0xfa, 0x4d, 0x4e, 0xee, 0x52, 0xfa, 0xa2, 0xf6, 0xa7, + 0xb7, 0xa8, 0x3c, 0x87, 0x67, 0x45, 0x5c, 0x52, 0xf6, 0xc6, 0xe0, 0xef, + 0x2b, 0xfa, 0xde, 0xcf, 0x8a, 0xf8, 0x68, 0xf2, 0x62, 0xb3, 0x1a, 0xd7, + 0xee, 0x1a, 0x87, 0x31, 0xed, 0x6a, 0x2c, 0xee, 0xa9, 0x75, 0x8a, 0x56, + 0xc5, 0x6f, 0x1f, 0x11, 0x75, 0x60, 0xb2, 0x56, 0x0f, 0xbf, 0x9f, 0xa6, + 0xb9, 0xf2, 0x5a, 0xda, 0x79, 0xec, 0xcf, 0x4a, 0x11, 0x61, 0xcb, 0xb5, + 0xb3, 0xce, 0x8b, 0x79, 0xd7, 0xcf, 0x09, 0x6b, 0xf1, 0x8b, 0xf8, 0x10, + 0x7f, 0x57, 0xcf, 0x39, 0x59, 0x9e, 0x13, 0x72, 0x34, 0xec, 0x90, 0xbc, + 0x97, 0x1e, 0xd7, 0xee, 0x1a, 0xa7, 0x79, 0x85, 0x8e, 0x3f, 0xfc, 0x80, + 0xe7, 0xf1, 0x37, 0x2a, 0x87, 0xd7, 0x14, 0xf1, 0x53, 0x99, 0xa3, 0xa1, + 0xbf, 0xc3, 0xbf, 0x8c, 0x9c, 0x0a, 0xe4, 0x49, 0xb8, 0xf9, 0x8d, 0x5c, + 0x6f, 0x00, 0xb2, 0xa8, 0x88, 0xb8, 0x29, 0xe2, 0x15, 0x8d, 0x74, 0xe7, + 0xbd, 0xc8, 0xcd, 0xdf, 0x81, 0x0e, 0xba, 0x1d, 0xfa, 0xb3, 0x3c, 0xe8, + 0xcf, 0xfd, 0x7c, 0xd4, 0xc1, 0xa1, 0x1e, 0x2e, 0x35, 0x61, 0x50, 0x89, + 0x6d, 0x05, 0x83, 0xf2, 0xa6, 0x8f, 0x9e, 0x72, 0xec, 0xf0, 0x0a, 0xc9, + 0x9a, 0xc9, 0xd8, 0xa2, 0x3d, 0xb1, 0x4e, 0xfb, 0x45, 0xcd, 0x38, 0x7a, + 0x1f, 0xe4, 0x59, 0x06, 0x9f, 0xa4, 0x09, 0xb6, 0x8f, 0xd8, 0xfe, 0x9c, + 0x45, 0xbc, 0x45, 0xef, 0x0b, 0x6a, 0xe0, 0xf1, 0x39, 0xc1, 0x70, 0x7a, + 0x6c, 0x37, 0xb5, 0x45, 0xf8, 0x9e, 0x13, 0xe0, 0x4f, 0xe8, 0xe7, 0x45, + 0x51, 0xb6, 0x93, 0x60, 0xb3, 0x9e, 0x9c, 0xb5, 0xcd, 0x3c, 0x19, 0x3c, + 0x16, 0xb6, 0x2b, 0xee, 0x83, 0xeb, 0x23, 0x66, 0x13, 0xd5, 0xd6, 0xe4, + 0x3e, 0x2b, 0xea, 0x14, 0xdf, 0x0d, 0xdf, 0x47, 0x46, 0x3f, 0xf8, 0x15, + 0xf6, 0xed, 0x5e, 0x15, 0x27, 0x3a, 0xcb, 0xdf, 0xc7, 0xd5, 0xf7, 0xaf, + 0x88, 0xfd, 0x94, 0xdf, 0x35, 0x7e, 0xe3, 0xef, 0x5f, 0x5a, 0xc8, 0xf9, + 0xa1, 0xca, 0x59, 0xa9, 0xca, 0x05, 0x09, 0x8d, 0x1a, 0x5f, 0xa1, 0xd3, + 0x2b, 0x9b, 0xf9, 0x5f, 0xbc, 0x6a, 0x5d, 0xbb, 0xb7, 0x59, 0xeb, 0xfa, + 0x07, 0xbb, 0x65, 0x6d, 0x99, 0x7b, 0x2e, 0xff, 0xc9, 0x73, 0xf1, 0xd2, + 0xc9, 0xea, 0xf4, 0x44, 0x5e, 0x6f, 0x89, 0xfe, 0x29, 0xfc, 0x49, 0xba, + 0x1e, 0x0c, 0xa9, 0x9c, 0x25, 0xe4, 0x28, 0xdd, 0xa7, 0xf0, 0x5a, 0xf3, + 0x7e, 0xf2, 0xe0, 0xfd, 0x8f, 0x89, 0x5c, 0x4d, 0x29, 0x3b, 0x06, 0x15, + 0x3c, 0x00, 0xb3, 0x90, 0x0b, 0x66, 0x7d, 0x2e, 0x98, 0x19, 0xea, 0x7b, + 0xa7, 0x38, 0x3e, 0xbd, 0xf2, 0x99, 0x6e, 0x59, 0x2f, 0x8e, 0x58, 0xe2, + 0xbc, 0xfa, 0xbe, 0xd5, 0x7a, 0x7f, 0xce, 0x6b, 0x15, 0xfe, 0x26, 0xd7, + 0x5a, 0x5f, 0x27, 0x72, 0x5a, 0x82, 0xf5, 0x30, 0xf8, 0x8e, 0xeb, 0x3c, + 0xe6, 0x38, 0xe6, 0x9a, 0xe3, 0x88, 0x6b, 0x8e, 0x77, 0x37, 0x98, 0x23, + 0xf3, 0xf8, 0xe2, 0x69, 0xfe, 0xbf, 0xdd, 0xb9, 0xca, 0x79, 0xce, 0x0b, + 0x78, 0xb6, 0x53, 0x3a, 0x18, 0x52, 0xb2, 0xe3, 0xfb, 0xaa, 0x16, 0xdd, + 0x6b, 0xce, 0xff, 0x40, 0x8d, 0xf7, 0xcd, 0x8d, 0xab, 0xee, 0xfa, 0xe3, + 0x97, 0x28, 0x26, 0xeb, 0xc8, 0x15, 0x6d, 0x7f, 0xb5, 0x81, 0x1f, 0xfa, + 0x41, 0xa1, 0xff, 0xcc, 0xcb, 0x78, 0xd0, 0x80, 0xec, 0xbf, 0x16, 0xa0, + 0xd5, 0x72, 0x2d, 0xaf, 0x5f, 0xd5, 0xee, 0xdc, 0x1f, 0xbc, 0xb3, 0x75, + 0xbc, 0x38, 0xff, 0x88, 0xf0, 0xe5, 0xc9, 0xf8, 0x51, 0x42, 0xd5, 0x23, + 0xdb, 0x16, 0x72, 0x03, 0x0a, 0x6b, 0xf0, 0xbf, 0x36, 0xaa, 0xdd, 0xc5, + 0xb5, 0xf0, 0x03, 0x6a, 0x3b, 0xfe, 0x84, 0xe0, 0x89, 0xd2, 0x3f, 0x26, + 0xeb, 0x6f, 0x0b, 0x6b, 0x27, 0x45, 0xcd, 0x6b, 0x54, 0xd5, 0xf1, 0x26, + 0xa9, 0x43, 0xe8, 0xb9, 0xb7, 0x5f, 0x7f, 0xfb, 0x5c, 0x70, 0xe7, 0xf5, + 0xb7, 0xee, 0x6b, 0x76, 0x56, 0x7f, 0x6b, 0xf2, 0xda, 0x8d, 0x65, 0x59, + 0x7f, 0x5b, 0x1d, 0x93, 0x91, 0xfe, 0xc0, 0xa4, 0x4b, 0x7f, 0x90, 0xfa, + 0xfa, 0x6f, 0xb9, 0xf2, 0xb7, 0x65, 0x6d, 0x6d, 0xa1, 0xac, 0xb3, 0xca, + 0xda, 0x5a, 0x99, 0xef, 0xed, 0xee, 0x03, 0x23, 0x63, 0x3f, 0xf2, 0x39, + 0x9d, 0x35, 0xb1, 0x1f, 0x59, 0x53, 0x6b, 0x19, 0x8d, 0x6c, 0x38, 0xd1, + 0xe7, 0xa2, 0x8f, 0xba, 0x22, 0x8c, 0xbb, 0xed, 0x0d, 0xfa, 0x21, 0x44, + 0x1a, 0xf4, 0x43, 0x70, 0xf3, 0x7e, 0xb7, 0x8e, 0x05, 0x9d, 0x18, 0xb2, + 0x11, 0xba, 0x30, 0xfa, 0x19, 0x84, 0xe9, 0x74, 0x59, 0xf7, 0xbc, 0x8f, + 0x12, 0x4a, 0xf7, 0x3c, 0xbd, 0xa2, 0xf9, 0xd1, 0x48, 0x0d, 0x3f, 0xf2, + 0xd2, 0x45, 0x6d, 0x95, 0xe7, 0xa3, 0xe9, 0x35, 0xe5, 0xa2, 0xd7, 0x94, + 0x07, 0xbd, 0x8a, 0x67, 0x34, 0x98, 0xf7, 0xf7, 0xd5, 0x35, 0xf8, 0x4f, + 0x84, 0xd0, 0xb3, 0x85, 0x79, 0x6a, 0x50, 0xe9, 0x7f, 0x2e, 0x7a, 0x3d, + 0xc5, 0xf4, 0xaa, 0xcf, 0x63, 0xbe, 0x0d, 0x73, 0x41, 0x95, 0xce, 0x38, + 0xe8, 0x3b, 0x74, 0xf1, 0x1b, 0x22, 0x4f, 0xaa, 0xda, 0x5e, 0xd4, 0xfa, + 0xc4, 0x3e, 0x41, 0x4b, 0xd7, 0xfd, 0xc8, 0x5b, 0xd1, 0xe7, 0x4c, 0xe5, + 0x27, 0xd3, 0xb0, 0x68, 0xae, 0xd2, 0x39, 0x2a, 0xfa, 0x86, 0xc8, 0xf1, + 0x75, 0xcd, 0xed, 0x43, 0x9e, 0x9b, 0x3e, 0xaf, 0x65, 0xe6, 0xb5, 0x2a, + 0x7f, 0xc6, 0xe5, 0xaa, 0x9e, 0x83, 0xf0, 0x1d, 0x75, 0x26, 0x0c, 0x27, + 0x2e, 0x72, 0x4c, 0x7b, 0x1c, 0xf8, 0xc9, 0xa2, 0x4c, 0xfb, 0x3d, 0x09, + 0xe4, 0x33, 0xf7, 0x2c, 0x59, 0x74, 0x3c, 0x73, 0xff, 0x5d, 0x12, 0x57, + 0xce, 0x8a, 0x3e, 0x92, 0xe8, 0x67, 0x16, 0x63, 0xf9, 0x1c, 0xf5, 0x4f, + 0xd3, 0xf9, 0x62, 0x0b, 0x15, 0x58, 0xbb, 0xf7, 0x3b, 0x79, 0xe1, 0xeb, + 0x63, 0x9e, 0x94, 0x45, 0x2f, 0x51, 0x63, 0xb9, 0x99, 0xef, 0xdb, 0x4f, + 0xab, 0xb9, 0x31, 0xd1, 0x13, 0x4a, 0xf6, 0x17, 0xc1, 0x58, 0x1f, 0xf5, + 0x3a, 0x07, 0xfb, 0xa8, 0xed, 0xb3, 0x22, 0xc7, 0xb2, 0x90, 0x3d, 0x2b, + 0x3f, 0xf3, 0x0f, 0xa8, 0x67, 0xf0, 0xf3, 0x8a, 0x7f, 0x4a, 0x91, 0x5e, + 0xcb, 0x65, 0xcb, 0xb9, 0xff, 0xbc, 0xf5, 0x95, 0xa3, 0x3b, 0xd2, 0x57, + 0x52, 0x89, 0x8a, 0xbe, 0xe2, 0xbe, 0x77, 0x39, 0x07, 0xa6, 0x5f, 0xf6, + 0x7b, 0x00, 0x0c, 0xda, 0xa1, 0x8b, 0x25, 0x00, 0x4b, 0x63, 0xc6, 0x0e, + 0x45, 0xfd, 0x53, 0xb4, 0x50, 0x1c, 0x32, 0x92, 0x59, 0xe8, 0xcc, 0xfc, + 0x99, 0x8f, 0xee, 0x91, 0x3e, 0x1a, 0x7d, 0x0d, 0xf8, 0xca, 0x6e, 0x1e, + 0xff, 0x7a, 0xbf, 0xcc, 0xcb, 0x76, 0x9f, 0xef, 0xe2, 0xf3, 0x7b, 0x42, + 0xd5, 0xe7, 0x77, 0xf1, 0xf9, 0xde, 0x04, 0xf6, 0xd0, 0x58, 0x82, 0x5f, + 0xd2, 0xa1, 0x34, 0xef, 0xcd, 0x42, 0x91, 0x65, 0xeb, 0xcb, 0xcc, 0x47, + 0x57, 0xf4, 0xb8, 0x3e, 0xd4, 0xec, 0x88, 0x3d, 0x31, 0x78, 0xcc, 0xb9, + 0xcc, 0x04, 0x8f, 0x1b, 0x24, 0xff, 0xcb, 0x6c, 0x8b, 0xae, 0x68, 0x5c, + 0xd5, 0xf9, 0xf6, 0xdf, 0xe8, 0x93, 0x39, 0x55, 0xdf, 0xdd, 0x23, 0xe1, + 0xe7, 0x08, 0x9e, 0x72, 0x9e, 0xe1, 0xf2, 0xbc, 0xc0, 0x43, 0x7b, 0xda, + 0x2a, 0x3f, 0xbf, 0x13, 0x78, 0xd5, 0x8a, 0xbc, 0xd9, 0xc0, 0x12, 0xf3, + 0xc5, 0x19, 0xc7, 0x4c, 0x97, 0x73, 0xd5, 0x1e, 0x1f, 0x90, 0xd7, 0xbf, + 0xd9, 0x27, 0xfb, 0x83, 0x7e, 0x6b, 0x40, 0xf7, 0x48, 0x94, 0x32, 0x07, + 0xf9, 0xcb, 0x3e, 0x01, 0x1b, 0xff, 0x32, 0xf8, 0xa5, 0xc1, 0xdf, 0x79, + 0x3d, 0x09, 0xcc, 0xf1, 0x4a, 0x9f, 0xee, 0x17, 0x23, 0xd7, 0x15, 0xe7, + 0xf9, 0x46, 0x78, 0x5d, 0xfa, 0xfc, 0x0c, 0x1f, 0x7b, 0xed, 0x2f, 0xee, + 0xd5, 0x96, 0x90, 0xfd, 0xc5, 0xda, 0x12, 0xc9, 0x09, 0xb9, 0xcf, 0x15, + 0x9f, 0x6e, 0xa8, 0xec, 0xd3, 0x3d, 0x9f, 0xb9, 0xd5, 0x07, 0xff, 0x86, + 0xb1, 0xc4, 0xfb, 0x1d, 0x7c, 0x9e, 0xc7, 0xa2, 0x56, 0x21, 0xcd, 0x9f, + 0x1d, 0x2a, 0xaf, 0xa7, 0x1e, 0x57, 0x64, 0x9e, 0x84, 0x96, 0x5b, 0xb8, + 0xf6, 0x43, 0xbe, 0x87, 0x94, 0x5d, 0x8d, 0x9f, 0x43, 0x75, 0x79, 0x30, + 0xf5, 0x38, 0xb6, 0x99, 0x1f, 0x56, 0xc4, 0x13, 0x3d, 0xf0, 0x6c, 0xb3, + 0x7e, 0x06, 0xd7, 0x84, 0x1f, 0x2d, 0x56, 0x47, 0xaf, 0xa0, 0xe3, 0x00, + 0xfd, 0xce, 0x62, 0x8a, 0x76, 0xf1, 0x5e, 0xfd, 0xa6, 0xf1, 0x00, 0xe2, + 0xed, 0x24, 0x73, 0x9e, 0x18, 0xc6, 0x19, 0x67, 0xe2, 0x94, 0x11, 0x01, + 0xbf, 0x2c, 0x05, 0x9c, 0x0e, 0x6a, 0x66, 0x5a, 0xfd, 0x65, 0x1a, 0x65, + 0xfb, 0x0f, 0x34, 0xeb, 0x84, 0xe2, 0x04, 0x7a, 0xb3, 0xcd, 0x43, 0xac, + 0x13, 0xc7, 0x8a, 0xc0, 0x67, 0x83, 0x3e, 0x9f, 0x23, 0xfa, 0x5c, 0x6e, + 0xd4, 0xfc, 0x26, 0x39, 0x56, 0xe5, 0x77, 0xdb, 0x8c, 0xf2, 0x3c, 0xe2, + 0xc5, 0x2f, 0xd3, 0xfb, 0xa2, 0xcf, 0x09, 0xe0, 0xa8, 0xf7, 0xfd, 0x4b, + 0x74, 0x32, 0x81, 0x79, 0x6f, 0x9f, 0x3e, 0x8f, 0xef, 0x88, 0x3e, 0xdb, + 0x3c, 0xe8, 0xf3, 0xc5, 0x7e, 0x89, 0x37, 0x25, 0xc6, 0xd1, 0x36, 0x9a, + 0xcb, 0x22, 0x07, 0xec, 0xd3, 0xe8, 0x3b, 0x95, 0x4d, 0x32, 0x5f, 0x4a, + 0x56, 0xf8, 0xd2, 0x85, 0x28, 0x1b, 0xc3, 0x4c, 0xe3, 0xe8, 0xcb, 0xa6, + 0xf2, 0x7e, 0xb0, 0x8e, 0x01, 0x1a, 0x5d, 0x6e, 0xe7, 0x6b, 0x69, 0x3d, + 0x3a, 0x15, 0x51, 0xb5, 0xfe, 0xb6, 0x15, 0x63, 0xfe, 0x78, 0x9e, 0x69, + 0x39, 0x9d, 0xbd, 0x97, 0x0a, 0xc1, 0x21, 0x1a, 0x59, 0xd6, 0xfd, 0x4d, + 0x44, 0xce, 0xc6, 0xa0, 0xe4, 0x49, 0x7a, 0xdd, 0x9f, 0x10, 0xbe, 0x0b, + 0xeb, 0xd2, 0xc7, 0xb5, 0xee, 0xf6, 0x2d, 0xf8, 0xd2, 0x25, 0x45, 0xb3, + 0xa5, 0xcb, 0xd1, 0x30, 0xa5, 0xa2, 0x53, 0xaf, 0xf4, 0x03, 0xff, 0x47, + 0x2e, 0xc1, 0x0f, 0x07, 0x1e, 0x6d, 0x51, 0x22, 0x53, 0x0b, 0x8b, 0x21, + 0x5e, 0x37, 0x7e, 0x2f, 0x7d, 0x30, 0x17, 0x7e, 0x40, 0xc8, 0xfe, 0xd1, + 0x4b, 0x3c, 0x4e, 0xca, 0x26, 0xc5, 0x37, 0xbc, 0xf0, 0x50, 0xf7, 0xc5, + 0xd4, 0xb8, 0x28, 0x73, 0x3d, 0x59, 0x7f, 0x33, 0x13, 0xfe, 0x5a, 0x9c, + 0xbc, 0xe6, 0x3b, 0xba, 0x68, 0xd1, 0xb1, 0x8c, 0xfd, 0xf5, 0x14, 0x4d, + 0x31, 0x5d, 0xbb, 0xe5, 0x05, 0x8f, 0x27, 0xe0, 0xd9, 0x34, 0xd3, 0x3e, + 0xdb, 0xcd, 0x59, 0x4b, 0xe6, 0xdd, 0x89, 0xde, 0x73, 0x38, 0x46, 0xdd, + 0xf1, 0x5f, 0xf5, 0x6b, 0x79, 0x90, 0xcc, 0xa2, 0x8e, 0x90, 0x3f, 0xf3, + 0x3c, 0x1e, 0xb9, 0xff, 0x39, 0xdc, 0x07, 0xf2, 0x0e, 0x73, 0xe7, 0xe3, + 0x55, 0xb9, 0xaf, 0x23, 0x7c, 0x6f, 0xd4, 0xdd, 0x1f, 0x2b, 0x4e, 0xf2, + 0xfe, 0x76, 0x09, 0xde, 0x2c, 0xf7, 0x73, 0x9a, 0xce, 0x79, 0xf2, 0x15, + 0xb9, 0x2f, 0x49, 0x17, 0x7d, 0x27, 0x05, 0x7d, 0x4f, 0x8b, 0xfd, 0x48, + 0xe6, 0x0c, 0xd6, 0xd7, 0xb4, 0xef, 0x81, 0xed, 0xec, 0x5c, 0x40, 0xe7, + 0x06, 0xf2, 0xf7, 0x0f, 0xfb, 0x45, 0x5e, 0x22, 0xec, 0xef, 0x1c, 0x3e, + 0xa7, 0xe9, 0x79, 0x96, 0xeb, 0x2f, 0x64, 0x5a, 0xe8, 0x6a, 0xb6, 0x85, + 0xde, 0xc9, 0x0e, 0xd1, 0x95, 0xc5, 0x6e, 0x3a, 0xc7, 0x3a, 0xf3, 0x39, + 0x27, 0x60, 0xa5, 0xa9, 0x1b, 0xf1, 0x45, 0xe4, 0x0c, 0x31, 0xdd, 0x61, + 0x3c, 0xf4, 0xbf, 0xe8, 0x5e, 0xc6, 0x39, 0xd6, 0xbd, 0x5b, 0xe9, 0x3d, + 0x7e, 0x66, 0x3a, 0xa3, 0x73, 0x1d, 0xe0, 0x93, 0x1f, 0x2b, 0xeb, 0xaf, + 0x5b, 0xe3, 0x88, 0xb9, 0x05, 0x8e, 0x4c, 0x8b, 0xf8, 0xd6, 0xc2, 0x22, + 0xff, 0xbe, 0x08, 0xff, 0x39, 0xc3, 0x9b, 0xf9, 0xf3, 0x93, 0x01, 0x8c, + 0xc7, 0x39, 0x47, 0xe6, 0x4a, 0x8a, 0xb5, 0x85, 0xf8, 0xd8, 0x27, 0x6a, + 0xa4, 0x25, 0x1c, 0x5a, 0x79, 0x7d, 0x3e, 0x31, 0x3e, 0xb9, 0xda, 0x4a, + 0xf3, 0x39, 0xd6, 0x41, 0x72, 0x7e, 0xb6, 0x61, 0x30, 0xf6, 0xef, 0x54, + 0x6f, 0x61, 0xdc, 0xbf, 0x8b, 0xd2, 0x62, 0x1c, 0x7f, 0xae, 0x76, 0xd1, + 0x42, 0xae, 0x43, 0x1d, 0xdf, 0x2b, 0x72, 0xdc, 0x65, 0x1f, 0x23, 0xfc, + 0xb6, 0x19, 0x7f, 0x7b, 0x97, 0x71, 0x0a, 0x32, 0x55, 0xda, 0xa5, 0xe0, + 0x35, 0x97, 0xeb, 0x7a, 0x22, 0x03, 0xe7, 0xa6, 0xe8, 0x25, 0x96, 0xb7, + 0x23, 0x2f, 0xc3, 0x7f, 0xfc, 0x38, 0xf0, 0x26, 0x9f, 0xa2, 0x41, 0x3e, + 0x46, 0x5f, 0x24, 0xbf, 0xa8, 0x73, 0x8a, 0x05, 0x27, 0x44, 0x6d, 0x88, + 0xa4, 0xd1, 0x59, 0xd1, 0x8b, 0xee, 0x2d, 0xc1, 0x9b, 0xec, 0x94, 0x65, + 0x40, 0x1f, 0x81, 0x0f, 0x46, 0xe6, 0x60, 0x1d, 0x77, 0x7a, 0xde, 0xed, + 0x9b, 0x19, 0xa7, 0x48, 0x3f, 0xf0, 0x5e, 0xd2, 0xac, 0xea, 0x2f, 0x20, + 0xf8, 0xbd, 0xb9, 0x4f, 0xd7, 0x4b, 0xea, 0x63, 0x2d, 0x2b, 0xf4, 0x71, + 0x47, 0xcd, 0xef, 0x66, 0xcd, 0xef, 0xe5, 0x7c, 0x39, 0x96, 0x79, 0x2c, + 0xe7, 0x49, 0xf6, 0x28, 0x4a, 0x2e, 0x4b, 0xfc, 0x33, 0xf7, 0x8d, 0x99, + 0x8f, 0x2a, 0x1d, 0x3c, 0xb9, 0x36, 0x1a, 0xea, 0x31, 0x26, 0x8c, 0xe4, + 0xe4, 0x3f, 0x96, 0x22, 0x09, 0xe8, 0x45, 0x4f, 0xee, 0x51, 0xf9, 0xa7, + 0x3c, 0xaf, 0x54, 0x18, 0xaa, 0xdb, 0xec, 0x5a, 0x07, 0xad, 0x8b, 0x9e, + 0x5c, 0x42, 0xc7, 0xe0, 0xeb, 0x71, 0x9f, 0x94, 0xd9, 0x44, 0xe8, 0x73, + 0x0e, 0x1a, 0xdf, 0x1f, 0xba, 0xc4, 0xfb, 0x19, 0x5f, 0xfb, 0x69, 0xe9, + 0xa4, 0xe8, 0x71, 0x83, 0xb1, 0x5d, 0x34, 0x27, 0x74, 0x7e, 0xd6, 0x5f, + 0xaa, 0xec, 0xaa, 0x29, 0xcc, 0x33, 0x85, 0xd8, 0x8a, 0xe1, 0xfc, 0xbe, + 0x2f, 0x99, 0x97, 0xb1, 0xf2, 0x78, 0x4d, 0xac, 0x7c, 0x56, 0xc4, 0xca, + 0x11, 0x27, 0x07, 0x5c, 0x01, 0x4b, 0xaf, 0x9c, 0x16, 0xec, 0x63, 0x98, + 0x90, 0x1b, 0x7e, 0xee, 0xa2, 0xe0, 0x37, 0xe1, 0x98, 0x5f, 0xe6, 0x57, + 0xc7, 0x79, 0xc6, 0x06, 0x5d, 0x60, 0x7c, 0xb0, 0x27, 0x36, 0x58, 0x97, + 0x58, 0xc9, 0x7e, 0x99, 0xae, 0xe4, 0x9b, 0x58, 0xd7, 0x5b, 0xa0, 0x8d, + 0x3c, 0xb1, 0x4e, 0xd8, 0x4d, 0x0b, 0x61, 0xc6, 0xb1, 0x89, 0x36, 0xde, + 0x4f, 0xd6, 0x6b, 0x27, 0x98, 0xee, 0x78, 0xee, 0x2b, 0xb9, 0xd2, 0x8f, + 0xd2, 0xe1, 0x88, 0x15, 0x9d, 0xea, 0x60, 0xbb, 0xc5, 0xe4, 0x7f, 0x87, + 0xff, 0x77, 0x85, 0x00, 0x93, 0xc2, 0x2a, 0x7e, 0x67, 0x9d, 0x27, 0x53, + 0xfa, 0xd1, 0x1c, 0x8f, 0x99, 0x9b, 0x82, 0xfd, 0x03, 0x3b, 0xcf, 0xe1, + 0x7f, 0x39, 0x66, 0x65, 0x95, 0xf1, 0xfb, 0x62, 0x2a, 0x64, 0x08, 0xde, + 0xbe, 0xce, 0x3c, 0xfe, 0x02, 0xcd, 0xf1, 0x1c, 0xae, 0x10, 0xae, 0xb5, + 0x28, 0x19, 0xde, 0xc7, 0x78, 0xdf, 0xcd, 0x9f, 0xa8, 0xbf, 0x6a, 0xa7, + 0x85, 0xc9, 0x31, 0x55, 0x7f, 0xf5, 0xbd, 0x06, 0xf5, 0x57, 0xb8, 0x8e, + 0xe5, 0xfe, 0x62, 0xe9, 0xe6, 0x5c, 0xd8, 0xfd, 0x3c, 0x32, 0x92, 0xe1, + 0x4e, 0xa1, 0x23, 0xad, 0xac, 0xfa, 0xf8, 0xd9, 0x11, 0x2b, 0x39, 0xc5, + 0x73, 0xcc, 0xb9, 0xe7, 0x5d, 0xba, 0x19, 0x0b, 0x63, 0x9c, 0xbf, 0x66, + 0x1c, 0xdb, 0xca, 0x53, 0x72, 0x3d, 0x85, 0x5c, 0xe9, 0xe7, 0xd1, 0xb0, + 0x5e, 0x9f, 0xfb, 0x5a, 0xac, 0x03, 0xf4, 0xc4, 0x9f, 0x2b, 0x5d, 0xbe, + 0x2b, 0x59, 0xd8, 0xdf, 0x06, 0xe3, 0x39, 0x66, 0x34, 0x44, 0xa9, 0x15, + 0xa6, 0xef, 0x8b, 0x1d, 0xbe, 0x8d, 0xec, 0x95, 0x52, 0xb2, 0x2a, 0x97, + 0xa5, 0xda, 0xef, 0x2e, 0x6d, 0xae, 0x21, 0x72, 0x96, 0x20, 0x33, 0x21, + 0x2f, 0x53, 0x25, 0xbf, 0x03, 0xfd, 0x0e, 0xb6, 0xd0, 0x59, 0xe6, 0x57, + 0x32, 0x1f, 0x89, 0x79, 0x27, 0xf3, 0x2c, 0x49, 0x2f, 0xf1, 0xaa, 0xd7, + 0x0d, 0x48, 0x9c, 0x1d, 0xa9, 0xe4, 0x41, 0xba, 0xe2, 0xe9, 0x01, 0x57, + 0x3c, 0xdd, 0x74, 0xe5, 0x41, 0x06, 0x85, 0x3e, 0x56, 0xd1, 0xa1, 0x82, + 0x4a, 0x87, 0x82, 0xae, 0x25, 0x79, 0x59, 0xa1, 0xcc, 0xcb, 0x76, 0x6f, + 0xc1, 0xcb, 0xbc, 0x6c, 0xd3, 0x75, 0xc5, 0x37, 0xec, 0x30, 0xe4, 0xfc, + 0xe5, 0xe2, 0x34, 0xbd, 0xcd, 0x3c, 0xe2, 0xad, 0x62, 0x98, 0xf9, 0xc6, + 0x24, 0xf3, 0x8d, 0x09, 0xe6, 0x1b, 0x0e, 0xc3, 0xc0, 0xe2, 0xb5, 0x5f, + 0xf3, 0x5d, 0x59, 0x84, 0xbc, 0x98, 0xa2, 0xe7, 0x8b, 0xe0, 0xc1, 0x93, + 0xac, 0xf3, 0x5c, 0xf3, 0x6d, 0x2c, 0x76, 0x31, 0xbe, 0x4a, 0x3d, 0xa7, + 0xda, 0x8e, 0x41, 0xaf, 0x15, 0xf8, 0x87, 0xaf, 0x82, 0xcf, 0xbc, 0x91, + 0xa2, 0x4e, 0x86, 0x3d, 0xe0, 0xbc, 0x8e, 0xde, 0x14, 0xaf, 0x81, 0x96, + 0xd1, 0x13, 0xf8, 0xbb, 0xe3, 0x53, 0x3c, 0xf7, 0x4e, 0xdf, 0x02, 0xef, + 0xcb, 0xd3, 0xe1, 0x94, 0xd9, 0xcb, 0x38, 0x7f, 0xac, 0x82, 0xf3, 0xa9, + 0x34, 0xaf, 0xa0, 0x67, 0xb9, 0x9b, 0xc6, 0x0e, 0x44, 0xf7, 0xf6, 0x30, + 0x9d, 0x22, 0x37, 0xa2, 0xd2, 0xa7, 0xc7, 0x4f, 0x27, 0x83, 0x6d, 0xaa, + 0xbf, 0x8f, 0xc5, 0xf2, 0xf1, 0x03, 0xbe, 0xcf, 0x2d, 0x5f, 0x3a, 0xfb, + 0x2a, 0x3f, 0x03, 0xc7, 0x5f, 0x85, 0xff, 0x93, 0xed, 0x83, 0x56, 0xe1, + 0x3f, 0x2a, 0x88, 0xb1, 0x38, 0xb6, 0x27, 0x98, 0x97, 0x85, 0xd7, 0x0d, + 0x7b, 0x3a, 0x62, 0x30, 0xd1, 0x75, 0x99, 0xbc, 0xde, 0xd2, 0xa0, 0x8c, + 0xc1, 0xed, 0xdd, 0x2b, 0xf9, 0x06, 0xe3, 0x66, 0x30, 0x22, 0x6c, 0xb4, + 0xa6, 0x25, 0x29, 0x27, 0x0b, 0xbc, 0xcf, 0x2b, 0xe1, 0x09, 0xde, 0xe7, + 0x0e, 0x25, 0x23, 0x53, 0xfc, 0xbb, 0x90, 0xbf, 0x2c, 0x2b, 0x87, 0xd0, + 0xb3, 0xda, 0x14, 0xfd, 0x20, 0x66, 0xd1, 0x6f, 0xa7, 0x83, 0xef, 0x6b, + 0x33, 0xd6, 0x82, 0x4f, 0x7c, 0xe0, 0x4b, 0x66, 0xf1, 0x5c, 0xe0, 0x21, + 0x7f, 0xcf, 0x4f, 0xd1, 0x85, 0x8c, 0x9e, 0xc3, 0x80, 0x61, 0xbc, 0x84, + 0x79, 0xf8, 0x68, 0xb7, 0xf3, 0x43, 0x86, 0x17, 0x1f, 0xff, 0x71, 0xed, + 0x9c, 0x86, 0xd5, 0x9c, 0xd0, 0xd3, 0xb2, 0x05, 0x3d, 0x7c, 0x08, 0xbd, + 0x8f, 0x0a, 0xa2, 0xe7, 0x64, 0xb3, 0xb0, 0x4d, 0x0b, 0xc2, 0xc6, 0x28, + 0x85, 0x2a, 0x7d, 0x30, 0xef, 0xa9, 0x39, 0xf7, 0x13, 0x5f, 0x7a, 0xf1, + 0xa0, 0xd0, 0xc5, 0x46, 0x0e, 0xec, 0x55, 0xf5, 0xa7, 0x5d, 0xe2, 0xbe, + 0xc6, 0x32, 0x7e, 0x7b, 0x50, 0xfd, 0xf6, 0x49, 0xa1, 0x03, 0x23, 0x2f, + 0x2e, 0xb0, 0x24, 0xf0, 0x9c, 0xf7, 0xd7, 0x99, 0x60, 0x3c, 0x0f, 0xad, + 0xc0, 0x77, 0x2f, 0xe0, 0xa9, 0xe1, 0x01, 0x58, 0x00, 0xf7, 0x3b, 0x14, + 0xde, 0xdb, 0x56, 0xdc, 0xaf, 0xd7, 0xdd, 0x08, 0xce, 0xac, 0xd3, 0x64, + 0xb0, 0x56, 0xac, 0x69, 0x8f, 0x2f, 0x92, 0xb7, 0x8c, 0xf4, 0x22, 0x6c, + 0x1a, 0xd4, 0xb5, 0xdc, 0x85, 0xbc, 0x29, 0x9e, 0xc3, 0x1e, 0x8a, 0x24, + 0x30, 0x2f, 0x8c, 0xd3, 0x30, 0xf8, 0xb7, 0x1a, 0x58, 0xb8, 0xaf, 0xeb, + 0x56, 0xd7, 0xb5, 0x8a, 0xbd, 0x20, 0x03, 0xcf, 0xd1, 0xcf, 0xc6, 0x73, + 0xf1, 0x7c, 0x5c, 0x87, 0xfb, 0xc9, 0xfb, 0xf6, 0x31, 0x7f, 0x8e, 0x4e, + 0xc9, 0x7b, 0x19, 0x97, 0xe4, 0x6f, 0x7d, 0x8e, 0xf7, 0x7c, 0xe5, 0xfe, + 0xf9, 0x54, 0xbf, 0x1e, 0xec, 0x5f, 0x37, 0xe5, 0x85, 0x8f, 0x13, 0xbf, + 0x75, 0x8a, 0xdf, 0xa2, 0x4e, 0xa7, 0xd8, 0xd7, 0xf3, 0x7c, 0x3c, 0x9f, + 0xed, 0xf2, 0xc1, 0x36, 0x4f, 0x27, 0x3a, 0x7d, 0xf9, 0x3c, 0xd6, 0xdb, + 0xe9, 0x8b, 0x33, 0xee, 0xc7, 0xb2, 0xf1, 0xd2, 0x82, 0xe0, 0x31, 0xac, + 0xd3, 0xf6, 0xda, 0xe6, 0x49, 0xe3, 0x4f, 0x86, 0x64, 0x6f, 0x5b, 0x7c, + 0x67, 0xfa, 0xcb, 0x30, 0xfd, 0x65, 0x98, 0xfe, 0x32, 0x4c, 0x7f, 0x19, + 0xa6, 0x3f, 0xb6, 0x4b, 0xdf, 0x64, 0x99, 0xf1, 0x6d, 0x96, 0x19, 0x92, + 0x66, 0x23, 0xca, 0x8f, 0xa9, 0x69, 0xb6, 0xb6, 0x3e, 0x53, 0xd3, 0x28, + 0xe4, 0x34, 0xf9, 0x0e, 0x8f, 0x57, 0xd3, 0xea, 0x55, 0xa6, 0xd5, 0xa6, + 0x99, 0x7e, 0xba, 0x91, 0xc3, 0x9e, 0xd9, 0xd6, 0x79, 0xe6, 0xd1, 0x71, + 0x3f, 0x74, 0xaa, 0x00, 0xd3, 0x13, 0x74, 0x4a, 0x9b, 0xe1, 0xde, 0x4f, + 0x37, 0x99, 0x4f, 0xdf, 0xc8, 0x81, 0x76, 0xef, 0x52, 0xc7, 0x19, 0xa6, + 0x5d, 0xc8, 0xb9, 0x25, 0xdf, 0xd5, 0xac, 0xc1, 0xba, 0x57, 0xc0, 0x4c, + 0x12, 0xf8, 0xa8, 0xd0, 0xc7, 0x78, 0xdf, 0xd7, 0x99, 0xdf, 0xc3, 0x57, + 0x87, 0xbe, 0x5f, 0x79, 0x1f, 0xcb, 0x89, 0xd0, 0x15, 0xe6, 0xa3, 0xa7, + 0x73, 0x4b, 0x4c, 0xef, 0xbd, 0xf4, 0x85, 0x1c, 0xe4, 0x31, 0x60, 0xc4, + 0xc7, 0x79, 0x12, 0x3e, 0x30, 0x63, 0x06, 0x6b, 0x1f, 0x4b, 0x19, 0x02, + 0x4f, 0x9e, 0x01, 0x1c, 0x18, 0xf6, 0x67, 0xf6, 0xa2, 0x67, 0x7d, 0xc4, + 0x68, 0x56, 0x3e, 0x45, 0x7c, 0xc7, 0x78, 0x8c, 0x05, 0xdc, 0x70, 0xdc, + 0x28, 0xfe, 0x88, 0xf7, 0x42, 0x84, 0x19, 0x1e, 0xb5, 0x7c, 0xeb, 0x02, + 0x7a, 0x91, 0x02, 0x5e, 0xd3, 0x51, 0x3f, 0x6a, 0xc5, 0xe9, 0x39, 0xbc, + 0xff, 0xe0, 0x85, 0x22, 0xe6, 0xbd, 0x48, 0x0b, 0x41, 0xf0, 0x21, 0x3b, + 0x7c, 0x9d, 0x24, 0xec, 0x5a, 0x59, 0xbf, 0xfc, 0xbc, 0x37, 0x6f, 0xb3, + 0xa2, 0x42, 0x1f, 0x6e, 0x61, 0xfb, 0x06, 0xb0, 0x79, 0x8b, 0x71, 0x2d, + 0x0c, 0x9b, 0x5f, 0xf1, 0xb5, 0x37, 0x99, 0xe7, 0x60, 0xcf, 0x3a, 0x85, + 0x8c, 0xf1, 0xe2, 0x65, 0x1b, 0x8a, 0x97, 0x39, 0x2e, 0x5e, 0x96, 0x2e, + 0xf3, 0x32, 0xc6, 0x09, 0xc1, 0xc3, 0xc0, 0xa3, 0x66, 0x59, 0x4f, 0x94, + 0xdf, 0xa1, 0xff, 0xed, 0x16, 0x3c, 0x8b, 0x79, 0x3d, 0xdb, 0x0d, 0x85, + 0x62, 0xca, 0x77, 0x48, 0xf0, 0x0e, 0x8d, 0xd7, 0xff, 0xa3, 0xe8, 0xa1, + 0x55, 0xf0, 0x81, 0xf4, 0x2c, 0xf8, 0x95, 0xd7, 0xf8, 0xff, 0x02, 0x6c, + 0x79, 0xbc, 0x13, 0x7a, 0x8d, 0xf9, 0x58, 0x21, 0x0c, 0x9b, 0xb5, 0x43, + 0xd9, 0x36, 0xe8, 0xbb, 0xb5, 0x07, 0xb9, 0x96, 0x56, 0xb4, 0xcc, 0xc7, + 0x76, 0x2b, 0xbf, 0x05, 0xfc, 0x8c, 0xd8, 0xeb, 0x3a, 0x5d, 0xc0, 0x82, + 0x2e, 0xc0, 0x63, 0x03, 0x0c, 0x1f, 0xd1, 0x1b, 0x9c, 0xe8, 0x16, 0xc3, + 0x01, 0xfb, 0x7c, 0x0b, 0xfb, 0xcc, 0xba, 0x2c, 0x05, 0xe6, 0xa6, 0x02, + 0x03, 0x98, 0xdf, 0xc2, 0x6a, 0x85, 0x1f, 0x9e, 0xcf, 0x0c, 0x18, 0x85, + 0xac, 0x9c, 0xe3, 0xca, 0xb8, 0xe4, 0x79, 0x85, 0x3c, 0x7a, 0x7b, 0x89, + 0xb9, 0xf2, 0x1c, 0xf5, 0xfa, 0x04, 0xff, 0x52, 0x74, 0xbf, 0x1d, 0x5a, + 0x4b, 0x30, 0x5d, 0x61, 0x4f, 0x52, 0x2e, 0x9c, 0x79, 0x94, 0x9f, 0x8f, + 0x73, 0x8d, 0xd7, 0x71, 0xb3, 0xbc, 0x8e, 0x08, 0xaf, 0x03, 0x63, 0x6f, + 0xf9, 0x6e, 0xa8, 0x75, 0xdc, 0x28, 0xaf, 0x63, 0x56, 0xad, 0x83, 0xd2, + 0xc6, 0xcc, 0x6e, 0xa5, 0xc7, 0x6f, 0x79, 0xcf, 0xd6, 0x28, 0xeb, 0x27, + 0xe9, 0x55, 0xc0, 0xf3, 0x1e, 0x85, 0x2f, 0x6e, 0x7f, 0xa8, 0x7b, 0x6e, + 0xf6, 0xc4, 0x75, 0xfa, 0x5d, 0xba, 0x29, 0xf4, 0x93, 0x61, 0xd6, 0x4f, + 0x70, 0x9e, 0x16, 0xc0, 0x87, 0xd3, 0x41, 0xf4, 0x9b, 0x1d, 0x64, 0x98, + 0xb1, 0x5d, 0x35, 0xc5, 0x9f, 0xc2, 0x4f, 0x86, 0xfb, 0xe8, 0xeb, 0xbf, + 0x48, 0x37, 0x17, 0xc1, 0xab, 0xa1, 0x8f, 0xca, 0x9e, 0xb4, 0x37, 0xd7, + 0xa4, 0x9f, 0x36, 0xee, 0xe9, 0xa7, 0x85, 0x8f, 0x36, 0x0c, 0x7d, 0xdd, + 0x84, 0x3f, 0x37, 0x26, 0xde, 0x67, 0xc1, 0xc7, 0x45, 0xdc, 0xcb, 0x8b, + 0xef, 0x4c, 0xbb, 0x72, 0xdc, 0x90, 0x73, 0x92, 0x62, 0x3e, 0xe2, 0x98, + 0x4d, 0x86, 0xac, 0x9d, 0xb9, 0x5c, 0xd4, 0x3a, 0x51, 0x9c, 0xf7, 0xc8, + 0x09, 0x1b, 0x46, 0x44, 0xf8, 0x0c, 0x5a, 0x9d, 0x0e, 0x6a, 0x61, 0x39, + 0x79, 0x8a, 0xd0, 0x13, 0xcd, 0xb6, 0xe0, 0xcb, 0xbf, 0xc0, 0xb8, 0xb7, + 0x10, 0xb6, 0x43, 0x9f, 0x13, 0xf6, 0x25, 0xe4, 0x07, 0xde, 0xa7, 0x02, + 0x18, 0x63, 0x0e, 0xfc, 0x7d, 0x15, 0xfd, 0x30, 0xc3, 0xbc, 0x7e, 0xf8, + 0x81, 0x47, 0xad, 0x77, 0x58, 0xee, 0x5c, 0x10, 0xfe, 0x95, 0xb3, 0x94, + 0x66, 0x3a, 0x3c, 0x2c, 0xe8, 0xd0, 0x18, 0x66, 0x6a, 0x61, 0xfa, 0x41, + 0x8e, 0xc1, 0x98, 0xe8, 0xbf, 0x23, 0x6d, 0x16, 0x5e, 0xe5, 0x9a, 0xea, + 0x6b, 0x90, 0x00, 0x6f, 0xd8, 0xbe, 0x6f, 0x21, 0xf1, 0x91, 0x7d, 0x2a, + 0x6e, 0x5d, 0xab, 0xd6, 0x87, 0x0d, 0xfb, 0xcc, 0x12, 0x7d, 0x1f, 0x01, + 0x3b, 0xe1, 0x17, 0x34, 0x26, 0x19, 0x6e, 0xfa, 0xdd, 0x35, 0x6e, 0xfb, + 0xff, 0x29, 0x51, 0x9f, 0xff, 0x46, 0x51, 0xca, 0xd8, 0x34, 0xdb, 0xe6, + 0x0b, 0x07, 0xdc, 0x3a, 0x87, 0x9d, 0x8d, 0x09, 0x9f, 0xcc, 0x00, 0x45, + 0x97, 0x27, 0xe9, 0xb1, 0x0c, 0x78, 0x14, 0x5d, 0x8f, 0x3a, 0x78, 0xc3, + 0x06, 0x68, 0x79, 0x92, 0xe2, 0x45, 0xc0, 0xc8, 0x47, 0x0b, 0x2c, 0x05, + 0xd2, 0x59, 0xc4, 0xee, 0xf9, 0x7b, 0x1e, 0xef, 0x57, 0xf9, 0x15, 0xe5, + 0xf7, 0x1e, 0xa2, 0xd8, 0x32, 0xa5, 0x92, 0xe1, 0x87, 0x45, 0xcf, 0xea, + 0x64, 0x78, 0x5c, 0xf9, 0x68, 0x42, 0x7c, 0x1e, 0x7e, 0x2f, 0x8b, 0x1e, + 0xcd, 0xd8, 0xa9, 0x24, 0x49, 0xdf, 0x03, 0xf1, 0x1c, 0x0c, 0x96, 0xad, + 0xbb, 0x99, 0x57, 0x1c, 0x17, 0xfe, 0x07, 0xd6, 0x44, 0x16, 0x31, 0x1e, + 0xbe, 0x83, 0x5e, 0x82, 0xbd, 0x95, 0xcc, 0x3e, 0xa0, 0xc6, 0x96, 0xc8, + 0x64, 0x5c, 0x30, 0x7f, 0xc9, 0x49, 0x85, 0x8d, 0xca, 0xf5, 0xf0, 0x5d, + 0x1c, 0x17, 0xfa, 0xe1, 0x30, 0xdb, 0x30, 0x62, 0x5c, 0x69, 0x4e, 0xf8, + 0x21, 0xf8, 0x38, 0xff, 0xd3, 0x01, 0xfd, 0x6e, 0x03, 0x9c, 0x97, 0xfe, + 0x09, 0xbe, 0x67, 0x9e, 0xe7, 0x51, 0x95, 0x17, 0x3f, 0x44, 0x91, 0x1d, + 0xf8, 0x8b, 0x66, 0xef, 0xa8, 0xbf, 0x88, 0x61, 0xcd, 0xb2, 0xe5, 0x32, + 0xd3, 0xc6, 0xdb, 0x5b, 0xda, 0x71, 0xef, 0x6b, 0x19, 0xcd, 0xb0, 0x32, + 0xc5, 0xfb, 0x2f, 0xd0, 0xeb, 0x73, 0xa1, 0xf8, 0x29, 0xbc, 0x47, 0xc6, + 0x97, 0x10, 0x3a, 0x6f, 0x88, 0x75, 0x17, 0xe8, 0x30, 0xa3, 0x22, 0xbe, + 0x15, 0x79, 0xc2, 0x32, 0x16, 0xd6, 0xfa, 0xc9, 0x0f, 0xbf, 0x9a, 0xa3, + 0x73, 0x22, 0x5a, 0x45, 0xfe, 0xba, 0x8c, 0x2b, 0x42, 0xfe, 0x82, 0x07, + 0xfe, 0xc4, 0x97, 0x5c, 0xf3, 0xf7, 0xe9, 0x7c, 0xb7, 0x48, 0xb0, 0x9c, + 0x4f, 0xa3, 0x78, 0x8a, 0xc6, 0x3d, 0x1d, 0xb3, 0x70, 0xbf, 0xd7, 0x0a, + 0xb4, 0xeb, 0xd6, 0x19, 0xe0, 0x67, 0x12, 0x7b, 0x74, 0x01, 0x71, 0x5c, + 0xa3, 0x2a, 0x1e, 0xd1, 0xc2, 0xfb, 0x04, 0x3b, 0x0f, 0xfe, 0xbb, 0xcf, + 0xf2, 0x27, 0xe2, 0x0a, 0x27, 0x07, 0xa1, 0x27, 0xf5, 0x38, 0x8c, 0x33, + 0x53, 0x38, 0xee, 0x67, 0xbb, 0x4b, 0xeb, 0xb5, 0xd2, 0xa7, 0xc4, 0xb6, + 0x98, 0xda, 0x2f, 0xf8, 0x93, 0x46, 0x54, 0xbf, 0x01, 0x9b, 0xac, 0x5e, + 0xc0, 0xe9, 0xe3, 0xa2, 0xc7, 0xad, 0x62, 0x10, 0xdb, 0xc9, 0x59, 0xc2, + 0x3b, 0xb7, 0xd0, 0x77, 0xf3, 0x6e, 0xc0, 0x9e, 0xf7, 0xc8, 0x1d, 0xa3, + 0xf8, 0x94, 0x7a, 0xff, 0xcf, 0x9d, 0xda, 0xb7, 0x5d, 0x1e, 0xfb, 0xf6, + 0xbd, 0x41, 0x19, 0x03, 0xbb, 0x4b, 0x8d, 0xf1, 0xca, 0x53, 0xfd, 0xfb, + 0xa7, 0xe1, 0x4f, 0xaa, 0xd4, 0x51, 0x5c, 0x13, 0x7c, 0xa5, 0xde, 0xa7, + 0x1d, 0x62, 0x7e, 0x2a, 0xe9, 0xf8, 0xb8, 0x07, 0x1d, 0xf7, 0xce, 0x40, + 0x2f, 0xb9, 0x7d, 0x3a, 0x3e, 0xd6, 0x90, 0x8e, 0xff, 0x75, 0x50, 0xfa, + 0x54, 0xeb, 0xe9, 0x18, 0xb5, 0x3c, 0xc7, 0x8b, 0x8d, 0xfc, 0x57, 0xd8, + 0x07, 0xd4, 0xa4, 0xc3, 0xe7, 0x01, 0x58, 0x69, 0xbf, 0x07, 0xe2, 0x7e, + 0xc0, 0x47, 0xc4, 0x4e, 0xfe, 0x90, 0xe2, 0x8b, 0xb5, 0xb1, 0xd0, 0xcd, + 0xae, 0xf9, 0x96, 0xc7, 0x35, 0xd0, 0xc5, 0x41, 0x0b, 0x76, 0x48, 0xda, + 0xf4, 0x1a, 0x5e, 0xef, 0xf9, 0x0e, 0xe5, 0xec, 0x54, 0x9e, 0xe0, 0xa3, + 0x0e, 0xd2, 0x53, 0x88, 0x2b, 0x2b, 0x1f, 0xf0, 0xd1, 0x8c, 0x5c, 0xb7, + 0x79, 0x40, 0xe0, 0x03, 0xf4, 0xd5, 0x50, 0xc2, 0x9f, 0xe0, 0x3d, 0x95, + 0xfe, 0xdf, 0xe4, 0x6a, 0x48, 0xed, 0x13, 0x8f, 0xc5, 0xfd, 0x3c, 0xeb, + 0xfc, 0xb0, 0x3f, 0xf6, 0xd7, 0xd7, 0xcb, 0x79, 0xc5, 0x90, 0x05, 0x25, + 0xfa, 0x0f, 0x96, 0x73, 0xfe, 0x03, 0xa6, 0xe8, 0xb9, 0x70, 0xb9, 0x78, + 0x80, 0xf5, 0x47, 0xec, 0x21, 0x7c, 0x87, 0xda, 0xb7, 0xfb, 0xf6, 0x30, + 0x75, 0xed, 0x67, 0xa9, 0x6f, 0x90, 0xc3, 0x7a, 0xa3, 0x71, 0x00, 0xf9, + 0xe1, 0x16, 0x5f, 0x83, 0x5e, 0x51, 0x63, 0x56, 0x9c, 0x3a, 0xe0, 0x4f, + 0x40, 0x0f, 0x68, 0x2b, 0x5d, 0x45, 0x53, 0xb3, 0x82, 0xa6, 0xe2, 0x6b, + 0xb3, 0x8a, 0xa6, 0x66, 0x95, 0xff, 0x7c, 0x56, 0xd1, 0xd4, 0xac, 0xa2, + 0xa9, 0x59, 0x45, 0x53, 0xb3, 0x8c, 0xd7, 0xa3, 0xac, 0xaf, 0x42, 0xf7, + 0xd0, 0xfe, 0xcb, 0x2e, 0x4a, 0xe6, 0x70, 0x1e, 0xf2, 0xb8, 0x96, 0xae, + 0x7e, 0x6d, 0x58, 0xfb, 0x47, 0x0b, 0x32, 0xcf, 0x8e, 0x9f, 0x85, 0x3d, + 0x78, 0x98, 0xe1, 0x77, 0xcd, 0x37, 0xbf, 0x88, 0xb9, 0xfa, 0x28, 0x26, + 0x7a, 0xc0, 0x36, 0x51, 0xd4, 0xad, 0xe3, 0x9a, 0xa8, 0xeb, 0x92, 0xb6, + 0x5c, 0xaa, 0x61, 0x8d, 0x97, 0xc6, 0x8b, 0x69, 0xb5, 0x5f, 0xb5, 0x76, + 0x4e, 0x0b, 0x25, 0xb2, 0x80, 0x2b, 0x72, 0x21, 0x2d, 0xde, 0x1b, 0x01, + 0xa7, 0x94, 0xe9, 0x01, 0x83, 0xa3, 0x0a, 0x06, 0x4f, 0x8b, 0x35, 0x22, + 0x97, 0x10, 0x3e, 0xc8, 0xc6, 0x70, 0x48, 0x67, 0x46, 0xf9, 0x3e, 0x8c, + 0xfb, 0x07, 0x42, 0xcc, 0x83, 0xb6, 0x0b, 0x07, 0xf7, 0xda, 0x1b, 0xf1, + 0x9a, 0xed, 0xd6, 0xd3, 0x5c, 0x77, 0xc9, 0x8e, 0x90, 0x92, 0x1b, 0x52, + 0xef, 0xdd, 0xe5, 0xd8, 0x89, 0x14, 0xcf, 0xed, 0x2f, 0xc2, 0x7f, 0x39, + 0x44, 0x6d, 0x25, 0x3a, 0x12, 0x06, 0x3e, 0x77, 0xb1, 0x5d, 0xc9, 0x73, + 0x18, 0x2b, 0xd1, 0x85, 0xf0, 0x3e, 0xb6, 0x5d, 0xf6, 0xb3, 0x0e, 0x3a, + 0xca, 0xff, 0x4e, 0xc4, 0xef, 0xc3, 0xbc, 0x3a, 0xf8, 0xda, 0x7e, 0x32, + 0x7a, 0x52, 0x66, 0x2b, 0xeb, 0x07, 0x47, 0x2a, 0xf6, 0x88, 0x05, 0xff, + 0x1c, 0xeb, 0xb6, 0xc6, 0x5c, 0xb8, 0x5b, 0xd5, 0x9c, 0xc1, 0x87, 0x8d, + 0xf8, 0xd6, 0x3f, 0x97, 0x64, 0xaf, 0x80, 0x21, 0x75, 0xfc, 0xe3, 0x52, + 0x64, 0x08, 0xc7, 0x78, 0xe7, 0x90, 0x3d, 0x11, 0xf1, 0xfd, 0x58, 0xea, + 0xf2, 0x3e, 0xfb, 0x88, 0x7c, 0x3f, 0x80, 0x6d, 0x5a, 0x3e, 0x2f, 0xbc, + 0x97, 0x3a, 0x4f, 0x25, 0x5f, 0x15, 0x74, 0x50, 0xa2, 0x7f, 0x67, 0x9a, + 0x35, 0x09, 0xb1, 0x8c, 0x29, 0x51, 0x0b, 0x8d, 0x7c, 0xe5, 0xf9, 0x45, + 0x3d, 0x2f, 0x47, 0xed, 0xf5, 0xfd, 0xc8, 0x37, 0xcb, 0x16, 0x68, 0x73, + 0x99, 0x01, 0x3f, 0xda, 0xe8, 0xf2, 0x46, 0x4f, 0x50, 0xd4, 0x66, 0x77, + 0xb3, 0x8e, 0xa3, 0xf3, 0x92, 0xc7, 0xf8, 0xfe, 0x01, 0xf1, 0xbe, 0xb9, + 0xd8, 0x12, 0xc6, 0x35, 0xd3, 0xc8, 0x72, 0xe9, 0x21, 0xfe, 0x5d, 0xc4, + 0x11, 0x93, 0xd4, 0xaa, 0x62, 0x04, 0x1d, 0x2a, 0xae, 0x14, 0x62, 0x5a, + 0xaa, 0xd4, 0x1c, 0x8f, 0x94, 0x7d, 0x6d, 0xc0, 0xf1, 0x5a, 0x5f, 0xdb, + 0x73, 0x5b, 0xc8, 0x9b, 0xad, 0xf0, 0x1a, 0x39, 0xa5, 0x2d, 0xa4, 0x7c, + 0x88, 0xd6, 0x02, 0x6d, 0xb7, 0xb6, 0x6e, 0xc7, 0xd7, 0xb4, 0x36, 0xcf, + 0xac, 0x9f, 0x79, 0xc7, 0x69, 0x53, 0xf8, 0xd4, 0x4c, 0xf3, 0xb9, 0x36, + 0x96, 0xd9, 0xa8, 0x97, 0x02, 0xbc, 0xfc, 0x43, 0xa8, 0x37, 0x79, 0x32, + 0xd0, 0x4c, 0xab, 0xab, 0xc8, 0x79, 0x78, 0xfc, 0x2e, 0x99, 0xe7, 0xfb, + 0x08, 0xc3, 0x65, 0x3f, 0xcb, 0x37, 0x43, 0xc5, 0x70, 0x70, 0x0e, 0xbc, + 0x41, 0xf4, 0xfd, 0x0c, 0x3c, 0x3c, 0xde, 0xc6, 0x7a, 0xbd, 0x8c, 0x01, + 0x1c, 0xe4, 0x7b, 0x7f, 0x33, 0xf7, 0x08, 0xfc, 0x59, 0xe6, 0x61, 0xbe, + 0x7f, 0x8c, 0xf5, 0x81, 0x08, 0x35, 0xd3, 0xca, 0x6a, 0x33, 0xeb, 0xf5, + 0xcd, 0xac, 0x0f, 0x8c, 0x9a, 0x23, 0x3e, 0xf1, 0x2c, 0x51, 0xdb, 0xf2, + 0xe9, 0xc0, 0x7e, 0xc6, 0x41, 0x3c, 0xeb, 0x8b, 0xea, 0x59, 0xb5, 0xcf, + 0xb8, 0x55, 0xc2, 0xf1, 0x61, 0xff, 0xfa, 0x99, 0xab, 0x78, 0x2f, 0xd4, + 0xe2, 0x34, 0xeb, 0xbe, 0x41, 0xf1, 0x6e, 0x46, 0x63, 0x66, 0x86, 0xed, + 0x80, 0x30, 0x1f, 0x1f, 0xa1, 0x54, 0x31, 0x41, 0xbf, 0x57, 0x74, 0xfb, + 0x6a, 0x8f, 0xf0, 0x9c, 0x65, 0x6d, 0x7d, 0x0b, 0xcf, 0xeb, 0x7d, 0xa7, + 0x96, 0x67, 0xb4, 0x91, 0xff, 0x6b, 0x41, 0x6a, 0x7e, 0x11, 0xbe, 0x91, + 0x12, 0x65, 0xc3, 0xf6, 0x85, 0xeb, 0xe2, 0xbd, 0x1b, 0x16, 0xbd, 0x22, + 0xf2, 0x5b, 0xf9, 0x7a, 0xbe, 0xe7, 0x79, 0x8c, 0x7b, 0xc5, 0xa2, 0x2b, + 0x8e, 0x84, 0xf7, 0x9f, 0x05, 0x82, 0xe4, 0x7f, 0x1d, 0x39, 0x48, 0xd0, + 0xb5, 0xd6, 0xcf, 0x38, 0xfb, 0x98, 0x5f, 0xbf, 0x88, 0xeb, 0xf8, 0xf3, + 0x75, 0x1c, 0xb7, 0xf1, 0x3a, 0x21, 0x6f, 0x91, 0x77, 0x02, 0x3e, 0xb7, + 0x3f, 0x64, 0x0a, 0xfc, 0x3b, 0xc2, 0x38, 0xd5, 0x24, 0x7c, 0x81, 0xbd, + 0x18, 0xeb, 0x0c, 0xb2, 0x6e, 0xb0, 0x7e, 0x66, 0x7c, 0x1f, 0x8e, 0x23, + 0x3d, 0x7e, 0x86, 0x91, 0xc4, 0xa1, 0xb0, 0x78, 0xff, 0xa1, 0xeb, 0x2f, + 0x70, 0x70, 0x9c, 0x78, 0x3f, 0xa1, 0x3f, 0xf0, 0x7e, 0x9a, 0xe8, 0xb3, + 0xd4, 0x46, 0x71, 0x7e, 0x46, 0x2c, 0x27, 0xd7, 0x7d, 0xbe, 0xe8, 0x27, + 0xe9, 0x47, 0x6a, 0x1e, 0xd6, 0xef, 0x29, 0xa4, 0x7e, 0xdc, 0x5b, 0xd3, + 0x0a, 0xbe, 0x77, 0xd1, 0x8d, 0x5c, 0x07, 0xdd, 0x54, 0xb1, 0xa5, 0x1b, + 0xc2, 0xae, 0x62, 0x9e, 0x9c, 0xe8, 0xa2, 0xeb, 0xab, 0x4d, 0x44, 0xbd, + 0x6d, 0x22, 0xf6, 0x7b, 0x23, 0x97, 0xc7, 0xf3, 0x87, 0xa5, 0xdf, 0xa5, + 0x82, 0x23, 0x37, 0x3c, 0x70, 0xe4, 0x3d, 0x81, 0x23, 0xef, 0x6d, 0x81, + 0x23, 0x7b, 0x95, 0x2d, 0xd1, 0x46, 0xcd, 0x0a, 0x3f, 0x5e, 0x63, 0xfc, + 0x78, 0x81, 0xf1, 0xe3, 0x50, 0x03, 0xfc, 0x30, 0x6a, 0xf0, 0xe3, 0xb0, + 0xc0, 0x8f, 0x9f, 0x6d, 0x8a, 0x1f, 0x87, 0xfc, 0x9b, 0xf9, 0x82, 0x34, + 0x6e, 0x0e, 0xd0, 0x4a, 0xce, 0xa1, 0xd5, 0x45, 0x9b, 0x2d, 0x7b, 0xd8, + 0xe6, 0x88, 0x19, 0xce, 0x88, 0x7a, 0x97, 0x82, 0xc0, 0x2b, 0x96, 0xe3, + 0x33, 0xa8, 0x69, 0xaa, 0xdb, 0x03, 0x12, 0xef, 0xa5, 0x14, 0xf0, 0x97, + 0x7b, 0x12, 0xcb, 0xac, 0x9f, 0xf9, 0x73, 0xde, 0xc7, 0x2b, 0x6b, 0x81, + 0x00, 0x7e, 0xf3, 0xcf, 0x04, 0x69, 0x63, 0x8d, 0xed, 0x54, 0xc6, 0xb1, + 0xab, 0xb9, 0x21, 0xba, 0x92, 0x1b, 0xa0, 0x8d, 0xdc, 0x30, 0xbd, 0x93, + 0xc3, 0x33, 0x00, 0x73, 0x3e, 0x16, 0x30, 0x37, 0xe8, 0x60, 0x90, 0xc7, + 0xac, 0x0e, 0xd0, 0xfa, 0xaa, 0xc6, 0x57, 0xe0, 0x2a, 0xf6, 0x3f, 0xd2, + 0x23, 0xeb, 0xd0, 0xea, 0x71, 0x20, 0x56, 0x85, 0x03, 0xf2, 0x1a, 0xec, + 0xfd, 0x42, 0x7d, 0x0d, 0x6d, 0xab, 0x39, 0x83, 0x1c, 0xb8, 0x36, 0xb6, + 0xc9, 0x6d, 0xe1, 0x73, 0x3d, 0xe8, 0x87, 0x4e, 0x6b, 0xdc, 0x4d, 0x5d, + 0xbc, 0x07, 0x0e, 0xf2, 0x87, 0x86, 0x59, 0x3f, 0xed, 0x16, 0xfa, 0x68, + 0xd4, 0x09, 0x84, 0x62, 0x54, 0x3a, 0x6b, 0x38, 0xe8, 0x93, 0xf8, 0x08, + 0xdf, 0xcf, 0x50, 0x7e, 0x9e, 0x4e, 0x17, 0x3e, 0xd5, 0xea, 0x9e, 0x88, + 0xd1, 0x9e, 0xe0, 0x39, 0x43, 0x4e, 0x56, 0xe2, 0x22, 0x54, 0x8e, 0x8b, + 0xb4, 0xf2, 0xba, 0x25, 0x2d, 0xcd, 0x39, 0x3c, 0xae, 0xc8, 0xe3, 0x8a, + 0x88, 0xa9, 0xf1, 0xf9, 0x55, 0xc4, 0x73, 0x87, 0x68, 0x63, 0x11, 0x34, + 0x07, 0xff, 0x44, 0x25, 0x86, 0xba, 0xb1, 0x86, 0xf3, 0xf0, 0x51, 0x54, + 0x62, 0xa8, 0x1b, 0x2a, 0x86, 0xba, 0xb1, 0x36, 0x2d, 0xf8, 0xf0, 0x42, + 0x8e, 0x79, 0x40, 0xce, 0xaf, 0xf2, 0x07, 0xf7, 0xa9, 0x77, 0xf6, 0x9c, + 0x10, 0x3e, 0xe4, 0x1e, 0x67, 0x73, 0x18, 0x1e, 0xac, 0x83, 0xe1, 0xb4, + 0xd0, 0x83, 0xe2, 0x7c, 0xcf, 0x58, 0xee, 0x04, 0xc3, 0x73, 0x96, 0x69, + 0x69, 0xb7, 0xa2, 0x25, 0x1d, 0x93, 0xed, 0x26, 0xf5, 0xfe, 0x1f, 0xa1, + 0xeb, 0x4b, 0xfe, 0x33, 0x54, 0xc3, 0x7f, 0x28, 0x10, 0x1d, 0x97, 0xd7, + 0xa7, 0x8b, 0xaf, 0x0c, 0x6b, 0xff, 0x5b, 0x9a, 0xef, 0xbb, 0x90, 0xdb, + 0x49, 0x4c, 0x97, 0xe5, 0xa6, 0x67, 0xce, 0xe0, 0x76, 0x9f, 0xad, 0x71, + 0xe1, 0xc4, 0x6d, 0xe0, 0x93, 0xbc, 0x47, 0x05, 0x9f, 0xfe, 0x77, 0x16, + 0xc0, 0xb2, 0x93, 0x05, 0x98, 0x57, 0x84, 0x80, 0xf5, 0x03, 0x03, 0xb4, + 0x8e, 0x39, 0x00, 0x1e, 0x53, 0x68, 0x02, 0xe6, 0x19, 0xa7, 0xf5, 0x40, + 0xfb, 0xfb, 0x95, 0xc1, 0xeb, 0x5d, 0x1b, 0xa0, 0x67, 0x4f, 0x2d, 0xea, + 0x79, 0x2c, 0x07, 0xca, 0xa3, 0x4e, 0x2a, 0x0c, 0x24, 0xe6, 0x27, 0x90, + 0xff, 0x80, 0xfe, 0x00, 0xf9, 0x11, 0x98, 0x9f, 0x9c, 0x81, 0x72, 0xa0, + 0x35, 0x53, 0xcd, 0x6b, 0x40, 0xfa, 0x40, 0x61, 0x08, 0x2a, 0x53, 0x41, + 0x63, 0x1d, 0x40, 0xf6, 0x12, 0x21, 0x68, 0xd8, 0x01, 0x69, 0x20, 0xbb, + 0x79, 0x8a, 0x08, 0x98, 0x9f, 0x14, 0x20, 0xc4, 0xd0, 0x00, 0xcf, 0x4f, + 0xec, 0x40, 0x97, 0xc2, 0xdc, 0xf4, 0xff, 0xff, 0x31, 0x15, 0x16, 0x60, + 0xda, 0x03, 0xad, 0xf9, 0xfc, 0xfd, 0xff, 0x80, 0x08, 0x0b, 0x43, 0x0b, + 0x7c, 0xed, 0x9e, 0xb0, 0x3c, 0xa8, 0x9c, 0x5b, 0x00, 0x64, 0xb5, 0xc1, + 0xeb, 0x6d, 0x16, 0xf0, 0x7d, 0xc4, 0x0b, 0x18, 0x7e, 0x01, 0xcb, 0x95, + 0xff, 0xff, 0x97, 0xc2, 0xd5, 0x82, 0x00, 0x00, 0xd4, 0xc2, 0xcb, 0x42, + 0x60, 0x7c, 0x00, 0x00, 0x00 }; +static u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 }; +static u32 bnx2_COM_b09FwRodata[(0x88/4) + 1] = { + 0x08001ad8, 0x08001b14, 0x08001b14, 0x08001b14, 0x08001b14, 0x08001b14, + 0x08001a24, 0x08001b14, 0x08001a98, 0x08001b14, 0x080019ac, 0x08001b14, + 0x08001b14, 0x08001b14, 0x080019b8, 0x0, 0x08002a2c, 0x08002a7c, + 0x08002aac, 0x08002adc, 0x08002b0c, 0x0, 0x08005fac, 0x08005fac, + 0x08005fac, 0x08005fac, 0x08005fac, 0x08005fd8, 0x08005fd8, 0x08006018, + 0x08006024, 0x08006024, 0x08005fac, 0x0, 0x0 }; +static u32 bnx2_COM_b09FwBss[(0x88/4) + 1] = { 0x0 }; +static u32 bnx2_COM_b09FwSbss[(0x5c/4) + 1] = { 0x0 }; static struct fw_info bnx2_com_fw_09 = { - .ver_major = 0x3, - .ver_minor = 0x4, - .ver_fix = 0x3, + .ver_major = 0x1, + .ver_minor = 0x0, + .ver_fix = 0x0, - .start_addr = 0x080000b4, + .start_addr = 0x080000b0, .text_addr = 0x08000000, - .text_len = 0x7dc0, + .text_len = 0x7c5c, .text_index = 0x0, .gz_text = bnx2_COM_b09FwText, .gz_text_len = sizeof(bnx2_COM_b09FwText), - .data_addr = 0x08007e60, + .data_addr = 0x08007d00, .data_len = 0x0, .data_index = 0x0, .data = bnx2_COM_b09FwData, - .sbss_addr = 0x08007e60, - .sbss_len = 0x60, + .sbss_addr = 0x08007d00, + .sbss_len = 0x5c, .sbss_index = 0x0, .sbss = bnx2_COM_b09FwSbss, - .bss_addr = 0x08007ec0, + .bss_addr = 0x08007d60, .bss_len = 0x88, .bss_index = 0x0, .bss = bnx2_COM_b09FwBss, - .rodata_addr = 0x08007dc0, + .rodata_addr = 0x08007c60, .rodata_len = 0x88, .rodata_index = 0x0, .rodata = bnx2_COM_b09FwRodata, }; static u8 bnx2_CP_b09FwText[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x0f, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xbd, 0x7d, - 0x0d, 0x74, 0x5c, 0x57, 0x7d, 0xe7, 0xff, 0xdd, 0x19, 0x49, 0x63, 0x59, - 0x96, 0x9f, 0xe5, 0x89, 0x32, 0x51, 0x84, 0x3d, 0x23, 0x3d, 0xd9, 0x22, - 0x12, 0xe1, 0xc5, 0x11, 0xac, 0xda, 0x2a, 0xe9, 0x30, 0x92, 0x3f, 0x12, - 0x02, 0xab, 0x10, 0x43, 0xb3, 0x1c, 0x4a, 0xc5, 0x48, 0x4e, 0x02, 0x04, - 0xea, 0x40, 0xe8, 0x86, 0xdd, 0xec, 0x66, 0x32, 0x92, 0x3f, 0x9a, 0x8e, - 0x3d, 0x93, 0x44, 0x89, 0xbd, 0xdd, 0x9c, 0xad, 0x90, 0x14, 0x3b, 0x74, - 0x07, 0x4f, 0xe2, 0x98, 0x96, 0x73, 0x0a, 0x8d, 0x50, 0x8c, 0x9b, 0xe6, - 0xb0, 0xdd, 0xd0, 0xa6, 0x34, 0xdb, 0x86, 0x22, 0x8c, 0x81, 0xf4, 0x2c, - 0xdd, 0x86, 0x42, 0x77, 0xd3, 0x36, 0xe5, 0xed, 0xef, 0x77, 0xef, 0x7d, - 0x9a, 0x91, 0x34, 0xce, 0x07, 0xdd, 0xad, 0xcf, 0x79, 0x7e, 0xf3, 0xee, - 0xbb, 0x1f, 0xff, 0xfb, 0xbf, 0xff, 0xef, 0xfb, 0xbf, 0x4f, 0x97, 0x8b, - 0x34, 0x8b, 0xfd, 0xb7, 0x01, 0xd7, 0xd5, 0xc9, 0xfd, 0xe3, 0x57, 0x5f, - 0x39, 0x70, 0x25, 0x9f, 0xa3, 0x91, 0x68, 0x44, 0xde, 0xc4, 0xbf, 0xe4, - 0x1b, 0xa8, 0x83, 0x0e, 0xdd, 0x70, 0x2c, 0x5e, 0x12, 0x53, 0x43, 0xde, - 0xfe, 0x8c, 0x27, 0xb1, 0xc8, 0x50, 0xee, 0xce, 0x71, 0x4f, 0x24, 0x5d, - 0xee, 0x4b, 0x0e, 0xcb, 0x3f, 0x05, 0xb9, 0x78, 0x54, 0x58, 0xfe, 0x96, - 0xa1, 0x57, 0x7f, 0xeb, 0x2b, 0xff, 0x2a, 0xf5, 0xf2, 0x4c, 0x44, 0x62, - 0xee, 0xd0, 0xed, 0xe2, 0x6e, 0x93, 0x58, 0xe7, 0x50, 0x72, 0xff, 0x23, - 0xdb, 0x97, 0x44, 0x5a, 0xc3, 0xbe, 0x5e, 0x0a, 0xbe, 0xb2, 0x5d, 0x72, - 0x1d, 0x43, 0x89, 0xb1, 0x86, 0x21, 0x57, 0x9e, 0xaa, 0xc8, 0xe8, 0x89, - 0xc2, 0xcb, 0x41, 0x74, 0x28, 0x88, 0x4c, 0x0d, 0x38, 0x12, 0x19, 0x92, - 0xb3, 0xe3, 0x03, 0xf7, 0x04, 0xca, 0xf3, 0xfc, 0x45, 0x69, 0x19, 0x3c, - 0x37, 0x80, 0xf7, 0x65, 0x41, 0xdd, 0xbd, 0xd7, 0x9c, 0x28, 0xc4, 0x44, - 0x0d, 0xf5, 0xbc, 0x90, 0x89, 0x5c, 0x25, 0x7c, 0x7f, 0x56, 0x7a, 0xfc, - 0xa7, 0x05, 0xe5, 0xe5, 0x98, 0x64, 0x2a, 0xd2, 0x82, 0x32, 0xdc, 0x9b, - 0x51, 0x27, 0xe5, 0x66, 0x22, 0xae, 0xe4, 0x2b, 0x3f, 0x5e, 0x67, 0xc6, - 0x9d, 0xb3, 0xf7, 0xbf, 0x8e, 0x99, 0x3b, 0xc6, 0x2d, 0xc6, 0x64, 0x29, - 0x92, 0x10, 0xc0, 0x82, 0x79, 0x25, 0x64, 0xb2, 0x98, 0x94, 0x4c, 0x81, - 0xb0, 0x45, 0x25, 0xeb, 0x12, 0xae, 0x04, 0xda, 0xb7, 0x39, 0xf5, 0xeb, - 0xb3, 0xee, 0x0b, 0xa8, 0x9b, 0x44, 0xbd, 0x4e, 0x79, 0x12, 0x75, 0x4f, - 0x57, 0xe2, 0xf2, 0x44, 0xe5, 0x57, 0x25, 0x8d, 0xb6, 0x8f, 0x57, 0x30, - 0x76, 0xb1, 0x51, 0x86, 0xa7, 0x9b, 0x25, 0x33, 0xdd, 0x9d, 0xc8, 0x4a, - 0x10, 0x7c, 0xda, 0xff, 0xa8, 0x8c, 0xb5, 0xa1, 0x7e, 0x91, 0xef, 0x12, - 0x2b, 0xde, 0x65, 0xfd, 0x3e, 0x37, 0xab, 0x1c, 0x49, 0xef, 0x4d, 0x25, - 0xc6, 0x14, 0x9f, 0x1b, 0x24, 0xd3, 0x8f, 0xe7, 0xd1, 0xa8, 0x44, 0xbc, - 0x20, 0xb8, 0xc3, 0xbf, 0x0c, 0x70, 0xa4, 0x92, 0x49, 0xc5, 0xb6, 0x6c, - 0x97, 0xca, 0x25, 0x55, 0x5c, 0x72, 0x95, 0x2b, 0x25, 0xd9, 0x16, 0x04, - 0xef, 0xf3, 0x3b, 0x51, 0x2e, 0x32, 0x5c, 0x90, 0xfd, 0x58, 0x23, 0xf4, - 0x29, 0xbe, 0x1a, 0xda, 0x8c, 0x79, 0xf4, 0xb9, 0xc3, 0xd2, 0x28, 0xe9, - 0xb8, 0xa4, 0xd5, 0x90, 0x24, 0xd5, 0xd0, 0x3a, 0x94, 0x39, 0xd2, 0xe0, - 0x7d, 0xc1, 0xd2, 0xd2, 0x46, 0x3c, 0xcb, 0xa8, 0x1a, 0x6a, 0x5b, 0x55, - 0x9e, 0x4a, 0x8a, 0x5a, 0x07, 0x5c, 0xa5, 0x7a, 0xd3, 0x8a, 0x65, 0xb8, - 0xeb, 0xb2, 0x0f, 0x36, 0xad, 0x2d, 0xdb, 0xef, 0xac, 0x2c, 0xbb, 0xbd, - 0x85, 0xb0, 0x8a, 0xe2, 0xef, 0xb8, 0x9e, 0x6b, 0x3a, 0xde, 0xed, 0x36, - 0x60, 0x5e, 0xa3, 0x7e, 0xca, 0xdd, 0xa9, 0x9e, 0x0f, 0xa4, 0x9d, 0x30, - 0xf3, 0x9d, 0xc2, 0x3b, 0x54, 0x1d, 0xf2, 0xb1, 0x6e, 0xae, 0x1c, 0xc2, - 0xdc, 0xce, 0x4f, 0xa7, 0xdc, 0x2e, 0x85, 0xfb, 0x3c, 0x7f, 0x07, 0x41, - 0xc6, 0xcf, 0xe9, 0x35, 0xfd, 0xee, 0x74, 0x02, 0xcf, 0x80, 0x3f, 0x9e, - 0x4e, 0x6d, 0x92, 0xab, 0xed, 0xba, 0x7c, 0x13, 0x63, 0x76, 0xbb, 0x77, - 0xa8, 0x6e, 0xd7, 0x57, 0x29, 0x77, 0x56, 0xce, 0xe0, 0x39, 0x08, 0x6e, - 0xf4, 0x53, 0x89, 0x1c, 0xd6, 0xec, 0x42, 0x21, 0x2e, 0xdf, 0x2b, 0xa4, - 0x40, 0xc5, 0xa9, 0xde, 0x39, 0xe9, 0xf3, 0xe7, 0x00, 0x6f, 0x1e, 0xd7, - 0x41, 0xbe, 0x2b, 0xe3, 0x5d, 0x99, 0x6d, 0x83, 0xe0, 0x26, 0xff, 0x37, - 0x83, 0xb1, 0x76, 0xc3, 0x17, 0x4f, 0x15, 0xb1, 0x9e, 0x80, 0xf9, 0x74, - 0x11, 0xeb, 0x89, 0xb5, 0x7a, 0x5c, 0xaf, 0x7b, 0x2f, 0xd6, 0x9d, 0xb4, - 0x41, 0xba, 0xd8, 0x61, 0x69, 0xf9, 0x03, 0xf6, 0x2e, 0x92, 0x29, 0x3a, - 0x92, 0xf1, 0xff, 0x31, 0x48, 0x6b, 0x7e, 0x11, 0x67, 0xb8, 0x48, 0x5a, - 0x6c, 0x00, 0xac, 0x7c, 0xcc, 0xda, 0x7a, 0x1b, 0x1d, 0xe0, 0x96, 0xeb, - 0xc0, 0xf7, 0x31, 0xe5, 0x35, 0xd9, 0xf7, 0x21, 0x5f, 0xf0, 0xdf, 0x26, - 0x47, 0xbc, 0x6a, 0xbd, 0x0c, 0x69, 0xb2, 0x92, 0x93, 0xec, 0x83, 0x81, - 0x0c, 0xfb, 0xc0, 0x13, 0xfb, 0x74, 0x7d, 0xd1, 0x6d, 0x5d, 0xd6, 0xd1, - 0x75, 0xf1, 0x6f, 0x7d, 0x23, 0xc6, 0x70, 0x46, 0x8a, 0xd5, 0xb6, 0x23, - 0xc5, 0xfc, 0x66, 0x0b, 0x1f, 0x9e, 0x07, 0x9d, 0x4c, 0xe5, 0x82, 0x5d, - 0xdb, 0x70, 0x1e, 0x57, 0xd7, 0xa1, 0x6d, 0x17, 0x7c, 0xe0, 0x4a, 0xb6, - 0x30, 0x88, 0x71, 0xe3, 0xb8, 0x07, 0xc1, 0x94, 0x9f, 0x4e, 0x45, 0x65, - 0x08, 0xcf, 0xa3, 0xe4, 0x3d, 0xe0, 0x4f, 0xa2, 0x99, 0xed, 0xbe, 0x8c, - 0x80, 0xee, 0xf3, 0x95, 0xd7, 0x97, 0x22, 0x7a, 0x0e, 0xfe, 0x3f, 0x59, - 0xdc, 0x70, 0x1c, 0x33, 0xe6, 0x54, 0xb1, 0x43, 0xf2, 0xd3, 0x9e, 0x4c, - 0x16, 0x16, 0x7a, 0x95, 0xbc, 0x4c, 0x7e, 0xc7, 0xfa, 0xa5, 0x40, 0xbb, - 0x43, 0x32, 0x5c, 0xf1, 0x24, 0x5f, 0xc0, 0xbd, 0xd8, 0x0d, 0xfa, 0x8d, - 0x4a, 0x3a, 0x61, 0xd6, 0x26, 0x5f, 0x18, 0xc1, 0xfc, 0x80, 0x6b, 0x8f, - 0xbf, 0x07, 0x2d, 0x4c, 0xae, 0x64, 0x06, 0x48, 0x3f, 0x6f, 0x06, 0x96, - 0x98, 0xcc, 0xfa, 0xe0, 0x0b, 0xd7, 0xc0, 0x92, 0x2f, 0xc6, 0xa2, 0xc3, - 0x98, 0xf7, 0x70, 0xf9, 0x57, 0xd0, 0x7f, 0x8b, 0xfe, 0x0d, 0x7e, 0xb2, - 0x65, 0x51, 0xdc, 0xe3, 0xb8, 0x13, 0xe6, 0x90, 0x56, 0x21, 0x1b, 0xa6, - 0x3b, 0x65, 0x12, 0xb4, 0x3a, 0x2c, 0xf8, 0x3d, 0xcf, 0xb9, 0x10, 0xae, - 0x0e, 0xfd, 0x7b, 0x72, 0x7a, 0x8b, 0x7e, 0xce, 0x8e, 0x76, 0x48, 0x6e, - 0x3e, 0x9c, 0x33, 0xe5, 0x05, 0x65, 0x44, 0xea, 0xb0, 0x08, 0x65, 0x46, - 0x10, 0x3c, 0xe8, 0x53, 0x6e, 0x04, 0xc1, 0x69, 0x9f, 0x72, 0xe4, 0x0c, - 0xe4, 0x03, 0x65, 0x07, 0x79, 0xd9, 0x53, 0x5c, 0xab, 0x4c, 0xa1, 0x17, - 0xeb, 0xd1, 0x28, 0xd9, 0xfe, 0xe3, 0x84, 0x15, 0x72, 0xe7, 0xa5, 0x4f, - 0x66, 0xbc, 0x5c, 0x22, 0xa2, 0xf1, 0x04, 0xca, 0x82, 0x3c, 0x4c, 0xeb, - 0x99, 0x75, 0x49, 0xbe, 0xbf, 0x64, 0xeb, 0xc8, 0xaf, 0xb2, 0x4e, 0x74, - 0x4d, 0x9d, 0x7f, 0xa7, 0x0c, 0x5f, 0xf6, 0x62, 0xdd, 0x3a, 0x14, 0xf1, - 0xd8, 0xb5, 0x8d, 0xcf, 0x12, 0x6b, 0x18, 0xfa, 0x3d, 0xbc, 0x7b, 0xee, - 0x53, 0x8f, 0x7a, 0xf5, 0xde, 0xfd, 0x28, 0xba, 0xf6, 0xdd, 0x94, 0x44, - 0xbd, 0x54, 0xef, 0x8d, 0xea, 0x4f, 0x1a, 0xa4, 0x35, 0x08, 0x1e, 0xf5, - 0xc3, 0xf2, 0xc6, 0x86, 0xb5, 0x63, 0x5c, 0x55, 0xa7, 0xec, 0x68, 0x9d, - 0xb2, 0xcf, 0xd7, 0x29, 0x7b, 0x7b, 0xe3, 0xda, 0xb2, 0xdb, 0xeb, 0x94, - 0xcd, 0xd6, 0x29, 0xfb, 0x69, 0x9d, 0x32, 0x69, 0x5a, 0x5b, 0x16, 0xa9, - 0x53, 0xd6, 0x57, 0xa7, 0x2c, 0x0a, 0xbe, 0xdb, 0x26, 0xf9, 0xf8, 0xbd, - 0x9c, 0xbb, 0xc5, 0x4d, 0x29, 0xb2, 0x16, 0x37, 0x0d, 0xa8, 0xd7, 0xb9, - 0xaa, 0xde, 0x17, 0xeb, 0xd4, 0x6b, 0x44, 0xbd, 0xb6, 0x55, 0xf5, 0x76, - 0xd4, 0xc1, 0x75, 0x13, 0xea, 0xc5, 0x56, 0xd5, 0x7b, 0xb0, 0x4e, 0x3d, - 0x96, 0x7f, 0xc6, 0x8e, 0xd3, 0x07, 0x2d, 0xf4, 0x5a, 0xeb, 0xd5, 0x28, - 0xd2, 0xce, 0xf2, 0x5e, 0xe8, 0x90, 0x0e, 0x65, 0xe4, 0x02, 0x65, 0x10, - 0xcb, 0x3a, 0x41, 0xe7, 0x71, 0xd0, 0x1d, 0xe5, 0x28, 0xf8, 0x8c, 0x73, - 0xa9, 0x6c, 0x90, 0xb1, 0x78, 0x9f, 0x7b, 0xb5, 0x6a, 0x01, 0x8d, 0xa5, - 0xdc, 0xa4, 0x22, 0xff, 0x49, 0x2e, 0x32, 0xe4, 0xe5, 0x86, 0x45, 0xc5, - 0x95, 0x04, 0x32, 0xe2, 0xab, 0x36, 0x25, 0xf7, 0x80, 0xbf, 0xd2, 0xd0, - 0x59, 0x37, 0x06, 0xc3, 0x9a, 0xb7, 0x4c, 0xdd, 0x8b, 0xcb, 0x54, 0x5f, - 0x0e, 0x52, 0x16, 0x0e, 0x8d, 0x7e, 0x2a, 0xe3, 0x2d, 0x0c, 0x36, 0x82, - 0x66, 0xcf, 0xa3, 0xcd, 0x6e, 0xb4, 0xdc, 0x57, 0x8e, 0xca, 0x48, 0x79, - 0x00, 0xbc, 0xe0, 0xc8, 0x39, 0x6f, 0xa3, 0x9c, 0xf3, 0x51, 0xb7, 0x12, - 0x91, 0xc5, 0xb8, 0x23, 0x8b, 0x78, 0xce, 0xf8, 0x78, 0x57, 0x09, 0x79, - 0x6b, 0x40, 0x0e, 0x14, 0x7d, 0x39, 0x5c, 0xbc, 0x41, 0x85, 0x7a, 0x6d, - 0xa7, 0xbf, 0x5e, 0x1e, 0x73, 0x4d, 0xdf, 0xbb, 0xbd, 0x05, 0x68, 0xd4, - 0xa8, 0x9c, 0xf7, 0x52, 0x89, 0x45, 0xcd, 0x13, 0xff, 0x27, 0x18, 0x41, - 0x3f, 0xb3, 0x5e, 0xca, 0xfd, 0x03, 0x3c, 0x8f, 0x95, 0x69, 0xcb, 0x54, - 0xfb, 0x9a, 0x44, 0x5f, 0x87, 0x8a, 0x1b, 0xe4, 0x56, 0xdb, 0x7e, 0x97, - 0xb7, 0xd0, 0x0b, 0x9e, 0x73, 0x4f, 0x50, 0x86, 0x14, 0x00, 0xd7, 0x5e, - 0xf0, 0x36, 0xda, 0x7e, 0x4d, 0xcb, 0x33, 0xd8, 0x3e, 0x85, 0x8d, 0x90, - 0xcf, 0x7f, 0x17, 0xdc, 0x1a, 0x67, 0x7d, 0x96, 0x51, 0xe7, 0x48, 0x49, - 0x0d, 0x41, 0x26, 0x0c, 0x50, 0x66, 0x26, 0x21, 0x2f, 0x21, 0x7b, 0x8a, - 0x3f, 0x0d, 0xd2, 0xd1, 0x5a, 0x39, 0x28, 0xb9, 0x6a, 0x1d, 0x96, 0x25, - 0x8d, 0x5c, 0x2d, 0x2e, 0x2d, 0xcb, 0x8a, 0x1c, 0xe4, 0xcb, 0x53, 0x15, - 0xca, 0x85, 0x0f, 0x82, 0x47, 0x3b, 0x65, 0xa4, 0x90, 0xca, 0xa5, 0x65, - 0x1b, 0xd6, 0xef, 0xd7, 0xb1, 0xa6, 0x51, 0x5c, 0x0f, 0xad, 0x97, 0x56, - 0x1f, 0xba, 0x9b, 0xe5, 0xe8, 0xb4, 0x9d, 0x36, 0xd2, 0x6f, 0x03, 0x0f, - 0x93, 0x5c, 0xf3, 0x44, 0x26, 0xe2, 0x8c, 0xd2, 0x5e, 0x19, 0x85, 0x7c, - 0xcc, 0x96, 0xd9, 0x37, 0xe1, 0x4d, 0xd8, 0xdf, 0xb0, 0x9b, 0x0a, 0x9d, - 0xf6, 0x77, 0x0b, 0x7e, 0x27, 0xed, 0x6f, 0xc8, 0xd4, 0x82, 0x67, 0x7f, - 0xc7, 0xb5, 0x1c, 0x32, 0xbf, 0x13, 0xf8, 0xdd, 0xaf, 0x7f, 0x4f, 0x15, - 0x77, 0xed, 0x52, 0xde, 0x95, 0x92, 0x9d, 0xef, 0x94, 0x03, 0x85, 0x77, - 0x58, 0xd9, 0x82, 0x4b, 0xbe, 0xe4, 0x98, 0x79, 0x26, 0xf4, 0xba, 0xe7, - 0x8b, 0x39, 0x67, 0x94, 0xf0, 0xe3, 0xf7, 0x70, 0xa1, 0xcf, 0xdd, 0x24, - 0xa4, 0x81, 0x29, 0x67, 0xb8, 0xe2, 0xa4, 0x23, 0x43, 0x3d, 0x89, 0x49, - 0x39, 0x8c, 0xdf, 0xe2, 0x46, 0x86, 0xbe, 0x84, 0xbb, 0xc1, 0xc1, 0x57, - 0xb6, 0x43, 0xb6, 0x16, 0x29, 0x2f, 0x3d, 0xcc, 0x3d, 0x29, 0x67, 0x56, - 0xd8, 0x58, 0xc4, 0x85, 0x92, 0xec, 0x74, 0xea, 0x78, 0x4e, 0x52, 0xb9, - 0x19, 0x30, 0xc4, 0x8d, 0x7e, 0x54, 0xde, 0xe7, 0x83, 0x76, 0xaf, 0x74, - 0x64, 0xd7, 0x95, 0x51, 0xd8, 0x44, 0xde, 0xcc, 0x2e, 0xc8, 0x58, 0xc8, - 0xbe, 0x08, 0xe9, 0x41, 0x9d, 0x92, 0xb1, 0xe8, 0x10, 0xb0, 0x7d, 0xaa, - 0x7f, 0x64, 0xb2, 0x90, 0xbd, 0x5d, 0x0d, 0xed, 0xff, 0x6c, 0x66, 0xe0, - 0xad, 0x92, 0xdd, 0xab, 0x80, 0xa3, 0xf6, 0x31, 0xc8, 0x4c, 0xcc, 0x2b, - 0x08, 0x40, 0xcf, 0x90, 0xe7, 0x37, 0xdd, 0x14, 0x19, 0x6a, 0x90, 0xe1, - 0xbd, 0xed, 0x68, 0xc3, 0x77, 0xc4, 0xd7, 0x79, 0xe0, 0x33, 0x95, 0x1c, - 0x11, 0xb9, 0x7b, 0x6a, 0x60, 0xc9, 0x99, 0x2c, 0x7d, 0x10, 0x3c, 0x79, - 0x15, 0xda, 0x3f, 0x80, 0xf6, 0x2f, 0x3b, 0xf9, 0xe9, 0x57, 0x9c, 0xc9, - 0xe9, 0xbf, 0x75, 0xa6, 0xa6, 0xb7, 0x6c, 0xd9, 0x39, 0xb8, 0x65, 0xcb, - 0xf8, 0x60, 0xd4, 0xea, 0x97, 0x2d, 0x5b, 0xa6, 0x06, 0x07, 0x81, 0x83, - 0x3e, 0x77, 0x44, 0x3c, 0x77, 0x97, 0x80, 0x7f, 0xe2, 0x1c, 0x93, 0xfa, - 0x27, 0x85, 0xf7, 0x6c, 0xef, 0xe9, 0xf7, 0xc3, 0xd2, 0x97, 0x68, 0x13, - 0x8e, 0x1f, 0xb1, 0x75, 0xda, 0x01, 0xfb, 0x03, 0x76, 0x7d, 0x0b, 0xaa, - 0xc1, 0x63, 0x39, 0xe7, 0xc2, 0x72, 0xae, 0xed, 0x8f, 0xac, 0x2d, 0xbb, - 0x11, 0xe5, 0x7c, 0x26, 0xce, 0x88, 0x17, 0xda, 0x22, 0x0d, 0xda, 0x76, - 0xcc, 0x16, 0x48, 0x33, 0x51, 0x99, 0x28, 0xb4, 0xa1, 0x0d, 0xe8, 0xe2, - 0x94, 0xbd, 0x8e, 0x02, 0xb6, 0xbd, 0xe8, 0xeb, 0xe8, 0x21, 0xb4, 0xa3, - 0xcc, 0x48, 0xf5, 0x8a, 0xfa, 0x04, 0xea, 0xf4, 0xb9, 0x9b, 0x85, 0x36, - 0xc7, 0x71, 0xc9, 0x16, 0xc9, 0xdf, 0x3d, 0x80, 0x27, 0x26, 0xc9, 0x76, - 0x3c, 0x57, 0x0e, 0xc0, 0x0e, 0x69, 0xb0, 0x3a, 0x33, 0x94, 0x17, 0xfc, - 0x77, 0x87, 0x12, 0xef, 0x80, 0x8c, 0xcd, 0x5d, 0x8e, 0x7a, 0x0e, 0xf0, - 0x42, 0x3b, 0x05, 0x36, 0xcb, 0x5c, 0x5a, 0x32, 0xdb, 0xee, 0xc5, 0xdd, - 0xc5, 0x73, 0x1e, 0xf7, 0xb7, 0xe0, 0x3e, 0x89, 0x7b, 0x08, 0x27, 0xf0, - 0xea, 0x47, 0xac, 0xce, 0xba, 0x06, 0x63, 0xff, 0x6b, 0xc9, 0x94, 0x12, - 0xb4, 0x39, 0x36, 0x66, 0xbc, 0xb4, 0xab, 0x44, 0x6d, 0x56, 0x32, 0x85, - 0xfa, 0xf0, 0x09, 0xbc, 0x83, 0x32, 0x7e, 0x12, 0xbf, 0x1f, 0xa4, 0x4d, - 0x3c, 0x25, 0xe3, 0x73, 0x1c, 0xa7, 0x00, 0x98, 0x4a, 0x92, 0x3d, 0xf9, - 0x00, 0xae, 0x69, 0x5c, 0x0f, 0xe3, 0xe2, 0xdc, 0xd8, 0xff, 0xe2, 0x26, - 0x05, 0x5c, 0xf3, 0x39, 0x4b, 0x3a, 0xae, 0xe0, 0x37, 0x69, 0xb8, 0x42, - 0xdb, 0x06, 0xf4, 0x5b, 0x09, 0xe9, 0xda, 0xb7, 0xbf, 0x13, 0x9a, 0xaf, - 0x73, 0x6d, 0xa0, 0x99, 0xca, 0xa0, 0x96, 0x39, 0x19, 0x0f, 0xf7, 0x0a, - 0x6c, 0x8f, 0x36, 0xce, 0xd1, 0xb3, 0x65, 0x9e, 0x2e, 0x4b, 0xea, 0xb2, - 0x7e, 0x5b, 0x86, 0x7b, 0xa5, 0x41, 0xc6, 0xda, 0x01, 0x31, 0xe5, 0xb3, - 0x84, 0xf8, 0xa4, 0x0c, 0x00, 0xfd, 0xc2, 0x66, 0x38, 0x73, 0x51, 0xf9, - 0xb7, 0xa4, 0x6d, 0xb1, 0xc7, 0x2b, 0xa4, 0x63, 0xd2, 0x76, 0x10, 0xdc, - 0xef, 0x37, 0xa1, 0x7f, 0xf2, 0xbc, 0x48, 0xc3, 0xd1, 0xa8, 0xcc, 0xb8, - 0xa4, 0x85, 0x77, 0xb4, 0x90, 0x06, 0x1a, 0x3d, 0xd2, 0x70, 0x2d, 0x7f, - 0x71, 0x0d, 0xd9, 0x5f, 0x0e, 0xf6, 0x1d, 0xed, 0xbc, 0x1e, 0xd8, 0xce, - 0x1c, 0xe3, 0x30, 0x9f, 0x5d, 0x05, 0x9e, 0xca, 0x2c, 0xf3, 0x94, 0xc8, - 0x6c, 0x81, 0xb8, 0x09, 0xed, 0x3f, 0xae, 0x33, 0xf1, 0xf3, 0x38, 0xe6, - 0xcc, 0xfb, 0x19, 0x8b, 0xa7, 0x2f, 0x59, 0x3c, 0x7d, 0xd9, 0xde, 0x5d, - 0x27, 0xab, 0x6d, 0xc1, 0x05, 0x3c, 0x73, 0x7d, 0xa2, 0x1a, 0x67, 0xd9, - 0xc2, 0x0c, 0xee, 0xa8, 0x5b, 0x7c, 0x5c, 0xc6, 0xb5, 0x9d, 0x16, 0x91, - 0x77, 0x69, 0xd9, 0x06, 0x21, 0xdd, 0x5c, 0x00, 0xcc, 0x0d, 0x92, 0x8b, - 0x47, 0xf4, 0xda, 0x47, 0xbd, 0x03, 0x51, 0x43, 0xab, 0xc4, 0xc9, 0x0a, - 0x5f, 0xaa, 0x06, 0xa6, 0xb8, 0x95, 0x73, 0x84, 0x8b, 0xb4, 0xfb, 0x88, - 0x86, 0xeb, 0x16, 0xc8, 0xbb, 0x9c, 0xa8, 0xf6, 0x46, 0xb9, 0x0c, 0xb4, - 0xa0, 0xe2, 0xd0, 0x5c, 0xc1, 0xd3, 0xb0, 0x9b, 0xb2, 0x73, 0xb4, 0xa1, - 0xbb, 0xe8, 0xb7, 0xc4, 0xb2, 0xfd, 0xad, 0xa4, 0x23, 0xa5, 0x60, 0x7f, - 0xe1, 0x59, 0x65, 0xfb, 0x35, 0x9d, 0x3a, 0xca, 0x8b, 0x6b, 0x3b, 0x19, - 0xbc, 0x12, 0xb1, 0xbe, 0x73, 0x54, 0x79, 0x9b, 0x57, 0x97, 0x25, 0xa9, - 0x87, 0xd1, 0x2e, 0x99, 0xed, 0x6f, 0x27, 0x8f, 0xb9, 0xca, 0x03, 0x2e, - 0x3d, 0xed, 0x1b, 0xe5, 0xd4, 0xc0, 0xc6, 0x55, 0xf5, 0xf5, 0xdd, 0xb1, - 0xcf, 0x51, 0x7b, 0x77, 0xed, 0x3d, 0x69, 0xef, 0xb9, 0xe8, 0x00, 0xef, - 0x8e, 0x44, 0x87, 0x78, 0xc7, 0x1a, 0x0e, 0xb1, 0x0f, 0xcd, 0x57, 0x56, - 0xce, 0xf4, 0xb8, 0x79, 0x21, 0x5f, 0xfd, 0xa9, 0xdc, 0x32, 0x67, 0xe4, - 0xef, 0x2e, 0xc8, 0x20, 0xf8, 0x6f, 0xee, 0xa2, 0x00, 0xfe, 0xbd, 0x65, - 0xb9, 0xa5, 0x42, 0xbc, 0xfd, 0x06, 0xf0, 0xb7, 0x35, 0x4a, 0xde, 0x74, - 0x85, 0x72, 0xf7, 0x4e, 0xd1, 0xf6, 0x69, 0x81, 0x38, 0x3f, 0x2b, 0x5c, - 0x9b, 0x7c, 0xe1, 0x19, 0xbd, 0x36, 0x07, 0x0b, 0x8b, 0xc0, 0xcf, 0xd7, - 0x41, 0xf7, 0x41, 0xb0, 0xe8, 0xe7, 0x41, 0x39, 0x7f, 0x84, 0xdf, 0xe8, - 0xbb, 0xf0, 0x1c, 0xde, 0xb7, 0x4a, 0xbe, 0x44, 0x9e, 0x8b, 0x5a, 0x1e, - 0x3e, 0x05, 0x7e, 0xba, 0x0c, 0xfd, 0xa2, 0x6c, 0x80, 0xbf, 0xff, 0x11, - 0xef, 0x70, 0x9f, 0xc3, 0x22, 0xb6, 0xd3, 0xd6, 0xe1, 0xd8, 0x5c, 0x3b, - 0xae, 0x59, 0x5c, 0xfb, 0xad, 0x8f, 0x2f, 0xaf, 0x1b, 0xd7, 0x2b, 0xd5, - 0x9b, 0x93, 0x70, 0xcd, 0x44, 0x1e, 0x2f, 0xb0, 0x3e, 0xe9, 0xff, 0x1f, - 0x62, 0x46, 0x17, 0xfc, 0xc9, 0x3a, 0x73, 0x5f, 0xdd, 0x96, 0x6b, 0x5e, - 0x4b, 0x83, 0xf4, 0x6f, 0x52, 0x83, 0x39, 0xc8, 0x9d, 0xa8, 0xd7, 0x2a, - 0x23, 0xda, 0x27, 0x22, 0x4d, 0x90, 0x06, 0x6e, 0x56, 0x86, 0x36, 0x3f, - 0xa4, 0x0c, 0x6d, 0x3e, 0x03, 0x5a, 0xc4, 0x55, 0x5c, 0x72, 0x0c, 0x6d, - 0x7e, 0x1d, 0x77, 0x5c, 0xc5, 0x0b, 0x4e, 0xc8, 0xc7, 0xc3, 0xf0, 0xf9, - 0x76, 0x15, 0xa2, 0xce, 0x78, 0x05, 0xf4, 0x5b, 0x8c, 0xa1, 0x7c, 0x81, - 0x38, 0xc7, 0xfc, 0x39, 0xce, 0x56, 0xdb, 0xff, 0xe3, 0x32, 0x51, 0x0c, - 0xb4, 0x5d, 0x95, 0x9d, 0xbb, 0x17, 0xf7, 0xf5, 0x5a, 0xce, 0x28, 0x2f, - 0xad, 0x8c, 0xbc, 0x7a, 0x17, 0xee, 0xdd, 0x89, 0x83, 0xd2, 0xed, 0x46, - 0xe4, 0x39, 0xf4, 0xf5, 0x43, 0x67, 0xa2, 0xf2, 0x32, 0xae, 0x9f, 0xe0, - 0x7a, 0x15, 0xd7, 0x2b, 0xe8, 0xf7, 0x45, 0x94, 0xaf, 0x97, 0x05, 0xb7, - 0x19, 0xf5, 0x45, 0x8d, 0x57, 0x5e, 0x70, 0xc6, 0x4e, 0xbe, 0x84, 0x2b, - 0xaa, 0x26, 0x2a, 0xcf, 0x3b, 0xd9, 0xb9, 0x60, 0xe3, 0xa2, 0x47, 0x19, - 0xf6, 0xa7, 0x8e, 0xe9, 0x7b, 0x08, 0x73, 0x00, 0x4d, 0x17, 0x17, 0x30, - 0xf6, 0x33, 0x9a, 0x67, 0x46, 0x20, 0xf3, 0xb3, 0xb0, 0x4b, 0xc6, 0x34, - 0x4c, 0x97, 0x03, 0x3e, 0xf8, 0xba, 0x03, 0xb8, 0xcf, 0x35, 0xca, 0x52, - 0x9c, 0x76, 0xe4, 0x97, 0x75, 0xfd, 0x6c, 0xb1, 0x5b, 0xe3, 0x76, 0x66, - 0x0d, 0xff, 0xd0, 0x3f, 0x0b, 0xe5, 0x81, 0x91, 0xc6, 0xb3, 0x05, 0xca, - 0x02, 0xe8, 0x9f, 0xc2, 0x14, 0xee, 0x8d, 0x5a, 0x26, 0xe4, 0x25, 0x94, - 0x07, 0x6c, 0x47, 0x99, 0x50, 0x2b, 0x77, 0x28, 0x6b, 0x28, 0x7b, 0x28, - 0x4b, 0xcc, 0x7a, 0x8c, 0x3f, 0x48, 0x19, 0x7e, 0x2d, 0xfc, 0x53, 0xda, - 0x1f, 0x9d, 0xc6, 0x07, 0x99, 0xce, 0x28, 0x23, 0x4f, 0xf7, 0xe8, 0xb5, - 0x98, 0x28, 0xa8, 0x38, 0x20, 0x47, 0x19, 0xae, 0x63, 0x7b, 0x71, 0xcf, - 0xaa, 0x09, 0x5c, 0xd9, 0x63, 0x1f, 0xc0, 0x6f, 0xae, 0xcd, 0x04, 0xea, - 0xe1, 0x2a, 0x8e, 0xe2, 0x8e, 0x0b, 0xb6, 0x99, 0x91, 0x23, 0x5c, 0xd3, - 0x84, 0x5d, 0xd3, 0x2f, 0x03, 0x0f, 0x9c, 0x9f, 0xd2, 0xf1, 0x07, 0xe5, - 0xed, 0x00, 0xde, 0x2b, 0xd6, 0xdf, 0x6d, 0x15, 0xc3, 0x83, 0xb8, 0x7a, - 0xc9, 0xcf, 0x2d, 0x66, 0xbd, 0x34, 0xed, 0x7e, 0x37, 0x6a, 0x78, 0x31, - 0x8e, 0xb2, 0x08, 0xca, 0xda, 0x45, 0xf3, 0xfe, 0x32, 0x1e, 0xd3, 0x16, - 0x8f, 0xfc, 0xad, 0xec, 0x6f, 0xd0, 0x13, 0x6c, 0xda, 0x8c, 0x37, 0x80, - 0x71, 0x31, 0x97, 0x63, 0x7b, 0xd4, 0x38, 0xe4, 0xf7, 0xb8, 0x47, 0x19, - 0xce, 0x38, 0x03, 0xe7, 0xc7, 0x7e, 0x51, 0xae, 0x71, 0xe0, 0x4b, 0xd5, - 0x87, 0xff, 0x32, 0xd6, 0xec, 0x71, 0xd9, 0x57, 0xbc, 0x5a, 0xfb, 0xd4, - 0x8d, 0x47, 0xcd, 0x7a, 0x88, 0x0a, 0xeb, 0xa1, 0xef, 0x38, 0x6d, 0x9b, - 0x31, 0xfd, 0x3e, 0x7a, 0x94, 0xbf, 0x29, 0x9f, 0x6b, 0xe5, 0xbd, 0xb1, - 0x6b, 0xf2, 0x2b, 0x64, 0x1d, 0x6d, 0x0b, 0xac, 0x59, 0xb9, 0x16, 0xef, - 0xf4, 0xf1, 0x29, 0xf3, 0xc8, 0x4f, 0x07, 0xc1, 0x13, 0xaa, 0xc1, 0xf0, - 0x3e, 0x7d, 0x8d, 0x7a, 0xfc, 0x04, 0xfb, 0x0b, 0xbc, 0x72, 0x02, 0xb6, - 0xdb, 0xae, 0xe5, 0x3e, 0x20, 0x2b, 0xe3, 0x31, 0x39, 0x59, 0x68, 0x91, - 0xb9, 0x82, 0x82, 0xc1, 0x60, 0x64, 0x67, 0x44, 0x12, 0x5a, 0xff, 0xd2, - 0xbe, 0x1b, 0x9e, 0x8e, 0x58, 0xba, 0x83, 0xc3, 0xd2, 0xfc, 0x1b, 0xd0, - 0xb1, 0x65, 0xe8, 0xd8, 0x56, 0xe8, 0xe0, 0xd5, 0x32, 0xa2, 0xab, 0x61, - 0xad, 0x8c, 0x60, 0x9b, 0x14, 0xbc, 0xf2, 0x83, 0x68, 0x17, 0xd2, 0x5f, - 0x4c, 0xd3, 0x5a, 0x56, 0x72, 0xce, 0xae, 0xca, 0x94, 0xb3, 0xbb, 0xb2, - 0x5a, 0x07, 0xf5, 0xb9, 0x51, 0x31, 0xb0, 0x9e, 0xd4, 0x71, 0xbc, 0x94, - 0x9f, 0x01, 0x4e, 0x76, 0x83, 0xee, 0x9e, 0x2e, 0xc1, 0x8f, 0xa7, 0x5c, - 0x06, 0xcc, 0x8f, 0x01, 0xe6, 0xd9, 0x92, 0x13, 0xda, 0x06, 0xc2, 0xe0, - 0xc9, 0xec, 0x74, 0xbf, 0x2c, 0xce, 0x93, 0x0e, 0x21, 0x03, 0x4a, 0x58, - 0x4f, 0x7f, 0x1d, 0xec, 0x00, 0x8e, 0x0f, 0xb9, 0x3d, 0xdd, 0xa1, 0xdf, - 0x19, 0x7d, 0xde, 0x29, 0x8b, 0xe5, 0xf7, 0x58, 0xd8, 0x0e, 0xd7, 0xc0, - 0xb6, 0x6e, 0x19, 0xb6, 0xdd, 0x80, 0x6d, 0x4f, 0x5d, 0xd8, 0xea, 0xe9, - 0xe2, 0x2e, 0xd8, 0x34, 0xe4, 0x8f, 0x10, 0xaf, 0xed, 0x96, 0x1e, 0x6e, - 0xb7, 0xf6, 0x2e, 0x6d, 0xa2, 0x9f, 0x02, 0x1e, 0xd2, 0x18, 0x7e, 0xcf, - 0x3d, 0x4a, 0x59, 0x86, 0x72, 0x3e, 0x7f, 0x06, 0x75, 0xf0, 0x3c, 0xf7, - 0xe7, 0x56, 0x0e, 0xde, 0x65, 0x61, 0xa1, 0x9d, 0x90, 0x86, 0x4d, 0x3c, - 0xe2, 0x64, 0xe6, 0x08, 0x43, 0x0e, 0xf0, 0xe2, 0x5d, 0xa5, 0xb6, 0x4f, - 0xde, 0xd9, 0xef, 0x15, 0xb6, 0x1f, 0xf6, 0x1d, 0xce, 0x65, 0xbd, 0xd5, - 0xf3, 0x21, 0x7d, 0x85, 0xf6, 0xf5, 0x94, 0x93, 0x5e, 0x33, 0xaf, 0x5a, - 0x9a, 0xa3, 0xbc, 0x8d, 0xca, 0x4e, 0xd0, 0xc9, 0xce, 0x15, 0xb4, 0xa6, - 0xdd, 0x10, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x18, 0xbe, 0xf1, 0x63, - 0xd0, 0x87, 0x94, 0x37, 0x37, 0x1b, 0xdf, 0x5c, 0x4e, 0x00, 0xd6, 0xf0, - 0x99, 0xb4, 0xc9, 0xdf, 0x94, 0x49, 0x55, 0x5a, 0x34, 0xbe, 0x4b, 0xa7, - 0x8e, 0x9f, 0x56, 0xed, 0xf5, 0xa8, 0x8c, 0x9a, 0x35, 0x3f, 0xcc, 0x35, - 0xa7, 0x2f, 0xd2, 0xfd, 0xc0, 0xa8, 0xe5, 0xaf, 0x54, 0x29, 0x27, 0xbb, - 0xed, 0xdc, 0xbf, 0x5c, 0x67, 0xed, 0x5a, 0x97, 0xd7, 0x6e, 0xb4, 0xb2, - 0x7a, 0x8e, 0x22, 0x5d, 0x0f, 0x44, 0xb5, 0x6f, 0x2b, 0xca, 0x97, 0x46, - 0x8f, 0xf2, 0x93, 0xb6, 0x12, 0xca, 0x67, 0xfb, 0xdc, 0x36, 0xd0, 0xdb, - 0x53, 0x6b, 0xec, 0xae, 0xa4, 0x95, 0x9b, 0xf4, 0x83, 0xc3, 0x31, 0x72, - 0x56, 0x4e, 0xe6, 0xd0, 0xff, 0x94, 0xb3, 0xb3, 0x52, 0x4f, 0x5e, 0x86, - 0x72, 0x92, 0xf3, 0xb9, 0x57, 0xee, 0x78, 0x90, 0x3c, 0x7a, 0xbb, 0xb6, - 0xaf, 0xaf, 0xda, 0x71, 0x00, 0xf8, 0x23, 0xfc, 0x8b, 0x9b, 0x60, 0x32, - 0x40, 0xe7, 0xa6, 0x65, 0xdc, 0xae, 0xdb, 0xf8, 0xf2, 0xfa, 0xf3, 0x6a, - 0xc7, 0x6f, 0xc6, 0x59, 0x95, 0x85, 0x59, 0xdb, 0xb1, 0xb0, 0xeb, 0x56, - 0xdb, 0xb2, 0x9c, 0x03, 0xed, 0xd9, 0x46, 0x63, 0x0b, 0x16, 0x69, 0x7f, - 0x52, 0x76, 0xd1, 0xfe, 0x8c, 0x35, 0x4a, 0x33, 0xe7, 0x33, 0x68, 0xcb, - 0x68, 0xa7, 0xae, 0x9e, 0xdf, 0x6a, 0xff, 0x91, 0x70, 0x12, 0x6e, 0x43, - 0x5b, 0x49, 0x45, 0xd8, 0x02, 0x19, 0xf5, 0xaf, 0xd5, 0x6b, 0xa0, 0x68, - 0xbb, 0xee, 0xf8, 0x76, 0x83, 0x89, 0x31, 0x27, 0xd1, 0x3f, 0xc7, 0x24, - 0xff, 0xf1, 0x4e, 0x3b, 0xbf, 0x9e, 0x2c, 0xab, 0xd5, 0x3d, 0x97, 0x2d, - 0xe3, 0x6f, 0xe7, 0x8a, 0x35, 0x0a, 0xf1, 0x17, 0xd2, 0x45, 0x2d, 0x0e, - 0x49, 0x13, 0xa4, 0x85, 0x90, 0x16, 0xb7, 0x5a, 0x7d, 0x13, 0xd2, 0xde, - 0xa5, 0xa0, 0xbd, 0xfb, 0x80, 0x27, 0xca, 0x70, 0xc6, 0xed, 0x36, 0xe3, - 0xf9, 0x08, 0x9e, 0x43, 0x3e, 0xb9, 0x98, 0x0c, 0xa7, 0xfc, 0x66, 0x9b, - 0x8c, 0x95, 0xfb, 0xa1, 0x9f, 0xcb, 0x36, 0x9c, 0x37, 0xe5, 0xff, 0x57, - 0xe9, 0x77, 0x35, 0x1a, 0x3b, 0xfd, 0x43, 0x8d, 0x94, 0xaf, 0x9b, 0xe4, - 0x60, 0x4d, 0xd9, 0xc5, 0xe4, 0x77, 0xed, 0x9c, 0x2f, 0xff, 0x7f, 0x30, - 0xe7, 0xc4, 0xaa, 0x39, 0xbb, 0x76, 0xce, 0x15, 0xbc, 0x6f, 0xc3, 0xfb, - 0x16, 0xea, 0x82, 0x64, 0x55, 0xde, 0x58, 0x5c, 0xe8, 0x79, 0xd5, 0xca, - 0x89, 0x50, 0x46, 0x70, 0x5e, 0x1f, 0xb1, 0x73, 0x78, 0xa0, 0x66, 0x5e, - 0x1f, 0x79, 0x13, 0xf3, 0xea, 0x5c, 0x31, 0xaf, 0x5d, 0x17, 0x9d, 0x57, - 0x3d, 0x1e, 0x27, 0x2f, 0x87, 0xf3, 0x8b, 0xc9, 0x8d, 0x05, 0xce, 0x71, - 0x27, 0xe6, 0x48, 0x18, 0xc2, 0x39, 0x0e, 0xd9, 0x39, 0x8a, 0xea, 0xda, - 0xf1, 0x73, 0xf8, 0x5d, 0x3b, 0x3f, 0xea, 0xfe, 0x1f, 0x83, 0xa6, 0x9b, - 0x24, 0xd3, 0xdf, 0x64, 0xe5, 0xff, 0x97, 0xe5, 0xd6, 0x22, 0xd7, 0x3a, - 0x95, 0x16, 0xd9, 0xa3, 0xf6, 0x15, 0x9f, 0x6d, 0x64, 0x8c, 0x7f, 0x97, - 0x6f, 0xf5, 0x18, 0xf4, 0xc5, 0x6e, 0xd8, 0x7c, 0x3b, 0x0b, 0x6a, 0x20, - 0x22, 0x41, 0x70, 0x9b, 0xdf, 0x8c, 0xb1, 0x37, 0x6a, 0x5f, 0x75, 0x6d, - 0x7c, 0xfd, 0x99, 0x46, 0xf1, 0x68, 0x6f, 0x50, 0x9f, 0x43, 0xdf, 0x1d, - 0xa3, 0x0d, 0x96, 0x81, 0x9d, 0x9c, 0x4e, 0x44, 0xb4, 0x2d, 0x46, 0x9d, - 0x98, 0x4a, 0xa4, 0xa5, 0x2c, 0xd9, 0x63, 0xe9, 0x84, 0x12, 0x8e, 0x01, - 0x5b, 0x0d, 0x36, 0xe4, 0xad, 0x90, 0x35, 0xb7, 0x56, 0xf6, 0xaa, 0x5b, - 0x60, 0xef, 0xdc, 0x72, 0xf2, 0x03, 0xea, 0x36, 0xd8, 0x3a, 0xb7, 0x9d, - 0xbc, 0x41, 0xed, 0x83, 0x6d, 0xb3, 0x0f, 0x76, 0xce, 0xbe, 0x0a, 0x6d, - 0xcf, 0x9b, 0x41, 0x7b, 0x9d, 0x35, 0xb4, 0x46, 0x1b, 0x87, 0xf3, 0x23, - 0xee, 0x8f, 0x71, 0x0d, 0xfc, 0xa4, 0x7a, 0x45, 0xaf, 0x4b, 0xdb, 0x8a, - 0xb2, 0xd7, 0x92, 0x55, 0xa1, 0x7e, 0xda, 0x60, 0xe3, 0x46, 0x94, 0xb7, - 0xaf, 0x45, 0x5b, 0xa4, 0x11, 0x17, 0x78, 0x26, 0xfe, 0x48, 0x5b, 0xb5, - 0xf3, 0xdf, 0xd4, 0x24, 0x5e, 0x67, 0x93, 0x34, 0xdf, 0x0b, 0xf9, 0x5a, - 0x4b, 0x53, 0xbc, 0xbb, 0x56, 0xd7, 0x90, 0xb6, 0x28, 0x83, 0x43, 0x7a, - 0xd8, 0xfa, 0x1a, 0xf2, 0xf7, 0xa2, 0xf4, 0x74, 0x4f, 0x64, 0x28, 0x08, - 0xc6, 0x07, 0x64, 0x23, 0xe3, 0x01, 0x99, 0x4a, 0x35, 0x26, 0xa0, 0xbc, - 0xda, 0x98, 0x00, 0xfd, 0xac, 0x47, 0x80, 0xdf, 0x19, 0x5c, 0x22, 0x63, - 0x8c, 0x3b, 0x54, 0x42, 0xbb, 0xfc, 0x1b, 0xd6, 0x2e, 0x0f, 0xe1, 0x48, - 0x02, 0x0e, 0x23, 0x9f, 0xd7, 0xea, 0xb9, 0x95, 0xfa, 0x3b, 0xb7, 0x6c, - 0xd3, 0x26, 0xe5, 0xc6, 0x22, 0xe7, 0x4d, 0x19, 0x4c, 0xdc, 0xd4, 0xca, - 0xe0, 0x84, 0xb5, 0xa3, 0x50, 0x47, 0xcb, 0xcf, 0xb5, 0xb2, 0x93, 0x72, - 0x8f, 0xf1, 0xf9, 0x07, 0x7c, 0xd2, 0xfa, 0x7b, 0x24, 0xbd, 0x1c, 0x9f, - 0x17, 0xd0, 0x9b, 0xf8, 0x91, 0x21, 0xbd, 0xdf, 0xe6, 0xce, 0xca, 0x6e, - 0x19, 0x8e, 0x33, 0xd6, 0xc9, 0x78, 0x9e, 0x97, 0x9b, 0x05, 0x0f, 0x4c, - 0x16, 0x15, 0x2c, 0xf8, 0x46, 0x19, 0x73, 0x03, 0xd9, 0xe5, 0x3b, 0x3a, - 0x76, 0x6c, 0x74, 0xed, 0x4c, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0xff, 0x5d, - 0x04, 0xf5, 0x2d, 0x6a, 0xfb, 0x56, 0x69, 0xfd, 0xbb, 0xa0, 0xeb, 0x7c, - 0xae, 0x29, 0x8c, 0x63, 0x2e, 0xba, 0x11, 0x5b, 0xaf, 0xb6, 0xfc, 0x8b, - 0x36, 0x3e, 0x9d, 0x84, 0xec, 0x0f, 0xcb, 0xfe, 0xb0, 0x4e, 0xd9, 0xb7, - 0xea, 0x94, 0xfd, 0xcf, 0x3a, 0x65, 0x26, 0x2e, 0xb8, 0xb3, 0xf0, 0xf7, - 0x78, 0x37, 0xa5, 0x7d, 0x77, 0xb1, 0xfb, 0x61, 0xb9, 0xe5, 0x3a, 0x1b, - 0xac, 0x5f, 0xc6, 0x18, 0xb1, 0x89, 0x0d, 0x67, 0x75, 0x6c, 0xb8, 0xcf, - 0xdd, 0xa1, 0xf4, 0x5e, 0xca, 0x7e, 0xc6, 0x19, 0xf7, 0x69, 0xbc, 0x10, - 0x27, 0x5f, 0x61, 0x0c, 0x38, 0xc7, 0xbd, 0xd8, 0xa4, 0xba, 0x18, 0x6d, - 0x57, 0x6d, 0x13, 0xb3, 0x6e, 0xb4, 0x8b, 0x5b, 0x64, 0x04, 0xb6, 0xc2, - 0xce, 0x42, 0x9b, 0xec, 0x9a, 0x1e, 0x58, 0x47, 0xbd, 0xb5, 0x7b, 0xda, - 0xf8, 0x83, 0xfb, 0xc0, 0x57, 0x69, 0x21, 0x8c, 0x29, 0x5f, 0x84, 0x36, - 0xf1, 0x5a, 0x5b, 0xf8, 0xb5, 0xfb, 0xfb, 0xa5, 0x8b, 0xf4, 0xe7, 0xc0, - 0x76, 0x78, 0xa3, 0xfd, 0x35, 0xcb, 0xc8, 0x74, 0x88, 0x2b, 0xf5, 0x33, - 0xb6, 0x8b, 0x5c, 0xa4, 0x9d, 0xb6, 0x4b, 0xe4, 0xe9, 0x65, 0x59, 0xbc, - 0x15, 0x36, 0x93, 0x04, 0x99, 0x01, 0xe9, 0x8c, 0x88, 0x8e, 0xf1, 0xf8, - 0x46, 0x36, 0xf7, 0x70, 0x6f, 0x07, 0xf4, 0x6f, 0x6c, 0x15, 0x13, 0x37, - 0x0d, 0xed, 0x94, 0x7a, 0xb4, 0x7b, 0x9d, 0xa5, 0x5d, 0xee, 0xb9, 0xee, - 0xa6, 0xcc, 0xd5, 0x6b, 0x42, 0x3a, 0xde, 0x55, 0x90, 0x64, 0x48, 0xc7, - 0x8b, 0x92, 0x5e, 0x41, 0xc7, 0x8b, 0x32, 0xa4, 0xe9, 0xb8, 0x71, 0x05, - 0x1d, 0x77, 0x5a, 0x3a, 0xde, 0x13, 0x33, 0x74, 0xa1, 0xb4, 0x9e, 0x22, - 0x9d, 0x1a, 0x3a, 0x76, 0x34, 0x1d, 0x2f, 0xe2, 0x1e, 0xf5, 0xae, 0xb3, - 0x75, 0x22, 0xb6, 0x8c, 0xbf, 0xc3, 0x32, 0xca, 0xc5, 0x4f, 0xc6, 0x8c, - 0x5e, 0x1a, 0x02, 0x1d, 0x85, 0xe5, 0xfb, 0x6d, 0xfc, 0xa0, 0xb6, 0xcc, - 0xc4, 0x47, 0x76, 0x16, 0xc6, 0x62, 0x2b, 0xe9, 0x73, 0x08, 0xf4, 0x19, - 0xd6, 0x79, 0x2d, 0xfa, 0x6c, 0xb6, 0xfb, 0x16, 0x71, 0xbd, 0x2f, 0x9f, - 0x8e, 0x1b, 0x5a, 0xbd, 0x45, 0xcf, 0x9d, 0xf3, 0x3e, 0xfb, 0x06, 0x68, - 0xd5, 0xac, 0xcd, 0xb9, 0xaa, 0xbf, 0xcd, 0x58, 0x54, 0xd2, 0xc4, 0xb0, - 0x19, 0x27, 0xbd, 0x98, 0xed, 0x68, 0xe4, 0x53, 0x83, 0x96, 0x4f, 0xad, - 0x63, 0xcc, 0x35, 0xa8, 0xca, 0xec, 0x01, 0xe8, 0x0a, 0xda, 0xd8, 0x5a, - 0x4e, 0xe3, 0x5d, 0x67, 0x32, 0x53, 0x78, 0x35, 0x88, 0x78, 0x8c, 0x0f, - 0x71, 0x5f, 0x40, 0xc6, 0x1c, 0x94, 0x75, 0x95, 0xcd, 0xbc, 0x94, 0xd7, - 0x8a, 0xe7, 0x01, 0xe9, 0x2a, 0x2b, 0xf9, 0xe8, 0x74, 0x8b, 0xec, 0x2f, - 0x44, 0xe5, 0xe3, 0x68, 0xff, 0xb1, 0x82, 0x0b, 0x7f, 0xfc, 0x4c, 0x8c, - 0x76, 0xe1, 0xbe, 0x02, 0xf7, 0x27, 0x59, 0x37, 0xbe, 0x6a, 0x7f, 0x36, - 0x22, 0x5d, 0x3d, 0x79, 0x78, 0x2a, 0x12, 0xdd, 0x03, 0x38, 0x9a, 0x86, - 0x86, 0xe4, 0x07, 0x03, 0x1b, 0x51, 0xf6, 0xb2, 0x1d, 0x6f, 0xd4, 0x31, - 0xf1, 0xde, 0x41, 0x79, 0x77, 0x65, 0x48, 0xae, 0xaf, 0x98, 0x3d, 0xd5, - 0xea, 0x9e, 0x69, 0xca, 0x5d, 0x80, 0xfe, 0x49, 0xbb, 0x41, 0x70, 0xce, - 0xc3, 0xaa, 0x1f, 0x89, 0x4a, 0xac, 0x27, 0x95, 0x58, 0x10, 0xf3, 0x7c, - 0xbe, 0xfc, 0x0f, 0xc1, 0x58, 0x3c, 0x2a, 0x3f, 0xf0, 0x38, 0xc7, 0x41, - 0xb9, 0xae, 0x5c, 0x3b, 0x36, 0x97, 0xf3, 0x0f, 0x63, 0xdc, 0xa7, 0xc8, - 0x54, 0x16, 0x62, 0x8c, 0xa5, 0xd3, 0xe7, 0xe8, 0x7a, 0x1b, 0xfc, 0x38, - 0x48, 0xee, 0xae, 0xb7, 0x81, 0x6e, 0xe2, 0xd0, 0xf9, 0x57, 0x01, 0xc6, - 0xab, 0x18, 0xfb, 0x62, 0xcc, 0x8b, 0xcf, 0x5f, 0xc7, 0xb8, 0x6c, 0xfb, - 0x1b, 0xd6, 0x5e, 0xe6, 0xfa, 0x1b, 0xde, 0xa9, 0xaf, 0x77, 0x5a, 0xc7, - 0x62, 0x43, 0xe2, 0xc4, 0xde, 0x91, 0x90, 0x75, 0x5e, 0xed, 0xf8, 0xdc, - 0x27, 0x86, 0xc5, 0x38, 0x20, 0xd1, 0xdd, 0xdb, 0x07, 0x65, 0x04, 0xf3, - 0xdb, 0xb9, 0x66, 0x7e, 0xf7, 0x08, 0xe3, 0xab, 0xe7, 0x0b, 0x9c, 0x43, - 0x75, 0x5e, 0xea, 0x0b, 0x66, 0x5e, 0xb1, 0x9e, 0xd5, 0xf3, 0xd1, 0xed, - 0xd5, 0x09, 0xc0, 0xf2, 0x35, 0x9d, 0x57, 0x10, 0x04, 0x6f, 0xed, 0x39, - 0x1f, 0x24, 0x2f, 0x49, 0xf5, 0x2e, 0x54, 0xf7, 0x77, 0xc6, 0x22, 0x43, - 0x69, 0xad, 0xcf, 0xf0, 0x9c, 0xcc, 0x96, 0xd3, 0x58, 0x47, 0x89, 0x66, - 0xfb, 0xa3, 0x9a, 0x4f, 0xb2, 0x5e, 0xda, 0xee, 0x61, 0x85, 0x3e, 0x54, - 0x10, 0x28, 0x6f, 0xb5, 0xdc, 0xa0, 0xbe, 0xc2, 0xdc, 0xe5, 0xdf, 0xda, - 0x1c, 0x96, 0x5e, 0xc6, 0xb3, 0xc6, 0xa2, 0x43, 0xb1, 0x64, 0xbe, 0xec, - 0xe1, 0x77, 0x0b, 0xee, 0x3b, 0x60, 0xaf, 0xf8, 0xb0, 0x67, 0x24, 0xae, - 0x8c, 0x6c, 0x00, 0x2d, 0xf7, 0xe4, 0x94, 0x22, 0x6f, 0xba, 0xc9, 0xc9, - 0x72, 0x3c, 0x59, 0x2a, 0x7f, 0x96, 0xed, 0x51, 0xb7, 0x5e, 0x2c, 0xcf, - 0xc8, 0x86, 0xa7, 0x2a, 0x1c, 0x83, 0xfe, 0xef, 0x1b, 0x19, 0x23, 0x6a, - 0xfb, 0x66, 0x9f, 0x21, 0x5e, 0xa2, 0x74, 0xc9, 0xf1, 0x2f, 0x6d, 0x7d, - 0x13, 0xce, 0xef, 0xb3, 0x16, 0xee, 0xd5, 0xe3, 0xbe, 0xa0, 0xed, 0x97, - 0xd3, 0x15, 0xda, 0x8c, 0xdc, 0xdf, 0x49, 0x1d, 0x9f, 0x11, 0xc2, 0x11, - 0x04, 0xcf, 0xf9, 0x46, 0x77, 0x3f, 0x55, 0xe1, 0x1e, 0x47, 0x10, 0xfc, - 0x88, 0x76, 0xf1, 0xde, 0x22, 0xc6, 0x0b, 0x71, 0xb0, 0x35, 0x17, 0x85, - 0x5c, 0x9c, 0x1a, 0x20, 0x7e, 0x05, 0x1e, 0x6a, 0x8f, 0x7b, 0xa3, 0xc4, - 0x92, 0x9f, 0x2a, 0xb7, 0x24, 0x3f, 0x5d, 0x76, 0x81, 0x67, 0xce, 0x3b, - 0x9e, 0x9c, 0xb0, 0x73, 0xce, 0x96, 0x89, 0xdf, 0xd7, 0xda, 0x87, 0x7c, - 0x61, 0x85, 0xbf, 0x44, 0x98, 0xaa, 0xb0, 0x10, 0xb6, 0xa4, 0xc5, 0x4d, - 0x10, 0xfc, 0xd8, 0x37, 0x6b, 0x3a, 0x55, 0x94, 0x29, 0x8c, 0x9b, 0xdb, - 0xac, 0x88, 0x87, 0x58, 0xf2, 0x0e, 0x8c, 0xfd, 0x29, 0x8c, 0xbd, 0xbf, - 0xcc, 0xf1, 0x20, 0x2b, 0x30, 0xf7, 0xa9, 0x4a, 0x08, 0x6f, 0xbd, 0xb1, - 0xc3, 0x35, 0xef, 0xb5, 0x36, 0x5e, 0xf8, 0xac, 0x11, 0xd9, 0xae, 0xbc, - 0x7e, 0xd0, 0xd7, 0xe2, 0xa6, 0xa8, 0xfc, 0x22, 0xe4, 0x6e, 0x20, 0x8f, - 0x42, 0x9e, 0x2d, 0x6a, 0xba, 0xc9, 0x5c, 0xce, 0xff, 0x23, 0xf2, 0xeb, - 0xeb, 0x18, 0x5f, 0x1e, 0xf6, 0x68, 0xbb, 0x2e, 0x05, 0x8b, 0x1e, 0xe5, - 0xf3, 0x06, 0x99, 0x71, 0x73, 0xbd, 0xd0, 0x15, 0x28, 0x6b, 0xa5, 0xbf, - 0x9d, 0xcc, 0x44, 0x52, 0xc9, 0x49, 0x61, 0x3e, 0x14, 0x73, 0x15, 0x98, - 0x23, 0x44, 0xd9, 0x10, 0x85, 0xcc, 0xe3, 0x1a, 0x9a, 0xf1, 0x26, 0xcb, - 0xd5, 0xba, 0x07, 0x84, 0x7b, 0x86, 0xa9, 0xc4, 0x3e, 0x6d, 0x9f, 0x88, - 0x8c, 0x17, 0x58, 0x77, 0x3b, 0xac, 0x13, 0xaf, 0xa6, 0xbe, 0xce, 0xe1, - 0x02, 0x9f, 0x87, 0x71, 0xac, 0x58, 0x2c, 0x53, 0x90, 0x97, 0x23, 0x03, - 0xf2, 0x32, 0xed, 0xce, 0x61, 0xd0, 0xb6, 0xeb, 0xf1, 0xbd, 0x29, 0xcf, - 0xf8, 0xb2, 0x94, 0x19, 0xec, 0xa3, 0x9d, 0x9d, 0x53, 0x9a, 0x27, 0x44, - 0xa1, 0x6d, 0x2c, 0x5b, 0x96, 0x91, 0x6c, 0xc1, 0xc6, 0x7a, 0x46, 0x39, - 0xe7, 0x0d, 0x35, 0x73, 0x6f, 0x95, 0x28, 0x60, 0x1a, 0x89, 0x24, 0x9d, - 0x06, 0xef, 0x23, 0x2d, 0x46, 0xe7, 0x43, 0xee, 0xb7, 0xdd, 0xdf, 0xce, - 0x3d, 0x53, 0x05, 0x1f, 0x5a, 0xb5, 0xdf, 0x7e, 0x8d, 0x1a, 0xfa, 0xf3, - 0x04, 0xf4, 0xa0, 0x95, 0x95, 0xb1, 0x91, 0xae, 0x65, 0xfa, 0xe6, 0xf8, - 0xd2, 0x1e, 0xf1, 0x92, 0x23, 0xc3, 0x65, 0x51, 0x91, 0x21, 0x37, 0x36, - 0x5c, 0x5e, 0x49, 0xf3, 0x4f, 0x55, 0xfe, 0xbd, 0xb5, 0x05, 0x6b, 0x63, - 0xaa, 0xb5, 0xef, 0xc8, 0x77, 0x2b, 0xf6, 0x2b, 0x92, 0x26, 0x07, 0x86, - 0xfb, 0xb4, 0x5c, 0x93, 0xf4, 0x5b, 0x1b, 0xa0, 0x7c, 0x66, 0xb4, 0x8f, - 0xc6, 0x9c, 0x8b, 0x98, 0xcd, 0x3d, 0x33, 0xb8, 0x4e, 0x97, 0x1d, 0x99, - 0x82, 0x7c, 0x38, 0x20, 0x7f, 0x1f, 0xa4, 0xe3, 0xe6, 0xbd, 0x59, 0x5f, - 0xd6, 0xe7, 0x5e, 0x44, 0xb3, 0xe4, 0x4f, 0x46, 0x25, 0x77, 0x92, 0x7b, - 0x60, 0xcf, 0xed, 0xaf, 0xe6, 0x6d, 0x50, 0x0e, 0x70, 0xbf, 0xd6, 0x91, - 0x3c, 0xfc, 0xda, 0x11, 0xee, 0xc3, 0xf7, 0xff, 0x1f, 0xf4, 0xc1, 0x7a, - 0x61, 0xdb, 0x16, 0xb4, 0x6d, 0xb4, 0x6d, 0x47, 0xef, 0x78, 0x73, 0x6d, - 0x5b, 0xd1, 0x36, 0x16, 0x8e, 0xfb, 0x06, 0xdb, 0x6a, 0x7c, 0x5e, 0x33, - 0x5c, 0x28, 0x2e, 0xc1, 0x4f, 0x4e, 0x4c, 0x48, 0xda, 0x19, 0x1f, 0xd0, - 0xf3, 0xb9, 0x66, 0xb8, 0x0c, 0x38, 0xe2, 0x41, 0x90, 0xf7, 0x43, 0x3d, - 0xcc, 0x7f, 0xc7, 0x44, 0x3c, 0x96, 0x71, 0xdf, 0x92, 0xfe, 0x04, 0xa3, - 0xa4, 0x2e, 0xf3, 0xd9, 0x24, 0xcf, 0xfd, 0xc9, 0xf8, 0x46, 0xdc, 0x55, - 0x17, 0x71, 0x92, 0xf5, 0x18, 0xef, 0xdd, 0x68, 0xcb, 0x23, 0x2c, 0x4f, - 0x45, 0x21, 0x4b, 0x4c, 0x79, 0xc4, 0x96, 0x03, 0x26, 0x3f, 0x9f, 0x04, - 0xb7, 0xd9, 0x72, 0x3e, 0x2b, 0x5d, 0x6e, 0x9e, 0x0d, 0x0f, 0x8d, 0x09, - 0xe3, 0x3a, 0x99, 0xeb, 0x1a, 0x64, 0x2b, 0xd6, 0x87, 0x3e, 0xa3, 0x23, - 0xcd, 0x80, 0xe3, 0x9c, 0xff, 0x76, 0xd8, 0xd6, 0x81, 0xfc, 0xc0, 0x37, - 0xf4, 0x3f, 0x2b, 0x3d, 0x69, 0xe5, 0x30, 0x07, 0x20, 0x90, 0x9d, 0xfe, - 0xb6, 0xc4, 0x2e, 0xfc, 0x1e, 0xef, 0x4f, 0xca, 0xec, 0x20, 0xe8, 0xb1, - 0x9f, 0xbc, 0xb1, 0x15, 0x36, 0x0f, 0x7e, 0xf7, 0xb4, 0xc8, 0x92, 0x9b, - 0x73, 0xd7, 0xc1, 0x5f, 0x1b, 0xc1, 0xac, 0xe6, 0x0a, 0x9e, 0x7b, 0x1b, - 0x84, 0x5c, 0xda, 0xed, 0xc1, 0xbd, 0x76, 0xbe, 0xdf, 0xc2, 0x7c, 0x7f, - 0xad, 0x59, 0x9a, 0x59, 0x5e, 0x5b, 0xb7, 0x51, 0xf6, 0xb8, 0xdb, 0xdd, - 0xd8, 0x8a, 0xba, 0xe7, 0x51, 0x97, 0x65, 0x9e, 0xcb, 0x1c, 0x9d, 0xd9, - 0x32, 0xe9, 0xcc, 0xc0, 0xda, 0xd5, 0x13, 0x04, 0xd7, 0xf9, 0x1c, 0x37, - 0x08, 0xae, 0xf7, 0xfb, 0xdc, 0x67, 0xe5, 0xf9, 0xc0, 0xd8, 0x54, 0x21, - 0xed, 0x3c, 0x67, 0xe5, 0x75, 0x10, 0xbc, 0xec, 0xf7, 0xca, 0xef, 0x54, - 0x52, 0x8f, 0xd3, 0xe7, 0x3e, 0x83, 0xe7, 0x33, 0xbe, 0xc9, 0x2b, 0xfa, - 0x13, 0xb4, 0x8b, 0xab, 0x7e, 0xd0, 0xb0, 0x27, 0x5f, 0xd4, 0x3e, 0x3a, - 0xf1, 0x67, 0x62, 0xfc, 0x55, 0x18, 0x30, 0x61, 0x2f, 0xb3, 0xc9, 0x65, - 0x7e, 0xa0, 0xa6, 0xdf, 0xda, 0x77, 0x0a, 0xef, 0x58, 0x16, 0x04, 0x97, - 0x0c, 0xfc, 0x31, 0xe6, 0x94, 0x2a, 0x71, 0xef, 0xee, 0x03, 0x9a, 0xff, - 0x04, 0x7e, 0x3d, 0xe9, 0x24, 0xea, 0x2a, 0xe5, 0x1d, 0xee, 0x52, 0xa9, - 0x9c, 0xc8, 0x5b, 0xb0, 0xfe, 0x5c, 0x63, 0x30, 0x48, 0x1b, 0x60, 0xdf, - 0xb6, 0xbd, 0xd9, 0xc4, 0x92, 0xe8, 0x4b, 0xa7, 0x37, 0xc1, 0xd7, 0xd5, - 0xf6, 0x4c, 0x14, 0x7c, 0x3d, 0xd1, 0x16, 0x04, 0xef, 0xf7, 0xc3, 0x35, - 0xb3, 0xb1, 0x6a, 0xe8, 0xf8, 0x6c, 0xff, 0xb9, 0x66, 0x63, 0xc7, 0x31, - 0x4f, 0x30, 0xa9, 0xe3, 0xfa, 0xaa, 0x1d, 0x3a, 0x64, 0xdb, 0x57, 0x39, - 0x7e, 0x8e, 0xe5, 0xef, 0xf3, 0x43, 0x98, 0xaa, 0xed, 0xb3, 0xfd, 0xeb, - 0xac, 0xcd, 0x19, 0x05, 0x2e, 0x3d, 0xb7, 0x4b, 0xfd, 0x4d, 0x60, 0x74, - 0x6b, 0x48, 0xc3, 0x7f, 0x17, 0x3c, 0x18, 0x37, 0xcf, 0x99, 0x6d, 0xec, - 0x63, 0xab, 0x4c, 0x6e, 0xc3, 0x73, 0xf4, 0x5a, 0xdc, 0x87, 0x2f, 0x8b, - 0xc8, 0x15, 0x89, 0x61, 0xb5, 0xcd, 0x7d, 0x50, 0xfa, 0xac, 0x8c, 0xfb, - 0x1a, 0xf4, 0x7d, 0x0e, 0xfe, 0x78, 0x93, 0x3c, 0x08, 0x9a, 0x56, 0x03, - 0xa9, 0xe4, 0x82, 0x4a, 0xf5, 0xce, 0xa8, 0x94, 0x3f, 0xa6, 0xae, 0xe7, - 0xbc, 0x06, 0x89, 0x8b, 0x19, 0xe2, 0xb7, 0x08, 0xfc, 0x17, 0x81, 0xe3, - 0x8b, 0xee, 0xf1, 0xfa, 0x56, 0xb7, 0x18, 0xfd, 0x96, 0xd3, 0xb4, 0x69, - 0xec, 0xf2, 0x3f, 0xf6, 0xc3, 0x35, 0x84, 0x6d, 0xc8, 0x1c, 0x99, 0xba, - 0x6b, 0x94, 0xe5, 0x1a, 0x41, 0x31, 0xe4, 0x40, 0xf7, 0xa9, 0xe4, 0x84, - 0x5a, 0x0a, 0x36, 0xed, 0xe8, 0xee, 0x7d, 0x42, 0xf7, 0x93, 0xf2, 0xd3, - 0x2a, 0x0f, 0x78, 0xb6, 0x4a, 0xd3, 0x0e, 0xe2, 0x99, 0xb0, 0xc6, 0x18, - 0x4f, 0x72, 0xef, 0x40, 0xdd, 0x31, 0xa5, 0xf7, 0xa0, 0x6d, 0x1d, 0xc2, - 0x1c, 0x5f, 0x2f, 0xcd, 0xd4, 0x43, 0x8c, 0x93, 0xbd, 0x96, 0x2e, 0x84, - 0x4c, 0x3a, 0x46, 0x19, 0x18, 0x31, 0xb1, 0xdf, 0xca, 0xcf, 0xa1, 0x9d, - 0xce, 0x67, 0x89, 0x45, 0x21, 0xa3, 0xa6, 0xc0, 0xc5, 0x87, 0x8e, 0x49, - 0xb4, 0xc1, 0xfb, 0x5f, 0xcd, 0xc6, 0x6f, 0xa2, 0x0f, 0xc5, 0xb1, 0x1b, - 0x24, 0xbf, 0x26, 0xde, 0x52, 0x02, 0xfc, 0xcd, 0x32, 0x79, 0x8c, 0x6b, - 0x11, 0x85, 0xcc, 0xe1, 0xd8, 0x12, 0xcd, 0xf4, 0x07, 0xc1, 0x38, 0xcb, - 0x4f, 0x92, 0x7f, 0x25, 0xc5, 0x77, 0xb9, 0x93, 0x0b, 0x9b, 0xd4, 0x0a, - 0x59, 0xdb, 0x62, 0xe1, 0xd0, 0x78, 0x92, 0x92, 0x96, 0x23, 0xd4, 0x37, - 0xb7, 0xd5, 0xc0, 0x33, 0x7a, 0xc7, 0x94, 0xd7, 0xf8, 0x26, 0xe0, 0xf9, - 0x3d, 0xc0, 0xd3, 0x62, 0xe1, 0x69, 0x5c, 0x05, 0x4f, 0x4b, 0x08, 0x0f, - 0xe4, 0x1c, 0xe5, 0x6a, 0xec, 0x9a, 0x74, 0x59, 0x9c, 0xbc, 0x27, 0x9d, - 0x4a, 0xfb, 0x2f, 0xd4, 0x37, 0x8d, 0xee, 0xf8, 0x80, 0x2b, 0xe3, 0x5a, - 0xd7, 0x44, 0xaf, 0xe9, 0x2e, 0x2f, 0xc0, 0x7a, 0x15, 0x27, 0xe3, 0x11, - 0xf6, 0x7a, 0x76, 0xd5, 0x3d, 0x90, 0xff, 0x8b, 0xa9, 0xa8, 0xb5, 0x25, - 0x4a, 0x3e, 0xfd, 0x96, 0xb8, 0xde, 0xdb, 0xaf, 0xc2, 0xf4, 0x12, 0x60, - 0x82, 0x3c, 0x3e, 0xd6, 0xe7, 0x8e, 0xca, 0xa5, 0xda, 0x37, 0xb3, 0xb8, - 0xc6, 0xdc, 0x62, 0x35, 0x73, 0x83, 0xfe, 0x53, 0xe1, 0xdc, 0x20, 0x13, - 0x51, 0xaf, 0x24, 0xf7, 0x5b, 0x5c, 0xb4, 0x62, 0x4e, 0xb1, 0x9a, 0xf9, - 0x74, 0x27, 0xf6, 0xb3, 0xcc, 0xcc, 0xa7, 0x27, 0xef, 0xc5, 0x2c, 0x7e, - 0x57, 0xc3, 0x58, 0xf5, 0x17, 0x67, 0x24, 0x90, 0x29, 0x1f, 0x6b, 0xd4, - 0x4b, 0xff, 0x24, 0x66, 0xf3, 0x98, 0x15, 0x9e, 0x37, 0x58, 0xfe, 0x72, - 0x25, 0xaf, 0xfd, 0xb7, 0x2f, 0xad, 0x37, 0x7c, 0x1a, 0xb5, 0xf9, 0x6b, - 0xfc, 0xdd, 0xb1, 0xde, 0xee, 0xef, 0xe7, 0xd2, 0xf2, 0xfb, 0xeb, 0x69, - 0x97, 0x34, 0x78, 0x43, 0xab, 0xca, 0x62, 0x28, 0xbb, 0x7d, 0xbd, 0x95, - 0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1a, 0xf3, 0x34, 0xf8, 0x8e, 0x32, 0xb8, - 0x16, 0x27, 0x7d, 0x60, 0x45, 0xf2, 0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc, - 0x51, 0x7d, 0x27, 0x8c, 0xa3, 0xe3, 0x77, 0x3d, 0xdb, 0x9f, 0xf8, 0x26, - 0xae, 0xe5, 0xdb, 0x53, 0xe0, 0xfb, 0x03, 0xbe, 0x13, 0x9d, 0x65, 0x1e, - 0x80, 0xa6, 0xe1, 0xda, 0xbe, 0xaf, 0x47, 0xdf, 0x21, 0x2d, 0x93, 0x5e, - 0xae, 0xd7, 0x74, 0xd3, 0x44, 0x5d, 0x7c, 0x8c, 0xf4, 0xc7, 0x58, 0x72, - 0xb3, 0xd6, 0x8f, 0xd5, 0x75, 0x6c, 0x82, 0xae, 0x89, 0x1b, 0x1e, 0x75, - 0xcd, 0x7e, 0x77, 0xb5, 0xbf, 0x31, 0xf4, 0x47, 0x3b, 0x0d, 0x7e, 0xba, - 0xc7, 0x68, 0x0e, 0xe5, 0x97, 0x13, 0x55, 0x57, 0x6a, 0x3f, 0x33, 0xa6, - 0xf3, 0x8e, 0x96, 0xeb, 0x4e, 0xd8, 0xb1, 0x49, 0xb7, 0x26, 0xfe, 0x5f, - 0x1d, 0x5f, 0x1c, 0xb5, 0x4d, 0x40, 0x65, 0x8d, 0x32, 0x35, 0x40, 0x1a, - 0xe5, 0xdc, 0xb5, 0x0d, 0x75, 0x0d, 0xed, 0x08, 0x43, 0x9f, 0xb4, 0x9d, - 0xa2, 0xd7, 0x64, 0x0b, 0x8d, 0xc6, 0x67, 0x89, 0xcb, 0xe6, 0x06, 0x9d, - 0x47, 0x80, 0xb2, 0x72, 0xa8, 0xcb, 0xa2, 0x32, 0xdb, 0xff, 0xbf, 0x83, - 0xf4, 0x5e, 0xd6, 0xad, 0xbb, 0x6f, 0x9f, 0x98, 0x11, 0x8d, 0xa7, 0xbf, - 0xa8, 0xe2, 0xc9, 0xce, 0x2d, 0xbe, 0x7a, 0x6e, 0x05, 0xc0, 0x7b, 0x0f, - 0x64, 0x27, 0xd7, 0xc9, 0xe4, 0x6f, 0x3f, 0x2e, 0x4e, 0x34, 0xd3, 0x5b, - 0x6f, 0x6e, 0xa5, 0x10, 0xaf, 0x9c, 0x1b, 0x68, 0x35, 0x9c, 0x17, 0x69, - 0x3b, 0xae, 0xf7, 0x89, 0x94, 0x22, 0x2c, 0xad, 0xab, 0x70, 0x1b, 0xd2, - 0x9d, 0xa1, 0xb9, 0xa7, 0x34, 0xcd, 0xb5, 0x58, 0x9a, 0x43, 0x5d, 0x97, - 0xfb, 0xde, 0xa3, 0x2d, 0x55, 0x9a, 0xdb, 0x60, 0x69, 0xee, 0x99, 0xf5, - 0x66, 0x4f, 0xfc, 0xfd, 0x2d, 0x66, 0x4f, 0xea, 0x2f, 0x57, 0x3d, 0x6f, - 0xa2, 0xcd, 0x08, 0x5f, 0x2c, 0x7c, 0xae, 0x85, 0xf5, 0x0c, 0x60, 0xad, - 0x95, 0x35, 0x4d, 0x36, 0xee, 0xc6, 0xfd, 0x73, 0xfa, 0x7d, 0x51, 0x79, - 0x14, 0x76, 0x50, 0xbe, 0xfc, 0x8f, 0xc1, 0x02, 0x7c, 0xbf, 0xa9, 0x65, - 0xdd, 0x7b, 0x5b, 0x0b, 0xf9, 0x6d, 0x06, 0xbf, 0x0e, 0xd6, 0xf8, 0x3c, - 0x98, 0x2f, 0xca, 0xfe, 0x01, 0xeb, 0x01, 0xb9, 0xbc, 0x5c, 0x97, 0x31, - 0x0b, 0xe3, 0xe3, 0x30, 0x66, 0x68, 0xf6, 0x13, 0x29, 0xe7, 0xef, 0x84, - 0x4f, 0x74, 0x0f, 0xf4, 0x24, 0xe9, 0xfb, 0xa5, 0x16, 0x93, 0xe7, 0x1b, - 0x87, 0x1e, 0xfb, 0x65, 0x9b, 0x0b, 0x75, 0xf8, 0x57, 0xeb, 0xe7, 0xf8, - 0x82, 0xf6, 0x1d, 0xd2, 0xcc, 0xdf, 0xb7, 0x98, 0x98, 0xf1, 0xb7, 0x5a, - 0xc8, 0x67, 0x6a, 0xdb, 0x0f, 0x37, 0x68, 0xbe, 0x70, 0xc2, 0xe7, 0xcf, - 0xb4, 0xae, 0x7c, 0x0e, 0xdb, 0x3d, 0xd9, 0xba, 0xb2, 0x5d, 0x58, 0xfe, - 0x73, 0x1b, 0x57, 0x96, 0x5f, 0xe3, 0xae, 0x6c, 0xff, 0xf5, 0x55, 0xcf, - 0x2d, 0x9b, 0x56, 0x3e, 0x5f, 0xbd, 0xea, 0x79, 0x6a, 0xd5, 0xf3, 0x85, - 0x55, 0xcf, 0x57, 0xb5, 0xad, 0x7c, 0xbe, 0xbd, 0xad, 0x3e, 0xbc, 0x87, - 0xdb, 0x56, 0xc2, 0x75, 0xa7, 0x8e, 0xf7, 0xcf, 0x54, 0xa2, 0xb2, 0xab, - 0x80, 0xf7, 0x4e, 0xe7, 0x66, 0xa3, 0xd7, 0x6a, 0xdf, 0x33, 0xbe, 0xf6, - 0xd7, 0xab, 0xfa, 0xab, 0xb6, 0xdb, 0x5d, 0x6d, 0xe7, 0x57, 0xdb, 0x19, - 0xd9, 0x36, 0x5b, 0xe1, 0x3b, 0x96, 0x87, 0xfd, 0x9a, 0xb6, 0x53, 0xc5, - 0x4e, 0x9d, 0x0b, 0x3b, 0xaa, 0x73, 0x61, 0x93, 0xe0, 0xc3, 0x3b, 0x75, - 0x4c, 0x69, 0x93, 0x42, 0x79, 0xa5, 0x55, 0xc7, 0x95, 0x74, 0x2c, 0xb5, - 0x30, 0x0a, 0xdb, 0x96, 0x39, 0xb0, 0x81, 0xec, 0xf1, 0xcd, 0xdd, 0xe4, - 0xc4, 0x1e, 0x0e, 0x86, 0xdd, 0x20, 0x98, 0xf4, 0x6e, 0xb3, 0xf9, 0x62, - 0xb8, 0x57, 0x4c, 0x1b, 0xea, 0xe0, 0x27, 0xa0, 0x83, 0xab, 0xba, 0xf7, - 0x4e, 0x8c, 0xb5, 0x00, 0x9a, 0x19, 0x90, 0xdf, 0xad, 0xa4, 0xbe, 0x24, - 0xfa, 0xcc, 0x4d, 0x3f, 0x6c, 0xb8, 0xa5, 0x4f, 0xbd, 0xdf, 0xf3, 0x61, - 0xeb, 0x05, 0xf2, 0xb0, 0x3f, 0x08, 0x1a, 0xea, 0x85, 0xbd, 0xe7, 0x69, - 0xbf, 0xf4, 0xb4, 0xa6, 0x2d, 0xd2, 0x58, 0x8b, 0xce, 0xd7, 0x7f, 0xd4, - 0x77, 0x62, 0x99, 0xfe, 0x3f, 0x32, 0x71, 0x1a, 0xbf, 0xdb, 0xfd, 0x1a, - 0xf8, 0x76, 0xa7, 0xb7, 0x05, 0x3e, 0x0a, 0x69, 0x88, 0xf1, 0xaf, 0xcb, - 0x75, 0x1e, 0x21, 0x03, 0x68, 0x33, 0x51, 0xc6, 0x09, 0x53, 0x83, 0x63, - 0xc2, 0x79, 0xa7, 0x12, 0x49, 0xa5, 0xed, 0xaa, 0xe0, 0x46, 0x9f, 0x39, - 0xb6, 0xdc, 0x63, 0x21, 0x3f, 0xef, 0xff, 0xf4, 0x94, 0x97, 0x73, 0x23, - 0x36, 0x2f, 0x37, 0x53, 0x30, 0xb4, 0x39, 0x41, 0xda, 0x84, 0x3f, 0xb5, - 0xd8, 0xff, 0xb7, 0x01, 0xed, 0xfb, 0xa4, 0x22, 0xed, 0xff, 0x4d, 0x30, - 0x17, 0x65, 0x5f, 0x84, 0x7b, 0xff, 0xa7, 0x33, 0x1a, 0x57, 0x77, 0xca, - 0x81, 0x22, 0x6d, 0xe1, 0x98, 0xce, 0xe7, 0x18, 0xf7, 0x69, 0xa7, 0xc5, - 0x80, 0xc7, 0x0f, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x47, 0x50, 0x27, 0x22, - 0x63, 0x60, 0xf1, 0xd9, 0x02, 0xf9, 0x93, 0xf7, 0x28, 0xea, 0xbb, 0x32, - 0x5f, 0xb8, 0x59, 0xe7, 0xdb, 0x9d, 0x46, 0xdb, 0x27, 0x71, 0xcd, 0x16, - 0x26, 0xd0, 0x66, 0xaf, 0xae, 0x3f, 0x5b, 0x62, 0x8e, 0xb2, 0x40, 0x2e, - 0xed, 0x97, 0xfc, 0x5c, 0x97, 0x8c, 0xc5, 0x17, 0x66, 0xa2, 0xcb, 0x71, - 0x99, 0x8f, 0x6f, 0xe0, 0x1e, 0x47, 0xfe, 0x4a, 0xee, 0x07, 0x4b, 0x74, - 0x74, 0xbb, 0xea, 0x6d, 0xd3, 0x3e, 0xd7, 0xa0, 0xec, 0xac, 0x0c, 0xc9, - 0x4d, 0x95, 0xcf, 0x6e, 0x36, 0xb1, 0xa8, 0x15, 0xf1, 0xad, 0xc3, 0xc4, - 0x8a, 0x3a, 0x1a, 0xe5, 0xb9, 0x25, 0x99, 0x3d, 0x25, 0x12, 0x39, 0x1a, - 0xc6, 0x12, 0x59, 0xe6, 0x4a, 0xd7, 0x95, 0x80, 0xeb, 0x14, 0x64, 0x6b, - 0x3c, 0x26, 0x5f, 0xdc, 0x16, 0x8e, 0x95, 0x0b, 0xa6, 0xb7, 0xe5, 0xe4, - 0xd3, 0xb8, 0xb2, 0x57, 0xa6, 0x4a, 0x19, 0xc5, 0x71, 0xbf, 0x13, 0x50, - 0x96, 0xa9, 0x21, 0x4f, 0x72, 0x6d, 0xe1, 0xd8, 0xf0, 0x6f, 0x76, 0x84, - 0xe3, 0xd3, 0xe6, 0x36, 0x67, 0x1e, 0xf2, 0xdc, 0x77, 0x01, 0xfd, 0x45, - 0x86, 0xee, 0xde, 0x40, 0xdf, 0x61, 0x58, 0xd8, 0x0e, 0x32, 0x5d, 0xb1, - 0x6f, 0xc2, 0x49, 0xf8, 0x6b, 0xe1, 0x5c, 0x4c, 0xc6, 0x81, 0xa3, 0xdc, - 0xeb, 0xc2, 0xdb, 0xe7, 0x7a, 0xaa, 0x1e, 0xbc, 0xa3, 0x36, 0x96, 0xc8, - 0xf8, 0xe0, 0x3a, 0xe0, 0xad, 0x05, 0xe5, 0x1f, 0x94, 0xa9, 0x63, 0x6f, - 0xdb, 0xcc, 0xbd, 0xec, 0x06, 0xcf, 0xb1, 0x39, 0xa7, 0x3c, 0xbf, 0x73, - 0x37, 0xea, 0xf0, 0xfd, 0xcd, 0x68, 0x93, 0xca, 0x65, 0x22, 0x9b, 0xe1, - 0x13, 0x71, 0xdc, 0x20, 0xd2, 0xb5, 0xa3, 0x59, 0xe7, 0x90, 0xca, 0x29, - 0xea, 0xf3, 0xb0, 0xed, 0xdd, 0x3a, 0x47, 0x03, 0x7e, 0x7b, 0x6e, 0x24, - 0x42, 0xf9, 0xd5, 0x2b, 0xc3, 0xd4, 0x27, 0xa7, 0x6e, 0xd6, 0xb4, 0xdf, - 0xbd, 0x8d, 0x67, 0x99, 0xfa, 0x8c, 0x8d, 0x1e, 0x27, 0x8c, 0xa3, 0x28, - 0x87, 0xfd, 0xfe, 0x9a, 0x30, 0xdc, 0xf5, 0x26, 0x61, 0xb8, 0xeb, 0x4d, - 0xc2, 0x40, 0x5c, 0x00, 0x8e, 0xca, 0x5f, 0x6c, 0x08, 0x63, 0xd5, 0x97, - 0x62, 0x1e, 0x07, 0x8b, 0x77, 0xc9, 0xa1, 0xa2, 0xa3, 0xe3, 0x8e, 0x0b, - 0x8a, 0x32, 0xc1, 0x05, 0x4f, 0x82, 0xf7, 0x8a, 0xe0, 0xcd, 0x22, 0x78, - 0xb1, 0x08, 0xbe, 0x84, 0xfd, 0x7f, 0x06, 0xf6, 0xff, 0x93, 0x58, 0x9b, - 0xd3, 0x2b, 0x78, 0x39, 0xad, 0x79, 0x39, 0x5f, 0xa4, 0xaf, 0xd6, 0x7f, - 0x11, 0x7e, 0x8d, 0xca, 0x70, 0x21, 0x05, 0x55, 0xe2, 0x44, 0xb3, 0xfd, - 0x9f, 0x24, 0xbf, 0xca, 0x83, 0xfe, 0x0d, 0x68, 0x73, 0x18, 0x34, 0x9e, - 0xa2, 0x1d, 0x48, 0xfb, 0x27, 0x07, 0xde, 0x3c, 0x4c, 0x5f, 0x4d, 0x5d, - 0xb9, 0x49, 0xa8, 0x5f, 0xa2, 0x3b, 0x98, 0x7b, 0xc8, 0xb9, 0x26, 0x57, - 0xe1, 0xc9, 0xf0, 0xef, 0x84, 0x47, 0x3d, 0x43, 0xbe, 0x7d, 0x99, 0x7c, - 0x5b, 0xc3, 0xab, 0x01, 0xe7, 0x17, 0xb8, 0xdb, 0xea, 0xb5, 0xad, 0xd6, - 0xdf, 0xb4, 0x5c, 0x5f, 0x8f, 0x5f, 0x22, 0x3f, 0x42, 0x27, 0x11, 0xf7, - 0xc9, 0x4c, 0x64, 0x8b, 0xc5, 0x3d, 0x6c, 0xb7, 0x1d, 0x97, 0x00, 0xf7, - 0x9d, 0x92, 0x9b, 0x0f, 0xc4, 0xdb, 0x11, 0xf6, 0x59, 0xed, 0xc7, 0xb5, - 0xfd, 0x8c, 0x17, 0x1c, 0x19, 0xd9, 0xc6, 0x7d, 0x08, 0x07, 0x7a, 0x3e, - 0x5c, 0x0f, 0xd8, 0xfb, 0x7a, 0xcd, 0x29, 0x63, 0x29, 0x5b, 0x5b, 0x6c, - 0xfc, 0x89, 0xfd, 0x1d, 0x5e, 0xb5, 0x4e, 0x17, 0x02, 0x9e, 0x11, 0x9b, - 0xf2, 0x6e, 0xa8, 0xa1, 0x95, 0xfb, 0x2c, 0xad, 0xa8, 0x55, 0xf3, 0xb8, - 0xdd, 0xd2, 0x4a, 0x08, 0x6f, 0x3c, 0xa4, 0x95, 0xa6, 0x90, 0x56, 0x72, - 0x33, 0x21, 0xad, 0xb0, 0xed, 0xed, 0x21, 0xad, 0x24, 0x6b, 0x69, 0x25, - 0x37, 0xe3, 0xe0, 0x5a, 0x0d, 0x07, 0xe9, 0x85, 0xfd, 0x90, 0x5e, 0x00, - 0x4b, 0xe5, 0xd6, 0xd6, 0x90, 0x5e, 0xe2, 0xe8, 0xe7, 0x50, 0xd1, 0xe4, - 0x74, 0xc0, 0xef, 0xb2, 0x3a, 0xc4, 0xc5, 0x9a, 0x1b, 0x1f, 0xb1, 0x3e, - 0x8d, 0xf8, 0x96, 0x46, 0xaa, 0x79, 0xee, 0xab, 0x68, 0x03, 0xb8, 0x67, - 0x2e, 0xeb, 0x76, 0x4d, 0x1b, 0xf7, 0xfb, 0x53, 0xa8, 0xbb, 0x07, 0xb4, - 0x11, 0xe2, 0xe0, 0x7a, 0x8b, 0x83, 0xd5, 0x6b, 0x39, 0x66, 0x71, 0xb0, - 0xc7, 0xe2, 0x40, 0xf3, 0x4b, 0x8e, 0x6b, 0xa6, 0x34, 0x0e, 0x9a, 0x34, - 0x0e, 0x44, 0x85, 0x6d, 0xc7, 0xea, 0xe0, 0x80, 0x75, 0xf6, 0xe8, 0xf9, - 0x47, 0x30, 0xff, 0xfd, 0x98, 0xbf, 0xd2, 0xf3, 0xe7, 0x3a, 0x70, 0xfe, - 0x80, 0xa5, 0x72, 0x72, 0x79, 0xfe, 0x6d, 0xe8, 0xe3, 0x60, 0x31, 0xa2, - 0xe7, 0x0f, 0xdb, 0x7e, 0x30, 0x9c, 0xff, 0xe9, 0x8a, 0xc9, 0x7f, 0x3e, - 0xbd, 0x46, 0xcf, 0x4d, 0x59, 0xde, 0xf0, 0xb4, 0x5f, 0xcc, 0x98, 0xf6, - 0x19, 0xe8, 0xb6, 0x69, 0x3f, 0x69, 0xcf, 0x43, 0x19, 0x7b, 0xe9, 0x1b, - 0x3e, 0x79, 0xe7, 0xe3, 0x3a, 0x0f, 0xe5, 0x71, 0xda, 0x4d, 0xc5, 0x36, - 0x19, 0x99, 0xae, 0x85, 0x9b, 0xf0, 0xe6, 0xb4, 0x1c, 0xcd, 0x62, 0x7e, - 0xe3, 0x7e, 0x2f, 0xe4, 0x9b, 0xa6, 0x25, 0x94, 0xa7, 0x72, 0xc3, 0x91, - 0x26, 0x51, 0x0f, 0x7c, 0x08, 0x73, 0x8e, 0xca, 0x66, 0xaf, 0xdb, 0xdd, - 0xa1, 0xa8, 0x0b, 0x2f, 0xab, 0xd1, 0x85, 0xed, 0x56, 0x17, 0x6e, 0xa2, - 0x2e, 0x04, 0xdc, 0x77, 0xca, 0xe1, 0x22, 0xd7, 0x2f, 0x97, 0x6c, 0x82, - 0xfe, 0xff, 0x81, 0xc7, 0xb3, 0x27, 0x3a, 0x6e, 0x96, 0x38, 0xac, 0x69, - 0x99, 0x3a, 0x2d, 0xa5, 0xcf, 0x6a, 0x2c, 0xd2, 0xc6, 0x8e, 0x33, 0x16, - 0x4a, 0xbd, 0xf7, 0xe3, 0xe0, 0x73, 0x75, 0xf4, 0xde, 0x64, 0xd1, 0xd8, - 0x6f, 0x0d, 0xb0, 0x09, 0xe5, 0x44, 0x3b, 0xae, 0x8d, 0x3c, 0xab, 0xd0, - 0xdb, 0xa3, 0x9a, 0xa5, 0xe1, 0x44, 0xab, 0x4c, 0x4c, 0x1b, 0x1b, 0x57, - 0x9d, 0x00, 0xfe, 0x4f, 0x30, 0xdf, 0x55, 0x74, 0x7e, 0x7e, 0xb6, 0x04, - 0x3b, 0x77, 0xf6, 0x4e, 0x93, 0xb7, 0x32, 0xdd, 0xa0, 0x7f, 0xd3, 0x06, - 0xc9, 0xfb, 0x69, 0xe8, 0xbb, 0x98, 0x4c, 0xa0, 0xcf, 0xee, 0x6d, 0x8d, - 0x98, 0x73, 0x1c, 0x6d, 0xe9, 0xf3, 0x31, 0x8e, 0xd6, 0x28, 0xd1, 0xd9, - 0xb8, 0xce, 0xad, 0xe7, 0xd9, 0xd1, 0xcc, 0x60, 0x1b, 0xde, 0x31, 0x9f, - 0xc1, 0xc5, 0x58, 0xa1, 0xec, 0x47, 0xbf, 0x47, 0xc5, 0xee, 0xf7, 0x0c, - 0x69, 0xfd, 0x17, 0x39, 0xea, 0xda, 0x33, 0x74, 0x83, 0x58, 0xf7, 0x7a, - 0x7a, 0xd1, 0x18, 0xb9, 0x19, 0xac, 0x9f, 0x3a, 0x15, 0xc5, 0xbd, 0x13, - 0xf7, 0xb0, 0xbf, 0x50, 0x8f, 0x40, 0x37, 0xbe, 0xb3, 0x6f, 0xa3, 0x34, - 0x03, 0xdf, 0xb3, 0x0a, 0xb8, 0x36, 0x39, 0x59, 0x39, 0xcd, 0x0b, 0x55, - 0x7a, 0x78, 0xf2, 0x75, 0xf9, 0x81, 0x34, 0x41, 0x5a, 0xa0, 0x5c, 0x24, - 0x6d, 0x50, 0x26, 0x3a, 0xfa, 0x6c, 0x03, 0xe9, 0xe1, 0x09, 0xdf, 0x8b, - 0x70, 0xdf, 0xde, 0xc4, 0xe5, 0x49, 0x1b, 0xa4, 0xf9, 0xa4, 0x8e, 0xd7, - 0xa7, 0xe5, 0x7b, 0x92, 0x6e, 0xeb, 0x86, 0x5d, 0xf6, 0x2f, 0xbb, 0xc6, - 0xe6, 0xdc, 0xad, 0xa6, 0x39, 0xe8, 0x26, 0xe6, 0xd0, 0xf5, 0xca, 0xfb, - 0x2a, 0x39, 0xe0, 0xe1, 0x5e, 0x28, 0xe5, 0x3b, 0x75, 0x5e, 0xe2, 0xee, - 0xc2, 0x46, 0xb9, 0xc5, 0x8f, 0xd9, 0xb8, 0xfb, 0x41, 0xd0, 0xc1, 0xa2, - 0x23, 0x27, 0xce, 0xe2, 0x3a, 0xe7, 0x70, 0xfd, 0xce, 0xfb, 0xe9, 0x94, - 0x22, 0xb3, 0x7b, 0xd1, 0xc4, 0xa2, 0xf4, 0xb9, 0x13, 0xfa, 0x0c, 0xc8, - 0x82, 0xd3, 0x74, 0xe2, 0xd0, 0x46, 0xe3, 0x4b, 0x03, 0x16, 0xaf, 0xd1, - 0x1d, 0xa1, 0x2d, 0xe7, 0x07, 0x41, 0x96, 0x76, 0x83, 0x28, 0xed, 0x23, - 0xc1, 0xe7, 0x43, 0x19, 0xe3, 0x13, 0x5b, 0x9d, 0xc6, 0x53, 0x2f, 0x5a, - 0x5a, 0x91, 0x88, 0x1a, 0x7a, 0xc6, 0x69, 0x38, 0x71, 0x9c, 0x6b, 0xa6, - 0xf3, 0xa4, 0x0d, 0x5d, 0x3d, 0xe7, 0x54, 0xe9, 0xea, 0x1b, 0xf6, 0xb7, - 0x1a, 0x6a, 0x92, 0x74, 0xaa, 0x09, 0xf3, 0x1d, 0x2e, 0x84, 0x30, 0x7e, - 0x1f, 0x70, 0x11, 0x1e, 0xd0, 0xed, 0xec, 0x9f, 0xe1, 0x5a, 0x02, 0x2c, - 0xf7, 0x01, 0xee, 0xf3, 0x80, 0xf9, 0x02, 0x2e, 0xd5, 0x11, 0x91, 0x3f, - 0x76, 0x22, 0xb3, 0xb5, 0xf0, 0x12, 0xc6, 0xd3, 0x16, 0xde, 0xd7, 0x82, - 0xd5, 0x95, 0xc5, 0x81, 0x2e, 0xc0, 0x43, 0x38, 0x5f, 0x02, 0x8c, 0xb4, - 0x5b, 0x9f, 0xc7, 0xb3, 0x0b, 0xf8, 0x5e, 0xb0, 0x30, 0x81, 0x1e, 0xa7, - 0xff, 0x47, 0xf5, 0x77, 0x81, 0x76, 0xf4, 0x9f, 0xdb, 0xe7, 0xce, 0x55, - 0x32, 0xa0, 0xc7, 0x21, 0x9e, 0xa7, 0x8a, 0x4b, 0xb4, 0x03, 0xc0, 0xf7, - 0x3f, 0x94, 0xc8, 0xa9, 0x84, 0x1c, 0x2a, 0x70, 0x0f, 0xe8, 0x24, 0xf0, - 0xa1, 0xcf, 0xa4, 0xa0, 0xce, 0x15, 0xb8, 0xa0, 0xec, 0x67, 0xb7, 0xe3, - 0xea, 0xc5, 0xf5, 0x56, 0x5c, 0x20, 0x87, 0xd9, 0x13, 0xb8, 0xfa, 0xd0, - 0xb7, 0x8a, 0x37, 0x09, 0x73, 0xa9, 0xbe, 0x8d, 0x36, 0xda, 0xb6, 0xcc, - 0xa9, 0xa1, 0x01, 0xe0, 0x6f, 0x00, 0xb0, 0x25, 0x70, 0x31, 0xff, 0xf8, - 0x87, 0x8e, 0x9c, 0x7a, 0x19, 0x17, 0x18, 0xec, 0x14, 0x08, 0xf3, 0xd4, - 0x20, 0x2e, 0x28, 0xb1, 0x53, 0x69, 0x5c, 0x23, 0xb8, 0xfe, 0xd2, 0x31, - 0x3c, 0xd7, 0x09, 0x7c, 0x85, 0x3c, 0x02, 0x9c, 0xaf, 0xe0, 0xb9, 0xaf, - 0x3b, 0x6f, 0x9c, 0xe7, 0x7e, 0xe2, 0x18, 0x9e, 0x7b, 0xc5, 0xa9, 0xf2, - 0xdc, 0x59, 0x47, 0x3d, 0xfc, 0x8c, 0x13, 0x79, 0x98, 0xbe, 0xc4, 0x59, - 0xc7, 0xf0, 0x7f, 0x44, 0x86, 0xf7, 0x82, 0x96, 0x1e, 0x5e, 0xc0, 0x45, - 0xba, 0x7a, 0x16, 0xe5, 0x2f, 0xac, 0x1a, 0xf7, 0xf9, 0x37, 0x31, 0xee, - 0xab, 0x76, 0x5c, 0x51, 0xd5, 0x71, 0x2f, 0xa0, 0xef, 0x97, 0xec, 0xb8, - 0x17, 0x6a, 0xc6, 0x05, 0xad, 0x3c, 0xbc, 0x84, 0x8b, 0x74, 0xf1, 0x22, - 0xca, 0x43, 0x99, 0x80, 0x85, 0x6e, 0x6e, 0xd0, 0x67, 0x9d, 0xe2, 0x5e, - 0xc3, 0xb2, 0x6e, 0x4c, 0xd7, 0xe8, 0x87, 0x37, 0xa2, 0x1f, 0x27, 0x8b, - 0xb4, 0x11, 0x17, 0x6a, 0xe4, 0x02, 0x7d, 0xa3, 0x40, 0x8e, 0x69, 0x3f, - 0x88, 0x3e, 0x11, 0xfd, 0xa3, 0xd5, 0xb6, 0xd5, 0x27, 0x75, 0xee, 0xd8, - 0xaf, 0x15, 0x3a, 0xe5, 0xd3, 0x05, 0xda, 0x84, 0xa4, 0x97, 0x20, 0x98, - 0xd8, 0x41, 0xfb, 0x34, 0x17, 0x5c, 0xe2, 0x91, 0x4e, 0x3c, 0xf7, 0x33, - 0x6b, 0x75, 0x46, 0x69, 0x18, 0xbe, 0x7b, 0xe6, 0xe8, 0xaf, 0x40, 0x67, - 0x34, 0x00, 0x6e, 0xd2, 0x5b, 0x87, 0xdc, 0x58, 0x52, 0x53, 0x9b, 0x25, - 0x21, 0x37, 0x15, 0x1a, 0x61, 0xf7, 0x30, 0xaf, 0xaa, 0x59, 0xba, 0x77, - 0xc4, 0x4c, 0xde, 0xb7, 0x1b, 0xc7, 0x6f, 0xd7, 0xe4, 0xa1, 0xc7, 0x13, - 0x78, 0xff, 0x7b, 0x2e, 0xe5, 0x60, 0xdc, 0xbb, 0x56, 0xe7, 0xf4, 0x74, - 0xed, 0xa0, 0xdd, 0x72, 0xbd, 0xd6, 0xe1, 0xd1, 0x35, 0x76, 0x92, 0xea, - 0x70, 0xa5, 0x6a, 0xa3, 0x8d, 0x17, 0x52, 0x49, 0xc2, 0xf5, 0x90, 0x70, - 0xff, 0xeb, 0x1e, 0xc9, 0xfb, 0xad, 0xf0, 0x0b, 0x18, 0x3b, 0x4f, 0xf5, - 0xd2, 0x36, 0x9a, 0x9d, 0x76, 0x6d, 0x5e, 0xf4, 0x46, 0x79, 0x4e, 0x8f, - 0xd3, 0xa8, 0x61, 0x34, 0x67, 0x25, 0xb8, 0x8f, 0x10, 0xd3, 0xe7, 0x73, - 0x66, 0xcb, 0x2d, 0x5a, 0xef, 0xcc, 0x96, 0x99, 0x87, 0x0f, 0x7f, 0xaa, - 0xcc, 0xbc, 0x7b, 0x5f, 0xdc, 0x77, 0xc2, 0xcf, 0x2d, 0x6f, 0x91, 0xf1, - 0xe9, 0x75, 0xd2, 0xe8, 0xa9, 0xf8, 0x66, 0xc8, 0x47, 0xb6, 0xe9, 0xda, - 0x01, 0xff, 0x70, 0x66, 0xab, 0x3c, 0x39, 0xc3, 0xbe, 0x3b, 0x64, 0x6e, - 0x5e, 0x1c, 0xf7, 0x9d, 0xeb, 0x51, 0x07, 0x72, 0x7d, 0x07, 0xcb, 0x92, - 0xb8, 0x8b, 0x72, 0xdf, 0x19, 0x95, 0x73, 0x03, 0x7c, 0x66, 0xee, 0xbf, - 0x44, 0xd9, 0xdf, 0xb9, 0x81, 0x4e, 0x79, 0x7c, 0x1e, 0x34, 0x01, 0xb9, - 0x3f, 0x72, 0x82, 0x30, 0x89, 0xec, 0x9a, 0x65, 0x2c, 0xbd, 0xdb, 0x65, - 0xdc, 0x94, 0xfb, 0x34, 0xb7, 0x0c, 0x70, 0x2c, 0xe8, 0x25, 0xe8, 0xb8, - 0xae, 0x1d, 0x46, 0x16, 0xa4, 0x67, 0x1b, 0x50, 0xce, 0x7e, 0xe1, 0x3f, - 0xee, 0x65, 0x3f, 0x61, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59, 0x5a, - 0xa5, 0x3f, 0xce, 0xfc, 0x4c, 0xf6, 0x37, 0xfb, 0xe8, 0xd5, 0x7b, 0x21, - 0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae, 0xba, - 0x42, 0xdb, 0x17, 0x73, 0x15, 0xae, 0x20, 0x63, 0x51, 0xe1, 0x1a, 0x25, - 0xe4, 0xd1, 0xe2, 0xf2, 0x3a, 0x6d, 0x69, 0x58, 0xb9, 0x4e, 0xa4, 0x15, - 0x7f, 0xcc, 0xda, 0x1e, 0x8b, 0x92, 0x83, 0x5d, 0xd6, 0xab, 0xd7, 0x6c, - 0x11, 0xb6, 0xac, 0x5d, 0x33, 0x6d, 0xcf, 0xe6, 0xc3, 0x35, 0x1b, 0x85, - 0xc6, 0x29, 0xab, 0x4d, 0x5c, 0x33, 0x97, 0xf1, 0x6e, 0xe0, 0x3d, 0x87, - 0x75, 0xca, 0x61, 0x8d, 0x72, 0xe5, 0x0e, 0x99, 0x3d, 0xa6, 0x3a, 0x1b, - 0x44, 0x92, 0xe3, 0x5e, 0x87, 0x4c, 0xce, 0x33, 0x96, 0xb0, 0x05, 0x36, - 0xd8, 0x56, 0x5c, 0x9d, 0x78, 0x66, 0x3b, 0xf0, 0x54, 0x59, 0xa1, 0x6d, - 0xd3, 0x1a, 0x3b, 0xeb, 0x71, 0x8c, 0xcd, 0x1c, 0xe1, 0x27, 0x80, 0x87, - 0x2a, 0xef, 0x4c, 0xd5, 0xc4, 0x9f, 0x38, 0x57, 0xad, 0x43, 0x31, 0xdf, - 0xb8, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x36, 0xbe, 0x19, 0x7b, 0x2a, 0x41, - 0x7b, 0x2a, 0x5b, 0x72, 0xcd, 0xf9, 0x80, 0x51, 0xf8, 0x4e, 0x5e, 0xef, - 0x26, 0xd2, 0xfa, 0xd8, 0x0c, 0xe1, 0x8a, 0x85, 0x70, 0xad, 0x58, 0x33, - 0x9e, 0xe7, 0x5a, 0x1b, 0xe7, 0x98, 0x5a, 0xce, 0x5f, 0x34, 0xb1, 0x7d, - 0xc6, 0x51, 0x3a, 0xeb, 0xc0, 0x74, 0xa7, 0xb6, 0x61, 0x45, 0x8d, 0xc9, - 0x81, 0x22, 0xcf, 0x82, 0x31, 0x9e, 0x78, 0x23, 0xe3, 0x49, 0xbd, 0xb3, - 0xf2, 0x5e, 0x8c, 0xcd, 0x5c, 0x1d, 0x65, 0xe3, 0x37, 0x1b, 0x6c, 0x8e, - 0x48, 0x6d, 0x0c, 0xc7, 0xe4, 0xf2, 0xac, 0xcc, 0x8b, 0x4e, 0x8d, 0x2e, - 0x61, 0x9d, 0x7f, 0x5d, 0xef, 0x0d, 0x4a, 0x29, 0x02, 0xed, 0x37, 0x3e, - 0x90, 0x1a, 0x34, 0xe7, 0x60, 0x92, 0xb2, 0xb3, 0x68, 0xe6, 0x7f, 0x5e, - 0xe7, 0xf4, 0x98, 0xdc, 0x45, 0x93, 0xef, 0x73, 0x8f, 0x9c, 0x87, 0x0e, - 0xaf, 0xae, 0x6d, 0x93, 0x4c, 0x02, 0x17, 0x59, 0xbd, 0x2f, 0x91, 0x94, - 0xec, 0xc0, 0xc7, 0x37, 0xf1, 0x9c, 0x44, 0x0c, 0xeb, 0x93, 0x9f, 0xe1, - 0xd9, 0x49, 0xf6, 0x7b, 0xb1, 0xbe, 0x28, 0x66, 0x99, 0x87, 0x0f, 0x59, - 0xf9, 0xb6, 0xbe, 0x44, 0xb3, 0x7e, 0xbf, 0xce, 0xe6, 0x5b, 0x3b, 0x22, - 0x37, 0x06, 0xf2, 0x87, 0x10, 0x9f, 0x8f, 0xd9, 0x39, 0x25, 0x75, 0xcc, - 0x4a, 0x82, 0x73, 0x7e, 0xc2, 0xc6, 0x2c, 0x39, 0x97, 0x1b, 0x2c, 0x7d, - 0x1b, 0xfb, 0xa7, 0x6a, 0x43, 0x9b, 0x7d, 0xbf, 0x27, 0xb5, 0x2c, 0xec, - 0xb7, 0xb6, 0xb3, 0x8e, 0xf3, 0x1c, 0x17, 0x9d, 0x13, 0x10, 0xfa, 0x46, - 0x3d, 0x35, 0x7e, 0x81, 0xf1, 0xe5, 0xf2, 0xd3, 0xf5, 0x64, 0x54, 0xd5, - 0x27, 0xa4, 0x2f, 0x37, 0xb1, 0x8d, 0xdf, 0x2d, 0x08, 0x7d, 0xb9, 0x7e, - 0xeb, 0xcb, 0xb5, 0x6a, 0x5f, 0xce, 0xc4, 0x1e, 0x5a, 0x97, 0x7d, 0xb9, - 0xfc, 0x74, 0x0e, 0xb4, 0x12, 0x7e, 0x67, 0xc1, 0xd8, 0x42, 0x93, 0x05, - 0x9e, 0x79, 0x69, 0x94, 0xec, 0xa8, 0x82, 0xdf, 0x60, 0x7c, 0x2c, 0xc6, - 0x2a, 0x94, 0xfa, 0x96, 0xf5, 0x2f, 0x3a, 0x25, 0xdd, 0xbe, 0x0e, 0xf3, - 0xbe, 0x53, 0xaf, 0xf9, 0x5c, 0xc1, 0xec, 0x7d, 0x66, 0xf7, 0x32, 0x26, - 0xc4, 0x73, 0x4d, 0x9a, 0xbf, 0x92, 0xc3, 0x91, 0x5e, 0x63, 0xcf, 0x7a, - 0xdf, 0x04, 0xde, 0x4f, 0x02, 0xe7, 0x31, 0x3b, 0x6e, 0x12, 0x30, 0x1d, - 0xc0, 0xda, 0x5c, 0x6b, 0x65, 0x32, 0xc7, 0xde, 0xd3, 0xc4, 0xd8, 0xc0, - 0x7c, 0x21, 0x8c, 0x11, 0x46, 0xec, 0x99, 0x4a, 0x2f, 0xd2, 0xe8, 0xad, - 0xab, 0x6b, 0xab, 0x9e, 0x7e, 0x5d, 0xdd, 0x44, 0x5a, 0xba, 0x53, 0xe7, - 0xb9, 0xac, 0x1f, 0x48, 0xed, 0xd1, 0x39, 0xf2, 0x3a, 0xc6, 0x98, 0x13, - 0xe6, 0x94, 0x7d, 0x57, 0xde, 0xa1, 0x65, 0xfe, 0x01, 0x9f, 0xfa, 0x6b, - 0x87, 0xfe, 0xdd, 0x38, 0x14, 0x04, 0xe7, 0x06, 0xee, 0x86, 0xad, 0xe2, - 0xb9, 0xdf, 0x97, 0xee, 0xc4, 0xb0, 0xb6, 0x9d, 0xb0, 0x46, 0x7b, 0x9b, - 0x65, 0x9d, 0x77, 0xb3, 0xcd, 0x99, 0xc9, 0x41, 0x6e, 0xa6, 0x60, 0x33, - 0xf1, 0x4c, 0x70, 0x8f, 0x7d, 0x97, 0x0b, 0x9a, 0x41, 0x47, 0x1f, 0x13, - 0x23, 0x63, 0xb2, 0x55, 0x19, 0xc3, 0x5c, 0x83, 0x34, 0x09, 0x39, 0x7a, - 0x44, 0x52, 0xfc, 0xee, 0x07, 0xc7, 0xce, 0xcb, 0xa5, 0xd0, 0xcb, 0x6c, - 0xa7, 0xbf, 0xd9, 0x83, 0x67, 0xee, 0xe1, 0x78, 0xee, 0x41, 0xe8, 0x96, - 0xeb, 0xd7, 0xea, 0x96, 0x04, 0xfd, 0xfa, 0x6c, 0x89, 0xbe, 0xe1, 0x7a, - 0xb4, 0xe9, 0x90, 0x8f, 0x4f, 0x77, 0xb7, 0x91, 0xb7, 0xc6, 0x20, 0xd7, - 0xd5, 0xfd, 0xe1, 0x59, 0x20, 0x96, 0xf1, 0x3d, 0xfb, 0x6d, 0x92, 0xe4, - 0xfb, 0x5d, 0xf9, 0x7c, 0x25, 0x95, 0x5c, 0x82, 0x6e, 0x1a, 0x73, 0x7e, - 0xf1, 0x72, 0x13, 0x53, 0x7d, 0x7b, 0x9b, 0x39, 0x3b, 0xd0, 0x4c, 0x9b, - 0xdd, 0xc6, 0x59, 0x6b, 0x69, 0x76, 0xc9, 0xca, 0xe3, 0x20, 0x68, 0x1e, - 0xd0, 0x32, 0x78, 0x0f, 0x65, 0xf0, 0x01, 0xbf, 0xc7, 0xd0, 0xbe, 0xf6, - 0x99, 0x02, 0xac, 0x23, 0xf0, 0x30, 0x10, 0x65, 0x7e, 0x9e, 0xe5, 0x4f, - 0x2f, 0xbd, 0x68, 0xe5, 0x92, 0x72, 0xd6, 0xf2, 0xa5, 0xba, 0x2a, 0xb6, - 0x42, 0xe6, 0x1e, 0x9a, 0xa6, 0x3e, 0xf6, 0x17, 0xbe, 0x0b, 0x39, 0x95, - 0xd5, 0x78, 0xe8, 0x90, 0xfb, 0xa6, 0x25, 0x7d, 0x1e, 0xba, 0x2a, 0x3f, - 0xbf, 0x92, 0x37, 0xd7, 0xf6, 0xc7, 0xb9, 0x7e, 0xb8, 0xcd, 0xf8, 0xb6, - 0x2b, 0xe7, 0xba, 0x80, 0xb9, 0xa6, 0xf5, 0x5c, 0xb9, 0x6f, 0xf3, 0x31, - 0x3b, 0xd7, 0xf5, 0xe1, 0x5c, 0x07, 0x57, 0xce, 0x35, 0xf4, 0xed, 0x43, - 0xb9, 0x9b, 0xd4, 0xf9, 0xf2, 0x3a, 0x4f, 0x7b, 0x7a, 0xbd, 0x0c, 0x97, - 0x5a, 0xad, 0xbc, 0x74, 0xa1, 0x7b, 0x98, 0xc3, 0xbe, 0x70, 0xaf, 0x2b, - 0x16, 0x67, 0x8a, 0x78, 0xa0, 0xac, 0x6d, 0xd3, 0x67, 0x6c, 0x66, 0xe1, - 0x5f, 0xdd, 0x5a, 0x60, 0xdd, 0xf0, 0xfd, 0xc5, 0x62, 0xc7, 0xa1, 0x4f, - 0x4d, 0xbf, 0xa9, 0x77, 0x4d, 0x4c, 0xc1, 0xc4, 0x87, 0x19, 0x17, 0x36, - 0x67, 0x7f, 0x99, 0x8b, 0x78, 0x07, 0x78, 0xea, 0x53, 0x85, 0xd4, 0x60, - 0x26, 0x42, 0x39, 0x7a, 0x5c, 0x0e, 0x55, 0x46, 0xa4, 0x4b, 0x9f, 0xff, - 0x7c, 0xdd, 0xd8, 0x71, 0xba, 0x36, 0x76, 0xcc, 0x74, 0x02, 0xc6, 0x8e, - 0xf7, 0xfc, 0x0c, 0xb1, 0x63, 0x71, 0x4c, 0xec, 0xb8, 0x9e, 0x7f, 0x35, - 0x55, 0x3c, 0x8e, 0x79, 0x35, 0x43, 0x96, 0x2c, 0x3a, 0xd9, 0xf9, 0x16, - 0xdc, 0xcf, 0xe2, 0x1e, 0xc3, 0xfd, 0x3c, 0xee, 0x2e, 0xee, 0x17, 0x70, - 0x8f, 0xcb, 0xd4, 0xb2, 0xce, 0x38, 0x0e, 0xb9, 0x41, 0x5d, 0xc6, 0xb6, - 0xc6, 0x1f, 0x98, 0x2b, 0xb7, 0xf3, 0x7b, 0x2d, 0xce, 0xec, 0x3c, 0xe7, - 0xd0, 0x2a, 0x93, 0xd3, 0x94, 0xd9, 0x6d, 0x52, 0x9a, 0x0e, 0x6d, 0xdb, - 0x9f, 0xef, 0xe0, 0x9e, 0xc1, 0x98, 0x84, 0xb6, 0xeb, 0x3d, 0x1d, 0x66, - 0xaf, 0xf1, 0x3b, 0x58, 0xe3, 0x8d, 0x58, 0x83, 0x93, 0x72, 0x7e, 0x66, - 0xe3, 0x0a, 0x1b, 0x36, 0x69, 0x63, 0x82, 0x33, 0x56, 0xf7, 0xd6, 0x97, - 0x11, 0xb5, 0xeb, 0x9f, 0xb0, 0x67, 0xcb, 0xc2, 0x1c, 0xa1, 0xa4, 0x5e, - 0x9f, 0xd1, 0xca, 0x71, 0x8c, 0x37, 0x28, 0xe9, 0x19, 0xce, 0x73, 0xf9, - 0x9b, 0x11, 0x90, 0x87, 0x27, 0xa0, 0x57, 0x57, 0xd0, 0x25, 0xe8, 0x96, - 0x73, 0x73, 0x40, 0xbb, 0x8f, 0xca, 0x6c, 0x89, 0xf0, 0xf5, 0x24, 0x22, - 0xfa, 0xac, 0x19, 0x9e, 0x67, 0x4c, 0x8e, 0xfb, 0x70, 0x25, 0x3c, 0x67, - 0xb6, 0x89, 0x67, 0x07, 0x57, 0x9d, 0x35, 0xb3, 0xfa, 0x59, 0xdb, 0x0e, - 0x3c, 0x73, 0x16, 0xce, 0xa1, 0x1e, 0x3d, 0x05, 0x32, 0xa9, 0xf3, 0xce, - 0x36, 0xcb, 0x63, 0x0f, 0x2e, 0xe7, 0xbc, 0xb6, 0xc1, 0x46, 0xe9, 0x84, - 0x89, 0x3c, 0x1a, 0x1d, 0xea, 0x81, 0x8f, 0xc7, 0x3c, 0x99, 0x9e, 0xc4, - 0x6d, 0x3a, 0x17, 0xb9, 0x7a, 0xee, 0xaf, 0x9a, 0x8f, 0x1c, 0x9e, 0xb3, - 0x4a, 0xe8, 0xef, 0x5a, 0xec, 0xd4, 0xe5, 0x71, 0xcc, 0x87, 0xfb, 0x7e, - 0x1a, 0x0f, 0x09, 0x7e, 0xa7, 0xeb, 0x29, 0xe0, 0x60, 0xb2, 0xf2, 0x6d, - 0xd0, 0xbb, 0x63, 0xcf, 0x9c, 0x91, 0xc6, 0x06, 0x64, 0xa2, 0x9c, 0x70, - 0x26, 0xca, 0x03, 0xce, 0xbe, 0xb2, 0x7d, 0x37, 0xb0, 0x67, 0xb3, 0x34, - 0xe3, 0xf7, 0x4c, 0x97, 0x33, 0x06, 0x7c, 0xe5, 0x8b, 0xdd, 0x4e, 0x5a, - 0xdf, 0x3d, 0x7b, 0x87, 0x1c, 0xc0, 0x5a, 0x0d, 0xcf, 0xc4, 0xb5, 0x9c, - 0xaf, 0x7e, 0x5b, 0x2a, 0x5c, 0x57, 0x7e, 0x13, 0x89, 0x7c, 0x7c, 0x5c, - 0x7f, 0xe7, 0xc8, 0xd8, 0x0e, 0x27, 0xd1, 0xdf, 0x71, 0x1b, 0x13, 0xef, - 0x73, 0xb2, 0xba, 0x1f, 0xb3, 0x1e, 0xf9, 0xe2, 0x09, 0xdc, 0x57, 0x9f, - 0x79, 0x0e, 0xf5, 0x8c, 0x85, 0xbb, 0x10, 0xdc, 0x63, 0xe4, 0xd5, 0x71, - 0x99, 0xaa, 0x30, 0x7f, 0xc4, 0xd1, 0x7c, 0x34, 0x59, 0x3e, 0x00, 0x9d, - 0xb4, 0xf2, 0xcc, 0xdf, 0xce, 0xea, 0x3a, 0x24, 0x67, 0x84, 0xb0, 0x70, - 0x0d, 0x56, 0x9e, 0x87, 0xbf, 0xf8, 0xbf, 0x70, 0x5f, 0xd1, 0xc8, 0x50, - 0x0b, 0x47, 0x9a, 0xf2, 0xce, 0xc8, 0x95, 0x69, 0x39, 0x08, 0x78, 0x0e, - 0xe3, 0x52, 0xf7, 0xf3, 0x3b, 0x2c, 0xf3, 0x92, 0x9f, 0xbb, 0x4f, 0xd4, - 0x43, 0xe7, 0x9d, 0xe8, 0x43, 0x07, 0x25, 0xf2, 0xd0, 0xa2, 0xd3, 0xf0, - 0x50, 0xb7, 0xf6, 0xcb, 0x77, 0xfb, 0xdd, 0x89, 0x7d, 0x72, 0x52, 0xa2, - 0xf7, 0x2b, 0x7d, 0xfe, 0x2b, 0xef, 0x32, 0xc6, 0x77, 0x52, 0x22, 0xf7, - 0xc7, 0xec, 0xd9, 0x51, 0x13, 0xd7, 0x5b, 0xd2, 0x7c, 0xff, 0x9b, 0x71, - 0xe2, 0x6c, 0x49, 0x8e, 0x6b, 0xde, 0x19, 0x86, 0x9e, 0xc8, 0x94, 0x92, - 0xcb, 0x75, 0x4c, 0xbe, 0xe7, 0xf3, 0x9b, 0x0d, 0xbf, 0xb0, 0x4e, 0x8f, - 0xc3, 0xef, 0x38, 0x18, 0x9d, 0x91, 0xb9, 0x2c, 0xcc, 0xfd, 0x34, 0x6b, - 0xca, 0xf7, 0x67, 0xb1, 0x86, 0x3d, 0x58, 0x2f, 0x8e, 0xe7, 0xe8, 0xfd, - 0x5c, 0x9e, 0x9d, 0x75, 0xa5, 0x2f, 0xd1, 0xb4, 0x6c, 0x07, 0xb1, 0xee, - 0x7d, 0xd2, 0x04, 0xb8, 0xd5, 0x43, 0x79, 0x63, 0xd7, 0x09, 0xe9, 0x54, - 0x20, 0xb9, 0x49, 0xb3, 0x3d, 0x83, 0xbb, 0xf5, 0x1a, 0xde, 0x6b, 0x69, - 0x66, 0x9d, 0xb1, 0x1f, 0xf1, 0x6c, 0xe8, 0x22, 0x2f, 0xbb, 0xa6, 0x7f, - 0x08, 0x3d, 0xcf, 0x7d, 0x17, 0x6d, 0x2f, 0xd6, 0xb1, 0x05, 0xc9, 0x4b, - 0xcf, 0x58, 0xbf, 0x32, 0x08, 0xa6, 0x7d, 0x1f, 0x78, 0xac, 0xe7, 0x4b, - 0x6e, 0x71, 0xe6, 0x4a, 0x5b, 0x9d, 0xd9, 0x52, 0x20, 0x13, 0x3e, 0xbf, - 0xe3, 0xc1, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x86, 0x6e, 0xfd, 0xeb, - 0xcd, 0x3c, 0x8f, 0x74, 0x93, 0xf7, 0xa2, 0x98, 0x7a, 0xc4, 0x31, 0x7d, - 0xe4, 0xee, 0xe3, 0x59, 0xe1, 0xf7, 0x34, 0xfa, 0x12, 0x71, 0xfd, 0x5d, - 0x8f, 0xcf, 0xa1, 0x1d, 0xc6, 0x28, 0x72, 0xdc, 0x67, 0x9d, 0x59, 0xc8, - 0xb3, 0xb9, 0x69, 0x9e, 0xe1, 0x67, 0x3e, 0x6d, 0xa4, 0x53, 0xc9, 0x15, - 0xee, 0xa4, 0xfd, 0x06, 0x5c, 0x0e, 0x2e, 0x50, 0x44, 0x97, 0xf5, 0xb9, - 0xe3, 0xcb, 0xdf, 0x85, 0x0b, 0xcb, 0xc2, 0xef, 0xc3, 0x29, 0x9d, 0x3b, - 0x0d, 0x5f, 0xf6, 0xb1, 0x31, 0xf9, 0x89, 0x33, 0x5f, 0x78, 0xc5, 0x79, - 0xb4, 0x90, 0xbe, 0xea, 0x12, 0xd0, 0xc7, 0x39, 0xbf, 0x97, 0xf2, 0x0b, - 0x36, 0x5f, 0x41, 0x72, 0x95, 0x09, 0x99, 0xe9, 0xe8, 0x76, 0xef, 0xd7, - 0x6b, 0x33, 0x03, 0x9c, 0x7d, 0x1b, 0xeb, 0xf7, 0xc9, 0x38, 0xf5, 0xdb, - 0x78, 0x41, 0x81, 0x97, 0xd5, 0xcf, 0xe3, 0x82, 0x6d, 0xdb, 0xa8, 0x6d, - 0x94, 0x7d, 0x3e, 0xeb, 0x6d, 0x75, 0x86, 0x4b, 0x5b, 0xb0, 0x8e, 0x7b, - 0xa1, 0x3f, 0x1d, 0xd8, 0x69, 0xa0, 0x6d, 0x94, 0x4d, 0x02, 0x07, 0xe3, - 0xbe, 0x91, 0xe7, 0xc3, 0x92, 0xd3, 0x3e, 0x9e, 0xb9, 0xa7, 0x95, 0x89, - 0x99, 0x05, 0xc1, 0x1c, 0xec, 0x83, 0x6c, 0x7f, 0x09, 0xbc, 0xf0, 0x08, - 0xae, 0xb7, 0xdb, 0x3d, 0xed, 0x17, 0x2e, 0xb2, 0xa7, 0xed, 0xca, 0xc9, - 0x8a, 0x3e, 0xd7, 0xae, 0xf3, 0xab, 0x92, 0xea, 0xbf, 0x5f, 0xa2, 0xd7, - 0x4a, 0xf5, 0xe8, 0x9c, 0xb4, 0xb4, 0x7c, 0x38, 0x6e, 0xf4, 0x30, 0x61, - 0x4a, 0x02, 0x9e, 0xad, 0xc0, 0x05, 0xe1, 0x31, 0x6d, 0x44, 0x6d, 0xba, - 0x94, 0xfa, 0x70, 0x49, 0x3e, 0x12, 0x0f, 0xcf, 0x14, 0xa0, 0x1f, 0xc8, - 0xb8, 0x8f, 0x5d, 0x6a, 0xf4, 0xe4, 0xe6, 0x3a, 0xfd, 0x84, 0x73, 0x73, - 0xec, 0xdc, 0x48, 0xb7, 0x7f, 0x96, 0xa0, 0x4f, 0xb1, 0x24, 0x4d, 0xab, - 0xea, 0x33, 0xa6, 0xbf, 0xe1, 0x72, 0x73, 0x46, 0x81, 0x75, 0x5d, 0xd8, - 0xa6, 0xb4, 0x73, 0x89, 0x47, 0xbd, 0x6e, 0x05, 0x25, 0x3c, 0x67, 0x00, - 0x6e, 0xae, 0x5c, 0xe1, 0xbe, 0x43, 0x91, 0x0e, 0x43, 0x5c, 0x7f, 0x5b, - 0xf3, 0xc9, 0x78, 0x81, 0xb1, 0x95, 0x47, 0x83, 0xf4, 0x28, 0x79, 0x8c, - 0x7d, 0xf0, 0x7d, 0x41, 0xc7, 0x73, 0xf7, 0xfa, 0x8c, 0x15, 0x75, 0x1f, - 0xbf, 0x43, 0x85, 0x72, 0x0a, 0xfa, 0xb7, 0xb8, 0xe8, 0xf0, 0x1b, 0x78, - 0x37, 0x0a, 0xee, 0xf3, 0x8b, 0xce, 0x77, 0xa7, 0x9f, 0xc5, 0x73, 0x83, - 0xfd, 0xee, 0x9d, 0xd1, 0x53, 0x22, 0xc5, 0x70, 0xbe, 0x89, 0x1c, 0xd6, - 0xfe, 0x02, 0xd6, 0xbe, 0xfe, 0x77, 0xee, 0xf0, 0xae, 0x8c, 0x77, 0xe5, - 0x0f, 0x07, 0xe9, 0x36, 0xd2, 0x22, 0xe9, 0xef, 0xb5, 0xfc, 0xe6, 0x41, - 0xcd, 0x17, 0x93, 0xc5, 0xc7, 0xc1, 0x17, 0x69, 0xee, 0x37, 0x07, 0x0f, - 0xfb, 0x37, 0x80, 0x2f, 0xf6, 0xc8, 0xef, 0xc3, 0x2e, 0xf8, 0xdd, 0xca, - 0x10, 0xf8, 0x63, 0x10, 0xfc, 0x32, 0x00, 0x1e, 0xf1, 0xb5, 0x8d, 0xfc, - 0x04, 0xf4, 0x1f, 0xf4, 0x9a, 0xb3, 0xaf, 0xd4, 0xe5, 0x64, 0x4b, 0x9e, - 0x33, 0x51, 0xe2, 0xf7, 0x5a, 0xd4, 0x5b, 0x1b, 0x24, 0x9a, 0x98, 0x13, - 0xf2, 0x42, 0x37, 0x73, 0x1c, 0xdb, 0x81, 0xab, 0x53, 0xc4, 0xd5, 0x5c, - 0xa5, 0xcf, 0xbd, 0x04, 0x3c, 0xd1, 0xae, 0x79, 0xa2, 0xd5, 0x49, 0xbb, - 0x37, 0x58, 0x9e, 0x78, 0x11, 0x3c, 0x71, 0x7e, 0x0d, 0x4f, 0x3c, 0x6d, - 0xe9, 0x7f, 0xa1, 0x86, 0x27, 0xe6, 0x6c, 0xd9, 0xcc, 0x45, 0x78, 0xe2, - 0x52, 0x2f, 0xf5, 0xa5, 0x31, 0x79, 0x15, 0x3c, 0x21, 0x8a, 0x3c, 0x71, - 0xa9, 0xe6, 0x09, 0xc6, 0x8e, 0xc8, 0x17, 0x9d, 0x90, 0x23, 0xe4, 0x8b, - 0xb3, 0xb2, 0x04, 0xbe, 0x78, 0x5e, 0x71, 0xec, 0x19, 0xda, 0x0a, 0x25, - 0xfa, 0x64, 0x27, 0x8a, 0x5d, 0xe0, 0x77, 0x25, 0xff, 0x65, 0x3a, 0x08, - 0x16, 0xe1, 0xa7, 0x3f, 0x08, 0x7b, 0x3e, 0xaa, 0xbf, 0xa9, 0xb8, 0x00, - 0xba, 0x0f, 0xe9, 0x7d, 0xc2, 0x01, 0xbd, 0x1f, 0x9e, 0xc5, 0x1c, 0x26, - 0xd4, 0x7f, 0x86, 0x2f, 0xec, 0x62, 0x5d, 0x69, 0xe7, 0x1f, 0xd3, 0x3c, - 0xd4, 0x00, 0x7d, 0xf0, 0xe8, 0x00, 0x63, 0x4d, 0x9e, 0xbb, 0x4f, 0x75, - 0xe7, 0x46, 0x00, 0x73, 0x44, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xad, 0xb2, - 0xf3, 0x29, 0x23, 0x46, 0x21, 0xeb, 0xcc, 0xbb, 0x5c, 0xd0, 0x04, 0x9b, - 0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x48, 0xb9, 0x1f, 0x84, 0x00, 0x6d, - 0x84, 0xbd, 0xb0, 0x0b, 0xab, 0x3d, 0x52, 0xa8, 0xb5, 0xf1, 0xff, 0x03, - 0x6c, 0x7c, 0xb6, 0x91, 0xa8, 0xb1, 0xf1, 0x7f, 0xcd, 0xf2, 0x1a, 0x7f, - 0xbb, 0xda, 0xde, 0x3f, 0x00, 0xf8, 0x76, 0x2f, 0xdb, 0xfb, 0xec, 0x83, - 0x76, 0x87, 0xc8, 0xf5, 0xb0, 0xf9, 0xde, 0x0d, 0x1e, 0xbc, 0x01, 0xbe, - 0xd4, 0x7b, 0x0a, 0xae, 0xec, 0x29, 0xb4, 0xc3, 0xe7, 0xee, 0x94, 0xf7, - 0x4e, 0x6f, 0x95, 0x9d, 0x25, 0xff, 0x12, 0x69, 0xee, 0x80, 0x8d, 0x5a, - 0x00, 0x9c, 0x11, 0x2b, 0xb7, 0xcf, 0x02, 0x6f, 0xdd, 0xc9, 0x9f, 0xa8, - 0x17, 0xad, 0x5d, 0xc4, 0xb3, 0x8e, 0xf5, 0xfa, 0x89, 0xa3, 0x3d, 0x63, - 0x29, 0x1d, 0x72, 0xea, 0x18, 0xbd, 0xaf, 0x24, 0xec, 0x72, 0x1f, 0x36, - 0xc9, 0x16, 0xf4, 0xc7, 0x78, 0xf2, 0x46, 0x79, 0xfa, 0xaa, 0xe8, 0x5d, - 0x59, 0xcd, 0x87, 0x9d, 0x4e, 0x66, 0x1a, 0x3e, 0xc0, 0xde, 0x18, 0xe6, - 0xa0, 0xda, 0x37, 0xcb, 0x75, 0xb2, 0x53, 0xcf, 0x67, 0x46, 0x0e, 0x42, - 0x37, 0xff, 0x41, 0x61, 0xa7, 0x2c, 0x8d, 0xb6, 0xe1, 0x39, 0x26, 0x4f, - 0x17, 0xfa, 0xe0, 0xfb, 0xbc, 0x0b, 0x38, 0x6a, 0xc4, 0x73, 0xa3, 0x0c, - 0x5f, 0x42, 0x5e, 0x6d, 0x91, 0x45, 0x94, 0xbf, 0x5b, 0x7e, 0xc1, 0x96, - 0xb3, 0x8c, 0xbc, 0xd1, 0x82, 0xb6, 0x31, 0x39, 0x57, 0xa0, 0x5d, 0xa9, - 0x79, 0x62, 0xf0, 0x7b, 0xd2, 0x97, 0xfe, 0x1e, 0xec, 0xd4, 0xb3, 0xb8, - 0x9e, 0x91, 0xd4, 0x9e, 0x71, 0xa7, 0x2f, 0xd9, 0xed, 0x40, 0x77, 0xe2, - 0x8a, 0x3a, 0x7d, 0x6e, 0xa3, 0x73, 0x85, 0xed, 0xa3, 0x41, 0x9e, 0xd9, - 0xab, 0x12, 0x2d, 0x58, 0x93, 0xed, 0x4e, 0x8f, 0x2d, 0xe3, 0x73, 0xca, - 0x78, 0x40, 0xa7, 0xd4, 0x96, 0x0d, 0x22, 0x5d, 0x2d, 0xb0, 0x79, 0x26, - 0x44, 0xb5, 0xb7, 0x48, 0x54, 0xba, 0x67, 0x55, 0x27, 0xca, 0x3c, 0x5b, - 0x16, 0x6f, 0x81, 0x7e, 0x40, 0x59, 0x07, 0xca, 0xb6, 0xd9, 0xb2, 0xb6, - 0x16, 0x69, 0x44, 0xd9, 0x8c, 0xe6, 0xf9, 0xf3, 0x3d, 0x9e, 0x9b, 0x75, - 0x9a, 0xa5, 0xeb, 0x44, 0x0b, 0x64, 0xc3, 0x46, 0x59, 0xbc, 0xaa, 0x49, - 0xba, 0xf0, 0x8e, 0x71, 0x6e, 0xff, 0x44, 0x4c, 0xae, 0x3d, 0xd1, 0x9d, - 0xf8, 0x38, 0xe6, 0xd0, 0x7d, 0x8a, 0x71, 0xef, 0xfc, 0x25, 0x8c, 0xfb, - 0x74, 0x9d, 0xe2, 0xbd, 0x49, 0xcb, 0x1f, 0xe2, 0xc3, 0x7c, 0x93, 0x88, - 0x32, 0xf9, 0x24, 0xfc, 0x5c, 0xea, 0xf0, 0x6e, 0xfb, 0xfd, 0x8c, 0xe3, - 0x97, 0xd0, 0x6f, 0x9b, 0xa5, 0x5d, 0x52, 0x24, 0x3f, 0x52, 0x0f, 0xe1, - 0x3e, 0xe3, 0x48, 0xbe, 0x2a, 0xb3, 0xe6, 0xc9, 0x57, 0xc7, 0x14, 0x73, - 0x59, 0x50, 0x56, 0xf9, 0xc5, 0xc0, 0xac, 0x31, 0x79, 0xc1, 0xc8, 0xa5, - 0x0f, 0x18, 0xb9, 0xf4, 0xd8, 0x99, 0x15, 0x72, 0xe9, 0xbc, 0x96, 0x4b, - 0x7b, 0x05, 0xf7, 0xf9, 0xf3, 0x90, 0x4b, 0x2f, 0xe2, 0xd9, 0xd5, 0x72, - 0x29, 0x2e, 0xd6, 0x5e, 0x96, 0xaf, 0xea, 0xf1, 0xe7, 0x8a, 0x51, 0x6d, - 0x57, 0xe5, 0x67, 0x60, 0x93, 0x14, 0xa7, 0xac, 0xfe, 0x96, 0xa1, 0x36, - 0xe9, 0x19, 0xfc, 0xa9, 0x84, 0x36, 0xe7, 0x7f, 0xba, 0x84, 0xdf, 0xee, - 0x7c, 0x5e, 0x51, 0x86, 0xbd, 0x0a, 0x19, 0x26, 0xaa, 0xbe, 0x0c, 0xc3, - 0xbb, 0x32, 0xde, 0x95, 0xd9, 0xef, 0x8f, 0x7e, 0x3a, 0xe6, 0x52, 0x7e, - 0x50, 0x66, 0x40, 0x26, 0x15, 0x21, 0x93, 0x8a, 0x90, 0x53, 0x45, 0xc8, - 0x25, 0xd8, 0x6c, 0x67, 0x8a, 0x90, 0x4b, 0x45, 0xc8, 0x25, 0xc8, 0xb8, - 0x27, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x85, 0x4c, 0x9b, 0x91, 0xfb, 0xac, - 0xae, 0x37, 0xb1, 0x92, 0x7e, 0xeb, 0x23, 0x0d, 0xe8, 0x18, 0xf2, 0x99, - 0x9a, 0xd8, 0xe0, 0x8d, 0x47, 0x34, 0xbf, 0xbb, 0x9e, 0xba, 0xc2, 0x61, - 0x0e, 0xcd, 0x4f, 0xb4, 0xff, 0xbe, 0x9d, 0xbf, 0xa5, 0x09, 0x7c, 0xfd, - 0x03, 0xcb, 0xd7, 0xdb, 0x97, 0xf9, 0x3a, 0xe5, 0x30, 0x56, 0x5c, 0x9f, - 0xaf, 0x3b, 0xec, 0xbb, 0x5c, 0xb0, 0x0e, 0x7c, 0xbd, 0x6e, 0x15, 0x5f, - 0xc7, 0xc0, 0xd7, 0x7b, 0xd6, 0xf0, 0xf5, 0x06, 0x67, 0x58, 0xb7, 0xe1, - 0x19, 0x09, 0x3e, 0x37, 0x3a, 0x55, 0xbe, 0xbe, 0x47, 0xf3, 0xf5, 0x21, - 0xf0, 0xf5, 0x75, 0x35, 0x7c, 0xbd, 0x47, 0x52, 0x37, 0x67, 0x22, 0x5b, - 0x65, 0xfc, 0x7e, 0xd5, 0xbe, 0x49, 0xfe, 0x49, 0x4c, 0x7b, 0xc3, 0x63, - 0xc3, 0xd3, 0xed, 0x92, 0x7d, 0xe8, 0x15, 0x94, 0x91, 0xcf, 0x52, 0x63, - 0x69, 0xc7, 0x95, 0x83, 0x47, 0x7e, 0x22, 0x0b, 0x9a, 0xb7, 0x44, 0x26, - 0x8e, 0xc4, 0x64, 0xf2, 0x08, 0xe3, 0x10, 0x7f, 0x63, 0xe9, 0xbd, 0x49, - 0x26, 0xf7, 0x32, 0x6f, 0x2e, 0x2a, 0xe3, 0x47, 0xe0, 0x6f, 0x1d, 0x61, - 0x1c, 0xe2, 0xa5, 0x65, 0x1e, 0x5b, 0x80, 0x6c, 0x19, 0x3f, 0xc2, 0xb5, - 0x8e, 0xa1, 0x9f, 0x16, 0x39, 0x74, 0x44, 0xe4, 0xb6, 0x23, 0x51, 0xf9, - 0xe8, 0x91, 0x65, 0x5e, 0x1b, 0x0d, 0x79, 0xed, 0x59, 0xf0, 0x5a, 0xb7, - 0xe5, 0x35, 0xb5, 0xcc, 0x6b, 0x7f, 0x5a, 0xc3, 0x6b, 0x6c, 0x4f, 0x5e, - 0x7b, 0xce, 0x96, 0xf1, 0x39, 0x2a, 0xfb, 0x8e, 0x74, 0xca, 0xf8, 0x43, - 0x6f, 0x91, 0x89, 0xfb, 0x09, 0xab, 0xf9, 0x8e, 0x13, 0x6d, 0xb1, 0x99, - 0x4a, 0x37, 0xfa, 0x0f, 0x73, 0x88, 0xf4, 0xf7, 0x10, 0x7a, 0x67, 0x25, - 0x95, 0xe3, 0x78, 0x8d, 0xf0, 0xa3, 0x4f, 0xc0, 0xbf, 0xd8, 0x07, 0x98, - 0x6e, 0x39, 0x22, 0xa9, 0xa8, 0xbc, 0x2c, 0x53, 0xfe, 0x27, 0x2e, 0x37, - 0xf6, 0x04, 0x6c, 0x11, 0x6d, 0xfb, 0xa4, 0x25, 0xfb, 0xce, 0x40, 0xfb, - 0x18, 0xa5, 0xb2, 0x30, 0x16, 0xc0, 0xb8, 0xb9, 0x63, 0xbe, 0xc7, 0xc4, - 0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0x07, 0xf8, 0x9e, 0xcf, - 0xb0, 0x67, 0xf4, 0x59, 0x43, 0xb6, 0x7f, 0x44, 0x7f, 0x1b, 0x91, 0x31, - 0xf5, 0x7c, 0x99, 0xdf, 0xb0, 0x81, 0xff, 0x59, 0xe6, 0xb7, 0xb0, 0xf6, - 0xb7, 0x9b, 0xf8, 0x2c, 0xf9, 0xee, 0x87, 0x0e, 0xbf, 0x5d, 0x35, 0xa5, - 0x73, 0xbd, 0xf0, 0xbb, 0xcc, 0x67, 0xd6, 0x7f, 0x84, 0xf1, 0x8e, 0x64, - 0x52, 0xbd, 0xf7, 0x72, 0xe6, 0x1e, 0xec, 0x9d, 0x67, 0xdd, 0xad, 0x96, - 0x47, 0xb7, 0x6a, 0xbf, 0x83, 0x36, 0xd6, 0x78, 0xe9, 0x45, 0xc9, 0xd3, - 0x36, 0x19, 0xdd, 0xea, 0xe4, 0x66, 0x92, 0x97, 0x1b, 0xfb, 0x79, 0xdd, - 0xa5, 0xcc, 0x3b, 0x4c, 0xab, 0xb5, 0x32, 0xf9, 0x84, 0x84, 0x32, 0x39, - 0x75, 0x33, 0xbf, 0xb7, 0x9b, 0x3d, 0xa2, 0xbf, 0x2f, 0x95, 0xec, 0x56, - 0x9c, 0xd3, 0xa7, 0x21, 0x5f, 0x43, 0x5a, 0x48, 0xc8, 0x27, 0x8f, 0x90, - 0x1e, 0x54, 0xbc, 0x55, 0x3e, 0x61, 0xe9, 0x61, 0x46, 0x0a, 0x90, 0x3b, - 0x47, 0x8e, 0x7c, 0x54, 0x66, 0x6e, 0x5c, 0x4d, 0x0f, 0x13, 0x55, 0x7a, - 0x88, 0xc3, 0x3e, 0x73, 0x6a, 0xe9, 0xe1, 0x97, 0x97, 0xe9, 0x61, 0xc6, - 0xf9, 0xe7, 0xd2, 0xc3, 0xf5, 0x2b, 0xe8, 0x61, 0x4a, 0xd3, 0xc3, 0xce, - 0x65, 0x7a, 0x98, 0x3a, 0xc2, 0x71, 0xf5, 0xde, 0xa8, 0xbb, 0xe8, 0x70, - 0xcd, 0x97, 0x69, 0x21, 0x39, 0xa9, 0xf3, 0xf5, 0x53, 0x39, 0x9e, 0x6f, - 0xda, 0xa0, 0x18, 0x27, 0xa9, 0xae, 0x7f, 0xeb, 0xbf, 0xe8, 0xfa, 0xbf, - 0xfc, 0xff, 0x79, 0xfd, 0xd5, 0xa5, 0xcc, 0xdd, 0xe7, 0x99, 0x55, 0x23, - 0x8f, 0x43, 0x7a, 0x88, 0x5d, 0x6a, 0xf4, 0x02, 0xd7, 0x98, 0xcf, 0x90, - 0x67, 0x90, 0x7f, 0x67, 0x20, 0xff, 0x9e, 0x84, 0xfc, 0x3b, 0xbd, 0x62, - 0x4f, 0x60, 0xd0, 0xc6, 0x23, 0x02, 0x39, 0xe8, 0x57, 0xf1, 0xb1, 0x38, - 0x40, 0x7c, 0x98, 0xfc, 0x13, 0xe6, 0xfe, 0xae, 0xc4, 0x49, 0x54, 0xe7, - 0x1c, 0x3d, 0xea, 0xd7, 0xe2, 0x84, 0x70, 0xbf, 0x5c, 0x33, 0x47, 0xfc, - 0x2e, 0xf3, 0x79, 0x46, 0xe7, 0x91, 0xe4, 0xf5, 0x1e, 0x14, 0xf1, 0xc2, - 0x3d, 0x28, 0xe2, 0x24, 0xaa, 0xed, 0xfd, 0x7c, 0xb9, 0x49, 0xe7, 0xd0, - 0x1f, 0x98, 0x8f, 0xcb, 0x62, 0x9c, 0x31, 0x3e, 0x7e, 0x97, 0x90, 0x7e, - 0xb3, 0x97, 0xc8, 0x4b, 0x8e, 0xb9, 0x72, 0xe0, 0xe9, 0x0d, 0x96, 0xb6, - 0x19, 0x1b, 0xe4, 0x99, 0xdd, 0x70, 0x2f, 0xa2, 0xd7, 0xca, 0xba, 0x96, - 0x9a, 0x98, 0x25, 0xf0, 0x3e, 0x2d, 0xc9, 0xcc, 0x00, 0xee, 0xf3, 0x1c, - 0x7b, 0xbf, 0x4c, 0x3d, 0x38, 0x01, 0x5b, 0x6e, 0x2f, 0x74, 0x0e, 0xcf, - 0x9f, 0x99, 0xef, 0x70, 0x13, 0x86, 0x59, 0xfd, 0xdd, 0x29, 0xfa, 0x80, - 0xa4, 0x87, 0x04, 0x9e, 0x67, 0x6c, 0x5c, 0x29, 0x21, 0xf9, 0xc2, 0x05, - 0xf3, 0x6d, 0xcb, 0xc2, 0x4b, 0xb8, 0xbf, 0xde, 0x7a, 0x18, 0x3f, 0x64, - 0xd4, 0xdc, 0xd1, 0xd7, 0x92, 0xa4, 0xcb, 0x26, 0xc7, 0xa5, 0x1a, 0x37, - 0x99, 0x91, 0xc3, 0xda, 0x7e, 0x1e, 0xb2, 0xb9, 0x2d, 0xa9, 0xd1, 0x9c, - 0x18, 0x1b, 0xfa, 0x77, 0x60, 0x43, 0x7f, 0xb1, 0x92, 0xd6, 0xfb, 0x58, - 0xa7, 0x61, 0x43, 0x3f, 0x01, 0xdd, 0x43, 0x9d, 0x13, 0xb7, 0x3a, 0x67, - 0x4a, 0xdd, 0xa8, 0x75, 0xce, 0x37, 0xb5, 0xce, 0x79, 0xef, 0x1a, 0x9d, - 0x73, 0x48, 0x75, 0x97, 0xa8, 0x73, 0x86, 0xd5, 0x1e, 0x87, 0xf6, 0xe2, - 0xe6, 0x3a, 0x3a, 0xe7, 0x7d, 0xf2, 0x2e, 0xfb, 0xee, 0x1e, 0x79, 0xff, - 0x0e, 0xbd, 0x77, 0xe3, 0xce, 0x2a, 0x7e, 0x6b, 0xc9, 0xe8, 0xa0, 0xeb, - 0x54, 0xaf, 0xde, 0xf3, 0xfd, 0x46, 0x8d, 0xce, 0xe9, 0x52, 0x03, 0xce, - 0xb0, 0x6e, 0xc3, 0xd8, 0x04, 0x9f, 0x7d, 0x27, 0x3d, 0xda, 0x84, 0xe7, - 0x84, 0x44, 0x8e, 0x60, 0xee, 0xe6, 0x7b, 0x50, 0xca, 0xbc, 0x7b, 0xab, - 0x7d, 0xa7, 0xc2, 0xf2, 0xa8, 0x29, 0xef, 0xb6, 0xe5, 0x46, 0x57, 0x75, - 0xa9, 0x4e, 0xad, 0xab, 0xb6, 0x83, 0xa1, 0x66, 0xa1, 0x5f, 0x67, 0x8b, - 0xa1, 0xce, 0xe2, 0x6f, 0xc6, 0x9e, 0x19, 0xa3, 0x08, 0x63, 0xd8, 0x49, - 0xd4, 0xc1, 0x55, 0x0c, 0x6d, 0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x1e, - 0x78, 0xbd, 0x19, 0xfc, 0xf3, 0x6f, 0x0a, 0x8c, 0x81, 0xb6, 0xcb, 0xd1, - 0xe9, 0xda, 0x77, 0x9d, 0xf2, 0x9e, 0xe9, 0x2d, 0xb2, 0xbf, 0xf4, 0x2d, - 0xf0, 0xc1, 0x56, 0x99, 0x2a, 0x15, 0xf4, 0x79, 0xf5, 0x4d, 0xfa, 0x3b, - 0x1e, 0xfc, 0xbe, 0x8d, 0x91, 0x91, 0x3b, 0x1d, 0x23, 0x23, 0xd3, 0xaa, - 0x6a, 0xb3, 0x86, 0x7d, 0xf2, 0xdb, 0x21, 0x23, 0xa5, 0x84, 0xfe, 0xc6, - 0xe9, 0x6c, 0xe5, 0x0a, 0xf9, 0xc2, 0x31, 0x75, 0xa7, 0xaa, 0x9e, 0xef, - 0xd5, 0x36, 0xeb, 0xdc, 0x0a, 0x9b, 0xf5, 0xaf, 0x64, 0xf1, 0xfd, 0x31, - 0xcc, 0x13, 0x34, 0x7c, 0xe5, 0xf7, 0xb8, 0x17, 0xda, 0x1e, 0x97, 0x0b, - 0x32, 0xa2, 0xf1, 0x47, 0x79, 0xda, 0x02, 0x39, 0xb8, 0xa4, 0xf5, 0xeb, - 0x66, 0xd0, 0x20, 0x65, 0xe9, 0xc7, 0xe4, 0x45, 0x2d, 0xcf, 0x36, 0x5b, - 0xdb, 0x75, 0x81, 0xb1, 0xd4, 0x23, 0xb4, 0x5d, 0xbf, 0x69, 0xcb, 0x59, - 0x96, 0x4a, 0x2c, 0x09, 0xf5, 0x5d, 0x1c, 0x32, 0x94, 0xf2, 0xf4, 0x8d, - 0xda, 0xae, 0x5f, 0xb3, 0x7d, 0x50, 0x7e, 0x1a, 0xd9, 0xbd, 0xdd, 0x59, - 0xb0, 0x65, 0x7c, 0x0e, 0xe3, 0xe9, 0x5e, 0x3a, 0x6b, 0xf9, 0x4c, 0x39, - 0x5f, 0xc2, 0xfb, 0x4d, 0x78, 0x4f, 0x3e, 0x3b, 0xad, 0xf9, 0x4c, 0xdb, - 0x27, 0x4e, 0xbf, 0xdd, 0x5f, 0x58, 0xde, 0x1b, 0xc8, 0x91, 0xcf, 0xd4, - 0x51, 0x77, 0xc1, 0xc8, 0x03, 0xe6, 0xa9, 0x7e, 0x1e, 0xba, 0x83, 0x6d, - 0x51, 0xfe, 0x70, 0x9a, 0xbe, 0x2d, 0xfc, 0x9f, 0x56, 0x3c, 0xb7, 0xe3, - 0x79, 0x56, 0xde, 0xbb, 0x37, 0xa6, 0xe7, 0x3d, 0x85, 0x79, 0x1c, 0x38, - 0x82, 0x39, 0x39, 0xc6, 0x76, 0x8e, 0x9e, 0x8a, 0x4a, 0xc3, 0x29, 0xf2, - 0x1d, 0xcf, 0xda, 0x04, 0xc1, 0xbe, 0x7e, 0xd2, 0x6d, 0xca, 0xdd, 0xa9, - 0xcf, 0x96, 0x6e, 0x4f, 0x44, 0x80, 0x93, 0x03, 0x58, 0x8f, 0xa9, 0x82, - 0xe7, 0x66, 0x1c, 0x2f, 0x81, 0x79, 0xc2, 0x06, 0xec, 0x86, 0x2d, 0xd8, - 0x0d, 0x3b, 0xb0, 0x1b, 0x76, 0xe0, 0x46, 0x39, 0x71, 0x15, 0x73, 0x4c, - 0x72, 0xd7, 0xc2, 0x2b, 0x97, 0xef, 0xe8, 0x38, 0x7d, 0xe3, 0xcd, 0x23, - 0xf0, 0xd9, 0xc5, 0x4d, 0x8d, 0x32, 0x0f, 0x7f, 0xc9, 0x6d, 0xbc, 0x79, - 0xa7, 0x74, 0x0f, 0xe2, 0xfd, 0xe0, 0x05, 0xe9, 0xb9, 0xf9, 0x56, 0xa7, - 0x71, 0x74, 0x04, 0x78, 0x4c, 0x3b, 0xa9, 0xc4, 0x98, 0xb3, 0x80, 0x71, - 0x32, 0xdb, 0x23, 0xc2, 0xb8, 0xe5, 0x02, 0x63, 0x11, 0x37, 0x77, 0x47, - 0xfa, 0x92, 0xe3, 0x4e, 0x6a, 0x54, 0x45, 0x52, 0xa3, 0x23, 0x4e, 0x58, - 0x8f, 0xdf, 0x48, 0x85, 0x9c, 0x01, 0xac, 0x07, 0x8a, 0xd3, 0xa0, 0xa7, - 0xff, 0x28, 0xf9, 0x63, 0x2d, 0x32, 0x5f, 0xe8, 0x76, 0x33, 0x2a, 0xae, - 0x73, 0x4b, 0xd4, 0x09, 0x10, 0xfd, 0xa9, 0x98, 0xcc, 0x96, 0xb6, 0x8a, - 0xd2, 0xb6, 0x7b, 0x87, 0x64, 0xa6, 0x4b, 0x72, 0x6e, 0x40, 0xda, 0x14, - 0xfa, 0xe7, 0xb7, 0x67, 0xd5, 0x09, 0xee, 0x25, 0x86, 0xbc, 0x70, 0x39, - 0xf9, 0xa4, 0x04, 0x1c, 0x82, 0x6e, 0x19, 0xe3, 0x6d, 0x12, 0xca, 0xbd, - 0x8f, 0xea, 0xf8, 0x29, 0x63, 0xb6, 0xb5, 0x7b, 0x0f, 0xe4, 0x8f, 0x58, - 0x5d, 0xfe, 0x98, 0x2b, 0x72, 0x9f, 0x46, 0x72, 0x51, 0xc6, 0x88, 0x3d, - 0xfc, 0x9e, 0x61, 0xdd, 0x26, 0x99, 0x1a, 0xc8, 0xd9, 0x3c, 0x8f, 0x47, - 0x12, 0xcc, 0x21, 0x26, 0x4e, 0xc6, 0x07, 0xc8, 0xeb, 0xab, 0xf7, 0x36, - 0x62, 0x35, 0xf2, 0xc0, 0x91, 0xc5, 0x52, 0xb8, 0x17, 0xc2, 0xfe, 0xf0, - 0x3c, 0x63, 0xe4, 0x6d, 0x66, 0x4d, 0x3b, 0xc2, 0xc5, 0xfd, 0xca, 0x95, - 0x32, 0x56, 0x79, 0x94, 0xa9, 0xae, 0x96, 0xaf, 0x8f, 0x55, 0x8c, 0x6c, - 0x9d, 0xa9, 0x84, 0xba, 0x25, 0x66, 0x74, 0xe9, 0x1a, 0x7d, 0x62, 0xa2, - 0x99, 0x55, 0x7d, 0x42, 0xbd, 0xa8, 0xe4, 0x03, 0xf3, 0x1d, 0x12, 0x7d, - 0x58, 0x96, 0xa6, 0xbc, 0xec, 0xe5, 0xcc, 0xd5, 0x98, 0xf2, 0xdf, 0x8c, - 0x7e, 0xfc, 0x6f, 0x09, 0xea, 0xc3, 0x31, 0xf5, 0x75, 0xdc, 0x37, 0x69, - 0xfa, 0x03, 0x4f, 0xe1, 0xd9, 0xf8, 0x09, 0xbf, 0x03, 0x3f, 0xe1, 0x8b, - 0xd0, 0x75, 0x67, 0xe0, 0x27, 0x3c, 0x09, 0x3f, 0xe1, 0x34, 0xfc, 0x84, - 0x27, 0xa0, 0x27, 0x6b, 0xfd, 0x83, 0xc9, 0x15, 0xfe, 0x41, 0xa0, 0xf9, - 0x9f, 0xf1, 0xc0, 0x27, 0x6b, 0x7c, 0x83, 0x7d, 0x46, 0x5f, 0xc1, 0xef, - 0x37, 0x7c, 0xd4, 0xa5, 0x6e, 0xd2, 0xfa, 0xd1, 0xe4, 0xed, 0x8e, 0x2e, - 0xeb, 0xab, 0x2e, 0x65, 0xf4, 0xd5, 0x6c, 0x55, 0x5f, 0x19, 0x3e, 0x7a, - 0xb8, 0x24, 0x11, 0xaf, 0xb4, 0x90, 0xf1, 0x77, 0x69, 0x1e, 0x6a, 0xf3, - 0xb6, 0x4a, 0xe4, 0x01, 0xd5, 0xde, 0x20, 0x19, 0xfb, 0x0c, 0xfa, 0x3a, - 0x3a, 0x8d, 0xbe, 0xae, 0x95, 0xac, 0xb6, 0xcf, 0x2e, 0x8e, 0xef, 0x27, - 0x56, 0xe1, 0x3b, 0x5f, 0xbc, 0x5b, 0xe3, 0xfc, 0xfe, 0x32, 0xf7, 0x59, - 0x5a, 0x64, 0xb2, 0x1c, 0xe2, 0x9c, 0xe7, 0x59, 0x99, 0x8b, 0xd1, 0x29, - 0x91, 0x87, 0x3b, 0x78, 0xce, 0x4a, 0x65, 0xfd, 0xf5, 0x3a, 0x87, 0xe5, - 0xc4, 0x80, 0x24, 0xb2, 0x03, 0xa4, 0xd5, 0xfb, 0x64, 0x56, 0xaf, 0x45, - 0x87, 0x34, 0x3c, 0x4c, 0x1b, 0x25, 0xdc, 0xcf, 0xeb, 0xba, 0xcc, 0x7e, - 0x23, 0x35, 0x66, 0xea, 0x89, 0x1c, 0xd4, 0xeb, 0x75, 0x5c, 0xe7, 0x19, - 0xde, 0x34, 0xcf, 0xb8, 0x3c, 0xbf, 0x47, 0xc5, 0x98, 0xfc, 0x3f, 0x67, - 0xfd, 0x7e, 0xe1, 0x32, 0x63, 0xcf, 0x6c, 0xb2, 0x76, 0x8c, 0x89, 0x53, - 0xd5, 0xb7, 0x61, 0xd8, 0x4f, 0xed, 0x37, 0x14, 0xb7, 0x38, 0x93, 0xa5, - 0xad, 0x4e, 0xbe, 0xc4, 0xbd, 0x6c, 0xfb, 0xf7, 0x2e, 0xdc, 0x3d, 0xce, - 0x01, 0x6f, 0x0b, 0xca, 0x18, 0xb3, 0x64, 0xcc, 0xe6, 0x97, 0x2e, 0x63, - 0x8c, 0x36, 0xe3, 0x71, 0x6c, 0x96, 0x6d, 0x71, 0xa6, 0x4a, 0xdd, 0xf0, - 0xcd, 0x79, 0xae, 0x8a, 0xef, 0x77, 0x72, 0xed, 0xa0, 0x83, 0x5d, 0x7d, - 0x66, 0x77, 0x42, 0xae, 0xb0, 0x31, 0x68, 0xea, 0xe1, 0x9f, 0x5f, 0xb1, - 0x77, 0x7b, 0x08, 0x7a, 0xec, 0x16, 0xc8, 0x23, 0xea, 0xe1, 0x43, 0x72, - 0xb5, 0xa5, 0xe7, 0x95, 0x7a, 0xf8, 0xbc, 0x30, 0x4e, 0xdc, 0x8f, 0x77, - 0xb9, 0x20, 0x06, 0x7a, 0x38, 0x5c, 0xe3, 0xab, 0xd1, 0xef, 0x6b, 0x1a, - 0x32, 0xfb, 0x61, 0x2b, 0xfd, 0x3e, 0xc8, 0x81, 0x78, 0xe8, 0xe7, 0x35, - 0x2e, 0xef, 0xd7, 0xee, 0xb1, 0x6d, 0xa7, 0xfc, 0xfb, 0x89, 0xa3, 0xe4, - 0x21, 0xe9, 0x81, 0x2e, 0x63, 0x0e, 0xc8, 0x6f, 0x69, 0x9c, 0x89, 0x22, - 0xed, 0x6d, 0xd2, 0x30, 0x5a, 0x39, 0x9f, 0x0c, 0x73, 0x38, 0xf2, 0xb6, - 0xed, 0x84, 0xdd, 0x93, 0xcf, 0xcb, 0xdc, 0x65, 0xd4, 0x83, 0x23, 0x91, - 0xf5, 0xfc, 0x7e, 0x22, 0xda, 0xf6, 0x18, 0xbd, 0x28, 0x61, 0x5f, 0x7c, - 0x6e, 0xa8, 0xe9, 0x9b, 0x76, 0x14, 0xef, 0xab, 0xcf, 0x91, 0x3d, 0xa3, - 0xf7, 0x19, 0xcd, 0xf7, 0x12, 0x42, 0x3e, 0x21, 0xef, 0x24, 0xf5, 0x59, - 0x27, 0xef, 0x61, 0xda, 0x3d, 0xdc, 0x83, 0x75, 0x17, 0x26, 0xfd, 0x4f, - 0xe8, 0x6f, 0xfc, 0xcd, 0x88, 0x38, 0x79, 0xff, 0x36, 0x9d, 0x7b, 0x92, - 0xd7, 0xb1, 0xe6, 0x1c, 0xee, 0x55, 0x1f, 0xb5, 0xeb, 0x61, 0xfe, 0x4d, - 0x0b, 0x96, 0x65, 0x01, 0x1b, 0x75, 0x08, 0x65, 0x6f, 0x5c, 0xba, 0x8e, - 0x7e, 0x58, 0xf3, 0xc2, 0x66, 0xf8, 0x02, 0xc3, 0x47, 0xa1, 0xab, 0x8f, - 0x26, 0x64, 0xe7, 0x51, 0xad, 0x1b, 0xd3, 0x6b, 0x63, 0x05, 0x7d, 0x6e, - 0xd4, 0x79, 0x8f, 0x3e, 0xc7, 0xf6, 0xd6, 0xa3, 0x11, 0x39, 0x1c, 0xef, - 0x73, 0x7b, 0x9c, 0xf7, 0x5a, 0x5d, 0x18, 0xc6, 0xb0, 0x5b, 0xd0, 0xfe, - 0xf5, 0xe2, 0xd8, 0x61, 0xfc, 0x3a, 0x22, 0x33, 0x7b, 0x3b, 0x01, 0xdb, - 0x5f, 0x5d, 0x66, 0xce, 0x20, 0x63, 0xad, 0xf4, 0xb7, 0xe7, 0xa3, 0x09, - 0xca, 0xb2, 0x2e, 0xc0, 0x32, 0x72, 0x94, 0xfa, 0xcc, 0xd3, 0x3c, 0x0e, - 0x18, 0xdc, 0x06, 0xed, 0x87, 0x90, 0x2f, 0xdf, 0x22, 0xde, 0x03, 0x90, - 0x71, 0x47, 0x63, 0xd2, 0x73, 0xb4, 0x45, 0xb6, 0x1d, 0xa5, 0x1f, 0x52, - 0xeb, 0x97, 0xd2, 0x2e, 0x7d, 0x04, 0x73, 0x7c, 0xb7, 0x96, 0x93, 0xdc, - 0xd3, 0xdc, 0x4f, 0xde, 0x45, 0xdd, 0x2c, 0x6c, 0xe6, 0xcc, 0x51, 0x57, - 0xef, 0x91, 0x66, 0x30, 0xe7, 0x6c, 0xd9, 0xc5, 0x38, 0x46, 0xe6, 0xe4, - 0xe9, 0xa7, 0x8c, 0x76, 0x00, 0xc7, 0xef, 0xb5, 0xbc, 0xb3, 0xbe, 0xc3, - 0xf2, 0xe8, 0xcf, 0xc8, 0x7b, 0x5b, 0x3a, 0x8c, 0xec, 0x7c, 0x4b, 0x07, - 0x73, 0x93, 0x36, 0x7b, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7, - 0xe2, 0x45, 0x01, 0x8e, 0xc2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0x38, 0xe7, - 0xeb, 0xf3, 0x2b, 0xfe, 0xa2, 0xfe, 0x3b, 0x21, 0xdc, 0x23, 0xab, 0x7e, - 0x6f, 0x65, 0x57, 0x85, 0x71, 0xf2, 0xcf, 0x86, 0x7f, 0x97, 0xa4, 0x26, - 0xef, 0xb0, 0x76, 0x0f, 0x8c, 0xb1, 0xa6, 0xe5, 0xdc, 0xa0, 0xa0, 0xa4, - 0xbf, 0x5f, 0xf4, 0x9c, 0x73, 0xbe, 0x70, 0xd6, 0xf9, 0xee, 0xb4, 0x04, - 0x51, 0xef, 0x27, 0xce, 0xf7, 0x3d, 0xee, 0x99, 0x7f, 0xdd, 0xf9, 0x5e, - 0xc1, 0x03, 0x1f, 0xde, 0x87, 0x79, 0xbc, 0xe2, 0xfc, 0x00, 0xeb, 0x7b, - 0xb0, 0x98, 0x4e, 0xb9, 0x36, 0x26, 0x7e, 0xb6, 0xf0, 0x8a, 0xf3, 0xb5, - 0x6a, 0x3c, 0x69, 0x30, 0xa4, 0x91, 0x43, 0x7c, 0x57, 0xc6, 0xbb, 0xb2, - 0xde, 0xff, 0x71, 0xe6, 0xa6, 0x6d, 0x7e, 0x89, 0xe6, 0xe3, 0x85, 0xe5, - 0x7d, 0x99, 0x51, 0xbd, 0x57, 0xf1, 0xac, 0x33, 0x37, 0x7f, 0x77, 0x87, - 0xc9, 0x33, 0x3a, 0x8b, 0x77, 0x26, 0xe7, 0x72, 0x76, 0xfe, 0x2c, 0xea, - 0x3c, 0xe3, 0xcc, 0xea, 0xf8, 0x97, 0xf6, 0xc5, 0x9d, 0x99, 0xf9, 0x67, - 0x9c, 0x79, 0xbd, 0x07, 0x7d, 0xce, 0x79, 0x74, 0x9a, 0x7d, 0x9f, 0x43, - 0x9d, 0x05, 0xe7, 0x04, 0xfa, 0x9b, 0x9f, 0xe6, 0x79, 0xdc, 0x6e, 0xd8, - 0x05, 0xfc, 0x7b, 0x3f, 0xfc, 0x1e, 0xc7, 0xb3, 0xce, 0xfc, 0x72, 0xbf, - 0x8b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x59, 0xf4, 0xbf, 0x76, - 0xaf, 0x6a, 0x2d, 0x4e, 0x5e, 0x00, 0x4e, 0x2e, 0x58, 0x9c, 0xbc, 0x6a, - 0x71, 0xf2, 0x7c, 0x0d, 0x4e, 0x44, 0xad, 0xc4, 0xc9, 0xab, 0xc0, 0x89, - 0xa8, 0xfa, 0x38, 0xc1, 0xbb, 0x32, 0xde, 0x69, 0x9c, 0xbc, 0xb4, 0x0a, - 0x27, 0x4b, 0xcb, 0x71, 0x79, 0x83, 0x93, 0x17, 0x81, 0x93, 0xaf, 0x5a, - 0xd8, 0x2f, 0x58, 0x9c, 0xe0, 0x3e, 0x7f, 0x01, 0x75, 0x5e, 0xaa, 0xc1, - 0xc9, 0x05, 0xe0, 0xe4, 0x25, 0x8b, 0x93, 0xef, 0x5b, 0x9c, 0x7c, 0x1f, - 0x75, 0x96, 0x80, 0x93, 0xf3, 0x75, 0x70, 0xf2, 0x22, 0x70, 0x12, 0xf6, - 0x7b, 0x1e, 0xfd, 0x7c, 0xbf, 0x06, 0x27, 0x2f, 0xd6, 0xc1, 0x09, 0xf7, - 0x62, 0xc3, 0x9c, 0xee, 0x99, 0xd7, 0xc9, 0xe9, 0x96, 0x3b, 0x5f, 0x3f, - 0xa7, 0x9b, 0x75, 0x66, 0xa4, 0xfa, 0x37, 0x25, 0xee, 0xb6, 0x39, 0x6a, - 0x26, 0x17, 0xb0, 0xfa, 0xcd, 0xa6, 0x6e, 0xf0, 0x79, 0x3e, 0xe7, 0x8a, - 0xc9, 0x29, 0x8d, 0xee, 0xf8, 0x10, 0x78, 0x6d, 0x97, 0x1c, 0x38, 0xd6, - 0x78, 0x38, 0x6b, 0xcb, 0xbc, 0x1d, 0xdd, 0x39, 0xa5, 0xf8, 0x2e, 0xcc, - 0x49, 0xa0, 0x5f, 0xd2, 0xc0, 0x6f, 0x0b, 0xf6, 0xa6, 0xa5, 0x76, 0x4f, - 0xba, 0xc0, 0x6f, 0x34, 0x61, 0xec, 0x25, 0xfe, 0xfd, 0x8b, 0x24, 0xf3, - 0xac, 0xf2, 0x1a, 0xde, 0x14, 0xf4, 0xc7, 0xa0, 0xce, 0xad, 0xca, 0x14, - 0x68, 0x73, 0x27, 0x99, 0xa3, 0x06, 0x5b, 0x79, 0xc8, 0x9e, 0x09, 0xf3, - 0xf5, 0x39, 0x95, 0x2a, 0xff, 0xd4, 0x9e, 0x87, 0x26, 0xdf, 0x55, 0xe9, - 0xe6, 0xe0, 0xf2, 0x77, 0x02, 0x4f, 0xca, 0xd3, 0x3a, 0x56, 0xdc, 0x8c, - 0xf5, 0x09, 0x82, 0xc7, 0x7c, 0x13, 0xa3, 0x5d, 0xd4, 0x31, 0x5a, 0x81, - 0x37, 0x3e, 0x69, 0xe3, 0xb4, 0x3d, 0x83, 0x2f, 0x2d, 0xc7, 0x68, 0x6b, - 0xf3, 0x59, 0xcc, 0xfe, 0x7a, 0xa6, 0xf4, 0x88, 0xce, 0xd1, 0x19, 0xe1, - 0xf7, 0x37, 0x20, 0x23, 0x26, 0x66, 0xe6, 0x65, 0xf2, 0x41, 0x3e, 0x53, - 0xbf, 0x45, 0xa0, 0xc3, 0x28, 0xc3, 0x73, 0x92, 0x19, 0x64, 0x99, 0x69, - 0x33, 0xa2, 0xfd, 0xe5, 0x93, 0x32, 0xbc, 0x3c, 0x3e, 0xf1, 0x7b, 0x57, - 0xcd, 0x77, 0xab, 0x69, 0xf3, 0xa4, 0x9d, 0x4c, 0x85, 0xef, 0xc3, 0x3d, - 0xf2, 0xbb, 0xec, 0xb7, 0xb3, 0xf8, 0xbe, 0xf6, 0x5b, 0xad, 0x5a, 0x74, - 0xe0, 0x37, 0xbf, 0x87, 0x36, 0xe5, 0x8c, 0xa0, 0xcd, 0x82, 0xdb, 0x32, - 0xaa, 0x86, 0x6e, 0x18, 0xe5, 0xb9, 0xb9, 0xd9, 0x35, 0xdf, 0xba, 0xae, - 0xea, 0xc5, 0xbc, 0x5e, 0x53, 0xe6, 0x67, 0xdd, 0x05, 0x5a, 0xd4, 0xb4, - 0xa5, 0xe9, 0xff, 0xc0, 0xb2, 0xbe, 0xa4, 0x9e, 0x35, 0xdf, 0x9e, 0x31, - 0xfa, 0x32, 0x95, 0x18, 0xc1, 0xf8, 0xfa, 0x6f, 0x2a, 0xd8, 0x73, 0xbd, - 0xd9, 0xf9, 0xdb, 0xb5, 0xae, 0x9f, 0xf2, 0xd3, 0xc9, 0xa8, 0xd4, 0xa9, - 0x5b, 0xaa, 0xa9, 0xab, 0xe7, 0xed, 0xca, 0x7f, 0xc5, 0xda, 0x7c, 0xbe, - 0x58, 0x96, 0xe1, 0xe9, 0xbf, 0x84, 0xff, 0x98, 0x90, 0xdf, 0x2e, 0x96, - 0x40, 0xaf, 0xb9, 0xcd, 0xf6, 0x5b, 0x4d, 0x19, 0xc0, 0xcd, 0x6f, 0xaf, - 0xe8, 0x7c, 0xe2, 0xc8, 0x17, 0x40, 0x17, 0x9f, 0x2b, 0x71, 0x0c, 0xc0, - 0x12, 0x81, 0x6d, 0x0f, 0x3b, 0x61, 0xa6, 0xa4, 0x73, 0xe7, 0xae, 0x2b, - 0x97, 0x74, 0xcc, 0x62, 0x67, 0xb9, 0x53, 0x76, 0x95, 0x5b, 0x64, 0x37, - 0xf4, 0xc2, 0xee, 0xb2, 0x87, 0x2b, 0x26, 0xef, 0x2e, 0x9b, 0x75, 0xfa, - 0x58, 0x99, 0xeb, 0xbd, 0x43, 0x66, 0x8f, 0xad, 0xfe, 0x3e, 0xe7, 0x42, - 0x2e, 0xfc, 0x3b, 0x4b, 0x4a, 0x31, 0xbf, 0x8c, 0xb4, 0x84, 0xab, 0x98, - 0x3a, 0xbc, 0xa0, 0xf1, 0xc0, 0x0c, 0xd7, 0x54, 0x69, 0x49, 0x98, 0xa7, - 0xcf, 0xbf, 0xad, 0x34, 0x73, 0x39, 0xcf, 0x4d, 0xf3, 0x5b, 0x5e, 0x3b, - 0x2b, 0x61, 0xde, 0x78, 0xbd, 0x9c, 0x71, 0xd8, 0xf9, 0x3b, 0xc2, 0x1c, - 0xbf, 0x18, 0x73, 0xc6, 0xa5, 0xeb, 0x54, 0x0b, 0xee, 0xa7, 0x2f, 0xd7, - 0x67, 0x9b, 0x4f, 0x89, 0x2d, 0xd3, 0xf9, 0xe4, 0x78, 0x5e, 0xfd, 0x7d, - 0xb5, 0x90, 0x1f, 0xaa, 0x7f, 0xa7, 0x40, 0xe4, 0xff, 0x02, 0xfb, 0x2e, - 0x88, 0x71, 0xec, 0x6e, 0x00, 0x00, 0x00 }; - -static const u32 bnx2_CP_b09FwData[(0x0/4) + 1] = { 0x0 }; -static const u32 bnx2_CP_b09FwRodata[(0x118/4) + 1] = { - 0x0800061c, 0x0800083c, 0x08000780, 0x080007a8, 0x080007d0, 0x080007f8, - 0x08000654, 0x08000640, 0x08000864, 0x08000864, 0x08000670, 0x0800068c, - 0x0800068c, 0x08000864, 0x080006a4, 0x080006b8, 0x08000864, 0x080006cc, - 0x08000864, 0x08000864, 0x080006e0, 0x08000864, 0x08000864, 0x08000864, - 0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864, - 0x08000864, 0x080006f4, 0x08000864, 0x08000708, 0x0800071c, 0x08000730, - 0x08000864, 0x08000744, 0x08000758, 0x0800076c, 0x08003200, 0x08003218, - 0x08003228, 0x08003238, 0x08003250, 0x08003268, 0x08003278, 0x08003288, - 0x080032a8, 0x080032b8, 0x080032c8, 0x08003358, 0x08003298, 0x080032d8, - 0x080032e8, 0x08003300, 0x08003320, 0x08003358, 0x08003338, 0x08003338, - 0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050fc, - 0x080050fc, 0x08005124, 0x08005174, 0x08005144, 0x00000000 }; -static const u32 bnx2_CP_b09FwBss[(0x3b0/4) + 1] = { 0x0 }; -static const u32 bnx2_CP_b09FwSbss[(0xa1/4) + 1] = { 0x0 }; + 0x1f, 0x8b, 0x08, 0x08, 0x8e, 0xfc, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xbd, 0x7d, 0x0d, 0x74, + 0x5c, 0x57, 0x7d, 0xe7, 0xff, 0xdd, 0x79, 0x92, 0xc6, 0xb2, 0x2c, 0x3f, + 0xcb, 0x63, 0x65, 0x22, 0x0b, 0x7b, 0x46, 0x7a, 0xb2, 0x95, 0x58, 0x64, + 0xc7, 0xae, 0x00, 0x6d, 0x3b, 0x85, 0xe9, 0x48, 0xb2, 0x9d, 0x0f, 0x8a, + 0x4c, 0x44, 0x4f, 0x5a, 0xe8, 0x22, 0xc6, 0x76, 0x48, 0x80, 0xb2, 0x4e, + 0x09, 0x69, 0x80, 0x04, 0x0f, 0x23, 0xf9, 0x83, 0x74, 0xec, 0x51, 0x12, + 0xc5, 0x76, 0x4f, 0x73, 0x58, 0x55, 0x92, 0x1d, 0x43, 0xa7, 0x1e, 0x27, + 0x71, 0x68, 0xf6, 0x6c, 0x68, 0xb4, 0x4a, 0xe2, 0xa6, 0x3d, 0xd9, 0xd6, + 0xf4, 0x84, 0x6e, 0xda, 0x43, 0x77, 0x85, 0x71, 0x88, 0x4b, 0xb3, 0x4b, + 0xf8, 0x68, 0x61, 0xa1, 0xe5, 0xed, 0xef, 0x77, 0xef, 0x7d, 0xd2, 0xe8, + 0xc3, 0x09, 0xa1, 0xbb, 0xf5, 0x39, 0xcf, 0x6f, 0xde, 0xfd, 0xfc, 0xdf, + 0xff, 0xfd, 0x7f, 0xdf, 0x0f, 0xad, 0x17, 0xa9, 0x17, 0xfb, 0x6f, 0x15, + 0x9e, 0x6d, 0x89, 0x7d, 0xbb, 0xb7, 0x5e, 0xd7, 0x73, 0x1d, 0x7e, 0x6e, + 0x75, 0x57, 0x46, 0x95, 0xbc, 0x89, 0x7f, 0x89, 0x9f, 0xa1, 0x4c, 0x44, + 0xc4, 0x0b, 0xfb, 0xe2, 0x23, 0x51, 0x95, 0x1e, 0xfc, 0x64, 0xd6, 0x97, + 0x68, 0x24, 0x7d, 0xf6, 0xb3, 0xbb, 0x7d, 0x91, 0x4c, 0x79, 0x4b, 0xa2, + 0x57, 0xfe, 0x25, 0xc8, 0xc7, 0x5c, 0x61, 0xfa, 0x5b, 0xd2, 0xff, 0xfc, + 0x9f, 0xbe, 0xf2, 0x8e, 0xe4, 0x6b, 0xe3, 0x11, 0x89, 0x7a, 0xe9, 0x8f, + 0x89, 0xb7, 0x49, 0xa2, 0xad, 0xe9, 0x81, 0x4f, 0x3e, 0xbc, 0xf9, 0x6f, + 0x44, 0x1a, 0xc3, 0xb6, 0x2e, 0x07, 0x5f, 0xd9, 0x2c, 0xf9, 0x96, 0x74, + 0x7c, 0xc8, 0x4d, 0x7b, 0xf2, 0x74, 0x45, 0x06, 0x0a, 0xc5, 0xa8, 0x44, + 0xd2, 0x1d, 0x2f, 0xf5, 0x46, 0xf6, 0x07, 0x11, 0xdf, 0xf7, 0x7a, 0xa5, + 0xa1, 0x27, 0xdb, 0x8d, 0xf4, 0xf2, 0x56, 0x51, 0x7e, 0x54, 0xb2, 0x15, + 0x69, 0x50, 0xbe, 0x8f, 0x77, 0xbd, 0xa8, 0x74, 0xd2, 0xcb, 0x46, 0x5c, + 0x29, 0x54, 0x2e, 0xac, 0x30, 0x6d, 0x96, 0xec, 0xfb, 0x6f, 0xa2, 0xe6, + 0x8d, 0x36, 0x4b, 0x51, 0x99, 0x8d, 0xc4, 0x05, 0xfd, 0x00, 0xe6, 0x06, + 0x19, 0x2e, 0x25, 0x24, 0x5b, 0x64, 0xbf, 0xae, 0xe4, 0x3c, 0xf6, 0xd9, + 0x80, 0xfa, 0x2b, 0x9d, 0xe5, 0xcb, 0xb3, 0xec, 0x4b, 0x28, 0x9b, 0x40, + 0xb9, 0x56, 0x79, 0xbc, 0x12, 0x97, 0xc7, 0x2a, 0x31, 0x79, 0xb4, 0x72, + 0x87, 0x64, 0x50, 0xf7, 0x6c, 0x05, 0x7d, 0x97, 0x6a, 0xa5, 0x77, 0xac, + 0x5e, 0xb2, 0x63, 0xed, 0xf1, 0x9c, 0x04, 0xc1, 0x27, 0x52, 0x1f, 0x95, + 0xa1, 0x26, 0x94, 0x2f, 0x31, 0x2f, 0xbe, 0x20, 0x2f, 0x97, 0xda, 0xe2, + 0xe5, 0x94, 0x23, 0x99, 0xc1, 0x64, 0x7c, 0x48, 0xf1, 0xbb, 0x46, 0xb2, + 0x5d, 0xf8, 0x1e, 0x70, 0x25, 0xe2, 0x07, 0xc1, 0x1d, 0xa9, 0x26, 0xc0, + 0x91, 0x4c, 0x24, 0x14, 0xeb, 0xb2, 0x5e, 0x32, 0x9f, 0x50, 0x51, 0xc9, + 0x57, 0xae, 0x93, 0x44, 0x53, 0x10, 0xbc, 0x37, 0xe5, 0x21, 0x5d, 0xa4, + 0xb7, 0x28, 0xfb, 0x54, 0xda, 0x47, 0x9b, 0x92, 0x52, 0xe9, 0xb5, 0x18, + 0xc7, 0x16, 0xe0, 0xa9, 0x56, 0x32, 0x31, 0xc9, 0xa8, 0xb4, 0x24, 0x54, + 0x7a, 0x05, 0xd2, 0x1c, 0xa9, 0xf1, 0xa7, 0x2c, 0x9d, 0xac, 0xc6, 0xb7, + 0x0c, 0xa8, 0x74, 0xd3, 0xa2, 0xf4, 0x64, 0x42, 0xd4, 0x8f, 0xea, 0xd0, + 0x67, 0x67, 0x46, 0x31, 0x0d, 0x6f, 0x9d, 0x76, 0xfd, 0x32, 0x69, 0x1f, + 0x74, 0x16, 0xa6, 0x3d, 0xb5, 0x8a, 0xb0, 0x8a, 0xe2, 0xef, 0x28, 0xe0, + 0x6a, 0x41, 0xff, 0xed, 0x5e, 0x0d, 0xc6, 0x35, 0x90, 0x4a, 0x7a, 0xfd, + 0xea, 0xc5, 0x40, 0x9a, 0x09, 0x33, 0xf3, 0x14, 0xf2, 0x50, 0x34, 0x9d, + 0xc2, 0xbc, 0xb9, 0x72, 0x08, 0x63, 0xbb, 0x38, 0x96, 0xf4, 0xda, 0x14, + 0xde, 0x53, 0xfc, 0xdd, 0x34, 0x14, 0x49, 0x07, 0x41, 0x36, 0x35, 0x2e, + 0xb9, 0x72, 0xd2, 0x9b, 0x05, 0x70, 0xbd, 0x63, 0x71, 0x8c, 0x1f, 0xe3, + 0x88, 0x65, 0x92, 0x6b, 0xa4, 0xcb, 0xce, 0xcf, 0x5f, 0xa2, 0xef, 0x76, + 0xef, 0x0e, 0xd5, 0xee, 0xa5, 0x54, 0xd2, 0x9b, 0x90, 0x3f, 0xc4, 0x77, + 0x10, 0xec, 0x4a, 0x25, 0xe3, 0x79, 0xcc, 0xdd, 0xa5, 0x62, 0x4c, 0x5e, + 0x2e, 0x26, 0x41, 0xa9, 0xc9, 0xce, 0x49, 0xd9, 0x92, 0x9a, 0x04, 0xdc, + 0x05, 0x3c, 0x07, 0x99, 0x57, 0x46, 0x5e, 0x99, 0x75, 0x83, 0xe0, 0xe6, + 0xd4, 0x89, 0x60, 0xa8, 0xd9, 0xd0, 0xfe, 0xd3, 0x25, 0xcc, 0x2b, 0xe6, + 0xe9, 0xb1, 0x12, 0xe6, 0xb5, 0x84, 0x39, 0xd5, 0xf3, 0xdf, 0x89, 0xf9, + 0x27, 0x8d, 0x90, 0x3e, 0xb6, 0x59, 0x7a, 0x7d, 0xb7, 0x7d, 0x8b, 0x64, + 0x4b, 0x8e, 0x64, 0x53, 0x3f, 0x09, 0x32, 0x9a, 0x27, 0xc4, 0xe9, 0x2d, + 0x91, 0x26, 0x6b, 0x00, 0x2b, 0x3f, 0x7f, 0xdd, 0x96, 0x8b, 0x3a, 0x18, + 0x06, 0xe7, 0x83, 0xf9, 0x51, 0xe5, 0xd7, 0xd9, 0xfc, 0x90, 0xf6, 0xf9, + 0x0f, 0x74, 0xe7, 0xcf, 0x97, 0xcb, 0x92, 0x36, 0x2b, 0x22, 0xb9, 0x07, + 0x03, 0xe9, 0x4d, 0x01, 0x5f, 0x6c, 0xd3, 0x4b, 0x89, 0xae, 0xeb, 0xb1, + 0x8c, 0x2e, 0x8b, 0x7f, 0x3f, 0xae, 0x41, 0x1f, 0x4e, 0x5f, 0x69, 0xbe, + 0x6e, 0x5f, 0xe9, 0x85, 0x98, 0x85, 0x0f, 0xdf, 0x3d, 0x4e, 0xb6, 0xf2, + 0x77, 0x76, 0x8e, 0xc3, 0x71, 0x74, 0x2d, 0x43, 0xe3, 0x2e, 0xf8, 0xc1, + 0x93, 0x5c, 0xb1, 0x07, 0xfd, 0xc6, 0xf0, 0x0e, 0x82, 0x91, 0x54, 0x26, + 0xe9, 0x4a, 0x1a, 0xdf, 0x03, 0x98, 0xaf, 0x0e, 0xe0, 0x4f, 0xdc, 0xec, + 0xe6, 0x94, 0xf4, 0x55, 0x40, 0x7b, 0x95, 0x37, 0x96, 0x14, 0x7a, 0x0c, + 0xa9, 0x7f, 0xb1, 0xb8, 0x61, 0x3f, 0x7c, 0xbb, 0x32, 0x02, 0xfa, 0x28, + 0x8c, 0xf9, 0x32, 0x5c, 0x9c, 0xf6, 0x94, 0x24, 0x41, 0xbb, 0x69, 0xe9, + 0xad, 0xf8, 0x52, 0x28, 0xe2, 0x5d, 0x6a, 0x07, 0xfd, 0xba, 0x92, 0x89, + 0x9b, 0x39, 0x29, 0x14, 0x7f, 0x09, 0xe3, 0x02, 0x8e, 0x7d, 0xfe, 0xee, + 0xb1, 0xb0, 0x80, 0xf7, 0xbb, 0x53, 0x1a, 0x3f, 0x6f, 0x0e, 0x06, 0xf6, + 0x8d, 0x31, 0x60, 0x9c, 0x85, 0xb2, 0x8b, 0x77, 0x0c, 0xef, 0x90, 0x16, + 0xe3, 0x80, 0xa9, 0x55, 0x86, 0x41, 0x8b, 0xbd, 0x82, 0xdf, 0x53, 0x84, + 0x91, 0xfd, 0xb6, 0xe8, 0xdf, 0xc3, 0x63, 0x1b, 0xf4, 0x77, 0x6e, 0xa0, + 0x45, 0xf2, 0x53, 0xe1, 0x58, 0x28, 0x0f, 0x28, 0x03, 0x92, 0x87, 0x45, + 0x28, 0x13, 0x82, 0xe0, 0xc1, 0x14, 0xe5, 0x42, 0x10, 0x3c, 0x96, 0xa2, + 0x9c, 0x38, 0x07, 0xfe, 0xa7, 0x6c, 0x20, 0xaf, 0xae, 0x55, 0x9c, 0x83, + 0x6c, 0x11, 0x7d, 0x40, 0x4e, 0xe4, 0xba, 0x4e, 0x40, 0x6e, 0x50, 0xae, + 0x5c, 0xf8, 0x44, 0xd6, 0xcf, 0xc7, 0x23, 0x1a, 0x0f, 0x98, 0x6f, 0xc8, + 0xbc, 0x8c, 0x86, 0xbc, 0x4d, 0x0a, 0x5d, 0xa3, 0xb6, 0xcc, 0x65, 0x5d, + 0xc6, 0x5d, 0x52, 0xe6, 0x76, 0x65, 0xf8, 0xae, 0x15, 0xf3, 0xb1, 0x42, + 0x11, 0x4f, 0x6d, 0x9b, 0xf8, 0x2d, 0xd1, 0x9a, 0xf4, 0x97, 0x90, 0x37, + 0x7d, 0xd7, 0x49, 0x7f, 0xb9, 0xbc, 0x59, 0x77, 0x69, 0xde, 0x88, 0xb8, + 0x7e, 0xb2, 0x73, 0x97, 0x9a, 0x01, 0x3d, 0x05, 0xc1, 0xc9, 0x54, 0x98, + 0xfe, 0x8f, 0xee, 0xd2, 0x3e, 0x12, 0x35, 0x4b, 0xd3, 0xee, 0x5d, 0x26, + 0xed, 0xc4, 0x32, 0x69, 0x1b, 0x6a, 0x97, 0xa6, 0xbd, 0x7f, 0x99, 0xb4, + 0xfb, 0x97, 0x49, 0xfb, 0x5f, 0xcb, 0xa4, 0x7d, 0x67, 0x99, 0xb4, 0xef, + 0x2d, 0x93, 0xd6, 0x52, 0xb7, 0x34, 0xcd, 0x05, 0x3f, 0x6d, 0x92, 0x42, + 0xec, 0x73, 0x1c, 0xbb, 0xc5, 0xcd, 0xfe, 0xc8, 0x52, 0xdc, 0xd4, 0xa0, + 0x5c, 0xeb, 0xa2, 0x72, 0x53, 0xcb, 0x94, 0xab, 0x45, 0xb9, 0xa6, 0x45, + 0xe5, 0x92, 0xcb, 0xe0, 0xba, 0x4e, 0xeb, 0xaf, 0x85, 0xe5, 0x0a, 0xcb, + 0x94, 0x63, 0xfa, 0x1e, 0xdb, 0xcf, 0x16, 0x68, 0x99, 0xd7, 0x9b, 0xaf, + 0x5a, 0x91, 0x66, 0xa6, 0xb7, 0x42, 0x47, 0xac, 0x50, 0x86, 0xdf, 0x29, + 0x5b, 0x98, 0xe6, 0x81, 0xee, 0xa3, 0xa0, 0x3b, 0xca, 0x47, 0xf0, 0x91, + 0x4f, 0xfe, 0x5d, 0x25, 0x43, 0xb1, 0x2d, 0xde, 0x2f, 0xa8, 0x06, 0xd0, + 0x58, 0xd2, 0x4b, 0x28, 0xf2, 0x97, 0xe4, 0x23, 0x69, 0x3f, 0xdf, 0x2b, + 0x2a, 0xa6, 0x24, 0x90, 0xbe, 0x94, 0x6a, 0x52, 0xb2, 0x1f, 0xfc, 0x93, + 0x81, 0x4e, 0xda, 0x15, 0xf4, 0x6a, 0x1e, 0x32, 0x65, 0xaf, 0x2c, 0x2b, + 0x7d, 0x39, 0x48, 0x19, 0x97, 0xce, 0xdc, 0x95, 0xf5, 0xa7, 0x7b, 0x6a, + 0x41, 0xb3, 0x17, 0x51, 0x67, 0x07, 0x6a, 0xee, 0x2d, 0xbb, 0xd2, 0x57, + 0xee, 0x04, 0x2f, 0x38, 0x72, 0xde, 0x5f, 0x2d, 0xe7, 0x53, 0x28, 0x5b, + 0x89, 0xc8, 0x4c, 0xcc, 0x91, 0x19, 0x7c, 0x67, 0x53, 0xc8, 0xab, 0x84, + 0xbc, 0xd5, 0x29, 0x07, 0x4a, 0xbe, 0x1c, 0x2e, 0xfd, 0x92, 0x0a, 0xf5, + 0x56, 0x7f, 0x6a, 0xa5, 0x9c, 0xf6, 0x4c, 0xdb, 0x3b, 0xfc, 0x69, 0x68, + 0x4c, 0x57, 0x2e, 0xfa, 0xc9, 0xf8, 0x8c, 0xe6, 0x89, 0x1f, 0x06, 0x7d, + 0x68, 0x67, 0xc2, 0x4f, 0x7a, 0x7f, 0x8a, 0xef, 0xa1, 0x32, 0xed, 0x90, + 0xf9, 0xb6, 0x86, 0xd1, 0xd6, 0xa1, 0xd2, 0x2a, 0xf9, 0xb0, 0xad, 0xbf, + 0xdd, 0x9f, 0xee, 0x04, 0xcf, 0x79, 0xa7, 0x28, 0x23, 0x8a, 0x80, 0x6b, + 0x10, 0xbc, 0x8d, 0xba, 0xcf, 0x69, 0x39, 0x05, 0xbb, 0xa5, 0xb8, 0x1a, + 0x72, 0xf7, 0x1f, 0x83, 0x0f, 0xc7, 0x58, 0x9e, 0x69, 0xd4, 0x25, 0x32, + 0xaa, 0xd2, 0x90, 0x09, 0xdd, 0x94, 0x85, 0x09, 0xc8, 0x41, 0xc8, 0x96, + 0xd2, 0x4f, 0x83, 0x8c, 0x5b, 0x2d, 0xdf, 0x24, 0x3f, 0x5f, 0x86, 0x69, + 0x09, 0x23, 0x2f, 0x4b, 0xb3, 0x73, 0xb2, 0x22, 0x0f, 0xf9, 0xf2, 0x74, + 0x85, 0x72, 0xe1, 0x7a, 0xf0, 0x68, 0xab, 0xf4, 0x15, 0x93, 0xf9, 0x8c, + 0x6c, 0xc2, 0xfc, 0x7d, 0x1e, 0x73, 0xea, 0xe2, 0xb9, 0xaf, 0x5e, 0x1a, + 0x53, 0xd0, 0xcd, 0x4c, 0x47, 0xa3, 0xcd, 0x51, 0xc8, 0xa8, 0xdf, 0x03, + 0x1e, 0x86, 0x39, 0xe7, 0xf1, 0x6c, 0xc4, 0x19, 0xa0, 0x3d, 0x32, 0x40, + 0xfd, 0x50, 0x66, 0xdb, 0x84, 0x37, 0x6e, 0x7f, 0x47, 0xb5, 0x8c, 0x31, + 0xbf, 0x1b, 0xf0, 0x3b, 0x61, 0x7f, 0x7b, 0xf8, 0xed, 0xdb, 0xdf, 0x31, + 0xfc, 0xee, 0xb4, 0xbf, 0xa1, 0x5b, 0x8b, 0x5d, 0xfa, 0xf7, 0x48, 0x69, + 0xfb, 0x76, 0xe5, 0x5f, 0x27, 0xb9, 0xa9, 0x56, 0x39, 0x50, 0xf4, 0xad, + 0x6c, 0xc1, 0x23, 0x4f, 0x3a, 0x66, 0x9c, 0x80, 0x9b, 0xb2, 0xb3, 0x94, + 0x77, 0x06, 0x08, 0x3f, 0x68, 0xa0, 0xb7, 0xb8, 0xc5, 0x5b, 0x23, 0xa4, + 0x81, 0x11, 0xa7, 0xb7, 0xe2, 0x64, 0x60, 0xaf, 0xc5, 0x87, 0xe5, 0x30, + 0x7e, 0x8b, 0x17, 0x49, 0x3f, 0x89, 0xb7, 0xc1, 0x01, 0xf5, 0xce, 0x70, + 0x89, 0xf2, 0xd2, 0xc7, 0xd8, 0x13, 0x72, 0x6e, 0x81, 0x0d, 0x45, 0x5c, + 0x28, 0xc9, 0x8d, 0x25, 0x4f, 0xe4, 0x25, 0x99, 0x1f, 0x07, 0x43, 0xec, + 0x4a, 0xb9, 0xf2, 0xde, 0x14, 0x68, 0xf7, 0x3a, 0x47, 0xb6, 0x5f, 0xe7, + 0xc2, 0xe6, 0xf1, 0xc7, 0xb7, 0x83, 0xfe, 0x31, 0xcf, 0x9a, 0x1e, 0xd4, + 0x19, 0x81, 0x9d, 0x08, 0x6c, 0x9f, 0xe9, 0xea, 0x1b, 0x2e, 0xe6, 0x3e, + 0xa6, 0xd2, 0xfb, 0x3e, 0x95, 0xed, 0xbe, 0x46, 0x72, 0x83, 0x0a, 0x38, + 0x6a, 0x1e, 0x82, 0x1e, 0xc4, 0xb8, 0x82, 0x00, 0xf4, 0x0c, 0x79, 0x7e, + 0xf3, 0xcd, 0x91, 0x74, 0x8d, 0xf4, 0x0e, 0x36, 0xa3, 0x0e, 0xf3, 0x88, + 0xaf, 0xaf, 0xa2, 0x9d, 0x64, 0xa2, 0x4f, 0xe4, 0x9e, 0x91, 0xee, 0x59, + 0x67, 0x78, 0xf4, 0x37, 0xc0, 0x93, 0x5b, 0x51, 0xff, 0x01, 0xd4, 0x7f, + 0xcd, 0x29, 0x8c, 0xfd, 0xc8, 0x19, 0x1e, 0xfb, 0x9e, 0x33, 0x32, 0xb6, + 0x61, 0x43, 0x7f, 0xcf, 0x86, 0x0d, 0xbb, 0x7b, 0x5c, 0x99, 0x00, 0x8f, + 0x65, 0xbc, 0x0d, 0x1b, 0x46, 0x7a, 0xba, 0x80, 0x83, 0x2d, 0x5e, 0x9f, + 0xf8, 0xde, 0x76, 0x01, 0xff, 0xc4, 0xd8, 0x67, 0x14, 0xf9, 0x49, 0xe4, + 0xb3, 0x7e, 0x5c, 0xe7, 0xf7, 0xca, 0x96, 0x78, 0x93, 0xb0, 0xff, 0x88, + 0x2d, 0x53, 0x13, 0x91, 0xfa, 0x07, 0xec, 0xfc, 0x66, 0x9c, 0x1a, 0x9f, + 0xe9, 0x1c, 0x0b, 0xd3, 0x39, 0xb7, 0x7f, 0x67, 0x6d, 0xd5, 0xd5, 0x48, + 0xe7, 0x37, 0x71, 0x46, 0xbc, 0xd0, 0xc6, 0xa8, 0xd1, 0xb6, 0x61, 0xae, + 0x48, 0x9a, 0x71, 0x65, 0x4f, 0xd1, 0x41, 0x1d, 0xd0, 0xc5, 0x19, 0xfb, + 0x1c, 0x05, 0x6c, 0x83, 0x68, 0xeb, 0xe8, 0x21, 0xd4, 0xa3, 0xcc, 0x48, + 0x76, 0x8a, 0xfa, 0x00, 0xca, 0x6c, 0xf1, 0xd6, 0x0a, 0x6d, 0x89, 0x3b, + 0x25, 0x57, 0x22, 0x7f, 0x77, 0x00, 0x9e, 0xa8, 0x24, 0x9a, 0xf1, 0x5d, + 0x81, 0x4d, 0xf1, 0x60, 0x8d, 0x58, 0xdb, 0x45, 0xe6, 0x6d, 0x91, 0x3b, + 0x94, 0xc0, 0xde, 0x18, 0x9a, 0x5c, 0x8f, 0x72, 0x0e, 0xf0, 0x42, 0xfb, + 0x03, 0xb4, 0x36, 0x99, 0x91, 0xec, 0x26, 0xf0, 0xc9, 0xa4, 0x87, 0x6f, + 0xc0, 0x35, 0xf9, 0x16, 0xbc, 0x23, 0xfa, 0xdb, 0xc0, 0x09, 0xbc, 0xa6, + 0x22, 0x56, 0x67, 0x75, 0xa1, 0xef, 0xf7, 0x48, 0x76, 0x34, 0x4e, 0x5b, + 0x62, 0x75, 0xd6, 0xcf, 0x40, 0xd7, 0x2b, 0x28, 0x41, 0x8c, 0x61, 0xd2, + 0x81, 0x3c, 0xa9, 0x95, 0xdd, 0x8f, 0xe0, 0xf7, 0x83, 0xc6, 0xe6, 0xdd, + 0x3d, 0xc9, 0x7e, 0x1a, 0x00, 0x13, 0x6c, 0x90, 0x47, 0x60, 0x9b, 0x3e, + 0x02, 0x1b, 0xe4, 0x91, 0x66, 0x3c, 0x1c, 0x1b, 0xdb, 0x9f, 0x59, 0x03, + 0x31, 0xa9, 0xbf, 0x73, 0xa4, 0x57, 0xd8, 0xea, 0xb9, 0x62, 0xca, 0x94, + 0x2f, 0x76, 0xeb, 0xb7, 0xa1, 0xeb, 0x1e, 0xfb, 0x3b, 0xae, 0xf9, 0x3a, + 0xdf, 0x04, 0x9a, 0xaf, 0x74, 0x69, 0x99, 0x93, 0xf5, 0xf1, 0x86, 0xcd, + 0x99, 0x69, 0xe2, 0x18, 0xe3, 0x36, 0x2d, 0xae, 0xd3, 0x12, 0x4d, 0xd6, + 0xde, 0x28, 0x59, 0x5b, 0x03, 0xb8, 0x19, 0x6a, 0x06, 0xc4, 0x94, 0xcf, + 0x12, 0xe2, 0x93, 0x32, 0x00, 0xf4, 0x0b, 0x9b, 0xe2, 0xdc, 0x15, 0xe5, + 0xdf, 0xac, 0xb6, 0xb1, 0xce, 0x56, 0x48, 0xc7, 0xa4, 0xed, 0x20, 0xb8, + 0x3f, 0x55, 0x87, 0xf6, 0xc9, 0xf3, 0xb0, 0x40, 0x8e, 0x02, 0x26, 0x60, + 0xa2, 0xc6, 0x3f, 0xab, 0x69, 0xa0, 0xd6, 0x27, 0x0d, 0x57, 0xf3, 0x97, + 0xe8, 0xf1, 0x9e, 0x05, 0x8f, 0xc1, 0xbe, 0x81, 0xfd, 0xd6, 0x01, 0xdb, + 0x98, 0x7d, 0x1c, 0xe6, 0xb7, 0xa7, 0xc0, 0x53, 0xd9, 0x39, 0x9e, 0x12, + 0x99, 0x28, 0x12, 0x37, 0xa1, 0x5d, 0xc7, 0x79, 0x26, 0x7e, 0x32, 0x18, + 0x33, 0xdf, 0x7d, 0x16, 0x4f, 0x3b, 0x2d, 0x9e, 0x6e, 0xb2, 0xef, 0x11, + 0xbc, 0x69, 0xe3, 0x0d, 0xe0, 0xcd, 0xf9, 0x19, 0xc4, 0x9b, 0xbc, 0x75, + 0x0b, 0xde, 0x28, 0x5b, 0xca, 0xc8, 0x6e, 0x6d, 0x87, 0x45, 0xe4, 0x57, + 0xb4, 0x6c, 0xfb, 0x02, 0xe6, 0xb2, 0x48, 0xfa, 0x95, 0x7c, 0x2c, 0x02, + 0x9c, 0x14, 0xf0, 0xfb, 0x4e, 0xd7, 0xd0, 0x2a, 0x71, 0xb2, 0xc0, 0x57, + 0xaa, 0x82, 0x29, 0x66, 0xe5, 0x5c, 0x42, 0xdb, 0xfa, 0xb9, 0xe2, 0x07, + 0x34, 0x5c, 0xb7, 0x42, 0xde, 0xe5, 0x45, 0x35, 0x43, 0x37, 0x80, 0x16, + 0x54, 0x0c, 0x9a, 0x2b, 0x78, 0x06, 0x7a, 0x29, 0x37, 0x49, 0xdb, 0xb8, + 0x8d, 0x7e, 0x49, 0x34, 0xd7, 0xd5, 0x48, 0x3a, 0x52, 0x0a, 0xf6, 0x17, + 0xbe, 0x55, 0xae, 0x4b, 0xd3, 0xa9, 0xa3, 0xfc, 0x98, 0xb6, 0x7f, 0x5d, + 0x1f, 0xd2, 0xd6, 0xf8, 0xbd, 0xae, 0xf2, 0xd7, 0x2e, 0x4e, 0x4b, 0x50, + 0x0f, 0xa3, 0x5e, 0x22, 0xd7, 0xd5, 0x4c, 0x1e, 0xf3, 0x40, 0xbf, 0x19, + 0xe5, 0x6b, 0xdf, 0x27, 0xaf, 0xba, 0x57, 0x2f, 0x2a, 0xaf, 0xdf, 0x8e, + 0xfd, 0x76, 0xed, 0xdb, 0xb3, 0xef, 0x84, 0x7d, 0xe7, 0xdd, 0x6e, 0xbe, + 0x1d, 0x71, 0xd3, 0x7c, 0x83, 0x92, 0xd3, 0x6c, 0x43, 0xf3, 0x95, 0x95, + 0x33, 0x1d, 0x5e, 0x41, 0xc8, 0x57, 0x9f, 0x93, 0x5b, 0x27, 0x8d, 0xfc, + 0xdd, 0x0e, 0x19, 0x04, 0xff, 0xcc, 0x9b, 0x11, 0xc0, 0x3f, 0x98, 0x96, + 0x5b, 0x2b, 0xc4, 0xdb, 0xef, 0x02, 0x7f, 0x60, 0xe2, 0x7a, 0xea, 0x74, + 0xca, 0xdd, 0x3b, 0x61, 0xf7, 0xa2, 0x7c, 0x91, 0x38, 0x1f, 0xd2, 0x73, + 0x53, 0x28, 0xee, 0xd1, 0x73, 0x73, 0xb0, 0x38, 0x03, 0xfc, 0xdc, 0x06, + 0xba, 0x0f, 0x82, 0x99, 0x54, 0x01, 0x94, 0xf3, 0x11, 0xfc, 0x86, 0x1d, + 0x50, 0xfc, 0x18, 0xf2, 0x1b, 0xa5, 0x30, 0x4a, 0x9e, 0x73, 0x2d, 0x0f, + 0xbf, 0x13, 0xfc, 0x14, 0x45, 0xbb, 0x48, 0xeb, 0xe6, 0xef, 0x9f, 0x20, + 0x0f, 0xef, 0x49, 0x4c, 0x62, 0x33, 0x6d, 0x1d, 0xf6, 0xcd, 0xb9, 0xe3, + 0x9c, 0xc5, 0xb4, 0x2c, 0x3f, 0x3b, 0x37, 0x6f, 0x97, 0xe7, 0xe8, 0x36, + 0x4f, 0x1f, 0x8f, 0xf9, 0x1a, 0x56, 0xd2, 0xfd, 0xb7, 0xb4, 0x5c, 0x72, + 0x8f, 0xce, 0xac, 0x30, 0xef, 0xc5, 0x75, 0x39, 0xe7, 0xd5, 0x34, 0x48, + 0xbf, 0x25, 0xd9, 0x93, 0x07, 0x3f, 0x61, 0x9c, 0xd2, 0xa7, 0x7d, 0x1d, + 0xd2, 0x04, 0x69, 0x60, 0xdc, 0xd2, 0xe6, 0x94, 0xa5, 0xcd, 0x27, 0xf1, + 0xc6, 0x53, 0xba, 0x60, 0x69, 0xf3, 0x29, 0xbc, 0xf1, 0x94, 0x5e, 0x9c, + 0xe3, 0xe3, 0x5e, 0xf8, 0x72, 0xdb, 0xa1, 0xdf, 0x76, 0x57, 0x40, 0xbf, + 0xe0, 0xbb, 0x1c, 0x7c, 0x80, 0x5c, 0x69, 0x1f, 0xde, 0xec, 0x67, 0xa3, + 0x6d, 0x3f, 0x23, 0x7b, 0x4a, 0x01, 0xc6, 0x78, 0x37, 0xc6, 0xfb, 0x39, + 0xbc, 0x3f, 0xa3, 0xe5, 0x8c, 0xf2, 0x0f, 0x5b, 0x79, 0xf5, 0x79, 0xbc, + 0xdb, 0xe3, 0x07, 0xa5, 0xdd, 0x8b, 0xc8, 0x34, 0xda, 0xfa, 0xba, 0xec, + 0xa9, 0xcc, 0xe2, 0xb9, 0x84, 0xe7, 0x55, 0x3c, 0x97, 0xd1, 0xde, 0x0b, + 0x48, 0x5f, 0x29, 0xd3, 0x5e, 0x3d, 0xca, 0xbf, 0x86, 0xdf, 0xcf, 0xcb, + 0xd0, 0x23, 0x2f, 0xe1, 0xf9, 0x01, 0xf2, 0x9f, 0x45, 0xfd, 0x60, 0xf5, + 0x8c, 0x4f, 0x19, 0xf6, 0x9c, 0x6d, 0x3b, 0xe5, 0xe4, 0x2a, 0xa0, 0xe9, + 0xd2, 0x00, 0xfa, 0xde, 0xa3, 0x79, 0xa6, 0x0f, 0x32, 0x3f, 0x07, 0x19, + 0x37, 0xa4, 0x61, 0x6a, 0x07, 0x7c, 0x79, 0xcc, 0x05, 0xde, 0x93, 0xb5, + 0x32, 0x1b, 0xa3, 0x1d, 0x79, 0x93, 0x2e, 0x9f, 0x2b, 0x35, 0x69, 0xbb, + 0x7a, 0x7c, 0x09, 0xff, 0xd0, 0xef, 0x0a, 0xe5, 0x81, 0x91, 0xc6, 0x13, + 0x45, 0xca, 0x02, 0xe8, 0x9f, 0xe2, 0x08, 0xde, 0xb5, 0x5a, 0x26, 0x14, + 0x24, 0x94, 0x07, 0xac, 0x47, 0x99, 0x50, 0x2d, 0x77, 0x28, 0x6b, 0x28, + 0x7b, 0x28, 0x4b, 0xcc, 0x7c, 0xec, 0x7e, 0x90, 0x32, 0x1c, 0xb4, 0x10, + 0xa3, 0xfd, 0xe1, 0x19, 0x1f, 0x64, 0xec, 0x3e, 0x2b, 0x4f, 0x47, 0xf5, + 0x5c, 0xec, 0x29, 0xaa, 0x98, 0x2b, 0xa7, 0x91, 0x86, 0xe7, 0xf8, 0xc3, + 0x78, 0x7f, 0x49, 0xf6, 0xe0, 0xc9, 0x1d, 0xff, 0x02, 0x7e, 0x73, 0x6e, + 0xca, 0x28, 0x87, 0xa7, 0x74, 0x02, 0x6f, 0x3c, 0xa5, 0x31, 0x2b, 0x47, + 0xc6, 0xad, 0x1c, 0xe1, 0x9c, 0xde, 0x04, 0x3c, 0x70, 0x7c, 0x4a, 0xc7, + 0x17, 0xc0, 0xcf, 0x4e, 0x6e, 0xf2, 0x5d, 0xd6, 0x8f, 0x6d, 0x14, 0xc3, + 0x83, 0x78, 0x3a, 0xc9, 0xcf, 0x0d, 0xda, 0x0e, 0xce, 0x69, 0xda, 0xfd, + 0x2b, 0xd7, 0xf0, 0x62, 0xcc, 0xe8, 0x14, 0xaf, 0x59, 0x34, 0xef, 0xcf, + 0xe1, 0x31, 0x63, 0xf1, 0xc8, 0xdf, 0xca, 0xfe, 0x86, 0xdc, 0x82, 0x4d, + 0x9b, 0xf5, 0x7d, 0xcc, 0x03, 0xc6, 0x72, 0x7c, 0x14, 0x7d, 0x3b, 0xb2, + 0xdb, 0xa7, 0x0c, 0x67, 0x0c, 0x81, 0xe3, 0x63, 0xbb, 0x48, 0xd7, 0x38, + 0x48, 0xc9, 0xbc, 0x6f, 0x7e, 0x13, 0xe6, 0x2c, 0x23, 0x7b, 0x4b, 0xf7, + 0x6a, 0x5f, 0xb9, 0xf6, 0x68, 0x93, 0xf5, 0x73, 0xc2, 0x72, 0xa0, 0xd5, + 0x18, 0x6d, 0x9b, 0x2f, 0xc5, 0x0c, 0xcd, 0xf3, 0x37, 0xe5, 0x73, 0xb5, + 0xbc, 0x37, 0x76, 0x4d, 0x61, 0x81, 0xac, 0xa3, 0x6d, 0x81, 0x39, 0x2b, + 0x57, 0xe3, 0x9d, 0xbe, 0x3b, 0xf9, 0x8a, 0xfc, 0x74, 0x10, 0x3c, 0xf1, + 0x5d, 0xcb, 0xfb, 0xf4, 0x35, 0xd8, 0xe7, 0x62, 0x7e, 0xf2, 0x60, 0xfb, + 0xba, 0x72, 0x0a, 0xb6, 0xdb, 0xf6, 0xb9, 0x36, 0xae, 0x06, 0x3c, 0x51, + 0x79, 0xa4, 0xd8, 0x20, 0x93, 0x45, 0xd5, 0x1c, 0xb1, 0xb2, 0x33, 0x22, + 0x09, 0x4d, 0xdf, 0xb4, 0xef, 0x7a, 0xc7, 0x22, 0x96, 0xee, 0xd6, 0xd5, + 0x48, 0xfd, 0xef, 0x42, 0xc7, 0xa6, 0xa1, 0x63, 0x1b, 0xa1, 0x83, 0x17, + 0xcb, 0x88, 0x35, 0x35, 0x4b, 0x65, 0x04, 0xeb, 0x24, 0xe1, 0x75, 0x1f, + 0x44, 0xbd, 0x90, 0xfe, 0xa2, 0x9a, 0xd6, 0x72, 0x92, 0x77, 0xb6, 0x57, + 0x46, 0x9c, 0x1d, 0x95, 0xc5, 0x3a, 0x68, 0x8b, 0xe7, 0x8a, 0x81, 0xf5, + 0x91, 0x22, 0x6d, 0xd4, 0x64, 0x2a, 0x0b, 0x9c, 0xec, 0x00, 0xcc, 0xcf, + 0x8c, 0xc2, 0x4f, 0xa7, 0x5c, 0x06, 0xcc, 0xa7, 0x01, 0xf3, 0xc4, 0xa8, + 0x13, 0xda, 0x06, 0xc2, 0xa0, 0xc8, 0xc4, 0x58, 0x97, 0xcc, 0x4c, 0x91, + 0x0e, 0x21, 0x03, 0x46, 0x31, 0x9f, 0xa9, 0x15, 0xb0, 0x03, 0xd8, 0x3f, + 0xe4, 0xf6, 0x58, 0x8b, 0xce, 0x33, 0xfa, 0xbc, 0x55, 0x66, 0xca, 0x69, + 0x0b, 0xdb, 0xe1, 0x2a, 0xd8, 0x56, 0xcc, 0xc1, 0xb6, 0x03, 0xb0, 0xed, + 0x5c, 0x16, 0xb6, 0xe5, 0x74, 0x71, 0x1b, 0x6c, 0x1a, 0xa3, 0x8b, 0x0d, + 0x5e, 0x9b, 0x2d, 0x3d, 0xbc, 0xdf, 0xda, 0xbb, 0xb4, 0x89, 0x7e, 0x0a, + 0x78, 0x48, 0x63, 0xf8, 0x3d, 0x79, 0x2f, 0x65, 0x19, 0xd2, 0xf9, 0xbd, + 0x07, 0x65, 0xf0, 0x3d, 0xf9, 0x67, 0x2b, 0x4c, 0xd9, 0xbb, 0x2d, 0x2c, + 0xb4, 0x13, 0x32, 0xb0, 0x89, 0xfb, 0x9c, 0xec, 0x24, 0x61, 0xf8, 0x8f, + 0x80, 0x17, 0x79, 0x95, 0xea, 0x36, 0xf9, 0x66, 0xbb, 0xd7, 0xda, 0x76, + 0xd8, 0x76, 0x38, 0x96, 0x95, 0x56, 0xcf, 0x87, 0xf4, 0x15, 0xda, 0xd7, + 0x23, 0x4e, 0x66, 0xc9, 0xb8, 0xaa, 0x69, 0x8e, 0xf2, 0xd6, 0x95, 0x7e, + 0xd0, 0x49, 0xff, 0x02, 0x5a, 0x33, 0x72, 0xc3, 0xd0, 0xf1, 0x0a, 0x3b, + 0xbe, 0x1a, 0xc3, 0x37, 0xa9, 0x28, 0xf4, 0x21, 0xe5, 0xcd, 0x0e, 0xe3, + 0x9b, 0xcb, 0x43, 0x80, 0x35, 0xfc, 0x3e, 0xa8, 0x6d, 0xce, 0xa7, 0x4b, + 0x94, 0x49, 0xf3, 0xb4, 0x68, 0x7c, 0x97, 0x56, 0xf4, 0x55, 0x6d, 0xaf, + 0xbb, 0x32, 0x60, 0xe6, 0xfc, 0x30, 0xe7, 0x9c, 0xbe, 0x48, 0xfb, 0x03, + 0x03, 0x96, 0xbf, 0x92, 0xa3, 0x79, 0x79, 0xbb, 0x1d, 0xfb, 0x1f, 0x2e, + 0x33, 0x77, 0x8d, 0x73, 0x73, 0x37, 0x50, 0x59, 0x3c, 0x46, 0x91, 0xb6, + 0x07, 0x58, 0xcf, 0x85, 0x8d, 0x94, 0x92, 0x5a, 0x9f, 0xf2, 0x93, 0xb6, + 0x12, 0xd2, 0x27, 0xb6, 0x78, 0x4d, 0xf0, 0x01, 0x9e, 0x5e, 0x62, 0x77, + 0x25, 0xac, 0xdc, 0xa4, 0x1f, 0x1c, 0xf6, 0x91, 0xb7, 0x72, 0x32, 0x8f, + 0xf6, 0x47, 0x9c, 0xfe, 0xca, 0x72, 0xf2, 0x32, 0x94, 0x93, 0x1c, 0x8f, + 0x23, 0x77, 0x3c, 0x48, 0x1e, 0x7d, 0xbf, 0xb6, 0xaf, 0xb7, 0x6e, 0xab, + 0x01, 0xfe, 0x08, 0xc7, 0xcc, 0x1a, 0xa2, 0x33, 0xf7, 0x08, 0x6c, 0x22, + 0x3b, 0x6f, 0xbb, 0xe7, 0xe6, 0x5f, 0xd3, 0x05, 0x7e, 0x33, 0x8e, 0x6a, + 0x68, 0xa4, 0xc6, 0x77, 0x34, 0x2d, 0xd4, 0x2e, 0xb1, 0x65, 0x39, 0x06, + 0xda, 0xb3, 0xb5, 0xc6, 0x16, 0x2c, 0xd1, 0xfe, 0xa4, 0xec, 0xa2, 0xfd, + 0xf9, 0x43, 0xe0, 0x88, 0xe3, 0xe9, 0xb2, 0x69, 0xb4, 0x53, 0x17, 0x8f, + 0x6f, 0xb1, 0xff, 0x48, 0x38, 0x09, 0xb7, 0xa1, 0xad, 0x84, 0x22, 0x6c, + 0x81, 0x0c, 0x80, 0x97, 0x39, 0x07, 0x8a, 0xb6, 0xeb, 0xb6, 0xbf, 0xa8, + 0x31, 0x31, 0xe4, 0xd5, 0xb5, 0x52, 0xcf, 0x3e, 0xc9, 0x7f, 0x7c, 0xaf, + 0xd2, 0xf6, 0xef, 0x52, 0x59, 0x56, 0xad, 0x7b, 0xae, 0x9e, 0xc3, 0x5f, + 0xff, 0x82, 0x39, 0x0a, 0xf1, 0x17, 0xd2, 0x45, 0x35, 0x0e, 0x49, 0x13, + 0x86, 0x16, 0x0c, 0x2d, 0x6e, 0xb4, 0xfa, 0x26, 0xa4, 0xbd, 0xab, 0x40, + 0x7b, 0xf7, 0x81, 0xc6, 0x28, 0xc3, 0x19, 0x97, 0x5b, 0x8b, 0xef, 0x23, + 0xf8, 0x0e, 0xf9, 0xe4, 0x4a, 0x32, 0x9c, 0xf2, 0x9b, 0x75, 0xb2, 0x56, + 0xee, 0x87, 0x7e, 0x2e, 0xeb, 0x70, 0xdc, 0x94, 0xff, 0xff, 0x15, 0xed, + 0xac, 0xad, 0x35, 0xf6, 0xca, 0x8d, 0xb5, 0x94, 0xaf, 0x6b, 0xe4, 0x60, + 0x55, 0xda, 0x95, 0xe4, 0x77, 0xf5, 0x98, 0xd7, 0xff, 0x3f, 0x18, 0x73, + 0x7c, 0xd1, 0x98, 0x3d, 0x3b, 0xe6, 0x77, 0x21, 0xbf, 0xc9, 0xf8, 0x38, + 0x1e, 0xf9, 0x2e, 0x1c, 0xb3, 0xc5, 0x85, 0x1e, 0x57, 0xb5, 0x9c, 0x08, + 0x65, 0x04, 0xc7, 0x35, 0x60, 0xc7, 0xf0, 0xb9, 0xaa, 0x71, 0x0d, 0xbc, + 0x89, 0x71, 0xb5, 0x2e, 0x18, 0xd7, 0xf6, 0x2b, 0x8e, 0x6b, 0x39, 0x1e, + 0x27, 0x2f, 0x87, 0xe3, 0x8b, 0xca, 0xae, 0x22, 0xc7, 0xd8, 0x8f, 0x31, + 0x1e, 0xd4, 0xfe, 0x80, 0x19, 0x63, 0xda, 0x8e, 0x51, 0x54, 0xdb, 0xb6, + 0x7f, 0x8f, 0xdf, 0xd5, 0xe3, 0xa3, 0xee, 0xff, 0x3e, 0x68, 0xba, 0x4e, + 0xb2, 0x5d, 0x75, 0x56, 0xfe, 0xdf, 0x24, 0x1f, 0x2e, 0x71, 0xae, 0x93, + 0x19, 0x91, 0x51, 0xe8, 0xe0, 0xff, 0x5c, 0xcb, 0xd8, 0xfd, 0xf6, 0x94, + 0xd5, 0x63, 0xd0, 0x17, 0x3b, 0x60, 0xf3, 0xf5, 0x17, 0x55, 0x77, 0x44, + 0x82, 0xe0, 0xb6, 0xd4, 0xa7, 0xd1, 0xf7, 0x7e, 0xed, 0xab, 0x2e, 0x8d, + 0x9b, 0x3f, 0x57, 0x2b, 0x3e, 0xed, 0x0d, 0xea, 0x73, 0xe8, 0xbb, 0xe3, + 0xb4, 0xc1, 0xb2, 0xb0, 0x93, 0x33, 0xf1, 0x88, 0xb6, 0xc5, 0xa8, 0x13, + 0x93, 0xf1, 0x8c, 0xa4, 0xd1, 0x5f, 0x26, 0xae, 0x84, 0x7d, 0xc0, 0x56, + 0x83, 0x0d, 0xf9, 0xe1, 0xca, 0x3e, 0x3c, 0x0f, 0xcb, 0xad, 0xb0, 0x77, + 0x6e, 0x7d, 0xe4, 0x0b, 0x72, 0x1b, 0x6c, 0x9d, 0xdb, 0x1e, 0x19, 0x93, + 0xbd, 0xb0, 0x6d, 0xf6, 0xc2, 0xce, 0xd9, 0x5b, 0xa1, 0xed, 0x39, 0x8e, + 0xb2, 0xad, 0x55, 0xb4, 0x46, 0x1b, 0x87, 0xe3, 0x23, 0xee, 0x0f, 0x72, + 0x0e, 0x52, 0x09, 0xf5, 0x8a, 0x9e, 0x97, 0xa6, 0x05, 0x69, 0xaf, 0x27, + 0xab, 0x42, 0xfd, 0xb4, 0xca, 0xc6, 0x8d, 0x8c, 0x0d, 0x78, 0x65, 0xda, + 0x22, 0x8d, 0x78, 0xc0, 0x33, 0xf1, 0x47, 0xda, 0xaa, 0x1e, 0x7f, 0x63, + 0x9d, 0xf8, 0x2b, 0xeb, 0xa4, 0xfe, 0x73, 0x90, 0xaf, 0xd5, 0x34, 0xc5, + 0xb7, 0x67, 0x75, 0x0d, 0x69, 0x8b, 0x32, 0x38, 0xa4, 0x87, 0x8d, 0xaf, + 0x23, 0x7f, 0xaf, 0x48, 0x4f, 0xfb, 0xb9, 0x2e, 0xb3, 0xbb, 0x5b, 0x56, + 0x33, 0x1e, 0x90, 0xad, 0xcc, 0xc7, 0x04, 0x94, 0x5f, 0x1d, 0x13, 0xa0, + 0x9f, 0xf5, 0x01, 0xe0, 0xec, 0x16, 0x3c, 0xfb, 0x64, 0x88, 0x71, 0x87, + 0x4a, 0x68, 0x97, 0x7f, 0xd5, 0xda, 0xe5, 0x21, 0x1c, 0x09, 0xc0, 0x61, + 0xe4, 0xf3, 0x52, 0x3d, 0xb7, 0x50, 0x7f, 0xe7, 0xe7, 0x6c, 0xda, 0x84, + 0xec, 0x2a, 0x71, 0xdc, 0x94, 0xc1, 0xc4, 0x4d, 0xb5, 0x0c, 0x8e, 0x5b, + 0x3b, 0x0a, 0x65, 0xb4, 0xfc, 0x5c, 0x2a, 0x3b, 0x29, 0xf7, 0x18, 0x9f, + 0x7f, 0x20, 0x45, 0x5a, 0x7f, 0xb7, 0x64, 0xe6, 0xe2, 0xf3, 0x02, 0x7a, + 0x93, 0x54, 0x24, 0xad, 0xd7, 0xd3, 0xbc, 0x09, 0xd9, 0x21, 0xbd, 0x31, + 0xc6, 0x3a, 0x19, 0xcf, 0xf3, 0xf3, 0x13, 0xb0, 0x1f, 0x86, 0x4b, 0x0a, + 0x16, 0x7c, 0xad, 0x0c, 0x79, 0x81, 0x6c, 0x4f, 0x39, 0x3a, 0x76, 0x6c, + 0x74, 0x6d, 0xa9, 0xce, 0xd8, 0xae, 0x8e, 0x8e, 0xff, 0xce, 0x80, 0xfa, + 0x66, 0xb4, 0x7d, 0xab, 0xb4, 0xfe, 0x9d, 0xd6, 0x65, 0x46, 0xeb, 0xc2, + 0x38, 0xe6, 0x8c, 0x17, 0xb1, 0xe5, 0xaa, 0xd3, 0xa7, 0xea, 0x42, 0x5b, + 0xb0, 0x50, 0x09, 0xd3, 0x9e, 0x5c, 0x26, 0xed, 0x85, 0x65, 0xd2, 0xfe, + 0x76, 0x99, 0x34, 0x13, 0x17, 0xec, 0x2f, 0x5e, 0x46, 0xde, 0x88, 0xe6, + 0x55, 0x69, 0x36, 0xf6, 0x75, 0x7e, 0xae, 0xcc, 0x2a, 0xeb, 0x97, 0x31, + 0x46, 0x6c, 0x62, 0xc3, 0x39, 0x1d, 0x1b, 0xde, 0xe2, 0x6d, 0x53, 0x8c, + 0x75, 0x11, 0x17, 0x09, 0xd9, 0xab, 0xf1, 0x42, 0x9c, 0x7c, 0x85, 0x31, + 0xe0, 0x3c, 0xd7, 0x5a, 0x13, 0xea, 0x4a, 0xb4, 0x3d, 0x6f, 0x9b, 0x98, + 0x79, 0x8b, 0xe9, 0x75, 0xd5, 0x3e, 0xd8, 0x0a, 0xfd, 0xc5, 0x26, 0xd9, + 0x3e, 0x96, 0x58, 0x41, 0xbd, 0xb5, 0x63, 0xcc, 0xf8, 0x83, 0x7b, 0xc1, + 0x57, 0x19, 0x21, 0x8c, 0xc9, 0x94, 0x08, 0x6d, 0xe2, 0xa5, 0xb6, 0xf0, + 0xeb, 0xb7, 0xd7, 0x7b, 0x85, 0xf6, 0x1c, 0xd8, 0x0e, 0x3f, 0x6b, 0x7b, + 0xf5, 0xd2, 0x37, 0x16, 0xe2, 0x4a, 0xfd, 0x9c, 0xf5, 0x22, 0x57, 0xa8, + 0xa7, 0xed, 0x12, 0x79, 0x66, 0x4e, 0x16, 0x6f, 0x84, 0xcd, 0x24, 0x41, + 0xb6, 0x5b, 0x5a, 0x23, 0xa2, 0x63, 0x3c, 0x29, 0x23, 0x9b, 0x3b, 0xb8, + 0xb6, 0x03, 0xfa, 0x37, 0xb6, 0x8a, 0x89, 0x9b, 0x86, 0x76, 0xca, 0x72, + 0xb4, 0x7b, 0xbd, 0xa5, 0x5d, 0xae, 0xa9, 0xee, 0xa0, 0xcc, 0xc5, 0x9c, + 0x18, 0x3a, 0xde, 0x5e, 0x94, 0x44, 0x48, 0xc7, 0x33, 0xf0, 0x8b, 0xab, + 0xe9, 0x78, 0x46, 0x52, 0x9a, 0x8e, 0x6b, 0x17, 0xd0, 0x71, 0xab, 0xa5, + 0xe3, 0x77, 0x44, 0x0d, 0x5d, 0x28, 0xad, 0xa7, 0x48, 0xa7, 0x86, 0x8e, + 0x1d, 0x4d, 0xc7, 0x33, 0x78, 0xbb, 0x7e, 0x8f, 0x2d, 0x13, 0xb1, 0x69, + 0xfc, 0x1d, 0xa6, 0x51, 0x2e, 0xfe, 0x66, 0xd4, 0xe8, 0xa5, 0x14, 0xe8, + 0x28, 0x4c, 0xff, 0x60, 0xd4, 0xd0, 0x67, 0x75, 0x9a, 0x89, 0x8f, 0xf4, + 0x17, 0xdf, 0x13, 0x5d, 0x48, 0x9f, 0x29, 0xd0, 0x67, 0x58, 0xe6, 0xf5, + 0xe8, 0xb3, 0xde, 0xae, 0x5b, 0x44, 0xf5, 0xba, 0x7b, 0x26, 0x66, 0x68, + 0xf5, 0x56, 0x3d, 0x76, 0x8e, 0xfb, 0xd9, 0x9f, 0x81, 0x56, 0xcd, 0xdc, + 0x9c, 0x9f, 0xf7, 0xb7, 0x19, 0x8b, 0x4a, 0x98, 0x18, 0x36, 0xe3, 0xa4, + 0x57, 0xb2, 0x1d, 0x8d, 0x7c, 0xaa, 0xd1, 0xf2, 0xa9, 0x71, 0x48, 0xa5, + 0xab, 0x65, 0x76, 0x37, 0x74, 0x05, 0x6d, 0x6c, 0x2d, 0xa7, 0x91, 0xd7, + 0x9a, 0xc8, 0x16, 0xff, 0xd9, 0xee, 0x5f, 0xe0, 0xba, 0x80, 0x0c, 0x39, + 0x48, 0x6b, 0x2b, 0x9b, 0x71, 0x29, 0xbf, 0x11, 0xdf, 0xdd, 0xd2, 0x56, + 0x56, 0x72, 0xfb, 0x58, 0x83, 0xec, 0x2b, 0xba, 0xf2, 0x51, 0xd4, 0xff, + 0x48, 0xd1, 0x83, 0x3f, 0x3e, 0x1e, 0xa5, 0x5d, 0xb8, 0xb7, 0xc8, 0xf5, + 0x49, 0xc7, 0xac, 0x19, 0x2d, 0x58, 0xf3, 0x8c, 0x48, 0x5b, 0x47, 0x01, + 0x9e, 0x8a, 0xb8, 0x3b, 0x01, 0x47, 0x5d, 0x3a, 0x2d, 0xaf, 0x74, 0x0f, + 0x38, 0xda, 0x97, 0x70, 0x7a, 0xe4, 0xc6, 0x4a, 0x5a, 0x6e, 0xa8, 0x98, + 0x75, 0xd2, 0xf9, 0x75, 0xd0, 0xa4, 0x37, 0x0d, 0x9d, 0x93, 0xf1, 0x82, + 0xe0, 0x3c, 0xe4, 0xb7, 0x3a, 0xe2, 0x4a, 0xb4, 0x23, 0x19, 0x9f, 0x16, + 0xf3, 0x7d, 0xb1, 0xfc, 0xe3, 0x60, 0x28, 0xe6, 0xca, 0x2b, 0x3e, 0xc7, + 0xd5, 0x23, 0xd7, 0x97, 0xab, 0xfb, 0xe3, 0x5a, 0xe9, 0x13, 0x51, 0xae, + 0x4d, 0x64, 0x2b, 0xe5, 0x28, 0xe3, 0xe7, 0x22, 0x79, 0x69, 0x7b, 0x2b, + 0x7c, 0x37, 0x48, 0xeb, 0xb6, 0xb7, 0x82, 0x56, 0x62, 0xd0, 0xf3, 0x5b, + 0x01, 0xd7, 0x56, 0xc6, 0xbb, 0x18, 0xe7, 0xe2, 0xf7, 0x5f, 0xa2, 0x5f, + 0xd6, 0xfd, 0x5d, 0xbd, 0x66, 0x25, 0x8a, 0x73, 0x6e, 0xf8, 0x65, 0x79, + 0x5d, 0xd3, 0x38, 0x14, 0x4d, 0x8b, 0x13, 0x7d, 0x5b, 0x5c, 0x56, 0xf8, + 0xd5, 0xfd, 0x73, 0xed, 0x57, 0x14, 0x70, 0xe8, 0xee, 0xd8, 0xdc, 0x23, + 0x7d, 0x18, 0x5f, 0xff, 0x92, 0xf1, 0xed, 0x17, 0xc6, 0x54, 0x2f, 0x16, + 0x39, 0x86, 0xf9, 0x71, 0xa9, 0x3f, 0x32, 0xe3, 0x8a, 0x76, 0x2c, 0x1e, + 0x8f, 0xae, 0xaf, 0x4e, 0x01, 0x96, 0xe7, 0xf4, 0x1e, 0x81, 0x20, 0xb8, + 0xa6, 0xe3, 0x62, 0x90, 0x58, 0x97, 0xec, 0x9c, 0x9e, 0x5f, 0xd3, 0x19, + 0x8a, 0xa4, 0x33, 0x1a, 0xff, 0xf8, 0x4e, 0xe4, 0xca, 0xdd, 0x98, 0x3b, + 0x71, 0x73, 0x5d, 0xae, 0xe6, 0x8d, 0x9c, 0xdf, 0x6d, 0xd7, 0xad, 0x42, + 0xbf, 0x29, 0x08, 0x94, 0xbf, 0x58, 0x56, 0x50, 0x47, 0x61, 0xec, 0xb2, + 0xdb, 0xee, 0x4b, 0x49, 0x31, 0x6e, 0x38, 0xe4, 0xa6, 0xa3, 0x89, 0x42, + 0xb9, 0x0b, 0xbf, 0x1b, 0xf0, 0xfe, 0x45, 0xd8, 0x28, 0x3d, 0xb0, 0x61, + 0x24, 0xa6, 0x8c, 0x3c, 0x00, 0xfd, 0x76, 0xe4, 0x95, 0x22, 0x3f, 0x7a, + 0x89, 0xe1, 0x72, 0x2c, 0x31, 0x5a, 0xde, 0xcb, 0xfa, 0x28, 0x7b, 0xa5, + 0xf8, 0x1d, 0xfb, 0x62, 0x1f, 0xf4, 0x79, 0x7f, 0x96, 0x3e, 0x5c, 0xdb, + 0x36, 0xdb, 0x0c, 0xf1, 0xe2, 0xd2, 0x0d, 0xc7, 0xbf, 0x6e, 0xeb, 0x8f, + 0x70, 0x7c, 0x7b, 0x2d, 0xdc, 0x8b, 0xfb, 0x7d, 0x49, 0xdb, 0x2c, 0x8f, + 0x55, 0x68, 0x27, 0x72, 0x4d, 0x27, 0x79, 0x62, 0x5c, 0x08, 0x47, 0x10, + 0x5c, 0x48, 0x19, 0x7d, 0xfd, 0x74, 0x85, 0xeb, 0x1a, 0x41, 0xf0, 0x5d, + 0xda, 0xc2, 0x83, 0x25, 0xf4, 0x17, 0xe2, 0x60, 0x63, 0xde, 0x85, 0x2c, + 0x1c, 0xe9, 0x26, 0x7e, 0x05, 0x5e, 0x69, 0x87, 0xb7, 0x4b, 0xa2, 0x89, + 0xdf, 0x2e, 0x37, 0x24, 0x3e, 0x51, 0xf6, 0x80, 0x67, 0x8e, 0x3b, 0x96, + 0xd8, 0x63, 0xc7, 0xcc, 0xfd, 0x20, 0xaf, 0xbf, 0x4f, 0xe3, 0xa5, 0x05, + 0x3e, 0x12, 0x61, 0x9a, 0x87, 0x85, 0xb0, 0x25, 0x2c, 0x6e, 0x82, 0xe0, + 0xfb, 0x29, 0xf6, 0xd9, 0xcd, 0xfd, 0x00, 0x23, 0xe8, 0x37, 0xbf, 0x56, + 0x11, 0x0f, 0xd1, 0xc4, 0x1d, 0xe8, 0xfb, 0xb7, 0xd1, 0xf7, 0xbe, 0x32, + 0xfb, 0x83, 0x7c, 0xc0, 0xd8, 0x47, 0x2a, 0x21, 0xbc, 0xcb, 0xf5, 0x1d, + 0xce, 0x79, 0xa7, 0xb5, 0xeb, 0xc2, 0x6f, 0x8d, 0x48, 0x4f, 0xc1, 0x97, + 0xcb, 0x56, 0x66, 0xd6, 0xb8, 0xf2, 0x2e, 0xc8, 0xda, 0x40, 0x4e, 0x42, + 0x86, 0xcd, 0x68, 0xba, 0xc9, 0xae, 0xe7, 0xff, 0x11, 0xf9, 0xe4, 0x0a, + 0xc6, 0x94, 0x7b, 0x7d, 0xda, 0xab, 0xb3, 0xc1, 0x8c, 0x4f, 0x99, 0xbc, + 0x4a, 0xc6, 0xbd, 0x7c, 0x27, 0xf4, 0x03, 0xd2, 0x1a, 0xe9, 0x63, 0x27, + 0xb2, 0x91, 0x64, 0x62, 0x58, 0xb8, 0xc7, 0x89, 0xfb, 0x13, 0xb8, 0xef, + 0x87, 0xf2, 0xc0, 0x85, 0x9c, 0xe3, 0x1c, 0x9a, 0xfe, 0x86, 0xcb, 0xf3, + 0x65, 0x0f, 0x08, 0xd7, 0x09, 0x93, 0xf1, 0xbd, 0xda, 0x26, 0x01, 0xd5, + 0x15, 0x59, 0x76, 0x33, 0x2c, 0x12, 0xbf, 0xaa, 0xbc, 0xde, 0x73, 0x05, + 0x3e, 0x67, 0x1c, 0x21, 0x1a, 0xcd, 0x16, 0xe5, 0xb5, 0x48, 0xb7, 0xbc, + 0x96, 0x4d, 0xd5, 0x4b, 0xaf, 0x96, 0xf9, 0xcc, 0xd3, 0xe9, 0xb3, 0x26, + 0xdd, 0x85, 0x2e, 0xe1, 0x9c, 0xf4, 0x40, 0x46, 0x4f, 0x00, 0x6e, 0xe2, + 0xb0, 0x87, 0x32, 0x89, 0xf3, 0xa7, 0x54, 0x3a, 0x16, 0xcd, 0x95, 0xa5, + 0x2f, 0x57, 0xb4, 0xb1, 0x9e, 0x01, 0x8e, 0x7f, 0x95, 0xc5, 0x43, 0xa3, + 0xb8, 0x80, 0xad, 0x2f, 0x92, 0x70, 0xe0, 0x2b, 0x43, 0xd7, 0x3f, 0xba, + 0x4a, 0x1a, 0x89, 0x9b, 0x1e, 0xf0, 0x52, 0x0d, 0x74, 0xd1, 0xfd, 0xcd, + 0x5c, 0x37, 0xd5, 0x36, 0x64, 0xec, 0x63, 0xbf, 0xac, 0xd2, 0x7f, 0x1b, + 0x57, 0xe9, 0x51, 0x2b, 0x2f, 0xa3, 0x7d, 0x94, 0x97, 0x4f, 0x97, 0x08, + 0x8f, 0x78, 0x11, 0x3f, 0xd1, 0xd7, 0x5b, 0x16, 0x15, 0x49, 0x7b, 0xd1, + 0xde, 0xf2, 0x42, 0xfa, 0x7f, 0xba, 0xf2, 0x61, 0x6b, 0x0b, 0x56, 0xc7, + 0x54, 0xab, 0xf3, 0xc8, 0x83, 0xcb, 0xe5, 0x11, 0x26, 0x89, 0xae, 0x48, + 0x5f, 0xf8, 0x54, 0x7b, 0x47, 0xde, 0xab, 0x15, 0xe2, 0x39, 0x80, 0xdc, + 0x06, 0xae, 0xcb, 0x5c, 0xaf, 0xde, 0x8f, 0x79, 0xfb, 0x3f, 0x41, 0x26, + 0xc6, 0x7c, 0x4f, 0xea, 0xe0, 0xdb, 0xbe, 0x0c, 0xdd, 0xf9, 0x8a, 0x7f, + 0xe1, 0x53, 0x9d, 0x1d, 0x41, 0xf0, 0xac, 0x9f, 0x4f, 0xb8, 0x90, 0x1f, + 0x87, 0x2d, 0xbe, 0x87, 0x81, 0xef, 0x89, 0x39, 0x7c, 0x27, 0xe4, 0x62, + 0xd7, 0xf7, 0x03, 0xae, 0xf5, 0x0d, 0x97, 0x6f, 0xbd, 0x55, 0xa5, 0x3f, + 0xfe, 0xa1, 0x6c, 0x37, 0xfb, 0x1b, 0x91, 0xc3, 0x95, 0x9b, 0x88, 0xbf, + 0x28, 0xc6, 0x7a, 0x4f, 0x9f, 0x6f, 0xfa, 0xed, 0x5b, 0xd0, 0x2f, 0xe9, + 0xe5, 0x47, 0xac, 0x8b, 0x32, 0xd5, 0x75, 0x33, 0xa0, 0xcb, 0xbc, 0xad, + 0x3b, 0x70, 0x85, 0xba, 0xde, 0x15, 0xea, 0x1e, 0x46, 0xdd, 0x3d, 0xb6, + 0xee, 0x85, 0xcf, 0xbc, 0xb9, 0x7e, 0x07, 0xb8, 0xc7, 0x0e, 0x3e, 0x80, + 0xb8, 0x11, 0xff, 0x36, 0xfc, 0xbe, 0x85, 0xed, 0x28, 0xda, 0xf7, 0x23, + 0x95, 0x21, 0x19, 0xae, 0xec, 0xc4, 0x33, 0x88, 0xb4, 0x3e, 0x3c, 0xfb, + 0xf0, 0x3b, 0x8d, 0x47, 0xa2, 0x6e, 0xfa, 0xc2, 0x5d, 0xc3, 0x7e, 0x88, + 0x57, 0xae, 0xcd, 0xb3, 0x0f, 0xd8, 0x17, 0x5d, 0x3f, 0x41, 0x1f, 0x61, + 0xfa, 0x07, 0x50, 0x67, 0x1a, 0x69, 0x2b, 0x69, 0x7b, 0x62, 0xae, 0xab, + 0xeb, 0x54, 0xc3, 0x36, 0x1d, 0xce, 0x05, 0xf2, 0x0d, 0x8d, 0xf6, 0x16, + 0x43, 0x18, 0xef, 0x44, 0x1b, 0xe3, 0x57, 0x29, 0xff, 0x1e, 0xc2, 0x15, + 0x57, 0xfe, 0xc7, 0xf0, 0x7e, 0x2d, 0xd8, 0x9d, 0x62, 0x4c, 0x9e, 0xf3, + 0x7e, 0xdd, 0xaa, 0xa5, 0x7b, 0x9f, 0x42, 0x1a, 0xe8, 0x84, 0x4e, 0x69, + 0xb0, 0x74, 0x5a, 0x80, 0xe5, 0x43, 0x1a, 0xe5, 0x98, 0x17, 0x97, 0x4d, + 0x76, 0xe6, 0xa5, 0x07, 0xba, 0x8c, 0xb2, 0xf6, 0xd3, 0xf5, 0x26, 0x0e, + 0x03, 0xcb, 0xd1, 0xef, 0x04, 0x3d, 0x37, 0x88, 0x87, 0xfa, 0x03, 0x11, + 0x0f, 0x34, 0x18, 0xd6, 0x4f, 0x7a, 0x03, 0x11, 0x8e, 0x19, 0x1c, 0x5f, + 0xe6, 0xba, 0x34, 0x6d, 0x6b, 0xd6, 0x0f, 0x6d, 0x1c, 0xfe, 0x7b, 0x59, + 0xc4, 0x67, 0x1a, 0xdb, 0x0b, 0xde, 0x55, 0xe3, 0x2f, 0x59, 0x63, 0xc1, + 0x38, 0xf3, 0x49, 0x68, 0x30, 0xaf, 0x4f, 0xcb, 0xe9, 0xfc, 0x35, 0x35, + 0xd2, 0xe0, 0xf5, 0xeb, 0xdf, 0x2c, 0xd3, 0xe0, 0x81, 0x4f, 0x17, 0x95, + 0x61, 0x1a, 0xf3, 0x0a, 0x6b, 0x94, 0xde, 0xab, 0xa4, 0xf7, 0x28, 0xc9, + 0x83, 0xa9, 0x64, 0x62, 0x48, 0x25, 0xbd, 0x71, 0xd9, 0x0f, 0xb9, 0x43, + 0x39, 0x39, 0x73, 0x7f, 0x44, 0xb8, 0x9f, 0xef, 0x5d, 0x92, 0xf5, 0x29, + 0x3f, 0x0b, 0x9f, 0x57, 0x94, 0x75, 0x95, 0x97, 0x1a, 0xcc, 0xd8, 0xb8, + 0x0f, 0x01, 0x70, 0x36, 0xd1, 0x86, 0xbb, 0xb5, 0x81, 0x3c, 0x94, 0x50, + 0x11, 0xd9, 0x45, 0x3f, 0x5f, 0x7d, 0xb1, 0x5e, 0xea, 0xa7, 0xd7, 0x78, + 0x52, 0xd1, 0xe9, 0x66, 0x7f, 0x60, 0xb2, 0x73, 0x48, 0x89, 0x1e, 0x7b, + 0x46, 0xbd, 0x91, 0xcc, 0x9e, 0xb5, 0xfa, 0x23, 0x90, 0xc7, 0xb4, 0xbe, + 0x98, 0xf9, 0xbc, 0x2b, 0x17, 0x82, 0xb6, 0x4d, 0x17, 0xda, 0xb3, 0x5d, + 0xb4, 0x73, 0x57, 0xd9, 0xfd, 0x95, 0x8c, 0x63, 0xbd, 0x4b, 0x9e, 0xf3, + 0x0b, 0x18, 0xf7, 0x7e, 0xb9, 0xe0, 0xb3, 0xbf, 0x99, 0xcf, 0x79, 0xc2, + 0x74, 0xc2, 0x6e, 0xfa, 0x13, 0xf5, 0xa7, 0x80, 0x87, 0x7d, 0x52, 0x07, + 0x5f, 0xc9, 0xee, 0x4b, 0x0e, 0xe4, 0x45, 0xcf, 0x4b, 0x8f, 0xa0, 0xad, + 0x15, 0x3e, 0xf8, 0x10, 0x76, 0x73, 0xcd, 0x91, 0xab, 0x21, 0x77, 0x1d, + 0xbd, 0xc7, 0x02, 0x93, 0xe1, 0x4d, 0x61, 0xde, 0x33, 0x03, 0x2c, 0x57, + 0x2f, 0xd3, 0x31, 0xf2, 0xba, 0xe6, 0x97, 0x4f, 0x65, 0xfd, 0x76, 0x4f, + 0x39, 0xc3, 0x8c, 0x31, 0x00, 0xaf, 0xa4, 0xcd, 0x54, 0x6c, 0xbb, 0xcf, + 0xb6, 0x58, 0xe6, 0x2a, 0xf9, 0xf6, 0xc0, 0x85, 0x7f, 0x78, 0xd6, 0xff, + 0x7b, 0xc0, 0x91, 0x81, 0x4c, 0xe0, 0xf3, 0x6a, 0x90, 0x8f, 0x31, 0xa6, + 0xf5, 0xbf, 0xeb, 0xad, 0x9d, 0xac, 0x79, 0x7f, 0x58, 0xef, 0x93, 0x79, + 0xfe, 0x33, 0x59, 0xae, 0x77, 0xc0, 0x36, 0xc9, 0x69, 0xb9, 0x18, 0xfd, + 0x69, 0x0e, 0xf0, 0x14, 0x2a, 0xb4, 0x43, 0xfe, 0x06, 0x76, 0x88, 0xd6, + 0x93, 0xf2, 0xed, 0x41, 0xe6, 0xb1, 0xdd, 0xec, 0xd5, 0xae, 0xd6, 0x0b, + 0x21, 0x2c, 0xc9, 0xce, 0x1c, 0xf2, 0x47, 0xb4, 0x1d, 0xef, 0xc9, 0xac, + 0xe7, 0xea, 0x7d, 0x27, 0xf9, 0xc1, 0x20, 0x78, 0xc5, 0x77, 0xe5, 0xa4, + 0x86, 0xf9, 0x05, 0xf4, 0xe1, 0xc8, 0xc4, 0x80, 0xfb, 0xd3, 0x93, 0x3e, + 0xc7, 0xc7, 0x3c, 0xae, 0x2b, 0x6d, 0x8e, 0x1b, 0xf8, 0x68, 0x9b, 0x7e, + 0x2f, 0x98, 0x8d, 0x71, 0xdd, 0x02, 0x3c, 0x5d, 0x6a, 0xf7, 0x6e, 0x90, + 0xdb, 0xe6, 0x6c, 0x9a, 0x69, 0x31, 0x36, 0xa3, 0xd1, 0x69, 0x17, 0xfe, + 0x61, 0xc4, 0xbf, 0xb0, 0xba, 0x80, 0xb9, 0x81, 0x0e, 0x5b, 0x0c, 0x4b, + 0x8a, 0xb0, 0x0c, 0x6b, 0x58, 0x62, 0xc0, 0xa5, 0x0b, 0xd9, 0x77, 0x9b, + 0x1c, 0x02, 0xde, 0x87, 0x06, 0x45, 0x9e, 0x85, 0x4d, 0x76, 0xbe, 0x0a, + 0x9e, 0x19, 0xc0, 0x73, 0xde, 0xe7, 0x5e, 0x00, 0xe6, 0xf9, 0xde, 0xb0, + 0x70, 0x2f, 0x00, 0x71, 0xd8, 0x81, 0xdf, 0x22, 0x33, 0xd0, 0xbf, 0x27, + 0xfd, 0xd7, 0x82, 0xf1, 0x18, 0x75, 0x23, 0xda, 0x99, 0xdb, 0x1b, 0x14, + 0xc8, 0xe7, 0x53, 0xd4, 0x43, 0xb5, 0xd2, 0xb6, 0x8e, 0x7e, 0x88, 0x91, + 0x9f, 0x37, 0xf8, 0x19, 0xf4, 0xf5, 0x5b, 0x2b, 0xa5, 0x3e, 0x2f, 0xfd, + 0x1d, 0x75, 0xc8, 0x73, 0x6d, 0xde, 0x80, 0xce, 0xeb, 0xef, 0x38, 0x8c, + 0xfc, 0x8f, 0xaf, 0x64, 0xbc, 0xdb, 0xf5, 0xd7, 0x4b, 0xdb, 0x1a, 0xe6, + 0x55, 0xf3, 0xe0, 0xab, 0xdc, 0x83, 0x69, 0x75, 0x38, 0x64, 0x59, 0x29, + 0xef, 0x71, 0xa7, 0xdd, 0x21, 0xcc, 0xc5, 0x6e, 0x9f, 0xb2, 0xed, 0xbf, + 0xa3, 0x6e, 0x4a, 0x6e, 0xf4, 0x07, 0x91, 0x37, 0x8d, 0xbc, 0xc3, 0x36, + 0x6f, 0xd0, 0xe6, 0x6d, 0x43, 0xde, 0x3e, 0xe0, 0xef, 0x6e, 0x9d, 0x9e, + 0xe5, 0x6f, 0x53, 0xc7, 0x5b, 0xd9, 0x71, 0xe1, 0x33, 0x37, 0xf8, 0x84, + 0x0b, 0x79, 0x25, 0xae, 0x8b, 0xde, 0x26, 0x79, 0x2f, 0x79, 0x0b, 0x7b, + 0xfd, 0x66, 0xb1, 0x0e, 0xb2, 0x89, 0x7b, 0x80, 0x69, 0xb3, 0x6e, 0xf1, + 0x5e, 0x96, 0xff, 0x40, 0xba, 0xeb, 0xc9, 0x38, 0x5f, 0x5b, 0xc9, 0xb8, + 0xd8, 0x88, 0x4f, 0xfb, 0x3a, 0x90, 0x9c, 0x5e, 0x3f, 0xa1, 0x7f, 0x5b, + 0x44, 0x3a, 0xe9, 0x41, 0x35, 0x45, 0xf4, 0x3e, 0x2d, 0x7e, 0x47, 0x61, + 0xf7, 0x06, 0x42, 0x9f, 0x8f, 0x36, 0x5d, 0xc6, 0xe3, 0xda, 0x50, 0x98, + 0xe7, 0x21, 0x4f, 0x6d, 0x8a, 0xc0, 0x26, 0xaa, 0xf5, 0x1d, 0x1d, 0xa3, + 0x2e, 0xe8, 0x75, 0x00, 0xc6, 0xdf, 0x32, 0xf0, 0x63, 0x02, 0xe9, 0x47, + 0xdf, 0xa4, 0xfd, 0x68, 0x87, 0xef, 0x1d, 0x10, 0xee, 0x67, 0x65, 0x7a, + 0xbb, 0xf7, 0x6d, 0x99, 0xa7, 0xf3, 0x19, 0x49, 0x66, 0x94, 0x03, 0xff, + 0x75, 0xab, 0x23, 0xf5, 0xb0, 0x3d, 0x6e, 0x30, 0xfa, 0xcd, 0xe3, 0x9e, + 0xc4, 0x8b, 0xda, 0x56, 0x6b, 0xb4, 0xf3, 0x91, 0x05, 0x6e, 0xb8, 0x1f, + 0x7c, 0xe0, 0x9e, 0xdd, 0x7e, 0x21, 0x09, 0x6a, 0xd4, 0xba, 0x71, 0x18, + 0xb4, 0x91, 0x4d, 0x19, 0xdd, 0x78, 0xc3, 0x9c, 0x6e, 0xfc, 0xf3, 0x95, + 0xe4, 0x89, 0xe1, 0x72, 0x1c, 0x75, 0xf5, 0x3a, 0x4a, 0x82, 0x75, 0x6b, + 0x31, 0x9f, 0xe7, 0xfd, 0xec, 0x35, 0xa0, 0x2f, 0xc8, 0xe1, 0x64, 0xe7, + 0x29, 0xd4, 0x2d, 0xa0, 0xee, 0xe4, 0x5c, 0x5d, 0x47, 0x46, 0x7c, 0xbd, + 0xef, 0x59, 0x26, 0xcb, 0x21, 0x1d, 0x26, 0xe3, 0xb7, 0x6a, 0x5e, 0xe0, + 0x7e, 0x30, 0x37, 0x71, 0x9f, 0x6c, 0xd6, 0xb4, 0xdd, 0x27, 0xdc, 0x27, + 0xc5, 0xb6, 0xef, 0x0b, 0xda, 0xd6, 0x10, 0xbe, 0x12, 0xde, 0xa4, 0x8d, + 0x31, 0xbc, 0xc3, 0xf9, 0x37, 0xf3, 0x3e, 0xe4, 0x10, 0xdf, 0xbf, 0x1f, + 0xe4, 0x07, 0x39, 0x2f, 0xfc, 0x9e, 0xa7, 0xb9, 0x11, 0xd0, 0x5c, 0xc4, + 0x7f, 0xbb, 0x0c, 0xeb, 0x3d, 0x10, 0x29, 0x99, 0xd0, 0xf1, 0xcc, 0x0b, + 0xc1, 0x23, 0x0b, 0xe4, 0xf8, 0x47, 0x94, 0xa1, 0x21, 0xfe, 0x2e, 0x24, + 0xea, 0x64, 0x66, 0x4d, 0x9d, 0xde, 0xf1, 0x41, 0x7c, 0x8c, 0xde, 0x73, + 0x3b, 0xf8, 0xf5, 0xfa, 0xb9, 0xb1, 0x00, 0xdf, 0xc0, 0xe3, 0x4e, 0x63, + 0xeb, 0x63, 0x1c, 0x19, 0xed, 0xbf, 0x67, 0x8b, 0x4a, 0xef, 0x0b, 0xa2, + 0x8e, 0x3f, 0x00, 0x9d, 0x6a, 0xf6, 0xa4, 0xe0, 0x5d, 0xe1, 0xbc, 0x29, + 0xed, 0x73, 0x1c, 0x04, 0x0f, 0x1f, 0xf4, 0xb3, 0x6b, 0x6a, 0x75, 0xdb, + 0x49, 0xef, 0x7a, 0x6d, 0x13, 0x6e, 0x94, 0x99, 0x14, 0xdb, 0x23, 0x5e, + 0xfe, 0x47, 0x30, 0xe4, 0xcd, 0xa0, 0x7f, 0x43, 0xff, 0x59, 0x5f, 0xb5, + 0xd4, 0x49, 0xf5, 0x3e, 0x53, 0xe2, 0xc9, 0x85, 0xbd, 0xd2, 0x01, 0xfc, + 0x18, 0x78, 0x73, 0xe5, 0xb7, 0x49, 0x21, 0xe6, 0xda, 0xb1, 0x45, 0xb4, + 0x2f, 0x37, 0x91, 0xaa, 0x83, 0x2d, 0xf8, 0x17, 0xc1, 0xe4, 0x82, 0x31, + 0x1e, 0xac, 0x1a, 0xe3, 0x4c, 0x02, 0xd8, 0x68, 0x89, 0xcc, 0xc9, 0x01, + 0xf6, 0x65, 0x64, 0x52, 0x38, 0xc6, 0x3a, 0x8c, 0x71, 0xc7, 0xdc, 0x18, + 0x0f, 0x2f, 0x1a, 0xe3, 0x61, 0x8c, 0x11, 0xf6, 0x42, 0x29, 0xd3, 0xe9, + 0xce, 0xcf, 0xfb, 0xd5, 0x35, 0x73, 0xf3, 0x29, 0xdc, 0xeb, 0x84, 0xf1, + 0xd3, 0xa6, 0xd8, 0x08, 0x78, 0x74, 0x5b, 0x90, 0x71, 0x0e, 0x64, 0x5b, + 0x76, 0x4d, 0x8d, 0x1d, 0xff, 0x76, 0x96, 0x2b, 0x1b, 0x1c, 0x9c, 0x4c, + 0xb9, 0x9d, 0x8f, 0xa0, 0xbf, 0xbd, 0x76, 0x5c, 0xbd, 0xe5, 0xab, 0x31, + 0xae, 0x0b, 0xdf, 0xc1, 0x18, 0xe0, 0xb3, 0x9d, 0xa0, 0x0f, 0x9c, 0x18, + 0x92, 0x05, 0xb2, 0xeb, 0x33, 0xf3, 0x72, 0xd4, 0xc0, 0x4c, 0xdb, 0xba, + 0x30, 0x07, 0xf3, 0xdd, 0x8b, 0x60, 0xbe, 0x1b, 0x30, 0xef, 0xb3, 0xf3, + 0xb2, 0xaf, 0x6a, 0xcf, 0x62, 0x48, 0x47, 0xfc, 0xfd, 0xbc, 0xf5, 0x45, + 0x3e, 0x20, 0xf7, 0x97, 0x3a, 0xe5, 0xcb, 0x95, 0xe4, 0x59, 0xc6, 0xd1, + 0xcf, 0x55, 0x92, 0xe3, 0x22, 0x5d, 0xf2, 0xc7, 0xb0, 0x73, 0xae, 0x82, + 0x6f, 0xf1, 0x34, 0xfc, 0xd7, 0x3f, 0xa9, 0xf8, 0xf2, 0xc4, 0xdc, 0x7e, + 0x38, 0xea, 0xba, 0xb4, 0x9c, 0x84, 0x4f, 0xbb, 0xed, 0x68, 0x1b, 0xf7, + 0x2a, 0x11, 0xbe, 0xbb, 0xa8, 0x73, 0xda, 0x94, 0xe6, 0xc5, 0xef, 0x62, + 0xbc, 0xa7, 0xa9, 0x6b, 0xd6, 0xfa, 0xbe, 0x77, 0xb3, 0x5a, 0x47, 0x99, + 0x90, 0xff, 0x5a, 0xe4, 0x03, 0xf5, 0x26, 0xc6, 0x92, 0xf1, 0x9a, 0xc9, + 0x1b, 0xdb, 0x3a, 0x12, 0x7d, 0x42, 0x5b, 0x82, 0xfe, 0x36, 0x6c, 0xa1, + 0xd2, 0xe6, 0xf8, 0x5a, 0xa1, 0x4c, 0xa2, 0x5d, 0x94, 0x96, 0x09, 0xc0, + 0x3e, 0x06, 0x89, 0x50, 0x68, 0xf6, 0x47, 0x7b, 0xd5, 0x44, 0x03, 0x79, + 0x70, 0xdb, 0x19, 0xd0, 0xd7, 0x36, 0x8c, 0xa9, 0x2b, 0x79, 0x76, 0x46, + 0x65, 0x4e, 0xac, 0x95, 0x57, 0x82, 0xa1, 0x66, 0x47, 0x9e, 0xd8, 0xc4, + 0x3c, 0x2d, 0xb7, 0x3f, 0xd5, 0x0b, 0xf9, 0xd4, 0xce, 0x73, 0x0b, 0x03, + 0xf2, 0x2f, 0x77, 0x80, 0x06, 0x7f, 0xb8, 0xe9, 0x6b, 0xc1, 0x6c, 0xb3, + 0x2b, 0x5b, 0x37, 0x25, 0xbd, 0xbc, 0xc2, 0x78, 0x4a, 0x18, 0x4f, 0x09, + 0xe3, 0xe3, 0x98, 0x4b, 0x18, 0xd7, 0x15, 0xf7, 0x4a, 0xf5, 0x2c, 0x88, + 0xcb, 0x1a, 0x3f, 0x2d, 0x93, 0x77, 0x65, 0x83, 0xdd, 0x2b, 0x35, 0x5c, + 0x1f, 0xae, 0xb1, 0x65, 0x64, 0x3c, 0x28, 0xf8, 0x7f, 0x70, 0x55, 0xb6, + 0x2b, 0xb6, 0x58, 0xe7, 0xdc, 0x35, 0xaf, 0x73, 0x44, 0x9e, 0x33, 0xf3, + 0x86, 0x39, 0xf3, 0xbd, 0x49, 0x6e, 0x86, 0x87, 0x0e, 0xdc, 0xaa, 0xf7, + 0x3c, 0x77, 0xe0, 0x9b, 0x36, 0xd5, 0xa7, 0xf5, 0x3a, 0xe2, 0x4c, 0xf9, + 0x1e, 0x3b, 0x77, 0xf7, 0x68, 0x3d, 0xbb, 0x75, 0xd3, 0xa5, 0x80, 0xfb, + 0xdc, 0xbc, 0x4d, 0xcb, 0xc5, 0x22, 0x68, 0xef, 0xd5, 0x69, 0xde, 0xe7, + 0x7a, 0x76, 0x41, 0x9f, 0x13, 0x01, 0xde, 0xe6, 0xe2, 0x62, 0xf5, 0x48, + 0xa3, 0xbe, 0xf8, 0x69, 0x83, 0x59, 0x47, 0xa5, 0x6c, 0x58, 0x83, 0x34, + 0xd7, 0xec, 0x05, 0x5e, 0x90, 0xf7, 0xdf, 0xea, 0xcd, 0x9e, 0x8f, 0xea, + 0xb2, 0xe0, 0x31, 0xbd, 0x2f, 0x84, 0xfb, 0x03, 0x7f, 0x79, 0xa5, 0xb1, + 0x4d, 0xc3, 0x7c, 0xa6, 0xff, 0x38, 0x98, 0xd0, 0x31, 0x36, 0xf6, 0xf5, + 0x43, 0xfc, 0x5e, 0xbc, 0x5f, 0x24, 0xb4, 0x5d, 0xeb, 0x40, 0xf7, 0xda, + 0x5f, 0x16, 0x94, 0x89, 0xe7, 0x25, 0x22, 0x13, 0x55, 0x30, 0x4e, 0x10, + 0xee, 0x52, 0xd7, 0xaa, 0xf9, 0xd8, 0xdd, 0x6a, 0xa4, 0x11, 0xc6, 0x75, + 0x8b, 0xf2, 0xc8, 0x1b, 0xad, 0x2b, 0x49, 0x37, 0xd3, 0xc2, 0xb4, 0xf9, + 0x31, 0xcd, 0x68, 0xfb, 0xb9, 0x6d, 0x95, 0xde, 0xfb, 0xc4, 0x35, 0x46, + 0xc6, 0x08, 0x63, 0x26, 0xdf, 0xf5, 0xff, 0x56, 0xd7, 0x19, 0x9a, 0xab, + 0xa3, 0xe7, 0x02, 0xf9, 0x6e, 0x55, 0x5e, 0x35, 0xdc, 0xd4, 0x5f, 0x43, + 0x9d, 0x75, 0xd0, 0x89, 0x17, 0x53, 0xab, 0xc3, 0xbd, 0xf0, 0xb0, 0x21, + 0xb2, 0xd7, 0xd4, 0x5a, 0x99, 0x3f, 0x81, 0x79, 0x7d, 0x26, 0x65, 0x78, + 0x51, 0xf3, 0x61, 0xf1, 0x36, 0xf8, 0xeb, 0xa1, 0xde, 0xa0, 0x9c, 0x26, + 0x6f, 0x22, 0xad, 0x42, 0x9f, 0xe0, 0xc2, 0xea, 0x99, 0xae, 0x57, 0x03, + 0xee, 0xb3, 0x7c, 0x45, 0xdb, 0x51, 0x43, 0xb2, 0xb0, 0xed, 0xd1, 0x7b, + 0x5e, 0xbf, 0xed, 0xa1, 0x65, 0xda, 0x1e, 0xb2, 0x6d, 0x8b, 0x6b, 0xda, + 0x8e, 0x5e, 0xa1, 0xed, 0x81, 0x37, 0x68, 0x7b, 0x70, 0x99, 0xb6, 0x07, + 0xc3, 0xb6, 0x95, 0x69, 0xdb, 0x0b, 0xdb, 0x4e, 0x2c, 0xc2, 0xc9, 0x67, + 0x5e, 0xbf, 0xed, 0x7d, 0xcb, 0xb4, 0xbd, 0x6f, 0x11, 0xdc, 0xc4, 0x49, + 0x2d, 0x74, 0xff, 0x3d, 0xda, 0xe6, 0xac, 0x03, 0xdf, 0x5c, 0x84, 0xfc, + 0x36, 0xfe, 0xc8, 0x85, 0xbb, 0x66, 0xcb, 0xe0, 0x2b, 0xf8, 0xd7, 0x99, + 0x72, 0x03, 0x9e, 0x71, 0xd8, 0x33, 0x28, 0x07, 0x7b, 0xbc, 0x26, 0x1d, + 0xc8, 0xc9, 0x6e, 0x96, 0xcd, 0xc7, 0x6b, 0xe7, 0xf4, 0xc6, 0x3d, 0xe8, + 0x8f, 0x6d, 0xfb, 0x5e, 0xbf, 0xbc, 0xa6, 0xfb, 0xcb, 0x95, 0xe9, 0x8f, + 0x21, 0xbd, 0x42, 0x1f, 0x97, 0xf5, 0x42, 0x19, 0x58, 0x67, 0xd7, 0x3e, + 0x68, 0x6b, 0x32, 0x0e, 0xa7, 0xed, 0x51, 0x29, 0x94, 0x7f, 0x12, 0x4c, + 0x83, 0x2e, 0x46, 0xe6, 0x74, 0xc8, 0x93, 0xab, 0x68, 0xb3, 0x8f, 0x53, + 0xb3, 0x54, 0xc5, 0xa0, 0x46, 0x7c, 0xa6, 0xfd, 0x98, 0x6d, 0xc2, 0x0e, + 0x0c, 0xcb, 0x32, 0x6e, 0x6c, 0x62, 0x4e, 0x67, 0x21, 0x33, 0xcd, 0x9e, + 0x0e, 0xfa, 0x2a, 0x4f, 0x81, 0x97, 0xf7, 0x43, 0x76, 0x24, 0xf3, 0x22, + 0x3d, 0x8d, 0xe6, 0xac, 0x45, 0x4c, 0x72, 0x5d, 0xbf, 0x69, 0xf1, 0xb8, + 0xef, 0xce, 0xe5, 0xcf, 0x59, 0x40, 0x3e, 0x38, 0x94, 0x91, 0xd7, 0x37, + 0x9a, 0x75, 0xbb, 0xb7, 0x36, 0x32, 0x1e, 0xa3, 0x36, 0x75, 0xaf, 0xd6, + 0xf2, 0xc7, 0x09, 0xbf, 0xbf, 0xb2, 0xe8, 0x3b, 0xac, 0xf7, 0x93, 0xd5, + 0x0b, 0xeb, 0x85, 0xe9, 0x70, 0x4d, 0x16, 0xa4, 0x1f, 0x58, 0xb3, 0xb0, + 0x7e, 0xac, 0x69, 0xe1, 0xf7, 0xe0, 0xa2, 0xef, 0xcf, 0x2c, 0xfa, 0x7e, + 0x61, 0xd1, 0xf7, 0x75, 0x6b, 0x17, 0x95, 0x5f, 0xf4, 0xfd, 0xe5, 0xb5, + 0xcb, 0xc3, 0xfb, 0x57, 0x6b, 0x17, 0xc2, 0xf5, 0x94, 0x5e, 0x73, 0x1d, + 0xaf, 0xb8, 0xb2, 0xbd, 0x88, 0x7c, 0xe7, 0xd6, 0x18, 0xf2, 0xe1, 0xcb, + 0x54, 0xe7, 0x73, 0x8d, 0xe3, 0x1d, 0xb1, 0x85, 0xed, 0xcd, 0xd7, 0xdb, + 0x31, 0x5f, 0x2f, 0x35, 0x5f, 0xcf, 0xf8, 0x23, 0x13, 0x15, 0xe6, 0x31, + 0x3d, 0x6c, 0xd7, 0xd4, 0x1d, 0x29, 0x79, 0xfa, 0x3c, 0xc2, 0x80, 0x3e, + 0x8f, 0x90, 0x80, 0x6f, 0xf4, 0x94, 0x8e, 0xeb, 0xaf, 0x51, 0x48, 0xaf, + 0x34, 0xea, 0xd8, 0xbe, 0xe8, 0x33, 0x09, 0x03, 0xb0, 0xb9, 0x78, 0x0e, + 0x21, 0x90, 0x9d, 0x29, 0xf3, 0x36, 0xe7, 0x12, 0x0e, 0x07, 0xbd, 0x5e, + 0x10, 0x0c, 0xfb, 0x67, 0xad, 0x2c, 0xc7, 0xbb, 0x62, 0xea, 0xd0, 0xd7, + 0x7c, 0x14, 0xfa, 0x66, 0xde, 0xc7, 0x7c, 0x8a, 0xf6, 0x3a, 0x68, 0xa6, + 0x1b, 0x7a, 0x37, 0xf9, 0xa4, 0x68, 0xdd, 0xd1, 0x05, 0x9d, 0xeb, 0xdd, + 0xfb, 0x3e, 0xd8, 0x3a, 0x5f, 0x06, 0xad, 0x1f, 0x4b, 0xf5, 0x68, 0xff, + 0xff, 0x1c, 0x74, 0x31, 0xe3, 0x84, 0x8f, 0x69, 0xda, 0x22, 0x8d, 0x35, + 0xe8, 0xb3, 0x50, 0x27, 0x53, 0x4e, 0x34, 0xdb, 0x75, 0xde, 0xc4, 0xcd, + 0x53, 0xed, 0xde, 0x73, 0xe0, 0xb5, 0x7e, 0x7f, 0x03, 0x6c, 0x66, 0xd1, + 0x3a, 0xbf, 0x50, 0x5a, 0x6f, 0x6d, 0x83, 0x66, 0x19, 0x77, 0xb9, 0x56, + 0x93, 0xec, 0x19, 0x32, 0x3e, 0x66, 0x3c, 0xa1, 0x18, 0x23, 0xe6, 0xfa, + 0x05, 0xcf, 0x39, 0x70, 0x9d, 0x9b, 0xf1, 0x90, 0xf1, 0x7b, 0x47, 0xfc, + 0xbc, 0x17, 0xb1, 0x67, 0x23, 0xb2, 0x45, 0x43, 0x9b, 0x7b, 0xb4, 0xad, + 0x1a, 0x05, 0x3f, 0x7d, 0x0f, 0x74, 0xcf, 0xba, 0xa4, 0xfd, 0xef, 0x04, + 0x93, 0xae, 0x89, 0x4f, 0x29, 0xd4, 0xcb, 0x6a, 0x5c, 0x3d, 0x25, 0x07, + 0x4a, 0xe4, 0xff, 0xa8, 0x96, 0xe5, 0xbb, 0x53, 0x94, 0x07, 0x51, 0xe0, + 0x71, 0x0a, 0xf8, 0x6b, 0x90, 0xdd, 0x5d, 0x45, 0x94, 0x89, 0xc8, 0xd0, + 0x40, 0x03, 0x78, 0x8f, 0x76, 0x09, 0xdf, 0x2e, 0xca, 0x7b, 0x32, 0x55, + 0x1c, 0xd7, 0x7b, 0x9e, 0x1f, 0x43, 0xdd, 0xc7, 0xf1, 0x4c, 0x14, 0xcb, + 0xa8, 0xf3, 0xb0, 0x2e, 0x3f, 0x31, 0xca, 0x73, 0x22, 0x02, 0x7b, 0xff, + 0x49, 0x29, 0x4c, 0xb6, 0xc1, 0x2f, 0x99, 0x1e, 0x77, 0xe7, 0xe2, 0xe4, + 0xff, 0xa5, 0x91, 0xeb, 0xcc, 0x85, 0xeb, 0xb8, 0x27, 0x47, 0xdc, 0x81, + 0xcd, 0xaa, 0xb3, 0x49, 0xaf, 0xf9, 0xf4, 0x48, 0x3f, 0x6c, 0x8a, 0x9b, + 0x2b, 0xcf, 0xc4, 0xcc, 0xda, 0xc0, 0x82, 0xf5, 0x86, 0xc3, 0xc4, 0x8a, + 0x3a, 0xea, 0xf2, 0xdc, 0xa7, 0x4c, 0x9c, 0x81, 0xf6, 0x39, 0x1a, 0xae, + 0xe7, 0x30, 0xcd, 0x93, 0xb6, 0xeb, 0x00, 0xd7, 0x99, 0x7f, 0xd2, 0xf2, + 0xf5, 0x89, 0x4d, 0x61, 0x5f, 0xf9, 0x60, 0x6c, 0x53, 0x5e, 0x3e, 0x81, + 0x27, 0x77, 0x5d, 0x72, 0x34, 0xab, 0xd8, 0xef, 0x37, 0x02, 0xc6, 0x02, + 0x54, 0xba, 0x55, 0xf2, 0x4d, 0xd5, 0xfd, 0x33, 0xad, 0xc3, 0x2b, 0xa8, + 0xd7, 0x83, 0x63, 0x26, 0x11, 0x03, 0x0e, 0xf2, 0x6f, 0x08, 0xcf, 0x16, + 0xcf, 0x57, 0xcb, 0xc1, 0x73, 0xc2, 0xae, 0xd7, 0x70, 0x0d, 0x66, 0x05, + 0xf0, 0xd2, 0x80, 0xf4, 0x09, 0x19, 0x39, 0xfe, 0x3b, 0x31, 0xee, 0x17, + 0xaa, 0xd1, 0x7e, 0xf5, 0x7d, 0xf5, 0x26, 0x06, 0xf2, 0x2c, 0xca, 0x30, + 0x7f, 0x1c, 0x75, 0x92, 0xf9, 0x6c, 0x64, 0xad, 0x0c, 0xe9, 0x7e, 0x83, + 0x48, 0xdb, 0xb6, 0x7a, 0xbd, 0x4f, 0x5f, 0xce, 0x30, 0x6e, 0x11, 0xd6, + 0x7d, 0x56, 0xef, 0x83, 0x73, 0xd3, 0xc9, 0x7c, 0x5f, 0x84, 0xf2, 0xa9, + 0x53, 0x7a, 0xb9, 0xce, 0x73, 0x66, 0x5c, 0xd3, 0x76, 0xfb, 0x26, 0x9e, + 0x07, 0xdd, 0x02, 0xfb, 0xef, 0x3b, 0x80, 0x89, 0x30, 0x9e, 0x40, 0x3a, + 0x7c, 0xc2, 0xd7, 0x85, 0x61, 0xfa, 0x4d, 0xc2, 0x30, 0xfd, 0x26, 0x61, + 0x20, 0x2e, 0x00, 0x47, 0xa5, 0x7d, 0x75, 0x68, 0x53, 0x5c, 0x85, 0x71, + 0x1c, 0x2c, 0x4d, 0xc3, 0xbf, 0xd5, 0x31, 0x94, 0xce, 0x69, 0x45, 0x9e, + 0xf7, 0xc0, 0x73, 0xe0, 0xad, 0x12, 0x78, 0x0f, 0xb6, 0xe1, 0x97, 0x61, + 0x1b, 0x3e, 0x01, 0xdb, 0xf0, 0x1c, 0x6c, 0xc3, 0xc7, 0x31, 0x37, 0x8f, + 0x2d, 0xe0, 0xd5, 0x8c, 0xe6, 0xd5, 0x42, 0xe9, 0x02, 0x78, 0xb5, 0xeb, + 0x0a, 0xfc, 0xe8, 0xc2, 0xc6, 0xa7, 0x0d, 0xed, 0xc0, 0x96, 0xff, 0xb8, + 0xf6, 0x8b, 0x1f, 0x4c, 0x8d, 0xb1, 0x0e, 0x68, 0x38, 0x49, 0x9f, 0x16, + 0xf2, 0x3f, 0x99, 0x07, 0xef, 0x61, 0xac, 0x8e, 0xa3, 0xae, 0x5b, 0x23, + 0xd4, 0x1f, 0xee, 0x36, 0xee, 0xef, 0xe6, 0x58, 0x13, 0x8b, 0xf0, 0x64, + 0xf8, 0x73, 0x8f, 0x4f, 0x3d, 0x42, 0xbe, 0x4c, 0x7c, 0x76, 0xc4, 0xaf, + 0xe6, 0xc5, 0x1d, 0x1c, 0x5f, 0xe0, 0x6d, 0x5a, 0xae, 0xee, 0x7c, 0xf9, + 0x35, 0x73, 0xe5, 0x75, 0xff, 0xa3, 0xe4, 0x37, 0xe8, 0x6e, 0xe2, 0x3e, + 0x91, 0x8d, 0x6c, 0xb0, 0xb8, 0xdf, 0x2f, 0x6d, 0xdb, 0x60, 0xaf, 0x0f, + 0x82, 0x7e, 0xa7, 0x02, 0xf1, 0xb7, 0x85, 0x6d, 0xce, 0xb7, 0xe3, 0xd9, + 0x76, 0x76, 0xc3, 0x96, 0xed, 0xdb, 0xc4, 0xb5, 0x5e, 0xd8, 0xf2, 0xa9, + 0x70, 0x3e, 0x60, 0xf9, 0xea, 0x39, 0xa7, 0x0c, 0xa5, 0xec, 0x6c, 0xb0, + 0xf1, 0x7e, 0xb6, 0x77, 0x61, 0xd1, 0x3c, 0x5d, 0x0a, 0x78, 0xce, 0x76, + 0xc4, 0x1f, 0xab, 0xa2, 0x95, 0xbf, 0xb2, 0xb4, 0xa2, 0x16, 0x8d, 0xe3, + 0x9c, 0xa5, 0x95, 0x10, 0xde, 0x58, 0x48, 0x2b, 0x75, 0x21, 0xad, 0xe4, + 0xc7, 0x43, 0x5a, 0x61, 0xdd, 0x73, 0x21, 0xad, 0x24, 0xaa, 0x69, 0x25, + 0x3f, 0xee, 0xe0, 0x59, 0x0c, 0x07, 0xe9, 0x85, 0xed, 0x90, 0x5e, 0x00, + 0x4b, 0xa5, 0x32, 0x47, 0x2f, 0x31, 0xb4, 0x73, 0xa8, 0xa4, 0x34, 0xad, + 0x0c, 0xa9, 0x50, 0x47, 0x78, 0x98, 0x73, 0xcc, 0xfd, 0x15, 0x69, 0x24, + 0x65, 0x69, 0x64, 0xfe, 0x2c, 0xd1, 0x22, 0xda, 0x00, 0xee, 0x79, 0x5e, + 0x60, 0xb3, 0xa6, 0x8d, 0xfb, 0x53, 0x2f, 0xa0, 0xec, 0x28, 0x68, 0x23, + 0xc4, 0xc1, 0x03, 0x16, 0x07, 0x8b, 0xe7, 0xf2, 0xb4, 0xc5, 0xc1, 0xa8, + 0xc5, 0x81, 0xe6, 0x97, 0x3c, 0xe7, 0x4c, 0x69, 0x1c, 0xd4, 0x69, 0x1c, + 0x88, 0x0a, 0xeb, 0x9e, 0x5e, 0x06, 0x07, 0x2c, 0x33, 0xaa, 0xc7, 0x1f, + 0xc1, 0xf8, 0xf7, 0x61, 0xfc, 0x4a, 0x8f, 0x9f, 0xf3, 0xc0, 0xf1, 0x03, + 0x96, 0xca, 0x77, 0xe6, 0xc6, 0xdf, 0x84, 0x36, 0x0e, 0x6a, 0xdb, 0x99, + 0xf1, 0x54, 0xea, 0x46, 0x33, 0xfe, 0xc7, 0x2a, 0xe6, 0x8c, 0xc9, 0x63, + 0x4b, 0xf4, 0xd8, 0x0b, 0x96, 0x37, 0x7c, 0xbd, 0xce, 0xc6, 0x73, 0x6d, + 0xe7, 0xa0, 0xbb, 0xc6, 0x52, 0x09, 0x7b, 0xe6, 0xd4, 0xd8, 0x43, 0x5f, + 0x4d, 0x91, 0x77, 0x3e, 0xaa, 0xf7, 0xfa, 0x9d, 0xa5, 0x5d, 0x54, 0x6a, + 0x92, 0xbe, 0xb1, 0x6a, 0xb8, 0x09, 0x6f, 0x3e, 0x50, 0x3e, 0x63, 0x37, + 0xfb, 0xa1, 0x3b, 0x4c, 0xdc, 0x1a, 0xb4, 0x84, 0xf4, 0x64, 0xbe, 0x37, + 0x52, 0x27, 0xea, 0x81, 0x0f, 0x60, 0xcc, 0x2e, 0x7c, 0xcc, 0x76, 0x6f, + 0x9b, 0xa2, 0xae, 0xbb, 0xba, 0x4a, 0xd7, 0x35, 0x5b, 0x5d, 0xb7, 0x86, + 0xba, 0x0e, 0x70, 0x3f, 0x25, 0x87, 0x4b, 0x9c, 0xbf, 0x7c, 0xa2, 0x4e, + 0xc7, 0x40, 0x1d, 0x1b, 0xe7, 0x4b, 0xc6, 0x0f, 0x6b, 0x5a, 0xa6, 0xce, + 0x4a, 0xea, 0xb8, 0xe4, 0x4c, 0xd7, 0x3f, 0xd9, 0x75, 0x10, 0xea, 0xb5, + 0xef, 0x07, 0x7f, 0xb0, 0x8c, 0x5e, 0x83, 0xfe, 0xd1, 0xf6, 0x59, 0x0d, + 0x64, 0xad, 0x9c, 0x6a, 0xc6, 0xb3, 0x9a, 0xe7, 0xc1, 0x3a, 0x3b, 0x54, + 0xbd, 0xd4, 0x9c, 0x6a, 0x94, 0x3d, 0x63, 0x7a, 0xdd, 0x5c, 0xd4, 0x29, + 0xe0, 0xff, 0x14, 0xcf, 0x14, 0x88, 0x3e, 0x03, 0x95, 0x1b, 0x85, 0x3f, + 0x33, 0xf1, 0x94, 0xd9, 0x1b, 0x38, 0x56, 0xa3, 0x7f, 0xd3, 0xc6, 0x28, + 0xa4, 0x32, 0xfa, 0xec, 0xd0, 0x1e, 0xb4, 0xd9, 0xbe, 0xa9, 0x16, 0x63, + 0x8e, 0xa1, 0x2e, 0xf7, 0x16, 0xaa, 0x36, 0x57, 0x6a, 0xc5, 0x9d, 0x88, + 0xea, 0xf3, 0x4b, 0x3c, 0x7f, 0x9f, 0xed, 0x69, 0x42, 0x5e, 0x44, 0xaf, + 0x15, 0xd4, 0x9c, 0x9a, 0x3f, 0xa7, 0xae, 0x8e, 0x8a, 0x5d, 0xc3, 0x4f, + 0x6b, 0xbd, 0x12, 0x39, 0x4a, 0x9d, 0xc3, 0xfd, 0x55, 0x3d, 0x98, 0xf7, + 0xe5, 0xf4, 0x8d, 0x31, 0x62, 0xb3, 0x98, 0x3f, 0x75, 0x86, 0x67, 0x8d, + 0x5b, 0xf1, 0x0e, 0xdb, 0x0b, 0xf5, 0x08, 0x74, 0xdf, 0xdb, 0x3f, 0xe1, + 0x49, 0x3d, 0xf0, 0x3d, 0xa1, 0x80, 0x6b, 0x57, 0xd3, 0x42, 0x5e, 0x85, + 0xb1, 0x69, 0x43, 0x0f, 0x8f, 0xbf, 0x21, 0x3f, 0x90, 0x26, 0x3a, 0x6d, + 0x6c, 0xc1, 0xb7, 0x31, 0x7e, 0xd2, 0xb6, 0xa1, 0x87, 0x47, 0x53, 0x19, + 0xc5, 0xbd, 0x51, 0x66, 0x1d, 0x94, 0xb4, 0x41, 0x9a, 0x4f, 0xe8, 0xf5, + 0xd1, 0x8c, 0xbc, 0x2c, 0x99, 0xa6, 0x76, 0xd8, 0x5d, 0xff, 0xb6, 0x73, + 0x6c, 0xee, 0x2e, 0xd0, 0x34, 0x07, 0xdd, 0xc4, 0x7d, 0xca, 0x9d, 0xf2, + 0x5e, 0x9e, 0x57, 0x98, 0x70, 0xa0, 0x94, 0x9f, 0xd2, 0x7b, 0xbf, 0x77, + 0x14, 0x57, 0xcb, 0xad, 0xa9, 0xa8, 0x5d, 0xe7, 0xac, 0x05, 0x1d, 0x40, + 0x50, 0x9f, 0xaa, 0xc5, 0x13, 0x75, 0x38, 0x7f, 0x17, 0x53, 0x99, 0xa4, + 0x22, 0xb3, 0xc3, 0xe7, 0x9f, 0x91, 0x2d, 0xde, 0x1e, 0x7d, 0xce, 0x4e, + 0x9c, 0xba, 0x53, 0x7f, 0xe9, 0xd1, 0x06, 0x25, 0xfd, 0xcc, 0xf8, 0xb5, + 0x7a, 0x5d, 0xab, 0x3f, 0x15, 0x04, 0x39, 0xcc, 0x5f, 0x41, 0x4c, 0xfc, + 0x6c, 0xc2, 0x67, 0x1a, 0xfd, 0xda, 0x06, 0xa7, 0xf6, 0x4c, 0xa3, 0x63, + 0x68, 0x45, 0x22, 0x2a, 0x5d, 0xef, 0xd4, 0x9c, 0xba, 0x93, 0x73, 0x06, + 0xba, 0xf2, 0x1c, 0x43, 0x57, 0x31, 0x67, 0x9e, 0xae, 0xd6, 0xd9, 0xdf, + 0x2a, 0x5d, 0x27, 0x99, 0x64, 0x1d, 0xc6, 0xdb, 0x5b, 0x0c, 0x61, 0x3c, + 0x0c, 0xb8, 0x08, 0xcf, 0xdd, 0x18, 0xc3, 0x30, 0x9e, 0x3c, 0x60, 0x01, + 0xb3, 0x9f, 0x2a, 0x00, 0xe6, 0x83, 0x78, 0x18, 0x27, 0x6b, 0x76, 0x22, + 0x13, 0xd5, 0xf0, 0x12, 0xc6, 0x1f, 0x5b, 0x78, 0x5f, 0x0f, 0x56, 0x4f, + 0x66, 0xba, 0x8b, 0x80, 0x87, 0x70, 0xde, 0x07, 0x18, 0x69, 0x97, 0x8e, + 0xe2, 0xdb, 0x03, 0x7c, 0x63, 0x16, 0x26, 0xd0, 0xe3, 0xd8, 0x43, 0xf3, + 0xbf, 0x8b, 0xb4, 0x93, 0x8f, 0xd9, 0xef, 0xd6, 0x45, 0x32, 0xe0, 0x15, + 0x87, 0x78, 0x1e, 0x29, 0xbd, 0xe6, 0xc0, 0x0e, 0x00, 0xdf, 0xbf, 0xe4, + 0x44, 0xce, 0xc4, 0xe5, 0x50, 0x91, 0x31, 0x84, 0xe3, 0x0e, 0xe7, 0x41, + 0xf9, 0x57, 0xa1, 0x4c, 0x5c, 0xc9, 0xc4, 0xd5, 0x78, 0xde, 0x82, 0x67, + 0x03, 0x9e, 0x8d, 0x78, 0xd6, 0xe3, 0x69, 0xc5, 0xf3, 0x2d, 0x94, 0x53, + 0xb1, 0x3a, 0xe1, 0x7e, 0xd5, 0x16, 0xa5, 0x34, 0x1f, 0x71, 0xcf, 0xc2, + 0x65, 0xc0, 0xe5, 0x2b, 0xd0, 0x3b, 0x1e, 0x9e, 0xf1, 0xf8, 0x3a, 0xfa, + 0x98, 0xc5, 0xd3, 0xa9, 0xe4, 0x4c, 0x17, 0x9e, 0x14, 0x9e, 0x6e, 0x3c, + 0x3d, 0x78, 0xd2, 0x78, 0x5e, 0x75, 0x0c, 0xcf, 0x5d, 0x02, 0xbe, 0x42, + 0x1e, 0x01, 0xce, 0x17, 0xf0, 0x9c, 0xe7, 0xbc, 0x09, 0x9e, 0x73, 0x2c, + 0xcf, 0x39, 0xf3, 0x3c, 0x57, 0xeb, 0xa8, 0x63, 0xf5, 0x4e, 0xe4, 0x18, + 0x7d, 0x85, 0x5a, 0xc7, 0xf0, 0x7f, 0x44, 0x7a, 0x07, 0x41, 0x4b, 0xc7, + 0x30, 0x67, 0xc7, 0x48, 0x57, 0x2e, 0xd2, 0xc7, 0x16, 0xf5, 0x3b, 0xfa, + 0x26, 0xfa, 0x3d, 0x61, 0xfb, 0x7d, 0xb8, 0xaa, 0xdf, 0x83, 0x68, 0xfb, + 0x3e, 0xdb, 0xef, 0xc1, 0xaa, 0x7e, 0x41, 0x2b, 0xc7, 0xf2, 0x78, 0x48, + 0x17, 0x23, 0x48, 0x0f, 0x65, 0xc2, 0xdd, 0x6b, 0xa4, 0xbe, 0x46, 0x9f, + 0x27, 0x8d, 0xf9, 0x35, 0x73, 0xba, 0x31, 0x53, 0xa5, 0x1f, 0x7e, 0x16, + 0xfd, 0x38, 0x5c, 0xa2, 0x8d, 0x38, 0x5d, 0x25, 0x17, 0xe8, 0xfb, 0x04, + 0x72, 0x5c, 0xfb, 0x39, 0xf4, 0x79, 0xe8, 0xff, 0x2c, 0xb6, 0xad, 0x3e, + 0xae, 0xf7, 0xe7, 0xde, 0x55, 0x6c, 0x95, 0x4f, 0x14, 0x69, 0x13, 0x92, + 0x5e, 0x82, 0x60, 0xcf, 0x36, 0xda, 0xa7, 0xf9, 0x60, 0x9d, 0x9f, 0xd4, + 0xb1, 0xb5, 0x4f, 0x2e, 0xd5, 0x19, 0xa3, 0xbd, 0xf0, 0xcd, 0xb3, 0x47, + 0x3f, 0x08, 0x9d, 0x51, 0x03, 0xb8, 0x9f, 0xd2, 0x77, 0x80, 0xec, 0x1a, + 0x55, 0x23, 0x6b, 0x25, 0x2e, 0x37, 0x17, 0x6b, 0x61, 0xf7, 0x30, 0x56, + 0x5e, 0x2f, 0xed, 0xdb, 0xa2, 0xe6, 0x6c, 0x8d, 0x17, 0xc3, 0x6f, 0xcf, + 0x9c, 0xf5, 0x89, 0xc5, 0x91, 0x1f, 0x69, 0xa2, 0x1c, 0x8c, 0xf9, 0xef, + 0xd4, 0xfb, 0x26, 0xdb, 0xb6, 0xd1, 0x6e, 0xb9, 0x41, 0xeb, 0x70, 0x77, + 0x89, 0x9d, 0xa4, 0x5a, 0x3c, 0x99, 0xb7, 0xd1, 0x76, 0x17, 0x93, 0x09, + 0xc2, 0xf5, 0x90, 0x70, 0x3f, 0xc1, 0x7e, 0x29, 0xa4, 0x1a, 0x25, 0x92, + 0xe6, 0xba, 0x5c, 0xb2, 0x93, 0xb6, 0xd1, 0xc4, 0x98, 0x67, 0xcf, 0x9e, + 0xac, 0x96, 0x0b, 0xba, 0x9f, 0x5a, 0x0d, 0xa3, 0x39, 0x8f, 0xc6, 0x35, + 0x2f, 0x9e, 0x81, 0x72, 0xf1, 0x6e, 0xd0, 0x7a, 0x67, 0xa2, 0xcc, 0xb3, + 0x4e, 0xf0, 0x97, 0xca, 0x31, 0x7d, 0xc6, 0xd4, 0x7b, 0x3b, 0xfc, 0xd8, + 0xf2, 0x06, 0xd9, 0x3d, 0xb6, 0x82, 0xeb, 0x28, 0xb1, 0xb5, 0xd0, 0x1f, + 0xac, 0xd3, 0xb6, 0x0d, 0xfe, 0xdf, 0xf8, 0x46, 0x79, 0x7c, 0x9c, 0x6d, + 0xb7, 0xc8, 0xe4, 0x94, 0x38, 0xde, 0xdb, 0x57, 0xa2, 0x8c, 0xc7, 0xf1, + 0x08, 0xf7, 0x3c, 0xb5, 0x6d, 0x13, 0xe5, 0xbd, 0xdd, 0x95, 0xf3, 0xdd, + 0x11, 0xbd, 0x26, 0xe3, 0x82, 0x4e, 0xd8, 0xde, 0xf9, 0xee, 0x56, 0x39, + 0x3b, 0x05, 0x9a, 0x80, 0xdc, 0xef, 0x3b, 0x45, 0x98, 0x44, 0xb6, 0x4f, + 0xc0, 0x5e, 0x90, 0x76, 0x3c, 0xa0, 0x0f, 0xc8, 0xef, 0x5b, 0xbb, 0xd9, + 0x17, 0xf4, 0x12, 0x74, 0x5c, 0xdb, 0x36, 0x23, 0x0b, 0x32, 0x13, 0x35, + 0x48, 0x67, 0xbb, 0xf0, 0x0f, 0x07, 0xd9, 0x4e, 0x58, 0x57, 0x61, 0x4c, + 0xb5, 0x9a, 0x5e, 0x66, 0x17, 0xe9, 0x8f, 0x73, 0x3f, 0x97, 0xfd, 0xcd, + 0x36, 0x3a, 0x41, 0x2b, 0xbe, 0xde, 0xc3, 0x63, 0x6c, 0x2b, 0xce, 0x09, + 0x6d, 0x22, 0xda, 0x55, 0xd7, 0x6a, 0xfb, 0x62, 0xb2, 0xc2, 0x19, 0xe4, + 0xda, 0x48, 0x38, 0x47, 0x71, 0x39, 0x59, 0x9a, 0x9b, 0xa7, 0x0d, 0x35, + 0x0b, 0xe7, 0x89, 0xb4, 0x92, 0x1a, 0xb2, 0xb6, 0xc7, 0x8c, 0x3c, 0x0f, + 0xbb, 0xac, 0x53, 0xcf, 0xd9, 0x0c, 0x6c, 0x59, 0x3b, 0x67, 0xda, 0x9e, + 0x2d, 0x84, 0x73, 0x36, 0x00, 0x8d, 0x53, 0xbe, 0x41, 0xcf, 0x99, 0x07, + 0xba, 0xc9, 0x03, 0xef, 0x79, 0xcc, 0x53, 0x1e, 0x73, 0x94, 0x2f, 0xb7, + 0xc8, 0xc4, 0x71, 0xd5, 0x5a, 0x23, 0x92, 0xd8, 0xed, 0xb7, 0xc8, 0xf0, + 0x14, 0x63, 0x05, 0x1b, 0x60, 0x83, 0x6d, 0xc4, 0xd3, 0x8a, 0x6f, 0xd6, + 0xe3, 0x1d, 0x1f, 0x0a, 0x75, 0xeb, 0x96, 0xd8, 0x59, 0x67, 0xd1, 0xf7, + 0xd3, 0xc0, 0xc3, 0xa3, 0xc0, 0xc3, 0x3c, 0xef, 0xbc, 0x50, 0x15, 0x5f, + 0xe2, 0x58, 0xb5, 0x0e, 0xc5, 0x78, 0x63, 0x7a, 0x3e, 0x75, 0x9c, 0xa9, + 0x54, 0xfb, 0x66, 0xec, 0xa9, 0x38, 0xed, 0xa9, 0xdc, 0xa8, 0x67, 0xce, + 0x60, 0x0d, 0xc0, 0x77, 0xf2, 0xf7, 0x69, 0x5a, 0x1f, 0x1a, 0x27, 0x5c, + 0xd1, 0x10, 0xae, 0x05, 0x73, 0xc6, 0x33, 0xb3, 0x4b, 0xe3, 0x18, 0x2f, + 0xcc, 0xed, 0x11, 0x87, 0x2e, 0x97, 0xd1, 0x14, 0xe3, 0x24, 0xad, 0xcb, + 0xc0, 0xf4, 0x94, 0xb6, 0x61, 0x45, 0x9d, 0x96, 0x03, 0x25, 0x9e, 0xb7, + 0xe5, 0x1a, 0xcc, 0xef, 0x31, 0x7e, 0xd4, 0x39, 0x21, 0xc7, 0xd0, 0x37, + 0xd7, 0xc5, 0x95, 0x8d, 0xcf, 0xac, 0xb2, 0x7b, 0xf2, 0xaa, 0x63, 0x34, + 0x66, 0xdd, 0x7c, 0xe1, 0xd9, 0x93, 0xe4, 0xc0, 0xac, 0x5e, 0x77, 0xe5, + 0x9a, 0xa1, 0x8c, 0x46, 0xa0, 0xfd, 0x76, 0x77, 0x27, 0x7b, 0xcc, 0x59, + 0xc3, 0x84, 0xf4, 0x97, 0xcc, 0xf8, 0x2f, 0xea, 0x7d, 0x93, 0x66, 0x7f, + 0xb8, 0xd9, 0x53, 0xb9, 0x5f, 0x2e, 0xa6, 0xa2, 0x55, 0x73, 0x5b, 0x27, + 0xc3, 0xc0, 0x85, 0x5e, 0xcb, 0x84, 0x5d, 0x9c, 0xeb, 0x7e, 0xbc, 0x89, + 0x67, 0xd1, 0xa2, 0x98, 0x9f, 0xc2, 0x38, 0xcf, 0xa7, 0xb3, 0xdd, 0x2b, + 0xb5, 0x45, 0x31, 0xcb, 0xb3, 0x4e, 0x90, 0x95, 0x6f, 0xdd, 0x12, 0xaf, + 0xd7, 0xf9, 0x2b, 0xec, 0x99, 0x16, 0xd8, 0x0d, 0xbb, 0x02, 0xf9, 0x33, + 0xe8, 0xc9, 0xd3, 0x76, 0x4c, 0x09, 0x1d, 0x93, 0x92, 0xe0, 0x7c, 0x2a, + 0x6e, 0xe3, 0xce, 0x1c, 0xcb, 0x98, 0xa5, 0x6f, 0x63, 0xff, 0xcc, 0xdb, + 0xd0, 0x5d, 0x9a, 0xd6, 0x1f, 0xd7, 0xb2, 0xb0, 0xcb, 0xda, 0xce, 0x3a, + 0x8e, 0x73, 0x42, 0xf4, 0x1e, 0xac, 0xd0, 0x37, 0xea, 0xa8, 0xf2, 0x0b, + 0x8c, 0x2f, 0x57, 0x18, 0x5b, 0x4e, 0x46, 0xcd, 0xfb, 0x84, 0xf4, 0xe5, + 0xf6, 0x6c, 0xe2, 0xdd, 0x30, 0xa1, 0x2f, 0xd7, 0x65, 0x7d, 0xb9, 0x46, + 0xed, 0xcb, 0x99, 0xd8, 0x43, 0xe3, 0x9c, 0x2f, 0x57, 0x18, 0xcb, 0x83, + 0x56, 0x6a, 0xed, 0x59, 0x09, 0x63, 0x0b, 0x0d, 0x17, 0x5d, 0xbd, 0x6f, + 0x24, 0x37, 0xa0, 0xe0, 0x37, 0x18, 0x1f, 0x8b, 0xb1, 0x0a, 0xa5, 0xfe, + 0xce, 0xfa, 0x17, 0x1b, 0x24, 0xd3, 0xbc, 0x02, 0xe3, 0x7e, 0x4a, 0xcf, + 0xb9, 0x59, 0xc3, 0x82, 0x5c, 0x1b, 0x64, 0xcc, 0x87, 0x67, 0x47, 0x35, + 0x7f, 0x25, 0x7a, 0x23, 0x9d, 0xc6, 0x9e, 0xf5, 0x13, 0x6b, 0xa5, 0xfe, + 0xb8, 0x53, 0x18, 0x8f, 0xda, 0x7e, 0x13, 0x80, 0xa9, 0x06, 0x73, 0xf3, + 0x4e, 0x2b, 0x93, 0xd9, 0xf7, 0x3b, 0xea, 0x18, 0x1b, 0x98, 0x2a, 0x9a, + 0x18, 0x60, 0x5f, 0x31, 0x12, 0x9e, 0x5b, 0x57, 0x5c, 0x47, 0xce, 0x0c, + 0xae, 0x00, 0x2c, 0x2b, 0x96, 0xb5, 0x59, 0x1f, 0x7b, 0x43, 0x1d, 0x45, + 0x9a, 0x7a, 0x4a, 0xef, 0x2f, 0x5c, 0xd9, 0x9d, 0xdc, 0xa9, 0xcf, 0x23, + 0xe9, 0x58, 0x62, 0x5e, 0xb8, 0x7f, 0xf7, 0x9b, 0xf2, 0x36, 0x2d, 0xfb, + 0x0f, 0xa4, 0xa8, 0xc7, 0xb6, 0xe9, 0xdf, 0xb5, 0xe9, 0x20, 0x38, 0xdf, + 0xfd, 0x2c, 0x6c, 0x16, 0xdf, 0xfb, 0x96, 0xb4, 0xc7, 0x7b, 0xb5, 0x0d, + 0x85, 0xb9, 0x1a, 0xac, 0x97, 0x15, 0xfe, 0xb8, 0xdd, 0xab, 0x68, 0xd6, + 0x03, 0x0b, 0xc2, 0xfb, 0x17, 0x3a, 0x6c, 0x5e, 0x3e, 0xa8, 0x07, 0x3d, + 0x7d, 0x44, 0x8c, 0xac, 0xc9, 0xcd, 0xcb, 0x1a, 0xee, 0xa7, 0xcb, 0x90, + 0xa0, 0xdd, 0x23, 0x92, 0xe4, 0xdd, 0x49, 0xec, 0xbb, 0x20, 0x57, 0x41, + 0x3f, 0xb3, 0x1e, 0x6d, 0x56, 0x7e, 0x73, 0x0f, 0x8a, 0xef, 0x1d, 0x84, + 0x8e, 0xb9, 0x61, 0xa9, 0x8e, 0x89, 0xd3, 0xbf, 0xcf, 0x8d, 0xd2, 0x47, + 0x5c, 0x89, 0x3a, 0x2d, 0xf2, 0xd1, 0xb1, 0xdf, 0x5a, 0x4b, 0x1e, 0x1b, + 0x82, 0x7c, 0x57, 0xf7, 0x87, 0xe7, 0x2e, 0x99, 0xc6, 0x7c, 0xb6, 0x5b, + 0x27, 0x89, 0xf7, 0x79, 0xf2, 0xc5, 0x4a, 0x32, 0x31, 0x0b, 0x1d, 0x35, + 0xe4, 0x0c, 0xb7, 0x9a, 0xd8, 0xe9, 0xa7, 0xd6, 0x9a, 0x73, 0x5a, 0xf5, + 0xc0, 0x69, 0x18, 0x4f, 0xad, 0xa6, 0xdd, 0x59, 0x2b, 0x97, 0x83, 0xa0, + 0xbe, 0x5b, 0xcb, 0xe2, 0x9d, 0x94, 0xc5, 0x07, 0x52, 0x1d, 0x86, 0x07, + 0xb4, 0xef, 0xc4, 0x3d, 0x00, 0xc0, 0x43, 0xb7, 0xcb, 0xbd, 0xd0, 0x96, + 0x4f, 0xfd, 0xcc, 0x8c, 0x95, 0x4f, 0xca, 0x59, 0xca, 0x9f, 0x6a, 0x6b, + 0x74, 0x81, 0xec, 0x3d, 0x34, 0x46, 0xbd, 0x9c, 0x9a, 0xfe, 0x26, 0xe4, + 0x55, 0x4e, 0xe3, 0xa1, 0x45, 0xee, 0x1b, 0x93, 0xcc, 0x45, 0xe8, 0xac, + 0xc2, 0xd4, 0x42, 0x1e, 0x5d, 0xda, 0x1e, 0xc7, 0x7a, 0x7a, 0xad, 0xf1, + 0x71, 0x17, 0x8e, 0x75, 0x9a, 0x7b, 0x8c, 0xf4, 0x58, 0xb9, 0x37, 0xff, + 0x9c, 0x1d, 0xeb, 0xca, 0x70, 0xac, 0x3d, 0x0b, 0xc7, 0x1a, 0xfa, 0xf8, + 0xa1, 0xfc, 0x4d, 0xe8, 0xb3, 0x49, 0xfa, 0x4c, 0xcc, 0xd8, 0x4a, 0xe9, + 0x1d, 0x6d, 0xb4, 0x72, 0xd3, 0x83, 0x0e, 0xe2, 0x79, 0xa1, 0xe9, 0xcf, + 0x79, 0x62, 0x71, 0xa6, 0x88, 0x07, 0xca, 0xdc, 0x26, 0x7d, 0x9e, 0x71, + 0x02, 0x7e, 0xd6, 0x87, 0x8b, 0x2c, 0x1b, 0xe6, 0x5f, 0x29, 0x46, 0x1c, + 0xfa, 0xd6, 0xf4, 0x9f, 0x3a, 0x97, 0xc4, 0x16, 0x4c, 0x1c, 0x98, 0xf1, + 0x5f, 0x73, 0xcf, 0x02, 0xf7, 0x7d, 0xdf, 0x01, 0xde, 0xfa, 0xed, 0x62, + 0xb2, 0x27, 0x1b, 0xa1, 0x3c, 0x9d, 0x95, 0x43, 0x95, 0x3e, 0x69, 0xd3, + 0x67, 0xed, 0xdf, 0x30, 0x46, 0x9c, 0xa9, 0x8e, 0x11, 0x8b, 0x63, 0x62, + 0xc4, 0x3b, 0x7f, 0x8e, 0x18, 0xb1, 0x38, 0x26, 0x46, 0xbc, 0x9c, 0x9f, + 0x35, 0x52, 0x9a, 0xc5, 0xb8, 0xea, 0x21, 0x53, 0x94, 0x93, 0x9b, 0x6a, + 0xc0, 0xbb, 0x16, 0x6f, 0xc0, 0x32, 0x56, 0xc0, 0xdb, 0xc3, 0xfb, 0x20, + 0xde, 0x31, 0x19, 0x99, 0xd3, 0x1d, 0xb3, 0x90, 0x1f, 0xd4, 0x69, 0xac, + 0x6b, 0xfc, 0x82, 0xc9, 0x72, 0x33, 0xca, 0x5d, 0x72, 0x26, 0x58, 0xaf, + 0xd4, 0x28, 0xc3, 0x63, 0x94, 0xdd, 0x4d, 0x32, 0x3a, 0x16, 0xda, 0xb8, + 0x9f, 0x5d, 0xcf, 0xb5, 0x81, 0x21, 0x09, 0x6d, 0xd8, 0x67, 0xd6, 0x9b, + 0xb5, 0xdb, 0x2d, 0x31, 0xa9, 0x5f, 0x8d, 0x39, 0x38, 0xee, 0x5c, 0x1c, + 0x5f, 0xbd, 0xc0, 0x96, 0x4d, 0xd8, 0xd8, 0xe0, 0xb8, 0xd5, 0xc1, 0xcb, + 0xcb, 0x88, 0xea, 0xf9, 0x8f, 0xdb, 0x73, 0xbc, 0x51, 0x7b, 0xd7, 0x5f, + 0x42, 0xcf, 0xcf, 0x40, 0x65, 0x16, 0xfd, 0xad, 0x57, 0x99, 0x71, 0x8e, + 0x73, 0xee, 0x7e, 0x1e, 0xc8, 0xc5, 0x56, 0x35, 0x34, 0xbe, 0x80, 0x2e, + 0x41, 0xb7, 0x1c, 0x9b, 0x03, 0xda, 0xbd, 0x57, 0x26, 0x46, 0x09, 0x5f, + 0x47, 0x3c, 0xa2, 0xcf, 0xf5, 0xe2, 0x7b, 0xdc, 0x9c, 0x27, 0xea, 0xad, + 0x84, 0x67, 0x7a, 0xd7, 0x00, 0xde, 0xc5, 0xe7, 0x7a, 0xad, 0x9e, 0xd6, + 0x36, 0x04, 0xcf, 0xf7, 0x86, 0x63, 0x58, 0x8e, 0x9e, 0x02, 0x19, 0xd6, + 0xfb, 0x7d, 0xd7, 0xca, 0xe9, 0x07, 0xe7, 0xce, 0x17, 0x34, 0xc1, 0x56, + 0x69, 0x85, 0xa9, 0x3c, 0xe0, 0xa6, 0xb9, 0xef, 0x82, 0xfb, 0x0b, 0x3a, + 0xe2, 0xb7, 0xe9, 0x73, 0x1f, 0xf3, 0x67, 0xac, 0xe7, 0xcf, 0x7e, 0x84, + 0x67, 0x5a, 0xe3, 0xd2, 0x07, 0x3a, 0xec, 0xd7, 0xe9, 0x31, 0x8c, 0x87, + 0x6b, 0xbe, 0x1a, 0x0f, 0x90, 0x3d, 0x5c, 0xfb, 0xc5, 0xd8, 0x2b, 0x2d, + 0x2a, 0xa7, 0xcf, 0x58, 0x47, 0x2d, 0x8d, 0x5d, 0x76, 0xf6, 0x94, 0x13, + 0x6a, 0x4f, 0xd9, 0x57, 0x7b, 0xcb, 0x36, 0xaf, 0xfb, 0x01, 0xcc, 0x07, + 0x7e, 0x8f, 0x17, 0x9d, 0x21, 0xe0, 0xab, 0x50, 0x3a, 0xe2, 0x64, 0xf4, + 0xfb, 0xa8, 0x7d, 0x43, 0x0e, 0x60, 0xae, 0x7a, 0xc7, 0xa3, 0x5a, 0xde, + 0xcf, 0xdf, 0xd3, 0x17, 0xce, 0xeb, 0x0b, 0x7a, 0x0d, 0x68, 0x5a, 0x88, + 0x6b, 0xcf, 0xda, 0x10, 0xc7, 0x9d, 0x9c, 0xc6, 0x3d, 0xcb, 0x7c, 0x4b, + 0xff, 0x06, 0x9d, 0x2b, 0xd3, 0x5e, 0x2b, 0xde, 0x8b, 0xf7, 0x4d, 0x86, + 0xfa, 0x86, 0x70, 0xdf, 0x09, 0xbd, 0x16, 0xec, 0x37, 0xf2, 0x6a, 0x56, + 0x46, 0x2a, 0x5c, 0xc3, 0x64, 0x3b, 0x48, 0x2f, 0xd7, 0xc0, 0x1e, 0x58, + 0x78, 0xbe, 0xba, 0x7f, 0x7e, 0x1e, 0x12, 0xe3, 0x42, 0x58, 0xee, 0xd6, + 0x67, 0x17, 0xab, 0xef, 0x1e, 0xb9, 0xf2, 0xbf, 0x70, 0xfd, 0xd0, 0xc8, + 0x50, 0x0b, 0x47, 0x86, 0xf2, 0xce, 0xc8, 0x95, 0xaf, 0xcb, 0x41, 0xe0, + 0xf1, 0x30, 0x60, 0x52, 0xf7, 0xf3, 0xce, 0xab, 0x57, 0xa5, 0x30, 0x59, + 0x2f, 0xea, 0xa1, 0x82, 0xe3, 0x3e, 0x54, 0x2b, 0x91, 0x87, 0x94, 0x53, + 0xf3, 0x50, 0xbb, 0xf6, 0xcf, 0x77, 0xa4, 0xda, 0xe3, 0x7b, 0xe5, 0xb8, + 0xe3, 0xde, 0xaf, 0xf4, 0x59, 0xdb, 0x82, 0xc7, 0x58, 0xdf, 0x71, 0x27, + 0x72, 0x7f, 0xd4, 0x9e, 0xd3, 0x37, 0xf1, 0xbd, 0x59, 0xcd, 0xf7, 0xdf, + 0x58, 0x47, 0x9c, 0xcd, 0x0a, 0xf1, 0xf1, 0x59, 0xc8, 0xad, 0x4f, 0x4b, + 0x76, 0x34, 0x31, 0x57, 0xc6, 0xec, 0xb3, 0xdf, 0xb0, 0xce, 0xf0, 0x0b, + 0xcb, 0xbc, 0xe2, 0xf0, 0xce, 0x1c, 0xa3, 0x33, 0x3e, 0xdf, 0x12, 0xee, + 0xb9, 0x37, 0x73, 0xca, 0xfc, 0xc6, 0x75, 0x52, 0xff, 0x0a, 0xe6, 0x8b, + 0xfd, 0x11, 0x57, 0xab, 0xf4, 0x3d, 0x05, 0x9e, 0x6c, 0x89, 0xd7, 0xcd, + 0xd9, 0x43, 0x46, 0xf6, 0xd6, 0x01, 0x6e, 0xc0, 0x6f, 0xec, 0x3b, 0x21, + 0x9d, 0x0a, 0x24, 0x37, 0x69, 0xb6, 0xa3, 0x67, 0x87, 0x98, 0x39, 0x33, + 0x34, 0xb3, 0xc2, 0xd8, 0x91, 0xf8, 0x36, 0x74, 0xa1, 0x64, 0xfb, 0xd8, + 0x4b, 0x4e, 0x3f, 0xcf, 0x3c, 0x8a, 0xb6, 0x1b, 0x97, 0xb3, 0x09, 0xc1, + 0x4b, 0xcf, 0x5b, 0xff, 0x32, 0x08, 0xc6, 0x52, 0x29, 0xde, 0x2b, 0xb8, + 0x8c, 0x4f, 0xb9, 0xca, 0x99, 0x1c, 0x6d, 0x70, 0x26, 0x46, 0x03, 0xd9, + 0x93, 0xe2, 0x9d, 0x49, 0xdc, 0x93, 0xa0, 0xe3, 0xe3, 0x48, 0x6b, 0x87, + 0x6e, 0x7d, 0xc7, 0x3a, 0xee, 0x71, 0xbb, 0xd9, 0x6f, 0xb4, 0xe5, 0x88, + 0x63, 0xfa, 0xca, 0xed, 0x27, 0x72, 0xc2, 0xbb, 0x8b, 0xb6, 0xc4, 0x63, + 0x7a, 0x7f, 0xe2, 0x17, 0x50, 0x0f, 0x7d, 0x94, 0xd8, 0xaf, 0xeb, 0x4c, + 0x40, 0x9e, 0x4d, 0x8e, 0xf1, 0xbe, 0x14, 0x9e, 0x63, 0x88, 0xb4, 0x2a, + 0xb9, 0xd6, 0x1b, 0xb6, 0xf7, 0x69, 0xe6, 0xe1, 0x0a, 0x45, 0x74, 0xda, + 0x16, 0x6f, 0xf7, 0xdc, 0x1d, 0x9b, 0x61, 0x5a, 0x78, 0xd7, 0xa6, 0xd2, + 0x67, 0x56, 0xe0, 0xd3, 0x9e, 0x1e, 0x92, 0xb8, 0x33, 0x55, 0x6c, 0x75, + 0x4e, 0x16, 0x33, 0x5b, 0xd7, 0x81, 0x3e, 0xce, 0xa7, 0x3e, 0x46, 0xf9, + 0x05, 0xdb, 0xef, 0x45, 0xc9, 0x57, 0x3e, 0x24, 0xe3, 0x2d, 0xed, 0xde, + 0xfd, 0x7a, 0x6e, 0x2e, 0x03, 0x67, 0x2d, 0x2a, 0x3b, 0xfa, 0xc4, 0x3a, + 0xea, 0xb7, 0xdd, 0x45, 0x05, 0x5e, 0x56, 0xbf, 0x88, 0x07, 0x36, 0x6e, + 0xad, 0xb6, 0x51, 0xf6, 0xa6, 0x58, 0xae, 0xc1, 0xe9, 0x1d, 0x5d, 0x85, + 0x79, 0xdc, 0x05, 0xfd, 0xe9, 0xc0, 0x46, 0x22, 0xae, 0x1b, 0x9c, 0x3d, + 0xa3, 0x79, 0xf4, 0xc8, 0x7d, 0xd6, 0xbc, 0xf7, 0xf0, 0x30, 0xc6, 0xa8, + 0xe5, 0x2b, 0x78, 0xf7, 0x12, 0xd7, 0xdb, 0x83, 0x49, 0xd8, 0x06, 0xb9, + 0xae, 0x7f, 0x67, 0xd7, 0xab, 0xa7, 0xaf, 0xb0, 0x5e, 0xed, 0xc9, 0x23, + 0x15, 0x7d, 0x6f, 0x48, 0xe7, 0xb8, 0xe2, 0x3a, 0x6e, 0xf3, 0x55, 0x7a, + 0x7e, 0x54, 0x87, 0xdd, 0x1b, 0x78, 0x72, 0x9d, 0xbd, 0xd3, 0x06, 0x70, + 0x5c, 0x05, 0x18, 0x36, 0x62, 0xfc, 0x84, 0xc1, 0xd4, 0x11, 0x75, 0x4b, + 0x9c, 0x3a, 0x70, 0x56, 0x4e, 0xaf, 0x0b, 0xf7, 0x7b, 0xa0, 0x1d, 0xc8, + 0xb5, 0x47, 0xe3, 0x46, 0x37, 0xae, 0x5d, 0xa6, 0x9d, 0x70, 0x3c, 0x8e, + 0x1d, 0x0f, 0x69, 0x75, 0x43, 0x0b, 0xfd, 0x89, 0x59, 0xa9, 0x5b, 0x54, + 0x9e, 0xf1, 0xfc, 0x5d, 0xad, 0x66, 0xdf, 0x11, 0xcb, 0x7a, 0xb0, 0x4b, + 0x69, 0xe3, 0x12, 0x77, 0x7a, 0xae, 0x8a, 0xdc, 0x5b, 0x9c, 0xf3, 0x2f, + 0x43, 0x9e, 0x5c, 0xeb, 0xbd, 0x4d, 0x91, 0xf6, 0x42, 0xfc, 0x12, 0xb7, + 0x09, 0xe0, 0x95, 0x71, 0x95, 0xd3, 0x41, 0x66, 0x80, 0x7c, 0xc5, 0x36, + 0x98, 0xff, 0xa2, 0x8e, 0xe5, 0x0e, 0xa6, 0x18, 0x27, 0x6a, 0x3f, 0x71, + 0x87, 0x0a, 0x65, 0xd3, 0x2c, 0xd7, 0x10, 0x1c, 0xde, 0x21, 0xba, 0x0b, + 0x1d, 0x5e, 0x9c, 0x52, 0xce, 0x37, 0xc7, 0x5c, 0x7c, 0xd7, 0xd8, 0xfb, + 0x42, 0x8d, 0x6e, 0x12, 0xf9, 0xeb, 0x70, 0xbc, 0xf1, 0x3c, 0xe6, 0xfb, + 0x12, 0xe6, 0x7b, 0xf9, 0xfb, 0x41, 0x91, 0x57, 0x46, 0x5e, 0xf9, 0x43, + 0x41, 0xa6, 0x89, 0xf4, 0x47, 0x9a, 0x7b, 0x3d, 0x9f, 0x59, 0xef, 0x63, + 0x02, 0x6c, 0x67, 0xc1, 0x0b, 0x19, 0xae, 0x25, 0x07, 0xc7, 0x52, 0x37, + 0x81, 0x17, 0x76, 0xca, 0x9f, 0xc0, 0x16, 0xf8, 0xe3, 0x4a, 0x1a, 0x3c, + 0xd1, 0x03, 0x1e, 0xe9, 0x06, 0x5f, 0xa4, 0xb4, 0x5d, 0xfc, 0x28, 0x74, + 0xde, 0xd9, 0x4a, 0xc9, 0xd9, 0x3b, 0x5a, 0x74, 0x72, 0xa3, 0x47, 0x41, + 0x17, 0xdc, 0x03, 0xab, 0xae, 0xa9, 0x11, 0x37, 0x3e, 0x29, 0xa4, 0xff, + 0x76, 0xee, 0xed, 0x68, 0x06, 0xae, 0xce, 0x10, 0x57, 0x93, 0x95, 0x2d, + 0xde, 0x3a, 0xf0, 0x41, 0xb3, 0xe6, 0x83, 0x46, 0x27, 0xe3, 0xdd, 0x64, + 0xf9, 0x60, 0x04, 0x7c, 0x50, 0x58, 0xc2, 0x07, 0xcf, 0x58, 0x9a, 0x9f, + 0xae, 0xe2, 0x83, 0x49, 0x9b, 0x36, 0x7e, 0x05, 0x3e, 0xb8, 0xca, 0x4f, + 0x3e, 0x39, 0x24, 0x27, 0xc0, 0x07, 0x0f, 0x6b, 0x3e, 0xb8, 0x4a, 0xf3, + 0x01, 0xe3, 0x46, 0xe4, 0x85, 0x56, 0xc8, 0x0e, 0xf2, 0xc2, 0xb3, 0x32, + 0x0b, 0x5e, 0x78, 0x51, 0xb1, 0xef, 0xcb, 0xb4, 0x0f, 0x46, 0xe9, 0x8f, + 0x9d, 0x2a, 0x15, 0xc1, 0xbb, 0x4a, 0xbe, 0x30, 0x16, 0x04, 0x33, 0xf0, + 0xd1, 0x1f, 0x84, 0x0d, 0xef, 0xea, 0x3b, 0x69, 0xa7, 0x61, 0xbb, 0x10, + 0x36, 0xda, 0xe4, 0xe3, 0x0e, 0xe8, 0xfd, 0xf0, 0x04, 0xc6, 0xb0, 0x47, + 0xfd, 0x3e, 0xfc, 0x60, 0x0f, 0xf3, 0x4a, 0xdb, 0xfe, 0xb8, 0xe6, 0x9b, + 0x1a, 0xe8, 0x80, 0x93, 0xdd, 0x8c, 0x33, 0xf9, 0xde, 0x5e, 0xd5, 0x9e, + 0xef, 0x03, 0xcc, 0x11, 0x75, 0xbf, 0x30, 0xc6, 0xd1, 0xb4, 0xc8, 0xb6, + 0xa7, 0x5c, 0x18, 0x90, 0xfb, 0x6c, 0x5e, 0x3e, 0xa8, 0x83, 0x1d, 0x5a, + 0xa7, 0x8c, 0x5d, 0xae, 0xb6, 0x25, 0xbd, 0xdf, 0x80, 0xd0, 0xac, 0x4d, + 0x9b, 0x3d, 0x81, 0x7d, 0xc5, 0x6a, 0xbb, 0xfe, 0x5e, 0xd8, 0xf5, 0xac, + 0x23, 0xae, 0xb1, 0xeb, 0xef, 0xb2, 0xbc, 0xc6, 0xdf, 0x9e, 0xb6, 0xf1, + 0x0f, 0x00, 0xbe, 0x1d, 0x73, 0x36, 0x3e, 0xdb, 0xa0, 0xad, 0x21, 0x72, + 0x03, 0xec, 0xbc, 0x1b, 0xc1, 0x83, 0x37, 0xc1, 0x8f, 0x7a, 0x77, 0xd1, + 0x93, 0x9d, 0xc5, 0x66, 0xf8, 0xdb, 0xad, 0xf2, 0xab, 0x63, 0x1b, 0xa5, + 0x7f, 0xf4, 0x77, 0x9a, 0xa1, 0x57, 0x61, 0x97, 0xbe, 0x08, 0x38, 0x23, + 0x56, 0x56, 0x47, 0xc1, 0x03, 0xed, 0x89, 0x1f, 0xa8, 0x44, 0xab, 0x91, + 0xed, 0x3c, 0x4b, 0xbe, 0x5c, 0x3b, 0x31, 0xd4, 0x67, 0x1c, 0xa5, 0x45, + 0xce, 0x1c, 0xa7, 0xe7, 0x95, 0x80, 0x2d, 0x9e, 0x82, 0x1d, 0xb2, 0x01, + 0xed, 0x31, 0x96, 0xbc, 0x5a, 0x9e, 0xd9, 0xea, 0xde, 0x9d, 0xd3, 0x7c, + 0x78, 0xc9, 0xc9, 0x8e, 0xdd, 0x24, 0x85, 0xc1, 0x28, 0xc6, 0xa0, 0x9a, + 0xd7, 0xca, 0xf5, 0xd2, 0xaf, 0xc7, 0x73, 0x59, 0x0e, 0x42, 0x1f, 0xff, + 0x69, 0xb1, 0x5f, 0x66, 0x07, 0x9a, 0xf0, 0x1d, 0x95, 0x67, 0x8a, 0x5b, + 0xe0, 0xef, 0xfc, 0x0a, 0x70, 0x54, 0x8b, 0xef, 0x5a, 0xe9, 0x5d, 0x47, + 0x5e, 0x6d, 0x90, 0x19, 0xa4, 0xdf, 0x28, 0xbf, 0x64, 0xd3, 0x99, 0x46, + 0xde, 0x68, 0x40, 0xdd, 0xa8, 0x9c, 0x2f, 0xd2, 0x96, 0xd4, 0x3c, 0xd1, + 0xf3, 0xb2, 0x6c, 0xc9, 0xbc, 0x0c, 0xdb, 0xf4, 0x59, 0x3c, 0xcf, 0x4b, + 0x72, 0xe7, 0x6e, 0x67, 0x4b, 0xa2, 0xdd, 0x81, 0xbe, 0xc4, 0xe3, 0x3a, + 0x5b, 0xbc, 0x5a, 0xe7, 0x5a, 0xdb, 0x46, 0x8d, 0x3c, 0x3f, 0xa8, 0xe2, + 0x0d, 0x98, 0x93, 0xcd, 0x4e, 0x87, 0x4d, 0xe3, 0xb7, 0xbe, 0x2f, 0x51, + 0xda, 0xcf, 0xa8, 0x0d, 0xab, 0x44, 0xda, 0x1a, 0x60, 0xe7, 0xec, 0x11, + 0xd5, 0xdc, 0x20, 0xae, 0xb4, 0x4f, 0xa8, 0x56, 0xa4, 0xf9, 0x36, 0x2d, + 0xd6, 0x00, 0x9d, 0x80, 0xb4, 0x16, 0xa4, 0x6d, 0xb2, 0x69, 0x4d, 0x0d, + 0x52, 0x8b, 0xb4, 0xcb, 0x9a, 0xe7, 0x2f, 0x76, 0xf8, 0x5e, 0xce, 0xa9, + 0x97, 0xb6, 0x53, 0x0d, 0x90, 0x0d, 0xab, 0x65, 0x66, 0x6b, 0x9d, 0xb4, + 0x21, 0x8f, 0x31, 0xee, 0xd4, 0xa9, 0xa8, 0xbc, 0xf3, 0x54, 0x7b, 0xfc, + 0xa3, 0x18, 0x43, 0xfb, 0x19, 0xc6, 0xbc, 0xff, 0xac, 0x99, 0x31, 0x9f, + 0xb6, 0x33, 0x7c, 0xd7, 0x69, 0xf9, 0x43, 0x7c, 0x98, 0x3b, 0xdf, 0x60, + 0x63, 0x94, 0x8e, 0x3b, 0xc3, 0xa3, 0xd4, 0xdb, 0xed, 0xf6, 0x7e, 0xa2, + 0xff, 0xd9, 0x4c, 0x5f, 0x6d, 0x82, 0x36, 0x54, 0x89, 0xfc, 0x48, 0xdd, + 0x83, 0xf7, 0xb8, 0x23, 0x85, 0x79, 0x99, 0x35, 0x45, 0xbe, 0x3a, 0xae, + 0xb8, 0x4f, 0x05, 0x69, 0x95, 0x77, 0x05, 0x66, 0x8e, 0xc9, 0x0b, 0x46, + 0x2e, 0xfd, 0x9a, 0x91, 0x4b, 0xa7, 0xcf, 0x2d, 0x90, 0x4b, 0x05, 0x2d, + 0x97, 0x06, 0x05, 0xef, 0xa9, 0x02, 0xe4, 0xd2, 0x08, 0xbe, 0x3d, 0x2d, + 0x97, 0x62, 0x62, 0x6d, 0x64, 0x89, 0x5e, 0xc5, 0xfe, 0x27, 0x4b, 0xae, + 0xb6, 0xa5, 0x0a, 0xe3, 0xb0, 0x43, 0x4a, 0x23, 0x56, 0x67, 0x4b, 0xba, + 0x49, 0x3a, 0x7a, 0x7e, 0x2a, 0xa1, 0x9d, 0x39, 0xdb, 0xcc, 0x3b, 0x8f, + 0x5f, 0x54, 0x94, 0x61, 0x27, 0x20, 0xc3, 0x1e, 0xbe, 0x82, 0x0c, 0x43, + 0x5e, 0x19, 0x79, 0x65, 0xb6, 0xfb, 0xdd, 0x9f, 0x0e, 0x79, 0x94, 0x1f, + 0x94, 0x19, 0x90, 0x49, 0x25, 0xc8, 0xa4, 0x12, 0xe4, 0x54, 0x09, 0x72, + 0xa9, 0x04, 0xb9, 0x54, 0x82, 0x5c, 0x2a, 0x41, 0x2e, 0x41, 0xc6, 0x3d, + 0x0a, 0x19, 0x67, 0x64, 0xda, 0x00, 0xed, 0x35, 0xb9, 0xcf, 0xea, 0x77, + 0x13, 0x27, 0xe9, 0xb2, 0x7e, 0x91, 0xd9, 0xb3, 0x7a, 0xae, 0x2a, 0x2e, + 0xb8, 0xeb, 0x88, 0xe6, 0x77, 0xcf, 0x57, 0xd7, 0x3a, 0xdc, 0x1f, 0xf3, + 0x03, 0xed, 0xb3, 0x6f, 0xe6, 0x6f, 0xa9, 0x03, 0x5f, 0xbf, 0x62, 0xf9, + 0x7a, 0xf3, 0x1c, 0x5f, 0x27, 0x1d, 0xc6, 0x89, 0x97, 0xe7, 0xeb, 0x16, + 0x9b, 0x97, 0x0f, 0x56, 0x80, 0xaf, 0x57, 0x2c, 0xe2, 0xeb, 0x28, 0xf8, + 0x7a, 0xe7, 0x12, 0xbe, 0x5e, 0xe5, 0xf4, 0xea, 0x3a, 0x3c, 0x83, 0xc6, + 0xef, 0x5a, 0x67, 0x9e, 0xaf, 0xf7, 0x6b, 0xbe, 0x3e, 0x04, 0xbe, 0xbe, + 0xbe, 0x8a, 0xaf, 0x77, 0x4a, 0xf2, 0x96, 0x6c, 0x64, 0xa3, 0xec, 0xbe, + 0x5f, 0x35, 0xaf, 0x91, 0x7f, 0x11, 0x53, 0xdf, 0xf0, 0x58, 0xef, 0x58, + 0xb3, 0xe4, 0x1e, 0xfa, 0x11, 0xd7, 0x06, 0xc8, 0x23, 0x43, 0x19, 0xc7, + 0x93, 0x83, 0x47, 0x7e, 0x20, 0xd3, 0x9a, 0xb7, 0x44, 0xf6, 0x1c, 0x89, + 0xca, 0xf0, 0x11, 0xc6, 0x1e, 0xbe, 0x63, 0xe9, 0xbd, 0x4e, 0x86, 0x07, + 0xb9, 0x5f, 0xd2, 0x95, 0xdd, 0x47, 0xe0, 0x63, 0x1d, 0x61, 0xec, 0xe1, + 0xf2, 0x1c, 0x8f, 0x4d, 0x43, 0xb6, 0xec, 0x3e, 0xa2, 0xe7, 0x1a, 0xed, + 0x34, 0xc8, 0xa1, 0x23, 0x22, 0xb7, 0x1d, 0x71, 0xe5, 0xf6, 0x23, 0x73, + 0xbc, 0x36, 0x10, 0xf2, 0xda, 0x9f, 0x83, 0xd7, 0xda, 0x2d, 0xaf, 0xa9, + 0x39, 0x5e, 0xfb, 0x5a, 0x15, 0xaf, 0xb1, 0x3e, 0x79, 0xed, 0x82, 0x4d, + 0xe3, 0xb7, 0x2b, 0x7b, 0x8f, 0xb4, 0xca, 0xee, 0x87, 0xde, 0x22, 0x7b, + 0xee, 0x27, 0xac, 0xe6, 0x9e, 0x3c, 0xda, 0x5f, 0xe3, 0x95, 0x76, 0xb4, + 0x1f, 0xee, 0x0f, 0xd2, 0x77, 0x65, 0x75, 0x4e, 0x48, 0x32, 0xcf, 0xfe, + 0x6a, 0xe1, 0x3b, 0x9f, 0x82, 0x4f, 0xb1, 0x17, 0x30, 0xdd, 0x7a, 0x44, + 0x92, 0xae, 0xbc, 0x26, 0x23, 0xa9, 0x47, 0x5b, 0x8d, 0x3d, 0x71, 0x09, + 0xbc, 0x42, 0xfa, 0xcf, 0x48, 0xee, 0xed, 0x81, 0xf6, 0x2b, 0x46, 0xcb, + 0x42, 0xff, 0x9f, 0x31, 0x73, 0xc7, 0xdc, 0x77, 0xc7, 0xf3, 0xbe, 0x35, + 0xfa, 0xbc, 0x9b, 0x8e, 0xd7, 0x76, 0x33, 0xbf, 0x46, 0xef, 0x37, 0xcd, + 0xe9, 0xb3, 0xdc, 0xac, 0xcf, 0x76, 0x62, 0x3a, 0x9e, 0x5e, 0x28, 0xf3, + 0x8e, 0x30, 0xde, 0xbd, 0xcc, 0xbb, 0x06, 0xff, 0xf8, 0x2a, 0x13, 0x9b, + 0x25, 0xdf, 0x7d, 0xdd, 0xc9, 0x15, 0x2f, 0xe9, 0x7d, 0x85, 0x59, 0x1f, + 0xbf, 0xcb, 0xfc, 0x66, 0xf9, 0x4b, 0x8c, 0x71, 0x24, 0x12, 0xea, 0x81, + 0x56, 0xee, 0x3b, 0x18, 0x9c, 0x32, 0x76, 0x94, 0xe1, 0xd1, 0x06, 0xed, + 0x6b, 0x8c, 0xe0, 0x7b, 0xf7, 0x68, 0xa3, 0x53, 0xa0, 0x6d, 0x32, 0xd0, + 0xe0, 0xe4, 0xc7, 0xf7, 0xb4, 0x1a, 0x9b, 0x79, 0x20, 0xce, 0x3d, 0x85, + 0x19, 0xb5, 0x54, 0x26, 0x9f, 0x92, 0x50, 0x26, 0x27, 0x6f, 0xc9, 0xc0, + 0xb6, 0xce, 0x1d, 0xd1, 0xf7, 0xf7, 0x25, 0xda, 0x15, 0xc7, 0xf4, 0x09, + 0xc8, 0xd7, 0x90, 0x16, 0xe2, 0xf2, 0xf1, 0x23, 0xa4, 0x07, 0x15, 0x6b, + 0x94, 0xdf, 0xb2, 0xf4, 0x70, 0x59, 0x8a, 0x90, 0x3b, 0x47, 0x8e, 0xdc, + 0x2e, 0xe3, 0xbb, 0x16, 0xd3, 0xc3, 0x9e, 0x79, 0x7a, 0x88, 0xc1, 0x3e, + 0x73, 0xaa, 0xe9, 0xe1, 0x37, 0xe7, 0xe8, 0x61, 0xdc, 0xf9, 0xd7, 0xd2, + 0xc3, 0x0d, 0x0b, 0xe8, 0x61, 0x44, 0xd3, 0x43, 0xff, 0x1c, 0x3d, 0x8c, + 0x1c, 0x61, 0xbf, 0x7a, 0x5d, 0xd4, 0x9b, 0x71, 0x38, 0xe7, 0x73, 0xb4, + 0x90, 0x18, 0xd6, 0xfb, 0x44, 0x93, 0x79, 0x9e, 0x25, 0x5d, 0xa5, 0x18, + 0x1b, 0x99, 0x9f, 0xff, 0xc6, 0x7f, 0xd3, 0xf9, 0x7f, 0x47, 0xfc, 0xff, + 0xef, 0xfc, 0x5f, 0x8f, 0xf6, 0x29, 0x8b, 0x43, 0x79, 0x1c, 0xd2, 0xc3, + 0x7b, 0xe2, 0x46, 0x2f, 0x70, 0x8e, 0xf9, 0x6d, 0xf6, 0xac, 0x9f, 0x83, + 0xfc, 0x7b, 0x1c, 0xf2, 0xef, 0xb1, 0x05, 0xeb, 0x01, 0x3d, 0x36, 0x06, + 0x11, 0xc8, 0xc1, 0xd4, 0x3c, 0x3e, 0x66, 0xba, 0x89, 0x0f, 0xb3, 0xf7, + 0xe4, 0x6c, 0x65, 0x31, 0x4e, 0x5c, 0xbd, 0xdf, 0xe8, 0x64, 0xaa, 0x1a, + 0x27, 0x84, 0x7b, 0xb6, 0x6a, 0x8c, 0xf8, 0x5d, 0xe6, 0xf7, 0x65, 0xbd, + 0x87, 0xa4, 0xa0, 0xd7, 0x9f, 0x88, 0x17, 0xae, 0x3f, 0x11, 0x27, 0xae, + 0xb6, 0xf7, 0x0b, 0xe5, 0x3a, 0xbd, 0x2f, 0xfc, 0xc0, 0x54, 0x4c, 0x66, + 0x62, 0x8c, 0xeb, 0xf1, 0xde, 0x57, 0xfa, 0xca, 0x7e, 0xbc, 0x20, 0x79, + 0x7b, 0xd6, 0x67, 0x95, 0xa5, 0x6d, 0xc6, 0x03, 0x79, 0x27, 0x42, 0xb8, + 0x0e, 0xd1, 0x69, 0x65, 0x5d, 0x43, 0x55, 0x9c, 0x12, 0x78, 0x1f, 0x93, + 0x44, 0xb6, 0x1b, 0xef, 0x29, 0xf6, 0xfd, 0xa4, 0x8c, 0x3c, 0x58, 0x86, + 0x2d, 0xf7, 0x30, 0x74, 0x8e, 0x23, 0x10, 0x93, 0xfa, 0x2e, 0x14, 0xc2, + 0x30, 0xa1, 0xef, 0xf5, 0xa3, 0xdf, 0x47, 0x7a, 0x88, 0xe3, 0xfb, 0xb2, + 0x8d, 0x25, 0xc5, 0xa5, 0x50, 0xfc, 0x01, 0xe0, 0xe7, 0x1d, 0x94, 0x3f, + 0xc2, 0xfb, 0x8d, 0xe6, 0xc3, 0xf8, 0x21, 0x03, 0xfa, 0xcd, 0xb9, 0x79, + 0xcd, 0xc9, 0x94, 0xcd, 0xfe, 0x96, 0xaa, 0xfb, 0xf5, 0xe5, 0xb0, 0xb6, + 0x9f, 0xd3, 0x76, 0x5f, 0x0b, 0xcf, 0xe7, 0x19, 0x1b, 0xfa, 0xcb, 0xb0, + 0xa1, 0x9f, 0xa8, 0x64, 0xf4, 0x1a, 0xd6, 0x63, 0xb0, 0xa1, 0x1f, 0x85, + 0xee, 0xa1, 0xce, 0x89, 0x59, 0x9d, 0x33, 0xa2, 0x76, 0x69, 0x9d, 0xf3, + 0xd7, 0x5a, 0xe7, 0xfc, 0xea, 0x12, 0x9d, 0x73, 0x48, 0xb5, 0x8f, 0x52, + 0xe7, 0xf4, 0xaa, 0x9d, 0x0e, 0xed, 0xc5, 0xb5, 0xcb, 0xe8, 0x9c, 0xf7, + 0xca, 0xaf, 0xd8, 0xbc, 0xfd, 0xf2, 0xbe, 0x6d, 0x7a, 0xdd, 0xc6, 0x9b, + 0x50, 0xbc, 0xcb, 0xce, 0xe8, 0xa0, 0xeb, 0x55, 0xa7, 0x5e, 0xef, 0xfd, + 0x6a, 0x95, 0xce, 0x69, 0x53, 0xdd, 0x4e, 0xaf, 0xae, 0xc3, 0x78, 0x04, + 0xbf, 0x53, 0x4e, 0x66, 0xa0, 0x0e, 0xdf, 0x71, 0x89, 0x1c, 0xc1, 0xd8, + 0xcd, 0x7d, 0x7b, 0xca, 0xe4, 0x5d, 0x63, 0xf3, 0x54, 0x98, 0xee, 0x9a, + 0xf4, 0x76, 0x9b, 0x6e, 0x74, 0x55, 0x9b, 0x6a, 0xd5, 0xba, 0x6a, 0x33, + 0x18, 0x6a, 0x02, 0xfa, 0x75, 0xa2, 0x14, 0xea, 0x2c, 0xfe, 0x66, 0xbc, + 0x99, 0x71, 0x89, 0x30, 0x6e, 0x9d, 0x40, 0x19, 0x3c, 0xa5, 0xd0, 0xa6, + 0xe4, 0x6f, 0xf8, 0x0a, 0x78, 0xa6, 0x80, 0xd7, 0x5b, 0xc0, 0x3f, 0xbf, + 0x5e, 0x64, 0xdc, 0xb3, 0x59, 0x8e, 0x8e, 0x55, 0xe7, 0xb5, 0xca, 0xbb, + 0xc7, 0x36, 0xc8, 0xbe, 0x51, 0xff, 0x6a, 0xa9, 0xdf, 0x28, 0x23, 0xa3, + 0x2f, 0xea, 0xfb, 0x40, 0xd6, 0xe8, 0x7b, 0x92, 0x78, 0x7f, 0x98, 0x91, + 0x91, 0xfd, 0x8e, 0x91, 0x91, 0x19, 0x35, 0x6f, 0xb3, 0x86, 0x6d, 0xf2, + 0x6e, 0xa6, 0xbe, 0xd1, 0xb8, 0xbe, 0x43, 0x7a, 0xa2, 0x72, 0xad, 0xfc, + 0xd1, 0x71, 0x75, 0xa7, 0x9a, 0xbf, 0x4b, 0x41, 0xdb, 0xac, 0x93, 0x0b, + 0x6c, 0xd6, 0xbf, 0x97, 0x99, 0xf7, 0x45, 0x31, 0x4e, 0xd0, 0xf0, 0x75, + 0x2f, 0x73, 0x1d, 0xb4, 0x39, 0x26, 0x97, 0xa4, 0x4f, 0xe3, 0x8f, 0xf2, + 0xb4, 0x01, 0x72, 0x70, 0x56, 0xeb, 0xd7, 0xb5, 0xbc, 0xf3, 0xf8, 0x08, + 0x6d, 0xd7, 0xaf, 0x6b, 0x79, 0xb6, 0xd6, 0xda, 0xae, 0xd3, 0x90, 0xd3, + 0x94, 0xa3, 0x37, 0xca, 0x5f, 0xdb, 0x74, 0xa6, 0x25, 0xe3, 0xb3, 0x42, + 0x7d, 0x17, 0x83, 0x0c, 0xa5, 0x3c, 0xfd, 0x59, 0x6d, 0xd7, 0xe7, 0x6c, + 0x1b, 0x94, 0x9f, 0x46, 0x76, 0x6f, 0x76, 0xa6, 0x6d, 0x1a, 0xbf, 0xc3, + 0x18, 0xba, 0x9f, 0xc9, 0x59, 0x3e, 0x53, 0xce, 0x93, 0xc8, 0x5f, 0x83, + 0x7c, 0xf2, 0xd9, 0x63, 0x9a, 0xcf, 0xb4, 0x7d, 0xe2, 0x74, 0xd9, 0x35, + 0x85, 0xb9, 0xf5, 0x80, 0x3c, 0xf9, 0x4c, 0x1d, 0xf5, 0xa6, 0x8d, 0x3c, + 0xf0, 0x90, 0xfe, 0x45, 0xe8, 0x0e, 0xd6, 0x45, 0xfa, 0xb1, 0x0c, 0xe6, + 0xf0, 0x24, 0xfc, 0x9f, 0x46, 0x7c, 0x37, 0xe3, 0x7b, 0x42, 0x7e, 0x75, + 0x30, 0xaa, 0xc7, 0x3d, 0x82, 0x71, 0x1c, 0x38, 0x82, 0x31, 0x39, 0xc6, + 0x76, 0x76, 0xcf, 0xb8, 0x52, 0x73, 0x86, 0x7c, 0xc7, 0x33, 0x86, 0x41, + 0xb0, 0xb7, 0x8b, 0x74, 0x9b, 0xf4, 0xfa, 0xf5, 0xf9, 0xb7, 0xcd, 0xf1, + 0x08, 0x70, 0x72, 0x00, 0xf3, 0x31, 0x52, 0xf4, 0xbd, 0xac, 0xe3, 0xc7, + 0x31, 0x4e, 0xd8, 0x80, 0xed, 0xb0, 0x05, 0xdb, 0x61, 0x07, 0xb6, 0xc3, + 0x0e, 0x5c, 0x2d, 0xa7, 0xb6, 0x72, 0x7f, 0x49, 0xfe, 0x9d, 0xbc, 0x77, + 0xf9, 0x1b, 0x3a, 0x36, 0x5f, 0x7b, 0x4b, 0x1f, 0x7c, 0x76, 0xf1, 0x92, + 0x03, 0xdc, 0x63, 0x3f, 0xeb, 0xd5, 0xde, 0xd2, 0x2f, 0xed, 0x3d, 0xc8, + 0xef, 0xb9, 0x24, 0x1d, 0xb7, 0x7c, 0xd8, 0xa9, 0x1d, 0xe8, 0x03, 0x1e, + 0x33, 0x4e, 0x32, 0x3e, 0xe4, 0x30, 0x4e, 0x91, 0xdd, 0x1c, 0xd1, 0x67, + 0xc4, 0xa6, 0x19, 0x8b, 0xb8, 0xa5, 0x3d, 0xb2, 0x25, 0xb1, 0xdb, 0x49, + 0x0e, 0xa8, 0x48, 0x72, 0xa0, 0xcf, 0x09, 0xcb, 0xf1, 0x0e, 0x6a, 0xc8, + 0x19, 0xc0, 0x7a, 0xa0, 0xf4, 0x75, 0xd0, 0xd3, 0x79, 0x29, 0x1c, 0x6f, + 0x90, 0xa9, 0x62, 0xbb, 0x97, 0x55, 0x31, 0xe1, 0xbe, 0x12, 0x75, 0x0a, + 0x44, 0x7f, 0x26, 0x2a, 0x13, 0xa3, 0x1b, 0x45, 0x69, 0xdb, 0xbd, 0x45, + 0xb2, 0x63, 0xa3, 0x72, 0xbe, 0x5b, 0x9a, 0x14, 0xda, 0xe7, 0xdd, 0xde, + 0xea, 0x14, 0xd7, 0x11, 0x43, 0x5e, 0x58, 0x4f, 0x3e, 0x19, 0x05, 0x0e, + 0x41, 0xb7, 0x8c, 0xeb, 0xd6, 0x09, 0xe5, 0xde, 0xed, 0x3a, 0x66, 0xca, + 0x38, 0x6d, 0xf5, 0x7a, 0x03, 0xf9, 0x23, 0xba, 0x2c, 0x7f, 0x4c, 0x96, + 0xb8, 0x36, 0x23, 0x79, 0x97, 0x71, 0x61, 0x1f, 0xbf, 0xc7, 0x59, 0xb6, + 0x4e, 0x46, 0xba, 0xf3, 0x76, 0x8f, 0xc7, 0x37, 0xc1, 0x07, 0x1c, 0x9f, + 0x5e, 0x27, 0x01, 0xaf, 0x2f, 0x5e, 0xcf, 0x88, 0x56, 0xc9, 0x03, 0x47, + 0x66, 0x46, 0xc3, 0xf5, 0x0f, 0xb6, 0x87, 0xef, 0x71, 0x23, 0x6f, 0xb3, + 0x4b, 0xea, 0x11, 0x2e, 0xae, 0x55, 0x2e, 0x94, 0xb1, 0x4a, 0x9f, 0x13, + 0xf6, 0xb4, 0x7c, 0x3d, 0x5d, 0x31, 0xb2, 0x75, 0xbc, 0x12, 0xea, 0x96, + 0xa8, 0xd1, 0xa5, 0x4b, 0xf4, 0x89, 0x89, 0x60, 0xce, 0xeb, 0x93, 0x4b, + 0x3a, 0x46, 0xf7, 0x6b, 0x53, 0x2d, 0xe2, 0x1e, 0x93, 0xd9, 0x11, 0xff, + 0x54, 0x2b, 0xf7, 0x69, 0x8c, 0xa4, 0xde, 0x8c, 0x7e, 0x8c, 0xb5, 0x50, + 0x1f, 0x0e, 0xa9, 0xb5, 0x78, 0xaf, 0xd1, 0xf4, 0x07, 0x9e, 0xc2, 0xb7, + 0xf1, 0x13, 0xbe, 0x0c, 0x3f, 0xe1, 0x09, 0xe8, 0xba, 0x73, 0xf0, 0x13, + 0x1e, 0x87, 0x9f, 0xf0, 0x18, 0xfc, 0x84, 0x47, 0xa1, 0x27, 0xab, 0xfd, + 0x83, 0xe1, 0x05, 0xfe, 0x41, 0xa0, 0xf9, 0x9f, 0x31, 0xc0, 0xc7, 0xab, + 0x7c, 0x83, 0xbd, 0x46, 0x5f, 0xc1, 0xef, 0x37, 0x7c, 0xd4, 0xa6, 0x6e, + 0xd6, 0xfa, 0xd1, 0xec, 0xd9, 0x1d, 0x98, 0xd3, 0x57, 0x6d, 0xca, 0xe8, + 0xab, 0x89, 0x79, 0x7d, 0x65, 0xf8, 0xe8, 0xd8, 0xa8, 0x44, 0xfc, 0xd1, + 0xe9, 0x6c, 0x6a, 0xbb, 0xe6, 0xa1, 0x26, 0x7f, 0xa3, 0x44, 0x1e, 0x50, + 0xcd, 0x35, 0x92, 0xb5, 0xdf, 0xa0, 0xaf, 0xa3, 0x5f, 0x47, 0x5b, 0xef, + 0x94, 0x9c, 0xb6, 0xcf, 0xae, 0x8c, 0xef, 0x47, 0x17, 0xe1, 0xbb, 0x50, + 0x7a, 0x56, 0xe3, 0xfc, 0x7e, 0x7d, 0x26, 0xbf, 0x41, 0x86, 0xcb, 0x21, + 0xce, 0x79, 0x06, 0x8e, 0xfb, 0x30, 0x5a, 0x25, 0x72, 0xac, 0x45, 0xfa, + 0x53, 0xa2, 0x72, 0xa9, 0x95, 0x7a, 0xff, 0xca, 0xa9, 0x6e, 0x89, 0xe7, + 0xba, 0x49, 0xab, 0xf7, 0xc9, 0x84, 0x9e, 0x8b, 0x16, 0xa9, 0x39, 0x46, + 0x1b, 0x25, 0x5c, 0xc3, 0xbb, 0xbd, 0xc5, 0xde, 0x41, 0x1d, 0x35, 0xe5, + 0x44, 0x0e, 0xea, 0xf9, 0x9a, 0xd5, 0x7b, 0x0c, 0x6f, 0x9e, 0x62, 0x2c, + 0x9e, 0xf7, 0xfd, 0x31, 0x0e, 0xff, 0xaf, 0x99, 0xbf, 0x42, 0x8b, 0xb1, + 0x67, 0xd6, 0x58, 0x3b, 0xc6, 0xc4, 0xa9, 0x96, 0xb7, 0x61, 0xd8, 0x4e, + 0xf5, 0x1d, 0xb5, 0xab, 0xe0, 0x03, 0x37, 0xa0, 0x4d, 0xae, 0x63, 0xdb, + 0xbf, 0x17, 0xe4, 0xfd, 0xb3, 0x73, 0xc0, 0x5f, 0x85, 0xb4, 0x06, 0xe4, + 0x31, 0x66, 0xf3, 0x85, 0x16, 0xc6, 0x65, 0xb3, 0x7e, 0xa3, 0x4d, 0x5b, + 0xe5, 0x8c, 0x8c, 0xb6, 0xc3, 0x37, 0xe7, 0x39, 0x76, 0xe6, 0xf7, 0x73, + 0xee, 0x84, 0x7f, 0xab, 0x69, 0x12, 0xf2, 0x67, 0x8f, 0x5c, 0x6b, 0xe3, + 0xce, 0xd4, 0xc3, 0xbf, 0xb8, 0x60, 0xbd, 0xf6, 0x10, 0xf4, 0xd8, 0xad, + 0x90, 0x47, 0xd4, 0xc3, 0x87, 0xe4, 0x17, 0x2c, 0x3d, 0x2f, 0xd4, 0xc3, + 0x17, 0x85, 0xb1, 0xe1, 0x2e, 0xe4, 0xe5, 0x83, 0x28, 0xe8, 0xe1, 0x70, + 0x95, 0xaf, 0x46, 0xbf, 0xaf, 0x2e, 0x6d, 0xd6, 0xc0, 0x16, 0xfa, 0x7d, + 0x90, 0x03, 0xb1, 0xd0, 0xcf, 0xab, 0x9d, 0x5b, 0xa3, 0xdd, 0x69, 0xeb, + 0x8e, 0xa4, 0x5e, 0x22, 0x8e, 0x12, 0x87, 0xe4, 0xf6, 0xf5, 0xbc, 0x26, + 0xcf, 0xf5, 0xbf, 0xa5, 0x71, 0x26, 0x8a, 0xb4, 0xb7, 0x46, 0xc3, 0x68, + 0xe5, 0x7c, 0x22, 0xdc, 0xbf, 0x51, 0xb0, 0x75, 0xf7, 0xd8, 0xf5, 0xf8, + 0x82, 0x7c, 0x9b, 0x71, 0xce, 0x44, 0x5f, 0x64, 0x25, 0xcf, 0x64, 0xa3, + 0xee, 0xed, 0xda, 0x6f, 0xcf, 0x48, 0xd8, 0x16, 0xbf, 0x6b, 0xaa, 0xda, + 0xa6, 0x1d, 0xc5, 0xf7, 0xe2, 0xfb, 0x1b, 0x9e, 0xd7, 0x6b, 0x8b, 0xe6, + 0x6e, 0x9a, 0x90, 0x4f, 0xc8, 0x3b, 0x09, 0x7d, 0x8e, 0xc9, 0x3f, 0x46, + 0xbb, 0x87, 0xeb, 0xae, 0xde, 0xf4, 0x70, 0xea, 0x23, 0xfa, 0x0e, 0xd5, + 0x71, 0x11, 0xa7, 0x90, 0xda, 0xab, 0xf7, 0x9d, 0x14, 0x74, 0x7c, 0x39, + 0x8f, 0xf7, 0xbc, 0x8f, 0xda, 0x76, 0x8c, 0x7f, 0x0b, 0x88, 0x69, 0x1f, + 0x04, 0x6c, 0xd4, 0x21, 0x94, 0xbd, 0x31, 0x69, 0x3b, 0xfa, 0x7e, 0xcd, + 0x0b, 0x6b, 0xe1, 0x0b, 0xf4, 0x1e, 0x85, 0xae, 0x3e, 0x1a, 0x97, 0xfe, + 0xa3, 0x5a, 0x37, 0x66, 0x96, 0xc6, 0x0a, 0xb6, 0x78, 0x2e, 0xfd, 0x89, + 0x98, 0x27, 0xd7, 0x1c, 0x8d, 0xc8, 0xe1, 0xd8, 0x16, 0xaf, 0xc3, 0xb9, + 0xd1, 0xea, 0x42, 0x43, 0x7f, 0xa0, 0x15, 0xd4, 0x37, 0xeb, 0x90, 0xbd, + 0xf3, 0xb1, 0x6b, 0xd4, 0x7f, 0x49, 0x46, 0xc8, 0x4b, 0x95, 0x88, 0x8c, + 0x0f, 0xb6, 0x02, 0x9e, 0xb7, 0xae, 0x07, 0x0e, 0x40, 0x53, 0x98, 0x1f, + 0xfd, 0xf7, 0x3c, 0xdc, 0x38, 0xe5, 0x57, 0x1b, 0xfa, 0xef, 0x3b, 0x4a, + 0x1d, 0xe6, 0x6b, 0xbe, 0x46, 0xbf, 0x5e, 0x8d, 0xf6, 0x3d, 0xc8, 0x8b, + 0x6f, 0x11, 0xff, 0x01, 0xc8, 0xb5, 0xa3, 0x51, 0xe9, 0x38, 0xda, 0x20, + 0x9b, 0x8e, 0xd2, 0xf7, 0xa8, 0xf6, 0x45, 0x69, 0x8b, 0x5e, 0xc2, 0xb8, + 0x6e, 0x34, 0xf7, 0x0d, 0x4e, 0x45, 0x65, 0x1f, 0xf9, 0x15, 0x65, 0x73, + 0xb0, 0x93, 0xb3, 0x47, 0x3d, 0xbd, 0x16, 0x9a, 0xc5, 0x38, 0xf9, 0x37, + 0x2c, 0xfa, 0x8e, 0x1a, 0x39, 0x53, 0xa0, 0x6f, 0x32, 0xd0, 0x02, 0xbc, + 0x3e, 0x60, 0xf9, 0xe5, 0x3d, 0xeb, 0x2d, 0x5f, 0xfe, 0x9c, 0xfc, 0x96, + 0x5b, 0x6f, 0xe4, 0xe5, 0x87, 0xd6, 0x73, 0x2f, 0xd2, 0x5a, 0x9f, 0xef, + 0x3a, 0x6d, 0x43, 0x18, 0xb9, 0xf9, 0x7a, 0xfc, 0x27, 0xc0, 0x51, 0xb8, + 0xfe, 0x44, 0x3e, 0xe4, 0x1a, 0xb2, 0x3e, 0xb3, 0x92, 0x9a, 0xd1, 0x7f, + 0x53, 0x89, 0x6b, 0x61, 0xf3, 0xf7, 0x59, 0x6d, 0xaf, 0x30, 0x36, 0xfe, + 0x4c, 0xf8, 0x37, 0x9c, 0xaa, 0xf6, 0x19, 0x56, 0xaf, 0x75, 0x31, 0xbe, + 0x34, 0xb7, 0x17, 0x28, 0x18, 0xd5, 0x77, 0xc2, 0xc5, 0x9c, 0x8b, 0xc5, + 0x5a, 0xe7, 0x9b, 0x63, 0x12, 0xb8, 0x7e, 0xdc, 0xf9, 0x96, 0xcf, 0xb5, + 0x71, 0xcf, 0x79, 0xb9, 0xe8, 0x83, 0xf7, 0xfe, 0x02, 0xe3, 0x68, 0x75, + 0x5e, 0xc1, 0x9c, 0x1e, 0x2c, 0x65, 0x92, 0x9e, 0x8d, 0x83, 0x3f, 0x5b, + 0x6c, 0x75, 0x9e, 0x9b, 0x8f, 0x21, 0xf5, 0x84, 0x74, 0x71, 0x88, 0x79, + 0x65, 0xe4, 0x95, 0x19, 0xeb, 0xad, 0x77, 0x26, 0xc7, 0xec, 0x7e, 0x12, + 0xa3, 0x8b, 0xe6, 0xd6, 0x5f, 0x06, 0xf4, 0xfa, 0x84, 0xeb, 0x4c, 0x4e, + 0x4d, 0xaf, 0x37, 0xfb, 0x8a, 0x6a, 0x91, 0x67, 0xf6, 0x58, 0x4e, 0x4c, + 0xd5, 0xa2, 0x4c, 0xbd, 0x33, 0xa1, 0x63, 0x5e, 0xda, 0xf6, 0x70, 0xc6, + 0xa7, 0xea, 0x9d, 0x29, 0xbd, 0xd6, 0x1c, 0x75, 0x4e, 0x8e, 0xb1, 0xed, + 0x28, 0xca, 0x88, 0x73, 0x0a, 0xed, 0x4d, 0x8d, 0xb5, 0xc7, 0xf7, 0x49, + 0x3b, 0x6c, 0x01, 0xfe, 0x8d, 0x34, 0xde, 0x17, 0xe0, 0x3a, 0x53, 0x73, + 0xed, 0x2a, 0xb4, 0xc3, 0xb2, 0xa4, 0x41, 0xf6, 0xeb, 0xa2, 0xfd, 0xa5, + 0x6b, 0x52, 0x4b, 0x71, 0x32, 0x06, 0x9c, 0x1c, 0xb4, 0x38, 0x39, 0x61, + 0x71, 0x32, 0x5a, 0x85, 0x93, 0x87, 0x17, 0xe1, 0xe4, 0x04, 0x70, 0xf2, + 0xf0, 0x15, 0x70, 0x82, 0xbc, 0xf2, 0xc3, 0x16, 0x27, 0xf7, 0x2d, 0xc2, + 0x49, 0x7e, 0x2e, 0x16, 0x6f, 0x70, 0x32, 0x02, 0x9c, 0xd4, 0xb4, 0x1a, + 0xd8, 0x0f, 0x5a, 0x9c, 0xe0, 0x3d, 0x75, 0x10, 0x65, 0xee, 0xab, 0xc2, + 0xc9, 0x41, 0xe0, 0xe4, 0x3e, 0x8b, 0x93, 0xc3, 0x16, 0x27, 0x87, 0x51, + 0x26, 0x0f, 0x9c, 0x14, 0x96, 0xc1, 0xc9, 0x08, 0x70, 0x12, 0xb6, 0x5b, + 0x40, 0x3b, 0x87, 0xab, 0x70, 0x32, 0xb2, 0x0c, 0x4e, 0xb8, 0xe6, 0x1a, + 0xee, 0xe1, 0xbe, 0xfc, 0x06, 0x7b, 0xb8, 0x53, 0x9f, 0x7d, 0xe3, 0x3d, + 0xdc, 0x2c, 0x73, 0xb9, 0xea, 0xcc, 0xfb, 0xb3, 0x76, 0x4f, 0x9a, 0xd9, + 0xfb, 0x37, 0x7f, 0x0f, 0x5e, 0x3b, 0xf8, 0xbc, 0x90, 0xf7, 0xc4, 0xec, + 0x21, 0x75, 0xb7, 0x4d, 0x81, 0xd7, 0x8e, 0xca, 0x81, 0xe3, 0xb5, 0x87, + 0x73, 0x36, 0xcd, 0xdf, 0xd6, 0x9e, 0x57, 0x8a, 0x79, 0xe1, 0xde, 0x83, + 0x17, 0xcd, 0x5d, 0x50, 0x31, 0x9e, 0xc7, 0xa8, 0x5e, 0x7b, 0x7e, 0xd1, + 0xde, 0x55, 0xe4, 0xdd, 0x9b, 0xf5, 0xa7, 0x13, 0xdc, 0x57, 0x55, 0xd0, + 0xf0, 0x72, 0x2d, 0xad, 0x47, 0xef, 0xa5, 0xca, 0x16, 0x69, 0x67, 0x27, + 0xb8, 0x27, 0x0d, 0xf6, 0x31, 0xf7, 0xed, 0x9a, 0x7d, 0xba, 0xbd, 0x0b, + 0xf6, 0xe9, 0x56, 0x9f, 0xef, 0x26, 0xdf, 0xcd, 0xd3, 0xcd, 0xc1, 0xb9, + 0xbb, 0x57, 0x8f, 0x3b, 0xcf, 0xe8, 0xf8, 0x70, 0x3d, 0xe6, 0x27, 0x08, + 0x4e, 0xa7, 0x4c, 0x5c, 0x76, 0x46, 0xc7, 0x65, 0x05, 0x1e, 0xf8, 0xb0, + 0x8d, 0xcd, 0x76, 0xf4, 0x5c, 0x9e, 0x8b, 0xcb, 0x2e, 0xd8, 0xa3, 0xa3, + 0xef, 0xff, 0xc8, 0x8e, 0x5e, 0xd2, 0x7b, 0x71, 0xfa, 0x52, 0x8e, 0x14, + 0x20, 0x23, 0xf6, 0x8c, 0xbf, 0x2a, 0xc3, 0x0f, 0xf2, 0x9b, 0x3a, 0x2d, + 0x02, 0xbd, 0x45, 0xb9, 0x9d, 0x97, 0x6c, 0x0f, 0xd3, 0x4c, 0x9d, 0x3e, + 0xed, 0x23, 0x1f, 0x77, 0x7a, 0xe7, 0xfa, 0x27, 0x7e, 0xc3, 0x35, 0x70, + 0xfe, 0xa6, 0x9d, 0x93, 0x71, 0xb2, 0x15, 0xe6, 0x87, 0x6b, 0xe1, 0x77, + 0xdb, 0xfb, 0x08, 0x99, 0x5f, 0x7d, 0xff, 0xb5, 0xe1, 0xd3, 0xac, 0xfe, + 0x3b, 0x22, 0x23, 0x4e, 0x1f, 0xea, 0x4c, 0x7b, 0x0d, 0x03, 0x2a, 0x7d, + 0xd3, 0x00, 0xcf, 0xca, 0x4d, 0x2c, 0xf9, 0xfb, 0x01, 0xf3, 0xba, 0xb0, + 0xa0, 0xe7, 0x94, 0xfb, 0xb0, 0xa6, 0x41, 0x8b, 0x9a, 0xb6, 0x34, 0xfd, + 0x1f, 0x98, 0xd3, 0x91, 0xd4, 0xad, 0xd4, 0x93, 0xa1, 0x8e, 0x4c, 0xc6, + 0xfb, 0x78, 0x7f, 0x84, 0xa6, 0x71, 0x7b, 0x97, 0xc4, 0xd4, 0x39, 0xad, + 0xdf, 0x47, 0x52, 0xbc, 0x5f, 0x66, 0x99, 0xb2, 0xa3, 0x55, 0x65, 0xf5, + 0xb8, 0x3d, 0xf9, 0x43, 0xcc, 0xcd, 0x17, 0x61, 0x6f, 0xf6, 0x8e, 0xbd, + 0x0a, 0x9f, 0x31, 0x2e, 0x5f, 0x2a, 0xbd, 0x04, 0x7a, 0xcd, 0xaf, 0xb5, + 0x77, 0xe1, 0x65, 0x01, 0x37, 0xcf, 0x38, 0xeb, 0xfd, 0xc3, 0x91, 0x3f, + 0x02, 0x5d, 0xfc, 0xc1, 0x4b, 0xec, 0x03, 0xb0, 0x44, 0x60, 0xcf, 0xc3, + 0x36, 0x18, 0x7f, 0x49, 0xef, 0x95, 0xbb, 0xbe, 0xfc, 0x92, 0x8e, 0x53, + 0xf4, 0x97, 0x5b, 0x65, 0x7b, 0xb9, 0x41, 0x76, 0x40, 0x2f, 0xec, 0x28, + 0xfb, 0x78, 0xa2, 0x72, 0x63, 0xd9, 0xcc, 0xd3, 0x47, 0xca, 0x9c, 0xef, + 0x6d, 0x32, 0x71, 0xbc, 0x9a, 0x66, 0xa7, 0xed, 0xde, 0x31, 0xd2, 0x0f, + 0x9e, 0x52, 0x32, 0x3f, 0xad, 0xc7, 0xce, 0x5d, 0xac, 0xc9, 0xc3, 0xb3, + 0xc2, 0xbd, 0xf8, 0xfc, 0x1b, 0x74, 0xdf, 0x68, 0xe5, 0x19, 0x77, 0xde, + 0x8f, 0xd8, 0x5f, 0x09, 0xf7, 0x86, 0xbf, 0xfe, 0x19, 0x10, 0xfd, 0x77, + 0x5d, 0xf4, 0xde, 0x70, 0x4d, 0x7b, 0xd2, 0x76, 0x26, 0xa6, 0x75, 0x84, + 0xa1, 0xf1, 0xf9, 0xbf, 0xe7, 0x22, 0xf2, 0x7f, 0x01, 0x95, 0xf6, 0x2d, + 0x58, 0xd0, 0x73, 0x00, 0x00, 0x00 }; +static u32 bnx2_CP_b09FwData[(0x50/4) + 1] = { + 0x00010030, 0x00000030, 0x00000000, 0x00000001, 0x00010fd0, 0x00000fd0, + 0x00001430, 0x0000007f, 0x00030400, 0x00001000, 0x00000030, 0x00000020, + 0x00050200, 0x00001000, 0x00000030, 0x00000010, 0x00010400, 0x00000400, + 0x00001030, 0x00000020, 0x00000000 }; +static u32 bnx2_CP_b09FwRodata[(0x118/4) + 1] = { + 0x080005d8, 0x080007f8, 0x0800073c, 0x08000764, 0x0800078c, 0x080007b4, + 0x08000610, 0x080005fc, 0x08000820, 0x08000820, 0x0800062c, 0x08000648, + 0x08000648, 0x08000820, 0x08000660, 0x08000674, 0x08000820, 0x08000688, + 0x08000820, 0x08000820, 0x0800069c, 0x08000820, 0x08000820, 0x08000820, + 0x08000820, 0x08000820, 0x08000820, 0x08000820, 0x08000820, 0x08000820, + 0x08000820, 0x080006b0, 0x08000820, 0x080006c4, 0x080006d8, 0x080006ec, + 0x08000820, 0x08000700, 0x08000714, 0x08000728, 0x08003740, 0x08003758, + 0x08003768, 0x08003778, 0x08003790, 0x080037a8, 0x080037b8, 0x080037c8, + 0x080037e8, 0x080037f8, 0x08003808, 0x08003898, 0x080037d8, 0x08003818, + 0x08003828, 0x08003840, 0x08003860, 0x08003898, 0x08003878, 0x08003878, + 0x080055f0, 0x080055f0, 0x080055f0, 0x080055f0, 0x080055f0, 0x08005618, + 0x08005618, 0x08005640, 0x08005690, 0x08005660, 0x00000000 }; +static u32 bnx2_CP_b09FwBss[(0x870/4) + 1] = { 0x0 }; +static u32 bnx2_CP_b09FwSbss[(0xe9/4) + 1] = { 0x0 }; static struct fw_info bnx2_cp_fw_09 = { - .ver_major = 0x3, - .ver_minor = 0x4, - .ver_fix = 0x3, + .ver_major = 0x1, + .ver_minor = 0x0, + .ver_fix = 0x0, .start_addr = 0x0800006c, .text_addr = 0x08000000, - .text_len = 0x6ee8, + .text_len = 0x73cc, .text_index = 0x0, .gz_text = bnx2_CP_b09FwText, .gz_text_len = sizeof(bnx2_CP_b09FwText), - .data_addr = 0x08007020, - .data_len = 0x0, + .data_addr = 0x08007500, + .data_len = 0x50, .data_index = 0x0, .data = bnx2_CP_b09FwData, - .sbss_addr = 0x08007024, - .sbss_len = 0xa1, + .sbss_addr = 0x08007554, + .sbss_len = 0xe9, .sbss_index = 0x0, .sbss = bnx2_CP_b09FwSbss, - .bss_addr = 0x080070d0, - .bss_len = 0x3b0, + .bss_addr = 0x08007640, + .bss_len = 0x870, .bss_index = 0x0, .bss = bnx2_CP_b09FwBss, - .rodata_addr = 0x08006ee8, + .rodata_addr = 0x080073d0, .rodata_len = 0x118, .rodata_index = 0x0, .rodata = bnx2_CP_b09FwRodata, }; static u8 bnx2_RXP_b09FwText[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xec, 0x5c, - 0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x43, 0x6a, 0x49, 0xf1, 0x67, - 0xb8, 0x5c, 0xb1, 0x2b, 0x99, 0x96, 0x77, 0xc9, 0x91, 0xc8, 0x58, 0x8a, - 0x31, 0xa2, 0x09, 0x5b, 0x48, 0x17, 0xf6, 0x76, 0x76, 0x25, 0xb1, 0xb1, - 0x03, 0x53, 0xb6, 0x62, 0x07, 0x45, 0x6a, 0xb0, 0x4b, 0xb9, 0x0e, 0x8c, - 0x06, 0x90, 0xff, 0x52, 0xbf, 0xb0, 0xde, 0x2c, 0xa9, 0x58, 0x4d, 0x17, - 0x9c, 0xb5, 0x4d, 0x9b, 0x0e, 0x60, 0xb7, 0x0b, 0x92, 0x12, 0xf5, 0xb0, - 0xd0, 0xb2, 0xa9, 0xdb, 0xea, 0xc1, 0x8e, 0x09, 0x56, 0xb1, 0x53, 0xa0, - 0x2d, 0x5c, 0x27, 0x69, 0xfc, 0x10, 0x14, 0xaa, 0xec, 0xc4, 0x42, 0xd1, - 0xa2, 0x02, 0x12, 0xd8, 0x29, 0x22, 0x7b, 0xfa, 0x7d, 0x77, 0x66, 0xc8, - 0x25, 0x2d, 0xdb, 0x41, 0x1f, 0xfa, 0xd2, 0xbd, 0xc0, 0x62, 0xee, 0xbd, - 0x73, 0xee, 0xb9, 0xe7, 0x9e, 0xff, 0x73, 0x87, 0xd2, 0x1f, 0x74, 0x48, - 0xbb, 0x84, 0xad, 0x13, 0xbf, 0xd4, 0x89, 0x27, 0x1e, 0xb9, 0x69, 0xf4, - 0xa6, 0x9b, 0xd1, 0xbd, 0xd9, 0x30, 0x4c, 0x23, 0x9a, 0x6f, 0xb6, 0x66, - 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, - 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, - 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, - 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, - 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, - 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0xfb, 0xff, 0xde, - 0x0c, 0x11, 0x8b, 0xcf, 0xce, 0xf0, 0x27, 0x31, 0x3d, 0x23, 0x0f, 0xb9, - 0xb6, 0xc4, 0x8c, 0xcc, 0xd5, 0xa9, 0x49, 0x5b, 0x24, 0x5b, 0xdb, 0x97, - 0xca, 0xc9, 0x87, 0x7e, 0x31, 0x61, 0x0a, 0xe7, 0xaf, 0xcf, 0x5c, 0xfd, - 0x8b, 0x57, 0x6f, 0x4d, 0x5f, 0xa9, 0x1a, 0x12, 0xb3, 0x32, 0x33, 0x07, - 0xac, 0xbd, 0x12, 0xeb, 0xc7, 0x9a, 0x17, 0x87, 0xfe, 0xa9, 0x4b, 0xba, - 0x22, 0x5c, 0x22, 0x0b, 0xe5, 0xb4, 0x73, 0x18, 0xcf, 0x33, 0xb5, 0x7d, - 0xce, 0x9a, 0x98, 0xb2, 0x6a, 0x05, 0x3b, 0x96, 0xca, 0x1a, 0xf1, 0x48, - 0xa9, 0x16, 0x93, 0x8b, 0xea, 0xdf, 0x79, 0x60, 0x4f, 0x9b, 0xfd, 0xf3, - 0x9a, 0x5b, 0xf7, 0xfd, 0xd3, 0x8e, 0xef, 0xbf, 0x8e, 0xdf, 0x7b, 0x0e, - 0xc6, 0xde, 0x47, 0x7e, 0xd6, 0x34, 0x44, 0xb7, 0xff, 0x4c, 0x73, 0x17, - 0x5b, 0xa5, 0x34, 0x2f, 0x32, 0xed, 0xc5, 0xe4, 0x94, 0x57, 0xd4, 0xf2, - 0xf5, 0xb2, 0x76, 0x68, 0x79, 0x56, 0x3b, 0xbc, 0x7c, 0x4a, 0x3b, 0xb2, - 0x5c, 0xd1, 0xdc, 0x65, 0x29, 0xea, 0x07, 0x3a, 0x24, 0x6b, 0x9d, 0xd5, - 0x72, 0xf5, 0x3e, 0xcd, 0x9d, 0xbf, 0xea, 0xbb, 0x4e, 0xda, 0xfa, 0x3d, - 0x31, 0xb3, 0xdc, 0xcf, 0x2d, 0xfb, 0x18, 0x9b, 0x92, 0x4d, 0xf8, 0xbe, - 0x9e, 0xf1, 0x9f, 0x74, 0x47, 0x6d, 0x4b, 0xd7, 0x62, 0x52, 0xaa, 0xb7, - 0x03, 0x6f, 0x87, 0x96, 0x9b, 0x37, 0xb5, 0xbc, 0xe7, 0xbf, 0xe6, 0x3a, - 0xd2, 0x6f, 0x88, 0xef, 0xcf, 0x38, 0x7b, 0x92, 0xc7, 0xe5, 0x0c, 0xf0, - 0xd6, 0x80, 0x4f, 0x2c, 0x3d, 0x43, 0xfa, 0x22, 0x9a, 0x8b, 0x5a, 0x6e, - 0x28, 0xa2, 0x4f, 0x52, 0xa4, 0xbf, 0xb0, 0xa4, 0x83, 0xce, 0xed, 0x52, - 0xa8, 0x5a, 0x32, 0xb1, 0xb4, 0x15, 0xfe, 0xa2, 0xff, 0xea, 0x50, 0x42, - 0xfe, 0xb2, 0x9e, 0x3e, 0x55, 0x04, 0x2f, 0x66, 0xbc, 0x94, 0x80, 0xcf, - 0x59, 0x77, 0xb4, 0x5f, 0x5e, 0xab, 0x27, 0xe5, 0xbb, 0x75, 0x3b, 0x59, - 0x92, 0x6d, 0x52, 0x48, 0x58, 0xb2, 0x82, 0x35, 0xd3, 0xa0, 0x43, 0xb7, - 0x6d, 0xab, 0x04, 0xd8, 0x52, 0xfd, 0x27, 0xfc, 0xb7, 0x32, 0xd6, 0xe4, - 0xa8, 0x5a, 0x53, 0x04, 0xdd, 0x21, 0x2c, 0xcf, 0xa1, 0x60, 0xd5, 0x59, - 0x02, 0x58, 0x29, 0x4e, 0x8e, 0x62, 0xae, 0xfe, 0x85, 0x50, 0x16, 0xad, - 0x38, 0x2f, 0x9f, 0xbb, 0x71, 0xbe, 0xdd, 0xe0, 0x89, 0x24, 0x74, 0xd9, - 0x93, 0x2c, 0x60, 0x66, 0xba, 0xde, 0x81, 0x31, 0x69, 0xf1, 0xfd, 0x23, - 0x8e, 0x58, 0x25, 0xa7, 0x1b, 0xbc, 0x4b, 0x49, 0xc9, 0xe9, 0xc2, 0x9a, - 0x16, 0xb1, 0x6c, 0x9e, 0x81, 0x78, 0xdb, 0x30, 0xef, 0x77, 0x1a, 0x19, - 0xdf, 0x9f, 0x1c, 0x95, 0xae, 0x60, 0x6e, 0x1f, 0x70, 0x98, 0x32, 0x31, - 0xae, 0x01, 0xee, 0x03, 0xd2, 0x17, 0x8b, 0x67, 0xd8, 0xe7, 0x73, 0x54, - 0xdc, 0xd9, 0x54, 0xb8, 0x6f, 0x87, 0x94, 0xbc, 0xeb, 0xc3, 0x3e, 0x78, - 0xed, 0xe1, 0xcc, 0xce, 0x4e, 0x8c, 0xb5, 0x1b, 0x80, 0xc7, 0x29, 0x09, - 0xf7, 0xd8, 0x21, 0x6b, 0x09, 0xd1, 0x2f, 0x39, 0xbd, 0x21, 0x5c, 0x17, - 0x68, 0x8d, 0x64, 0xde, 0x2e, 0x33, 0xf3, 0xad, 0x72, 0x72, 0x9e, 0xbc, - 0x2d, 0x43, 0x16, 0x78, 0xde, 0x52, 0xd4, 0xb2, 0xf5, 0x53, 0xe8, 0x9b, - 0x32, 0x69, 0xfb, 0xaf, 0xcd, 0x38, 0xb3, 0x5a, 0x6e, 0xf9, 0x8c, 0x96, - 0x87, 0x0e, 0x1c, 0x5a, 0x3e, 0xaf, 0x1d, 0xae, 0xaf, 0x76, 0x4a, 0x7b, - 0x1a, 0xda, 0x66, 0xca, 0x49, 0x4f, 0x13, 0xd2, 0xbb, 0x00, 0x7e, 0x65, - 0x2d, 0x70, 0xde, 0xee, 0xd2, 0x0e, 0x03, 0x57, 0x8b, 0xfd, 0xad, 0x0e, - 0xe9, 0x32, 0x64, 0x9b, 0x1d, 0xc1, 0xc6, 0xe4, 0x5b, 0xa0, 0x6d, 0xcd, - 0x49, 0x00, 0x4e, 0xba, 0x83, 0x35, 0x3d, 0x21, 0x3d, 0xd4, 0x25, 0xea, - 0x91, 0x9e, 0xcd, 0xcf, 0xfd, 0x69, 0x6f, 0x69, 0xff, 0x76, 0xc2, 0xc0, - 0x3e, 0x52, 0x0f, 0x4d, 0xda, 0x6e, 0x8f, 0x29, 0x45, 0x4b, 0x97, 0xb4, - 0x95, 0x93, 0x1b, 0x64, 0xc6, 0x11, 0xc9, 0x41, 0xbf, 0x75, 0xdb, 0x04, - 0x8f, 0x6c, 0xf0, 0x68, 0xcf, 0xa9, 0x41, 0xfd, 0x0e, 0x49, 0xf5, 0x15, - 0x35, 0x33, 0xe4, 0xe7, 0x82, 0xdc, 0xa6, 0xd6, 0xeb, 0x19, 0x07, 0x3a, - 0xd9, 0xce, 0x3e, 0xf6, 0x8d, 0xa9, 0x7d, 0x8d, 0x8c, 0x9d, 0x5c, 0x14, - 0xd1, 0xf4, 0xcc, 0x3e, 0xe0, 0xa3, 0xae, 0x12, 0xee, 0x29, 0xd0, 0x48, - 0xda, 0xd9, 0xb7, 0xb1, 0x26, 0x26, 0xae, 0xd3, 0xd9, 0x40, 0x27, 0xe8, - 0x49, 0x90, 0xe7, 0xe4, 0xa1, 0x3a, 0xa7, 0xb6, 0x71, 0xce, 0x5f, 0xfb, - 0xdb, 0x46, 0x4c, 0x79, 0x5d, 0x9d, 0x97, 0x76, 0x45, 0x38, 0x75, 0x46, - 0x21, 0x7f, 0xa6, 0x3d, 0xd1, 0x0a, 0x8e, 0xb5, 0x8e, 0x0b, 0x7a, 0xa1, - 0x1b, 0x99, 0x0e, 0xc9, 0x29, 0xfa, 0x0e, 0x62, 0x2f, 0xda, 0x1b, 0xec, - 0xc6, 0xe6, 0x59, 0x38, 0x97, 0x81, 0xed, 0xa6, 0x95, 0xfe, 0x14, 0x2a, - 0xf4, 0x07, 0xa4, 0x6d, 0x35, 0xad, 0x4b, 0x80, 0xaf, 0xf4, 0x6c, 0x37, - 0x68, 0xe3, 0x18, 0xb6, 0x67, 0xe3, 0xfd, 0x7e, 0xd8, 0xfa, 0xc1, 0x41, - 0xf0, 0x87, 0x70, 0x76, 0x0a, 0xf2, 0xce, 0xba, 0xd8, 0xd3, 0x75, 0x6e, - 0x56, 0x3c, 0xe8, 0xc1, 0x79, 0x06, 0x67, 0xc9, 0xaf, 0x76, 0xe8, 0xb3, - 0x26, 0x05, 0x27, 0x9d, 0xa2, 0xfc, 0x03, 0xda, 0x75, 0xd9, 0x76, 0x4b, - 0x23, 0xed, 0x91, 0xac, 0xa8, 0x8f, 0xa6, 0xc4, 0x47, 0x08, 0x4b, 0x38, - 0xc2, 0xa7, 0x0f, 0x8a, 0xfe, 0x6b, 0xdf, 0xda, 0x74, 0x56, 0x5b, 0x06, - 0x66, 0x41, 0x43, 0xc0, 0x5b, 0xf0, 0xe4, 0xb3, 0x60, 0xc9, 0xd7, 0xad, - 0xfc, 0x23, 0x6c, 0x23, 0x1c, 0x74, 0xa2, 0x8f, 0x34, 0xac, 0x74, 0x04, - 0xf6, 0x15, 0xd1, 0x14, 0xc9, 0x46, 0x0b, 0x71, 0x7c, 0xda, 0x39, 0x08, - 0x0f, 0xbb, 0xf7, 0x60, 0xf7, 0x1e, 0x7c, 0x82, 0x07, 0x9b, 0xf7, 0xe8, - 0x27, 0x52, 0xf2, 0xea, 0x10, 0xfc, 0xda, 0x86, 0x5f, 0x41, 0x1b, 0x43, - 0x5f, 0x17, 0x03, 0x7e, 0x65, 0xba, 0xaa, 0xc3, 0x76, 0x61, 0x43, 0x4b, - 0x9c, 0xb3, 0xf0, 0xcc, 0xe3, 0x69, 0xc3, 0x8f, 0x52, 0xaf, 0x22, 0xff, - 0x49, 0x3f, 0x93, 0x84, 0x4f, 0xa1, 0xaf, 0xa1, 0x2f, 0x21, 0xac, 0xef, - 0xe7, 0x1d, 0xae, 0xf5, 0x65, 0xdc, 0xa1, 0x1d, 0x75, 0x88, 0x1e, 0x2f, - 0x6a, 0x47, 0x87, 0x60, 0x63, 0x37, 0xb6, 0x80, 0x56, 0xda, 0xda, 0x75, - 0x74, 0x15, 0x68, 0xbf, 0xe8, 0x0c, 0xfe, 0x5d, 0xde, 0x36, 0xc0, 0x28, - 0xa1, 0x76, 0x05, 0xe3, 0xb6, 0xd0, 0x9f, 0xf0, 0x7d, 0x3a, 0x95, 0x95, - 0xdd, 0xe1, 0x98, 0xfd, 0x75, 0x7a, 0x1d, 0xfd, 0x96, 0x98, 0x0c, 0x9c, - 0x09, 0xfc, 0xe0, 0xc0, 0x82, 0x25, 0xf6, 0x99, 0x80, 0xc6, 0x81, 0x73, - 0x91, 0x3f, 0x6c, 0x01, 0x3e, 0xd0, 0xe7, 0x6d, 0xc4, 0x09, 0x91, 0xf7, - 0x34, 0x98, 0x0a, 0xe6, 0xb6, 0xf2, 0x82, 0x3e, 0x98, 0xf6, 0x66, 0x35, - 0xda, 0xdb, 0x01, 0xd8, 0x9b, 0xd3, 0x2a, 0x69, 0xe7, 0xef, 0x60, 0x6f, - 0x4f, 0x39, 0x1a, 0x78, 0x23, 0x72, 0xa1, 0xdc, 0x01, 0x5b, 0x37, 0x93, - 0xef, 0xc8, 0x9e, 0xd4, 0xb4, 0x68, 0x72, 0x9a, 0x73, 0x35, 0xcc, 0x29, - 0xff, 0x1b, 0xd8, 0xf7, 0x45, 0xe3, 0x69, 0xd0, 0xe5, 0xfb, 0xd3, 0xc0, - 0x59, 0xd8, 0x6f, 0x84, 0xb6, 0x15, 0xcd, 0xa7, 0x10, 0xf3, 0xdc, 0xcf, - 0x19, 0x52, 0x1c, 0x6e, 0x91, 0xf4, 0xf0, 0x02, 0x70, 0x4f, 0x3a, 0x81, - 0x1d, 0x53, 0xd7, 0x17, 0x81, 0x7f, 0xc6, 0x1b, 0x82, 0x1e, 0xd3, 0x0e, - 0x40, 0x17, 0xf0, 0x2f, 0x02, 0xff, 0x4c, 0xbd, 0x45, 0xbe, 0x69, 0x46, - 0xb1, 0x34, 0x3a, 0x4f, 0x1b, 0xc0, 0xa2, 0x7d, 0x4f, 0xc8, 0x17, 0xbd, - 0xb8, 0xe6, 0x3e, 0x4b, 0x3f, 0x5b, 0x1a, 0x86, 0x9d, 0x68, 0x25, 0x87, - 0x7b, 0x1b, 0xb2, 0xb8, 0x0e, 0x23, 0xd9, 0x52, 0x60, 0x83, 0x59, 0x77, - 0xa8, 0x98, 0x34, 0x94, 0x2f, 0x11, 0x39, 0x5c, 0x36, 0x01, 0xc3, 0x31, - 0xe7, 0x83, 0xb9, 0xb1, 0x72, 0x1f, 0x7c, 0x23, 0xc7, 0x57, 0xfd, 0x49, - 0x27, 0x98, 0xfb, 0xdd, 0x72, 0x81, 0x32, 0x62, 0xdc, 0x4e, 0x95, 0x9c, - 0x7f, 0xf7, 0xa1, 0xbf, 0x9b, 0xd6, 0x5c, 0x1b, 0x4f, 0x7a, 0x2c, 0x8c, - 0xf5, 0xda, 0x11, 0x5b, 0xef, 0x6b, 0x0d, 0x7d, 0xd8, 0x11, 0x4c, 0x1e, - 0x2a, 0x97, 0x7a, 0x5b, 0xe5, 0xaa, 0xc1, 0xd8, 0x79, 0x09, 0x46, 0xed, - 0x96, 0xf7, 0x82, 0x1f, 0xa5, 0x9e, 0x86, 0xb9, 0x58, 0xbe, 0xec, 0xcb, - 0x9a, 0x13, 0xac, 0xc1, 0xb8, 0x23, 0x57, 0xd6, 0xfb, 0x62, 0xb2, 0x3e, - 0xb6, 0xb8, 0x66, 0x49, 0xf6, 0x0e, 0x2f, 0x8a, 0x5a, 0xdb, 0x1b, 0xdb, - 0x58, 0x9b, 0xc8, 0x97, 0x4b, 0x3d, 0x0d, 0xe3, 0x64, 0x0e, 0xb8, 0xf4, - 0x03, 0xeb, 0x6b, 0xfb, 0x37, 0xd6, 0xee, 0x90, 0x54, 0x0f, 0xd7, 0xeb, - 0x7d, 0x6d, 0x1b, 0xb8, 0x53, 0x21, 0x3d, 0xbd, 0x6d, 0x1b, 0x38, 0x6c, - 0xe2, 0x6c, 0x18, 0x0f, 0x13, 0xe7, 0xc0, 0x06, 0xce, 0xfd, 0x9b, 0xe9, - 0x39, 0x21, 0xf0, 0x41, 0xb1, 0xd6, 0x8c, 0x1c, 0xb8, 0x50, 0x1e, 0x1c, - 0xff, 0xa2, 0x20, 0xe6, 0xed, 0xdf, 0x16, 0xfa, 0x64, 0xf3, 0x80, 0x0b, - 0x5e, 0x99, 0x42, 0x1f, 0xa7, 0x49, 0x09, 0x72, 0x7e, 0xa8, 0x26, 0x07, - 0xd6, 0x6a, 0x12, 0xea, 0x12, 0x75, 0xe2, 0x32, 0x6c, 0x4c, 0x8a, 0xbb, - 0x32, 0x1d, 0x13, 0x66, 0xc6, 0x82, 0xad, 0xc9, 0x78, 0x09, 0x3e, 0xd9, - 0xc8, 0xec, 0x79, 0x3b, 0x67, 0x3c, 0xe9, 0x1b, 0x88, 0xdb, 0x39, 0xe9, - 0x38, 0xe8, 0x8e, 0x62, 0xbe, 0x46, 0xdb, 0x82, 0x5f, 0xa9, 0x13, 0xf7, - 0x7c, 0xb7, 0x74, 0x21, 0x2e, 0xd6, 0x5e, 0xda, 0x11, 0xd8, 0x8e, 0x98, - 0x26, 0x7c, 0xed, 0xcc, 0x28, 0xe3, 0x78, 0x6b, 0x0c, 0xf0, 0x13, 0x46, - 0x66, 0x6c, 0xe7, 0xf1, 0xda, 0x9d, 0x3b, 0x0b, 0xb5, 0xe2, 0xce, 0x42, - 0xd9, 0xa2, 0x9d, 0xe8, 0xee, 0x28, 0xfa, 0x2a, 0x57, 0x4a, 0xc2, 0x26, - 0x2e, 0xab, 0x3c, 0xe2, 0xb5, 0x7a, 0x1d, 0xf6, 0x47, 0xfb, 0x16, 0x19, - 0xf7, 0xb0, 0xc7, 0xc8, 0x87, 0x90, 0x3b, 0x68, 0x83, 0x4f, 0xcb, 0xe2, - 0xd4, 0xfa, 0xc8, 0xbf, 0x85, 0xf6, 0xc9, 0xfe, 0xfb, 0x7e, 0xe0, 0xef, - 0xef, 0xe8, 0x0e, 0xe6, 0xde, 0x0a, 0x6d, 0x3a, 0xc2, 0x45, 0x3c, 0xc3, - 0xda, 0x38, 0x72, 0x92, 0xf1, 0xba, 0xa9, 0xd1, 0x3f, 0xe7, 0x3c, 0xe6, - 0x12, 0xcc, 0x23, 0xa6, 0x43, 0x3f, 0x27, 0xd9, 0x1c, 0xfc, 0x88, 0x8e, - 0xdc, 0xa2, 0x00, 0xbb, 0x31, 0x33, 0x57, 0x64, 0x46, 0xf9, 0x48, 0x89, - 0xb5, 0x64, 0x9e, 0x00, 0xcc, 0x7f, 0xc0, 0xe6, 0xda, 0xba, 0x43, 0x3d, - 0x0c, 0x7d, 0xbc, 0xf2, 0xbb, 0x80, 0xbd, 0xbc, 0x05, 0xf6, 0xdd, 0x46, - 0x58, 0xbc, 0xbf, 0xb8, 0xe5, 0xfd, 0x4f, 0x69, 0xbf, 0x78, 0xb7, 0x0a, - 0x7f, 0xda, 0x1a, 0xda, 0xfe, 0x05, 0x29, 0xc0, 0xb7, 0x9a, 0x36, 0x73, - 0xc7, 0xdb, 0xb0, 0x16, 0xe3, 0x1a, 0x68, 0x84, 0xbf, 0x40, 0xcc, 0x04, - 0xbf, 0x11, 0x13, 0x12, 0x37, 0x30, 0x3f, 0xa2, 0x9f, 0x00, 0x2c, 0xfd, - 0x2f, 0x61, 0x5f, 0xe9, 0x20, 0xcf, 0x0b, 0x35, 0xae, 0xa1, 0xaf, 0x12, - 0xdf, 0x1d, 0x6d, 0x83, 0x46, 0xf9, 0xaf, 0x19, 0x76, 0x04, 0x1b, 0xe1, - 0xdd, 0x0a, 0xcb, 0x7c, 0x85, 0xb8, 0xbb, 0xc3, 0x3c, 0x60, 0x4c, 0xb2, - 0xf5, 0x2c, 0x7e, 0x45, 0x99, 0x7c, 0x16, 0xb9, 0x98, 0xdd, 0x42, 0x5e, - 0x90, 0x35, 0x56, 0xc0, 0xa3, 0x68, 0xdd, 0x13, 0xbd, 0x9b, 0xc7, 0xf7, - 0xc5, 0x37, 0x7c, 0x25, 0x2d, 0x4d, 0xb2, 0x88, 0x15, 0xe0, 0x71, 0x6a, - 0x42, 0xcf, 0x24, 0x24, 0x57, 0x0b, 0xf8, 0x8b, 0x78, 0x0b, 0xff, 0xc8, - 0x2e, 0x64, 0xb2, 0xee, 0x07, 0x23, 0x99, 0x53, 0xcf, 0xb2, 0x90, 0x4d, - 0x0a, 0xba, 0x34, 0x86, 0xb5, 0x72, 0x02, 0x38, 0x18, 0x87, 0x1d, 0x3d, - 0x13, 0x97, 0x82, 0xc5, 0x7c, 0x41, 0xe5, 0x7a, 0x59, 0xfa, 0x01, 0x3d, - 0xd3, 0x86, 0x39, 0xf6, 0x1f, 0xee, 0x0e, 0x64, 0xdd, 0xc9, 0xf1, 0xb8, - 0x9e, 0xe9, 0xde, 0x32, 0xff, 0x7a, 0x67, 0x40, 0x9b, 0x1a, 0x63, 0xfe, - 0x5f, 0xb6, 0x8c, 0xbf, 0x1e, 0xdf, 0x3c, 0x7e, 0x60, 0x67, 0xa4, 0x0f, - 0x7a, 0xe6, 0x89, 0x90, 0x5e, 0xea, 0xe9, 0x56, 0x5a, 0x7f, 0x13, 0x7d, - 0x79, 0x0e, 0x38, 0x95, 0x8e, 0xff, 0x06, 0xfa, 0xb2, 0x0e, 0xfb, 0x09, - 0xfa, 0xd2, 0x48, 0xc3, 0x7a, 0x5d, 0x51, 0xd1, 0x91, 0x93, 0xba, 0xa3, - 0x7b, 0x90, 0x77, 0xa4, 0x24, 0x5f, 0x07, 0xef, 0xd6, 0xe3, 0xea, 0x3a, - 0x4c, 0x71, 0x03, 0x26, 0x88, 0x3b, 0xf9, 0xba, 0x8f, 0x3c, 0xae, 0x31, - 0x06, 0x0f, 0xa3, 0x5f, 0xc4, 0x59, 0x57, 0x64, 0xd2, 0x5b, 0xcb, 0xea, - 0xf6, 0xa9, 0x20, 0x0f, 0xb5, 0xbf, 0xad, 0xe5, 0x17, 0x99, 0xa3, 0xc6, - 0xd0, 0x57, 0xf5, 0x07, 0x62, 0xdc, 0x33, 0x5a, 0x76, 0x79, 0x0e, 0xf9, - 0xe9, 0x12, 0x7e, 0x67, 0xf1, 0xab, 0xe1, 0x17, 0xd5, 0x01, 0x2f, 0xa0, - 0x8e, 0x50, 0xfe, 0x1e, 0xb1, 0x29, 0xd8, 0xff, 0x67, 0x4b, 0xc8, 0x8f, - 0xe7, 0x12, 0xf2, 0x94, 0xad, 0xf7, 0xea, 0x81, 0x8f, 0xcb, 0x22, 0xb7, - 0xb6, 0x2e, 0xcb, 0x97, 0xc2, 0x1c, 0x4d, 0xe4, 0x9d, 0x0a, 0x64, 0xb9, - 0xff, 0x48, 0xe8, 0x9f, 0xbe, 0xf6, 0xa0, 0xab, 0x7c, 0x79, 0x98, 0x83, - 0xc1, 0xef, 0x64, 0x15, 0xd4, 0x1b, 0xe0, 0x8f, 0x26, 0xef, 0x41, 0x8f, - 0xdf, 0xa9, 0xb4, 0x83, 0x1e, 0x5b, 0x0a, 0xc7, 0x90, 0xbb, 0x68, 0x83, - 0xd6, 0x36, 0xad, 0x1d, 0x79, 0x18, 0xfc, 0x8e, 0x1a, 0x93, 0x67, 0x17, - 0xa7, 0x16, 0xca, 0x3a, 0x60, 0xc1, 0xf3, 0x51, 0xf4, 0xa1, 0x7f, 0x97, - 0x2a, 0x5c, 0xa7, 0xcb, 0xbb, 0x15, 0x43, 0x7e, 0x8e, 0xbc, 0xee, 0x3d, - 0xfb, 0xe2, 0x14, 0x6c, 0xb0, 0x0f, 0xf1, 0x0a, 0xb5, 0xd0, 0x1e, 0xc6, - 0x8c, 0x01, 0x13, 0xcf, 0x3c, 0x7e, 0x87, 0x91, 0xe7, 0x5d, 0x7b, 0xcd, - 0x27, 0xc1, 0x93, 0xb6, 0x18, 0xd6, 0x10, 0xde, 0x04, 0x6d, 0x5d, 0xd0, - 0xc1, 0xb4, 0x35, 0x21, 0xdd, 0x96, 0xca, 0x9d, 0x34, 0xce, 0x07, 0x7e, - 0xf2, 0xe3, 0xf3, 0xe4, 0xb3, 0x01, 0x1d, 0xe2, 0x98, 0xef, 0xe8, 0xcf, - 0x89, 0x2f, 0x7d, 0x30, 0x8b, 0xc3, 0x5c, 0xaa, 0x04, 0xfd, 0x68, 0x4e, - 0xb4, 0x28, 0xa6, 0xd2, 0x4f, 0xe7, 0x61, 0xab, 0x1c, 0x8f, 0x8b, 0x92, - 0xc1, 0x26, 0x79, 0x52, 0x8f, 0x56, 0xa7, 0x66, 0x6c, 0xca, 0xd5, 0x92, - 0xe9, 0x72, 0x24, 0x57, 0xca, 0x08, 0x75, 0x66, 0xe5, 0xdb, 0x90, 0xab, - 0x1e, 0xd6, 0x20, 0xf0, 0x03, 0x73, 0x94, 0x2f, 0xea, 0xc4, 0x0a, 0xf2, - 0xb0, 0x8a, 0xc4, 0x83, 0x1a, 0xea, 0x19, 0xd4, 0x1d, 0x90, 0x5f, 0x79, - 0x0e, 0x38, 0x12, 0x78, 0x2e, 0xe1, 0x99, 0xc4, 0xf3, 0x2c, 0x9e, 0xfd, - 0x78, 0xd6, 0x68, 0x1f, 0x61, 0xde, 0xf3, 0x31, 0x7a, 0x60, 0x27, 0x79, - 0xda, 0xb4, 0x7c, 0xaf, 0x9e, 0x91, 0xbf, 0xad, 0x1f, 0x94, 0xbf, 0xa9, - 0x8f, 0xca, 0x5f, 0xd7, 0x1d, 0x79, 0xb9, 0xbe, 0x5f, 0xfe, 0xaa, 0x3e, - 0xcc, 0x9a, 0x10, 0x39, 0x5c, 0x0a, 0xbe, 0xf9, 0xbc, 0x3c, 0xe8, 0xd5, - 0xe1, 0x73, 0x28, 0xff, 0x8b, 0x53, 0xd9, 0xda, 0x75, 0x52, 0x78, 0xd6, - 0x42, 0x9e, 0x69, 0xb0, 0x2e, 0x93, 0xc7, 0x9c, 0x3b, 0xe2, 0x94, 0xbd, - 0x6e, 0xb3, 0x4e, 0x39, 0x49, 0x38, 0xd4, 0xbb, 0x1a, 0xf2, 0x97, 0x16, - 0x99, 0x48, 0xa4, 0x57, 0x5c, 0x23, 0x19, 0xfa, 0xa3, 0x3b, 0x01, 0x87, - 0x3d, 0xbd, 0x0e, 0x59, 0x7b, 0x1e, 0xb6, 0xe0, 0xa0, 0x56, 0x4e, 0xc4, - 0xe0, 0xfb, 0x54, 0x7e, 0xa2, 0x7c, 0x4b, 0xe0, 0x4b, 0xa3, 0x9a, 0x91, - 0x73, 0xd9, 0x70, 0x8e, 0xf1, 0xd1, 0x02, 0xec, 0x72, 0x18, 0x43, 0xb6, - 0xe2, 0xa4, 0x6f, 0x3c, 0x16, 0xfa, 0xc7, 0x15, 0x39, 0xe1, 0x0d, 0x66, - 0xaf, 0x20, 0xf6, 0x68, 0x2d, 0x51, 0x5e, 0xb4, 0x0b, 0xb4, 0xf9, 0xfe, - 0xdd, 0xac, 0xbf, 0xe3, 0xa6, 0xfc, 0x70, 0x36, 0x6d, 0x3d, 0xa2, 0xcf, - 0x40, 0xce, 0xbe, 0x7f, 0xd4, 0x4e, 0x9f, 0x9a, 0xd0, 0x3b, 0xe5, 0x27, - 0xcf, 0x30, 0x26, 0xaf, 0x4e, 0x7d, 0x1f, 0x7a, 0x50, 0x5d, 0x6a, 0x95, - 0x6a, 0xd5, 0x94, 0x4b, 0x23, 0x83, 0x6a, 0xdf, 0x6a, 0x2d, 0x8e, 0x3c, - 0xaf, 0x4d, 0xa6, 0xfb, 0x94, 0xb2, 0xc3, 0x6f, 0x0f, 0x2b, 0xbf, 0xed, - 0xda, 0x78, 0xd6, 0x92, 0xd6, 0x66, 0x5a, 0x5e, 0x96, 0x82, 0x07, 0x1d, - 0x8b, 0xef, 0x02, 0x4f, 0xd8, 0x1f, 0xb4, 0x0a, 0x3a, 0x62, 0xa0, 0x39, - 0x68, 0x3d, 0xa8, 0xff, 0xd2, 0xff, 0x1d, 0x93, 0x7c, 0x7c, 0x1b, 0xb1, - 0x85, 0xb1, 0x52, 0x53, 0x7a, 0xb7, 0xb0, 0xf4, 0x53, 0x8b, 0xfe, 0x65, - 0xa5, 0xb6, 0x2b, 0x1c, 0xd3, 0xbf, 0x73, 0xdc, 0x2e, 0x2f, 0x57, 0xb7, - 0xcb, 0x62, 0x95, 0xef, 0x5b, 0x65, 0xa1, 0x3a, 0x78, 0xa5, 0x57, 0xef, - 0x93, 0xd5, 0xeb, 0x6e, 0xb4, 0xee, 0xd7, 0xc1, 0x93, 0x63, 0x1f, 0xc9, - 0x07, 0x23, 0xdd, 0xf2, 0xd6, 0x7d, 0xe9, 0x17, 0xfe, 0x44, 0x87, 0x3e, - 0x8e, 0x74, 0xd0, 0xce, 0xd0, 0xe7, 0x7c, 0xfa, 0x4a, 0x56, 0xa7, 0x9e, - 0xfd, 0x00, 0xfa, 0x95, 0xae, 0x04, 0x3a, 0x49, 0xdc, 0xc4, 0x0b, 0xf9, - 0xd8, 0x6f, 0x00, 0x27, 0xde, 0xd5, 0x06, 0x81, 0xeb, 0x0d, 0xc5, 0x8b, - 0xbb, 0x9d, 0xf4, 0x15, 0x84, 0x28, 0xff, 0x92, 0x3d, 0x38, 0x3c, 0xa0, - 0xef, 0x92, 0x6a, 0xf2, 0x46, 0xeb, 0xbb, 0x88, 0x07, 0xd9, 0x44, 0xfa, - 0xd4, 0x45, 0x59, 0x9d, 0xba, 0x60, 0x53, 0x17, 0x69, 0xc3, 0xff, 0x80, - 0x9c, 0xd4, 0x92, 0x4a, 0x8d, 0xbe, 0x8b, 0xb8, 0x58, 0x17, 0xec, 0xb5, - 0x4e, 0x80, 0x06, 0x77, 0x3f, 0xde, 0x61, 0xde, 0xf8, 0x3c, 0xe5, 0xd6, - 0xc2, 0xb5, 0xc3, 0x59, 0xbd, 0x7f, 0x0b, 0x8f, 0x06, 0xad, 0x43, 0x3a, - 0xf7, 0xfb, 0x2f, 0xec, 0xfb, 0x3e, 0x68, 0x1d, 0xc4, 0x5a, 0xc4, 0xd0, - 0x64, 0xe3, 0x1e, 0x3f, 0x52, 0x7b, 0x3c, 0x5b, 0x43, 0x0e, 0xb8, 0xbe, - 0x07, 0xe6, 0x6a, 0x3a, 0xce, 0x69, 0x2a, 0xb9, 0x5c, 0x1a, 0x21, 0x7f, - 0x6f, 0xef, 0x61, 0x2c, 0x37, 0x32, 0x2f, 0x85, 0x79, 0x46, 0x4c, 0x7e, - 0x8c, 0xba, 0x6b, 0x12, 0xfe, 0x7f, 0x61, 0xef, 0x20, 0x68, 0x40, 0x7d, - 0x9a, 0x54, 0xf1, 0x7c, 0xca, 0x05, 0x8e, 0x9c, 0xc2, 0xfd, 0xa6, 0x2c, - 0x01, 0xf7, 0x38, 0xf9, 0x00, 0xdc, 0x33, 0x9c, 0x57, 0x32, 0xc0, 0x7c, - 0x2d, 0x05, 0xbc, 0xbd, 0xa1, 0xff, 0x8b, 0x43, 0x57, 0xf7, 0x59, 0x77, - 0x4b, 0x2c, 0xf4, 0x7f, 0x71, 0x79, 0xeb, 0x79, 0xe8, 0x7d, 0x9c, 0xfa, - 0x93, 0xe8, 0xd9, 0xd0, 0x9f, 0x46, 0xfc, 0xad, 0x92, 0xaf, 0xc4, 0x80, - 0x17, 0x39, 0xf7, 0x28, 0xf1, 0x62, 0x5c, 0xa5, 0x2e, 0x17, 0x43, 0x5d, - 0xee, 0x08, 0x71, 0xaf, 0x41, 0x97, 0xd3, 0xa9, 0x55, 0x9d, 0xf5, 0xd5, - 0x4e, 0x55, 0xf3, 0x1a, 0xb0, 0xaf, 0x42, 0x99, 0xb1, 0x88, 0xb6, 0x75, - 0x71, 0x6a, 0x12, 0x35, 0x6c, 0xa1, 0x7c, 0x50, 0x2f, 0xd4, 0x47, 0xf5, - 0x82, 0x47, 0x7d, 0xdb, 0x6b, 0x2d, 0x28, 0x1e, 0x27, 0x65, 0xa1, 0xfe, - 0x81, 0x5f, 0xda, 0xbb, 0x0d, 0x7d, 0xe8, 0xfe, 0x38, 0xe5, 0x7b, 0x3d, - 0xe9, 0x42, 0x50, 0x27, 0xbf, 0x13, 0x72, 0x66, 0xe8, 0x7b, 0xdd, 0xcc, - 0xd1, 0x96, 0x87, 0x88, 0x1f, 0x74, 0x24, 0x12, 0xb2, 0xe8, 0x71, 0x8f, - 0xd5, 0x29, 0xf2, 0xb2, 0x30, 0x67, 0xc9, 0x09, 0x25, 0x3f, 0x9e, 0x9b, - 0xf7, 0x47, 0x86, 0x4c, 0xc6, 0x07, 0xad, 0x47, 0x25, 0x7d, 0x65, 0xcd, - 0x48, 0xbf, 0x30, 0x81, 0xb8, 0xba, 0x30, 0x6f, 0x88, 0xab, 0xea, 0x30, - 0xca, 0x28, 0x5d, 0x81, 0x35, 0x86, 0x67, 0xbf, 0xa7, 0xe1, 0xec, 0x5d, - 0x72, 0xe1, 0xf9, 0xcf, 0xc3, 0xee, 0x5f, 0x81, 0x2c, 0xcc, 0xd4, 0x71, - 0xe4, 0x19, 0xcf, 0xc9, 0xa0, 0x55, 0x42, 0xfe, 0x0c, 0xbe, 0xa3, 0xbd, - 0xa2, 0x6c, 0x60, 0x41, 0xc7, 0xb8, 0x9f, 0x7c, 0xe2, 0x78, 0xb7, 0x2c, - 0xf4, 0x05, 0x36, 0xce, 0x77, 0x03, 0xc0, 0x11, 0xbc, 0xe3, 0xf8, 0xb7, - 0x64, 0x40, 0xbd, 0xab, 0xaa, 0x75, 0x25, 0xe9, 0x0d, 0xe5, 0xf7, 0x18, - 0xf6, 0x24, 0x8f, 0xa3, 0xf9, 0x4e, 0x09, 0x6c, 0x29, 0xe2, 0xbb, 0x25, - 0x47, 0x6b, 0x09, 0xb9, 0xa7, 0x96, 0x94, 0x2f, 0xd7, 0xfa, 0x25, 0x0f, - 0x39, 0x4e, 0x8e, 0x3e, 0xd9, 0xc3, 0xb3, 0xe5, 0x96, 0xd2, 0x2f, 0x88, - 0x4e, 0x5a, 0xab, 0x72, 0xdc, 0x8b, 0xe8, 0xe9, 0x08, 0xe9, 0x33, 0xc3, - 0x71, 0x2c, 0xa4, 0xa1, 0x11, 0x5f, 0x07, 0x70, 0x65, 0x81, 0xe7, 0xa5, - 0x10, 0x0f, 0xfd, 0x08, 0x68, 0x3d, 0x96, 0x94, 0x25, 0x8f, 0x74, 0x6c, - 0x97, 0x52, 0x82, 0xfd, 0x57, 0xa0, 0x6f, 0xc4, 0xb3, 0x8d, 0xf9, 0xcd, - 0x26, 0x1e, 0x3f, 0x5c, 0x2b, 0x82, 0xc7, 0xe4, 0x2f, 0xe1, 0xe0, 0xaf, - 0xbf, 0x40, 0xf9, 0xed, 0x43, 0x8e, 0x6f, 0x07, 0xba, 0x69, 0x6d, 0xec, - 0x99, 0x9f, 0xeb, 0x82, 0xac, 0xb8, 0x6f, 0xbb, 0x1c, 0x83, 0xdd, 0xe7, - 0xaa, 0xdc, 0xff, 0x18, 0xf4, 0xe8, 0x2d, 0xb5, 0x7f, 0x7e, 0xa9, 0x2f, - 0x5c, 0xcf, 0xb5, 0x5d, 0x5b, 0xd6, 0xb6, 0xca, 0xa1, 0x8a, 0x75, 0x8d, - 0xf5, 0xbf, 0x8f, 0xf5, 0xba, 0x9c, 0x1e, 0xe5, 0x7a, 0xe2, 0x01, 0x5c, - 0x35, 0xf1, 0x29, 0x78, 0xe2, 0xaa, 0xde, 0xcf, 0x55, 0x5b, 0x25, 0x57, - 0x89, 0x70, 0x11, 0xcf, 0x47, 0xa8, 0x87, 0xbf, 0xaa, 0x70, 0x4d, 0x2a, - 0x5c, 0x78, 0x5f, 0xa5, 0xcf, 0xb9, 0x15, 0xeb, 0x3b, 0xe8, 0xff, 0xa5, - 0x14, 0xef, 0x94, 0x92, 0xaa, 0xe9, 0xdb, 0x95, 0xaf, 0x29, 0xc5, 0xdb, - 0xf0, 0xbe, 0x13, 0x36, 0xbf, 0x0f, 0xb9, 0x45, 0x17, 0xeb, 0xdc, 0x2d, - 0x73, 0x5b, 0xe9, 0x8f, 0x6d, 0xa1, 0x3f, 0x06, 0xb8, 0x5e, 0xec, 0x19, - 0xc0, 0xe5, 0x01, 0x37, 0x3d, 0x07, 0x3e, 0x3b, 0xf4, 0x2b, 0x8c, 0x93, - 0xd7, 0x29, 0x5a, 0xa6, 0x97, 0xfe, 0x1b, 0xe7, 0xea, 0xc3, 0xda, 0x68, - 0x1c, 0xf0, 0xe1, 0x69, 0xe0, 0x99, 0xab, 0xaa, 0xbb, 0x0b, 0xc8, 0x60, - 0x7b, 0x9c, 0x67, 0x2f, 0x55, 0x3f, 0x8b, 0x67, 0xd7, 0x35, 0xf0, 0x8b, - 0xbc, 0x22, 0xbd, 0xa4, 0x95, 0xf7, 0x48, 0xb0, 0x37, 0x07, 0x7a, 0x1c, - 0x37, 0x24, 0x3f, 0x6a, 0x21, 0x3f, 0xe7, 0x3d, 0x2c, 0xed, 0xd2, 0xe2, - 0xdd, 0x67, 0x4c, 0xb7, 0x19, 0x6b, 0x4d, 0x75, 0xf6, 0xe3, 0x4b, 0xbc, - 0x8b, 0x4d, 0xf1, 0xee, 0x6e, 0x98, 0xd7, 0x18, 0x8f, 0x2c, 0xd9, 0xf2, - 0x78, 0x6d, 0x58, 0x1e, 0xad, 0xa5, 0xad, 0xfb, 0xe1, 0x03, 0x0a, 0xeb, - 0x77, 0xb4, 0x43, 0x71, 0xfa, 0x2f, 0x13, 0x79, 0x60, 0x8b, 0x1d, 0xe4, - 0x05, 0x25, 0xd6, 0x6c, 0x73, 0x69, 0xde, 0xe3, 0x58, 0x55, 0xd9, 0x9a, - 0x3b, 0xfc, 0x5f, 0xe6, 0x0d, 0xdc, 0x9f, 0xfe, 0x1a, 0x79, 0x82, 0x87, - 0x3c, 0xc1, 0x43, 0x9e, 0xe0, 0x21, 0x4f, 0xf0, 0x90, 0x27, 0x78, 0xc8, - 0x13, 0x3c, 0xe4, 0x09, 0x1e, 0xf2, 0x04, 0xc4, 0xee, 0xa0, 0x5e, 0x18, - 0x43, 0xfe, 0x0b, 0xff, 0xe5, 0xdd, 0x06, 0x3e, 0xf1, 0xfe, 0x92, 0x31, - 0x87, 0xb1, 0x99, 0x73, 0xab, 0xdb, 0x5c, 0xca, 0x4d, 0xf9, 0xbe, 0x3b, - 0x31, 0x37, 0x1e, 0xe6, 0x23, 0x84, 0x89, 0x62, 0x37, 0xe1, 0xe4, 0xa0, - 0xeb, 0x68, 0xb0, 0x31, 0xe6, 0x2b, 0x41, 0xcc, 0x0a, 0x72, 0xe5, 0xb7, - 0x91, 0xb3, 0xa4, 0x90, 0xb3, 0xf4, 0x23, 0x3f, 0xe1, 0x9d, 0x75, 0x74, - 0xc7, 0x94, 0xd5, 0x8e, 0x7a, 0x63, 0xda, 0x3d, 0x1e, 0x73, 0x69, 0x3b, - 0x55, 0xd0, 0xf5, 0xb9, 0x5e, 0xf1, 0x25, 0x37, 0xf2, 0x4d, 0xe4, 0xad, - 0xcf, 0xa9, 0xfb, 0xb4, 0xf1, 0x21, 0xca, 0xbc, 0xf2, 0x09, 0xb9, 0x6b, - 0xc4, 0xdf, 0xe0, 0x1e, 0x50, 0x5f, 0x20, 0xff, 0x44, 0x7a, 0xce, 0x81, - 0xe1, 0xe7, 0x62, 0x12, 0x3f, 0xb3, 0x1d, 0x73, 0x96, 0xf4, 0xaa, 0xbb, - 0x24, 0x88, 0xf2, 0xdc, 0x55, 0xc8, 0xcb, 0x16, 0xfd, 0x1c, 0x6f, 0x1c, - 0x88, 0x97, 0xfe, 0x75, 0x65, 0x2a, 0x57, 0x5d, 0x51, 0x3a, 0x75, 0xb4, - 0x96, 0x47, 0x7d, 0xd4, 0xd3, 0x2b, 0xed, 0x26, 0x6a, 0xab, 0x08, 0x37, - 0x71, 0xfe, 0x32, 0xae, 0x6a, 0x9e, 0x73, 0xeb, 0xf2, 0x84, 0xac, 0xb9, - 0xcf, 0xca, 0x54, 0xa9, 0x92, 0x4e, 0xb2, 0x56, 0xce, 0x5a, 0x2b, 0x53, - 0x27, 0x81, 0x63, 0x11, 0xb9, 0x81, 0xa1, 0xf6, 0x5e, 0x99, 0x9a, 0xae, - 0x04, 0xf7, 0x59, 0x01, 0x0d, 0x8c, 0x57, 0xed, 0x62, 0x2c, 0x04, 0xf7, - 0x5a, 0xba, 0x5a, 0xcb, 0x75, 0x5c, 0x6f, 0x62, 0x1d, 0xe5, 0x36, 0x8c, - 0xb5, 0x94, 0x1d, 0x69, 0x58, 0x99, 0x2a, 0x56, 0x1b, 0x69, 0x20, 0x1e, - 0xe2, 0x8d, 0xce, 0xc3, 0xb3, 0xc4, 0x45, 0x3f, 0xe3, 0xfb, 0x85, 0x91, - 0xfe, 0x30, 0xef, 0x3a, 0x89, 0xfc, 0xce, 0x0c, 0xf4, 0x5c, 0x8d, 0xbf, - 0xa3, 0xe2, 0x54, 0x4a, 0xe7, 0x3c, 0x9f, 0x78, 0x37, 0xba, 0x80, 0x39, - 0x8c, 0x17, 0x23, 0x58, 0x3d, 0x84, 0xed, 0x6c, 0xe0, 0x67, 0x4b, 0xb8, - 0x1f, 0x69, 0xe2, 0x39, 0x2f, 0x61, 0x2f, 0xd2, 0x45, 0x98, 0x38, 0x68, - 0x83, 0x2c, 0xbd, 0xff, 0x2d, 0xef, 0x1b, 0xcf, 0x44, 0x9e, 0x9a, 0x58, - 0x43, 0x78, 0xe2, 0x88, 0xd6, 0xe0, 0xc5, 0xb9, 0x60, 0x9d, 0xbe, 0x7e, - 0xff, 0xf7, 0x69, 0xfb, 0x36, 0xd2, 0x1a, 0xed, 0x1f, 0xe1, 0x19, 0x0e, - 0xe4, 0xb6, 0xbe, 0x5e, 0xfd, 0x9f, 0x61, 0x78, 0x42, 0x17, 0x3f, 0x76, - 0x8f, 0x3a, 0xdc, 0x50, 0x87, 0x46, 0xf7, 0x17, 0xbc, 0x0f, 0x60, 0x7d, - 0xcf, 0x6f, 0x07, 0x8d, 0xb5, 0xe2, 0xcb, 0x61, 0x2c, 0xdb, 0x29, 0x59, - 0x93, 0x75, 0xc3, 0xf9, 0x70, 0xbc, 0x03, 0xb1, 0x8d, 0xe3, 0x3a, 0xf8, - 0x0b, 0x5d, 0x76, 0xda, 0xc3, 0xba, 0x25, 0x1e, 0x7c, 0xe3, 0x19, 0xa6, - 0x1d, 0xb1, 0xee, 0x6b, 0x0b, 0xe7, 0x22, 0x3b, 0xa2, 0x1f, 0x36, 0xc3, - 0x39, 0xfa, 0x5b, 0x1d, 0xb5, 0x0b, 0xfb, 0xc0, 0xb3, 0xd8, 0x68, 0x4b, - 0xd1, 0x33, 0x2e, 0x67, 0xe7, 0x23, 0xbf, 0x05, 0x9f, 0x32, 0x64, 0x86, - 0xbe, 0xbf, 0x03, 0xbe, 0xaf, 0x4b, 0x0e, 0xc1, 0x67, 0x1d, 0x86, 0xcf, - 0x3a, 0x82, 0x7a, 0x71, 0x6c, 0xa9, 0xf1, 0x9e, 0x97, 0x35, 0x6a, 0x97, - 0x76, 0x5c, 0xc9, 0xbf, 0xe8, 0x1b, 0xf6, 0x47, 0xd0, 0x01, 0xd6, 0x5d, - 0x91, 0x4e, 0xc0, 0xdf, 0x3a, 0x71, 0xe8, 0xc4, 0xd6, 0xfb, 0xe4, 0x61, - 0xd8, 0x46, 0x7b, 0x56, 0xc5, 0x86, 0xa5, 0x80, 0xf7, 0xa5, 0x6a, 0xc0, - 0x7b, 0xf8, 0x65, 0xe0, 0x37, 0xa5, 0x58, 0xb3, 0xa4, 0x88, 0x7d, 0x8b, - 0xd8, 0xb7, 0x88, 0x3a, 0x6f, 0xba, 0xd6, 0xf8, 0x1d, 0xab, 0x33, 0xa4, - 0x9d, 0x6b, 0xa3, 0xbe, 0xd5, 0x70, 0xfe, 0xe8, 0x79, 0x0a, 0xfc, 0x7f, - 0x0c, 0xfc, 0x3f, 0x81, 0xfa, 0xe6, 0x8f, 0x50, 0xdf, 0x7c, 0x0d, 0xf5, - 0xcd, 0x71, 0xd4, 0x37, 0x13, 0xa8, 0x6f, 0xbe, 0x0a, 0xff, 0xf1, 0x15, - 0xf8, 0x8f, 0x63, 0xf0, 0x1f, 0xe3, 0xea, 0xee, 0xe9, 0xa8, 0xb7, 0xf5, - 0x4e, 0x25, 0xda, 0x8b, 0xed, 0x67, 0x22, 0x76, 0x11, 0x67, 0x1a, 0x93, - 0x6a, 0x9d, 0xf5, 0x8d, 0x23, 0xee, 0x41, 0xd6, 0x37, 0xc7, 0xb4, 0x09, - 0xe4, 0xef, 0xf7, 0xef, 0x67, 0xdd, 0x13, 0xd7, 0x72, 0xaa, 0xee, 0x49, - 0x9f, 0x77, 0x91, 0x22, 0x21, 0xf7, 0xc3, 0x99, 0xd3, 0x67, 0x73, 0xa0, - 0x25, 0xc8, 0xf9, 0x7a, 0x42, 0xbf, 0xd7, 0x21, 0x8b, 0xb3, 0xa8, 0x19, - 0xbc, 0x1f, 0x6b, 0x05, 0xe5, 0x1b, 0x2d, 0x8c, 0x51, 0x2b, 0x7b, 0xff, - 0x1c, 0x8e, 0x47, 0x64, 0x72, 0x1e, 0xb5, 0xed, 0xf3, 0xff, 0xa8, 0xe5, - 0xd4, 0xd8, 0xc1, 0x18, 0xf9, 0xee, 0xf3, 0x7f, 0x1f, 0x8e, 0x8b, 0xa1, - 0x3e, 0x84, 0xb4, 0x5a, 0x0e, 0x9e, 0xdd, 0x61, 0xce, 0xf1, 0x6a, 0xef, - 0xe6, 0xff, 0xd3, 0x8e, 0xad, 0x45, 0x13, 0xfb, 0x1b, 0x3b, 0x82, 0xfa, - 0xac, 0x71, 0xbe, 0xab, 0x61, 0xfe, 0x8a, 0xfa, 0xce, 0x5a, 0x28, 0xb7, - 0xfd, 0x0a, 0x1e, 0x58, 0x96, 0x86, 0x98, 0xe7, 0x7d, 0xe4, 0xf3, 0xfb, - 0x9f, 0xab, 0xb7, 0xab, 0x6f, 0x72, 0xae, 0xca, 0xb7, 0x61, 0xe7, 0x23, - 0xa5, 0x1d, 0x81, 0x2f, 0x60, 0x3f, 0xa1, 0x05, 0xfe, 0xfd, 0x8f, 0x81, - 0x07, 0xbc, 0xf6, 0x1a, 0x6b, 0x38, 0x2b, 0xbc, 0x4b, 0xb9, 0x32, 0xc5, - 0xdc, 0xba, 0xa4, 0x70, 0xb3, 0xd6, 0x63, 0xdd, 0x17, 0xc5, 0x80, 0x08, - 0xd7, 0xcf, 0x13, 0x01, 0xdd, 0xe3, 0xa8, 0xe9, 0x08, 0x13, 0x8d, 0x1b, - 0xeb, 0xbf, 0x8e, 0xf0, 0x1e, 0xee, 0x4a, 0x90, 0x57, 0x29, 0x7c, 0x66, - 0x88, 0xef, 0x3f, 0xfd, 0xc0, 0xf7, 0x70, 0xbd, 0xd5, 0xb0, 0xfe, 0x3c, - 0x72, 0x3d, 0xde, 0x99, 0xec, 0x52, 0xdf, 0x19, 0xdf, 0x9f, 0xed, 0x94, - 0x5f, 0x3c, 0xe3, 0xfb, 0xe3, 0x4e, 0x7a, 0xf8, 0x4d, 0xd4, 0x1e, 0x67, - 0x68, 0x27, 0x23, 0xa4, 0x73, 0x30, 0x35, 0x2d, 0x03, 0xbd, 0x41, 0x2e, - 0xfe, 0x75, 0xed, 0xe3, 0x74, 0xeb, 0xe1, 0x3e, 0x3f, 0x6c, 0xd8, 0x27, - 0xd5, 0xb0, 0xcf, 0x0a, 0x6d, 0xb6, 0x7a, 0x2f, 0xce, 0x5c, 0xdc, 0x75, - 0xa3, 0x95, 0x08, 0xeb, 0xb2, 0x47, 0x47, 0xda, 0xa4, 0xd2, 0x97, 0x5e, - 0xf9, 0x11, 0xf2, 0xf5, 0xc2, 0x08, 0xe6, 0x12, 0x83, 0x78, 0xc7, 0xf9, - 0x74, 0x15, 0xb9, 0xe8, 0x4a, 0x55, 0x86, 0xb0, 0x3e, 0x5d, 0x14, 0xe1, - 0x3c, 0xfb, 0x8a, 0xb6, 0x6a, 0xe8, 0x03, 0x92, 0x6b, 0x38, 0xf3, 0x04, - 0xea, 0xaf, 0x13, 0xeb, 0xf5, 0x30, 0xf7, 0xb9, 0x59, 0x5b, 0x53, 0xb9, - 0xf1, 0x01, 0xad, 0x98, 0x08, 0xce, 0xf8, 0x87, 0xf0, 0x17, 0x86, 0xce, - 0xb5, 0xef, 0x03, 0xb7, 0x26, 0x0b, 0xcf, 0x18, 0xea, 0x0e, 0xb6, 0x30, - 0x42, 0x59, 0xf3, 0x79, 0x2d, 0xde, 0x45, 0x67, 0xfa, 0xf3, 0xf0, 0x4c, - 0xd9, 0xb0, 0x9e, 0x8e, 0xce, 0x14, 0x93, 0x77, 0x67, 0x2d, 0xac, 0xfd, - 0x1c, 0xf8, 0x91, 0x97, 0xa5, 0x7a, 0xea, 0x33, 0xf0, 0x94, 0x1b, 0x78, - 0x63, 0x6e, 0x91, 0x61, 0x71, 0xa3, 0x86, 0x1f, 0x4f, 0xc2, 0x0e, 0xbf, - 0xd1, 0x1b, 0xdd, 0x0d, 0x1b, 0xb6, 0xcf, 0xba, 0x07, 0x8d, 0xf3, 0xfd, - 0xb0, 0xc5, 0x14, 0xec, 0x93, 0x39, 0x53, 0x9e, 0xb5, 0x0a, 0xed, 0xc9, - 0x72, 0x8d, 0xb4, 0x75, 0x4c, 0x86, 0x51, 0xef, 0xf0, 0xfc, 0x19, 0x59, - 0xac, 0x47, 0x34, 0x8c, 0xc2, 0x1e, 0x0f, 0xe2, 0xb7, 0x1f, 0xef, 0x1c, - 0xfc, 0x58, 0x2b, 0xad, 0xc8, 0xe3, 0x2a, 0x17, 0x47, 0xae, 0x3d, 0x44, - 0xfa, 0xee, 0x04, 0x3c, 0xf5, 0x99, 0x7a, 0x7a, 0xa7, 0xb8, 0x7d, 0xf4, - 0x15, 0x49, 0xe0, 0xc6, 0x1a, 0xef, 0x22, 0x6c, 0xbd, 0x1f, 0xcf, 0xb4, - 0x55, 0x20, 0x6f, 0x15, 0x7e, 0xdf, 0x37, 0x46, 0xf9, 0x8d, 0xe2, 0x7c, - 0x38, 0x1e, 0xb4, 0xbe, 0x4c, 0xdd, 0x4b, 0xee, 0x96, 0x95, 0xf9, 0x28, - 0x0e, 0x9e, 0x86, 0x0d, 0xf2, 0xce, 0x76, 0x0c, 0x7c, 0xe1, 0x58, 0x0b, - 0xe3, 0x21, 0xe6, 0x17, 0x97, 0x71, 0xee, 0x8c, 0x9c, 0x41, 0xfd, 0x2f, - 0x7d, 0x7c, 0xa6, 0x80, 0x7f, 0x7b, 0xa8, 0xef, 0x9b, 0xd7, 0x1b, 0x36, - 0xfb, 0x63, 0xa0, 0xcf, 0x6c, 0x58, 0xcf, 0x35, 0x41, 0x7d, 0xb2, 0x26, - 0x88, 0xc7, 0x49, 0xff, 0x76, 0x3d, 0xf3, 0xa2, 0x3c, 0xa0, 0xce, 0x54, - 0x93, 0xe3, 0xf3, 0xbe, 0xef, 0x8e, 0x0e, 0x0e, 0x2f, 0x4a, 0x7a, 0xf8, - 0xa4, 0xec, 0xb3, 0x0e, 0xb1, 0x1e, 0xb3, 0x88, 0xc7, 0xbf, 0xbd, 0x25, - 0xe3, 0xfb, 0xa7, 0x41, 0xfb, 0xf7, 0xd5, 0x3e, 0x2f, 0x82, 0x7e, 0xf0, - 0x4a, 0xd5, 0x24, 0xa4, 0x15, 0xcf, 0x04, 0xe9, 0x2d, 0xcb, 0xf1, 0xfa, - 0x85, 0x50, 0x36, 0x8f, 0x89, 0xeb, 0x5d, 0x36, 0x5c, 0xbb, 0x0c, 0xd8, - 0x85, 0x90, 0xb6, 0x0c, 0xe8, 0xc5, 0xfe, 0xf5, 0xb7, 0x13, 0xf4, 0x0d, - 0x94, 0xb9, 0x8b, 0xac, 0xd1, 0x1d, 0x41, 0x1e, 0x95, 0xf8, 0x24, 0x3f, - 0x10, 0x97, 0xcd, 0x7e, 0x80, 0xeb, 0xe2, 0xd7, 0xd0, 0x15, 0xd2, 0x51, - 0x54, 0xfe, 0x53, 0xc5, 0x2d, 0x85, 0xcf, 0xd8, 0xe2, 0x0b, 0x2a, 0xea, - 0xb9, 0x6a, 0xd0, 0x37, 0x31, 0xfe, 0x51, 0x87, 0xbb, 0xe0, 0xff, 0xa0, - 0x83, 0xb0, 0xe3, 0xdc, 0x3c, 0xef, 0x27, 0x86, 0x78, 0xaf, 0x74, 0x36, - 0x0f, 0xd9, 0x2e, 0xf0, 0xfb, 0x63, 0x22, 0xa8, 0x31, 0x83, 0xfa, 0x2b, - 0x45, 0x5f, 0x88, 0xb6, 0xa4, 0xfc, 0x64, 0x5e, 0x7d, 0x6f, 0x8c, 0x03, - 0xc6, 0xa7, 0xef, 0x6c, 0xf8, 0x9b, 0x89, 0x1f, 0x64, 0x83, 0xbf, 0x99, - 0x08, 0xbf, 0xfd, 0x56, 0x83, 0x3c, 0xe2, 0xe1, 0x9a, 0x29, 0x13, 0xb5, - 0xe8, 0x6f, 0x28, 0x28, 0x07, 0xf8, 0xe6, 0x5a, 0x94, 0x3b, 0xf8, 0x41, - 0x4d, 0xb3, 0x49, 0x96, 0x4b, 0x61, 0x4e, 0xc4, 0x1a, 0x80, 0x3c, 0xc4, - 0x78, 0x31, 0xaa, 0x2f, 0x07, 0x20, 0x3f, 0xf0, 0x1c, 0x74, 0xbd, 0x3b, - 0x1b, 0xd4, 0xb9, 0x25, 0xfa, 0xc5, 0xfe, 0xa8, 0xee, 0xdd, 0x25, 0xa5, - 0x63, 0x7c, 0x1f, 0x93, 0x77, 0x66, 0x63, 0xea, 0x7d, 0x41, 0x62, 0xe1, - 0x7b, 0x8e, 0xe3, 0x52, 0x50, 0xef, 0xab, 0x21, 0x3e, 0xd4, 0x69, 0x5f, - 0x89, 0xc6, 0xa6, 0x76, 0xbc, 0x1e, 0xac, 0x9b, 0xac, 0x57, 0xe5, 0xf1, - 0xfa, 0x2a, 0xce, 0xaf, 0x49, 0x6e, 0xbc, 0x28, 0xbb, 0x6d, 0x4b, 0xc5, - 0x7d, 0x37, 0x4e, 0x1d, 0xa3, 0x7e, 0x8d, 0xa9, 0xba, 0xb3, 0x88, 0x7c, - 0xa1, 0x30, 0xc2, 0x6f, 0x3c, 0xbf, 0xba, 0xab, 0x50, 0x4e, 0x5b, 0x59, - 0xf9, 0xd0, 0x77, 0x4d, 0x8e, 0x45, 0x47, 0x3d, 0x74, 0xd7, 0xc3, 0xb5, - 0x0b, 0x77, 0x05, 0x67, 0xc5, 0xfb, 0x1a, 0x61, 0x0d, 0xf5, 0x6d, 0xf6, - 0x5f, 0x6f, 0x35, 0x65, 0xed, 0x56, 0xdf, 0xbf, 0xdf, 0xb1, 0xc4, 0x0d, - 0x6b, 0x57, 0x4b, 0xd5, 0xae, 0xed, 0x2a, 0x07, 0x71, 0x47, 0x52, 0x5a, - 0x1e, 0xf6, 0x7a, 0xc6, 0x43, 0x9d, 0xa3, 0xa7, 0x0f, 0xae, 0xea, 0x16, - 0x62, 0x6e, 0x3a, 0x35, 0x27, 0x6e, 0x2f, 0xbf, 0x37, 0xcf, 0x38, 0x84, - 0xd9, 0x19, 0xdc, 0x75, 0xdd, 0x34, 0xae, 0xfc, 0xac, 0x48, 0x18, 0x7b, - 0x6e, 0x6a, 0xb4, 0x89, 0xc6, 0xdc, 0x92, 0xb6, 0x20, 0x13, 0x26, 0x68, - 0x29, 0x95, 0xa3, 0x3c, 0x8d, 0x7f, 0x1b, 0xb0, 0x7a, 0xd7, 0xd3, 0xa0, - 0x73, 0x1a, 0x74, 0xf2, 0x1c, 0xd3, 0xb5, 0x48, 0xe7, 0xa2, 0x5a, 0x81, - 0x7d, 0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0x3d, - 0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0xbd, 0xf1, - 0x30, 0x4f, 0x7b, 0x62, 0x3d, 0x4f, 0x5b, 0xa9, 0xf3, 0x3b, 0x94, 0xa2, - 0xa5, 0x58, 0x94, 0x20, 0xcf, 0x15, 0x9d, 0x39, 0x4d, 0x94, 0xe7, 0x5e, - 0xfb, 0x9b, 0x48, 0xb0, 0x8e, 0x39, 0x1e, 0xd7, 0x15, 0x35, 0xdd, 0xe6, - 0xba, 0x20, 0xcf, 0x63, 0x6d, 0xb5, 0x79, 0x0d, 0xf2, 0xb5, 0x0c, 0xfd, - 0x19, 0xed, 0x22, 0x11, 0xd4, 0x8b, 0x99, 0xf3, 0xf7, 0xba, 0x88, 0xbf, - 0x85, 0x9a, 0x8a, 0xc1, 0xbc, 0x17, 0xbc, 0x97, 0x7f, 0xb7, 0x00, 0x39, - 0xf0, 0xdd, 0x7d, 0xac, 0x27, 0x0a, 0xb5, 0xa4, 0x14, 0x17, 0xa3, 0xfc, - 0x07, 0xeb, 0xbc, 0x7d, 0x5a, 0xbe, 0x42, 0xd9, 0xea, 0x32, 0x9d, 0x00, - 0x53, 0xec, 0xc6, 0xbc, 0xee, 0x4d, 0x55, 0x23, 0xad, 0xd4, 0x49, 0xcf, - 0x7e, 0xd0, 0x16, 0xdd, 0xe3, 0x8a, 0x18, 0xb3, 0x09, 0xd1, 0x67, 0x91, - 0xd3, 0xda, 0x43, 0xea, 0x6f, 0x1d, 0x7a, 0xb0, 0x8f, 0x3e, 0x3b, 0x10, - 0xfd, 0x2d, 0x06, 0xeb, 0xae, 0xec, 0xc6, 0xfd, 0x2b, 0xcf, 0x91, 0x80, - 0xbd, 0x7e, 0x69, 0x27, 0xce, 0x06, 0xb9, 0x5e, 0xde, 0xa1, 0xf2, 0x6e, - 0xf8, 0xce, 0xd3, 0x43, 0xe9, 0x3e, 0xe9, 0xda, 0x25, 0x67, 0x86, 0x58, - 0xa3, 0xb5, 0x01, 0x1f, 0x61, 0x79, 0xe7, 0xb4, 0x4b, 0x96, 0xe7, 0xe1, - 0x5b, 0xe7, 0xd3, 0x0e, 0xff, 0xbe, 0x60, 0x01, 0x21, 0x6d, 0xa1, 0x3e, - 0xd6, 0xc7, 0x98, 0xbc, 0x58, 0xa7, 0xae, 0xf4, 0x60, 0x7d, 0x3f, 0x74, - 0x71, 0x1b, 0x6c, 0x48, 0xc7, 0xfe, 0x11, 0xee, 0xf7, 0x14, 0xee, 0x1e, - 0xfb, 0xb7, 0x77, 0x2a, 0xdd, 0xd0, 0xd3, 0x56, 0x4a, 0x07, 0xed, 0x1f, - 0xab, 0x2d, 0x1d, 0xe1, 0xf7, 0xc2, 0x69, 0xaf, 0xf1, 0xbb, 0xe1, 0x3e, - 0xad, 0x50, 0xe1, 0xdf, 0x38, 0x0c, 0xc9, 0x21, 0x8b, 0x7f, 0xff, 0xb3, - 0x4f, 0x7b, 0xa0, 0x4a, 0x18, 0x1b, 0x7d, 0xd6, 0xe1, 0xcb, 0xb0, 0xe5, - 0xff, 0x29, 0xdc, 0xea, 0x62, 0xdb, 0x3a, 0xcb, 0xf0, 0xfb, 0x1d, 0xe7, - 0xc7, 0x4d, 0xdd, 0xe4, 0x34, 0x71, 0x12, 0x27, 0xca, 0xc0, 0xc7, 0x39, - 0x49, 0x3d, 0x39, 0xd5, 0x4e, 0xa2, 0x14, 0x22, 0x88, 0x84, 0xe5, 0xfc, - 0xcc, 0x63, 0x14, 0x3c, 0xc8, 0xa6, 0x4e, 0x42, 0x55, 0x94, 0x74, 0x5b, - 0x27, 0xee, 0xb8, 0x40, 0x5c, 0x80, 0x6a, 0x39, 0x69, 0xe9, 0x86, 0x3d, - 0xa7, 0x5b, 0xba, 0x00, 0x57, 0x9e, 0xe3, 0xa4, 0x4d, 0xe7, 0xcc, 0x1a, - 0x03, 0x69, 0x70, 0x41, 0x23, 0x33, 0x6d, 0xe3, 0x66, 0x37, 0x48, 0x5c, - 0x57, 0x29, 0x83, 0x02, 0x6b, 0x2b, 0xb8, 0xe1, 0xef, 0xe2, 0xf0, 0x3c, - 0xdf, 0x39, 0x76, 0xd3, 0xc0, 0x44, 0x24, 0xeb, 0x7c, 0xe7, 0x3b, 0xdf, - 0xff, 0xf7, 0xbe, 0xcf, 0xfb, 0x9b, 0x6e, 0xb9, 0x08, 0x3a, 0xce, 0x8d, - 0xb5, 0xfa, 0xfe, 0xd6, 0x0e, 0x9f, 0x87, 0x07, 0xfb, 0x7c, 0x19, 0xa5, - 0x75, 0xc9, 0x9c, 0xd6, 0xa7, 0xbb, 0x0e, 0x7d, 0x7b, 0x16, 0x6b, 0x8a, - 0xe0, 0x1c, 0x1e, 0xe9, 0xd3, 0x78, 0x64, 0xf0, 0xbd, 0xff, 0xd0, 0x7b, - 0xdf, 0xa1, 0xf7, 0xde, 0xff, 0xd1, 0x9e, 0xe5, 0xc3, 0xf4, 0xc0, 0x75, - 0x5a, 0x53, 0x1a, 0xfd, 0xf2, 0x93, 0x6a, 0x39, 0x6f, 0x25, 0xa9, 0x0b, - 0xcc, 0x88, 0xab, 0x66, 0x9c, 0x36, 0x60, 0x5c, 0x9b, 0xac, 0xae, 0x83, - 0xe6, 0xb1, 0x8f, 0x76, 0x9b, 0xf1, 0xf2, 0x89, 0x3e, 0xf2, 0x4c, 0x10, - 0xd7, 0x60, 0xd8, 0xc3, 0x11, 0xb4, 0x73, 0x5f, 0x74, 0x12, 0xe6, 0x39, - 0xed, 0xbf, 0xa1, 0x0e, 0xe3, 0xaa, 0x9c, 0xce, 0xfd, 0x60, 0x9b, 0x16, - 0xb9, 0x6d, 0xa7, 0xba, 0xfd, 0xdc, 0x20, 0xd8, 0xbb, 0xa9, 0x3e, 0xea, - 0x17, 0x2f, 0x38, 0xcd, 0x3a, 0x73, 0x5f, 0x98, 0x77, 0x05, 0xa2, 0x79, - 0x4a, 0xa4, 0x54, 0x11, 0xb9, 0x86, 0xdf, 0x6f, 0x2a, 0x7e, 0xfc, 0x42, - 0xd1, 0xd6, 0x9e, 0x96, 0x1b, 0xc5, 0x2f, 0x48, 0x15, 0x32, 0x67, 0xc7, - 0x71, 0xdd, 0x3b, 0x4e, 0x54, 0x9f, 0xf9, 0x0f, 0xf2, 0x4a, 0x62, 0xe3, - 0x94, 0x69, 0x6d, 0xf2, 0xc3, 0x75, 0xe6, 0xd5, 0x59, 0xe6, 0x1d, 0x61, - 0x7e, 0x5b, 0x44, 0xd2, 0xe1, 0x80, 0xd6, 0x4b, 0xe5, 0x69, 0x68, 0x12, - 0xf8, 0xf6, 0x87, 0xf5, 0xb3, 0x7d, 0xf4, 0xb9, 0x7c, 0xbc, 0xce, 0x77, - 0x03, 0x4f, 0x43, 0xea, 0x76, 0x00, 0xfa, 0x2b, 0x80, 0xc7, 0xe4, 0xb9, - 0x73, 0xbf, 0xcf, 0x73, 0x6d, 0xa8, 0xa3, 0x0d, 0xdb, 0x26, 0xb9, 0x11, - 0xe0, 0xa0, 0x1a, 0xd6, 0xf9, 0x47, 0xf5, 0xb0, 0xc6, 0xe5, 0x40, 0x99, - 0x7e, 0x7b, 0xf3, 0xa8, 0xc6, 0xe8, 0xd4, 0xee, 0xf7, 0xf4, 0x5e, 0x50, - 0xce, 0x96, 0x1d, 0xd2, 0xaa, 0x29, 0x3b, 0xe0, 0xb5, 0xeb, 0xb5, 0x37, - 0xfa, 0x79, 0x57, 0x37, 0x6a, 0xdf, 0xef, 0xf3, 0x6c, 0x34, 0xd6, 0x5d, - 0xe8, 0xf3, 0xea, 0xa2, 0xbe, 0xcd, 0x45, 0xdb, 0xac, 0x84, 0xbd, 0x7d, - 0x5b, 0x6a, 0x1b, 0xdf, 0x95, 0x77, 0x8b, 0xdf, 0x91, 0x5f, 0x6c, 0x9c, - 0x81, 0xce, 0x61, 0x95, 0xb2, 0x90, 0x27, 0x6f, 0xd7, 0x5c, 0xf7, 0x6d, - 0x67, 0x01, 0xf6, 0x81, 0xeb, 0xfe, 0xd6, 0xd9, 0x93, 0xd8, 0xc4, 0x37, - 0xb1, 0xe7, 0x0c, 0x78, 0x88, 0x58, 0x98, 0x06, 0xbd, 0x7d, 0xb1, 0x5f, - 0x3a, 0x42, 0x9a, 0x4e, 0x86, 0x27, 0x5a, 0xb1, 0x07, 0xc3, 0xd7, 0xc3, - 0xb9, 0x97, 0xe9, 0x7e, 0xd2, 0x8c, 0x51, 0xfb, 0x09, 0xe6, 0x6f, 0x05, - 0x5f, 0x1c, 0xc5, 0x4f, 0xc9, 0x9d, 0x71, 0xac, 0x75, 0x9c, 0xb4, 0xd7, - 0x2a, 0xb1, 0xc7, 0xb0, 0x8f, 0x4c, 0x8b, 0xdc, 0xcb, 0x6f, 0xf6, 0xd1, - 0x9f, 0x77, 0x2f, 0xcf, 0xb2, 0xf1, 0xb9, 0x4e, 0x71, 0xa5, 0x05, 0xf2, - 0x7b, 0x75, 0xd2, 0xd3, 0x95, 0x7e, 0xad, 0x4e, 0xa0, 0xbd, 0x9d, 0x7d, - 0x4f, 0x51, 0xb7, 0xcb, 0xba, 0xad, 0xd0, 0xc5, 0xe7, 0xa0, 0x03, 0xa5, - 0x6a, 0x17, 0xa4, 0x3e, 0x1e, 0x42, 0x1b, 0xea, 0x28, 0x1a, 0x4b, 0x64, - 0x26, 0xcf, 0x7c, 0x2d, 0xe6, 0x4e, 0x61, 0x8d, 0x0b, 0xc4, 0x0d, 0xae, - 0xb1, 0x8d, 0x31, 0x38, 0xbf, 0xce, 0x06, 0x8d, 0xb0, 0x8e, 0xf4, 0x9d, - 0x04, 0x4f, 0x26, 0x29, 0x37, 0x31, 0xde, 0x18, 0xc6, 0x63, 0xb9, 0x13, - 0xe3, 0x5d, 0x90, 0x94, 0xd3, 0x18, 0x73, 0x0a, 0x6d, 0x88, 0x33, 0x53, - 0xd0, 0x1f, 0x86, 0xd4, 0xec, 0x7a, 0x18, 0xf2, 0xbb, 0x4f, 0x66, 0xcd, - 0x23, 0x07, 0xf6, 0x98, 0xd5, 0xf6, 0x81, 0x61, 0x8c, 0xf9, 0x6b, 0xea, - 0x3c, 0xb0, 0x26, 0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x6a, 0x7d, 0x0d, 0x38, - 0xb5, 0xf6, 0x61, 0xca, 0x39, 0x2b, 0x33, 0x61, 0xae, 0x89, 0xf5, 0x61, - 0xac, 0x99, 0x7e, 0xac, 0x67, 0x81, 0x43, 0x47, 0xfc, 0x3a, 0xb6, 0x15, - 0x23, 0x85, 0xb3, 0xf7, 0xec, 0x5a, 0xd6, 0x7d, 0x56, 0x52, 0x6b, 0x19, - 0x99, 0xd7, 0xfd, 0x78, 0x86, 0x83, 0x5a, 0xf7, 0x20, 0xaf, 0xc6, 0x7a, - 0x70, 0x96, 0x89, 0x07, 0x36, 0x70, 0xb4, 0x47, 0xcb, 0xcc, 0x7e, 0x8f, - 0x67, 0xf1, 0xad, 0x87, 0x77, 0xd4, 0x26, 0xb1, 0x6f, 0x40, 0x46, 0xe6, - 0x1b, 0xf5, 0x21, 0xf9, 0x24, 0xdf, 0xd1, 0xcf, 0x38, 0xcb, 0xdd, 0xbc, - 0x29, 0x1f, 0xe7, 0x75, 0x2c, 0x74, 0x31, 0x20, 0xd6, 0x79, 0xcf, 0x3e, - 0x1f, 0x59, 0x5c, 0x55, 0xfc, 0x3e, 0x72, 0x7e, 0x4b, 0x05, 0xd1, 0x36, - 0x84, 0x76, 0x5c, 0x87, 0x29, 0x73, 0xf9, 0xbf, 0xb9, 0x4b, 0xa3, 0xae, - 0x3b, 0xaf, 0xf3, 0xc3, 0x12, 0xe6, 0xaa, 0x6a, 0xe8, 0xe4, 0x71, 0xc9, - 0x87, 0xdb, 0x31, 0x57, 0xc2, 0xdc, 0x52, 0x23, 0x58, 0x0f, 0xcb, 0x3d, - 0xe4, 0x89, 0xc8, 0x9e, 0x70, 0x7c, 0x2b, 0xbd, 0xa9, 0x12, 0xd1, 0x61, - 0x65, 0x25, 0x73, 0xf8, 0xb5, 0x28, 0x1d, 0x47, 0x8c, 0x44, 0x15, 0x78, - 0x17, 0x7b, 0xb2, 0x4f, 0xba, 0x6e, 0xda, 0x66, 0x7d, 0xc2, 0x0c, 0x29, - 0xfa, 0x5b, 0x3a, 0x74, 0xbc, 0xf1, 0x72, 0x6f, 0xc2, 0x3c, 0xa9, 0x8e, - 0xfb, 0xef, 0x53, 0xc0, 0xcc, 0xe6, 0x78, 0x67, 0x36, 0x95, 0x29, 0x2f, - 0xe5, 0x13, 0xd1, 0x65, 0x65, 0x65, 0x30, 0x66, 0x66, 0x56, 0x11, 0x37, - 0x12, 0x66, 0x87, 0xa2, 0x4f, 0xb4, 0x5d, 0xef, 0x3b, 0x8d, 0xfe, 0x09, - 0xd5, 0xe2, 0xaf, 0x87, 0xf7, 0xf5, 0xe3, 0x7e, 0x8f, 0x67, 0x88, 0x39, - 0xa3, 0xc0, 0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x64, 0x6c, 0x62, 0x54, - 0x63, 0xe8, 0xfd, 0x53, 0x7f, 0x47, 0x1d, 0xca, 0x25, 0xd6, 0xc5, 0x7d, - 0x7e, 0x1b, 0xd5, 0x3a, 0xf3, 0xfd, 0x53, 0x59, 0x9d, 0xc7, 0x58, 0x57, - 0x31, 0x7f, 0xdf, 0xcd, 0x3b, 0x8b, 0xa6, 0x9c, 0x47, 0x38, 0xce, 0x5a, - 0x60, 0xba, 0x5d, 0x98, 0x23, 0x3a, 0x57, 0x6c, 0xd0, 0x06, 0xfd, 0x01, - 0xcc, 0x17, 0x68, 0xc4, 0xbd, 0x2f, 0x88, 0x31, 0x11, 0x3c, 0x40, 0x27, - 0xd0, 0x35, 0xa1, 0xa3, 0x56, 0x30, 0x4e, 0x6e, 0x5d, 0xb2, 0x5e, 0x7f, - 0x09, 0x32, 0x27, 0x35, 0x57, 0xf9, 0xb4, 0x31, 0x38, 0x37, 0xe6, 0xc0, - 0xfb, 0xfd, 0x53, 0xa4, 0x4f, 0x9e, 0x4d, 0x54, 0xcd, 0x6d, 0x70, 0x3d, - 0x83, 0x32, 0xbf, 0x3e, 0x24, 0xcb, 0xf8, 0xad, 0xae, 0x7b, 0xf7, 0xb6, - 0x0d, 0xdd, 0x7a, 0x3e, 0x6f, 0x6a, 0x7e, 0x5d, 0x76, 0x18, 0x33, 0x01, - 0xaf, 0xe8, 0x9c, 0x2a, 0xf6, 0x65, 0x5e, 0xe1, 0x10, 0xe5, 0xa3, 0x53, - 0x87, 0x5c, 0xdd, 0xae, 0x51, 0x4f, 0x65, 0xbd, 0x35, 0x15, 0x0d, 0x74, - 0xc9, 0x2a, 0xf0, 0xae, 0x0c, 0xd9, 0x99, 0x7b, 0x25, 0x24, 0xcb, 0x79, - 0x1d, 0x4f, 0x8e, 0xfe, 0x5e, 0x39, 0x52, 0xad, 0x4d, 0xca, 0x6e, 0x2d, - 0xae, 0xbf, 0x51, 0xae, 0xe5, 0x5e, 0x37, 0xe4, 0xf9, 0x51, 0x9d, 0x57, - 0x17, 0x2f, 0x4b, 0xef, 0x00, 0x75, 0x9e, 0x2d, 0x9d, 0x63, 0x07, 0xec, - 0x80, 0xce, 0xf1, 0x33, 0xe8, 0x1c, 0xef, 0x40, 0xe7, 0xf8, 0x69, 0x11, - 0xf8, 0x52, 0x4c, 0xfb, 0xf8, 0xbf, 0x08, 0x1c, 0xa2, 0xac, 0xb6, 0xce, - 0xe0, 0x4e, 0x17, 0xb3, 0xa0, 0xc1, 0x5b, 0x92, 0x06, 0xde, 0xa6, 0xe4, - 0xfa, 0xc6, 0xbc, 0xec, 0x6c, 0x78, 0x79, 0xc8, 0x1f, 0x30, 0x07, 0x6c, - 0x9c, 0xf7, 0x14, 0x07, 0x0e, 0x1d, 0x91, 0xd8, 0x49, 0xe2, 0x47, 0x50, - 0x36, 0x0b, 0xef, 0x68, 0x1c, 0xda, 0x2c, 0xb0, 0x1c, 0x10, 0x9d, 0x4f, - 0xb6, 0xb0, 0x27, 0x65, 0xe7, 0x97, 0xa8, 0x3f, 0xa6, 0x7d, 0x40, 0x9e, - 0x4f, 0x9e, 0x78, 0xf9, 0x67, 0xff, 0xee, 0x95, 0xce, 0xb3, 0x5b, 0x32, - 0xbb, 0xd0, 0xae, 0x81, 0x5d, 0xc3, 0x5e, 0xcc, 0x5b, 0xfd, 0x05, 0x6d, - 0x30, 0x47, 0xb1, 0x4b, 0xb6, 0x21, 0x43, 0xea, 0xf1, 0x2e, 0xad, 0xfb, - 0xd5, 0xe3, 0x43, 0x3a, 0x17, 0x97, 0xe3, 0xe4, 0x0a, 0xb6, 0xac, 0x14, - 0xac, 0x68, 0x16, 0xf4, 0xb7, 0x0b, 0x5b, 0xed, 0x3a, 0xee, 0x60, 0x07, - 0x67, 0x70, 0xa3, 0x46, 0x39, 0x7f, 0x57, 0x63, 0xef, 0x66, 0xed, 0x4f, - 0x18, 0xc7, 0x3a, 0x93, 0x94, 0x3f, 0xf6, 0x13, 0x03, 0xe9, 0x8f, 0x9a, - 0xd1, 0xfd, 0xbd, 0x7e, 0xd7, 0xd1, 0x76, 0xa7, 0x46, 0x3c, 0x16, 0xb9, - 0x94, 0xb7, 0x21, 0x4b, 0x5e, 0x8f, 0x50, 0x07, 0x28, 0xa9, 0x46, 0x3f, - 0xd7, 0x5f, 0xb3, 0xeb, 0x1e, 0xb5, 0xb9, 0xae, 0xb8, 0x8f, 0xdb, 0x94, - 0xfd, 0x7b, 0x5a, 0xee, 0xe7, 0x8b, 0x67, 0xe5, 0x2d, 0xdc, 0xb7, 0xa7, - 0xe3, 0x64, 0xe4, 0x4d, 0xe8, 0x78, 0xb5, 0x62, 0x23, 0x6f, 0x7b, 0x1a, - 0xe7, 0x64, 0xa9, 0x95, 0x2b, 0x2f, 0xcb, 0xe5, 0xab, 0xfb, 0xea, 0xa5, - 0xab, 0x31, 0xf5, 0xf2, 0x95, 0x61, 0x95, 0xbb, 0xe2, 0xba, 0xff, 0x74, - 0x96, 0xe4, 0xdd, 0x0d, 0x57, 0x4e, 0x3b, 0xc6, 0x40, 0x40, 0x1a, 0xb9, - 0x75, 0xae, 0x1b, 0x04, 0x36, 0xdf, 0xe8, 0x75, 0xdd, 0x47, 0xc7, 0xc7, - 0x25, 0xde, 0x4b, 0x1d, 0xe5, 0xf3, 0x11, 0xe6, 0xbb, 0x12, 0x73, 0x52, - 0xb6, 0x7d, 0xbe, 0xac, 0x14, 0xf0, 0xad, 0xcb, 0xd3, 0x5f, 0x1e, 0x3b, - 0xe6, 0xc7, 0x4a, 0x7e, 0xf4, 0x22, 0x7d, 0xc9, 0x91, 0xff, 0xf2, 0x25, - 0x9b, 0x72, 0xae, 0xf0, 0x19, 0xf4, 0x0f, 0xcb, 0xb7, 0x0a, 0xa1, 0x43, - 0x65, 0x13, 0xcf, 0x31, 0x95, 0x2b, 0xdc, 0x73, 0x87, 0x75, 0xcc, 0x00, - 0x3a, 0x89, 0xe9, 0xba, 0xcb, 0x0e, 0xe7, 0xeb, 0xc2, 0x7c, 0x7b, 0xe6, - 0x31, 0xc8, 0xff, 0xd3, 0x5a, 0x3e, 0x9f, 0x53, 0xb0, 0x7d, 0xc1, 0xdf, - 0x61, 0x99, 0x2d, 0x40, 0xc6, 0x2b, 0xe6, 0x9c, 0x52, 0x57, 0xb0, 0x22, - 0xcb, 0xc0, 0x8e, 0x25, 0xe0, 0xcd, 0x93, 0x3a, 0xb6, 0xda, 0xa3, 0xb1, - 0x67, 0x85, 0xe5, 0x8c, 0x24, 0xcb, 0x4e, 0xb7, 0x3e, 0xbf, 0xfd, 0xdd, - 0x57, 0x23, 0xde, 0x9d, 0x83, 0x8f, 0x33, 0x4a, 0xda, 0x60, 0x03, 0xcd, - 0x6c, 0x2d, 0x80, 0x27, 0x22, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x75, 0xc8, - 0xef, 0xba, 0xf6, 0x23, 0x7a, 0xf1, 0x8a, 0xba, 0xc9, 0x76, 0xcf, 0xa0, - 0x5f, 0xbb, 0xa4, 0xae, 0xb4, 0x69, 0x5c, 0x7d, 0xb8, 0x2e, 0x09, 0x3d, - 0xe4, 0x69, 0x94, 0x03, 0xa8, 0x8b, 0xfa, 0x65, 0x03, 0xe5, 0x45, 0x94, - 0x5b, 0xf0, 0x64, 0x9b, 0x11, 0xe8, 0x15, 0x78, 0xbe, 0x81, 0xf1, 0xc6, - 0xb1, 0xe6, 0x8c, 0x29, 0x1f, 0x9d, 0xa2, 0x2c, 0x19, 0x53, 0xcc, 0x4b, - 0x5e, 0xb6, 0xf1, 0xac, 0x0e, 0xab, 0x99, 0x35, 0x96, 0xf1, 0x2c, 0x79, - 0xdf, 0x1f, 0xc2, 0x24, 0xf4, 0x49, 0x5d, 0xf5, 0x30, 0xe9, 0xa3, 0x26, - 0x26, 0xb1, 0xae, 0x5d, 0x66, 0xaf, 0x90, 0xd7, 0x4d, 0xd0, 0x5b, 0x87, - 0xcc, 0x5c, 0x0d, 0x6b, 0x7d, 0xb4, 0x0c, 0x5a, 0xdc, 0x06, 0x5d, 0x6d, - 0x82, 0xa6, 0x52, 0x05, 0x6b, 0x6a, 0x51, 0x45, 0xb5, 0x2f, 0xe0, 0x09, - 0xd0, 0x6b, 0xf0, 0x15, 0xea, 0xa2, 0xe4, 0xe5, 0x38, 0x68, 0x4f, 0xdc, - 0xa0, 0x6d, 0xa7, 0xe3, 0xca, 0x06, 0x0d, 0x82, 0x2e, 0x0b, 0x1e, 0x4f, - 0xbf, 0xa7, 0x34, 0xae, 0x4e, 0xdd, 0x96, 0x44, 0xf2, 0xb6, 0x58, 0xc0, - 0x02, 0xcb, 0xf9, 0x50, 0x1c, 0x8c, 0x39, 0x29, 0xd7, 0x30, 0x8f, 0x01, - 0xfe, 0x1e, 0x3d, 0xa1, 0xf9, 0x7b, 0x4a, 0x02, 0x87, 0x79, 0x1c, 0xf4, - 0x06, 0x0c, 0xf2, 0x78, 0x3a, 0xe9, 0xd3, 0xe8, 0xd7, 0xc1, 0xbf, 0x16, - 0x2c, 0xb1, 0xb0, 0xac, 0x82, 0xff, 0xb7, 0xf1, 0xfd, 0x66, 0x6d, 0x44, - 0xad, 0xac, 0x29, 0x3f, 0x97, 0xe4, 0x19, 0xe8, 0xc9, 0xb7, 0x70, 0x76, - 0x9d, 0x5a, 0x77, 0x8f, 0x8d, 0x33, 0x7e, 0x96, 0x56, 0x97, 0xed, 0x93, - 0xb2, 0x3f, 0x36, 0x89, 0xf2, 0x31, 0x3c, 0x0d, 0x9c, 0x43, 0x48, 0xc7, - 0xbf, 0x37, 0xf3, 0x8e, 0xf2, 0xfe, 0x67, 0x61, 0x42, 0xe7, 0xe7, 0x1b, - 0x76, 0x2f, 0xbe, 0xd3, 0x17, 0xc3, 0xbd, 0x41, 0x67, 0x52, 0x11, 0x9d, - 0x6f, 0x5a, 0x86, 0x2e, 0xb1, 0x85, 0xf1, 0xde, 0xa7, 0x2f, 0xaf, 0x0a, - 0x1e, 0x1e, 0xfb, 0x97, 0x9b, 0x0c, 0x33, 0x47, 0xfd, 0x6e, 0xc4, 0x93, - 0x7f, 0x9f, 0xb8, 0xfb, 0xf6, 0xca, 0x94, 0x81, 0x97, 0x5b, 0x66, 0x18, - 0x6d, 0x21, 0xcb, 0x20, 0x8b, 0x4a, 0x9a, 0x7e, 0xd9, 0xce, 0xeb, 0x9b, - 0xab, 0x26, 0xcc, 0x0f, 0xc4, 0xeb, 0xbb, 0x6a, 0x53, 0xee, 0xb4, 0x03, - 0x5f, 0xa2, 0x5a, 0xaf, 0x7c, 0xdf, 0xce, 0x02, 0x15, 0xac, 0x68, 0x1a, - 0x34, 0xda, 0x26, 0x56, 0x7c, 0x4e, 0x1e, 0xcc, 0xbb, 0xac, 0xfb, 0xb2, - 0x6d, 0xa3, 0x6f, 0x63, 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b, - 0x36, 0x35, 0x8d, 0xd6, 0xab, 0xdd, 0x03, 0x1e, 0x8d, 0x36, 0xf6, 0x11, - 0xfe, 0x3f, 0xfb, 0x20, 0x9d, 0x38, 0xca, 0xcb, 0xbb, 0xc0, 0xb3, 0xca, - 0xf3, 0x1c, 0x01, 0x6d, 0x1c, 0xa4, 0x9f, 0x86, 0x6f, 0xd1, 0xa3, 0x9f, - 0x47, 0x9b, 0xf4, 0x43, 0xba, 0xe9, 0x90, 0xd9, 0xab, 0xb6, 0xcc, 0x17, - 0xf4, 0x7d, 0x43, 0xd7, 0xa4, 0xcf, 0x68, 0x12, 0x74, 0x43, 0x5a, 0x27, - 0x6f, 0x99, 0x52, 0x02, 0x1d, 0x95, 0x80, 0x4f, 0x25, 0xd0, 0x54, 0x19, - 0xf8, 0x56, 0x02, 0xbe, 0x95, 0x6a, 0x56, 0xbc, 0x82, 0x3d, 0x53, 0x66, - 0x6f, 0x81, 0x8e, 0xb6, 0x6b, 0xbc, 0x7f, 0xbd, 0x66, 0x93, 0x72, 0xf0, - 0x66, 0xf3, 0xee, 0xff, 0x81, 0xbb, 0x1f, 0x92, 0x5d, 0xd8, 0x2d, 0x6f, - 0x15, 0xc7, 0x80, 0x49, 0x02, 0x8c, 0x72, 0x40, 0x1b, 0x53, 0x72, 0xbd, - 0x38, 0x2d, 0x3b, 0x90, 0x4f, 0x37, 0x36, 0x62, 0xd0, 0xa7, 0x23, 0xb2, - 0xf2, 0xda, 0xa8, 0xbc, 0xb9, 0xa1, 0x64, 0x09, 0xf4, 0x9b, 0xdb, 0xa4, - 0xdf, 0x1d, 0xf4, 0x5c, 0xea, 0xd0, 0x71, 0xfa, 0xd9, 0x8a, 0xe7, 0x7f, - 0x9f, 0xab, 0x74, 0xca, 0x7c, 0xc5, 0x94, 0xc7, 0x2b, 0xdd, 0xf2, 0xe5, - 0x4a, 0x58, 0x4e, 0xc3, 0x0e, 0xfc, 0x4a, 0x65, 0x50, 0x9e, 0xac, 0x0c, - 0xc9, 0x57, 0xab, 0x51, 0xf9, 0x5a, 0xd5, 0x96, 0x4c, 0x35, 0x2e, 0xe9, - 0xea, 0x98, 0x3c, 0x51, 0xa5, 0x5f, 0x1d, 0xf3, 0xe1, 0x37, 0xd3, 0xf4, - 0x57, 0x70, 0x5d, 0x41, 0xac, 0x2b, 0xae, 0xe6, 0x74, 0x9c, 0x52, 0x32, - 0x9e, 0xcf, 0x43, 0xe4, 0x39, 0x8c, 0x75, 0xf1, 0x35, 0x25, 0x65, 0x3d, - 0x7f, 0xe3, 0xff, 0x46, 0x42, 0xda, 0x36, 0x7a, 0xae, 0x34, 0x88, 0x36, - 0x90, 0x7b, 0xf9, 0x86, 0xef, 0xa3, 0xe1, 0xf3, 0x6f, 0xd8, 0x5e, 0x86, - 0xf6, 0x5b, 0xdf, 0xa4, 0xed, 0xa5, 0xcf, 0x9e, 0xf8, 0x41, 0x3b, 0xe7, - 0x9a, 0xf6, 0x9b, 0x3c, 0x88, 0x6d, 0x34, 0xe6, 0xbd, 0x98, 0x79, 0xf8, - 0xff, 0x53, 0xbc, 0x18, 0xd5, 0xb9, 0xea, 0x20, 0xff, 0x4f, 0x05, 0x6b, - 0xf9, 0xf4, 0xdc, 0xf1, 0xf9, 0xe2, 0xac, 0x7a, 0xbc, 0x48, 0x8d, 0xc6, - 0x95, 0x8b, 0xcd, 0x9c, 0xb8, 0x2f, 0xc9, 0xa6, 0x13, 0xd2, 0x6b, 0xf0, - 0xf3, 0x1f, 0x75, 0x7e, 0xdc, 0xec, 0x09, 0xd2, 0x1f, 0x63, 0x6f, 0x9d, - 0x7e, 0x3c, 0x01, 0xba, 0xad, 0x63, 0xca, 0xa5, 0x8a, 0xe7, 0xb3, 0x5a, - 0xd1, 0xf4, 0xf2, 0x2b, 0xd0, 0x1c, 0x63, 0x0e, 0xde, 0x33, 0x5b, 0xf2, - 0xfa, 0xce, 0xe0, 0xde, 0x60, 0x8f, 0x63, 0xbf, 0x46, 0x37, 0xe7, 0xe2, - 0xff, 0xe9, 0xa0, 0xec, 0xaf, 0x97, 0xb9, 0xc6, 0xb6, 0xa6, 0x45, 0x2f, - 0xae, 0x1b, 0x97, 0x17, 0x70, 0x7e, 0x65, 0x93, 0xeb, 0x0f, 0x4a, 0x39, - 0x4e, 0xdb, 0x96, 0xf8, 0x7d, 0x42, 0x4a, 0x98, 0xa7, 0x1c, 0x6f, 0xf8, - 0xc3, 0x3c, 0x9c, 0x2d, 0x9b, 0x0f, 0xe6, 0x5d, 0x2c, 0x1d, 0xc7, 0x3b, - 0xea, 0xe2, 0xd0, 0x99, 0x16, 0xf8, 0x7e, 0x11, 0x65, 0xfa, 0x46, 0x56, - 0xf0, 0x8c, 0xf8, 0x75, 0xd5, 0x01, 0xad, 0xab, 0x4f, 0x3f, 0xe8, 0xb7, - 0x54, 0xb2, 0xb2, 0xa9, 0x40, 0x42, 0x19, 0xaf, 0xfe, 0x7c, 0x80, 0x98, - 0x7b, 0xdc, 0xe6, 0x2f, 0x24, 0x7f, 0x35, 0xb5, 0x4f, 0xc1, 0xff, 0x76, - 0x44, 0x9e, 0x32, 0x99, 0xc7, 0x9e, 0x54, 0xb3, 0xc5, 0x9c, 0x9f, 0xe3, - 0x9b, 0x50, 0xc7, 0xcb, 0x37, 0x07, 0xbc, 0x9c, 0x77, 0x8e, 0x7d, 0x30, - 0xcf, 0xfd, 0x20, 0x9d, 0x30, 0xdf, 0xbd, 0xbd, 0xf9, 0x3f, 0x52, 0xe5, - 0x3c, 0xf0, 0xce, 0x6e, 0xd1, 0xfc, 0x98, 0xab, 0xfe, 0xdb, 0xdd, 0xd3, - 0xfc, 0xdc, 0xf0, 0x31, 0xfc, 0x6e, 0x80, 0xb6, 0x2d, 0x71, 0xe3, 0x92, - 0x97, 0x3b, 0xaa, 0x6d, 0x68, 0x60, 0x05, 0xea, 0xc8, 0xab, 0xe0, 0x93, - 0x66, 0x5b, 0xfe, 0xfd, 0x07, 0x69, 0x3f, 0x51, 0x42, 0x6c, 0x67, 0x00, - 0x00, 0x00 }; - -static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 }; -static const u32 bnx2_RXP_b09FwRodata[(0x278/4) + 1] = { - 0x08004050, 0x08003f50, 0x08003ff4, 0x0800400c, 0x08004024, 0x08004044, - 0x08004050, 0x08004050, 0x08003f58, 0x00000000, 0x08004a0c, 0x08004a44, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004a7c, 0x08004c40, - 0x08004b88, 0x08004bc0, 0x08004c40, 0x08004b10, 0x08004c40, 0x08004c40, - 0x08004bc0, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c00, - 0x08004c40, 0x08004c00, 0x08004b88, 0x08004c40, 0x08004c40, 0x08004c00, - 0x08004c00, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, - 0x08004aec, 0x00000000, 0x08006058, 0x08006070, 0x08006070, 0x08006070, - 0x08006058, 0x08006070, 0x08006070, 0x08006070, 0x08006058, 0x08006070, - 0x08006070, 0x08006070, 0x08006058, 0x08006070, 0x08006070, 0x08006070, - 0x08006064, 0x00000000, 0x00000000 }; -static const u32 bnx2_RXP_b09FwBss[(0x13dc/4) + 1] = { 0x0 }; -static const u32 bnx2_RXP_b09FwSbss[(0x20/4) + 1] = { 0x0 }; + 0x1f, 0x8b, 0x08, 0x08, 0x19, 0xfd, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xec, 0x5c, 0x6b, 0x6c, + 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x20, 0xb5, 0xa2, 0xf8, 0x18, 0x2e, 0x57, + 0xcc, 0x4a, 0x66, 0xec, 0x5d, 0x71, 0x24, 0xb2, 0x16, 0x6b, 0x8c, 0xd8, + 0xad, 0x4d, 0x04, 0x6b, 0x7b, 0x33, 0xbb, 0x92, 0x98, 0x54, 0x85, 0x29, + 0x87, 0x75, 0x0c, 0xc3, 0x75, 0xd9, 0xa5, 0x1a, 0xbb, 0xae, 0x51, 0xc8, + 0x8f, 0xc4, 0x06, 0x6a, 0xd6, 0x9b, 0x25, 0xdd, 0xa8, 0xe9, 0x82, 0x43, + 0x4b, 0xaa, 0xe9, 0x02, 0x69, 0xbb, 0x20, 0xa9, 0xc7, 0x8f, 0x85, 0x56, + 0x76, 0x52, 0xc7, 0xf9, 0xe1, 0x48, 0x50, 0x95, 0x20, 0x28, 0x0c, 0x43, + 0x48, 0x8d, 0xd6, 0x3f, 0xda, 0x40, 0x95, 0x9f, 0x68, 0x92, 0x42, 0x41, + 0x0b, 0xc7, 0x68, 0x6c, 0x4f, 0xbf, 0xef, 0xce, 0x0c, 0xb9, 0xa4, 0x5f, + 0x40, 0x7f, 0xf4, 0x4f, 0xe7, 0x02, 0x8b, 0xb9, 0xf7, 0xce, 0x3d, 0xe7, + 0x9e, 0x7b, 0xde, 0xe7, 0x0e, 0xa5, 0xdf, 0xef, 0x94, 0x0e, 0x09, 0x5b, + 0x17, 0x7e, 0x99, 0xc3, 0x8f, 0x3d, 0x74, 0xc3, 0xd8, 0x0d, 0xa3, 0x22, + 0x7b, 0xf6, 0x18, 0x5b, 0x12, 0x7a, 0x34, 0x1f, 0xb7, 0xb8, 0xc5, 0x2d, + 0x6e, 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, + 0x71, 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, + 0x8b, 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, + 0x5b, 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, + 0xdc, 0xe2, 0x16, 0xb7, 0xb8, 0xc5, 0x2d, 0x6e, 0x71, 0x8b, 0x5b, 0xdc, + 0xe2, 0xf6, 0xff, 0xbd, 0x19, 0x22, 0x16, 0x9f, 0x5d, 0xe1, 0x4f, 0x12, + 0x7a, 0xfe, 0xf2, 0x1f, 0xba, 0xb6, 0x24, 0x8c, 0xfc, 0xcf, 0x66, 0xa6, + 0x6d, 0x91, 0x42, 0x63, 0x77, 0xa6, 0x28, 0xef, 0xfb, 0x95, 0x94, 0x29, + 0x9c, 0xff, 0x6c, 0xfe, 0xbd, 0xbf, 0x7d, 0xf1, 0xa6, 0xec, 0xd5, 0xba, + 0x21, 0x09, 0x2b, 0x3f, 0xb7, 0xc7, 0xda, 0x25, 0x89, 0x01, 0xc0, 0x7c, + 0x6b, 0xe8, 0xc7, 0xdd, 0xd2, 0x2d, 0x6b, 0x78, 0xec, 0x84, 0x5c, 0x36, + 0x5e, 0xd0, 0xdc, 0xa6, 0xef, 0x9f, 0x70, 0x7c, 0xff, 0x87, 0xf8, 0xbd, + 0xe5, 0x60, 0xec, 0x7d, 0xe0, 0x17, 0x4c, 0x43, 0x74, 0xfb, 0x2f, 0x34, + 0x77, 0xb9, 0x43, 0xaa, 0x8b, 0xa6, 0xcc, 0x7a, 0x29, 0x39, 0xe2, 0x55, + 0xb4, 0x52, 0xb3, 0xa6, 0xed, 0x3d, 0x35, 0xaf, 0xed, 0x3b, 0x75, 0x44, + 0xdb, 0x7f, 0x6a, 0x41, 0x73, 0x4f, 0x49, 0x45, 0xdf, 0xd3, 0x29, 0x05, + 0xeb, 0xb4, 0x56, 0x6c, 0xf6, 0x6b, 0xee, 0xe2, 0x7b, 0xbe, 0xeb, 0x64, + 0xad, 0xbb, 0xc4, 0x2c, 0x80, 0x16, 0x71, 0x6b, 0x3e, 0xc6, 0xa6, 0x14, + 0x52, 0xbe, 0xaf, 0xe7, 0xfd, 0x27, 0xdc, 0x9c, 0x6d, 0xe9, 0x5a, 0x4a, + 0xaa, 0xcd, 0x7e, 0xe0, 0xed, 0xd4, 0x8a, 0x8b, 0xa6, 0x56, 0xf2, 0xfc, + 0x73, 0xae, 0x23, 0x03, 0x86, 0xf8, 0xfe, 0x9c, 0xb3, 0x33, 0x7d, 0x48, + 0x4e, 0x02, 0x6f, 0x03, 0xf8, 0xc4, 0xd2, 0xf3, 0xa4, 0x8f, 0x74, 0x92, + 0xe4, 0x8a, 0x56, 0x1c, 0x8a, 0xe8, 0x93, 0x0c, 0xe9, 0x2f, 0xaf, 0xe8, + 0xa0, 0x73, 0x8b, 0x94, 0xeb, 0x96, 0x4c, 0xad, 0x6c, 0x5c, 0x7f, 0xd9, + 0x7f, 0x71, 0x28, 0x25, 0xcf, 0x36, 0xb3, 0x47, 0x2a, 0x92, 0x90, 0x39, + 0x2f, 0x23, 0x7a, 0x5e, 0x0a, 0x6e, 0x6e, 0x40, 0xce, 0x35, 0xd3, 0xf2, + 0x5c, 0xd3, 0x4e, 0x57, 0x65, 0x93, 0x94, 0x53, 0x96, 0x9c, 0x6d, 0xa6, + 0x70, 0x46, 0xff, 0x9c, 0x6e, 0xdb, 0x56, 0x15, 0x6b, 0xab, 0xcd, 0x97, + 0xf8, 0xef, 0x5f, 0xac, 0xe9, 0x9c, 0x82, 0xa9, 0x80, 0xee, 0x70, 0x2d, + 0xcf, 0xa1, 0xd6, 0xaa, 0xb3, 0x04, 0x6b, 0xa5, 0x32, 0x9d, 0xc3, 0x5c, + 0x73, 0x34, 0xe4, 0xef, 0x16, 0x9c, 0x97, 0x4f, 0x4b, 0xaa, 0x9e, 0x01, + 0xde, 0xb0, 0xff, 0xcf, 0xc0, 0x37, 0x80, 0xf3, 0x5e, 0xab, 0x7e, 0xee, + 0xa2, 0xa4, 0x74, 0xd9, 0x99, 0x2e, 0x0b, 0x78, 0xdb, 0xec, 0xc4, 0x98, + 0xf4, 0xf9, 0xfe, 0x7e, 0x47, 0xac, 0xaa, 0xd3, 0x03, 0x98, 0x8c, 0x54, + 0x9d, 0x6e, 0xe0, 0x69, 0x13, 0xcb, 0xe6, 0xb9, 0xb8, 0xd7, 0x66, 0xcc, + 0xfb, 0x5d, 0x46, 0xde, 0xf7, 0xa7, 0x73, 0xd2, 0x1d, 0xcc, 0xed, 0x56, + 0x38, 0xa6, 0x26, 0x34, 0xac, 0xfb, 0x05, 0x69, 0x4e, 0x24, 0xf3, 0xec, + 0xf3, 0x99, 0x13, 0x77, 0xfe, 0xda, 0x90, 0x96, 0x34, 0x68, 0xb9, 0x26, + 0xec, 0x83, 0xff, 0x1e, 0xf8, 0xe0, 0x7c, 0x06, 0x63, 0xed, 0x3a, 0xe0, + 0x19, 0xae, 0x0a, 0xf7, 0xe8, 0x93, 0xa5, 0x94, 0xe8, 0x57, 0x9c, 0xde, + 0x70, 0x5d, 0x37, 0x68, 0x8d, 0xf4, 0xa0, 0x5f, 0xe6, 0x16, 0xc9, 0xeb, + 0x1a, 0x64, 0x83, 0xe7, 0x8d, 0x15, 0xad, 0xd0, 0x3c, 0x82, 0xbe, 0x29, + 0xd3, 0xb6, 0x7f, 0x6e, 0xce, 0x99, 0xd7, 0x8a, 0xa7, 0x4e, 0x6a, 0xa5, + 0x53, 0x2f, 0x68, 0x7b, 0x9b, 0x2f, 0x74, 0x49, 0x47, 0x16, 0xa7, 0x4e, + 0xc8, 0x93, 0x9e, 0x26, 0xa4, 0x73, 0x09, 0xbc, 0x2b, 0x58, 0x15, 0x31, + 0xed, 0x6e, 0x6d, 0x1f, 0xf0, 0xb4, 0xd9, 0x7f, 0xd2, 0x29, 0xdd, 0x86, + 0x6c, 0xb2, 0xa3, 0xb5, 0x29, 0xf9, 0x33, 0xd0, 0x74, 0xc1, 0x49, 0x91, + 0x5f, 0x3d, 0x01, 0x4c, 0x44, 0x07, 0xf5, 0x8a, 0x3a, 0xa5, 0x17, 0x4a, + 0xc7, 0xff, 0xbc, 0xaf, 0x3a, 0xb2, 0x85, 0x6b, 0xa0, 0xff, 0xd6, 0xfd, + 0xd3, 0xb6, 0xdb, 0x6b, 0x4a, 0xc5, 0xd2, 0x25, 0x6b, 0x15, 0xe5, 0x3a, + 0x99, 0x73, 0x44, 0x8a, 0x35, 0xec, 0x69, 0x9b, 0xe0, 0x8d, 0x0d, 0xde, + 0xec, 0x3c, 0x32, 0xa8, 0xff, 0x96, 0x64, 0xfa, 0x2b, 0x9a, 0x19, 0xf2, + 0x71, 0x49, 0x6e, 0x51, 0xf0, 0x7a, 0xde, 0x81, 0x7e, 0x76, 0xb0, 0x8f, + 0x7d, 0x13, 0x6a, 0x5f, 0x23, 0x6f, 0xa7, 0x97, 0x45, 0x34, 0x3d, 0xbf, + 0x1b, 0xf8, 0xa8, 0xb7, 0x5c, 0xf7, 0x04, 0x68, 0x24, 0xed, 0xec, 0xdb, + 0x80, 0x49, 0x88, 0xeb, 0x74, 0xb5, 0xd0, 0x49, 0x79, 0x93, 0xd7, 0xe4, + 0x9d, 0x3a, 0xa7, 0xb6, 0x76, 0xce, 0x5f, 0xf9, 0x9b, 0x46, 0x4d, 0xf9, + 0xa1, 0x3a, 0x2f, 0x6d, 0x8c, 0xeb, 0x52, 0xa1, 0x4e, 0x24, 0xa0, 0x47, + 0xa2, 0x95, 0x1d, 0x6b, 0x15, 0x57, 0x59, 0x44, 0x37, 0xf2, 0x9d, 0x52, + 0x54, 0xf4, 0x8d, 0x61, 0x2f, 0xda, 0x1e, 0x6c, 0xc8, 0xe6, 0x59, 0x38, + 0x97, 0x87, 0x8d, 0x67, 0xd9, 0x97, 0xf2, 0x02, 0xed, 0x9d, 0xb4, 0x9d, + 0xcf, 0xaa, 0x7f, 0x8e, 0x45, 0x5d, 0x3c, 0xd6, 0x03, 0xda, 0x38, 0x86, + 0x1d, 0xda, 0x78, 0x3f, 0xa2, 0x89, 0x3b, 0x36, 0x08, 0xfe, 0x70, 0x9d, + 0x9d, 0x81, 0x9c, 0x0b, 0x2e, 0xf6, 0x74, 0x9d, 0xdf, 0x50, 0x3c, 0xe8, + 0xc5, 0x79, 0x06, 0xe7, 0xc9, 0xaf, 0x0e, 0xe8, 0xb6, 0x26, 0x65, 0x27, + 0x9b, 0xa1, 0xdc, 0x03, 0xda, 0x75, 0xd9, 0x74, 0x63, 0x2b, 0xed, 0x91, + 0xac, 0xa8, 0x87, 0xa6, 0x24, 0x47, 0xb9, 0x96, 0xeb, 0xb8, 0x3e, 0x3b, + 0x26, 0xfa, 0xaf, 0x7c, 0x6b, 0xdd, 0x59, 0x6d, 0xd9, 0x31, 0x0f, 0x1a, + 0x02, 0xde, 0x82, 0x27, 0x9f, 0xb6, 0x96, 0x7c, 0xdd, 0xc8, 0x3f, 0xae, + 0x6d, 0x5d, 0x07, 0x9d, 0xe8, 0x27, 0x0d, 0x27, 0x3a, 0x03, 0x5b, 0x8b, + 0x68, 0x8a, 0x64, 0xa3, 0x85, 0x38, 0x3e, 0xe9, 0x1c, 0x5c, 0x0f, 0x1f, + 0xe0, 0xc1, 0x07, 0xc0, 0xaf, 0x3d, 0xeb, 0xc1, 0xfe, 0x3d, 0xfa, 0x8c, + 0x8c, 0xbc, 0x38, 0x04, 0x1f, 0xb7, 0xe6, 0x63, 0xd0, 0xc6, 0xd1, 0xd7, + 0xc5, 0x80, 0x8f, 0x99, 0xad, 0xeb, 0xb0, 0x59, 0xf0, 0x78, 0x85, 0x73, + 0xb0, 0xed, 0x95, 0x12, 0x9e, 0xb6, 0x54, 0x1b, 0xd4, 0xab, 0xc8, 0x97, + 0xd2, 0xe7, 0xa4, 0xe1, 0x5f, 0xe8, 0x77, 0xe8, 0x57, 0xb8, 0xd6, 0xf7, + 0x4b, 0x0e, 0x61, 0x7d, 0x99, 0x70, 0x68, 0x43, 0x9d, 0xa2, 0x27, 0x2b, + 0xda, 0xc1, 0x21, 0xd8, 0xd6, 0xf5, 0x6d, 0xa0, 0x95, 0x36, 0x76, 0x8d, + 0x48, 0x3b, 0xf7, 0xfb, 0x69, 0x57, 0xf0, 0xef, 0xee, 0x36, 0x61, 0x0d, + 0x9f, 0xef, 0x86, 0x63, 0x2d, 0xf4, 0x2d, 0x7c, 0x9f, 0xcd, 0x14, 0xa4, + 0x3f, 0x1c, 0xb3, 0xbf, 0x4a, 0xaf, 0xa3, 0xdf, 0x98, 0x90, 0x1d, 0x27, + 0x03, 0x9f, 0xb8, 0x63, 0xc9, 0x12, 0xfb, 0x64, 0x40, 0xe3, 0x8e, 0x33, + 0x91, 0x6f, 0x7c, 0x1f, 0xf0, 0xa0, 0xcf, 0x5b, 0x8d, 0x03, 0x68, 0x3f, + 0xd3, 0x60, 0x2a, 0x98, 0xdb, 0xc8, 0x0b, 0xfa, 0x63, 0xda, 0x9b, 0xd5, + 0x6a, 0x6f, 0x7b, 0x60, 0x6f, 0x4e, 0xbb, 0x64, 0x9d, 0xbf, 0x87, 0xbd, + 0x7d, 0xc3, 0xd1, 0xc0, 0x1b, 0x91, 0x8b, 0xb5, 0x34, 0x6c, 0xdd, 0x4c, + 0xbf, 0x26, 0x3b, 0x33, 0xb3, 0xa2, 0xc9, 0x09, 0xce, 0x35, 0x30, 0xa7, + 0x7c, 0x71, 0xe0, 0x0b, 0x2e, 0x1b, 0x4f, 0x81, 0x2e, 0xdf, 0x9f, 0x05, + 0xce, 0xf2, 0x88, 0x11, 0xda, 0x56, 0x34, 0x6f, 0xdd, 0xef, 0xda, 0xee, + 0xaf, 0x19, 0x52, 0x19, 0x6e, 0x93, 0xec, 0xf0, 0x12, 0x70, 0x4f, 0x3b, + 0x81, 0x1d, 0x53, 0xd7, 0x97, 0x81, 0x7f, 0xce, 0x1b, 0x82, 0x1e, 0xd3, + 0x0e, 0x40, 0x17, 0xf0, 0x2f, 0x03, 0xff, 0x5c, 0xb3, 0x4d, 0xbe, 0x6e, + 0x46, 0xb1, 0x32, 0x3a, 0x4f, 0x37, 0x96, 0x45, 0xfb, 0x1e, 0x96, 0x2f, + 0x7a, 0x49, 0xcd, 0x3d, 0x46, 0xff, 0x5a, 0x1d, 0x86, 0x9d, 0x68, 0x55, + 0x87, 0x7b, 0x1b, 0xb2, 0xbc, 0xba, 0x46, 0x0a, 0xd5, 0xc0, 0x06, 0x0b, + 0xee, 0x50, 0x25, 0x6d, 0x28, 0x5f, 0x22, 0xb2, 0x0f, 0xb6, 0xb7, 0x6c, + 0x73, 0xcc, 0xf9, 0x60, 0x6e, 0xbc, 0xd6, 0x0f, 0x9f, 0xc8, 0xf1, 0x7b, + 0xfe, 0xb4, 0x13, 0xcc, 0x7d, 0xa1, 0x76, 0x57, 0x37, 0xfd, 0x2e, 0xe2, + 0x44, 0xa6, 0xea, 0xfc, 0xbb, 0x0f, 0xfd, 0x5d, 0x07, 0xf3, 0xd1, 0x78, + 0xb2, 0xe3, 0x81, 0xce, 0x8a, 0xb6, 0xdf, 0xd6, 0xfb, 0xdb, 0x43, 0x1f, + 0xb6, 0x1f, 0x93, 0x7b, 0x6b, 0xd5, 0xbe, 0x76, 0x79, 0xcf, 0x60, 0x1c, + 0xbd, 0x22, 0x62, 0xba, 0xb5, 0x5d, 0xe0, 0x47, 0xb5, 0xb7, 0x65, 0x2e, + 0x51, 0xaa, 0xf9, 0x72, 0xc1, 0x09, 0x60, 0x30, 0xee, 0x2c, 0xd6, 0xf4, + 0xfe, 0x84, 0xac, 0x8e, 0x2d, 0xc2, 0xac, 0xc8, 0xae, 0xe1, 0x65, 0x51, + 0xb0, 0x7d, 0x89, 0x35, 0xd8, 0x54, 0xa9, 0x56, 0xed, 0x6d, 0x19, 0xa7, + 0x8b, 0xc0, 0xa5, 0xef, 0x59, 0x85, 0x1d, 0x58, 0x83, 0xdd, 0x2a, 0x99, + 0x5e, 0xc2, 0xeb, 0xfd, 0x9b, 0xd7, 0x70, 0x67, 0x42, 0x7a, 0xfa, 0x36, + 0xaf, 0xe1, 0xb0, 0x89, 0xb3, 0x65, 0x3c, 0x4c, 0x9c, 0x3b, 0xd6, 0x70, + 0x8e, 0xac, 0xa7, 0xe7, 0xb0, 0xc0, 0x07, 0x25, 0xda, 0xf3, 0xb2, 0xe7, + 0x62, 0x6d, 0x70, 0xe2, 0x8b, 0x82, 0x58, 0x37, 0xb2, 0x29, 0xf4, 0xc9, + 0xe6, 0x1e, 0x17, 0xbc, 0x32, 0x85, 0x3e, 0x4e, 0x93, 0x2a, 0xe4, 0x7c, + 0x7f, 0x43, 0xf6, 0x5c, 0x68, 0x98, 0xa1, 0x2e, 0x51, 0x27, 0xde, 0x86, + 0x8d, 0x75, 0x4e, 0x99, 0x88, 0xc3, 0xe7, 0x94, 0x8d, 0xc9, 0x44, 0xb5, + 0x26, 0x95, 0xed, 0xf9, 0x27, 0x7c, 0xe8, 0xe2, 0x94, 0x05, 0x3f, 0x5a, + 0x94, 0xce, 0x31, 0x37, 0x87, 0xf9, 0x06, 0x6d, 0x0b, 0x7e, 0x05, 0xb0, + 0xd0, 0xb5, 0x84, 0x31, 0xbf, 0xf3, 0x55, 0xd7, 0xe0, 0x3e, 0x19, 0xe4, + 0x4d, 0x89, 0x84, 0x3e, 0x7f, 0xd5, 0xa7, 0x9e, 0x4d, 0x8f, 0x5c, 0x45, + 0x9e, 0x62, 0xc1, 0x57, 0xc2, 0x7f, 0x40, 0xdf, 0x67, 0x9b, 0x82, 0xb8, + 0xfe, 0x40, 0x4f, 0x60, 0x63, 0x47, 0xb7, 0x06, 0x4f, 0x31, 0xe9, 0x9b, + 0xa7, 0x73, 0xcc, 0x01, 0xda, 0x13, 0x6e, 0x6e, 0x7c, 0x9b, 0x71, 0xe6, + 0xc0, 0x36, 0xfd, 0x4c, 0x65, 0x9b, 0x0e, 0x9f, 0x0e, 0x9b, 0xd2, 0xdd, + 0x1c, 0xfa, 0x67, 0x22, 0x1b, 0x4a, 0xc3, 0x86, 0xde, 0x56, 0x39, 0xc8, + 0xb9, 0xe6, 0x29, 0xd8, 0xab, 0xa2, 0x55, 0x26, 0x90, 0x13, 0xe8, 0xa3, + 0xef, 0x43, 0x4f, 0x70, 0x16, 0xf8, 0xc0, 0x02, 0xb8, 0xa4, 0x8f, 0xbe, + 0x11, 0xda, 0x33, 0xfb, 0xef, 0xf8, 0x41, 0x7c, 0xf8, 0x7c, 0xb8, 0xff, + 0x3f, 0x75, 0x07, 0x3e, 0x20, 0xc2, 0x45, 0x3c, 0xc3, 0xda, 0x04, 0xf2, + 0x99, 0x89, 0xa6, 0xa9, 0xd1, 0x9f, 0x17, 0x3d, 0xe6, 0x21, 0xcc, 0x41, + 0x1e, 0x0b, 0xfd, 0x22, 0x73, 0x8f, 0xce, 0x90, 0xa7, 0xb9, 0x28, 0xce, + 0x29, 0x7b, 0x43, 0xcc, 0xc9, 0x94, 0x9d, 0x36, 0xe5, 0x93, 0xa7, 0x73, + 0x9d, 0x58, 0x87, 0xb9, 0x26, 0xce, 0x0d, 0xbf, 0x84, 0x5c, 0x06, 0x6b, + 0xce, 0x63, 0x7d, 0x7b, 0x68, 0xf3, 0x17, 0xa5, 0x0c, 0x9f, 0x6a, 0xda, + 0x7c, 0x9f, 0xeb, 0x91, 0x0e, 0x8c, 0x1b, 0xd8, 0x0b, 0x7e, 0xc2, 0x50, + 0x7c, 0x46, 0x2c, 0x48, 0x5d, 0xc7, 0x1c, 0x09, 0x6b, 0x33, 0x58, 0x4b, + 0xbf, 0xcb, 0xb5, 0xcf, 0x82, 0x0e, 0x8c, 0x1b, 0x84, 0xa1, 0x8f, 0x12, + 0xdf, 0xcd, 0x6d, 0x86, 0x26, 0xf9, 0xe7, 0x0c, 0x3b, 0x5a, 0x1b, 0xe1, + 0xdd, 0xb8, 0x96, 0xf9, 0x09, 0x71, 0xf7, 0x84, 0xf1, 0x7f, 0x5c, 0x0a, + 0xcd, 0x02, 0x7e, 0x22, 0xd3, 0xc7, 0x90, 0x8f, 0xd9, 0x6d, 0x88, 0x55, + 0x9c, 0xdf, 0x6a, 0x05, 0x67, 0x8d, 0xe0, 0xee, 0xef, 0x5b, 0x3f, 0xfe, + 0x42, 0x72, 0xcd, 0x47, 0xd2, 0xc2, 0xa4, 0x80, 0x18, 0x01, 0x5e, 0x65, + 0xa6, 0x98, 0xc3, 0x15, 0x1b, 0x4a, 0xa6, 0x98, 0x1b, 0x83, 0x5f, 0x0c, + 0xf2, 0xa2, 0x73, 0xde, 0x46, 0xd9, 0x59, 0xe0, 0x77, 0x01, 0x3c, 0xce, + 0x40, 0x87, 0xc6, 0x01, 0x2b, 0x87, 0x81, 0x83, 0xf1, 0xd7, 0xd1, 0xf3, + 0x49, 0x29, 0x5b, 0xcc, 0x13, 0xda, 0x49, 0x67, 0x81, 0xf6, 0xaf, 0xe7, + 0x37, 0x63, 0x8e, 0xfd, 0x7b, 0x7b, 0x02, 0x99, 0x75, 0x71, 0x3c, 0xa1, + 0xe7, 0x7b, 0x36, 0xcc, 0x7f, 0xbf, 0x2b, 0xa0, 0x4d, 0x8d, 0x31, 0xff, + 0xf2, 0x86, 0xf1, 0xef, 0x25, 0xd7, 0x8f, 0xef, 0xda, 0x16, 0xea, 0x20, + 0xfa, 0x8f, 0x85, 0xf4, 0x82, 0xb6, 0x55, 0x5a, 0xa3, 0x9c, 0x57, 0x16, + 0x74, 0xe4, 0x7f, 0x6e, 0x6e, 0x27, 0x62, 0x7d, 0x46, 0x4a, 0x4d, 0xd0, + 0xbd, 0x1a, 0xcb, 0x56, 0xd7, 0x54, 0xd6, 0xd6, 0x04, 0xbe, 0xbe, 0xd4, + 0xf4, 0x91, 0x3b, 0xb5, 0xc6, 0xbd, 0x61, 0xf4, 0x2b, 0xd8, 0xa7, 0x20, + 0xd3, 0xde, 0x85, 0x82, 0x6e, 0x1f, 0x09, 0xf2, 0x3e, 0xfb, 0x9b, 0x5a, + 0x69, 0x99, 0xf9, 0x20, 0xec, 0xc9, 0x56, 0xf9, 0x3f, 0xe2, 0xca, 0x51, + 0xad, 0x70, 0xea, 0x38, 0xf2, 0xc1, 0x15, 0xfc, 0x4e, 0xe3, 0xd7, 0xc0, + 0x2f, 0xca, 0xc3, 0x9f, 0x41, 0x1e, 0xaf, 0x7c, 0x2c, 0xe2, 0x41, 0xb0, + 0xff, 0x1b, 0x2b, 0xd0, 0xb3, 0xe3, 0x29, 0xf9, 0x86, 0xad, 0xf7, 0xe9, + 0x81, 0x5f, 0x29, 0x20, 0x8f, 0xb5, 0xde, 0x96, 0xdf, 0x0e, 0xf3, 0x22, + 0x91, 0xd7, 0x16, 0xc0, 0xc7, 0x91, 0xfd, 0xa1, 0xce, 0x16, 0xee, 0x75, + 0x95, 0xff, 0x0c, 0xf3, 0x1e, 0xe4, 0x5f, 0x05, 0xb5, 0xea, 0x5b, 0xe0, + 0x8d, 0x26, 0x6f, 0x41, 0x87, 0x5e, 0x5b, 0xe8, 0x00, 0x3d, 0xb6, 0x94, + 0x27, 0x91, 0x2f, 0x68, 0x83, 0xd6, 0x26, 0xad, 0x03, 0x76, 0x0c, 0x1b, + 0x57, 0x63, 0x49, 0xb4, 0xe5, 0x2f, 0xcd, 0x2c, 0xd5, 0x74, 0xac, 0x45, + 0xee, 0x93, 0x43, 0x1f, 0xb2, 0xbf, 0xb2, 0x40, 0x38, 0x5d, 0x5e, 0x5f, + 0x30, 0xe4, 0x4d, 0xe4, 0x52, 0x6f, 0xd9, 0x97, 0x66, 0x10, 0xb7, 0xfa, + 0x11, 0x23, 0x50, 0x8b, 0xec, 0xa4, 0x9f, 0xde, 0x61, 0xe2, 0x59, 0xc2, + 0x6f, 0x1f, 0x72, 0xc1, 0x8f, 0x86, 0xf9, 0xb8, 0xf5, 0xa4, 0x2d, 0x01, + 0x18, 0xae, 0x37, 0x41, 0x5b, 0x37, 0xe4, 0x9f, 0xb5, 0xa6, 0xe4, 0xf5, + 0x1e, 0x95, 0xaf, 0x68, 0x9c, 0x0f, 0x7c, 0xd3, 0x87, 0xe7, 0xc9, 0x67, + 0x03, 0x3a, 0xce, 0x31, 0xdf, 0xd1, 0x87, 0x12, 0x5f, 0x76, 0xac, 0x80, + 0xc3, 0x5c, 0x59, 0x08, 0xfa, 0xd1, 0x9c, 0x68, 0x51, 0x1c, 0xa3, 0x6f, + 0x2c, 0xc1, 0x4e, 0x38, 0x9e, 0x10, 0x25, 0x83, 0x75, 0xf2, 0x94, 0x84, + 0x99, 0x3f, 0x3b, 0x33, 0x67, 0x53, 0xae, 0xf0, 0x71, 0xb5, 0x48, 0xae, + 0x94, 0x51, 0xbb, 0x54, 0x17, 0xbe, 0x09, 0xb9, 0xea, 0x61, 0xbe, 0x0f, + 0x1b, 0x3f, 0x4e, 0xf9, 0xa2, 0xfe, 0x5b, 0x40, 0xee, 0xb3, 0x20, 0xc9, + 0xa0, 0x5e, 0x39, 0x8a, 0x3c, 0x1f, 0xf2, 0xab, 0x1d, 0x07, 0x0e, 0xd8, + 0x69, 0x6d, 0x05, 0x4f, 0xd4, 0x16, 0xb5, 0xd3, 0x78, 0x0e, 0xe0, 0xd9, + 0xa0, 0x6e, 0x86, 0xb9, 0xc6, 0x87, 0xe8, 0x81, 0x3d, 0x95, 0x68, 0x4f, + 0xf2, 0xfd, 0x66, 0x5e, 0xbe, 0xdb, 0x1c, 0x93, 0xe7, 0x9b, 0x39, 0xf9, + 0xbb, 0xa6, 0x23, 0xdf, 0x69, 0x8e, 0xc8, 0xb7, 0x9b, 0xc3, 0xac, 0xc9, + 0x90, 0x37, 0x65, 0x98, 0x37, 0xc9, 0xbd, 0xde, 0xad, 0xb0, 0x77, 0xca, + 0xff, 0xd2, 0x4c, 0xa1, 0x31, 0x28, 0xe5, 0x63, 0xf0, 0xcf, 0xce, 0xcd, + 0xac, 0x25, 0xe5, 0x11, 0x87, 0x35, 0x41, 0x1b, 0xdf, 0xa3, 0xce, 0x84, + 0xff, 0x86, 0x3f, 0x9b, 0x4a, 0x65, 0x4f, 0xbb, 0x46, 0x47, 0xe8, 0x03, + 0x6e, 0x49, 0x4a, 0x07, 0xf6, 0x82, 0x0f, 0x5c, 0x7a, 0x1a, 0x36, 0xa0, + 0x6a, 0x9a, 0x04, 0xfc, 0x0d, 0x73, 0x01, 0x93, 0x76, 0x8c, 0x3a, 0x30, + 0x9b, 0x71, 0x0d, 0xd6, 0x77, 0xb4, 0x67, 0x03, 0x81, 0x83, 0x70, 0xfb, + 0x2c, 0xca, 0xcd, 0xb4, 0xe9, 0x57, 0x0b, 0xa1, 0x8f, 0x4b, 0x84, 0x7a, + 0x69, 0x61, 0xfe, 0xf1, 0xd0, 0x27, 0x6f, 0xdc, 0x07, 0xf1, 0x02, 0xf9, + 0x64, 0xb0, 0x8e, 0xb0, 0x5a, 0x08, 0xdb, 0x17, 0xce, 0x75, 0x82, 0xdf, + 0x8e, 0x94, 0xbd, 0x37, 0x35, 0xe6, 0xd9, 0xc8, 0x77, 0x30, 0x1e, 0xc1, + 0xf8, 0x4a, 0x38, 0xfe, 0x9c, 0x4c, 0x2f, 0x0a, 0x68, 0xfd, 0x89, 0x56, + 0x54, 0xe3, 0x31, 0x8c, 0x75, 0x8c, 0x0d, 0xd6, 0x02, 0x68, 0x37, 0x27, + 0xa9, 0xeb, 0xba, 0x4d, 0x5f, 0x38, 0x19, 0xfa, 0xc3, 0x82, 0x1c, 0xf6, + 0x06, 0x0b, 0x57, 0x11, 0x33, 0xb4, 0xb6, 0x28, 0xff, 0xd9, 0x0e, 0xbe, + 0xf8, 0xfe, 0xed, 0xac, 0xb9, 0x93, 0xa6, 0x7c, 0x7b, 0x3e, 0x6b, 0x3d, + 0xa4, 0x7f, 0x0d, 0x67, 0xf2, 0xfd, 0x83, 0x76, 0xf6, 0xc8, 0x94, 0xde, + 0x25, 0xdf, 0x3d, 0xca, 0xd8, 0x7b, 0x76, 0xe6, 0x07, 0xd0, 0xbd, 0xfa, + 0x4a, 0xbb, 0xd4, 0xeb, 0xa6, 0x5c, 0x19, 0x1d, 0x04, 0x9d, 0x96, 0xd4, + 0x1b, 0x49, 0xe4, 0x73, 0x9b, 0x65, 0xb6, 0x5f, 0x19, 0x18, 0xfc, 0xf4, + 0xb0, 0xf2, 0xd3, 0xae, 0x8d, 0x67, 0xe3, 0xe7, 0x3d, 0xeb, 0xcf, 0x5c, + 0x02, 0xfd, 0xd0, 0xeb, 0xe4, 0x76, 0x25, 0xe7, 0xb2, 0x37, 0x68, 0x95, + 0x75, 0xc4, 0x2e, 0x73, 0xd0, 0xba, 0x57, 0xff, 0x2f, 0xff, 0xf3, 0x26, + 0x65, 0xf7, 0xaa, 0xaa, 0x61, 0x54, 0xac, 0xc3, 0x7e, 0x4b, 0x2b, 0x2f, + 0x83, 0x16, 0xf8, 0xd8, 0xc6, 0xf6, 0x70, 0x9c, 0x51, 0xbc, 0x38, 0xdb, + 0xe8, 0x90, 0xef, 0xd4, 0xb7, 0xc8, 0x72, 0x9d, 0xef, 0xdb, 0x65, 0xa9, + 0x3e, 0x78, 0xb5, 0x4f, 0xef, 0x97, 0xf3, 0xd7, 0x5c, 0x6f, 0xdd, 0xa3, + 0x23, 0x37, 0x98, 0xfc, 0x40, 0x7e, 0x39, 0xda, 0x23, 0x3f, 0xfe, 0x72, + 0xf6, 0x99, 0x3f, 0xd5, 0x61, 0x03, 0xa3, 0x9d, 0xb4, 0x6d, 0xf4, 0x39, + 0x9f, 0xbd, 0x5a, 0xd0, 0xa9, 0xdb, 0x3f, 0x02, 0x4f, 0xb3, 0x0b, 0x81, + 0x1d, 0x10, 0x37, 0xf1, 0x42, 0x37, 0xec, 0xef, 0x01, 0x27, 0xde, 0x35, + 0x06, 0x81, 0xeb, 0x7b, 0x8a, 0x17, 0xb7, 0x3b, 0xd9, 0xab, 0x08, 0x49, + 0xfe, 0x15, 0x7b, 0x70, 0x78, 0x87, 0xbe, 0x5d, 0xea, 0xe9, 0xeb, 0xad, + 0xe7, 0xe0, 0xff, 0x0b, 0xa9, 0xec, 0x91, 0xcb, 0x72, 0x76, 0xe6, 0xa2, + 0x4d, 0xfd, 0xa7, 0xdf, 0x78, 0x09, 0xb9, 0xa7, 0x25, 0x0b, 0x0d, 0xfa, + 0x4b, 0xe2, 0x62, 0xfe, 0xbf, 0xcb, 0x3a, 0xac, 0x33, 0x4f, 0xc0, 0x3b, + 0xcc, 0x1b, 0xbf, 0x4e, 0x39, 0xb7, 0x11, 0x76, 0xb8, 0xa0, 0xff, 0x62, + 0x03, 0x8f, 0x06, 0xad, 0xbd, 0x3a, 0xf7, 0xfb, 0x37, 0xec, 0xfb, 0x0e, + 0x68, 0x1d, 0x04, 0x2c, 0x62, 0x66, 0xba, 0x75, 0x8f, 0x57, 0xd4, 0x1e, + 0xc7, 0x1a, 0xc8, 0xf5, 0x56, 0xf7, 0xc0, 0x5c, 0x43, 0xc7, 0x39, 0x4d, + 0x25, 0x97, 0x2b, 0xa3, 0xe4, 0xef, 0x9e, 0x5e, 0xe6, 0x99, 0x46, 0xfe, + 0xaf, 0xfd, 0xa8, 0x7e, 0x7c, 0x7e, 0x7e, 0x12, 0xfe, 0xd9, 0xf7, 0x2f, + 0xec, 0x1a, 0x04, 0x0d, 0xa8, 0x43, 0xd3, 0xe4, 0xf9, 0xd9, 0x19, 0x17, + 0x38, 0x8a, 0x0a, 0xf7, 0x25, 0x59, 0x01, 0xee, 0x09, 0xf2, 0x01, 0xb8, + 0xe7, 0x38, 0xaf, 0x64, 0x80, 0xf9, 0x46, 0x06, 0x78, 0x23, 0xfd, 0x4c, + 0x42, 0xd7, 0x76, 0x5b, 0xb7, 0x07, 0xba, 0x9e, 0x60, 0x6c, 0x7b, 0x0e, + 0xba, 0x57, 0x48, 0x52, 0x7f, 0xda, 0x7b, 0xd7, 0xf4, 0xa7, 0x15, 0x7f, + 0xbb, 0x94, 0x16, 0x12, 0xc0, 0x6b, 0xca, 0x5c, 0x8e, 0x78, 0x31, 0xae, + 0x53, 0xf7, 0x2b, 0xa1, 0xee, 0x77, 0x86, 0xb8, 0x17, 0xc1, 0x93, 0x6c, + 0xa6, 0xae, 0xb3, 0x8e, 0xda, 0xa6, 0x6a, 0x5b, 0x03, 0x36, 0x5d, 0xae, + 0xb1, 0x0e, 0xe5, 0xfd, 0xc8, 0xa5, 0x99, 0x69, 0xd4, 0xaa, 0xe5, 0xda, + 0x88, 0x56, 0x6e, 0xda, 0x5a, 0xd9, 0xa3, 0xbe, 0xed, 0xb2, 0x2e, 0x28, + 0x1e, 0xa7, 0x65, 0xa9, 0xf9, 0x4b, 0xbf, 0xba, 0x6b, 0x13, 0xfa, 0xd0, + 0xfd, 0x09, 0xca, 0xf7, 0xb3, 0xa4, 0x0b, 0x41, 0x9c, 0xfc, 0x4e, 0xc9, + 0xc9, 0x21, 0x14, 0xbd, 0xc8, 0xad, 0x4e, 0x0d, 0x11, 0x3f, 0xe8, 0x48, + 0xa5, 0x64, 0xd9, 0xe3, 0x1e, 0x67, 0x67, 0xc8, 0xcb, 0xf2, 0x71, 0x4b, + 0x0e, 0x2b, 0xf9, 0xbd, 0xac, 0x6c, 0xbb, 0xbc, 0x62, 0xc8, 0x74, 0x72, + 0xd0, 0x7a, 0x58, 0xb2, 0x57, 0x2f, 0x18, 0xd9, 0x67, 0xa6, 0x60, 0xd7, + 0x4b, 0x8b, 0x86, 0xb8, 0xaa, 0xde, 0xa2, 0x8c, 0xb2, 0x0b, 0xb0, 0xfc, + 0xf0, 0xec, 0x7b, 0x5b, 0xce, 0xde, 0x2d, 0x2b, 0x4f, 0xff, 0x26, 0x7c, + 0xce, 0x01, 0xc8, 0xc2, 0xcc, 0x1c, 0x42, 0x5e, 0xf1, 0xb4, 0x0c, 0x5a, + 0x55, 0xe4, 0xc9, 0xe0, 0x3b, 0xda, 0x01, 0x65, 0x03, 0x17, 0x74, 0x8c, + 0x07, 0xc8, 0x27, 0x8e, 0xaf, 0x95, 0x0b, 0xca, 0x96, 0xd2, 0xea, 0xdd, + 0x0e, 0xe0, 0x08, 0xde, 0x71, 0xfc, 0x19, 0xd9, 0xa1, 0xde, 0xdd, 0xa9, + 0xde, 0x55, 0xe9, 0x2b, 0x94, 0xfc, 0xbe, 0x82, 0x3d, 0xc9, 0xe3, 0x68, + 0xbe, 0x4b, 0x02, 0x5b, 0x8a, 0xf8, 0x6e, 0xc9, 0xc1, 0x46, 0x4a, 0xbe, + 0x84, 0xfa, 0xe7, 0x8e, 0xc6, 0x80, 0x94, 0x20, 0xc7, 0xe9, 0xdc, 0x83, + 0xbd, 0x3c, 0x5b, 0x71, 0x25, 0xfb, 0x8c, 0xe8, 0xa4, 0xf5, 0x4e, 0x39, + 0xe4, 0x45, 0xf4, 0x74, 0x86, 0xf4, 0x4d, 0x86, 0xe3, 0x44, 0x48, 0x43, + 0x2b, 0xbe, 0x4e, 0xe0, 0x42, 0xac, 0xcf, 0x79, 0x21, 0x1e, 0xfa, 0x11, + 0xd0, 0x3a, 0x99, 0x96, 0x15, 0x8f, 0x74, 0x6c, 0x91, 0x6a, 0x8a, 0xfd, + 0x03, 0xd0, 0x37, 0xe2, 0xd9, 0xc4, 0x7c, 0x66, 0x1d, 0x8f, 0x1f, 0x6c, + 0x54, 0xc0, 0x63, 0xf2, 0x97, 0xeb, 0x10, 0x23, 0x3e, 0x47, 0xf9, 0xed, + 0x46, 0x2e, 0x6f, 0x07, 0xba, 0x69, 0xad, 0xed, 0x59, 0x3a, 0xde, 0x0d, + 0x59, 0x71, 0xdf, 0x0e, 0x99, 0x84, 0xdd, 0x17, 0xeb, 0xdc, 0x7f, 0x12, + 0x7a, 0x74, 0x51, 0xed, 0x5f, 0x5a, 0xe9, 0x0f, 0xe1, 0x09, 0xdb, 0xbd, + 0x01, 0xb6, 0x5d, 0xf6, 0x2e, 0x58, 0x1f, 0x01, 0xff, 0xbb, 0x80, 0xd7, + 0xe5, 0x44, 0x8e, 0xf0, 0xc4, 0x83, 0x75, 0xf5, 0xd4, 0x27, 0xe0, 0x49, + 0xaa, 0xba, 0xbe, 0x58, 0x6f, 0x97, 0xe2, 0x42, 0x84, 0x8b, 0x78, 0x3e, + 0x40, 0xdd, 0x7b, 0xb7, 0xc2, 0x35, 0xad, 0x70, 0xe1, 0x7d, 0x9d, 0x3e, + 0xe7, 0x26, 0xc0, 0xa3, 0x76, 0xb7, 0x41, 0x5b, 0xb2, 0x4b, 0xaa, 0xaa, + 0x76, 0xef, 0x50, 0xbe, 0xa6, 0x9a, 0xdc, 0x8c, 0xf7, 0x3e, 0xf6, 0xdc, + 0x8d, 0x7c, 0xa6, 0x1b, 0x73, 0x99, 0x0d, 0x73, 0x1b, 0xe9, 0x4f, 0x6c, + 0xa0, 0xff, 0xbf, 0x7b, 0x19, 0x52, 0xe6, 0x72, 0xc1, 0xba, 0x12, 0xd6, + 0xcd, 0x1e, 0x87, 0x4d, 0x30, 0x4f, 0x4f, 0x31, 0x36, 0x5f, 0xa3, 0x68, + 0x99, 0x5d, 0xf9, 0x29, 0xd6, 0xf5, 0x03, 0x36, 0x1a, 0x07, 0x7c, 0x78, + 0x0a, 0x78, 0x8e, 0xd7, 0xd5, 0x1d, 0x05, 0x64, 0xf0, 0xbe, 0x3a, 0x7b, + 0xb5, 0xfe, 0x69, 0x3c, 0xbb, 0xa6, 0x85, 0x5f, 0xe4, 0x15, 0xe9, 0x25, + 0xad, 0xbc, 0x2f, 0x82, 0xbd, 0x39, 0xd0, 0xe3, 0xa4, 0x21, 0xa5, 0x1c, + 0xe2, 0xba, 0xc7, 0xbb, 0x57, 0xda, 0xe5, 0x40, 0x50, 0x23, 0xd8, 0x8c, + 0xef, 0xa6, 0x3a, 0xfb, 0xa1, 0x15, 0xde, 0xbf, 0x66, 0x78, 0x47, 0x37, + 0x8c, 0xda, 0x5b, 0x1e, 0x5a, 0xb1, 0xe5, 0x6b, 0x8d, 0x61, 0x79, 0xb8, + 0x91, 0xb5, 0xee, 0x81, 0x0f, 0x28, 0xaf, 0xde, 0xcb, 0x6e, 0x4b, 0xd2, + 0x7f, 0x99, 0xc8, 0x3d, 0xdb, 0xec, 0x20, 0x17, 0xa9, 0xb2, 0x36, 0x3b, + 0x9e, 0xe5, 0x7d, 0x8d, 0x55, 0x97, 0x8d, 0xf9, 0xca, 0xff, 0x65, 0xae, + 0xc2, 0xfd, 0xe9, 0xaf, 0x91, 0x9b, 0x78, 0xc8, 0x4d, 0x3c, 0xe4, 0x26, + 0x1e, 0x72, 0x13, 0x0f, 0xb9, 0x89, 0x87, 0xdc, 0xc4, 0x43, 0x6e, 0xe2, + 0x21, 0x37, 0x41, 0x1d, 0x10, 0xd4, 0x07, 0xe3, 0xc8, 0xb9, 0xe1, 0xbf, + 0xbc, 0x5b, 0xc2, 0xdc, 0x22, 0x8a, 0xcd, 0x9c, 0x3b, 0xbf, 0xc9, 0x0d, + 0xea, 0x2b, 0xe5, 0x13, 0x0a, 0xcd, 0x89, 0x30, 0x07, 0xe2, 0x9a, 0x28, + 0x76, 0x73, 0x9d, 0x8c, 0xb9, 0xa8, 0x3d, 0x0b, 0x93, 0xcc, 0x91, 0x82, + 0x98, 0x15, 0xe4, 0xe7, 0xaf, 0x22, 0x4f, 0xca, 0x20, 0x4f, 0x1a, 0x40, + 0x4e, 0xc4, 0x7b, 0xea, 0xe8, 0x2e, 0xa9, 0xa0, 0x1d, 0xf4, 0xc6, 0xb5, + 0x2f, 0x79, 0xcc, 0xdf, 0xed, 0x4c, 0x59, 0xd7, 0x8f, 0xf7, 0x89, 0x2f, + 0xc5, 0xd1, 0xaf, 0x23, 0x57, 0xfe, 0x4b, 0x75, 0x6f, 0x36, 0x31, 0x44, + 0x99, 0xdf, 0xf7, 0x31, 0xf9, 0x72, 0xc4, 0xdf, 0xe0, 0xbe, 0x4f, 0x5f, + 0x22, 0xff, 0x44, 0x7a, 0xcf, 0x80, 0xe1, 0x67, 0x12, 0x92, 0x3c, 0xb9, + 0x05, 0x73, 0x96, 0xf4, 0xa9, 0x3b, 0x23, 0x88, 0xf2, 0xcc, 0x7f, 0x40, + 0x5e, 0xb6, 0xe8, 0x67, 0x78, 0xb3, 0x40, 0xbc, 0xf4, 0xaf, 0xf5, 0x99, + 0x62, 0xbd, 0xae, 0x74, 0xea, 0x60, 0xa3, 0x84, 0x3c, 0xca, 0xe8, 0x93, + 0x0e, 0x13, 0xb5, 0x54, 0x84, 0x9b, 0x38, 0xdf, 0x4c, 0xaa, 0x1a, 0xe7, + 0xcc, 0xaa, 0x3c, 0x21, 0x6b, 0xee, 0x53, 0x9f, 0xa9, 0x2e, 0x64, 0xd3, + 0xac, 0x71, 0x0b, 0x56, 0x7d, 0xe6, 0x49, 0xe0, 0x58, 0x46, 0x6e, 0x60, + 0xa8, 0xbd, 0xeb, 0x33, 0xb3, 0x0b, 0xc1, 0xbd, 0x55, 0x40, 0x03, 0xe3, + 0x55, 0x87, 0x18, 0x4b, 0xc1, 0xfd, 0x95, 0xae, 0x60, 0x09, 0x47, 0x78, + 0x13, 0x70, 0x94, 0xdb, 0x30, 0x60, 0x29, 0x3b, 0xd2, 0x50, 0x9f, 0xa9, + 0xd4, 0x5b, 0x69, 0x20, 0x1e, 0xe2, 0x8d, 0xce, 0xc3, 0xb3, 0x24, 0x45, + 0x3f, 0xe9, 0xfb, 0xe5, 0xd1, 0x81, 0xb0, 0xae, 0x44, 0x1d, 0x79, 0xcc, + 0x0c, 0xf4, 0x5c, 0x8d, 0xff, 0x58, 0xc5, 0xa9, 0x8c, 0xce, 0x79, 0x3e, + 0xf1, 0x2e, 0xf7, 0x28, 0xe6, 0x30, 0x5e, 0x8e, 0xd6, 0xea, 0xe1, 0xda, + 0xae, 0x16, 0x7e, 0xb6, 0x85, 0xfb, 0x91, 0x26, 0x9e, 0xf3, 0x15, 0xec, + 0x45, 0xba, 0xb8, 0xc6, 0x04, 0x6d, 0x90, 0xa5, 0xf7, 0xbf, 0xe5, 0x7d, + 0xeb, 0x99, 0xc8, 0x53, 0x13, 0x30, 0x5c, 0x4f, 0x1c, 0x11, 0x0c, 0x5e, + 0x9c, 0x09, 0xe0, 0xf4, 0xd5, 0x7b, 0xbe, 0x4f, 0xda, 0xb7, 0x95, 0xd6, + 0x68, 0xff, 0x08, 0xcf, 0x70, 0x20, 0xb7, 0x55, 0x78, 0xf5, 0x7f, 0x7f, + 0xe1, 0x09, 0x5d, 0xfc, 0xd0, 0x7d, 0xe9, 0x70, 0x4b, 0x8d, 0x1c, 0xdd, + 0x3b, 0xb0, 0xfe, 0x67, 0x3d, 0xcf, 0xef, 0x03, 0xad, 0xf5, 0x69, 0x29, + 0x8c, 0x65, 0xdb, 0xa4, 0x60, 0xb2, 0x56, 0x19, 0x0f, 0xc7, 0x5b, 0x11, + 0xdb, 0x38, 0xbe, 0x15, 0xfc, 0x85, 0x2e, 0x3b, 0x1d, 0x61, 0xad, 0x94, + 0x0c, 0xbe, 0xeb, 0x0c, 0xd3, 0x8e, 0x58, 0x6b, 0x6e, 0x0e, 0xe7, 0x22, + 0x3b, 0xa2, 0x1f, 0x36, 0xc3, 0x39, 0xfa, 0x5b, 0x1d, 0xf5, 0x12, 0xfb, + 0xc0, 0xb3, 0xdc, 0x6a, 0x4b, 0xd1, 0x33, 0x29, 0xa7, 0x17, 0x23, 0xbf, + 0x05, 0x9f, 0x32, 0x64, 0x86, 0xbe, 0xbf, 0x13, 0xbe, 0xaf, 0x5b, 0xf6, + 0xc2, 0x67, 0xed, 0x83, 0xcf, 0xda, 0x8f, 0x1a, 0x75, 0x7c, 0xa5, 0xf5, + 0x3e, 0x97, 0x75, 0x71, 0x55, 0x0e, 0x29, 0xf9, 0x57, 0x7c, 0xc3, 0xfe, + 0x00, 0x3a, 0xb0, 0x53, 0xe5, 0x7b, 0x81, 0x4e, 0xc0, 0xdf, 0x3a, 0x49, + 0xe8, 0xc4, 0xc6, 0x7b, 0xe3, 0x61, 0xd8, 0x46, 0x47, 0x41, 0xc5, 0x86, + 0x95, 0x80, 0xf7, 0xd5, 0x7a, 0xc0, 0x7b, 0xf8, 0x65, 0xe0, 0x37, 0xa5, + 0xd2, 0xb0, 0xa4, 0x82, 0x7d, 0x2b, 0xd8, 0xb7, 0x82, 0xda, 0x72, 0xb6, + 0xd1, 0xfa, 0xed, 0xaa, 0x2b, 0xa4, 0x9d, 0xb0, 0x51, 0xdf, 0x6a, 0x39, + 0x7f, 0xf4, 0x3c, 0x02, 0xfe, 0x3f, 0x02, 0xfe, 0x1f, 0x46, 0x4d, 0xf5, + 0x00, 0x6a, 0xaa, 0xfb, 0x50, 0x53, 0x1d, 0x42, 0x4d, 0x35, 0x85, 0x9a, + 0xea, 0x6e, 0xf8, 0x8f, 0x3b, 0xe1, 0x3f, 0x26, 0xe1, 0x3f, 0x26, 0xd4, + 0x9d, 0xd1, 0x41, 0x6f, 0xe3, 0x1d, 0x4a, 0xb4, 0x17, 0xdb, 0x1b, 0x22, + 0x50, 0x81, 0xf2, 0xb1, 0x71, 0xa9, 0x37, 0x59, 0x5b, 0x39, 0xea, 0x3e, + 0x6c, 0xda, 0x99, 0xd4, 0xa6, 0x90, 0xbf, 0xdf, 0x33, 0xc2, 0x9a, 0x2b, + 0xa9, 0x15, 0x55, 0xcd, 0x95, 0x7d, 0xc1, 0x45, 0x8a, 0x84, 0xdc, 0x0f, + 0x67, 0xce, 0x9e, 0x2e, 0x1a, 0x51, 0xbd, 0xd3, 0xbb, 0x5a, 0xef, 0x2c, + 0xcf, 0xb3, 0xde, 0x79, 0x75, 0xb5, 0xde, 0x59, 0x9e, 0x67, 0xbd, 0xf3, + 0xca, 0xba, 0x7a, 0xe7, 0xca, 0xd3, 0x97, 0xd6, 0xd5, 0x3b, 0x57, 0x9e, + 0x7e, 0x29, 0x1c, 0x4b, 0xa8, 0x0f, 0x21, 0xad, 0x96, 0x83, 0x67, 0x4f, + 0x98, 0x73, 0x34, 0xfb, 0xd6, 0xff, 0xdf, 0x74, 0xca, 0x96, 0x35, 0xb1, + 0xff, 0x68, 0x6b, 0x50, 0x23, 0xb5, 0xce, 0x77, 0xb7, 0xcc, 0x5f, 0x56, + 0xdf, 0x4b, 0xcb, 0xb5, 0xcd, 0xef, 0xc2, 0x03, 0xcb, 0xca, 0x10, 0xf3, + 0xbc, 0x0f, 0x7c, 0x7e, 0xf3, 0x73, 0xf5, 0x0e, 0xf5, 0xcd, 0xcd, 0x55, + 0xf9, 0x36, 0xec, 0x7c, 0xf4, 0xd1, 0xad, 0x81, 0x2f, 0x60, 0x3f, 0xa5, + 0x05, 0xfe, 0xfd, 0x01, 0xe0, 0x01, 0xaf, 0x3d, 0x53, 0xdd, 0x07, 0x05, + 0xe7, 0x0d, 0xee, 0xc6, 0xcd, 0xfc, 0xe5, 0x19, 0xe6, 0xd6, 0x55, 0x85, + 0x9b, 0xf5, 0x23, 0x6b, 0xce, 0x28, 0x06, 0x44, 0xb8, 0x5e, 0x4d, 0x05, + 0x74, 0xbb, 0xa8, 0x1d, 0xb9, 0x26, 0x1a, 0xb7, 0xd6, 0x9a, 0x9d, 0xe1, + 0xbd, 0xdb, 0xe5, 0x20, 0xaf, 0x52, 0xf8, 0xcc, 0x10, 0xdf, 0xcf, 0xfd, + 0xc0, 0xf7, 0x10, 0xde, 0x6a, 0x81, 0x1f, 0x47, 0xae, 0xc7, 0x7b, 0x1a, + 0xe6, 0x6c, 0xa6, 0xbc, 0x33, 0xdf, 0x25, 0xff, 0x79, 0xd4, 0xf7, 0x27, + 0x9c, 0xec, 0xf0, 0x25, 0xd4, 0x1e, 0x27, 0x69, 0x27, 0xa3, 0xa4, 0x73, + 0x30, 0x33, 0x2b, 0xa9, 0x3e, 0xd2, 0x72, 0x5e, 0x3f, 0xac, 0x7d, 0x98, + 0x6e, 0x3d, 0xdc, 0xe7, 0x1f, 0x5b, 0xf6, 0xc9, 0xb4, 0xec, 0x53, 0xa0, + 0xcd, 0xd6, 0xef, 0xc0, 0x99, 0x2b, 0xdb, 0xaf, 0xb7, 0x52, 0x61, 0x5d, + 0xf6, 0xf0, 0xe8, 0x66, 0x59, 0xe8, 0xcf, 0x9e, 0x7d, 0x05, 0xf9, 0x7a, + 0x79, 0x14, 0x73, 0xa9, 0x41, 0xbc, 0xe3, 0x7c, 0xb6, 0x8e, 0x5c, 0xf4, + 0x6c, 0x5d, 0xb6, 0x01, 0x3e, 0x5b, 0x11, 0xe1, 0x3c, 0xfb, 0x8a, 0xb6, + 0x7a, 0xe8, 0x03, 0xd2, 0x17, 0x70, 0xe6, 0x29, 0xd4, 0x5f, 0x87, 0x83, + 0x7b, 0xb4, 0x70, 0x9f, 0x1b, 0xb5, 0x20, 0x6f, 0xce, 0x69, 0x95, 0xf0, + 0x0e, 0xf0, 0x2b, 0xf0, 0x17, 0x86, 0x4e, 0xd8, 0x77, 0x80, 0x5b, 0x93, + 0xa5, 0xa3, 0x86, 0xba, 0x3b, 0x2d, 0x8f, 0x52, 0xd6, 0x7c, 0x7e, 0x14, + 0xef, 0xa2, 0x33, 0xfd, 0x4d, 0x78, 0xa6, 0xd1, 0xb0, 0x6e, 0x8f, 0xce, + 0x94, 0x90, 0xd7, 0xe7, 0x2d, 0xc0, 0x8e, 0x80, 0x1f, 0x25, 0x59, 0x69, + 0x66, 0x3e, 0x05, 0x4f, 0xad, 0x85, 0x37, 0xe6, 0x06, 0x19, 0x46, 0x75, + 0x0f, 0x78, 0x30, 0x91, 0x86, 0x1d, 0xde, 0xd7, 0x17, 0xdd, 0xe9, 0x1a, + 0xb6, 0xae, 0x05, 0x75, 0x3c, 0xe7, 0x07, 0x60, 0x8b, 0x19, 0xd8, 0x27, + 0x73, 0xa6, 0x12, 0x6b, 0x15, 0xda, 0x93, 0xe5, 0x1a, 0x59, 0x6b, 0x52, + 0x86, 0x51, 0xef, 0xf0, 0xfc, 0x79, 0x59, 0x6e, 0x46, 0x34, 0xe4, 0x60, + 0x8f, 0x63, 0xf8, 0x8d, 0xe0, 0x9d, 0x83, 0x1f, 0x6b, 0xa5, 0x82, 0x7c, + 0x55, 0xe5, 0xe2, 0xc8, 0xb5, 0x87, 0x48, 0xdf, 0x01, 0xac, 0xa7, 0x3e, + 0x53, 0x4f, 0x0f, 0x88, 0xdb, 0x4f, 0x5f, 0x91, 0x06, 0x6e, 0xc0, 0x78, + 0xaf, 0xc1, 0xd6, 0x07, 0xf0, 0xcc, 0x5a, 0x65, 0xf2, 0x56, 0xe1, 0xf7, + 0x7d, 0x23, 0xc7, 0x6f, 0x11, 0xe3, 0xe1, 0x78, 0xd0, 0xfa, 0x1d, 0xea, + 0x5e, 0xfa, 0x5a, 0x39, 0xbb, 0x18, 0xc5, 0xc1, 0x19, 0xd8, 0x20, 0xef, + 0x68, 0xc7, 0xc1, 0x17, 0x8e, 0xb5, 0x30, 0x1e, 0x62, 0x7e, 0xf9, 0xaf, + 0x70, 0xee, 0xbc, 0x9c, 0x44, 0xfd, 0x2f, 0xfd, 0x7c, 0x66, 0x80, 0x7f, + 0x4b, 0xa8, 0xef, 0xeb, 0xe1, 0x0d, 0x9b, 0xfd, 0x71, 0xd0, 0x67, 0xb6, + 0xc0, 0x13, 0x26, 0xac, 0x4f, 0x04, 0xf1, 0x38, 0xed, 0xdf, 0xaa, 0xe7, + 0xef, 0x96, 0x3f, 0x50, 0x67, 0xca, 0xcb, 0xa1, 0x45, 0xdf, 0x77, 0x73, + 0x83, 0xc3, 0xcb, 0x92, 0x1d, 0x7e, 0x52, 0x76, 0x5b, 0x7b, 0x59, 0x8f, + 0x59, 0xc4, 0xe3, 0xdf, 0xda, 0x96, 0xf7, 0xfd, 0x13, 0xa0, 0xfd, 0x07, + 0x6a, 0x9f, 0xbb, 0x41, 0x3f, 0x78, 0xa5, 0x6a, 0x12, 0xd2, 0x0a, 0xde, + 0xa4, 0x48, 0x6f, 0xa7, 0x1c, 0x6a, 0x3e, 0x1f, 0xca, 0xe6, 0x11, 0x71, + 0xbd, 0xb7, 0x0d, 0xde, 0x6f, 0x97, 0x9b, 0x8f, 0x86, 0xb4, 0xe5, 0x41, + 0x2f, 0xf6, 0x6f, 0xfe, 0x43, 0x8a, 0xbe, 0x81, 0x32, 0x77, 0x91, 0x35, + 0xba, 0xa3, 0xcf, 0x40, 0x07, 0x3f, 0xce, 0x0f, 0x24, 0x65, 0xbd, 0x1f, + 0x20, 0x5c, 0xf2, 0x23, 0x74, 0x85, 0x74, 0x88, 0xf2, 0x9f, 0x2a, 0x6e, + 0x29, 0x7c, 0xc6, 0x06, 0x5f, 0xf0, 0xa4, 0x7a, 0x9e, 0x37, 0xe8, 0x9b, + 0x18, 0xff, 0xa8, 0xc3, 0xdd, 0xf0, 0x7f, 0xd0, 0x41, 0xd8, 0x71, 0x71, + 0x91, 0xf7, 0x13, 0x43, 0xea, 0x4e, 0xab, 0x04, 0xd9, 0x2e, 0xf1, 0x3b, + 0x63, 0x2a, 0xc8, 0x27, 0x83, 0xfa, 0x2b, 0x43, 0x5f, 0x88, 0xf6, 0xb8, + 0xf2, 0x93, 0x25, 0xf5, 0x5d, 0x31, 0x89, 0x35, 0x3e, 0x9e, 0xad, 0x7f, + 0x27, 0xf1, 0xa3, 0x42, 0xf0, 0x77, 0x12, 0xe1, 0x37, 0xde, 0x7a, 0x90, + 0x47, 0x3c, 0xd8, 0x30, 0x65, 0xaa, 0x11, 0xfd, 0xdd, 0x04, 0xe5, 0x60, + 0x4b, 0xb9, 0x11, 0xe5, 0x0e, 0x7e, 0x50, 0xd3, 0xac, 0x93, 0xe5, 0xe3, + 0x61, 0x4e, 0xc4, 0x1a, 0x80, 0x3c, 0xc4, 0x78, 0x39, 0x90, 0xdf, 0x92, + 0xbe, 0x03, 0xf2, 0x03, 0xcf, 0x3d, 0x13, 0xb6, 0x94, 0x0e, 0xe3, 0xba, + 0xc5, 0x1a, 0x33, 0xac, 0x7b, 0xb7, 0x4b, 0x75, 0x92, 0xef, 0x13, 0xf2, + 0xda, 0xfc, 0x40, 0x70, 0x4f, 0x24, 0x89, 0xf0, 0x3d, 0xc7, 0x49, 0x29, + 0xab, 0xf7, 0x77, 0x86, 0xf8, 0x50, 0xa7, 0xdd, 0x19, 0x8d, 0xd3, 0x90, + 0x63, 0x00, 0x37, 0x8d, 0x58, 0xf6, 0x55, 0xc4, 0xb1, 0x69, 0xf0, 0xbd, + 0x38, 0x51, 0x91, 0x6b, 0x6d, 0x4b, 0xc5, 0x7d, 0x37, 0x49, 0x1d, 0xa3, + 0x7e, 0x11, 0xa6, 0x07, 0xb9, 0x2a, 0xce, 0x3b, 0x2a, 0x53, 0x46, 0xfe, + 0xdd, 0xdb, 0xca, 0xb5, 0xac, 0x55, 0x90, 0xf7, 0x7d, 0xd7, 0xe4, 0xf8, + 0xfc, 0x6d, 0x0f, 0x06, 0x77, 0xfe, 0xba, 0x9e, 0xbf, 0x78, 0x5b, 0x39, + 0xe8, 0xe3, 0xcc, 0xef, 0x86, 0x7d, 0xc2, 0x19, 0xea, 0x7b, 0xec, 0x4f, + 0x6e, 0x32, 0xe5, 0xc2, 0x4d, 0xbe, 0x7f, 0x0f, 0xbf, 0x09, 0x85, 0x75, + 0xac, 0xa5, 0xea, 0xd8, 0x0e, 0x95, 0x8f, 0xb8, 0xa3, 0x19, 0xad, 0x04, + 0xdb, 0x3d, 0xe9, 0xa1, 0xe6, 0xd1, 0xb3, 0x63, 0xe7, 0x75, 0x0b, 0xf1, + 0x37, 0x9b, 0x39, 0x2e, 0xb9, 0x3e, 0x7e, 0x63, 0x9e, 0x73, 0xb8, 0x66, + 0x5b, 0x70, 0xef, 0x75, 0x83, 0xab, 0x7c, 0xae, 0x48, 0x18, 0x87, 0x6e, + 0x68, 0xb5, 0x8f, 0xd6, 0x3c, 0x93, 0x76, 0x21, 0x53, 0x26, 0xe8, 0xa9, + 0xd6, 0xa2, 0x9c, 0x8d, 0x7f, 0x0f, 0x70, 0xfe, 0xb6, 0xa7, 0x1a, 0x17, + 0x6f, 0x9b, 0x85, 0x7c, 0x78, 0xa6, 0xd9, 0x46, 0xa4, 0x7f, 0x51, 0xdd, + 0xc0, 0x3e, 0xe2, 0xbf, 0x87, 0xf8, 0xef, 0x21, 0xfe, 0x7b, 0x88, 0xff, + 0x1e, 0xe2, 0xbf, 0x87, 0xf8, 0x0f, 0x1e, 0x3e, 0x07, 0x7d, 0x79, 0xd6, + 0x9b, 0x08, 0x73, 0xb6, 0xc7, 0x56, 0x73, 0x36, 0xfe, 0xcd, 0xcb, 0xb9, + 0xa6, 0xa2, 0xa5, 0x52, 0x91, 0x20, 0xe7, 0x15, 0x9d, 0xf9, 0x4d, 0x94, + 0xf3, 0x7e, 0xf4, 0xf7, 0x90, 0x00, 0x8e, 0xf9, 0x1e, 0xe1, 0x2a, 0x9a, + 0x6e, 0x13, 0x2e, 0xc8, 0xf9, 0x58, 0x67, 0xad, 0x87, 0xe1, 0x77, 0x37, + 0xfa, 0xb6, 0xe0, 0x9b, 0x4f, 0xf0, 0x7d, 0xa9, 0x76, 0x87, 0x8b, 0x58, + 0x5c, 0x6e, 0xa8, 0x78, 0x8c, 0x71, 0xe3, 0x0e, 0xfe, 0xad, 0x02, 0x64, + 0xc0, 0x77, 0x5f, 0x66, 0x6d, 0x51, 0x6e, 0x20, 0x2f, 0x5a, 0x8e, 0x72, + 0x21, 0xc0, 0x79, 0x6f, 0x6a, 0xa5, 0x05, 0xca, 0x59, 0x97, 0xd9, 0x14, + 0x98, 0x62, 0xb7, 0xe6, 0x78, 0x97, 0x54, 0xbd, 0x74, 0xb6, 0x49, 0x7a, + 0x46, 0x40, 0x5b, 0x74, 0x8f, 0x2c, 0x62, 0xcc, 0xa7, 0x44, 0x9f, 0x47, + 0x7e, 0x6b, 0x0f, 0xa9, 0xbf, 0x6f, 0xe8, 0xc5, 0x3e, 0xfa, 0xfc, 0x8e, + 0x96, 0x7b, 0x5a, 0x29, 0x04, 0x3e, 0x9b, 0xb1, 0x87, 0xe7, 0x48, 0xc1, + 0x76, 0xdd, 0x6d, 0x38, 0x1b, 0xe4, 0xfa, 0xaf, 0x5b, 0x55, 0x0e, 0x0e, + 0x3f, 0x7a, 0x62, 0xa8, 0xbf, 0x5f, 0xba, 0xb7, 0xcb, 0xc9, 0x21, 0xd6, + 0x6b, 0x9b, 0x81, 0x8f, 0x6b, 0x79, 0xff, 0xb4, 0x5d, 0x4e, 0x2d, 0xc2, + 0xcf, 0x2e, 0x66, 0x1d, 0xea, 0xf2, 0xd2, 0x50, 0x0a, 0xfe, 0xf9, 0xe6, + 0x7e, 0xc6, 0xe7, 0xe5, 0x26, 0x75, 0xa5, 0x17, 0xf0, 0x03, 0xd0, 0xcb, + 0x4d, 0xb0, 0x27, 0x1d, 0xfb, 0x47, 0xb8, 0xff, 0x45, 0xe1, 0xee, 0xb5, + 0x9d, 0x6d, 0x4a, 0x37, 0xf4, 0xac, 0x95, 0xd1, 0x41, 0xfb, 0xff, 0x14, + 0x6e, 0x6d, 0x31, 0x71, 0x5c, 0x67, 0xf8, 0x3f, 0xb3, 0xdc, 0x8c, 0xd7, + 0x30, 0x86, 0xf5, 0xb2, 0x58, 0xae, 0xba, 0x03, 0x63, 0x33, 0xd1, 0x62, + 0x65, 0xb0, 0xec, 0x16, 0x55, 0x96, 0xba, 0xda, 0x05, 0x42, 0xe2, 0x3a, + 0xdd, 0x24, 0xb4, 0x72, 0xd5, 0x2a, 0x42, 0x60, 0x37, 0x8e, 0xfa, 0xd2, + 0x46, 0x55, 0xdb, 0x37, 0xaf, 0x16, 0xec, 0x38, 0xcd, 0xac, 0x17, 0x37, + 0x38, 0xf4, 0x71, 0xb3, 0x2c, 0x0e, 0x90, 0x75, 0x56, 0x6e, 0xf2, 0x90, + 0x3e, 0x19, 0x6d, 0xa2, 0x24, 0x55, 0xa5, 0xbc, 0x54, 0x7d, 0xab, 0x5a, + 0x0b, 0x27, 0xc4, 0x0f, 0xa9, 0xad, 0xf6, 0xa5, 0x77, 0x4d, 0xbf, 0xef, + 0xcc, 0x2c, 0xc6, 0xa4, 0x51, 0x91, 0x56, 0x73, 0xe6, 0xcc, 0xb9, 0x9f, + 0xff, 0xf2, 0xfd, 0x17, 0x3e, 0x67, 0x67, 0xba, 0xc2, 0xbd, 0xcd, 0x95, + 0x76, 0xc6, 0xfe, 0xb6, 0xd4, 0xcc, 0x02, 0xf3, 0x1a, 0x86, 0x64, 0xdc, + 0x64, 0xae, 0xcf, 0x96, 0x3a, 0x57, 0x66, 0x1b, 0x1b, 0x65, 0xda, 0xe4, + 0x4b, 0x6a, 0xa6, 0xdc, 0x23, 0x17, 0x41, 0xc7, 0x85, 0xe1, 0xd6, 0xd0, + 0xf7, 0xda, 0x19, 0xf2, 0x73, 0x77, 0x3c, 0xd4, 0x57, 0x1a, 0x57, 0x16, + 0x34, 0xb6, 0xee, 0xde, 0xf5, 0xed, 0x49, 0xac, 0x29, 0x41, 0x5f, 0x79, + 0x5c, 0xcb, 0x26, 0x83, 0xef, 0x7d, 0xbb, 0xde, 0xe3, 0xbb, 0xde, 0x0f, + 0xfc, 0x8f, 0xf6, 0x2c, 0xef, 0xa6, 0x07, 0xae, 0xd3, 0x1a, 0xe5, 0x2c, + 0x05, 0xcf, 0x36, 0x66, 0x3d, 0x2b, 0x4d, 0x5c, 0x90, 0x15, 0x5f, 0x65, + 0xdd, 0x36, 0xc8, 0xbb, 0x36, 0x99, 0x5f, 0x04, 0xcd, 0x63, 0x1f, 0xed, + 0x36, 0x63, 0xe4, 0x43, 0x71, 0xf2, 0x4c, 0x07, 0xae, 0xc1, 0xb0, 0x07, + 0x13, 0x68, 0xe7, 0x3f, 0xef, 0xa6, 0xcc, 0xb3, 0xda, 0x97, 0x43, 0x3c, + 0xe3, 0xab, 0x82, 0xce, 0xf7, 0x60, 0x9b, 0x16, 0xb9, 0x63, 0x67, 0x7a, + 0xc2, 0x7c, 0x20, 0xd8, 0xbe, 0x5f, 0x8d, 0x13, 0x6b, 0x3c, 0xe7, 0x6e, + 0xd7, 0x99, 0x9b, 0xc2, 0x1c, 0x2b, 0x10, 0xcd, 0x53, 0x22, 0xe5, 0xaa, + 0xc8, 0xeb, 0xf8, 0xfd, 0xa6, 0x1a, 0xc6, 0x4f, 0x14, 0xed, 0xee, 0x93, + 0xb2, 0x5e, 0xfa, 0x9a, 0xd4, 0xa0, 0x7f, 0xd6, 0x5c, 0xdf, 0xbf, 0xeb, + 0x26, 0xf5, 0x99, 0xbf, 0xe8, 0x29, 0x19, 0x18, 0xa1, 0x7e, 0x6b, 0x93, + 0x97, 0x17, 0x5b, 0x64, 0xc3, 0xb4, 0xcc, 0xbb, 0x44, 0x01, 0x5e, 0x42, + 0x26, 0x63, 0x11, 0x8d, 0x51, 0xe5, 0x5b, 0x22, 0x5b, 0xf8, 0xb6, 0xb5, + 0xf8, 0x4c, 0x9c, 0xfe, 0x97, 0x4f, 0x16, 0xf9, 0x6e, 0xe0, 0x69, 0x48, + 0xc3, 0x8e, 0x00, 0xcb, 0x42, 0x08, 0x99, 0x3c, 0x77, 0xee, 0xf7, 0xbb, + 0x5c, 0x1b, 0xea, 0x68, 0xcf, 0xb6, 0x49, 0xe1, 0x30, 0x64, 0xa2, 0x1a, + 0xd4, 0x39, 0x47, 0x8d, 0x98, 0x96, 0xd1, 0x91, 0x0a, 0x7d, 0xf8, 0xe6, + 0x5e, 0x2d, 0xaf, 0x33, 0x37, 0x7e, 0xa4, 0xf7, 0x82, 0x72, 0xbe, 0xe2, + 0x92, 0x56, 0x4d, 0x59, 0x03, 0xaf, 0xad, 0xd6, 0x5f, 0xed, 0xe3, 0x5d, + 0xad, 0xd7, 0x5f, 0x88, 0x07, 0xf6, 0x1a, 0xeb, 0x7e, 0x1c, 0x0f, 0xea, + 0x92, 0xa1, 0xfd, 0x45, 0x3b, 0xad, 0x8c, 0xbd, 0xbd, 0x20, 0xf5, 0xa5, + 0x9f, 0xc9, 0x3b, 0xa5, 0x9f, 0xc8, 0xaf, 0x97, 0xce, 0x00, 0x7f, 0x58, + 0xe5, 0x3c, 0xf4, 0xc9, 0xcd, 0xba, 0xef, 0xdf, 0x74, 0xa7, 0x60, 0x2b, + 0xf8, 0xfe, 0xef, 0xdc, 0x0d, 0x19, 0x38, 0xf6, 0x3d, 0xec, 0x39, 0x07, + 0x1e, 0xa2, 0x2c, 0x9c, 0x04, 0xbd, 0xb9, 0x7d, 0xd2, 0x19, 0xd5, 0x74, + 0x32, 0x78, 0xac, 0x15, 0x7b, 0x30, 0x42, 0x4c, 0xce, 0xbd, 0x8c, 0xf4, + 0x91, 0x66, 0x8c, 0x7a, 0x09, 0xf3, 0xb7, 0x82, 0x2f, 0xf6, 0xe2, 0xa7, + 0xe4, 0xee, 0x08, 0xd6, 0x3a, 0x42, 0xda, 0x6b, 0x95, 0x81, 0x47, 0xb1, + 0x8f, 0x5c, 0x8b, 0xdc, 0xf3, 0x7e, 0x19, 0xa7, 0x6f, 0xef, 0x9e, 0xc7, + 0xb2, 0xf1, 0x95, 0x2e, 0xf1, 0xa5, 0x05, 0xba, 0x7c, 0xfe, 0x78, 0x80, + 0x9b, 0xde, 0x55, 0x43, 0x68, 0x6f, 0xe7, 0xdf, 0x53, 0xc4, 0x79, 0x79, + 0xbf, 0x15, 0xb8, 0x7c, 0x1c, 0x78, 0x28, 0x53, 0xbf, 0x20, 0x8d, 0x91, + 0x28, 0xda, 0x10, 0xaf, 0x68, 0x59, 0x22, 0x59, 0x8f, 0x39, 0x5a, 0xcc, + 0x97, 0xc2, 0x1a, 0xa7, 0x74, 0x2e, 0x57, 0x1f, 0xcf, 0x9c, 0x58, 0x3e, + 0xa8, 0xb3, 0x41, 0x23, 0xac, 0x23, 0x7d, 0xa7, 0x35, 0xa6, 0x82, 0x0e, + 0xc5, 0x78, 0xc3, 0x92, 0xd1, 0xe5, 0x2e, 0x8c, 0x77, 0x41, 0x32, 0x6e, + 0x73, 0xcc, 0x51, 0xb4, 0xa1, 0x9c, 0x19, 0x05, 0x96, 0xf8, 0x58, 0x8d, + 0x2d, 0xc6, 0xa0, 0xcb, 0xe3, 0x32, 0x66, 0xee, 0xd9, 0xb1, 0xc7, 0xbc, + 0xb6, 0x15, 0x0c, 0x63, 0x38, 0x5c, 0x53, 0xd7, 0x8e, 0x35, 0xb1, 0x3f, + 0x7e, 0xb0, 0x93, 0x33, 0x8b, 0x0b, 0x90, 0x53, 0x0b, 0x1f, 0x66, 0xdc, + 0x67, 0x25, 0x1b, 0x6b, 0xd3, 0xb6, 0x4d, 0x05, 0xf7, 0x92, 0xf5, 0xe8, + 0xd3, 0xfa, 0x0e, 0xe4, 0xd0, 0x9e, 0xb0, 0x8e, 0x6d, 0xc5, 0xc8, 0xe0, + 0xec, 0x03, 0x1b, 0x97, 0x75, 0x5f, 0x96, 0xcc, 0x42, 0x4e, 0x26, 0x74, + 0x3f, 0x9e, 0xe1, 0x41, 0x8d, 0x43, 0xc8, 0xab, 0x03, 0xbd, 0x38, 0xcb, + 0xd4, 0x03, 0x7b, 0x38, 0xd9, 0x4b, 0x2e, 0xfa, 0x4f, 0xc8, 0xb3, 0xf8, + 0xd6, 0xcb, 0x3b, 0x6a, 0x93, 0x81, 0x67, 0xa0, 0x2f, 0xbd, 0x66, 0x7d, + 0x54, 0x3e, 0xf3, 0xfc, 0x38, 0x63, 0x2e, 0x7f, 0xf6, 0x4c, 0xf9, 0xc4, + 0xd3, 0xb1, 0xd8, 0xe9, 0x88, 0x58, 0xe7, 0x03, 0x5b, 0xfd, 0xf0, 0xf4, + 0xbc, 0xe2, 0xf7, 0xc3, 0xe7, 0x57, 0x54, 0x07, 0xda, 0x46, 0xd1, 0x8e, + 0xeb, 0x30, 0x65, 0xdc, 0xfb, 0xab, 0x3f, 0x73, 0xc4, 0xf7, 0x27, 0x74, + 0x4e, 0x58, 0xca, 0x9c, 0x57, 0x4d, 0x7c, 0xee, 0x88, 0x17, 0x6b, 0xc7, + 0x5c, 0x29, 0x73, 0x45, 0x1d, 0xc6, 0x7a, 0x58, 0xee, 0x25, 0x4f, 0x24, + 0x36, 0x84, 0xe3, 0x5b, 0x93, 0xcb, 0x2a, 0x95, 0x1c, 0x54, 0x56, 0xba, + 0x80, 0x5f, 0x8b, 0xd2, 0x71, 0xcc, 0x44, 0x52, 0x81, 0x77, 0xb1, 0x27, + 0xfb, 0xa8, 0xef, 0x4f, 0xda, 0xac, 0x4f, 0x99, 0x51, 0x45, 0xdf, 0x4b, + 0xa7, 0x8e, 0x77, 0x5e, 0x3e, 0x90, 0x32, 0x8f, 0xaa, 0xfd, 0xe1, 0xfb, + 0x28, 0x64, 0xe6, 0xf6, 0x78, 0x67, 0x96, 0x95, 0x29, 0x2f, 0x79, 0xa9, + 0xe4, 0xac, 0xb2, 0x72, 0x18, 0x33, 0x37, 0xa6, 0x28, 0x37, 0x52, 0x66, + 0xa7, 0xa2, 0x7f, 0xb4, 0x5d, 0xef, 0x7b, 0x12, 0xfd, 0x53, 0xaa, 0x25, + 0x5c, 0x0f, 0xef, 0xeb, 0x4a, 0x5f, 0xc0, 0x33, 0x94, 0x39, 0xfd, 0xc6, + 0xcc, 0x02, 0xf3, 0xcb, 0x74, 0x5e, 0x43, 0x7a, 0xe0, 0x18, 0xdf, 0x0d, + 0xb9, 0x7f, 0xe2, 0x6f, 0xa8, 0x43, 0xb9, 0xcc, 0x3a, 0x27, 0xe4, 0xb7, + 0x23, 0x1a, 0x3f, 0xdf, 0x3f, 0x91, 0xd7, 0xb9, 0x8b, 0x0d, 0x35, 0x10, + 0xee, 0x7b, 0xfb, 0xce, 0x92, 0x19, 0xf7, 0x4b, 0x1c, 0x67, 0x21, 0x72, + 0xb2, 0x5d, 0x98, 0x23, 0x3a, 0x5e, 0x6a, 0xd2, 0x06, 0x7d, 0x03, 0xcc, + 0x15, 0x68, 0xc6, 0xdd, 0x2f, 0x88, 0x71, 0xac, 0x63, 0x07, 0x9d, 0x00, + 0x77, 0x02, 0xaf, 0x56, 0x31, 0x4e, 0x61, 0x51, 0xf2, 0x41, 0x7f, 0xe9, + 0x60, 0x4e, 0x6a, 0xa1, 0xfa, 0x45, 0x63, 0x04, 0x3a, 0x70, 0x1c, 0xef, + 0xf7, 0x4f, 0x90, 0x3e, 0x79, 0x36, 0x49, 0x35, 0xbe, 0xc4, 0xf5, 0x1c, + 0x94, 0x89, 0x45, 0x60, 0x23, 0xfc, 0xe6, 0x17, 0x83, 0x7b, 0xbb, 0x0e, + 0x9c, 0x3d, 0xe1, 0x99, 0x9a, 0x5f, 0x67, 0x5d, 0xc6, 0x4f, 0xc0, 0x2b, + 0x3a, 0x8f, 0x8a, 0x7d, 0x99, 0x4b, 0x78, 0x88, 0xfa, 0xd1, 0x6d, 0x48, + 0x0c, 0x6d, 0x89, 0x59, 0x59, 0x6f, 0x8d, 0x26, 0x23, 0xdd, 0x32, 0x0f, + 0x79, 0x57, 0x81, 0xee, 0x2c, 0x5c, 0x89, 0xca, 0xac, 0xa7, 0xe3, 0xd9, + 0xc9, 0x8f, 0x95, 0x2b, 0xb5, 0xfa, 0x71, 0xb9, 0x51, 0x77, 0xf4, 0x37, + 0xea, 0xb5, 0xc2, 0xab, 0x86, 0x7c, 0xff, 0x88, 0xce, 0xa5, 0x73, 0x2a, + 0xd2, 0xd9, 0x4f, 0xcc, 0xb3, 0xa2, 0xf3, 0xea, 0x20, 0x3b, 0x80, 0x39, + 0xde, 0x06, 0xe6, 0x78, 0x0b, 0x98, 0xe3, 0x57, 0xc0, 0xd8, 0x37, 0x4b, + 0x93, 0xa1, 0xfc, 0x9f, 0x86, 0x1c, 0xa2, 0xae, 0xb6, 0xce, 0xe0, 0x4e, + 0xa7, 0xf3, 0xa0, 0xc1, 0xdb, 0xb0, 0x3f, 0xd6, 0x4b, 0x19, 0x59, 0x5d, + 0x9a, 0x90, 0xb5, 0xa5, 0x20, 0x0f, 0xf9, 0x03, 0xe6, 0x7d, 0x8d, 0xf0, + 0x9e, 0x1c, 0xc8, 0xa1, 0x3d, 0x32, 0x70, 0x94, 0xf2, 0xa3, 0x43, 0x96, + 0x8b, 0xab, 0x5a, 0x0e, 0x2d, 0x17, 0x59, 0x8e, 0x88, 0xce, 0x21, 0x9b, + 0xda, 0x90, 0x8a, 0x5b, 0x47, 0xfd, 0x3e, 0xed, 0x0f, 0x0a, 0xfc, 0xf3, + 0x94, 0x97, 0x7f, 0x0a, 0xef, 0x5e, 0xe9, 0xdc, 0xba, 0x19, 0xb3, 0x1b, + 0xed, 0x9a, 0xb2, 0x6b, 0x30, 0x88, 0xb9, 0xab, 0xdb, 0x68, 0x83, 0x39, + 0x80, 0x19, 0xaf, 0x43, 0x87, 0x34, 0x9c, 0x6e, 0x8d, 0xfd, 0x1a, 0xce, + 0x21, 0x9d, 0x77, 0xcb, 0x71, 0x0a, 0x45, 0x5b, 0xe6, 0x8a, 0x56, 0x32, + 0x0f, 0xfa, 0xbb, 0x01, 0xbb, 0x6d, 0x15, 0x77, 0xb0, 0x86, 0x33, 0x58, + 0xaf, 0x53, 0xcf, 0x6f, 0x6a, 0xd9, 0xbb, 0x5c, 0xff, 0x23, 0xc6, 0xb1, + 0xce, 0xa4, 0xe5, 0x0f, 0x7d, 0x94, 0x81, 0xf4, 0x4d, 0x65, 0x75, 0xff, + 0xa0, 0xdf, 0x2a, 0xda, 0xae, 0xd5, 0x29, 0x8f, 0x45, 0x2e, 0x79, 0x36, + 0x74, 0xc9, 0xcb, 0x09, 0x62, 0x80, 0xb2, 0x6a, 0xf6, 0xf3, 0xc3, 0x35, + 0xfb, 0xfe, 0x5e, 0x9b, 0xeb, 0x72, 0x42, 0xb9, 0x4d, 0xdd, 0xbf, 0xa1, + 0xb1, 0x8d, 0x57, 0x7a, 0x56, 0xde, 0xc4, 0x7d, 0x07, 0x18, 0x27, 0x27, + 0x6f, 0x00, 0xe3, 0xd5, 0x4b, 0xcd, 0xbc, 0xed, 0x93, 0x38, 0xa7, 0x92, + 0x9a, 0xbb, 0xda, 0x29, 0x97, 0xaf, 0x15, 0xd4, 0x4b, 0xd7, 0x3c, 0xf5, + 0xf3, 0xab, 0x45, 0x55, 0xb8, 0xea, 0xfb, 0xff, 0x70, 0x67, 0xe4, 0x9d, + 0x25, 0x5f, 0x4e, 0xbb, 0x46, 0x7f, 0x44, 0x9a, 0xf9, 0x74, 0xbe, 0xdf, + 0x01, 0xd9, 0xbc, 0x7e, 0xc0, 0xf7, 0x1f, 0x19, 0x19, 0x11, 0xe7, 0x00, + 0x31, 0xca, 0x70, 0x82, 0x39, 0xae, 0x94, 0x39, 0x19, 0xdb, 0x3e, 0x5f, + 0x51, 0x0a, 0xf2, 0xad, 0x3b, 0xc0, 0x2f, 0x8f, 0xee, 0x0b, 0xe3, 0x26, + 0x3f, 0x7c, 0x9e, 0x7e, 0xe5, 0xc4, 0xe7, 0xfc, 0xca, 0xa6, 0x9c, 0x2d, + 0xf6, 0xa2, 0x7f, 0x4c, 0x7e, 0x50, 0x8c, 0xee, 0x2a, 0x9b, 0x78, 0x3a, + 0x46, 0xa1, 0x78, 0xcf, 0x1f, 0xd4, 0xf1, 0x03, 0x60, 0x12, 0xd3, 0xf7, + 0x67, 0x5d, 0xce, 0xd7, 0x8d, 0xf9, 0x36, 0xcc, 0x7d, 0xd0, 0xff, 0xa7, + 0xb5, 0x7e, 0x2e, 0x2b, 0xd8, 0xc1, 0xe0, 0xef, 0x98, 0x8c, 0x15, 0xa1, + 0xe3, 0x15, 0xf3, 0x4c, 0x89, 0x15, 0xac, 0xc4, 0x2c, 0x64, 0xc7, 0x0c, + 0xe4, 0xcd, 0x29, 0x1d, 0x67, 0xed, 0xd5, 0xb2, 0x67, 0x8e, 0xe5, 0x9c, + 0xa4, 0x2b, 0x6e, 0x8f, 0x3e, 0xbf, 0xcd, 0x1b, 0x2f, 0x26, 0x82, 0x3b, + 0x07, 0x1f, 0xe7, 0x94, 0xb4, 0xc1, 0x1e, 0xca, 0xae, 0x4c, 0x81, 0x27, + 0x12, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x0d, 0xe8, 0xef, 0x86, 0xf6, 0x29, + 0x06, 0xb1, 0x8b, 0x86, 0xc9, 0x76, 0xa7, 0xd0, 0xaf, 0x5d, 0x32, 0x57, + 0xdb, 0xb4, 0x5c, 0x7d, 0xb8, 0x2e, 0x0d, 0x1c, 0xf2, 0x04, 0xca, 0x11, + 0xd4, 0x25, 0xc3, 0xb2, 0x81, 0xf2, 0x34, 0xca, 0x2d, 0x78, 0xb2, 0xcd, + 0x61, 0xe0, 0x0a, 0x3c, 0x5f, 0xc3, 0x78, 0x23, 0x58, 0x73, 0xce, 0x94, + 0x8f, 0x4e, 0x50, 0x97, 0x38, 0x06, 0x73, 0x91, 0x67, 0x6d, 0x3c, 0x6b, + 0x45, 0x95, 0x5d, 0x60, 0x19, 0xcf, 0x72, 0xf0, 0xfd, 0x21, 0x99, 0x84, + 0x3e, 0x99, 0x6b, 0x81, 0x4c, 0xfa, 0x68, 0x5b, 0x26, 0xb1, 0xae, 0x5d, + 0xc6, 0xae, 0x92, 0xd7, 0x4d, 0xd0, 0x5b, 0xa7, 0x64, 0xaf, 0xc5, 0x34, + 0x1e, 0xad, 0x80, 0x16, 0xaf, 0x83, 0xae, 0x96, 0x41, 0x53, 0x99, 0xa2, + 0x35, 0x3a, 0xad, 0x92, 0xda, 0x2f, 0xf0, 0x38, 0xe8, 0xb5, 0xe3, 0x0a, + 0xb1, 0x28, 0x79, 0xd9, 0x01, 0xed, 0x89, 0xdf, 0x61, 0xdb, 0x93, 0x8e, + 0xb2, 0x41, 0x83, 0xa0, 0xcb, 0x62, 0xc0, 0xd3, 0xef, 0x29, 0x2d, 0x57, + 0x47, 0xef, 0x48, 0x2a, 0x7d, 0x47, 0x2c, 0xc8, 0x02, 0xcb, 0xfd, 0x50, + 0x5c, 0x8c, 0x79, 0x5c, 0x5e, 0xc7, 0x3c, 0x06, 0xf8, 0xfb, 0xc8, 0x90, + 0xe6, 0xef, 0x51, 0x89, 0xec, 0xe6, 0x71, 0xd0, 0x1b, 0x64, 0x50, 0xc0, + 0xd3, 0xe9, 0x90, 0x46, 0x9f, 0x06, 0xff, 0x5a, 0xb0, 0xca, 0x92, 0x32, + 0x0f, 0xfe, 0xbf, 0x8e, 0xef, 0xb7, 0xea, 0x9f, 0xaa, 0xb9, 0x05, 0x15, + 0xe6, 0xb2, 0x7c, 0x1b, 0x38, 0xf9, 0xf7, 0x38, 0xbb, 0x2e, 0x8d, 0xdd, + 0x07, 0x46, 0x18, 0x4b, 0xfb, 0xb7, 0xba, 0x6c, 0x1f, 0x95, 0xcd, 0xe1, + 0xe3, 0x28, 0xef, 0xc3, 0xd3, 0xc0, 0x39, 0x44, 0x75, 0x2c, 0x7c, 0xd9, + 0x1b, 0x36, 0x0a, 0x3a, 0xef, 0xe0, 0x98, 0xce, 0xcf, 0x37, 0xec, 0x03, + 0xf8, 0x4e, 0xbf, 0x0c, 0xf7, 0x06, 0xcc, 0xa4, 0x12, 0x3a, 0xc7, 0xb4, + 0x02, 0x2c, 0xb1, 0x82, 0xf1, 0xde, 0xa7, 0x5f, 0xaf, 0x06, 0x1e, 0x1e, + 0xfe, 0xa7, 0x9f, 0x8e, 0x31, 0x27, 0x7d, 0x33, 0x11, 0xe8, 0xbf, 0xcf, + 0xfc, 0x4d, 0x7b, 0x6e, 0xd4, 0xc0, 0xcb, 0x6d, 0x33, 0x86, 0xb6, 0xd0, + 0x65, 0xd0, 0x45, 0x65, 0x4d, 0xbf, 0x6c, 0x17, 0xf4, 0x2d, 0xd4, 0x52, + 0xe6, 0x07, 0x12, 0xf4, 0x9d, 0xb7, 0xa9, 0x77, 0xda, 0x21, 0x5f, 0x92, + 0x1a, 0x57, 0xbe, 0x6f, 0xe7, 0x21, 0x15, 0xac, 0xe4, 0x24, 0x68, 0xb4, + 0x4d, 0x2c, 0x67, 0x5c, 0x1e, 0xcc, 0x3b, 0xab, 0xfb, 0xb2, 0x6d, 0xb3, + 0x6f, 0x73, 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0xa7, 0x36, 0x35, + 0x8d, 0x36, 0x6a, 0xed, 0xfd, 0x01, 0x8d, 0x36, 0xf7, 0x11, 0xfb, 0x3f, + 0xfb, 0x20, 0x9d, 0x0c, 0x1b, 0x41, 0x0e, 0x06, 0x9e, 0x35, 0x9e, 0xe7, + 0xa7, 0xc0, 0xf7, 0x3b, 0xe9, 0xa7, 0xe9, 0x67, 0x0c, 0xe8, 0xe7, 0x91, + 0x6d, 0xfa, 0x21, 0xdd, 0x74, 0xca, 0xd8, 0x35, 0x5b, 0x26, 0x8a, 0xfa, + 0xbe, 0x81, 0x35, 0xe9, 0x3f, 0x3a, 0x0e, 0xba, 0x21, 0xad, 0x93, 0xb7, + 0x4c, 0x29, 0x83, 0x8e, 0xca, 0x90, 0x4f, 0x65, 0xd0, 0x14, 0x31, 0x50, + 0x19, 0xf2, 0xad, 0x5c, 0xb7, 0x9c, 0x2a, 0xf6, 0x4c, 0x9d, 0xbd, 0x02, + 0x3a, 0xba, 0x5e, 0xe7, 0xfd, 0xeb, 0x35, 0x9b, 0xd4, 0x83, 0xb7, 0xb6, + 0xef, 0xfe, 0xef, 0xb8, 0xfb, 0x43, 0x72, 0x03, 0x76, 0xcb, 0x9b, 0xa5, + 0x61, 0xc8, 0x24, 0x21, 0x5e, 0x04, 0x6d, 0x8c, 0xca, 0x6a, 0xe9, 0xa4, + 0xac, 0x41, 0x3f, 0xad, 0x2f, 0x0d, 0x00, 0x4f, 0x43, 0x8e, 0xbe, 0x72, + 0x44, 0xde, 0x58, 0x52, 0x32, 0x63, 0x43, 0xbf, 0x2c, 0xd3, 0x07, 0x0f, + 0x7a, 0x2e, 0x77, 0xea, 0x98, 0xfd, 0x58, 0x35, 0xf0, 0xc5, 0x8f, 0x57, + 0xbb, 0x64, 0xa2, 0x6a, 0xca, 0x63, 0xd5, 0x1e, 0x79, 0xa2, 0x1a, 0x93, + 0xd3, 0xb5, 0x84, 0x7c, 0xa3, 0x7a, 0x50, 0x4e, 0x55, 0x0f, 0xc9, 0x93, + 0xb5, 0xa4, 0x7c, 0x13, 0x76, 0x61, 0xae, 0xe6, 0xc8, 0x64, 0x6d, 0x58, + 0x1e, 0xaf, 0xd1, 0xc7, 0x8e, 0xf9, 0xf0, 0xcb, 0x6e, 0xfb, 0x2e, 0xb8, + 0xae, 0x0e, 0xac, 0xcb, 0x51, 0xe3, 0x3a, 0x66, 0x29, 0xb9, 0xc0, 0xff, + 0x21, 0x72, 0x0e, 0x7d, 0x2f, 0xbe, 0xa2, 0xa4, 0xa2, 0xe7, 0x6f, 0xfe, + 0xdf, 0x48, 0x54, 0xdb, 0x46, 0xe7, 0xca, 0x07, 0xd1, 0xc6, 0xa6, 0x4d, + 0x12, 0xfa, 0x41, 0x9a, 0xfe, 0xff, 0xa6, 0xed, 0x65, 0x68, 0x1f, 0xf6, + 0x2d, 0xda, 0x5e, 0xfa, 0xec, 0x29, 0x3f, 0x68, 0xe7, 0xd0, 0xd6, 0xda, + 0x19, 0xe7, 0x68, 0xce, 0x7b, 0x31, 0xf7, 0xf0, 0xff, 0xa7, 0x04, 0xf1, + 0xaa, 0xb3, 0xb5, 0x83, 0xfc, 0x3f, 0x15, 0xac, 0xe5, 0x8b, 0xf3, 0xc5, + 0x27, 0x4a, 0x63, 0xea, 0xb1, 0x12, 0x11, 0x8d, 0x2f, 0x17, 0xb7, 0x73, + 0xf2, 0xbe, 0x2e, 0xcb, 0x6e, 0x54, 0xaf, 0x21, 0xf0, 0xdb, 0xa7, 0x75, + 0x7e, 0xde, 0xd8, 0x10, 0xe9, 0x8f, 0x71, 0xb8, 0xae, 0x30, 0xb6, 0x00, + 0x6c, 0xeb, 0x9a, 0x72, 0xa9, 0x1a, 0xf8, 0xaf, 0xe6, 0x34, 0xbd, 0xbc, + 0x05, 0x9a, 0x63, 0xfc, 0x21, 0x78, 0xe6, 0xcb, 0x41, 0xdf, 0xec, 0x90, + 0x43, 0x7b, 0x1c, 0xfb, 0x35, 0x7a, 0x38, 0x17, 0xff, 0x4f, 0x07, 0xe5, + 0x70, 0xbd, 0xcc, 0x2f, 0xb6, 0x35, 0x2d, 0x06, 0x31, 0x5e, 0x47, 0x9e, + 0xc3, 0x5d, 0x54, 0x4c, 0xae, 0xbf, 0x43, 0x2a, 0x0e, 0x6d, 0x5b, 0xca, + 0xef, 0x21, 0x29, 0x63, 0x9e, 0x8a, 0xd3, 0xf4, 0x8d, 0x05, 0x72, 0xb6, + 0x62, 0x3e, 0x98, 0x77, 0xba, 0xbc, 0x1f, 0xef, 0xa8, 0x73, 0x80, 0x99, + 0xa6, 0xf8, 0x7e, 0x11, 0x65, 0xfa, 0x46, 0xe6, 0xf0, 0x4c, 0x84, 0x75, + 0xaf, 0xf5, 0x6b, 0xac, 0x7e, 0xf2, 0x41, 0xbf, 0x99, 0xb2, 0x95, 0xcf, + 0x44, 0xb6, 0x94, 0xf1, 0x8b, 0xf5, 0x7e, 0xca, 0xdc, 0xfd, 0x36, 0x7f, + 0x51, 0xf9, 0x8b, 0xa9, 0x7d, 0x0a, 0xe1, 0xb7, 0x3d, 0xf2, 0x94, 0xc9, + 0xdc, 0xf5, 0xb4, 0x1a, 0x2b, 0xfd, 0x34, 0xcc, 0xd3, 0xdd, 0x52, 0xfb, + 0x2b, 0x6f, 0xf7, 0x07, 0x79, 0xee, 0x1c, 0x7b, 0x67, 0x6e, 0xfb, 0x4e, + 0x3a, 0x61, 0x8e, 0x7b, 0x3b, 0x70, 0xab, 0x56, 0x62, 0xe0, 0x41, 0xc8, + 0x3b, 0xbb, 0x45, 0xf3, 0x63, 0xa1, 0xf6, 0x2f, 0x7f, 0x43, 0xf3, 0x73, + 0xd3, 0xc7, 0xf0, 0xdb, 0x7e, 0xda, 0xb6, 0x94, 0x1b, 0x97, 0x02, 0xbf, + 0x91, 0xb6, 0xa1, 0x21, 0x2b, 0x50, 0x47, 0x5e, 0x05, 0x9f, 0x6c, 0xb7, + 0xe5, 0xdf, 0x7f, 0x01, 0x99, 0xe7, 0xd3, 0x46, 0x40, 0x67, 0x00, 0x00, + 0x00 }; +static u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 }; +static u32 bnx2_RXP_b09FwRodata[(0x278/4) + 1] = { + 0x08003fa4, 0x08003ea4, 0x08003f48, 0x08003f60, 0x08003f78, 0x08003f98, + 0x08003fa4, 0x08003fa4, 0x08003eac, 0x00000000, 0x080049d4, 0x08004a0c, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004a44, 0x08004c08, + 0x08004b50, 0x08004b88, 0x08004c08, 0x08004ad8, 0x08004c08, 0x08004c08, + 0x08004b88, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004bc8, + 0x08004c08, 0x08004bc8, 0x08004b50, 0x08004c08, 0x08004c08, 0x08004bc8, + 0x08004bc8, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, 0x08004c08, + 0x08004ab4, 0x00000000, 0x0800602c, 0x08006044, 0x08006044, 0x08006044, + 0x0800602c, 0x08006044, 0x08006044, 0x08006044, 0x0800602c, 0x08006044, + 0x08006044, 0x08006044, 0x0800602c, 0x08006044, 0x08006044, 0x08006044, + 0x08006038, 0x00000000, 0x00000000 }; +static u32 bnx2_RXP_b09FwBss[(0x13dc/4) + 1] = { 0x0 }; +static u32 bnx2_RXP_b09FwSbss[(0x2c/4) + 1] = { 0x0 }; static struct fw_info bnx2_rxp_fw_09 = { - .ver_major = 0x3, - .ver_minor = 0x4, - .ver_fix = 0x3, + .ver_major = 0x1, + .ver_minor = 0x0, + .ver_fix = 0x0, .start_addr = 0x08003184, .text_addr = 0x08000000, - .text_len = 0x6768, + .text_len = 0x673c, .text_index = 0x0, .gz_text = bnx2_RXP_b09FwText, .gz_text_len = sizeof(bnx2_RXP_b09FwText), - .data_addr = 0x08006a00, + .data_addr = 0x080069e0, .data_len = 0x0, .data_index = 0x0, .data = bnx2_RXP_b09FwData, - .sbss_addr = 0x08006a00, - .sbss_len = 0x20, + .sbss_addr = 0x080069e0, + .sbss_len = 0x2c, .sbss_index = 0x0, .sbss = bnx2_RXP_b09FwSbss, - .bss_addr = 0x08006a20, + .bss_addr = 0x08006a10, .bss_len = 0x13dc, .bss_index = 0x0, .bss = bnx2_RXP_b09FwBss, - .rodata_addr = 0x08006768, + .rodata_addr = 0x08006740, .rodata_len = 0x278, .rodata_index = 0x0, .rodata = bnx2_RXP_b09FwRodata, }; static u8 bnx2_TPAT_b09FwText[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xcd, 0x58, - 0x5d, 0x68, 0x1c, 0xd7, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0x52, 0x24, 0xeb, - 0x5a, 0xd9, 0xa6, 0xeb, 0xa0, 0x34, 0x33, 0xda, 0x91, 0xac, 0x22, 0x13, - 0x4f, 0x9d, 0x25, 0x16, 0x65, 0x21, 0x93, 0xd9, 0x91, 0xac, 0x98, 0x3c, - 0x28, 0xc5, 0x90, 0x87, 0x52, 0x50, 0x57, 0x32, 0x09, 0x79, 0x69, 0xda, - 0xc6, 0x90, 0x3e, 0x79, 0x3b, 0x2b, 0xc7, 0x0e, 0x6c, 0xbc, 0x8d, 0x52, - 0xe4, 0x52, 0xfa, 0x60, 0xd6, 0xb1, 0x05, 0xcd, 0x46, 0x93, 0xd4, 0x7e, - 0x35, 0x36, 0x4e, 0x93, 0xa7, 0x42, 0x9f, 0x52, 0xf4, 0x18, 0xd2, 0x12, - 0xda, 0x52, 0x8a, 0x69, 0xa1, 0x09, 0x8d, 0xeb, 0xdb, 0xef, 0xdc, 0x99, - 0x91, 0x57, 0xb6, 0xec, 0xa4, 0x25, 0x85, 0x0a, 0x56, 0x77, 0xe6, 0xce, - 0x3d, 0xe7, 0x9e, 0x7b, 0xee, 0x77, 0xbe, 0x73, 0xee, 0x2d, 0xeb, 0x34, - 0x48, 0xd9, 0xdf, 0x30, 0x7e, 0x2f, 0x7e, 0xf7, 0x85, 0x17, 0xab, 0x8f, - 0x3c, 0xea, 0x10, 0x3d, 0xfa, 0x88, 0x66, 0x98, 0x06, 0x7d, 0x09, 0x7f, - 0x50, 0x22, 0x72, 0xfd, 0xfc, 0x23, 0x5b, 0xaf, 0x9d, 0x72, 0x42, 0x8f, - 0x6c, 0xa3, 0x26, 0xbe, 0xbe, 0xe4, 0x11, 0x05, 0xbd, 0x69, 0xa7, 0x4e, - 0xff, 0x92, 0xcd, 0x92, 0x49, 0xdc, 0xff, 0x50, 0xed, 0xc6, 0xfe, 0xcb, - 0x07, 0xdd, 0xeb, 0x67, 0x0d, 0xb2, 0x45, 0x6d, 0xd1, 0x16, 0x93, 0x64, - 0x8f, 0xd5, 0x9a, 0xce, 0x2f, 0xf6, 0x1e, 0x28, 0xd0, 0xae, 0x5c, 0x97, - 0xa0, 0xb8, 0x43, 0x4d, 0xab, 0x66, 0x53, 0xd4, 0x7e, 0x49, 0x0b, 0x3b, - 0x9e, 0x98, 0x85, 0x8e, 0xa0, 0x04, 0xfd, 0x1e, 0xde, 0x13, 0x53, 0x8b, - 0xce, 0xd8, 0xa4, 0xd7, 0x02, 0x3c, 0x4f, 0x51, 0xab, 0x23, 0xe5, 0x2b, - 0xbe, 0x46, 0x4b, 0xbe, 0x4d, 0x8b, 0xc2, 0x0d, 0x1c, 0xed, 0xa6, 0xac, - 0x4c, 0x48, 0xf9, 0x9c, 0xaf, 0x93, 0xee, 0xcd, 0x69, 0xe1, 0xfa, 0xbc, - 0x56, 0x5f, 0x9f, 0x67, 0x7f, 0xc0, 0xbe, 0x39, 0x2d, 0x58, 0xe7, 0xb6, - 0x66, 0xd7, 0xdb, 0xbb, 0x68, 0xb1, 0x44, 0x23, 0xba, 0x37, 0x85, 0xf9, - 0x4a, 0xd0, 0xe3, 0x50, 0xe8, 0x4f, 0x0b, 0x9d, 0x2a, 0xf8, 0x0d, 0xd0, - 0xac, 0x4f, 0x03, 0xba, 0xa7, 0x53, 0xa3, 0xa4, 0xd1, 0x1b, 0x55, 0x0b, - 0xbf, 0xc3, 0x5a, 0xb4, 0xfe, 0x7c, 0xa6, 0x87, 0xc7, 0xdb, 0xf8, 0xc6, - 0x36, 0xb3, 0x7c, 0xbf, 0xec, 0x30, 0x9e, 0x9f, 0xc3, 0x38, 0x8b, 0xc2, - 0xea, 0xed, 0xdf, 0x06, 0xf0, 0xac, 0xa1, 0xff, 0x30, 0xec, 0x62, 0x3d, - 0x0e, 0xec, 0x28, 0xd3, 0x4a, 0x67, 0x1e, 0xeb, 0x29, 0x50, 0x53, 0x4c, - 0x4c, 0x35, 0xc8, 0x84, 0x8c, 0x41, 0x41, 0xe9, 0x8a, 0xd4, 0x6b, 0x52, - 0x86, 0x55, 0x6f, 0xaa, 0xab, 0xe6, 0xd0, 0xc9, 0xf0, 0x0a, 0x14, 0xf9, - 0xc3, 0xd4, 0x12, 0x06, 0xc5, 0xfb, 0x2c, 0x0a, 0x16, 0x4c, 0xac, 0x71, - 0x14, 0x72, 0x1a, 0xe4, 0x5f, 0xcb, 0xf6, 0xbc, 0x48, 0xb1, 0x28, 0xa0, - 0x7f, 0x84, 0xe2, 0xd2, 0x6e, 0x4d, 0xaf, 0xbd, 0x82, 0xfe, 0x09, 0xd1, - 0xa5, 0x53, 0x68, 0x35, 0xbc, 0xef, 0xc6, 0x58, 0x7e, 0xd7, 0xa0, 0x8f, - 0x44, 0x98, 0x78, 0xd4, 0x4a, 0x72, 0x59, 0xee, 0x4f, 0xfb, 0x9a, 0xc9, - 0xed, 0xfb, 0xed, 0xc1, 0x4e, 0x41, 0x27, 0x3a, 0xb3, 0x98, 0x8f, 0x9a, - 0x46, 0x0d, 0xe3, 0xb0, 0x37, 0xbc, 0xbf, 0x81, 0xc2, 0xc1, 0xe3, 0xdc, - 0xcf, 0x7f, 0xe8, 0x77, 0xc8, 0xa8, 0xf1, 0xb7, 0x6f, 0x52, 0xfa, 0x2d, - 0xb5, 0x3f, 0xf4, 0x1f, 0xcb, 0xde, 0x4b, 0x22, 0x3c, 0xf3, 0x28, 0xd6, - 0xa8, 0x60, 0x83, 0xe7, 0x02, 0xf0, 0x11, 0xcf, 0xe8, 0xd4, 0x2c, 0x17, - 0xc9, 0xf5, 0x8f, 0xa2, 0xf7, 0xd7, 0x6d, 0x83, 0xea, 0xec, 0x2b, 0xdf, - 0xcc, 0x64, 0x18, 0x1b, 0x1f, 0x64, 0x76, 0x0a, 0x5a, 0x3c, 0x22, 0xe5, - 0x8a, 0x2f, 0xa5, 0x55, 0xf3, 0x9c, 0x13, 0x34, 0x5d, 0x36, 0x69, 0x52, - 0xa0, 0x85, 0x8f, 0xbd, 0x72, 0x83, 0x2c, 0x60, 0xa1, 0x1f, 0xff, 0xfc, - 0xf7, 0xa6, 0x86, 0x25, 0xd0, 0xb5, 0x36, 0xeb, 0x98, 0x70, 0x66, 0x95, - 0x8c, 0x94, 0xf1, 0xcc, 0xbd, 0x64, 0x2e, 0x65, 0x32, 0x52, 0x46, 0x55, - 0x81, 0x3d, 0x6f, 0x0a, 0xd8, 0x87, 0x75, 0x31, 0xc6, 0x89, 0xa2, 0x9e, - 0x6f, 0x37, 0xda, 0xb0, 0xd1, 0x43, 0xdb, 0x13, 0xf0, 0x0f, 0x51, 0x0b, - 0x63, 0xf5, 0xea, 0x7d, 0x8c, 0x0d, 0xec, 0xef, 0x82, 0x1d, 0xb5, 0xdd, - 0xf2, 0x29, 0x5a, 0xb0, 0xeb, 0xbd, 0xe9, 0xf2, 0x32, 0x3d, 0xc4, 0x73, - 0xd8, 0x56, 0xed, 0x88, 0xdd, 0x55, 0x72, 0x88, 0xc4, 0x41, 0x3c, 0xf7, - 0x88, 0xe2, 0x36, 0x69, 0xa1, 0x7f, 0x1f, 0xaf, 0x15, 0x72, 0xf3, 0x99, - 0xdc, 0x7c, 0x26, 0x37, 0x92, 0xc9, 0x3d, 0xd5, 0x27, 0xf7, 0x14, 0xcb, - 0x61, 0x6c, 0x90, 0x8d, 0x0d, 0xb2, 0xb1, 0x66, 0x36, 0x36, 0xca, 0xc6, - 0xa2, 0xed, 0x8d, 0xc1, 0x36, 0x77, 0xca, 0xd1, 0x6c, 0x8a, 0x3d, 0xf9, - 0x70, 0xe8, 0x53, 0x50, 0xf7, 0xdc, 0xcd, 0xba, 0x31, 0x42, 0xe7, 0xfc, - 0x21, 0x5a, 0x49, 0xc6, 0x28, 0x4e, 0x56, 0x28, 0x4c, 0x74, 0xc8, 0x8e, - 0x50, 0xd7, 0xbb, 0x2e, 0x67, 0x7d, 0x1f, 0x7b, 0x66, 0xb3, 0x5c, 0x79, - 0x96, 0x1c, 0x7c, 0x9f, 0x16, 0xcb, 0xe4, 0x03, 0x2b, 0x3a, 0xf6, 0xad, - 0xa2, 0x9e, 0xe3, 0xc4, 0xe7, 0x35, 0x37, 0xf5, 0xaa, 0x2b, 0x62, 0x72, - 0xcb, 0xa1, 0x41, 0x42, 0xaf, 0xc1, 0x4f, 0x49, 0x93, 0xa2, 0xc4, 0xa6, - 0x0f, 0x8d, 0x97, 0x54, 0x8c, 0xc6, 0x9d, 0x4d, 0x79, 0x79, 0xaf, 0x43, - 0x57, 0x30, 0xcf, 0xc5, 0xa4, 0x4c, 0xbf, 0x4a, 0x4a, 0xf4, 0x4e, 0x42, - 0x7a, 0xe8, 0x03, 0xc3, 0x25, 0x41, 0x6f, 0x27, 0xfd, 0x3e, 0xff, 0x88, - 0x7d, 0x6e, 0xdf, 0x5f, 0x23, 0x7b, 0xb4, 0xc6, 0x38, 0x4b, 0x39, 0xa0, - 0x9e, 0x72, 0x80, 0xc2, 0x52, 0xab, 0x13, 0x3f, 0x68, 0x80, 0x7f, 0x96, - 0xfc, 0x60, 0xb7, 0xa1, 0xf6, 0xa3, 0x89, 0x3d, 0xcc, 0x5b, 0xde, 0x9b, - 0xab, 0xce, 0x92, 0xe7, 0x9e, 0xaa, 0x33, 0x6a, 0x4f, 0x5b, 0x39, 0x2e, - 0xfb, 0xe6, 0xf8, 0x33, 0xe6, 0x18, 0xa2, 0x06, 0xe2, 0xec, 0x09, 0x13, - 0xb1, 0xe3, 0xfd, 0xdd, 0x60, 0x5c, 0x39, 0x1b, 0x8c, 0x6f, 0xa2, 0xf1, - 0x0d, 0x9b, 0xd6, 0xdb, 0x45, 0x72, 0xba, 0x43, 0xb4, 0xd4, 0x19, 0xa4, - 0xca, 0x05, 0x13, 0x63, 0xef, 0xa3, 0xca, 0xaa, 0x5e, 0xe2, 0x38, 0xae, - 0xc3, 0xc7, 0xe3, 0x5d, 0x09, 0x7c, 0x0e, 0xd2, 0xf8, 0x9a, 0xab, 0xb0, - 0xb3, 0xe4, 0xb5, 0x7c, 0x83, 0x7e, 0x4c, 0xd7, 0xf6, 0x15, 0xb0, 0xa6, - 0x12, 0xf9, 0x93, 0xfd, 0xf3, 0xe9, 0x80, 0x18, 0xf7, 0xc5, 0x45, 0xda, - 0xe5, 0x3a, 0xa4, 0xb3, 0x3e, 0x9b, 0xc6, 0x2f, 0xd8, 0x5a, 0xbd, 0xc3, - 0x3e, 0x63, 0xfc, 0xd9, 0x19, 0xfe, 0x4c, 0x2d, 0x3c, 0x53, 0xc4, 0x5c, - 0x7f, 0x91, 0xa1, 0x27, 0xb1, 0x0f, 0x3a, 0x2d, 0x55, 0x7f, 0x04, 0xfb, - 0xd0, 0xd7, 0xe5, 0x6f, 0xd7, 0xb3, 0x7e, 0xd6, 0x01, 0x7e, 0xf0, 0xef, - 0xa7, 0x90, 0xb9, 0xe0, 0x08, 0xcb, 0x14, 0x69, 0x7c, 0x95, 0xf9, 0x05, - 0x6d, 0x97, 0xdf, 0x79, 0x6d, 0x03, 0xd4, 0x80, 0x57, 0x1a, 0x53, 0x25, - 0xd8, 0xa5, 0x2b, 0xbe, 0x68, 0x80, 0x3f, 0x74, 0x6f, 0x10, 0x2d, 0xcf, - 0xf7, 0x73, 0x23, 0x8f, 0xa9, 0xb8, 0x33, 0x44, 0x75, 0xe0, 0xd7, 0x84, - 0x3d, 0xcb, 0x34, 0x51, 0x3e, 0xaa, 0xbe, 0xa1, 0xaf, 0xc7, 0xdf, 0xc4, - 0x6d, 0xdf, 0xf0, 0xde, 0xcb, 0x6d, 0x40, 0x6c, 0x7b, 0x2d, 0xcc, 0x62, - 0x65, 0x7e, 0xe1, 0xf1, 0xcd, 0x32, 0xf6, 0x06, 0x7c, 0x46, 0xf0, 0x25, - 0x51, 0xb7, 0x6d, 0x82, 0x6f, 0xf4, 0xaf, 0xea, 0x2c, 0x57, 0x62, 0x3d, - 0x58, 0xff, 0x9a, 0xa9, 0xd5, 0xcf, 0x78, 0xce, 0x1f, 0x88, 0xe5, 0x2b, - 0xf0, 0xc1, 0xc4, 0x4c, 0x8b, 0xc7, 0xf7, 0x2c, 0xf2, 0x56, 0x9b, 0xc2, - 0xc4, 0x9e, 0xc2, 0x73, 0x54, 0xff, 0xc9, 0x08, 0xf6, 0xda, 0x75, 0x5a, - 0xf4, 0x5b, 0xd8, 0x53, 0x20, 0xaf, 0x6b, 0xd2, 0x1b, 0x6d, 0xf6, 0x85, - 0x4d, 0x95, 0x35, 0x29, 0x4f, 0xfa, 0xbc, 0x27, 0xbf, 0x83, 0x5f, 0x08, - 0x2b, 0x9c, 0x98, 0xf9, 0x08, 0xfb, 0xb3, 0xde, 0xe3, 0xbd, 0xb1, 0x94, - 0x4f, 0xbc, 0xd5, 0x29, 0xec, 0xeb, 0x54, 0x66, 0x23, 0xef, 0x97, 0x49, - 0x2b, 0x55, 0x9d, 0xce, 0x57, 0x3f, 0x93, 0xba, 0xc7, 0xfc, 0x5a, 0x80, - 0x6f, 0x31, 0xae, 0x8b, 0x71, 0x49, 0x01, 0x3e, 0xfc, 0x07, 0x78, 0x45, - 0xca, 0xf3, 0x55, 0xf4, 0xaf, 0x1e, 0x87, 0xad, 0x06, 0x64, 0x53, 0x8c, - 0xb1, 0x3d, 0x73, 0xed, 0x7c, 0x7d, 0xde, 0xcc, 0x7b, 0x4a, 0xdf, 0x10, - 0x4d, 0x6e, 0x0c, 0xd1, 0xb3, 0xbd, 0x21, 0x1a, 0x3f, 0xcd, 0x32, 0xe0, - 0xa6, 0xaa, 0x27, 0x22, 0xc6, 0xa8, 0xa7, 0xfc, 0x50, 0x36, 0x74, 0x5e, - 0x27, 0xbe, 0x6f, 0x10, 0x2d, 0xf7, 0x78, 0x0e, 0xb3, 0x4f, 0xa7, 0x4e, - 0x87, 0x7e, 0x4a, 0x74, 0xa8, 0xc7, 0xb2, 0x5b, 0xbe, 0x83, 0x5e, 0x01, - 0x9d, 0x82, 0x38, 0x0f, 0x19, 0x1e, 0xf2, 0xdd, 0x7a, 0x88, 0xfc, 0x15, - 0xe1, 0x37, 0x87, 0x9c, 0xc6, 0xeb, 0x9f, 0x42, 0xfc, 0x31, 0x8f, 0xdf, - 0xc4, 0xda, 0x0b, 0xb4, 0xe2, 0xcf, 0x63, 0x0c, 0xef, 0xf1, 0x61, 0x7c, - 0x1f, 0x46, 0x1e, 0xc8, 0xf2, 0x84, 0xe0, 0x3c, 0xb1, 0x1b, 0x71, 0x30, - 0x00, 0xee, 0xdf, 0x63, 0x6e, 0xcf, 0x13, 0x18, 0x57, 0xda, 0x83, 0xbc, - 0x70, 0x3f, 0xfa, 0x59, 0xd7, 0x28, 0xda, 0x01, 0xbc, 0xef, 0xc1, 0xd8, - 0xfe, 0x1c, 0x91, 0xcb, 0xdd, 0x2d, 0x3f, 0x20, 0x26, 0x56, 0x11, 0x2b, - 0x6b, 0x9c, 0x27, 0x38, 0x16, 0x79, 0x4f, 0x8b, 0xe0, 0x6f, 0x1b, 0x3a, - 0x78, 0x6f, 0x8b, 0xd8, 0x43, 0xce, 0x71, 0x82, 0x2a, 0x1b, 0x3b, 0xe5, - 0x0f, 0x5e, 0x0f, 0x38, 0xec, 0x34, 0xaf, 0xc5, 0x15, 0x0d, 0xf0, 0x59, - 0xb8, 0x31, 0x8d, 0xef, 0xc8, 0x85, 0x22, 0xb2, 0x1b, 0xa7, 0x53, 0x2e, - 0x6b, 0x6c, 0x8c, 0x29, 0x9c, 0xc6, 0x89, 0xc0, 0x3b, 0x73, 0x59, 0xce, - 0x5d, 0x8c, 0x25, 0x0a, 0x20, 0xbb, 0x19, 0x1a, 0x52, 0x2e, 0xf9, 0x23, - 0xd4, 0x00, 0x2e, 0x03, 0xf0, 0x59, 0x03, 0x7c, 0x56, 0xef, 0xe3, 0xb3, - 0xfa, 0xe7, 0xf2, 0x19, 0xb8, 0xaa, 0x03, 0xae, 0xea, 0x80, 0xab, 0x50, - 0x1b, 0xbc, 0x03, 0xec, 0xbf, 0xdd, 0xd9, 0x89, 0xe3, 0x98, 0xdf, 0x98, - 0xe7, 0xa6, 0xe8, 0xf2, 0xde, 0xff, 0x94, 0xe7, 0x8e, 0x83, 0x13, 0x6c, - 0xfa, 0xfe, 0xde, 0x7b, 0x73, 0xdd, 0x09, 0x70, 0x9d, 0xf5, 0xf9, 0x5c, - 0xd7, 0x64, 0xae, 0x33, 0x81, 0xbd, 0x26, 0x78, 0x40, 0x5f, 0xed, 0x9f, - 0xe7, 0x24, 0xe6, 0xe1, 0x3e, 0x33, 0xcb, 0xa5, 0x3a, 0x75, 0x81, 0x7b, - 0xc3, 0xe3, 0x79, 0x60, 0x73, 0x92, 0x72, 0xd1, 0x13, 0x66, 0x89, 0xac, - 0x49, 0xe0, 0x61, 0x75, 0x88, 0x8c, 0xd3, 0xb7, 0xf0, 0x8e, 0x7a, 0x00, - 0x71, 0x8e, 0x7f, 0x1b, 0xb9, 0x8e, 0x41, 0x70, 0x8d, 0x49, 0x85, 0x55, - 0x0b, 0xef, 0xda, 0xb6, 0x71, 0x87, 0x90, 0x6f, 0x8c, 0x9a, 0x3b, 0xf3, - 0x7b, 0x7e, 0xee, 0xf1, 0x98, 0x41, 0xd2, 0xd7, 0x5c, 0xc7, 0xd1, 0x5d, - 0xff, 0x1a, 0xb8, 0xe1, 0x7d, 0x8f, 0xf9, 0x2f, 0x06, 0x0a, 0x0a, 0x64, - 0xae, 0xca, 0xe3, 0x56, 0x8d, 0xe7, 0x6e, 0x3a, 0x88, 0x73, 0xe7, 0x35, - 0xe0, 0x87, 0x73, 0xe7, 0xf9, 0x2a, 0xd7, 0x7b, 0x69, 0x8c, 0xb6, 0x7a, - 0xf9, 0x9c, 0xa3, 0xb0, 0xdb, 0x82, 0x4c, 0xff, 0x58, 0xc6, 0x8b, 0x94, - 0xcf, 0x62, 0x4d, 0x06, 0xe6, 0xb1, 0xd6, 0x6c, 0x2a, 0xac, 0xb1, 0x5f, - 0x5c, 0xc8, 0x57, 0xc4, 0x1c, 0x6d, 0x6e, 0xe3, 0x83, 0x93, 0xbd, 0x0f, - 0x4c, 0xe6, 0x50, 0x03, 0xb1, 0x59, 0xc4, 0xbc, 0xd6, 0x96, 0x2e, 0xca, - 0x74, 0xb1, 0xbc, 0x57, 0x7e, 0x76, 0x4b, 0x9e, 0x79, 0x6d, 0xa2, 0xcc, - 0xfc, 0xc5, 0x76, 0x18, 0x8a, 0x4b, 0x07, 0x33, 0x2e, 0xad, 0x60, 0x3f, - 0x07, 0x55, 0x5c, 0xea, 0xde, 0xc3, 0x19, 0x9f, 0xee, 0x46, 0xcb, 0x7d, - 0x37, 0xb2, 0x38, 0x31, 0x61, 0x2f, 0xeb, 0x1d, 0x24, 0x03, 0x76, 0x45, - 0x6a, 0x4d, 0x7f, 0x93, 0x4b, 0x1e, 0x73, 0x04, 0xe3, 0x53, 0x71, 0x29, - 0xfa, 0x27, 0x60, 0x33, 0xf3, 0x02, 0xcb, 0xb1, 0xfc, 0x4e, 0x72, 0x7f, - 0x85, 0x9c, 0xd8, 0x41, 0x0e, 0x7d, 0x1b, 0x2c, 0xc3, 0xdc, 0x30, 0x8a, - 0xf1, 0x21, 0xf3, 0x02, 0x7c, 0xc6, 0xb2, 0xe5, 0x2c, 0x0e, 0x23, 0x7c, - 0xe3, 0xba, 0x97, 0xe3, 0x23, 0x20, 0xab, 0xc6, 0xeb, 0xe0, 0x9a, 0x98, - 0xf3, 0x22, 0xd7, 0xa1, 0x5c, 0x6f, 0xe6, 0xf5, 0xa9, 0x37, 0x35, 0x7b, - 0xb7, 0x5a, 0x53, 0xf4, 0xd7, 0x9a, 0xe8, 0xd8, 0xb1, 0xd6, 0xf4, 0xac, - 0xb4, 0xd6, 0xac, 0x58, 0x77, 0xaf, 0x35, 0x73, 0xd9, 0x7b, 0xd7, 0x9a, - 0x71, 0x87, 0xf7, 0x08, 0xb9, 0x54, 0xf0, 0x5a, 0xa8, 0x69, 0x66, 0x7c, - 0x11, 0xdd, 0xc6, 0x17, 0xd1, 0x69, 0xb7, 0x7c, 0x8e, 0x38, 0xa6, 0xdd, - 0x72, 0x8b, 0x6b, 0xa0, 0x0d, 0xae, 0x81, 0x0c, 0xe4, 0xd2, 0x7e, 0xce, - 0xc8, 0x7d, 0xc2, 0xbe, 0x1c, 0x04, 0x27, 0xb3, 0x1f, 0x8b, 0x19, 0x3f, - 0xa0, 0xf5, 0x3e, 0x05, 0x3f, 0xe4, 0xbc, 0xc2, 0x3e, 0xfb, 0x7f, 0xe2, - 0x15, 0xb2, 0x07, 0xc0, 0x0f, 0x36, 0xea, 0xcd, 0x46, 0x47, 0xd9, 0x02, - 0x5f, 0x48, 0x39, 0xe7, 0x33, 0xf6, 0x53, 0xbe, 0x50, 0x3e, 0x51, 0x78, - 0x2c, 0xd2, 0xbb, 0x3e, 0x63, 0x01, 0xe7, 0x23, 0x8f, 0x73, 0x22, 0xf3, - 0xef, 0x4d, 0xf9, 0xae, 0x17, 0xa2, 0x2f, 0xc2, 0x9e, 0x33, 0x0e, 0xe6, - 0xb5, 0x43, 0xeb, 0x36, 0xe4, 0x18, 0x0b, 0xe5, 0x3b, 0xce, 0x3d, 0xe9, - 0xf9, 0x84, 0x6b, 0xe1, 0xff, 0x16, 0x1b, 0x17, 0xef, 0x82, 0x8d, 0x37, - 0x33, 0x6c, 0xfc, 0xf2, 0x1e, 0xd8, 0xb8, 0xf8, 0x05, 0xb1, 0xe1, 0x3a, - 0x1f, 0xa3, 0x5e, 0x7a, 0xcf, 0x63, 0x7c, 0x48, 0xf9, 0xb1, 0xbf, 0x53, - 0x3e, 0x09, 0x6c, 0xe3, 0xd5, 0x9b, 0x32, 0xce, 0x72, 0x89, 0xfe, 0xd6, - 0xad, 0x5c, 0x32, 0xfe, 0x6a, 0x8a, 0x8b, 0xf1, 0xb7, 0xa4, 0x3c, 0xb7, - 0x03, 0x0e, 0xb8, 0x56, 0xbe, 0x0a, 0x1e, 0x68, 0xd1, 0xff, 0xa2, 0x56, - 0x66, 0xce, 0xae, 0xda, 0x47, 0xdb, 0xf9, 0xbe, 0xe7, 0x7b, 0x5e, 0xa0, - 0xb3, 0x62, 0x17, 0xfc, 0xb5, 0x9f, 0x5a, 0xaf, 0x9b, 0x7c, 0x7e, 0x00, - 0x1e, 0x1e, 0x37, 0x39, 0x56, 0x71, 0x56, 0xc4, 0x73, 0x7f, 0x3d, 0x0d, - 0x3c, 0xfa, 0xbc, 0x76, 0xb5, 0xee, 0x3e, 0xae, 0xff, 0x1e, 0x4a, 0x92, - 0x3b, 0xf2, 0xc8, 0xb6, 0x73, 0xb3, 0x81, 0x73, 0x73, 0x5d, 0xe9, 0xe0, - 0xb3, 0x55, 0xea, 0xbf, 0x13, 0xea, 0xac, 0x7c, 0x53, 0x9e, 0x53, 0xe7, - 0xe5, 0xd1, 0x02, 0x0d, 0xce, 0x67, 0x58, 0x61, 0x5f, 0x0c, 0xab, 0x7a, - 0x82, 0x31, 0xd5, 0x42, 0xbe, 0x5d, 0x82, 0x3f, 0x1a, 0x2a, 0x16, 0xb0, - 0xf6, 0xcc, 0x1f, 0x2d, 0xf8, 0xa3, 0x9e, 0xa4, 0x31, 0xf1, 0xe5, 0x9e, - 0x1d, 0xfe, 0x88, 0x7c, 0x6a, 0x2f, 0x9a, 0x38, 0x6f, 0x5f, 0x49, 0x54, - 0xfe, 0x5c, 0x68, 0xb5, 0xa9, 0xf9, 0x60, 0xed, 0x38, 0xd7, 0x6d, 0x5c, - 0x77, 0xcd, 0x2c, 0x55, 0xd1, 0xd7, 0xb3, 0x29, 0x84, 0x4f, 0xbe, 0x7d, - 0x90, 0x16, 0x8d, 0x1a, 0xe3, 0x17, 0xef, 0x09, 0x35, 0xc3, 0x83, 0xa8, - 0xa5, 0x92, 0xb1, 0x45, 0xbd, 0x36, 0x06, 0x1c, 0x35, 0x29, 0x80, 0x9d, - 0x01, 0x74, 0xcf, 0xb5, 0x6d, 0x7b, 0xb9, 0xcd, 0x67, 0xa4, 0x26, 0xf1, - 0x19, 0xbc, 0xdb, 0xbb, 0x0e, 0x7d, 0x03, 0xcf, 0xe0, 0xcc, 0xea, 0xc4, - 0xc0, 0xd5, 0xcb, 0x89, 0x45, 0xad, 0x12, 0xdf, 0x51, 0x30, 0x57, 0x96, - 0xa1, 0xe3, 0x99, 0x42, 0x8a, 0xcb, 0x32, 0xf4, 0x70, 0xcc, 0x10, 0xe6, - 0x63, 0xff, 0xe5, 0x58, 0x2b, 0xf7, 0xd5, 0xee, 0x85, 0xec, 0xbc, 0x4a, - 0xca, 0x07, 0xec, 0xdf, 0xd0, 0x7b, 0xbe, 0x90, 0xdf, 0xc7, 0xb4, 0x10, - 0xf3, 0x8d, 0x7d, 0x8c, 0x43, 0x0d, 0x78, 0xc3, 0x98, 0x84, 0xfb, 0x90, - 0x57, 0xf6, 0x21, 0x37, 0x97, 0x8a, 0xaa, 0x6d, 0x26, 0xc7, 0xb2, 0xf1, - 0xba, 0x1a, 0xc7, 0x39, 0x21, 0x4e, 0xd4, 0x59, 0x41, 0x8b, 0x3a, 0xe4, - 0x34, 0x7c, 0x9c, 0x81, 0x50, 0x5b, 0xac, 0x24, 0x9c, 0xcf, 0xf7, 0xd9, - 0xba, 0xe2, 0xb9, 0x4d, 0xc8, 0xe0, 0x79, 0x83, 0xf4, 0x86, 0xcf, 0xf7, - 0x07, 0xd9, 0xdd, 0x46, 0x89, 0x86, 0x21, 0x0f, 0xbb, 0xc6, 0xd8, 0xae, - 0xa0, 0xa1, 0x6a, 0x11, 0xd6, 0xbd, 0x5f, 0x4f, 0xef, 0x5c, 0x7e, 0x93, - 0xcd, 0x65, 0x83, 0x5f, 0x08, 0xe7, 0x1d, 0x9f, 0xf3, 0xda, 0xd7, 0x0c, - 0xba, 0x4e, 0x8a, 0x23, 0xc5, 0x37, 0x90, 0xef, 0x0e, 0x42, 0x26, 0x50, - 0xfc, 0x92, 0x9e, 0x19, 0x72, 0x99, 0x8a, 0xb1, 0x5d, 0xc7, 0x77, 0xcc, - 0xed, 0xef, 0x01, 0x62, 0xab, 0x9a, 0xcd, 0xd7, 0x8f, 0xd3, 0x4d, 0xe0, - 0x74, 0xb3, 0xb0, 0x75, 0xee, 0x28, 0x15, 0x30, 0x8e, 0x6d, 0x64, 0x2e, - 0x61, 0x99, 0x4f, 0xac, 0xed, 0x7a, 0x2a, 0x3b, 0xe8, 0xf8, 0x53, 0x9f, - 0x8e, 0x12, 0xaf, 0x4d, 0x34, 0xd2, 0xf3, 0xb3, 0xfa, 0x6b, 0xc0, 0xcf, - 0x38, 0x6f, 0x3c, 0xa0, 0x63, 0x1d, 0x5c, 0x7f, 0xd5, 0x55, 0x3f, 0x0e, - 0x56, 0xdb, 0xf4, 0xfe, 0x30, 0x9b, 0x67, 0x5f, 0x1a, 0x0f, 0x1e, 0xda, - 0x64, 0xb3, 0xcf, 0x76, 0x6b, 0x87, 0x79, 0x91, 0xd8, 0xbd, 0x19, 0x8d, - 0xf1, 0x66, 0xd4, 0x38, 0x07, 0xe3, 0x79, 0x0b, 0x1f, 0x8c, 0xd5, 0xcf, - 0xc7, 0xa8, 0xf5, 0x05, 0x31, 0xfa, 0x46, 0x9b, 0xb9, 0x22, 0xc5, 0x68, - 0xe3, 0x0e, 0x8c, 0xa2, 0x06, 0x2a, 0xe5, 0xf8, 0xe4, 0x78, 0xc9, 0xf1, - 0x99, 0x3f, 0xf3, 0xfd, 0x08, 0x38, 0x38, 0xe3, 0xb6, 0x18, 0xdc, 0x16, - 0xa9, 0x1c, 0xe7, 0x96, 0x23, 0x4a, 0xe3, 0x78, 0x19, 0x71, 0x1c, 0x19, - 0x9c, 0xf3, 0x38, 0x86, 0x59, 0x8e, 0xe3, 0x98, 0xe5, 0x46, 0x32, 0x39, - 0xb4, 0x88, 0xe7, 0x28, 0x8b, 0xe7, 0x16, 0x78, 0x37, 0xca, 0xe2, 0xb9, - 0x85, 0x18, 0x5e, 0xc9, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0xdf, 0xdb, 0x19, - 0x55, 0x95, 0x8b, 0x9d, 0x3a, 0x78, 0x6d, 0x45, 0xe9, 0x6c, 0x62, 0x9d, - 0xb0, 0xb1, 0x93, 0xc7, 0xc5, 0x1d, 0xf7, 0x5b, 0x58, 0xcf, 0xad, 0xbc, - 0x32, 0x8b, 0xbc, 0x72, 0x0e, 0x79, 0xa5, 0xdb, 0x77, 0xbf, 0x75, 0x56, - 0xe5, 0x95, 0x27, 0x8b, 0x79, 0x5e, 0xe9, 0x66, 0x79, 0xa5, 0xab, 0xf2, - 0xca, 0x13, 0x45, 0xce, 0x2b, 0x31, 0x05, 0xc5, 0xfe, 0xbc, 0x12, 0x6f, - 0xcb, 0x2b, 0xb9, 0x2c, 0xf7, 0xef, 0x94, 0x57, 0x72, 0x9f, 0x71, 0x6e, - 0xb1, 0x72, 0x5e, 0xbd, 0x2d, 0x9f, 0xe4, 0x63, 0xd8, 0x56, 0xe6, 0x25, - 0xe6, 0xe0, 0xb4, 0xae, 0xbf, 0x92, 0xe4, 0xb1, 0x74, 0x0c, 0xf3, 0xe0, - 0xbd, 0xb3, 0x53, 0x2c, 0xd9, 0x59, 0x2c, 0x0d, 0xa7, 0x32, 0x9d, 0xfe, - 0x78, 0x3a, 0x56, 0xdc, 0x1e, 0x4f, 0xb9, 0x9e, 0x3c, 0x9e, 0x52, 0x9d, - 0x1f, 0x1a, 0x65, 0xae, 0x07, 0x70, 0x96, 0x76, 0xfd, 0x39, 0xf4, 0x5e, - 0xe8, 0x4d, 0xa3, 0xae, 0x36, 0xe9, 0x6a, 0xce, 0x37, 0xea, 0xbe, 0x07, - 0x6d, 0x2f, 0xb7, 0xb5, 0xb8, 0xf5, 0xad, 0x8b, 0xda, 0xfa, 0x7d, 0xf0, - 0xc8, 0x79, 0xf5, 0xfd, 0x33, 0x79, 0xb5, 0x84, 0x33, 0xb0, 0x97, 0x8f, - 0x7b, 0x1d, 0xf3, 0xb9, 0xe2, 0x2c, 0x9e, 0x5e, 0xee, 0xdd, 0x82, 0xf9, - 0x8a, 0xc7, 0x7d, 0xff, 0x44, 0x0e, 0x41, 0x5d, 0xbe, 0x35, 0x96, 0xcf, - 0x38, 0x1e, 0xd6, 0xec, 0xd0, 0xa5, 0x6d, 0xe7, 0x9c, 0xf4, 0x7c, 0x83, - 0x75, 0xa3, 0x3e, 0xe1, 0x3a, 0x25, 0xfc, 0x8a, 0x4e, 0x2f, 0xd1, 0xb7, - 0x7c, 0xee, 0xd3, 0x69, 0xf6, 0x31, 0x29, 0x5f, 0x40, 0xcd, 0xf2, 0xf4, - 0xb6, 0x9a, 0xa5, 0x48, 0xe3, 0x07, 0xfa, 0xcf, 0x87, 0x37, 0xe5, 0xf8, - 0xa4, 0x7b, 0x36, 0xa0, 0x40, 0x9b, 0x5d, 0xe7, 0x5a, 0x76, 0xab, 0x76, - 0x25, 0x1a, 0xbd, 0x21, 0xf5, 0x49, 0xce, 0x85, 0x57, 0x33, 0x5f, 0xe1, - 0xdb, 0x99, 0x1b, 0xe0, 0xd6, 0x48, 0xdd, 0xf1, 0x06, 0xeb, 0x3c, 0x0f, - 0xbf, 0xa3, 0x4d, 0xb8, 0xbe, 0xb9, 0xdb, 0xbd, 0xab, 0x89, 0x7d, 0x71, - 0x9d, 0xa3, 0x06, 0xa9, 0xbb, 0x8b, 0x25, 0xdf, 0xfd, 0x59, 0x8b, 0x52, - 0x9e, 0x88, 0xfc, 0x05, 0xd8, 0x02, 0x9c, 0x8b, 0x45, 0xec, 0xcd, 0x24, - 0x78, 0xc9, 0x75, 0x0e, 0xe8, 0x42, 0x61, 0x7f, 0x19, 0xba, 0x8d, 0x03, - 0x5c, 0x3f, 0x7e, 0x2a, 0x97, 0x7b, 0x2a, 0x07, 0xfb, 0x8c, 0x91, 0x7a, - 0xb2, 0x5b, 0xe7, 0x36, 0x48, 0xf8, 0xb9, 0x80, 0x79, 0x9c, 0xbb, 0xe0, - 0xa7, 0x24, 0xa2, 0x33, 0x8e, 0x98, 0xed, 0x38, 0x62, 0xae, 0xa3, 0x03, - 0xdd, 0xb6, 0x4d, 0xbb, 0xb0, 0x27, 0xc8, 0xc1, 0xf4, 0x00, 0x6c, 0xb9, - 0xe0, 0x88, 0x3a, 0x6a, 0xc1, 0x1f, 0x18, 0xae, 0x78, 0x9a, 0x3e, 0xc1, - 0x1a, 0x6f, 0xc8, 0xf4, 0xde, 0xc5, 0x11, 0xd1, 0xd6, 0xdc, 0x37, 0x30, - 0x37, 0xdb, 0xc4, 0x31, 0xca, 0xf9, 0x72, 0x5e, 0x5b, 0x80, 0x8f, 0x8e, - 0xac, 0x6b, 0xe0, 0x35, 0xce, 0x97, 0x23, 0xd9, 0xfd, 0x12, 0xf6, 0x07, - 0xeb, 0xbf, 0x74, 0x47, 0xad, 0x99, 0xd7, 0x94, 0xe9, 0xdd, 0x69, 0x3c, - 0xc3, 0xf3, 0x13, 0x6c, 0x99, 0x98, 0xba, 0xa0, 0xce, 0x3d, 0xd3, 0xa8, - 0xf1, 0xb8, 0x95, 0xa8, 0x83, 0xf8, 0xae, 0x8b, 0x6b, 0x27, 0x89, 0xf8, - 0x4f, 0x9f, 0x63, 0x3e, 0x13, 0xcd, 0xb0, 0x0e, 0x3e, 0x1b, 0x71, 0xfc, - 0xfc, 0x1b, 0x2f, 0xf3, 0x0a, 0xbd, 0x68, 0x18, 0x00, 0x00, 0x00 }; - -static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 }; -static const u32 bnx2_TPAT_b09FwRodata[(0x0/4) + 1] = { 0x0 }; -static const u32 bnx2_TPAT_b09FwBss[(0x850/4) + 1] = { 0x0 }; -static const u32 bnx2_TPAT_b09FwSbss[(0x2c/4) + 1] = { 0x0 }; + 0x1f, 0x8b, 0x08, 0x08, 0xdb, 0xfd, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xc5, 0x58, 0x5d, 0x6c, + 0x1c, 0x57, 0x15, 0x3e, 0xf3, 0xbb, 0x13, 0x77, 0xed, 0xbd, 0x49, 0x97, + 0x6a, 0x13, 0xb9, 0x74, 0xc6, 0x1e, 0x3b, 0x8b, 0x1c, 0x35, 0x93, 0xb0, + 0x24, 0x16, 0x5a, 0xd1, 0xc9, 0xcc, 0xae, 0x6b, 0xe5, 0x29, 0x86, 0xbc, + 0xf1, 0xb2, 0xac, 0xed, 0x46, 0x54, 0x48, 0x4d, 0x51, 0x84, 0x22, 0x81, + 0x94, 0x65, 0x76, 0x53, 0x40, 0x5a, 0x65, 0xc1, 0xa0, 0x04, 0x21, 0x84, + 0x22, 0x9b, 0x66, 0x91, 0x58, 0x3c, 0x4d, 0xe9, 0x6b, 0x94, 0xbc, 0x90, + 0x96, 0x17, 0x9e, 0x4b, 0x9e, 0xac, 0x02, 0x12, 0x0f, 0xa8, 0x8a, 0x78, + 0x40, 0x15, 0x0d, 0x1e, 0xbe, 0x33, 0x3f, 0x9b, 0x5d, 0xd7, 0x29, 0x79, + 0xa8, 0x84, 0xa5, 0xf1, 0xcc, 0xfd, 0x39, 0xf7, 0xe7, 0x7c, 0xdf, 0x77, + 0xee, 0xb9, 0x5b, 0x92, 0x69, 0x82, 0xd2, 0xbf, 0x49, 0x3c, 0x97, 0xbe, + 0x71, 0xf1, 0xd2, 0xe2, 0x8b, 0x27, 0x4d, 0x3a, 0x71, 0xe2, 0x45, 0xe9, + 0x19, 0x43, 0xa6, 0xcf, 0xe0, 0x4f, 0x21, 0x12, 0xd9, 0xf8, 0xfc, 0x90, + 0x21, 0x57, 0x6f, 0x4e, 0x7b, 0x36, 0x19, 0x4a, 0xd5, 0x79, 0x61, 0xd5, + 0x26, 0x72, 0x07, 0x0b, 0xa6, 0x4f, 0xff, 0x89, 0x5a, 0x45, 0x95, 0xb8, + 0xfe, 0xf9, 0xea, 0xa3, 0xe3, 0x77, 0x4e, 0x5b, 0x0f, 0x6f, 0x2a, 0x64, + 0x88, 0x6a, 0xc3, 0x10, 0xf3, 0x64, 0x4c, 0xc3, 0xe6, 0x97, 0x47, 0x57, + 0x34, 0x9a, 0xca, 0xc6, 0x12, 0x14, 0xf4, 0x0c, 0xaa, 0x77, 0x31, 0x8e, + 0x7d, 0x59, 0xf2, 0x43, 0x55, 0xf2, 0x6f, 0x18, 0x24, 0x57, 0x5d, 0xc9, + 0x0b, 0x6d, 0xb4, 0x49, 0xe4, 0x39, 0x39, 0x72, 0x45, 0x14, 0x7d, 0xd3, + 0x91, 0x49, 0xb6, 0x77, 0xa3, 0xd9, 0xb9, 0x25, 0xc9, 0xeb, 0x2f, 0x4b, + 0x7e, 0xdf, 0xe3, 0x7d, 0x63, 0x1d, 0x4b, 0x92, 0xdb, 0xe7, 0x77, 0xd5, + 0xf0, 0xbb, 0x53, 0xd4, 0x28, 0x52, 0x41, 0xb6, 0xd9, 0xd6, 0x24, 0xdf, + 0x59, 0x28, 0x29, 0x34, 0x8b, 0xe7, 0x00, 0xad, 0x3b, 0x94, 0xf7, 0x1c, + 0x52, 0x15, 0x5b, 0x26, 0xbf, 0x28, 0xd1, 0xaf, 0x2b, 0x1a, 0x9e, 0xb3, + 0x52, 0xad, 0xbf, 0x96, 0x8e, 0x53, 0xa4, 0x36, 0xd6, 0xd2, 0x2c, 0xf2, + 0xda, 0x12, 0x7b, 0xcf, 0x59, 0x10, 0x32, 0xcd, 0xe2, 0x99, 0xc4, 0x77, + 0x13, 0xfd, 0x34, 0xf2, 0x2a, 0x7b, 0xdb, 0x0e, 0xe0, 0x1b, 0xeb, 0xc4, + 0x58, 0x5e, 0xbc, 0x0e, 0x13, 0xeb, 0xb0, 0xa9, 0xd3, 0x5b, 0xc6, 0x3e, + 0xe6, 0x4a, 0x4d, 0xd2, 0xa9, 0x13, 0xaf, 0x7d, 0x92, 0x02, 0xa1, 0x50, + 0x70, 0x4c, 0x23, 0xf7, 0x9c, 0x8a, 0xf2, 0x21, 0x6a, 0x09, 0x09, 0x7d, + 0x3a, 0x29, 0x7e, 0x39, 0xb4, 0xeb, 0xa8, 0x2f, 0x50, 0x50, 0x3c, 0x28, + 0xc9, 0xd5, 0xef, 0xa1, 0x7e, 0x4e, 0x34, 0xe9, 0xbb, 0x78, 0x4b, 0x28, + 0x1f, 0xe4, 0xf1, 0x50, 0x96, 0x48, 0xb1, 0x49, 0x78, 0xa1, 0x49, 0xed, + 0x30, 0xb3, 0xe5, 0xfa, 0xa4, 0xae, 0x15, 0xee, 0xc5, 0x0e, 0xfd, 0x7a, + 0x75, 0x6a, 0x08, 0x6a, 0xa9, 0x55, 0xf4, 0xe9, 0xd9, 0xa2, 0x06, 0x9c, + 0xdc, 0x18, 0xcf, 0x97, 0xb8, 0x9e, 0xff, 0x50, 0x6f, 0x92, 0x52, 0xb5, + 0x85, 0x4f, 0x5f, 0xa6, 0xa4, 0x8d, 0xf7, 0x29, 0x63, 0x6f, 0xa7, 0xd2, + 0x72, 0x51, 0x78, 0x37, 0xbe, 0x48, 0x6e, 0xec, 0x1f, 0x03, 0xdf, 0x02, + 0x7b, 0xd4, 0x81, 0x75, 0xe0, 0xca, 0xd4, 0x2a, 0x19, 0x64, 0x2d, 0xae, + 0xa1, 0xe5, 0x6f, 0x5d, 0x05, 0x7e, 0x67, 0xdc, 0xd4, 0xd4, 0x8e, 0x71, + 0xfe, 0x23, 0xd6, 0xd9, 0x12, 0x06, 0xf0, 0x6e, 0x9c, 0x8f, 0xa2, 0x37, + 0x9d, 0x28, 0xd2, 0xab, 0x76, 0xf9, 0x16, 0x2d, 0x94, 0x34, 0x9a, 0x17, + 0x78, 0xc3, 0x8f, 0x36, 0x7c, 0xa5, 0x65, 0xeb, 0xc9, 0x78, 0x86, 0xbf, + 0xcb, 0x12, 0x96, 0x42, 0x1f, 0x74, 0xdf, 0x63, 0x7f, 0x94, 0x97, 0x62, + 0x9b, 0x28, 0xda, 0x5c, 0xfc, 0x34, 0x9b, 0xef, 0xa7, 0x36, 0x51, 0x54, + 0xaf, 0xf0, 0xbc, 0x16, 0xf6, 0xcc, 0x5c, 0x25, 0xaa, 0x0f, 0x1c, 0xa3, + 0xd9, 0xc5, 0xfa, 0x6c, 0xbc, 0x07, 0x25, 0xec, 0xc1, 0x2a, 0x9b, 0x92, + 0x41, 0x81, 0x1d, 0xbd, 0x00, 0x7e, 0xb8, 0xbe, 0x6d, 0xbd, 0xef, 0x2b, + 0x05, 0xda, 0x72, 0xf2, 0xd4, 0x09, 0x4b, 0x14, 0x84, 0x1d, 0xf2, 0x42, + 0x19, 0x73, 0x14, 0x68, 0xd3, 0x7e, 0x18, 0xd5, 0x1d, 0x07, 0x7e, 0x21, + 0xb6, 0x2b, 0xd5, 0x69, 0x1a, 0xed, 0x0b, 0x62, 0x8d, 0x1c, 0x60, 0x21, + 0xc3, 0x37, 0xb3, 0xf1, 0x77, 0x10, 0x3a, 0x68, 0xa7, 0x96, 0x5c, 0xb1, + 0x44, 0x40, 0x56, 0xc9, 0x53, 0x48, 0xc8, 0x55, 0x81, 0x3e, 0x2d, 0xaa, + 0x85, 0x06, 0xed, 0x28, 0x97, 0x63, 0x7e, 0xb7, 0x7b, 0x3b, 0xd1, 0x9d, + 0xa3, 0x25, 0xba, 0x1b, 0x16, 0xe9, 0x76, 0x48, 0x72, 0xd3, 0x01, 0x37, + 0x8a, 0x82, 0xde, 0x0a, 0x47, 0xf7, 0xf2, 0x1b, 0xec, 0x25, 0x38, 0xa2, + 0x40, 0x83, 0xab, 0xce, 0x3d, 0x30, 0xc8, 0x02, 0x46, 0x2d, 0xec, 0x3d, + 0x7b, 0xf3, 0xbe, 0x76, 0xa6, 0x57, 0x6d, 0xeb, 0x87, 0x3e, 0xa3, 0x76, + 0x4d, 0x43, 0xed, 0x5e, 0x7f, 0x0c, 0x30, 0x86, 0xa0, 0xab, 0xd0, 0x93, + 0x0c, 0xbf, 0xcc, 0x6c, 0x1b, 0xd4, 0xef, 0xe6, 0xc8, 0xdc, 0x54, 0xa9, + 0xd9, 0x2b, 0x92, 0x33, 0x6f, 0x99, 0x24, 0xcb, 0x45, 0x99, 0x54, 0x9a, + 0xd9, 0x8c, 0x68, 0x09, 0xeb, 0xb8, 0x6f, 0xff, 0x48, 0xa7, 0xa9, 0xc0, + 0xd1, 0x89, 0xfb, 0x18, 0x34, 0x73, 0xcb, 0x90, 0xfc, 0x1e, 0xef, 0x83, + 0x7d, 0x6e, 0xa4, 0x3e, 0x57, 0x25, 0xef, 0x46, 0x8e, 0x66, 0x37, 0xfe, + 0x11, 0x79, 0x36, 0x7c, 0x0d, 0x9e, 0xaf, 0x56, 0xbe, 0xa0, 0xd0, 0x04, + 0xea, 0x36, 0xb9, 0xed, 0x61, 0x5a, 0xcf, 0x63, 0x44, 0x91, 0xe7, 0x3c, + 0x4b, 0x1e, 0xf3, 0xff, 0x3c, 0xdb, 0xe4, 0x68, 0x66, 0x83, 0x75, 0x83, + 0xf7, 0x26, 0x97, 0x79, 0x6d, 0x07, 0xa8, 0x89, 0x1d, 0x35, 0xcb, 0x45, + 0xf8, 0x41, 0x8e, 0x35, 0xd2, 0xc4, 0x8e, 0x65, 0x7b, 0x02, 0x6f, 0x9e, + 0xef, 0xac, 0x92, 0xf0, 0x9d, 0xe3, 0x46, 0x9e, 0x7c, 0xe0, 0xab, 0x62, + 0x3d, 0x6b, 0x34, 0x57, 0x5a, 0x8f, 0xdb, 0x50, 0x37, 0xe0, 0x36, 0xb1, + 0xa7, 0x0d, 0xe5, 0x41, 0xb6, 0x06, 0x70, 0xda, 0x6e, 0x63, 0x16, 0x2d, + 0xde, 0x6b, 0xdd, 0xe1, 0xfe, 0xdc, 0xb7, 0x55, 0xd6, 0xc8, 0x2a, 0x6f, + 0x62, 0xf4, 0x7e, 0x17, 0xfb, 0xbd, 0xce, 0xb1, 0xc8, 0x36, 0xff, 0x4a, + 0xdc, 0x7f, 0x16, 0x7b, 0x9e, 0x5b, 0x6c, 0x73, 0xdb, 0x40, 0x23, 0x7b, + 0xa3, 0x25, 0x54, 0xf8, 0x5f, 0x86, 0xf3, 0xfd, 0x1f, 0xff, 0x2b, 0xd2, + 0xaa, 0xe0, 0x74, 0xa5, 0x00, 0x7c, 0x2c, 0xb3, 0x0d, 0xbd, 0xdb, 0x18, + 0x37, 0x70, 0x14, 0xd8, 0x25, 0x38, 0x71, 0xbf, 0xa5, 0x6e, 0x44, 0xed, + 0x78, 0xae, 0x2b, 0x3c, 0x17, 0x62, 0x92, 0xbd, 0xf8, 0x07, 0x70, 0xa3, + 0x49, 0x79, 0x9a, 0xdf, 0xce, 0xd3, 0x85, 0x41, 0x9e, 0x66, 0xae, 0xe9, + 0xf0, 0x43, 0x14, 0x75, 0x2a, 0xac, 0x51, 0xe0, 0x6d, 0x73, 0x3f, 0xab, + 0xa4, 0xc8, 0xbc, 0x0e, 0xb4, 0x6f, 0x13, 0xad, 0x0d, 0x74, 0xf8, 0x4d, + 0x1d, 0x19, 0x5b, 0xa6, 0x97, 0x7f, 0x46, 0xf4, 0xf2, 0x80, 0x6d, 0x79, + 0xfc, 0xc4, 0xa6, 0x89, 0x3d, 0xcb, 0xc0, 0xfc, 0xc2, 0x40, 0x46, 0xbc, + 0x40, 0x3c, 0xed, 0x7b, 0x88, 0x93, 0x35, 0x3c, 0x4b, 0x88, 0x9d, 0x8c, + 0x0d, 0xc7, 0x91, 0x5d, 0xe0, 0xb3, 0x8c, 0xb6, 0xb3, 0xa8, 0x4b, 0xf4, + 0xae, 0xd8, 0x3a, 0xd5, 0x9c, 0x49, 0x6a, 0x67, 0xb1, 0x4a, 0x70, 0xac, + 0x3a, 0x08, 0x4e, 0x1d, 0x40, 0xfc, 0xf9, 0x9d, 0x32, 0x1e, 0xab, 0x10, + 0xd3, 0x8a, 0x87, 0x11, 0x9b, 0xfa, 0xa8, 0xe7, 0xf1, 0x6e, 0xe1, 0x7d, + 0x00, 0xe5, 0xc3, 0xe8, 0x3b, 0x1a, 0xa7, 0x32, 0xbb, 0x27, 0xc5, 0x28, + 0xf0, 0x6e, 0xc3, 0x40, 0x7f, 0x13, 0xba, 0x61, 0x7f, 0xe7, 0x10, 0x3f, + 0xd8, 0xe7, 0x39, 0xf8, 0x54, 0xc7, 0xdc, 0x82, 0x66, 0xb7, 0xa9, 0xa5, + 0xa4, 0xf1, 0xcb, 0x1f, 0xc6, 0xaf, 0x52, 0xcc, 0x83, 0x20, 0x14, 0xb0, + 0x61, 0xfd, 0x66, 0x7a, 0x65, 0xec, 0xc8, 0xf5, 0xa0, 0x65, 0x4f, 0x89, + 0xa2, 0x55, 0xa7, 0x40, 0x4d, 0xe0, 0xee, 0x42, 0xc3, 0x4d, 0x68, 0xd8, + 0x1f, 0xd1, 0xb0, 0xff, 0x3f, 0x35, 0x0c, 0x7d, 0x42, 0x23, 0xb7, 0xc1, + 0xa9, 0xb7, 0x7a, 0xfb, 0xe9, 0x99, 0xb5, 0xcc, 0x9a, 0x36, 0xe9, 0xce, + 0xd1, 0xa7, 0xd5, 0x74, 0x49, 0x7e, 0x4a, 0x4d, 0xb7, 0x58, 0xd3, 0x2a, + 0x6b, 0xba, 0xb8, 0x57, 0xd3, 0xd3, 0x18, 0x23, 0xd1, 0xe6, 0x19, 0xb5, + 0x48, 0xda, 0x3c, 0xf0, 0xd8, 0xc8, 0x93, 0x72, 0xed, 0x31, 0xef, 0x98, + 0xcb, 0xfe, 0x00, 0xff, 0xb6, 0x35, 0xb4, 0x49, 0xe3, 0xf5, 0x88, 0x81, + 0x6a, 0xd5, 0x2a, 0xad, 0xc5, 0x7d, 0x54, 0xd2, 0xe1, 0xff, 0xd7, 0x8f, + 0x5a, 0xa6, 0x29, 0x8f, 0x6a, 0x1f, 0xea, 0xdf, 0x88, 0xae, 0x68, 0x55, + 0x9e, 0xa7, 0x65, 0x82, 0xf3, 0xe6, 0x4f, 0x80, 0x55, 0xbb, 0xcb, 0x7c, + 0xb7, 0x45, 0x3d, 0xe6, 0x19, 0xca, 0xd0, 0x84, 0x06, 0xde, 0xe6, 0xd0, + 0x4f, 0xdd, 0x48, 0x74, 0x74, 0x1b, 0xe3, 0x6e, 0x75, 0x99, 0x67, 0x06, + 0xe9, 0xd7, 0xed, 0xd2, 0x85, 0x38, 0x06, 0xcf, 0x8a, 0x25, 0x62, 0x0d, + 0xf2, 0xb9, 0x88, 0xf6, 0x41, 0x8e, 0x94, 0x58, 0xf7, 0x13, 0xa9, 0xee, + 0x9f, 0x87, 0xaf, 0x26, 0x50, 0x66, 0xed, 0x1f, 0x4e, 0xb5, 0x3f, 0x85, + 0x37, 0xd7, 0xad, 0xa8, 0x09, 0x87, 0xc0, 0xc7, 0x0d, 0xc6, 0x37, 0x8f, + 0x58, 0xc7, 0xf3, 0xff, 0x33, 0x5a, 0xb5, 0x19, 0x63, 0xdb, 0xfc, 0x01, + 0xcd, 0x41, 0x7f, 0xa8, 0xdf, 0xe6, 0xbe, 0x6c, 0x93, 0xf5, 0x15, 0x69, + 0xdf, 0x0f, 0xf7, 0xf4, 0x45, 0xfd, 0x36, 0xf7, 0x63, 0x7d, 0x1c, 0x22, + 0xe5, 0x3a, 0x9f, 0xdb, 0x1e, 0xeb, 0x03, 0x76, 0x35, 0xd4, 0x71, 0x6e, + 0xc1, 0xf6, 0x7c, 0x86, 0xf3, 0x3a, 0x39, 0xef, 0xe0, 0x73, 0x7e, 0xcf, + 0x79, 0x3e, 0xd4, 0xc8, 0x19, 0xf0, 0xfe, 0x3b, 0xea, 0x27, 0x35, 0xb2, + 0x02, 0x4d, 0x5c, 0x54, 0x13, 0x8d, 0xbc, 0x86, 0xf7, 0x19, 0x94, 0x57, + 0xf6, 0x68, 0x24, 0xb3, 0x7b, 0xf2, 0x39, 0x1e, 0xf4, 0x4a, 0xf1, 0x99, + 0xcb, 0xf3, 0x29, 0x1b, 0xd4, 0xd2, 0x52, 0x3d, 0xd4, 0x87, 0x7a, 0x98, + 0x40, 0xcc, 0xc8, 0xa5, 0x5c, 0xc7, 0xdb, 0xfe, 0x48, 0xf1, 0x1d, 0x4b, + 0xb4, 0x89, 0xb5, 0x31, 0x7a, 0x9e, 0xfd, 0xbf, 0xf4, 0x41, 0xe0, 0x51, + 0x3c, 0x37, 0x72, 0x11, 0x3e, 0x17, 0xa2, 0xe8, 0x15, 0x07, 0xed, 0x59, + 0x4e, 0x12, 0x63, 0x9f, 0xc3, 0xd9, 0xcb, 0x78, 0x20, 0x0f, 0xb4, 0x67, + 0xa1, 0x07, 0x8e, 0x05, 0xbb, 0xd1, 0x96, 0xed, 0xa1, 0xae, 0x06, 0xff, + 0x33, 0x26, 0xcb, 0xd2, 0x52, 0xdf, 0x60, 0x3b, 0xe8, 0x6d, 0xbf, 0x5c, + 0x4c, 0x87, 0xae, 0x1e, 0xe3, 0xc4, 0x3c, 0x6a, 0x8e, 0xe0, 0xd4, 0x88, + 0x71, 0xda, 0x19, 0xe2, 0xd4, 0x4c, 0x71, 0x6a, 0xc6, 0x38, 0x3d, 0x48, + 0x71, 0xfa, 0xf3, 0x13, 0x70, 0xda, 0x79, 0x0a, 0x9c, 0x0c, 0xda, 0xb2, + 0x4b, 0x38, 0x6f, 0xf5, 0x38, 0x77, 0xbd, 0xef, 0xec, 0x97, 0x7b, 0xb1, + 0xdf, 0xc7, 0xb0, 0x8a, 0x18, 0xab, 0x2d, 0x1a, 0xcd, 0x43, 0x2c, 0xf3, + 0x1e, 0x15, 0x70, 0x6e, 0xe4, 0xe9, 0xea, 0x9e, 0x5c, 0x24, 0x00, 0x4e, + 0xb5, 0x14, 0xa7, 0xab, 0xc0, 0xa9, 0x96, 0xe2, 0xb4, 0x3e, 0x82, 0xd3, + 0xfa, 0x18, 0x4e, 0x1c, 0x53, 0x2a, 0xc6, 0x7a, 0x37, 0xc3, 0x28, 0xc3, + 0x47, 0xa7, 0x9b, 0x62, 0x0a, 0xfb, 0x3f, 0x4e, 0xed, 0x9f, 0xaa, 0x9c, + 0xff, 0x02, 0xbb, 0x97, 0x54, 0x39, 0x3e, 0x17, 0xf8, 0xfb, 0x71, 0xbe, + 0x82, 0xb9, 0x5c, 0xcf, 0xe1, 0x3d, 0x21, 0xcf, 0xb5, 0x47, 0x63, 0xd1, + 0x07, 0x88, 0x45, 0x5c, 0xc7, 0xfd, 0x54, 0xa9, 0x06, 0xcd, 0x2b, 0xc8, + 0xe1, 0xfd, 0x61, 0x0e, 0x9f, 0xf8, 0xe1, 0x6a, 0x9a, 0xc3, 0x6f, 0xd9, + 0x9c, 0xc3, 0x9f, 0xd0, 0x68, 0x62, 0x39, 0xc5, 0x93, 0x79, 0x3d, 0x89, + 0xb6, 0xb3, 0x31, 0xee, 0x6d, 0xc4, 0xf2, 0x55, 0xf8, 0xa0, 0x19, 0xf3, + 0x13, 0x79, 0x57, 0xca, 0x5d, 0xe4, 0xbb, 0xe4, 0x87, 0x09, 0x4f, 0x3f, + 0xdb, 0x5c, 0xec, 0xef, 0x88, 0xd9, 0x46, 0x43, 0xc5, 0x1d, 0xe0, 0x6e, + 0x18, 0xc7, 0xea, 0x73, 0x41, 0x97, 0x5a, 0x47, 0xaa, 0x57, 0x22, 0xe0, + 0xee, 0x7e, 0xfd, 0x34, 0x9f, 0x39, 0xf9, 0x45, 0xaf, 0x82, 0xfa, 0x81, + 0x41, 0xc8, 0x83, 0x70, 0xa7, 0xa1, 0x96, 0x77, 0x5a, 0x42, 0xbe, 0x83, + 0x32, 0x6c, 0x82, 0x70, 0xba, 0x21, 0x57, 0x4b, 0xe0, 0x43, 0x8b, 0x5c, + 0xac, 0xd3, 0x0d, 0xe3, 0x7b, 0x4d, 0x43, 0xa9, 0x1a, 0xc8, 0x37, 0xc9, + 0xc0, 0x99, 0x0f, 0x9f, 0x98, 0x46, 0x7b, 0x80, 0x9c, 0x08, 0x79, 0x80, + 0xb7, 0x08, 0xbf, 0x1c, 0x03, 0x76, 0xa1, 0x0a, 0xdb, 0x6f, 0xe9, 0xc9, + 0x9d, 0x88, 0xc8, 0x8b, 0xfd, 0xf5, 0x71, 0xca, 0x91, 0x38, 0xe7, 0x92, + 0x6a, 0x3d, 0x32, 0x9b, 0x0e, 0xb8, 0x8e, 0x33, 0xa5, 0x13, 0x72, 0x5e, + 0x7d, 0xcc, 0x90, 0xaf, 0x71, 0x3c, 0x7f, 0x00, 0x1f, 0xe2, 0x7b, 0x9b, + 0xcf, 0x19, 0x85, 0x73, 0x73, 0xdc, 0x7d, 0xca, 0x88, 0x37, 0x34, 0x89, + 0xd8, 0x87, 0xd8, 0x3b, 0xcd, 0x58, 0xb9, 0xc9, 0x19, 0xc4, 0xe3, 0x1d, + 0x97, 0x93, 0x79, 0xfe, 0xa4, 0x25, 0x1c, 0xc6, 0x7d, 0x07, 0xfe, 0x5b, + 0xed, 0x39, 0x1c, 0x73, 0x3f, 0xaf, 0xd0, 0x43, 0x8a, 0x39, 0x29, 0x4e, + 0x20, 0x16, 0x9f, 0x86, 0x8d, 0x1b, 0xeb, 0x31, 0xc9, 0xbd, 0x32, 0x9b, + 0x0f, 0xf7, 0x8c, 0xf1, 0x17, 0x65, 0xbc, 0xec, 0x82, 0xd3, 0x95, 0x74, + 0xbe, 0x51, 0x8e, 0x2c, 0x20, 0xe5, 0x79, 0xa0, 0x0d, 0xf3, 0xb7, 0xa2, + 0x8e, 0x7e, 0xbc, 0x46, 0xd6, 0x25, 0xdb, 0x1c, 0xd1, 0xc6, 0xc7, 0x99, + 0xdd, 0x67, 0x8c, 0xea, 0xc8, 0x18, 0x45, 0xde, 0x9b, 0x68, 0x3a, 0xcf, + 0xa4, 0xf7, 0x0c, 0x8e, 0x2d, 0x02, 0x3a, 0x95, 0x9f, 0x93, 0xb1, 0x0f, + 0x0f, 0x7b, 0xf6, 0xe3, 0xfa, 0x5f, 0xe9, 0xe3, 0xe3, 0xfe, 0x56, 0x4d, + 0xca, 0xc7, 0x12, 0x6e, 0xda, 0x78, 0x87, 0x0f, 0x46, 0xd6, 0xae, 0xed, + 0x33, 0xef, 0xd7, 0x38, 0x5d, 0x43, 0xbc, 0x21, 0x57, 0xc1, 0x1d, 0xcc, + 0x27, 0x7c, 0x87, 0xaf, 0x67, 0x3e, 0x04, 0x6f, 0xe8, 0x5c, 0x3b, 0xe5, + 0x8b, 0x9c, 0xf0, 0x85, 0xf3, 0xba, 0xc5, 0x55, 0xf0, 0xa5, 0x0d, 0xbe, + 0xc0, 0xae, 0xa1, 0x55, 0xa7, 0xc1, 0x05, 0x8e, 0x4d, 0x28, 0x87, 0xcc, + 0x1d, 0xe6, 0x0a, 0xf3, 0xe6, 0x31, 0x5f, 0x5e, 0xe9, 0x1a, 0xc6, 0xe6, + 0xa7, 0x70, 0xe5, 0x8d, 0x98, 0x2b, 0xcc, 0xd9, 0x24, 0x7e, 0x74, 0x80, + 0x55, 0x90, 0xc6, 0x8f, 0x00, 0xf1, 0xa3, 0xc6, 0xf9, 0x4f, 0x1c, 0x0b, + 0x12, 0xfd, 0xac, 0x41, 0x3f, 0x35, 0x85, 0xf3, 0x23, 0xd6, 0x0e, 0xdb, + 0xb1, 0x7e, 0xd8, 0xae, 0x90, 0xda, 0x8d, 0xc7, 0x91, 0x76, 0xcf, 0x32, + 0xb3, 0x38, 0xd2, 0x86, 0x76, 0x3a, 0xa9, 0x8e, 0xda, 0xa9, 0x8e, 0xd0, + 0xa7, 0xa5, 0x54, 0xf8, 0x4c, 0xb0, 0x4c, 0x1f, 0xf1, 0xa3, 0x13, 0x8f, + 0xd9, 0xa2, 0xe4, 0x2e, 0xc3, 0xda, 0xe6, 0xb8, 0x3b, 0x12, 0x6f, 0xd3, + 0x7b, 0x6e, 0x23, 0xbe, 0xe7, 0x7e, 0x45, 0x1f, 0x8f, 0xb7, 0x38, 0x6b, + 0xe2, 0x7b, 0xee, 0x29, 0x9d, 0xef, 0xb9, 0x01, 0x7d, 0x49, 0x1f, 0xbd, + 0xe7, 0x06, 0x63, 0xf7, 0xdc, 0xcc, 0x96, 0xeb, 0xf7, 0x8b, 0xbb, 0x99, + 0x4f, 0x38, 0xf6, 0x32, 0x9f, 0xf6, 0xcb, 0x15, 0xb3, 0x3e, 0x1c, 0x93, + 0x58, 0xef, 0x1c, 0xcb, 0x92, 0xdc, 0xec, 0x6e, 0x98, 0xe9, 0xe2, 0x55, + 0xcc, 0x83, 0x72, 0x6f, 0x3f, 0x5d, 0x18, 0xa9, 0x2e, 0x26, 0x13, 0x9b, + 0xde, 0xa8, 0x36, 0x5e, 0xd5, 0xc7, 0xb5, 0x91, 0x8d, 0x93, 0x69, 0x23, + 0x19, 0x73, 0x47, 0x29, 0xe1, 0x0c, 0x2c, 0x23, 0x1e, 0x09, 0xbe, 0xa3, + 0x21, 0x5e, 0x54, 0xf3, 0xb8, 0xa7, 0x14, 0x78, 0xec, 0x76, 0xf8, 0x2c, + 0x35, 0x8a, 0x8c, 0x0b, 0xaf, 0xff, 0x61, 0x7c, 0x7f, 0xc0, 0xba, 0x0b, + 0x01, 0xff, 0xfe, 0xf1, 0x09, 0x3e, 0xbe, 0x06, 0x3e, 0x66, 0xfb, 0x19, + 0xad, 0xbf, 0x34, 0x52, 0x5f, 0x4e, 0x31, 0x4f, 0x7c, 0x7e, 0x2f, 0xd5, + 0xc8, 0x26, 0x72, 0xb7, 0xfb, 0xc8, 0x8b, 0xde, 0x44, 0xfc, 0x0e, 0x06, + 0x1f, 0x47, 0xf7, 0x8a, 0x2a, 0x75, 0x86, 0x36, 0xbf, 0xc0, 0xba, 0x2d, + 0x71, 0x13, 0x5f, 0x6f, 0x0c, 0xb2, 0xb1, 0xb9, 0x9d, 0xeb, 0xfe, 0x8d, + 0xf3, 0x19, 0x79, 0xdf, 0xb0, 0xef, 0xfb, 0x11, 0xe7, 0xbb, 0x77, 0x81, + 0xc5, 0x3b, 0xe1, 0x34, 0xfd, 0x1e, 0x1c, 0x7b, 0x3b, 0xce, 0x79, 0x93, + 0x5c, 0x17, 0xfe, 0xc3, 0x99, 0xc7, 0x67, 0xbd, 0xf7, 0x39, 0x99, 0x2e, + 0xd3, 0x57, 0x1d, 0xae, 0x93, 0xa9, 0x7e, 0x2a, 0x8a, 0x2e, 0xe2, 0xdc, + 0x5f, 0x19, 0x3b, 0xf7, 0x71, 0x07, 0x3c, 0xc9, 0xf9, 0x7f, 0x96, 0xf3, + 0xef, 0x46, 0x33, 0xf3, 0xd6, 0x4d, 0x97, 0x5c, 0xa9, 0xde, 0xe7, 0x7c, + 0x6c, 0x98, 0x8b, 0x11, 0x1d, 0x7a, 0x14, 0xc9, 0xf3, 0x7c, 0x36, 0xbd, + 0x9b, 0xfa, 0x1c, 0x6d, 0x37, 0x1e, 0xe1, 0x1e, 0x53, 0x8b, 0x7f, 0x17, + 0x72, 0xfb, 0x3c, 0x0f, 0x97, 0xf1, 0x0e, 0x39, 0x47, 0x78, 0xd2, 0x6f, + 0x35, 0x2a, 0xf0, 0xb5, 0xcc, 0x75, 0x85, 0xe2, 0x7b, 0x21, 0xee, 0x6e, + 0x3f, 0x6f, 0x53, 0x12, 0x3b, 0x6a, 0xce, 0x39, 0xac, 0x05, 0x98, 0x88, + 0x06, 0x30, 0x9e, 0x47, 0xac, 0xb2, 0xcc, 0x93, 0x72, 0xf2, 0x5b, 0xd5, + 0x1a, 0xc6, 0x56, 0x4e, 0x72, 0x2e, 0xf9, 0x51, 0xb4, 0x36, 0x88, 0xcf, + 0x44, 0x87, 0xb9, 0xe6, 0x87, 0x07, 0x65, 0x7e, 0xbb, 0x21, 0x7f, 0xeb, + 0x98, 0xc7, 0x7c, 0x02, 0x0f, 0x8b, 0xa2, 0x76, 0xc3, 0x14, 0xf5, 0x9e, + 0x29, 0x96, 0x7a, 0x32, 0x54, 0x52, 0xc8, 0xd1, 0x14, 0xe7, 0x08, 0x3a, + 0xd1, 0x73, 0x58, 0xcb, 0x2d, 0x53, 0xf8, 0xc8, 0xa3, 0xbe, 0xad, 0x58, + 0x62, 0x85, 0x76, 0xb1, 0xc7, 0x47, 0x51, 0x72, 0xa7, 0x35, 0x45, 0x6d, + 0x38, 0xf7, 0x23, 0xcc, 0xcd, 0x6b, 0x62, 0x2d, 0xf3, 0x79, 0xb6, 0x2c, + 0x9d, 0x83, 0x8f, 0xce, 0xf7, 0x77, 0x11, 0x43, 0xf9, 0x3c, 0xcb, 0x23, + 0xe6, 0x59, 0x26, 0x5f, 0xf6, 0xef, 0x62, 0xff, 0xef, 0xf4, 0x80, 0x0f, + 0x72, 0xc7, 0xb7, 0x87, 0x79, 0x1a, 0x63, 0x58, 0x06, 0x17, 0xd9, 0x3e, + 0x8a, 0x82, 0xc5, 0x38, 0x47, 0xc1, 0x5a, 0xe6, 0xca, 0xb7, 0x90, 0xa7, + 0xd7, 0x69, 0xa1, 0x5c, 0x8f, 0xdf, 0x11, 0x72, 0x12, 0xfe, 0x5d, 0xc0, + 0x12, 0x4d, 0x7c, 0xd7, 0xd2, 0xef, 0x80, 0x73, 0xf8, 0x45, 0x1e, 0x83, + 0x73, 0x79, 0xd6, 0xe1, 0x7f, 0x01, 0x17, 0xc6, 0xf1, 0xb2, 0x84, 0x14, + 0x00, 0x00, 0x00 }; +static u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 }; +static u32 bnx2_TPAT_b09FwRodata[(0x0/4) + 1] = { 0x0 }; +static u32 bnx2_TPAT_b09FwBss[(0x250/4) + 1] = { 0x0 }; +static u32 bnx2_TPAT_b09FwSbss[(0x34/4) + 1] = { 0x0 }; static struct fw_info bnx2_tpat_fw_09 = { - .ver_major = 0x3, - .ver_minor = 0x4, - .ver_fix = 0x3, + .ver_major = 0x1, + .ver_minor = 0x0, + .ver_fix = 0x0, .start_addr = 0x08000860, .text_addr = 0x08000800, - .text_len = 0x1864, + .text_len = 0x1480, .text_index = 0x0, .gz_text = bnx2_TPAT_b09FwText, .gz_text_len = sizeof(bnx2_TPAT_b09FwText), - .data_addr = 0x08002080, + .data_addr = 0x08001ca0, .data_len = 0x0, .data_index = 0x0, .data = bnx2_TPAT_b09FwData, - .sbss_addr = 0x08002088, - .sbss_len = 0x2c, + .sbss_addr = 0x08001ca0, + .sbss_len = 0x34, .sbss_index = 0x0, .sbss = bnx2_TPAT_b09FwSbss, - .bss_addr = 0x080020c0, - .bss_len = 0x850, + .bss_addr = 0x08001ce0, + .bss_len = 0x250, .bss_index = 0x0, .bss = bnx2_TPAT_b09FwBss, @@ -3279,769 +3308,732 @@ static struct fw_info bnx2_tpat_fw_09 = { }; static u8 bnx2_TXP_b09FwText[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, 0xcd, 0x7c, - 0x6f, 0x70, 0x5b, 0xd7, 0x95, 0xdf, 0x79, 0xef, 0x81, 0x24, 0x48, 0xd1, - 0xd4, 0x13, 0x17, 0x56, 0x60, 0x87, 0x71, 0x00, 0xf1, 0x81, 0x66, 0x42, - 0xae, 0x04, 0x2b, 0x4c, 0xc2, 0x6d, 0xd1, 0xf8, 0x05, 0x00, 0x29, 0x48, - 0xd1, 0x6c, 0x68, 0x95, 0x49, 0x94, 0x54, 0xe3, 0x62, 0x41, 0x52, 0xf1, - 0xb6, 0xce, 0x54, 0x9b, 0x78, 0x5a, 0x4d, 0xeb, 0xad, 0x11, 0x90, 0xfa, - 0xe7, 0x85, 0x04, 0xda, 0x62, 0x44, 0x7f, 0xc8, 0x07, 0x18, 0x80, 0x24, - 0x6f, 0xf2, 0x44, 0x28, 0x9b, 0x7f, 0xfd, 0xd0, 0xac, 0x50, 0x4a, 0xd6, - 0xba, 0x9b, 0xb4, 0xa3, 0xed, 0x66, 0x67, 0x3b, 0xd3, 0x2f, 0x1c, 0x49, - 0xf6, 0x7a, 0x77, 0x67, 0x36, 0xda, 0x6e, 0xb6, 0xab, 0xb6, 0xb2, 0xd1, - 0xdf, 0xef, 0xbe, 0xf7, 0x28, 0x90, 0xa6, 0x6c, 0xcb, 0xb3, 0xed, 0x94, - 0x33, 0x18, 0xe0, 0xdd, 0x77, 0xdf, 0xb9, 0xe7, 0x9e, 0x73, 0xee, 0x39, - 0xe7, 0x77, 0xee, 0x7d, 0x0c, 0x8b, 0x74, 0x89, 0xf7, 0xf7, 0x00, 0x3e, - 0x91, 0x43, 0x87, 0x9f, 0xd9, 0x3e, 0xb2, 0xfd, 0x13, 0xf8, 0xf9, 0x09, - 0x31, 0x02, 0x06, 0x6f, 0xbe, 0x69, 0x88, 0x64, 0xff, 0x42, 0x3e, 0xf0, - 0x1f, 0x1e, 0x37, 0x7d, 0xfa, 0xfc, 0x48, 0x50, 0x4f, 0x4c, 0xec, 0x4a, - 0x5a, 0x12, 0x34, 0x12, 0xb2, 0x6f, 0xca, 0x12, 0xb1, 0x9d, 0xa1, 0x48, - 0x4a, 0xde, 0x6a, 0xe6, 0x43, 0x01, 0x61, 0xfb, 0x47, 0x12, 0x77, 0x9e, - 0xfb, 0xc9, 0xa7, 0xa3, 0xb7, 0xca, 0x86, 0x04, 0xcd, 0x44, 0x56, 0xcc, - 0x01, 0x09, 0xf6, 0xe1, 0x99, 0x6f, 0x3f, 0x6a, 0x18, 0xd2, 0xb3, 0xca, - 0xab, 0xcc, 0x95, 0x56, 0x9a, 0x3f, 0x79, 0x34, 0x2c, 0xbf, 0x57, 0x0f, - 0xc9, 0xf7, 0xea, 0xa6, 0x5c, 0xac, 0x07, 0xb4, 0xf1, 0x92, 0x29, 0xb3, - 0xa5, 0x69, 0xfd, 0x48, 0x31, 0x2f, 0xa9, 0x7a, 0x56, 0x2f, 0x2c, 0x98, - 0x3d, 0xc9, 0xf3, 0x39, 0x7d, 0x76, 0xa1, 0xb7, 0x27, 0x75, 0x7e, 0x5a, - 0x2f, 0x14, 0xc3, 0x3d, 0xc9, 0xba, 0xd9, 0x93, 0x5a, 0x0c, 0xe1, 0xba, - 0xb7, 0x27, 0xb9, 0x18, 0x9d, 0x17, 0xd9, 0x8a, 0x3e, 0xe1, 0x9e, 0x54, - 0x29, 0x9a, 0x15, 0xe9, 0x8f, 0xbf, 0x2a, 0x7d, 0x3d, 0xa9, 0xfa, 0x3f, - 0xd1, 0x1b, 0xa6, 0x26, 0x85, 0x5f, 0x15, 0x33, 0x9c, 0xb8, 0xd5, 0x7c, - 0xc8, 0xd2, 0xc4, 0xb4, 0x6e, 0x37, 0xb7, 0x58, 0x41, 0xc9, 0x9d, 0xee, - 0x14, 0x5b, 0xcd, 0xc9, 0x94, 0xdc, 0xe2, 0x90, 0xb9, 0x2c, 0x6d, 0x62, - 0x87, 0xfc, 0xeb, 0x66, 0x33, 0x19, 0xff, 0x32, 0xe5, 0x8a, 0x71, 0xa4, - 0x67, 0xbc, 0x2e, 0x92, 0x2c, 0x05, 0x25, 0x19, 0x7f, 0xab, 0xe9, 0x3e, - 0x13, 0xc4, 0x98, 0x81, 0x9e, 0xb1, 0x52, 0xb3, 0x99, 0x8e, 0x83, 0x7e, - 0xdc, 0x7f, 0xb6, 0x4d, 0xca, 0x21, 0xbb, 0x3c, 0x1b, 0xff, 0x6f, 0xba, - 0xab, 0x13, 0xce, 0x91, 0xd7, 0xb6, 0xe8, 0x56, 0x5e, 0x72, 0x21, 0x29, - 0x17, 0xe2, 0x9f, 0x92, 0x13, 0xf1, 0x30, 0xe6, 0x17, 0x94, 0x63, 0x71, - 0xc8, 0xd1, 0x3a, 0xac, 0x25, 0xeb, 0xd1, 0x48, 0x56, 0x9e, 0x97, 0xe4, - 0x62, 0xbf, 0x99, 0x16, 0x8c, 0x6d, 0x35, 0x3f, 0x9a, 0x8c, 0x63, 0xbc, - 0xe1, 0xff, 0xd5, 0xb4, 0x43, 0xd1, 0x6c, 0x59, 0x06, 0xa5, 0x50, 0xea, - 0x8f, 0xff, 0x4c, 0x34, 0x09, 0x5a, 0x62, 0x4f, 0x59, 0x26, 0xe4, 0x16, - 0x1d, 0x4c, 0x19, 0x4d, 0xd9, 0x83, 0xf1, 0x93, 0x16, 0xee, 0xd7, 0x65, - 0xb3, 0x6e, 0xb5, 0x4b, 0xc1, 0x94, 0x50, 0x97, 0x3c, 0x22, 0x85, 0xd3, - 0x68, 0x8f, 0xdb, 0xbd, 0x3a, 0x9e, 0xc9, 0x8c, 0xb0, 0x4d, 0x34, 0x23, - 0x11, 0x33, 0x53, 0xe0, 0xa8, 0xe2, 0x0c, 0x62, 0xfc, 0x98, 0xdd, 0xa9, - 0x99, 0xb2, 0x62, 0x06, 0xa4, 0xea, 0xc4, 0xec, 0xb0, 0xd6, 0x2e, 0xc7, - 0x62, 0x5d, 0x90, 0x69, 0x18, 0xb4, 0xe5, 0x9b, 0x7a, 0x22, 0x16, 0xce, - 0x41, 0x51, 0x3a, 0x64, 0x35, 0x07, 0x7e, 0xe6, 0xe2, 0x59, 0x2d, 0x55, - 0xff, 0x8a, 0x96, 0x3c, 0xbf, 0x5f, 0xdb, 0x75, 0x1e, 0x7d, 0xea, 0xe7, - 0x3c, 0xbb, 0x0b, 0x83, 0x37, 0x1d, 0xcf, 0xb2, 0x1d, 0x3c, 0x2b, 0xde, - 0xd1, 0x06, 0x5d, 0x36, 0x26, 0x43, 0x3d, 0x49, 0xa5, 0x4b, 0xf2, 0xa6, - 0x4b, 0x6e, 0x42, 0x93, 0x5e, 0xcb, 0x96, 0xe0, 0x27, 0xa1, 0xcf, 0x45, - 0xe8, 0x72, 0x31, 0x22, 0x47, 0x4a, 0x12, 0xd2, 0x85, 0x63, 0x65, 0xf5, - 0xaa, 0x43, 0x7b, 0x80, 0x6e, 0xa1, 0xfb, 0x82, 0xc3, 0x67, 0xa1, 0xc3, - 0x52, 0x1a, 0xf2, 0xc9, 0x60, 0xec, 0x7d, 0xda, 0x9e, 0xea, 0xa4, 0x96, - 0x81, 0x9d, 0x14, 0x4e, 0x0f, 0x41, 0x77, 0xd1, 0xc8, 0x8a, 0x6c, 0x96, - 0x82, 0x65, 0x45, 0xbe, 0x2c, 0xdd, 0x72, 0x6c, 0xd1, 0x92, 0x23, 0x8b, - 0x21, 0xc9, 0x9b, 0x51, 0xb3, 0x26, 0x7d, 0xd9, 0x4d, 0x89, 0x1e, 0x79, - 0xfe, 0x74, 0x34, 0x53, 0x96, 0x7e, 0xfb, 0x75, 0xdc, 0xcf, 0x9d, 0xa4, - 0x4e, 0x25, 0x9f, 0x8a, 0x1b, 0x92, 0x85, 0x4d, 0x18, 0xd6, 0x1f, 0x81, - 0xff, 0xe6, 0x73, 0xc9, 0x78, 0x34, 0x2c, 0xa2, 0x4b, 0xea, 0x0b, 0xfd, - 0xe6, 0x6e, 0x89, 0x9a, 0x19, 0xca, 0x3f, 0x3e, 0x04, 0x3d, 0xfc, 0x77, - 0xca, 0x1e, 0xb4, 0xa8, 0xe3, 0xa1, 0xf0, 0x31, 0xe8, 0x32, 0xab, 0x74, - 0xdc, 0x83, 0xf1, 0x03, 0x9e, 0xed, 0xf4, 0x48, 0xbe, 0x7a, 0xc3, 0x93, - 0x43, 0x8f, 0xcc, 0x57, 0xbb, 0xa5, 0x00, 0x1d, 0x16, 0xc4, 0x92, 0xc2, - 0xf9, 0x3f, 0xf7, 0xda, 0x2d, 0x99, 0x3b, 0xff, 0x32, 0xec, 0xe1, 0xb0, - 0xb6, 0xbf, 0xfe, 0x0b, 0xcd, 0xb3, 0x1f, 0xd8, 0x5f, 0x50, 0xec, 0x89, - 0xa0, 0x9c, 0xab, 0xbb, 0xf6, 0x57, 0xc1, 0x1a, 0xb3, 0x4d, 0x1b, 0xb6, - 0xf4, 0xc6, 0x6a, 0x9f, 0x73, 0xf5, 0x3e, 0x3c, 0x1b, 0x94, 0x23, 0x75, - 0xf6, 0xcf, 0xc3, 0xc6, 0x82, 0xb2, 0xf4, 0x68, 0xb7, 0x64, 0xd1, 0x5e, - 0x58, 0x14, 0x3b, 0x19, 0xd7, 0xf1, 0x4c, 0x0f, 0xe6, 0xb2, 0x15, 0x9f, - 0x2e, 0x99, 0xaa, 0x76, 0xd8, 0x86, 0x15, 0x92, 0xa9, 0x3a, 0xf5, 0x8f, - 0xef, 0x92, 0x6f, 0x03, 0x94, 0x2f, 0xdb, 0xf9, 0x1c, 0xdb, 0x4d, 0xb4, - 0xb7, 0xb6, 0xd1, 0xb6, 0x37, 0x53, 0xa6, 0x83, 0x82, 0xb6, 0x5c, 0x29, - 0x66, 0xee, 0xe7, 0x77, 0x9d, 0xf6, 0xd0, 0x6a, 0x0b, 0x01, 0xf4, 0x87, - 0x1e, 0xab, 0x18, 0xeb, 0xf4, 0x9d, 0x66, 0xdb, 0x08, 0xae, 0x2d, 0x2c, - 0xaa, 0x2e, 0x8e, 0x1d, 0x00, 0x5f, 0xba, 0x64, 0xab, 0x8a, 0xb7, 0x08, - 0x6d, 0xc0, 0x9d, 0x47, 0x9f, 0xcc, 0x2e, 0x76, 0xf7, 0xa4, 0x17, 0xd9, - 0x9e, 0x0c, 0x1b, 0x98, 0xe7, 0x54, 0x5c, 0x1a, 0x73, 0x71, 0xbd, 0x3f, - 0x00, 0xbe, 0xa6, 0xb1, 0xe0, 0x30, 0x0f, 0x8f, 0xc7, 0x06, 0xee, 0xf7, - 0xca, 0xd4, 0x79, 0xf6, 0xe5, 0x18, 0x85, 0x2d, 0xba, 0x24, 0xc0, 0x1b, - 0x3e, 0x56, 0x14, 0xf7, 0x3b, 0x31, 0x4e, 0x37, 0x6c, 0x27, 0x83, 0x31, - 0x9b, 0x8f, 0x27, 0xe3, 0xbd, 0x92, 0x5d, 0xed, 0x2b, 0xb0, 0x3b, 0xf6, - 0x1f, 0x5c, 0xd7, 0x17, 0xf2, 0x3d, 0x0f, 0x9a, 0x8b, 0x9d, 0x90, 0x21, - 0xdb, 0x75, 0xf0, 0xdc, 0x01, 0x1e, 0x82, 0x98, 0x4f, 0x3f, 0xd6, 0x43, - 0x07, 0xe8, 0x6f, 0xc2, 0x9c, 0x3a, 0x65, 0xfa, 0x74, 0x2f, 0x74, 0x61, - 0xa2, 0x6f, 0x50, 0x9e, 0x2f, 0x45, 0x61, 0x03, 0xec, 0x0f, 0x1d, 0x2c, - 0x46, 0xc3, 0x55, 0xb1, 0x65, 0x2e, 0xde, 0x01, 0xfb, 0x6a, 0x36, 0x67, - 0x60, 0x1f, 0xdf, 0x51, 0xfe, 0x62, 0xc8, 0x1c, 0xd3, 0x24, 0xdf, 0x91, - 0x38, 0x0c, 0x7e, 0xa2, 0x4f, 0x89, 0xf0, 0x7a, 0x87, 0xc6, 0x35, 0x0b, - 0x39, 0x72, 0x6c, 0xf8, 0xa4, 0xad, 0x90, 0x21, 0xfd, 0x56, 0x1f, 0xec, - 0x39, 0xac, 0xfc, 0xc9, 0xd8, 0x86, 0xfe, 0x24, 0x3a, 0x51, 0xc6, 0x58, - 0x85, 0xf3, 0x01, 0xfa, 0xb0, 0x51, 0x2c, 0x57, 0x79, 0x00, 0x6b, 0x6f, - 0x56, 0xd9, 0xc7, 0x09, 0xce, 0xb7, 0xf9, 0xf9, 0x38, 0xf9, 0xe2, 0x7c, - 0x6d, 0x3c, 0x4b, 0x1b, 0x8c, 0x1e, 0xb6, 0xd5, 0xf8, 0x27, 0xbc, 0xf1, - 0x5d, 0xde, 0x0b, 0xa5, 0x1e, 0x2d, 0xa5, 0x78, 0xf0, 0xe9, 0x88, 0x2c, - 0x9f, 0xec, 0x37, 0xf7, 0xc0, 0x86, 0xe9, 0xa7, 0x96, 0x2f, 0x50, 0xc7, - 0xa0, 0x31, 0x42, 0x1d, 0x9b, 0x8a, 0xbf, 0xe4, 0x22, 0xd7, 0x9e, 0xf4, - 0x19, 0x42, 0x1f, 0x01, 0x9f, 0x8b, 0xb5, 0x38, 0xeb, 0xad, 0xc5, 0x9c, - 0x43, 0xfb, 0x7b, 0x06, 0xcf, 0xea, 0x32, 0x16, 0xa3, 0x7f, 0x78, 0x5e, - 0x52, 0xf0, 0x91, 0xd0, 0xa3, 0x54, 0x31, 0x97, 0x4a, 0xa9, 0xd5, 0x6f, - 0xc1, 0xb6, 0x86, 0xff, 0xae, 0xe9, 0xfa, 0x43, 0xfa, 0x06, 0xfa, 0x9a, - 0x82, 0xa9, 0x43, 0x72, 0x3a, 0x9c, 0x21, 0x74, 0x13, 0x4f, 0x1a, 0xd1, - 0x4c, 0x16, 0x7c, 0x4d, 0x59, 0x4d, 0xb1, 0x1e, 0x13, 0x44, 0x0c, 0xf4, - 0xa9, 0xcb, 0x4e, 0xdf, 0x3f, 0x2d, 0x3b, 0xbe, 0x2e, 0xa8, 0x57, 0xea, - 0xc1, 0xf7, 0x11, 0x01, 0xb9, 0x0c, 0xdf, 0x35, 0x57, 0xea, 0x96, 0x06, - 0x78, 0xba, 0xe2, 0xf8, 0xb6, 0x66, 0x78, 0xb6, 0xc6, 0x67, 0xba, 0xf1, - 0x7c, 0x00, 0x7e, 0x4d, 0xf2, 0x46, 0x02, 0xbf, 0x8b, 0xa4, 0xc9, 0x36, - 0xdf, 0xce, 0xb9, 0x66, 0xa2, 0x76, 0x59, 0xda, 0x25, 0x13, 0x43, 0xfc, - 0x58, 0xd4, 0x31, 0x56, 0x1f, 0x7c, 0x79, 0x40, 0x0e, 0x96, 0x42, 0xf2, - 0xd5, 0x12, 0xe7, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xb1, 0x09, 0x9d, - 0x8f, 0xc3, 0xe7, 0x65, 0xb4, 0x31, 0xf8, 0x9f, 0xdd, 0xd5, 0xaf, 0x68, - 0xe9, 0xf3, 0x59, 0x6d, 0xbc, 0xbe, 0x5f, 0xcb, 0x9c, 0x9f, 0xd4, 0x76, - 0xb5, 0xf8, 0x22, 0xd1, 0xde, 0xdd, 0x17, 0x9d, 0x38, 0xcd, 0x31, 0xfb, - 0xe3, 0x1b, 0xfb, 0xa2, 0x5f, 0x6a, 0xad, 0xbe, 0xa8, 0x1f, 0xbe, 0x28, - 0x03, 0x5f, 0x34, 0x7e, 0xdf, 0xbe, 0xa8, 0x5d, 0xdf, 0xd8, 0x17, 0x75, - 0xeb, 0x77, 0x7d, 0x11, 0x63, 0xcf, 0xbf, 0xc6, 0xb5, 0x29, 0xdb, 0x76, - 0xfa, 0x72, 0x0e, 0xc3, 0x0f, 0x6f, 0x82, 0xac, 0xbb, 0xb8, 0x76, 0x22, - 0x05, 0xd8, 0xfd, 0x34, 0xc6, 0xfa, 0x4d, 0xd8, 0xfb, 0xb6, 0x98, 0x65, - 0x3e, 0xa1, 0xc6, 0x7d, 0xa7, 0xce, 0xc7, 0x56, 0x75, 0x4e, 0x1e, 0xdf, - 0x53, 0xe7, 0xb6, 0xab, 0x73, 0xea, 0xba, 0x53, 0x66, 0xd4, 0xb8, 0x4d, - 0x09, 0x3c, 0x26, 0xf0, 0x2a, 0xf2, 0x59, 0x23, 0x11, 0x05, 0x3d, 0x1d, - 0xe3, 0x53, 0x5f, 0x31, 0xf0, 0x20, 0xd0, 0x6f, 0xb7, 0xf2, 0x45, 0xbb, - 0xa0, 0xf7, 0x65, 0xe7, 0xfe, 0x74, 0x95, 0x69, 0xd1, 0xd5, 0x9e, 0x35, - 0xba, 0xea, 0x90, 0xe1, 0x98, 0xaf, 0xa3, 0xcd, 0x92, 0x8c, 0x51, 0x67, - 0xf7, 0xa3, 0xab, 0x7f, 0xaa, 0xff, 0xfd, 0xe8, 0xea, 0xb7, 0xee, 0xa1, - 0xab, 0x7f, 0xb5, 0x4e, 0x57, 0x96, 0xf9, 0x82, 0x46, 0xda, 0x8c, 0x1f, - 0xf4, 0x47, 0xcd, 0x8f, 0x4e, 0x31, 0x7f, 0xa8, 0x73, 0x4d, 0xfb, 0x79, - 0x07, 0xd7, 0xf3, 0xa5, 0xa6, 0x61, 0x59, 0x90, 0x1d, 0xd7, 0x34, 0xe5, - 0x16, 0x35, 0x3f, 0x4f, 0xfe, 0x11, 0x3b, 0xa6, 0x10, 0x6b, 0x5c, 0x1e, - 0xda, 0xa5, 0xbc, 0xc5, 0xed, 0x3f, 0x55, 0x6a, 0xfe, 0x42, 0x4f, 0xbc, - 0xdd, 0x4c, 0x8e, 0x58, 0x5e, 0x1c, 0x08, 0xca, 0xd7, 0xaa, 0xd1, 0xac, - 0xad, 0x75, 0x4b, 0xfe, 0x41, 0xc4, 0x9e, 0x12, 0xfd, 0xd7, 0xd6, 0x7b, - 0xc4, 0xe8, 0x3e, 0x2f, 0x46, 0x57, 0xc1, 0x2b, 0xf3, 0xab, 0xef, 0xbe, - 0xd5, 0x08, 0xf1, 0x3b, 0x66, 0xee, 0x93, 0x2f, 0x73, 0x8e, 0x88, 0xf7, - 0x8c, 0xfb, 0x16, 0x73, 0x9e, 0x7c, 0x20, 0xd1, 0x25, 0xf9, 0x2d, 0x5c, - 0x8f, 0xf4, 0x73, 0xf4, 0x5d, 0xed, 0x1e, 0xdf, 0x7e, 0x8e, 0xa4, 0x78, - 0x33, 0x30, 0x65, 0xf4, 0x41, 0x3e, 0x54, 0xe2, 0x3c, 0xde, 0xf2, 0xec, - 0x89, 0xb9, 0x82, 0xb4, 0xb9, 0xbe, 0x61, 0x2f, 0x72, 0x01, 0xda, 0x81, - 0xaf, 0x73, 0xea, 0x9b, 0x39, 0x82, 0x44, 0x74, 0x8b, 0x39, 0x82, 0x98, - 0x46, 0x62, 0x9f, 0x66, 0x43, 0xf7, 0x36, 0x74, 0x6f, 0x43, 0xf7, 0x36, - 0x74, 0x9f, 0xac, 0x1f, 0xc6, 0x3d, 0x95, 0x87, 0x80, 0x17, 0x97, 0x7e, - 0xda, 0xa5, 0x0f, 0x3e, 0xb7, 0x4a, 0x4e, 0xe9, 0x84, 0xf3, 0x45, 0xae, - 0xa1, 0xfc, 0xf5, 0xb8, 0xe6, 0xfa, 0x6b, 0xd2, 0xcb, 0xe0, 0xf9, 0xdb, - 0x98, 0xa7, 0xad, 0xeb, 0xd6, 0x5d, 0x99, 0xcc, 0xb5, 0xc8, 0x64, 0xd6, - 0xa1, 0x8c, 0xd8, 0x9f, 0x3e, 0x77, 0x5a, 0xaf, 0xac, 0xca, 0x65, 0x2f, - 0x78, 0xe8, 0xe0, 0xdc, 0xbd, 0x79, 0x90, 0x7e, 0xaf, 0x47, 0xff, 0x6f, - 0xd1, 0x87, 0xfe, 0x75, 0xa3, 0x71, 0x39, 0x26, 0x73, 0xc6, 0x77, 0x9b, - 0x0f, 0x72, 0x66, 0xac, 0x81, 0xef, 0x21, 0x96, 0x5f, 0x44, 0x2c, 0x59, - 0x31, 0x22, 0xf2, 0x93, 0x47, 0xaf, 0x21, 0x97, 0x96, 0xfc, 0xc3, 0x89, - 0x66, 0x24, 0x90, 0x78, 0xab, 0x39, 0x37, 0x82, 0x18, 0x97, 0x88, 0x86, - 0x93, 0xc6, 0xb0, 0x5c, 0xaa, 0x0f, 0xca, 0x8f, 0xea, 0x96, 0xfc, 0xb0, - 0x1e, 0x91, 0x1f, 0x20, 0xe6, 0x7f, 0xbf, 0xde, 0x9a, 0x73, 0x47, 0x68, - 0x4f, 0x3d, 0xe9, 0xfa, 0x46, 0xb9, 0x7f, 0x13, 0x34, 0xde, 0x82, 0x9d, - 0x04, 0xb2, 0xc8, 0xf5, 0x19, 0xbf, 0x26, 0x0e, 0x15, 0x9f, 0x6b, 0x82, - 0xb7, 0x6c, 0x5b, 0xc2, 0xca, 0xeb, 0x7a, 0xf7, 0xa8, 0xf9, 0x29, 0xb4, - 0x39, 0xa3, 0x81, 0x6a, 0xb1, 0x53, 0xe5, 0x8b, 0xd0, 0x91, 0xd8, 0xf5, - 0x60, 0xb0, 0x56, 0xbc, 0x85, 0x7e, 0xcd, 0xe6, 0xa1, 0xf8, 0x6f, 0xed, - 0x30, 0xff, 0x81, 0x85, 0x35, 0xdd, 0xf9, 0x25, 0x23, 0xb1, 0x49, 0x66, - 0x43, 0xdf, 0x6f, 0x98, 0x03, 0x7d, 0x59, 0x3d, 0x11, 0x94, 0x74, 0x91, - 0x6b, 0x2a, 0x24, 0xb3, 0x55, 0x28, 0xff, 0x3c, 0xd7, 0x85, 0x3c, 0x3b, - 0x17, 0xef, 0x86, 0xed, 0xff, 0x9a, 0xe1, 0xae, 0x03, 0x18, 0x50, 0x75, - 0x50, 0xf2, 0xe0, 0x37, 0x5f, 0x7f, 0xcb, 0xc3, 0x0e, 0xf0, 0x2a, 0x5b, - 0x21, 0xf8, 0xc4, 0x70, 0xda, 0x76, 0xfe, 0x30, 0x88, 0xb6, 0xe0, 0x56, - 0xeb, 0xce, 0x26, 0x7c, 0x3f, 0x10, 0xb2, 0x88, 0x4d, 0x24, 0xf3, 0x05, - 0x7c, 0xff, 0x4a, 0x42, 0x36, 0xf7, 0xe2, 0x7b, 0x4b, 0x02, 0x26, 0x99, - 0x60, 0xcc, 0xd5, 0x5a, 0x62, 0xae, 0x68, 0x69, 0xc8, 0x6e, 0x0e, 0x73, - 0x4f, 0x43, 0x9e, 0x5f, 0xac, 0x07, 0xb5, 0xd4, 0xe9, 0x47, 0xc0, 0x87, - 0x9f, 0x3b, 0x23, 0x3f, 0x33, 0x97, 0xb7, 0x04, 0xe4, 0x16, 0x7c, 0x5c, - 0x12, 0x7e, 0xcc, 0x46, 0x6e, 0xb1, 0x03, 0xcb, 0x35, 0xfa, 0x5f, 0xbf, - 0x20, 0x5f, 0xf3, 0x78, 0x6b, 0x93, 0x05, 0x65, 0xa3, 0x6c, 0xcf, 0x67, - 0xfe, 0xcd, 0xc0, 0xdd, 0xf6, 0x17, 0x57, 0xdb, 0xcb, 0x99, 0x7f, 0xb8, - 0xda, 0xde, 0xdb, 0xe6, 0xf2, 0x3f, 0xaa, 0x4d, 0xd4, 0xf7, 0x78, 0x6d, - 0xb7, 0xa1, 0xb3, 0x66, 0x93, 0xb9, 0x45, 0x01, 0xd8, 0x24, 0x1d, 0xa7, - 0x2f, 0xbe, 0x1f, 0x5f, 0xbb, 0xc6, 0xcf, 0x9a, 0x49, 0x83, 0xb6, 0x10, - 0x14, 0x97, 0x26, 0xef, 0x77, 0x20, 0x7f, 0xbf, 0x8d, 0xdf, 0x8c, 0xa3, - 0x7e, 0x6e, 0xce, 0x3e, 0x7c, 0xfe, 0xcd, 0x7b, 0xd8, 0x4b, 0x08, 0xf6, - 0xf2, 0xff, 0xab, 0x5d, 0x5c, 0xba, 0x1f, 0xbb, 0xc0, 0x9f, 0xb2, 0x0b, - 0xd5, 0xff, 0xd2, 0xea, 0x5a, 0x09, 0x43, 0x3e, 0x8c, 0x07, 0x83, 0xd0, - 0xf1, 0x66, 0x99, 0xb5, 0xc8, 0x8f, 0x15, 0xc9, 0xc1, 0x5f, 0x9e, 0x58, - 0x17, 0xbb, 0xbb, 0x10, 0x0f, 0x8e, 0x9f, 0x8e, 0x8e, 0x32, 0x1e, 0xc4, - 0xe0, 0x1b, 0x93, 0xef, 0x88, 0x07, 0x37, 0x8c, 0xd6, 0x78, 0x60, 0x20, - 0x1e, 0xec, 0x7a, 0x97, 0x78, 0x70, 0xe2, 0x1d, 0xf1, 0x40, 0x83, 0x6c, - 0x38, 0xbf, 0xbf, 0x35, 0xfc, 0x78, 0x50, 0x58, 0x13, 0x0f, 0x7c, 0x5d, - 0x59, 0x0a, 0x0b, 0xdc, 0xd5, 0x5b, 0x97, 0xa7, 0x2b, 0x09, 0x06, 0x12, - 0x8d, 0xcc, 0x9c, 0xf5, 0xb0, 0xb4, 0xc1, 0xe7, 0x5e, 0xaa, 0x8f, 0x40, - 0x67, 0x97, 0x30, 0xf7, 0x68, 0x9c, 0x89, 0x65, 0x5b, 0x82, 0xeb, 0xe1, - 0xcd, 0x08, 0x30, 0xe2, 0x6e, 0xe0, 0xbe, 0xdd, 0x67, 0xd5, 0xfa, 0x78, - 0x33, 0xea, 0x61, 0xf7, 0x6d, 0xc0, 0xee, 0x78, 0x3e, 0x00, 0x4c, 0xc8, - 0xf6, 0x2b, 0x66, 0x12, 0x7a, 0xaa, 0x3a, 0xf6, 0xee, 0x02, 0x3e, 0x73, - 0xaa, 0xef, 0xad, 0x08, 0xfb, 0x76, 0x24, 0x12, 0xd1, 0x3f, 0xc3, 0x77, - 0x7b, 0x22, 0xbc, 0xed, 0xaa, 0x45, 0xba, 0x87, 0xa2, 0x67, 0x15, 0x8d, - 0x80, 0x14, 0xd4, 0xb3, 0x91, 0x6d, 0x7c, 0xf6, 0x18, 0x62, 0xf6, 0x51, - 0xc7, 0x94, 0x23, 0x4e, 0x76, 0x77, 0x0e, 0x1f, 0x62, 0xd5, 0x4b, 0x25, - 0xde, 0x1f, 0xc5, 0xfd, 0x80, 0x30, 0x97, 0xfc, 0x2a, 0xfa, 0x1c, 0x44, - 0x9f, 0x19, 0xc7, 0xd7, 0x05, 0xef, 0x37, 0x32, 0x29, 0xdc, 0x9f, 0x29, - 0x36, 0x32, 0xe9, 0x22, 0xf3, 0xd6, 0xa1, 0xf0, 0x11, 0xc8, 0x33, 0x8b, - 0x5c, 0xcd, 0x96, 0xe8, 0x60, 0x5e, 0x9e, 0xee, 0x1c, 0x07, 0x4e, 0x3a, - 0x87, 0x1c, 0xc2, 0x9e, 0x8c, 0xc6, 0xcb, 0xf2, 0xe1, 0xce, 0xe4, 0x69, - 0xe4, 0x0b, 0xf1, 0xed, 0x90, 0x61, 0x23, 0xa3, 0xc7, 0x04, 0xb6, 0x1e, - 0x87, 0x5f, 0x1e, 0xd1, 0x53, 0xc5, 0x7e, 0x73, 0x56, 0x1e, 0x95, 0x86, - 0x19, 0x0d, 0x8f, 0xcb, 0x26, 0x49, 0x05, 0xd0, 0x6f, 0xf0, 0x43, 0x92, - 0x0d, 0x53, 0xd6, 0x0f, 0xc2, 0xdf, 0x6b, 0xd2, 0x61, 0xb5, 0xc6, 0x9e, - 0x5b, 0x10, 0x6f, 0x2e, 0x40, 0x9f, 0xdd, 0x61, 0x75, 0x7a, 0x3a, 0xd9, - 0x24, 0xcb, 0xef, 0xe8, 0x77, 0xbb, 0xa5, 0x5f, 0x6b, 0xfb, 0xdb, 0x68, - 0xdf, 0x84, 0x9c, 0xb3, 0x91, 0x09, 0xc4, 0x20, 0x7f, 0xcc, 0xa1, 0x0d, - 0x76, 0x72, 0x15, 0xf3, 0x61, 0x1c, 0x2c, 0x94, 0x99, 0xf7, 0x18, 0x52, - 0x36, 0x71, 0xcf, 0x69, 0x36, 0x2b, 0x16, 0xf8, 0xbd, 0x40, 0x9e, 0x83, - 0x32, 0xee, 0x0c, 0x88, 0x5d, 0xa3, 0x1c, 0xa2, 0xf0, 0x4a, 0x0f, 0x77, - 0xa5, 0x16, 0xa3, 0x76, 0x1e, 0x14, 0x8d, 0x0b, 0x7d, 0x5d, 0x49, 0xe4, - 0x39, 0xfa, 0x85, 0x48, 0x57, 0x0a, 0x36, 0x6b, 0x5c, 0x78, 0xa8, 0x2b, - 0x7d, 0x9a, 0x7c, 0x19, 0xc8, 0x73, 0x3e, 0x0a, 0x9c, 0xdf, 0x94, 0xdf, - 0x45, 0x2e, 0x5b, 0x18, 0x44, 0x0e, 0x80, 0xd5, 0xaf, 0x83, 0xef, 0xbc, - 0x29, 0xc1, 0xae, 0xc4, 0xab, 0xe0, 0x6f, 0x18, 0xb2, 0xd9, 0x84, 0x3e, - 0x06, 0xda, 0x07, 0x58, 0x13, 0x68, 0x69, 0xb7, 0xba, 0x10, 0x4f, 0x11, - 0xbb, 0x24, 0x98, 0x1c, 0xe9, 0x06, 0xfd, 0x2b, 0x01, 0xe6, 0x82, 0xc1, - 0xd8, 0x6a, 0xfb, 0x37, 0xdd, 0xf6, 0x41, 0xf0, 0xc2, 0xe7, 0x88, 0x09, - 0x24, 0x38, 0x35, 0x62, 0x82, 0x07, 0xf6, 0x0d, 0xa9, 0xbe, 0xe9, 0x45, - 0xda, 0x40, 0x23, 0x53, 0xb1, 0x1e, 0x91, 0xd4, 0xc2, 0x56, 0x19, 0x5f, - 0xe8, 0x95, 0x5d, 0x0b, 0xc4, 0x30, 0xac, 0x69, 0x60, 0x2a, 0xc0, 0x18, - 0xfa, 0x05, 0xe6, 0x76, 0xd1, 0xf0, 0x41, 0xe9, 0x0f, 0x7f, 0x15, 0xeb, - 0x60, 0xca, 0x8a, 0x45, 0x66, 0xb1, 0xc6, 0x02, 0x8a, 0x4e, 0xd8, 0x1f, - 0x93, 0x36, 0xba, 0x66, 0xdc, 0xf4, 0xe2, 0xbd, 0xe8, 0x62, 0xe1, 0x5c, - 0x08, 0xaf, 0xa3, 0xfb, 0x57, 0x1e, 0x5d, 0x13, 0x74, 0xfb, 0x40, 0x93, - 0x73, 0x7c, 0xa8, 0x73, 0xec, 0xb4, 0xd8, 0x1d, 0xe0, 0x2f, 0x1d, 0x7b, - 0x58, 0x66, 0x41, 0xe7, 0xe8, 0x02, 0xfd, 0xa4, 0x6c, 0xc5, 0x67, 0xb8, - 0x4d, 0x62, 0x83, 0xe7, 0x81, 0x73, 0xc6, 0x14, 0x0d, 0x17, 0x73, 0xe8, - 0x17, 0x12, 0xc0, 0xa9, 0x1f, 0x07, 0x3f, 0xcc, 0xb1, 0x38, 0xe7, 0x00, - 0xe6, 0x9b, 0xc0, 0x3a, 0x64, 0x7d, 0x85, 0xeb, 0x1b, 0xbf, 0xcf, 0x87, - 0x3b, 0x53, 0xa7, 0xdb, 0xb1, 0xee, 0xe4, 0x11, 0x43, 0xc5, 0x7e, 0xea, - 0xc5, 0xea, 0x4c, 0x96, 0x14, 0xdf, 0x9d, 0xa9, 0x12, 0x65, 0x14, 0xef, - 0x4c, 0x97, 0x28, 0x23, 0x01, 0x3f, 0x71, 0xd8, 0x64, 0x40, 0x22, 0x5b, - 0xa8, 0xc7, 0x43, 0xe8, 0xf7, 0x57, 0x01, 0xe2, 0xb8, 0xa4, 0xc5, 0xdf, - 0xf0, 0xb5, 0x17, 0x0e, 0xa3, 0x2f, 0x7f, 0x6f, 0x07, 0xdd, 0xfe, 0xc1, - 0x82, 0xb4, 0x0f, 0xce, 0xc0, 0x4f, 0xe8, 0x23, 0xc0, 0x91, 0xca, 0xce, - 0x9b, 0xc0, 0xd8, 0x3b, 0x30, 0x1f, 0xac, 0x8d, 0x98, 0x25, 0xd3, 0xf3, - 0x94, 0xab, 0x7c, 0x08, 0x73, 0xc0, 0xfc, 0x63, 0xf0, 0x2d, 0x9c, 0x03, - 0xc7, 0x16, 0xe4, 0x36, 0x4b, 0x92, 0x9b, 0x0f, 0x2a, 0x2c, 0x6b, 0x9b, - 0x1c, 0x5f, 0xd3, 0xf4, 0x44, 0x17, 0x74, 0xcc, 0xb9, 0xcd, 0x81, 0xb7, - 0x67, 0x10, 0xff, 0xa2, 0x0a, 0x43, 0x19, 0x17, 0xb8, 0x56, 0x46, 0xb1, - 0x4e, 0xc8, 0xbf, 0x67, 0x7b, 0x5a, 0x03, 0x3e, 0x45, 0xf9, 0x7f, 0xe4, - 0xea, 0x09, 0xf8, 0x91, 0x51, 0xf9, 0x7d, 0xf8, 0x92, 0x1f, 0xd7, 0xe3, - 0xc8, 0x1b, 0x86, 0x91, 0x37, 0x0c, 0x22, 0x6f, 0xb0, 0x90, 0x37, 0x44, - 0x90, 0x37, 0xf4, 0x21, 0x6f, 0x08, 0x23, 0x3e, 0x88, 0x1c, 0xad, 0xe7, - 0x61, 0x63, 0x0d, 0xf8, 0x41, 0x33, 0x68, 0xd7, 0x43, 0xc1, 0x64, 0x3d, - 0x1c, 0x4c, 0xd5, 0x03, 0x98, 0xd3, 0x01, 0x8e, 0x89, 0xf9, 0xe5, 0x3b, - 0xc7, 0x4a, 0xc3, 0x88, 0x39, 0x36, 0xfc, 0x52, 0x1a, 0xf1, 0x36, 0x2e, - 0x47, 0xf0, 0xcc, 0xf2, 0x7c, 0x04, 0xcf, 0x34, 0x25, 0x1d, 0x6f, 0x93, - 0x59, 0x33, 0x0e, 0x1a, 0x5b, 0x94, 0x9d, 0x22, 0xdf, 0x6a, 0x83, 0x9d, - 0x4a, 0xae, 0xc8, 0x7c, 0xab, 0x0f, 0xf4, 0x3a, 0x11, 0x97, 0xe9, 0x1f, - 0xe8, 0x0b, 0xec, 0xdd, 0x5f, 0xb2, 0xb8, 0xe6, 0xba, 0xb4, 0xe4, 0xe9, - 0xbc, 0x10, 0x6b, 0x22, 0x0e, 0xc2, 0x2e, 0xd8, 0x36, 0x81, 0xe7, 0xf8, - 0xfb, 0x6d, 0xcf, 0xef, 0x7f, 0x24, 0x28, 0x30, 0xde, 0x4b, 0x8c, 0xf9, - 0x16, 0xe8, 0x39, 0xad, 0xeb, 0xb5, 0xa6, 0x8b, 0xe5, 0xdf, 0x67, 0xfd, - 0x8d, 0x35, 0xc7, 0xd7, 0xc0, 0x73, 0xbf, 0xb9, 0x8c, 0x1c, 0xd9, 0xde, - 0xbf, 0x82, 0xdf, 0xad, 0xfd, 0xeb, 0xe8, 0xaf, 0xda, 0x82, 0x66, 0x22, - 0xce, 0x7c, 0x18, 0x3e, 0x73, 0x10, 0xfe, 0xf1, 0x56, 0x46, 0x5f, 0xba, - 0x89, 0x79, 0x42, 0x9e, 0xc5, 0x5b, 0x99, 0xc0, 0xc0, 0xb5, 0xe6, 0x8b, - 0xc0, 0x37, 0x63, 0x4b, 0x23, 0x92, 0x5a, 0xea, 0x0f, 0x5f, 0x96, 0xce, - 0xdb, 0xb6, 0x5c, 0x6b, 0xce, 0x3a, 0xd1, 0xe3, 0xb6, 0x10, 0x6f, 0x99, - 0x52, 0x01, 0xa9, 0x6d, 0x3b, 0x3b, 0x88, 0x19, 0x2f, 0x8a, 0x1e, 0x91, - 0xe4, 0x29, 0x5b, 0x46, 0x76, 0xfa, 0xb9, 0xfb, 0x9d, 0x0e, 0xe9, 0x42, - 0xdb, 0x52, 0x04, 0x7d, 0x88, 0x53, 0x39, 0xef, 0x2c, 0xe6, 0xac, 0xb9, - 0xcf, 0x78, 0xf5, 0xc9, 0x42, 0x09, 0x73, 0xaf, 0xdf, 0xca, 0x5c, 0x3e, - 0x05, 0xec, 0x0e, 0x1d, 0x25, 0x4f, 0xb1, 0xae, 0xb0, 0x09, 0x72, 0x1a, - 0x83, 0xad, 0xd0, 0x06, 0xfa, 0xf1, 0x6c, 0x53, 0xbe, 0x11, 0xa7, 0x5d, - 0xbc, 0x04, 0x59, 0x82, 0x56, 0xc0, 0x9f, 0x0f, 0x70, 0xde, 0x3c, 0xe5, - 0x17, 0x46, 0x6e, 0xce, 0xb1, 0x25, 0xd8, 0x99, 0x58, 0x9f, 0x77, 0xdf, - 0xca, 0x2c, 0x9f, 0x02, 0xfd, 0x01, 0xd6, 0xde, 0xe0, 0xb3, 0x8b, 0xac, - 0x1d, 0x32, 0x27, 0xdd, 0x05, 0x3d, 0xed, 0x55, 0xb5, 0xb8, 0x64, 0x35, - 0x2e, 0xd6, 0x49, 0xfa, 0x2c, 0x89, 0x18, 0xd6, 0x7e, 0xe4, 0xaf, 0x62, - 0xea, 0x89, 0x49, 0xdc, 0xa3, 0x3c, 0x35, 0xe4, 0x1c, 0xb8, 0x7f, 0x61, - 0x45, 0xe9, 0xc4, 0x80, 0xee, 0x72, 0x3b, 0x99, 0x84, 0xc9, 0xbc, 0x91, - 0x80, 0x2f, 0x1c, 0xe1, 0x1c, 0xd4, 0xd8, 0xc8, 0xc7, 0xb9, 0xfe, 0x30, - 0x67, 0xd8, 0x55, 0x4b, 0x5e, 0xae, 0xfe, 0x66, 0x4b, 0x47, 0x60, 0xd3, - 0x92, 0x6f, 0x43, 0x3e, 0x90, 0x1c, 0xc1, 0x6f, 0x38, 0x81, 0xa3, 0xd0, - 0xe7, 0xd9, 0x11, 0xd6, 0x3f, 0x5f, 0x02, 0xb6, 0x27, 0xdf, 0xb1, 0xc8, - 0x11, 0xb5, 0x86, 0x71, 0xed, 0x30, 0x97, 0xdb, 0x24, 0x97, 0xd5, 0xfc, - 0x1e, 0x22, 0xf6, 0x80, 0x9e, 0xee, 0x67, 0x7e, 0xe3, 0xf7, 0x39, 0x3f, - 0x97, 0x3e, 0x63, 0x57, 0xd2, 0x8a, 0x48, 0xaa, 0x78, 0xa9, 0x19, 0xb0, - 0x2c, 0x60, 0x67, 0x57, 0x8f, 0x29, 0x27, 0x08, 0x3e, 0x58, 0x6b, 0xdb, - 0xa9, 0x74, 0x09, 0x3e, 0x68, 0x3b, 0xf9, 0x60, 0x62, 0xb3, 0x9c, 0x9b, - 0xef, 0x91, 0xca, 0xfc, 0xcf, 0xa5, 0x3a, 0xdf, 0x25, 0xe7, 0xe7, 0x9b, - 0x72, 0x35, 0xae, 0x7c, 0x93, 0xd5, 0xae, 0xd6, 0xb5, 0x3c, 0xec, 0xd6, - 0x61, 0x62, 0xa3, 0xd7, 0xe5, 0x79, 0x39, 0x57, 0x76, 0x79, 0xcf, 0xb4, - 0xf0, 0x7e, 0x15, 0xb6, 0xf6, 0xaa, 0x45, 0xfe, 0x47, 0xa4, 0x52, 0x24, - 0xef, 0xfb, 0x14, 0xef, 0xbb, 0x56, 0x79, 0x97, 0xac, 0x61, 0x91, 0xff, - 0x8d, 0x78, 0xef, 0x90, 0xec, 0x56, 0xf2, 0x1f, 0xc1, 0xb3, 0xef, 0xb4, - 0xbf, 0x8a, 0x73, 0xad, 0xb9, 0x5c, 0x6c, 0x53, 0x3c, 0x1b, 0x89, 0x11, - 0xc8, 0xe7, 0x5a, 0xb3, 0xe1, 0x70, 0x1d, 0xe1, 0xb7, 0xf3, 0x2f, 0xe0, - 0xab, 0x7a, 0x55, 0xce, 0x92, 0x9b, 0xec, 0xee, 0x4c, 0x2e, 0x8e, 0x42, - 0xb7, 0x9d, 0x6a, 0x1d, 0xc2, 0x6d, 0x40, 0x67, 0xff, 0x1e, 0xfd, 0xbf, - 0xcd, 0xf5, 0xa6, 0xe4, 0x92, 0x86, 0x5c, 0x0a, 0xc5, 0xf1, 0x76, 0xe0, - 0x27, 0x8c, 0xd3, 0xc8, 0x64, 0x1d, 0x3e, 0xd3, 0x07, 0xdf, 0xc6, 0xef, - 0xf7, 0x6d, 0x0f, 0x79, 0xf8, 0x5c, 0xe8, 0x1c, 0x79, 0x05, 0xd7, 0xf3, - 0x48, 0x03, 0x31, 0x36, 0x36, 0x58, 0x51, 0xfb, 0x10, 0x71, 0x85, 0x85, - 0x67, 0x9d, 0x6f, 0xe3, 0xe3, 0x8e, 0x37, 0x56, 0xe7, 0x98, 0x6b, 0xe7, - 0x54, 0x70, 0x1a, 0xc8, 0xdf, 0x2d, 0xd0, 0xe5, 0xb8, 0x79, 0x31, 0x12, - 0x06, 0xc6, 0x65, 0x5b, 0x37, 0x7c, 0x4c, 0x04, 0x3e, 0x6b, 0x18, 0xbe, - 0x9f, 0x6b, 0x99, 0x7e, 0xde, 0xe7, 0x7d, 0x18, 0x34, 0xe9, 0x7f, 0x87, - 0x31, 0x67, 0xe6, 0xd8, 0xf4, 0x9f, 0x88, 0x27, 0xb5, 0x70, 0x57, 0xf2, - 0xb4, 0x5b, 0x1b, 0x74, 0x7f, 0xf3, 0xbe, 0x04, 0x1f, 0x49, 0x44, 0xcb, - 0x79, 0xe4, 0x7e, 0x29, 0xac, 0xd1, 0xa4, 0x85, 0x3c, 0xbb, 0x16, 0x7d, - 0x85, 0x98, 0x5b, 0xa7, 0x0c, 0x96, 0x28, 0x27, 0xd6, 0xa9, 0x4c, 0xc9, - 0x57, 0xbe, 0x0b, 0x79, 0x04, 0x65, 0x8b, 0x95, 0x85, 0x4f, 0x01, 0xff, - 0x98, 0xfb, 0x5c, 0x89, 0xb5, 0xc8, 0x7e, 0xc4, 0x31, 0x03, 0x42, 0x40, - 0x4e, 0xb5, 0x64, 0xc8, 0x67, 0x03, 0x43, 0xc8, 0x01, 0x9f, 0x45, 0xdf, - 0x80, 0xe4, 0x97, 0x18, 0x0f, 0x02, 0x32, 0xb7, 0x24, 0x72, 0xfd, 0x14, - 0xfd, 0x8a, 0xfa, 0x83, 0xcc, 0x1b, 0x99, 0x69, 0x62, 0xed, 0x79, 0xfa, - 0x18, 0xfa, 0x89, 0x07, 0xa1, 0x8b, 0xd8, 0x4b, 0xdf, 0x40, 0x6c, 0x9a, - 0x2d, 0xf6, 0xc3, 0x67, 0x4a, 0x43, 0x87, 0x4c, 0x11, 0xd3, 0x98, 0xa3, - 0x6f, 0x50, 0x77, 0xf4, 0x6b, 0x8e, 0x41, 0x29, 0x9c, 0x62, 0xbd, 0x31, - 0x08, 0x5e, 0x98, 0xb7, 0x1a, 0x2a, 0x0f, 0x7a, 0x50, 0xf9, 0x56, 0x7e, - 0x07, 0x5a, 0xc6, 0x8d, 0x1d, 0xdf, 0xa6, 0xd3, 0x8f, 0x3d, 0x22, 0xf6, - 0xc4, 0xa1, 0xce, 0x5d, 0xa5, 0x76, 0x29, 0xf7, 0xd2, 0x2e, 0xa9, 0xff, - 0xac, 0x4e, 0x5f, 0x8b, 0x3c, 0x0c, 0xf4, 0x58, 0x23, 0x08, 0xa0, 0x5f, - 0xc8, 0xeb, 0x47, 0xb9, 0xfe, 0xb6, 0x4c, 0xed, 0xfc, 0x3b, 0xf0, 0xe5, - 0xfa, 0xb5, 0xdc, 0x4e, 0xf8, 0xdb, 0x09, 0x5d, 0x1e, 0xfb, 0x54, 0x1a, - 0xcf, 0x32, 0x16, 0xde, 0xf2, 0xf0, 0x38, 0xdb, 0x58, 0xa3, 0x45, 0x9e, - 0x7e, 0xce, 0xc4, 0x77, 0xaf, 0xe4, 0xcf, 0x05, 0x21, 0x07, 0xe4, 0xc4, - 0x15, 0x97, 0x16, 0xf3, 0xde, 0xe3, 0xd0, 0x91, 0x7e, 0x32, 0x28, 0x6d, - 0x27, 0x7b, 0x25, 0xf0, 0xad, 0x2e, 0x69, 0xff, 0xd6, 0x80, 0x18, 0xdf, - 0x62, 0x2d, 0x29, 0x1a, 0x39, 0xaa, 0xea, 0x58, 0x69, 0x39, 0x86, 0xf8, - 0xa5, 0x23, 0x16, 0x2b, 0x3b, 0x35, 0xb7, 0x8a, 0x81, 0xc4, 0x55, 0x7f, - 0xc1, 0x96, 0xaf, 0xef, 0xfc, 0x85, 0xaa, 0xa3, 0x26, 0x47, 0x70, 0xfd, - 0x72, 0x06, 0xd8, 0x44, 0x83, 0xad, 0x34, 0x32, 0xd7, 0x1e, 0xf5, 0x73, - 0xcb, 0x41, 0x55, 0x93, 0xff, 0xfa, 0x4e, 0x37, 0xb7, 0x9c, 0x45, 0x6e, - 0x99, 0x56, 0xb9, 0x25, 0xfc, 0x6b, 0x80, 0xfd, 0xb6, 0x8a, 0x8e, 0xb1, - 0x72, 0xc2, 0x5c, 0xfd, 0xa3, 0x62, 0x1f, 0xc0, 0xba, 0x38, 0x23, 0xf3, - 0x7a, 0x42, 0x53, 0x34, 0x8d, 0x17, 0xe8, 0xa7, 0xe8, 0xbf, 0x68, 0xe3, - 0xac, 0x69, 0xa1, 0xed, 0x65, 0xfa, 0x28, 0xd7, 0xb6, 0xc7, 0x5a, 0x7c, - 0xdd, 0x5c, 0xa9, 0x0e, 0x1d, 0x22, 0xa7, 0xb7, 0xda, 0x30, 0x7f, 0xc4, - 0x74, 0x8b, 0xd7, 0x9c, 0x3f, 0x7c, 0x67, 0x28, 0xa4, 0xae, 0x0b, 0x65, - 0xb7, 0x86, 0xe1, 0xd2, 0x67, 0xfe, 0x01, 0x1f, 0x53, 0x27, 0x1f, 0x1c, - 0xb7, 0x4f, 0x8c, 0x33, 0x21, 0x09, 0x9c, 0xa1, 0xfd, 0x45, 0x23, 0x69, - 0xc8, 0x6f, 0xce, 0x22, 0x06, 0x3c, 0x04, 0x6c, 0xf4, 0x88, 0xe8, 0xe7, - 0x06, 0xb1, 0x76, 0xa2, 0xe1, 0xb2, 0xc4, 0xc4, 0xa8, 0x04, 0xe5, 0x8d, - 0x53, 0xd1, 0x08, 0xed, 0xe5, 0x2c, 0xe2, 0xd5, 0x91, 0x7a, 0xe7, 0xed, - 0x86, 0xe2, 0x82, 0x6d, 0xdf, 0x08, 0x00, 0x3b, 0x0c, 0xda, 0x7a, 0xb7, - 0xdc, 0x80, 0xbe, 0xb3, 0xaa, 0xed, 0x11, 0xd0, 0x05, 0x0f, 0x67, 0x58, - 0x1b, 0x24, 0xdd, 0xa3, 0xa0, 0x49, 0xda, 0x8d, 0xcc, 0x32, 0x73, 0xd3, - 0x53, 0xb4, 0xdd, 0x5e, 0xd8, 0x1d, 0xae, 0xeb, 0xed, 0x92, 0x9d, 0x8c, - 0x88, 0x7e, 0x6a, 0x8f, 0xf4, 0xef, 0xd4, 0xdd, 0xf9, 0xa8, 0x39, 0xb2, - 0x8d, 0x35, 0xe7, 0x11, 0xb5, 0x1e, 0xf5, 0x25, 0xd8, 0xcc, 0x3e, 0xea, - 0x18, 0xb1, 0x1f, 0x71, 0x8c, 0x7e, 0xcc, 0x40, 0x1c, 0x4b, 0xd5, 0x5d, - 0xbd, 0x97, 0xf7, 0x6d, 0x95, 0x63, 0x67, 0x68, 0x4f, 0xb8, 0xb7, 0x6a, - 0x53, 0xfe, 0xde, 0x10, 0xef, 0x59, 0x72, 0xfc, 0x45, 0xe6, 0x1e, 0xcc, - 0x39, 0x98, 0x67, 0x45, 0xc3, 0xbb, 0x30, 0x1f, 0xfd, 0x31, 0xfa, 0x03, - 0x5d, 0xd9, 0x6e, 0x0e, 0x3e, 0xba, 0x50, 0xa7, 0xde, 0x86, 0xb9, 0x7f, - 0x66, 0x32, 0x5f, 0xb3, 0xc3, 0xae, 0xbc, 0x0b, 0x68, 0x9b, 0x85, 0xef, - 0x4f, 0x39, 0x6d, 0xb2, 0x32, 0x69, 0x43, 0xf7, 0x5f, 0x02, 0x5f, 0x07, - 0x3a, 0x59, 0x23, 0x58, 0x99, 0x4c, 0xe3, 0xfa, 0x80, 0xca, 0xd1, 0x8c, - 0xc7, 0x6c, 0xd0, 0xd8, 0xca, 0x75, 0xe4, 0xe9, 0x29, 0xae, 0x17, 0xe6, - 0x1f, 0xd3, 0x67, 0xe1, 0xb3, 0xc7, 0xe3, 0x8c, 0xf1, 0xdc, 0x4b, 0xe8, - 0x00, 0x1f, 0xdd, 0x0a, 0x57, 0xe8, 0xd6, 0x4e, 0xbd, 0x50, 0xa6, 0x9f, - 0xcf, 0x87, 0xdb, 0x85, 0x78, 0xc4, 0xd4, 0x2b, 0x16, 0x75, 0xa2, 0xc9, - 0x65, 0xb5, 0xef, 0x20, 0x92, 0x76, 0x0e, 0x61, 0xac, 0xb8, 0x5e, 0x2d, - 0xef, 0xd4, 0xf3, 0x65, 0x43, 0x56, 0x42, 0xe4, 0x3b, 0xa2, 0xf2, 0xf8, - 0x9d, 0xca, 0xd6, 0x8a, 0x88, 0x25, 0xb0, 0x99, 0xf8, 0x87, 0x31, 0xae, - 0x6a, 0x83, 0x4d, 0x51, 0xf7, 0xd4, 0xbb, 0xf2, 0x91, 0x9e, 0xee, 0x37, - 0x8a, 0x99, 0x45, 0xf8, 0x5f, 0xd6, 0x2f, 0x3a, 0xbc, 0x5a, 0xe3, 0x4b, - 0x5e, 0x3e, 0xf4, 0x8c, 0x30, 0x4f, 0x99, 0x2b, 0x91, 0x97, 0x22, 0xfc, - 0xe1, 0x46, 0xb6, 0x44, 0x39, 0xba, 0x3e, 0xe5, 0x10, 0xec, 0x42, 0x5f, - 0x32, 0x3d, 0x1b, 0xe0, 0xdf, 0x28, 0xee, 0x31, 0x06, 0xe0, 0xbb, 0xde, - 0x86, 0xf5, 0xbe, 0x17, 0x32, 0xa2, 0x6e, 0xa0, 0xbf, 0x25, 0xee, 0xbb, - 0x42, 0x7f, 0x4b, 0x57, 0xde, 0xb6, 0x7b, 0xe9, 0xf3, 0x46, 0xe4, 0x18, - 0xfc, 0xe8, 0xd1, 0x45, 0xf2, 0x93, 0xf6, 0x70, 0xd9, 0x30, 0x64, 0x42, - 0x1f, 0x3f, 0x2c, 0x6f, 0xd4, 0x7e, 0xa0, 0x70, 0xe0, 0xb6, 0x9d, 0x0d, - 0x99, 0x86, 0x7f, 0x98, 0x71, 0x20, 0x7f, 0x33, 0x82, 0xf5, 0x19, 0x56, - 0xfe, 0x71, 0xe6, 0xfd, 0xe5, 0x24, 0x01, 0x37, 0x66, 0x7f, 0xf6, 0x3e, - 0x63, 0xf6, 0x03, 0xc0, 0x61, 0xef, 0x8b, 0xbe, 0xe1, 0xd2, 0xff, 0x33, - 0xe8, 0xea, 0xd7, 0x55, 0xfd, 0x22, 0xb7, 0x73, 0x2b, 0x65, 0xfa, 0x5e, - 0xcf, 0xe9, 0xee, 0x73, 0x9f, 0xbb, 0x4f, 0xbe, 0x4c, 0xa9, 0x01, 0x2b, - 0xe4, 0x55, 0x1c, 0x65, 0xae, 0xd8, 0xe6, 0xe9, 0x6f, 0x10, 0x18, 0x9a, - 0x74, 0x7d, 0xdf, 0xdb, 0x21, 0xf9, 0x5e, 0x3f, 0xff, 0x84, 0xcf, 0x5e, - 0x6d, 0xf7, 0xf3, 0x59, 0x3e, 0xbf, 0x92, 0x41, 0xfe, 0x0c, 0x1b, 0x60, - 0x2c, 0x60, 0x5b, 0x5c, 0xf9, 0xa1, 0x77, 0xe7, 0x9b, 0xf5, 0x0b, 0xf2, - 0xbd, 0x5b, 0xf1, 0x9d, 0x56, 0x7c, 0xb3, 0x06, 0xb9, 0x5f, 0x4b, 0x9d, - 0x67, 0x1d, 0xd2, 0xaf, 0x3b, 0x92, 0x1e, 0xb0, 0x01, 0xf4, 0xfd, 0x63, - 0xd0, 0xfd, 0x11, 0xf4, 0xfa, 0xc3, 0x12, 0xb0, 0x41, 0x09, 0xd8, 0xa0, - 0x04, 0x6c, 0x50, 0x02, 0x36, 0x28, 0x85, 0xbd, 0x3a, 0x8b, 0x4d, 0x6c, - 0xff, 0x3e, 0x6d, 0xd7, 0xaf, 0x6d, 0xac, 0xb7, 0x4b, 0xb7, 0xb6, 0x99, - 0xaa, 0xfb, 0x18, 0x39, 0xc8, 0x5a, 0x2b, 0xb0, 0x9a, 0x5f, 0xf7, 0xf0, - 0x62, 0x44, 0x8d, 0xfb, 0x5e, 0x88, 0x11, 0x35, 0x1b, 0xeb, 0x66, 0x28, - 0x6c, 0x00, 0x1b, 0x1a, 0x12, 0xc6, 0x6f, 0x13, 0xbe, 0x17, 0xb4, 0x86, - 0xfb, 0xb1, 0x92, 0xda, 0x55, 0x5d, 0xef, 0x88, 0xaa, 0x3b, 0x58, 0x32, - 0x5b, 0xf6, 0x73, 0xb7, 0x98, 0x8c, 0xcd, 0x13, 0x6f, 0xca, 0x16, 0x3d, - 0x01, 0x1d, 0x38, 0xc4, 0x88, 0xdc, 0x27, 0xe4, 0xf8, 0xb1, 0xc1, 0x2a, - 0xc6, 0x2c, 0x58, 0x2e, 0x7f, 0x47, 0x9c, 0xbb, 0xcf, 0xec, 0x82, 0x7f, - 0xce, 0x14, 0x23, 0x32, 0x5e, 0x74, 0x31, 0x01, 0xf2, 0x9f, 0x75, 0xf5, - 0xe5, 0x5b, 0xd0, 0xc3, 0xad, 0xcc, 0x94, 0xb5, 0x6a, 0x1b, 0x91, 0xcb, - 0x71, 0xca, 0x98, 0xfa, 0xdf, 0xab, 0xf6, 0x29, 0x76, 0x55, 0xdd, 0xbd, - 0xa4, 0x71, 0x65, 0x0b, 0x01, 0xfa, 0x19, 0xd0, 0x89, 0xbb, 0x6b, 0x18, - 0x76, 0x91, 0x73, 0x7c, 0xb9, 0xb4, 0xe2, 0x91, 0x2f, 0x6a, 0x62, 0x6d, - 0xd4, 0xfe, 0x1b, 0x2d, 0xed, 0xab, 0xf7, 0x3d, 0x7e, 0xe1, 0xfb, 0x56, - 0x6b, 0x0d, 0xf4, 0x53, 0x77, 0xdb, 0x81, 0xdd, 0x24, 0xa0, 0xee, 0xc3, - 0x87, 0xd7, 0x42, 0x92, 0xaa, 0x59, 0x92, 0x2e, 0xb3, 0x1f, 0xeb, 0x17, - 0xf4, 0x47, 0x7f, 0x22, 0x29, 0xe4, 0xab, 0xd9, 0x50, 0x34, 0x6e, 0xcb, - 0x7f, 0x96, 0xe5, 0x85, 0x7c, 0x84, 0xe7, 0x0a, 0xf2, 0x13, 0x1a, 0x9e, - 0xfb, 0x19, 0xae, 0xc9, 0xb3, 0x25, 0x33, 0x45, 0xc6, 0x9d, 0xa1, 0x70, - 0x0d, 0xf7, 0xb2, 0x93, 0xac, 0xd9, 0x7c, 0x07, 0x36, 0x19, 0x8d, 0x94, - 0xa1, 0xef, 0x2b, 0x45, 0x8e, 0x07, 0x6c, 0x54, 0x64, 0x5d, 0xc7, 0xbf, - 0xff, 0x27, 0xc0, 0x81, 0xf0, 0xd5, 0x21, 0xaf, 0x8f, 0x9a, 0xab, 0x6d, - 0x06, 0x60, 0xe3, 0x0d, 0xcf, 0xdf, 0x56, 0x8a, 0x6e, 0x1d, 0xe5, 0x2c, - 0xf9, 0x70, 0xfe, 0x77, 0xb3, 0x11, 0x42, 0x0e, 0xb4, 0x3a, 0xc7, 0xab, - 0xa4, 0x6f, 0xc2, 0xdd, 0xca, 0x51, 0xc7, 0x97, 0x05, 0xef, 0xb3, 0x8d, - 0x67, 0x27, 0x9a, 0xcd, 0xb3, 0xd6, 0x07, 0xad, 0x99, 0xf5, 0x6d, 0x4f, - 0x5a, 0xf9, 0xdd, 0x15, 0x27, 0xef, 0xd5, 0xcc, 0xbe, 0xbd, 0xc3, 0xad, - 0x99, 0xd5, 0x76, 0xac, 0xad, 0x99, 0x59, 0xdb, 0xdd, 0x9a, 0xd9, 0xfc, - 0xee, 0x02, 0x3e, 0x6e, 0xcd, 0x2c, 0xbb, 0xdd, 0xad, 0x99, 0x95, 0xb7, - 0xbb, 0x35, 0x33, 0x67, 0x87, 0x5b, 0x33, 0xfb, 0xf9, 0xf6, 0xb5, 0x35, - 0xb3, 0x1f, 0xec, 0x58, 0x5b, 0x33, 0xbb, 0xb8, 0x3b, 0x87, 0xcf, 0xdd, - 0x9a, 0xd9, 0xcf, 0x76, 0xdc, 0xbb, 0x66, 0xf6, 0x9a, 0x8f, 0xd7, 0x31, - 0x9f, 0x11, 0xcc, 0x21, 0x0e, 0xbc, 0x3e, 0x0c, 0xbc, 0xfe, 0x6e, 0x75, - 0xfe, 0x00, 0xe6, 0x39, 0xe8, 0xc5, 0x83, 0x0f, 0x82, 0xdb, 0x47, 0xbc, - 0x67, 0x6d, 0xe4, 0xbb, 0x11, 0x2f, 0x57, 0x21, 0x76, 0xdf, 0xec, 0xe5, - 0x6c, 0xff, 0xa8, 0xf3, 0xee, 0xb9, 0x97, 0xd6, 0xef, 0x0f, 0x21, 0xf5, - 0xf6, 0xf1, 0x3c, 0xe7, 0x95, 0x47, 0xee, 0x47, 0x39, 0xd8, 0xe8, 0x3f, - 0xbf, 0xfb, 0x1b, 0x16, 0x31, 0xfe, 0x73, 0x58, 0xab, 0xf6, 0x16, 0x43, - 0x9d, 0x01, 0x60, 0x8c, 0x3a, 0x2e, 0x29, 0xf4, 0x4f, 0xa9, 0xfe, 0xd7, - 0x5a, 0xfa, 0xaf, 0xa0, 0x3f, 0xe9, 0x46, 0xff, 0x1d, 0x3e, 0x2f, 0x29, - 0xfb, 0xb6, 0x5c, 0x0c, 0x9f, 0x2e, 0xf9, 0x78, 0x2b, 0xe0, 0x61, 0xe7, - 0x46, 0xc6, 0x76, 0x3e, 0x8f, 0x67, 0xa2, 0x17, 0x6d, 0xb9, 0xa9, 0xf0, - 0xbb, 0x91, 0x88, 0x5e, 0xcc, 0xaa, 0x7c, 0xad, 0x91, 0xc9, 0x39, 0x7e, - 0xfe, 0x8d, 0x1c, 0x6a, 0x80, 0x39, 0x0c, 0xec, 0x7d, 0x69, 0x10, 0x71, - 0xac, 0x35, 0xc7, 0x66, 0x5e, 0xad, 0x7b, 0x79, 0xb5, 0x29, 0x9f, 0xd9, - 0xd9, 0x8a, 0xcd, 0x2f, 0xee, 0xfe, 0xc7, 0x0a, 0x9b, 0x6f, 0x42, 0x6e, - 0x4e, 0xec, 0x4d, 0x1c, 0x43, 0x0c, 0x41, 0x7c, 0xce, 0x7a, 0x01, 0xf3, - 0x19, 0xc6, 0x46, 0xe6, 0x37, 0x21, 0x7c, 0x78, 0x26, 0xc9, 0xc7, 0xe8, - 0xed, 0x9e, 0x7f, 0x67, 0x5e, 0xe4, 0x63, 0x95, 0xe4, 0x26, 0x37, 0x37, - 0xda, 0xa4, 0xb9, 0xf9, 0x67, 0xc4, 0xeb, 0x13, 0x58, 0xc5, 0xc2, 0x81, - 0x55, 0x2c, 0xbc, 0x66, 0x1f, 0x4b, 0xd4, 0xf9, 0x27, 0xb5, 0x1f, 0xc6, - 0xfd, 0xb1, 0x46, 0xe6, 0xca, 0x80, 0x68, 0x7a, 0x82, 0xfb, 0x64, 0xc0, - 0x3a, 0x16, 0xf7, 0xcd, 0xe8, 0x3b, 0xf7, 0x69, 0xa9, 0x2a, 0xe3, 0x0f, - 0xf1, 0x91, 0xbf, 0x17, 0xee, 0xeb, 0x89, 0xb2, 0x63, 0xdb, 0x1f, 0x6b, - 0xc8, 0x79, 0xe3, 0xed, 0xd6, 0x53, 0xe0, 0x25, 0x83, 0x6f, 0x5f, 0xa6, - 0x9f, 0x55, 0xb1, 0xaf, 0x03, 0xb6, 0x7b, 0xa4, 0x44, 0xec, 0xba, 0x59, - 0x6a, 0x1e, 0x7e, 0x3d, 0x37, 0xef, 0x62, 0xd7, 0xc0, 0x5a, 0xec, 0x1a, - 0x5f, 0x16, 0x97, 0xc7, 0x5d, 0x1b, 0xf2, 0x48, 0xbc, 0x4a, 0xfe, 0x18, - 0x77, 0xf6, 0xc2, 0xff, 0x35, 0x80, 0x69, 0x19, 0x73, 0x18, 0x6f, 0x22, - 0xc0, 0xf6, 0xf7, 0xe2, 0x4f, 0xb5, 0x1d, 0xea, 0xb0, 0x82, 0xf8, 0x4c, - 0xc3, 0x7f, 0x4c, 0xe0, 0x99, 0x8c, 0xcc, 0x9e, 0xfe, 0x1a, 0xe6, 0x36, - 0x2d, 0x57, 0xe6, 0x27, 0xc1, 0xdf, 0x73, 0x32, 0x17, 0xcf, 0xc3, 0x8f, - 0x70, 0xcf, 0x83, 0xb8, 0xad, 0xdf, 0xfb, 0x9e, 0xd6, 0xcf, 0x5a, 0x51, - 0xe2, 0x46, 0xa9, 0x16, 0xe9, 0x83, 0xb9, 0x67, 0xc8, 0xbd, 0x61, 0xda, - 0x0f, 0xeb, 0x27, 0xc8, 0x5d, 0x99, 0xc3, 0x9e, 0xe2, 0xf8, 0x6b, 0x75, - 0xb2, 0xec, 0x10, 0x7f, 0x35, 0x32, 0x8d, 0x25, 0xe2, 0xc7, 0xf7, 0x8b, - 0x25, 0xa9, 0x07, 0xe2, 0xc9, 0xfb, 0xc1, 0x91, 0xd1, 0x79, 0x60, 0xc8, - 0x57, 0x1a, 0x7a, 0x2b, 0x8e, 0x74, 0x31, 0x64, 0x72, 0x29, 0x0b, 0x9a, - 0x71, 0x85, 0x95, 0x91, 0xc7, 0xc1, 0xed, 0xf5, 0xe3, 0xd9, 0x7e, 0xe4, - 0xe4, 0x2e, 0x66, 0x4c, 0x01, 0x33, 0xfe, 0x06, 0x30, 0xe3, 0xac, 0x74, - 0x76, 0x11, 0x33, 0xda, 0x1e, 0x66, 0x4c, 0xc3, 0x9e, 0x73, 0x6b, 0xec, - 0x59, 0x53, 0xb5, 0x28, 0xde, 0xcb, 0x01, 0xf3, 0xa5, 0x4e, 0x45, 0xef, - 0x03, 0x27, 0x6a, 0x12, 0x52, 0xe7, 0x52, 0x02, 0x2d, 0x34, 0x7d, 0x3c, - 0xb8, 0x4d, 0xe1, 0xbc, 0xdd, 0xa5, 0x4d, 0xc8, 0x51, 0x14, 0xee, 0xf3, - 0xf6, 0x4b, 0x03, 0xeb, 0xf6, 0x90, 0x03, 0x2d, 0x7b, 0xc8, 0x77, 0xf1, - 0x21, 0x9e, 0xf3, 0x6a, 0x7d, 0x6d, 0xf0, 0x05, 0xff, 0x13, 0x3c, 0x71, - 0x7d, 0x71, 0x2d, 0x68, 0xee, 0x7a, 0x59, 0x83, 0x13, 0xff, 0x7a, 0x1d, - 0x4e, 0x44, 0xec, 0x3a, 0x17, 0x92, 0x24, 0x30, 0xa2, 0xbd, 0x44, 0x5a, - 0x5c, 0xd3, 0xc3, 0xd2, 0x8e, 0xf9, 0x75, 0x9c, 0xea, 0x05, 0x36, 0xea, - 0x92, 0x20, 0x30, 0x52, 0x9b, 0xc2, 0x48, 0x03, 0xc4, 0x32, 0x83, 0x33, - 0xc0, 0x36, 0xb5, 0x55, 0x9c, 0x14, 0x8d, 0xff, 0x01, 0xf4, 0xf2, 0x94, - 0xf2, 0x3d, 0x69, 0x39, 0x01, 0x5f, 0xda, 0xbe, 0x04, 0x7c, 0x77, 0xce, - 0xc5, 0x4f, 0x6d, 0xeb, 0xf0, 0xd3, 0xc1, 0x0d, 0xf1, 0x93, 0xaa, 0xdf, - 0x8f, 0x52, 0x26, 0x37, 0x1c, 0xb7, 0x7e, 0x7f, 0xdd, 0x71, 0xeb, 0xf7, - 0x37, 0x9c, 0xd6, 0xfa, 0xfd, 0x47, 0xa4, 0x60, 0x46, 0xed, 0x15, 0x59, - 0x57, 0xbf, 0x9f, 0x60, 0x3d, 0xdc, 0xe9, 0x72, 0xeb, 0xf4, 0x5d, 0x5e, - 0xfd, 0x3e, 0x2a, 0x85, 0x35, 0xed, 0xa6, 0xbc, 0x69, 0xf9, 0xf5, 0xfb, - 0xef, 0xa2, 0xad, 0x1b, 0x63, 0xac, 0xad, 0xdd, 0x5f, 0x77, 0x58, 0xbb, - 0x0f, 0xb1, 0x9f, 0x57, 0xbb, 0x67, 0x3f, 0xe4, 0xf2, 0x0e, 0xeb, 0xf6, - 0x8f, 0x40, 0x16, 0x5b, 0x21, 0x87, 0x5e, 0x69, 0x3f, 0x13, 0x66, 0x1f, - 0x55, 0xaf, 0x5f, 0x71, 0x42, 0x78, 0xce, 0xad, 0xab, 0xcf, 0xc0, 0xae, - 0x0e, 0xae, 0xd6, 0xeb, 0xdd, 0x31, 0x6e, 0x3a, 0x6b, 0xe9, 0xaf, 0xa5, - 0xd3, 0xe7, 0xd1, 0x09, 0x81, 0x4e, 0x78, 0x1d, 0x9d, 0xbb, 0xf5, 0xf9, - 0x9b, 0x8e, 0x5b, 0x9b, 0x4f, 0x9f, 0x16, 0xbb, 0x1d, 0xbe, 0xf9, 0xe2, - 0xc0, 0xc3, 0x1e, 0x8d, 0xd5, 0xda, 0x3c, 0x7d, 0x08, 0x70, 0x7b, 0x4c, - 0x9d, 0xbd, 0x9a, 0xf9, 0x7f, 0x50, 0x9b, 0x67, 0x5d, 0xde, 0xdd, 0x5f, - 0xe1, 0xfa, 0x04, 0x3e, 0x7f, 0xd1, 0xad, 0xc9, 0x8f, 0x95, 0xfc, 0x5a, - 0x3b, 0xf3, 0x47, 0xff, 0x5c, 0x54, 0x7f, 0xe4, 0x88, 0xd0, 0x56, 0xc8, - 0x1f, 0xe9, 0x76, 0xcb, 0x94, 0xc2, 0x47, 0xb0, 0xa9, 0xd8, 0xbd, 0x31, - 0x72, 0xe5, 0x94, 0x8f, 0x91, 0x43, 0x0a, 0x23, 0x57, 0x96, 0x7c, 0x8c, - 0x9c, 0xbc, 0x07, 0x46, 0x6e, 0x76, 0xb9, 0x71, 0x20, 0x28, 0x79, 0x85, - 0x91, 0xef, 0x75, 0x96, 0x8c, 0xf7, 0xba, 0x88, 0x07, 0xc4, 0x3d, 0x5f, - 0xd0, 0x7b, 0x8f, 0xb5, 0xe6, 0xe3, 0x66, 0xc6, 0xfe, 0xad, 0x32, 0x71, - 0xe6, 0x2e, 0x6e, 0x76, 0xb1, 0x71, 0x34, 0x72, 0x48, 0xc5, 0x44, 0xe0, - 0x84, 0x3a, 0xeb, 0xdf, 0xc4, 0xbe, 0x8c, 0x39, 0x01, 0x85, 0xcf, 0x72, - 0x45, 0xe6, 0x01, 0x6c, 0x23, 0x16, 0xee, 0xe4, 0x31, 0x2b, 0x2f, 0x26, - 0xf9, 0x58, 0xd3, 0x3f, 0xd7, 0xc2, 0x3d, 0x86, 0x37, 0x8d, 0xa4, 0x85, - 0x76, 0xc7, 0xcf, 0x15, 0xe2, 0xea, 0x3c, 0x50, 0x12, 0x58, 0x72, 0x6a, - 0x15, 0x4b, 0xd2, 0x57, 0xfc, 0xf4, 0x6d, 0xdb, 0xa4, 0x5f, 0xf3, 0xb1, - 0x22, 0x72, 0xa2, 0x12, 0xd7, 0xb6, 0x8f, 0x15, 0x5d, 0x9c, 0x98, 0x72, - 0x1a, 0xc0, 0xcb, 0x01, 0x19, 0x03, 0x4e, 0x6f, 0x7c, 0x89, 0x35, 0x28, - 0x1f, 0x1b, 0xd9, 0xf8, 0x6e, 0xad, 0x49, 0xf1, 0xba, 0x5d, 0xed, 0x05, - 0x5e, 0x1e, 0x08, 0xb6, 0xb4, 0x3f, 0x0b, 0xff, 0x8d, 0xfc, 0x08, 0xd8, - 0xc4, 0xc5, 0x44, 0x3b, 0xa0, 0x83, 0x91, 0x7b, 0x60, 0xa2, 0xf5, 0x31, - 0x8a, 0x31, 0xf3, 0x6e, 0x8c, 0x4a, 0xd7, 0xe9, 0xcf, 0xef, 0xc6, 0xa8, - 0x7b, 0xc7, 0x50, 0xb6, 0x61, 0x76, 0x56, 0x06, 0x9f, 0x69, 0x29, 0xac, - 0x8b, 0x51, 0x73, 0x1f, 0x20, 0x46, 0xb9, 0xf8, 0xc0, 0xe5, 0xfb, 0xf7, - 0x21, 0x9b, 0x1f, 0x43, 0xa6, 0x3f, 0x02, 0xe6, 0xfa, 0x21, 0xe6, 0xf5, - 0x03, 0xe0, 0xa1, 0xef, 0x97, 0xd6, 0x9f, 0x07, 0x19, 0x15, 0xe6, 0x87, - 0x2e, 0x66, 0x72, 0x31, 0xfd, 0x0c, 0x56, 0x57, 0xad, 0xd8, 0xc8, 0x4c, - 0x15, 0x87, 0xcc, 0x69, 0x77, 0x1f, 0x35, 0x92, 0x95, 0xa7, 0x3b, 0x53, - 0x8b, 0x8c, 0x19, 0xea, 0x3a, 0xcc, 0xfa, 0x25, 0xb1, 0x43, 0x55, 0xe5, - 0x99, 0x03, 0x52, 0xae, 0xb9, 0x78, 0x6b, 0x6e, 0xd1, 0xa5, 0x31, 0xe5, - 0xe1, 0xad, 0x9c, 0x87, 0xb7, 0xb2, 0xb5, 0xe5, 0x48, 0x00, 0xfd, 0xe7, - 0xe2, 0x6b, 0x31, 0xd6, 0x8c, 0x87, 0xb1, 0xa6, 0x3f, 0x20, 0xc6, 0xe2, - 0x58, 0x39, 0x3c, 0x33, 0x3e, 0x1f, 0x91, 0x5d, 0x90, 0xf3, 0x58, 0x91, - 0xfa, 0xe2, 0x19, 0xb2, 0xf7, 0xd2, 0x19, 0xf5, 0xe5, 0xea, 0x2a, 0x10, - 0xdb, 0xa7, 0x8d, 0x43, 0x57, 0x63, 0xef, 0xa9, 0x2b, 0x31, 0xdf, 0x18, - 0x09, 0xe2, 0xf3, 0xf7, 0xa5, 0x2b, 0xce, 0x83, 0xfa, 0x5a, 0x8f, 0xc5, - 0xee, 0x07, 0x93, 0xad, 0xc5, 0x63, 0xb6, 0xc2, 0x63, 0xed, 0x5e, 0x1f, - 0xd9, 0x33, 0x0e, 0x5d, 0xfe, 0x27, 0xf4, 0xf9, 0x99, 0xd5, 0x2d, 0x3f, - 0x85, 0xff, 0xfe, 0x43, 0xe8, 0xe4, 0x3f, 0x22, 0x57, 0x78, 0xcd, 0xea, - 0x93, 0x3f, 0x40, 0xdb, 0x5d, 0x9c, 0xc3, 0xfe, 0xc1, 0xc7, 0x92, 0xd6, - 0x35, 0xe0, 0x93, 0x6b, 0x1e, 0x3e, 0x79, 0x3a, 0x99, 0xb4, 0x26, 0x59, - 0x37, 0x87, 0x9c, 0x0f, 0xa4, 0xa6, 0x14, 0x36, 0xf1, 0x31, 0xc9, 0xed, - 0x34, 0xc7, 0x9f, 0x75, 0x56, 0x80, 0x7d, 0x56, 0x3c, 0xec, 0x73, 0x60, - 0xcc, 0xc5, 0x3e, 0xc1, 0xcf, 0x50, 0xff, 0x2e, 0xee, 0x59, 0xb1, 0x93, - 0x18, 0xa7, 0x0a, 0x4c, 0x52, 0x71, 0x0e, 0x48, 0xbe, 0xbe, 0x57, 0x7d, - 0x8e, 0x94, 0xec, 0x68, 0x1b, 0xe4, 0xc4, 0xda, 0xeb, 0x49, 0xae, 0x4a, - 0x27, 0x6a, 0x16, 0xf1, 0x9d, 0x75, 0xa2, 0xe1, 0xdf, 0xf1, 0xae, 0x9f, - 0xf7, 0xae, 0x4f, 0x78, 0xd7, 0xc7, 0x11, 0x87, 0x8f, 0xa9, 0x58, 0xca, - 0x76, 0xb6, 0x41, 0xc9, 0x0e, 0x68, 0x01, 0x7b, 0x9c, 0x1d, 0xfe, 0x8b, - 0x66, 0x59, 0xe9, 0x98, 0xf4, 0x27, 0xf0, 0x39, 0x8e, 0xcf, 0x34, 0x3e, - 0xfb, 0xf1, 0xc9, 0xe3, 0xb3, 0x2a, 0x53, 0x2d, 0x55, 0x9a, 0x84, 0x8d, - 0x0c, 0x4a, 0xaa, 0xfe, 0x12, 0xf4, 0xf8, 0x1c, 0x74, 0x7b, 0x58, 0x0a, - 0xd5, 0x3f, 0x95, 0xd9, 0x79, 0x4d, 0xba, 0x2c, 0xe8, 0xb4, 0x0a, 0x5b, - 0x9e, 0x77, 0xf7, 0x13, 0x3b, 0x13, 0x7b, 0xd1, 0xb7, 0x29, 0x4f, 0xc5, - 0x9f, 0x13, 0xfd, 0xb1, 0x39, 0xf4, 0x13, 0xbd, 0x30, 0xfc, 0x31, 0xb5, - 0x6f, 0x56, 0x8d, 0xbb, 0x32, 0xde, 0x65, 0xd9, 0x51, 0xe8, 0x7c, 0xf0, - 0x18, 0x68, 0x27, 0xd5, 0xd9, 0xd8, 0x8c, 0x1c, 0x3d, 0xbd, 0xbc, 0xc5, - 0xf5, 0xad, 0x51, 0xf3, 0x26, 0xf5, 0x8e, 0x79, 0xd8, 0xf0, 0x85, 0x19, - 0xd8, 0xfb, 0x41, 0x27, 0xa0, 0x8d, 0x21, 0xde, 0x8c, 0x39, 0x37, 0x55, - 0xbc, 0x81, 0xef, 0xca, 0xc4, 0x4e, 0x86, 0x70, 0xcd, 0xb3, 0x45, 0x88, - 0x8b, 0xea, 0x6c, 0xe5, 0x32, 0xf0, 0x8d, 0xa6, 0xea, 0x80, 0xb3, 0xab, - 0xfb, 0x43, 0x86, 0xf2, 0x5b, 0xb1, 0x98, 0x2e, 0xb9, 0x11, 0xe2, 0xdc, - 0xbd, 0x2a, 0x36, 0xd5, 0x8a, 0xf6, 0x43, 0xcc, 0x15, 0x6f, 0x08, 0xe3, - 0xdc, 0xe3, 0xe8, 0xd7, 0x07, 0x7f, 0x8c, 0x7b, 0x75, 0xda, 0x27, 0xe7, - 0xca, 0x67, 0xa6, 0xa5, 0x5a, 0x1e, 0xc5, 0x7c, 0xbd, 0x1c, 0x49, 0xe5, - 0x12, 0x11, 0xd8, 0xa3, 0xbf, 0x17, 0xe5, 0xd6, 0x4f, 0xaa, 0x8e, 0x8f, - 0x29, 0xba, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xee, 0x9f, 0xa9, 0xbd, - 0xb3, 0x82, 0x33, 0x0a, 0x39, 0x25, 0xd1, 0xce, 0x5a, 0x35, 0x7e, 0x97, - 0x75, 0x55, 0x13, 0x58, 0x31, 0x66, 0xa4, 0x56, 0x6e, 0x82, 0x5f, 0xc4, - 0xdc, 0x2d, 0x33, 0x52, 0x29, 0x4f, 0xcb, 0x2b, 0xe5, 0x9f, 0x77, 0x03, - 0x53, 0x41, 0xa6, 0xe4, 0xbf, 0x5b, 0xee, 0x9e, 0xbf, 0xf5, 0xdb, 0x21, - 0xcf, 0xd3, 0xf9, 0xb0, 0x9b, 0xe7, 0xe6, 0x55, 0x2d, 0xc6, 0xfd, 0xb6, - 0xf5, 0x29, 0x2b, 0x1a, 0x9e, 0x45, 0xcf, 0x83, 0x0b, 0xb4, 0xcd, 0xfc, - 0xf8, 0x9c, 0xb5, 0x43, 0xae, 0xc6, 0x37, 0xcb, 0x72, 0x5c, 0xe5, 0xc5, - 0xc4, 0x0f, 0x58, 0xeb, 0x51, 0xb3, 0x21, 0x7b, 0xe4, 0x28, 0xd6, 0xed, - 0xd5, 0xf8, 0xd3, 0xb0, 0xd3, 0x67, 0x61, 0x0b, 0xac, 0x01, 0x1c, 0x62, - 0xae, 0x25, 0x0d, 0x55, 0x23, 0x6b, 0x36, 0xc7, 0xd5, 0x19, 0xee, 0x76, - 0x59, 0x56, 0x58, 0xcc, 0xad, 0x9d, 0x2f, 0x4f, 0xba, 0x6b, 0xc4, 0x50, - 0x76, 0xff, 0xc7, 0xe0, 0xc7, 0x84, 0xed, 0xb6, 0xa9, 0x3e, 0x46, 0xa2, - 0xc3, 0xeb, 0xa3, 0xf4, 0xdb, 0xd2, 0xe7, 0x95, 0x44, 0xd2, 0xda, 0xff, - 0x89, 0xa4, 0x75, 0x73, 0xb7, 0x5b, 0x6f, 0x89, 0x9a, 0xb6, 0xc6, 0xf7, - 0x52, 0xdc, 0xf5, 0x98, 0xc1, 0xba, 0xba, 0xb4, 0x8a, 0xa1, 0x61, 0xa4, - 0x2f, 0x5f, 0x81, 0x7e, 0x03, 0xd2, 0x7e, 0xb2, 0xf9, 0xf8, 0x54, 0x7c, - 0x28, 0x72, 0x50, 0x78, 0x02, 0x8b, 0x79, 0x75, 0x34, 0x9e, 0x95, 0x2b, - 0x88, 0x93, 0x77, 0x88, 0x1d, 0x06, 0x2f, 0xcb, 0x9d, 0xc7, 0x93, 0xf1, - 0x51, 0xad, 0x32, 0x89, 0xac, 0xe5, 0xe5, 0x49, 0xc6, 0xd9, 0x43, 0x22, - 0xc0, 0x97, 0x27, 0x47, 0x24, 0x5d, 0x54, 0xef, 0xa9, 0xf0, 0x9c, 0xad, - 0x36, 0x0d, 0xf9, 0xe1, 0xf9, 0x09, 0x06, 0x46, 0xdd, 0xea, 0x8f, 0xa4, - 0xe5, 0x69, 0xd6, 0xc0, 0x24, 0xb7, 0x20, 0xdb, 0x92, 0xf0, 0xab, 0xf6, - 0x44, 0xbb, 0x4c, 0xd7, 0x1a, 0x99, 0xfe, 0x53, 0xcf, 0x82, 0xc6, 0x14, - 0x68, 0xed, 0x45, 0x6e, 0x92, 0x45, 0xac, 0xa6, 0x7c, 0xe9, 0xbb, 0x9f, - 0x81, 0x8c, 0x3e, 0xc2, 0x3d, 0xe5, 0xd1, 0xac, 0x44, 0x27, 0xf2, 0x8a, - 0xee, 0x5b, 0x5a, 0x6e, 0xf8, 0x57, 0x10, 0xeb, 0x02, 0xb2, 0x2b, 0x26, - 0xfa, 0xde, 0x58, 0xe0, 0xed, 0x29, 0x8b, 0x6d, 0x41, 0xb6, 0xe9, 0x68, - 0x0b, 0xfc, 0x7a, 0x2c, 0xa8, 0x27, 0x63, 0xd1, 0x51, 0x9e, 0x8f, 0x36, - 0xac, 0x29, 0xee, 0x4d, 0x3c, 0x20, 0x5d, 0x7b, 0xa5, 0xe7, 0x42, 0x74, - 0xf4, 0x06, 0x78, 0x09, 0x28, 0x5f, 0x3f, 0x25, 0xba, 0xd7, 0xde, 0xbd, - 0xda, 0x1e, 0xf0, 0xda, 0xf7, 0x4a, 0xd7, 0x85, 0x21, 0xf3, 0x75, 0x99, - 0x01, 0x4d, 0x43, 0xae, 0x23, 0xd7, 0xb1, 0x06, 0xa6, 0x60, 0x8b, 0x4f, - 0x92, 0x97, 0xfd, 0xc0, 0x1a, 0x58, 0x1b, 0xc8, 0xbf, 0xad, 0x0f, 0xcb, - 0x57, 0xcd, 0x4e, 0xc9, 0xa9, 0x5c, 0x37, 0xe0, 0xd6, 0x52, 0x61, 0xef, - 0x8f, 0x0e, 0x1c, 0xec, 0x71, 0xeb, 0x05, 0xdc, 0xef, 0x18, 0x46, 0xdb, - 0x9d, 0xe6, 0x39, 0x8b, 0x6d, 0xbc, 0x77, 0xa7, 0x59, 0xb5, 0x86, 0xcc, - 0x94, 0x16, 0xf4, 0xf6, 0xbd, 0x0f, 0xa9, 0xb9, 0xe7, 0xcb, 0xfd, 0x66, - 0x45, 0x1e, 0xd5, 0x52, 0x0f, 0x22, 0x5e, 0x38, 0xd3, 0xe8, 0x7b, 0x87, - 0xe7, 0x29, 0x54, 0x7d, 0xbf, 0x22, 0xfe, 0x35, 0xe9, 0x0c, 0x99, 0xe3, - 0xea, 0xd9, 0x21, 0xf3, 0xa8, 0xd6, 0xfa, 0x6c, 0x58, 0x1b, 0x5f, 0xf3, - 0x6c, 0x97, 0x92, 0x91, 0x61, 0xb9, 0x7d, 0x66, 0xcb, 0x7b, 0xe5, 0x79, - 0x87, 0xfd, 0xee, 0x34, 0x53, 0xd6, 0x03, 0xda, 0xd1, 0x07, 0xe9, 0x0b, - 0xd9, 0xf7, 0xf6, 0xba, 0x71, 0x78, 0x7d, 0xaf, 0x31, 0x9a, 0xb2, 0x76, - 0x8c, 0x4d, 0xaa, 0xcf, 0x55, 0xd5, 0x27, 0xa0, 0x64, 0xbd, 0x76, 0x9c, - 0xbf, 0x91, 0xb5, 0xe3, 0x74, 0xad, 0xce, 0x79, 0x16, 0x34, 0x8f, 0xa1, - 0x6f, 0xd1, 0xe9, 0x0f, 0x57, 0xe5, 0x76, 0x33, 0x67, 0xbd, 0x29, 0x57, - 0x57, 0x69, 0xff, 0x12, 0xd7, 0xad, 0x3c, 0xfd, 0xd2, 0xe3, 0x91, 0xbf, - 0xd9, 0xf6, 0x2f, 0x95, 0xbc, 0x1f, 0xb0, 0xfa, 0xf7, 0x57, 0xb4, 0xe8, - 0xe8, 0x5f, 0x0a, 0x75, 0xf5, 0xcf, 0x94, 0xaf, 0xf9, 0x18, 0xf4, 0xb4, - 0xed, 0x05, 0xac, 0xdd, 0xe1, 0xa4, 0xea, 0x73, 0xdd, 0xda, 0x2b, 0xdb, - 0x4e, 0xf6, 0x9b, 0xd7, 0xe5, 0x33, 0x92, 0x0e, 0xf1, 0x1a, 0x39, 0x94, - 0xc5, 0xf7, 0x52, 0x3e, 0xc1, 0xbc, 0x00, 0xba, 0xec, 0x1f, 0xfc, 0x4b, - 0x79, 0x56, 0x8e, 0x96, 0xe6, 0xe0, 0x7b, 0xa6, 0x64, 0xf0, 0x05, 0xfa, - 0x9f, 0xbc, 0xe9, 0xd6, 0x6a, 0xdc, 0x98, 0x98, 0xf2, 0x62, 0xe2, 0x9c, - 0xf2, 0x73, 0xaf, 0x79, 0xe7, 0x22, 0xfa, 0x07, 0xcf, 0xe1, 0xd9, 0x57, - 0x94, 0x0f, 0xf8, 0x3d, 0xa9, 0x62, 0x2d, 0x44, 0x5e, 0xde, 0x2c, 0x0f, - 0x3c, 0x41, 0x9b, 0x44, 0x06, 0xf0, 0xb1, 0x36, 0xf5, 0x1e, 0x8c, 0x6e, - 0x75, 0x88, 0x6c, 0xa1, 0xfd, 0x5c, 0x86, 0xad, 0x4d, 0xb9, 0x7b, 0x5f, - 0x6b, 0xae, 0xa3, 0x13, 0x2b, 0xf2, 0x1f, 0x94, 0x1d, 0x7e, 0xfc, 0x82, - 0xfb, 0x3d, 0x7c, 0x01, 0xe9, 0x72, 0x6c, 0xaf, 0x6c, 0xbf, 0xe0, 0xda, - 0xdd, 0xec, 0xfc, 0xb3, 0x4a, 0xbe, 0x53, 0x4a, 0xbe, 0x4d, 0x99, 0x89, - 0x53, 0xf6, 0x9c, 0x13, 0xcf, 0x4f, 0xba, 0x32, 0xf9, 0x9c, 0x67, 0x47, - 0xfd, 0x2f, 0xf0, 0x3d, 0x35, 0xca, 0x88, 0x7c, 0xcf, 0xf4, 0x70, 0x3f, - 0x76, 0xdb, 0x05, 0xce, 0xb7, 0x6f, 0xcd, 0x7c, 0x4f, 0xc0, 0xc7, 0x0e, - 0x0c, 0xb8, 0x73, 0x7e, 0x6d, 0xfe, 0xfd, 0xcf, 0xf9, 0x77, 0x57, 0xe7, - 0x6c, 0x48, 0x55, 0xe5, 0xb9, 0xb1, 0xcd, 0xd2, 0x95, 0x93, 0x06, 0xec, - 0xe3, 0xcf, 0x85, 0x67, 0xc6, 0xc9, 0x8b, 0x3b, 0xee, 0xb2, 0x43, 0x9e, - 0xfc, 0x39, 0x90, 0xaf, 0x29, 0x4f, 0x7f, 0xe4, 0xe3, 0xd9, 0x0d, 0xef, - 0x5d, 0x97, 0x46, 0x66, 0x10, 0x6d, 0xba, 0xd2, 0xe1, 0x98, 0xb7, 0xde, - 0xf6, 0x8a, 0xae, 0x74, 0x98, 0x5c, 0xd5, 0xe1, 0x0d, 0xe8, 0xb0, 0x2a, - 0x9f, 0xc6, 0x9c, 0xb0, 0xbe, 0x5f, 0x18, 0x32, 0x67, 0x64, 0xab, 0xd2, - 0xbf, 0x35, 0x00, 0x9f, 0xea, 0xe9, 0xb2, 0xfd, 0x3e, 0x74, 0xf9, 0xba, - 0x28, 0x7d, 0xaa, 0x73, 0x44, 0x55, 0x45, 0x87, 0xbe, 0x8d, 0x73, 0x6b, - 0x57, 0x3e, 0x81, 0x3c, 0xaa, 0xb3, 0x01, 0x13, 0xae, 0x7e, 0xd5, 0x9a, - 0xf7, 0xf4, 0x9b, 0x9d, 0xa0, 0x0e, 0x7f, 0xad, 0xc7, 0xd5, 0x67, 0x87, - 0xea, 0x73, 0x2a, 0x36, 0xaa, 0xd6, 0xbb, 0x35, 0xf0, 0xe9, 0x1e, 0xea, - 0xf4, 0x79, 0xc7, 0xfd, 0x2e, 0x22, 0xce, 0x9d, 0x72, 0xde, 0x4b, 0xaf, - 0xae, 0x4e, 0xc7, 0xc4, 0x5d, 0x57, 0xeb, 0xf5, 0xa9, 0x5f, 0x08, 0x28, - 0x1b, 0x1e, 0x83, 0x0c, 0x8f, 0x97, 0x1e, 0xf4, 0xec, 0xde, 0x9d, 0xf3, - 0xc0, 0xfb, 0x9c, 0xf3, 0x91, 0x62, 0xbf, 0xf9, 0x26, 0xee, 0x8d, 0x63, - 0xce, 0x33, 0xd2, 0x26, 0x29, 0x6f, 0xce, 0x91, 0xd5, 0x39, 0xfb, 0x3c, - 0xba, 0xfd, 0x52, 0xcc, 0x63, 0x1d, 0xfa, 0xaf, 0x7f, 0xab, 0xde, 0x37, - 0xb9, 0x59, 0xa4, 0xdf, 0x06, 0x56, 0x0a, 0xf5, 0xca, 0xf5, 0x5a, 0x44, - 0xae, 0x13, 0x83, 0x8c, 0xe0, 0xdb, 0x99, 0xf3, 0x62, 0x78, 0x50, 0x5e, - 0x2f, 0x6e, 0xc4, 0xc7, 0xb0, 0xdc, 0x28, 0xfa, 0xbc, 0x10, 0x0b, 0x33, - 0x5f, 0x98, 0x92, 0x37, 0xe6, 0xfb, 0xa5, 0x31, 0x81, 0xb8, 0x3f, 0x40, - 0x99, 0x0c, 0x99, 0x7b, 0xd4, 0x7b, 0x48, 0x77, 0x9a, 0x97, 0x2d, 0xd0, - 0x5f, 0x68, 0xca, 0x41, 0xee, 0x67, 0xf3, 0x77, 0xed, 0x21, 0x69, 0x30, - 0xa7, 0x18, 0xe8, 0x95, 0xca, 0x02, 0xf2, 0xf9, 0x22, 0xe9, 0x53, 0x6e, - 0x7b, 0xd5, 0xef, 0x71, 0x8c, 0xf7, 0x39, 0xbe, 0x1f, 0x10, 0xa2, 0x6e, - 0xee, 0x34, 0x97, 0x2d, 0xee, 0x67, 0x4e, 0x49, 0x0d, 0xfa, 0xfb, 0xe7, - 0x31, 0xee, 0xb7, 0xe7, 0xd4, 0xf9, 0xdb, 0x4a, 0x6d, 0x02, 0xb9, 0xc3, - 0x9d, 0xe6, 0x9c, 0x75, 0x56, 0xe9, 0xad, 0x56, 0x7e, 0xc2, 0x6b, 0xe7, - 0x35, 0xef, 0x35, 0x32, 0xdb, 0x06, 0x98, 0xaf, 0x3e, 0x81, 0x7c, 0x81, - 0xb9, 0xea, 0x04, 0xf0, 0x1a, 0x65, 0x12, 0x91, 0xd9, 0x22, 0x69, 0x49, - 0x68, 0x13, 0xf2, 0xfb, 0x9c, 0x8c, 0x83, 0x9f, 0x08, 0x72, 0x7b, 0xc6, - 0x87, 0x47, 0x65, 0x39, 0xe4, 0xc6, 0x01, 0x9e, 0xfb, 0x5a, 0x46, 0x6c, - 0x58, 0x5e, 0x8d, 0x0d, 0x5b, 0x71, 0xdd, 0xc8, 0xc4, 0x07, 0xfe, 0x06, - 0xf4, 0x59, 0xb7, 0x61, 0x6c, 0x18, 0x45, 0x7f, 0xb6, 0xf5, 0xca, 0xec, - 0x02, 0x92, 0x08, 0xe4, 0x2c, 0x15, 0xe1, 0x99, 0x8e, 0xac, 0x9c, 0xaa, - 0xf5, 0x87, 0x2f, 0x6b, 0x69, 0x75, 0xf6, 0x23, 0x36, 0xc0, 0xf3, 0x2c, - 0xbd, 0x52, 0x5b, 0x90, 0x88, 0x91, 0x78, 0x52, 0x9c, 0x9a, 0x8b, 0xd9, - 0xe7, 0x34, 0x9e, 0x69, 0xb1, 0xa5, 0xb6, 0xb6, 0x8f, 0x89, 0xdc, 0x57, - 0xbe, 0xe3, 0xf5, 0x49, 0xab, 0x3e, 0x7f, 0xdd, 0xc3, 0x3d, 0xb4, 0x9a, - 0xd3, 0x03, 0x1e, 0xc8, 0xdb, 0xc3, 0xad, 0xe3, 0x46, 0xee, 0x8e, 0xcb, - 0x31, 0x91, 0xcd, 0x6c, 0xb1, 0x31, 0xee, 0x4d, 0x3c, 0xf3, 0x24, 0xf8, - 0xb8, 0x63, 0xe8, 0xd6, 0x93, 0x52, 0xa8, 0xad, 0x1f, 0xa3, 0x95, 0x07, - 0x3e, 0x43, 0xfa, 0x1c, 0xe7, 0x00, 0xf8, 0xbb, 0xa3, 0xe9, 0xd6, 0x01, - 0xc8, 0xd2, 0x1d, 0xc3, 0x38, 0x13, 0x35, 0x7f, 0x2a, 0x03, 0xa2, 0x9f, - 0xd3, 0x94, 0xfc, 0xf5, 0xca, 0x30, 0x16, 0x48, 0x46, 0xba, 0x96, 0x26, - 0xc5, 0x58, 0x62, 0x0d, 0xe1, 0xb5, 0xce, 0xb4, 0xda, 0xbf, 0xdd, 0x84, - 0xf5, 0x2d, 0x76, 0xc0, 0x62, 0xbd, 0x80, 0xf5, 0xe0, 0x9f, 0x6e, 0x96, - 0x1e, 0xd6, 0x0b, 0x98, 0x37, 0xec, 0xc7, 0x37, 0x73, 0x87, 0x4b, 0x4d, - 0xe4, 0x7a, 0x9b, 0x19, 0x5f, 0x73, 0x35, 0xde, 0x8f, 0x46, 0x44, 0x78, - 0x8f, 0x7e, 0xa3, 0x57, 0xda, 0xbe, 0x35, 0x08, 0x5f, 0xf1, 0x34, 0xb0, - 0x37, 0xe8, 0x9e, 0x1c, 0x90, 0x80, 0x7b, 0x66, 0x42, 0xd5, 0x5b, 0xde, - 0x58, 0x88, 0x7a, 0xef, 0x73, 0xc9, 0xb6, 0xcb, 0x71, 0xd6, 0x44, 0xfb, - 0x58, 0xf3, 0x41, 0x3f, 0xd1, 0x97, 0x91, 0x9f, 0x5e, 0xaf, 0x59, 0x9b, - 0x79, 0x7e, 0xf3, 0x86, 0x83, 0x6b, 0x62, 0xff, 0x90, 0xc2, 0x98, 0xde, - 0x3d, 0xfe, 0x46, 0xbe, 0xf4, 0x8e, 0x77, 0x13, 0x98, 0x4f, 0x4d, 0x7a, - 0x67, 0xe7, 0x1a, 0x99, 0xa3, 0x6b, 0x72, 0xaa, 0x41, 0x55, 0xef, 0x6d, - 0x38, 0x16, 0xfc, 0xe3, 0x08, 0xec, 0x93, 0x6b, 0xa0, 0xa9, 0x3d, 0x01, - 0x6c, 0x16, 0xe9, 0x55, 0x39, 0xd1, 0xf1, 0x27, 0xc4, 0xb5, 0x77, 0x58, - 0x99, 0xf2, 0x65, 0x8d, 0xb2, 0x9b, 0x83, 0x2c, 0x97, 0x33, 0xf2, 0x47, - 0xce, 0x15, 0x55, 0x6b, 0x9d, 0x47, 0x5e, 0x12, 0x38, 0xa5, 0x72, 0xb2, - 0x16, 0x7c, 0x0b, 0xbf, 0xf7, 0xe2, 0xd7, 0xb1, 0x16, 0xa3, 0xea, 0x8c, - 0x82, 0x7e, 0xae, 0xd9, 0x4c, 0xc1, 0x7f, 0xe8, 0x96, 0x65, 0x16, 0x10, - 0x0f, 0x53, 0xea, 0x9c, 0x0b, 0xd7, 0xf1, 0x6f, 0x2b, 0xff, 0x2c, 0x15, - 0xc8, 0xe6, 0x4c, 0x04, 0x74, 0x34, 0x65, 0x9f, 0x86, 0xd2, 0xc3, 0x13, - 0x0a, 0xf3, 0x1a, 0xe7, 0xe0, 0xb0, 0x96, 0x06, 0x44, 0xce, 0x65, 0x64, - 0x0e, 0x6b, 0x38, 0xb0, 0x44, 0x1d, 0x50, 0xb6, 0x93, 0xd2, 0x06, 0xd9, - 0x1f, 0x01, 0xf6, 0x30, 0x4e, 0x51, 0xc6, 0x61, 0xac, 0x8b, 0x5e, 0x09, - 0x9c, 0x81, 0x8c, 0x4f, 0x01, 0x23, 0x2c, 0xb4, 0xcb, 0xf7, 0x6a, 0xbe, - 0x4c, 0x2f, 0xf1, 0x5c, 0xbf, 0x3e, 0x35, 0xd2, 0x47, 0x1c, 0x25, 0xd5, - 0xda, 0x9c, 0xcc, 0x9d, 0x66, 0xce, 0x3e, 0xa9, 0xce, 0x0c, 0x04, 0xd4, - 0x99, 0x15, 0x37, 0x67, 0x76, 0xbf, 0x5d, 0x8c, 0x59, 0x15, 0xee, 0xb5, - 0x09, 0x6c, 0x67, 0x18, 0xe3, 0x6e, 0x24, 0x5f, 0x37, 0x57, 0x1d, 0x07, - 0xbf, 0x97, 0xe7, 0xa3, 0x99, 0xbc, 0xc4, 0x79, 0x76, 0x7a, 0xc2, 0xc6, - 0xfc, 0x97, 0xe1, 0x3f, 0xe7, 0x4a, 0x3c, 0x27, 0x5d, 0xc0, 0x0a, 0xcb, - 0xc8, 0xe5, 0x22, 0x73, 0xc6, 0x8f, 0x43, 0x6f, 0xbc, 0x2e, 0x8c, 0x1a, - 0xf0, 0x03, 0x2b, 0xea, 0xdd, 0xcf, 0xa8, 0xdd, 0x40, 0x0e, 0x1b, 0xd1, - 0xf6, 0x43, 0xd7, 0x79, 0xb3, 0xcd, 0xb3, 0x07, 0x9e, 0xc5, 0x3f, 0x0b, - 0x3f, 0x7a, 0x5e, 0xf8, 0x4e, 0xd6, 0xed, 0x26, 0xf3, 0xa5, 0xab, 0xf0, - 0x7b, 0x99, 0x58, 0x06, 0x36, 0x94, 0x0f, 0x77, 0x80, 0xe7, 0xdf, 0xc4, - 0xbd, 0x9c, 0xc3, 0x71, 0xa2, 0xf1, 0x15, 0x29, 0x44, 0x02, 0x32, 0x14, - 0xb9, 0x22, 0x9b, 0xe1, 0xc9, 0x34, 0x79, 0xdd, 0x8a, 0x8e, 0x8a, 0xa6, - 0xe8, 0x0d, 0xee, 0x86, 0x0d, 0xde, 0x84, 0xbf, 0x6b, 0xf7, 0x72, 0xfd, - 0x54, 0x91, 0x18, 0xea, 0x59, 0x75, 0xb6, 0xe0, 0xaa, 0xc5, 0x3a, 0x20, - 0xdf, 0xc5, 0xfe, 0x1f, 0x6a, 0x8c, 0xbb, 0x7b, 0x77, 0xac, 0x43, 0x93, - 0x3f, 0x77, 0x8e, 0xbb, 0x2c, 0x97, 0x47, 0xd2, 0x69, 0x6b, 0xa1, 0x73, - 0xd9, 0xa3, 0x73, 0xd6, 0xa3, 0x53, 0xf1, 0xe8, 0x5c, 0x5d, 0xa5, 0xb3, - 0x07, 0x76, 0xd0, 0x6c, 0x9e, 0x00, 0xde, 0x48, 0xc6, 0x9b, 0xcd, 0x34, - 0xf2, 0xb2, 0xd9, 0xe1, 0x69, 0xb5, 0xe7, 0xaa, 0x27, 0x46, 0xc7, 0x93, - 0x96, 0x2b, 0x7f, 0x58, 0x81, 0x4c, 0xc3, 0x1e, 0xf3, 0xe2, 0x62, 0x75, - 0xee, 0x07, 0xba, 0xfb, 0x85, 0x5d, 0xf0, 0x03, 0x4f, 0x23, 0x96, 0x5c, - 0x1c, 0x3f, 0x6f, 0x49, 0x7e, 0xdb, 0x27, 0x75, 0xd8, 0x7b, 0x0f, 0xdf, - 0x27, 0x35, 0xa5, 0xeb, 0xe2, 0x78, 0xb5, 0xf6, 0x34, 0xf2, 0x23, 0xf6, - 0xdf, 0x4e, 0x0c, 0xb6, 0xab, 0x52, 0x8b, 0xec, 0x3a, 0xcb, 0xfd, 0x21, - 0xf4, 0xab, 0xd4, 0xba, 0x21, 0xf7, 0x6e, 0x55, 0x57, 0xb9, 0x52, 0x0c, - 0x41, 0x8f, 0x26, 0x6c, 0x3e, 0x84, 0xb6, 0x30, 0xec, 0xa0, 0x0f, 0xed, - 0x3f, 0xc7, 0xda, 0x8e, 0xa0, 0x7d, 0xa5, 0x73, 0x5c, 0xe1, 0x58, 0x4b, - 0xce, 0x39, 0x37, 0x11, 0x73, 0xdf, 0x84, 0x1f, 0x1d, 0x44, 0x9f, 0x61, - 0xf4, 0xf9, 0x14, 0xc6, 0xe1, 0x3b, 0xcd, 0x1b, 0xf1, 0xd4, 0x00, 0x4f, - 0x7a, 0x0b, 0x4f, 0x0d, 0xf0, 0x03, 0xdf, 0x79, 0x92, 0x35, 0xe8, 0x61, - 0x39, 0x5a, 0xe4, 0x19, 0x29, 0xbe, 0x17, 0x6f, 0x4a, 0x00, 0x98, 0xb4, - 0xed, 0x64, 0x34, 0xdc, 0x50, 0xb5, 0x1e, 0xda, 0xd6, 0x50, 0xbc, 0x2a, - 0x2a, 0xce, 0x44, 0x8e, 0x22, 0x7e, 0xdd, 0x74, 0xba, 0xe5, 0x75, 0x6f, - 0xac, 0x15, 0xe1, 0xfe, 0xe5, 0xda, 0xb1, 0x8e, 0x95, 0xae, 0x8d, 0xbf, - 0x6a, 0x19, 0xde, 0xbc, 0x7a, 0x31, 0xd6, 0xaf, 0xa2, 0xef, 0xb5, 0xf1, - 0xcb, 0xb5, 0x8d, 0xfa, 0xde, 0x44, 0xdf, 0xb6, 0x96, 0xbe, 0x37, 0xd1, - 0xaf, 0x1b, 0x71, 0xb0, 0x5b, 0xcd, 0x69, 0x16, 0x7c, 0x5d, 0x2f, 0xaa, - 0xf7, 0xb4, 0x21, 0x77, 0x8e, 0x69, 0x12, 0x53, 0x67, 0xdc, 0x5a, 0x49, - 0xd4, 0x8c, 0x68, 0xef, 0xa8, 0xf7, 0x28, 0x1b, 0x18, 0xb3, 0x80, 0x7b, - 0xe7, 0x27, 0xb4, 0x54, 0x35, 0x87, 0x98, 0xf5, 0x30, 0xf1, 0x53, 0xdc, - 0x46, 0xcc, 0xac, 0x80, 0x5e, 0xad, 0xd8, 0xe0, 0x79, 0x6a, 0xd8, 0xc5, - 0x2d, 0xe2, 0xec, 0x87, 0x0d, 0x75, 0xae, 0x21, 0xad, 0x6a, 0x76, 0x95, - 0xa2, 0x98, 0xc9, 0x11, 0x9e, 0x65, 0xf8, 0x0c, 0xd6, 0xe5, 0x57, 0xd0, - 0x96, 0x44, 0x7c, 0x3c, 0xa0, 0x25, 0xcf, 0x8f, 0xe3, 0xfa, 0x49, 0x5c, - 0xc3, 0x1f, 0x2f, 0x64, 0x71, 0xff, 0x49, 0x5c, 0x4f, 0x6b, 0xa9, 0x7a, - 0x16, 0xd7, 0x4f, 0xe1, 0x7a, 0xca, 0x64, 0x9e, 0xf2, 0xaa, 0x95, 0xd1, - 0x6c, 0xd0, 0xb2, 0xcf, 0x8f, 0xe3, 0xd3, 0x4a, 0x8f, 0xf7, 0xa0, 0xa7, - 0x22, 0xf7, 0xda, 0x62, 0xe0, 0x69, 0x9f, 0x96, 0xae, 0x76, 0x81, 0xc6, - 0x00, 0x9e, 0xa7, 0x4d, 0xed, 0xf7, 0xc6, 0x67, 0xcd, 0xe9, 0x63, 0xaa, - 0xe6, 0x64, 0x24, 0x32, 0xc0, 0xc9, 0x87, 0x91, 0x07, 0x68, 0x92, 0xb6, - 0x9e, 0x93, 0x42, 0x1c, 0x7e, 0xa5, 0x6a, 0x48, 0x2a, 0x94, 0xc7, 0xef, - 0xbc, 0x24, 0x47, 0x71, 0xbf, 0x4a, 0x5b, 0x60, 0xbf, 0x3f, 0x95, 0x42, - 0x99, 0xb8, 0x9f, 0x75, 0x26, 0xd6, 0xa6, 0x58, 0x5f, 0xca, 0x41, 0x06, - 0x21, 0xda, 0xef, 0x06, 0x35, 0x31, 0xf7, 0x8c, 0x34, 0xe2, 0xb2, 0x96, - 0xac, 0x72, 0xdf, 0xaf, 0x91, 0xb9, 0x6c, 0xf1, 0xfd, 0xb1, 0x69, 0xee, - 0x23, 0x16, 0x8c, 0x04, 0xeb, 0x23, 0xaa, 0xbe, 0x1e, 0x77, 0xf7, 0x07, - 0x5b, 0xcf, 0xa4, 0xf8, 0xeb, 0x85, 0xe3, 0x7e, 0x0d, 0xcf, 0xbb, 0xf5, - 0xac, 0x54, 0xfd, 0x9d, 0xba, 0xe0, 0x3b, 0x00, 0xe7, 0xa0, 0x8b, 0xcb, - 0x2a, 0x37, 0xe6, 0x1e, 0xee, 0xbb, 0xe5, 0x54, 0xc8, 0x61, 0x8a, 0xac, - 0x91, 0xf9, 0xfb, 0x76, 0xbe, 0x1c, 0xd7, 0xf3, 0x4a, 0x3e, 0x67, 0x40, - 0x53, 0xe2, 0xf4, 0xbb, 0xd9, 0x10, 0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf3, - 0x2e, 0xdf, 0xe4, 0x99, 0xf2, 0x38, 0x0c, 0xff, 0xc9, 0xf7, 0x2b, 0x9e, - 0x93, 0x5c, 0x9c, 0x35, 0x1e, 0x03, 0xb1, 0x31, 0x8f, 0xdf, 0x77, 0xe5, - 0x37, 0xeb, 0xc9, 0x2f, 0x57, 0xfe, 0x2f, 0x4a, 0x87, 0x15, 0x8b, 0xe3, - 0xf9, 0xb5, 0x8f, 0xbd, 0x4a, 0x77, 0x15, 0x75, 0x7e, 0xd7, 0x97, 0x81, - 0x5f, 0xbf, 0xdb, 0xd8, 0xf6, 0xc6, 0x2d, 0xf2, 0xf6, 0x10, 0xcf, 0x43, - 0x0c, 0xda, 0x42, 0xfe, 0x39, 0x0f, 0xc6, 0x30, 0x7f, 0xaf, 0xd5, 0x9f, - 0x83, 0x3f, 0xcf, 0xfb, 0x95, 0x0f, 0xf9, 0xfd, 0xe4, 0x16, 0xe9, 0xca, - 0x98, 0x86, 0xc5, 0xd8, 0xf0, 0xb8, 0xb7, 0x3f, 0xf0, 0x7f, 0x43, 0xce, - 0xae, 0x2c, 0x02, 0x09, 0x99, 0xf5, 0xde, 0xbf, 0xde, 0xc0, 0x1e, 0xd6, - 0xef, 0x35, 0x37, 0x32, 0x67, 0xad, 0xbb, 0xf3, 0xae, 0x6c, 0x30, 0xef, - 0x8a, 0x37, 0xef, 0xea, 0x7d, 0xf2, 0x5b, 0x99, 0xb7, 0x31, 0x67, 0xda, - 0xdc, 0x46, 0xf6, 0x28, 0xea, 0xdd, 0xb0, 0x15, 0x23, 0x18, 0xb4, 0x9d, - 0x7b, 0xd5, 0x50, 0x99, 0x57, 0xbb, 0x76, 0x79, 0x16, 0xb1, 0xb0, 0x5c, - 0x76, 0x73, 0xec, 0xb2, 0xc3, 0x5a, 0xf6, 0xbb, 0xf1, 0xc0, 0x77, 0xb9, - 0xbe, 0xa8, 0xce, 0xbb, 0xcc, 0x3a, 0x6e, 0xdd, 0xab, 0x5c, 0x6e, 0x8d, - 0xa9, 0x0f, 0x32, 0x9e, 0x0e, 0xe6, 0x65, 0x82, 0xef, 0x94, 0xe3, 0xfa, - 0x11, 0xb9, 0xb2, 0xa0, 0xf6, 0xac, 0xbc, 0xbd, 0x21, 0xee, 0xf9, 0xa8, - 0xfd, 0x6f, 0xf8, 0xb5, 0x49, 0xe5, 0xd7, 0x97, 0x17, 0xd4, 0x3d, 0x17, - 0x2b, 0x39, 0x13, 0xf0, 0xfb, 0xc8, 0x25, 0xac, 0x07, 0xa4, 0x80, 0x9c, - 0xfb, 0xac, 0x75, 0x78, 0x0b, 0x71, 0x0e, 0x69, 0x2d, 0x83, 0xd6, 0xe5, - 0x05, 0xd9, 0xc2, 0x33, 0x25, 0x65, 0xb5, 0xcf, 0xe6, 0xd6, 0xc5, 0xa7, - 0xc5, 0xff, 0x7f, 0x1d, 0x41, 0x2f, 0x16, 0xf2, 0x5c, 0x0b, 0xdf, 0x73, - 0xa6, 0xaf, 0x40, 0x1e, 0x34, 0xc1, 0x7d, 0x9c, 0x66, 0xd3, 0xad, 0x9b, - 0x37, 0xb1, 0x2e, 0xda, 0xf8, 0x0e, 0x05, 0xfe, 0x0e, 0xc3, 0x7e, 0xb0, - 0x4e, 0x56, 0xdb, 0x79, 0xcd, 0xdc, 0xc3, 0xbf, 0x66, 0x60, 0xfb, 0x3f, - 0xe8, 0xf3, 0x49, 0x14, 0x38, 0x46, 0x00, 0x00, 0x00 }; - -static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = { + 0x1f, 0x8b, 0x08, 0x08, 0x51, 0xfe, 0x2f, 0x45, 0x00, 0x03, 0x74, 0x65, + 0x73, 0x74, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xcd, 0x7b, 0x7f, 0x70, + 0x1b, 0xe7, 0x99, 0xde, 0xbb, 0x0b, 0x80, 0x04, 0x29, 0x8a, 0x5a, 0x31, + 0x30, 0x83, 0x38, 0xb4, 0x8d, 0x15, 0x17, 0x34, 0x6d, 0xf2, 0x1c, 0x58, + 0xe5, 0xf9, 0xd8, 0x06, 0xb5, 0xd7, 0xc0, 0x92, 0xa2, 0x63, 0x26, 0x47, + 0xbb, 0xcc, 0x9d, 0x92, 0x51, 0x7d, 0x28, 0x48, 0x29, 0x6e, 0xe3, 0xb4, + 0xaa, 0xe3, 0x3f, 0x34, 0x4d, 0x5b, 0xc3, 0x00, 0x25, 0xcb, 0x2e, 0x44, + 0xd0, 0x16, 0x63, 0xa5, 0x33, 0x37, 0x53, 0x18, 0x80, 0x28, 0xe7, 0xba, + 0x24, 0xdc, 0xe4, 0x2e, 0xe9, 0x1f, 0xc9, 0x99, 0xa5, 0x6c, 0xc5, 0x6d, + 0xae, 0x33, 0xbe, 0x3f, 0xda, 0xa6, 0x37, 0xd7, 0x19, 0x8d, 0xfc, 0x23, + 0xce, 0x8f, 0xb9, 0xb8, 0x69, 0x7a, 0x56, 0x5b, 0xd9, 0xe8, 0xf3, 0x7c, + 0xbb, 0x4b, 0x82, 0x32, 0x15, 0x5b, 0xd7, 0x76, 0xa6, 0x9c, 0xc1, 0x10, + 0xfb, 0xed, 0xb7, 0xdf, 0xf7, 0xfe, 0x7e, 0xdf, 0xe7, 0xfd, 0x16, 0x71, + 0x91, 0x6e, 0xf1, 0xff, 0x76, 0xe3, 0x93, 0x38, 0x7a, 0xec, 0xb1, 0x3b, + 0xc6, 0xef, 0xd8, 0x2f, 0x72, 0xe7, 0x9d, 0xb2, 0x2b, 0xaa, 0xf3, 0xe6, + 0xdb, 0x21, 0x91, 0xdc, 0x4f, 0xe5, 0xaf, 0xfc, 0x87, 0xc7, 0x8d, 0x60, + 0x7d, 0x7e, 0x24, 0xaa, 0xa7, 0x5f, 0xcc, 0x64, 0x2c, 0x89, 0x86, 0xd2, + 0x33, 0x9f, 0x9d, 0xb3, 0x44, 0x6c, 0x77, 0x24, 0x91, 0x95, 0xf7, 0x5a, + 0x85, 0x58, 0x58, 0x38, 0x7e, 0x53, 0xfa, 0xca, 0xe3, 0xdf, 0xff, 0x2d, + 0xf3, 0x9d, 0x6a, 0x48, 0xa2, 0x46, 0x3a, 0x27, 0xc6, 0x90, 0x44, 0x07, + 0xf0, 0xcc, 0xef, 0xdf, 0x3a, 0xa5, 0x4b, 0x6f, 0xb0, 0x56, 0x5c, 0x16, + 0x2a, 0x6f, 0xb7, 0xbe, 0x7f, 0x6b, 0x4c, 0xfe, 0x55, 0xd3, 0x90, 0x17, + 0x9b, 0x61, 0x6d, 0xb2, 0xd2, 0x23, 0xa5, 0x8a, 0x2b, 0xc7, 0xcb, 0x05, + 0xc9, 0x36, 0x5f, 0x90, 0xe2, 0xb2, 0xd1, 0x9b, 0x39, 0xf7, 0x07, 0x52, + 0x5a, 0xee, 0xeb, 0xcd, 0x9e, 0x73, 0xa5, 0x58, 0x8e, 0xf7, 0x66, 0x9a, + 0x46, 0x6f, 0xf6, 0x4c, 0x0c, 0xd7, 0x7d, 0xbd, 0x99, 0x33, 0x66, 0x41, + 0xa4, 0x1f, 0x73, 0xe2, 0xbd, 0xd9, 0x8a, 0x99, 0x13, 0x19, 0x4c, 0xbd, + 0x22, 0x03, 0xbd, 0xd9, 0x66, 0x4d, 0x5b, 0x37, 0x34, 0x29, 0xfe, 0x86, + 0x18, 0xbd, 0xe9, 0xcb, 0xad, 0x4f, 0x58, 0x86, 0xec, 0xb5, 0x64, 0xcf, + 0x1e, 0x4b, 0x9e, 0x88, 0xa7, 0xa3, 0x92, 0x3f, 0xdd, 0x25, 0xb6, 0xe2, + 0xc9, 0x90, 0xfc, 0x99, 0x11, 0x63, 0x43, 0x22, 0x62, 0xc7, 0x82, 0xeb, + 0x56, 0x2b, 0x93, 0xfa, 0x02, 0xe5, 0x8a, 0xbd, 0xa4, 0x77, 0xb2, 0x29, + 0x92, 0xa9, 0x44, 0x25, 0x93, 0x7a, 0xaf, 0xe5, 0x3d, 0x13, 0xc5, 0xbe, + 0xe1, 0xde, 0x89, 0x4a, 0xab, 0xe5, 0xa4, 0xb0, 0x47, 0x2a, 0x78, 0x36, + 0x22, 0xd5, 0x98, 0x5d, 0x2d, 0xa5, 0x4c, 0xdd, 0xd3, 0x09, 0x79, 0xe4, + 0xb5, 0x2d, 0xba, 0xf5, 0xdb, 0x92, 0x8f, 0x49, 0xb5, 0x98, 0xba, 0x4b, + 0x9e, 0x4e, 0x19, 0x72, 0x12, 0xeb, 0x3d, 0x95, 0x82, 0x1c, 0xad, 0x63, + 0x5a, 0xa6, 0x69, 0xc6, 0x45, 0x7b, 0x5a, 0x32, 0x67, 0x06, 0x8d, 0xac, + 0x60, 0x6f, 0xab, 0x75, 0x4b, 0x26, 0x85, 0xfd, 0x46, 0xff, 0x67, 0xcb, + 0x8e, 0x99, 0xb9, 0xaa, 0x0c, 0x48, 0xb1, 0x32, 0x98, 0xfa, 0x13, 0xd1, + 0xa4, 0xd3, 0xa2, 0x7c, 0x5a, 0x72, 0x3f, 0xf6, 0xcd, 0x58, 0x18, 0x6f, + 0x8a, 0xad, 0x27, 0x23, 0xf2, 0x0f, 0x0c, 0x33, 0x91, 0x09, 0xf5, 0x4b, + 0xf1, 0x74, 0x27, 0xe8, 0xb4, 0xfb, 0x74, 0xcc, 0x3d, 0x30, 0x26, 0xb1, + 0x5d, 0x22, 0x5a, 0x28, 0x9d, 0xc4, 0xba, 0x22, 0x45, 0x77, 0x00, 0xcf, + 0x26, 0xc7, 0x7f, 0x2a, 0x7b, 0x24, 0xb1, 0x37, 0x2c, 0x25, 0xb7, 0x1b, + 0x72, 0x34, 0xa0, 0x83, 0xe4, 0xf8, 0x5f, 0x40, 0x29, 0xba, 0x95, 0x8c, + 0x1f, 0x93, 0x9c, 0x96, 0x6d, 0x76, 0x48, 0x29, 0x19, 0x95, 0x05, 0xd0, + 0xb1, 0x90, 0xfa, 0xa2, 0x96, 0x39, 0x77, 0x50, 0xcb, 0x9e, 0xc3, 0xbc, + 0x66, 0xdd, 0xb7, 0x35, 0x03, 0xeb, 0xe8, 0x52, 0x4c, 0x1e, 0xc4, 0xbd, + 0xa8, 0xcc, 0x61, 0xde, 0x1c, 0x78, 0x2a, 0x35, 0xf7, 0xc8, 0xfa, 0x6c, + 0xac, 0x37, 0x03, 0x1d, 0x16, 0x71, 0xff, 0xb7, 0x67, 0x34, 0x31, 0x2c, + 0x5b, 0x7e, 0x3c, 0x06, 0x1d, 0x9e, 0x81, 0xfe, 0xce, 0xc4, 0xe5, 0x78, + 0x45, 0x62, 0xba, 0x24, 0xe3, 0x79, 0x79, 0x41, 0xea, 0x2e, 0xf5, 0x0f, + 0x7d, 0x42, 0xdf, 0x45, 0x97, 0xcf, 0x41, 0x6f, 0x15, 0x07, 0xf2, 0x98, + 0x02, 0x0d, 0x0f, 0x6a, 0xf7, 0xd7, 0x67, 0xb5, 0x03, 0xcd, 0x1f, 0x6b, + 0xd2, 0x7d, 0x4c, 0xfb, 0x5c, 0xf3, 0x88, 0xe6, 0xcb, 0x1e, 0xba, 0x8b, + 0x8a, 0x3d, 0x13, 0x95, 0x95, 0xa6, 0xa7, 0xbb, 0x1a, 0xec, 0xd3, 0x36, + 0x6c, 0xe8, 0xe1, 0x6f, 0x6f, 0xce, 0x59, 0x69, 0xc6, 0x64, 0x01, 0xb4, + 0x1d, 0x6f, 0x72, 0xfe, 0xef, 0x41, 0x3f, 0x51, 0x71, 0x6f, 0xed, 0x91, + 0x1c, 0xc6, 0x8b, 0x67, 0xc4, 0xce, 0xa4, 0x74, 0x3c, 0xd3, 0x2b, 0x21, + 0xab, 0x1f, 0x9f, 0x6e, 0x99, 0xab, 0x77, 0xda, 0x21, 0x2b, 0x26, 0x73, + 0x4d, 0xca, 0x10, 0xff, 0x2b, 0x81, 0x1c, 0x49, 0x2b, 0xc7, 0xf9, 0x1c, + 0xc7, 0x0d, 0x8c, 0xb7, 0x8f, 0xd1, 0x2e, 0x7a, 0x41, 0x8f, 0x39, 0x2c, + 0x18, 0xcb, 0x57, 0x92, 0xc6, 0xe7, 0xf8, 0xbf, 0x49, 0xd9, 0x06, 0x32, + 0x0d, 0x63, 0xae, 0x2e, 0xf9, 0x3a, 0xf6, 0x39, 0x7d, 0xa5, 0x15, 0x19, + 0xc3, 0xb5, 0xf5, 0x4b, 0xc8, 0x92, 0xfb, 0x86, 0x41, 0x93, 0x2e, 0xb9, + 0x3a, 0xd7, 0xe2, 0x7d, 0x81, 0xee, 0x8b, 0x7b, 0x75, 0x19, 0x86, 0x7e, + 0x4d, 0xec, 0xd3, 0x85, 0x39, 0x3d, 0x90, 0x1f, 0x78, 0x3d, 0x87, 0xef, + 0xe0, 0x5d, 0xb7, 0x74, 0x3c, 0xdf, 0x29, 0x73, 0x29, 0xda, 0x0b, 0xe9, + 0xdc, 0x85, 0xb5, 0xbb, 0x64, 0xfe, 0x34, 0xe5, 0x01, 0xbb, 0xaa, 0xc4, + 0xa4, 0x74, 0xc6, 0x34, 0x1c, 0x31, 0x21, 0x1b, 0x1b, 0xf3, 0x3a, 0x25, + 0x67, 0xb4, 0x5a, 0x13, 0xa9, 0x11, 0xe3, 0x9b, 0xca, 0xce, 0x47, 0x8c, + 0xa4, 0x26, 0x85, 0x8e, 0xf4, 0x10, 0x64, 0x6b, 0x1e, 0x14, 0xe1, 0xf5, + 0x0f, 0xc4, 0x9e, 0xa5, 0xff, 0xc4, 0xb8, 0x17, 0xfc, 0xa9, 0x1f, 0xf4, + 0xd3, 0xe7, 0x06, 0xa0, 0x97, 0xb8, 0xf2, 0x83, 0x89, 0x1d, 0xfd, 0xc0, + 0x9c, 0xaa, 0x82, 0xdf, 0xe2, 0xb9, 0x30, 0xfd, 0x2f, 0x05, 0x73, 0x93, + 0x5d, 0x56, 0x14, 0xb6, 0x40, 0x5a, 0xc6, 0xb1, 0x7e, 0xab, 0xf5, 0xd9, + 0x94, 0x47, 0x53, 0xf1, 0x8c, 0x8d, 0x67, 0xc3, 0x90, 0xbb, 0xf9, 0x70, + 0x42, 0xed, 0x3f, 0xee, 0xef, 0x6f, 0xc8, 0x1c, 0xe8, 0x2e, 0x56, 0x42, + 0x92, 0x35, 0xb8, 0xc6, 0x9f, 0x71, 0x3c, 0xe7, 0xad, 0x05, 0xbb, 0x3d, + 0x35, 0x68, 0xdc, 0x07, 0x5f, 0xa2, 0x8f, 0x15, 0x57, 0x29, 0x63, 0xac, + 0x33, 0x46, 0x19, 0x1b, 0x8a, 0xc6, 0xcc, 0x19, 0xda, 0x91, 0x0c, 0x84, + 0x84, 0x76, 0x8e, 0x98, 0x01, 0xbb, 0x2a, 0xf9, 0x76, 0x95, 0x77, 0xa9, + 0xff, 0xbb, 0x7d, 0xff, 0xd4, 0x65, 0x28, 0x49, 0x7b, 0x7f, 0x5a, 0xb2, + 0xf0, 0xf1, 0x39, 0xec, 0x54, 0x07, 0x4f, 0xb5, 0xca, 0x20, 0x64, 0x15, + 0xf8, 0x1d, 0xf4, 0x3b, 0xfa, 0x6e, 0x2b, 0x88, 0x05, 0xc5, 0x0a, 0x7d, + 0xa6, 0x68, 0xe8, 0x52, 0xc0, 0x07, 0x76, 0x63, 0x99, 0xc3, 0x99, 0x90, + 0x39, 0x93, 0x03, 0x6d, 0xb0, 0x7b, 0xc9, 0xdc, 0x49, 0x7b, 0xc6, 0x9c, + 0xa6, 0xec, 0x0f, 0xfc, 0xac, 0xe6, 0x52, 0x4f, 0xdd, 0xd8, 0x37, 0xa0, + 0x29, 0x8c, 0x31, 0xae, 0x13, 0x85, 0xcd, 0x07, 0x36, 0x43, 0xfb, 0x33, + 0xed, 0x75, 0xe9, 0x90, 0xe1, 0x24, 0x62, 0xd9, 0x19, 0x1d, 0xfa, 0x1b, + 0x40, 0x4c, 0x09, 0xcb, 0x11, 0xc8, 0xea, 0x4b, 0x15, 0xd2, 0xe7, 0xc0, + 0xef, 0x10, 0xdb, 0xce, 0x4c, 0xc2, 0xcf, 0xa6, 0xb4, 0x09, 0xf8, 0xc4, + 0x67, 0xea, 0xa4, 0xa9, 0x25, 0xf4, 0x4b, 0xe7, 0x5c, 0x4e, 0x9b, 0x6c, + 0x1e, 0xd4, 0xa6, 0xce, 0xd1, 0x4f, 0xe8, 0x23, 0xa6, 0xf1, 0x80, 0x78, + 0x3c, 0x14, 0x9b, 0xaf, 0x68, 0xf4, 0xd5, 0xe2, 0xa9, 0x2e, 0xd0, 0xb1, + 0x0b, 0xf4, 0x18, 0xf0, 0x3d, 0xd8, 0x97, 0x65, 0xce, 0xd0, 0x66, 0x9c, + 0xa4, 0x95, 0xf8, 0xe7, 0xf2, 0x41, 0x39, 0x4c, 0x6c, 0xca, 0x61, 0x04, + 0x32, 0xd9, 0x2e, 0x87, 0x85, 0x0f, 0xca, 0xc1, 0x2e, 0x40, 0x0e, 0x0b, + 0x88, 0x43, 0x0b, 0x4d, 0xf2, 0xdc, 0x12, 0xfd, 0x4e, 0x81, 0x75, 0xca, + 0xbd, 0x7a, 0x9a, 0x36, 0x4a, 0x3f, 0x49, 0x26, 0x4a, 0x58, 0xa1, 0xe1, + 0xf6, 0x28, 0xdf, 0x98, 0x54, 0xb2, 0xf8, 0x30, 0x7e, 0xc9, 0xdf, 0x16, + 0xcf, 0x53, 0x75, 0xc6, 0x1b, 0xd8, 0x79, 0xd2, 0x32, 0xbe, 0x20, 0x5b, + 0x7c, 0xdf, 0xb7, 0xc5, 0x37, 0xf6, 0x09, 0x62, 0x10, 0x79, 0x0e, 0xe2, + 0x31, 0x6d, 0xe5, 0xa5, 0x56, 0xc8, 0xb2, 0xa0, 0x03, 0xda, 0x0b, 0x69, + 0x30, 0x8d, 0xcf, 0x0a, 0xfe, 0x23, 0x2e, 0xd0, 0x97, 0x72, 0x6a, 0x5e, + 0x87, 0xe4, 0xf6, 0x7a, 0xf3, 0xe7, 0x2a, 0xad, 0x5f, 0xe8, 0xe9, 0xf7, + 0x5b, 0x99, 0x31, 0xcb, 0xf7, 0xf1, 0xa8, 0x7c, 0xb9, 0x6e, 0xe6, 0x12, + 0x5a, 0x8f, 0x14, 0x6e, 0x40, 0x5c, 0xa9, 0xd0, 0x3f, 0xfa, 0xaf, 0x11, + 0xcb, 0x06, 0xfc, 0x58, 0xf6, 0x13, 0xc8, 0x9e, 0xb9, 0xe7, 0xf0, 0xfb, + 0xeb, 0x31, 0xfe, 0x4f, 0x1a, 0x33, 0xf2, 0x05, 0xe6, 0x9b, 0x3d, 0xba, + 0x8a, 0xdf, 0x16, 0x73, 0x41, 0x21, 0x9c, 0xee, 0x96, 0xc2, 0x5e, 0x29, + 0x84, 0xd2, 0xf4, 0x23, 0xfa, 0x46, 0x87, 0x4f, 0x77, 0x90, 0x3b, 0xf8, + 0x77, 0x4c, 0x17, 0x8b, 0x73, 0x90, 0x27, 0x2a, 0xe4, 0xe3, 0xbd, 0x40, + 0x27, 0x78, 0x46, 0x22, 0x9e, 0xcd, 0x4d, 0x23, 0x66, 0x52, 0xa6, 0xed, + 0xf6, 0xc2, 0x58, 0x2a, 0x09, 0xdd, 0x62, 0x2c, 0x15, 0x23, 0x94, 0x7e, + 0x50, 0xb3, 0xeb, 0x5f, 0xd4, 0x6c, 0xc8, 0xce, 0x86, 0xec, 0x6c, 0xc8, + 0x2e, 0x03, 0xd9, 0x65, 0x9b, 0xa4, 0x87, 0xb4, 0x78, 0xeb, 0x3b, 0xde, + 0xfa, 0xa0, 0xb3, 0x5f, 0xf2, 0xca, 0xc7, 0xc9, 0x2f, 0x62, 0xb2, 0x8a, + 0x07, 0x93, 0x9a, 0x17, 0x0f, 0xb8, 0xde, 0x14, 0x9e, 0xbf, 0x1b, 0x79, + 0xce, 0xd6, 0x75, 0x6b, 0x4b, 0x26, 0x0b, 0x6d, 0x32, 0x29, 0xb9, 0x94, + 0x11, 0xe7, 0xd3, 0x97, 0x5d, 0xe8, 0x3d, 0x90, 0xcb, 0x34, 0x68, 0xe8, + 0x24, 0xef, 0x3e, 0x1f, 0x5c, 0xbf, 0xcf, 0x5f, 0xff, 0xd3, 0x58, 0x93, + 0xbe, 0xbb, 0xd3, 0xbe, 0xdc, 0x93, 0xb9, 0xf4, 0xd7, 0xf1, 0x83, 0x5a, + 0x02, 0x31, 0xfa, 0x45, 0xf8, 0xda, 0xc5, 0x50, 0x5c, 0xbe, 0x7f, 0xeb, + 0x6b, 0xa8, 0x2f, 0xa4, 0x70, 0x63, 0xba, 0x95, 0x08, 0xa7, 0xdf, 0x6b, + 0x2d, 0x8c, 0x21, 0x7e, 0xa6, 0xcd, 0x78, 0x26, 0x34, 0x2a, 0x2f, 0x35, + 0x87, 0xe5, 0x3b, 0x4d, 0x4b, 0xfe, 0xa8, 0x99, 0x90, 0x3f, 0x6c, 0x0e, + 0xc8, 0xb7, 0x9b, 0x71, 0xf9, 0x56, 0x33, 0xa8, 0x45, 0xe2, 0xb4, 0xa5, + 0x5e, 0xa7, 0xb9, 0x53, 0x3d, 0x04, 0x3b, 0xc7, 0x5a, 0x99, 0xb1, 0x70, + 0x2e, 0x94, 0x56, 0x35, 0xc2, 0xcc, 0xd1, 0xf2, 0xe3, 0x2d, 0xdd, 0xb2, + 0x0a, 0xba, 0xde, 0x33, 0x6e, 0xdc, 0x25, 0x39, 0x3d, 0x8d, 0x31, 0x77, + 0x3c, 0xec, 0x94, 0xbb, 0x90, 0x5f, 0xa2, 0xa8, 0x65, 0x06, 0xa4, 0x80, + 0x75, 0x0b, 0xcd, 0x56, 0x6b, 0x29, 0xf5, 0x0f, 0x3f, 0x65, 0xfc, 0x8d, + 0x7f, 0xd9, 0x29, 0xbd, 0xdf, 0x5e, 0x37, 0x86, 0xfe, 0xbb, 0x5f, 0x0f, + 0xa1, 0xc6, 0xea, 0x57, 0x8b, 0xe7, 0xb4, 0xf4, 0xa8, 0x93, 0x70, 0x37, + 0x70, 0x5f, 0xa2, 0xfd, 0xd6, 0xcf, 0x51, 0x85, 0xc8, 0xee, 0x98, 0xc5, + 0x9a, 0x6b, 0x26, 0xfb, 0x79, 0xfc, 0xff, 0x58, 0x5a, 0xf6, 0xf4, 0xe1, + 0xff, 0xde, 0x34, 0x4c, 0x2a, 0xcd, 0x98, 0xac, 0xb5, 0xc5, 0x64, 0xd1, + 0x1c, 0xe4, 0xdf, 0x05, 0xf0, 0xe4, 0x40, 0x1e, 0xbf, 0xd3, 0x8c, 0x6a, + 0xd9, 0xd3, 0xfd, 0x52, 0xaa, 0x33, 0xaf, 0x71, 0x5e, 0xd4, 0xaf, 0x7b, + 0x78, 0xdd, 0x81, 0x6b, 0x41, 0xae, 0xf9, 0x94, 0x48, 0xaf, 0xf9, 0xa3, + 0xcf, 0x4b, 0xdd, 0xaf, 0x5b, 0x22, 0xb2, 0xac, 0x6c, 0x8c, 0xe3, 0xaf, + 0x65, 0xbf, 0x36, 0xb4, 0x35, 0xfe, 0xec, 0xe6, 0xf8, 0x3b, 0xd9, 0x4f, + 0x6f, 0x8e, 0x77, 0x87, 0x3d, 0x1e, 0xc6, 0xb5, 0x99, 0x66, 0xc1, 0x1f, + 0xbb, 0x0c, 0xb9, 0xb7, 0x5a, 0x0b, 0xc8, 0x3d, 0x45, 0xeb, 0x32, 0xea, + 0x24, 0xc6, 0x9f, 0xeb, 0x89, 0x37, 0xdb, 0x62, 0x8d, 0x91, 0x09, 0x51, + 0x9f, 0x51, 0xf1, 0xd6, 0xe4, 0xfd, 0x4e, 0xc4, 0x9d, 0xcb, 0xf8, 0xce, + 0x3c, 0x17, 0xc4, 0x3c, 0xce, 0xe1, 0xf3, 0x6f, 0x5f, 0x43, 0xe7, 0x31, + 0xe8, 0xfc, 0xff, 0x1b, 0xdd, 0xe2, 0x4f, 0xe9, 0x56, 0xc5, 0x9d, 0x97, + 0xb6, 0xd9, 0x2c, 0xe9, 0xef, 0xf6, 0x69, 0x96, 0x68, 0x38, 0x6d, 0x38, + 0x0b, 0xd6, 0x8d, 0x12, 0x41, 0x0d, 0x4b, 0x9b, 0x2d, 0x35, 0xbf, 0x8b, + 0xe7, 0x99, 0x27, 0x25, 0x1a, 0x49, 0xd3, 0x2e, 0xd6, 0x07, 0x32, 0xd6, + 0x31, 0xa7, 0xe6, 0x1e, 0x73, 0xce, 0x2a, 0x3b, 0x59, 0xbf, 0xc9, 0xab, + 0xcd, 0x7f, 0x74, 0x13, 0x6a, 0x73, 0x3c, 0xcf, 0x98, 0xcb, 0xf1, 0x46, + 0x4f, 0xc6, 0x62, 0x0e, 0x5a, 0x72, 0x8a, 0xf8, 0x2c, 0xa8, 0xb9, 0xaf, + 0x0e, 0x70, 0x6e, 0x67, 0x3a, 0x76, 0xd3, 0x8f, 0xf1, 0xbf, 0x23, 0xfd, + 0xce, 0x4d, 0x17, 0x2c, 0xae, 0x3b, 0x75, 0xd3, 0x59, 0xb5, 0x46, 0x18, + 0xf1, 0x8c, 0xf3, 0x2e, 0xdf, 0xc4, 0x67, 0x9f, 0x44, 0x1c, 0x3f, 0xe1, + 0x42, 0x97, 0xee, 0x8b, 0x4e, 0x1e, 0x9f, 0x39, 0xd2, 0x54, 0xe1, 0x7d, + 0xe3, 0xe6, 0x8c, 0x15, 0x56, 0xf9, 0xf6, 0x4b, 0x98, 0x73, 0x04, 0x73, + 0x0e, 0xbb, 0x01, 0x3f, 0xea, 0xbe, 0x93, 0xc5, 0xfd, 0xc3, 0x65, 0xc3, + 0x71, 0xca, 0xe6, 0x38, 0x6a, 0x8e, 0xf8, 0x71, 0xe4, 0xe3, 0x1c, 0x72, + 0xa0, 0x2d, 0xe6, 0x70, 0x41, 0xd2, 0x5d, 0x93, 0xa8, 0xe5, 0x56, 0x90, + 0x4f, 0x50, 0x87, 0xa4, 0xaa, 0x32, 0xd8, 0x95, 0x39, 0xad, 0xc3, 0x3e, + 0xef, 0x80, 0xbd, 0x1a, 0x8e, 0x9e, 0x44, 0x5c, 0x47, 0xdc, 0x5c, 0xa8, + 0x58, 0x5a, 0xb6, 0x3c, 0x68, 0x94, 0xe4, 0x56, 0x59, 0x37, 0xcc, 0xf8, + 0xa4, 0xec, 0x92, 0x6c, 0x18, 0xf3, 0x86, 0x3f, 0x2e, 0xb9, 0xb8, 0x86, + 0xd8, 0x70, 0x03, 0xe2, 0x16, 0xeb, 0xe4, 0xf6, 0x18, 0xfa, 0x0b, 0x11, + 0xeb, 0x8b, 0x21, 0xc6, 0x9e, 0x4e, 0x8b, 0x75, 0x3f, 0xe7, 0xed, 0x92, + 0x8d, 0x0f, 0xcc, 0x7b, 0xb7, 0x6d, 0x5e, 0xfb, 0xf8, 0x7b, 0x18, 0xdf, + 0x25, 0x17, 0x41, 0x47, 0x38, 0x39, 0x26, 0x25, 0xf0, 0x10, 0x39, 0xd5, + 0x6a, 0x5d, 0x00, 0x3f, 0x3a, 0xf8, 0x2f, 0x56, 0x59, 0x0b, 0x84, 0xa4, + 0x6a, 0xe0, 0x9e, 0xdb, 0x6a, 0xd5, 0x10, 0x46, 0xf5, 0x55, 0xd2, 0x1c, + 0x95, 0x49, 0x77, 0x48, 0xec, 0x06, 0xe5, 0x60, 0xc2, 0xeb, 0xfe, 0xac, + 0x2b, 0x7b, 0x86, 0x39, 0x13, 0x16, 0xb1, 0xfa, 0xe7, 0x5d, 0x19, 0xe4, + 0x3e, 0x7d, 0xf5, 0x62, 0x57, 0x16, 0x7a, 0x0f, 0xad, 0xfe, 0xe7, 0x2e, + 0xe7, 0x34, 0xe9, 0x0a, 0x21, 0xf7, 0xdd, 0x22, 0x45, 0xa3, 0x25, 0xdf, + 0x44, 0x8d, 0x50, 0x1c, 0x46, 0x2e, 0x83, 0x17, 0xe8, 0xa0, 0xbb, 0x60, + 0x48, 0xb4, 0x3b, 0xfd, 0x7d, 0xd0, 0x37, 0x06, 0xd9, 0xec, 0xc2, 0x9c, + 0x10, 0xc6, 0x87, 0xf0, 0xbf, 0x7d, 0xfc, 0x8d, 0x2e, 0xe4, 0x05, 0xc4, + 0x60, 0x89, 0x66, 0xc6, 0x7a, 0xb0, 0xfe, 0xf7, 0x30, 0x8e, 0x09, 0xc9, + 0xcd, 0xf1, 0x27, 0xbc, 0xf1, 0xb7, 0x41, 0x0b, 0x9f, 0x63, 0x8d, 0x22, + 0xd1, 0xb9, 0x31, 0x03, 0x34, 0x70, 0x6e, 0x4c, 0xcd, 0x75, 0xce, 0xd0, + 0x06, 0x0c, 0xa7, 0x66, 0xdd, 0x2c, 0xd9, 0xe5, 0x7e, 0x99, 0x5c, 0xee, + 0x93, 0x03, 0xcb, 0xe6, 0x4c, 0x95, 0xd8, 0x0f, 0x3c, 0x0b, 0xea, 0x30, + 0x7d, 0x55, 0x20, 0x01, 0x33, 0x7e, 0x44, 0x06, 0xe3, 0x5f, 0x92, 0x5f, + 0xb6, 0x90, 0xef, 0x91, 0xeb, 0x7b, 0x24, 0xac, 0xd6, 0x89, 0x07, 0x7b, + 0xd2, 0x46, 0xb7, 0xed, 0xeb, 0x9c, 0xb9, 0xd6, 0xba, 0x70, 0xfe, 0xd5, + 0xf8, 0x55, 0xeb, 0xfe, 0x85, 0xbf, 0xae, 0x81, 0x75, 0x07, 0xb0, 0x26, + 0x79, 0x34, 0xbb, 0x26, 0x4e, 0x8b, 0xdd, 0x09, 0xfa, 0x9c, 0xe4, 0x8d, + 0xc0, 0x86, 0xfd, 0x72, 0x62, 0x99, 0xf1, 0x42, 0xfa, 0xf1, 0x19, 0x8d, + 0x48, 0x72, 0xf8, 0x1c, 0xea, 0xae, 0x09, 0xb5, 0x86, 0x57, 0x93, 0xe9, + 0xab, 0x29, 0xd4, 0xc4, 0x3f, 0x05, 0x3d, 0xac, 0x15, 0xc8, 0x73, 0x18, + 0xfc, 0xa6, 0x50, 0x8b, 0x11, 0x47, 0xb5, 0x1e, 0xcf, 0xa4, 0xf0, 0xfd, + 0x5c, 0xa2, 0x2b, 0x8b, 0x98, 0x08, 0xff, 0xbe, 0x39, 0xa4, 0x72, 0x18, + 0xf5, 0x32, 0xda, 0x45, 0x3c, 0x83, 0xe7, 0xa1, 0x27, 0xca, 0x68, 0xbc, + 0xcb, 0xa9, 0x50, 0x46, 0x02, 0x7a, 0x2c, 0xd8, 0x64, 0x58, 0x61, 0x29, + 0x7d, 0xd5, 0xc6, 0xbc, 0xb7, 0x42, 0xac, 0x77, 0x33, 0x16, 0xbf, 0x23, + 0xe6, 0xac, 0x4e, 0x61, 0x2e, 0xbf, 0xdf, 0x85, 0x75, 0x07, 0x87, 0x8b, + 0xd2, 0x31, 0x7c, 0x18, 0xf1, 0x4e, 0x1f, 0x1b, 0x01, 0x6d, 0xb4, 0xf3, + 0x16, 0xb0, 0xc0, 0x6f, 0x81, 0x1f, 0xf8, 0x46, 0xd2, 0x92, 0xf9, 0x25, + 0xca, 0x55, 0x3e, 0x0e, 0x1e, 0xc0, 0x7f, 0x12, 0x71, 0x8d, 0x3c, 0x70, + 0x6f, 0x41, 0x8e, 0xbe, 0x5b, 0xf2, 0x4b, 0x51, 0x55, 0xeb, 0xdb, 0x06, + 0xf7, 0xd7, 0x34, 0x3d, 0xdd, 0x0d, 0x1d, 0x93, 0xb7, 0x1c, 0x68, 0x7b, + 0x0c, 0x79, 0x80, 0xbc, 0x91, 0x2f, 0xfa, 0xca, 0x28, 0xfc, 0x84, 0xf4, + 0xfb, 0xb6, 0xa7, 0xad, 0x23, 0xa6, 0xa8, 0x38, 0x98, 0xca, 0x20, 0xb0, + 0xbd, 0xd4, 0x1c, 0x97, 0x3f, 0x6e, 0x8e, 0xc9, 0x77, 0x9b, 0x29, 0xe4, + 0xc0, 0x51, 0xe4, 0xc0, 0x61, 0xe4, 0x40, 0x0b, 0x39, 0x30, 0x81, 0x1c, + 0x38, 0x80, 0x1c, 0x18, 0x47, 0x9c, 0x14, 0x39, 0xa1, 0xf2, 0x6d, 0x2c, + 0x0a, 0xcc, 0x1d, 0xb5, 0x9b, 0x0e, 0x78, 0x99, 0xc1, 0x5e, 0xb3, 0xe0, + 0xeb, 0x50, 0xd7, 0x44, 0x65, 0x1c, 0x31, 0xd7, 0x42, 0x3c, 0x4a, 0x20, + 0xdf, 0x8c, 0x01, 0x6b, 0x89, 0x6c, 0x2c, 0x25, 0x10, 0x13, 0x5b, 0xe2, + 0x00, 0x13, 0x97, 0x8c, 0x14, 0x9e, 0xdd, 0xab, 0xec, 0x33, 0x94, 0xbe, + 0x3b, 0x2c, 0xdd, 0xa3, 0x92, 0x2f, 0x9f, 0xc4, 0x58, 0x1c, 0xeb, 0x75, + 0x21, 0x2f, 0x31, 0x2e, 0x30, 0x06, 0x2c, 0x39, 0xbf, 0x6b, 0xd1, 0xd7, + 0xba, 0xb5, 0xcc, 0xe9, 0x82, 0x30, 0x96, 0x23, 0x0f, 0xc0, 0x1e, 0x38, + 0x36, 0x89, 0xe7, 0xf8, 0xfd, 0x2f, 0xfd, 0x98, 0xf9, 0xb1, 0x4e, 0x81, + 0xd1, 0xbe, 0xc4, 0x9c, 0x67, 0x61, 0x3d, 0xb7, 0xdd, 0x4f, 0x9f, 0x47, + 0xad, 0x14, 0xdc, 0x27, 0xae, 0x66, 0x3f, 0xe1, 0x24, 0x68, 0x1e, 0x04, + 0xbe, 0x47, 0x6d, 0x75, 0xb0, 0x8a, 0xef, 0xed, 0xf3, 0x5d, 0xcc, 0x57, + 0x63, 0x51, 0x23, 0x6d, 0xb1, 0x9e, 0x43, 0xac, 0x3c, 0x86, 0xb8, 0x68, + 0x3b, 0xfa, 0x5a, 0x03, 0x7c, 0x42, 0x8e, 0x65, 0xdb, 0x09, 0x0f, 0xbd, + 0xd6, 0x7a, 0xd6, 0x1a, 0x96, 0x89, 0xb5, 0x31, 0xc9, 0xae, 0x0d, 0xc6, + 0xcf, 0x4b, 0xd7, 0x65, 0x5b, 0x5e, 0x6b, 0x95, 0x5c, 0xf3, 0xa4, 0x0d, + 0xbb, 0xdc, 0xb7, 0xdf, 0x90, 0x1a, 0x30, 0xdc, 0xbe, 0xfd, 0x9d, 0xac, + 0xe9, 0x5f, 0x14, 0x3d, 0x21, 0x99, 0x45, 0x5b, 0xc6, 0xf6, 0x07, 0xb5, + 0xe7, 0x2f, 0x3b, 0xa4, 0x1b, 0x63, 0x6b, 0x09, 0xcc, 0x61, 0xdd, 0xaf, + 0xfa, 0x27, 0xe0, 0x59, 0xf3, 0x9e, 0x51, 0x39, 0x8f, 0x98, 0x19, 0xbc, + 0x37, 0x6d, 0xe7, 0xfc, 0x22, 0x70, 0x0d, 0xe4, 0x99, 0x59, 0x24, 0xee, + 0xda, 0x05, 0x39, 0x45, 0x60, 0x23, 0xd4, 0xfd, 0x20, 0x9e, 0x6d, 0xc9, + 0x57, 0x53, 0xb4, 0x87, 0xc7, 0x20, 0x4b, 0xac, 0x15, 0x0e, 0xf8, 0xf9, + 0x9a, 0xcc, 0x2d, 0x51, 0x7e, 0x71, 0xd4, 0x96, 0xdc, 0x5b, 0xa2, 0x5d, + 0xe9, 0xab, 0xeb, 0x46, 0xdb, 0xd9, 0x58, 0xc4, 0xfa, 0x43, 0xc4, 0xd8, + 0x88, 0xd5, 0x65, 0xf6, 0x06, 0x58, 0x53, 0x1d, 0x80, 0x4e, 0xa6, 0x15, + 0xe6, 0xce, 0xd4, 0x53, 0x62, 0x9d, 0x62, 0xac, 0x92, 0x44, 0xc8, 0x22, + 0xbe, 0x17, 0x43, 0x4f, 0xcf, 0xe2, 0x1e, 0xe5, 0xc9, 0x5a, 0x1f, 0xf7, + 0x57, 0xff, 0xa3, 0xd2, 0x49, 0x08, 0xba, 0xcb, 0xef, 0x67, 0x11, 0x22, + 0x4b, 0xa1, 0x34, 0x62, 0xe0, 0x18, 0x79, 0x50, 0x7b, 0xa3, 0x9e, 0xa4, + 0xdf, 0x81, 0x67, 0xd8, 0x46, 0x5b, 0x5d, 0xa9, 0xfe, 0x4a, 0x95, 0x08, + 0x6c, 0x59, 0x0a, 0x91, 0x34, 0x78, 0x1a, 0xc3, 0x77, 0x38, 0xff, 0x09, + 0xe8, 0xf3, 0x2c, 0x9e, 0x5f, 0x00, 0x5f, 0x1b, 0x65, 0xd2, 0x9d, 0x4c, + 0x1c, 0x57, 0xbe, 0x8b, 0x6b, 0x97, 0xb5, 0xcc, 0xd7, 0xe4, 0xbc, 0xe2, + 0xef, 0x13, 0xac, 0x9d, 0xa1, 0xa7, 0xeb, 0xe1, 0x6f, 0xf2, 0x3a, 0xf9, + 0xf3, 0xd6, 0x67, 0xce, 0xca, 0x58, 0x09, 0xc9, 0x96, 0x5f, 0x6a, 0x85, + 0x2d, 0x2b, 0x3e, 0xef, 0xeb, 0x31, 0xeb, 0x46, 0x41, 0x07, 0xfb, 0x00, + 0xfb, 0x95, 0x2e, 0x41, 0x07, 0x6d, 0xa7, 0x10, 0x4d, 0x3f, 0x2e, 0x2b, + 0x4b, 0xff, 0x54, 0x6a, 0x4b, 0x05, 0xa9, 0x2f, 0xfd, 0x23, 0x39, 0xb7, + 0xd4, 0x92, 0x0b, 0x29, 0x15, 0x93, 0xac, 0x0e, 0xe5, 0xcf, 0x72, 0xa3, + 0x87, 0x07, 0x93, 0xe3, 0x97, 0x20, 0xc0, 0x95, 0xaa, 0x47, 0xfb, 0x54, + 0x1b, 0xed, 0x17, 0x60, 0x6b, 0xaf, 0x58, 0xa4, 0x7f, 0x4c, 0x6a, 0x65, + 0xd2, 0xfe, 0xa0, 0xa2, 0xfd, 0xc0, 0x26, 0xed, 0x92, 0x0b, 0x59, 0xa4, + 0x7f, 0x27, 0xda, 0x81, 0xf3, 0xfb, 0x49, 0x7f, 0x02, 0xcf, 0x7e, 0xd0, + 0xfe, 0x6a, 0xee, 0x6b, 0xad, 0x8d, 0x72, 0x44, 0xd1, 0x1c, 0x4a, 0x8f, + 0x41, 0x3e, 0xaf, 0xb5, 0xd6, 0x5d, 0xfa, 0x11, 0xbe, 0xbb, 0xf7, 0x20, + 0x46, 0xf5, 0x61, 0xaf, 0x5e, 0xc9, 0xcf, 0x46, 0x11, 0x27, 0xc7, 0xa1, + 0xdb, 0x2e, 0xe5, 0x87, 0x08, 0x17, 0xd0, 0xd9, 0x34, 0xe6, 0x1f, 0xa2, + 0xbf, 0x29, 0xb9, 0x38, 0x90, 0x4b, 0xb1, 0x9c, 0x8e, 0xa0, 0xfe, 0xc7, + 0x3e, 0x86, 0x93, 0x73, 0xf9, 0xcc, 0x00, 0x62, 0x1a, 0xff, 0x7f, 0x64, + 0x7b, 0x28, 0x20, 0xd6, 0x42, 0xe7, 0x3d, 0x90, 0x1f, 0xe8, 0x18, 0x9b, + 0x41, 0x6e, 0x4d, 0x0e, 0xd7, 0x54, 0x7f, 0x91, 0x71, 0xe5, 0x28, 0xf2, + 0xe9, 0x21, 0x7c, 0xbc, 0xfd, 0x26, 0x9a, 0xdc, 0x73, 0x3b, 0x4f, 0x45, + 0x77, 0x7d, 0x2f, 0x01, 0x52, 0xa6, 0xc9, 0x7d, 0x0b, 0x12, 0x4a, 0x87, + 0xb0, 0x2f, 0xc7, 0x7a, 0x10, 0x63, 0x06, 0xa2, 0xd9, 0xe6, 0xcf, 0x31, + 0x4e, 0x5f, 0x66, 0x7c, 0x0f, 0x68, 0x1f, 0xc5, 0x9a, 0x8c, 0xbb, 0x63, + 0xe0, 0x99, 0x35, 0x26, 0xe3, 0x26, 0xf2, 0x48, 0xe3, 0x47, 0xcc, 0x2d, + 0xf8, 0x3e, 0xe0, 0x7f, 0xe7, 0x7d, 0x89, 0xde, 0x9c, 0x36, 0xab, 0x05, + 0x31, 0xb1, 0x27, 0x74, 0x6e, 0xc5, 0xa5, 0xd8, 0x30, 0x5f, 0x20, 0x66, + 0xd4, 0x29, 0x83, 0x35, 0xca, 0x89, 0xfd, 0x27, 0xd4, 0x7f, 0xb5, 0xe7, + 0x21, 0x8f, 0xa8, 0xec, 0xb5, 0x0e, 0x22, 0xa6, 0x80, 0xfe, 0xca, 0x18, + 0x78, 0x63, 0x8f, 0x66, 0x10, 0xf9, 0x2b, 0x04, 0x21, 0xa0, 0x96, 0x5a, + 0x0b, 0xc9, 0xbd, 0xe1, 0x11, 0xa3, 0x28, 0x8f, 0x46, 0x58, 0x36, 0x17, + 0xd6, 0x98, 0x07, 0xc2, 0xb2, 0xb0, 0x26, 0x72, 0x69, 0x91, 0x71, 0x45, + 0xfd, 0x41, 0xe6, 0x86, 0x33, 0x8f, 0x3c, 0x5b, 0x5a, 0x62, 0x8c, 0x61, + 0x9c, 0xb8, 0x01, 0xba, 0x48, 0x7e, 0xe3, 0xab, 0xc8, 0x49, 0xa5, 0xf2, + 0x20, 0x62, 0xa6, 0xac, 0xeb, 0x90, 0x29, 0x72, 0x19, 0x6b, 0xd4, 0x1d, + 0xfa, 0x32, 0x41, 0x4f, 0x26, 0x2a, 0xc5, 0x45, 0xf6, 0x63, 0xa2, 0xa0, + 0x85, 0x35, 0x76, 0x48, 0xd5, 0x3f, 0x37, 0xa8, 0xd8, 0xca, 0xff, 0xe1, + 0xb6, 0x7d, 0x93, 0x27, 0xf7, 0xe9, 0x8c, 0x63, 0x37, 0x8b, 0x3d, 0x63, + 0x77, 0x1d, 0xa8, 0x74, 0x48, 0xb5, 0x8f, 0x76, 0x49, 0xfd, 0xbf, 0xa0, + 0x62, 0xed, 0x02, 0x78, 0x2a, 0x2e, 0x12, 0xe3, 0x86, 0x31, 0x2f, 0xe6, + 0xcf, 0xa3, 0x5c, 0xff, 0x89, 0xcc, 0xed, 0x7f, 0x17, 0x74, 0x79, 0x71, + 0x2d, 0xbf, 0x1f, 0xf1, 0x76, 0x46, 0x97, 0x3b, 0xef, 0x1a, 0xc7, 0xb3, + 0xcc, 0x81, 0xef, 0xf8, 0x78, 0x92, 0x63, 0xec, 0x61, 0x81, 0xbe, 0x15, + 0x03, 0xff, 0xfb, 0xa4, 0xb0, 0x12, 0x85, 0x1c, 0x90, 0x4b, 0x6b, 0xde, + 0x5a, 0xac, 0x77, 0x4f, 0x42, 0x47, 0xfa, 0xa9, 0xa8, 0x44, 0x4e, 0xf5, + 0x49, 0xf8, 0xeb, 0xdd, 0xd2, 0xf1, 0xf5, 0x21, 0x09, 0x7d, 0xdd, 0x64, + 0x4e, 0x4f, 0x9c, 0x80, 0xbe, 0xe6, 0x65, 0x5c, 0x9e, 0x44, 0xde, 0x62, + 0x5e, 0x57, 0x76, 0x6a, 0xf4, 0x4b, 0x08, 0x05, 0xab, 0xfe, 0x8c, 0x2d, + 0x8f, 0xee, 0xff, 0x85, 0xea, 0x33, 0x01, 0xc3, 0x8b, 0xfe, 0xfc, 0x94, + 0xd8, 0xcd, 0x77, 0x21, 0x6b, 0xc3, 0x79, 0xed, 0xd6, 0xa0, 0xa6, 0x1c, + 0x56, 0xfd, 0xc2, 0x47, 0xf7, 0x7b, 0x35, 0x25, 0xf0, 0xb8, 0xe6, 0xa8, + 0x9a, 0x12, 0xf1, 0x35, 0xcc, 0x79, 0xfd, 0xa2, 0x63, 0xaf, 0xbc, 0x0c, + 0x42, 0x4f, 0xb7, 0x88, 0x7d, 0x08, 0x7e, 0xf1, 0x9c, 0x2c, 0xe9, 0x69, + 0x4d, 0xad, 0x19, 0x7a, 0x86, 0x71, 0x8a, 0xf1, 0x8b, 0x36, 0x9e, 0x4c, + 0x14, 0x61, 0x7f, 0xa1, 0xe7, 0x19, 0xa3, 0x3c, 0xdb, 0x9e, 0x68, 0x8b, + 0x75, 0x0b, 0x95, 0x7b, 0xa0, 0x43, 0xd4, 0xf2, 0x16, 0xe2, 0x9c, 0x81, + 0x5c, 0x6e, 0xf1, 0xda, 0xeb, 0xe1, 0xe5, 0x63, 0x31, 0x75, 0x5d, 0xac, + 0x7a, 0x18, 0xdc, 0x5b, 0x9f, 0x75, 0x07, 0x62, 0x4c, 0x93, 0x74, 0x70, + 0xdf, 0x01, 0x09, 0x3d, 0x17, 0x93, 0xf0, 0x73, 0xb4, 0x3f, 0x33, 0xe1, + 0x40, 0x7e, 0x0b, 0x16, 0x31, 0xd0, 0x0a, 0xb0, 0xc5, 0xcd, 0xa2, 0xaf, + 0x0c, 0xc0, 0x77, 0xcc, 0x78, 0x55, 0x92, 0x12, 0xaa, 0x45, 0xe5, 0xad, + 0x45, 0x33, 0x41, 0x7b, 0x39, 0x6b, 0x61, 0xbc, 0xd9, 0x75, 0x79, 0x5d, + 0x51, 0xc1, 0xb1, 0x2f, 0x87, 0x80, 0x19, 0x86, 0x6d, 0xbd, 0x47, 0x5e, + 0x87, 0xbe, 0x73, 0x6a, 0xec, 0x66, 0xac, 0x0b, 0x1a, 0x9e, 0x33, 0xc1, + 0x03, 0xd7, 0xfd, 0x1e, 0xd6, 0x54, 0xf8, 0xca, 0xd9, 0x60, 0x4d, 0xba, + 0x48, 0xdb, 0xed, 0x83, 0xdd, 0xe1, 0xba, 0xd9, 0x21, 0xb9, 0xd9, 0x84, + 0xe8, 0x8b, 0x9f, 0x91, 0xc1, 0xfd, 0xba, 0xc7, 0x8f, 0xe2, 0x91, 0x63, + 0xec, 0xc7, 0xdd, 0xae, 0xfc, 0x51, 0x5f, 0x83, 0xcd, 0x3c, 0x48, 0x1d, + 0x23, 0xf7, 0x23, 0x8f, 0x31, 0x8e, 0x85, 0x90, 0xc7, 0xb2, 0x4d, 0x4f, + 0xef, 0xd5, 0x07, 0xfb, 0xe5, 0xc9, 0xe7, 0x68, 0x4f, 0xb8, 0xb7, 0x69, + 0x53, 0x41, 0x0f, 0x98, 0xf7, 0x2c, 0x39, 0xf9, 0x6c, 0x50, 0x73, 0xb0, + 0xbe, 0x32, 0xe3, 0x07, 0xc0, 0x8f, 0x7e, 0x27, 0xe3, 0x81, 0xae, 0x6c, + 0x37, 0x6f, 0x59, 0x5e, 0xdd, 0x51, 0x49, 0xb0, 0x2f, 0x6e, 0xb0, 0x4e, + 0xb3, 0xe3, 0x9e, 0xbc, 0x8b, 0x18, 0x2b, 0x35, 0x67, 0x11, 0xa3, 0x23, + 0x72, 0x71, 0xd6, 0x86, 0xee, 0x3f, 0x0b, 0xba, 0x0e, 0x75, 0x11, 0x23, + 0x5f, 0x9c, 0x75, 0x70, 0x7d, 0x48, 0xd5, 0x66, 0xa1, 0x3b, 0x61, 0xc7, + 0xcd, 0x7e, 0xfa, 0x91, 0xaf, 0xa7, 0x84, 0x56, 0x5c, 0x32, 0xb5, 0x12, + 0x62, 0xf6, 0x64, 0x8a, 0x39, 0xbe, 0x53, 0xf5, 0x4d, 0xd9, 0xaf, 0xc9, + 0x2b, 0xbc, 0xb0, 0x4f, 0x2b, 0x56, 0x19, 0xe7, 0x0b, 0xf1, 0x0e, 0x21, + 0x0e, 0x11, 0xad, 0x66, 0x51, 0x27, 0x9a, 0x9c, 0x57, 0xbd, 0x58, 0x11, + 0xc7, 0x3d, 0x42, 0x19, 0x68, 0xf5, 0xea, 0x3e, 0xad, 0x50, 0x0d, 0xc9, + 0xc5, 0x18, 0xe9, 0x4e, 0xa8, 0xfa, 0x7d, 0xbf, 0xb2, 0xb5, 0x1e, 0xe4, + 0x12, 0xd8, 0x4c, 0xea, 0x93, 0xd8, 0x57, 0x8d, 0xc1, 0xa6, 0xa8, 0x7b, + 0xea, 0x5d, 0xc5, 0x48, 0x5f, 0xf7, 0x3b, 0xe5, 0x4c, 0xd0, 0x51, 0x26, + 0x7e, 0xef, 0xf4, 0xf1, 0xfb, 0xa2, 0x5f, 0x0f, 0x3d, 0x26, 0xac, 0x53, + 0x16, 0x2a, 0xa4, 0x05, 0xf1, 0xd6, 0xdd, 0xc9, 0x96, 0x28, 0x47, 0x2f, + 0xa6, 0x1c, 0x45, 0x1d, 0xa3, 0xaf, 0x19, 0xbe, 0x0d, 0xf0, 0x6f, 0x14, + 0xf7, 0xbc, 0x5a, 0xaa, 0xd8, 0x8c, 0xc0, 0xdf, 0xa7, 0x21, 0x23, 0xea, + 0x06, 0xfa, 0x5b, 0xe3, 0x99, 0x0a, 0xf4, 0xb7, 0xf6, 0xf2, 0xfb, 0x76, + 0x1f, 0x63, 0xde, 0xb0, 0x3c, 0x89, 0xf1, 0x13, 0x67, 0x48, 0xcf, 0xb8, + 0x8f, 0xc7, 0x12, 0x90, 0x09, 0x63, 0xfc, 0xa8, 0xbc, 0xd5, 0x70, 0x14, + 0xfe, 0xdb, 0xb7, 0x7f, 0x46, 0xe6, 0xdd, 0x59, 0xe0, 0x3f, 0xc8, 0xdf, + 0x48, 0xc0, 0x3f, 0xe3, 0x2a, 0x3e, 0x1e, 0xfe, 0x68, 0x35, 0x49, 0xd8, + 0xcb, 0xd9, 0xf7, 0x5e, 0x67, 0xce, 0xde, 0x0d, 0xfc, 0xf5, 0x91, 0xd6, + 0x0f, 0x79, 0xeb, 0xff, 0x17, 0xe8, 0xea, 0x73, 0xd8, 0x23, 0x0a, 0xfa, + 0xfa, 0x29, 0xd3, 0x0f, 0x7b, 0x4e, 0xf7, 0x9e, 0xbb, 0xff, 0x3a, 0xe9, + 0x32, 0xa4, 0x01, 0x8c, 0x50, 0x50, 0x79, 0x94, 0xb5, 0x62, 0xc4, 0xd7, + 0xdf, 0x31, 0x60, 0x67, 0xae, 0x1b, 0xc4, 0xde, 0x4e, 0x29, 0xf4, 0x05, + 0xf5, 0x27, 0x62, 0xf6, 0xe6, 0x78, 0x50, 0xcf, 0xf2, 0xf9, 0x94, 0x93, + 0x2f, 0xb3, 0x4f, 0xc8, 0x5c, 0xc0, 0x31, 0x65, 0x87, 0x1f, 0x42, 0xb7, + 0x09, 0xcf, 0x20, 0xdd, 0xf7, 0x29, 0xba, 0x1d, 0x45, 0x37, 0xfd, 0x8b, + 0x67, 0x3a, 0xec, 0xa3, 0x05, 0x7d, 0x33, 0xae, 0x07, 0x4c, 0x00, 0x7d, + 0x7f, 0x17, 0x3a, 0xfe, 0x4e, 0x05, 0x98, 0xa0, 0x02, 0x4c, 0x80, 0x3d, + 0xbe, 0x0d, 0x1d, 0x7f, 0xab, 0x02, 0x4c, 0x50, 0x89, 0xfb, 0x3d, 0x0a, + 0x9b, 0x98, 0xfe, 0x23, 0xda, 0x6e, 0xd0, 0x93, 0xb9, 0xda, 0x2e, 0x39, + 0xce, 0xf9, 0x01, 0x36, 0x8e, 0xc2, 0x8e, 0x78, 0x6e, 0x11, 0xf4, 0x3b, + 0xfc, 0x1c, 0xd1, 0xe0, 0xb9, 0x00, 0x72, 0x44, 0x83, 0xe7, 0x18, 0x23, + 0xf1, 0x10, 0x30, 0x61, 0x48, 0xe2, 0xc2, 0x5e, 0xef, 0xdc, 0x18, 0xd6, + 0x1a, 0x1d, 0x84, 0x27, 0x75, 0xa8, 0xbe, 0xd6, 0x71, 0xd5, 0x6f, 0x40, + 0x5c, 0xa8, 0x06, 0xb5, 0x5b, 0x52, 0x26, 0x96, 0x88, 0x33, 0x65, 0xaf, + 0x9e, 0x86, 0x0e, 0x5c, 0x62, 0xc3, 0xcd, 0xbe, 0xf4, 0x70, 0x1d, 0x7b, + 0x16, 0x2d, 0x8f, 0xbe, 0xe3, 0xee, 0xd6, 0x33, 0x07, 0x10, 0x9f, 0xa7, + 0xca, 0x09, 0x99, 0x2c, 0x7b, 0x98, 0x00, 0xf5, 0xcf, 0x55, 0xfd, 0x51, + 0x9b, 0x7a, 0x80, 0xfe, 0x36, 0x6d, 0x23, 0x71, 0x3e, 0x45, 0x19, 0x53, + 0xff, 0xd3, 0xaa, 0x67, 0x7d, 0xa0, 0xee, 0xf5, 0xe5, 0x27, 0x95, 0x2d, + 0x84, 0x19, 0x67, 0xa8, 0x3f, 0xcf, 0x87, 0x61, 0x17, 0x79, 0x37, 0x90, + 0x4b, 0x3b, 0x1e, 0xf9, 0xbc, 0x26, 0xd6, 0x4e, 0xe3, 0xb9, 0xb6, 0xf1, + 0xcd, 0xfb, 0x3e, 0xbd, 0x88, 0x7d, 0x9b, 0x3d, 0x06, 0xc6, 0xa9, 0xad, + 0xf1, 0x10, 0xea, 0x87, 0xb0, 0xba, 0x8f, 0x18, 0xde, 0x88, 0x49, 0xb6, + 0x61, 0x89, 0x53, 0xe5, 0x3c, 0xf6, 0x2d, 0x18, 0x8f, 0x9e, 0x90, 0xec, + 0x52, 0xaf, 0xe4, 0x62, 0x66, 0xca, 0x96, 0xbf, 0x27, 0x1b, 0xcb, 0x85, + 0x04, 0xcf, 0x0d, 0x0b, 0x33, 0x1a, 0x9e, 0x7b, 0x18, 0xd7, 0xa4, 0xd9, + 0x92, 0xc3, 0x65, 0xe6, 0x9d, 0x91, 0x78, 0x03, 0xf7, 0x72, 0xb3, 0xec, + 0xd5, 0x54, 0x61, 0x93, 0x66, 0xa2, 0x8a, 0x78, 0xf0, 0x72, 0x99, 0xfb, + 0x01, 0x1b, 0x95, 0xd9, 0xcf, 0x09, 0xee, 0x3f, 0x01, 0x1c, 0x88, 0x58, + 0x1d, 0xf3, 0xe7, 0x28, 0x5e, 0x6d, 0x23, 0x2c, 0x81, 0xae, 0x3b, 0x65, + 0xdd, 0x8f, 0xbb, 0xb5, 0xb2, 0xd7, 0x47, 0x39, 0x4b, 0x7a, 0xdc, 0xff, + 0xd5, 0x5a, 0x8f, 0xa1, 0x16, 0xda, 0xe4, 0xf5, 0x8f, 0xb9, 0x8f, 0x81, + 0xb0, 0x2b, 0x27, 0xdc, 0x40, 0x26, 0xbc, 0xcf, 0x31, 0x9e, 0x8d, 0xb6, + 0x5a, 0x67, 0xad, 0xf6, 0x9e, 0xdf, 0xf5, 0xf4, 0xcc, 0xde, 0xb8, 0x2d, + 0x63, 0xbd, 0xe6, 0xa0, 0x26, 0xf6, 0x7b, 0x66, 0x87, 0x46, 0xbc, 0x9e, + 0xd9, 0xfc, 0xc8, 0xf6, 0x9e, 0xd9, 0xcf, 0x6f, 0xf3, 0x7a, 0x66, 0x17, + 0x9d, 0x22, 0x3e, 0x5e, 0xcf, 0x6c, 0xf8, 0x76, 0xaf, 0x67, 0xf6, 0xf0, + 0xed, 0x5e, 0xcf, 0xec, 0x91, 0x11, 0xaf, 0x67, 0xf6, 0xfb, 0xb7, 0x6f, + 0xef, 0x99, 0x3d, 0x36, 0xb2, 0xbd, 0x67, 0x26, 0x13, 0xc8, 0x77, 0x13, + 0x5b, 0x3d, 0xb3, 0xf2, 0xc8, 0xb5, 0x7b, 0x66, 0xaf, 0x06, 0x78, 0x1d, + 0xfc, 0x8c, 0x81, 0x87, 0x14, 0xf0, 0xfa, 0x28, 0xf0, 0xfa, 0xaf, 0xeb, + 0x59, 0x87, 0xc1, 0xe7, 0xcd, 0x7e, 0x5e, 0xb8, 0x1e, 0xdc, 0x7e, 0xbb, + 0xff, 0x8c, 0xa0, 0xde, 0x4d, 0xf8, 0xb5, 0x0a, 0xb1, 0xfb, 0x1e, 0xbf, + 0x66, 0xfb, 0x6b, 0xd1, 0xad, 0xf3, 0xec, 0xf6, 0xff, 0x37, 0xa0, 0xf4, + 0x0e, 0xf0, 0x3c, 0xf9, 0x79, 0x0d, 0xb5, 0x1f, 0xf9, 0x47, 0xa2, 0xef, + 0xbe, 0xe8, 0x7c, 0xd5, 0x22, 0xc6, 0x7f, 0x1c, 0xbe, 0x6a, 0xef, 0x0d, + 0xc9, 0x3a, 0xfc, 0x96, 0x39, 0xea, 0xa4, 0x64, 0x31, 0x3f, 0xab, 0xe6, + 0x27, 0x26, 0xb6, 0xe6, 0xa7, 0x26, 0xbe, 0xaa, 0x6a, 0x52, 0xf3, 0x5f, + 0xe3, 0xf3, 0x0d, 0x65, 0xdf, 0x96, 0x87, 0xe1, 0x9d, 0x4a, 0x80, 0xb7, + 0xc2, 0x3e, 0x76, 0x36, 0x1c, 0xdb, 0x9d, 0xc0, 0x33, 0xe6, 0x8b, 0xb6, + 0x34, 0x14, 0x7e, 0x0f, 0xa5, 0xcd, 0x17, 0x73, 0xaa, 0x5e, 0x33, 0x9c, + 0xbc, 0x1b, 0xd4, 0xdf, 0xa8, 0xa1, 0x86, 0x06, 0xd5, 0xf9, 0x9b, 0xbe, + 0x36, 0x8c, 0x3c, 0xd6, 0x5e, 0x63, 0xb3, 0xae, 0xd6, 0xfd, 0xba, 0xda, + 0x90, 0xbb, 0xf7, 0xb7, 0x63, 0x73, 0x99, 0xf8, 0x5b, 0x0a, 0x9b, 0xef, + 0x42, 0x6d, 0x4e, 0xec, 0x4d, 0x1c, 0x43, 0x0c, 0x41, 0x7c, 0xce, 0x7e, + 0x01, 0xeb, 0x19, 0xe6, 0x46, 0xd6, 0x37, 0x31, 0x7c, 0xf8, 0xbe, 0x41, + 0x80, 0xd1, 0x3b, 0xfc, 0xf8, 0xce, 0xba, 0x28, 0xc0, 0x2a, 0x77, 0x75, + 0x7b, 0xb5, 0xd1, 0x2e, 0xcd, 0xab, 0x3f, 0x13, 0xfe, 0x9c, 0xf0, 0x26, + 0x16, 0x0e, 0x6f, 0x62, 0xe1, 0x6d, 0xe7, 0x30, 0xa2, 0xde, 0x6d, 0x50, + 0xe7, 0x39, 0x3c, 0xdf, 0x11, 0x4d, 0x4f, 0xf3, 0x8c, 0x07, 0x38, 0xc7, + 0xe2, 0x99, 0x0f, 0x7d, 0xe9, 0x41, 0x2d, 0x5b, 0x37, 0x10, 0xef, 0x99, + 0x7f, 0x90, 0x6b, 0xcb, 0xc1, 0xd9, 0x62, 0xa0, 0x27, 0xca, 0x8e, 0x63, + 0x7f, 0xaa, 0xa1, 0xe6, 0x4d, 0x45, 0xac, 0x43, 0xa0, 0x65, 0x0a, 0xff, + 0x03, 0x99, 0xde, 0xa3, 0x72, 0x5f, 0x27, 0x6c, 0xf6, 0x78, 0x85, 0xd8, + 0xf5, 0x71, 0x69, 0xf8, 0xf8, 0x75, 0x65, 0xc9, 0xc3, 0xae, 0xe1, 0xed, + 0xd8, 0x35, 0xb5, 0x21, 0x1e, 0x8d, 0x07, 0x76, 0xa4, 0xd1, 0x70, 0x5e, + 0x19, 0x22, 0x66, 0x25, 0x9d, 0xcc, 0x3d, 0xd3, 0x88, 0x81, 0xcc, 0x39, + 0xcc, 0x37, 0xc4, 0xa5, 0xd7, 0xa2, 0x4f, 0x8d, 0x1d, 0xed, 0xb0, 0xa2, + 0xf8, 0xcc, 0x83, 0x8e, 0x19, 0x3c, 0x93, 0x96, 0x85, 0xd3, 0x5f, 0xd1, + 0x9c, 0xfa, 0x3c, 0xe8, 0x99, 0x42, 0xae, 0xa3, 0x2d, 0x15, 0x0c, 0xcf, + 0x8e, 0xd6, 0x11, 0xf7, 0x5d, 0xc6, 0x02, 0xd4, 0xae, 0xa8, 0x47, 0xca, + 0x8c, 0xbd, 0x3c, 0xeb, 0x0a, 0x62, 0x2e, 0xfb, 0x26, 0xa8, 0x59, 0x59, + 0xbb, 0x2e, 0x72, 0xdf, 0xed, 0xba, 0xa8, 0xb9, 0xc4, 0x5d, 0x86, 0xb3, + 0xbe, 0x46, 0xdc, 0xf8, 0x51, 0x31, 0xa4, 0xe1, 0xbc, 0x3c, 0x44, 0x1c, + 0x79, 0x3d, 0xf8, 0xd1, 0x84, 0x34, 0xcd, 0x17, 0xd6, 0xf5, 0x76, 0xfc, + 0xe8, 0x61, 0xc7, 0xcc, 0xda, 0x41, 0xac, 0xc9, 0xda, 0x8c, 0x38, 0xd1, + 0x44, 0x98, 0x1b, 0xc4, 0xb3, 0x83, 0xe0, 0xc7, 0xc3, 0x8a, 0x59, 0x60, + 0xc5, 0xbf, 0x03, 0xac, 0x58, 0x92, 0xf7, 0xa2, 0xc4, 0x8a, 0xb6, 0x8f, + 0x15, 0x1d, 0xd8, 0x71, 0x7e, 0x9b, 0x1d, 0x6b, 0xaa, 0x07, 0xc5, 0x7b, + 0x79, 0x60, 0xbd, 0xec, 0xa2, 0x79, 0x1d, 0xf8, 0x50, 0x93, 0x98, 0x3a, + 0xaf, 0x0f, 0xb7, 0xad, 0x19, 0xe0, 0xc0, 0x7d, 0x0a, 0xdf, 0xdd, 0x57, + 0xd9, 0x85, 0xda, 0x44, 0xe1, 0x3d, 0xff, 0x9c, 0x2f, 0x7c, 0xd5, 0xd9, + 0x67, 0xb8, 0xed, 0xec, 0x73, 0x0b, 0x17, 0xe2, 0x39, 0xbf, 0xc7, 0x17, + 0x81, 0xde, 0xfe, 0x07, 0x69, 0x82, 0x5f, 0xd1, 0x07, 0x34, 0xcf, 0x4f, + 0xb6, 0xe1, 0xc3, 0xff, 0x7a, 0x15, 0x3e, 0x44, 0xce, 0x5a, 0x89, 0x49, + 0x06, 0xd8, 0xd0, 0x5e, 0xe3, 0x5a, 0xf4, 0xe5, 0x51, 0xe9, 0x00, 0x7f, + 0x9d, 0x8b, 0x7d, 0xc0, 0x44, 0xdd, 0x12, 0x05, 0x36, 0x8a, 0x28, 0x6c, + 0x34, 0x44, 0x0c, 0x33, 0x7c, 0x18, 0x98, 0xa6, 0xb1, 0x89, 0x8f, 0xcc, + 0xd4, 0x0f, 0xa0, 0x97, 0x87, 0x95, 0xad, 0x8c, 0xcb, 0x53, 0x88, 0x9d, + 0x1d, 0x6b, 0xc0, 0x75, 0x2b, 0x1e, 0x6e, 0x8a, 0x5c, 0x85, 0x9b, 0x8e, + 0xec, 0x88, 0x9b, 0x54, 0xbf, 0x7e, 0x9c, 0x32, 0x79, 0xdd, 0xf5, 0xfa, + 0xf5, 0x97, 0x5c, 0xaf, 0x5f, 0xff, 0xba, 0xdb, 0xde, 0xaf, 0xbf, 0x49, + 0x8a, 0x86, 0x69, 0x5f, 0x94, 0xab, 0xfa, 0xf5, 0x33, 0xec, 0x7f, 0x57, + 0xbb, 0xbc, 0xbe, 0x7c, 0xb7, 0xdf, 0xaf, 0x37, 0xa5, 0xb8, 0x6d, 0xdc, + 0x90, 0xb7, 0xad, 0xa0, 0x5f, 0xff, 0x2f, 0x30, 0xd6, 0x83, 0x3d, 0xb6, + 0xf7, 0xea, 0x2f, 0xb9, 0xec, 0xd5, 0xc7, 0x38, 0xcf, 0xef, 0xd5, 0x73, + 0x1e, 0x6a, 0x78, 0x97, 0x7d, 0xfa, 0x9b, 0x21, 0x8b, 0x7e, 0xc8, 0xa1, + 0x4f, 0x3a, 0x9e, 0x8b, 0x73, 0x8e, 0xea, 0xcf, 0x5f, 0x74, 0x63, 0x78, + 0xce, 0xeb, 0xa3, 0x1f, 0x86, 0x5d, 0x1d, 0xd9, 0xec, 0xcf, 0x7b, 0x7b, + 0xbc, 0xe1, 0x6e, 0x5f, 0x7f, 0xfb, 0x3a, 0x03, 0xfe, 0x3a, 0x31, 0xac, + 0x13, 0xbf, 0x6a, 0x9d, 0xad, 0x7e, 0xfc, 0x1b, 0xae, 0xd7, 0x8b, 0x77, + 0x4e, 0x8b, 0xdd, 0x81, 0x98, 0xfc, 0xe2, 0xd0, 0x8d, 0xfe, 0x1a, 0x9b, + 0xbd, 0x78, 0xc6, 0x0e, 0xe0, 0x75, 0xc6, 0x0f, 0x3e, 0xff, 0xff, 0xbe, + 0x17, 0xcf, 0x3e, 0xbc, 0x77, 0x9e, 0x42, 0xff, 0x04, 0x2e, 0x7f, 0xd6, + 0xeb, 0xc1, 0x4f, 0x54, 0x82, 0xde, 0x3a, 0xeb, 0xc6, 0xe0, 0xbd, 0x8c, + 0xc1, 0xc4, 0x71, 0xa1, 0xad, 0x90, 0x3e, 0xae, 0xdb, 0x23, 0x73, 0x0a, + 0x17, 0xc1, 0xa6, 0x92, 0xd7, 0xc6, 0xc6, 0xb5, 0xc5, 0x00, 0x1b, 0xc7, + 0x14, 0x36, 0xae, 0xad, 0x05, 0xd8, 0x38, 0x73, 0x0d, 0x6c, 0xfc, 0xdf, + 0xba, 0xbc, 0xf8, 0x1f, 0x95, 0x82, 0xc2, 0xc6, 0xd7, 0x7a, 0xc7, 0x86, + 0xf7, 0xba, 0x89, 0x03, 0xc4, 0x3b, 0x17, 0xef, 0xbb, 0x86, 0xaf, 0x05, + 0x78, 0x99, 0xb9, 0xbe, 0x5f, 0x66, 0x9e, 0xdb, 0xc2, 0xcb, 0x1e, 0x26, + 0x36, 0x13, 0x47, 0x55, 0x2e, 0x04, 0x3e, 0x68, 0xb2, 0xef, 0x7d, 0x48, + 0xd9, 0x6e, 0xa9, 0x32, 0xab, 0x70, 0x59, 0x1e, 0xb5, 0x6d, 0x51, 0xe1, + 0x60, 0x62, 0xe0, 0x2e, 0x91, 0xbe, 0x20, 0x17, 0x05, 0x18, 0x33, 0xec, + 0xc7, 0x67, 0x9e, 0x29, 0xbc, 0x1d, 0xca, 0x10, 0x03, 0xbb, 0x41, 0x8d, + 0x40, 0x39, 0x0f, 0x23, 0x76, 0x19, 0xbe, 0xac, 0x3c, 0x9f, 0xdd, 0xb7, + 0xff, 0x87, 0xef, 0xdb, 0x06, 0xe3, 0x5a, 0x80, 0x11, 0x51, 0x03, 0x55, + 0xc6, 0xd5, 0xbb, 0x0e, 0x1e, 0x46, 0xf4, 0xf0, 0x61, 0xd6, 0x9d, 0x01, + 0x4e, 0x9e, 0x95, 0x09, 0xe0, 0xf3, 0xf5, 0xdf, 0x65, 0xef, 0x29, 0xc0, + 0x44, 0x36, 0xfe, 0xb7, 0xf7, 0xa2, 0x78, 0xdd, 0xa1, 0xce, 0xfe, 0xce, + 0x0f, 0x45, 0xdb, 0xc6, 0xff, 0x3e, 0xe2, 0x37, 0xea, 0xa1, 0x0a, 0x73, + 0x1d, 0xb1, 0xd0, 0x6f, 0x40, 0x07, 0x63, 0xd7, 0xc0, 0x42, 0x57, 0xe7, + 0x26, 0xe6, 0xcb, 0xad, 0xbc, 0xe4, 0x6c, 0xe6, 0x25, 0xee, 0xf1, 0xeb, + 0x72, 0x27, 0xc7, 0x6c, 0x23, 0x62, 0x4d, 0xe1, 0x33, 0x8f, 0x7c, 0xbd, + 0x3d, 0x37, 0xcd, 0x5d, 0x47, 0x6e, 0x9a, 0x50, 0xb9, 0x89, 0xf4, 0xa2, + 0x9e, 0x83, 0x4c, 0xbe, 0x0b, 0x59, 0x7e, 0x07, 0xb4, 0xff, 0x11, 0xf8, + 0xf9, 0x43, 0x60, 0xac, 0x6f, 0x03, 0x63, 0x7d, 0xab, 0xd2, 0xfe, 0x0e, + 0xc3, 0xb8, 0xb0, 0x0e, 0xf4, 0xea, 0x66, 0x0f, 0xc3, 0x1f, 0x86, 0x57, + 0x35, 0xca, 0x86, 0x33, 0x57, 0x1e, 0x31, 0xe6, 0xbd, 0xf3, 0xd2, 0x44, + 0x4e, 0xd2, 0x88, 0x11, 0xcc, 0x15, 0xea, 0x3a, 0xce, 0x7e, 0x25, 0xb1, + 0x42, 0x5d, 0xd5, 0x93, 0x43, 0x52, 0x6d, 0x78, 0xf8, 0x6a, 0xe1, 0x8c, + 0xb7, 0xc6, 0x9c, 0x8f, 0xaf, 0xf2, 0x3e, 0xbe, 0xca, 0x35, 0x36, 0x12, + 0xac, 0xcf, 0x17, 0x52, 0xdb, 0x31, 0xd5, 0x61, 0x1f, 0x53, 0xcd, 0xff, + 0x15, 0x31, 0x15, 0xf7, 0xca, 0xe3, 0x99, 0xc9, 0xa5, 0x84, 0x1c, 0x80, + 0x7c, 0x27, 0xca, 0xd4, 0x93, 0x69, 0xc3, 0x6e, 0x3e, 0x44, 0x57, 0x8e, + 0xd2, 0x4b, 0x28, 0xe9, 0xe9, 0x69, 0x12, 0x7a, 0x9a, 0xf8, 0xb5, 0xf5, + 0x8d, 0x1a, 0x33, 0xde, 0x1c, 0x8b, 0xe2, 0xf3, 0x7f, 0xaa, 0x23, 0xd2, + 0x4f, 0x3d, 0x5d, 0x8d, 0xb9, 0xae, 0x07, 0x7b, 0x6d, 0xc7, 0x5d, 0xb6, + 0xc2, 0x5d, 0x1d, 0xfe, 0x9c, 0x99, 0x89, 0x49, 0xe8, 0xf0, 0xdf, 0x63, + 0xce, 0x9f, 0xc0, 0xb7, 0x7e, 0x88, 0x78, 0xfd, 0xef, 0xa0, 0x8b, 0x7f, + 0x8b, 0xda, 0xe0, 0x55, 0xe4, 0x9f, 0x1f, 0x60, 0x6c, 0x0b, 0xc7, 0xa8, + 0x33, 0xfa, 0xd1, 0x8c, 0x95, 0x98, 0x28, 0xba, 0x89, 0x09, 0x0f, 0x7f, + 0xfc, 0xea, 0x6f, 0x66, 0xac, 0x29, 0xbe, 0xc3, 0x00, 0xf9, 0xfe, 0xf9, + 0xdd, 0x73, 0x0a, 0x7b, 0x04, 0x98, 0x23, 0x67, 0x73, 0xff, 0x92, 0x9b, + 0x9a, 0xa8, 0xe1, 0xe3, 0x61, 0x9b, 0xef, 0xd9, 0x1e, 0xb6, 0x59, 0xfa, + 0xeb, 0xd4, 0xbb, 0x87, 0x6b, 0x1e, 0x4e, 0xd3, 0xaf, 0xeb, 0xc0, 0x1c, + 0x35, 0xf8, 0x64, 0xa1, 0x69, 0xab, 0xcf, 0xf1, 0x8a, 0x6d, 0x46, 0x20, + 0x1f, 0xf6, 0x58, 0x4f, 0xd1, 0x0b, 0x5d, 0xd3, 0x28, 0x13, 0x81, 0xba, + 0x66, 0xfc, 0x9f, 0xf9, 0xd7, 0x4f, 0xfb, 0xd7, 0x4f, 0xf9, 0xd7, 0x27, + 0x91, 0x77, 0x9f, 0x54, 0xb9, 0x93, 0xe3, 0x1c, 0x83, 0x72, 0x5d, 0xac, + 0x85, 0xf5, 0xce, 0x8e, 0xfe, 0xb4, 0x55, 0x8d, 0x79, 0xfe, 0x5c, 0x68, + 0x3a, 0xf8, 0xfc, 0x63, 0x7c, 0x0e, 0xe2, 0x33, 0x8d, 0xcf, 0x63, 0xf8, + 0x6c, 0xca, 0x54, 0xcb, 0x56, 0xa8, 0xa3, 0x61, 0xc9, 0x62, 0xbc, 0x88, + 0x3a, 0x34, 0x93, 0x7a, 0x44, 0x8a, 0xf5, 0x92, 0x94, 0x96, 0x34, 0xe9, + 0xb6, 0xd2, 0x52, 0xaa, 0x1f, 0x93, 0xe3, 0x4b, 0xde, 0xb9, 0x61, 0x57, + 0xda, 0xc6, 0xdc, 0x96, 0x3c, 0x9c, 0x7a, 0x5c, 0xf4, 0x3b, 0x8f, 0x61, + 0x9e, 0xe8, 0xc5, 0xd1, 0xdb, 0xd4, 0xf9, 0x58, 0x3d, 0xe5, 0xc9, 0xf8, + 0x80, 0x65, 0x9b, 0xc8, 0x5b, 0xc3, 0x4f, 0x62, 0xed, 0x8c, 0x7a, 0x3f, + 0x30, 0x2d, 0x27, 0x4e, 0x6f, 0xec, 0xf5, 0x62, 0xa9, 0x69, 0xbc, 0x81, + 0x4d, 0xeb, 0xe0, 0xc3, 0x46, 0xec, 0x9b, 0x82, 0x9d, 0x1f, 0x71, 0xc3, + 0xda, 0x04, 0x62, 0xe0, 0x84, 0xab, 0x6a, 0x3d, 0xc4, 0x2a, 0xc3, 0x49, + 0x9e, 0x8a, 0xe1, 0x9a, 0xef, 0xd0, 0x20, 0x0f, 0x2a, 0x5b, 0xd9, 0x00, + 0x8e, 0xd1, 0x54, 0xbf, 0xaf, 0xb4, 0x79, 0x0e, 0xa4, 0xfa, 0xff, 0x4e, + 0x32, 0xa9, 0x4b, 0x7e, 0x8c, 0x38, 0xd6, 0x56, 0xb9, 0xa8, 0x51, 0xb6, + 0x3f, 0xc1, 0xda, 0xf0, 0x75, 0x61, 0x5e, 0xbb, 0x07, 0xf3, 0x06, 0x10, + 0x7f, 0x71, 0xaf, 0x09, 0x5e, 0x4e, 0x93, 0x57, 0x3e, 0x83, 0xda, 0xb6, + 0xfa, 0x49, 0xbd, 0xb8, 0xe4, 0xd7, 0x44, 0xaa, 0x76, 0x48, 0x48, 0x7d, + 0xf3, 0xcc, 0xc9, 0xeb, 0x93, 0xd4, 0xdd, 0x00, 0x3b, 0xf4, 0x60, 0x0e, + 0xeb, 0x08, 0xc8, 0xc8, 0x3b, 0x27, 0x53, 0x67, 0x64, 0x45, 0xf7, 0x93, + 0x7a, 0x69, 0x29, 0x83, 0x71, 0xf6, 0xa4, 0xf1, 0xbd, 0xaa, 0x2b, 0xec, + 0x7f, 0x31, 0x74, 0x58, 0x1a, 0xd5, 0x16, 0xe8, 0x45, 0x8e, 0xdd, 0x7b, + 0x58, 0x6a, 0xd5, 0x79, 0x79, 0xa1, 0xba, 0xb1, 0x0b, 0xd8, 0x09, 0x32, + 0x25, 0xfd, 0x3d, 0x3e, 0xfd, 0x54, 0x41, 0x30, 0x0e, 0x79, 0x9e, 0x2e, + 0xc4, 0xbd, 0xba, 0x96, 0xb8, 0xed, 0x24, 0xdf, 0x1b, 0x8c, 0xf3, 0x3d, + 0xbe, 0x23, 0xcb, 0xb4, 0xc9, 0x8b, 0xf7, 0x2e, 0x58, 0x9f, 0x92, 0x0b, + 0xa9, 0x3d, 0xb2, 0x91, 0x52, 0xf5, 0x2f, 0xf1, 0x01, 0x7c, 0xdb, 0x34, + 0xd6, 0xe5, 0x6e, 0x39, 0x01, 0x3f, 0xbd, 0x90, 0xca, 0xa9, 0xf3, 0x9b, + 0xe3, 0x4d, 0x62, 0xfb, 0x79, 0xd6, 0x54, 0xb2, 0xae, 0x7a, 0x60, 0xad, + 0xd6, 0x64, 0x8a, 0xb1, 0xa7, 0x43, 0x36, 0x14, 0xd6, 0xf2, 0x7a, 0xe3, + 0x1b, 0xb3, 0x9e, 0x6f, 0x84, 0x94, 0xbd, 0xff, 0x1b, 0xd0, 0x71, 0x0c, + 0x36, 0x1b, 0x51, 0x73, 0x42, 0xe9, 0x4e, 0x7f, 0x8e, 0xc2, 0x66, 0x6d, + 0x73, 0xc6, 0xc7, 0x33, 0x96, 0xf1, 0xa9, 0x8c, 0x35, 0x36, 0xe1, 0xf5, + 0x53, 0x4c, 0xc3, 0xd6, 0x2e, 0xb6, 0x82, 0xf7, 0x4d, 0xa6, 0xe0, 0x4f, + 0x2f, 0x6d, 0x62, 0x63, 0x18, 0xe7, 0xf3, 0x0b, 0xd0, 0x6b, 0x58, 0x3a, + 0x4e, 0xb5, 0xee, 0x99, 0x4b, 0x8d, 0x24, 0x8e, 0x08, 0xdf, 0x30, 0x62, + 0xfd, 0x6c, 0x82, 0xda, 0x05, 0xe4, 0xc3, 0x2b, 0xc4, 0x08, 0xc3, 0xe7, + 0xe5, 0xca, 0x3d, 0x99, 0xd4, 0x7e, 0xad, 0x36, 0x8b, 0xea, 0xe4, 0xf9, + 0x29, 0xe6, 0xd3, 0xa3, 0xec, 0x7d, 0x86, 0x4e, 0xbd, 0xad, 0x39, 0x65, + 0xf5, 0x8e, 0x39, 0xf4, 0xd2, 0xd2, 0xe6, 0x21, 0x37, 0x3c, 0x3f, 0xc3, + 0x04, 0xa8, 0x5b, 0x83, 0x09, 0x47, 0x72, 0xec, 0x71, 0x49, 0x7e, 0x59, + 0xf6, 0x65, 0x10, 0x47, 0xed, 0x99, 0x0e, 0x99, 0x6f, 0x18, 0xce, 0xe0, + 0xe2, 0x51, 0xac, 0x31, 0x87, 0xb5, 0xa6, 0x51, 0x83, 0xcc, 0x22, 0x27, + 0x53, 0xae, 0x8c, 0xd5, 0x0f, 0x43, 0x46, 0x37, 0xf1, 0xcc, 0x78, 0x3c, + 0x27, 0xe6, 0x4c, 0x41, 0xad, 0xfb, 0x9e, 0x96, 0x1f, 0xfd, 0x18, 0x72, + 0x5a, 0x58, 0x0e, 0x24, 0x45, 0x9f, 0x4e, 0x86, 0xdf, 0x9f, 0xb3, 0x38, + 0x16, 0xe5, 0x98, 0x8e, 0xb1, 0xf0, 0xe7, 0x92, 0x51, 0x3d, 0x93, 0x34, + 0xc7, 0xd9, 0xef, 0x0d, 0x59, 0x73, 0x12, 0x7a, 0xbe, 0xb7, 0x47, 0xba, + 0xa7, 0xa5, 0x77, 0xd5, 0x1c, 0x7f, 0x1d, 0xb4, 0x84, 0x55, 0x6c, 0x9f, + 0x13, 0xdd, 0x1f, 0xef, 0xd9, 0x1c, 0x0f, 0xfb, 0xe3, 0xd3, 0xd2, 0xbd, + 0x3a, 0x62, 0xbc, 0x29, 0x87, 0xb1, 0x66, 0x48, 0x2e, 0xa1, 0xa6, 0xb1, + 0x86, 0xe6, 0xe0, 0x73, 0x0f, 0x91, 0x96, 0x83, 0xc0, 0x14, 0xf0, 0x09, + 0xd4, 0xd9, 0xd6, 0x27, 0xe5, 0x4b, 0x46, 0x97, 0xe4, 0x55, 0x4d, 0x1b, + 0xf6, 0x7a, 0xa5, 0xb0, 0xf3, 0x5b, 0x87, 0xa6, 0x77, 0x7b, 0xfd, 0x00, + 0x9e, 0x67, 0x8c, 0x62, 0xec, 0x4a, 0x6b, 0xc5, 0xe2, 0x18, 0xef, 0x5d, + 0x69, 0xd5, 0xad, 0x11, 0x23, 0xab, 0x45, 0xfd, 0x73, 0xed, 0x79, 0xc5, + 0x7b, 0xa1, 0x3a, 0x68, 0xd4, 0xe4, 0x16, 0x2d, 0x7b, 0x03, 0xf2, 0x83, + 0xfb, 0x19, 0xcc, 0xbd, 0xd2, 0xca, 0x58, 0xf3, 0xaa, 0x7f, 0x5f, 0x93, + 0xe0, 0x9a, 0xeb, 0x8c, 0x18, 0x93, 0xea, 0xd9, 0x11, 0xe3, 0x84, 0xd6, + 0xfe, 0xac, 0xa1, 0x4d, 0x6e, 0x7b, 0xb6, 0x5b, 0xc9, 0x28, 0x64, 0x79, + 0x73, 0x4a, 0xd5, 0x69, 0x79, 0xda, 0xe5, 0xbc, 0x2b, 0xad, 0xac, 0x15, + 0xd1, 0x4e, 0xdc, 0xc0, 0x18, 0xc8, 0xb9, 0x97, 0xaf, 0xda, 0x87, 0xd7, + 0xd7, 0xda, 0xe3, 0x5d, 0xd9, 0xbe, 0xc7, 0x2e, 0x35, 0xe7, 0x82, 0x9a, + 0x13, 0x56, 0xb2, 0xde, 0xbe, 0xcf, 0xcf, 0x64, 0xfb, 0x3e, 0xdd, 0x9b, + 0x3c, 0x97, 0xb0, 0xe6, 0x93, 0x98, 0x5b, 0x76, 0x07, 0xe3, 0x75, 0xb9, + 0xdc, 0xca, 0x5b, 0x17, 0xe5, 0xc2, 0xe6, 0xda, 0xbf, 0xc2, 0x75, 0x3b, + 0x4d, 0xbf, 0xf2, 0x69, 0xe4, 0x77, 0x8e, 0x3d, 0xaa, 0xe4, 0xbd, 0xdb, + 0x1a, 0x3c, 0x58, 0xd3, 0xcc, 0xf1, 0x9f, 0x09, 0x75, 0x75, 0x44, 0xc5, + 0x98, 0xdb, 0xa0, 0xa7, 0x7d, 0xcf, 0xc0, 0x67, 0x47, 0x6d, 0x35, 0xe7, + 0x92, 0x35, 0x2d, 0xfb, 0x4e, 0x0d, 0x1a, 0x97, 0x10, 0xdb, 0x9c, 0x18, + 0xaf, 0x51, 0x2b, 0x59, 0x7c, 0x27, 0xfe, 0x4e, 0xd6, 0x01, 0xd0, 0xe5, + 0xe0, 0xf0, 0xcf, 0xe4, 0xa8, 0x9c, 0xa8, 0x1c, 0x43, 0x2e, 0x9c, 0x93, + 0xe1, 0x67, 0x90, 0x37, 0x2a, 0x05, 0x3c, 0x49, 0x9f, 0xf5, 0x72, 0xe0, + 0x9c, 0x7a, 0xcf, 0xfc, 0x24, 0xea, 0x64, 0xd8, 0x6e, 0x79, 0x70, 0x78, + 0x05, 0xcf, 0xbc, 0xa0, 0x70, 0xa8, 0x2b, 0x0d, 0xf8, 0x40, 0xe2, 0xf9, + 0x3d, 0xb2, 0xfb, 0x01, 0xda, 0x22, 0x32, 0xfd, 0x6d, 0x11, 0xf5, 0xee, + 0xbd, 0x6e, 0x75, 0x8a, 0xec, 0xa5, 0xdd, 0x34, 0x61, 0x63, 0x73, 0xde, + 0x99, 0xd6, 0xb6, 0x6b, 0x73, 0xe6, 0xa2, 0xac, 0x2a, 0xfb, 0xbb, 0x7d, + 0xd5, 0xfb, 0x3f, 0xba, 0x8a, 0x72, 0x38, 0x39, 0x2d, 0x77, 0xac, 0x7a, + 0xf6, 0x56, 0x5a, 0x3a, 0xaa, 0xe4, 0x3a, 0xa7, 0xe4, 0xda, 0x92, 0xc3, + 0x29, 0xca, 0x9c, 0xbc, 0xf0, 0xbd, 0x40, 0x4f, 0x16, 0xf7, 0xfb, 0xf6, + 0x33, 0xf8, 0x0c, 0x7f, 0x57, 0x42, 0xd9, 0xb0, 0xee, 0xbe, 0x7f, 0x37, + 0xcf, 0x59, 0xf7, 0xad, 0x92, 0xcf, 0x1b, 0xb7, 0xf1, 0xf9, 0x14, 0x62, + 0xea, 0xd0, 0x90, 0xc7, 0xeb, 0xab, 0x4b, 0x1f, 0xce, 0xeb, 0x37, 0x37, + 0x79, 0x0d, 0x49, 0x43, 0xd5, 0xaf, 0x5d, 0xbd, 0xd2, 0x8d, 0xa8, 0x07, + 0x7b, 0xf8, 0x09, 0xf6, 0x9a, 0x12, 0xd2, 0xe0, 0xed, 0xb7, 0xe1, 0x92, + 0x96, 0x80, 0x76, 0xd2, 0x73, 0x9f, 0xaf, 0x2f, 0xee, 0x7f, 0x74, 0xc7, + 0x7b, 0x97, 0xc4, 0x70, 0x86, 0x31, 0xa6, 0x2b, 0x9d, 0x65, 0x7d, 0xff, + 0x9a, 0x16, 0x5d, 0xe9, 0xcc, 0xde, 0xd4, 0xd9, 0xeb, 0xd0, 0x59, 0x5d, + 0x7e, 0x13, 0xbc, 0xc0, 0x9f, 0x9f, 0x19, 0x31, 0x0e, 0x13, 0x5b, 0x18, + 0x5c, 0x0f, 0x31, 0xd4, 0xd7, 0x5d, 0xc7, 0x47, 0xd0, 0xdd, 0x9b, 0xa2, + 0xf4, 0x07, 0x7e, 0x90, 0x7f, 0xd4, 0xf3, 0x8c, 0x61, 0xe4, 0xa9, 0x43, + 0xf9, 0x3e, 0x69, 0x53, 0x67, 0xfc, 0x33, 0x9e, 0x3e, 0x95, 0x6f, 0xfb, + 0xfa, 0xcc, 0xcd, 0x50, 0x67, 0xe6, 0x6e, 0x4f, 0x7f, 0x9d, 0x6a, 0xce, + 0x62, 0x32, 0xa1, 0xfc, 0xda, 0x1a, 0xba, 0x65, 0x37, 0x75, 0xf8, 0xb4, + 0xeb, 0xfd, 0x2f, 0xbb, 0xd3, 0xb2, 0xe8, 0x7e, 0x98, 0x1e, 0x3d, 0x1d, + 0x4e, 0x88, 0xe7, 0x3f, 0x57, 0xeb, 0x4f, 0x5f, 0x0d, 0x2b, 0x5b, 0x9d, + 0x80, 0xec, 0x4e, 0x56, 0x3e, 0xe6, 0xdb, 0xb7, 0xc7, 0xeb, 0xd0, 0x87, + 0xf0, 0x7a, 0xb8, 0x3c, 0x68, 0xbc, 0x8d, 0xb5, 0x26, 0x15, 0x86, 0x8b, + 0x88, 0xe3, 0xf3, 0x9a, 0xd8, 0xe4, 0x35, 0xa0, 0xcd, 0x9b, 0x97, 0x65, + 0x5d, 0xea, 0x32, 0x3e, 0x3d, 0xaa, 0xde, 0xbf, 0x7f, 0xa3, 0xcc, 0xb8, + 0x0c, 0xcc, 0x13, 0xeb, 0x93, 0x4b, 0x8d, 0x84, 0x5c, 0x22, 0x96, 0x18, + 0xc3, 0x7f, 0xf7, 0x98, 0x9f, 0x9b, 0xa3, 0xf2, 0x66, 0xb9, 0xbd, 0x56, + 0x1c, 0x95, 0xd7, 0xcb, 0x41, 0xbd, 0x48, 0x2c, 0xcb, 0xfc, 0x3f, 0x27, + 0x6f, 0x2d, 0x0d, 0xca, 0xfa, 0x0c, 0xf2, 0xf8, 0x10, 0x65, 0x30, 0x62, + 0x7c, 0x46, 0xfd, 0xbe, 0xe2, 0x4a, 0xeb, 0xbc, 0x85, 0x75, 0x97, 0x5b, + 0x72, 0x84, 0xe7, 0xd0, 0xfc, 0xde, 0xf8, 0x04, 0x56, 0xe1, 0xbc, 0x3e, + 0xa9, 0x2d, 0xa3, 0x2e, 0x2f, 0x73, 0x5d, 0xca, 0x69, 0x5a, 0x7d, 0x9f, + 0xc4, 0x3e, 0xf7, 0xf3, 0xbd, 0xf4, 0x18, 0x75, 0x71, 0xa5, 0xb5, 0x61, + 0xf1, 0x1c, 0x72, 0x4e, 0x1a, 0xd0, 0xd7, 0x97, 0x93, 0x3c, 0x27, 0xcf, + 0x0b, 0x7f, 0x9f, 0x52, 0x6b, 0xcc, 0xa0, 0x16, 0xb8, 0xd2, 0x5a, 0xb0, + 0x9e, 0x52, 0x7a, 0x6a, 0x54, 0x1f, 0xf0, 0xc7, 0x79, 0xcd, 0x7b, 0x86, + 0xb3, 0x6f, 0x88, 0xf5, 0xe7, 0x03, 0xc8, 0xff, 0xac, 0x3d, 0x89, 0xb7, + 0x28, 0x8b, 0x04, 0x6a, 0x5c, 0xae, 0xc5, 0xdf, 0x04, 0x25, 0x87, 0xf3, + 0x32, 0x09, 0x7a, 0x80, 0xcb, 0x5c, 0xc6, 0xfd, 0x5b, 0x65, 0x23, 0xe6, + 0xc5, 0x77, 0xbe, 0xaf, 0xb5, 0x81, 0x98, 0xbf, 0xb1, 0x19, 0xf3, 0xfb, + 0x71, 0x6d, 0x38, 0xa9, 0xa1, 0xff, 0x84, 0xf5, 0xd9, 0x77, 0x61, 0xcc, + 0x1f, 0xc7, 0x7c, 0x8e, 0xf5, 0x49, 0x69, 0x59, 0x6c, 0xf6, 0x99, 0x6a, + 0xc2, 0x77, 0x31, 0x72, 0xb2, 0xd8, 0x18, 0x8c, 0x9f, 0xd7, 0x1c, 0xf5, + 0xce, 0x46, 0x72, 0x88, 0x7d, 0xb7, 0x3e, 0x69, 0x2c, 0x4b, 0x22, 0x94, + 0x7e, 0x48, 0xdc, 0x86, 0x87, 0xb9, 0x17, 0x34, 0xf6, 0xdf, 0x6c, 0x69, + 0x6c, 0x9f, 0x63, 0x84, 0xd2, 0x87, 0xe4, 0x0f, 0xfc, 0x39, 0x8e, 0x9a, + 0xf3, 0x1f, 0x76, 0xf3, 0xec, 0xab, 0xe1, 0xf6, 0x82, 0x06, 0xd2, 0x76, + 0x63, 0xfb, 0xbe, 0x89, 0xad, 0x7d, 0xb9, 0x27, 0x6a, 0x98, 0xbd, 0x36, + 0xf6, 0x7d, 0x15, 0xcf, 0x3c, 0x04, 0x3a, 0xae, 0x84, 0x74, 0xeb, 0x21, + 0x29, 0x36, 0xae, 0xde, 0xa3, 0x9d, 0x06, 0x3e, 0xc3, 0xf5, 0xb9, 0xcf, + 0x21, 0xd0, 0x77, 0x45, 0xd3, 0xad, 0x43, 0x90, 0xa5, 0xb7, 0x47, 0xe8, + 0x39, 0xd3, 0xf8, 0xa1, 0x0c, 0x89, 0xbe, 0xa2, 0x29, 0xf9, 0xeb, 0xb5, + 0x51, 0x38, 0xc4, 0x94, 0x74, 0xaf, 0xcd, 0x4a, 0x68, 0x8d, 0x3d, 0x00, + 0xda, 0x22, 0xf5, 0xb8, 0x0b, 0x7e, 0x2c, 0x76, 0xd8, 0x22, 0xde, 0x67, + 0x1f, 0x77, 0xb5, 0x57, 0x7a, 0x89, 0xf7, 0x59, 0x0f, 0x1c, 0xc4, 0x7f, + 0xd6, 0x04, 0x2f, 0xb5, 0x32, 0xa9, 0x77, 0x54, 0xde, 0xcc, 0x37, 0x78, + 0xdf, 0x4c, 0x88, 0xf0, 0x1e, 0xe3, 0x43, 0x9f, 0x44, 0xbe, 0x3e, 0x8c, + 0x98, 0x90, 0x03, 0x76, 0xc6, 0xba, 0xa7, 0x86, 0x24, 0xec, 0xbd, 0xeb, + 0xa0, 0xfa, 0x25, 0x6f, 0x2d, 0x9b, 0xfe, 0xef, 0x53, 0x64, 0xdf, 0xf9, + 0x14, 0x7b, 0x9a, 0x03, 0xb0, 0x53, 0xd6, 0x23, 0xa2, 0x6f, 0xa0, 0xde, + 0xbc, 0xd4, 0x88, 0xf6, 0xf2, 0x7d, 0xcb, 0xd7, 0x5d, 0x5c, 0x13, 0xbb, + 0xc7, 0x14, 0x56, 0xf4, 0xef, 0xf1, 0x3b, 0xea, 0xa0, 0x6d, 0x98, 0x32, + 0x01, 0x4c, 0xc9, 0x3a, 0x69, 0xca, 0x7f, 0xe7, 0xcd, 0x70, 0x4e, 0x6c, + 0xab, 0x95, 0x86, 0x65, 0x03, 0x38, 0x6b, 0xdd, 0xb5, 0x10, 0x07, 0xdf, + 0xd6, 0xea, 0x65, 0xf5, 0xbb, 0x34, 0xed, 0x01, 0x60, 0xac, 0x44, 0x9f, + 0xaa, 0x75, 0x4e, 0x3e, 0x20, 0x9e, 0xbd, 0xc3, 0xca, 0x54, 0xcc, 0x5a, + 0xaf, 0x7a, 0xb5, 0xc5, 0x46, 0x75, 0x4a, 0xfe, 0xd4, 0x5d, 0x50, 0xbd, + 0xd2, 0x25, 0xd4, 0x1b, 0xe1, 0x45, 0x55, 0x6b, 0xb5, 0xe1, 0x54, 0xc4, + 0xb7, 0x67, 0x8f, 0xc0, 0x07, 0x4d, 0xf5, 0x6e, 0x81, 0xbe, 0xd2, 0x6a, + 0x65, 0x11, 0x2f, 0x74, 0xcb, 0x32, 0x8a, 0xc8, 0x73, 0x59, 0xf5, 0x7e, + 0x0a, 0xfd, 0xf7, 0xf7, 0x54, 0x1c, 0x96, 0x1a, 0x64, 0xf3, 0x5c, 0x02, + 0xeb, 0x68, 0xca, 0x3e, 0x43, 0x4a, 0x0f, 0x0f, 0x28, 0xec, 0x1a, 0x5a, + 0x41, 0x80, 0x5a, 0x1b, 0x12, 0x59, 0x81, 0xbf, 0xc2, 0x77, 0xc3, 0x6b, + 0xd4, 0x01, 0x65, 0x3b, 0x2b, 0x11, 0xc8, 0x9e, 0x58, 0x22, 0xb4, 0x48, + 0x19, 0xc7, 0x61, 0x17, 0x5c, 0x07, 0x32, 0xe6, 0xbb, 0x2c, 0xcb, 0x1d, + 0xf2, 0x4c, 0xc3, 0xf4, 0xdf, 0x3d, 0x7f, 0x89, 0xef, 0xa3, 0xeb, 0x73, + 0x63, 0x03, 0xc4, 0x4f, 0x52, 0x6a, 0x00, 0x63, 0x9c, 0x66, 0x0d, 0xce, + 0x18, 0x50, 0x88, 0x47, 0x94, 0xaf, 0xb3, 0x06, 0xf6, 0x7c, 0x9f, 0xf8, + 0x3a, 0x62, 0x11, 0xdb, 0x8e, 0x62, 0x8f, 0x9d, 0xe4, 0xea, 0xd5, 0x9e, + 0x93, 0xa0, 0xf3, 0xfc, 0x92, 0x39, 0x55, 0x90, 0x14, 0xdf, 0x71, 0x9e, + 0xb1, 0xc1, 0xf7, 0x06, 0xe2, 0xe4, 0x42, 0x85, 0xef, 0x33, 0x17, 0xe1, + 0x59, 0x53, 0x72, 0xbe, 0xcc, 0x1a, 0xf0, 0x76, 0xe8, 0x8b, 0xd7, 0xc5, + 0xf1, 0x10, 0xfc, 0xff, 0xa2, 0xc1, 0xdf, 0x91, 0xf1, 0x77, 0x41, 0x66, + 0x2a, 0xa1, 0x1d, 0x84, 0x8e, 0x0b, 0x46, 0xc4, 0xb7, 0x03, 0xa7, 0x4c, + 0x8c, 0x35, 0x62, 0x9c, 0xc3, 0xf7, 0x97, 0xdd, 0xcb, 0x2d, 0xd6, 0x3f, + 0x17, 0x10, 0xe7, 0xa6, 0x92, 0x53, 0xb0, 0x9d, 0x42, 0xbc, 0x13, 0xb4, + 0xfe, 0x5d, 0xdc, 0xcb, 0xbb, 0xdc, 0xc7, 0x4c, 0x5d, 0x94, 0x22, 0x30, + 0xfd, 0x48, 0xe2, 0x65, 0xd9, 0x83, 0x3a, 0x55, 0x93, 0x37, 0x2d, 0x73, + 0x5c, 0x34, 0xb5, 0xde, 0xf0, 0x7d, 0xb0, 0xbd, 0x37, 0x10, 0xdf, 0x3a, + 0xfc, 0xda, 0x3d, 0x5b, 0x26, 0x16, 0x3a, 0xaa, 0xde, 0x05, 0xb8, 0x60, + 0xb1, 0x7f, 0xc7, 0xdf, 0x44, 0xfe, 0xa5, 0xda, 0x63, 0xeb, 0x8c, 0x8d, + 0xfd, 0x63, 0xd2, 0xe7, 0xf1, 0x78, 0xc0, 0xf2, 0x68, 0xe4, 0x3a, 0x91, + 0xb6, 0x75, 0xce, 0xfb, 0xeb, 0x9c, 0xf5, 0xd7, 0xa9, 0xf9, 0xeb, 0x5c, + 0xd8, 0x5c, 0xe7, 0x6e, 0xe8, 0xbf, 0xd5, 0x7a, 0x0a, 0xf8, 0x21, 0x93, + 0x6a, 0xb5, 0x1c, 0xd4, 0x59, 0xa5, 0xd1, 0x79, 0x75, 0x46, 0xaa, 0xa7, + 0xbf, 0x71, 0x6f, 0xc6, 0x2a, 0xc4, 0xc3, 0x0a, 0x7b, 0xa0, 0x92, 0x82, + 0x1d, 0x16, 0xc4, 0xc3, 0xdc, 0x3c, 0xb7, 0xf3, 0xce, 0xf5, 0xba, 0xa1, + 0xc3, 0x1c, 0x72, 0x86, 0x91, 0x39, 0x67, 0x49, 0x61, 0xdf, 0x6f, 0xea, + 0xb0, 0xf3, 0x5e, 0xe4, 0x87, 0x9f, 0xc0, 0x66, 0x8c, 0x4c, 0xbd, 0x91, + 0x43, 0xbd, 0xc3, 0xf9, 0x77, 0x40, 0x8f, 0x85, 0x4c, 0xad, 0x51, 0xc8, + 0x9c, 0xe5, 0x79, 0x0e, 0xe6, 0xd5, 0x1a, 0x3d, 0x90, 0x7b, 0x8f, 0xea, + 0x8b, 0xbc, 0x5c, 0x8e, 0x31, 0x06, 0xc1, 0xd6, 0x63, 0x18, 0x8b, 0xab, + 0xdf, 0x68, 0xd5, 0xdd, 0x65, 0xf8, 0x74, 0x02, 0xe3, 0xd5, 0xae, 0x49, + 0x85, 0x47, 0x2d, 0x59, 0x71, 0x7f, 0xa5, 0x15, 0xcb, 0x97, 0xb5, 0x52, + 0x79, 0x18, 0x73, 0x46, 0xf9, 0x5b, 0x9f, 0x3d, 0xc0, 0x49, 0x53, 0xd5, + 0x1d, 0x69, 0x4a, 0x80, 0x26, 0xbd, 0x8d, 0xa6, 0x04, 0xe8, 0x41, 0xcc, + 0x3c, 0xc5, 0xde, 0xf1, 0xa8, 0x9c, 0x28, 0xf3, 0x9d, 0x26, 0xfe, 0x46, + 0xd5, 0x90, 0x30, 0xb0, 0x65, 0xe4, 0x94, 0x19, 0x5f, 0x57, 0xbd, 0x1a, + 0x73, 0xb8, 0x2e, 0x23, 0xa9, 0xba, 0xa8, 0xfc, 0x92, 0x38, 0x81, 0x7c, + 0xf5, 0x86, 0xdb, 0x23, 0x6f, 0xfa, 0x7b, 0x5d, 0x14, 0x9e, 0x33, 0x6e, + 0xdf, 0xeb, 0xc9, 0x4a, 0x2a, 0xf3, 0x8a, 0x15, 0xf2, 0xf9, 0xea, 0xc3, + 0x5e, 0x7b, 0x30, 0x37, 0x95, 0x39, 0xdf, 0xd8, 0x69, 0xae, 0x83, 0xb9, + 0x91, 0xb6, 0xb9, 0x0e, 0xe6, 0xf5, 0x20, 0xef, 0xf5, 0x28, 0x9e, 0x4a, + 0xa0, 0xeb, 0x52, 0x99, 0x3c, 0xf1, 0x0c, 0x82, 0x7b, 0x1a, 0xc4, 0xc6, + 0x53, 0xe2, 0x9f, 0xd9, 0xf2, 0xf7, 0x7a, 0x57, 0xf5, 0x6b, 0x94, 0x0d, + 0x4c, 0x58, 0x3c, 0x9b, 0x99, 0xd1, 0xb2, 0xf5, 0x3c, 0x72, 0xd5, 0x8d, + 0xc4, 0x43, 0x29, 0x1b, 0xb9, 0x92, 0xe7, 0x3c, 0x8d, 0x72, 0x81, 0xef, + 0x3d, 0xc3, 0x2e, 0xde, 0x21, 0x5e, 0xbe, 0x31, 0xa4, 0xde, 0x43, 0x70, + 0xfc, 0x73, 0x20, 0x31, 0x32, 0x63, 0x7c, 0xf7, 0xe0, 0x6e, 0xa9, 0x2f, + 0x7f, 0x11, 0x63, 0x19, 0xe4, 0xc5, 0x43, 0x5a, 0xe6, 0xdc, 0x24, 0xae, + 0x1f, 0xc2, 0x35, 0xe2, 0xf0, 0x72, 0x0e, 0xf7, 0x1f, 0xc2, 0xf5, 0xbc, + 0x96, 0x6d, 0xe6, 0x70, 0xfd, 0x30, 0xae, 0x27, 0x48, 0x9b, 0xf3, 0x8a, + 0x35, 0xa5, 0xd9, 0x58, 0xcb, 0x3e, 0x37, 0x89, 0x4f, 0xfb, 0x7a, 0xbc, + 0x07, 0x3d, 0x95, 0x79, 0x3e, 0x96, 0x04, 0x4d, 0x0f, 0x6a, 0x4e, 0xbd, + 0x1b, 0x6b, 0x0c, 0xe1, 0x79, 0xda, 0x54, 0xfb, 0x39, 0xd4, 0x6d, 0xaa, + 0x67, 0x14, 0x4a, 0xa7, 0x81, 0x77, 0x1f, 0x41, 0xde, 0xd7, 0xc4, 0xb1, + 0x1e, 0x97, 0x62, 0x2a, 0x2d, 0x0b, 0xf5, 0x90, 0x64, 0x63, 0x05, 0x7c, + 0x2f, 0x48, 0x66, 0x1c, 0xf7, 0xeb, 0xb4, 0x05, 0xce, 0x2b, 0x49, 0xb1, + 0x4a, 0xfc, 0xce, 0x7e, 0xd1, 0x57, 0xc0, 0x37, 0xfb, 0x44, 0x79, 0xc8, + 0x20, 0x46, 0xfb, 0xdd, 0xa1, 0xa7, 0xe5, 0xbd, 0xd3, 0x8c, 0x7c, 0xac, + 0x65, 0xea, 0xfe, 0x59, 0x9d, 0xc5, 0xdf, 0x2b, 0xb1, 0x47, 0x25, 0xc5, + 0x50, 0x9a, 0x7d, 0x0e, 0xd5, 0x17, 0x4f, 0x79, 0x67, 0x7a, 0xed, 0xef, + 0x90, 0x04, 0xfe, 0xc2, 0x7d, 0xbf, 0x82, 0xe7, 0xbd, 0xbe, 0x54, 0xb6, + 0xf9, 0x41, 0x5d, 0xf0, 0x5d, 0xfd, 0x15, 0xe8, 0xe2, 0xfc, 0x87, 0xf6, + 0xb9, 0xd8, 0xe3, 0x9a, 0x47, 0x2c, 0x62, 0x7f, 0x2c, 0x90, 0xdf, 0xd5, + 0x34, 0x92, 0xbe, 0xc3, 0x58, 0x4b, 0x52, 0x8c, 0xb3, 0xb9, 0x58, 0x42, + 0xd5, 0xbe, 0x1b, 0x4b, 0xf2, 0xc4, 0x16, 0xbd, 0xa4, 0x95, 0x72, 0x78, + 0x04, 0xf5, 0x1a, 0x7f, 0xff, 0xf0, 0xb8, 0xe4, 0x53, 0xec, 0xd1, 0x84, + 0x90, 0x0b, 0x0b, 0xf8, 0xbe, 0x25, 0xb7, 0x92, 0x2f, 0xb7, 0x7c, 0xf5, + 0x5b, 0x4a, 0x77, 0x35, 0x8b, 0xfb, 0x05, 0xbd, 0x8b, 0x69, 0xa5, 0xb3, + 0x9a, 0x7a, 0xcf, 0x36, 0xe0, 0x3d, 0xe8, 0xbf, 0xed, 0x6c, 0x73, 0x93, + 0x16, 0x69, 0xfb, 0x38, 0xdf, 0x5b, 0x18, 0xb6, 0x85, 0xf4, 0x93, 0x0f, + 0xe6, 0xac, 0xe0, 0x5c, 0x34, 0xe0, 0x21, 0xe0, 0xf3, 0xa3, 0xca, 0x85, + 0x74, 0xee, 0x31, 0xa4, 0x7b, 0xca, 0x08, 0x59, 0xcc, 0x01, 0x9f, 0xf6, + 0xfb, 0xf8, 0xff, 0x37, 0xe5, 0xea, 0xf1, 0x1e, 0x86, 0xa8, 0xfc, 0xdf, + 0x8b, 0xee, 0xa0, 0xf7, 0xab, 0xcf, 0x80, 0x0d, 0xe7, 0xac, 0xb5, 0xc5, + 0x67, 0x6d, 0x07, 0x3e, 0x6b, 0x3e, 0x9f, 0x1f, 0x7e, 0x4e, 0xea, 0xd1, + 0x59, 0x5b, 0xb2, 0xc1, 0x23, 0x6d, 0x6a, 0x27, 0x7b, 0xe3, 0x6f, 0x9c, + 0xd4, 0xef, 0xad, 0xa2, 0xb6, 0x7b, 0xad, 0x5e, 0x27, 0xeb, 0x64, 0xcf, + 0xee, 0xce, 0x22, 0xd7, 0x55, 0xab, 0x5e, 0xcd, 0x5c, 0x75, 0xd9, 0x6b, + 0xde, 0x69, 0x6f, 0x0d, 0x34, 0xff, 0x8e, 0x7a, 0xef, 0xa4, 0xe4, 0x7a, + 0x7d, 0xa9, 0x6a, 0xb5, 0x3d, 0x57, 0xde, 0xc0, 0x3c, 0x39, 0x5c, 0x90, + 0x19, 0xe8, 0x31, 0x89, 0xeb, 0x9b, 0xe5, 0xe5, 0x65, 0x75, 0x86, 0xe4, + 0x9f, 0xd5, 0xf0, 0x0c, 0x46, 0x9d, 0x43, 0x23, 0x5e, 0xcd, 0xaa, 0x78, + 0xbd, 0xb1, 0xac, 0xee, 0xa9, 0xdf, 0x3c, 0xd4, 0xdd, 0x19, 0xc4, 0x73, + 0xd4, 0x06, 0xd6, 0x6e, 0x29, 0xa2, 0x86, 0x3e, 0x6b, 0xcd, 0x18, 0xc4, + 0x29, 0x5c, 0x6b, 0x03, 0x6b, 0x9d, 0x5f, 0x96, 0xbd, 0x7c, 0xa7, 0xa3, + 0xaa, 0xce, 0xbd, 0xbc, 0x7e, 0xf5, 0xbc, 0x04, 0xbf, 0xd7, 0x8d, 0xfa, + 0x39, 0x8e, 0xef, 0x95, 0xf0, 0xb7, 0xa7, 0x8c, 0x01, 0xa8, 0x6b, 0x66, + 0x0a, 0x58, 0xaf, 0xd5, 0xf2, 0xfa, 0xd9, 0x2d, 0xd8, 0x7d, 0x84, 0xbf, + 0x65, 0xc0, 0xdf, 0x23, 0xb0, 0x13, 0xf8, 0xc1, 0xe6, 0x38, 0xaf, 0x59, + 0x4b, 0x04, 0xd7, 0x4c, 0x58, 0xff, 0x1b, 0xed, 0xcc, 0xfa, 0xa1, 0x98, + 0x41, 0x00, 0x00, 0x00 }; +static u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = { 0x00000000, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000010, 0x00000030, 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x00000010, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00008002, 0x00000000, @@ -4051,42 +4043,42 @@ static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; -static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = { - 0x08004060, 0x0800408c, 0x080040d4, 0x080040d4, 0x08003f60, 0x08003f8c, - 0x08003f8c, 0x080040d4, 0x080040d4, 0x080040d4, 0x08003ff4, 0x00000000, +static u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = { + 0x08003be8, 0x08003c14, 0x08003c5c, 0x08003c5c, 0x08003ae8, 0x08003b14, + 0x08003b14, 0x08003c5c, 0x08003c5c, 0x08003c5c, 0x08003b7c, 0x00000000, 0x00000000 }; -static const u32 bnx2_TXP_b09FwBss[(0xa20/4) + 1] = { 0x0 }; -static const u32 bnx2_TXP_b09FwSbss[(0x8c/4) + 1] = { 0x0 }; +static u32 bnx2_TXP_b09FwBss[(0xa20/4) + 1] = { 0x0 }; +static u32 bnx2_TXP_b09FwSbss[(0x80/4) + 1] = { 0x0 }; static struct fw_info bnx2_txp_fw_09 = { - .ver_major = 0x3, - .ver_minor = 0x4, - .ver_fix = 0x3, + .ver_major = 0x1, + .ver_minor = 0x0, + .ver_fix = 0x0, .start_addr = 0x08000060, .text_addr = 0x08000000, - .text_len = 0x4634, + .text_len = 0x4194, .text_index = 0x0, .gz_text = bnx2_TXP_b09FwText, .gz_text_len = sizeof(bnx2_TXP_b09FwText), - .data_addr = 0x08004680, + .data_addr = 0x080041e0, .data_len = 0xd0, .data_index = 0x0, .data = bnx2_TXP_b09FwData, - .sbss_addr = 0x08004750, - .sbss_len = 0x8c, + .sbss_addr = 0x080042b0, + .sbss_len = 0x80, .sbss_index = 0x0, .sbss = bnx2_TXP_b09FwSbss, - .bss_addr = 0x080047e0, + .bss_addr = 0x08004330, .bss_len = 0xa20, .bss_index = 0x0, .bss = bnx2_TXP_b09FwBss, - .rodata_addr = 0x08004638, + .rodata_addr = 0x08004198, .rodata_len = 0x30, .rodata_index = 0x0, .rodata = bnx2_TXP_b09FwRodata, diff --git a/trunk/drivers/net/cxgb3/version.h b/trunk/drivers/net/cxgb3/version.h index b112317f033e..042e27e291cd 100644 --- a/trunk/drivers/net/cxgb3/version.h +++ b/trunk/drivers/net/cxgb3/version.h @@ -38,7 +38,7 @@ #define DRV_VERSION "1.0-ko" /* Firmware version */ -#define FW_VERSION_MAJOR 4 -#define FW_VERSION_MINOR 0 +#define FW_VERSION_MAJOR 3 +#define FW_VERSION_MINOR 3 #define FW_VERSION_MICRO 0 #endif /* __CHELSIO_VERSION_H */ diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index 264fa0e2e075..8cc1174e7f64 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -77,6 +77,9 @@ #define DM9000_PHY 0x40 /* PHY address 0x01 */ +#define TRUE 1 +#define FALSE 0 + #define CARDNAME "dm9000" #define PFX CARDNAME ": " @@ -598,7 +601,7 @@ dm9000_probe(struct platform_device *pdev) printk("%s: not found (%d).\n", CARDNAME, ret); dm9000_release_board(pdev, db); - free_netdev(ndev); + kfree(ndev); return ret; } @@ -893,7 +896,7 @@ dm9000_rx(struct net_device *dev) struct dm9000_rxhdr rxhdr; struct sk_buff *skb; u8 rxbyte, *rdptr; - bool GoodPacket; + int GoodPacket; int RxLen; /* Check packet ready or not */ @@ -915,7 +918,7 @@ dm9000_rx(struct net_device *dev) return; /* A packet ready now & Get status/length */ - GoodPacket = true; + GoodPacket = TRUE; writeb(DM9000_MRCMD, db->io_addr); (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr)); @@ -924,7 +927,7 @@ dm9000_rx(struct net_device *dev) /* Packet Status check */ if (RxLen < 0x40) { - GoodPacket = false; + GoodPacket = FALSE; PRINTK1("Bad Packet received (runt)\n"); } @@ -933,7 +936,7 @@ dm9000_rx(struct net_device *dev) } if (rxhdr.RxStatus & 0xbf00) { - GoodPacket = false; + GoodPacket = FALSE; if (rxhdr.RxStatus & 0x100) { PRINTK1("fifo error\n"); db->stats.rx_fifo_errors++; @@ -1190,7 +1193,7 @@ dm9000_drv_remove(struct platform_device *pdev) unregister_netdev(ndev); dm9000_release_board(pdev, (board_info_t *) ndev->priv); - free_netdev(ndev); /* free device structure */ + kfree(ndev); /* free device structure */ PRINTK1("clean_module() exit\n"); diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index f6e0cb1ada1f..c7a5614e66c0 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -1803,10 +1803,10 @@ static inline int ehea_hash_skb(struct sk_buff *skb, int num_qps) u32 tmp; if ((skb->protocol == htons(ETH_P_IP)) && - (ip_hdr(skb)->protocol == IPPROTO_TCP)) { - tcp = (struct tcphdr*)(skb_network_header(skb) + (ip_hdr(skb)->ihl * 4)); + (skb->nh.iph->protocol == IPPROTO_TCP)) { + tcp = (struct tcphdr*)(skb->nh.raw + (skb->nh.iph->ihl * 4)); tmp = (tcp->source + (tcp->dest << 16)) % 31; - tmp += ip_hdr(skb)->daddr % 31; + tmp += skb->nh.iph->daddr % 31; return tmp % num_qps; } else @@ -2603,13 +2603,14 @@ static int ehea_setup_ports(struct ehea_adapter *adapter) { struct device_node *lhea_dn; struct device_node *eth_dn = NULL; - const u32 *dn_log_port_id; + + u32 *dn_log_port_id; int i = 0; lhea_dn = adapter->ebus_dev->ofdev.node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { - dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", + dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no", NULL); if (!dn_log_port_id) { ehea_error("bad device node: eth_dn name=%s", @@ -2644,12 +2645,12 @@ static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, { struct device_node *lhea_dn; struct device_node *eth_dn = NULL; - const u32 *dn_log_port_id; + u32 *dn_log_port_id; lhea_dn = adapter->ebus_dev->ofdev.node; while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) { - dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no", + dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no", NULL); if (dn_log_port_id) if (*dn_log_port_id == logical_port_id) @@ -2773,7 +2774,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, const struct of_device_id *id) { struct ehea_adapter *adapter; - const u64 *adapter_handle; + u64 *adapter_handle; int ret; if (!dev || !dev->ofdev.node) { @@ -2790,7 +2791,7 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev, adapter->ebus_dev = dev; - adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle", + adapter_handle = (u64*)get_property(dev->ofdev.node, "ibm,hea-handle", NULL); if (adapter_handle) adapter->handle = *adapter_handle; diff --git a/trunk/drivers/net/fec_8xx/fec_main.c b/trunk/drivers/net/fec_8xx/fec_main.c index 88efe9731bab..e824d5d231af 100644 --- a/trunk/drivers/net/fec_8xx/fec_main.c +++ b/trunk/drivers/net/fec_8xx/fec_main.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/fec_8xx/fec_mii.c b/trunk/drivers/net/fec_8xx/fec_mii.c index b3fa0d6a159c..e79700abf7b6 100644 --- a/trunk/drivers/net/fec_8xx/fec_mii.c +++ b/trunk/drivers/net/fec_8xx/fec_mii.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/fs_enet/fs_enet-main.c b/trunk/drivers/net/fs_enet/fs_enet-main.c index a4a2a0ea43d3..e2ddd617493a 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-main.c +++ b/trunk/drivers/net/fs_enet/fs_enet-main.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/fs_enet/mac-fcc.c b/trunk/drivers/net/fs_enet/mac-fcc.c index 5603121132cd..8545e84fc9a0 100644 --- a/trunk/drivers/net/fs_enet/mac-fcc.c +++ b/trunk/drivers/net/fs_enet/mac-fcc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/fs_enet/mac-fec.c b/trunk/drivers/net/fs_enet/mac-fec.c index 04b4f80a1cde..cdcfb96f360f 100644 --- a/trunk/drivers/net/fs_enet/mac-fec.c +++ b/trunk/drivers/net/fs_enet/mac-fec.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/fs_enet/mac-scc.c b/trunk/drivers/net/fs_enet/mac-scc.c index d0f28981b55a..65925b5a224f 100644 --- a/trunk/drivers/net/fs_enet/mac-scc.c +++ b/trunk/drivers/net/fs_enet/mac-scc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/fs_enet/mii-bitbang.c b/trunk/drivers/net/fs_enet/mii-bitbang.c index d3840108ffbd..f91447837fd4 100644 --- a/trunk/drivers/net/fs_enet/mii-bitbang.c +++ b/trunk/drivers/net/fs_enet/mii-bitbang.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/fs_enet/mii-fec.c b/trunk/drivers/net/fs_enet/mii-fec.c index 0a563a83016f..235b177fb9ac 100644 --- a/trunk/drivers/net/fs_enet/mii-fec.c +++ b/trunk/drivers/net/fs_enet/mii-fec.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/ibm_emac/ibm_emac_core.c b/trunk/drivers/net/ibm_emac/ibm_emac_core.c index 50035ebd4f52..3d82d46f4998 100644 --- a/trunk/drivers/net/ibm_emac/ibm_emac_core.c +++ b/trunk/drivers/net/ibm_emac/ibm_emac_core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/irda/pxaficp_ir.c b/trunk/drivers/net/irda/pxaficp_ir.c index 55ff0fbe525a..fb196fd91855 100644 --- a/trunk/drivers/net/irda/pxaficp_ir.c +++ b/trunk/drivers/net/irda/pxaficp_ir.c @@ -134,7 +134,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) DCSR(si->rxdma) &= ~DCSR_RUN; /* disable FICP */ ICCR0 = 0; - pxa_set_cken(CKEN_FICP, 0); + pxa_set_cken(CKEN13_FICP, 0); /* set board transceiver to SIR mode */ si->pdata->transceiver_mode(si->dev, IR_SIRMODE); @@ -144,7 +144,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) pxa_gpio_mode(GPIO47_STTXD_MD); /* enable the STUART clock */ - pxa_set_cken(CKEN_STUART, 1); + pxa_set_cken(CKEN5_STUART, 1); } /* disable STUART first */ @@ -169,7 +169,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) /* disable STUART */ STIER = 0; STISR = 0; - pxa_set_cken(CKEN_STUART, 0); + pxa_set_cken(CKEN5_STUART, 0); /* disable FICP first */ ICCR0 = 0; @@ -182,7 +182,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) pxa_gpio_mode(GPIO47_ICPTXD_MD); /* enable the FICP clock */ - pxa_set_cken(CKEN_FICP, 1); + pxa_set_cken(CKEN13_FICP, 1); si->speed = speed; pxa_irda_fir_dma_rx_start(si); @@ -593,7 +593,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si) /* disable STUART SIR mode */ STISR = 0; /* disable the STUART clock */ - pxa_set_cken(CKEN_STUART, 0); + pxa_set_cken(CKEN5_STUART, 0); /* disable DMA */ DCSR(si->txdma) &= ~DCSR_RUN; @@ -601,7 +601,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si) /* disable FICP */ ICCR0 = 0; /* disable the FICP clock */ - pxa_set_cken(CKEN_FICP, 0); + pxa_set_cken(CKEN13_FICP, 0); DRCMR17 = 0; DRCMR18 = 0; diff --git a/trunk/drivers/net/irda/sir_dev.c b/trunk/drivers/net/irda/sir_dev.c index 9d6c8f391b2d..17b0c3ab6201 100644 --- a/trunk/drivers/net/irda/sir_dev.c +++ b/trunk/drivers/net/irda/sir_dev.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/net/irda/sir_dongle.c b/trunk/drivers/net/irda/sir_dongle.c index 25d5b8a96bdc..d7e32d9554fc 100644 --- a/trunk/drivers/net/irda/sir_dongle.c +++ b/trunk/drivers/net/irda/sir_dongle.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/net/irda/smsc-ircc2.c b/trunk/drivers/net/irda/smsc-ircc2.c index 9043bf4aa49e..198bf3bfa70f 100644 --- a/trunk/drivers/net/irda/smsc-ircc2.c +++ b/trunk/drivers/net/irda/smsc-ircc2.c @@ -79,17 +79,11 @@ MODULE_AUTHOR("Daniele Peri "); MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); MODULE_LICENSE("GPL"); -static int smsc_nopnp; -module_param_named(nopnp, smsc_nopnp, bool, 0); -MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings"); - -#define DMA_INVAL 255 -static int ircc_dma = DMA_INVAL; +static int ircc_dma = 255; module_param(ircc_dma, int, 0); MODULE_PARM_DESC(ircc_dma, "DMA channel"); -#define IRQ_INVAL 255 -static int ircc_irq = IRQ_INVAL; +static int ircc_irq = 255; module_param(ircc_irq, int, 0); MODULE_PARM_DESC(ircc_irq, "IRQ line"); @@ -366,6 +360,7 @@ static inline void register_bank(int iobase, int bank) iobase + IRCC_MASTER); } +#ifdef CONFIG_PNP /* PNP hotplug support */ static const struct pnp_device_id smsc_ircc_pnp_table[] = { { .id = "SMCf010", .driver_data = 0 }, @@ -373,35 +368,7 @@ static const struct pnp_device_id smsc_ircc_pnp_table[] = { { } }; MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); - -static int pnp_driver_registered; - -static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev, - const struct pnp_device_id *dev_id) -{ - unsigned int firbase, sirbase; - u8 dma, irq; - - if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && - pnp_dma_valid(dev, 0) && pnp_irq_valid(dev, 0))) - return -EINVAL; - - sirbase = pnp_port_start(dev, 0); - firbase = pnp_port_start(dev, 1); - dma = pnp_dma(dev, 0); - irq = pnp_irq(dev, 0); - - if (smsc_ircc_open(firbase, sirbase, dma, irq)) - return -ENODEV; - - return 0; -} - -static struct pnp_driver smsc_ircc_pnp_driver = { - .name = "smsc-ircc2", - .id_table = smsc_ircc_pnp_table, - .probe = smsc_ircc_pnp_probe, -}; +#endif /******************************************************************************* @@ -412,35 +379,6 @@ static struct pnp_driver smsc_ircc_pnp_driver = { * *******************************************************************************/ -static int __init smsc_ircc_legacy_probe(void) -{ - int ret = 0; - - if (ircc_fir > 0 && ircc_sir > 0) { - IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); - IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); - - if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) - ret = -ENODEV; - } else { - ret = -ENODEV; - - /* try user provided configuration register base address */ - if (ircc_cfg > 0) { - IRDA_MESSAGE(" Overriding configuration address " - "0x%04x\n", ircc_cfg); - if (!smsc_superio_fdc(ircc_cfg)) - ret = 0; - if (!smsc_superio_lpc(ircc_cfg)) - ret = 0; - } - - if (smsc_ircc_look_for_chips() > 0) - ret = 0; - } - return ret; -} - /* * Function smsc_ircc_init () * @@ -468,20 +406,31 @@ static int __init smsc_ircc_init(void) dev_count = 0; - if (smsc_nopnp || !pnp_platform_devices || - ircc_cfg || ircc_fir || ircc_sir || - ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) { - ret = smsc_ircc_legacy_probe(); + if (ircc_fir > 0 && ircc_sir > 0) { + IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); + IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); + + if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq)) + ret = -ENODEV; } else { - if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0) - pnp_driver_registered = 1; + ret = -ENODEV; + + /* try user provided configuration register base address */ + if (ircc_cfg > 0) { + IRDA_MESSAGE(" Overriding configuration address " + "0x%04x\n", ircc_cfg); + if (!smsc_superio_fdc(ircc_cfg)) + ret = 0; + if (!smsc_superio_lpc(ircc_cfg)) + ret = 0; + } + + if (smsc_ircc_look_for_chips() > 0) + ret = 0; } - if (ret) { - if (pnp_driver_registered) - pnp_unregister_driver(&smsc_ircc_pnp_driver); + if (ret) platform_driver_unregister(&smsc_ircc_driver); - } return ret; } @@ -697,7 +646,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE; self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED; - if (irq != IRQ_INVAL) { + if (irq < 255) { if (irq != chip_irq) IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", driver_name, chip_irq, irq); @@ -705,7 +654,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self, } else self->io.irq = chip_irq; - if (dma != DMA_INVAL) { + if (dma < 255) { if (dma != chip_dma) IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", driver_name, chip_dma, dma); @@ -1891,9 +1840,6 @@ static void __exit smsc_ircc_cleanup(void) smsc_ircc_close(dev_self[i]); } - if (pnp_driver_registered) - pnp_unregister_driver(&smsc_ircc_pnp_driver); - platform_driver_unregister(&smsc_ircc_driver); } @@ -2890,9 +2836,9 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg, tmpconf.fir_io = ircc_fir; if (ircc_sir != 0) tmpconf.sir_io = ircc_sir; - if (ircc_dma != DMA_INVAL) + if (ircc_dma != 0xff) tmpconf.fir_dma = ircc_dma; - if (ircc_irq != IRQ_INVAL) + if (ircc_irq != 0xff) tmpconf.fir_irq = ircc_irq; IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); diff --git a/trunk/drivers/net/irda/vlsi_ir.c b/trunk/drivers/net/irda/vlsi_ir.c index bf78ef1120ad..c4be973867a6 100644 --- a/trunk/drivers/net/irda/vlsi_ir.c +++ b/trunk/drivers/net/irda/vlsi_ir.c @@ -44,6 +44,7 @@ MODULE_LICENSE("GPL"); #include #include #include +#include #include #include diff --git a/trunk/drivers/net/ixgb/ixgb_osdep.h b/trunk/drivers/net/ixgb/ixgb_osdep.h index 9e04a6b3ae0d..8434d752fd81 100644 --- a/trunk/drivers/net/ixgb/ixgb_osdep.h +++ b/trunk/drivers/net/ixgb/ixgb_osdep.h @@ -34,6 +34,7 @@ #define _IXGB_OSDEP_H_ #include +#include #include #include #include diff --git a/trunk/drivers/net/jazzsonic.c b/trunk/drivers/net/jazzsonic.c index 75f6f441e876..d34afb52ea7f 100644 --- a/trunk/drivers/net/jazzsonic.c +++ b/trunk/drivers/net/jazzsonic.c @@ -88,23 +88,6 @@ static unsigned short known_revisions[] = 0xffff /* end of list */ }; -static int jazzsonic_open(struct net_device* dev) -{ - if (request_irq(dev->irq, &sonic_interrupt, IRQF_DISABLED, "sonic", dev)) { - printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq); - return -EAGAIN; - } - return sonic_open(dev); -} - -static int jazzsonic_close(struct net_device* dev) -{ - int err; - err = sonic_close(dev); - free_irq(dev->irq, dev); - return err; -} - static int __init sonic_probe1(struct net_device *dev) { static unsigned version_printed; @@ -186,8 +169,8 @@ static int __init sonic_probe1(struct net_device *dev) lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS * SONIC_BUS_SCALE(lp->dma_bitmode)); - dev->open = jazzsonic_open; - dev->stop = jazzsonic_close; + dev->open = sonic_open; + dev->stop = sonic_close; dev->hard_start_xmit = sonic_send_packet; dev->get_stats = sonic_get_stats; dev->set_multicast_list = &sonic_multicast_list; @@ -277,6 +260,8 @@ MODULE_DESCRIPTION("Jazz SONIC ethernet driver"); module_param(sonic_debug, int, 0); MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)"); +#define SONIC_IRQ_FLAG IRQF_DISABLED + #include "sonic.c" static int __devexit jazz_sonic_device_remove (struct platform_device *pdev) @@ -284,11 +269,11 @@ static int __devexit jazz_sonic_device_remove (struct platform_device *pdev) struct net_device *dev = platform_get_drvdata(pdev); struct sonic_local* lp = netdev_priv(dev); - unregister_netdev(dev); + unregister_netdev (dev); dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), lp->descriptors, lp->descriptors_laddr); release_region (dev->base_addr, SONIC_MEM_SIZE); - free_netdev(dev); + free_netdev (dev); return 0; } diff --git a/trunk/drivers/net/lasi_82596.c b/trunk/drivers/net/lasi_82596.c index 6b49fc4bd1a1..0edcd125fd61 100644 --- a/trunk/drivers/net/lasi_82596.c +++ b/trunk/drivers/net/lasi_82596.c @@ -81,6 +81,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/net/mac8390.c b/trunk/drivers/net/mac8390.c index 90b0c3ed4bb6..a12bb64e3694 100644 --- a/trunk/drivers/net/mac8390.c +++ b/trunk/drivers/net/mac8390.c @@ -14,8 +14,6 @@ /* 2001-05-15: support for Cabletron ported from old daynaport driver * and fixed access to Sonic Sys card which masquerades as a Farallon * by rayk@knightsmanor.org */ -/* 2002-12-30: Try to support more cards, some clues from NetBSD driver */ -/* 2003-12-26: Make sure Asante cards always work. */ #include #include @@ -63,21 +61,25 @@ static char version[] = #define DAYNA_8390_BASE 0x80000 #define DAYNA_8390_MEM 0x00000 +#define KINETICS_8390_BASE 0x80000 +#define KINETICS_8390_MEM 0x00000 + #define CABLETRON_8390_BASE 0x90000 #define CABLETRON_8390_MEM 0x00000 -#define INTERLAN_8390_BASE 0xE0000 -#define INTERLAN_8390_MEM 0xD0000 - enum mac8390_type { MAC8390_NONE = -1, MAC8390_APPLE, MAC8390_ASANTE, - MAC8390_FARALLON, + MAC8390_FARALLON, /* Apple, Asante, and Farallon are all compatible */ MAC8390_CABLETRON, MAC8390_DAYNA, MAC8390_INTERLAN, MAC8390_KINETICS, + MAC8390_FOCUS, + MAC8390_SONICSYS, + MAC8390_DAYNA2, + MAC8390_DAYNA3, }; static const char * cardname[] = { @@ -88,6 +90,10 @@ static const char * cardname[] = { "dayna", "interlan", "kinetics", + "focus", + "sonic systems", + "dayna2", + "dayna_lc", }; static int word16[] = { @@ -98,6 +104,10 @@ static int word16[] = { 0, /* dayna */ 1, /* interlan */ 0, /* kinetics */ + 1, /* focus (??) */ + 1, /* sonic systems */ + 1, /* dayna2 */ + 1, /* dayna-lc */ }; /* on which cards do we use NuBus resources? */ @@ -109,12 +119,10 @@ static int useresources[] = { 0, /* dayna */ 0, /* interlan */ 0, /* kinetics */ -}; - -enum mac8390_access { - ACCESS_UNKNOWN = 0, - ACCESS_32, - ACCESS_16, + 0, /* focus (??) */ + 1, /* sonic systems */ + 1, /* dayna2 */ + 1, /* dayna-lc */ }; extern enum mac8390_type mac8390_ident(struct nubus_dev * dev); @@ -126,9 +134,8 @@ static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, static int mac8390_open(struct net_device * dev); static int mac8390_close(struct net_device * dev); static void mac8390_no_reset(struct net_device *dev); -static void interlan_reset(struct net_device *dev); -/* Sane (32-bit chunk memory read/write) - Some Farallon and Apple do this*/ +/* Sane (32-bit chunk memory read/write) - Apple/Asante/Farallon do this*/ static void sane_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); static void sane_block_input(struct net_device * dev, int count, @@ -165,93 +172,23 @@ static void word_memcpy_fromcard(void *tp, const void *fp, int count); enum mac8390_type __init mac8390_ident(struct nubus_dev * dev) { - switch (dev->dr_sw) { - case NUBUS_DRSW_3COM: - switch (dev->dr_hw) { - case NUBUS_DRHW_APPLE_SONIC_NB: - case NUBUS_DRHW_APPLE_SONIC_LC: - case NUBUS_DRHW_SONNET: - return MAC8390_NONE; - break; - default: - return MAC8390_APPLE; - break; - } - break; - - case NUBUS_DRSW_APPLE: - switch (dev->dr_hw) { - case NUBUS_DRHW_ASANTE_LC: - return MAC8390_NONE; - break; - case NUBUS_DRHW_CABLETRON: - return MAC8390_CABLETRON; - break; - default: - return MAC8390_APPLE; - break; - } - break; - - case NUBUS_DRSW_ASANTE: - return MAC8390_ASANTE; - break; - - case NUBUS_DRSW_TECHWORKS: - case NUBUS_DRSW_DAYNA2: - case NUBUS_DRSW_DAYNA_LC: - if (dev->dr_hw == NUBUS_DRHW_CABLETRON) - return MAC8390_CABLETRON; - else - return MAC8390_APPLE; - break; - - case NUBUS_DRSW_FARALLON: - return MAC8390_FARALLON; - break; - - case NUBUS_DRSW_KINETICS: - switch (dev->dr_hw) { - case NUBUS_DRHW_INTERLAN: - return MAC8390_INTERLAN; - break; - default: - return MAC8390_KINETICS; - break; - } - break; - - case NUBUS_DRSW_DAYNA: - // These correspond to Dayna Sonic cards - // which use the macsonic driver - if (dev->dr_hw == NUBUS_DRHW_SMC9194 || - dev->dr_hw == NUBUS_DRHW_INTERLAN ) - return MAC8390_NONE; - else - return MAC8390_DAYNA; - break; - } + if (dev->dr_sw == NUBUS_DRSW_ASANTE) + return MAC8390_ASANTE; + if (dev->dr_sw == NUBUS_DRSW_FARALLON) + return MAC8390_FARALLON; + if (dev->dr_sw == NUBUS_DRSW_KINETICS) + return MAC8390_KINETICS; + if (dev->dr_sw == NUBUS_DRSW_DAYNA) + return MAC8390_DAYNA; + if (dev->dr_sw == NUBUS_DRSW_DAYNA2) + return MAC8390_DAYNA2; + if (dev->dr_sw == NUBUS_DRSW_DAYNA_LC) + return MAC8390_DAYNA3; + if (dev->dr_hw == NUBUS_DRHW_CABLETRON) + return MAC8390_CABLETRON; return MAC8390_NONE; } -enum mac8390_access __init mac8390_testio(volatile unsigned long membase) -{ - unsigned long outdata = 0xA5A0B5B0; - unsigned long indata = 0x00000000; - /* Try writing 32 bits */ - memcpy((char *)membase, (char *)&outdata, 4); - /* Now compare them */ - if (memcmp((char *)&outdata, (char *)membase, 4) == 0) - return ACCESS_32; - /* Write 16 bit output */ - word_memcpy_tocard((char *)membase, (char *)&outdata, 4); - /* Now read it back */ - word_memcpy_fromcard((char *)&indata, (char *)membase, 4); - if (outdata == indata) - return ACCESS_16; - return ACCESS_UNKNOWN; -} - int __init mac8390_memsize(unsigned long membase) { unsigned long flags; @@ -350,6 +287,14 @@ struct net_device * __init mac8390_probe(int unit) continue; } else { nubus_get_rsrc_mem(dev->dev_addr, &ent, 6); + /* Some Sonic Sys cards masquerade as Farallon */ + if (cardtype == MAC8390_FARALLON && + dev->dev_addr[0] == 0x0 && + dev->dev_addr[1] == 0x40 && + dev->dev_addr[2] == 0x10) { + /* This is really Sonic Sys card */ + cardtype = MAC8390_SONICSYS; + } } if (useresources[cardtype] == 1) { @@ -389,17 +334,6 @@ struct net_device * __init mac8390_probe(int unit) dev->mem_start + mac8390_memsize(dev->mem_start); break; - case MAC8390_INTERLAN: - dev->base_addr = - (int)(ndev->board->slot_addr + - INTERLAN_8390_BASE); - dev->mem_start = - (int)(ndev->board->slot_addr + - INTERLAN_8390_MEM); - dev->mem_end = - dev->mem_start + - mac8390_memsize(dev->mem_start); - break; case MAC8390_CABLETRON: dev->base_addr = (int)(ndev->board->slot_addr + @@ -422,8 +356,8 @@ struct net_device * __init mac8390_probe(int unit) default: printk(KERN_ERR "Card type %s is" - " unsupported, sorry\n", - ndev->board->name); + " unsupported, sorry\n", + cardname[cardtype]); continue; } } @@ -504,7 +438,7 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd 24, 26, 28, 30 }; - int access_bitmode = 0; + int access_bitmode; /* Now fill in our stuff */ dev->open = &mac8390_open; @@ -534,47 +468,29 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd /* Fill in model-specific information and functions */ switch(type) { - case MAC8390_FARALLON: - case MAC8390_APPLE: - switch(mac8390_testio(dev->mem_start)) { - case ACCESS_UNKNOWN: - printk("Don't know how to access card memory!\n"); - return -ENODEV; - break; - - case ACCESS_16: - /* 16 bit card, register map is reversed */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; - ei_status.reg_offset = back4_offsets; - break; - - case ACCESS_32: - /* 32 bit card, register map is reversed */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &sane_block_input; - ei_status.block_output = &sane_block_output; - ei_status.get_8390_hdr = &sane_get_8390_hdr; - ei_status.reg_offset = back4_offsets; - access_bitmode = 1; - break; - } - break; - - case MAC8390_ASANTE: - /* Some Asante cards pass the 32 bit test - * but overwrite system memory when run at 32 bit. - * so we run them all at 16 bit. - */ + case MAC8390_SONICSYS: + /* 16 bit card, register map is reversed */ ei_status.reset_8390 = &mac8390_no_reset; ei_status.block_input = &slow_sane_block_input; ei_status.block_output = &slow_sane_block_output; ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; + access_bitmode = 0; + break; + case MAC8390_FARALLON: + case MAC8390_APPLE: + case MAC8390_ASANTE: + case MAC8390_DAYNA2: + case MAC8390_DAYNA3: + /* 32 bit card, register map is reversed */ + /* sane */ + ei_status.reset_8390 = &mac8390_no_reset; + ei_status.block_input = &sane_block_input; + ei_status.block_output = &sane_block_output; + ei_status.get_8390_hdr = &sane_get_8390_hdr; + ei_status.reg_offset = back4_offsets; + access_bitmode = 1; break; - case MAC8390_CABLETRON: /* 16 bit card, register map is short forward */ ei_status.reset_8390 = &mac8390_no_reset; @@ -582,30 +498,21 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd ei_status.block_output = &slow_sane_block_output; ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; ei_status.reg_offset = fwrd2_offsets; + access_bitmode = 0; break; - case MAC8390_DAYNA: case MAC8390_KINETICS: - /* 16 bit memory, register map is forward */ + /* 16 bit memory */ /* dayna and similar */ ei_status.reset_8390 = &mac8390_no_reset; ei_status.block_input = &dayna_block_input; ei_status.block_output = &dayna_block_output; ei_status.get_8390_hdr = &dayna_get_8390_hdr; ei_status.reg_offset = fwrd4_offsets; + access_bitmode = 0; break; - - case MAC8390_INTERLAN: - /* 16 bit memory, register map is forward */ - ei_status.reset_8390 = &interlan_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; - ei_status.reg_offset = fwrd4_offsets; - break; - default: - printk(KERN_ERR "Card type %s is unsupported, sorry\n", ndev->board->name); + printk(KERN_ERR "Card type %s is unsupported, sorry\n", cardname[type]); return -ENODEV; } @@ -623,9 +530,9 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd printk(":"); } } - printk(" IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n", - dev->irq, (int)((dev->mem_end - dev->mem_start)/0x1000) * 4, - dev->mem_start, access_bitmode?32:16); + printk(" IRQ %d, shared memory at %#lx-%#lx, %d-bit access.\n", + dev->irq, dev->mem_start, dev->mem_end-1, + access_bitmode?32:16); return 0; } @@ -654,18 +561,6 @@ static void mac8390_no_reset(struct net_device *dev) return; } -static void interlan_reset(struct net_device *dev) -{ - unsigned char *target=nubus_slot_addr(IRQ2SLOT(dev->irq)); - if (ei_debug > 1) - printk("Need to reset the NS8390 t=%lu...", jiffies); - ei_status.txing = 0; - target[0xC0000] = 0; - if (ei_debug > 1) - printk("reset complete\n"); - return; -} - /* dayna_memcpy_fromio/dayna_memcpy_toio */ /* directly from daynaport.c by Alan Cox */ static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, int count) diff --git a/trunk/drivers/net/mac89x0.c b/trunk/drivers/net/mac89x0.c index 26a3b45a4a34..90e695d53266 100644 --- a/trunk/drivers/net/mac89x0.c +++ b/trunk/drivers/net/mac89x0.c @@ -128,7 +128,7 @@ struct net_local { extern void reset_chip(struct net_device *dev); #endif static int net_open(struct net_device *dev); -static int net_send_packet(struct sk_buff *skb, struct net_device *dev); +static int net_send_packet(struct sk_buff *skb, struct net_device *dev); static irqreturn_t net_interrupt(int irq, void *dev_id); static void set_multicast_list(struct net_device *dev); static void net_rx(struct net_device *dev); @@ -374,39 +374,56 @@ net_open(struct net_device *dev) static int net_send_packet(struct sk_buff *skb, struct net_device *dev) { - struct net_local *lp = netdev_priv(dev); - unsigned long flags; + if (dev->tbusy) { + /* If we get here, some higher level has decided we are broken. + There should really be a "kick me" function call instead. */ + int tickssofar = jiffies - dev->trans_start; + if (tickssofar < 5) + return 1; + if (net_debug > 0) printk("%s: transmit timed out, %s?\n", dev->name, + tx_done(dev) ? "IRQ conflict" : "network cable problem"); + /* Try to restart the adaptor. */ + dev->tbusy=0; + dev->trans_start = jiffies; + } - if (net_debug > 3) - printk("%s: sent %d byte packet of type %x\n", - dev->name, skb->len, - (skb->data[ETH_ALEN+ETH_ALEN] << 8) - | skb->data[ETH_ALEN+ETH_ALEN+1]); + /* Block a timer-based transmit from overlapping. This could better be + done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ + if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) + printk("%s: Transmitter access conflict.\n", dev->name); + else { + struct net_local *lp = netdev_priv(dev); + unsigned long flags; - /* keep the upload from being interrupted, since we - ask the chip to start transmitting before the - whole packet has been completely uploaded. */ - local_irq_save(flags); - netif_stop_queue(dev); + if (net_debug > 3) + printk("%s: sent %d byte packet of type %x\n", + dev->name, skb->len, + (skb->data[ETH_ALEN+ETH_ALEN] << 8) + | skb->data[ETH_ALEN+ETH_ALEN+1]); + + /* keep the upload from being interrupted, since we + ask the chip to start transmitting before the + whole packet has been completely uploaded. */ + local_irq_save(flags); - /* initiate a transmit sequence */ - writereg(dev, PP_TxCMD, lp->send_cmd); - writereg(dev, PP_TxLength, skb->len); + /* initiate a transmit sequence */ + writereg(dev, PP_TxCMD, lp->send_cmd); + writereg(dev, PP_TxLength, skb->len); - /* Test to see if the chip has allocated memory for the packet */ - if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { - /* Gasp! It hasn't. But that shouldn't happen since - we're waiting for TxOk, so return 1 and requeue this packet. */ - local_irq_restore(flags); - return 1; - } + /* Test to see if the chip has allocated memory for the packet */ + if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { + /* Gasp! It hasn't. But that shouldn't happen since + we're waiting for TxOk, so return 1 and requeue this packet. */ + local_irq_restore(flags); + return 1; + } - /* Write the contents of the packet */ - skb_copy_from_linear_data(skb, (void *)(dev->mem_start + PP_TxFrame), - skb->len+1); + /* Write the contents of the packet */ + memcpy_toio(dev->mem_start + PP_TxFrame, skb->data, skb->len+1); - local_irq_restore(flags); - dev->trans_start = jiffies; + local_irq_restore(flags); + dev->trans_start = jiffies; + } dev_kfree_skb (skb); return 0; @@ -424,6 +441,9 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) printk ("net_interrupt(): irq %d for unknown device.\n", irq); return IRQ_NONE; } + if (dev->interrupt) + printk("%s: Re-entering the interrupt handler.\n", dev->name); + dev->interrupt = 1; ioaddr = dev->base_addr; lp = netdev_priv(dev); @@ -444,7 +464,8 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) break; case ISQ_TRANSMITTER_EVENT: lp->stats.tx_packets++; - netif_wake_queue(dev); + dev->tbusy = 0; + mark_bh(NET_BH); /* Inform upper layers. */ if ((status & TX_OK) == 0) lp->stats.tx_errors++; if (status & TX_LOST_CRS) lp->stats.tx_carrier_errors++; if (status & TX_SQE_ERROR) lp->stats.tx_heartbeat_errors++; @@ -458,7 +479,8 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) That shouldn't happen since we only ever load one packet. Shrug. Do the right thing anyway. */ - netif_wake_queue(dev); + dev->tbusy = 0; + mark_bh(NET_BH); /* Inform upper layers. */ } if (status & TX_UNDERRUN) { if (net_debug > 0) printk("%s: transmit underrun\n", dev->name); @@ -475,6 +497,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id) break; } } + dev->interrupt = 0; return IRQ_HANDLED; } @@ -508,8 +531,7 @@ net_rx(struct net_device *dev) } skb_put(skb, length); - skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame), - length); + memcpy_fromio(skb->data, dev->mem_start + PP_RxFrame, length); if (net_debug > 3)printk("%s: received %d byte packet of type %x\n", dev->name, length, @@ -588,6 +610,8 @@ static void set_multicast_list(struct net_device *dev) static int set_mac_address(struct net_device *dev, void *addr) { int i; + if (dev->start) + return -EBUSY; printk("%s: Setting MAC address to ", dev->name); for (i = 0; i < 6; i++) printk(" %2.2x", dev->dev_addr[i] = ((unsigned char *)addr)[i]); diff --git a/trunk/drivers/net/mace.c b/trunk/drivers/net/mace.c index 52b9332810c5..b3bd62394958 100644 --- a/trunk/drivers/net/mace.c +++ b/trunk/drivers/net/mace.c @@ -110,9 +110,9 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i return -ENODEV; } - addr = of_get_property(mace, "mac-address", NULL); + addr = get_property(mace, "mac-address", NULL); if (addr == NULL) { - addr = of_get_property(mace, "local-mac-address", NULL); + addr = get_property(mace, "local-mac-address", NULL); if (addr == NULL) { printk(KERN_ERR "Can't get mac-address for MACE %s\n", mace->full_name); diff --git a/trunk/drivers/net/macmace.c b/trunk/drivers/net/macmace.c index fef3193121f9..27911c07558d 100644 --- a/trunk/drivers/net/macmace.c +++ b/trunk/drivers/net/macmace.c @@ -12,11 +12,6 @@ * Copyright (C) 1998 Alan Cox * * Modified heavily by Joshua M. Thompson based on Dave Huang's NetBSD driver - * - * Copyright (C) 2007 Finn Thain - * - * Converted to DMA API, converted to unified driver model, - * sync'd some routines with mace.c and fixed various bugs. */ @@ -28,9 +23,8 @@ #include #include #include -#include -#include #include +#include #include #include #include @@ -38,20 +32,13 @@ #include #include "mace.h" -static char mac_mace_string[] = "macmace"; -static struct platform_device *mac_mace_device; - -#define N_TX_BUFF_ORDER 0 -#define N_TX_RING (1 << N_TX_BUFF_ORDER) -#define N_RX_BUFF_ORDER 3 -#define N_RX_RING (1 << N_RX_BUFF_ORDER) - +#define N_TX_RING 1 +#define N_RX_RING 8 +#define N_RX_PAGES ((N_RX_RING * 0x0800 + PAGE_SIZE - 1) / PAGE_SIZE) #define TX_TIMEOUT HZ -#define MACE_BUFF_SIZE 0x800 - -/* Chip rev needs workaround on HW & multicast addr change */ -#define BROKEN_ADDRCHG_REV 0x0941 +/* Bits in transmit DMA status */ +#define TX_DMA_ERR 0x80 /* The MACE is simply wired down on a Mac68K box */ @@ -60,46 +47,40 @@ static struct platform_device *mac_mace_device; struct mace_data { volatile struct mace *mace; - unsigned char *tx_ring; - dma_addr_t tx_ring_phys; - unsigned char *rx_ring; - dma_addr_t rx_ring_phys; + volatile unsigned char *tx_ring; + volatile unsigned char *tx_ring_phys; + volatile unsigned char *rx_ring; + volatile unsigned char *rx_ring_phys; int dma_intr; struct net_device_stats stats; int rx_slot, rx_tail; int tx_slot, tx_sloti, tx_count; - int chipid; - struct device *device; }; struct mace_frame { - u8 rcvcnt; - u8 pad1; - u8 rcvsts; - u8 pad2; - u8 rntpc; - u8 pad3; - u8 rcvcc; - u8 pad4; - u32 pad5; - u32 pad6; + u16 len; + u16 status; + u16 rntpc; + u16 rcvcc; + u32 pad1; + u32 pad2; u8 data[1]; /* And frame continues.. */ }; #define PRIV_BYTES sizeof(struct mace_data) +extern void psc_debug_dump(void); + static int mace_open(struct net_device *dev); static int mace_close(struct net_device *dev); static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats *mace_stats(struct net_device *dev); static void mace_set_multicast(struct net_device *dev); static int mace_set_address(struct net_device *dev, void *addr); -static void mace_reset(struct net_device *dev); static irqreturn_t mace_interrupt(int irq, void *dev_id); static irqreturn_t mace_dma_intr(int irq, void *dev_id); static void mace_tx_timeout(struct net_device *dev); -static void __mace_set_address(struct net_device *dev, void *addr); /* * Load a receive DMA channel with a base address and ring length @@ -107,7 +88,7 @@ static void __mace_set_address(struct net_device *dev, void *addr); static void mace_load_rxdma_base(struct net_device *dev, int set) { - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; psc_write_word(PSC_ENETRD_CMD + set, 0x0100); psc_write_long(PSC_ENETRD_ADDR + set, (u32) mp->rx_ring_phys); @@ -122,7 +103,7 @@ static void mace_load_rxdma_base(struct net_device *dev, int set) static void mace_rxdma_reset(struct net_device *dev) { - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mace = mp->mace; u8 maccc = mace->maccc; @@ -149,7 +130,7 @@ static void mace_rxdma_reset(struct net_device *dev) static void mace_txdma_reset(struct net_device *dev) { - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mace = mp->mace; u8 maccc; @@ -187,7 +168,7 @@ static void mace_dma_off(struct net_device *dev) * model of Macintrash has a MACE (AV macintoshes) */ -static int __devinit mace_probe(struct platform_device *pdev) +struct net_device *mace_probe(int unit) { int j; struct mace_data *mp; @@ -198,28 +179,24 @@ static int __devinit mace_probe(struct platform_device *pdev) int err; if (found || macintosh_config->ether_type != MAC_ETHER_MACE) - return -ENODEV; + return ERR_PTR(-ENODEV); found = 1; /* prevent 'finding' one on every device probe */ dev = alloc_etherdev(PRIV_BYTES); if (!dev) - return -ENOMEM; + return ERR_PTR(-ENOMEM); - mp = netdev_priv(dev); - - mp->device = &pdev->dev; - SET_NETDEV_DEV(dev, &pdev->dev); - SET_MODULE_OWNER(dev); + if (unit >= 0) + sprintf(dev->name, "eth%d", unit); + mp = (struct mace_data *) dev->priv; dev->base_addr = (u32)MACE_BASE; mp->mace = (volatile struct mace *) MACE_BASE; dev->irq = IRQ_MAC_MACE; mp->dma_intr = IRQ_MAC_MACE_DMA; - mp->chipid = mp->mace->chipid_hi << 8 | mp->mace->chipid_lo; - /* * The PROM contains 8 bytes which total 0xFF when XOR'd * together. Due to the usual peculiar apple brain damage @@ -240,7 +217,7 @@ static int __devinit mace_probe(struct platform_device *pdev) if (checksum != 0xFF) { free_netdev(dev); - return -ENODEV; + return ERR_PTR(-ENODEV); } memset(&mp->stats, 0, sizeof(mp->stats)); @@ -260,98 +237,22 @@ static int __devinit mace_probe(struct platform_device *pdev) err = register_netdev(dev); if (!err) - return 0; + return dev; free_netdev(dev); - return err; -} - -/* - * Reset the chip. - */ - -static void mace_reset(struct net_device *dev) -{ - struct mace_data *mp = netdev_priv(dev); - volatile struct mace *mb = mp->mace; - int i; - - /* soft-reset the chip */ - i = 200; - while (--i) { - mb->biucc = SWRST; - if (mb->biucc & SWRST) { - udelay(10); - continue; - } - break; - } - if (!i) { - printk(KERN_ERR "macmace: cannot reset chip!\n"); - return; - } - - mb->maccc = 0; /* turn off tx, rx */ - mb->imr = 0xFF; /* disable all intrs for now */ - i = mb->ir; - - mb->biucc = XMTSP_64; - mb->utr = RTRD; - mb->fifocc = XMTFW_8 | RCVFW_64 | XMTFWU | RCVFWU; - - mb->xmtfc = AUTO_PAD_XMIT; /* auto-pad short frames */ - mb->rcvfc = 0; - - /* load up the hardware address */ - __mace_set_address(dev, dev->dev_addr); - - /* clear the multicast filter */ - if (mp->chipid == BROKEN_ADDRCHG_REV) - mb->iac = LOGADDR; - else { - mb->iac = ADDRCHG | LOGADDR; - while ((mb->iac & ADDRCHG) != 0) - ; - } - for (i = 0; i < 8; ++i) - mb->ladrf = 0; - - /* done changing address */ - if (mp->chipid != BROKEN_ADDRCHG_REV) - mb->iac = 0; - - mb->plscc = PORTSEL_AUI; + return ERR_PTR(err); } /* * Load the address on a mace controller. */ -static void __mace_set_address(struct net_device *dev, void *addr) -{ - struct mace_data *mp = netdev_priv(dev); - volatile struct mace *mb = mp->mace; - unsigned char *p = addr; - int i; - - /* load up the hardware address */ - if (mp->chipid == BROKEN_ADDRCHG_REV) - mb->iac = PHYADDR; - else { - mb->iac = ADDRCHG | PHYADDR; - while ((mb->iac & ADDRCHG) != 0) - ; - } - for (i = 0; i < 6; ++i) - mb->padr = dev->dev_addr[i] = p[i]; - if (mp->chipid != BROKEN_ADDRCHG_REV) - mb->iac = 0; -} - static int mace_set_address(struct net_device *dev, void *addr) { - struct mace_data *mp = netdev_priv(dev); + unsigned char *p = addr; + struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; + int i; unsigned long flags; u8 maccc; @@ -359,10 +260,15 @@ static int mace_set_address(struct net_device *dev, void *addr) maccc = mb->maccc; - __mace_set_address(dev, addr); + /* load up the hardware address */ + mb->iac = ADDRCHG | PHYADDR; + while ((mb->iac & ADDRCHG) != 0); - mb->maccc = maccc; + for (i = 0; i < 6; ++i) { + mb->padr = dev->dev_addr[i] = p[i]; + } + mb->maccc = maccc; local_irq_restore(flags); return 0; @@ -375,11 +281,31 @@ static int mace_set_address(struct net_device *dev, void *addr) static int mace_open(struct net_device *dev) { - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; +#if 0 + int i; - /* reset the chip */ - mace_reset(dev); + i = 200; + while (--i) { + mb->biucc = SWRST; + if (mb->biucc & SWRST) { + udelay(10); + continue; + } + break; + } + if (!i) { + printk(KERN_ERR "%s: software reset failed!!\n", dev->name); + return -EAGAIN; + } +#endif + + mb->biucc = XMTSP_64; + mb->fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST; + mb->xmtfc = AUTO_PAD_XMIT; + mb->plscc = PORTSEL_AUI; + /* mb->utr = RTRD; */ if (request_irq(dev->irq, mace_interrupt, 0, dev->name, dev)) { printk(KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq); @@ -393,22 +319,26 @@ static int mace_open(struct net_device *dev) /* Allocate the DMA ring buffers */ - mp->tx_ring = dma_alloc_coherent(mp->device, - N_TX_RING * MACE_BUFF_SIZE, - &mp->tx_ring_phys, GFP_KERNEL); - if (mp->tx_ring == NULL) { - printk(KERN_ERR "%s: unable to allocate DMA tx buffers\n", dev->name); - goto out1; - } + mp->rx_ring = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, N_RX_PAGES); + mp->tx_ring = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, 0); - mp->rx_ring = dma_alloc_coherent(mp->device, - N_RX_RING * MACE_BUFF_SIZE, - &mp->rx_ring_phys, GFP_KERNEL); - if (mp->rx_ring == NULL) { - printk(KERN_ERR "%s: unable to allocate DMA rx buffers\n", dev->name); - goto out2; + if (mp->tx_ring==NULL || mp->rx_ring==NULL) { + if (mp->rx_ring) free_pages((u32) mp->rx_ring, N_RX_PAGES); + if (mp->tx_ring) free_pages((u32) mp->tx_ring, 0); + free_irq(dev->irq, dev); + free_irq(mp->dma_intr, dev); + printk(KERN_ERR "%s: unable to allocate DMA buffers\n", dev->name); + return -ENOMEM; } + mp->rx_ring_phys = (unsigned char *) virt_to_bus((void *)mp->rx_ring); + mp->tx_ring_phys = (unsigned char *) virt_to_bus((void *)mp->tx_ring); + + /* We want the Rx buffer to be uncached and the Tx buffer to be writethrough */ + + kernel_set_cachemode((void *)mp->rx_ring, N_RX_PAGES * PAGE_SIZE, IOMAP_NOCACHE_NONSER); + kernel_set_cachemode((void *)mp->tx_ring, PAGE_SIZE, IOMAP_WRITETHROUGH); + mace_dma_off(dev); /* Not sure what these do */ @@ -418,22 +348,34 @@ static int mace_open(struct net_device *dev) psc_write_word(PSC_ENETWR_CTL, 0x0400); psc_write_word(PSC_ENETRD_CTL, 0x0400); - mace_rxdma_reset(dev); - mace_txdma_reset(dev); +#if 0 + /* load up the hardware address */ + + mb->iac = ADDRCHG | PHYADDR; + + while ((mb->iac & ADDRCHG) != 0); + + for (i = 0; i < 6; ++i) + mb->padr = dev->dev_addr[i]; + + /* clear the multicast filter */ + mb->iac = ADDRCHG | LOGADDR; + + while ((mb->iac & ADDRCHG) != 0); + + for (i = 0; i < 8; ++i) + mb->ladrf = 0; + + mb->plscc = PORTSEL_GPSI + ENPLSIO; - /* turn it on! */ mb->maccc = ENXMT | ENRCV; - /* enable all interrupts except receive interrupts */ mb->imr = RCVINT; - return 0; +#endif -out2: - dma_free_coherent(mp->device, N_TX_RING * MACE_BUFF_SIZE, - mp->tx_ring, mp->tx_ring_phys); -out1: - free_irq(dev->irq, dev); - free_irq(mp->dma_intr, dev); - return -ENOMEM; + mace_rxdma_reset(dev); + mace_txdma_reset(dev); + + return 0; } /* @@ -442,13 +384,19 @@ static int mace_open(struct net_device *dev) static int mace_close(struct net_device *dev) { - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; mb->maccc = 0; /* disable rx and tx */ mb->imr = 0xFF; /* disable all irqs */ mace_dma_off(dev); /* disable rx and tx dma */ + free_irq(dev->irq, dev); + free_irq(IRQ_MAC_MACE_DMA, dev); + + free_pages((u32) mp->rx_ring, N_RX_PAGES); + free_pages((u32) mp->tx_ring, 0); + return 0; } @@ -458,20 +406,15 @@ static int mace_close(struct net_device *dev) static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev) { - struct mace_data *mp = netdev_priv(dev); - unsigned long flags; + struct mace_data *mp = (struct mace_data *) dev->priv; - /* Stop the queue since there's only the one buffer */ + /* Stop the queue if the buffer is full */ - local_irq_save(flags); - netif_stop_queue(dev); if (!mp->tx_count) { - printk(KERN_ERR "macmace: tx queue running but no free buffers.\n"); - local_irq_restore(flags); - return NETDEV_TX_BUSY; + netif_stop_queue(dev); + return 1; } mp->tx_count--; - local_irq_restore(flags); mp->stats.tx_packets++; mp->stats.tx_bytes += skb->len; @@ -489,26 +432,23 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb(skb); - dev->trans_start = jiffies; - return NETDEV_TX_OK; + return 0; } static struct net_device_stats *mace_stats(struct net_device *dev) { - struct mace_data *mp = netdev_priv(dev); - return &mp->stats; + struct mace_data *p = (struct mace_data *) dev->priv; + return &p->stats; } static void mace_set_multicast(struct net_device *dev) { - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; int i, j; u32 crc; u8 maccc; - unsigned long flags; - local_irq_save(flags); maccc = mb->maccc; mb->maccc &= ~PROM; @@ -533,122 +473,116 @@ static void mace_set_multicast(struct net_device *dev) } } - if (mp->chipid == BROKEN_ADDRCHG_REV) - mb->iac = LOGADDR; - else { - mb->iac = ADDRCHG | LOGADDR; - while ((mb->iac & ADDRCHG) != 0) - ; - } - for (i = 0; i < 8; ++i) + mb->iac = ADDRCHG | LOGADDR; + while (mb->iac & ADDRCHG); + + for (i = 0; i < 8; ++i) { mb->ladrf = multicast_filter[i]; - if (mp->chipid != BROKEN_ADDRCHG_REV) - mb->iac = 0; + } } mb->maccc = maccc; - local_irq_restore(flags); } +/* + * Miscellaneous interrupts are handled here. We may end up + * having to bash the chip on the head for bad errors + */ + static void mace_handle_misc_intrs(struct mace_data *mp, int intr) { volatile struct mace *mb = mp->mace; static int mace_babbles, mace_jabbers; - if (intr & MPCO) + if (intr & MPCO) { mp->stats.rx_missed_errors += 256; - mp->stats.rx_missed_errors += mb->mpc; /* reading clears it */ - if (intr & RNTPCO) + } + mp->stats.rx_missed_errors += mb->mpc; /* reading clears it */ + + if (intr & RNTPCO) { mp->stats.rx_length_errors += 256; - mp->stats.rx_length_errors += mb->rntpc; /* reading clears it */ - if (intr & CERR) + } + mp->stats.rx_length_errors += mb->rntpc; /* reading clears it */ + + if (intr & CERR) { ++mp->stats.tx_heartbeat_errors; - if (intr & BABBLE) - if (mace_babbles++ < 4) - printk(KERN_DEBUG "macmace: babbling transmitter\n"); - if (intr & JABBER) - if (mace_jabbers++ < 4) - printk(KERN_DEBUG "macmace: jabbering transceiver\n"); + } + if (intr & BABBLE) { + if (mace_babbles++ < 4) { + printk(KERN_DEBUG "mace: babbling transmitter\n"); + } + } + if (intr & JABBER) { + if (mace_jabbers++ < 4) { + printk(KERN_DEBUG "mace: jabbering transceiver\n"); + } + } } -static irqreturn_t mace_interrupt(int irq, void *dev_id) +/* + * A transmit error has occurred. (We kick the transmit side from + * the DMA completion) + */ + +static void mace_xmit_error(struct net_device *dev) { - struct net_device *dev = (struct net_device *) dev_id; - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; - int intr, fs; - unsigned int flags; + u8 xmtfs, xmtrc; - /* don't want the dma interrupt handler to fire */ - local_irq_save(flags); + xmtfs = mb->xmtfs; + xmtrc = mb->xmtrc; - intr = mb->ir; /* read interrupt register */ - mace_handle_misc_intrs(mp, intr); - - if (intr & XMTINT) { - fs = mb->xmtfs; - if ((fs & XMTSV) == 0) { - printk(KERN_ERR "macmace: xmtfs not valid! (fs=%x)\n", fs); - mace_reset(dev); - /* - * XXX mace likes to hang the machine after a xmtfs error. - * This is hard to reproduce, reseting *may* help - */ + if (xmtfs & XMTSV) { + if (xmtfs & UFLO) { + printk("%s: DMA underrun.\n", dev->name); + mp->stats.tx_errors++; + mp->stats.tx_fifo_errors++; + mace_txdma_reset(dev); } - /* dma should have finished */ - if (!mp->tx_count) { - printk(KERN_DEBUG "macmace: tx ring ran out? (fs=%x)\n", fs); - } - /* Update stats */ - if (fs & (UFLO|LCOL|LCAR|RTRY)) { - ++mp->stats.tx_errors; - if (fs & LCAR) - ++mp->stats.tx_carrier_errors; - else if (fs & (UFLO|LCOL|RTRY)) { - ++mp->stats.tx_aborted_errors; - if (mb->xmtfs & UFLO) { - printk(KERN_ERR "%s: DMA underrun.\n", dev->name); - mp->stats.tx_fifo_errors++; - mace_txdma_reset(dev); - } - } + if (xmtfs & RTRY) { + mp->stats.collisions++; } } +} - if (mp->tx_count) - netif_wake_queue(dev); - - local_irq_restore(flags); +/* + * A receive interrupt occurred. + */ - return IRQ_HANDLED; +static void mace_recv_interrupt(struct net_device *dev) +{ +/* struct mace_data *mp = (struct mace_data *) dev->priv; */ +// volatile struct mace *mb = mp->mace; } -static void mace_tx_timeout(struct net_device *dev) +/* + * Process the chip interrupt + */ + +static irqreturn_t mace_interrupt(int irq, void *dev_id) { - struct mace_data *mp = netdev_priv(dev); + struct net_device *dev = (struct net_device *) dev_id; + struct mace_data *mp = (struct mace_data *) dev->priv; volatile struct mace *mb = mp->mace; - unsigned long flags; + u8 ir; - local_irq_save(flags); - - /* turn off both tx and rx and reset the chip */ - mb->maccc = 0; - printk(KERN_ERR "macmace: transmit timeout - resetting\n"); - mace_txdma_reset(dev); - mace_reset(dev); - - /* restart rx dma */ - mace_rxdma_reset(dev); - - mp->tx_count = N_TX_RING; - netif_wake_queue(dev); + ir = mb->ir; + mace_handle_misc_intrs(mp, ir); - /* turn it on! */ - mb->maccc = ENXMT | ENRCV; - /* enable all interrupts except receive interrupts */ - mb->imr = RCVINT; + if (ir & XMTINT) { + mace_xmit_error(dev); + } + if (ir & RCVINT) { + mace_recv_interrupt(dev); + } + return IRQ_HANDLED; +} - local_irq_restore(flags); +static void mace_tx_timeout(struct net_device *dev) +{ +/* struct mace_data *mp = (struct mace_data *) dev->priv; */ +// volatile struct mace *mb = mp->mace; } /* @@ -657,39 +591,40 @@ static void mace_tx_timeout(struct net_device *dev) static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf) { - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; struct sk_buff *skb; - unsigned int frame_status = mf->rcvsts; - if (frame_status & (RS_OFLO | RS_CLSN | RS_FRAMERR | RS_FCSERR)) { + if (mf->status & RS_OFLO) { + printk("%s: fifo overflow.\n", dev->name); + mp->stats.rx_errors++; + mp->stats.rx_fifo_errors++; + } + if (mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR)) mp->stats.rx_errors++; - if (frame_status & RS_OFLO) { - printk(KERN_DEBUG "%s: fifo overflow.\n", dev->name); - mp->stats.rx_fifo_errors++; - } - if (frame_status & RS_CLSN) - mp->stats.collisions++; - if (frame_status & RS_FRAMERR) - mp->stats.rx_frame_errors++; - if (frame_status & RS_FCSERR) - mp->stats.rx_crc_errors++; - } else { - unsigned int frame_length = mf->rcvcnt + ((frame_status & 0x0F) << 8 ); - skb = dev_alloc_skb(frame_length + 2); - if (!skb) { - mp->stats.rx_dropped++; - return; - } - skb_reserve(skb, 2); - memcpy(skb_put(skb, frame_length), mf->data, frame_length); - - skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); - dev->last_rx = jiffies; - mp->stats.rx_packets++; - mp->stats.rx_bytes += frame_length; + if (mf->status&RS_CLSN) { + mp->stats.collisions++; + } + if (mf->status&RS_FRAMERR) { + mp->stats.rx_frame_errors++; } + if (mf->status&RS_FCSERR) { + mp->stats.rx_crc_errors++; + } + + skb = dev_alloc_skb(mf->len+2); + if (!skb) { + mp->stats.rx_dropped++; + return; + } + skb_reserve(skb,2); + memcpy(skb_put(skb, mf->len), mf->data, mf->len); + + skb->protocol = eth_type_trans(skb, dev); + netif_rx(skb); + dev->last_rx = jiffies; + mp->stats.rx_packets++; + mp->stats.rx_bytes += mf->len; } /* @@ -699,7 +634,7 @@ static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf) static irqreturn_t mace_dma_intr(int irq, void *dev_id) { struct net_device *dev = (struct net_device *) dev_id; - struct mace_data *mp = netdev_priv(dev); + struct mace_data *mp = (struct mace_data *) dev->priv; int left, head; u16 status; u32 baka; @@ -726,8 +661,7 @@ static irqreturn_t mace_dma_intr(int irq, void *dev_id) /* Loop through the ring buffer and process new packages */ while (mp->rx_tail < head) { - mace_dma_rx_frame(dev, (struct mace_frame*) (mp->rx_ring - + (mp->rx_tail * MACE_BUFF_SIZE))); + mace_dma_rx_frame(dev, (struct mace_frame *) (mp->rx_ring + (mp->rx_tail * 0x0800))); mp->rx_tail++; } @@ -754,76 +688,9 @@ static irqreturn_t mace_dma_intr(int irq, void *dev_id) psc_write_word(PSC_ENETWR_CMD + mp->tx_sloti, 0x0100); mp->tx_sloti ^= 0x10; mp->tx_count++; + netif_wake_queue(dev); } return IRQ_HANDLED; } MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Macintosh MACE ethernet driver"); - -static int __devexit mac_mace_device_remove (struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct mace_data *mp = netdev_priv(dev); - - unregister_netdev(dev); - - free_irq(dev->irq, dev); - free_irq(IRQ_MAC_MACE_DMA, dev); - - dma_free_coherent(mp->device, N_RX_RING * MACE_BUFF_SIZE, - mp->rx_ring, mp->rx_ring_phys); - dma_free_coherent(mp->device, N_TX_RING * MACE_BUFF_SIZE, - mp->tx_ring, mp->tx_ring_phys); - - free_netdev(dev); - - return 0; -} - -static struct platform_driver mac_mace_driver = { - .probe = mace_probe, - .remove = __devexit_p(mac_mace_device_remove), - .driver = { - .name = mac_mace_string, - }, -}; - -static int __init mac_mace_init_module(void) -{ - int err; - - if ((err = platform_driver_register(&mac_mace_driver))) { - printk(KERN_ERR "Driver registration failed\n"); - return err; - } - - mac_mace_device = platform_device_alloc(mac_mace_string, 0); - if (!mac_mace_device) - goto out_unregister; - - if (platform_device_add(mac_mace_device)) { - platform_device_put(mac_mace_device); - mac_mace_device = NULL; - } - - return 0; - -out_unregister: - platform_driver_unregister(&mac_mace_driver); - - return -ENOMEM; -} - -static void __exit mac_mace_cleanup_module(void) -{ - platform_driver_unregister(&mac_mace_driver); - - if (mac_mace_device) { - platform_device_unregister(mac_mace_device); - mac_mace_device = NULL; - } -} - -module_init(mac_mace_init_module); -module_exit(mac_mace_cleanup_module); diff --git a/trunk/drivers/net/macsonic.c b/trunk/drivers/net/macsonic.c index e9ecdbf352ae..8ca57a0a4c11 100644 --- a/trunk/drivers/net/macsonic.c +++ b/trunk/drivers/net/macsonic.c @@ -130,46 +130,6 @@ static inline void bit_reverse_addr(unsigned char addr[6]) addr[i] = bitrev8(addr[i]); } -static irqreturn_t macsonic_interrupt(int irq, void *dev_id) -{ - irqreturn_t result; - unsigned long flags; - - local_irq_save(flags); - result = sonic_interrupt(irq, dev_id); - local_irq_restore(flags); - return result; -} - -static int macsonic_open(struct net_device* dev) -{ - if (request_irq(dev->irq, &sonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) { - printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq); - return -EAGAIN; - } - /* Under the A/UX interrupt scheme, the onboard SONIC interrupt comes - * in at priority level 3. However, we sometimes get the level 2 inter- - * rupt as well, which must prevent re-entrance of the sonic handler. - */ - if (dev->irq == IRQ_AUTO_3) - if (request_irq(IRQ_NUBUS_9, &macsonic_interrupt, IRQ_FLG_FAST, "sonic", dev)) { - printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, IRQ_NUBUS_9); - free_irq(dev->irq, dev); - return -EAGAIN; - } - return sonic_open(dev); -} - -static int macsonic_close(struct net_device* dev) -{ - int err; - err = sonic_close(dev); - free_irq(dev->irq, dev); - if (dev->irq == IRQ_AUTO_3) - free_irq(IRQ_NUBUS_9, dev); - return err; -} - int __init macsonic_init(struct net_device* dev) { struct sonic_local* lp = netdev_priv(dev); @@ -200,8 +160,8 @@ int __init macsonic_init(struct net_device* dev) lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS * SONIC_BUS_SCALE(lp->dma_bitmode)); - dev->open = macsonic_open; - dev->stop = macsonic_close; + dev->open = sonic_open; + dev->stop = sonic_close; dev->hard_start_xmit = sonic_send_packet; dev->get_stats = sonic_get_stats; dev->set_multicast_list = &sonic_multicast_list; @@ -442,7 +402,7 @@ int __init macsonic_ident(struct nubus_dev* ndev) ndev->dr_sw == NUBUS_DRSW_DAYNA) return MACSONIC_DAYNA; - if (ndev->dr_hw == NUBUS_DRHW_APPLE_SONIC_LC && + if (ndev->dr_hw == NUBUS_DRHW_SONIC_LC && ndev->dr_sw == 0) { /* huh? */ return MACSONIC_APPLE16; } @@ -562,7 +522,7 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) return macsonic_init(dev); } -static int __init mac_sonic_probe(struct platform_device *pdev) +static int __init mac_sonic_probe(struct platform_device *device) { struct net_device *dev; struct sonic_local *lp; @@ -574,8 +534,8 @@ static int __init mac_sonic_probe(struct platform_device *pdev) return -ENOMEM; lp = netdev_priv(dev); - lp->device = &pdev->dev; - SET_NETDEV_DEV(dev, &pdev->dev); + lp->device = &device->dev; + SET_NETDEV_DEV(dev, &device->dev); SET_MODULE_OWNER(dev); /* This will catch fatal stuff like -ENOMEM as well as success */ @@ -612,17 +572,19 @@ MODULE_DESCRIPTION("Macintosh SONIC ethernet driver"); module_param(sonic_debug, int, 0); MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); +#define SONIC_IRQ_FLAG IRQ_FLG_FAST + #include "sonic.c" -static int __devexit mac_sonic_device_remove (struct platform_device *pdev) +static int __devexit mac_sonic_device_remove (struct platform_device *device) { - struct net_device *dev = platform_get_drvdata(pdev); + struct net_device *dev = platform_get_drvdata(device); struct sonic_local* lp = netdev_priv(dev); - unregister_netdev(dev); + unregister_netdev (dev); dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), lp->descriptors, lp->descriptors_laddr); - free_netdev(dev); + free_netdev (dev); return 0; } @@ -645,8 +607,9 @@ static int __init mac_sonic_init_module(void) } mac_sonic_device = platform_device_alloc(mac_sonic_string, 0); - if (!mac_sonic_device) + if (!mac_sonic_device) { goto out_unregister; + } if (platform_device_add(mac_sonic_device)) { platform_device_put(mac_sonic_device); diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 5d14be7405a3..16e3c4315e82 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -290,8 +290,6 @@ MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8) -static void myri10ge_set_multicast_list(struct net_device *dev); - static inline void put_be32(__be32 val, __be32 __iomem * p) { __raw_writel((__force __u32) val, (__force void __iomem *)p); @@ -355,8 +353,6 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, return 0; } else if (result == MXGEFW_CMD_UNKNOWN) { return -ENOSYS; - } else if (result == MXGEFW_CMD_ERROR_UNALIGNED) { - return -E2BIG; } else { dev_err(&mgp->pdev->dev, "command %d failed, result = %d\n", @@ -716,78 +712,14 @@ myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic) mgp->dev->name); } -static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type) +static int myri10ge_reset(struct myri10ge_priv *mgp) { struct myri10ge_cmd cmd; int status; + size_t bytes; u32 len; struct page *dmatest_page; dma_addr_t dmatest_bus; - char *test = " "; - - dmatest_page = alloc_page(GFP_KERNEL); - if (!dmatest_page) - return -ENOMEM; - dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE, - DMA_BIDIRECTIONAL); - - /* Run a small DMA test. - * The magic multipliers to the length tell the firmware - * to do DMA read, write, or read+write tests. The - * results are returned in cmd.data0. The upper 16 - * bits or the return is the number of transfers completed. - * The lower 16 bits is the time in 0.5us ticks that the - * transfers took to complete. - */ - - len = mgp->tx.boundary; - - cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); - cmd.data2 = len * 0x10000; - status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); - if (status != 0) { - test = "read"; - goto abort; - } - mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff); - cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); - cmd.data2 = len * 0x1; - status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); - if (status != 0) { - test = "write"; - goto abort; - } - mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff); - - cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); - cmd.data2 = len * 0x10001; - status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); - if (status != 0) { - test = "read/write"; - goto abort; - } - mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) / - (cmd.data0 & 0xffff); - -abort: - pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL); - put_page(dmatest_page); - - if (status != 0 && test_type != MXGEFW_CMD_UNALIGNED_TEST) - dev_warn(&mgp->pdev->dev, "DMA %s benchmark failed: %d\n", - test, status); - - return status; -} - -static int myri10ge_reset(struct myri10ge_priv *mgp) -{ - struct myri10ge_cmd cmd; - int status; - size_t bytes; /* try to send a reset command to the card to see if it * is alive */ @@ -797,8 +729,11 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) dev_err(&mgp->pdev->dev, "failed reset\n"); return -ENXIO; } - - (void)myri10ge_dma_test(mgp, MXGEFW_DMA_TEST); + dmatest_page = alloc_page(GFP_KERNEL); + if (!dmatest_page) + return -ENOMEM; + dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE, + DMA_BIDIRECTIONAL); /* Now exchange information about interrupts */ @@ -826,6 +761,52 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); + /* Run a small DMA test. + * The magic multipliers to the length tell the firmware + * to do DMA read, write, or read+write tests. The + * results are returned in cmd.data0. The upper 16 + * bits or the return is the number of transfers completed. + * The lower 16 bits is the time in 0.5us ticks that the + * transfers took to complete. + */ + + len = mgp->tx.boundary; + + cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); + cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); + cmd.data2 = len * 0x10000; + status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); + if (status == 0) + mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / + (cmd.data0 & 0xffff); + else + dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n", + status); + cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); + cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); + cmd.data2 = len * 0x1; + status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); + if (status == 0) + mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / + (cmd.data0 & 0xffff); + else + dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n", + status); + + cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); + cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); + cmd.data2 = len * 0x10001; + status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); + if (status == 0) + mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) / + (cmd.data0 & 0xffff); + else + dev_warn(&mgp->pdev->dev, + "DMA read/write benchmark failed: %d\n", status); + + pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL); + put_page(dmatest_page); + memset(mgp->rx_done.entry, 0, bytes); /* reset mcp/driver shared state back to 0 */ @@ -839,8 +820,10 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) mgp->rx_done.cnt = 0; mgp->link_changes = 0; status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); + myri10ge_change_promisc(mgp, 0, 0); myri10ge_change_pause(mgp, mgp->pause); - myri10ge_set_multicast_list(mgp->dev); + if (mgp->adopted_rx_filter_bug) + (void)myri10ge_send_cmd(mgp, MXGEFW_ENABLE_ALLMULTI, &cmd, 1); return status; } @@ -1372,9 +1355,7 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", "wake_queue", "stop_queue", "watchdog_resets", "tx_linearized", "link_changes", "link_up", "dropped_link_overflow", - "dropped_link_error_or_filtered", - "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32", - "dropped_unicast_filtered", "dropped_multicast_filtered", + "dropped_link_error_or_filtered", "dropped_multicast_filtered", "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", "dropped_no_big_buffer" }; @@ -1431,11 +1412,6 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy); - data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32); - data[i++] = - (unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt); @@ -2300,7 +2276,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev) myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1); /* This firmware is known to not support multicast */ - if (!mgp->fw_multicast_support) + if (!mgp->fw_multicast_support || mgp->adopted_rx_filter_bug) return; /* Disable multicast filtering */ @@ -2312,7 +2288,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev) goto abort; } - if ((dev->flags & IFF_ALLMULTI) || mgp->adopted_rx_filter_bug) { + if (dev->flags & IFF_ALLMULTI) { /* request to disable multicast filtering, so quit here */ return; } @@ -2485,6 +2461,8 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) err_cap |= PCI_ERR_CAP_ECRC_GENE; pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap); dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge)); + mgp->tx.boundary = 4096; + mgp->fw_name = myri10ge_fw_aligned; } /* @@ -2506,70 +2484,22 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) * firmware image, and set tx.boundary to 4KB. */ -static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) -{ - struct pci_dev *pdev = mgp->pdev; - struct device *dev = &pdev->dev; - int cap, status; - u16 val; - - mgp->tx.boundary = 4096; - /* - * Verify the max read request size was set to 4KB - * before trying the test with 4KB. - */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (cap < 64) { - dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap); - goto abort; - } - status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val); - if (status != 0) { - dev_err(dev, "Couldn't read max read req size: %d\n", status); - goto abort; - } - if ((val & (5 << 12)) != (5 << 12)) { - dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val); - mgp->tx.boundary = 2048; - } - /* - * load the optimized firmware (which assumes aligned PCIe - * completions) in order to see if it works on this host. - */ - mgp->fw_name = myri10ge_fw_aligned; - status = myri10ge_load_firmware(mgp); - if (status != 0) { - goto abort; - } - - /* - * Enable ECRC if possible - */ - myri10ge_enable_ecrc(mgp); +#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 +#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa +#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510 +#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b +#define PCI_DEVICE_ID_INTEL_E3000_PCIE 0x2779 +#define PCI_DEVICE_ID_INTEL_E3010_PCIE 0x277a +#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140 +#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142 - /* - * Run a DMA test which watches for unaligned completions and - * aborts on the first one seen. - */ - - status = myri10ge_dma_test(mgp, MXGEFW_CMD_UNALIGNED_TEST); - if (status == 0) - return; /* keep the aligned firmware */ +static void myri10ge_select_firmware(struct myri10ge_priv *mgp) +{ + struct pci_dev *bridge = mgp->pdev->bus->self; - if (status != -E2BIG) - dev_warn(dev, "DMA test failed: %d\n", status); - if (status == -ENOSYS) - dev_warn(dev, "Falling back to ethp! " - "Please install up to date fw\n"); -abort: - /* fall back to using the unaligned firmware */ mgp->tx.boundary = 2048; mgp->fw_name = myri10ge_fw_unaligned; -} - -static void myri10ge_select_firmware(struct myri10ge_priv *mgp) -{ if (myri10ge_force_firmware == 0) { int link_width, exp_cap; u16 lnk; @@ -2578,6 +2508,8 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk); link_width = (lnk >> 4) & 0x3f; + myri10ge_enable_ecrc(mgp); + /* Check to see if Link is less than 8 or if the * upstream bridge is known to provide aligned * completions */ @@ -2586,8 +2518,46 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) link_width); mgp->tx.boundary = 4096; mgp->fw_name = myri10ge_fw_aligned; - } else { - myri10ge_firmware_probe(mgp); + } else if (bridge && + /* ServerWorks HT2000/HT1000 */ + ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS + && bridge->device == + PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) + /* ServerWorks HT2100 */ + || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS + && bridge->device >= + PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST + && bridge->device <= + PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST) + /* All Intel E3000/E3010 PCIE ports */ + || (bridge->vendor == PCI_VENDOR_ID_INTEL + && (bridge->device == + PCI_DEVICE_ID_INTEL_E3000_PCIE + || bridge->device == + PCI_DEVICE_ID_INTEL_E3010_PCIE)) + /* All Intel 6310/6311/6321ESB PCIE ports */ + || (bridge->vendor == PCI_VENDOR_ID_INTEL + && bridge->device >= + PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 + && bridge->device <= + PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4) + /* All Intel E5000 PCIE ports */ + || (bridge->vendor == PCI_VENDOR_ID_INTEL + && bridge->device >= + PCI_DEVICE_ID_INTEL_E5000_PCIE23 + && bridge->device <= + PCI_DEVICE_ID_INTEL_E5000_PCIE47))) { + dev_info(&mgp->pdev->dev, + "Assuming aligned completions (0x%x:0x%x)\n", + bridge->vendor, bridge->device); + mgp->tx.boundary = 4096; + mgp->fw_name = myri10ge_fw_aligned; + } else if (bridge && + bridge->vendor == PCI_VENDOR_ID_SGI && + bridge->device == 0x4002 /* TIOCE pcie-port */ ) { + /* this pcie bridge does not support 4K rdma request */ + mgp->tx.boundary = 2048; + mgp->fw_name = myri10ge_fw_aligned; } } else { if (myri10ge_force_firmware == 1) { @@ -2855,6 +2825,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) status = -ENODEV; goto abort_with_netdev; } + myri10ge_select_firmware(mgp); /* Find the vendor-specific cap so we can check * the reboot register later on */ @@ -2948,8 +2919,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto abort_with_ioremap; memset(mgp->rx_done.entry, 0, bytes); - myri10ge_select_firmware(mgp); - status = myri10ge_load_firmware(mgp); if (status != 0) { dev_err(&pdev->dev, "failed to load firmware\n"); diff --git a/trunk/drivers/net/myri10ge/myri10ge_mcp.h b/trunk/drivers/net/myri10ge/myri10ge_mcp.h index a1d2a22296a9..29463b301a84 100644 --- a/trunk/drivers/net/myri10ge/myri10ge_mcp.h +++ b/trunk/drivers/net/myri10ge/myri10ge_mcp.h @@ -200,13 +200,6 @@ enum myri10ge_mcp_cmd_type { /* data0, data1 = bus addr, * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows * adding new stuff to mcp_irq_data without changing the ABI */ - - MXGEFW_CMD_UNALIGNED_TEST, - /* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned - * chipset */ - - MXGEFW_CMD_UNALIGNED_STATUS - /* return data = boolean, true if the chipset is known to be unaligned */ }; enum myri10ge_mcp_cmd_status { @@ -219,27 +212,18 @@ enum myri10ge_mcp_cmd_status { MXGEFW_CMD_ERROR_HASH_ERROR, MXGEFW_CMD_ERROR_BAD_PORT, MXGEFW_CMD_ERROR_RESOURCES, - MXGEFW_CMD_ERROR_MULTICAST, - MXGEFW_CMD_ERROR_UNALIGNED + MXGEFW_CMD_ERROR_MULTICAST }; #define MXGEFW_OLD_IRQ_DATA_LEN 40 struct mcp_irq_data { /* add new counters at the beginning */ - __be32 future_use[1]; - __be32 dropped_pause; - __be32 dropped_unicast_filtered; - __be32 dropped_bad_crc32; - __be32 dropped_bad_phy; + __be32 future_use[5]; __be32 dropped_multicast_filtered; /* 40 Bytes */ __be32 send_done_count; -#define MXGEFW_LINK_DOWN 0 -#define MXGEFW_LINK_UP 1 -#define MXGEFW_LINK_MYRINET 2 -#define MXGEFW_LINK_UNKNOWN 3 __be32 link_up; __be32 dropped_link_overflow; __be32 dropped_link_error_or_filtered; diff --git a/trunk/drivers/net/natsemi.c b/trunk/drivers/net/natsemi.c index 223e0e6264ba..a8d7ff2c96ac 100644 --- a/trunk/drivers/net/natsemi.c +++ b/trunk/drivers/net/natsemi.c @@ -81,8 +81,6 @@ static const int multicast_filter_limit = 100; Setting to > 1518 effectively disables this feature. */ static int rx_copybreak; -static int dspcfg_workaround = 1; - /* Used to pass the media type, etc. Both 'options[]' and 'full_duplex[]' should exist for driver interoperability. @@ -141,14 +139,12 @@ MODULE_LICENSE("GPL"); module_param(mtu, int, 0); module_param(debug, int, 0); module_param(rx_copybreak, int, 0); -module_param(dspcfg_workaround, int, 1); module_param_array(options, int, NULL, 0); module_param_array(full_duplex, int, NULL, 0); MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)"); MODULE_PARM_DESC(debug, "DP8381x default debug level"); MODULE_PARM_DESC(rx_copybreak, "DP8381x copy breakpoint for copy-only-tiny-frames"); -MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround"); MODULE_PARM_DESC(options, "DP8381x: Bits 0-3: media type, bit 17: full duplex"); MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)"); @@ -594,7 +590,6 @@ struct netdev_private { u32 srr; /* expected DSPCFG value */ u16 dspcfg; - int dspcfg_workaround; /* parms saved in ethtool format */ u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ u8 duplex; /* Duplex, half or full */ @@ -661,56 +656,6 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf); static int netdev_get_eeprom(struct net_device *dev, u8 *buf); static const struct ethtool_ops ethtool_ops; -#define NATSEMI_ATTR(_name) \ -static ssize_t natsemi_show_##_name(struct device *dev, \ - struct device_attribute *attr, char *buf); \ - static ssize_t natsemi_set_##_name(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count); \ - static DEVICE_ATTR(_name, 0644, natsemi_show_##_name, natsemi_set_##_name) - -#define NATSEMI_CREATE_FILE(_dev, _name) \ - device_create_file(&_dev->dev, &dev_attr_##_name) -#define NATSEMI_REMOVE_FILE(_dev, _name) \ - device_create_file(&_dev->dev, &dev_attr_##_name) - -NATSEMI_ATTR(dspcfg_workaround); - -static ssize_t natsemi_show_dspcfg_workaround(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct netdev_private *np = netdev_priv(to_net_dev(dev)); - - return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off"); -} - -static ssize_t natsemi_set_dspcfg_workaround(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct netdev_private *np = netdev_priv(to_net_dev(dev)); - int new_setting; - u32 flags; - - /* Find out the new setting */ - if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1)) - new_setting = 1; - else if (!strncmp("off", buf, count - 1) - || !strncmp("0", buf, count - 1)) - new_setting = 0; - else - return count; - - spin_lock_irqsave(&np->lock, flags); - - np->dspcfg_workaround = new_setting; - - spin_unlock_irqrestore(&np->lock, flags); - - return count; -} - static inline void __iomem *ns_ioaddr(struct net_device *dev) { return (void __iomem *) dev->base_addr; @@ -875,7 +820,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, np->ignore_phy = 1; else np->ignore_phy = 0; - np->dspcfg_workaround = dspcfg_workaround; /* Initial port: * - If configured to ignore the PHY set up for external. @@ -955,9 +899,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, if (i) goto err_register_netdev; - if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround)) - goto err_create_file; - if (netif_msg_drv(np)) { printk(KERN_INFO "natsemi %s: %s at %#08lx (%s), ", dev->name, natsemi_pci_info[chip_idx].name, iostart, @@ -974,9 +915,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, } return 0; - err_create_file: - unregister_netdev(dev); - err_register_netdev: iounmap(ioaddr); @@ -1789,8 +1727,7 @@ static void init_registers(struct net_device *dev) * It seems that a reference set for this chip went out with incorrect info, * and there exist boards that aren't quite right. An unexpected voltage * drop can cause the PHY to get itself in a weird state (basically reset). - * NOTE: this only seems to affect revC chips. The user can disable - * this check via dspcfg_workaround sysfs option. + * NOTE: this only seems to affect revC chips. * 3) check of death of the RX path due to OOM */ static void netdev_timer(unsigned long data) @@ -1816,10 +1753,10 @@ static void netdev_timer(unsigned long data) writew(1, ioaddr+PGSEL); dspcfg = readw(ioaddr+DSPCFG); writew(0, ioaddr+PGSEL); - if (np->dspcfg_workaround && dspcfg != np->dspcfg) { + if (dspcfg != np->dspcfg) { if (!netif_queue_stopped(dev)) { spin_unlock_irq(&np->lock); - if (netif_msg_drv(np)) + if (netif_msg_hw(np)) printk(KERN_NOTICE "%s: possible phy reset: " "re-initializing\n", dev->name); disable_irq(dev->irq); @@ -3220,7 +3157,6 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); void __iomem * ioaddr = ns_ioaddr(dev); - NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround); unregister_netdev (dev); pci_release_regions (pdev); iounmap(ioaddr); diff --git a/trunk/drivers/net/ne.c b/trunk/drivers/net/ne.c index c9f74bf5f491..a5c4199e2754 100644 --- a/trunk/drivers/net/ne.c +++ b/trunk/drivers/net/ne.c @@ -51,11 +51,14 @@ static const char version2[] = #include #include #include -#include #include #include +#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) +#include +#endif + #include "8390.h" #define DRV_NAME "ne" @@ -74,13 +77,8 @@ static const char version2[] = /* Do we have a non std. amount of memory? (in units of 256 byte pages) */ /* #define PACKETBUF_MEMSIZE 0x40 */ -#if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R)) -/* Do we need a portlist for the ISA auto-probe ? */ -#define NEEDS_PORTLIST -#endif - /* A zero-terminated list of I/O addresses to be probed at boot. */ -#ifdef NEEDS_PORTLIST +#ifndef MODULE static unsigned int netcard_portlist[] __initdata = { 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0 }; @@ -148,7 +146,7 @@ bad_clone_list[] __initdata = { # define DCR_VAL 0x49 #endif -static int ne_probe1(struct net_device *dev, unsigned long ioaddr); +static int ne_probe1(struct net_device *dev, int ioaddr); static int ne_probe_isapnp(struct net_device *dev); static int ne_open(struct net_device *dev); @@ -186,8 +184,8 @@ static void ne_block_output(struct net_device *dev, const int count, static int __init do_ne_probe(struct net_device *dev) { - unsigned long base_addr = dev->base_addr; -#ifdef NEEDS_PORTLIST + unsigned int base_addr = dev->base_addr; +#ifndef MODULE int orig_irq = dev->irq; #endif @@ -203,7 +201,7 @@ static int __init do_ne_probe(struct net_device *dev) if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) return 0; -#ifdef NEEDS_PORTLIST +#ifndef MODULE /* Last resort. The semi-risky ISA auto-probe. */ for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { int ioaddr = netcard_portlist[base_addr]; @@ -228,6 +226,10 @@ struct net_device * __init ne_probe(int unit) sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); +#ifdef CONFIG_TOSHIBA_RBTX4938 + dev->base_addr = RBTX4938_RTL_8019_BASE; + dev->irq = RBTX4938_RTL_8019_IRQ; +#endif err = do_ne_probe(dev); if (err) goto out; @@ -283,7 +285,7 @@ static int __init ne_probe_isapnp(struct net_device *dev) return -ENODEV; } -static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) +static int __init ne_probe1(struct net_device *dev, int ioaddr) { int i; unsigned char SA_prom[32]; @@ -322,7 +324,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) if (ei_debug && version_printed++ == 0) printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); - printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr); + printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr); /* A user with a poor card that fails to ack the reset, or that does not have a valid 0x57,0x57 signature can still use this @@ -514,7 +516,8 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) } #endif - printk("\n"); + printk("\n%s: %s found at %#x, using IRQ %d.\n", + dev->name, name, ioaddr, dev->irq); ei_status.name = name; ei_status.tx_start_page = start_page; @@ -544,8 +547,6 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) ret = register_netdev(dev); if (ret) goto out_irq; - printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n", - dev->name, name, ioaddr, dev->irq); return 0; out_irq: @@ -806,87 +807,6 @@ static void ne_block_output(struct net_device *dev, int count, return; } -static int __init ne_drv_probe(struct platform_device *pdev) -{ - struct net_device *dev; - struct resource *res; - int err, irq; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - irq = platform_get_irq(pdev, 0); - if (!res || irq < 0) - return -ENODEV; - - dev = alloc_ei_netdev(); - if (!dev) - return -ENOMEM; - dev->irq = irq; - dev->base_addr = res->start; - err = do_ne_probe(dev); - if (err) { - free_netdev(dev); - return err; - } - platform_set_drvdata(pdev, dev); - return 0; -} - -static int __exit ne_drv_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - - unregister_netdev(dev); - free_irq(dev->irq, dev); - release_region(dev->base_addr, NE_IO_EXTENT); - free_netdev(dev); - return 0; -} - -#ifdef CONFIG_PM -static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct net_device *dev = platform_get_drvdata(pdev); - - if (netif_running(dev)) - netif_device_detach(dev); - return 0; -} - -static int ne_drv_resume(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - - if (netif_running(dev)) { - ne_reset_8390(dev); - NS8390_init(dev, 1); - netif_device_attach(dev); - } - return 0; -} -#else -#define ne_drv_suspend NULL -#define ne_drv_resume NULL -#endif - -static struct platform_driver ne_driver = { - .remove = __exit_p(ne_drv_remove), - .suspend = ne_drv_suspend, - .resume = ne_drv_resume, - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, -}; - -static int __init ne_init(void) -{ - return platform_driver_probe(&ne_driver, ne_drv_probe); -} - -static void __exit ne_exit(void) -{ - platform_driver_unregister(&ne_driver); -} #ifdef MODULE #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ @@ -912,7 +832,6 @@ ISA device autoprobes on a running machine are not recommended anyway. */ int __init init_module(void) { int this_dev, found = 0; - int plat_found = !ne_init(); for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { struct net_device *dev = alloc_ei_netdev(); @@ -926,7 +845,7 @@ int __init init_module(void) continue; } free_netdev(dev); - if (found || plat_found) + if (found) break; if (io[this_dev] != 0) printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]); @@ -934,7 +853,7 @@ int __init init_module(void) printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); return -ENXIO; } - if (found || plat_found) + if (found) return 0; return -ENODEV; } @@ -952,7 +871,6 @@ void __exit cleanup_module(void) { int this_dev; - ne_exit(); for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { struct net_device *dev = dev_ne[this_dev]; if (dev) { @@ -962,7 +880,4 @@ void __exit cleanup_module(void) } } } -#else /* MODULE */ -module_init(ne_init); -module_exit(ne_exit); #endif /* MODULE */ diff --git a/trunk/drivers/net/ns83820.c b/trunk/drivers/net/ns83820.c index 3439f8c649f9..6a32338623f1 100644 --- a/trunk/drivers/net/ns83820.c +++ b/trunk/drivers/net/ns83820.c @@ -104,6 +104,7 @@ #include #include #include +#include #include #include #include /* for iph */ diff --git a/trunk/drivers/net/pasemi_mac.c b/trunk/drivers/net/pasemi_mac.c index bc7f3dee6e5b..76fe9dd8e841 100644 --- a/trunk/drivers/net/pasemi_mac.c +++ b/trunk/drivers/net/pasemi_mac.c @@ -33,8 +33,6 @@ #include #include -#include - #include "pasemi_mac.h" @@ -53,16 +51,6 @@ #define RX_RING_SIZE 512 #define TX_RING_SIZE 512 -#define DEFAULT_MSG_ENABLE \ - (NETIF_MSG_DRV | \ - NETIF_MSG_PROBE | \ - NETIF_MSG_LINK | \ - NETIF_MSG_TIMER | \ - NETIF_MSG_IFDOWN | \ - NETIF_MSG_IFUP | \ - NETIF_MSG_RX_ERR | \ - NETIF_MSG_TX_ERR) - #define TX_DESC(mac, num) ((mac)->tx->desc[(num) & (TX_RING_SIZE-1)]) #define TX_DESC_INFO(mac, num) ((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)]) #define RX_DESC(mac, num) ((mac)->rx->desc[(num) & (RX_RING_SIZE-1)]) @@ -71,13 +59,11 @@ #define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */ -MODULE_LICENSE("GPL"); -MODULE_AUTHOR ("Olof Johansson "); -MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); - -static int debug = -1; /* -1 == use DEFAULT_MSG_ENABLE as value */ -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value"); +/* XXXOJN these should come out of the device tree some day */ +#define PAS_DMA_CAP_BASE 0xe00d0040 +#define PAS_DMA_CAP_SIZE 0x100 +#define PAS_DMA_COM_BASE 0xe00d0100 +#define PAS_DMA_COM_SIZE 0x100 static struct pasdma_status *dma_status; @@ -94,12 +80,7 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -ENOENT; } - maddr = of_get_property(dn, "local-mac-address", NULL); - - /* Fall back to mac-address for older firmware */ - if (maddr == NULL) - maddr = of_get_property(dn, "mac-address", NULL); - + maddr = get_property(dn, "mac-address", NULL); if (maddr == NULL) { dev_warn(&pdev->dev, "no mac address in device tree, not configuring\n"); @@ -296,8 +277,8 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev) for (i = 0; i < RX_RING_SIZE; i++) { info = &RX_DESC_INFO(mac, i); dp = &RX_DESC(mac, i); - if (info->skb) { - if (info->dma) { + if (info->dma) { + if (info->skb) { pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, @@ -328,120 +309,82 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) struct pasemi_mac *mac = netdev_priv(dev); unsigned int i; int start = mac->rx->next_to_fill; - unsigned int limit, count; + unsigned int count; - limit = (mac->rx->next_to_clean + RX_RING_SIZE - + count = (mac->rx->next_to_clean + RX_RING_SIZE - mac->rx->next_to_fill) & (RX_RING_SIZE - 1); /* Check to see if we're doing first-time setup */ if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0)) - limit = RX_RING_SIZE; + count = RX_RING_SIZE; - if (limit <= 0) + if (count <= 0) return; - i = start; - for (count = limit; count; count--) { + for (i = start; i < start + count; i++) { struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i); u64 *buff = &RX_BUFF(mac, i); struct sk_buff *skb; dma_addr_t dma; - /* skb might still be in there for recycle on short receives */ - if (info->skb) - skb = info->skb; - else - skb = dev_alloc_skb(BUF_SIZE); + skb = dev_alloc_skb(BUF_SIZE); - if (unlikely(!skb)) + if (!skb) { + count = i - start; break; + } dma = pci_map_single(mac->dma_pdev, skb->data, skb->len, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(dma))) { + if (dma_mapping_error(dma)) { dev_kfree_skb_irq(info->skb); + count = i - start; break; } info->skb = skb; info->dma = dma; *buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma); - i++; } wmb(); pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), - limit - count); + count); pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_INCR(mac->dma_if), - limit - count); + count); - mac->rx->next_to_fill += limit - count; + mac->rx->next_to_fill += count; } -static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) -{ - unsigned int reg, stat; - /* Re-enable packet count interrupts: finally - * ack the packet count interrupt we got in rx_intr. - */ - - pci_read_config_dword(mac->iob_pdev, - PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch), - &stat); - - reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M) - | PAS_IOB_DMA_RXCH_RESET_PINTC; - - pci_write_config_dword(mac->iob_pdev, - PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), - reg); -} - -static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) -{ - unsigned int reg, stat; - - /* Re-enable packet count interrupts */ - pci_read_config_dword(mac->iob_pdev, - PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat); - - reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) - | PAS_IOB_DMA_TXCH_RESET_PINTC; - - pci_write_config_dword(mac->iob_pdev, - PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); -} - - static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) { - unsigned int n; - int count; - struct pas_dma_xct_descr *dp; - struct pasemi_mac_buffer *info; - struct sk_buff *skb; - unsigned int i, len; - u64 macrx; - dma_addr_t dma; + unsigned int i; + int start, count; spin_lock(&mac->rx->lock); - n = mac->rx->next_to_clean; + start = mac->rx->next_to_clean; + count = 0; - for (count = limit; count; count--) { + for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) { + struct pas_dma_xct_descr *dp; + struct pasemi_mac_buffer *info; + struct sk_buff *skb; + unsigned int j, len; + dma_addr_t dma; rmb(); - dp = &RX_DESC(mac, n); - macrx = dp->macrx; + dp = &RX_DESC(mac, i); - if (!(macrx & XCT_MACRX_O)) + if (!(dp->macrx & XCT_MACRX_O)) break; + count++; info = NULL; @@ -453,42 +396,29 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) */ dma = (dp->ptr & XCT_PTR_ADDR_M); - for (i = n; i < (n + RX_RING_SIZE); i++) { - info = &RX_DESC_INFO(mac, i); + for (j = start; j < (start + RX_RING_SIZE); j++) { + info = &RX_DESC_INFO(mac, j); if (info->dma == dma) break; } - skb = info->skb; - info->dma = 0; + BUG_ON(!info); + BUG_ON(info->dma != dma); - pci_unmap_single(mac->dma_pdev, dma, skb->len, + pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, PCI_DMA_FROMDEVICE); - len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; - - if (len < 256) { - struct sk_buff *new_skb = - netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN); - if (new_skb) { - skb_reserve(new_skb, NET_IP_ALIGN); - memcpy(new_skb->data - NET_IP_ALIGN, - skb->data - NET_IP_ALIGN, - len + NET_IP_ALIGN); - /* save the skb in buffer_info as good */ - skb = new_skb; - } - /* else just continue with the old one */ - } else - info->skb = NULL; + skb = info->skb; + + len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; skb_put(skb, len); skb->protocol = eth_type_trans(skb, mac->netdev); - if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) { + if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) { skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = (macrx & XCT_MACRX_CSUM_M) >> + skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >> XCT_MACRX_CSUM_S; } else skb->ip_summed = CHECKSUM_NONE; @@ -498,13 +428,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) netif_receive_skb(skb); + info->dma = 0; + info->skb = NULL; dp->ptr = 0; dp->macrx = 0; - - n++; } - mac->rx->next_to_clean += limit - count; + mac->rx->next_to_clean += count; pasemi_mac_replenish_rx_ring(mac->netdev); spin_unlock(&mac->rx->lock); @@ -546,8 +476,6 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac) mac->tx->next_to_clean += count; spin_unlock_irqrestore(&mac->tx->lock, flags); - netif_wake_queue(mac->netdev); - return count; } @@ -558,28 +486,18 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data) struct pasemi_mac *mac = netdev_priv(dev); unsigned int reg; - if (!(*mac->rx_status & PAS_STATUS_CAUSE_M)) + if (!(*mac->rx_status & PAS_STATUS_INT)) return IRQ_NONE; - if (*mac->rx_status & PAS_STATUS_ERROR) - printk("rx_status reported error\n"); - - /* Don't reset packet count so it won't fire again but clear - * all others. - */ - - pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), ®); + netif_rx_schedule(dev); + pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0)); - reg = 0; - if (*mac->rx_status & PAS_STATUS_SOFT) - reg |= PAS_IOB_DMA_RXCH_RESET_SINTC; - if (*mac->rx_status & PAS_STATUS_ERROR) - reg |= PAS_IOB_DMA_RXCH_RESET_DINTC; + reg = PAS_IOB_DMA_RXCH_RESET_PINTC | PAS_IOB_DMA_RXCH_RESET_SINTC | + PAS_IOB_DMA_RXCH_RESET_DINTC; if (*mac->rx_status & PAS_STATUS_TIMER) reg |= PAS_IOB_DMA_RXCH_RESET_TINTC; - netif_rx_schedule(dev); - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); @@ -592,137 +510,31 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) struct net_device *dev = data; struct pasemi_mac *mac = netdev_priv(dev); unsigned int reg; + int was_full; - if (!(*mac->tx_status & PAS_STATUS_CAUSE_M)) + was_full = mac->tx->next_to_clean - mac->tx->next_to_use == TX_RING_SIZE; + + if (!(*mac->tx_status & PAS_STATUS_INT)) return IRQ_NONE; pasemi_mac_clean_tx(mac); - reg = PAS_IOB_DMA_TXCH_RESET_PINTC; - - if (*mac->tx_status & PAS_STATUS_SOFT) - reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; - if (*mac->tx_status & PAS_STATUS_ERROR) - reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; + reg = PAS_IOB_DMA_TXCH_RESET_PINTC | PAS_IOB_DMA_TXCH_RESET_SINTC; + if (*mac->tx_status & PAS_STATUS_TIMER) + reg |= PAS_IOB_DMA_TXCH_RESET_TINTC; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); - return IRQ_HANDLED; -} + if (was_full) + netif_wake_queue(dev); -static void pasemi_adjust_link(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - int msg; - unsigned int flags; - unsigned int new_flags; - - if (!mac->phydev->link) { - /* If no link, MAC speed settings don't matter. Just report - * link down and return. - */ - if (mac->link && netif_msg_link(mac)) - printk(KERN_INFO "%s: Link is down.\n", dev->name); - - netif_carrier_off(dev); - mac->link = 0; - - return; - } else - netif_carrier_on(dev); - - pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags); - new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M | - PAS_MAC_CFG_PCFG_TSR_M); - - if (!mac->phydev->duplex) - new_flags |= PAS_MAC_CFG_PCFG_HD; - - switch (mac->phydev->speed) { - case 1000: - new_flags |= PAS_MAC_CFG_PCFG_SPD_1G | - PAS_MAC_CFG_PCFG_TSR_1G; - break; - case 100: - new_flags |= PAS_MAC_CFG_PCFG_SPD_100M | - PAS_MAC_CFG_PCFG_TSR_100M; - break; - case 10: - new_flags |= PAS_MAC_CFG_PCFG_SPD_10M | - PAS_MAC_CFG_PCFG_TSR_10M; - break; - default: - printk("Unsupported speed %d\n", mac->phydev->speed); - } - - /* Print on link or speed/duplex change */ - msg = mac->link != mac->phydev->link || flags != new_flags; - - mac->duplex = mac->phydev->duplex; - mac->speed = mac->phydev->speed; - mac->link = mac->phydev->link; - - if (new_flags != flags) - pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags); - - if (msg && netif_msg_link(mac)) - printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n", - dev->name, mac->speed, mac->duplex ? "full" : "half"); -} - -static int pasemi_mac_phy_init(struct net_device *dev) -{ - struct pasemi_mac *mac = netdev_priv(dev); - struct device_node *dn, *phy_dn; - struct phy_device *phydev; - unsigned int phy_id; - const phandle *ph; - const unsigned int *prop; - struct resource r; - int ret; - - dn = pci_device_to_OF_node(mac->pdev); - ph = of_get_property(dn, "phy-handle", NULL); - if (!ph) - return -ENODEV; - phy_dn = of_find_node_by_phandle(*ph); - - prop = of_get_property(phy_dn, "reg", NULL); - ret = of_address_to_resource(phy_dn->parent, 0, &r); - if (ret) - goto err; - - phy_id = *prop; - snprintf(mac->phy_id, BUS_ID_SIZE, PHY_ID_FMT, (int)r.start, phy_id); - - of_node_put(phy_dn); - - mac->link = 0; - mac->speed = 0; - mac->duplex = -1; - - phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII); - - if (IS_ERR(phydev)) { - printk(KERN_ERR "%s: Could not attach to phy\n", dev->name); - return PTR_ERR(phydev); - } - - mac->phydev = phydev; - - return 0; - -err: - of_node_put(phy_dn); - return -ENODEV; + return IRQ_HANDLED; } - static int pasemi_mac_open(struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); - int base_irq; unsigned int flags; int ret; @@ -746,18 +558,10 @@ static int pasemi_mac_open(struct net_device *dev) flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), - PAS_IOB_DMA_RXCH_CFG_CNTTH(1)); + PAS_IOB_DMA_RXCH_CFG_CNTTH(30)); - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), - PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); - - /* Clear out any residual packet count state from firmware */ - pasemi_mac_restart_rx_intr(mac); - pasemi_mac_restart_tx_intr(mac); - - /* 0xffffff is max value, about 16ms */ pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff)); + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000)); pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags); @@ -791,50 +595,31 @@ static int pasemi_mac_open(struct net_device *dev) pasemi_mac_replenish_rx_ring(dev); - ret = pasemi_mac_phy_init(dev); - /* Some configs don't have PHYs (XAUI etc), so don't complain about - * failed init due to -ENODEV. - */ - if (ret && ret != -ENODEV) - dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret); - netif_start_queue(dev); netif_poll_enable(dev); - /* Interrupts are a bit different for our DMA controller: While - * it's got one a regular PCI device header, the interrupt there - * is really the base of the range it's using. Each tx and rx - * channel has it's own interrupt source. - */ - - base_irq = virq_to_hw(mac->dma_pdev->irq); - - mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch); - mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch); - - ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED, + ret = request_irq(mac->dma_pdev->irq + mac->dma_txch, + &pasemi_mac_tx_intr, IRQF_DISABLED, mac->tx->irq_name, dev); if (ret) { dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", - base_irq + mac->dma_txch, ret); + mac->dma_pdev->irq + mac->dma_txch, ret); goto out_tx_int; } - ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED, + ret = request_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, + &pasemi_mac_rx_intr, IRQF_DISABLED, mac->rx->irq_name, dev); if (ret) { dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", - base_irq + 20 + mac->dma_rxch, ret); + mac->dma_pdev->irq + 20 + mac->dma_rxch, ret); goto out_rx_int; } - if (mac->phydev) - phy_start(mac->phydev); - return 0; out_rx_int: - free_irq(mac->tx_irq, dev); + free_irq(mac->dma_pdev->irq + mac->dma_txch, dev); out_tx_int: netif_poll_disable(dev); netif_stop_queue(dev); @@ -854,11 +639,6 @@ static int pasemi_mac_close(struct net_device *dev) unsigned int stat; int retries; - if (mac->phydev) { - phy_stop(mac->phydev); - phy_disconnect(mac->phydev); - } - netif_stop_queue(dev); /* Clean out any pending buffers */ @@ -880,37 +660,40 @@ static int pasemi_mac_close(struct net_device *dev) pci_read_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), &stat); - if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT) break; cond_resched(); } - if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT) + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) { dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n"); + } for (retries = 0; retries < MAX_RETRIES; retries++) { pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), &stat); - if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) + if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT) break; cond_resched(); } - if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT) + if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) { dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n"); + } for (retries = 0; retries < MAX_RETRIES; retries++) { pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), &stat); - if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) + if (stat & PAS_DMA_RXINT_RCMDSTA_ACT) break; cond_resched(); } - if (stat & PAS_DMA_RXINT_RCMDSTA_ACT) + if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) { dev_err(&mac->dma_pdev->dev, "Failed to stop rx interface\n"); + } /* Then, disable the channel. This must be done separately from * stopping, since you can't disable when active. @@ -923,8 +706,8 @@ static int pasemi_mac_close(struct net_device *dev) pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); - free_irq(mac->tx_irq, dev); - free_irq(mac->rx_irq, dev); + free_irq(mac->dma_pdev->irq + mac->dma_txch, dev); + free_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, dev); /* Free resources */ pasemi_mac_free_rx_resources(dev); @@ -1019,7 +802,6 @@ static struct net_device_stats *pasemi_mac_get_stats(struct net_device *dev) return &mac->stats; } - static void pasemi_mac_set_rx_mode(struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); @@ -1044,17 +826,18 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget) pkts = pasemi_mac_clean_rx(mac, limit); - dev->quota -= pkts; - *budget -= pkts; - if (pkts < limit) { /* all done, no more packets present */ netif_rx_complete(dev); - pasemi_mac_restart_rx_intr(mac); + /* re-enable receive interrupts */ + pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000)); return 0; } else { /* used up our quantum, so reschedule */ + dev->quota -= pkts; + *budget -= pkts; return 1; } } @@ -1154,11 +937,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mac->rx_status = &dma_status->rx_sta[mac->dma_rxch]; mac->tx_status = &dma_status->tx_sta[mac->dma_txch]; - mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); - - /* Enable most messages by default */ - mac->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; - err = register_netdev(dev); if (err) { @@ -1233,5 +1011,9 @@ int pasemi_mac_init_module(void) return pci_register_driver(&pasemi_mac_driver); } +MODULE_LICENSE("GPL"); +MODULE_AUTHOR ("Olof Johansson "); +MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); + module_init(pasemi_mac_init_module); module_exit(pasemi_mac_cleanup_module); diff --git a/trunk/drivers/net/pasemi_mac.h b/trunk/drivers/net/pasemi_mac.h index 8bc0cea8b145..c3e37e46a18a 100644 --- a/trunk/drivers/net/pasemi_mac.h +++ b/trunk/drivers/net/pasemi_mac.h @@ -24,7 +24,6 @@ #include #include #include -#include struct pasemi_mac_txring { spinlock_t lock; @@ -55,7 +54,6 @@ struct pasemi_mac { struct pci_dev *pdev; struct pci_dev *dma_pdev; struct pci_dev *iob_pdev; - struct phy_device *phydev; struct net_device_stats stats; /* Pointer to the cacheable per-channel status registers */ @@ -75,14 +73,6 @@ struct pasemi_mac { struct pasemi_mac_txring *tx; struct pasemi_mac_rxring *rx; - unsigned long tx_irq; - unsigned long rx_irq; - int link; - int speed; - int duplex; - - unsigned int msg_enable; - char phy_id[BUS_ID_SIZE]; }; /* Software status descriptor (desc_info) */ @@ -203,15 +193,11 @@ enum { #define PAS_DMA_RXINT_RCMDSTA(i) (0x200+(i)*_PAS_DMA_RXINT_STRIDE) #define PAS_DMA_RXINT_RCMDSTA_EN 0x00000001 #define PAS_DMA_RXINT_RCMDSTA_ST 0x00000002 -#define PAS_DMA_RXINT_RCMDSTA_MBT 0x00000008 -#define PAS_DMA_RXINT_RCMDSTA_MDR 0x00000010 -#define PAS_DMA_RXINT_RCMDSTA_MOO 0x00000020 -#define PAS_DMA_RXINT_RCMDSTA_MBP 0x00000040 +#define PAS_DMA_RXINT_RCMDSTA_OO 0x00000100 +#define PAS_DMA_RXINT_RCMDSTA_BP 0x00000200 +#define PAS_DMA_RXINT_RCMDSTA_DR 0x00000400 #define PAS_DMA_RXINT_RCMDSTA_BT 0x00000800 -#define PAS_DMA_RXINT_RCMDSTA_DR 0x00001000 -#define PAS_DMA_RXINT_RCMDSTA_OO 0x00002000 -#define PAS_DMA_RXINT_RCMDSTA_BP 0x00004000 -#define PAS_DMA_RXINT_RCMDSTA_TB 0x00008000 +#define PAS_DMA_RXINT_RCMDSTA_TB 0x00001000 #define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000 #define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000 #define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17 @@ -311,7 +297,6 @@ enum { #define PAS_STATUS_DCNT_S 16 #define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull #define PAS_STATUS_BPCNT_S 32 -#define PAS_STATUS_CAUSE_M 0xf000000000000000ull #define PAS_STATUS_TIMER 0x1000000000000000ull #define PAS_STATUS_ERROR 0x2000000000000000ull #define PAS_STATUS_SOFT 0x4000000000000000ull diff --git a/trunk/drivers/net/pcmcia/xirc2ps_cs.c b/trunk/drivers/net/pcmcia/xirc2ps_cs.c index 258d6f396186..809ec440b8eb 100644 --- a/trunk/drivers/net/pcmcia/xirc2ps_cs.c +++ b/trunk/drivers/net/pcmcia/xirc2ps_cs.c @@ -1420,7 +1420,7 @@ set_addresses(struct net_device *dev) kio_addr_t ioaddr = dev->base_addr; local_info_t *lp = netdev_priv(dev); struct dev_mc_list *dmi = dev->mc_list; - unsigned char *addr; + char *addr; int i,j,k,n; SelectPage(k=0x50); @@ -1429,9 +1429,6 @@ set_addresses(struct net_device *dev) if (++n > 9) break; i = 0; - if (n > 1 && n <= dev->mc_count && dmi) { - dmi = dmi->next; - } } if (j > 15) { j = 8; @@ -1439,9 +1436,10 @@ set_addresses(struct net_device *dev) SelectPage(k); } - if (n && n <= dev->mc_count && dmi) + if (n && n <= dev->mc_count && dmi) { addr = dmi->dmi_addr; - else + dmi = dmi->next; + } else addr = dev->dev_addr; if (lp->mohawk) @@ -1467,10 +1465,10 @@ set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) { /* snoop */ PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */ } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) { - PutByte(XIRCREG42_SWC1, 0x02); /* set MPE */ + PutByte(XIRCREG42_SWC1, 0x06); /* set MPE */ } else if (dev->mc_count) { /* the chip can filter 9 addresses perfectly */ - PutByte(XIRCREG42_SWC1, 0x01); + PutByte(XIRCREG42_SWC1, 0x00); SelectPage(0x40); PutByte(XIRCREG40_CMD0, Offline); set_addresses(dev); diff --git a/trunk/drivers/net/ppp_generic.c b/trunk/drivers/net/ppp_generic.c index 541168713f1f..6d596ca50cfd 100644 --- a/trunk/drivers/net/ppp_generic.c +++ b/trunk/drivers/net/ppp_generic.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index b07da1054add..21afe108d3cb 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -135,13 +135,10 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, /* Wake on Lan only supported on Yukon chips with rev 1 or above */ static u32 wol_supported(const struct skge_hw *hw) { - if (hw->chip_id == CHIP_ID_GENESIS) - return 0; - - if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0) + if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0) + return WAKE_MAGIC | WAKE_PHY; + else return 0; - - return WAKE_MAGIC | WAKE_PHY; } static u32 pci_wake_enabled(struct pci_dev *dev) diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index a307310f13f5..238c2ca34da6 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -124,7 +124,10 @@ static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ +#ifdef broken + /* This device causes data corruption problems that are not resolved */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ +#endif { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ @@ -3578,21 +3581,10 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out; } - /* Some Gigabyte motherboards have 88e8056 but cause problems - * There is some unresolved hardware related problem that causes - * descriptor errors and receive data corruption. - */ - if (pdev->vendor == PCI_VENDOR_ID_MARVELL && - pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) { - dev_err(&pdev->dev, - "88E8056 on Gigabyte motherboards not supported\n"); - goto err_out_disable; - } - err = pci_request_regions(pdev, DRV_NAME); if (err) { dev_err(&pdev->dev, "cannot obtain PCI resources\n"); - goto err_out_disable; + goto err_out; } pci_set_master(pdev); @@ -3729,7 +3721,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, kfree(hw); err_out_free_regions: pci_release_regions(pdev); -err_out_disable: pci_disable_device(pdev); err_out: return err; diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h index 111f23d05764..d2767e6584a9 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -55,53 +55,6 @@ #define SMC_insw(a, r, p, l) readsw((a) + (r), p, l) #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) -#elif defined(CONFIG_BFIN) - -#define SMC_IRQ_FLAGS IRQF_TRIGGER_HIGH - -# if defined (CONFIG_BFIN561_EZKIT) -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 -#define SMC_IO_SHIFT 0 -#define SMC_NOWAIT 1 -#define SMC_USE_BFIN_DMA 0 - - -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_inl(a, r) readl((a) + (r)) -#define SMC_outl(v, a, r) writel(v, (a) + (r)) -#define SMC_outsl(a, r, p, l) outsl((unsigned long *)((a) + (r)), p, l) -#define SMC_insl(a, r, p, l) insl ((unsigned long *)((a) + (r)), p, l) -# else -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 -#define SMC_IO_SHIFT 0 -#define SMC_NOWAIT 1 -#define SMC_USE_BFIN_DMA 0 - - -#define SMC_inw(a, r) readw((a) + (r)) -#define SMC_outw(v, a, r) writew(v, (a) + (r)) -#define SMC_outsw(a, r, p, l) outsw((unsigned long *)((a) + (r)), p, l) -#define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) -# endif -/* check if the mac in reg is valid */ -#define SMC_GET_MAC_ADDR(addr) \ - do { \ - unsigned int __v; \ - __v = SMC_inw(ioaddr, ADDR0_REG); \ - addr[0] = __v; addr[1] = __v >> 8; \ - __v = SMC_inw(ioaddr, ADDR1_REG); \ - addr[2] = __v; addr[3] = __v >> 8; \ - __v = SMC_inw(ioaddr, ADDR2_REG); \ - addr[4] = __v; addr[5] = __v >> 8; \ - if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ - random_ether_addr(addr); \ - } \ - } while (0) #elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6) /* We can only do 16-bit reads and writes in the static memory space. */ @@ -279,40 +232,6 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_insw(a, r, p, l) insw((a) + (r), p, l) #define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) -#elif defined(CONFIG_SUPERH) - -#if defined(CONFIG_SH_7780_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE) -#define SMC_CAN_USE_8BIT 0 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 0 -#define SMC_IO_SHIFT 0 -#define SMC_NOWAIT 1 - -#define SMC_inb(a, r) (inw((a) + ((r)&~1)) >> (8*(r%2)))&0xff -#define SMC_inw(a, r) inw((a) + (r)) -#define SMC_outb(v, a, r) outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1)) - -#define SMC_outw(v, a, r) outw(v, (a) + (r)) -#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) - -#else /* BOARDS */ - -#define SMC_CAN_USE_8BIT 1 -#define SMC_CAN_USE_16BIT 1 -#define SMC_CAN_USE_32BIT 1 - -#define SMC_inb(a, r) inb((a) + (r)) -#define SMC_inw(a, r) inw((a) + (r)) -#define SMC_outb(v, a, r) outb(v, (a) + (r)) -#define SMC_outw(v, a, r) outw(v, (a) + (r)) -#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) -#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) - -#endif /* BOARDS */ - -#define set_irq_type(irq, type) do {} while (0) - #elif defined(CONFIG_M32R) #define SMC_CAN_USE_8BIT 0 diff --git a/trunk/drivers/net/sonic.c b/trunk/drivers/net/sonic.c index 8069f3e32d83..c6320c719931 100644 --- a/trunk/drivers/net/sonic.c +++ b/trunk/drivers/net/sonic.c @@ -50,6 +50,29 @@ static int sonic_open(struct net_device *dev) if (sonic_debug > 2) printk("sonic_open: initializing sonic driver.\n"); + /* + * We don't need to deal with auto-irq stuff since we + * hardwire the sonic interrupt. + */ +/* + * XXX Horrible work around: We install sonic_interrupt as fast interrupt. + * This means that during execution of the handler interrupt are disabled + * covering another bug otherwise corrupting data. This doesn't mean + * this glue works ok under all situations. + * + * Note (dhd): this also appears to prevent lockups on the Macintrash + * when more than one Ethernet card is installed (knock on wood) + * + * Note (fthain): whether the above is still true is anyones guess. Certainly + * the buffer handling algorithms will not tolerate re-entrance without some + * mutual exclusion added. Anyway, the memcpy has now been eliminated from the + * rx code to make this a faster "fast interrupt". + */ + if (request_irq(dev->irq, &sonic_interrupt, SONIC_IRQ_FLAG, "sonic", dev)) { + printk(KERN_ERR "\n%s: unable to get IRQ %d .\n", dev->name, dev->irq); + return -EAGAIN; + } + for (i = 0; i < SONIC_NUM_RRS; i++) { struct sk_buff *skb = dev_alloc_skb(SONIC_RBSIZE + 2); if (skb == NULL) { @@ -146,6 +169,8 @@ static int sonic_close(struct net_device *dev) } } + free_irq(dev->irq, dev); /* release the IRQ */ + return 0; } @@ -153,13 +178,8 @@ static void sonic_tx_timeout(struct net_device *dev) { struct sonic_local *lp = netdev_priv(dev); int i; - /* - * put the Sonic into software-reset mode and - * disable all interrupts before releasing DMA buffers - */ + /* Stop the interrupts for this */ SONIC_WRITE(SONIC_IMR, 0); - SONIC_WRITE(SONIC_ISR, 0x7fff); - SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); /* We could resend the original skbs. Easier to re-initialise. */ for (i = 0; i < SONIC_NUM_TDS; i++) { if(lp->tx_laddr[i]) { diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index c15e97253ede..230da14b1b68 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -1830,7 +1830,7 @@ spider_net_init_firmware(struct spider_net_card *card) if (!dn) goto out_err; - fw_prop = of_get_property(dn, "firmware", &fw_size); + fw_prop = get_property(dn, "firmware", &fw_size); if (!fw_prop) goto out_err; @@ -2236,7 +2236,7 @@ spider_net_setup_netdev(struct spider_net_card *card) if (!dn) return -EIO; - mac = of_get_property(dn, "local-mac-address", NULL); + mac = get_property(dn, "local-mac-address", NULL); if (!mac) return -EIO; memcpy(addr.sa_data, mac, ETH_ALEN); diff --git a/trunk/drivers/net/sun3_82586.c b/trunk/drivers/net/sun3_82586.c index a123ea87893b..396c3d961f88 100644 --- a/trunk/drivers/net/sun3_82586.c +++ b/trunk/drivers/net/sun3_82586.c @@ -1023,11 +1023,10 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev) { len = skb->len; if (len < ETH_ZLEN) { - memset((void *)p->xmit_cbuffs[p->xmit_count], 0, - ETH_ZLEN); + memset((char *)p->xmit_cbuffs[p->xmit_count], 0, ETH_ZLEN); len = ETH_ZLEN; } - skb_copy_from_linear_data(skb, (void *)p->xmit_cbuffs[p->xmit_count], skb->len); + skb_copy_from_linear_data(skb, p->xmit_cbuffs[p->xmit_count], skb->len); #if (NUM_XMIT_BUFFS == 1) # ifdef NO_NOPCOMMANDS diff --git a/trunk/drivers/net/sungem.c b/trunk/drivers/net/sungem.c index 432803855034..5da73212ac91 100644 --- a/trunk/drivers/net/sungem.c +++ b/trunk/drivers/net/sungem.c @@ -2903,7 +2903,7 @@ static int __devinit gem_get_device_address(struct gem *gp) struct net_device *dev = gp->dev; const unsigned char *addr; - addr = of_get_property(gp->of_node, "local-mac-address", NULL); + addr = get_property(gp->of_node, "local-mac-address", NULL); if (addr == NULL) { #ifdef CONFIG_SPARC addr = idprom->id_ethaddr; diff --git a/trunk/drivers/net/sungem_phy.c b/trunk/drivers/net/sungem_phy.c index 61843fd57525..56a110ca5e6f 100644 --- a/trunk/drivers/net/sungem_phy.c +++ b/trunk/drivers/net/sungem_phy.c @@ -451,7 +451,7 @@ static int bcm5421_init(struct mii_phy* phy) if (phy->platform_data) { struct device_node *np = of_get_parent(phy->platform_data); int can_low_power = 1; - if (np == NULL || of_get_property(np, "no-autolowpower", NULL)) + if (np == NULL || get_property(np, "no-autolowpower", NULL)) can_low_power = 0; if (can_low_power) { /* Enable automatic low-power */ diff --git a/trunk/drivers/net/tc35815.c b/trunk/drivers/net/tc35815.c index 463d600ed83d..f1e2dfc795a2 100644 --- a/trunk/drivers/net/tc35815.c +++ b/trunk/drivers/net/tc35815.c @@ -540,6 +540,7 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev, skb = dev_alloc_skb(RX_BUF_SIZE); if (!skb) return NULL; + skb->dev = dev; *dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); if (pci_dma_mapping_error(*dma_handle)) { diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index e5e901ecd808..9488f49ea569 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -64,8 +64,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.76" -#define DRV_MODULE_RELDATE "May 5, 2007" +#define DRV_MODULE_VERSION "3.75" +#define DRV_MODULE_RELDATE "March 23, 2007" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -1300,11 +1300,9 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) msleep(1); } } - if (tp->tg3_flags & TG3_FLAG_WOL_CAP) - tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE | - WOL_DRV_STATE_SHUTDOWN | - WOL_DRV_WOL | - WOL_SET_MAGIC_PKT); + tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE | + WOL_DRV_STATE_SHUTDOWN | + WOL_DRV_WOL | WOL_SET_MAGIC_PKT); pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps); @@ -2595,8 +2593,10 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status) { int current_link_up = 0; - if (!(mac_status & MAC_STATUS_PCS_SYNCED)) + if (!(mac_status & MAC_STATUS_PCS_SYNCED)) { + tp->tg3_flags &= ~TG3_FLAG_GOT_SERDES_FLOWCTL; goto out; + } if (tp->link_config.autoneg == AUTONEG_ENABLE) { u32 flags; @@ -2614,6 +2614,7 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status) tg3_setup_flow_control(tp, local_adv, remote_adv); + tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; current_link_up = 1; } for (i = 0; i < 30; i++) { @@ -2636,6 +2637,7 @@ static int tg3_setup_fiber_by_hand(struct tg3 *tp, u32 mac_status) } else { /* Forcing 1000FD link up. */ current_link_up = 1; + tp->tg3_flags |= TG3_FLAG_GOT_SERDES_FLOWCTL; tw32_f(MAC_MODE, (tp->mac_mode | MAC_MODE_SEND_CONFIGS)); udelay(40); @@ -3019,16 +3021,6 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) } } - if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) { - u32 val = tr32(PCIE_PWR_MGMT_THRESH); - if (!netif_carrier_ok(tp->dev)) - val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) | - tp->pwrmgmt_thresh; - else - val |= PCIE_PWR_MGMT_L1_THRESH_MSK; - tw32(PCIE_PWR_MGMT_THRESH, val); - } - return err; } @@ -3590,12 +3582,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id) * Writing non-zero to intr-mbox-0 additional tells the * NIC to stop sending us irqs, engaging "in-intr-handler" * event coalescing. - * - * Flush the mailbox to de-assert the IRQ immediately to prevent - * spurious interrupts. The flush impacts performance but - * excessive spurious interrupts can be worse in some cases. */ - tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); if (tg3_irq_sync(tp)) goto out; sblk->status &= ~SD_STATUS_UPDATED; @@ -3639,12 +3627,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) * writing non-zero to intr-mbox-0 additional tells the * NIC to stop sending us irqs, engaging "in-intr-handler" * event coalescing. - * - * Flush the mailbox to de-assert the IRQ immediately to prevent - * spurious interrupts. The flush impacts performance but - * excessive spurious interrupts can be worse in some cases. */ - tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); if (tg3_irq_sync(tp)) goto out; if (netif_rx_schedule_prep(dev)) { @@ -3911,7 +3895,8 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) entry = tp->tx_prod; base_flags = 0; mss = 0; - if ((mss = skb_shinfo(skb)->gso_size) != 0) { + if (skb->len > (tp->dev->mtu + ETH_HLEN) && + (mss = skb_shinfo(skb)->gso_size) != 0) { int tcp_opt_len, ip_tcp_len; if (skb_header_cloned(skb) && @@ -4068,7 +4053,8 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) if (skb->ip_summed == CHECKSUM_PARTIAL) base_flags |= TXD_FLAG_TCPUDP_CSUM; mss = 0; - if ((mss = skb_shinfo(skb)->gso_size) != 0) { + if (skb->len > (tp->dev->mtu + ETH_HLEN) && + (mss = skb_shinfo(skb)->gso_size) != 0) { struct iphdr *iph; int tcp_opt_len, ip_tcp_len, hdr_len; @@ -5948,7 +5934,7 @@ static int tg3_load_tso_firmware(struct tg3 *tp) /* tp->lock is held. */ -static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1) +static void __tg3_set_mac_addr(struct tg3 *tp) { u32 addr_high, addr_low; int i; @@ -5960,8 +5946,6 @@ static void __tg3_set_mac_addr(struct tg3 *tp, int skip_mac_1) (tp->dev->dev_addr[4] << 8) | (tp->dev->dev_addr[5] << 0)); for (i = 0; i < 4; i++) { - if (i == 1 && skip_mac_1) - continue; tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high); tw32(MAC_ADDR_0_LOW + (i * 8), addr_low); } @@ -5988,7 +5972,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) { struct tg3 *tp = netdev_priv(dev); struct sockaddr *addr = p; - int err = 0, skip_mac_1 = 0; + int err = 0; if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; @@ -5999,21 +5983,22 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) return 0; if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { - u32 addr0_high, addr0_low, addr1_high, addr1_low; - - addr0_high = tr32(MAC_ADDR_0_HIGH); - addr0_low = tr32(MAC_ADDR_0_LOW); - addr1_high = tr32(MAC_ADDR_1_HIGH); - addr1_low = tr32(MAC_ADDR_1_LOW); + /* Reset chip so that ASF can re-init any MAC addresses it + * needs. + */ + tg3_netif_stop(tp); + tg3_full_lock(tp, 1); - /* Skip MAC addr 1 if ASF is using it. */ - if ((addr0_high != addr1_high || addr0_low != addr1_low) && - !(addr1_high == 0 && addr1_low == 0)) - skip_mac_1 = 1; + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); + err = tg3_restart_hw(tp, 0); + if (!err) + tg3_netif_start(tp); + tg3_full_unlock(tp); + } else { + spin_lock_bh(&tp->lock); + __tg3_set_mac_addr(tp); + spin_unlock_bh(&tp->lock); } - spin_lock_bh(&tp->lock); - __tg3_set_mac_addr(tp, skip_mac_1); - spin_unlock_bh(&tp->lock); return err; } @@ -6330,7 +6315,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tp->rx_jumbo_ptr); /* Initialize MAC address and backoff seed. */ - __tg3_set_mac_addr(tp, 0); + __tg3_set_mac_addr(tp); /* MTU + ethernet header + FCS + optional VLAN tag */ tw32(MAC_RX_MTU_SIZE, tp->dev->mtu + ETH_HLEN + 8); @@ -6361,7 +6346,8 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) { if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE && - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) { + (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 || + tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) { rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128; } else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) && !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) { @@ -6471,7 +6457,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) gpio_mask |= GRC_LCLCTRL_GPIO_UART_SEL; - tp->grc_local_ctrl &= ~gpio_mask; tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask; /* GPIO1 must be driven high for eeprom write protect */ @@ -7051,7 +7036,11 @@ static int tg3_open(struct net_device *dev) if (err) return err; - if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) { + if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && + (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) && + (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX) && + !((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) && + (tp->pdev_peer == tp->pdev))) { /* All MSI supporting chips should support tagged * status. Assert that this is the case. */ @@ -7410,7 +7399,9 @@ static int tg3_close(struct net_device *dev) tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_free_rings(tp); - tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; + tp->tg3_flags &= + ~(TG3_FLAG_INIT_COMPLETE | + TG3_FLAG_GOT_SERDES_FLOWCTL); tg3_full_unlock(tp); @@ -8045,10 +8036,7 @@ static void tg3_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct tg3 *tp = netdev_priv(dev); - if (tp->tg3_flags & TG3_FLAG_WOL_CAP) - wol->supported = WAKE_MAGIC; - else - wol->supported = 0; + wol->supported = WAKE_MAGIC; wol->wolopts = 0; if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) wol->wolopts = WAKE_MAGIC; @@ -8062,7 +8050,8 @@ static int tg3_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) if (wol->wolopts & ~WAKE_MAGIC) return -EINVAL; if ((wol->wolopts & WAKE_MAGIC) && - !(tp->tg3_flags & TG3_FLAG_WOL_CAP)) + tp->tg3_flags2 & TG3_FLG2_ANY_SERDES && + !(tp->tg3_flags & TG3_FLAG_SERDES_WOL_CAP)) return -EINVAL; spin_lock_bh(&tp->lock); @@ -9300,7 +9289,7 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp) return; } } - tp->nvram_size = 0x80000; + tp->nvram_size = 0x20000; } static void __devinit tg3_get_nvram_info(struct tg3 *tp) @@ -9419,31 +9408,33 @@ static void __devinit tg3_get_5752_nvram_info(struct tg3 *tp) static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp) { - u32 nvcfg1, protect = 0; + u32 nvcfg1; nvcfg1 = tr32(NVRAM_CFG1); /* NVRAM protection for TPM */ - if (nvcfg1 & (1 << 27)) { + if (nvcfg1 & (1 << 27)) tp->tg3_flags2 |= TG3_FLG2_PROTECTED_NVRAM; - protect = 1; - } - nvcfg1 &= NVRAM_CFG1_5752VENDOR_MASK; - switch (nvcfg1) { + switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) { + case FLASH_5755VENDOR_ATMEL_EEPROM_64KHZ: + case FLASH_5755VENDOR_ATMEL_EEPROM_376KHZ: + tp->nvram_jedecnum = JEDEC_ATMEL; + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; + tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE; + + nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS; + tw32(NVRAM_CFG1, nvcfg1); + break; + case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED: case FLASH_5755VENDOR_ATMEL_FLASH_1: case FLASH_5755VENDOR_ATMEL_FLASH_2: case FLASH_5755VENDOR_ATMEL_FLASH_3: + case FLASH_5755VENDOR_ATMEL_FLASH_4: tp->nvram_jedecnum = JEDEC_ATMEL; tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; tp->tg3_flags2 |= TG3_FLG2_FLASH; tp->nvram_pagesize = 264; - if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1) - tp->nvram_size = (protect ? 0x3e200 : 0x80000); - else if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_2) - tp->nvram_size = (protect ? 0x1f200 : 0x40000); - else - tp->nvram_size = (protect ? 0x1f200 : 0x20000); break; case FLASH_5752VENDOR_ST_M45PE10: case FLASH_5752VENDOR_ST_M45PE20: @@ -9452,12 +9443,6 @@ static void __devinit tg3_get_5755_nvram_info(struct tg3 *tp) tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED; tp->tg3_flags2 |= TG3_FLG2_FLASH; tp->nvram_pagesize = 256; - if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10) - tp->nvram_size = (protect ? 0x10000 : 0x20000); - else if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE20) - tp->nvram_size = (protect ? 0x10000 : 0x40000); - else - tp->nvram_size = (protect ? 0x20000 : 0x80000); break; } } @@ -9533,8 +9518,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) } tg3_enable_nvram_access(tp); - tp->nvram_size = 0; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) tg3_get_5752_nvram_info(tp); else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) @@ -9546,8 +9529,7 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) else tg3_get_nvram_info(tp); - if (tp->nvram_size == 0) - tg3_get_nvram_size(tp); + tg3_get_nvram_size(tp); tg3_disable_nvram_access(tp); tg3_nvram_unlock(tp); @@ -10014,16 +9996,14 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->phy_id = PHY_ID_INVALID; tp->led_ctrl = LED_CTRL_MODE_PHY_1; - /* Assume an onboard device and WOL capable by default. */ - tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT | TG3_FLAG_WOL_CAP; + /* Assume an onboard device by default. */ + tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) { tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; tp->tg3_flags2 |= TG3_FLG2_IS_NIC; } - if (tr32(VCPU_CFGSHDW) & VCPU_CFGSHDW_ASPM_DBNC) - tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; return; } @@ -10140,9 +10120,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE; } - if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES && - !(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)) - tp->tg3_flags &= ~TG3_FLAG_WOL_CAP; + if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL) + tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP; if (cfg2 & (1 << 17)) tp->tg3_flags2 |= TG3_FLG2_CAPACITIVE_COUPLING; @@ -10151,14 +10130,6 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) /* bootcode if bit 18 is set */ if (cfg2 & (1 << 18)) tp->tg3_flags2 |= TG3_FLG2_SERDES_PREEMPHASIS; - - if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { - u32 cfg3; - - tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3); - if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE) - tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; - } } } @@ -10428,8 +10399,6 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) } } -static struct pci_dev * __devinit tg3_find_peer(struct tg3 *); - static int __devinit tg3_get_invariants(struct tg3 *tp) { static struct pci_device_id write_reorder_chipsets[] = { @@ -10585,10 +10554,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->pci_hdr_type = (cacheline_sz_reg >> 16) & 0xff; tp->pci_bist = (cacheline_sz_reg >> 24) & 0xff; - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) - tp->pdev_peer = tg3_find_peer(tp); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || @@ -10602,14 +10567,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags2 |= TG3_FLG2_5705_PLUS; if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { - tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI; - if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX || - GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX || - (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 && - tp->pci_chip_rev_id <= CHIPREV_ID_5714_A2 && - tp->pdev_peer == tp->pdev)) - tp->tg3_flags &= ~TG3_FLAG_SUPPORT_MSI; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { @@ -10711,6 +10668,17 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG; + /* Back to back register writes can cause problems on this chip, + * the workaround is to read back all reg writes except those to + * mailbox regs. See tg3_write_indirect_reg32(). + * + * PCI Express 5750_A0 rev chips need this workaround too. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || + ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && + tp->pci_chip_rev_id == CHIPREV_ID_5750_A0)) + tp->tg3_flags |= TG3_FLAG_5701_REG_WRITE_BUG; + if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0) tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED; if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0) @@ -10734,19 +10702,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) /* Various workaround register access methods */ if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) tp->write32 = tg3_write_indirect_reg32; - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 || - ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && - tp->pci_chip_rev_id == CHIPREV_ID_5750_A0)) { - /* - * Back to back register writes can cause problems on these - * chips, the workaround is to read back all reg writes - * except those to mailbox regs. - * - * See tg3_write_indirect_reg32(). - */ + else if (tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) tp->write32 = tg3_write_flush_reg32; - } - if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) || (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) { @@ -11026,10 +10983,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) */ tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE; - if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) - tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) & - PCIE_PWR_MGMT_L1_THRESH_MSK; - return err; } @@ -11939,6 +11892,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->rx_pending = 63; } + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) + tp->pdev_peer = tg3_find_peer(tp); + err = tg3_get_device_address(tp); if (err) { printk(KERN_ERR PFX "Could not obtain valid ethernet address, " diff --git a/trunk/drivers/net/tg3.h b/trunk/drivers/net/tg3.h index 4d334cf5a243..d515ed23841b 100644 --- a/trunk/drivers/net/tg3.h +++ b/trunk/drivers/net/tg3.h @@ -131,7 +131,6 @@ #define CHIPREV_ID_5752_A0_HW 0x5000 #define CHIPREV_ID_5752_A0 0x6000 #define CHIPREV_ID_5752_A1 0x6001 -#define CHIPREV_ID_5714_A2 0x9002 #define CHIPREV_ID_5906_A1 0xc001 #define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12) #define ASIC_REV_5700 0x07 @@ -1150,9 +1149,6 @@ #define VCPU_STATUS_INIT_DONE 0x04000000 #define VCPU_STATUS_DRV_RESET 0x08000000 -#define VCPU_CFGSHDW 0x00005104 -#define VCPU_CFGSHDW_ASPM_DBNC 0x00001000 - /* Mailboxes */ #define GRCMBOX_BASE 0x00005600 #define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */ @@ -1510,8 +1506,6 @@ #define PCIE_TRANS_CFG_1SHOT_MSI 0x20000000 #define PCIE_TRANS_CFG_LOM 0x00000020 -#define PCIE_PWR_MGMT_THRESH 0x00007d28 -#define PCIE_PWR_MGMT_L1_THRESH_MSK 0x0000ff00 #define TG3_EEPROM_MAGIC 0x669955aa #define TG3_EEPROM_MAGIC_FW 0xa5000000 @@ -1598,9 +1592,6 @@ #define SHASTA_EXT_LED_MAC 0x00010000 #define SHASTA_EXT_LED_COMBO 0x00018000 -#define NIC_SRAM_DATA_CFG_3 0x00000d3c -#define NIC_SRAM_ASPM_DEBOUNCE 0x00000002 - #define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000 #define NIC_SRAM_DMA_DESC_POOL_BASE 0x00002000 @@ -2208,7 +2199,7 @@ struct tg3 { #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 #define TG3_FLAG_USE_MI_INTERRUPT 0x00000010 #define TG3_FLAG_ENABLE_ASF 0x00000020 -#define TG3_FLAG_ASPM_WORKAROUND 0x00000040 +#define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040 #define TG3_FLAG_POLL_SERDES 0x00000080 #define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100 #define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200 @@ -2224,14 +2215,14 @@ struct tg3 { #define TG3_FLAG_PCI_32BIT 0x00080000 #define TG3_FLAG_SRAM_USE_CONFIG 0x00100000 #define TG3_FLAG_TX_RECOVERY_PENDING 0x00200000 -#define TG3_FLAG_WOL_CAP 0x00400000 +#define TG3_FLAG_SERDES_WOL_CAP 0x00400000 #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 #define TG3_FLAG_10_100_ONLY 0x01000000 #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 #define TG3_FLAG_IN_RESET_TASK 0x04000000 #define TG3_FLAG_40BIT_DMA_BUG 0x08000000 #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 -#define TG3_FLAG_SUPPORT_MSI 0x20000000 +#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 #define TG3_FLAG_CHIP_RESETTING 0x40000000 #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; @@ -2297,7 +2288,6 @@ struct tg3 { u32 grc_local_ctrl; u32 dma_rwctrl; u32 coalesce_mode; - u32 pwrmgmt_thresh; /* PCI block */ u16 pci_chip_rev_id; diff --git a/trunk/drivers/net/tokenring/madgemc.c b/trunk/drivers/net/tokenring/madgemc.c index f8f4d74f01f1..ed274d6909d0 100644 --- a/trunk/drivers/net/tokenring/madgemc.c +++ b/trunk/drivers/net/tokenring/madgemc.c @@ -23,6 +23,7 @@ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/tokenring/smctr.c b/trunk/drivers/net/tokenring/smctr.c index 58d7e5d452fa..9bbea5c8acf4 100644 --- a/trunk/drivers/net/tokenring/smctr.c +++ b/trunk/drivers/net/tokenring/smctr.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/tsi108_eth.c b/trunk/drivers/net/tsi108_eth.c index 1aabc91f6458..0bfc2c9c1c08 100644 --- a/trunk/drivers/net/tsi108_eth.c +++ b/trunk/drivers/net/tsi108_eth.c @@ -82,7 +82,6 @@ struct tsi108_prv_data { unsigned int phy; /* Index of PHY for this interface */ unsigned int irq_num; unsigned int id; - unsigned int phy_type; struct timer_list timer;/* Timer that triggers the check phy function */ unsigned int rxtail; /* Next entry in rxring to read */ @@ -1257,11 +1256,11 @@ static void tsi108_init_phy(struct net_device *dev) if (i == 0) printk(KERN_ERR "%s function time out \n", __FUNCTION__); - if (data->phy_type == TSI108_PHY_BCM54XX) { - tsi108_write_mii(data, 0x09, 0x0300); - tsi108_write_mii(data, 0x10, 0x1020); - tsi108_write_mii(data, 0x1c, 0x8c00); - } +#if (TSI108_PHY_TYPE == PHY_BCM54XX) /* Broadcom BCM54xx PHY */ + tsi108_write_mii(data, 0x09, 0x0300); + tsi108_write_mii(data, 0x10, 0x1020); + tsi108_write_mii(data, 0x1c, 0x8c00); +#endif tsi108_write_mii(data, MII_BMCR, @@ -1588,7 +1587,6 @@ tsi108_init_one(struct platform_device *pdev) data->mii_if.supports_gmii = mii_check_gmii_support(&data->mii_if); data->phy = einfo->phy; - data->phy_type = einfo->phy_type; data->irq_num = einfo->irq_num; data->id = pdev->id; dev->open = tsi108_open; diff --git a/trunk/drivers/net/tsi108_eth.h b/trunk/drivers/net/tsi108_eth.h index 5a77ae6c5f36..77a769df228a 100644 --- a/trunk/drivers/net/tsi108_eth.h +++ b/trunk/drivers/net/tsi108_eth.h @@ -42,6 +42,15 @@ #define TSI_READ_PHY(offset) \ in_be32((data->phyregs + (offset))) +/* + * PHY Configuration Options + * + * NOTE: Enable set of definitions corresponding to your board type + */ +#define PHY_MV88E 1 /* Marvel 88Exxxx PHY */ +#define PHY_BCM54XX 2 /* Broardcom BCM54xx PHY */ +#define TSI108_PHY_TYPE PHY_MV88E + /* * TSI108 GIGE port registers */ diff --git a/trunk/drivers/net/tulip/21142.c b/trunk/drivers/net/tulip/21142.c index 6c400ccd38b4..942b839ccc5b 100644 --- a/trunk/drivers/net/tulip/21142.c +++ b/trunk/drivers/net/tulip/21142.c @@ -14,6 +14,7 @@ */ +#include #include #include "tulip.h" diff --git a/trunk/drivers/net/tulip/pnic.c b/trunk/drivers/net/tulip/pnic.c index be82a2effee3..85a521e0d052 100644 --- a/trunk/drivers/net/tulip/pnic.c +++ b/trunk/drivers/net/tulip/pnic.c @@ -15,6 +15,7 @@ */ #include +#include #include #include "tulip.h" diff --git a/trunk/drivers/net/tulip/pnic2.c b/trunk/drivers/net/tulip/pnic2.c index 4e4a879c3fa5..c31be0e377a8 100644 --- a/trunk/drivers/net/tulip/pnic2.c +++ b/trunk/drivers/net/tulip/pnic2.c @@ -76,6 +76,7 @@ +#include #include "tulip.h" #include diff --git a/trunk/drivers/net/tulip/timer.c b/trunk/drivers/net/tulip/timer.c index d2c1f42109b0..df326fe1cc8f 100644 --- a/trunk/drivers/net/tulip/timer.c +++ b/trunk/drivers/net/tulip/timer.c @@ -14,6 +14,7 @@ */ +#include #include "tulip.h" diff --git a/trunk/drivers/net/tulip/tulip.h b/trunk/drivers/net/tulip/tulip.h index 16f26a8364f0..c840d2e67b23 100644 --- a/trunk/drivers/net/tulip/tulip.h +++ b/trunk/drivers/net/tulip/tulip.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/net/ucc_geth.c b/trunk/drivers/net/ucc_geth.c index d7aff8189377..16b9acdabbe8 100644 --- a/trunk/drivers/net/ucc_geth.c +++ b/trunk/drivers/net/ucc_geth.c @@ -3787,7 +3787,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ugeth_vdbg("%s: IN", __FUNCTION__); - prop = of_get_property(np, "device-id", NULL); + prop = get_property(np, "device-id", NULL); ucc_num = *prop - 1; if ((ucc_num < 0) || (ucc_num > 7)) return -ENODEV; @@ -3795,9 +3795,9 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info = &ugeth_info[ucc_num]; ug_info->uf_info.ucc_num = ucc_num; - prop = of_get_property(np, "rx-clock", NULL); + prop = get_property(np, "rx-clock", NULL); ug_info->uf_info.rx_clock = *prop; - prop = of_get_property(np, "tx-clock", NULL); + prop = get_property(np, "tx-clock", NULL); ug_info->uf_info.tx_clock = *prop; err = of_address_to_resource(np, 0, &res); if (err) @@ -3806,23 +3806,23 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ug_info->uf_info.regs = res.start; ug_info->uf_info.irq = irq_of_parse_and_map(np, 0); - ph = of_get_property(np, "phy-handle", NULL); + ph = get_property(np, "phy-handle", NULL); phy = of_find_node_by_phandle(*ph); if (phy == NULL) return -ENODEV; /* set the PHY address */ - prop = of_get_property(phy, "reg", NULL); + prop = get_property(phy, "reg", NULL); if (prop == NULL) return -1; ug_info->phy_address = *prop; /* get the phy interface type, or default to MII */ - prop = of_get_property(np, "interface-type", NULL); + prop = get_property(np, "interface-type", NULL); if (!prop) { /* handle interface property present in old trees */ - prop = of_get_property(phy, "interface", NULL); + prop = get_property(phy, "interface", NULL); if (prop != NULL) phy_interface = enet_to_phy_interface[*prop]; else @@ -3832,10 +3832,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma } /* get speed, or derive from interface */ - prop = of_get_property(np, "max-speed", NULL); + prop = get_property(np, "max-speed", NULL); if (!prop) { /* handle interface property present in old trees */ - prop = of_get_property(phy, "interface", NULL); + prop = get_property(phy, "interface", NULL); if (prop != NULL) max_speed = enet_to_speed[*prop]; } else { diff --git a/trunk/drivers/net/ucc_geth_mii.c b/trunk/drivers/net/ucc_geth_mii.c index 27a1ef3b7b06..73b5a538e8f4 100644 --- a/trunk/drivers/net/ucc_geth_mii.c +++ b/trunk/drivers/net/ucc_geth_mii.c @@ -172,7 +172,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma while ((child = of_get_next_child(np, child)) != NULL) { int irq = irq_of_parse_and_map(child, 0); if (irq != NO_IRQ) { - const u32 *id = of_get_property(child, "reg", NULL); + const u32 *id = get_property(child, "reg", NULL); new_bus->irq[*id] = irq; } } @@ -203,7 +203,7 @@ static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *ma if ((res.start >= tempres.start) && (res.end <= tempres.end)) { /* set this UCC to be the MII master */ - const u32 *id = of_get_property(tempnp, "device-id", NULL); + const u32 *id = get_property(tempnp, "device-id", NULL); if (id == NULL) goto bus_register_fail; diff --git a/trunk/drivers/net/wan/cosa.c b/trunk/drivers/net/wan/cosa.c index 9ef49ce148b2..23464735fa88 100644 --- a/trunk/drivers/net/wan/cosa.c +++ b/trunk/drivers/net/wan/cosa.c @@ -90,6 +90,7 @@ #include #include #include +#include #include #undef COSA_SLOW_IO /* for testing purposes only */ diff --git a/trunk/drivers/net/wan/lmc/lmc_media.c b/trunk/drivers/net/wan/lmc/lmc_media.c index 574737b55f39..ae01555d24cf 100644 --- a/trunk/drivers/net/wan/lmc/lmc_media.c +++ b/trunk/drivers/net/wan/lmc/lmc_media.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/wan/lmc/lmc_proto.c b/trunk/drivers/net/wan/lmc/lmc_proto.c index 31e1799571ad..74876c0073e8 100644 --- a/trunk/drivers/net/wan/lmc/lmc_proto.c +++ b/trunk/drivers/net/wan/lmc/lmc_proto.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/wan/pc300_tty.c b/trunk/drivers/net/wan/pc300_tty.c index e24a7b095dd6..07dbdfbfc15d 100644 --- a/trunk/drivers/net/wan/pc300_tty.c +++ b/trunk/drivers/net/wan/pc300_tty.c @@ -38,6 +38,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index e273347dc606..c4b3dc291a5a 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -153,8 +153,8 @@ config IPW2100 If you want to compile the driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), - say M here and read . - The module will be called ipw2100.ko. + say M here and read . The module + will be called ipw2100.ko. config IPW2100_MONITOR bool "Enable promiscuous mode" @@ -208,8 +208,8 @@ config IPW2200 If you want to compile the driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), - say M here and read . - The module will be called ipw2200.ko. + say M here and read . The module + will be called ipw2200.ko. config IPW2200_MONITOR bool "Enable promiscuous mode" @@ -267,7 +267,7 @@ config IPW2200_DEBUG config LIBERTAS_USB tristate "Marvell Libertas 8388 802.11a/b/g cards" - depends on USB && WLAN_80211 + depends on NET_RADIO && USB select FW_LOADER ---help--- A driver for Marvell Libertas 8388 USB devices. @@ -517,8 +517,8 @@ config PRISM54 If you want to compile the driver as a module ( = code which can be inserted in and removed from the running kernel whenever you want), - say M here and read . - The module will be called prism54.ko. + say M here and read . The module + will be called prism54.ko. config USB_ZD1201 tristate "USB ZD1201 based Wireless device support" diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index 2d3a180dada0..f21bbafcb728 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c index cdea7f71b9eb..cb08bc5db2bd 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c @@ -1,6 +1,7 @@ /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */ #include +#include #include #include diff --git a/trunk/drivers/net/wireless/strip.c b/trunk/drivers/net/wireless/strip.c index ef32a5c1e818..2a299a0676a6 100644 --- a/trunk/drivers/net/wireless/strip.c +++ b/trunk/drivers/net/wireless/strip.c @@ -1971,7 +1971,8 @@ static struct net_device *get_strip_dev(struct strip *strip_info) sizeof(zero_address))) { struct net_device *dev; read_lock_bh(&dev_base_lock); - for_each_netdev(dev) { + dev = dev_base; + while (dev) { if (dev->type == strip_info->dev->type && !memcmp(dev->dev_addr, &strip_info->true_dev_addr, @@ -1982,6 +1983,7 @@ static struct net_device *get_strip_dev(struct strip *strip_info) read_unlock_bh(&dev_base_lock); return (dev); } + dev = dev->next; } read_unlock_bh(&dev_base_lock); } diff --git a/trunk/drivers/parisc/hppb.c b/trunk/drivers/parisc/hppb.c index a68b3b3761a2..9bb4db552f3c 100644 --- a/trunk/drivers/parisc/hppb.c +++ b/trunk/drivers/parisc/hppb.c @@ -22,6 +22,8 @@ #include #include +#include + struct hppb_card { unsigned long hpa; struct resource mmio_region; diff --git a/trunk/drivers/parisc/lba_pci.c b/trunk/drivers/parisc/lba_pci.c index 5b86ee5c1eeb..21c4c299b3d6 100644 --- a/trunk/drivers/parisc/lba_pci.c +++ b/trunk/drivers/parisc/lba_pci.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/parisc/led.c b/trunk/drivers/parisc/led.c index 98be2880757d..3df82fe9ce8c 100644 --- a/trunk/drivers/parisc/led.c +++ b/trunk/drivers/parisc/led.c @@ -365,7 +365,7 @@ static __inline__ int led_get_net_activity(void) * for reading should be OK */ read_lock(&dev_base_lock); rcu_read_lock(); - for_each_netdev(dev) { + for (dev = dev_base; dev; dev = dev->next) { struct net_device_stats *stats; struct in_device *in_dev = __in_dev_get_rcu(dev); if (!in_dev || !in_dev->ifa_list) diff --git a/trunk/drivers/parisc/pdc_stable.c b/trunk/drivers/parisc/pdc_stable.c index 815e445c3125..ea1b7a63598e 100644 --- a/trunk/drivers/parisc/pdc_stable.c +++ b/trunk/drivers/parisc/pdc_stable.c @@ -520,17 +520,17 @@ static struct pdcspath_entry *pdcspath_entries[] = { /** * pdcs_size_read - Stable Storage size output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. */ static ssize_t -pdcs_size_read(struct kset *kset, char *buf) +pdcs_size_read(struct subsystem *entry, char *buf) { char *out = buf; - - if (!kset || !buf) + + if (!entry || !buf) return -EINVAL; - + /* show the size of the stable storage */ out += sprintf(out, "%ld\n", pdcs_size); @@ -539,17 +539,17 @@ pdcs_size_read(struct kset *kset, char *buf) /** * pdcs_auto_read - Stable Storage autoboot/search flag output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag */ static ssize_t -pdcs_auto_read(struct kset *kset, char *buf, int knob) +pdcs_auto_read(struct subsystem *entry, char *buf, int knob) { char *out = buf; struct pdcspath_entry *pathentry; - if (!kset || !buf) + if (!entry || !buf) return -EINVAL; /* Current flags are stored in primary boot path entry */ @@ -565,40 +565,40 @@ pdcs_auto_read(struct kset *kset, char *buf, int knob) /** * pdcs_autoboot_read - Stable Storage autoboot flag output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. */ static inline ssize_t -pdcs_autoboot_read(struct kset *kset, char *buf) +pdcs_autoboot_read(struct subsystem *entry, char *buf) { - return pdcs_auto_read(kset, buf, PF_AUTOBOOT); + return pdcs_auto_read(entry, buf, PF_AUTOBOOT); } /** * pdcs_autosearch_read - Stable Storage autoboot flag output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. */ static inline ssize_t -pdcs_autosearch_read(struct kset *kset, char *buf) +pdcs_autosearch_read(struct subsystem *entry, char *buf) { - return pdcs_auto_read(kset, buf, PF_AUTOSEARCH); + return pdcs_auto_read(entry, buf, PF_AUTOSEARCH); } /** * pdcs_timer_read - Stable Storage timer count output (in seconds). - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. * * The value of the timer field correponds to a number of seconds in powers of 2. */ static ssize_t -pdcs_timer_read(struct kset *kset, char *buf) +pdcs_timer_read(struct subsystem *entry, char *buf) { char *out = buf; struct pdcspath_entry *pathentry; - if (!kset || !buf) + if (!entry || !buf) return -EINVAL; /* Current flags are stored in primary boot path entry */ @@ -615,15 +615,15 @@ pdcs_timer_read(struct kset *kset, char *buf) /** * pdcs_osid_read - Stable Storage OS ID register output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. */ static ssize_t -pdcs_osid_read(struct kset *kset, char *buf) +pdcs_osid_read(struct subsystem *entry, char *buf) { char *out = buf; - if (!kset || !buf) + if (!entry || !buf) return -EINVAL; out += sprintf(out, "%s dependent data (0x%.4x)\n", @@ -634,18 +634,18 @@ pdcs_osid_read(struct kset *kset, char *buf) /** * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. * * This can hold 16 bytes of OS-Dependent data. */ static ssize_t -pdcs_osdep1_read(struct kset *kset, char *buf) +pdcs_osdep1_read(struct subsystem *entry, char *buf) { char *out = buf; u32 result[4]; - if (!kset || !buf) + if (!entry || !buf) return -EINVAL; if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK) @@ -661,18 +661,18 @@ pdcs_osdep1_read(struct kset *kset, char *buf) /** * pdcs_diagnostic_read - Stable Storage Diagnostic register output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. * * I have NFC how to interpret the content of that register ;-). */ static ssize_t -pdcs_diagnostic_read(struct kset *kset, char *buf) +pdcs_diagnostic_read(struct subsystem *entry, char *buf) { char *out = buf; u32 result; - if (!kset || !buf) + if (!entry || !buf) return -EINVAL; /* get diagnostic */ @@ -686,18 +686,18 @@ pdcs_diagnostic_read(struct kset *kset, char *buf) /** * pdcs_fastsize_read - Stable Storage FastSize register output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. * * This register holds the amount of system RAM to be tested during boot sequence. */ static ssize_t -pdcs_fastsize_read(struct kset *kset, char *buf) +pdcs_fastsize_read(struct subsystem *entry, char *buf) { char *out = buf; u32 result; - if (!kset || !buf) + if (!entry || !buf) return -EINVAL; /* get fast-size */ @@ -715,13 +715,13 @@ pdcs_fastsize_read(struct kset *kset, char *buf) /** * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. - * @kset: An allocated and populated struct kset. We don't use it tho. + * @entry: An allocated and populated subsytem struct. We don't use it tho. * @buf: The output buffer to write to. * * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. */ static ssize_t -pdcs_osdep2_read(struct kset *kset, char *buf) +pdcs_osdep2_read(struct subsystem *entry, char *buf) { char *out = buf; unsigned long size; @@ -733,7 +733,7 @@ pdcs_osdep2_read(struct kset *kset, char *buf) size = pdcs_size - 224; - if (!kset || !buf) + if (!entry || !buf) return -EINVAL; for (i=0; iio.BasePort1, link->io.BasePort2, link->irq.AssignedIRQ, PARPORT_DMA_NONE, - &link->dev); + NULL); if (p == NULL) { printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " "0x%3x, irq %u failed\n", link->io.BasePort1, diff --git a/trunk/drivers/parport/parport_mfc3.c b/trunk/drivers/parport/parport_mfc3.c index 77726fc49766..e5b0a544de40 100644 --- a/trunk/drivers/parport/parport_mfc3.c +++ b/trunk/drivers/parport/parport_mfc3.c @@ -356,7 +356,6 @@ static int __init parport_mfc3_init(void) if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops)) goto out_irq; } - p->dev = &z->dev; this_port[pias++] = p; printk(KERN_INFO "%s: Multiface III port using irq\n", p->name); diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index 02c0d52c9f76..3de2623afa13 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include @@ -621,7 +620,6 @@ static size_t parport_pc_fifo_write_block_dma (struct parport *port, unsigned long dmaflag; size_t left = length; const struct parport_pc_private *priv = port->physport->private_data; - struct device *dev = port->physport->dev; dma_addr_t dma_addr, dma_handle; size_t maxlen = 0x10000; /* max 64k per DMA transfer */ unsigned long start = (unsigned long) buf; @@ -633,8 +631,8 @@ dump_parport_state ("enter fifo_write_block_dma", port); if ((start ^ end) & ~0xffffUL) maxlen = 0x10000 - (start & 0xffff); - dma_addr = dma_handle = dma_map_single(dev, (void *)buf, length, - DMA_TO_DEVICE); + dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length, + PCI_DMA_TODEVICE); } else { /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */ maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */ @@ -730,9 +728,9 @@ dump_parport_state ("enter fifo_write_block_dma", port); /* Turn off DMA mode */ frob_econtrol (port, 1<<3, 0); - + if (dma_handle) - dma_unmap_single(dev, dma_handle, length, DMA_TO_DEVICE); + pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE); dump_parport_state ("leave fifo_write_block_dma", port); return length - left; @@ -2148,7 +2146,7 @@ static DEFINE_SPINLOCK(ports_lock); struct parport *parport_pc_probe_port (unsigned long int base, unsigned long int base_hi, int irq, int dma, - struct device *dev) + struct pci_dev *dev) { struct parport_pc_private *priv; struct parport_operations *ops; @@ -2157,17 +2155,6 @@ struct parport *parport_pc_probe_port (unsigned long int base, struct resource *base_res; struct resource *ECR_res = NULL; struct resource *EPP_res = NULL; - struct platform_device *pdev = NULL; - - if (!dev) { - /* We need a physical device to attach to, but none was - * provided. Create our own. */ - pdev = platform_device_register_simple("parport_pc", - base, NULL, 0); - if (IS_ERR(pdev)) - return NULL; - dev = &pdev->dev; - } ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL); if (!ops) @@ -2193,10 +2180,9 @@ struct parport *parport_pc_probe_port (unsigned long int base, priv->fifo_depth = 0; priv->dma_buf = NULL; priv->dma_handle = 0; + priv->dev = dev; INIT_LIST_HEAD(&priv->list); priv->port = p; - - p->dev = dev; p->base_hi = base_hi; p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; p->private_data = priv; @@ -2319,10 +2305,9 @@ struct parport *parport_pc_probe_port (unsigned long int base, p->dma = PARPORT_DMA_NONE; } else { priv->dma_buf = - dma_alloc_coherent(dev, + pci_alloc_consistent(priv->dev, PAGE_SIZE, - &priv->dma_handle, - GFP_KERNEL); + &priv->dma_handle); if (! priv->dma_buf) { printk (KERN_WARNING "%s: " "cannot get buffer for DMA, " @@ -2371,8 +2356,6 @@ struct parport *parport_pc_probe_port (unsigned long int base, out2: kfree (ops); out1: - if (pdev) - platform_device_unregister(pdev); return NULL; } @@ -2400,7 +2383,7 @@ void parport_pc_unregister_port (struct parport *p) release_region(p->base_hi, 3); #if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA) if (priv->dma_buf) - dma_free_coherent(p->physport->dev, PAGE_SIZE, + pci_free_consistent(priv->dev, PAGE_SIZE, priv->dma_buf, priv->dma_handle); #endif @@ -2506,7 +2489,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq, */ release_resource(base_res); if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi, - irq, PARPORT_DMA_NONE, &pdev->dev)) { + irq, PARPORT_DMA_NONE, NULL)) { printk (KERN_INFO "parport_pc: ITE 8872 parallel port: io=0x%X", ite8872_lpt); @@ -2689,7 +2672,7 @@ static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq, } /* finally, do the probe with values obtained */ - if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) { + if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) { printk (KERN_INFO "parport_pc: VIA parallel port: io=0x%X", port1); if (irq != PARPORT_IRQ_NONE) @@ -2987,7 +2970,7 @@ static int parport_pc_pci_probe (struct pci_dev *dev, parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi); data->ports[count] = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, - PARPORT_DMA_NONE, &dev->dev); + PARPORT_DMA_NONE, dev); if (data->ports[count]) count++; } @@ -3094,8 +3077,8 @@ static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id } else dma = PARPORT_DMA_NONE; - dev_info(&dev->dev, "reported by %s\n", dev->protocol->name); - if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev))) + printk(KERN_INFO "parport: PnPBIOS parport detected.\n"); + if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, NULL))) return -ENODEV; pnp_set_drvdata(dev,pdata); @@ -3120,21 +3103,6 @@ static struct pnp_driver parport_pc_pnp_driver = { }; -static int __devinit parport_pc_platform_probe(struct platform_device *pdev) -{ - /* Always succeed, the actual probing is done in - * parport_pc_probe_port(). */ - return 0; -} - -static struct platform_driver parport_pc_platform_driver = { - .driver = { - .owner = THIS_MODULE, - .name = "parport_pc", - }, - .probe = parport_pc_platform_probe, -}; - /* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ static int __devinit __attribute__((unused)) parport_pc_find_isa_ports (int autoirq, int autodma) @@ -3410,15 +3378,9 @@ __setup("parport_init_mode=",parport_init_mode_setup); static int __init parport_pc_init(void) { - int err; - if (parse_parport_params()) return -EINVAL; - err = platform_driver_register(&parport_pc_platform_driver); - if (err) - return err; - if (io[0]) { int i; /* Only probe the ports we were given. */ @@ -3443,7 +3405,6 @@ static void __exit parport_pc_exit(void) pci_unregister_driver (&parport_pc_pci_driver); if (pnp_registered_parport) pnp_unregister_driver (&parport_pc_pnp_driver); - platform_driver_unregister(&parport_pc_platform_driver); spin_lock(&ports_lock); while (!list_empty(&ports_list)) { @@ -3452,9 +3413,6 @@ static void __exit parport_pc_exit(void) priv = list_entry(ports_list.next, struct parport_pc_private, list); port = priv->port; - if (port->dev && port->dev->bus == &platform_bus_type) - platform_device_unregister( - to_platform_device(port->dev)); spin_unlock(&ports_lock); parport_pc_unregister_port(port); spin_lock(&ports_lock); diff --git a/trunk/drivers/parport/parport_serial.c b/trunk/drivers/parport/parport_serial.c index 90ea3b8b99b0..78c0a269a2ba 100644 --- a/trunk/drivers/parport/parport_serial.c +++ b/trunk/drivers/parport/parport_serial.c @@ -305,7 +305,7 @@ static int __devinit parport_register (struct pci_dev *dev, dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " "%#lx(%#lx)\n", io_lo, io_hi); port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, - PARPORT_DMA_NONE, &dev->dev); + PARPORT_DMA_NONE, dev); if (port) { priv->port[priv->num_par++] = port; success = 1; @@ -392,7 +392,6 @@ static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state) static int parport_serial_pci_resume(struct pci_dev *dev) { struct parport_serial_private *priv = pci_get_drvdata(dev); - int err; pci_set_power_state(dev, PCI_D0); pci_restore_state(dev); @@ -400,12 +399,7 @@ static int parport_serial_pci_resume(struct pci_dev *dev) /* * The device may have been disabled. Re-enable it. */ - err = pci_enable_device(dev); - if (err) { - printk(KERN_ERR "parport_serial: %s: error enabling " - "device for resume (%d)\n", pci_name(dev), err); - return err; - } + pci_enable_device(dev); if (priv->serial) pciserial_resume_ports(priv->serial); diff --git a/trunk/drivers/parport/parport_sunbpp.c b/trunk/drivers/parport/parport_sunbpp.c index d27019c2f860..400bb90084cf 100644 --- a/trunk/drivers/parport/parport_sunbpp.c +++ b/trunk/drivers/parport/parport_sunbpp.c @@ -322,7 +322,6 @@ static int __devinit init_one_port(struct sbus_dev *sdev) goto out_free_ops; p->size = size; - p->dev = &sdev->ofdev.dev; if ((err = request_irq(p->irq, parport_sunbpp_interrupt, IRQF_SHARED, p->name, p)) != 0) { diff --git a/trunk/drivers/parport/share.c b/trunk/drivers/parport/share.c index cd66442acfee..fd9129e424f9 100644 --- a/trunk/drivers/parport/share.c +++ b/trunk/drivers/parport/share.c @@ -365,11 +365,6 @@ void parport_announce_port (struct parport *port) parport_daisy_init(port); #endif - if (!port->dev) - printk(KERN_WARNING "%s: fix this legacy " - "no-device port driver!\n", - port->name); - parport_proc_register(port); mutex_lock(®istration_lock); spin_lock_irq(&parportlist_lock); diff --git a/trunk/drivers/pci/Kconfig b/trunk/drivers/pci/Kconfig index 7a1d6d512837..5ea5bc70cb82 100644 --- a/trunk/drivers/pci/Kconfig +++ b/trunk/drivers/pci/Kconfig @@ -1,14 +1,10 @@ # # PCI configuration # -config ARCH_SUPPORTS_MSI - bool - default n - config PCI_MSI bool "Message Signaled Interrupts (MSI and MSI-X)" depends on PCI - depends on ARCH_SUPPORTS_MSI + depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 || SPARC64 help This allows device drivers to enable MSI (Message Signaled Interrupts). Message Signaled Interrupts enable a device to @@ -21,6 +17,31 @@ config PCI_MSI If you don't know what to do here, say N. +config PCI_MULTITHREAD_PROBE + bool "PCI Multi-threaded probe (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL && BROKEN + help + Say Y here if you want the PCI core to spawn a new thread for + every PCI device that is probed. This can cause a huge + speedup in boot times on multiprocessor machines, and even a + smaller speedup on single processor machines. + + But it can also cause lots of bad things to happen. A number + of PCI drivers cannot properly handle running in this way, + some will just not work properly at all, while others might + decide to blow up power supplies with a huge load all at once, + so use this option at your own risk. + + It is very unwise to use this option if you are not using a + boot process that can handle devices being created in any + order. A program that can create persistent block and network + device names (like udev) is a good idea if you wish to use + this option. + + Again, use this option at your own risk, you have been warned! + + When in doubt, say N. + config PCI_DEBUG bool "PCI Debugging" depends on PCI && DEBUG_KERNEL diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index 9e5ea074ad20..aadaa3c8096b 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -77,7 +77,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, * This adds a single pci device to the global * device list and adds sysfs and procfs entries */ -int pci_bus_add_device(struct pci_dev *dev) +int __devinit pci_bus_add_device(struct pci_dev *dev) { int retval; retval = device_add(&dev->dev); @@ -105,7 +105,7 @@ int pci_bus_add_device(struct pci_dev *dev) * * Call hotplug for each new devices. */ -void pci_bus_add_devices(struct pci_bus *bus) +void __devinit pci_bus_add_devices(struct pci_bus *bus) { struct pci_dev *dev; int retval; diff --git a/trunk/drivers/pci/hotplug/Kconfig b/trunk/drivers/pci/hotplug/Kconfig index 63d62752fb91..be92695a7833 100644 --- a/trunk/drivers/pci/hotplug/Kconfig +++ b/trunk/drivers/pci/hotplug/Kconfig @@ -2,7 +2,9 @@ # PCI Hotplug support # -menuconfig HOTPLUG_PCI +menu "PCI Hotplug Support" + +config HOTPLUG_PCI tristate "Support for PCI Hotplug (EXPERIMENTAL)" depends on PCI && EXPERIMENTAL && HOTPLUG ---help--- @@ -15,10 +17,9 @@ menuconfig HOTPLUG_PCI When in doubt, say N. -if HOTPLUG_PCI - config HOTPLUG_PCI_FAKE tristate "Fake PCI Hotplug driver" + depends on HOTPLUG_PCI help Say Y here if you want to use the fake PCI hotplug driver. It can be used to simulate PCI hotplug events if even if your system is @@ -41,7 +42,7 @@ config HOTPLUG_PCI_FAKE config HOTPLUG_PCI_COMPAQ tristate "Compaq PCI Hotplug driver" - depends on X86 && PCI_BIOS + depends on HOTPLUG_PCI && X86 && PCI_BIOS help Say Y here if you have a motherboard with a Compaq PCI Hotplug controller. @@ -63,7 +64,7 @@ config HOTPLUG_PCI_COMPAQ_NVRAM config HOTPLUG_PCI_IBM tristate "IBM PCI Hotplug driver" - depends on X86_IO_APIC && X86 && PCI_BIOS + depends on HOTPLUG_PCI && X86_IO_APIC && X86 && PCI_BIOS help Say Y here if you have a motherboard with a IBM PCI Hotplug controller. @@ -75,6 +76,7 @@ config HOTPLUG_PCI_IBM config HOTPLUG_PCI_ACPI tristate "ACPI PCI Hotplug driver" + depends on HOTPLUG_PCI depends on (!ACPI_DOCK && ACPI) || (ACPI_DOCK) help Say Y here if you have a system that supports PCI Hotplug using @@ -99,6 +101,7 @@ config HOTPLUG_PCI_ACPI_IBM config HOTPLUG_PCI_CPCI bool "CompactPCI Hotplug driver" + depends on HOTPLUG_PCI help Say Y here if you have a CompactPCI system card with CompactPCI hotswap support per the PICMG 2.1 specification. @@ -107,7 +110,7 @@ config HOTPLUG_PCI_CPCI config HOTPLUG_PCI_CPCI_ZT5550 tristate "Ziatech ZT5550 CompactPCI Hotplug driver" - depends on HOTPLUG_PCI_CPCI && X86 + depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86 help Say Y here if you have an Performance Technologies (formerly Intel, formerly just Ziatech) Ziatech ZT5550 CompactPCI system card. @@ -119,7 +122,7 @@ config HOTPLUG_PCI_CPCI_ZT5550 config HOTPLUG_PCI_CPCI_GENERIC tristate "Generic port I/O CompactPCI Hotplug driver" - depends on HOTPLUG_PCI_CPCI && X86 + depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86 help Say Y here if you have a CompactPCI system card that exposes the #ENUM hotswap signal as a bit in a system register that can be read through @@ -132,6 +135,7 @@ config HOTPLUG_PCI_CPCI_GENERIC config HOTPLUG_PCI_SHPC tristate "SHPC PCI Hotplug driver" + depends on HOTPLUG_PCI help Say Y here if you have a motherboard with a SHPC PCI Hotplug controller. @@ -143,7 +147,7 @@ config HOTPLUG_PCI_SHPC config HOTPLUG_PCI_RPA tristate "RPA PCI Hotplug driver" - depends on PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE + depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE help Say Y here if you have a RPA system that supports PCI Hotplug. @@ -166,11 +170,12 @@ config HOTPLUG_PCI_RPA_DLPAR config HOTPLUG_PCI_SGI tristate "SGI PCI Hotplug Support" - depends on IA64_SGI_SN2 || IA64_GENERIC + depends on HOTPLUG_PCI && (IA64_SGI_SN2 || IA64_GENERIC) help Say Y here if you want to use the SGI Altix Hotplug Driver for PCI devices. When in doubt, say N. -endif # HOTPLUG_PCI +endmenu + diff --git a/trunk/drivers/pci/hotplug/acpiphp_core.c b/trunk/drivers/pci/hotplug/acpiphp_core.c index fa5c0197d571..40c79b03c7ef 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_core.c +++ b/trunk/drivers/pci/hotplug/acpiphp_core.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "acpiphp.h" #define MY_NAME "acpiphp" diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 9ef4e989afc4..fca978fb158e 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "../pci.h" diff --git a/trunk/drivers/pci/hotplug/acpiphp_ibm.c b/trunk/drivers/pci/hotplug/acpiphp_ibm.c index e7322c25d377..7f03881a8b68 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_ibm.c +++ b/trunk/drivers/pci/hotplug/acpiphp_ibm.c @@ -424,7 +424,7 @@ static int __init ibm_acpiphp_init(void) int retval = 0; acpi_status status; struct acpi_device *device; - struct kobject *sysdir = &pci_hotplug_slots_subsys.kobj; + struct kobject *sysdir = &pci_hotplug_slots_subsys.kset.kobj; dbg("%s\n", __FUNCTION__); @@ -471,7 +471,7 @@ static int __init ibm_acpiphp_init(void) static void __exit ibm_acpiphp_exit(void) { acpi_status status; - struct kobject *sysdir = &pci_hotplug_slots_subsys.kobj; + struct kobject *sysdir = &pci_hotplug_slots_subsys.kset.kobj; dbg("%s\n", __FUNCTION__); diff --git a/trunk/drivers/pci/hotplug/cpcihp_zt5550.c b/trunk/drivers/pci/hotplug/cpcihp_zt5550.c index 41f6a8d79c81..1c12e9171097 100644 --- a/trunk/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/trunk/drivers/pci/hotplug/cpcihp_zt5550.c @@ -296,17 +296,13 @@ static struct pci_driver zt5550_hc_driver = { static int __init zt5550_init(void) { struct resource* r; - int rc; info(DRIVER_DESC " version: " DRIVER_VERSION); r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register"); if(!r) return -EBUSY; - rc = pci_register_driver(&zt5550_hc_driver); - if(rc < 0) - release_region(ENUM_PORT, 1); - return rc; + return pci_register_driver(&zt5550_hc_driver); } static void __exit diff --git a/trunk/drivers/pci/hotplug/fakephp.c b/trunk/drivers/pci/hotplug/fakephp.c index 027f6865d7e3..e27907c91d92 100644 --- a/trunk/drivers/pci/hotplug/fakephp.c +++ b/trunk/drivers/pci/hotplug/fakephp.c @@ -238,7 +238,7 @@ static void pci_rescan_bus(const struct pci_bus *bus) { unsigned int devfn; struct pci_dev *dev; - dev = alloc_pci_dev(); + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) return; diff --git a/trunk/drivers/pci/hotplug/ibmphp_core.c b/trunk/drivers/pci/hotplug/ibmphp_core.c index 0316eeaaeb29..59392946c2bd 100644 --- a/trunk/drivers/pci/hotplug/ibmphp_core.c +++ b/trunk/drivers/pci/hotplug/ibmphp_core.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "../pci.h" #include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */ #include "ibmphp.h" diff --git a/trunk/drivers/pci/hotplug/ibmphp_hpc.c b/trunk/drivers/pci/hotplug/ibmphp_hpc.c index 46abaa8c41f1..f55ac3885cb3 100644 --- a/trunk/drivers/pci/hotplug/ibmphp_hpc.c +++ b/trunk/drivers/pci/hotplug/ibmphp_hpc.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/pci/hotplug/pci_hotplug_core.c b/trunk/drivers/pci/hotplug/pci_hotplug_core.c index bd433ef6bfc6..f5d632e72323 100644 --- a/trunk/drivers/pci/hotplug/pci_hotplug_core.c +++ b/trunk/drivers/pci/hotplug/pci_hotplug_core.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +62,7 @@ static int debug; static LIST_HEAD(pci_hotplug_slot_list); -struct kset pci_hotplug_slots_subsys; +struct subsystem pci_hotplug_slots_subsys; static ssize_t hotplug_slot_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) @@ -763,7 +764,7 @@ static int __init pci_hotplug_init (void) { int result; - kobj_set_kset_s(&pci_hotplug_slots_subsys, pci_bus_type.subsys); + kset_set_kset_s(&pci_hotplug_slots_subsys, pci_bus_type.subsys); result = subsystem_register(&pci_hotplug_slots_subsys); if (result) { err("Register subsys with error %d\n", result); diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index ccc57627201e..d19fcae8a7c0 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -43,7 +43,6 @@ extern int pciehp_poll_mode; extern int pciehp_poll_time; extern int pciehp_debug; extern int pciehp_force; -extern struct workqueue_struct *pciehp_wq; #define dbg(format, arg...) \ do { \ @@ -71,16 +70,14 @@ struct slot { struct list_head slot_list; char name[SLOT_NAME_SIZE]; unsigned long last_emi_toggle; - struct delayed_work work; /* work for button event */ - struct mutex lock; }; struct event_info { u32 event_type; - struct slot *p_slot; - struct work_struct work; + u8 hp_slot; }; +#define MAX_EVENTS 10 struct controller { struct controller *next; struct mutex crit_sect; /* critical section mutex */ @@ -89,9 +86,11 @@ struct controller { int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; struct list_head slot_list; + struct event_info event_queue[MAX_EVENTS]; struct slot *slot; struct hpc_ops *hpc_ops; wait_queue_head_t queue; /* sleep & wake process */ + u8 next_event; u8 bus; u8 device; u8 function; @@ -150,17 +149,21 @@ struct controller { #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) #define EMI(cap) (cap & EMI_PRSN) -extern int pciehp_sysfs_enable_slot(struct slot *slot); -extern int pciehp_sysfs_disable_slot(struct slot *slot); +extern int pciehp_event_start_thread(void); +extern void pciehp_event_stop_thread(void); +extern int pciehp_enable_slot(struct slot *slot); +extern int pciehp_disable_slot(struct slot *slot); extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); extern int pciehp_configure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot); -extern void pciehp_queue_pushbutton_work(struct work_struct *work); int pcie_init(struct controller *ctrl, struct pcie_device *dev); +/* Global variables */ +extern struct controller *pciehp_ctrl_list; + static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) { struct slot *slot; diff --git a/trunk/drivers/pci/hotplug/pciehp_core.c b/trunk/drivers/pci/hotplug/pciehp_core.c index e5d3f0b4f45a..a92eda6e02f6 100644 --- a/trunk/drivers/pci/hotplug/pciehp_core.c +++ b/trunk/drivers/pci/hotplug/pciehp_core.c @@ -41,7 +41,7 @@ int pciehp_debug; int pciehp_poll_mode; int pciehp_poll_time; int pciehp_force; -struct workqueue_struct *pciehp_wq; +struct controller *pciehp_ctrl_list; #define DRIVER_VERSION "0.4" #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " @@ -62,6 +62,7 @@ MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing" #define PCIE_MODULE_NAME "pciehp" +static int pcie_start_thread (void); static int set_attention_status (struct hotplug_slot *slot, u8 value); static int enable_slot (struct hotplug_slot *slot); static int disable_slot (struct hotplug_slot *slot); @@ -228,8 +229,6 @@ static int init_slots(struct controller *ctrl) slot->device = ctrl->slot_device_offset + i; slot->hpc_ops = ctrl->hpc_ops; slot->number = ctrl->first_slot; - mutex_init(&slot->lock); - INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; @@ -287,9 +286,6 @@ static void cleanup_slots(struct controller *ctrl) if (EMI(ctrl->ctrlcap)) sysfs_remove_file(&slot->hotplug_slot->kobj, &hotplug_slot_attr_lock.attr); - cancel_delayed_work(&slot->work); - flush_scheduled_work(); - flush_workqueue(pciehp_wq); pci_hp_deregister(slot->hotplug_slot); } } @@ -318,7 +314,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - return pciehp_sysfs_enable_slot(slot); + return pciehp_enable_slot(slot); } @@ -328,7 +324,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - return pciehp_sysfs_disable_slot(slot); + return pciehp_disable_slot(slot); } static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) @@ -470,6 +466,17 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); + /* Finish setting up the hot plug ctrl device */ + ctrl->next_event = 0; + + if (!pciehp_ctrl_list) { + pciehp_ctrl_list = ctrl; + ctrl->next = NULL; + } else { + ctrl->next = pciehp_ctrl_list; + pciehp_ctrl_list = ctrl; + } + t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ @@ -489,14 +496,48 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ return -ENODEV; } -static void pciehp_remove (struct pcie_device *dev) + +static int pcie_start_thread(void) { - struct pci_dev *pdev = dev->port; - struct controller *ctrl = pci_get_drvdata(pdev); + int retval = 0; + + dbg("Initialize + Start the notification/polling mechanism \n"); + + retval = pciehp_event_start_thread(); + if (retval) { + dbg("pciehp_event_start_thread() failed\n"); + return retval; + } + + return retval; +} + +static void __exit unload_pciehpd(void) +{ + struct controller *ctrl; + struct controller *tctrl; + + ctrl = pciehp_ctrl_list; + + while (ctrl) { + cleanup_slots(ctrl); + + ctrl->hpc_ops->release_ctlr(ctrl); + + tctrl = ctrl; + ctrl = ctrl->next; + + kfree(tctrl); + } + + /* Stop the notification mechanism */ + pciehp_event_stop_thread(); - cleanup_slots(ctrl); - ctrl->hpc_ops->release_ctlr(ctrl); - kfree(ctrl); +} + +static void pciehp_remove (struct pcie_device *device) +{ + /* XXX - Needs to be adapted to device driver model */ } #ifdef CONFIG_PM @@ -544,18 +585,31 @@ static int __init pcied_init(void) pciehp_poll_mode = 1; #endif + retval = pcie_start_thread(); + if (retval) + goto error_hpc_init; + retval = pcie_port_service_register(&hpdriver_portdrv); dbg("pcie_port_service_register = %d\n", retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); if (retval) dbg("%s: Failure to register service\n", __FUNCTION__); + +error_hpc_init: + if (retval) { + pciehp_event_stop_thread(); + }; + return retval; } static void __exit pcied_cleanup(void) { dbg("unload_pciehpd()\n"); + unload_pciehpd(); + pcie_port_service_unregister(&hpdriver_portdrv); + info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); } diff --git a/trunk/drivers/pci/hotplug/pciehp_ctrl.c b/trunk/drivers/pci/hotplug/pciehp_ctrl.c index 7f22caa70178..4283ef56dbd9 100644 --- a/trunk/drivers/pci/hotplug/pciehp_ctrl.c +++ b/trunk/drivers/pci/hotplug/pciehp_ctrl.c @@ -32,61 +32,92 @@ #include #include #include -#include #include "../pci.h" #include "pciehp.h" -static void interrupt_event_handler(struct work_struct *work); -static int pciehp_enable_slot(struct slot *p_slot); -static int pciehp_disable_slot(struct slot *p_slot); +static void interrupt_event_handler(struct controller *ctrl); -static int queue_interrupt_event(struct slot *p_slot, u32 event_type) -{ - struct event_info *info; - - info = kmalloc(sizeof(*info), GFP_ATOMIC); - if (!info) - return -ENOMEM; - - info->event_type = event_type; - info->p_slot = p_slot; - INIT_WORK(&info->work, interrupt_event_handler); +static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ +static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ +static int event_finished; +static unsigned long pushbutton_pending; /* = 0 */ +static unsigned long surprise_rm_pending; /* = 0 */ - schedule_work(&info->work); - - return 0; +static inline char *slot_name(struct slot *p_slot) +{ + return p_slot->hotplug_slot->name; } u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) { struct slot *p_slot; - u32 event_type; + u8 rc = 0; + u8 getstatus; + struct event_info *taskInfo; /* Attention Button Change */ dbg("pciehp: Attention button interrupt received.\n"); - + + /* This is the structure that tells the worker thread what to do */ + taskInfo = &(ctrl->event_queue[ctrl->next_event]); p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); + p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + + ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS; + taskInfo->hp_slot = hp_slot; + + rc++; + /* * Button pressed - See if need to TAKE ACTION!!! */ - info("Button pressed on Slot(%s)\n", p_slot->name); - event_type = INT_BUTTON_PRESS; + info("Button pressed on Slot(%s)\n", slot_name(p_slot)); + taskInfo->event_type = INT_BUTTON_PRESS; + + if ((p_slot->state == BLINKINGON_STATE) + || (p_slot->state == BLINKINGOFF_STATE)) { + /* Cancel if we are still blinking; this means that we press the + * attention again before the 5 sec. limit expires to cancel hot-add + * or hot-remove + */ + taskInfo->event_type = INT_BUTTON_CANCEL; + info("Button cancel on Slot(%s)\n", slot_name(p_slot)); + } else if ((p_slot->state == POWERON_STATE) + || (p_slot->state == POWEROFF_STATE)) { + /* Ignore if the slot is on power-on or power-off state; this + * means that the previous attention button action to hot-add or + * hot-remove is undergoing + */ + taskInfo->event_type = INT_BUTTON_IGNORE; + info("Button ignore on Slot(%s)\n", slot_name(p_slot)); + } - queue_interrupt_event(p_slot, event_type); + if (rc) + up(&event_semaphore); /* signal event thread that new event is posted */ return 0; + } u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) { struct slot *p_slot; + u8 rc = 0; u8 getstatus; - u32 event_type; + struct event_info *taskInfo; /* Switch Change */ dbg("pciehp: Switch interrupt received.\n"); + /* This is the structure that tells the worker thread + * what to do + */ + taskInfo = &(ctrl->event_queue[ctrl->next_event]); + ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS; + taskInfo->hp_slot = hp_slot; + + rc++; p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); @@ -94,30 +125,39 @@ u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) /* * Switch opened */ - info("Latch open on Slot(%s)\n", p_slot->name); - event_type = INT_SWITCH_OPEN; + info("Latch open on Slot(%s)\n", slot_name(p_slot)); + taskInfo->event_type = INT_SWITCH_OPEN; } else { /* * Switch closed */ - info("Latch close on Slot(%s)\n", p_slot->name); - event_type = INT_SWITCH_CLOSE; + info("Latch close on Slot(%s)\n", slot_name(p_slot)); + taskInfo->event_type = INT_SWITCH_CLOSE; } - queue_interrupt_event(p_slot, event_type); + if (rc) + up(&event_semaphore); /* signal event thread that new event is posted */ - return 1; + return rc; } u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) { struct slot *p_slot; - u32 event_type; - u8 presence_save; + u8 presence_save, rc = 0; + struct event_info *taskInfo; /* Presence Change */ dbg("pciehp: Presence/Notify input change.\n"); + /* This is the structure that tells the worker thread + * what to do + */ + taskInfo = &(ctrl->event_queue[ctrl->next_event]); + ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS; + taskInfo->hp_slot = hp_slot; + + rc++; p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); /* Switch is open, assume a presence change @@ -128,49 +168,59 @@ u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) /* * Card Present */ - info("Card present on Slot(%s)\n", p_slot->name); - event_type = INT_PRESENCE_ON; + info("Card present on Slot(%s)\n", slot_name(p_slot)); + taskInfo->event_type = INT_PRESENCE_ON; } else { /* * Not Present */ - info("Card not present on Slot(%s)\n", p_slot->name); - event_type = INT_PRESENCE_OFF; + info("Card not present on Slot(%s)\n", slot_name(p_slot)); + taskInfo->event_type = INT_PRESENCE_OFF; } - queue_interrupt_event(p_slot, event_type); + if (rc) + up(&event_semaphore); /* signal event thread that new event is posted */ - return 1; + return rc; } u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) { struct slot *p_slot; - u32 event_type; + u8 rc = 0; + struct event_info *taskInfo; /* power fault */ dbg("pciehp: Power fault interrupt received.\n"); + /* this is the structure that tells the worker thread + * what to do + */ + taskInfo = &(ctrl->event_queue[ctrl->next_event]); + ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS; + taskInfo->hp_slot = hp_slot; + + rc++; p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { /* * power fault Cleared */ - info("Power fault cleared on Slot(%s)\n", p_slot->name); - event_type = INT_POWER_FAULT_CLEAR; + info("Power fault cleared on Slot(%s)\n", slot_name(p_slot)); + taskInfo->event_type = INT_POWER_FAULT_CLEAR; } else { /* * power fault */ - info("Power fault on Slot(%s)\n", p_slot->name); - event_type = INT_POWER_FAULT; + info("Power fault on Slot(%s)\n", slot_name(p_slot)); + taskInfo->event_type = INT_POWER_FAULT; info("power fault bit %x set\n", hp_slot); } + if (rc) + up(&event_semaphore); /* signal event thread that new event is posted */ - queue_interrupt_event(p_slot, event_type); - - return 1; + return rc; } /* The following routines constitute the bulk of the @@ -307,10 +357,13 @@ static int remove_board(struct slot *p_slot) return 0; } -struct power_work_info { - struct slot *p_slot; - struct work_struct work; -}; + +static void pushbutton_helper_thread(unsigned long data) +{ + pushbutton_pending = data; + + up(&event_semaphore); +} /** * pciehp_pushbutton_thread @@ -319,212 +372,274 @@ struct power_work_info { * Handles all pending events and exits. * */ -static void pciehp_power_thread(struct work_struct *work) +static void pciehp_pushbutton_thread(unsigned long slot) { - struct power_work_info *info = - container_of(work, struct power_work_info, work); - struct slot *p_slot = info->p_slot; - - mutex_lock(&p_slot->lock); - switch (p_slot->state) { - case POWEROFF_STATE: - mutex_unlock(&p_slot->lock); - dbg("%s: disabling bus:device(%x:%x)\n", - __FUNCTION__, p_slot->bus, p_slot->device); + struct slot *p_slot = (struct slot *) slot; + u8 getstatus; + + pushbutton_pending = 0; + + if (!p_slot) { + dbg("%s: Error! slot NULL\n", __FUNCTION__); + return; + } + + p_slot->hpc_ops->get_power_status(p_slot, &getstatus); + if (getstatus) { + p_slot->state = POWEROFF_STATE; + dbg("%s: disabling bus:device(%x:%x)\n", __FUNCTION__, + p_slot->bus, p_slot->device); + pciehp_disable_slot(p_slot); - mutex_lock(&p_slot->lock); p_slot->state = STATIC_STATE; - break; - case POWERON_STATE: - mutex_unlock(&p_slot->lock); + } else { + p_slot->state = POWERON_STATE; + dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, + p_slot->bus, p_slot->device); + if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) p_slot->hpc_ops->green_led_off(p_slot); - mutex_lock(&p_slot->lock); + p_slot->state = STATIC_STATE; - break; - default: - break; } - mutex_unlock(&p_slot->lock); - kfree(info); + return; } -void pciehp_queue_pushbutton_work(struct work_struct *work) +/** + * pciehp_surprise_rm_thread + * + * Scheduled procedure to handle blocking stuff for the surprise removal + * Handles all pending events and exits. + * + */ +static void pciehp_surprise_rm_thread(unsigned long slot) { - struct slot *p_slot = container_of(work, struct slot, work.work); - struct power_work_info *info; + struct slot *p_slot = (struct slot *) slot; + u8 getstatus; + + surprise_rm_pending = 0; - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - err("%s: Cannot allocate memory\n", __FUNCTION__); + if (!p_slot) { + dbg("%s: Error! slot NULL\n", __FUNCTION__); return; } - info->p_slot = p_slot; - INIT_WORK(&info->work, pciehp_power_thread); - mutex_lock(&p_slot->lock); - switch (p_slot->state) { - case BLINKINGOFF_STATE: + p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); + if (!getstatus) { p_slot->state = POWEROFF_STATE; - break; - case BLINKINGON_STATE: + dbg("%s: removing bus:device(%x:%x)\n", + __FUNCTION__, p_slot->bus, p_slot->device); + + pciehp_disable_slot(p_slot); + p_slot->state = STATIC_STATE; + } else { p_slot->state = POWERON_STATE; - break; - default: - goto out; + dbg("%s: adding bus:device(%x:%x)\n", + __FUNCTION__, p_slot->bus, p_slot->device); + + if (pciehp_enable_slot(p_slot) && + PWR_LED(p_slot->ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_off(p_slot); + + p_slot->state = STATIC_STATE; } - queue_work(pciehp_wq, &info->work); - out: - mutex_unlock(&p_slot->lock); + + return; } + + +/* this is the main worker thread */ +static int event_thread(void* data) +{ + struct controller *ctrl; + lock_kernel(); + daemonize("pciehpd_event"); + + unlock_kernel(); + + while (1) { + dbg("!!!!event_thread sleeping\n"); + down_interruptible (&event_semaphore); + dbg("event_thread woken finished = %d\n", event_finished); + if (event_finished || signal_pending(current)) + break; + /* Do stuff here */ + if (pushbutton_pending) + pciehp_pushbutton_thread(pushbutton_pending); + else if (surprise_rm_pending) + pciehp_surprise_rm_thread(surprise_rm_pending); + else + for (ctrl = pciehp_ctrl_list; ctrl; ctrl=ctrl->next) + interrupt_event_handler(ctrl); + } + dbg("event_thread signals exit\n"); + up(&event_exit); + return 0; +} + +int pciehp_event_start_thread(void) +{ + int pid; + + /* initialize our semaphores */ + init_MUTEX_LOCKED(&event_exit); + event_finished=0; + + init_MUTEX_LOCKED(&event_semaphore); + pid = kernel_thread(event_thread, NULL, 0); + + if (pid < 0) { + err ("Can't start up our event thread\n"); + return -1; + } + return 0; +} + + +void pciehp_event_stop_thread(void) +{ + event_finished = 1; + up(&event_semaphore); + down(&event_exit); +} + + static int update_slot_info(struct slot *slot) { struct hotplug_slot_info *info; + /* char buffer[SLOT_NAME_SIZE]; */ int result; - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); if (!info) return -ENOMEM; + /* make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot); */ + slot->hpc_ops->get_power_status(slot, &(info->power_status)); slot->hpc_ops->get_attention_status(slot, &(info->attention_status)); slot->hpc_ops->get_latch_status(slot, &(info->latch_status)); slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status)); + /* result = pci_hp_change_slot_info(buffer, info); */ result = pci_hp_change_slot_info(slot->hotplug_slot, info); kfree (info); return result; } -/* - * Note: This function must be called with slot->lock held - */ -static void handle_button_press_event(struct slot *p_slot) -{ - struct controller *ctrl = p_slot->ctrl; - u8 getstatus; - - switch (p_slot->state) { - case STATIC_STATE: - p_slot->hpc_ops->get_power_status(p_slot, &getstatus); - if (getstatus) { - p_slot->state = BLINKINGOFF_STATE; - info("PCI slot #%s - powering off due to button " - "press.\n", p_slot->name); - } else { - p_slot->state = BLINKINGON_STATE; - info("PCI slot #%s - powering on due to button " - "press.\n", p_slot->name); - } - /* blink green LED and turn off amber */ - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_blink(p_slot); - if (ATTN_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->set_attention_status(p_slot, 0); - - schedule_delayed_work(&p_slot->work, 5*HZ); - break; - case BLINKINGOFF_STATE: - case BLINKINGON_STATE: - /* - * Cancel if we are still blinking; this means that we - * press the attention again before the 5 sec. limit - * expires to cancel hot-add or hot-remove - */ - info("Button cancel on Slot(%s)\n", p_slot->name); - dbg("%s: button cancel\n", __FUNCTION__); - cancel_delayed_work(&p_slot->work); - if (p_slot->state == BLINKINGOFF_STATE) { - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_on(p_slot); - } else { - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_off(p_slot); - } - if (ATTN_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->set_attention_status(p_slot, 0); - info("PCI slot #%s - action canceled due to button press\n", - p_slot->name); - p_slot->state = STATIC_STATE; - break; - case POWEROFF_STATE: - case POWERON_STATE: - /* - * Ignore if the slot is on power-on or power-off state; - * this means that the previous attention button action - * to hot-add or hot-remove is undergoing - */ - info("Button ignore on Slot(%s)\n", p_slot->name); - update_slot_info(p_slot); - break; - default: - warn("Not a valid state\n"); - break; - } -} - -/* - * Note: This function must be called with slot->lock held - */ -static void handle_surprise_event(struct slot *p_slot) +static void interrupt_event_handler(struct controller *ctrl) { + int loop = 0; + int change = 1; + u8 hp_slot; u8 getstatus; - struct power_work_info *info; - - info = kmalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - err("%s: Cannot allocate memory\n", __FUNCTION__); - return; - } - info->p_slot = p_slot; - INIT_WORK(&info->work, pciehp_power_thread); - - p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); - if (!getstatus) - p_slot->state = POWEROFF_STATE; - else - p_slot->state = POWERON_STATE; - - queue_work(pciehp_wq, &info->work); -} - -static void interrupt_event_handler(struct work_struct *work) -{ - struct event_info *info = container_of(work, struct event_info, work); - struct slot *p_slot = info->p_slot; - struct controller *ctrl = p_slot->ctrl; + struct slot *p_slot; - mutex_lock(&p_slot->lock); - switch (info->event_type) { - case INT_BUTTON_PRESS: - handle_button_press_event(p_slot); - break; - case INT_POWER_FAULT: - if (!POWER_CTRL(ctrl->ctrlcap)) - break; - if (ATTN_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->set_attention_status(p_slot, 1); - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_off(p_slot); - break; - case INT_PRESENCE_ON: - case INT_PRESENCE_OFF: - if (!HP_SUPR_RM(ctrl->ctrlcap)) - break; - dbg("Surprise Removal\n"); - update_slot_info(p_slot); - handle_surprise_event(p_slot); - break; - default: - update_slot_info(p_slot); - break; + while (change) { + change = 0; + + for (loop = 0; loop < MAX_EVENTS; loop++) { + if (ctrl->event_queue[loop].event_type != 0) { + hp_slot = ctrl->event_queue[loop].hp_slot; + + p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); + + if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { + dbg("button cancel\n"); + del_timer(&p_slot->task_event); + + switch (p_slot->state) { + case BLINKINGOFF_STATE: + if (PWR_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_on(p_slot); + + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 0); + break; + case BLINKINGON_STATE: + if (PWR_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_off(p_slot); + + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 0); + break; + default: + warn("Not a valid state\n"); + return; + } + info("PCI slot #%s - action canceled due to button press.\n", slot_name(p_slot)); + p_slot->state = STATIC_STATE; + } + /* ***********Button Pressed (No action on 1st press...) */ + else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) { + + if (ATTN_BUTTN(ctrl->ctrlcap)) { + dbg("Button pressed\n"); + p_slot->hpc_ops->get_power_status(p_slot, &getstatus); + if (getstatus) { + /* slot is on */ + dbg("slot is on\n"); + p_slot->state = BLINKINGOFF_STATE; + info("PCI slot #%s - powering off due to button press.\n", slot_name(p_slot)); + } else { + /* slot is off */ + dbg("slot is off\n"); + p_slot->state = BLINKINGON_STATE; + info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot)); + } + + /* blink green LED and turn off amber */ + if (PWR_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_blink(p_slot); + + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 0); + + init_timer(&p_slot->task_event); + p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ + p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; + p_slot->task_event.data = (unsigned long) p_slot; + + add_timer(&p_slot->task_event); + } + } + /***********POWER FAULT********************/ + else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { + if (POWER_CTRL(ctrl->ctrlcap)) { + dbg("power fault\n"); + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 1); + + if (PWR_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_off(p_slot); + } + } + /***********SURPRISE REMOVAL********************/ + else if ((ctrl->event_queue[loop].event_type == INT_PRESENCE_ON) || + (ctrl->event_queue[loop].event_type == INT_PRESENCE_OFF)) { + if (HP_SUPR_RM(ctrl->ctrlcap)) { + dbg("Surprise Removal\n"); + if (p_slot) { + surprise_rm_pending = (unsigned long) p_slot; + up(&event_semaphore); + update_slot_info(p_slot); + } + } + } else { + /* refresh notification */ + if (p_slot) + update_slot_info(p_slot); + } + + ctrl->event_queue[loop].event_type = 0; + + change = 1; + } + } /* End of FOR loop */ } - mutex_unlock(&p_slot->lock); - - kfree(info); } int pciehp_enable_slot(struct slot *p_slot) @@ -538,7 +653,7 @@ int pciehp_enable_slot(struct slot *p_slot) rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (rc || !getstatus) { info("%s: no adapter on slot(%s)\n", __FUNCTION__, - p_slot->name); + slot_name(p_slot)); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -546,7 +661,7 @@ int pciehp_enable_slot(struct slot *p_slot) rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%s)\n", __FUNCTION__, - p_slot->name); + slot_name(p_slot)); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -556,7 +671,7 @@ int pciehp_enable_slot(struct slot *p_slot) rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%s)\n", __FUNCTION__, - p_slot->name); + slot_name(p_slot)); mutex_unlock(&p_slot->ctrl->crit_sect); return -EINVAL; } @@ -591,7 +706,7 @@ int pciehp_disable_slot(struct slot *p_slot) ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: no adapter on slot(%s)\n", __FUNCTION__, - p_slot->name); + slot_name(p_slot)); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -601,7 +716,7 @@ int pciehp_disable_slot(struct slot *p_slot) ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%s)\n", __FUNCTION__, - p_slot->name); + slot_name(p_slot)); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -611,7 +726,7 @@ int pciehp_disable_slot(struct slot *p_slot) ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%s)\n", __FUNCTION__, - p_slot->name); + slot_name(p_slot)); mutex_unlock(&p_slot->ctrl->crit_sect); return -EINVAL; } @@ -624,66 +739,3 @@ int pciehp_disable_slot(struct slot *p_slot) return ret; } -int pciehp_sysfs_enable_slot(struct slot *p_slot) -{ - int retval = -ENODEV; - - mutex_lock(&p_slot->lock); - switch (p_slot->state) { - case BLINKINGON_STATE: - cancel_delayed_work(&p_slot->work); - case STATIC_STATE: - p_slot->state = POWERON_STATE; - mutex_unlock(&p_slot->lock); - retval = pciehp_enable_slot(p_slot); - mutex_lock(&p_slot->lock); - p_slot->state = STATIC_STATE; - break; - case POWERON_STATE: - info("Slot %s is already in powering on state\n", - p_slot->name); - break; - case BLINKINGOFF_STATE: - case POWEROFF_STATE: - info("Already enabled on slot %s\n", p_slot->name); - break; - default: - err("Not a valid state on slot %s\n", p_slot->name); - break; - } - mutex_unlock(&p_slot->lock); - - return retval; -} - -int pciehp_sysfs_disable_slot(struct slot *p_slot) -{ - int retval = -ENODEV; - - mutex_lock(&p_slot->lock); - switch (p_slot->state) { - case BLINKINGOFF_STATE: - cancel_delayed_work(&p_slot->work); - case STATIC_STATE: - p_slot->state = POWEROFF_STATE; - mutex_unlock(&p_slot->lock); - retval = pciehp_disable_slot(p_slot); - mutex_lock(&p_slot->lock); - p_slot->state = STATIC_STATE; - break; - case POWEROFF_STATE: - info("Slot %s is already in powering off state\n", - p_slot->name); - break; - case BLINKINGON_STATE: - case POWERON_STATE: - info("Already disabled on slot %s\n", p_slot->name); - break; - default: - err("Not a valid state on slot %s\n", p_slot->name); - break; - } - mutex_unlock(&p_slot->lock); - - return retval; -} diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index 9aac6a87eb53..fbc64aa2dd68 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -71,8 +71,6 @@ #define DBG_LEAVE_ROUTINE #endif /* DEBUG */ -static atomic_t pciehp_num_controllers = ATOMIC_INIT(0); - struct ctrl_reg { u8 cap_id; u8 nxt_ptr; @@ -221,7 +219,10 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) #define EMI_STATE 0x0080 #define EMI_STATUS_BIT 7 +static spinlock_t hpc_event_lock; + DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ +static int ctlr_seq_num = 0; /* Controller sequence # */ static irqreturn_t pcie_isr(int irq, void *dev_id); static void start_int_poll_timer(struct controller *ctrl, int sec); @@ -655,13 +656,6 @@ static void hpc_release_ctlr(struct controller *ctrl) else free_irq(ctrl->pci_dev->irq, ctrl); - /* - * If this is the last controller to be released, destroy the - * pciehp work queue - */ - if (atomic_dec_and_test(&pciehp_num_controllers)) - destroy_workqueue(pciehp_wq); - DBG_LEAVE_ROUTINE } @@ -1158,6 +1152,7 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) int pcie_init(struct controller * ctrl, struct pcie_device *dev) { int rc; + static int first = 1; u16 temp_word; u16 cap_reg; u16 intr_enable = 0; @@ -1226,6 +1221,11 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); + if (first) { + spin_lock_init(&hpc_event_lock); + first = 0; + } + for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) if (pci_resource_len(pdev, rc) > 0) dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc, @@ -1286,8 +1286,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED, MY_NAME, (void *)ctrl); dbg("%s: request_irq %d for hpc%d (returns %d)\n", - __FUNCTION__, ctrl->pci_dev->irq, - atomic_read(&pciehp_num_controllers), rc); + __FUNCTION__, ctrl->pci_dev->irq, ctlr_seq_num, rc); if (rc) { err("Can't get irq %d for the hotplug controller\n", ctrl->pci_dev->irq); @@ -1297,18 +1296,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); - /* - * If this is the first controller to be initialized, - * initialize the pciehp work queue - */ - if (atomic_add_return(1, &pciehp_num_controllers) == 1) { - pciehp_wq = create_singlethread_workqueue("pciehpd"); - if (!pciehp_wq) { - rc = -ENOMEM; - goto abort_free_irq; - } - } - rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); if (rc) { err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); @@ -1362,6 +1349,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_disable_intr; } + ctlr_seq_num++; ctrl->hpc_ops = &pciehp_hpc_ops; DBG_LEAVE_ROUTINE diff --git a/trunk/drivers/pci/hotplug/rpadlpar_core.c b/trunk/drivers/pci/hotplug/rpadlpar_core.c index bb3c101c2c5a..72383467a0d5 100644 --- a/trunk/drivers/pci/hotplug/rpadlpar_core.c +++ b/trunk/drivers/pci/hotplug/rpadlpar_core.c @@ -98,15 +98,7 @@ static struct device_node *find_dlpar_node(char *drc_name, int *node_type) return NULL; } -/** - * find_php_slot - return hotplug slot structure for device node - * - * This routine will return the hotplug slot structure - * for a given device node. Note that built-in PCI slots - * may be dlpar-able, but not hot-pluggable, so this routine - * will return NULL for built-in PCI slots. - */ -static struct slot *find_php_slot(struct device_node *dn) +static struct slot *find_slot(struct device_node *dn) { struct list_head *tmp, *n; struct slot *slot; @@ -232,9 +224,9 @@ static int dlpar_remove_phb(char *drc_name, struct device_node *dn) if (!pcibios_find_pci_bus(dn)) return -EINVAL; - /* If pci slot is hotplugable, use hotplug to remove it */ - slot = find_php_slot(dn); + slot = find_slot(dn); if (slot) { + /* Remove hotplug slot */ if (rpaphp_deregister_slot(slot)) { printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", @@ -378,17 +370,22 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) if (!bus) return -EINVAL; - /* If pci slot is hotplugable, use hotplug to remove it */ - slot = find_php_slot(dn); + slot = find_slot(dn); if (slot) { + /* Remove hotplug slot */ if (rpaphp_deregister_slot(slot)) { printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", __FUNCTION__, drc_name); return -EIO; } - } else - pcibios_remove_pci_devices(bus); + } else { + struct pci_dev *dev, *tmp; + list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { + eeh_remove_bus_device(dev); + pci_remove_bus_device(dev); + } + } if (unmap_bus_range(bus)) { printk(KERN_ERR "%s: failed to unmap bus range\n", diff --git a/trunk/drivers/pci/hotplug/rpaphp.h b/trunk/drivers/pci/hotplug/rpaphp.h index c822a779653f..2e7accf0f734 100644 --- a/trunk/drivers/pci/hotplug/rpaphp.h +++ b/trunk/drivers/pci/hotplug/rpaphp.h @@ -83,15 +83,19 @@ struct slot { extern struct hotplug_slot_ops rpaphp_hotplug_slot_ops; extern struct list_head rpaphp_slot_head; +extern int num_slots; /* function prototypes */ /* rpaphp_pci.c */ -extern int rpaphp_enable_slot(struct slot *slot); +extern int rpaphp_enable_pci_slot(struct slot *slot); +extern int rpaphp_register_pci_slot(struct slot *slot); +extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); extern int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); +extern int rpaphp_remove_slot(struct slot *slot); extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, char **drc_name, char **drc_type, int *drc_power_domain); @@ -100,5 +104,7 @@ extern void dealloc_slot_struct(struct slot *slot); extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); extern int rpaphp_register_slot(struct slot *slot); extern int rpaphp_deregister_slot(struct slot *slot); +extern int rpaphp_get_power_status(struct slot *slot, u8 * value); +extern int rpaphp_set_attention_status(struct slot *slot, u8 status); #endif /* _PPC64PHP_H */ diff --git a/trunk/drivers/pci/hotplug/rpaphp_core.c b/trunk/drivers/pci/hotplug/rpaphp_core.c index 458c08ef2654..71a2cb8baa4a 100644 --- a/trunk/drivers/pci/hotplug/rpaphp_core.c +++ b/trunk/drivers/pci/hotplug/rpaphp_core.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include /* for eeh_add_device() */ #include /* rtas_call */ @@ -38,7 +39,9 @@ #include "rpaphp.h" int debug; +static struct semaphore rpaphp_sem; LIST_HEAD(rpaphp_slot_head); +int num_slots; #define DRIVER_VERSION "0.1" #define DRIVER_AUTHOR "Linda Xie " @@ -52,6 +55,11 @@ MODULE_LICENSE("GPL"); module_param(debug, bool, 0644); +static int rpaphp_get_attention_status(struct slot *slot) +{ + return slot->hotplug_slot->info->attention_status; +} + /** * set_attention_status - set attention LED * echo 0 > attention -- set LED OFF @@ -61,75 +69,79 @@ module_param(debug, bool, 0644); */ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) { - int rc; + int retval = 0; struct slot *slot = (struct slot *)hotplug_slot->private; + down(&rpaphp_sem); switch (value) { case 0: - case 1: - case 2: + retval = rpaphp_set_attention_status(slot, LED_OFF); + hotplug_slot->info->attention_status = 0; break; + case 1: default: - value = 1; + retval = rpaphp_set_attention_status(slot, LED_ON); + hotplug_slot->info->attention_status = 1; + break; + case 2: + retval = rpaphp_set_attention_status(slot, LED_ID); + hotplug_slot->info->attention_status = 2; break; } - - rc = rtas_set_indicator(DR_INDICATOR, slot->index, value); - if (!rc) - hotplug_slot->info->attention_status = value; - - return rc; + up(&rpaphp_sem); + return retval; } /** * get_power_status - get power status of a slot * @hotplug_slot: slot to get status * @value: pointer to store status + * + * */ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) { - int retval, level; + int retval; struct slot *slot = (struct slot *)hotplug_slot->private; - retval = rtas_get_power_level (slot->power_domain, &level); - if (!retval) - *value = level; + down(&rpaphp_sem); + retval = rpaphp_get_power_status(slot, value); + up(&rpaphp_sem); return retval; } /** * get_attention_status - get attention LED status + * + * */ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) { + int retval = 0; struct slot *slot = (struct slot *)hotplug_slot->private; - *value = slot->hotplug_slot->info->attention_status; - return 0; + + down(&rpaphp_sem); + *value = rpaphp_get_attention_status(slot); + up(&rpaphp_sem); + return retval; } static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) { struct slot *slot = (struct slot *)hotplug_slot->private; - int rc, state; - - rc = rpaphp_get_sensor_state(slot, &state); - - *value = NOT_VALID; - if (rc) - return rc; - - if (state == EMPTY) - *value = EMPTY; - else if (state == PRESENT) - *value = slot->state; + int retval = 0; - return 0; + down(&rpaphp_sem); + retval = rpaphp_get_pci_adapter_status(slot, 0, value); + up(&rpaphp_sem); + return retval; } static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { struct slot *slot = (struct slot *)hotplug_slot->private; + down(&rpaphp_sem); switch (slot->type) { case 1: case 2: @@ -160,6 +172,7 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe break; } + up(&rpaphp_sem); return 0; } @@ -169,10 +182,10 @@ static int get_children_props(struct device_node *dn, const int **drc_indexes, { const int *indexes, *names, *types, *domains; - indexes = of_get_property(dn, "ibm,drc-indexes", NULL); - names = of_get_property(dn, "ibm,drc-names", NULL); - types = of_get_property(dn, "ibm,drc-types", NULL); - domains = of_get_property(dn, "ibm,drc-power-domains", NULL); + indexes = get_property(dn, "ibm,drc-indexes", NULL); + names = get_property(dn, "ibm,drc-names", NULL); + types = get_property(dn, "ibm,drc-types", NULL); + domains = get_property(dn, "ibm,drc-power-domains", NULL); if (!indexes || !names || !types || !domains) { /* Slot does not have dynamically-removable children */ @@ -205,7 +218,7 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, char *name_tmp, *type_tmp; int i, rc; - my_index = of_get_property(dn, "ibm,my-drc-index", NULL); + my_index = get_property(dn, "ibm,my-drc-index", NULL); if (!my_index) { /* Node isn't DLPAR/hotplug capable */ return -EINVAL; @@ -252,14 +265,6 @@ static int is_php_type(char *drc_type) return 1; } -/** - * is_php_dn() - return 1 if this is a hotpluggable pci slot, else 0 - * - * This routine will return true only if the device node is - * a hotpluggable slot. This routine will return false - * for built-in pci slots (even when the built-in slots are - * dlparable.) - */ static int is_php_dn(struct device_node *dn, const int **indexes, const int **names, const int **types, const int **power_domains) { @@ -267,31 +272,24 @@ static int is_php_dn(struct device_node *dn, const int **indexes, int rc; rc = get_children_props(dn, indexes, names, &drc_types, power_domains); - if (rc < 0) - return 0; - - if (!is_php_type((char *) &drc_types[1])) - return 0; + if (rc >= 0) { + if (is_php_type((char *) &drc_types[1])) { + *types = drc_types; + return 1; + } + } - *types = drc_types; - return 1; + return 0; } /** - * rpaphp_add_slot -- declare a hotplug slot to the hotplug subsystem. - * @dn device node of slot - * - * This subroutine will register a hotplugable slot with the - * PCI hotplug infrastructure. This routine is typicaly called - * during boot time, if the hotplug slots are present at boot time, - * or is called later, by the dlpar add code, if the slot is - * being dynamically added during runtime. - * - * If the device node points at an embedded (built-in) slot, this - * routine will just return without doing anything, since embedded - * slots cannot be hotplugged. + * rpaphp_add_slot -- add hotplug or dlpar slot * - * To remove a slot, it suffices to call rpaphp_deregister_slot() + * rpaphp not only registers PCI hotplug slots(HOTPLUG), + * but also logical DR slots(EMBEDDED). + * HOTPLUG slot: An adapter can be physically added/removed. + * EMBEDDED slot: An adapter can be logically removed/added + * from/to a partition with the slot. */ int rpaphp_add_slot(struct device_node *dn) { @@ -301,42 +299,34 @@ int rpaphp_add_slot(struct device_node *dn) const int *indexes, *names, *types, *power_domains; char *name, *type; - if (!dn->name || strcmp(dn->name, "pci")) - return 0; - - /* If this is not a hotplug slot, return without doing anything. */ - if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) - return 0; - dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name); /* register PCI devices */ - name = (char *) &names[1]; - type = (char *) &types[1]; - for (i = 0; i < indexes[0]; i++) { - - slot = alloc_slot_struct(dn, indexes[i + 1], name, power_domains[i + 1]); - if (!slot) - return -ENOMEM; - - slot->type = simple_strtoul(type, NULL, 10); + if (dn->name != 0 && strcmp(dn->name, "pci") == 0) { + if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) + goto exit; + + name = (char *) &names[1]; + type = (char *) &types[1]; + for (i = 0; i < indexes[0]; i++, + name += (strlen(name) + 1), type += (strlen(type) + 1)) { + + if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, + power_domains[i + 1]))) { + retval = -ENOMEM; + goto exit; + } + slot->type = simple_strtoul(type, NULL, 10); - dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", - indexes[i + 1], name, type); + dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", + indexes[i + 1], name, type); - retval = rpaphp_enable_slot(slot); - if (!retval) - retval = rpaphp_register_slot(slot); - - if (retval) - dealloc_slot_struct(slot); - - name += strlen(name) + 1; - type += strlen(type) + 1; + retval = rpaphp_register_pci_slot(slot); + } } - dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); - - /* XXX FIXME: reports a failure only if last entry in loop failed */ +exit: + dbg("%s - Exit: num_slots=%d rc[%d]\n", + __FUNCTION__, num_slots, retval); return retval; } @@ -364,6 +354,7 @@ static int __init rpaphp_init(void) struct device_node *dn = NULL; info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); + init_MUTEX(&rpaphp_sem); while ((dn = of_find_node_by_name(dn, "pci"))) rpaphp_add_slot(dn); @@ -376,9 +367,8 @@ static void __exit rpaphp_exit(void) cleanup_slots(); } -static int enable_slot(struct hotplug_slot *hotplug_slot) +static int __enable_slot(struct slot *slot) { - struct slot *slot = (struct slot *)hotplug_slot->private; int state; int retval; @@ -402,17 +392,46 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) return 0; } -static int disable_slot(struct hotplug_slot *hotplug_slot) +static int enable_slot(struct hotplug_slot *hotplug_slot) { + int retval; struct slot *slot = (struct slot *)hotplug_slot->private; + + down(&rpaphp_sem); + retval = __enable_slot(slot); + up(&rpaphp_sem); + + return retval; +} + +static int __disable_slot(struct slot *slot) +{ + struct pci_dev *dev, *tmp; + if (slot->state == NOT_CONFIGURED) return -EINVAL; - pcibios_remove_pci_devices(slot->bus); + list_for_each_entry_safe(dev, tmp, &slot->bus->devices, bus_list) { + eeh_remove_bus_device(dev); + pci_remove_bus_device(dev); + } + slot->state = NOT_CONFIGURED; return 0; } +static int disable_slot(struct hotplug_slot *hotplug_slot) +{ + struct slot *slot = (struct slot *)hotplug_slot->private; + int retval; + + down(&rpaphp_sem); + retval = __disable_slot (slot); + up(&rpaphp_sem); + + return retval; +} + struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .owner = THIS_MODULE, .enable_slot = enable_slot, diff --git a/trunk/drivers/pci/hotplug/rpaphp_pci.c b/trunk/drivers/pci/hotplug/rpaphp_pci.c index 54ca8650d511..6f6cbede5135 100644 --- a/trunk/drivers/pci/hotplug/rpaphp_pci.c +++ b/trunk/drivers/pci/hotplug/rpaphp_pci.c @@ -64,6 +64,75 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state) return rc; } +/** + * get_pci_adapter_status - get the status of a slot + * + * 0-- slot is empty + * 1-- adapter is configured + * 2-- adapter is not configured + * 3-- not valid + */ +int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) +{ + struct pci_bus *bus; + int state, rc; + + *value = NOT_VALID; + rc = rpaphp_get_sensor_state(slot, &state); + if (rc) + goto exit; + + if (state == EMPTY) + *value = EMPTY; + else if (state == PRESENT) { + if (!is_init) { + /* at run-time slot->state can be changed by */ + /* config/unconfig adapter */ + *value = slot->state; + } else { + bus = pcibios_find_pci_bus(slot->dn); + if (bus && !list_empty(&bus->devices)) + *value = CONFIGURED; + else + *value = NOT_CONFIGURED; + } + } +exit: + return rc; +} + +static void print_slot_pci_funcs(struct pci_bus *bus) +{ + struct device_node *dn; + struct pci_dev *dev; + + dn = pci_bus_to_OF_node(bus); + if (!dn) + return; + + dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name); + list_for_each_entry (dev, &bus->devices, bus_list) + dbg("\t%s\n", pci_name(dev)); + return; +} + +static int setup_pci_hotplug_slot_info(struct slot *slot) +{ + struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info; + + dbg("%s Initilize the PCI slot's hotplug->info structure ...\n", + __FUNCTION__); + rpaphp_get_power_status(slot, &hotplug_slot_info->power_status); + rpaphp_get_pci_adapter_status(slot, 1, + &hotplug_slot_info->adapter_status); + if (hotplug_slot_info->adapter_status == NOT_VALID) { + err("%s: NOT_VALID: skip dn->full_name=%s\n", + __FUNCTION__, slot->dn->full_name); + return -EINVAL; + } + return 0; +} + static void set_slot_name(struct slot *slot) { struct pci_bus *bus = slot->bus; @@ -77,73 +146,69 @@ static void set_slot_name(struct slot *slot) bus->number); } -/** - * rpaphp_enable_slot - record slot state, config pci device - * - * Initialize values in the slot, and the hotplug_slot info - * structures to indicate if there is a pci card plugged into - * the slot. If the slot is not empty, run the pcibios routine - * to get pcibios stuff correctly set up. - */ -int rpaphp_enable_slot(struct slot *slot) +static int setup_pci_slot(struct slot *slot) { - int rc, level, state; + struct device_node *dn = slot->dn; struct pci_bus *bus; - struct hotplug_slot_info *info = slot->hotplug_slot->info; - - info->adapter_status = NOT_VALID; - slot->state = EMPTY; - - /* Find out if the power is turned on for the slot */ - rc = rtas_get_power_level(slot->power_domain, &level); - if (rc) - return rc; - info->power_status = level; - - /* Figure out if there is an adapter in the slot */ - rc = rpaphp_get_sensor_state(slot, &state); - if (rc) - return rc; - bus = pcibios_find_pci_bus(slot->dn); + BUG_ON(!dn); + bus = pcibios_find_pci_bus(dn); if (!bus) { - err("%s: no pci_bus for dn %s\n", __FUNCTION__, slot->dn->full_name); - return -EINVAL; + err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name); + goto exit_rc; } - info->adapter_status = EMPTY; slot->bus = bus; slot->pci_devs = &bus->devices; set_slot_name(slot); - /* if there's an adapter in the slot, go add the pci devices */ - if (state == PRESENT) { - info->adapter_status = NOT_CONFIGURED; - slot->state = NOT_CONFIGURED; - - /* non-empty slot has to have child */ - if (!slot->dn->child) { - err("%s: slot[%s]'s device_node doesn't have child for adapter\n", - __FUNCTION__, slot->name); - return -EINVAL; + /* find slot's pci_dev if it's not empty */ + if (slot->hotplug_slot->info->adapter_status == EMPTY) { + slot->state = EMPTY; /* slot is empty */ + } else { + /* slot is occupied */ + if (!dn->child) { + /* non-empty slot has to have child */ + err("%s: slot[%s]'s device_node doesn't have child for adapter\n", + __FUNCTION__, slot->name); + goto exit_rc; } - if (list_empty(&bus->devices)) - pcibios_add_pci_devices(bus); + if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { + dbg("%s CONFIGURING pci adapter in slot[%s]\n", + __FUNCTION__, slot->name); + pcibios_add_pci_devices(slot->bus); - if (!list_empty(&bus->devices)) { - info->adapter_status = CONFIGURED; - slot->state = CONFIGURED; + } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) { + err("%s: slot[%s]'s adapter_status is NOT_VALID.\n", + __FUNCTION__, slot->name); + goto exit_rc; } - - if (debug) { - struct pci_dev *dev; - dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, slot->dn->full_name); - list_for_each_entry (dev, &bus->devices, bus_list) - dbg("\t%s\n", pci_name(dev)); + print_slot_pci_funcs(slot->bus); + if (!list_empty(slot->pci_devs)) { + slot->state = CONFIGURED; + } else { + /* DLPAR add as opposed to + * boot time */ + slot->state = NOT_CONFIGURED; } } - return 0; +exit_rc: + dealloc_slot_struct(slot); + return -EINVAL; +} + +int rpaphp_register_pci_slot(struct slot *slot) +{ + int rc = -EINVAL; + + if (setup_pci_hotplug_slot_info(slot)) + goto exit_rc; + if (setup_pci_slot(slot)) + goto exit_rc; + rc = rpaphp_register_slot(slot); +exit_rc: + return rc; } diff --git a/trunk/drivers/pci/hotplug/rpaphp_slot.c b/trunk/drivers/pci/hotplug/rpaphp_slot.c index d4ee8723fcb3..3009193f0058 100644 --- a/trunk/drivers/pci/hotplug/rpaphp_slot.c +++ b/trunk/drivers/pci/hotplug/rpaphp_slot.c @@ -56,6 +56,7 @@ static struct hotplug_slot_attribute php_attr_location = { static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = (struct slot *) hotplug_slot->private; + dealloc_slot_struct(slot); } @@ -64,12 +65,12 @@ void dealloc_slot_struct(struct slot *slot) kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); - kfree(slot->location); kfree(slot); + return; } -struct slot *alloc_slot_struct(struct device_node *dn, - int drc_index, char *drc_name, int power_domain) +struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, + int power_domain) { struct slot *slot; @@ -114,7 +115,7 @@ struct slot *alloc_slot_struct(struct device_node *dn, static int is_registered(struct slot *slot) { - struct slot *tmp_slot; + struct slot *tmp_slot; list_for_each_entry(tmp_slot, &rpaphp_slot_head, rpaphp_slot_list) { if (!strcmp(tmp_slot->name, slot->name)) @@ -139,6 +140,8 @@ int rpaphp_deregister_slot(struct slot *slot) retval = pci_hp_deregister(php_slot); if (retval) err("Problem unregistering a slot %s\n", slot->name); + else + num_slots--; dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; @@ -157,13 +160,14 @@ int rpaphp_register_slot(struct slot *slot) /* should not try to register the same slot twice */ if (is_registered(slot)) { err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); - return -EAGAIN; + retval = -EAGAIN; + goto register_fail; } retval = pci_hp_register(php_slot); if (retval) { err("pci_hp_register failed with error %d\n", retval); - return retval; + goto register_fail; } /* create "phy_location" file */ @@ -177,10 +181,43 @@ int rpaphp_register_slot(struct slot *slot) list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); info("Slot [%s](PCI location=%s) registered\n", slot->name, slot->location); + num_slots++; return 0; sysfs_fail: pci_hp_deregister(php_slot); +register_fail: + rpaphp_release_slot(php_slot); return retval; } +int rpaphp_get_power_status(struct slot *slot, u8 * value) +{ + int rc = 0, level; + + rc = rtas_get_power_level(slot->power_domain, &level); + if (rc < 0) { + err("failed to get power-level for slot(%s), rc=0x%x\n", + slot->location, rc); + return rc; + } + + dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n", + __FUNCTION__, slot->name, slot->power_domain, level); + *value = level; + + return rc; +} + +int rpaphp_set_attention_status(struct slot *slot, u8 status) +{ + int rc; + + /* status: LED_OFF or LED_ON */ + rc = rtas_set_indicator(DR_INDICATOR, slot->index, status); + if (rc < 0) + err("slot(name=%s location=%s index=0x%x) set attention-status(%d) failed! rc=0x%x\n", + slot->name, slot->location, slot->index, status, rc); + + return rc; +} diff --git a/trunk/drivers/pci/hotplug/shpchp.h b/trunk/drivers/pci/hotplug/shpchp.h index 37ed0884b972..01d31a1f697c 100644 --- a/trunk/drivers/pci/hotplug/shpchp.h +++ b/trunk/drivers/pci/hotplug/shpchp.h @@ -166,7 +166,7 @@ extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); extern int shpchp_configure_device(struct slot *p_slot); extern int shpchp_unconfigure_device(struct slot *p_slot); extern void cleanup_slots(struct controller *ctrl); -extern void shpchp_queue_pushbutton_work(struct work_struct *work); +extern void queue_pushbutton_work(struct work_struct *work); extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); #ifdef CONFIG_ACPI diff --git a/trunk/drivers/pci/hotplug/shpchp_core.c b/trunk/drivers/pci/hotplug/shpchp_core.c index 80dec9796b31..5f4bc08a633a 100644 --- a/trunk/drivers/pci/hotplug/shpchp_core.c +++ b/trunk/drivers/pci/hotplug/shpchp_core.c @@ -136,7 +136,7 @@ static int init_slots(struct controller *ctrl) slot->hpc_ops = ctrl->hpc_ops; slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i); mutex_init(&slot->lock); - INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work); + INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; diff --git a/trunk/drivers/pci/hotplug/shpchp_ctrl.c b/trunk/drivers/pci/hotplug/shpchp_ctrl.c index d2fc35598cdd..b746bd265bc6 100644 --- a/trunk/drivers/pci/hotplug/shpchp_ctrl.c +++ b/trunk/drivers/pci/hotplug/shpchp_ctrl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "../pci.h" @@ -432,7 +433,7 @@ static void shpchp_pushbutton_thread(struct work_struct *work) kfree(info); } -void shpchp_queue_pushbutton_work(struct work_struct *work) +void queue_pushbutton_work(struct work_struct *work) { struct slot *p_slot = container_of(work, struct slot, work.work); struct pushbutton_work_info *info; diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index e6740d1a0824..435c1958a7b7 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -23,8 +24,20 @@ #include "pci.h" #include "msi.h" +static struct kmem_cache* msi_cachep; + static int pci_msi_enable = 1; +static int msi_cache_init(void) +{ + msi_cachep = kmem_cache_create("msi_cache", sizeof(struct msi_desc), + 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + if (!msi_cachep) + return -ENOMEM; + + return 0; +} + static void msi_set_enable(struct pci_dev *dev, int enable) { int pos; @@ -55,29 +68,6 @@ static void msix_set_enable(struct pci_dev *dev, int enable) } } -static void msix_flush_writes(unsigned int irq) -{ - struct msi_desc *entry; - - entry = get_irq_msi(irq); - BUG_ON(!entry || !entry->dev); - switch (entry->msi_attrib.type) { - case PCI_CAP_ID_MSI: - /* nothing to do */ - break; - case PCI_CAP_ID_MSIX: - { - int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; - readl(entry->mask_base + offset); - break; - } - default: - BUG(); - break; - } -} - static void msi_set_mask_bit(unsigned int irq, int flag) { struct msi_desc *entry; @@ -197,28 +187,41 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) void mask_msi_irq(unsigned int irq) { msi_set_mask_bit(irq, 1); - msix_flush_writes(irq); } void unmask_msi_irq(unsigned int irq) { msi_set_mask_bit(irq, 0); - msix_flush_writes(irq); } -static int msi_free_irqs(struct pci_dev* dev); +static int msi_free_irq(struct pci_dev* dev, int irq); + +static int msi_init(void) +{ + static int status = -ENOMEM; + + if (!status) + return status; + status = msi_cache_init(); + if (status < 0) { + pci_msi_enable = 0; + printk(KERN_WARNING "PCI: MSI cache init failed\n"); + return status; + } + + return status; +} static struct msi_desc* alloc_msi_entry(void) { struct msi_desc *entry; - entry = kzalloc(sizeof(struct msi_desc), GFP_KERNEL); + entry = kmem_cache_zalloc(msi_cachep, GFP_KERNEL); if (!entry) return NULL; - INIT_LIST_HEAD(&entry->list); - entry->irq = 0; + entry->link.tail = entry->link.head = 0; /* single message */ entry->dev = NULL; return entry; @@ -253,6 +256,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev) static void __pci_restore_msix_state(struct pci_dev *dev) { int pos; + int irq, head, tail = 0; struct msi_desc *entry; u16 control; @@ -262,15 +266,18 @@ static void __pci_restore_msix_state(struct pci_dev *dev) /* route the table */ pci_intx(dev, 0); /* disable intx */ msix_set_enable(dev, 0); + irq = head = dev->first_msi_irq; + entry = get_irq_msi(irq); + pos = entry->msi_attrib.pos; + while (head != tail) { + entry = get_irq_msi(irq); + write_msi_msg(irq, &entry->msg); + msi_set_mask_bit(irq, entry->msi_attrib.masked); - list_for_each_entry(entry, &dev->msi_list, list) { - write_msi_msg(entry->irq, &entry->msg); - msi_set_mask_bit(entry->irq, entry->msi_attrib.masked); + tail = entry->link.tail; + irq = tail; } - BUG_ON(list_empty(&dev->msi_list)); - entry = list_entry(dev->msi_list.next, struct msi_desc, list); - pos = entry->msi_attrib.pos; pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); control &= ~PCI_MSIX_FLAGS_MASKALL; control |= PCI_MSIX_FLAGS_ENABLE; @@ -296,7 +303,7 @@ void pci_restore_msi_state(struct pci_dev *dev) static int msi_capability_init(struct pci_dev *dev) { struct msi_desc *entry; - int pos, ret; + int pos, irq; u16 control; msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */ @@ -333,21 +340,23 @@ static int msi_capability_init(struct pci_dev *dev) msi_mask_bits_reg(pos, is_64bit_address(control)), maskbits); } - list_add(&entry->list, &dev->msi_list); - /* Configure MSI capability structure */ - ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI); - if (ret) { - msi_free_irqs(dev); - return ret; + irq = arch_setup_msi_irq(dev, entry); + if (irq < 0) { + kmem_cache_free(msi_cachep, entry); + return irq; } + entry->link.head = irq; + entry->link.tail = irq; + dev->first_msi_irq = irq; + set_irq_msi(irq, entry); /* Set MSI enabled bits */ pci_intx(dev, 0); /* disable intx */ msi_set_enable(dev, 1); dev->msi_enabled = 1; - dev->irq = entry->irq; + dev->irq = irq; return 0; } @@ -364,8 +373,8 @@ static int msi_capability_init(struct pci_dev *dev) static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { - struct msi_desc *entry; - int pos, i, j, nr_entries, ret; + struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; + int irq, pos, i, j, nr_entries, temp = 0; unsigned long phys_addr; u32 table_offset; u16 control; @@ -404,34 +413,44 @@ static int msix_capability_init(struct pci_dev *dev, entry->dev = dev; entry->mask_base = base; - list_add(&entry->list, &dev->msi_list); - } - - ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX); - if (ret) { - int avail = 0; - list_for_each_entry(entry, &dev->msi_list, list) { - if (entry->irq != 0) { - avail++; - } + /* Configure MSI-X capability structure */ + irq = arch_setup_msi_irq(dev, entry); + if (irq < 0) { + kmem_cache_free(msi_cachep, entry); + break; } + entries[i].vector = irq; + if (!head) { + entry->link.head = irq; + entry->link.tail = irq; + head = entry; + } else { + entry->link.head = temp; + entry->link.tail = tail->link.tail; + tail->link.tail = irq; + head->link.head = irq; + } + temp = irq; + tail = entry; - msi_free_irqs(dev); - + set_irq_msi(irq, entry); + } + if (i != nvec) { + int avail = i - 1; + i--; + for (; i >= 0; i--) { + irq = (entries + i)->vector; + msi_free_irq(dev, irq); + (entries + i)->vector = 0; + } /* If we had some success report the number of irqs * we succeeded in setting up. */ - if (avail == 0) - avail = ret; + if (avail <= 0) + avail = -EBUSY; return avail; } - - i = 0; - list_for_each_entry(entry, &dev->msi_list, list) { - entries[i].vector = entry->irq; - set_irq_msi(entry->irq, entry); - i++; - } + dev->first_msi_irq = entries[0].vector; /* Set MSI-X enabled bits */ pci_intx(dev, 0); /* disable intx */ msix_set_enable(dev, 1); @@ -441,32 +460,21 @@ static int msix_capability_init(struct pci_dev *dev, } /** - * pci_msi_check_device - check whether MSI may be enabled on a device + * pci_msi_supported - check whether MSI may be enabled on device * @dev: pointer to the pci_dev data structure of MSI device function - * @nvec: how many MSIs have been requested ? - * @type: are we checking for MSI or MSI-X ? * * Look at global flags, the device itself, and its parent busses - * to determine if MSI/-X are supported for the device. If MSI/-X is - * supported return 0, else return an error code. + * to return 0 if MSI are supported for the device. **/ -static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type) +static +int pci_msi_supported(struct pci_dev * dev) { struct pci_bus *bus; - int ret; /* MSI must be globally enabled and supported by the device */ if (!pci_msi_enable || !dev || dev->no_msi) return -EINVAL; - /* - * You can't ask to have 0 or less MSIs configured. - * a) it's stupid .. - * b) the list manipulation code assumes nvec >= 1. - */ - if (nvec < 1) - return -ERANGE; - /* Any bridge which does NOT route MSI transactions from it's * secondary bus to it's primary bus must set NO_MSI flag on * the secondary pci_bus. @@ -477,13 +485,6 @@ static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type) if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) return -EINVAL; - ret = arch_msi_check_device(dev, nvec, type); - if (ret) - return ret; - - if (!pci_find_capability(dev, type)) - return -EINVAL; - return 0; } @@ -499,12 +500,19 @@ static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type) **/ int pci_enable_msi(struct pci_dev* dev) { - int status; + int pos, status; + + if (pci_msi_supported(dev) < 0) + return -EINVAL; - status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI); - if (status) + status = msi_init(); + if (status < 0) return status; + pos = pci_find_capability(dev, PCI_CAP_ID_MSI); + if (!pos) + return -EINVAL; + WARN_ON(!!dev->msi_enabled); /* Check whether driver already requested for MSI-X irqs */ @@ -517,54 +525,69 @@ int pci_enable_msi(struct pci_dev* dev) status = msi_capability_init(dev); return status; } -EXPORT_SYMBOL(pci_enable_msi); void pci_disable_msi(struct pci_dev* dev) { struct msi_desc *entry; int default_irq; - if (!pci_msi_enable || !dev || !dev->msi_enabled) + if (!pci_msi_enable) + return; + if (!dev) + return; + + if (!dev->msi_enabled) return; msi_set_enable(dev, 0); pci_intx(dev, 1); /* enable intx */ dev->msi_enabled = 0; - BUG_ON(list_empty(&dev->msi_list)); - entry = list_entry(dev->msi_list.next, struct msi_desc, list); - if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { + entry = get_irq_msi(dev->first_msi_irq); + if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { return; } - - default_irq = entry->msi_attrib.default_irq; - msi_free_irqs(dev); - - /* Restore dev->irq to its default pin-assertion irq */ - dev->irq = default_irq; + if (irq_has_action(dev->first_msi_irq)) { + printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " + "free_irq() on MSI irq %d\n", + pci_name(dev), dev->first_msi_irq); + BUG_ON(irq_has_action(dev->first_msi_irq)); + } else { + default_irq = entry->msi_attrib.default_irq; + msi_free_irq(dev, dev->first_msi_irq); + + /* Restore dev->irq to its default pin-assertion irq */ + dev->irq = default_irq; + } + dev->first_msi_irq = 0; } -EXPORT_SYMBOL(pci_disable_msi); -static int msi_free_irqs(struct pci_dev* dev) +static int msi_free_irq(struct pci_dev* dev, int irq) { - struct msi_desc *entry, *tmp; - - list_for_each_entry(entry, &dev->msi_list, list) - BUG_ON(irq_has_action(entry->irq)); - - arch_teardown_msi_irqs(dev); - - list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { - if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) { - if (list_is_last(&entry->list, &dev->msi_list)) - iounmap(entry->mask_base); + struct msi_desc *entry; + int head, entry_nr, type; + void __iomem *base; - writel(1, entry->mask_base + entry->msi_attrib.entry_nr - * PCI_MSIX_ENTRY_SIZE - + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); - } - list_del(&entry->list); - kfree(entry); + entry = get_irq_msi(irq); + if (!entry || entry->dev != dev) { + return -EINVAL; + } + type = entry->msi_attrib.type; + entry_nr = entry->msi_attrib.entry_nr; + head = entry->link.head; + base = entry->mask_base; + get_irq_msi(entry->link.head)->link.tail = entry->link.tail; + get_irq_msi(entry->link.tail)->link.head = entry->link.head; + + arch_teardown_msi_irq(irq); + kmem_cache_free(msi_cachep, entry); + + if (type == PCI_CAP_ID_MSIX) { + writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); + + if (head == irq) + iounmap(base); } return 0; @@ -591,14 +614,17 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) int i, j; u16 control; - if (!entries) + if (!entries || pci_msi_supported(dev) < 0) return -EINVAL; - status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); - if (status) + status = msi_init(); + if (status < 0) return status; pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + if (!pos) + return -EINVAL; + pci_read_config_word(dev, msi_control_reg(pos), &control); nr_entries = multi_msix_capable(control); if (nvec > nr_entries) @@ -625,25 +651,41 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) status = msix_capability_init(dev, entries, nvec); return status; } -EXPORT_SYMBOL(pci_enable_msix); - -static void msix_free_all_irqs(struct pci_dev *dev) -{ - msi_free_irqs(dev); -} void pci_disable_msix(struct pci_dev* dev) { - if (!pci_msi_enable || !dev || !dev->msix_enabled) + int irq, head, tail = 0, warning = 0; + + if (!pci_msi_enable) + return; + if (!dev) + return; + + if (!dev->msix_enabled) return; msix_set_enable(dev, 0); pci_intx(dev, 1); /* enable intx */ dev->msix_enabled = 0; - msix_free_all_irqs(dev); + irq = head = dev->first_msi_irq; + while (head != tail) { + tail = get_irq_msi(irq)->link.tail; + if (irq_has_action(irq)) + warning = 1; + else if (irq != head) /* Release MSI-X irq */ + msi_free_irq(dev, irq); + irq = tail; + } + msi_free_irq(dev, irq); + if (warning) { + printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " + "free_irq() on all MSI-X irqs\n", + pci_name(dev)); + BUG_ON(warning > 0); + } + dev->first_msi_irq = 0; } -EXPORT_SYMBOL(pci_disable_msix); /** * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state @@ -659,11 +701,38 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) if (!pci_msi_enable || !dev) return; - if (dev->msi_enabled) - msi_free_irqs(dev); - - if (dev->msix_enabled) - msix_free_all_irqs(dev); + if (dev->msi_enabled) { + if (irq_has_action(dev->first_msi_irq)) { + printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " + "called without free_irq() on MSI irq %d\n", + pci_name(dev), dev->first_msi_irq); + BUG_ON(irq_has_action(dev->first_msi_irq)); + } else /* Release MSI irq assigned to this device */ + msi_free_irq(dev, dev->first_msi_irq); + } + if (dev->msix_enabled) { + int irq, head, tail = 0, warning = 0; + void __iomem *base = NULL; + + irq = head = dev->first_msi_irq; + while (head != tail) { + tail = get_irq_msi(irq)->link.tail; + base = get_irq_msi(irq)->mask_base; + if (irq_has_action(irq)) + warning = 1; + else if (irq != head) /* Release MSI-X irq */ + msi_free_irq(dev, irq); + irq = tail; + } + msi_free_irq(dev, irq); + if (warning) { + iounmap(base); + printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " + "called without free_irq() on all MSI-X irqs\n", + pci_name(dev)); + BUG_ON(warning > 0); + } + } } void pci_no_msi(void) @@ -671,53 +740,7 @@ void pci_no_msi(void) pci_msi_enable = 0; } -void pci_msi_init_pci_dev(struct pci_dev *dev) -{ - INIT_LIST_HEAD(&dev->msi_list); -} - - -/* Arch hooks */ - -int __attribute__ ((weak)) -arch_msi_check_device(struct pci_dev* dev, int nvec, int type) -{ - return 0; -} - -int __attribute__ ((weak)) -arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry) -{ - return 0; -} - -int __attribute__ ((weak)) -arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) -{ - struct msi_desc *entry; - int ret; - - list_for_each_entry(entry, &dev->msi_list, list) { - ret = arch_setup_msi_irq(dev, entry); - if (ret) - return ret; - } - - return 0; -} - -void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq) -{ - return; -} - -void __attribute__ ((weak)) -arch_teardown_msi_irqs(struct pci_dev *dev) -{ - struct msi_desc *entry; - - list_for_each_entry(entry, &dev->msi_list, list) { - if (entry->irq != 0) - arch_teardown_msi_irq(entry->irq); - } -} +EXPORT_SYMBOL(pci_enable_msi); +EXPORT_SYMBOL(pci_disable_msi); +EXPORT_SYMBOL(pci_enable_msix); +EXPORT_SYMBOL(pci_disable_msix); diff --git a/trunk/drivers/pci/pci-driver.c b/trunk/drivers/pci/pci-driver.c index 3bb7739d26a5..39e80fcef4b3 100644 --- a/trunk/drivers/pci/pci-driver.c +++ b/trunk/drivers/pci/pci-driver.c @@ -13,6 +13,20 @@ #include #include "pci.h" +/* + * Registration of PCI drivers and handling of hot-pluggable devices. + */ + +/* multithreaded probe logic */ +static int pci_multithread_probe = +#ifdef CONFIG_PCI_MULTITHREAD_PROBE + 1; +#else + 0; +#endif +__module_param_call("", pci_multithread_probe, param_set_bool, param_get_bool, &pci_multithread_probe, 0644); + + /* * Dynamic device IDs are disabled for !CONFIG_HOTPLUG */ @@ -38,7 +52,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) { struct pci_dynid *dynid; struct pci_driver *pdrv = to_pci_driver(driver); - __u32 vendor, device, subvendor=PCI_ANY_ID, + __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID, subdevice=PCI_ANY_ID, class=0, class_mask=0; unsigned long driver_data=0; int fields=0; @@ -47,7 +61,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) fields = sscanf(buf, "%x %x %x %x %x %x %lux", &vendor, &device, &subvendor, &subdevice, &class, &class_mask, &driver_data); - if (fields < 2) + if (fields < 0) return -EINVAL; dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); @@ -555,6 +569,7 @@ struct bus_type pci_bus_type = { static int __init pci_driver_init(void) { + pci_bus_type.multithread_probe = pci_multithread_probe; return bus_register(&pci_bus_type); } diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index 284e83a527f9..cd913a2a416f 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -620,8 +620,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) goto err_bin_file; /* If the device has a ROM, try to expose it in sysfs. */ - if (pci_resource_len(pdev, PCI_ROM_RESOURCE) || - (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) { + if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) { rom_attr = kzalloc(sizeof(*rom_attr), GFP_ATOMIC); if (rom_attr) { pdev->rom_attr = rom_attr; @@ -636,7 +635,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) goto err_rom; } else { retval = -ENOMEM; - goto err_resource_files; + goto err_bin_file; } } /* add platform-specific attributes */ @@ -646,8 +645,6 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) err_rom: kfree(rom_attr); -err_resource_files: - pci_remove_resource_files(pdev); err_bin_file: if (pdev->cfg_size < 4096) sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); @@ -698,4 +695,4 @@ static int __init pci_sysfs_init(void) return 0; } -late_initcall(pci_sysfs_init); +__initcall(pci_sysfs_init); diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index fd47ac0c4730..2a458279327a 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -35,7 +35,8 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; * Given a PCI bus, returns the highest PCI bus number present in the set * including the given PCI bus and its list of child PCI buses. */ -unsigned char pci_bus_max_busnr(struct pci_bus* bus) +unsigned char __devinit +pci_bus_max_busnr(struct pci_bus* bus) { struct list_head *tmp; unsigned char max, n; @@ -890,34 +891,6 @@ pci_disable_device(struct pci_dev *dev) pcibios_disable_device(dev); } -/** - * pcibios_set_pcie_reset_state - set reset state for device dev - * @dev: the PCI-E device reset - * @state: Reset state to enter into - * - * - * Sets the PCI-E reset state for the device. This is the default - * implementation. Architecture implementations can override this. - */ -int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, - enum pcie_reset_state state) -{ - return -EINVAL; -} - -/** - * pci_set_pcie_reset_state - set reset state for device dev - * @dev: the PCI-E device reset - * @state: Reset state to enter into - * - * - * Sets the PCI reset state for the device. - */ -int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) -{ - return pcibios_set_pcie_reset_state(dev, state); -} - /** * pci_enable_wake - enable PCI device as wakeup event source * @dev: PCI device affected @@ -1322,7 +1295,7 @@ pci_intx(struct pci_dev *pdev, int enable) /** * pci_msi_off - disables any msi or msix capabilities - * @dev: the PCI device to operate on + * @pdev: the PCI device to operate on * * If you want to use msi see pci_enable_msi and friends. * This is a lower level primitive that allows us to disable @@ -1454,5 +1427,4 @@ EXPORT_SYMBOL(pci_set_power_state); EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_enable_wake); -EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 3fec13d3add7..62ea04c8af64 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -47,10 +47,8 @@ extern unsigned int pci_pm_d3_delay; #ifdef CONFIG_PCI_MSI void pci_no_msi(void); -extern void pci_msi_init_pci_dev(struct pci_dev *dev); #else static inline void pci_no_msi(void) { } -static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #endif #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index e48fcf089621..2fe1d690eb13 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -364,7 +364,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) } } -static struct pci_bus * pci_alloc_bus(void) +static struct pci_bus * __devinit pci_alloc_bus(void) { struct pci_bus *b; @@ -432,7 +432,7 @@ pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) return NULL; } -struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) +struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) { struct pci_bus *child; @@ -461,7 +461,7 @@ static void pci_enable_crs(struct pci_dev *dev) pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl); } -static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) +static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) { struct pci_bus *parent = child->parent; @@ -477,7 +477,7 @@ static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) } } -unsigned int pci_scan_child_bus(struct pci_bus *bus); +unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); /* * If it's a bridge, configure it and scan the bus behind it. @@ -489,7 +489,7 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus); * them, we proceed to assigning numbers to the remaining buses in * order to avoid overlaps between old and new bus numbers. */ -int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass) +int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass) { struct pci_bus *child; int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); @@ -846,23 +846,6 @@ static void pci_release_bus_bridge_dev(struct device *dev) kfree(dev); } -struct pci_dev *alloc_pci_dev(void) -{ - struct pci_dev *dev; - - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); - if (!dev) - return NULL; - - INIT_LIST_HEAD(&dev->global_list); - INIT_LIST_HEAD(&dev->bus_list); - - pci_msi_init_pci_dev(dev); - - return dev; -} -EXPORT_SYMBOL(alloc_pci_dev); - /* * Read the config data for a PCI device, sanity-check it * and fill in the dev structure... @@ -902,7 +885,7 @@ pci_scan_device(struct pci_bus *bus, int devfn) if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) return NULL; - dev = alloc_pci_dev(); + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) return NULL; @@ -929,7 +912,7 @@ pci_scan_device(struct pci_bus *bus, int devfn) return dev; } -void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) +void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus) { device_initialize(&dev->dev); dev->dev.release = pci_release_dev; @@ -952,7 +935,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) up_write(&pci_bus_sem); } -struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn) +struct pci_dev * __devinit +pci_scan_single_device(struct pci_bus *bus, int devfn) { struct pci_dev *dev; @@ -974,7 +958,7 @@ struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn) * discovered devices to the @bus->devices list. New devices * will have an empty dev->global_list head. */ -int pci_scan_slot(struct pci_bus *bus, int devfn) +int __devinit pci_scan_slot(struct pci_bus *bus, int devfn) { int func, nr = 0; int scan_all_fns; @@ -1007,7 +991,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) return nr; } -unsigned int pci_scan_child_bus(struct pci_bus *bus) +unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) { unsigned int devfn, pass, max = bus->secondary; struct pci_dev *dev; @@ -1057,7 +1041,7 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) return max; } -struct pci_bus * pci_create_bus(struct device *parent, +struct pci_bus * __devinit pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { int error; @@ -1135,7 +1119,7 @@ struct pci_bus * pci_create_bus(struct device *parent, } EXPORT_SYMBOL_GPL(pci_create_bus); -struct pci_bus *pci_scan_bus_parented(struct device *parent, +struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { struct pci_bus *b; diff --git a/trunk/drivers/pci/proc.c b/trunk/drivers/pci/proc.c index 0425a7b7350d..ed87aa59f0b1 100644 --- a/trunk/drivers/pci/proc.c +++ b/trunk/drivers/pci/proc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 147d86f8edbf..3411483240cd 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -1648,8 +1648,6 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_msi); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_msi); /* Go through the list of Hypertransport capabilities and * return 1 if a HT MSI capability is found and enabled */ diff --git a/trunk/drivers/pci/search.c b/trunk/drivers/pci/search.c index b137a27472c7..2dd8681d6b31 100644 --- a/trunk/drivers/pci/search.c +++ b/trunk/drivers/pci/search.c @@ -15,7 +15,8 @@ DECLARE_RWSEM(pci_bus_sem); -static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) +static struct pci_bus * +pci_do_find_bus(struct pci_bus* bus, unsigned char busnr) { struct pci_bus* child; struct list_head *tmp; diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index 5ec297d7a5b4..3554f3948814 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -36,7 +36,8 @@ #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) -static void pbus_assign_resources_sorted(struct pci_bus *bus) +static void __devinit +pbus_assign_resources_sorted(struct pci_bus *bus) { struct pci_dev *dev; struct resource *res; @@ -219,7 +220,8 @@ pci_setup_bridge(struct pci_bus *bus) /* Check whether the bridge supports optional I/O and prefetchable memory ranges. If not, the respective base/limit registers must be read-only and read as 0. */ -static void pci_bridge_check_ranges(struct pci_bus *bus) +static void __devinit +pci_bridge_check_ranges(struct pci_bus *bus) { u16 io; u32 pmem; @@ -257,7 +259,8 @@ static void pci_bridge_check_ranges(struct pci_bus *bus) bus resource of a given type. Note: we intentionally skip the bus resources which have already been assigned (that is, have non-NULL parent resource). */ -static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type) +static struct resource * __devinit +find_free_bus_resource(struct pci_bus *bus, unsigned long type) { int i; struct resource *r; @@ -278,7 +281,8 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon since these windows have 4K granularity and the IO ranges of non-bridge PCI devices are limited to 256 bytes. We must be careful with the ISA aliasing though. */ -static void pbus_size_io(struct pci_bus *bus) +static void __devinit +pbus_size_io(struct pci_bus *bus) { struct pci_dev *dev; struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); @@ -322,7 +326,8 @@ static void pbus_size_io(struct pci_bus *bus) /* Calculate the size of the bus and minimal alignment which guarantees that all child resources fit in this size. */ -static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) +static int __devinit +pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) { struct pci_dev *dev; unsigned long min_align, align, size; @@ -442,7 +447,8 @@ pci_bus_size_cardbus(struct pci_bus *bus) } } -void pci_bus_size_bridges(struct pci_bus *bus) +void __devinit +pci_bus_size_bridges(struct pci_bus *bus) { struct pci_dev *dev; unsigned long mask, prefmask; @@ -492,7 +498,8 @@ void pci_bus_size_bridges(struct pci_bus *bus) } EXPORT_SYMBOL(pci_bus_size_bridges); -void pci_bus_assign_resources(struct pci_bus *bus) +void __devinit +pci_bus_assign_resources(struct pci_bus *bus) { struct pci_bus *b; struct pci_dev *dev; diff --git a/trunk/drivers/pci/setup-res.c b/trunk/drivers/pci/setup-res.c index 6dfd86167e39..cb4ced3560e9 100644 --- a/trunk/drivers/pci/setup-res.c +++ b/trunk/drivers/pci/setup-res.c @@ -101,7 +101,8 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) new & ~PCI_REGION_FLAG_MASK); } -int pci_claim_resource(struct pci_dev *dev, int resource) +int __devinit +pci_claim_resource(struct pci_dev *dev, int resource) { struct resource *res = &dev->resource[resource]; struct resource *root = NULL; @@ -211,7 +212,8 @@ EXPORT_SYMBOL_GPL(pci_assign_resource_fixed); #endif /* Sort resources by alignment */ -void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) +void __devinit +pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) { int i; diff --git a/trunk/drivers/pcmcia/at91_cf.c b/trunk/drivers/pcmcia/at91_cf.c index 948efc775a78..99baabc23599 100644 --- a/trunk/drivers/pcmcia/at91_cf.c +++ b/trunk/drivers/pcmcia/at91_cf.c @@ -360,6 +360,7 @@ static struct platform_driver at91_cf_driver = { .name = (char *) driver_name, .owner = THIS_MODULE, }, + .probe = at91_cf_probe, .remove = __exit_p(at91_cf_remove), .suspend = at91_cf_suspend, .resume = at91_cf_resume, @@ -369,7 +370,7 @@ static struct platform_driver at91_cf_driver = { static int __init at91_cf_init(void) { - return platform_driver_probe(&at91_cf_driver, at91_cf_probe); + return platform_driver_register(&at91_cf_driver); } module_init(at91_cf_init); diff --git a/trunk/drivers/pcmcia/cs.c b/trunk/drivers/pcmcia/cs.c index 50cad3a59a6c..ac004248324a 100644 --- a/trunk/drivers/pcmcia/cs.c +++ b/trunk/drivers/pcmcia/cs.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/pcmcia/ds.c b/trunk/drivers/pcmcia/ds.c index 143c6efc478a..18e111e12339 100644 --- a/trunk/drivers/pcmcia/ds.c +++ b/trunk/drivers/pcmcia/ds.c @@ -234,89 +234,6 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) /*======================================================================*/ -struct pcmcia_dynid { - struct list_head node; - struct pcmcia_device_id id; -}; - -/** - * pcmcia_store_new_id - add a new PCMCIA device ID to this driver and re-probe devices - * @driver: target device driver - * @buf: buffer for scanning device ID data - * @count: input size - * - * Adds a new dynamic PCMCIA device ID to this driver, - * and causes the driver to probe for all devices again. - */ -static ssize_t -pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count) -{ - struct pcmcia_dynid *dynid; - struct pcmcia_driver *pdrv = to_pcmcia_drv(driver); - __u16 match_flags, manf_id, card_id; - __u8 func_id, function, device_no; - __u32 prod_id_hash[4] = {0, 0, 0, 0}; - int fields=0; - int retval = 0; - - fields = sscanf(buf, "%hx %hx %hx %hhx %hhx %hhx %x %x %x %x", - &match_flags, &manf_id, &card_id, &func_id, &function, &device_no, - &prod_id_hash[0], &prod_id_hash[1], &prod_id_hash[2], &prod_id_hash[3]); - if (fields < 6) - return -EINVAL; - - dynid = kzalloc(sizeof(struct pcmcia_dynid), GFP_KERNEL); - if (!dynid) - return -ENOMEM; - - INIT_LIST_HEAD(&dynid->node); - dynid->id.match_flags = match_flags; - dynid->id.manf_id = manf_id; - dynid->id.card_id = card_id; - dynid->id.func_id = func_id; - dynid->id.function = function; - dynid->id.device_no = device_no; - memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4); - - spin_lock(&pdrv->dynids.lock); - list_add_tail(&pdrv->dynids.list, &dynid->node); - spin_unlock(&pdrv->dynids.lock); - - if (get_driver(&pdrv->drv)) { - retval = driver_attach(&pdrv->drv); - put_driver(&pdrv->drv); - } - - if (retval) - return retval; - return count; -} -static DRIVER_ATTR(new_id, S_IWUSR, NULL, pcmcia_store_new_id); - -static void -pcmcia_free_dynids(struct pcmcia_driver *drv) -{ - struct pcmcia_dynid *dynid, *n; - - spin_lock(&drv->dynids.lock); - list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { - list_del(&dynid->node); - kfree(dynid); - } - spin_unlock(&drv->dynids.lock); -} - -static int -pcmcia_create_newid_file(struct pcmcia_driver *drv) -{ - int error = 0; - if (drv->probe != NULL) - error = sysfs_create_file(&drv->drv.kobj, - &driver_attr_new_id.attr); - return error; -} - - /** * pcmcia_register_driver - register a PCMCIA driver with the bus core * @@ -324,8 +241,6 @@ pcmcia_create_newid_file(struct pcmcia_driver *drv) */ int pcmcia_register_driver(struct pcmcia_driver *driver) { - int error; - if (!driver) return -EINVAL; @@ -334,20 +249,10 @@ int pcmcia_register_driver(struct pcmcia_driver *driver) /* initialize common fields */ driver->drv.bus = &pcmcia_bus_type; driver->drv.owner = driver->owner; - spin_lock_init(&driver->dynids.lock); - INIT_LIST_HEAD(&driver->dynids.list); ds_dbg(3, "registering driver %s\n", driver->drv.name); - error = driver_register(&driver->drv); - if (error < 0) - return error; - - error = pcmcia_create_newid_file(driver); - if (error) - driver_unregister(&driver->drv); - - return error; + return driver_register(&driver->drv); } EXPORT_SYMBOL(pcmcia_register_driver); @@ -358,7 +263,6 @@ void pcmcia_unregister_driver(struct pcmcia_driver *driver) { ds_dbg(3, "unregistering driver %s\n", driver->drv.name); driver_unregister(&driver->drv); - pcmcia_free_dynids(driver); } EXPORT_SYMBOL(pcmcia_unregister_driver); @@ -1023,21 +927,6 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { struct pcmcia_device * p_dev = to_pcmcia_dev(dev); struct pcmcia_driver * p_drv = to_pcmcia_drv(drv); struct pcmcia_device_id *did = p_drv->id_table; - struct pcmcia_dynid *dynid; - - /* match dynamic devices first */ - spin_lock(&p_drv->dynids.lock); - list_for_each_entry(dynid, &p_drv->dynids.list, node) { - ds_dbg(3, "trying to match %s to %s\n", dev->bus_id, - drv->name); - if (pcmcia_devmatch(p_dev, &dynid->id)) { - ds_dbg(0, "matched %s to %s\n", dev->bus_id, - drv->name); - spin_unlock(&p_drv->dynids.lock); - return 1; - } - } - spin_unlock(&p_drv->dynids.lock); #ifdef CONFIG_PCMCIA_IOCTL /* matching by cardmgr */ diff --git a/trunk/drivers/pcmcia/pxa2xx_mainstone.c b/trunk/drivers/pcmcia/pxa2xx_mainstone.c index 383107ba4bd3..fda06941e730 100644 --- a/trunk/drivers/pcmcia/pxa2xx_mainstone.c +++ b/trunk/drivers/pcmcia/pxa2xx_mainstone.c @@ -175,7 +175,6 @@ static int __init mst_pcmcia_init(void) if (!mst_pcmcia_device) return -ENOMEM; - mst_pcmcia_device->dev.uevent_suppress = 0; mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; ret = platform_device_add(mst_pcmcia_device); diff --git a/trunk/drivers/pcmcia/pxa2xx_sharpsl.c b/trunk/drivers/pcmcia/pxa2xx_sharpsl.c index a2daa3f531b2..b7b9e149c5b9 100644 --- a/trunk/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/trunk/drivers/pcmcia/pxa2xx_sharpsl.c @@ -261,7 +261,6 @@ static int __init sharpsl_pcmcia_init(void) if (!sharpsl_pcmcia_device) return -ENOMEM; - sharpsl_pcmcia_device->dev.uevent_suppress = 0; sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; diff --git a/trunk/drivers/pcmcia/socket_sysfs.c b/trunk/drivers/pcmcia/socket_sysfs.c index a2bb46526b56..ea5765c3bdc0 100644 --- a/trunk/drivers/pcmcia/socket_sysfs.c +++ b/trunk/drivers/pcmcia/socket_sysfs.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/pnp/core.c b/trunk/drivers/pnp/core.c index 3e20b1cc7778..aec83ec5ea23 100644 --- a/trunk/drivers/pnp/core.c +++ b/trunk/drivers/pnp/core.c @@ -14,7 +14,6 @@ #include #include #include -#include #include "base.h" @@ -23,14 +22,6 @@ static LIST_HEAD(pnp_protocols); LIST_HEAD(pnp_global); DEFINE_SPINLOCK(pnp_lock); -/* - * ACPI or PNPBIOS should tell us about all platform devices, so we can - * skip some blind probes. ISAPNP typically enumerates only plug-in ISA - * devices, not built-in things like COM ports. - */ -int pnp_platform_devices; -EXPORT_SYMBOL(pnp_platform_devices); - void *pnp_alloc(long size) { void *result; @@ -123,8 +114,6 @@ int __pnp_add_device(struct pnp_dev *dev) int ret; pnp_fixup_device(dev); dev->dev.bus = &pnp_bus_type; - dev->dev.dma_mask = &dev->dma_mask; - dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK; dev->dev.release = &pnp_release_device; dev->status = PNP_READY; spin_lock(&pnp_lock); diff --git a/trunk/drivers/pnp/pnpacpi/core.c b/trunk/drivers/pnp/pnpacpi/core.c index a00548799e98..62eda5d59024 100644 --- a/trunk/drivers/pnp/pnpacpi/core.c +++ b/trunk/drivers/pnp/pnpacpi/core.c @@ -3,7 +3,7 @@ * * Copyright (c) 2004 Matthieu Castet * Copyright (c) 2004 Li Shaohua - * + * * 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, or (at your option) any @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + #include #include #include @@ -82,7 +82,7 @@ static void __init pnpidacpi_to_pnpid(char *id, char *str) static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res) { acpi_status status; - status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data, + status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data, &dev->res); return ACPI_FAILURE(status) ? -ENODEV : 0; } @@ -112,9 +112,9 @@ static int pnpacpi_set_resources(struct pnp_dev * dev, struct pnp_resource_table static int pnpacpi_disable_resources(struct pnp_dev *dev) { acpi_status status; - + /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ - status = acpi_evaluate_object((acpi_handle)dev->data, + status = acpi_evaluate_object((acpi_handle)dev->data, "_DIS", NULL, NULL); return ACPI_FAILURE(status) ? -ENODEV : 0; } @@ -167,7 +167,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device) strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); dev->number = num; - + /* set the initial values for the PnP device */ dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); if (!dev_id) @@ -185,14 +185,14 @@ static int __init pnpacpi_add_device(struct acpi_device *device) } if(dev->capabilities & PNP_CONFIGURABLE) { - status = pnpacpi_parse_resource_option_data(device->handle, + status = pnpacpi_parse_resource_option_data(device->handle, dev); if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id); goto err1; } } - + /* parse compatible ids */ if (device->flags.compatible_ids) { struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; @@ -236,42 +236,6 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle, return AE_OK; } -static int __init acpi_pnp_match(struct device *dev, void *_pnp) -{ - struct acpi_device *acpi = to_acpi_device(dev); - struct pnp_dev *pnp = _pnp; - - /* true means it matched */ - return acpi->flags.hardware_id - && !acpi_get_physical_device(acpi->handle) - && compare_pnp_id(pnp->id, acpi->pnp.hardware_id); -} - -static int __init acpi_pnp_find_device(struct device *dev, acpi_handle *handle) -{ - struct device *adev; - struct acpi_device *acpi; - - adev = bus_find_device(&acpi_bus_type, NULL, - to_pnp_dev(dev), - acpi_pnp_match); - if (!adev) - return -ENODEV; - - acpi = to_acpi_device(adev); - *handle = acpi->handle; - put_device(adev); - return 0; -} - -/* complete initialization of a PNPACPI device includes having - * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling. - */ -static struct acpi_bus_type __initdata acpi_pnp_bus = { - .bus = &pnp_bus_type, - .find_device = acpi_pnp_find_device, -}; - int pnpacpi_disabled __initdata; static int __init pnpacpi_init(void) { @@ -281,11 +245,8 @@ static int __init pnpacpi_init(void) } pnp_info("PnP ACPI init"); pnp_register_protocol(&pnpacpi_protocol); - register_acpi_bus_type(&acpi_pnp_bus); acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); pnp_info("PnP ACPI: found %d devices", num); - unregister_acpi_bus_type(&acpi_pnp_bus); - pnp_platform_devices = 1; return 0; } subsys_initcall(pnpacpi_init); diff --git a/trunk/drivers/pnp/pnpbios/core.c b/trunk/drivers/pnp/pnpbios/core.c index 3a201b77b963..95738dbd5d45 100644 --- a/trunk/drivers/pnp/pnpbios/core.c +++ b/trunk/drivers/pnp/pnpbios/core.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #include @@ -160,7 +159,9 @@ static int pnp_dock_thread(void * unused) { static struct pnp_docking_station_info now; int docked = -1, d = 0; - while (!unloading) + daemonize("kpnpbiosd"); + allow_signal(SIGKILL); + while(!unloading && !signal_pending(current)) { int status; @@ -169,8 +170,11 @@ static int pnp_dock_thread(void * unused) */ msleep_interruptible(2000); - if (try_to_freeze()) - continue; + if(signal_pending(current)) { + if (try_to_freeze()) + continue; + break; + } status = pnp_bios_dock_station_info(&now); @@ -570,7 +574,6 @@ static int __init pnpbios_init(void) /* scan for pnpbios devices */ build_devlist(); - pnp_platform_devices = 1; return 0; } @@ -578,7 +581,6 @@ subsys_initcall(pnpbios_init); static int __init pnpbios_thread_init(void) { - struct task_struct *task; #if defined(CONFIG_PPC_MERGE) if (check_legacy_ioport(PNPBIOS_BASE)) return 0; @@ -587,8 +589,7 @@ static int __init pnpbios_thread_init(void) return 0; #ifdef CONFIG_HOTPLUG init_completion(&unload_sem); - task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd"); - if (!IS_ERR(task)) + if (kernel_thread(pnp_dock_thread, NULL, CLONE_KERNEL) > 0) unloading = 0; #endif return 0; diff --git a/trunk/drivers/pnp/quirks.c b/trunk/drivers/pnp/quirks.c index 277df50c89ae..e97ecefe8584 100644 --- a/trunk/drivers/pnp/quirks.c +++ b/trunk/drivers/pnp/quirks.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "base.h" @@ -107,34 +106,6 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev) return; } -static void quirk_smc_enable(struct pnp_dev *dev) -{ - unsigned int firbase; - - if (!dev->active || !pnp_port_valid(dev, 1)) - return; - - /* - * On the HP/Compaq nw8240 (and probably other similar machines), - * there is an SMCF010 device with two I/O port regions: - * - * 0x3e8-0x3ef SIR - * 0x100-0x10f FIR - * - * _STA reports the device is enabled, but in fact, the BIOS - * neglects to enable the FIR range. Fortunately, it does fully - * enable the device if we call _SRS. - */ - firbase = pnp_port_start(dev, 1); - if (inb(firbase + 0x7 /* IRCC_MASTER */) == 0xff) { - pnp_err("%s (%s) enabled but not responding, disabling and " - "re-enabling", dev->dev.bus_id, pnp_dev_name(dev)); - pnp_disable_dev(dev); - pnp_activate_dev(dev); - } -} - - /* * PnP Quirks * Cards or devices that need some tweaking due to incomplete resource info @@ -155,7 +126,6 @@ static struct pnp_fixup pnp_fixups[] = { { "CTL0043", quirk_sb16audio_resources }, { "CTL0044", quirk_sb16audio_resources }, { "CTL0045", quirk_sb16audio_resources }, - { "SMCf010", quirk_smc_enable }, { "" } }; diff --git a/trunk/drivers/ps3/ps3av.c b/trunk/drivers/ps3/ps3av.c index 1393e64335f9..d21e04ccb021 100644 --- a/trunk/drivers/ps3/ps3av.c +++ b/trunk/drivers/ps3/ps3av.c @@ -38,24 +38,7 @@ static int timeout = 5000; /* in msec ( 5 sec ) */ module_param(timeout, int, 0644); -static struct ps3av { - int available; - struct mutex mutex; - struct work_struct work; - struct completion done; - struct workqueue_struct *wq; - int open_count; - struct ps3_vuart_port_device *dev; - - int region; - struct ps3av_pkt_av_get_hw_conf av_hw_conf; - u32 av_port[PS3AV_AV_PORT_MAX + PS3AV_OPT_PORT_MAX]; - u32 opt_port[PS3AV_OPT_PORT_MAX]; - u32 head[PS3AV_HEAD_MAX]; - u32 audio_port; - int ps3av_mode; - int ps3av_mode_old; -} ps3av; +static struct ps3av ps3av; static struct ps3_vuart_port_device ps3av_dev = { .match_id = PS3_MATCH_ID_AV_SETTINGS @@ -176,7 +159,7 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr) else printk(KERN_ERR "%s: failed event packet, cid:%08x size:%d\n", - __func__, hdr->cid, hdr->size); + __FUNCTION__, hdr->cid, hdr->size); return 1; /* receive event packet */ } return 0; @@ -198,7 +181,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, if (res < 0) { dev_dbg(&ps3av_dev.core, "%s: ps3av_vuart_write() failed (result=%d)\n", - __func__, res); + __FUNCTION__, res); return res; } @@ -211,7 +194,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, if (res != PS3AV_HDR_SIZE) { dev_dbg(&ps3av_dev.core, "%s: ps3av_vuart_read() failed (result=%d)\n", - __func__, res); + __FUNCTION__, res); return res; } @@ -221,7 +204,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, if (res < 0) { dev_dbg(&ps3av_dev.core, "%s: ps3av_vuart_read() failed (result=%d)\n", - __func__, res); + __FUNCTION__, res); return res; } res += PS3AV_HDR_SIZE; /* total len */ @@ -231,7 +214,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) { dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n", - __func__, recv_buf->cid); + __FUNCTION__, recv_buf->cid); return -EINVAL; } @@ -267,7 +250,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, struct ps3av_send_hdr *buf) { int res = 0; - static union { + union { struct ps3av_reply_hdr reply_hdr; u8 raw[PS3AV_BUF_SIZE]; } recv_buf; @@ -276,7 +259,8 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, BUG_ON(!ps3av.available); - mutex_lock(&ps3av.mutex); + if (down_interruptible(&ps3av.sem)) + return -ERESTARTSYS; table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK); BUG_ON(!table); @@ -293,7 +277,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, if (res < 0) { printk(KERN_ERR "%s: ps3av_send_cmd_pkt() failed (result=%d)\n", - __func__, res); + __FUNCTION__, res); goto err; } @@ -302,16 +286,16 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, usr_buf_size); if (res < 0) { printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n", - __func__, res); + __FUNCTION__, res); goto err; } - mutex_unlock(&ps3av.mutex); + up(&ps3av.sem); return 0; err: - mutex_unlock(&ps3av.mutex); - printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res); + up(&ps3av.sem); + printk(KERN_ERR "%s: failed cid:%x res:%d\n", __FUNCTION__, cid, res); return res; } @@ -456,7 +440,7 @@ static int ps3av_set_videomode(void) ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); /* wake up ps3avd to do the actual video mode setting */ - queue_work(ps3av.wq, &ps3av.work); + up(&ps3av.ping); return 0; } @@ -522,7 +506,7 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id) if (res == PS3AV_STATUS_NO_SYNC_HEAD) printk(KERN_WARNING "%s: Command failed. Please try your request again. \n", - __func__); + __FUNCTION__); else if (res) dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n"); @@ -531,10 +515,18 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id) ps3av_set_av_video_mute(PS3AV_CMD_MUTE_OFF); } -static void ps3avd(struct work_struct *work) +static int ps3avd(void *p) { - ps3av_set_videomode_cont(ps3av.ps3av_mode, ps3av.ps3av_mode_old); - complete(&ps3av.done); + struct ps3av *info = p; + + daemonize("ps3avd"); + while (1) { + down(&info->ping); + ps3av_set_videomode_cont(info->ps3av_mode, + info->ps3av_mode_old); + up(&info->pong); + } + return 0; } static int ps3av_vid2table_id(int vid) @@ -715,7 +707,8 @@ int ps3av_set_video_mode(u32 id, int boot) size = ARRAY_SIZE(video_mode_table); if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) { - dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __func__, id); + dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __FUNCTION__, + id); return -EINVAL; } @@ -724,14 +717,15 @@ int ps3av_set_video_mode(u32 id, int boot) if ((id & PS3AV_MODE_MASK) == 0) { id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot); if (id < 1) { - printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); + printk(KERN_ERR "%s: invalid id :%d\n", __FUNCTION__, + id); return -EINVAL; } id |= option; } /* set videomode */ - wait_for_completion(&ps3av.done); + down(&ps3av.pong); ps3av.ps3av_mode_old = ps3av.ps3av_mode; ps3av.ps3av_mode = id; if (ps3av_set_videomode()) @@ -742,13 +736,6 @@ int ps3av_set_video_mode(u32 id, int boot) EXPORT_SYMBOL_GPL(ps3av_set_video_mode); -int ps3av_get_auto_mode(int boot) -{ - return ps3av_auto_videomode(&ps3av.av_hw_conf, boot); -} - -EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); - int ps3av_set_mode(u32 id, int boot) { int res; @@ -784,7 +771,7 @@ int ps3av_get_scanmode(int id) id = id & PS3AV_MODE_MASK; size = ARRAY_SIZE(video_mode_table); if (id > size - 1 || id < 0) { - printk(KERN_ERR "%s: invalid mode %d\n", __func__, id); + printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id); return -EINVAL; } return video_mode_table[id].interlace; @@ -799,7 +786,7 @@ int ps3av_get_refresh_rate(int id) id = id & PS3AV_MODE_MASK; size = ARRAY_SIZE(video_mode_table); if (id > size - 1 || id < 0) { - printk(KERN_ERR "%s: invalid mode %d\n", __func__, id); + printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id); return -EINVAL; } return video_mode_table[id].freq; @@ -815,7 +802,7 @@ int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres) id = id & PS3AV_MODE_MASK; size = ARRAY_SIZE(video_mode_table); if (id > size - 1 || id < 0) { - printk(KERN_ERR "%s: invalid mode %d\n", __func__, id); + printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id); return -EINVAL; } *xres = video_mode_table[id].x; @@ -851,7 +838,7 @@ int ps3av_dev_open(void) status = lv1_gpu_open(0); if (status) { printk(KERN_ERR "%s: lv1_gpu_open failed %d\n", - __func__, status); + __FUNCTION__, status); ps3av.open_count--; } } @@ -868,13 +855,13 @@ int ps3av_dev_close(void) mutex_lock(&ps3av.mutex); if (ps3av.open_count <= 0) { - printk(KERN_ERR "%s: GPU already closed\n", __func__); + printk(KERN_ERR "%s: GPU already closed\n", __FUNCTION__); status = -1; } else if (!--ps3av.open_count) { status = lv1_gpu_close(); if (status) printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n", - __func__, status); + __FUNCTION__, status); } mutex_unlock(&ps3av.mutex); @@ -893,16 +880,13 @@ static int ps3av_probe(struct ps3_vuart_port_device *dev) memset(&ps3av, 0, sizeof(ps3av)); + init_MUTEX(&ps3av.sem); + init_MUTEX_LOCKED(&ps3av.ping); + init_MUTEX(&ps3av.pong); mutex_init(&ps3av.mutex); ps3av.ps3av_mode = 0; ps3av.dev = dev; - - INIT_WORK(&ps3av.work, ps3avd); - init_completion(&ps3av.done); - complete(&ps3av.done); - ps3av.wq = create_singlethread_workqueue("ps3avd"); - if (!ps3av.wq) - return -ENOMEM; + kernel_thread(ps3avd, &ps3av, CLONE_KERNEL); ps3av.available = 1; switch (ps3_os_area_get_av_multi_out()) { @@ -924,7 +908,7 @@ static int ps3av_probe(struct ps3_vuart_port_device *dev) /* init avsetting modules */ res = ps3av_cmd_init(); if (res < 0) - printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__, + printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __FUNCTION__, res); ps3av_get_hw_conf(&ps3av); @@ -942,8 +926,6 @@ static int ps3av_remove(struct ps3_vuart_port_device *dev) { if (ps3av.available) { ps3av_cmd_fin(); - if (ps3av.wq) - destroy_workqueue(ps3av.wq); ps3av.available = 0; } @@ -976,7 +958,7 @@ static int ps3av_module_init(void) if (error) { printk(KERN_ERR "%s: ps3_vuart_port_driver_register failed %d\n", - __func__, error); + __FUNCTION__, error); return error; } @@ -984,7 +966,7 @@ static int ps3av_module_init(void) if (error) printk(KERN_ERR "%s: ps3_vuart_port_device_register failed %d\n", - __func__, error); + __FUNCTION__, error); return error; } diff --git a/trunk/drivers/ps3/ps3av_cmd.c b/trunk/drivers/ps3/ps3av_cmd.c index 0145ea173c42..bc70e81f8cb0 100644 --- a/trunk/drivers/ps3/ps3av_cmd.c +++ b/trunk/drivers/ps3/ps3av_cmd.c @@ -395,7 +395,7 @@ u32 ps3av_cmd_set_video_mode(void *p, u32 head, int video_vid, int video_fmt, video_mode->video_order = ps3av_video_fmt_table[video_fmt].order; pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n", - __func__, video_vid, video_mode->width, video_mode->height, + __FUNCTION__, video_vid, video_mode->width, video_mode->height, video_mode->pitch, video_mode->video_out_format, video_mode->video_format, video_mode->video_order); return sizeof(*video_mode); @@ -477,7 +477,7 @@ static u8 ps3av_cnv_mclk(u32 fs) if (ps3av_cnv_mclk_table[i].fs == fs) return ps3av_cnv_mclk_table[i].mclk; - printk(KERN_ERR "%s failed, fs:%x\n", __func__, fs); + printk(KERN_ERR "%s failed, fs:%x\n", __FUNCTION__, fs); return 0; } @@ -526,12 +526,13 @@ static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid) d = 4; break; default: - printk(KERN_ERR "%s failed, vid:%x\n", __func__, video_vid); + printk(KERN_ERR "%s failed, vid:%x\n", __FUNCTION__, + video_vid); break; } if (fs < PS3AV_CMD_AUDIO_FS_44K || fs > PS3AV_CMD_AUDIO_FS_192K) - printk(KERN_ERR "%s failed, fs:%x\n", __func__, fs); + printk(KERN_ERR "%s failed, fs:%x\n", __FUNCTION__, fs); else ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d]; @@ -554,7 +555,8 @@ static u8 ps3av_cnv_enable(u32 source, const u8 *enable) ret = ((p[0] << 4) + (p[1] << 5) + (p[2] << 6) + (p[3] << 7)) | 0x01; } else - printk(KERN_ERR "%s failed, source:%x\n", __func__, source); + printk(KERN_ERR "%s failed, source:%x\n", __FUNCTION__, + source); return ret; } @@ -583,7 +585,7 @@ static u8 ps3av_cnv_inputlen(u32 word_bits) ret = PS3AV_CMD_AV_INPUTLEN_24; break; default: - printk(KERN_ERR "%s failed, word_bits:%x\n", __func__, + printk(KERN_ERR "%s failed, word_bits:%x\n", __FUNCTION__, word_bits); break; } @@ -593,7 +595,7 @@ static u8 ps3av_cnv_inputlen(u32 word_bits) static u8 ps3av_cnv_layout(u32 num_of_ch) { if (num_of_ch > PS3AV_CMD_AUDIO_NUM_OF_CH_8) { - printk(KERN_ERR "%s failed, num_of_ch:%x\n", __func__, + printk(KERN_ERR "%s failed, num_of_ch:%x\n", __FUNCTION__, num_of_ch); return 0; } @@ -862,7 +864,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len) res = get_status(avb); if (res) - pr_debug("%s: PS3AV_CID_AVB_PARAM: failed %x\n", __func__, + pr_debug("%s: PS3AV_CID_AVB_PARAM: failed %x\n", __FUNCTION__, res); out: @@ -1011,7 +1013,7 @@ int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf, return size; if (error != -EAGAIN) { printk(KERN_ERR "%s: ps3_vuart_read failed %d\n", - __func__, error); + __FUNCTION__, error); return error; } msleep(POLLING_INTERVAL); diff --git a/trunk/drivers/ps3/vuart.c b/trunk/drivers/ps3/vuart.c index ec2d36a1bc67..7d7cab1d91b4 100644 --- a/trunk/drivers/ps3/vuart.c +++ b/trunk/drivers/ps3/vuart.c @@ -886,12 +886,12 @@ static int ps3_vuart_probe(struct device *_dev) if (++vuart_bus_priv.use_count == 1) { - result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY, + result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY, (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq); if (result) { dev_dbg(&dev->core, - "%s:%d: ps3_vuart_irq_setup failed (%d)\n", + "%s:%d: ps3_alloc_vuart_irq failed (%d)\n", __func__, __LINE__, result); result = -EPERM; goto fail_alloc_irq; @@ -937,7 +937,7 @@ static int ps3_vuart_probe(struct device *_dev) fail_probe: ps3_vuart_set_interrupt_mask(dev, 0); fail_request_irq: - ps3_vuart_irq_destroy(vuart_bus_priv.virq); + ps3_free_vuart_irq(vuart_bus_priv.virq); vuart_bus_priv.virq = NO_IRQ; fail_alloc_irq: --vuart_bus_priv.use_count; @@ -975,7 +975,7 @@ static int ps3_vuart_remove(struct device *_dev) if (--vuart_bus_priv.use_count == 0) { BUG(); free_irq(vuart_bus_priv.virq, &vuart_bus_priv); - ps3_vuart_irq_destroy(vuart_bus_priv.virq); + ps3_free_vuart_irq(vuart_bus_priv.virq); vuart_bus_priv.virq = NO_IRQ; } diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 5e439836db2d..95826b92ca4b 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -21,31 +21,21 @@ config RTC_CLASS will be called rtc-class. config RTC_HCTOSYS - bool "Set system time from RTC on startup and resume" + bool "Set system time from RTC on startup" depends on RTC_CLASS = y default y help - If you say yes here, the system time (wall clock) will be set using - the value read from a specified RTC device. This is useful to avoid - unnecessary fsck runs at boot time, and to network better. + If you say yes here, the system time will be set using + the value read from the specified RTC device. This is useful + in order to avoid unnecessary fsck runs. config RTC_HCTOSYS_DEVICE - string "RTC used to set the system time" + string "The RTC to read the time from" depends on RTC_HCTOSYS = y default "rtc0" help - The RTC device that will be used to (re)initialize the system - clock, usually rtc0. Initialization is done when the system - starts up, and when it resumes from a low power state. - - This clock should be battery-backed, so that it reads the correct - time when the system boots from a power-off state. Otherwise, your - system will need an external clock source (like an NTP server). - - If the clock you specify here is not battery backed, it may still - be useful to reinitialize system time when resuming from system - sleep states. Do not specify an RTC here unless it stays powered - during all this system's supported sleep states. + The RTC device that will be used as the source for + the system time, usually rtc0. config RTC_DEBUG bool "RTC debug support" @@ -58,7 +48,7 @@ comment "RTC interfaces" depends on RTC_CLASS config RTC_INTF_SYSFS - boolean "sysfs" + tristate "sysfs" depends on RTC_CLASS && SYSFS default RTC_CLASS help @@ -69,7 +59,7 @@ config RTC_INTF_SYSFS will be called rtc-sysfs. config RTC_INTF_PROC - boolean "proc" + tristate "proc" depends on RTC_CLASS && PROC_FS default RTC_CLASS help @@ -81,7 +71,7 @@ config RTC_INTF_PROC will be called rtc-proc. config RTC_INTF_DEV - boolean "dev" + tristate "dev" depends on RTC_CLASS default RTC_CLASS help @@ -102,26 +92,44 @@ config RTC_INTF_DEV_UIE_EMUL driver does not expose RTC_UIE ioctls. Those requests generate once-per-second update interrupts, used for synchronization. -config RTC_DRV_TEST - tristate "Test driver/device" +comment "RTC drivers" depends on RTC_CLASS + +# this 'CMOS' RTC driver is arch dependent because +# requires defining CMOS_READ/CMOS_WRITE, and a +# global rtc_lock ... it's not yet just another platform_device. + +config RTC_DRV_CMOS + tristate "PC-style 'CMOS' real time clock" + depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \ + || M32R || ATARI || POWERPC) help - If you say yes here you get support for the - RTC test driver. It's a software RTC which can be - used to test the RTC subsystem APIs. It gets - the time from the system clock. - You want this driver only if you are doing development - on the RTC subsystem. Please read the source code - for further details. + Say "yes" here to get direct support for the real time clock + found in every PC or ACPI-based system, and some other boards. + Specifically the original MC146818, compatibles like those in + PC south bridges, the DS12887 or M48T86, some multifunction + or LPC bus chips, and so on. + + Your system will need to define the platform device used by + this driver, otherwise it won't be accessible. This means + you can safely enable this driver if you don't know whether + or not your board has this kind of hardware. This driver can also be built as a module. If so, the module - will be called rtc-test. + will be called rtc-cmos. -comment "I2C RTC drivers" - depends on RTC_CLASS +config RTC_DRV_X1205 + tristate "Xicor/Intersil X1205" + depends on RTC_CLASS && I2C + help + If you say yes here you get support for the + Xicor/Intersil X1205 RTC chip. + + This driver can also be built as a module. If so, the module + will be called rtc-x1205. config RTC_DRV_DS1307 - tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00" + tristate "Dallas/Maxim DS1307 and similar I2C RTC chips" depends on RTC_CLASS && I2C help If you say yes here you get support for various compatible RTC @@ -138,55 +146,53 @@ config RTC_DRV_DS1307 This driver can also be built as a module. If so, the module will be called rtc-ds1307. -config RTC_DRV_DS1672 - tristate "Dallas/Maxim DS1672" - depends on RTC_CLASS && I2C +config RTC_DRV_DS1553 + tristate "Dallas DS1553" + depends on RTC_CLASS help If you say yes here you get support for the - Dallas/Maxim DS1672 timekeeping chip. + Dallas DS1553 timekeeping chip. This driver can also be built as a module. If so, the module - will be called rtc-ds1672. + will be called rtc-ds1553. -config RTC_DRV_MAX6900 - tristate "Maxim 6900" +config RTC_DRV_ISL1208 + tristate "Intersil 1208" depends on RTC_CLASS && I2C help - If you say yes here you will get support for the - Maxim MAX6900 I2C RTC chip. + If you say yes here you get support for the + Intersil 1208 RTC chip. This driver can also be built as a module. If so, the module - will be called rtc-max6900. + will be called rtc-isl1208. -config RTC_DRV_RS5C372 - tristate "Ricoh RS5C372A/B" +config RTC_DRV_DS1672 + tristate "Dallas/Maxim DS1672" depends on RTC_CLASS && I2C help If you say yes here you get support for the - Ricoh RS5C372A and RS5C372B RTC chips. + Dallas/Maxim DS1672 timekeeping chip. This driver can also be built as a module. If so, the module - will be called rtc-rs5c372. + will be called rtc-ds1672. -config RTC_DRV_ISL1208 - tristate "Intersil 1208" - depends on RTC_CLASS && I2C +config RTC_DRV_DS1742 + tristate "Dallas DS1742/1743" + depends on RTC_CLASS help If you say yes here you get support for the - Intersil 1208 RTC chip. + Dallas DS1742/1743 timekeeping chip. This driver can also be built as a module. If so, the module - will be called rtc-isl1208. + will be called rtc-ds1742. -config RTC_DRV_X1205 - tristate "Xicor/Intersil X1205" - depends on RTC_CLASS && I2C +config RTC_DRV_OMAP + tristate "TI OMAP1" + depends on RTC_CLASS && ( \ + ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 ) help - If you say yes here you get support for the - Xicor/Intersil X1205 RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-x1205. + Say "yes" here to support the real time clock on TI OMAP1 chips. + This driver can also be built as a module called rtc-omap. config RTC_DRV_PCF8563 tristate "Philips PCF8563/Epson RTC8564" @@ -201,20 +207,16 @@ config RTC_DRV_PCF8563 config RTC_DRV_PCF8583 tristate "Philips PCF8583" - depends on RTC_CLASS && I2C + depends on RTC_CLASS && I2C && ARCH_RPC help If you say yes here you get support for the Philips PCF8583 - RTC chip found on Acorn RiscPCs. This driver supports the + RTC chip found on Acorn RiscPCs. This driver supports the platform specific method of retrieving the current year from - the RTC's SRAM. It will work on other platforms with the same - chip, but the year will probably have to be tweaked. + the RTC's SRAM. This driver can also be built as a module. If so, the module will be called rtc-pcf8583. -comment "SPI RTC drivers" - depends on RTC_CLASS - config RTC_DRV_RS5C348 tristate "Ricoh RS5C348A/B" depends on RTC_CLASS && SPI @@ -225,92 +227,15 @@ config RTC_DRV_RS5C348 This driver can also be built as a module. If so, the module will be called rtc-rs5c348. -config RTC_DRV_MAX6902 - tristate "Maxim 6902" - depends on RTC_CLASS && SPI - help - If you say yes here you will get support for the - Maxim MAX6902 SPI RTC chip. - - This driver can also be built as a module. If so, the module - will be called rtc-max6902. - -comment "Platform RTC drivers" - depends on RTC_CLASS - -# this 'CMOS' RTC driver is arch dependent because -# requires defining CMOS_READ/CMOS_WRITE, and a -# global rtc_lock ... it's not yet just another platform_device. - -config RTC_DRV_CMOS - tristate "PC-style 'CMOS'" - depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \ - || M32R || ATARI || POWERPC) - help - Say "yes" here to get direct support for the real time clock - found in every PC or ACPI-based system, and some other boards. - Specifically the original MC146818, compatibles like those in - PC south bridges, the DS12887 or M48T86, some multifunction - or LPC bus chips, and so on. - - Your system will need to define the platform device used by - this driver, otherwise it won't be accessible. This means - you can safely enable this driver if you don't know whether - or not your board has this kind of hardware. - - This driver can also be built as a module. If so, the module - will be called rtc-cmos. - -config RTC_DRV_DS1553 - tristate "Dallas DS1553" - depends on RTC_CLASS - help - If you say yes here you get support for the - Dallas DS1553 timekeeping chip. - - This driver can also be built as a module. If so, the module - will be called rtc-ds1553. - -config RTC_DRV_DS1742 - tristate "Dallas DS1742/1743" - depends on RTC_CLASS +config RTC_DRV_RS5C372 + tristate "Ricoh RS5C372A/B" + depends on RTC_CLASS && I2C help If you say yes here you get support for the - Dallas DS1742/1743 timekeeping chip. - - This driver can also be built as a module. If so, the module - will be called rtc-ds1742. - -config RTC_DRV_M48T86 - tristate "ST M48T86/Dallas DS12887" - depends on RTC_CLASS - help - If you say Y here you will get support for the - ST M48T86 and Dallas DS12887 RTC chips. - - This driver can also be built as a module. If so, the module - will be called rtc-m48t86. - -config RTC_DRV_V3020 - tristate "EM Microelectronic V3020" - depends on RTC_CLASS - help - If you say yes here you will get support for the - EM Microelectronic v3020 RTC chip. + Ricoh RS5C372A and RS5C372B RTC chips. This driver can also be built as a module. If so, the module - will be called rtc-v3020. - -comment "on-CPU RTC drivers" - depends on RTC_CLASS - -config RTC_DRV_OMAP - tristate "TI OMAP1" - depends on RTC_CLASS && ( \ - ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 ) - help - Say "yes" here to support the real time clock on TI OMAP1 chips. - This driver can also be built as a module called rtc-omap. + will be called rtc-rs5c372. config RTC_DRV_S3C tristate "Samsung S3C series SoC RTC" @@ -328,6 +253,16 @@ config RTC_DRV_S3C This driver can also be build as a module. If so, the module will be called rtc-s3c. +config RTC_DRV_M48T86 + tristate "ST M48T86/Dallas DS12887" + depends on RTC_CLASS + help + If you say Y here you will get support for the + ST M48T86 and Dallas DS12887 RTC chips. + + This driver can also be built as a module. If so, the module + will be called rtc-m48t86. + config RTC_DRV_EP93XX tristate "Cirrus Logic EP93XX" depends on RTC_CLASS && ARCH_EP93XX @@ -373,7 +308,7 @@ config RTC_DRV_PL031 depends on RTC_CLASS && ARM_AMBA help If you say Y here you will get access to ARM AMBA - PrimeCell PL031 RTC found on certain ARM SOCs. + PrimeCell PL031 UART found on certain ARM SOCs. To compile this driver as a module, choose M here: the module will be called rtc-pl031. @@ -384,20 +319,39 @@ config RTC_DRV_AT91RM9200 help Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock). -config RTC_DRV_BFIN - tristate "Blackfin On-Chip RTC" - depends on RTC_CLASS && BFIN +config RTC_DRV_TEST + tristate "Test driver/device" + depends on RTC_CLASS + help + If you say yes here you get support for the + RTC test driver. It's a software RTC which can be + used to test the RTC subsystem APIs. It gets + the time from the system clock. + You want this driver only if you are doing development + on the RTC subsystem. Please read the source code + for further details. + + This driver can also be built as a module. If so, the module + will be called rtc-test. + +config RTC_DRV_MAX6902 + tristate "Maxim 6902" + depends on RTC_CLASS && SPI help If you say yes here you will get support for the - Blackfin On-Chip Real Time Clock. + Maxim MAX6902 spi RTC chip. This driver can also be built as a module. If so, the module - will be called rtc-bfin. + will be called rtc-max6902. -config RTC_DRV_RS5C313 - tristate "Ricoh RS5C313" - depends on RTC_CLASS && BROKEN +config RTC_DRV_V3020 + tristate "EM Microelectronic V3020" + depends on RTC_CLASS help - If you say yes here you get support for the Ricoh RS5C313 RTC chips. + If you say yes here you will get support for the + EM Microelectronic v3020 RTC chip. + + This driver can also be built as a module. If so, the module + will be called rtc-v3020. endmenu diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index a1afbc236073..92bfe1b3a5fa 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -11,9 +11,9 @@ obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o obj-$(CONFIG_RTC_CLASS) += rtc-core.o rtc-core-y := class.o interface.o -rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o -rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o -rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o +obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o +obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o +obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o @@ -30,14 +30,11 @@ obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o -obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o -obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o obj-$(CONFIG_RTC_DRV_SH) += rtc-sh.o -obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o diff --git a/trunk/drivers/rtc/class.c b/trunk/drivers/rtc/class.c index 8b3cd31d6a61..04aaa6347234 100644 --- a/trunk/drivers/rtc/class.c +++ b/trunk/drivers/rtc/class.c @@ -16,94 +16,19 @@ #include #include -#include "rtc-core.h" - - static DEFINE_IDR(rtc_idr); static DEFINE_MUTEX(idr_lock); struct class *rtc_class; -static void rtc_device_release(struct device *dev) +static void rtc_device_release(struct class_device *class_dev) { - struct rtc_device *rtc = to_rtc_device(dev); + struct rtc_device *rtc = to_rtc_device(class_dev); mutex_lock(&idr_lock); idr_remove(&rtc_idr, rtc->id); mutex_unlock(&idr_lock); kfree(rtc); } -#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE) - -/* - * On suspend(), measure the delta between one RTC and the - * system's wall clock; restore it on resume(). - */ - -static struct timespec delta; -static time_t oldtime; - -static int rtc_suspend(struct device *dev, pm_message_t mesg) -{ - struct rtc_device *rtc = to_rtc_device(dev); - struct rtc_time tm; - - if (strncmp(rtc->dev.bus_id, - CONFIG_RTC_HCTOSYS_DEVICE, - BUS_ID_SIZE) != 0) - return 0; - - rtc_read_time(rtc, &tm); - rtc_tm_to_time(&tm, &oldtime); - - /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */ - set_normalized_timespec(&delta, - xtime.tv_sec - oldtime, - xtime.tv_nsec - (NSEC_PER_SEC >> 1)); - - return 0; -} - -static int rtc_resume(struct device *dev) -{ - struct rtc_device *rtc = to_rtc_device(dev); - struct rtc_time tm; - time_t newtime; - struct timespec time; - - if (strncmp(rtc->dev.bus_id, - CONFIG_RTC_HCTOSYS_DEVICE, - BUS_ID_SIZE) != 0) - return 0; - - rtc_read_time(rtc, &tm); - if (rtc_valid_tm(&tm) != 0) { - pr_debug("%s: bogus resume time\n", rtc->dev.bus_id); - return 0; - } - rtc_tm_to_time(&tm, &newtime); - if (newtime <= oldtime) { - if (newtime < oldtime) - pr_debug("%s: time travel!\n", rtc->dev.bus_id); - return 0; - } - - /* restore wall clock using delta against this RTC; - * adjust again for avg 1/2 second RTC sampling error - */ - set_normalized_timespec(&time, - newtime + delta.tv_sec, - (NSEC_PER_SEC >> 1) + delta.tv_nsec); - do_settimeofday(&time); - - return 0; -} - -#else -#define rtc_suspend NULL -#define rtc_resume NULL -#endif - - /** * rtc_device_register - register w/ RTC class * @dev: the device to register @@ -145,29 +70,23 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, rtc->ops = ops; rtc->owner = owner; rtc->max_user_freq = 64; - rtc->dev.parent = dev; - rtc->dev.class = rtc_class; - rtc->dev.release = rtc_device_release; + rtc->class_dev.dev = dev; + rtc->class_dev.class = rtc_class; + rtc->class_dev.release = rtc_device_release; mutex_init(&rtc->ops_lock); spin_lock_init(&rtc->irq_lock); spin_lock_init(&rtc->irq_task_lock); strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); - snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id); + snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id); - rtc_dev_prepare(rtc); - - err = device_register(&rtc->dev); + err = class_device_register(&rtc->class_dev); if (err) goto exit_kfree; - rtc_dev_add_device(rtc); - rtc_sysfs_add_device(rtc); - rtc_proc_add_device(rtc); - dev_info(dev, "rtc core: registered %s as %s\n", - rtc->name, rtc->dev.bus_id); + rtc->name, rtc->class_dev.class_id); return rtc; @@ -194,22 +113,26 @@ EXPORT_SYMBOL_GPL(rtc_device_register); */ void rtc_device_unregister(struct rtc_device *rtc) { - if (get_device(&rtc->dev) != NULL) { + if (class_device_get(&rtc->class_dev) != NULL) { mutex_lock(&rtc->ops_lock); /* remove innards of this RTC, then disable it, before * letting any rtc_class_open() users access it again */ - rtc_sysfs_del_device(rtc); - rtc_dev_del_device(rtc); - rtc_proc_del_device(rtc); - device_unregister(&rtc->dev); + class_device_unregister(&rtc->class_dev); rtc->ops = NULL; mutex_unlock(&rtc->ops_lock); - put_device(&rtc->dev); + class_device_put(&rtc->class_dev); } } EXPORT_SYMBOL_GPL(rtc_device_unregister); +int rtc_interface_register(struct class_interface *intf) +{ + intf->class = rtc_class; + return class_interface_register(intf); +} +EXPORT_SYMBOL_GPL(rtc_interface_register); + static int __init rtc_init(void) { rtc_class = class_create(THIS_MODULE, "rtc"); @@ -217,16 +140,11 @@ static int __init rtc_init(void) printk(KERN_ERR "%s: couldn't create class\n", __FILE__); return PTR_ERR(rtc_class); } - rtc_class->suspend = rtc_suspend; - rtc_class->resume = rtc_resume; - rtc_dev_init(); - rtc_sysfs_init(rtc_class); return 0; } static void __exit rtc_exit(void) { - rtc_dev_exit(); class_destroy(rtc_class); } diff --git a/trunk/drivers/rtc/hctosys.c b/trunk/drivers/rtc/hctosys.c index 178527252c6a..d02fe9a0001f 100644 --- a/trunk/drivers/rtc/hctosys.c +++ b/trunk/drivers/rtc/hctosys.c @@ -26,15 +26,15 @@ static int __init rtc_hctosys(void) { int err; struct rtc_time tm; - struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); + struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); - if (rtc == NULL) { + if (class_dev == NULL) { printk("%s: unable to open rtc device (%s)\n", __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); return -ENODEV; } - err = rtc_read_time(rtc, &tm); + err = rtc_read_time(class_dev, &tm); if (err == 0) { err = rtc_valid_tm(&tm); if (err == 0) { @@ -46,7 +46,7 @@ static int __init rtc_hctosys(void) do_settimeofday(&tv); - dev_info(rtc->dev.parent, + dev_info(class_dev->dev, "setting the system clock to " "%d-%02d-%02d %02d:%02d:%02d (%u)\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, @@ -54,14 +54,14 @@ static int __init rtc_hctosys(void) (unsigned int) tv.tv_sec); } else - dev_err(rtc->dev.parent, + dev_err(class_dev->dev, "hctosys: invalid date/time\n"); } else - dev_err(rtc->dev.parent, + dev_err(class_dev->dev, "hctosys: unable to read the hardware clock\n"); - rtc_class_close(rtc); + rtc_class_close(class_dev); return 0; } diff --git a/trunk/drivers/rtc/interface.c b/trunk/drivers/rtc/interface.c index ad66c6ecf365..ef40df0f169d 100644 --- a/trunk/drivers/rtc/interface.c +++ b/trunk/drivers/rtc/interface.c @@ -13,9 +13,10 @@ #include -int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) +int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) { int err; + struct rtc_device *rtc = to_rtc_device(class_dev); err = mutex_lock_interruptible(&rtc->ops_lock); if (err) @@ -27,7 +28,7 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) err = -EINVAL; else { memset(tm, 0, sizeof(struct rtc_time)); - err = rtc->ops->read_time(rtc->dev.parent, tm); + err = rtc->ops->read_time(class_dev->dev, tm); } mutex_unlock(&rtc->ops_lock); @@ -35,9 +36,10 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) } EXPORT_SYMBOL_GPL(rtc_read_time); -int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) +int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm) { int err; + struct rtc_device *rtc = to_rtc_device(class_dev); err = rtc_valid_tm(tm); if (err != 0) @@ -52,16 +54,17 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) else if (!rtc->ops->set_time) err = -EINVAL; else - err = rtc->ops->set_time(rtc->dev.parent, tm); + err = rtc->ops->set_time(class_dev->dev, tm); mutex_unlock(&rtc->ops_lock); return err; } EXPORT_SYMBOL_GPL(rtc_set_time); -int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) +int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) { int err; + struct rtc_device *rtc = to_rtc_device(class_dev); err = mutex_lock_interruptible(&rtc->ops_lock); if (err) @@ -70,11 +73,11 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) if (!rtc->ops) err = -ENODEV; else if (rtc->ops->set_mmss) - err = rtc->ops->set_mmss(rtc->dev.parent, secs); + err = rtc->ops->set_mmss(class_dev->dev, secs); else if (rtc->ops->read_time && rtc->ops->set_time) { struct rtc_time new, old; - err = rtc->ops->read_time(rtc->dev.parent, &old); + err = rtc->ops->read_time(class_dev->dev, &old); if (err == 0) { rtc_time_to_tm(secs, &new); @@ -86,8 +89,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) */ if (!((old.tm_hour == 23 && old.tm_min == 59) || (new.tm_hour == 23 && new.tm_min == 59))) - err = rtc->ops->set_time(rtc->dev.parent, - &new); + err = rtc->ops->set_time(class_dev->dev, &new); } } else @@ -99,9 +101,10 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) } EXPORT_SYMBOL_GPL(rtc_set_mmss); -int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) +int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) { int err; + struct rtc_device *rtc = to_rtc_device(class_dev); err = mutex_lock_interruptible(&rtc->ops_lock); if (err) @@ -113,7 +116,7 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) err = -EINVAL; else { memset(alarm, 0, sizeof(struct rtc_wkalrm)); - err = rtc->ops->read_alarm(rtc->dev.parent, alarm); + err = rtc->ops->read_alarm(class_dev->dev, alarm); } mutex_unlock(&rtc->ops_lock); @@ -121,13 +124,10 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) } EXPORT_SYMBOL_GPL(rtc_read_alarm); -int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) +int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) { int err; - - err = rtc_valid_tm(&alarm->time); - if (err != 0) - return err; + struct rtc_device *rtc = to_rtc_device(class_dev); err = mutex_lock_interruptible(&rtc->ops_lock); if (err) @@ -138,7 +138,7 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) else if (!rtc->ops->set_alarm) err = -EINVAL; else - err = rtc->ops->set_alarm(rtc->dev.parent, alarm); + err = rtc->ops->set_alarm(class_dev->dev, alarm); mutex_unlock(&rtc->ops_lock); return err; @@ -147,14 +147,16 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm); /** * rtc_update_irq - report RTC periodic, alarm, and/or update irqs - * @rtc: the rtc device + * @class_dev: the rtc's class device * @num: how many irqs are being reported (usually one) * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF * Context: in_interrupt(), irqs blocked */ -void rtc_update_irq(struct rtc_device *rtc, +void rtc_update_irq(struct class_device *class_dev, unsigned long num, unsigned long events) { + struct rtc_device *rtc = to_rtc_device(class_dev); + spin_lock(&rtc->irq_lock); rtc->irq_data = (rtc->irq_data + (num << 8)) | events; spin_unlock(&rtc->irq_lock); @@ -169,43 +171,40 @@ void rtc_update_irq(struct rtc_device *rtc, } EXPORT_SYMBOL_GPL(rtc_update_irq); -struct rtc_device *rtc_class_open(char *name) +struct class_device *rtc_class_open(char *name) { - struct device *dev; - struct rtc_device *rtc = NULL; + struct class_device *class_dev = NULL, + *class_dev_tmp; down(&rtc_class->sem); - list_for_each_entry(dev, &rtc_class->devices, node) { - if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) { - dev = get_device(dev); - if (dev) - rtc = to_rtc_device(dev); + list_for_each_entry(class_dev_tmp, &rtc_class->children, node) { + if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) { + class_dev = class_device_get(class_dev_tmp); break; } } - if (rtc) { - if (!try_module_get(rtc->owner)) { - put_device(dev); - rtc = NULL; - } + if (class_dev) { + if (!try_module_get(to_rtc_device(class_dev)->owner)) + class_dev = NULL; } up(&rtc_class->sem); - return rtc; + return class_dev; } EXPORT_SYMBOL_GPL(rtc_class_open); -void rtc_class_close(struct rtc_device *rtc) +void rtc_class_close(struct class_device *class_dev) { - module_put(rtc->owner); - put_device(&rtc->dev); + module_put(to_rtc_device(class_dev)->owner); + class_device_put(class_dev); } EXPORT_SYMBOL_GPL(rtc_class_close); -int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task) +int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) { int retval = -EBUSY; + struct rtc_device *rtc = to_rtc_device(class_dev); if (task == NULL || task->func == NULL) return -EINVAL; @@ -221,8 +220,9 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task) } EXPORT_SYMBOL_GPL(rtc_irq_register); -void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task) +void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) { + struct rtc_device *rtc = to_rtc_device(class_dev); spin_lock_irq(&rtc->irq_task_lock); if (rtc->irq_task == task) @@ -231,10 +231,11 @@ void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task) } EXPORT_SYMBOL_GPL(rtc_irq_unregister); -int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled) +int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled) { int err = 0; unsigned long flags; + struct rtc_device *rtc = to_rtc_device(class_dev); if (rtc->ops->irq_set_state == NULL) return -ENXIO; @@ -245,16 +246,17 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled spin_unlock_irqrestore(&rtc->irq_task_lock, flags); if (err == 0) - err = rtc->ops->irq_set_state(rtc->dev.parent, enabled); + err = rtc->ops->irq_set_state(class_dev->dev, enabled); return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_state); -int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) +int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) { int err = 0; unsigned long flags; + struct rtc_device *rtc = to_rtc_device(class_dev); if (rtc->ops->irq_set_freq == NULL) return -ENXIO; @@ -265,7 +267,7 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) spin_unlock_irqrestore(&rtc->irq_task_lock, flags); if (err == 0) { - err = rtc->ops->irq_set_freq(rtc->dev.parent, freq); + err = rtc->ops->irq_set_freq(class_dev->dev, freq); if (err == 0) rtc->irq_freq = freq; } diff --git a/trunk/drivers/rtc/rtc-at91rm9200.c b/trunk/drivers/rtc/rtc-at91rm9200.c index 33795e5a5595..ac0e68e2f025 100644 --- a/trunk/drivers/rtc/rtc-at91rm9200.c +++ b/trunk/drivers/rtc/rtc-at91rm9200.c @@ -263,7 +263,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ - rtc_update_irq(rtc, 1, events); + rtc_update_irq(&rtc->class_dev, 1, events); pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__, events >> 8, events & 0x000000FF); @@ -348,10 +348,21 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) /* AT91RM9200 RTC Power management control */ +static struct timespec at91_rtc_delta; static u32 at91_rtc_imr; static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) { + struct rtc_time tm; + struct timespec time; + + time.tv_nsec = 0; + + /* calculate time delta for suspend */ + at91_rtc_readtime(&pdev->dev, &tm); + rtc_tm_to_time(&tm, &time.tv_sec); + save_time_delta(&at91_rtc_delta, &time); + /* this IRQ is shared with DBGU and other hardware which isn't * necessarily doing PM like we are... */ @@ -363,17 +374,36 @@ static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) else at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); } + + pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, + 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + return 0; } static int at91_rtc_resume(struct platform_device *pdev) { + struct rtc_time tm; + struct timespec time; + + time.tv_nsec = 0; + + at91_rtc_readtime(&pdev->dev, &tm); + rtc_tm_to_time(&tm, &time.tv_sec); + restore_time_delta(&at91_rtc_delta, &time); + if (at91_rtc_imr) { if (device_may_wakeup(&pdev->dev)) disable_irq_wake(AT91_ID_SYS); else at91_sys_write(AT91_RTC_IER, at91_rtc_imr); } + + pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__, + 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + return 0; } #else diff --git a/trunk/drivers/rtc/rtc-bfin.c b/trunk/drivers/rtc/rtc-bfin.c deleted file mode 100644 index 260ead959918..000000000000 --- a/trunk/drivers/rtc/rtc-bfin.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * Blackfin On-Chip Real Time Clock Driver - * Supports BF531/BF532/BF533/BF534/BF536/BF537 - * - * Copyright 2004-2007 Analog Devices Inc. - * - * Enter bugs at http://blackfin.uclinux.org/ - * - * Licensed under the GPL-2 or later. - */ - -/* The biggest issue we deal with in this driver is that register writes are - * synced to the RTC frequency of 1Hz. So if you write to a register and - * attempt to write again before the first write has completed, the new write - * is simply discarded. This can easily be troublesome if userspace disables - * one event (say periodic) and then right after enables an event (say alarm). - * Since all events are maintained in the same interrupt mask register, if - * we wrote to it to disable the first event and then wrote to it again to - * enable the second event, that second event would not be enabled as the - * write would be discarded and things quickly fall apart. - * - * To keep this delay from significantly degrading performance (we, in theory, - * would have to sleep for up to 1 second everytime we wanted to write a - * register), we only check the write pending status before we start to issue - * a new write. We bank on the idea that it doesnt matter when the sync - * happens so long as we don't attempt another write before it does. The only - * time userspace would take this penalty is when they try and do multiple - * operations right after another ... but in this case, they need to take the - * sync penalty, so we should be OK. - * - * Also note that the RTC_ISTAT register does not suffer this penalty; its - * writes to clear status registers complete immediately. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __FUNCTION__, __LINE__, ## args) -#define stampit() stamp("here i am") - -struct bfin_rtc { - struct rtc_device *rtc_dev; - struct rtc_time rtc_alarm; - spinlock_t lock; -}; - -/* Bit values for the ISTAT / ICTL registers */ -#define RTC_ISTAT_WRITE_COMPLETE 0x8000 -#define RTC_ISTAT_WRITE_PENDING 0x4000 -#define RTC_ISTAT_ALARM_DAY 0x0040 -#define RTC_ISTAT_24HR 0x0020 -#define RTC_ISTAT_HOUR 0x0010 -#define RTC_ISTAT_MIN 0x0008 -#define RTC_ISTAT_SEC 0x0004 -#define RTC_ISTAT_ALARM 0x0002 -#define RTC_ISTAT_STOPWATCH 0x0001 - -/* Shift values for RTC_STAT register */ -#define DAY_BITS_OFF 17 -#define HOUR_BITS_OFF 12 -#define MIN_BITS_OFF 6 -#define SEC_BITS_OFF 0 - -/* Some helper functions to convert between the common RTC notion of time - * and the internal Blackfin notion that is stored in 32bits. - */ -static inline u32 rtc_time_to_bfin(unsigned long now) -{ - u32 sec = (now % 60); - u32 min = (now % (60 * 60)) / 60; - u32 hour = (now % (60 * 60 * 24)) / (60 * 60); - u32 days = (now / (60 * 60 * 24)); - return (sec << SEC_BITS_OFF) + - (min << MIN_BITS_OFF) + - (hour << HOUR_BITS_OFF) + - (days << DAY_BITS_OFF); -} -static inline unsigned long rtc_bfin_to_time(u32 rtc_bfin) -{ - return (((rtc_bfin >> SEC_BITS_OFF) & 0x003F)) + - (((rtc_bfin >> MIN_BITS_OFF) & 0x003F) * 60) + - (((rtc_bfin >> HOUR_BITS_OFF) & 0x001F) * 60 * 60) + - (((rtc_bfin >> DAY_BITS_OFF) & 0x7FFF) * 60 * 60 * 24); -} -static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm) -{ - rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm); -} - -/* Wait for the previous write to a RTC register to complete. - * Unfortunately, we can't sleep here as that introduces a race condition when - * turning on interrupt events. Consider this: - * - process sets alarm - * - process enables alarm - * - process sleeps while waiting for rtc write to sync - * - interrupt fires while process is sleeping - * - interrupt acks the event by writing to ISTAT - * - interrupt sets the WRITE PENDING bit - * - interrupt handler finishes - * - process wakes up, sees WRITE PENDING bit set, goes to sleep - * - interrupt fires while process is sleeping - * If anyone can point out the obvious solution here, i'm listening :). This - * shouldn't be an issue on an SMP or preempt system as this function should - * only be called with the rtc lock held. - */ -static void rtc_bfin_sync_pending(void) -{ - stampit(); - while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE)) { - if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)) - break; - } - bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); -} - -static void rtc_bfin_reset(struct bfin_rtc *rtc) -{ - /* Initialize the RTC. Enable pre-scaler to scale RTC clock - * to 1Hz and clear interrupt/status registers. */ - spin_lock_irq(&rtc->lock); - rtc_bfin_sync_pending(); - bfin_write_RTC_PREN(0x1); - bfin_write_RTC_ICTL(0); - bfin_write_RTC_SWCNT(0); - bfin_write_RTC_ALARM(0); - bfin_write_RTC_ISTAT(0xFFFF); - spin_unlock_irq(&rtc->lock); -} - -static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) -{ - struct platform_device *pdev = to_platform_device(dev_id); - struct bfin_rtc *rtc = platform_get_drvdata(pdev); - unsigned long events = 0; - u16 rtc_istat; - - stampit(); - - spin_lock_irq(&rtc->lock); - - rtc_istat = bfin_read_RTC_ISTAT(); - - if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { - bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); - events |= RTC_AF | RTC_IRQF; - } - - if (rtc_istat & RTC_ISTAT_STOPWATCH) { - bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); - events |= RTC_PF | RTC_IRQF; - bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); - } - - if (rtc_istat & RTC_ISTAT_SEC) { - bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); - events |= RTC_UF | RTC_IRQF; - } - - rtc_update_irq(rtc->rtc_dev, 1, events); - - spin_unlock_irq(&rtc->lock); - - return IRQ_HANDLED; -} - -static int bfin_rtc_open(struct device *dev) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - int ret; - - stampit(); - - ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_DISABLED, "rtc-bfin", dev); - if (unlikely(ret)) { - dev_err(dev, "request RTC IRQ failed with %d\n", ret); - return ret; - } - - rtc_bfin_reset(rtc); - - return ret; -} - -static void bfin_rtc_release(struct device *dev) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - stampit(); - rtc_bfin_reset(rtc); - free_irq(IRQ_RTC, dev); -} - -static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - - stampit(); - - switch (cmd) { - case RTC_PIE_ON: - stampit(); - spin_lock_irq(&rtc->lock); - rtc_bfin_sync_pending(); - bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); - bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); - bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_STOPWATCH); - spin_unlock_irq(&rtc->lock); - return 0; - case RTC_PIE_OFF: - stampit(); - spin_lock_irq(&rtc->lock); - rtc_bfin_sync_pending(); - bfin_write_RTC_SWCNT(0); - bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_STOPWATCH); - spin_unlock_irq(&rtc->lock); - return 0; - - case RTC_UIE_ON: - stampit(); - spin_lock_irq(&rtc->lock); - rtc_bfin_sync_pending(); - bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); - bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_SEC); - spin_unlock_irq(&rtc->lock); - return 0; - case RTC_UIE_OFF: - stampit(); - spin_lock_irq(&rtc->lock); - rtc_bfin_sync_pending(); - bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_SEC); - spin_unlock_irq(&rtc->lock); - return 0; - - case RTC_AIE_ON: { - unsigned long rtc_alarm; - u16 which_alarm; - int ret = 0; - - stampit(); - - spin_lock_irq(&rtc->lock); - - rtc_bfin_sync_pending(); - if (rtc->rtc_alarm.tm_yday == -1) { - struct rtc_time now; - rtc_bfin_to_tm(bfin_read_RTC_STAT(), &now); - now.tm_sec = rtc->rtc_alarm.tm_sec; - now.tm_min = rtc->rtc_alarm.tm_min; - now.tm_hour = rtc->rtc_alarm.tm_hour; - ret = rtc_tm_to_time(&now, &rtc_alarm); - which_alarm = RTC_ISTAT_ALARM; - } else { - ret = rtc_tm_to_time(&rtc->rtc_alarm, &rtc_alarm); - which_alarm = RTC_ISTAT_ALARM_DAY; - } - if (ret == 0) { - bfin_write_RTC_ISTAT(which_alarm); - bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm)); - bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | which_alarm); - } - - spin_unlock_irq(&rtc->lock); - - return ret; - } - case RTC_AIE_OFF: - stampit(); - spin_lock_irq(&rtc->lock); - rtc_bfin_sync_pending(); - bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); - spin_unlock_irq(&rtc->lock); - return 0; - } - - return -ENOIOCTLCMD; -} - -static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - - stampit(); - - spin_lock_irq(&rtc->lock); - rtc_bfin_sync_pending(); - rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm); - spin_unlock_irq(&rtc->lock); - - return 0; -} - -static int bfin_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - int ret; - unsigned long now; - - stampit(); - - spin_lock_irq(&rtc->lock); - - ret = rtc_tm_to_time(tm, &now); - if (ret == 0) { - rtc_bfin_sync_pending(); - bfin_write_RTC_STAT(rtc_time_to_bfin(now)); - } - - spin_unlock_irq(&rtc->lock); - - return ret; -} - -static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - stampit(); - memcpy(&alrm->time, &rtc->rtc_alarm, sizeof(struct rtc_time)); - alrm->pending = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); - return 0; -} - -static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - stampit(); - memcpy(&rtc->rtc_alarm, &alrm->time, sizeof(struct rtc_time)); - return 0; -} - -static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) -{ -#define yesno(x) (x ? "yes" : "no") - u16 ictl = bfin_read_RTC_ICTL(); - stampit(); - seq_printf(seq, "alarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM)); - seq_printf(seq, "wkalarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM_DAY)); - seq_printf(seq, "seconds_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_SEC)); - seq_printf(seq, "periodic_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_STOPWATCH)); -#ifdef DEBUG - seq_printf(seq, "RTC_STAT\t: 0x%08X\n", bfin_read_RTC_STAT()); - seq_printf(seq, "RTC_ICTL\t: 0x%04X\n", bfin_read_RTC_ICTL()); - seq_printf(seq, "RTC_ISTAT\t: 0x%04X\n", bfin_read_RTC_ISTAT()); - seq_printf(seq, "RTC_SWCNT\t: 0x%04X\n", bfin_read_RTC_SWCNT()); - seq_printf(seq, "RTC_ALARM\t: 0x%08X\n", bfin_read_RTC_ALARM()); - seq_printf(seq, "RTC_PREN\t: 0x%04X\n", bfin_read_RTC_PREN()); -#endif - return 0; -} - -static int bfin_irq_set_freq(struct device *dev, int freq) -{ - struct bfin_rtc *rtc = dev_get_drvdata(dev); - stampit(); - rtc->rtc_dev->irq_freq = freq; - return 0; -} - -static struct rtc_class_ops bfin_rtc_ops = { - .open = bfin_rtc_open, - .release = bfin_rtc_release, - .ioctl = bfin_rtc_ioctl, - .read_time = bfin_rtc_read_time, - .set_time = bfin_rtc_set_time, - .read_alarm = bfin_rtc_read_alarm, - .set_alarm = bfin_rtc_set_alarm, - .proc = bfin_rtc_proc, - .irq_set_freq = bfin_irq_set_freq, -}; - -static int __devinit bfin_rtc_probe(struct platform_device *pdev) -{ - struct bfin_rtc *rtc; - int ret = 0; - - stampit(); - - rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); - if (unlikely(!rtc)) - return -ENOMEM; - - spin_lock_init(&rtc->lock); - - rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE); - if (unlikely(IS_ERR(rtc))) { - ret = PTR_ERR(rtc->rtc_dev); - goto err; - } - rtc->rtc_dev->irq_freq = 0; - rtc->rtc_dev->max_user_freq = (2 << 16); /* stopwatch is an unsigned 16 bit reg */ - - platform_set_drvdata(pdev, rtc); - - return 0; - -err: - kfree(rtc); - return ret; -} - -static int __devexit bfin_rtc_remove(struct platform_device *pdev) -{ - struct bfin_rtc *rtc = platform_get_drvdata(pdev); - - rtc_device_unregister(rtc->rtc_dev); - platform_set_drvdata(pdev, NULL); - kfree(rtc); - - return 0; -} - -static struct platform_driver bfin_rtc_driver = { - .driver = { - .name = "rtc-bfin", - .owner = THIS_MODULE, - }, - .probe = bfin_rtc_probe, - .remove = __devexit_p(bfin_rtc_remove), -}; - -static int __init bfin_rtc_init(void) -{ - stampit(); - return platform_driver_register(&bfin_rtc_driver); -} - -static void __exit bfin_rtc_exit(void) -{ - platform_driver_unregister(&bfin_rtc_driver); -} - -module_init(bfin_rtc_init); -module_exit(bfin_rtc_exit); - -MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver"); -MODULE_AUTHOR("Mike Frysinger "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-cmos.c b/trunk/drivers/rtc/rtc-cmos.c index 6085261aa2c1..7c0d60910077 100644 --- a/trunk/drivers/rtc/rtc-cmos.c +++ b/trunk/drivers/rtc/rtc-cmos.c @@ -46,10 +46,6 @@ struct cmos_rtc { int irq; struct resource *iomem; - void (*wake_on)(struct device *); - void (*wake_off)(struct device *); - - u8 enabled_wake; u8 suspend_ctrl; /* newer hardware extends the original register set */ @@ -207,7 +203,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; if (is_intr(rtc_intr)) - rtc_update_irq(cmos->rtc, 1, rtc_intr); + rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); /* update alarm */ CMOS_WRITE(hrs, RTC_HOURS_ALARM); @@ -227,7 +223,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; if (is_intr(rtc_intr)) - rtc_update_irq(cmos->rtc, 1, rtc_intr); + rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); } spin_unlock_irq(&rtc_lock); @@ -308,7 +304,7 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) rtc_intr = CMOS_READ(RTC_INTR_FLAGS); rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; if (is_intr(rtc_intr)) - rtc_update_irq(cmos->rtc, 1, rtc_intr); + rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); spin_unlock_irqrestore(&rtc_lock, flags); return 0; } @@ -383,12 +379,12 @@ static irqreturn_t cmos_interrupt(int irq, void *p) return IRQ_NONE; } -#ifdef CONFIG_PNP -#define is_pnp() 1 +#ifdef CONFIG_PNPACPI +#define is_pnpacpi() 1 #define INITSECTION #else -#define is_pnp() 0 +#define is_pnpacpi() 0 #define INITSECTION __init #endif @@ -409,20 +405,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) cmos_rtc.irq = rtc_irq; cmos_rtc.iomem = ports; - /* For ACPI systems extension info comes from the FADT. On others, - * board specific setup provides it as appropriate. Systems where - * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and - * some almost-clones) can provide hooks to make that behave. + /* For ACPI systems the info comes from the FADT. On others, + * board specific setup provides it as appropriate. */ if (info) { cmos_rtc.day_alrm = info->rtc_day_alarm; cmos_rtc.mon_alrm = info->rtc_mon_alarm; cmos_rtc.century = info->rtc_century; - - if (info->wake_on && info->wake_off) { - cmos_rtc.wake_on = info->wake_on; - cmos_rtc.wake_off = info->wake_off; - } } cmos_rtc.rtc = rtc_device_register(driver_name, dev, @@ -438,14 +427,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) * REVISIT for non-x86 systems we may need to handle io memory * resources: ioremap them, and request_mem_region(). */ - if (is_pnp()) { + if (is_pnpacpi()) { retval = request_resource(&ioport_resource, ports); if (retval < 0) { dev_dbg(dev, "i/o registers already in use\n"); goto cleanup0; } } - rename_region(ports, cmos_rtc.rtc->dev.bus_id); + rename_region(ports, cmos_rtc.rtc->class_dev.class_id); spin_lock_irq(&rtc_lock); @@ -481,8 +470,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) if (is_valid_irq(rtc_irq)) retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED, - cmos_rtc.rtc->dev.bus_id, - cmos_rtc.rtc); + cmos_rtc.rtc->class_dev.class_id, + &cmos_rtc.rtc->class_dev); if (retval < 0) { dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); goto cleanup1; @@ -494,7 +483,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) */ pr_info("%s: alarms up to one %s%s\n", - cmos_rtc.rtc->dev.bus_id, + cmos_rtc.rtc->class_dev.class_id, is_valid_irq(rtc_irq) ? (cmos_rtc.mon_alrm ? "year" @@ -531,12 +520,12 @@ static void __exit cmos_do_remove(struct device *dev) cmos_do_shutdown(); - if (is_pnp()) + if (is_pnpacpi()) release_resource(cmos->iomem); rename_region(cmos->iomem, NULL); if (is_valid_irq(cmos->irq)) - free_irq(cmos->irq, cmos_rtc.rtc); + free_irq(cmos->irq, &cmos_rtc.rtc->class_dev); rtc_device_unregister(cmos_rtc.rtc); @@ -566,20 +555,16 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg) irqstat = CMOS_READ(RTC_INTR_FLAGS); irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF; if (is_intr(irqstat)) - rtc_update_irq(cmos->rtc, 1, irqstat); + rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat); } spin_unlock_irq(&rtc_lock); - if (tmp & RTC_AIE) { - cmos->enabled_wake = 1; - if (cmos->wake_on) - cmos->wake_on(dev); - else - enable_irq_wake(cmos->irq); - } + /* ACPI HOOK: enable ACPI_EVENT_RTC when (tmp & RTC_AIE) + * ... it'd be best if we could do that under rtc_lock. + */ pr_debug("%s: suspend%s, ctrl %02x\n", - cmos_rtc.rtc->dev.bus_id, + cmos_rtc.rtc->class_dev.class_id, (tmp & RTC_AIE) ? ", alarm may wake" : "", tmp); @@ -591,28 +576,26 @@ static int cmos_resume(struct device *dev) struct cmos_rtc *cmos = dev_get_drvdata(dev); unsigned char tmp = cmos->suspend_ctrl; + /* REVISIT: a mechanism to resync the system clock (jiffies) + * on resume should be portable between platforms ... + */ + /* re-enable any irqs previously active */ if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { - if (cmos->enabled_wake) { - if (cmos->wake_off) - cmos->wake_off(dev); - else - disable_irq_wake(cmos->irq); - cmos->enabled_wake = 0; - } + /* ACPI HOOK: disable ACPI_EVENT_RTC when (tmp & RTC_AIE) */ spin_lock_irq(&rtc_lock); CMOS_WRITE(tmp, RTC_CONTROL); tmp = CMOS_READ(RTC_INTR_FLAGS); tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF; if (is_intr(tmp)) - rtc_update_irq(cmos->rtc, 1, tmp); + rtc_update_irq(&cmos->rtc->class_dev, 1, tmp); spin_unlock_irq(&rtc_lock); } pr_debug("%s: resume, ctrl %02x\n", - cmos_rtc.rtc->dev.bus_id, + cmos_rtc.rtc->class_dev.class_id, cmos->suspend_ctrl); @@ -630,7 +613,7 @@ static int cmos_resume(struct device *dev) * the device node will always be created as a PNPACPI device. */ -#ifdef CONFIG_PNP +#ifdef CONFIG_PNPACPI #include @@ -701,11 +684,11 @@ static void __exit cmos_exit(void) } module_exit(cmos_exit); -#else /* no PNP */ +#else /* no PNPACPI */ /*----------------------------------------------------------------*/ -/* Platform setup should have set up an RTC device, when PNP is +/* Platform setup should have set up an RTC device, when PNPACPI is * unavailable ... this could happen even on (older) PCs. */ @@ -751,7 +734,7 @@ static void __exit cmos_exit(void) module_exit(cmos_exit); -#endif /* !PNP */ +#endif /* !PNPACPI */ MODULE_AUTHOR("David Brownell"); MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); diff --git a/trunk/drivers/rtc/rtc-core.h b/trunk/drivers/rtc/rtc-core.h deleted file mode 100644 index 5f9df7430a22..000000000000 --- a/trunk/drivers/rtc/rtc-core.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifdef CONFIG_RTC_INTF_DEV - -extern void __init rtc_dev_init(void); -extern void __exit rtc_dev_exit(void); -extern void rtc_dev_prepare(struct rtc_device *rtc); -extern void rtc_dev_add_device(struct rtc_device *rtc); -extern void rtc_dev_del_device(struct rtc_device *rtc); - -#else - -static inline void rtc_dev_init(void) -{ -} - -static inline void rtc_dev_exit(void) -{ -} - -static inline void rtc_dev_prepare(struct rtc_device *rtc) -{ -} - -static inline void rtc_dev_add_device(struct rtc_device *rtc) -{ -} - -static inline void rtc_dev_del_device(struct rtc_device *rtc) -{ -} - -#endif - -#ifdef CONFIG_RTC_INTF_PROC - -extern void rtc_proc_add_device(struct rtc_device *rtc); -extern void rtc_proc_del_device(struct rtc_device *rtc); - -#else - -static inline void rtc_proc_add_device(struct rtc_device *rtc) -{ -} - -static inline void rtc_proc_del_device(struct rtc_device *rtc) -{ -} - -#endif - -#ifdef CONFIG_RTC_INTF_SYSFS - -extern void __init rtc_sysfs_init(struct class *); -extern void rtc_sysfs_add_device(struct rtc_device *rtc); -extern void rtc_sysfs_del_device(struct rtc_device *rtc); - -#else - -static inline void rtc_sysfs_init(struct class *rtc) -{ -} - -static inline void rtc_sysfs_add_device(struct rtc_device *rtc) -{ -} - -static inline void rtc_sysfs_del_device(struct rtc_device *rtc) -{ -} - -#endif diff --git a/trunk/drivers/rtc/rtc-dev.c b/trunk/drivers/rtc/rtc-dev.c index f4e5f0040ff7..137330b8636b 100644 --- a/trunk/drivers/rtc/rtc-dev.c +++ b/trunk/drivers/rtc/rtc-dev.c @@ -13,8 +13,8 @@ #include #include -#include "rtc-core.h" +static struct class *rtc_dev_class; static dev_t rtc_devt; #define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */ @@ -32,9 +32,9 @@ static int rtc_dev_open(struct inode *inode, struct file *file) if (!(mutex_trylock(&rtc->char_lock))) return -EBUSY; - file->private_data = rtc; + file->private_data = &rtc->class_dev; - err = ops->open ? ops->open(rtc->dev.parent) : 0; + err = ops->open ? ops->open(rtc->class_dev.dev) : 0; if (err == 0) { spin_lock_irq(&rtc->irq_lock); rtc->irq_data = 0; @@ -61,7 +61,7 @@ static void rtc_uie_task(struct work_struct *work) int num = 0; int err; - err = rtc_read_time(rtc, &tm); + err = rtc_read_time(&rtc->class_dev, &tm); local_irq_disable(); spin_lock(&rtc->irq_lock); @@ -79,7 +79,7 @@ static void rtc_uie_task(struct work_struct *work) } spin_unlock(&rtc->irq_lock); if (num) - rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF); + rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); local_irq_enable(); } static void rtc_uie_timer(unsigned long data) @@ -121,7 +121,7 @@ static int set_uie(struct rtc_device *rtc) struct rtc_time tm; int err; - err = rtc_read_time(rtc, &tm); + err = rtc_read_time(&rtc->class_dev, &tm); if (err) return err; spin_lock_irq(&rtc->irq_lock); @@ -180,7 +180,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) if (ret == 0) { /* Check for any data updates */ if (rtc->ops->read_callback) - data = rtc->ops->read_callback(rtc->dev.parent, + data = rtc->ops->read_callback(rtc->class_dev.dev, data); if (sizeof(int) != sizeof(long) && @@ -210,7 +210,8 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; - struct rtc_device *rtc = file->private_data; + struct class_device *class_dev = file->private_data; + struct rtc_device *rtc = to_rtc_device(class_dev); const struct rtc_class_ops *ops = rtc->ops; struct rtc_time tm; struct rtc_wkalrm alarm; @@ -251,7 +252,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, /* try the driver's ioctl interface */ if (ops->ioctl) { - err = ops->ioctl(rtc->dev.parent, cmd, arg); + err = ops->ioctl(class_dev->dev, cmd, arg); if (err != -ENOIOCTLCMD) return err; } @@ -263,7 +264,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, switch (cmd) { case RTC_ALM_READ: - err = rtc_read_alarm(rtc, &alarm); + err = rtc_read_alarm(class_dev, &alarm); if (err < 0) return err; @@ -277,53 +278,17 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, alarm.enabled = 0; alarm.pending = 0; + alarm.time.tm_mday = -1; + alarm.time.tm_mon = -1; + alarm.time.tm_year = -1; alarm.time.tm_wday = -1; alarm.time.tm_yday = -1; alarm.time.tm_isdst = -1; - - /* RTC_ALM_SET alarms may be up to 24 hours in the future. - * Rather than expecting every RTC to implement "don't care" - * for day/month/year fields, just force the alarm to have - * the right values for those fields. - * - * RTC_WKALM_SET should be used instead. Not only does it - * eliminate the need for a separate RTC_AIE_ON call, it - * doesn't have the "alarm 23:59:59 in the future" race. - * - * NOTE: some legacy code may have used invalid fields as - * wildcards, exposing hardware "periodic alarm" capabilities. - * Not supported here. - */ - { - unsigned long now, then; - - err = rtc_read_time(rtc, &tm); - if (err < 0) - return err; - rtc_tm_to_time(&tm, &now); - - alarm.time.tm_mday = tm.tm_mday; - alarm.time.tm_mon = tm.tm_mon; - alarm.time.tm_year = tm.tm_year; - err = rtc_valid_tm(&alarm.time); - if (err < 0) - return err; - rtc_tm_to_time(&alarm.time, &then); - - /* alarm may need to wrap into tomorrow */ - if (then < now) { - rtc_time_to_tm(now + 24 * 60 * 60, &tm); - alarm.time.tm_mday = tm.tm_mday; - alarm.time.tm_mon = tm.tm_mon; - alarm.time.tm_year = tm.tm_year; - } - } - - err = rtc_set_alarm(rtc, &alarm); + err = rtc_set_alarm(class_dev, &alarm); break; case RTC_RD_TIME: - err = rtc_read_time(rtc, &tm); + err = rtc_read_time(class_dev, &tm); if (err < 0) return err; @@ -335,7 +300,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, if (copy_from_user(&tm, uarg, sizeof(tm))) return -EFAULT; - err = rtc_set_time(rtc, &tm); + err = rtc_set_time(class_dev, &tm); break; case RTC_IRQP_READ: @@ -345,7 +310,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, case RTC_IRQP_SET: if (ops->irq_set_freq) - err = rtc_irq_set_freq(rtc, rtc->irq_task, arg); + err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg); break; #if 0 @@ -371,11 +336,11 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, if (copy_from_user(&alarm, uarg, sizeof(alarm))) return -EFAULT; - err = rtc_set_alarm(rtc, &alarm); + err = rtc_set_alarm(class_dev, &alarm); break; case RTC_WKALM_RD: - err = rtc_read_alarm(rtc, &alarm); + err = rtc_read_alarm(class_dev, &alarm); if (err < 0) return err; @@ -407,7 +372,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file) clear_uie(rtc); #endif if (rtc->ops->release) - rtc->ops->release(rtc->dev.parent); + rtc->ops->release(rtc->class_dev.dev); mutex_unlock(&rtc->char_lock); return 0; @@ -432,18 +397,17 @@ static const struct file_operations rtc_dev_fops = { /* insertion/removal hooks */ -void rtc_dev_prepare(struct rtc_device *rtc) +static int rtc_dev_add_device(struct class_device *class_dev, + struct class_interface *class_intf) { - if (!rtc_devt) - return; + int err = 0; + struct rtc_device *rtc = to_rtc_device(class_dev); if (rtc->id >= RTC_DEV_MAX) { - pr_debug("%s: too many RTC devices\n", rtc->name); - return; + dev_err(class_dev->dev, "too many RTCs\n"); + return -EINVAL; } - rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); - mutex_init(&rtc->char_lock); spin_lock_init(&rtc->irq_lock); init_waitqueue_head(&rtc->irq_queue); @@ -454,36 +418,100 @@ void rtc_dev_prepare(struct rtc_device *rtc) cdev_init(&rtc->char_dev, &rtc_dev_fops); rtc->char_dev.owner = rtc->owner; -} -void rtc_dev_add_device(struct rtc_device *rtc) -{ - if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1)) - printk(KERN_WARNING "%s: failed to add char device %d:%d\n", - rtc->name, MAJOR(rtc_devt), rtc->id); - else - pr_debug("%s: dev (%d:%d)\n", rtc->name, + if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) { + dev_err(class_dev->dev, + "failed to add char device %d:%d\n", MAJOR(rtc_devt), rtc->id); + return -ENODEV; + } + + rtc->rtc_dev = class_device_create(rtc_dev_class, NULL, + MKDEV(MAJOR(rtc_devt), rtc->id), + class_dev->dev, "rtc%d", rtc->id); + if (IS_ERR(rtc->rtc_dev)) { + dev_err(class_dev->dev, "cannot create rtc_dev device\n"); + err = PTR_ERR(rtc->rtc_dev); + goto err_cdev_del; + } + + dev_dbg(class_dev->dev, "rtc intf: dev (%d:%d)\n", + MAJOR(rtc->rtc_dev->devt), + MINOR(rtc->rtc_dev->devt)); + + return 0; + +err_cdev_del: + + cdev_del(&rtc->char_dev); + return err; } -void rtc_dev_del_device(struct rtc_device *rtc) +static void rtc_dev_remove_device(struct class_device *class_dev, + struct class_interface *class_intf) { - if (rtc->dev.devt) + struct rtc_device *rtc = to_rtc_device(class_dev); + + if (rtc->rtc_dev) { + dev_dbg(class_dev->dev, "removing char %d:%d\n", + MAJOR(rtc->rtc_dev->devt), + MINOR(rtc->rtc_dev->devt)); + + class_device_unregister(rtc->rtc_dev); cdev_del(&rtc->char_dev); + } } -void __init rtc_dev_init(void) +/* interface registration */ + +static struct class_interface rtc_dev_interface = { + .add = &rtc_dev_add_device, + .remove = &rtc_dev_remove_device, +}; + +static int __init rtc_dev_init(void) { int err; + rtc_dev_class = class_create(THIS_MODULE, "rtc-dev"); + if (IS_ERR(rtc_dev_class)) + return PTR_ERR(rtc_dev_class); + err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); - if (err < 0) + if (err < 0) { printk(KERN_ERR "%s: failed to allocate char dev region\n", __FILE__); + goto err_destroy_class; + } + + err = rtc_interface_register(&rtc_dev_interface); + if (err < 0) { + printk(KERN_ERR "%s: failed to register the interface\n", + __FILE__); + goto err_unregister_chrdev; + } + + return 0; + +err_unregister_chrdev: + unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); + +err_destroy_class: + class_destroy(rtc_dev_class); + + return err; } -void __exit rtc_dev_exit(void) +static void __exit rtc_dev_exit(void) { - if (rtc_devt) - unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); + class_interface_unregister(&rtc_dev_interface); + class_destroy(rtc_dev_class); + unregister_chrdev_region(rtc_devt, RTC_DEV_MAX); } + +subsys_initcall(rtc_dev_init); +module_exit(rtc_dev_exit); + +MODULE_AUTHOR("Alessandro Zummo "); +MODULE_DESCRIPTION("RTC class dev interface"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-ds1553.c b/trunk/drivers/rtc/rtc-ds1553.c index afa64c7fa2e2..e27176c0e18f 100644 --- a/trunk/drivers/rtc/rtc-ds1553.c +++ b/trunk/drivers/rtc/rtc-ds1553.c @@ -203,7 +203,7 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id) events |= RTC_UF; else events |= RTC_AF; - rtc_update_irq(pdata->rtc, 1, events); + rtc_update_irq(&pdata->rtc->class_dev, 1, events); return IRQ_HANDLED; } diff --git a/trunk/drivers/rtc/rtc-lib.c b/trunk/drivers/rtc/rtc-lib.c index ba795a4db1e9..7bbc26a34bd2 100644 --- a/trunk/drivers/rtc/rtc-lib.c +++ b/trunk/drivers/rtc/rtc-lib.c @@ -117,4 +117,85 @@ int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) } EXPORT_SYMBOL(rtc_tm_to_time); + +/* Merge the valid (i.e. non-negative) fields of alarm into the current + * time. If the valid alarm fields are earlier than the equivalent + * fields in the time, carry one into the least significant invalid + * field, so that the alarm expiry is in the future. It assumes that the + * least significant invalid field is more significant than the most + * significant valid field, and that the seconds field is valid. + * + * This is used by alarms that take relative (rather than absolute) + * times, and/or have a simple binary second counter instead of + * day/hour/minute/sec registers. + */ +void rtc_merge_alarm(struct rtc_time *now, struct rtc_time *alarm) +{ + int *alarmp = &alarm->tm_sec; + int *timep = &now->tm_sec; + int carry_into, i; + + /* Ignore everything past the 6th element (tm_year). */ + for (i = 5; i > 0; i--) { + if (alarmp[i] < 0) + alarmp[i] = timep[i]; + else + break; + } + + /* No carry needed if all fields are valid. */ + if (i == 5) + return; + + for (carry_into = i + 1; i >= 0; i--) { + if (alarmp[i] < timep[i]) + break; + + if (alarmp[i] > timep[i]) + return; + } + + switch (carry_into) { + case 1: + alarm->tm_min++; + + if (alarm->tm_min < 60) + return; + + alarm->tm_min = 0; + /* fall-through */ + + case 2: + alarm->tm_hour++; + + if (alarm->tm_hour < 60) + return; + + alarm->tm_hour = 0; + /* fall-through */ + + case 3: + alarm->tm_mday++; + + if (alarm->tm_mday <= rtc_days_in_month[alarm->tm_mon]) + return; + + alarm->tm_mday = 1; + /* fall-through */ + + case 4: + alarm->tm_mon++; + + if (alarm->tm_mon <= 12) + return; + + alarm->tm_mon = 1; + /* fall-through */ + + case 5: + alarm->tm_year++; + } +} +EXPORT_SYMBOL(rtc_merge_alarm); + MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-max6900.c b/trunk/drivers/rtc/rtc-max6900.c deleted file mode 100644 index eee4ee5bb75a..000000000000 --- a/trunk/drivers/rtc/rtc-max6900.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - * rtc class driver for the Maxim MAX6900 chip - * - * Author: Dale Farnsworth - * - * based on previously existing rtc class drivers - * - * 2007 (c) MontaVista, Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ - -#include -#include -#include -#include -#include - -#define DRV_NAME "max6900" -#define DRV_VERSION "0.1" - -/* - * register indices - */ -#define MAX6900_REG_SC 0 /* seconds 00-59 */ -#define MAX6900_REG_MN 1 /* minutes 00-59 */ -#define MAX6900_REG_HR 2 /* hours 00-23 */ -#define MAX6900_REG_DT 3 /* day of month 00-31 */ -#define MAX6900_REG_MO 4 /* month 01-12 */ -#define MAX6900_REG_DW 5 /* day of week 1-7 */ -#define MAX6900_REG_YR 6 /* year 00-99 */ -#define MAX6900_REG_CT 7 /* control */ -#define MAX6900_REG_LEN 8 - -#define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */ - -/* - * register read/write commands - */ -#define MAX6900_REG_CONTROL_WRITE 0x8e -#define MAX6900_REG_BURST_READ 0xbf -#define MAX6900_REG_BURST_WRITE 0xbe -#define MAX6900_REG_RESERVED_READ 0x96 - -#define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */ - -#define MAX6900_I2C_ADDR 0xa0 - -static unsigned short normal_i2c[] = { - MAX6900_I2C_ADDR >> 1, - I2C_CLIENT_END -}; - -I2C_CLIENT_INSMOD; /* defines addr_data */ - -static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind); - -static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf) -{ - u8 reg_addr[1] = { MAX6900_REG_BURST_READ }; - struct i2c_msg msgs[2] = { - { - .addr = client->addr, - .flags = 0, /* write */ - .len = sizeof(reg_addr), - .buf = reg_addr - }, - { - .addr = client->addr, - .flags = I2C_M_RD, - .len = MAX6900_REG_LEN, - .buf = buf - } - }; - int rc; - - rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (rc != ARRAY_SIZE(msgs)) { - dev_err(&client->dev, "%s: register read failed\n", - __FUNCTION__); - return -EIO; - } - return 0; -} - -static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf) -{ - u8 i2c_buf[MAX6900_REG_LEN + 1] = { MAX6900_REG_BURST_WRITE }; - struct i2c_msg msgs[1] = { - { - .addr = client->addr, - .flags = 0, /* write */ - .len = MAX6900_REG_LEN + 1, - .buf = i2c_buf - } - }; - int rc; - - memcpy(&i2c_buf[1], buf, MAX6900_REG_LEN); - - rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); - if (rc != ARRAY_SIZE(msgs)) { - dev_err(&client->dev, "%s: register write failed\n", - __FUNCTION__); - return -EIO; - } - msleep(MAX6900_IDLE_TIME_AFTER_WRITE); - return 0; -} - -static int max6900_i2c_validate_client(struct i2c_client *client) -{ - u8 regs[MAX6900_REG_LEN]; - u8 zero_mask[MAX6900_REG_LEN] = { - 0x80, /* seconds */ - 0x80, /* minutes */ - 0x40, /* hours */ - 0xc0, /* day of month */ - 0xe0, /* month */ - 0xf8, /* day of week */ - 0x00, /* year */ - 0x7f, /* control */ - }; - int i; - int rc; - int reserved; - - reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ); - if (reserved != 0x07) - return -ENODEV; - - rc = max6900_i2c_read_regs(client, regs); - if (rc < 0) - return rc; - - for (i = 0; i < MAX6900_REG_LEN; ++i) { - if (regs[i] & zero_mask[i]) - return -ENODEV; - } - - return 0; -} - -static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm) -{ - int rc; - u8 regs[MAX6900_REG_LEN]; - - rc = max6900_i2c_read_regs(client, regs); - if (rc < 0) - return rc; - - tm->tm_sec = BCD2BIN(regs[MAX6900_REG_SC]); - tm->tm_min = BCD2BIN(regs[MAX6900_REG_MN]); - tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f); - tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]); - tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1; - tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + 100; - tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]); - - return 0; -} - -static int max6900_i2c_clear_write_protect(struct i2c_client *client) -{ - int rc; - rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0); - if (rc < 0) { - dev_err(&client->dev, "%s: control register write failed\n", - __FUNCTION__); - return -EIO; - } - return 0; -} - -static int max6900_i2c_set_time(struct i2c_client *client, - struct rtc_time const *tm) -{ - u8 regs[MAX6900_REG_LEN]; - int rc; - - rc = max6900_i2c_clear_write_protect(client); - if (rc < 0) - return rc; - - regs[MAX6900_REG_SC] = BIN2BCD(tm->tm_sec); - regs[MAX6900_REG_MN] = BIN2BCD(tm->tm_min); - regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour); - regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday); - regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1); - regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year - 100); - regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday); - regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP; /* set write protect */ - - rc = max6900_i2c_write_regs(client, regs); - if (rc < 0) - return rc; - - return 0; -} - -static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - return max6900_i2c_read_time(to_i2c_client(dev), tm); -} - -static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return max6900_i2c_set_time(to_i2c_client(dev), tm); -} - -static int max6900_attach_adapter(struct i2c_adapter *adapter) -{ - return i2c_probe(adapter, &addr_data, max6900_probe); -} - -static int max6900_detach_client(struct i2c_client *client) -{ - struct rtc_device *const rtc = i2c_get_clientdata(client); - - if (rtc) - rtc_device_unregister(rtc); - - return i2c_detach_client(client); -} - -static struct i2c_driver max6900_driver = { - .driver = { - .name = DRV_NAME, - }, - .id = I2C_DRIVERID_MAX6900, - .attach_adapter = max6900_attach_adapter, - .detach_client = max6900_detach_client, -}; - -static const struct rtc_class_ops max6900_rtc_ops = { - .read_time = max6900_rtc_read_time, - .set_time = max6900_rtc_set_time, -}; - -static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind) -{ - int rc = 0; - struct i2c_client *client = NULL; - struct rtc_device *rtc = NULL; - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - rc = -ENODEV; - goto failout; - } - - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) { - rc = -ENOMEM; - goto failout; - } - - client->addr = addr; - client->adapter = adapter; - client->driver = &max6900_driver; - strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE); - - if (kind < 0) { - rc = max6900_i2c_validate_client(client); - if (rc < 0) - goto failout; - } - - rc = i2c_attach_client(client); - if (rc < 0) - goto failout; - - dev_info(&client->dev, - "chip found, driver version " DRV_VERSION "\n"); - - rtc = rtc_device_register(max6900_driver.driver.name, - &client->dev, - &max6900_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - rc = PTR_ERR(rtc); - goto failout_detach; - } - - i2c_set_clientdata(client, rtc); - - return 0; - -failout_detach: - i2c_detach_client(client); -failout: - kfree(client); - return rc; -} - -static int __init max6900_init(void) -{ - return i2c_add_driver(&max6900_driver); -} - -static void __exit max6900_exit(void) -{ - i2c_del_driver(&max6900_driver); -} - -MODULE_DESCRIPTION("Maxim MAX6900 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - -module_init(max6900_init); -module_exit(max6900_exit); diff --git a/trunk/drivers/rtc/rtc-omap.c b/trunk/drivers/rtc/rtc-omap.c index 60a8a4bb8bd2..9de8d67f4f8d 100644 --- a/trunk/drivers/rtc/rtc-omap.c +++ b/trunk/drivers/rtc/rtc-omap.c @@ -124,7 +124,7 @@ static void rtc_wait_not_busy(void) /* now we have ~15 usec to read/write various registers */ } -static irqreturn_t rtc_irq(int irq, void *rtc) +static irqreturn_t rtc_irq(int irq, void *class_dev) { unsigned long events = 0; u8 irq_data; @@ -141,7 +141,7 @@ static irqreturn_t rtc_irq(int irq, void *rtc) if (irq_data & OMAP_RTC_STATUS_1S_EVENT) events |= RTC_IRQF | RTC_UF; - rtc_update_irq(rtc, 1, events); + rtc_update_irq(class_dev, 1, events); return IRQ_HANDLED; } @@ -289,6 +289,34 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) { u8 reg; + /* Much userspace code uses RTC_ALM_SET, thus "don't care" for + * day/month/year specifies alarms up to 24 hours in the future. + * So we need to handle that ... but let's ignore the "don't care" + * values for hours/minutes/seconds. + */ + if (alm->time.tm_mday <= 0 + && alm->time.tm_mon < 0 + && alm->time.tm_year < 0) { + struct rtc_time tm; + unsigned long now, then; + + omap_rtc_read_time(dev, &tm); + rtc_tm_to_time(&tm, &now); + + alm->time.tm_mday = tm.tm_mday; + alm->time.tm_mon = tm.tm_mon; + alm->time.tm_year = tm.tm_year; + rtc_tm_to_time(&alm->time, &then); + + /* sometimes the alarm wraps into tomorrow */ + if (then < now) { + rtc_time_to_tm(now + 24 * 60 * 60, &tm); + alm->time.tm_mday = tm.tm_mday; + alm->time.tm_mon = tm.tm_mon; + alm->time.tm_year = tm.tm_year; + } + } + if (tm2bcd(&alm->time) < 0) return -EINVAL; @@ -371,7 +399,7 @@ static int __devinit omap_rtc_probe(struct platform_device *pdev) goto fail; } platform_set_drvdata(pdev, rtc); - dev_set_devdata(&rtc->dev, mem); + class_set_devdata(&rtc->class_dev, mem); /* clear pending irqs, and set 1/second periodic, * which we'll use instead of update irqs @@ -390,13 +418,13 @@ static int __devinit omap_rtc_probe(struct platform_device *pdev) /* handle periodic and alarm irqs */ if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, - rtc->dev.bus_id, rtc)) { + rtc->class_dev.class_id, &rtc->class_dev)) { pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_timer); goto fail0; } if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, - rtc->dev.bus_id, rtc)) { + rtc->class_dev.class_id, &rtc->class_dev)) { pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", pdev->name, omap_rtc_alarm); goto fail1; @@ -453,17 +481,26 @@ static int __devexit omap_rtc_remove(struct platform_device *pdev) free_irq(omap_rtc_timer, rtc); free_irq(omap_rtc_alarm, rtc); - release_resource(dev_get_devdata(&rtc->dev)); + release_resource(class_get_devdata(&rtc->class_dev)); rtc_device_unregister(rtc); return 0; } #ifdef CONFIG_PM +static struct timespec rtc_delta; static u8 irqstat; static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) { + struct rtc_time rtc_tm; + struct timespec time; + + time.tv_nsec = 0; + omap_rtc_read_time(NULL, &rtc_tm); + rtc_tm_to_time(&rtc_tm, &time.tv_sec); + + save_time_delta(&rtc_delta, &time); irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); /* FIXME the RTC alarm is not currently acting as a wakeup event @@ -480,6 +517,14 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) static int omap_rtc_resume(struct platform_device *pdev) { + struct rtc_time rtc_tm; + struct timespec time; + + time.tv_nsec = 0; + omap_rtc_read_time(NULL, &rtc_tm); + rtc_tm_to_time(&rtc_tm, &time.tv_sec); + + restore_time_delta(&rtc_delta, &time); if (device_may_wakeup(&pdev->dev)) disable_irq_wake(omap_rtc_alarm); else diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c index e4bf68ca96f7..f13daa9fecaa 100644 --- a/trunk/drivers/rtc/rtc-pl031.c +++ b/trunk/drivers/rtc/rtc-pl031.c @@ -51,7 +51,7 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id) { struct rtc_device *rtc = dev_id; - rtc_update_irq(rtc, 1, RTC_AF); + rtc_update_irq(&rtc->class_dev, 1, RTC_AF); return IRQ_HANDLED; } diff --git a/trunk/drivers/rtc/rtc-proc.c b/trunk/drivers/rtc/rtc-proc.c index 8d300e6d0d9e..1bd624fc685c 100644 --- a/trunk/drivers/rtc/rtc-proc.c +++ b/trunk/drivers/rtc/rtc-proc.c @@ -16,18 +16,18 @@ #include #include -#include "rtc-core.h" - +static struct class_device *rtc_dev = NULL; +static DEFINE_MUTEX(rtc_lock); static int rtc_proc_show(struct seq_file *seq, void *offset) { int err; - struct rtc_device *rtc = seq->private; - const struct rtc_class_ops *ops = rtc->ops; + struct class_device *class_dev = seq->private; + const struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; struct rtc_wkalrm alrm; struct rtc_time tm; - err = rtc_read_time(rtc, &tm); + err = rtc_read_time(class_dev, &tm); if (err == 0) { seq_printf(seq, "rtc_time\t: %02d:%02d:%02d\n" @@ -36,7 +36,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); } - err = rtc_read_alarm(rtc, &alrm); + err = rtc_read_alarm(class_dev, &alrm); if (err == 0) { seq_printf(seq, "alrm_time\t: "); if ((unsigned int)alrm.time.tm_hour <= 24) @@ -74,19 +74,19 @@ static int rtc_proc_show(struct seq_file *seq, void *offset) seq_printf(seq, "24hr\t\t: yes\n"); if (ops->proc) - ops->proc(rtc->dev.parent, seq); + ops->proc(class_dev->dev, seq); return 0; } static int rtc_proc_open(struct inode *inode, struct file *file) { - struct rtc_device *rtc = PDE(inode)->data; + struct class_device *class_dev = PDE(inode)->data; if (!try_module_get(THIS_MODULE)) return -ENODEV; - return single_open(file, rtc_proc_show, rtc); + return single_open(file, rtc_proc_show, class_dev); } static int rtc_proc_release(struct inode *inode, struct file *file) @@ -103,22 +103,62 @@ static const struct file_operations rtc_proc_fops = { .release = rtc_proc_release, }; -void rtc_proc_add_device(struct rtc_device *rtc) +static int rtc_proc_add_device(struct class_device *class_dev, + struct class_interface *class_intf) { - if (rtc->id == 0) { + mutex_lock(&rtc_lock); + if (rtc_dev == NULL) { struct proc_dir_entry *ent; + rtc_dev = class_dev; + ent = create_proc_entry("driver/rtc", 0, NULL); if (ent) { + struct rtc_device *rtc = to_rtc_device(class_dev); + ent->proc_fops = &rtc_proc_fops; ent->owner = rtc->owner; - ent->data = rtc; + ent->data = class_dev; + + dev_dbg(class_dev->dev, "rtc intf: proc\n"); } + else + rtc_dev = NULL; } + mutex_unlock(&rtc_lock); + + return 0; } -void rtc_proc_del_device(struct rtc_device *rtc) +static void rtc_proc_remove_device(struct class_device *class_dev, + struct class_interface *class_intf) { - if (rtc->id == 0) + mutex_lock(&rtc_lock); + if (rtc_dev == class_dev) { remove_proc_entry("driver/rtc", NULL); + rtc_dev = NULL; + } + mutex_unlock(&rtc_lock); +} + +static struct class_interface rtc_proc_interface = { + .add = &rtc_proc_add_device, + .remove = &rtc_proc_remove_device, +}; + +static int __init rtc_proc_init(void) +{ + return rtc_interface_register(&rtc_proc_interface); } + +static void __exit rtc_proc_exit(void) +{ + class_interface_unregister(&rtc_proc_interface); +} + +subsys_initcall(rtc_proc_init); +module_exit(rtc_proc_exit); + +MODULE_AUTHOR("Alessandro Zummo "); +MODULE_DESCRIPTION("RTC class proc interface"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-rs5c313.c b/trunk/drivers/rtc/rtc-rs5c313.c deleted file mode 100644 index 9d6de371495b..000000000000 --- a/trunk/drivers/rtc/rtc-rs5c313.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Ricoh RS5C313 RTC device/driver - * Copyright (C) 2007 Nobuhiro Iwamatsu - * - * 2005-09-19 modifed by kogiidena - * - * Based on the old drivers/char/rs5c313_rtc.c by: - * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka - * - * Based on code written by Paul Gortmaker. - * Copyright (C) 1996 Paul Gortmaker - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Based on other minimal char device drivers, like Alan's - * watchdog, Ted's random, etc. etc. - * - * 1.07 Paul Gortmaker. - * 1.08 Miquel van Smoorenburg: disallow certain things on the - * DEC Alpha as the CMOS clock is also used for other things. - * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup. - * 1.09a Pete Zaitcev: Sun SPARC - * 1.09b Jeff Garzik: Modularize, init cleanup - * 1.09c Jeff Garzik: SMP cleanup - * 1.10 Paul Barton-Davis: add support for async I/O - * 1.10a Andrea Arcangeli: Alpha updates - * 1.10b Andrew Morton: SMP lock fix - * 1.10c Cesar Barros: SMP locking fixes and cleanup - * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit - * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness. - * 1.11 Takashi Iwai: Kernel access functions - * rtc_register/rtc_unregister/rtc_control - * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init - * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer - * CONFIG_HPET_EMULATE_RTC - * 1.13 Nobuhiro Iwamatsu: Updata driver. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "rs5c313" -#define DRV_VERSION "1.13" - -#ifdef CONFIG_SH_LANDISK -/*****************************************************/ -/* LANDISK dependence part of RS5C313 */ -/*****************************************************/ - -#define SCSMR1 0xFFE00000 -#define SCSCR1 0xFFE00008 -#define SCSMR1_CA 0x80 -#define SCSCR1_CKE 0x03 -#define SCSPTR1 0xFFE0001C -#define SCSPTR1_EIO 0x80 -#define SCSPTR1_SPB1IO 0x08 -#define SCSPTR1_SPB1DT 0x04 -#define SCSPTR1_SPB0IO 0x02 -#define SCSPTR1_SPB0DT 0x01 - -#define SDA_OEN SCSPTR1_SPB1IO -#define SDA SCSPTR1_SPB1DT -#define SCL_OEN SCSPTR1_SPB0IO -#define SCL SCSPTR1_SPB0DT - -/* RICOH RS5C313 CE port */ -#define RS5C313_CE 0xB0000003 - -/* RICOH RS5C313 CE port bit */ -#define RS5C313_CE_RTCCE 0x02 - -/* SCSPTR1 data */ -unsigned char scsptr1_data; - -#define RS5C313_CEENABLE ctrl_outb(RS5C313_CE_RTCCE, RS5C313_CE); -#define RS5C313_CEDISABLE ctrl_outb(0x00, RS5C313_CE) -#define RS5C313_MISCOP ctrl_outb(0x02, 0xB0000008) - -static void rs5c313_init_port(void) -{ - /* Set SCK as I/O port and Initialize SCSPTR1 data & I/O port. */ - ctrl_outb(ctrl_inb(SCSMR1) & ~SCSMR1_CA, SCSMR1); - ctrl_outb(ctrl_inb(SCSCR1) & ~SCSCR1_CKE, SCSCR1); - - /* And Initialize SCL for RS5C313 clock */ - scsptr1_data = ctrl_inb(SCSPTR1) | SCL; /* SCL:H */ - ctrl_outb(scsptr1_data, SCSPTR1); - scsptr1_data = ctrl_inb(SCSPTR1) | SCL_OEN; /* SCL output enable */ - ctrl_outb(scsptr1_data, SCSPTR1); - RS5C313_CEDISABLE; /* CE:L */ -} - -static void rs5c313_write_data(unsigned char data) -{ - int i; - - for (i = 0; i < 8; i++) { - /* SDA:Write Data */ - scsptr1_data = (scsptr1_data & ~SDA) | - ((((0x80 >> i) & data) >> (7 - i)) << 2); - ctrl_outb(scsptr1_data, SCSPTR1); - if (i == 0) { - scsptr1_data |= SDA_OEN; /* SDA:output enable */ - ctrl_outb(scsptr1_data, SCSPTR1); - } - ndelay(700); - scsptr1_data &= ~SCL; /* SCL:L */ - ctrl_outb(scsptr1_data, SCSPTR1); - ndelay(700); - scsptr1_data |= SCL; /* SCL:H */ - ctrl_outb(scsptr1_data, SCSPTR1); - } - - scsptr1_data &= ~SDA_OEN; /* SDA:output disable */ - ctrl_outb(scsptr1_data, SCSPTR1); -} - -static unsigned char rs5c313_read_data(void) -{ - int i; - unsigned char data; - - for (i = 0; i < 8; i++) { - ndelay(700); - /* SDA:Read Data */ - data |= ((ctrl_inb(SCSPTR1) & SDA) >> 2) << (7 - i); - scsptr1_data &= ~SCL; /* SCL:L */ - ctrl_outb(scsptr1_data, SCSPTR1); - ndelay(700); - scsptr1_data |= SCL; /* SCL:H */ - ctrl_outb(scsptr1_data, SCSPTR1); - } - return data & 0x0F; -} - -#endif /* CONFIG_SH_LANDISK */ - -/*****************************************************/ -/* machine independence part of RS5C313 */ -/*****************************************************/ - -/* RICOH RS5C313 address */ -#define RS5C313_ADDR_SEC 0x00 -#define RS5C313_ADDR_SEC10 0x01 -#define RS5C313_ADDR_MIN 0x02 -#define RS5C313_ADDR_MIN10 0x03 -#define RS5C313_ADDR_HOUR 0x04 -#define RS5C313_ADDR_HOUR10 0x05 -#define RS5C313_ADDR_WEEK 0x06 -#define RS5C313_ADDR_INTINTVREG 0x07 -#define RS5C313_ADDR_DAY 0x08 -#define RS5C313_ADDR_DAY10 0x09 -#define RS5C313_ADDR_MON 0x0A -#define RS5C313_ADDR_MON10 0x0B -#define RS5C313_ADDR_YEAR 0x0C -#define RS5C313_ADDR_YEAR10 0x0D -#define RS5C313_ADDR_CNTREG 0x0E -#define RS5C313_ADDR_TESTREG 0x0F - -/* RICOH RS5C313 control register */ -#define RS5C313_CNTREG_ADJ_BSY 0x01 -#define RS5C313_CNTREG_WTEN_XSTP 0x02 -#define RS5C313_CNTREG_12_24 0x04 -#define RS5C313_CNTREG_CTFG 0x08 - -/* RICOH RS5C313 test register */ -#define RS5C313_TESTREG_TEST 0x01 - -/* RICOH RS5C313 control bit */ -#define RS5C313_CNTBIT_READ 0x40 -#define RS5C313_CNTBIT_AD 0x20 -#define RS5C313_CNTBIT_DT 0x10 - -static unsigned char rs5c313_read_reg(unsigned char addr) -{ - - rs5c313_write_data(addr | RS5C313_CNTBIT_READ | RS5C313_CNTBIT_AD); - return rs5c313_read_data(); -} - -static void rs5c313_write_reg(unsigned char addr, unsigned char data) -{ - data &= 0x0f; - rs5c313_write_data(addr | RS5C313_CNTBIT_AD); - rs5c313_write_data(data | RS5C313_CNTBIT_DT); - return; -} - -static inline unsigned char rs5c313_read_cntreg(unsigned char addr) -{ - return rs5c313_read_reg(RS5C313_ADDR_CNTREG); -} - -static inline void rs5c313_write_cntreg(unsigned char data) -{ - rs5c313_write_reg(RS5C313_ADDR_CNTREG, data); -} - -static inline void rs5c313_write_intintvreg(unsigned char data) -{ - rs5c313_write_reg(RS5C313_ADDR_INTINTVREG, data); -} - -static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - int data; - - while (1) { - RS5C313_CEENABLE; /* CE:H */ - - /* Initialize control reg. 24 hour */ - rs5c313_write_cntreg(0x04); - - if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)) - break; - - RS5C313_CEDISABLE; - ndelay(700); /* CE:L */ - - } - - data = rs5c313_read_reg(RS5C313_ADDR_SEC); - data |= (rs5c313_read_reg(RS5C313_ADDR_SEC10) << 4); - tm->tm_sec = BCD2BIN(data); - - data = rs5c313_read_reg(RS5C313_ADDR_MIN); - data |= (rs5c313_read_reg(RS5C313_ADDR_MIN10) << 4); - tm->tm_min = BCD2BIN(data); - - data = rs5c313_read_reg(RS5C313_ADDR_HOUR); - data |= (rs5c313_read_reg(RS5C313_ADDR_HOUR10) << 4); - tm->tm_hour = BCD2BIN(data); - - data = rs5c313_read_reg(RS5C313_ADDR_DAY); - data |= (rs5c313_read_reg(RS5C313_ADDR_DAY10) << 4); - tm->tm_mday = BCD2BIN(data); - - data = rs5c313_read_reg(RS5C313_ADDR_MON); - data |= (rs5c313_read_reg(RS5C313_ADDR_MON10) << 4); - tm->tm_mon = BCD2BIN(data) - 1; - - data = rs5c313_read_reg(RS5C313_ADDR_YEAR); - data |= (rs5c313_read_reg(RS5C313_ADDR_YEAR10) << 4); - tm->tm_year = BCD2BIN(data); - - if (tm->tm_year < 70) - tm->tm_year += 100; - - data = rs5c313_read_reg(RS5C313_ADDR_WEEK); - tm->tm_wday = BCD2BIN(data); - - RS5C313_CEDISABLE; - ndelay(700); /* CE:L */ - - return 0; -} - -static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - int data; - - /* busy check. */ - while (1) { - RS5C313_CEENABLE; /* CE:H */ - - /* Initiatlize control reg. 24 hour */ - rs5c313_write_cntreg(0x04); - - if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)) - break; - RS5C313_MISCOP; - RS5C313_CEDISABLE; - ndelay(700); /* CE:L */ - } - - data = BIN2BCD(tm->tm_sec); - rs5c313_write_reg(RS5C313_ADDR_SEC, data); - rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4)); - - data = BIN2BCD(tm->tm_min); - rs5c313_write_reg(RS5C313_ADDR_MIN, data ); - rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4)); - - data = BIN2BCD(tm->tm_hour); - rs5c313_write_reg(RS5C313_ADDR_HOUR, data); - rs5c313_write_reg(RS5C313_ADDR_HOUR10, (data >> 4)); - - data = BIN2BCD(tm->tm_mday); - rs5c313_write_reg(RS5C313_ADDR_DAY, data); - rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4)); - - data = BIN2BCD(tm->tm_mon + 1); - rs5c313_write_reg(RS5C313_ADDR_MON, data); - rs5c313_write_reg(RS5C313_ADDR_MON10, (data >> 4)); - - data = BIN2BCD(tm->tm_year % 100); - rs5c313_write_reg(RS5C313_ADDR_YEAR, data); - rs5c313_write_reg(RS5C313_ADDR_YEAR10, (data >> 4)); - - data = BIN2BCD(tm->tm_wday); - rs5c313_write_reg(RS5C313_ADDR_WEEK, data); - - RS5C313_CEDISABLE; /* CE:H */ - ndelay(700); - - return 0; -} - -static void rs5c313_check_xstp_bit(void) -{ - struct rtc_time tm; - - RS5C313_CEENABLE; /* CE:H */ - if (rs5c313_read_cntreg() & RS5C313_CNTREG_WTEN_XSTP) { - /* INT interval reg. OFF */ - rs5c313_write_intintvreg(0x00); - /* Initialize control reg. 24 hour & adjust */ - rs5c313_write_cntreg(0x07); - - /* busy check. */ - while (rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY) - RS5C313_MISCOP; - - memset(&tm, 0, sizeof(struct rtc_time)); - tm.tm_mday = 1; - tm.tm_mon = 1; - - rs5c313_rtc_set_time(NULL, &tm); - printk(KERN_ERR "RICHO RS5C313: invalid value, resetting to " - "1 Jan 2000\n"); - } - RS5C313_CEDISABLE; - ndelay(700); /* CE:L */ -} - -static const struct rtc_class_ops rs5c313_rtc_ops = { - .read_time = rs5c313_rtc_read_time, - .set_time = rs5c313_rtc_set_time, -}; - -static int rs5c313_rtc_probe(struct platform_device *pdev) -{ - struct rtc_device *rtc = rtc_device_register("rs5c313", &pdev->dev, - &rs5c313_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) - return PTR_ERR(rtc); - - platform_set_drvdata(pdev, rtc); - - return err; -} - -static int __devexit rs5c313_rtc_remove(struct platform_device *pdev) -{ - struct rtc_device *rtc = platform_get_drvdata( pdev ); - - rtc_device_unregister(rtc); - - return 0; -} - -static struct platform_driver rs5c313_rtc_platform_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = rs5c313_rtc_probe, - .remove = __devexit_p( rs5c313_rtc_remove ), -}; - -static int __init rs5c313_rtc_init(void) -{ - int err; - - err = platform_driver_register(&rs5c313_rtc_platform_driver); - if (err) - return err; - - rs5c313_init_port(); - rs5c313_check_xstp_bit(); - - return 0; -} - -static void __exit rs5c313_rtc_exit(void) -{ - platform_driver_unregister( &rs5c313_rtc_platform_driver ); -} - -module_init(rs5c313_rtc_init); -module_exit(rs5c313_rtc_exit); - -MODULE_VERSION(DRV_VERSION); -MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu "); -MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-s3c.c b/trunk/drivers/rtc/rtc-s3c.c index 54b613053468..9a79a24a7487 100644 --- a/trunk/drivers/rtc/rtc-s3c.c +++ b/trunk/drivers/rtc/rtc-s3c.c @@ -50,7 +50,7 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id) { struct rtc_device *rdev = id; - rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF); + rtc_update_irq(&rdev->class_dev, 1, RTC_AF | RTC_IRQF); return IRQ_HANDLED; } @@ -58,7 +58,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id) { struct rtc_device *rdev = id; - rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF); + rtc_update_irq(&rdev->class_dev, tick_count++, RTC_PF | RTC_IRQF); return IRQ_HANDLED; } @@ -548,15 +548,37 @@ static int ticnt_save; static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) { + struct rtc_time tm; + struct timespec time; + + time.tv_nsec = 0; + /* save TICNT for anyone using periodic interrupts */ + ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); + + /* calculate time delta for suspend */ + + s3c_rtc_gettime(&pdev->dev, &tm); + rtc_tm_to_time(&tm, &time.tv_sec); + save_time_delta(&s3c_rtc_delta, &time); s3c_rtc_enable(pdev, 0); + return 0; } static int s3c_rtc_resume(struct platform_device *pdev) { + struct rtc_time tm; + struct timespec time; + + time.tv_nsec = 0; + s3c_rtc_enable(pdev, 1); + s3c_rtc_gettime(&pdev->dev, &tm); + rtc_tm_to_time(&tm, &time.tv_sec); + restore_time_delta(&s3c_rtc_delta, &time); + writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); return 0; } diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index 0918b787c4dd..677bae820dc3 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -93,7 +93,7 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id) if (rtsr & RTSR_HZ) events |= RTC_UF | RTC_IRQF; - rtc_update_irq(rtc, 1, events); + rtc_update_irq(&rtc->class_dev, 1, events); if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) rtc_update_alarm(&rtc_alarm); @@ -119,7 +119,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id) */ OSSR = OSSR_M1; /* clear match on timer1 */ - rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF); + rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF); if (rtc_timer1_count == 1) rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); diff --git a/trunk/drivers/rtc/rtc-sh.c b/trunk/drivers/rtc/rtc-sh.c index 6abf4811958c..198b9f22fbff 100644 --- a/trunk/drivers/rtc/rtc-sh.c +++ b/trunk/drivers/rtc/rtc-sh.c @@ -104,7 +104,7 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) writeb(tmp, rtc->regbase + RCR1); - rtc_update_irq(&rtc->rtc_dev, 1, events); + rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events); spin_unlock(&rtc->lock); @@ -139,7 +139,7 @@ static irqreturn_t sh_rtc_alarm(int irq, void *dev_id) rtc->rearm_aie = 1; - rtc_update_irq(&rtc->rtc_dev, 1, events); + rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events); } spin_unlock(&rtc->lock); @@ -153,7 +153,7 @@ static irqreturn_t sh_rtc_periodic(int irq, void *dev_id) spin_lock(&rtc->lock); - rtc_update_irq(&rtc->rtc_dev, 1, RTC_PF | RTC_IRQF); + rtc_update_irq(&rtc->rtc_dev->class_dev, 1, RTC_PF | RTC_IRQF); spin_unlock(&rtc->lock); diff --git a/trunk/drivers/rtc/rtc-sysfs.c b/trunk/drivers/rtc/rtc-sysfs.c index 69df94b44841..899ab8c514fa 100644 --- a/trunk/drivers/rtc/rtc-sysfs.c +++ b/trunk/drivers/rtc/rtc-sysfs.c @@ -12,26 +12,20 @@ #include #include -#include "rtc-core.h" - - /* device attributes */ -static ssize_t -rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t rtc_sysfs_show_name(struct class_device *dev, char *buf) { return sprintf(buf, "%s\n", to_rtc_device(dev)->name); } +static CLASS_DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL); -static ssize_t -rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf) { ssize_t retval; struct rtc_time tm; - retval = rtc_read_time(to_rtc_device(dev), &tm); + retval = rtc_read_time(dev, &tm); if (retval == 0) { retval = sprintf(buf, "%04d-%02d-%02d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); @@ -39,15 +33,14 @@ rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr, return retval; } +static CLASS_DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL); -static ssize_t -rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf) { ssize_t retval; struct rtc_time tm; - retval = rtc_read_time(to_rtc_device(dev), &tm); + retval = rtc_read_time(dev, &tm); if (retval == 0) { retval = sprintf(buf, "%02d:%02d:%02d\n", tm.tm_hour, tm.tm_min, tm.tm_sec); @@ -55,15 +48,14 @@ rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr, return retval; } +static CLASS_DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL); -static ssize_t -rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf) { ssize_t retval; struct rtc_time tm; - retval = rtc_read_time(to_rtc_device(dev), &tm); + retval = rtc_read_time(dev, &tm); if (retval == 0) { unsigned long time; rtc_tm_to_time(&tm, &time); @@ -72,18 +64,23 @@ rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr, return retval; } +static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL); + +static struct attribute *rtc_attrs[] = { + &class_device_attr_name.attr, + &class_device_attr_date.attr, + &class_device_attr_time.attr, + &class_device_attr_since_epoch.attr, + NULL, +}; -static struct device_attribute rtc_attrs[] = { - __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL), - __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL), - __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL), - __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL), - { }, +static struct attribute_group rtc_attr_group = { + .attrs = rtc_attrs, }; + static ssize_t -rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, - char *buf) +rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf) { ssize_t retval; unsigned long alarm; @@ -97,7 +94,7 @@ rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, * REVISIT maybe we should require RTC implementations to * disable the RTC alarm after it triggers, for uniformity. */ - retval = rtc_read_alarm(to_rtc_device(dev), &alm); + retval = rtc_read_alarm(dev, &alm); if (retval == 0 && alm.enabled) { rtc_tm_to_time(&alm.time, &alarm); retval = sprintf(buf, "%lu\n", alarm); @@ -107,18 +104,16 @@ rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, } static ssize_t -rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, - const char *buf, size_t n) +rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n) { ssize_t retval; unsigned long now, alarm; struct rtc_wkalrm alm; - struct rtc_device *rtc = to_rtc_device(dev); /* Only request alarms that trigger in the future. Disable them * by writing another time, e.g. 0 meaning Jan 1 1970 UTC. */ - retval = rtc_read_time(rtc, &alm.time); + retval = rtc_read_time(dev, &alm.time); if (retval < 0) return retval; rtc_tm_to_time(&alm.time, &now); @@ -129,7 +124,7 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, * entirely prevent that here, without even the minimal * locking from the /dev/rtcN api. */ - retval = rtc_read_alarm(rtc, &alm); + retval = rtc_read_alarm(dev, &alm); if (retval < 0) return retval; if (alm.enabled) @@ -146,10 +141,10 @@ rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr, } rtc_time_to_tm(alarm, &alm.time); - retval = rtc_set_alarm(rtc, &alm); + retval = rtc_set_alarm(dev, &alm); return (retval < 0) ? retval : n; } -static DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, +static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm); @@ -158,37 +153,71 @@ static DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, * suspend-to-disk. So: no attribute unless that side effect is possible. * (Userspace may disable that mechanism later.) */ -static inline int rtc_does_wakealarm(struct rtc_device *rtc) +static inline int rtc_does_wakealarm(struct class_device *class_dev) { - if (!device_can_wakeup(rtc->dev.parent)) + struct rtc_device *rtc; + + if (!device_can_wakeup(class_dev->dev)) return 0; + rtc = to_rtc_device(class_dev); return rtc->ops->set_alarm != NULL; } -void rtc_sysfs_add_device(struct rtc_device *rtc) +static int rtc_sysfs_add_device(struct class_device *class_dev, + struct class_interface *class_intf) { int err; - /* not all RTCs support both alarms and wakeup */ - if (!rtc_does_wakealarm(rtc)) - return; + dev_dbg(class_dev->dev, "rtc intf: sysfs\n"); - err = device_create_file(&rtc->dev, &dev_attr_wakealarm); + err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group); if (err) - dev_err(rtc->dev.parent, "failed to create " - "alarm attribute, %d", - err); + dev_err(class_dev->dev, "failed to create %s\n", + "sysfs attributes"); + else if (rtc_does_wakealarm(class_dev)) { + /* not all RTCs support both alarms and wakeup */ + err = class_device_create_file(class_dev, + &class_device_attr_wakealarm); + if (err) { + dev_err(class_dev->dev, "failed to create %s\n", + "alarm attribute"); + sysfs_remove_group(&class_dev->kobj, &rtc_attr_group); + } + } + + return err; } -void rtc_sysfs_del_device(struct rtc_device *rtc) +static void rtc_sysfs_remove_device(struct class_device *class_dev, + struct class_interface *class_intf) { - /* REVISIT did we add it successfully? */ - if (rtc_does_wakealarm(rtc)) - device_remove_file(&rtc->dev, &dev_attr_wakealarm); + if (rtc_does_wakealarm(class_dev)) + class_device_remove_file(class_dev, + &class_device_attr_wakealarm); + sysfs_remove_group(&class_dev->kobj, &rtc_attr_group); } -void __init rtc_sysfs_init(struct class *rtc_class) +/* interface registration */ + +static struct class_interface rtc_sysfs_interface = { + .add = &rtc_sysfs_add_device, + .remove = &rtc_sysfs_remove_device, +}; + +static int __init rtc_sysfs_init(void) { - rtc_class->dev_attrs = rtc_attrs; + return rtc_interface_register(&rtc_sysfs_interface); } + +static void __exit rtc_sysfs_exit(void) +{ + class_interface_unregister(&rtc_sysfs_interface); +} + +subsys_initcall(rtc_sysfs_init); +module_exit(rtc_sysfs_exit); + +MODULE_AUTHOR("Alessandro Zummo "); +MODULE_DESCRIPTION("RTC class sysfs interface"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-test.c b/trunk/drivers/rtc/rtc-test.c index 254c9fce27da..f50a1b8e1607 100644 --- a/trunk/drivers/rtc/rtc-test.c +++ b/trunk/drivers/rtc/rtc-test.c @@ -101,11 +101,11 @@ static ssize_t test_irq_store(struct device *dev, retval = count; local_irq_disable(); if (strncmp(buf, "tick", 4) == 0) - rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF); + rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF); else if (strncmp(buf, "alarm", 5) == 0) - rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); + rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF); else if (strncmp(buf, "update", 6) == 0) - rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF); + rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF); else retval = -EINVAL; local_irq_enable(); diff --git a/trunk/drivers/rtc/rtc-vr41xx.c b/trunk/drivers/rtc/rtc-vr41xx.c index af7596ef29e2..e40322b71938 100644 --- a/trunk/drivers/rtc/rtc-vr41xx.c +++ b/trunk/drivers/rtc/rtc-vr41xx.c @@ -97,7 +97,6 @@ static DEFINE_SPINLOCK(rtc_lock); static char rtc_name[] = "RTC"; static unsigned long periodic_frequency; static unsigned long periodic_count; -static unsigned int alarm_enabled; struct resource rtc_resource[2] = { { .name = rtc_name, @@ -189,7 +188,6 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) low = rtc1_read(ECMPLREG); mid = rtc1_read(ECMPMREG); high = rtc1_read(ECMPHREG); - wkalrm->enabled = alarm_enabled; spin_unlock_irq(&rtc_lock); @@ -208,18 +206,10 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) spin_lock_irq(&rtc_lock); - if (alarm_enabled) - disable_irq(ELAPSEDTIME_IRQ); - rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); - if (wkalrm->enabled) - enable_irq(ELAPSEDTIME_IRQ); - - alarm_enabled = wkalrm->enabled; - spin_unlock_irq(&rtc_lock); return 0; @@ -231,24 +221,10 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long switch (cmd) { case RTC_AIE_ON: - spin_lock_irq(&rtc_lock); - - if (!alarm_enabled) { - enable_irq(ELAPSEDTIME_IRQ); - alarm_enabled = 1; - } - - spin_unlock_irq(&rtc_lock); + enable_irq(ELAPSEDTIME_IRQ); break; case RTC_AIE_OFF: - spin_lock_irq(&rtc_lock); - - if (alarm_enabled) { - disable_irq(ELAPSEDTIME_IRQ); - alarm_enabled = 0; - } - - spin_unlock_irq(&rtc_lock); + disable_irq(ELAPSEDTIME_IRQ); break; case RTC_PIE_ON: enable_irq(RTCLONG1_IRQ); @@ -299,7 +275,7 @@ static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id) rtc2_write(RTCINTREG, ELAPSEDTIME_INT); - rtc_update_irq(rtc, 1, RTC_AF); + rtc_update_irq(&rtc->class_dev, 1, RTC_AF); return IRQ_HANDLED; } @@ -315,7 +291,7 @@ static irqreturn_t rtclong1_interrupt(int irq, void *dev_id) rtc1_write(RTCL1LREG, count); rtc1_write(RTCL1HREG, count >> 16); - rtc_update_irq(rtc, 1, RTC_PF); + rtc_update_irq(&rtc->class_dev, 1, RTC_PF); return IRQ_HANDLED; } diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 977521013fe8..e71929db8b06 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -2174,51 +2174,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event) return ret; } -struct dasd_ccw_req * dasd_generic_build_rdc(struct dasd_device *device, - void *rdc_buffer, - int rdc_buffer_size, char *magic) -{ - struct dasd_ccw_req *cqr; - struct ccw1 *ccw; - - cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device); - - if (IS_ERR(cqr)) { - DEV_MESSAGE(KERN_WARNING, device, "%s", - "Could not allocate RDC request"); - return cqr; - } - - ccw = cqr->cpaddr; - ccw->cmd_code = CCW_CMD_RDC; - ccw->cda = (__u32)(addr_t)rdc_buffer; - ccw->count = rdc_buffer_size; - - cqr->device = device; - cqr->expires = 10*HZ; - clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); - cqr->retries = 2; - cqr->buildclk = get_clock(); - cqr->status = DASD_CQR_FILLED; - return cqr; -} - - -int dasd_generic_read_dev_chars(struct dasd_device *device, char *magic, - void **rdc_buffer, int rdc_buffer_size) -{ - int ret; - struct dasd_ccw_req *cqr; - - cqr = dasd_generic_build_rdc(device, *rdc_buffer, rdc_buffer_size, - magic); - if (IS_ERR(cqr)) - return PTR_ERR(cqr); - - ret = dasd_sleep_on(cqr); - dasd_sfree_request(cqr, cqr->device); - return ret; -} static int __init dasd_init(void) diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index c9583fbc2a7d..cecab2274a6e 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -450,81 +450,6 @@ dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid) return 0; } -struct dasd_ccw_req * dasd_eckd_build_rcd_lpm(struct dasd_device *device, - void *rcd_buffer, - struct ciw *ciw, __u8 lpm) -{ - struct dasd_ccw_req *cqr; - struct ccw1 *ccw; - - cqr = dasd_smalloc_request("ECKD", 1 /* RCD */, ciw->count, device); - - if (IS_ERR(cqr)) { - DEV_MESSAGE(KERN_WARNING, device, "%s", - "Could not allocate RCD request"); - return cqr; - } - - ccw = cqr->cpaddr; - ccw->cmd_code = ciw->cmd; - ccw->cda = (__u32)(addr_t)rcd_buffer; - ccw->count = ciw->count; - - cqr->device = device; - cqr->expires = 10*HZ; - cqr->lpm = lpm; - clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); - cqr->retries = 2; - cqr->buildclk = get_clock(); - cqr->status = DASD_CQR_FILLED; - return cqr; -} - -static int dasd_eckd_read_conf_lpm(struct dasd_device *device, - void **rcd_buffer, - int *rcd_buffer_size, __u8 lpm) -{ - struct ciw *ciw; - char *rcd_buf = NULL; - int ret; - struct dasd_ccw_req *cqr; - - /* - * scan for RCD command in extended SenseID data - */ - ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD); - if (!ciw || ciw->cmd == 0) { - ret = -EOPNOTSUPP; - goto out_error; - } - rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA); - if (!rcd_buf) { - ret = -ENOMEM; - goto out_error; - } - cqr = dasd_eckd_build_rcd_lpm(device, rcd_buf, ciw, lpm); - if (IS_ERR(cqr)) { - ret = PTR_ERR(cqr); - goto out_error; - } - ret = dasd_sleep_on(cqr); - /* - * on success we update the user input parms - */ - dasd_sfree_request(cqr, cqr->device); - if (ret) - goto out_error; - - *rcd_buffer_size = ciw->count; - *rcd_buffer = rcd_buf; - return 0; -out_error: - kfree(rcd_buf); - *rcd_buffer = NULL; - *rcd_buffer_size = 0; - return ret; -} - static int dasd_eckd_read_conf(struct dasd_device *device) { @@ -544,8 +469,8 @@ dasd_eckd_read_conf(struct dasd_device *device) /* get configuration data per operational path */ for (lpm = 0x80; lpm; lpm>>= 1) { if (lpm & path_data->opm){ - rc = dasd_eckd_read_conf_lpm(device, &conf_data, - &conf_len, lpm); + rc = read_conf_data_lpm(device->cdev, &conf_data, + &conf_len, lpm); if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ MESSAGE(KERN_WARNING, "Read configuration data returned " @@ -714,7 +639,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) /* Read Device Characteristics */ rdc_data = (void *) &(private->rdc_data); memset(rdc_data, 0, sizeof(rdc_data)); - rc = dasd_generic_read_dev_chars(device, "ECKD", &rdc_data, 64); + rc = read_dev_chars(device->cdev, &rdc_data, 64); if (rc) DEV_MESSAGE(KERN_WARNING, device, "Read device characteristics returned " diff --git a/trunk/drivers/s390/block/dasd_fba.c b/trunk/drivers/s390/block/dasd_fba.c index da16ead8aff2..be0909e39226 100644 --- a/trunk/drivers/s390/block/dasd_fba.c +++ b/trunk/drivers/s390/block/dasd_fba.c @@ -135,7 +135,7 @@ dasd_fba_check_characteristics(struct dasd_device *device) } /* Read Device Characteristics */ rdc_data = (void *) &(private->rdc_data); - rc = dasd_generic_read_dev_chars(device, "FBA ", &rdc_data, 32); + rc = read_dev_chars(device->cdev, &rdc_data, 32); if (rc) { DEV_MESSAGE(KERN_WARNING, device, "Read device characteristics returned error %d", diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index 241294cba415..a2cc69e11410 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -509,8 +509,6 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); int dasd_generic_set_offline (struct ccw_device *cdev); int dasd_generic_notify(struct ccw_device *, int); -int dasd_generic_read_dev_chars(struct dasd_device *, char *, void **, int); - /* externals in dasd_devmap.c */ extern int dasd_max_devindex; extern int dasd_probeonly; diff --git a/trunk/drivers/s390/char/tape.h b/trunk/drivers/s390/char/tape.h index 3b52f5c1dbef..bb4ff537729d 100644 --- a/trunk/drivers/s390/char/tape.h +++ b/trunk/drivers/s390/char/tape.h @@ -103,7 +103,6 @@ enum tape_op { TO_CRYPT_OFF, /* Disable encrpytion */ TO_KEKL_SET, /* Set KEK label */ TO_KEKL_QUERY, /* Query KEK label */ - TO_RDC, /* Read device characteristics */ TO_SIZE, /* #entries in tape_op_t */ }; diff --git a/trunk/drivers/s390/char/tape_3590.c b/trunk/drivers/s390/char/tape_3590.c index 7e2b2ab49264..50f5edab83d7 100644 --- a/trunk/drivers/s390/char/tape_3590.c +++ b/trunk/drivers/s390/char/tape_3590.c @@ -788,7 +788,6 @@ tape_3590_done(struct tape_device *device, struct tape_request *request) case TO_SIZE: case TO_KEKL_SET: case TO_KEKL_QUERY: - case TO_RDC: break; } return TAPE_IO_SUCCESS; @@ -1550,26 +1549,6 @@ tape_3590_irq(struct tape_device *device, struct tape_request *request, return TAPE_IO_STOP; } - -static int tape_3590_read_dev_chars(struct tape_device *device, - struct tape_3590_rdc_data *rdc_data) -{ - int rc; - struct tape_request *request; - - request = tape_alloc_request(1, sizeof(*rdc_data)); - if (IS_ERR(request)) - return PTR_ERR(request); - request->op = TO_RDC; - tape_ccw_end(request->cpaddr, CCW_CMD_RDC, sizeof(*rdc_data), - request->cpdata); - rc = tape_do_io(device, request); - if (rc == 0) - memcpy(rdc_data, request->cpdata, sizeof(*rdc_data)); - tape_free_request(request); - return rc; -} - /* * Setup device function */ @@ -1578,7 +1557,7 @@ tape_3590_setup_device(struct tape_device *device) { int rc; struct tape_3590_disc_data *data; - struct tape_3590_rdc_data *rdc_data; + char *rdc_data; DBF_EVENT(6, "3590 device setup\n"); data = kzalloc(sizeof(struct tape_3590_disc_data), GFP_KERNEL | GFP_DMA); @@ -1587,12 +1566,12 @@ tape_3590_setup_device(struct tape_device *device) data->read_back_op = READ_PREVIOUS; device->discdata = data; - rdc_data = kmalloc(sizeof(*rdc_data), GFP_KERNEL | GFP_DMA); + rdc_data = kmalloc(64, GFP_KERNEL | GFP_DMA); if (!rdc_data) { rc = -ENOMEM; goto fail_kmalloc; } - rc = tape_3590_read_dev_chars(device, rdc_data); + rc = read_dev_chars(device->cdev, (void**)&rdc_data, 64); if (rc) { DBF_LH(3, "Read device characteristics failed!\n"); goto fail_kmalloc; @@ -1600,7 +1579,7 @@ tape_3590_setup_device(struct tape_device *device) rc = tape_std_assign(device); if (rc) goto fail_rdc_data; - if (rdc_data->data[31] == 0x13) { + if (rdc_data[31] == 0x13) { PRINT_INFO("Device has crypto support\n"); data->crypt_info.capability |= TAPE390_CRYPT_SUPPORTED_MASK; tape_3592_disable_crypt(device); diff --git a/trunk/drivers/s390/char/tape_3590.h b/trunk/drivers/s390/char/tape_3590.h index 4534055f1376..aa5138807af1 100644 --- a/trunk/drivers/s390/char/tape_3590.h +++ b/trunk/drivers/s390/char/tape_3590.h @@ -129,10 +129,6 @@ struct tape_3590_med_sense { char pad2[116]; } __attribute__ ((packed)); -struct tape_3590_rdc_data { - char data[64]; -} __attribute__ ((packed)); - /* Datastructures for 3592 encryption support */ struct tape3592_kekl { diff --git a/trunk/drivers/s390/char/tape_core.c b/trunk/drivers/s390/char/tape_core.c index 2fae6338ee1c..e2a8a1a04bab 100644 --- a/trunk/drivers/s390/char/tape_core.c +++ b/trunk/drivers/s390/char/tape_core.c @@ -73,7 +73,7 @@ const char *tape_op_verbose[TO_SIZE] = [TO_DIS] = "DIS", [TO_ASSIGN] = "ASS", [TO_UNASSIGN] = "UAS", [TO_CRYPT_ON] = "CON", [TO_CRYPT_OFF] = "COF", [TO_KEKL_SET] = "KLS", - [TO_KEKL_QUERY] = "KLQ",[TO_RDC] = "RDC", + [TO_KEKL_QUERY] = "KLQ", }; static int @@ -911,7 +911,6 @@ __tape_start_request(struct tape_device *device, struct tape_request *request) case TO_ASSIGN: case TO_UNASSIGN: case TO_READ_ATTMSG: - case TO_RDC: if (device->tape_state == TS_INIT) break; if (device->tape_state == TS_UNUSED) diff --git a/trunk/drivers/s390/cio/qdio.c b/trunk/drivers/s390/cio/qdio.c index f770018fe1d5..05fac0733f3d 100644 --- a/trunk/drivers/s390/cio/qdio.c +++ b/trunk/drivers/s390/cio/qdio.c @@ -69,6 +69,7 @@ static const char version[] = "QDIO base support version 2"; static int qdio_performance_stats = 0; static int proc_perf_file_registration; +static unsigned long i_p_c, i_p_nc, o_p_c, o_p_nc, ii_p_c, ii_p_nc; static struct qdio_perf_stats perf_stats; static int hydra_thinints; @@ -110,31 +111,6 @@ qdio_min(int a,int b) } /***************** SCRUBBER HELPER ROUTINES **********************/ -#ifdef CONFIG_64BIT -static inline void qdio_perf_stat_inc(atomic64_t *count) -{ - if (qdio_performance_stats) - atomic64_inc(count); -} - -static inline void qdio_perf_stat_dec(atomic64_t *count) -{ - if (qdio_performance_stats) - atomic64_dec(count); -} -#else /* CONFIG_64BIT */ -static inline void qdio_perf_stat_inc(atomic_t *count) -{ - if (qdio_performance_stats) - atomic_inc(count); -} - -static inline void qdio_perf_stat_dec(atomic_t *count) -{ - if (qdio_performance_stats) - atomic_dec(count); -} -#endif /* CONFIG_64BIT */ static inline __u64 qdio_get_micros(void) @@ -301,7 +277,8 @@ qdio_siga_sync(struct qdio_q *q, unsigned int gpr2, QDIO_DBF_TEXT4(0,trace,"sigasync"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - qdio_perf_stat_inc(&perf_stats.siga_syncs); + if (qdio_performance_stats) + perf_stats.siga_syncs++; cc = do_siga_sync(q->schid, gpr2, gpr3); if (cc) @@ -346,7 +323,8 @@ qdio_siga_output(struct qdio_q *q) __u32 busy_bit; __u64 start_time=0; - qdio_perf_stat_inc(&perf_stats.siga_outs); + if (qdio_performance_stats) + perf_stats.siga_outs++; QDIO_DBF_TEXT4(0,trace,"sigaout"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); @@ -380,7 +358,8 @@ qdio_siga_input(struct qdio_q *q) QDIO_DBF_TEXT4(0,trace,"sigain"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - qdio_perf_stat_inc(&perf_stats.siga_ins); + if (qdio_performance_stats) + perf_stats.siga_ins++; cc = do_siga_input(q->schid, q->mask); @@ -974,7 +953,8 @@ __qdio_outbound_processing(struct qdio_q *q) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - qdio_perf_stat_inc(&perf_stats.outbound_tl_runs_resched); + if (qdio_performance_stats) + o_p_c++; /* as we're sissies, we'll check next time */ if (likely(!atomic_read(&q->is_in_shutdown))) { qdio_mark_q(q); @@ -982,8 +962,10 @@ __qdio_outbound_processing(struct qdio_q *q) } return; } - qdio_perf_stat_inc(&perf_stats.outbound_tl_runs); - qdio_perf_stat_inc(&perf_stats.tl_runs); + if (qdio_performance_stats) { + o_p_nc++; + perf_stats.tl_runs++; + } /* see comment in qdio_kick_outbound_q */ siga_attempts=atomic_read(&q->busy_siga_counter); @@ -996,25 +978,18 @@ __qdio_outbound_processing(struct qdio_q *q) if (qdio_has_outbound_q_moved(q)) qdio_kick_outbound_handler(q); - if (q->queue_type == QDIO_ZFCP_QFMT) { - if ((!q->hydra_gives_outbound_pcis) && - (!qdio_is_outbound_q_done(q))) - qdio_mark_q(q); - } - else if (((!q->is_iqdio_q) && (!q->is_pci_out)) || - (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) { + if (q->is_iqdio_q) { /* - * make sure buffer switch from PRIMED to EMPTY is noticed - * and outbound_handler is called + * for asynchronous queues, we better check, if the sent + * buffer is already switched from PRIMED to EMPTY. */ - if (qdio_is_outbound_q_done(q)) { - del_timer(&q->timer); - } else { - if (!timer_pending(&q->timer)) - mod_timer(&q->timer, jiffies + - QDIO_FORCE_CHECK_TIMEOUT); - } - } + if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) && + !qdio_is_outbound_q_done(q)) + qdio_mark_q(q); + + } else if (!q->hydra_gives_outbound_pcis) + if (!qdio_is_outbound_q_done(q)) + qdio_mark_q(q); qdio_release_q(q); } @@ -1164,6 +1139,17 @@ qdio_has_inbound_q_moved(struct qdio_q *q) { int i; + static int old_pcis=0; + static int old_thinints=0; + + if (qdio_performance_stats) { + if ((old_pcis==perf_stats.pcis)&& + (old_thinints==perf_stats.thinints)) + perf_stats.start_time_inbound=NOW; + else + old_pcis=perf_stats.pcis; + } + i=qdio_get_inbound_buffer_frontier(q); if ( (i!=GET_SAVED_FRONTIER(q)) || (q->error_status_flags&QDIO_STATUS_LOOK_FOR_ERROR) ) { @@ -1351,7 +1337,10 @@ qdio_kick_inbound_handler(struct qdio_q *q) q->siga_error=0; q->error_status_flags=0; - qdio_perf_stat_inc(&perf_stats.inbound_cnt); + if (qdio_performance_stats) { + perf_stats.inbound_time+=NOW-perf_stats.start_time_inbound; + perf_stats.inbound_cnt++; + } } static void @@ -1371,7 +1360,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) */ if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs_resched); + if (qdio_performance_stats) + ii_p_c++; /* * as we might just be about to stop polling, we make * sure that we check again at least once more @@ -1379,7 +1369,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) tiqdio_sched_tl(); return; } - qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs); + if (qdio_performance_stats) + ii_p_nc++; if (unlikely(atomic_read(&q->is_in_shutdown))) { qdio_unmark_q(q); goto out; @@ -1421,7 +1412,8 @@ __tiqdio_inbound_processing(struct qdio_q *q, int spare_ind_was_set) for (i=0;ino_output_qs;i++) { oq = irq_ptr->output_qs[i]; if (!qdio_is_outbound_q_done(oq)) { - qdio_perf_stat_dec(&perf_stats.tl_runs); + if (qdio_performance_stats) + perf_stats.tl_runs--; __qdio_outbound_processing(oq); } } @@ -1460,7 +1452,8 @@ __qdio_inbound_processing(struct qdio_q *q) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - qdio_perf_stat_inc(&perf_stats.inbound_tl_runs_resched); + if (qdio_performance_stats) + i_p_c++; /* as we're sissies, we'll check next time */ if (likely(!atomic_read(&q->is_in_shutdown))) { qdio_mark_q(q); @@ -1468,8 +1461,10 @@ __qdio_inbound_processing(struct qdio_q *q) } return; } - qdio_perf_stat_inc(&perf_stats.inbound_tl_runs); - qdio_perf_stat_inc(&perf_stats.tl_runs); + if (qdio_performance_stats) { + i_p_nc++; + perf_stats.tl_runs++; + } again: if (qdio_has_inbound_q_moved(q)) { @@ -1515,7 +1510,8 @@ tiqdio_reset_processing_state(struct qdio_q *q, int q_laps) if (unlikely(qdio_reserve_q(q))) { qdio_release_q(q); - qdio_perf_stat_inc(&perf_stats.inbound_thin_tl_runs_resched); + if (qdio_performance_stats) + ii_p_c++; /* * as we might just be about to stop polling, we make * sure that we check again at least once more @@ -1606,7 +1602,8 @@ tiqdio_tl(unsigned long data) { QDIO_DBF_TEXT4(0,trace,"iqdio_tl"); - qdio_perf_stat_inc(&perf_stats.tl_runs); + if (qdio_performance_stats) + perf_stats.tl_runs++; tiqdio_inbound_checks(); } @@ -1833,7 +1830,6 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, q->queue_type = QDIO_IQDIO_QFMT_ASYNCH; q->int_parm=int_parm; q->is_input_q=0; - q->is_pci_out = 0; q->schid = irq_ptr->schid; q->cdev = cdev; q->irq_ptr = irq_ptr; @@ -1846,10 +1842,6 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, q->tasklet.data=(unsigned long)q; q->tasklet.func=(void(*)(unsigned long)) &qdio_outbound_processing; - q->timer.function=(void(*)(unsigned long)) - &qdio_outbound_processing; - q->timer.data = (long)q; - init_timer(&q->timer); atomic_set(&q->busy_siga_counter,0); q->timing.busy_start=0; @@ -1922,7 +1914,10 @@ tiqdio_thinint_handler(void) { QDIO_DBF_TEXT4(0,trace,"thin_int"); - qdio_perf_stat_inc(&perf_stats.thinints); + if (qdio_performance_stats) { + perf_stats.thinints++; + perf_stats.start_time_inbound=NOW; + } /* SVS only when needed: * issue SVS to benefit from iqdio interrupt avoidance @@ -1977,12 +1972,17 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) int i; struct qdio_q *q; - qdio_perf_stat_inc(&perf_stats.pcis); + if (qdio_performance_stats) { + perf_stats.pcis++; + perf_stats.start_time_inbound=NOW; + } for (i=0;ino_input_qs;i++) { q=irq_ptr->input_qs[i]; if (q->is_input_q&QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT) qdio_mark_q(q); else { + if (qdio_performance_stats) + perf_stats.tl_runs--; __qdio_inbound_processing(q); } } @@ -1992,7 +1992,8 @@ qdio_handle_pci(struct qdio_irq *irq_ptr) q=irq_ptr->output_qs[i]; if (qdio_is_outbound_q_done(q)) continue; - qdio_perf_stat_dec(&perf_stats.tl_runs); + if (qdio_performance_stats) + perf_stats.tl_runs--; if (!irq_ptr->sync_done_on_outb_pcis) SYNC_MEMORY; __qdio_outbound_processing(q); @@ -2647,7 +2648,6 @@ qdio_shutdown(struct ccw_device *cdev, int how) for (i=0;ino_output_qs;i++) { tasklet_kill(&irq_ptr->output_qs[i]->tasklet); - del_timer(&irq_ptr->output_qs[i]->timer); wait_event_interruptible_timeout(cdev->private->wait_q, !atomic_read(&irq_ptr-> output_qs[i]-> @@ -3463,18 +3463,20 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; /* This is the outbound handling of queues */ + if (qdio_performance_stats) + perf_stats.start_time_outbound=NOW; + qdio_do_qdio_fill_output(q,qidx,count,buffers); used_elements=atomic_add_return(count, &q->number_of_buffers_used) - count; if (callflags&QDIO_FLAG_DONT_SIGA) { - qdio_perf_stat_inc(&perf_stats.outbound_cnt); + if (qdio_performance_stats) { + perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; + perf_stats.outbound_cnt++; + } return; } - if (callflags & QDIO_FLAG_PCI_OUT) - q->is_pci_out = 1; - else - q->is_pci_out = 0; if (q->is_iqdio_q) { /* one siga for every sbal */ while (count--) @@ -3502,7 +3504,8 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, qdio_kick_outbound_q(q); } else { QDIO_DBF_TEXT3(0,trace, "fast-req"); - qdio_perf_stat_inc(&perf_stats.fast_reqs); + if (qdio_performance_stats) + perf_stats.fast_reqs++; } } /* @@ -3513,7 +3516,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags, __qdio_outbound_processing(q); } - qdio_perf_stat_inc(&perf_stats.outbound_cnt); + if (qdio_performance_stats) { + perf_stats.outbound_time+=NOW-perf_stats.start_time_outbound; + perf_stats.outbound_cnt++; + } } /* count must be 1 in iqdio */ @@ -3583,67 +3589,33 @@ qdio_perf_procfile_read(char *buffer, char **buffer_location, off_t offset, return 0; #define _OUTP_IT(x...) c+=sprintf(buffer+c,x) -#ifdef CONFIG_64BIT - _OUTP_IT("Number of tasklet runs (total) : %li\n", - (long)atomic64_read(&perf_stats.tl_runs)); - _OUTP_IT("Inbound tasklet runs tried/retried : %li/%li\n", - (long)atomic64_read(&perf_stats.inbound_tl_runs), - (long)atomic64_read(&perf_stats.inbound_tl_runs_resched)); - _OUTP_IT("Inbound-thin tasklet runs tried/retried : %li/%li\n", - (long)atomic64_read(&perf_stats.inbound_thin_tl_runs), - (long)atomic64_read(&perf_stats.inbound_thin_tl_runs_resched)); - _OUTP_IT("Outbound tasklet runs tried/retried : %li/%li\n", - (long)atomic64_read(&perf_stats.outbound_tl_runs), - (long)atomic64_read(&perf_stats.outbound_tl_runs_resched)); - _OUTP_IT("\n"); - _OUTP_IT("Number of SIGA sync's issued : %li\n", - (long)atomic64_read(&perf_stats.siga_syncs)); - _OUTP_IT("Number of SIGA in's issued : %li\n", - (long)atomic64_read(&perf_stats.siga_ins)); - _OUTP_IT("Number of SIGA out's issued : %li\n", - (long)atomic64_read(&perf_stats.siga_outs)); - _OUTP_IT("Number of PCIs caught : %li\n", - (long)atomic64_read(&perf_stats.pcis)); - _OUTP_IT("Number of adapter interrupts caught : %li\n", - (long)atomic64_read(&perf_stats.thinints)); - _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %li\n", - (long)atomic64_read(&perf_stats.fast_reqs)); + _OUTP_IT("i_p_nc/c=%lu/%lu\n",i_p_nc,i_p_c); + _OUTP_IT("ii_p_nc/c=%lu/%lu\n",ii_p_nc,ii_p_c); + _OUTP_IT("o_p_nc/c=%lu/%lu\n",o_p_nc,o_p_c); + _OUTP_IT("Number of tasklet runs (total) : %lu\n", + perf_stats.tl_runs); _OUTP_IT("\n"); - _OUTP_IT("Number of inbound transfers : %li\n", - (long)atomic64_read(&perf_stats.inbound_cnt)); - _OUTP_IT("Number of do_QDIOs outbound : %li\n", - (long)atomic64_read(&perf_stats.outbound_cnt)); -#else /* CONFIG_64BIT */ - _OUTP_IT("Number of tasklet runs (total) : %i\n", - atomic_read(&perf_stats.tl_runs)); - _OUTP_IT("Inbound tasklet runs tried/retried : %i/%i\n", - atomic_read(&perf_stats.inbound_tl_runs), - atomic_read(&perf_stats.inbound_tl_runs_resched)); - _OUTP_IT("Inbound-thin tasklet runs tried/retried : %i/%i\n", - atomic_read(&perf_stats.inbound_thin_tl_runs), - atomic_read(&perf_stats.inbound_thin_tl_runs_resched)); - _OUTP_IT("Outbound tasklet runs tried/retried : %i/%i\n", - atomic_read(&perf_stats.outbound_tl_runs), - atomic_read(&perf_stats.outbound_tl_runs_resched)); + _OUTP_IT("Number of SIGA sync's issued : %lu\n", + perf_stats.siga_syncs); + _OUTP_IT("Number of SIGA in's issued : %lu\n", + perf_stats.siga_ins); + _OUTP_IT("Number of SIGA out's issued : %lu\n", + perf_stats.siga_outs); + _OUTP_IT("Number of PCIs caught : %lu\n", + perf_stats.pcis); + _OUTP_IT("Number of adapter interrupts caught : %lu\n", + perf_stats.thinints); + _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %lu\n", + perf_stats.fast_reqs); _OUTP_IT("\n"); - _OUTP_IT("Number of SIGA sync's issued : %i\n", - atomic_read(&perf_stats.siga_syncs)); - _OUTP_IT("Number of SIGA in's issued : %i\n", - atomic_read(&perf_stats.siga_ins)); - _OUTP_IT("Number of SIGA out's issued : %i\n", - atomic_read(&perf_stats.siga_outs)); - _OUTP_IT("Number of PCIs caught : %i\n", - atomic_read(&perf_stats.pcis)); - _OUTP_IT("Number of adapter interrupts caught : %i\n", - atomic_read(&perf_stats.thinints)); - _OUTP_IT("Number of fast requeues (outg. SBALs w/o SIGA) : %i\n", - atomic_read(&perf_stats.fast_reqs)); - _OUTP_IT("\n"); - _OUTP_IT("Number of inbound transfers : %i\n", - atomic_read(&perf_stats.inbound_cnt)); - _OUTP_IT("Number of do_QDIOs outbound : %i\n", - atomic_read(&perf_stats.outbound_cnt)); -#endif /* CONFIG_64BIT */ + _OUTP_IT("Total time of all inbound actions (us) incl. UL : %lu\n", + perf_stats.inbound_time); + _OUTP_IT("Number of inbound transfers : %lu\n", + perf_stats.inbound_cnt); + _OUTP_IT("Total time of all outbound do_QDIOs (us) : %lu\n", + perf_stats.outbound_time); + _OUTP_IT("Number of do_QDIOs outbound : %lu\n", + perf_stats.outbound_cnt); _OUTP_IT("\n"); return c; @@ -3670,6 +3642,8 @@ qdio_add_procfs_entry(void) static void qdio_remove_procfs_entry(void) { + perf_stats.tl_runs=0; + if (!proc_perf_file_registration) /* means if it went ok earlier */ remove_proc_entry(QDIO_PERF,&proc_root); } @@ -3697,38 +3671,13 @@ qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count qdio_performance_stats = i; if (i==0) { /* reset perf. stat. info */ -#ifdef CONFIG_64BIT - atomic64_set(&perf_stats.tl_runs, 0); - atomic64_set(&perf_stats.outbound_tl_runs, 0); - atomic64_set(&perf_stats.inbound_tl_runs, 0); - atomic64_set(&perf_stats.inbound_tl_runs_resched, 0); - atomic64_set(&perf_stats.inbound_thin_tl_runs, 0); - atomic64_set(&perf_stats.inbound_thin_tl_runs_resched, - 0); - atomic64_set(&perf_stats.siga_outs, 0); - atomic64_set(&perf_stats.siga_ins, 0); - atomic64_set(&perf_stats.siga_syncs, 0); - atomic64_set(&perf_stats.pcis, 0); - atomic64_set(&perf_stats.thinints, 0); - atomic64_set(&perf_stats.fast_reqs, 0); - atomic64_set(&perf_stats.outbound_cnt, 0); - atomic64_set(&perf_stats.inbound_cnt, 0); -#else /* CONFIG_64BIT */ - atomic_set(&perf_stats.tl_runs, 0); - atomic_set(&perf_stats.outbound_tl_runs, 0); - atomic_set(&perf_stats.inbound_tl_runs, 0); - atomic_set(&perf_stats.inbound_tl_runs_resched, 0); - atomic_set(&perf_stats.inbound_thin_tl_runs, 0); - atomic_set(&perf_stats.inbound_thin_tl_runs_resched, 0); - atomic_set(&perf_stats.siga_outs, 0); - atomic_set(&perf_stats.siga_ins, 0); - atomic_set(&perf_stats.siga_syncs, 0); - atomic_set(&perf_stats.pcis, 0); - atomic_set(&perf_stats.thinints, 0); - atomic_set(&perf_stats.fast_reqs, 0); - atomic_set(&perf_stats.outbound_cnt, 0); - atomic_set(&perf_stats.inbound_cnt, 0); -#endif /* CONFIG_64BIT */ + i_p_nc = 0; + i_p_c = 0; + ii_p_nc = 0; + ii_p_c = 0; + o_p_nc = 0; + o_p_c = 0; + memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); } } else { QDIO_PRINT_WARN("QDIO performance_stats: write 0 or 1 to this file!\n"); diff --git a/trunk/drivers/s390/cio/qdio.h b/trunk/drivers/s390/cio/qdio.h index 6d7aad18f6f0..ec9af72b2afc 100644 --- a/trunk/drivers/s390/cio/qdio.h +++ b/trunk/drivers/s390/cio/qdio.h @@ -60,7 +60,6 @@ #define QDIO_ACTIVATE_TIMEOUT ((5*HZ)>>10) #define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ) #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) -#define QDIO_FORCE_CHECK_TIMEOUT (10*HZ) enum qdio_irq_states { QDIO_IRQ_STATE_INACTIVE, @@ -407,43 +406,21 @@ do_clear_global_summary(void) #define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04 struct qdio_perf_stats { -#ifdef CONFIG_64BIT - atomic64_t tl_runs; - atomic64_t outbound_tl_runs; - atomic64_t outbound_tl_runs_resched; - atomic64_t inbound_tl_runs; - atomic64_t inbound_tl_runs_resched; - atomic64_t inbound_thin_tl_runs; - atomic64_t inbound_thin_tl_runs_resched; - - atomic64_t siga_outs; - atomic64_t siga_ins; - atomic64_t siga_syncs; - atomic64_t pcis; - atomic64_t thinints; - atomic64_t fast_reqs; - - atomic64_t outbound_cnt; - atomic64_t inbound_cnt; -#else /* CONFIG_64BIT */ - atomic_t tl_runs; - atomic_t outbound_tl_runs; - atomic_t outbound_tl_runs_resched; - atomic_t inbound_tl_runs; - atomic_t inbound_tl_runs_resched; - atomic_t inbound_thin_tl_runs; - atomic_t inbound_thin_tl_runs_resched; - - atomic_t siga_outs; - atomic_t siga_ins; - atomic_t siga_syncs; - atomic_t pcis; - atomic_t thinints; - atomic_t fast_reqs; - - atomic_t outbound_cnt; - atomic_t inbound_cnt; -#endif /* CONFIG_64BIT */ + unsigned long tl_runs; + + unsigned long siga_outs; + unsigned long siga_ins; + unsigned long siga_syncs; + unsigned long pcis; + unsigned long thinints; + unsigned long fast_reqs; + + __u64 start_time_outbound; + unsigned long outbound_cnt; + unsigned long outbound_time; + __u64 start_time_inbound; + unsigned long inbound_cnt; + unsigned long inbound_time; }; /* unlikely as the later the better */ @@ -512,8 +489,8 @@ struct qdio_q { void *irq_ptr; - struct timer_list timer; #ifdef QDIO_USE_TIMERS_FOR_POLLING + struct timer_list timer; atomic_t timer_already_set; spinlock_t timer_lock; #else /* QDIO_USE_TIMERS_FOR_POLLING */ @@ -559,7 +536,6 @@ struct qdio_q { } timing; atomic_t busy_siga_counter; unsigned int queue_type; - unsigned int is_pci_out; /* leave this member at the end. won't be cleared in qdio_fill_qs */ struct slib *slib; /* a page is allocated under this pointer, diff --git a/trunk/drivers/s390/net/netiucv.c b/trunk/drivers/s390/net/netiucv.c index c358764f3264..e10e85e85c84 100644 --- a/trunk/drivers/s390/net/netiucv.c +++ b/trunk/drivers/s390/net/netiucv.c @@ -1862,14 +1862,12 @@ static void netiucv_remove_connection(struct iucv_connection *conn) write_lock_bh(&iucv_connection_rwlock); list_del_init(&conn->list); write_unlock_bh(&iucv_connection_rwlock); - fsm_deltimer(&conn->timer); - netiucv_purge_skb_queue(&conn->collect_queue); if (conn->path) { iucv_path_sever(conn->path, iucvMagic); kfree(conn->path); conn->path = NULL; } - netiucv_purge_skb_queue(&conn->commit_queue); + fsm_deltimer(&conn->timer); kfree_fsm(conn->fsm); kfree_skb(conn->rx_buff); kfree_skb(conn->tx_buff); @@ -2117,6 +2115,7 @@ static void __exit netiucv_exit(void) while (!list_empty(&iucv_connection_list)) { cp = list_entry(iucv_connection_list.next, struct iucv_connection, list); + list_del(&cp->list); ndev = cp->netdev; priv = netdev_priv(ndev); dev = priv->dev; diff --git a/trunk/drivers/s390/net/qeth.h b/trunk/drivers/s390/net/qeth.h index b34eb82edd98..84b108d7c7fd 100644 --- a/trunk/drivers/s390/net/qeth.h +++ b/trunk/drivers/s390/net/qeth.h @@ -288,7 +288,6 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) */ #define IF_NAME_LEN 16 #define QETH_TX_TIMEOUT 100 * HZ -#define QETH_RCD_TIMEOUT 60 * HZ #define QETH_HEADER_SIZE 32 #define MAX_PORTNO 15 #define QETH_FAKE_LL_LEN_ETH ETH_HLEN @@ -583,8 +582,6 @@ enum qeth_channel_states { CH_STATE_ACTIVATING, CH_STATE_HALTED, CH_STATE_STOPPED, - CH_STATE_RCD, - CH_STATE_RCD_DONE, }; /** * card state machine diff --git a/trunk/drivers/s390/net/qeth_eddp.c b/trunk/drivers/s390/net/qeth_eddp.c index 4640f32daae5..dd7034fbfff8 100644 --- a/trunk/drivers/s390/net/qeth_eddp.c +++ b/trunk/drivers/s390/net/qeth_eddp.c @@ -620,10 +620,10 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb, struct qeth_eddp_context * qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb, - struct qeth_hdr *qhdr, unsigned char sk_protocol) + struct qeth_hdr *qhdr) { QETH_DBF_TEXT(trace, 5, "creddpc"); - switch (sk_protocol) { + switch (skb->sk->sk_protocol){ case IPPROTO_TCP: return qeth_eddp_create_context_tcp(card, skb, qhdr); default: diff --git a/trunk/drivers/s390/net/qeth_eddp.h b/trunk/drivers/s390/net/qeth_eddp.h index 52910c9252c0..103768d3bab2 100644 --- a/trunk/drivers/s390/net/qeth_eddp.h +++ b/trunk/drivers/s390/net/qeth_eddp.h @@ -34,8 +34,7 @@ struct qeth_eddp_context_reference { }; extern struct qeth_eddp_context * -qeth_eddp_create_context(struct qeth_card *,struct sk_buff *, - struct qeth_hdr *, unsigned char); +qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,struct qeth_hdr *); extern void qeth_eddp_put_context(struct qeth_eddp_context *); diff --git a/trunk/drivers/s390/net/qeth_main.c b/trunk/drivers/s390/net/qeth_main.c index 29d176036e5c..ad7792dc1a04 100644 --- a/trunk/drivers/s390/net/qeth_main.c +++ b/trunk/drivers/s390/net/qeth_main.c @@ -315,8 +315,7 @@ qeth_alloc_card(void) } static long -__qeth_check_irb_error(struct ccw_device *cdev, unsigned long intparm, - struct irb *irb) +__qeth_check_irb_error(struct ccw_device *cdev, struct irb *irb) { if (!IS_ERR(irb)) return 0; @@ -331,14 +330,6 @@ __qeth_check_irb_error(struct ccw_device *cdev, unsigned long intparm, PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id); QETH_DBF_TEXT(trace, 2, "ckirberr"); QETH_DBF_TEXT_(trace, 2, " rc%d", -ETIMEDOUT); - if (intparm == QETH_RCD_PARM) { - struct qeth_card *card = CARD_FROM_CDEV(cdev); - - if (card && (card->data.ccwdev == cdev)) { - card->data.state = CH_STATE_DOWN; - wake_up(&card->wait_q); - } - } break; default: PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb), @@ -410,7 +401,7 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) QETH_DBF_TEXT(trace,5,"irq"); - if (__qeth_check_irb_error(cdev, intparm, irb)) + if (__qeth_check_irb_error(cdev, irb)) return; cstat = irb->scsw.cstat; dstat = irb->scsw.dstat; @@ -438,8 +429,7 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) channel->state = CH_STATE_HALTED; /*let's wake up immediately on data channel*/ - if ((channel == &card->data) && (intparm != 0) && - (intparm != QETH_RCD_PARM)) + if ((channel == &card->data) && (intparm != 0)) goto out; if (intparm == QETH_CLEAR_CHANNEL_PARM) { @@ -463,10 +453,6 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) HEXDUMP16(WARN,"irb: ",irb); HEXDUMP16(WARN,"sense data: ",irb->ecw); } - if (intparm == QETH_RCD_PARM) { - channel->state = CH_STATE_DOWN; - goto out; - } rc = qeth_get_problem(cdev,irb); if (rc) { qeth_schedule_recovery(card); @@ -474,10 +460,6 @@ qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) } } - if (intparm == QETH_RCD_PARM) { - channel->state = CH_STATE_RCD_DONE; - goto out; - } if (intparm) { buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm); buffer->state = BUF_STATE_PROCESSED; @@ -1222,54 +1204,6 @@ qeth_probe_device(struct ccwgroup_device *gdev) } -static int qeth_read_conf_data(struct qeth_card *card, void **buffer, - int *length) -{ - struct ciw *ciw; - char *rcd_buf; - int ret; - struct qeth_channel *channel = &card->data; - unsigned long flags; - - /* - * scan for RCD command in extended SenseID data - */ - ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD); - if (!ciw || ciw->cmd == 0) - return -EOPNOTSUPP; - rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA); - if (!rcd_buf) - return -ENOMEM; - - channel->ccw.cmd_code = ciw->cmd; - channel->ccw.cda = (__u32) __pa (rcd_buf); - channel->ccw.count = ciw->count; - channel->ccw.flags = CCW_FLAG_SLI; - channel->state = CH_STATE_RCD; - spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); - ret = ccw_device_start_timeout(channel->ccwdev, &channel->ccw, - QETH_RCD_PARM, LPM_ANYPATH, 0, - QETH_RCD_TIMEOUT); - spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); - if (!ret) - wait_event(card->wait_q, - (channel->state == CH_STATE_RCD_DONE || - channel->state == CH_STATE_DOWN)); - if (channel->state == CH_STATE_DOWN) - ret = -EIO; - else - channel->state = CH_STATE_DOWN; - if (ret) { - kfree(rcd_buf); - *buffer = NULL; - *length = 0; - } else { - *length = ciw->count; - *buffer = rcd_buf; - } - return ret; -} - static int qeth_get_unitaddr(struct qeth_card *card) { @@ -1278,9 +1212,9 @@ qeth_get_unitaddr(struct qeth_card *card) int rc; QETH_DBF_TEXT(setup, 2, "getunit"); - rc = qeth_read_conf_data(card, (void **) &prcd, &length); + rc = read_conf_data(CARD_DDEV(card), (void **) &prcd, &length); if (rc) { - PRINT_ERR("qeth_read_conf_data for device %s returned %i\n", + PRINT_ERR("read_conf_data for device %s returned %i\n", CARD_DDEV_ID(card), rc); return rc; } @@ -1289,7 +1223,6 @@ qeth_get_unitaddr(struct qeth_card *card) card->info.cula = prcd[63]; card->info.guestlan = ((prcd[0x10] == _ascebc['V']) && (prcd[0x11] == _ascebc['M'])); - kfree(prcd); return 0; } @@ -1682,21 +1615,6 @@ qeth_put_reply(struct qeth_reply *reply) kfree(reply); } -static void -qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, struct qeth_card *card) -{ - int rc; - int com; - char * ipa_name; - - com = cmd->hdr.command; - rc = cmd->hdr.return_code; - ipa_name = qeth_get_ipa_cmd_name(com); - - PRINT_ERR("%s(x%X) for %s returned x%X \"%s\"\n", ipa_name, com, - QETH_CARD_IFNAME(card), rc, qeth_get_ipa_msg(rc)); -} - static struct qeth_ipa_cmd * qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) { @@ -1705,11 +1623,8 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob) QETH_DBF_TEXT(trace,5,"chkipad"); if (IS_IPA(iob->data)){ cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data); - if (IS_IPA_REPLY(cmd)) { - if (cmd->hdr.return_code) - qeth_issue_ipa_msg(cmd, card); + if (IS_IPA_REPLY(cmd)) return cmd; - } else { switch (cmd->hdr.command) { case IPA_CMD_STOPLAN: @@ -2834,7 +2749,6 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, struct qeth_qdio_out_buffer *buf; int rc; int i; - unsigned int qdio_flags; QETH_DBF_TEXT(trace, 6, "flushbuf"); @@ -2878,13 +2792,13 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int, queue->card->perf_stats.outbound_do_qdio_start_time = qeth_get_micros(); } - qdio_flags = QDIO_FLAG_SYNC_OUTPUT; if (under_int) - qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT; - if (atomic_read(&queue->set_pci_flags_count)) - qdio_flags |= QDIO_FLAG_PCI_OUT; - rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags, - queue->queue_no, index, count, NULL); + rc = do_QDIO(CARD_DDEV(queue->card), + QDIO_FLAG_SYNC_OUTPUT | QDIO_FLAG_UNDER_INTERRUPT, + queue->queue_no, index, count, NULL); + else + rc = do_QDIO(CARD_DDEV(queue->card), QDIO_FLAG_SYNC_OUTPUT, + queue->queue_no, index, count, NULL); if (queue->card->options.performance_stats) queue->card->perf_stats.outbound_do_qdio_time += qeth_get_micros() - @@ -4509,8 +4423,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) qeth_fill_header(card, hdr, new_skb, ipv, cast_type); } if (large_send == QETH_LARGE_SEND_EDDP) { - ctx = qeth_eddp_create_context(card, new_skb, hdr, - skb->sk->sk_protocol); + ctx = qeth_eddp_create_context(card, new_skb, hdr); if (ctx == NULL) { __qeth_free_new_skb(skb, new_skb); PRINT_WARN("could not create eddp context\n"); @@ -5968,6 +5881,9 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data; if (cmd->hdr.return_code) { QETH_DBF_TEXT_(trace, 2, "L2er%x", cmd->hdr.return_code); + PRINT_WARN("Error in registering MAC address on " \ + "device %s: x%x\n", CARD_BUS_ID(card), + cmd->hdr.return_code); card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED; cmd->hdr.return_code = -EIO; } else { @@ -6002,6 +5918,9 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card, QETH_DBF_TEXT(trace, 2, "L2Dmaccb"); cmd = (struct qeth_ipa_cmd *) data; if (cmd->hdr.return_code) { + PRINT_WARN("Error in deregistering MAC address on " \ + "device %s: x%x\n", CARD_BUS_ID(card), + cmd->hdr.return_code); QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code); cmd->hdr.return_code = -EIO; return 0; @@ -6665,7 +6584,7 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card, QETH_DBF_TEXT(trace,4,"chgmaccb"); cmd = (struct qeth_ipa_cmd *) data; - if (!card->options.layer2 || + if (!card->options.layer2 || card->info.guestlan || !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) { memcpy(card->dev->dev_addr, &cmd->data.setadapterparms.data.change_addr.addr, @@ -8511,7 +8430,6 @@ __qeth_reboot_event_card(struct device *dev, void *data) card = (struct qeth_card *) dev->driver_data; qeth_clear_ip_list(card, 0, 0); qeth_qdio_clear_card(card, 0); - qeth_clear_qdio_buffers(card); return 0; } diff --git a/trunk/drivers/s390/net/qeth_mpc.c b/trunk/drivers/s390/net/qeth_mpc.c index f54fdfdbf06f..77c83209d70e 100644 --- a/trunk/drivers/s390/net/qeth_mpc.c +++ b/trunk/drivers/s390/net/qeth_mpc.c @@ -157,113 +157,12 @@ unsigned char READ_CCW[]={ }; -struct ipa_rc_msg { - enum qeth_ipa_return_codes rc; - char *msg; -}; -struct ipa_rc_msg qeth_ipa_rc_msg[] = { - {IPA_RC_SUCCESS, "success"}, - {IPA_RC_NOTSUPP, "Command not supported"}, - {IPA_RC_IP_TABLE_FULL, "Add Addr IP Table Full - ipv6"}, - {IPA_RC_UNKNOWN_ERROR, "IPA command failed - reason unknown"}, - {IPA_RC_UNSUPPORTED_COMMAND, "Command not supported"}, - {IPA_RC_DUP_IPV6_REMOTE,"ipv6 address already registered remote"}, - {IPA_RC_DUP_IPV6_HOME, "ipv6 address already registered"}, - {IPA_RC_UNREGISTERED_ADDR, "Address not registered"}, - {IPA_RC_NO_ID_AVAILABLE, "No identifiers available"}, - {IPA_RC_ID_NOT_FOUND, "Identifier not found"}, - {IPA_RC_INVALID_IP_VERSION, "IP version incorrect"}, - {IPA_RC_LAN_FRAME_MISMATCH, "LAN and frame mismatch"}, - {IPA_RC_L2_UNSUPPORTED_CMD, "Unsupported layer 2 command"}, - {IPA_RC_L2_DUP_MAC, "Duplicate MAC address"}, - {IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"}, - {IPA_RC_L2_DUP_LAYER3_MAC, "Duplicate with layer 3 MAC"}, - {IPA_RC_L2_GMAC_NOT_FOUND, "GMAC not found"}, - {IPA_RC_L2_MAC_NOT_FOUND, "L2 mac address not found"}, - {IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"}, - {IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"}, - {IPA_RC_L2_VLAN_ID_NOT_FOUND, "L2 vlan id not found"}, - {IPA_RC_DATA_MISMATCH, "Data field mismatch (v4/v6 mixed)"}, - {IPA_RC_INVALID_MTU_SIZE, "Invalid MTU size"}, - {IPA_RC_INVALID_LANTYPE, "Invalid LAN type"}, - {IPA_RC_INVALID_LANNUM, "Invalid LAN num"}, - {IPA_RC_DUPLICATE_IP_ADDRESS, "Address already registered"}, - {IPA_RC_IP_ADDR_TABLE_FULL, "IP address table full"}, - {IPA_RC_LAN_PORT_STATE_ERROR, "LAN port state error"}, - {IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"}, - {IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"}, - {IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"}, - {IPA_RC_MULTICAST_FULL, "No task available, multicast full"}, - {IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"}, - {IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"}, - {IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"}, - {IPA_RC_PRIMARY_ALREADY_DEFINED,"Primary already defined"}, - {IPA_RC_SECOND_ALREADY_DEFINED, "Secondary already defined"}, - {IPA_RC_INVALID_SETRTG_INDICATOR,"Invalid SETRTG indicator"}, - {IPA_RC_MC_ADDR_ALREADY_DEFINED,"Multicast address already defined"}, - {IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"}, - {IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"}, - {IPA_RC_FFFF, "Unknown Error"} -}; -char * -qeth_get_ipa_msg(enum qeth_ipa_return_codes rc) -{ - int x = 0; - qeth_ipa_rc_msg[sizeof(qeth_ipa_rc_msg) / - sizeof(struct ipa_rc_msg) - 1].rc = rc; - while(qeth_ipa_rc_msg[x].rc != rc) - x++; - return qeth_ipa_rc_msg[x].msg; -} -struct ipa_cmd_names { - enum qeth_ipa_cmds cmd; - char *name; -}; - -struct ipa_cmd_names qeth_ipa_cmd_names[] = { - {IPA_CMD_STARTLAN, "startlan"}, - {IPA_CMD_STOPLAN, "stoplan"}, - {IPA_CMD_SETVMAC, "setvmac"}, - {IPA_CMD_DELVMAC, "delvmca"}, - {IPA_CMD_SETGMAC, "setgmac"}, - {IPA_CMD_DELGMAC, "delgmac"}, - {IPA_CMD_SETVLAN, "setvlan"}, - {IPA_CMD_DELVLAN, "delvlan"}, - {IPA_CMD_SETCCID, "setccid"}, - {IPA_CMD_DELCCID, "delccid"}, - {IPA_CMD_MODCCID, "setip"}, - {IPA_CMD_SETIP, "setip"}, - {IPA_CMD_QIPASSIST, "qipassist"}, - {IPA_CMD_SETASSPARMS, "setassparms"}, - {IPA_CMD_SETIPM, "setipm"}, - {IPA_CMD_DELIPM, "delipm"}, - {IPA_CMD_SETRTG, "setrtg"}, - {IPA_CMD_DELIP, "delip"}, - {IPA_CMD_SETADAPTERPARMS, "setadapterparms"}, - {IPA_CMD_SET_DIAG_ASS, "set_diag_ass"}, - {IPA_CMD_CREATE_ADDR, "create_addr"}, - {IPA_CMD_DESTROY_ADDR, "destroy_addr"}, - {IPA_CMD_REGISTER_LOCAL_ADDR, "register_local_addr"}, - {IPA_CMD_UNREGISTER_LOCAL_ADDR, "unregister_local_addr"}, - {IPA_CMD_UNKNOWN, "unknown"}, -}; -char * -qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd) -{ - int x = 0; - qeth_ipa_cmd_names[ - sizeof(qeth_ipa_cmd_names)/ - sizeof(struct ipa_cmd_names)-1].cmd = cmd; - while(qeth_ipa_cmd_names[x].cmd != cmd) - x++; - return qeth_ipa_cmd_names[x].name; -} diff --git a/trunk/drivers/s390/net/qeth_mpc.h b/trunk/drivers/s390/net/qeth_mpc.h index 1d8083c91765..0477c47471c5 100644 --- a/trunk/drivers/s390/net/qeth_mpc.h +++ b/trunk/drivers/s390/net/qeth_mpc.h @@ -25,19 +25,18 @@ extern unsigned char IPA_PDU_HEADER[]; #define IPA_CMD_LENGTH (IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd)) -#define QETH_SEQ_NO_LENGTH 4 -#define QETH_MPC_TOKEN_LENGTH 4 +#define QETH_SEQ_NO_LENGTH 4 +#define QETH_MPC_TOKEN_LENGTH 4 #define QETH_MCL_LENGTH 4 #define OSA_ADDR_LEN 6 -#define QETH_TIMEOUT (10 * HZ) -#define QETH_IPA_TIMEOUT (45 * HZ) -#define QETH_IDX_COMMAND_SEQNO 0xffff0000 +#define QETH_TIMEOUT (10 * HZ) +#define QETH_IPA_TIMEOUT (45 * HZ) +#define QETH_IDX_COMMAND_SEQNO 0xffff0000 #define SR_INFO_LEN 16 #define QETH_CLEAR_CHANNEL_PARM -10 #define QETH_HALT_CHANNEL_PARM -11 -#define QETH_RCD_PARM -12 /*****************************************************************************/ /* IP Assist related definitions */ @@ -93,107 +92,79 @@ enum qeth_checksum_types { */ #define RESET_ROUTING_FLAG 0x10 /* indicate that routing type shall be set */ enum qeth_routing_types { - NO_ROUTER = 0, /* TODO: set to bit flag used in IPA Command */ - PRIMARY_ROUTER = 1, - SECONDARY_ROUTER = 2, - MULTICAST_ROUTER = 3, - PRIMARY_CONNECTOR = 4, - SECONDARY_CONNECTOR = 5, + NO_ROUTER = 0, /* TODO: set to bit flag used in IPA Command */ + PRIMARY_ROUTER = 1, + SECONDARY_ROUTER = 2, + MULTICAST_ROUTER = 3, + PRIMARY_CONNECTOR = 4, + SECONDARY_CONNECTOR = 5, }; + /* IPA Commands */ enum qeth_ipa_cmds { - IPA_CMD_STARTLAN = 0x01, - IPA_CMD_STOPLAN = 0x02, - IPA_CMD_SETVMAC = 0x21, - IPA_CMD_DELVMAC = 0x22, - IPA_CMD_SETGMAC = 0x23, - IPA_CMD_DELGMAC = 0x24, - IPA_CMD_SETVLAN = 0x25, - IPA_CMD_DELVLAN = 0x26, - IPA_CMD_SETCCID = 0x41, - IPA_CMD_DELCCID = 0x42, - IPA_CMD_MODCCID = 0x43, - IPA_CMD_SETIP = 0xb1, - IPA_CMD_QIPASSIST = 0xb2, - IPA_CMD_SETASSPARMS = 0xb3, - IPA_CMD_SETIPM = 0xb4, - IPA_CMD_DELIPM = 0xb5, - IPA_CMD_SETRTG = 0xb6, - IPA_CMD_DELIP = 0xb7, - IPA_CMD_SETADAPTERPARMS = 0xb8, - IPA_CMD_SET_DIAG_ASS = 0xb9, - IPA_CMD_CREATE_ADDR = 0xc3, - IPA_CMD_DESTROY_ADDR = 0xc4, - IPA_CMD_REGISTER_LOCAL_ADDR = 0xd1, - IPA_CMD_UNREGISTER_LOCAL_ADDR = 0xd2, - IPA_CMD_UNKNOWN = 0x00 + IPA_CMD_STARTLAN = 0x01, + IPA_CMD_STOPLAN = 0x02, + IPA_CMD_SETVMAC = 0x21, + IPA_CMD_DELVMAC = 0x22, + IPA_CMD_SETGMAC = 0x23, + IPA_CMD_DELGMAC = 0x24, + IPA_CMD_SETVLAN = 0x25, + IPA_CMD_DELVLAN = 0x26, + IPA_CMD_SETCCID = 0x41, + IPA_CMD_DELCCID = 0x42, + IPA_CMD_MODCCID = 0x43, + IPA_CMD_SETIP = 0xb1, + IPA_CMD_DELIP = 0xb7, + IPA_CMD_QIPASSIST = 0xb2, + IPA_CMD_SETASSPARMS = 0xb3, + IPA_CMD_SETIPM = 0xb4, + IPA_CMD_DELIPM = 0xb5, + IPA_CMD_SETRTG = 0xb6, + IPA_CMD_SETADAPTERPARMS = 0xb8, + IPA_CMD_IPFRAME = 0xb9, + IPA_CMD_ADD_ADDR_ENTRY = 0xc1, + IPA_CMD_DELETE_ADDR_ENTRY = 0xc2, + IPA_CMD_CREATE_ADDR = 0xc3, + IPA_CMD_DESTROY_ADDR = 0xc4, + IPA_CMD_REGISTER_LOCAL_ADDR = 0xd1, + IPA_CMD_UNREGISTER_LOCAL_ADDR = 0xd2, }; enum qeth_ip_ass_cmds { IPA_CMD_ASS_START = 0x0001, IPA_CMD_ASS_STOP = 0x0002, - IPA_CMD_ASS_CONFIGURE = 0x0003, - IPA_CMD_ASS_ENABLE = 0x0004, + IPA_CMD_ASS_CONFIGURE = 0x0003, + IPA_CMD_ASS_ENABLE = 0x0004, }; enum qeth_arp_process_subcmds { - IPA_CMD_ASS_ARP_SET_NO_ENTRIES = 0x0003, - IPA_CMD_ASS_ARP_QUERY_CACHE = 0x0004, - IPA_CMD_ASS_ARP_ADD_ENTRY = 0x0005, - IPA_CMD_ASS_ARP_REMOVE_ENTRY = 0x0006, - IPA_CMD_ASS_ARP_FLUSH_CACHE = 0x0007, - IPA_CMD_ASS_ARP_QUERY_INFO = 0x0104, - IPA_CMD_ASS_ARP_QUERY_STATS = 0x0204, + IPA_CMD_ASS_ARP_SET_NO_ENTRIES = 0x0003, + IPA_CMD_ASS_ARP_QUERY_CACHE = 0x0004, + IPA_CMD_ASS_ARP_ADD_ENTRY = 0x0005, + IPA_CMD_ASS_ARP_REMOVE_ENTRY = 0x0006, + IPA_CMD_ASS_ARP_FLUSH_CACHE = 0x0007, + IPA_CMD_ASS_ARP_QUERY_INFO = 0x0104, + IPA_CMD_ASS_ARP_QUERY_STATS = 0x0204, }; - -/* Return Codes for IPA Commands - * according to OSA card Specs */ - +/* Return Codes for IPA Commands */ enum qeth_ipa_return_codes { - IPA_RC_SUCCESS = 0x0000, - IPA_RC_NOTSUPP = 0x0001, - IPA_RC_IP_TABLE_FULL = 0x0002, - IPA_RC_UNKNOWN_ERROR = 0x0003, - IPA_RC_UNSUPPORTED_COMMAND = 0x0004, - IPA_RC_DUP_IPV6_REMOTE = 0x0008, - IPA_RC_DUP_IPV6_HOME = 0x0010, - IPA_RC_UNREGISTERED_ADDR = 0x0011, - IPA_RC_NO_ID_AVAILABLE = 0x0012, - IPA_RC_ID_NOT_FOUND = 0x0013, - IPA_RC_INVALID_IP_VERSION = 0x0020, - IPA_RC_LAN_FRAME_MISMATCH = 0x0040, - IPA_RC_L2_UNSUPPORTED_CMD = 0x2003, - IPA_RC_L2_DUP_MAC = 0x2005, - IPA_RC_L2_ADDR_TABLE_FULL = 0x2006, - IPA_RC_L2_DUP_LAYER3_MAC = 0x200a, - IPA_RC_L2_GMAC_NOT_FOUND = 0x200b, - IPA_RC_L2_MAC_NOT_FOUND = 0x2010, - IPA_RC_L2_INVALID_VLAN_ID = 0x2015, - IPA_RC_L2_DUP_VLAN_ID = 0x2016, - IPA_RC_L2_VLAN_ID_NOT_FOUND = 0x2017, - IPA_RC_DATA_MISMATCH = 0xe001, - IPA_RC_INVALID_MTU_SIZE = 0xe002, - IPA_RC_INVALID_LANTYPE = 0xe003, - IPA_RC_INVALID_LANNUM = 0xe004, - IPA_RC_DUPLICATE_IP_ADDRESS = 0xe005, - IPA_RC_IP_ADDR_TABLE_FULL = 0xe006, - IPA_RC_LAN_PORT_STATE_ERROR = 0xe007, - IPA_RC_SETIP_NO_STARTLAN = 0xe008, - IPA_RC_SETIP_ALREADY_RECEIVED = 0xe009, - IPA_RC_IP_ADDR_ALREADY_USED = 0xe00a, - IPA_RC_MULTICAST_FULL = 0xe00b, - IPA_RC_SETIP_INVALID_VERSION = 0xe00d, - IPA_RC_UNSUPPORTED_SUBCMD = 0xe00e, - IPA_RC_ARP_ASSIST_NO_ENABLE = 0xe00f, - IPA_RC_PRIMARY_ALREADY_DEFINED = 0xe010, - IPA_RC_SECOND_ALREADY_DEFINED = 0xe011, - IPA_RC_INVALID_SETRTG_INDICATOR = 0xe012, - IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013, - IPA_RC_LAN_OFFLINE = 0xe080, - IPA_RC_INVALID_IP_VERSION2 = 0xf001, - IPA_RC_FFFF = 0xffff + IPA_RC_SUCCESS = 0x0000, + IPA_RC_NOTSUPP = 0x0001, + IPA_RC_NO_ACCESS = 0x0002, + IPA_RC_FAILED = 0x0003, + IPA_RC_DATA_MISMATCH = 0xe001, + IPA_RC_INVALID_LAN_TYPE = 0xe003, + IPA_RC_INVALID_LAN_NO = 0xe004, + IPA_RC_IPADDR_ALREADY_REG = 0xe005, + IPA_RC_IPADDR_TABLE_FULL = 0xe006, + IPA_RC_IPADDR_ALREADY_USED = 0xe00a, + IPA_RC_ASSNO_NOT_SUPP = 0xe00d, + IPA_RC_ASSCMD_START_FAILED = 0xe00e, + IPA_RC_ASSCMD_PART_SUCCESS = 0xe00f, + IPA_RC_IPADDR_NOT_DEFINED = 0xe010, + IPA_RC_LAN_OFFLINE = 0xe080, }; /* IPA function flags; each flag marks availability of respective function */ @@ -211,9 +182,7 @@ enum qeth_ipa_funcs { IPA_SETADAPTERPARMS = 0x00000400L, IPA_VLAN_PRIO = 0x00000800L, IPA_PASSTHRU = 0x00001000L, - IPA_FLUSH_ARP_SUPPORT = 0x00002000L, IPA_FULL_VLAN = 0x00004000L, - IPA_INBOUND_PASSTHRU = 0x00008000L, IPA_SOURCE_MAC = 0x00010000L, IPA_OSA_MC_ROUTER = 0x00020000L, IPA_QUERY_ARP_ASSIST = 0x00040000L, @@ -234,30 +203,31 @@ enum qeth_ipa_setdelip_flags { /* SETADAPTER IPA Command: ****************************************************/ enum qeth_ipa_setadp_cmd { IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x01, - IPA_SETADP_ALTER_MAC_ADDRESS = 0x02, - IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x04, - IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x08, - IPA_SETADP_SET_ADDRESSING_MODE = 0x10, - IPA_SETADP_SET_CONFIG_PARMS = 0x20, - IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x40, - IPA_SETADP_SET_BROADCAST_MODE = 0x80, - IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, - IPA_SETADP_SET_SNMP_CONTROL = 0x0200, - IPA_SETADP_QUERY_CARD_INFO = 0x0400, + IPA_SETADP_ALTER_MAC_ADDRESS = 0x02, + IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x04, + IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x08, + IPA_SETADP_SET_ADDRESSING_MODE = 0x10, + IPA_SETADP_SET_CONFIG_PARMS = 0x20, + IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x40, + IPA_SETADP_SET_BROADCAST_MODE = 0x80, + IPA_SETADP_SEND_OSA_MESSAGE = 0x0100, + IPA_SETADP_SET_SNMP_CONTROL = 0x0200, + IPA_SETADP_READ_SNMP_PARMS = 0x0400, IPA_SETADP_SET_PROMISC_MODE = 0x0800, + IPA_SETADP_QUERY_CARD_INFO = 0x1000, }; enum qeth_ipa_mac_ops { - CHANGE_ADDR_READ_MAC = 0, - CHANGE_ADDR_REPLACE_MAC = 1, - CHANGE_ADDR_ADD_MAC = 2, - CHANGE_ADDR_DEL_MAC = 4, - CHANGE_ADDR_RESET_MAC = 8, + CHANGE_ADDR_READ_MAC = 0, + CHANGE_ADDR_REPLACE_MAC = 1, + CHANGE_ADDR_ADD_MAC = 2, + CHANGE_ADDR_DEL_MAC = 4, + CHANGE_ADDR_RESET_MAC = 8, }; enum qeth_ipa_addr_ops { - CHANGE_ADDR_READ_ADDR = 0, - CHANGE_ADDR_ADD_ADDR = 1, - CHANGE_ADDR_DEL_ADDR = 2, - CHANGE_ADDR_FLUSH_ADDR_TABLE = 4, + CHANGE_ADDR_READ_ADDR = 0, + CHANGE_ADDR_ADD_ADDR = 1, + CHANGE_ADDR_DEL_ADDR = 2, + CHANGE_ADDR_FLUSH_ADDR_TABLE = 4, }; enum qeth_ipa_promisc_modes { SET_PROMISC_MODE_OFF = 0, @@ -436,15 +406,15 @@ struct qeth_ipacmd_hdr { struct qeth_ipa_cmd { struct qeth_ipacmd_hdr hdr; union { - struct qeth_ipacmd_setdelip4 setdelip4; - struct qeth_ipacmd_setdelip6 setdelip6; + struct qeth_ipacmd_setdelip4 setdelip4; + struct qeth_ipacmd_setdelip6 setdelip6; struct qeth_ipacmd_setdelipm setdelipm; - struct qeth_ipacmd_setassparms setassparms; - struct qeth_ipacmd_layer2setdelmac setdelmac; - struct qeth_ipacmd_layer2setdelvlan setdelvlan; - struct qeth_create_destroy_address create_destroy_addr; - struct qeth_ipacmd_setadpparms setadapterparms; - struct qeth_set_routing setrtg; + struct qeth_ipacmd_setassparms setassparms; + struct qeth_ipacmd_layer2setdelmac setdelmac; + struct qeth_ipacmd_layer2setdelvlan setdelvlan; + struct qeth_create_destroy_address create_destroy_addr; + struct qeth_ipacmd_setadpparms setadapterparms; + struct qeth_set_routing setrtg; } data; } __attribute__ ((packed)); @@ -462,12 +432,6 @@ enum qeth_ipa_arp_return_codes { QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008, }; - -extern char * -qeth_get_ipa_msg(enum qeth_ipa_return_codes rc); -extern char * -qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd); - #define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \ sizeof(struct qeth_ipacmd_setassparms_hdr)) #define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \ @@ -556,7 +520,7 @@ extern unsigned char DM_ACT[]; extern unsigned char IDX_ACTIVATE_READ[]; extern unsigned char IDX_ACTIVATE_WRITE[]; -#define IDX_ACTIVATE_SIZE 0x22 +#define IDX_ACTIVATE_SIZE 0x22 #define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer+0x0c) #define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b]&0x80) #define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer+0x10) diff --git a/trunk/drivers/s390/net/qeth_sys.c b/trunk/drivers/s390/net/qeth_sys.c index 65ffc21afc37..d518419cd0c6 100644 --- a/trunk/drivers/s390/net/qeth_sys.c +++ b/trunk/drivers/s390/net/qeth_sys.c @@ -384,6 +384,8 @@ qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route, route->type = PRIMARY_CONNECTOR; } else if (!strcmp(tmp, "secondary_connector")) { route->type = SECONDARY_CONNECTOR; + } else if (!strcmp(tmp, "multicast_router")) { + route->type = MULTICAST_ROUTER; } else if (!strcmp(tmp, "primary_router")) { route->type = PRIMARY_ROUTER; } else if (!strcmp(tmp, "secondary_router")) { diff --git a/trunk/drivers/s390/scsi/zfcp_aux.c b/trunk/drivers/s390/scsi/zfcp_aux.c index 324899c96efe..1f9554e08013 100644 --- a/trunk/drivers/s390/scsi/zfcp_aux.c +++ b/trunk/drivers/s390/scsi/zfcp_aux.c @@ -118,32 +118,97 @@ _zfcp_hex_dump(char *addr, int count) #define ZFCP_LOG_AREA ZFCP_LOG_AREA_FSF -static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) +static int zfcp_reqlist_init(struct zfcp_adapter *adapter) { - int idx; + int i; adapter->req_list = kcalloc(REQUEST_LIST_SIZE, sizeof(struct list_head), GFP_KERNEL); + if (!adapter->req_list) return -ENOMEM; - for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) - INIT_LIST_HEAD(&adapter->req_list[idx]); + for (i=0; ireq_list[i]); + return 0; } static void zfcp_reqlist_free(struct zfcp_adapter *adapter) { + struct zfcp_fsf_req *request, *tmp; + unsigned int i; + + for (i=0; ireq_list[i])) + continue; + + list_for_each_entry_safe(request, tmp, + &adapter->req_list[i], list) + list_del(&request->list); + } + kfree(adapter->req_list); } +void zfcp_reqlist_add(struct zfcp_adapter *adapter, + struct zfcp_fsf_req *fsf_req) +{ + unsigned int i; + + i = fsf_req->req_id % REQUEST_LIST_SIZE; + list_add_tail(&fsf_req->list, &adapter->req_list[i]); +} + +void zfcp_reqlist_remove(struct zfcp_adapter *adapter, unsigned long req_id) +{ + struct zfcp_fsf_req *request, *tmp; + unsigned int i, counter; + u64 dbg_tmp[2]; + + i = req_id % REQUEST_LIST_SIZE; + BUG_ON(list_empty(&adapter->req_list[i])); + + counter = 0; + list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) { + if (request->req_id == req_id) { + dbg_tmp[0] = (u64) atomic_read(&adapter->reqs_active); + dbg_tmp[1] = (u64) counter; + debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16); + list_del(&request->list); + break; + } + counter++; + } +} + +struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *adapter, + unsigned long req_id) +{ + struct zfcp_fsf_req *request, *tmp; + unsigned int i; + + /* 0 is reserved as an invalid req_id */ + if (req_id == 0) + return NULL; + + i = req_id % REQUEST_LIST_SIZE; + + list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list) + if (request->req_id == req_id) + return request; + + return NULL; +} + int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) { - unsigned int idx; + unsigned int i; - for (idx = 0; idx < REQUEST_LIST_SIZE; idx++) - if (!list_empty(&adapter->req_list[idx])) + for (i=0; ireq_list[i])) return 0; + return 1; } @@ -848,8 +913,6 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun) unit->sysfs_device.release = zfcp_sysfs_unit_release; dev_set_drvdata(&unit->sysfs_device, unit); - init_waitqueue_head(&unit->scsi_scan_wq); - /* mark unit unusable as long as sysfs registration is not complete */ atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); @@ -1041,7 +1104,7 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) /* initialize list of fsf requests */ spin_lock_init(&adapter->req_list_lock); - retval = zfcp_reqlist_alloc(adapter); + retval = zfcp_reqlist_init(adapter); if (retval) { ZFCP_LOG_INFO("request list initialization failed\n"); goto failed_low_mem_buffers; @@ -1102,7 +1165,6 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) zfcp_sysfs_adapter_remove_files(&adapter->ccw_device->dev); sysfs_failed: dev_set_drvdata(&ccw_device->dev, NULL); - zfcp_reqlist_free(adapter); failed_low_mem_buffers: zfcp_free_low_mem_buffers(adapter); if (qdio_free(ccw_device) != 0) @@ -1435,7 +1497,7 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter, if (!port || (port->wwpn != (*(wwn_t *) &els_plogi->serv_param.wwpn))) { ZFCP_LOG_DEBUG("ignored incoming PLOGI for nonexisting port " - "with d_id 0x%06x on adapter %s\n", + "with d_id 0x%08x on adapter %s\n", status_buffer->d_id, zfcp_get_busid_by_adapter(adapter)); } else { @@ -1460,7 +1522,7 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter, if (!port || (port->wwpn != els_logo->nport_wwpn)) { ZFCP_LOG_DEBUG("ignored incoming LOGO for nonexisting port " - "with d_id 0x%06x on adapter %s\n", + "with d_id 0x%08x on adapter %s\n", status_buffer->d_id, zfcp_get_busid_by_adapter(adapter)); } else { @@ -1642,7 +1704,7 @@ static void zfcp_ns_gid_pn_handler(unsigned long data) /* looks like a valid d_id */ port->d_id = ct_iu_resp->d_id & ZFCP_DID_MASK; atomic_set_mask(ZFCP_STATUS_PORT_DID_DID, &port->status); - ZFCP_LOG_DEBUG("adapter %s: wwpn=0x%016Lx ---> d_id=0x%06x\n", + ZFCP_LOG_DEBUG("adapter %s: wwpn=0x%016Lx ---> d_id=0x%08x\n", zfcp_get_busid_by_port(port), port->wwpn, port->d_id); goto out; diff --git a/trunk/drivers/s390/scsi/zfcp_def.h b/trunk/drivers/s390/scsi/zfcp_def.h index 22649639230b..32933ed54b8a 100644 --- a/trunk/drivers/s390/scsi/zfcp_def.h +++ b/trunk/drivers/s390/scsi/zfcp_def.h @@ -637,7 +637,6 @@ do { \ #define ZFCP_STATUS_UNIT_SHARED 0x00000004 #define ZFCP_STATUS_UNIT_READONLY 0x00000008 #define ZFCP_STATUS_UNIT_REGISTERED 0x00000010 -#define ZFCP_STATUS_UNIT_SCSI_WORK_PENDING 0x00000020 /* FSF request status (this does not have a common part) */ #define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000 @@ -981,10 +980,6 @@ struct zfcp_unit { struct scsi_device *device; /* scsi device struct pointer */ struct zfcp_erp_action erp_action; /* pending error recovery */ atomic_t erp_counter; - wait_queue_head_t scsi_scan_wq; /* can be used to wait until - all scsi_scan_target - requests have been - completed. */ }; /* FSF request */ @@ -1089,42 +1084,6 @@ extern void _zfcp_hex_dump(char *, int); #define zfcp_get_busid_by_port(port) (zfcp_get_busid_by_adapter(port->adapter)) #define zfcp_get_busid_by_unit(unit) (zfcp_get_busid_by_port(unit->port)) -/* - * Helper functions for request ID management. - */ -static inline int zfcp_reqlist_hash(unsigned long req_id) -{ - return req_id % REQUEST_LIST_SIZE; -} - -static inline void zfcp_reqlist_add(struct zfcp_adapter *adapter, - struct zfcp_fsf_req *fsf_req) -{ - unsigned int idx; - - idx = zfcp_reqlist_hash(fsf_req->req_id); - list_add_tail(&fsf_req->list, &adapter->req_list[idx]); -} - -static inline void zfcp_reqlist_remove(struct zfcp_adapter *adapter, - struct zfcp_fsf_req *fsf_req) -{ - list_del(&fsf_req->list); -} - -static inline struct zfcp_fsf_req * -zfcp_reqlist_find(struct zfcp_adapter *adapter, unsigned long req_id) -{ - struct zfcp_fsf_req *request; - unsigned int idx; - - idx = zfcp_reqlist_hash(req_id); - list_for_each_entry(request, &adapter->req_list[idx], list) - if (request->req_id == req_id) - return request; - return NULL; -} - /* * functions needed for reference/usage counting */ diff --git a/trunk/drivers/s390/scsi/zfcp_erp.c b/trunk/drivers/s390/scsi/zfcp_erp.c index aef66bc2b6ca..421da1e7c0ea 100644 --- a/trunk/drivers/s390/scsi/zfcp_erp.c +++ b/trunk/drivers/s390/scsi/zfcp_erp.c @@ -179,14 +179,14 @@ static void zfcp_close_fsf(struct zfcp_adapter *adapter) static void zfcp_fsf_request_timeout_handler(unsigned long data) { struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; - zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); + zfcp_erp_adapter_reopen(adapter, 0); } void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) { fsf_req->timer.function = zfcp_fsf_request_timeout_handler; fsf_req->timer.data = (unsigned long) fsf_req->adapter; - fsf_req->timer.expires = jiffies + timeout; + fsf_req->timer.expires = timeout; add_timer(&fsf_req->timer); } @@ -342,9 +342,9 @@ zfcp_erp_adisc(struct zfcp_port *port) adisc->wwpn = fc_host_port_name(adapter->scsi_host); adisc->wwnn = fc_host_node_name(adapter->scsi_host); adisc->nport_id = fc_host_port_id(adapter->scsi_host); - ZFCP_LOG_INFO("ADISC request from s_id 0x%06x to d_id 0x%06x " + ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x " "(wwpn=0x%016Lx, wwnn=0x%016Lx, " - "hard_nport_id=0x%06x, nport_id=0x%06x)\n", + "hard_nport_id=0x%08x, nport_id=0x%08x)\n", adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn, adisc->hard_nport_id, adisc->nport_id); @@ -352,7 +352,7 @@ zfcp_erp_adisc(struct zfcp_port *port) retval = zfcp_fsf_send_els(send_els); if (retval != 0) { ZFCP_LOG_NORMAL("error: initiation of Send ELS failed for port " - "0x%06x on adapter %s\n", send_els->d_id, + "0x%08x on adapter %s\n", send_els->d_id, zfcp_get_busid_by_adapter(adapter)); goto freemem; } @@ -398,7 +398,7 @@ zfcp_erp_adisc_handler(unsigned long data) if (send_els->status != 0) { ZFCP_LOG_NORMAL("ELS request rejected/timed out, " "force physical port reopen " - "(adapter %s, port d_id=0x%06x)\n", + "(adapter %s, port d_id=0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); debug_text_event(adapter->erp_dbf, 3, "forcreop"); if (zfcp_erp_port_forced_reopen(port, 0)) @@ -411,9 +411,9 @@ zfcp_erp_adisc_handler(unsigned long data) adisc = zfcp_sg_to_address(send_els->resp); - ZFCP_LOG_INFO("ADISC response from d_id 0x%06x to s_id " - "0x%06x (wwpn=0x%016Lx, wwnn=0x%016Lx, " - "hard_nport_id=0x%06x, nport_id=0x%06x)\n", + ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id " + "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, " + "hard_nport_id=0x%08x, nport_id=0x%08x)\n", d_id, fc_host_port_id(adapter->scsi_host), (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn, adisc->hard_nport_id, adisc->nport_id); @@ -847,7 +847,8 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) if (erp_action->fsf_req) { /* take lock to ensure that request is not deleted meanwhile */ spin_lock(&adapter->req_list_lock); - if (zfcp_reqlist_find(adapter, erp_action->fsf_req->req_id)) { + if (zfcp_reqlist_ismember(adapter, + erp_action->fsf_req->req_id)) { /* fsf_req still exists */ debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req, @@ -1376,7 +1377,7 @@ zfcp_erp_port_failed(struct zfcp_port *port) if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) ZFCP_LOG_NORMAL("port erp failed (adapter %s, " - "port d_id=0x%06x)\n", + "port d_id=0x%08x)\n", zfcp_get_busid_by_port(port), port->d_id); else ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n", @@ -1590,62 +1591,6 @@ zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result) return result; } -struct zfcp_erp_add_work { - struct zfcp_unit *unit; - struct work_struct work; -}; - -/** - * zfcp_erp_scsi_scan - * @data: pointer to a struct zfcp_erp_add_work - * - * Registers a logical unit with the SCSI stack. - */ -static void zfcp_erp_scsi_scan(struct work_struct *work) -{ - struct zfcp_erp_add_work *p = - container_of(work, struct zfcp_erp_add_work, work); - struct zfcp_unit *unit = p->unit; - struct fc_rport *rport = unit->port->rport; - scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, - unit->scsi_lun, 0); - atomic_clear_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); - wake_up(&unit->scsi_scan_wq); - zfcp_unit_put(unit); - kfree(p); -} - -/** - * zfcp_erp_schedule_work - * @unit: pointer to unit which should be registered with SCSI stack - * - * Schedules work which registers a unit with the SCSI stack - */ -static void -zfcp_erp_schedule_work(struct zfcp_unit *unit) -{ - struct zfcp_erp_add_work *p; - - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (!p) { - ZFCP_LOG_NORMAL("error: Out of resources. Could not register " - "the FCP-LUN 0x%Lx connected to " - "the port with WWPN 0x%Lx connected to " - "the adapter %s with the SCSI stack.\n", - unit->fcp_lun, - unit->port->wwpn, - zfcp_get_busid_by_unit(unit)); - return; - } - - zfcp_unit_get(unit); - memset(p, 0, sizeof(*p)); - atomic_set_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, &unit->status); - INIT_WORK(&p->work, zfcp_erp_scsi_scan); - p->unit = unit; - schedule_work(&p->work); -} - /* * function: * @@ -2456,7 +2401,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) retval = ZFCP_ERP_FAILED; } } else { - ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%06x -> " + ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> " "trying open\n", port->wwpn, port->d_id); retval = zfcp_erp_port_strategy_open_port(erp_action); } @@ -2496,7 +2441,7 @@ zfcp_erp_port_strategy_open_nameserver(struct zfcp_erp_action *erp_action) case ZFCP_ERP_STEP_UNINITIALIZED: case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: case ZFCP_ERP_STEP_PORT_CLOSING: - ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%06x -> trying open\n", + ZFCP_LOG_DEBUG("port 0x%016Lx has d_id=0x%08x -> trying open\n", port->wwpn, port->d_id); retval = zfcp_erp_port_strategy_open_port(erp_action); break; @@ -3147,9 +3092,9 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, && port->rport) { atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); - if (atomic_test_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, - &unit->status) == 0) - zfcp_erp_schedule_work(unit); + scsi_scan_target(&port->rport->dev, 0, + port->rport->scsi_target_id, + unit->scsi_lun, 0); } zfcp_unit_put(unit); break; @@ -3176,7 +3121,7 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, zfcp_get_busid_by_port(port), port->wwpn); else { - scsi_target_unblock(&port->rport->dev); + scsi_flush_work(adapter->scsi_host); port->rport->maxframe_size = port->maxframe_size; port->rport->supported_classes = port->supported_classes; diff --git a/trunk/drivers/s390/scsi/zfcp_ext.h b/trunk/drivers/s390/scsi/zfcp_ext.h index 991d45667a44..01386ac688a2 100644 --- a/trunk/drivers/s390/scsi/zfcp_ext.h +++ b/trunk/drivers/s390/scsi/zfcp_ext.h @@ -184,6 +184,10 @@ extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, unsigned long); extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, struct scsi_cmnd *); +extern void zfcp_reqlist_add(struct zfcp_adapter *, struct zfcp_fsf_req *); +extern void zfcp_reqlist_remove(struct zfcp_adapter *, unsigned long); +extern struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *, + unsigned long); extern int zfcp_reqlist_isempty(struct zfcp_adapter *); #endif /* ZFCP_EXT_H */ diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c index a8b02542ac2d..ef16f7ca4bb1 100644 --- a/trunk/drivers/s390/scsi/zfcp_fsf.c +++ b/trunk/drivers/s390/scsi/zfcp_fsf.c @@ -299,10 +299,9 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) } /* log additional information provided by FSF (if any) */ - if (likely(qtcb->header.log_length)) { + if (unlikely(qtcb->header.log_length)) { /* do not trust them ;-) */ - if (unlikely(qtcb->header.log_start > - sizeof(struct fsf_qtcb))) { + if (qtcb->header.log_start > sizeof(struct fsf_qtcb)) { ZFCP_LOG_NORMAL ("bug: ULP (FSF logging) log data starts " "beyond end of packet header. Ignored. " @@ -311,9 +310,8 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) sizeof(struct fsf_qtcb)); goto forget_log; } - if (unlikely((size_t) (qtcb->header.log_start + - qtcb->header.log_length) > - sizeof(struct fsf_qtcb))) { + if ((size_t) (qtcb->header.log_start + qtcb->header.log_length) + > sizeof(struct fsf_qtcb)) { ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends " "beyond end of packet header. Ignored. " "(start=%i, length=%i, size=%li)\n", @@ -828,7 +826,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) if (!port || (port->d_id != (status_buffer->d_id & ZFCP_DID_MASK))) { ZFCP_LOG_NORMAL("bug: Reopen port indication received for" - "nonexisting port with d_id 0x%06x on " + "nonexisting port with d_id 0x%08x on " "adapter %s. Ignored.\n", status_buffer->d_id & ZFCP_DID_MASK, zfcp_get_busid_by_adapter(adapter)); @@ -853,7 +851,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) &status_buffer->status_subtype, sizeof (u32)); ZFCP_LOG_NORMAL("bug: Undefined status subtype received " "for a reopen indication on port with " - "d_id 0x%06x on the adapter %s. " + "d_id 0x%08x on the adapter %s. " "Ignored. (debug info 0x%x)\n", status_buffer->d_id, zfcp_get_busid_by_adapter(adapter), @@ -1156,7 +1154,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id, } ZFCP_LOG_DEBUG("Abort FCP Command request initiated " - "(adapter%s, port d_id=0x%06x, " + "(adapter%s, port d_id=0x%08x, " "unit x%016Lx, old_req_id=0x%lx)\n", zfcp_get_busid_by_adapter(adapter), unit->port->d_id, @@ -1554,7 +1552,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) case FSF_ACCESS_DENIED: ZFCP_LOG_NORMAL("access denied, cannot send generic service " - "command (adapter %s, port d_id=0x%06x)\n", + "command (adapter %s, port d_id=0x%08x)\n", zfcp_get_busid_by_port(port), port->d_id); for (counter = 0; counter < 2; counter++) { subtable = header->fsf_status_qual.halfword[counter * 2]; @@ -1576,7 +1574,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) case FSF_GENERIC_COMMAND_REJECTED: ZFCP_LOG_INFO("generic service command rejected " - "(adapter %s, port d_id=0x%06x)\n", + "(adapter %s, port d_id=0x%08x)\n", zfcp_get_busid_by_port(port), port->d_id); ZFCP_LOG_INFO("status qualifier:\n"); ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, @@ -1602,7 +1600,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) case FSF_PORT_BOXED: ZFCP_LOG_INFO("port needs to be reopened " - "(adapter %s, port d_id=0x%06x)\n", + "(adapter %s, port d_id=0x%08x)\n", zfcp_get_busid_by_port(port), port->d_id); debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed"); zfcp_erp_port_boxed(port); @@ -1683,7 +1681,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) NULL, &lock_flags, &fsf_req); if (ret < 0) { ZFCP_LOG_INFO("error: creation of ELS request failed " - "(adapter %s, port d_id: 0x%06x)\n", + "(adapter %s, port d_id: 0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); goto failed_req; } @@ -1708,7 +1706,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) ZFCP_MAX_SBALS_PER_ELS_REQ); if (bytes <= 0) { ZFCP_LOG_INFO("error: creation of ELS request failed " - "(adapter %s, port d_id: 0x%06x)\n", + "(adapter %s, port d_id: 0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); if (bytes == 0) { ret = -ENOMEM; @@ -1725,7 +1723,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) ZFCP_MAX_SBALS_PER_ELS_REQ); if (bytes <= 0) { ZFCP_LOG_INFO("error: creation of ELS request failed " - "(adapter %s, port d_id: 0x%06x)\n", + "(adapter %s, port d_id: 0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); if (bytes == 0) { ret = -ENOMEM; @@ -1739,7 +1737,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) /* reject request */ ZFCP_LOG_INFO("error: microcode does not support chained SBALs" ", ELS request too big (adapter %s, " - "port d_id: 0x%06x)\n", + "port d_id: 0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); ret = -EOPNOTSUPP; goto failed_send; @@ -1760,13 +1758,13 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) ret = zfcp_fsf_req_send(fsf_req); if (ret) { ZFCP_LOG_DEBUG("error: initiation of ELS request failed " - "(adapter %s, port d_id: 0x%06x)\n", + "(adapter %s, port d_id: 0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); goto failed_send; } ZFCP_LOG_DEBUG("ELS request initiated (adapter %s, port d_id: " - "0x%06x)\n", zfcp_get_busid_by_adapter(adapter), d_id); + "0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); goto out; failed_send: @@ -1859,7 +1857,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) case FSF_ELS_COMMAND_REJECTED: ZFCP_LOG_INFO("ELS has been rejected because command filter " "prohibited sending " - "(adapter: %s, port d_id: 0x%06x)\n", + "(adapter: %s, port d_id: 0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); break; @@ -1907,7 +1905,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) case FSF_ACCESS_DENIED: ZFCP_LOG_NORMAL("access denied, cannot send ELS command " - "(adapter %s, port d_id=0x%06x)\n", + "(adapter %s, port d_id=0x%08x)\n", zfcp_get_busid_by_adapter(adapter), d_id); for (counter = 0; counter < 2; counter++) { subtable = header->fsf_status_qual.halfword[counter * 2]; @@ -2070,7 +2068,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" "WWNN 0x%016Lx, " "WWPN 0x%016Lx, " - "S_ID 0x%06x,\n" + "S_ID 0x%08x,\n" "adapter version 0x%x, " "LIC version 0x%x, " "FC link speed %d Gb/s\n", @@ -3043,7 +3041,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) queue_designator = &header->fsf_status_qual.fsf_queue_designator; atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | - ZFCP_STATUS_COMMON_ACCESS_BOXED | ZFCP_STATUS_UNIT_SHARED | ZFCP_STATUS_UNIT_READONLY, &unit->status); @@ -4646,22 +4643,23 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, fsf_req->adapter = adapter; fsf_req->fsf_command = fsf_cmd; INIT_LIST_HEAD(&fsf_req->list); + + /* this is serialized (we are holding req_queue-lock of adapter */ + if (adapter->req_no == 0) + adapter->req_no++; + fsf_req->req_id = adapter->req_no++; + init_timer(&fsf_req->timer); + zfcp_fsf_req_qtcb_init(fsf_req); /* initialize waitqueue which may be used to wait on this request completion */ init_waitqueue_head(&fsf_req->completion_wq); ret = zfcp_fsf_req_sbal_get(adapter, req_flags, lock_flags); - if (ret < 0) + if(ret < 0) { goto failed_sbals; - - /* this is serialized (we are holding req_queue-lock of adapter) */ - if (adapter->req_no == 0) - adapter->req_no++; - fsf_req->req_id = adapter->req_no++; - - zfcp_fsf_req_qtcb_init(fsf_req); + } /* * We hold queue_lock here. Check if QDIOUP is set and let request fail @@ -4788,7 +4786,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) retval = -EIO; del_timer(&fsf_req->timer); spin_lock(&adapter->req_list_lock); - zfcp_reqlist_remove(adapter, fsf_req); + zfcp_reqlist_remove(adapter, fsf_req->req_id); spin_unlock(&adapter->req_list_lock); /* undo changes in request queue made for this request */ zfcp_qdio_zero_sbals(req_queue->buffer, diff --git a/trunk/drivers/s390/scsi/zfcp_qdio.c b/trunk/drivers/s390/scsi/zfcp_qdio.c index cb08ca3cc0f9..1e12a78e8edd 100644 --- a/trunk/drivers/s390/scsi/zfcp_qdio.c +++ b/trunk/drivers/s390/scsi/zfcp_qdio.c @@ -283,10 +283,10 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device, } /** - * zfcp_qdio_reqid_check - checks for valid reqids. + * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status */ -static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, - unsigned long req_id) +static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, + unsigned long req_id) { struct zfcp_fsf_req *fsf_req; unsigned long flags; @@ -294,22 +294,23 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, debug_long_event(adapter->erp_dbf, 4, req_id); spin_lock_irqsave(&adapter->req_list_lock, flags); - fsf_req = zfcp_reqlist_find(adapter, req_id); + fsf_req = zfcp_reqlist_ismember(adapter, req_id); - if (!fsf_req) - /* - * Unknown request means that we have potentially memory - * corruption and must stop the machine immediatly. - */ - panic("error: unknown request id (%ld) on adapter %s.\n", - req_id, zfcp_get_busid_by_adapter(adapter)); + if (!fsf_req) { + spin_unlock_irqrestore(&adapter->req_list_lock, flags); + ZFCP_LOG_NORMAL("error: unknown request id (%ld).\n", req_id); + zfcp_erp_adapter_reopen(adapter, 0); + return -EINVAL; + } - zfcp_reqlist_remove(adapter, fsf_req); + zfcp_reqlist_remove(adapter, req_id); atomic_dec(&adapter->reqs_active); spin_unlock_irqrestore(&adapter->req_list_lock, flags); /* finish the FSF request */ zfcp_fsf_req_complete(fsf_req); + + return 0; } /* @@ -373,9 +374,27 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device, /* look for QDIO request identifiers in SB */ buffere = &buffer->element[buffere_index]; - zfcp_qdio_reqid_check(adapter, - (unsigned long) buffere->addr); - + retval = zfcp_qdio_reqid_check(adapter, + (unsigned long) buffere->addr); + + if (retval) { + ZFCP_LOG_NORMAL("bug: unexpected inbound " + "packet on adapter %s " + "(reqid=0x%lx, " + "first_element=%d, " + "elements_processed=%d)\n", + zfcp_get_busid_by_adapter(adapter), + (unsigned long) buffere->addr, + first_element, + elements_processed); + ZFCP_LOG_NORMAL("hex dump of inbound buffer " + "at address %p " + "(buffer_index=%d, " + "buffere_index=%d)\n", buffer, + buffer_index, buffere_index); + ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, + (char *) buffer, SBAL_SIZE); + } /* * A single used SBALE per inbound SBALE has been * implemented by QDIO so far. Hope they will diff --git a/trunk/drivers/s390/scsi/zfcp_scsi.c b/trunk/drivers/s390/scsi/zfcp_scsi.c index 16e2d64658af..99db02062c3b 100644 --- a/trunk/drivers/s390/scsi/zfcp_scsi.c +++ b/trunk/drivers/s390/scsi/zfcp_scsi.c @@ -22,7 +22,6 @@ #define ZFCP_LOG_AREA ZFCP_LOG_AREA_SCSI #include "zfcp_ext.h" -#include static void zfcp_scsi_slave_destroy(struct scsi_device *sdp); static int zfcp_scsi_slave_alloc(struct scsi_device *sdp); @@ -180,10 +179,6 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; if (unit) { - zfcp_erp_wait(unit->port->adapter); - wait_event(unit->scsi_scan_wq, - atomic_test_mask(ZFCP_STATUS_UNIT_SCSI_WORK_PENDING, - &unit->status) == 0); atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); sdpnt->hostdata = NULL; unit->device = NULL; @@ -407,8 +402,8 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) /* Check whether corresponding fsf_req is still pending */ spin_lock(&adapter->req_list_lock); - fsf_req = zfcp_reqlist_find(adapter, - (unsigned long) scpnt->host_scribble); + fsf_req = zfcp_reqlist_ismember(adapter, (unsigned long) + scpnt->host_scribble); spin_unlock(&adapter->req_list_lock); if (!fsf_req) { write_unlock_irqrestore(&adapter->abort_lock, flags); diff --git a/trunk/drivers/sbus/char/bpp.c b/trunk/drivers/sbus/char/bpp.c index 74b999d77bbf..a39ee80c9715 100644 --- a/trunk/drivers/sbus/char/bpp.c +++ b/trunk/drivers/sbus/char/bpp.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/sbus/char/rtc.c b/trunk/drivers/sbus/char/rtc.c index 18d18f1a114e..94d185829119 100644 --- a/trunk/drivers/sbus/char/rtc.c +++ b/trunk/drivers/sbus/char/rtc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/sbus/char/vfc_dev.c b/trunk/drivers/sbus/char/vfc_dev.c index 6afc7e5df0d4..c3135e2fbd5a 100644 --- a/trunk/drivers/sbus/char/vfc_dev.c +++ b/trunk/drivers/sbus/char/vfc_dev.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/sbus/sbus.c b/trunk/drivers/sbus/sbus.c index 002643392d42..eee590a51d8a 100644 --- a/trunk/drivers/sbus/sbus.c +++ b/trunk/drivers/sbus/sbus.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/scsi/BusLogic.c b/trunk/drivers/scsi/BusLogic.c index 96f4cab07614..e874b8944875 100644 --- a/trunk/drivers/scsi/BusLogic.c +++ b/trunk/drivers/scsi/BusLogic.c @@ -579,17 +579,17 @@ static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapt /* Append the list of standard BusLogic MultiMaster ISA I/O Addresses. */ - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe330) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x330); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe334) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x334); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe230) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x230); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe234) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x234); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe130) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x130); - if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe134) + if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0) BusLogic_AppendProbeAddressISA(0x134); } @@ -795,9 +795,7 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd host adapters are probed. */ if (!BusLogic_ProbeOptions.NoProbeISA) - if (PrimaryProbeInfo->IO_Address == 0 && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe330)) { + if (PrimaryProbeInfo->IO_Address == 0 && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)) { PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster; PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus; PrimaryProbeInfo->IO_Address = 0x330; @@ -807,25 +805,15 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd omitting the Primary I/O Address which has already been handled. */ if (!BusLogic_ProbeOptions.NoProbeISA) { - if (!StandardAddressSeen[1] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe334)) + if (!StandardAddressSeen[1] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x334); - if (!StandardAddressSeen[2] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe230)) + if (!StandardAddressSeen[2] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x230); - if (!StandardAddressSeen[3] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe234)) + if (!StandardAddressSeen[3] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x234); - if (!StandardAddressSeen[4] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe130)) + if (!StandardAddressSeen[4] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x130); - if (!StandardAddressSeen[5] && - (!BusLogic_ProbeOptions.LimitedProbeISA || - BusLogic_ProbeOptions.Probe134)) + if (!StandardAddressSeen[5] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)) BusLogic_AppendProbeAddressISA(0x134); } /* @@ -2232,35 +2220,22 @@ static int __init BusLogic_init(void) HostAdapter->PCI_Device = ProbeInfo->PCI_Device; HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel; HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType]; - - /* - Make sure region is free prior to probing. - */ - if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, - "BusLogic")) - continue; /* Probe the Host Adapter. If unsuccessful, abort further initialization. */ - if (!BusLogic_ProbeHostAdapter(HostAdapter)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue; - } /* Hard Reset the Host Adapter. If unsuccessful, abort further initialization. */ - if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue; - } /* Check the Host Adapter. If unsuccessful, abort further initialization. */ - if (!BusLogic_CheckHostAdapter(HostAdapter)) { - release_region(HostAdapter->IO_Address, HostAdapter->AddressCount); + if (!BusLogic_CheckHostAdapter(HostAdapter)) continue; - } /* Initialize the Driver Options field if provided. */ @@ -2271,6 +2246,16 @@ static int __init BusLogic_init(void) and Electronic Mail Address. */ BusLogic_AnnounceDriver(HostAdapter); + /* + Register usage of the I/O Address range. From this point onward, any + failure will be assumed to be due to a problem with the Host Adapter, + rather than due to having mistakenly identified this port as belonging + to a BusLogic Host Adapter. The I/O Address range will not be + released, thereby preventing it from being incorrectly identified as + any other type of Host Adapter. + */ + if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, "BusLogic")) + continue; /* Register the SCSI Host structure. */ @@ -2295,12 +2280,6 @@ static int __init BusLogic_init(void) Acquire the System Resources necessary to use the Host Adapter, then Create the Initial CCBs, Initialize the Host Adapter, and finally perform Target Device Inquiry. - - From this point onward, any failure will be assumed to be due to a - problem with the Host Adapter, rather than due to having mistakenly - identified this port as belonging to a BusLogic Host Adapter. The - I/O Address range will not be released, thereby preventing it from - being incorrectly identified as any other type of Host Adapter. */ if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) && BusLogic_ReportHostAdapterConfiguration(HostAdapter) && @@ -3619,7 +3598,6 @@ static void __exit BusLogic_exit(void) __setup("BusLogic=", BusLogic_Setup); -#ifdef MODULE static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -3629,7 +3607,6 @@ static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { } }; -#endif MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl); module_init(BusLogic_init); diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index e62d23f65180..fcc4cb6c7f46 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -170,7 +170,7 @@ config CHR_DEV_SCH If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), - say M here and read and + say M here and read and . The module will be called ch.o. If unsure, say N. @@ -241,12 +241,6 @@ config SCSI_SCAN_ASYNC You can override this choice by specifying "scsi_mod.scan=sync" or async on the kernel's command line. -config SCSI_WAIT_SCAN - tristate - default m - depends on SCSI - depends on MODULES - menu "SCSI Transports" depends on SCSI @@ -1200,6 +1194,17 @@ config SCSI_NCR53C8XX_SYNC There is no safe option other than using good cabling, right terminations and SCSI conformant devices. +config SCSI_NCR53C8XX_PROFILE + bool "enable profiling" + depends on SCSI_ZALON || SCSI_NCR_Q720 + help + This option allows you to enable profiling information gathering. + These statistics are not very accurate due to the low frequency + of the kernel clock (100 Hz on i386) and have performance impact + on systems that use very fast devices. + + The normal answer therefore is N. + config SCSI_NCR53C8XX_NO_DISCONNECT bool "not allow targets to disconnect" depends on (SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0 @@ -1329,6 +1334,11 @@ config SCSI_SIM710 It currently supports Compaq EISA cards and NCR MCA cards +config 53C700_IO_MAPPED + bool + depends on SCSI_SIM710 + default y + config SCSI_SYM53C416 tristate "Symbios 53c416 SCSI support" depends on ISA && SCSI @@ -1639,7 +1649,7 @@ config OKTAGON_SCSI config ATARI_SCSI tristate "Atari native SCSI support" - depends on ATARI && SCSI + depends on ATARI && SCSI && BROKEN select SCSI_SPI_ATTRS ---help--- If you have an Atari with built-in NCR5380 SCSI controller (TT, @@ -1783,7 +1793,7 @@ config ZFCP This driver is also available as a module. This module will be called zfcp. If you want to compile it as a module, say M here - and read . + and read . config SCSI_SRP tristate "SCSI RDMA Protocol helper library" diff --git a/trunk/drivers/scsi/Makefile b/trunk/drivers/scsi/Makefile index 51e884fa10b0..70cff4c599d7 100644 --- a/trunk/drivers/scsi/Makefile +++ b/trunk/drivers/scsi/Makefile @@ -146,7 +146,7 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o # This goes last, so that "real" scsi devices probe earlier obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o -obj-$(CONFIG_SCSI_WAIT_SCAN) += scsi_wait_scan.o +obj-$(CONFIG_SCSI) += scsi_wait_scan.o scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ scsicam.o scsi_error.o scsi_lib.o \ diff --git a/trunk/drivers/scsi/aacraid/aachba.c b/trunk/drivers/scsi/aacraid/aachba.c index 1e82c69b36b0..d789e61bdc49 100644 --- a/trunk/drivers/scsi/aacraid/aachba.c +++ b/trunk/drivers/scsi/aacraid/aachba.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * 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 @@ -172,30 +172,6 @@ MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. int expose_physicals = -1; module_param(expose_physicals, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(expose_physicals, "Expose physical components of the arrays. -1=protect 0=off, 1=on"); - - -static inline int aac_valid_context(struct scsi_cmnd *scsicmd, - struct fib *fibptr) { - struct scsi_device *device; - - if (unlikely(!scsicmd || !scsicmd->scsi_done )) { - dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n")) -; - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - return 0; - } - scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; - device = scsicmd->device; - if (unlikely(!device || !scsi_device_online(device))) { - dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n")); - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - return 0; - } - return 1; -} - /** * aac_get_config_status - check the adapter configuration * @common: adapter to query @@ -282,10 +258,13 @@ int aac_get_containers(struct aac_dev *dev) u32 index; int status = 0; struct fib * fibptr; + unsigned instance; struct aac_get_container_count *dinfo; struct aac_get_container_count_resp *dresp; int maximum_num_containers = MAXIMUM_NUM_CONTAINERS; + instance = dev->scsi_host_ptr->unique_id; + if (!(fibptr = aac_fib_alloc(dev))) return -ENOMEM; @@ -305,35 +284,88 @@ int aac_get_containers(struct aac_dev *dev) maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); aac_fib_complete(fibptr); } - aac_fib_free(fibptr); if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) maximum_num_containers = MAXIMUM_NUM_CONTAINERS; - fsa_dev_ptr = kmalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers, - GFP_KERNEL); - if (!fsa_dev_ptr) + fsa_dev_ptr = kmalloc( + sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL); + if (!fsa_dev_ptr) { + aac_fib_free(fibptr); return -ENOMEM; + } memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); dev->fsa_dev = fsa_dev_ptr; dev->maximum_num_containers = maximum_num_containers; - for (index = 0; index < dev->maximum_num_containers; ) { + for (index = 0; index < dev->maximum_num_containers; index++) { + struct aac_query_mount *dinfo; + struct aac_mount *dresp; + fsa_dev_ptr[index].devname[0] = '\0'; - status = aac_probe_container(dev, index); + aac_fib_init(fibptr); + dinfo = (struct aac_query_mount *) fib_data(fibptr); + + dinfo->command = cpu_to_le32(VM_NameServe); + dinfo->count = cpu_to_le32(index); + dinfo->type = cpu_to_le32(FT_FILESYS); - if (status < 0) { + status = aac_fib_send(ContainerCommand, + fibptr, + sizeof (struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL); + if (status < 0 ) { printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n"); break; } + dresp = (struct aac_mount *)fib_data(fibptr); + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { + dinfo->command = cpu_to_le32(VM_NameServe64); + dinfo->count = cpu_to_le32(index); + dinfo->type = cpu_to_le32(FT_FILESYS); + + if (aac_fib_send(ContainerCommand, + fibptr, + sizeof(struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL) < 0) + continue; + } else + dresp->mnt[0].capacityhigh = 0; + + dprintk ((KERN_DEBUG + "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%llu\n", + (int)index, (int)le32_to_cpu(dresp->status), + (int)le32_to_cpu(dresp->mnt[0].vol), + (int)le32_to_cpu(dresp->mnt[0].state), + ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32))); + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && + (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { + fsa_dev_ptr[index].valid = 1; + fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol); + fsa_dev_ptr[index].size + = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); + if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) + fsa_dev_ptr[index].ro = 1; + } + aac_fib_complete(fibptr); /* * If there are no more containers, then stop asking. */ - if (++index >= status) + if ((index + 1) >= le32_to_cpu(dresp->count)){ break; + } } + aac_fib_free(fibptr); return status; } @@ -350,9 +382,8 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne buf = scsicmd->request_buffer; transfer_len = min(scsicmd->request_bufflen, len + offset); } - transfer_len -= offset; - if (buf && transfer_len) - memcpy(buf + offset, data, transfer_len); + + memcpy(buf + offset, data, transfer_len - offset); if (scsicmd->use_sg) kunmap_atomic(buf - sg->offset, KM_IRQ0); @@ -365,9 +396,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr) struct scsi_cmnd * scsicmd; scsicmd = (struct scsi_cmnd *) context; - - if (!aac_valid_context(scsicmd, fibptr)) - return; + scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); BUG_ON(fibptr == NULL); @@ -402,7 +431,7 @@ static void get_container_name_callback(void *context, struct fib * fibptr) /** * aac_get_container_name - get container name, none blocking. */ -static int aac_get_container_name(struct scsi_cmnd * scsicmd) +static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid) { int status; struct aac_get_name *dinfo; @@ -419,7 +448,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) dinfo->command = cpu_to_le32(VM_ContainerConfig); dinfo->type = cpu_to_le32(CT_READ_NAME); - dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); + dinfo->cid = cpu_to_le32(cid); dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); status = aac_fib_send(ContainerCommand, @@ -444,192 +473,85 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) return -1; } -static int aac_probe_container_callback2(struct scsi_cmnd * scsicmd) -{ - struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; - - if (fsa_dev_ptr[scmd_id(scsicmd)].valid) - return aac_scsi_cmd(scsicmd); - - scsicmd->result = DID_NO_CONNECT << 16; - scsicmd->scsi_done(scsicmd); - return 0; -} - -static int _aac_probe_container2(void * context, struct fib * fibptr) +/** + * aac_probe_container - query a logical volume + * @dev: device to query + * @cid: container identifier + * + * Queries the controller about the given volume. The volume information + * is updated in the struct fsa_dev_info structure rather than returned. + */ + +int aac_probe_container(struct aac_dev *dev, int cid) { struct fsa_dev_info *fsa_dev_ptr; - int (*callback)(struct scsi_cmnd *); - struct scsi_cmnd * scsicmd = (struct scsi_cmnd *)context; - - if (!aac_valid_context(scsicmd, fibptr)) - return 0; - - fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; - - scsicmd->SCp.Status = 0; - if (fsa_dev_ptr) { - struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr); - fsa_dev_ptr += scmd_id(scsicmd); - - if ((le32_to_cpu(dresp->status) == ST_OK) && - (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && - (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { - fsa_dev_ptr->valid = 1; - fsa_dev_ptr->type = le32_to_cpu(dresp->mnt[0].vol); - fsa_dev_ptr->size - = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + - (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); - fsa_dev_ptr->ro = ((le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) != 0); - } - if ((fsa_dev_ptr->valid & 1) == 0) - fsa_dev_ptr->valid = 0; - scsicmd->SCp.Status = le32_to_cpu(dresp->count); - } - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - callback = (int (*)(struct scsi_cmnd *))(scsicmd->SCp.ptr); - scsicmd->SCp.ptr = NULL; - return (*callback)(scsicmd); -} - -static int _aac_probe_container1(void * context, struct fib * fibptr) -{ - struct scsi_cmnd * scsicmd; - struct aac_mount * dresp; - struct aac_query_mount *dinfo; int status; + struct aac_query_mount *dinfo; + struct aac_mount *dresp; + struct fib * fibptr; + unsigned instance; - dresp = (struct aac_mount *) fib_data(fibptr); - dresp->mnt[0].capacityhigh = 0; - if ((le32_to_cpu(dresp->status) != ST_OK) || - (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) - return _aac_probe_container2(context, fibptr); - scsicmd = (struct scsi_cmnd *) context; - scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; + fsa_dev_ptr = dev->fsa_dev; + if (!fsa_dev_ptr) + return -ENOMEM; + instance = dev->scsi_host_ptr->unique_id; - if (!aac_valid_context(scsicmd, fibptr)) - return 0; + if (!(fibptr = aac_fib_alloc(dev))) + return -ENOMEM; aac_fib_init(fibptr); dinfo = (struct aac_query_mount *)fib_data(fibptr); - dinfo->command = cpu_to_le32(VM_NameServe64); - dinfo->count = cpu_to_le32(scmd_id(scsicmd)); + dinfo->command = cpu_to_le32(VM_NameServe); + dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); status = aac_fib_send(ContainerCommand, - fibptr, - sizeof(struct aac_query_mount), - FsaNormal, - 0, 1, - (fib_callback) _aac_probe_container2, - (void *) scsicmd); - /* - * Check that the command queued to the controller - */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; - return 0; - } + fibptr, + sizeof(struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL); if (status < 0) { - /* Inherit results from VM_NameServe, if any */ - dresp->status = cpu_to_le32(ST_OK); - return _aac_probe_container2(context, fibptr); + printk(KERN_WARNING "aacraid: aac_probe_container query failed.\n"); + goto error; } - return 0; -} - -static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(struct scsi_cmnd *)) -{ - struct fib * fibptr; - int status = -ENOMEM; - - if ((fibptr = aac_fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) { - struct aac_query_mount *dinfo; - - aac_fib_init(fibptr); - dinfo = (struct aac_query_mount *)fib_data(fibptr); + dresp = (struct aac_mount *) fib_data(fibptr); - dinfo->command = cpu_to_le32(VM_NameServe); - dinfo->count = cpu_to_le32(scmd_id(scsicmd)); + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) == CT_NONE)) { + dinfo->command = cpu_to_le32(VM_NameServe64); + dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); - scsicmd->SCp.ptr = (char *)callback; - status = aac_fib_send(ContainerCommand, - fibptr, - sizeof(struct aac_query_mount), - FsaNormal, - 0, 1, - (fib_callback) _aac_probe_container1, - (void *) scsicmd); - /* - * Check that the command queued to the controller - */ - if (status == -EINPROGRESS) { - scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; - return 0; - } - if (status < 0) { - scsicmd->SCp.ptr = NULL; - aac_fib_complete(fibptr); - aac_fib_free(fibptr); - } - } - if (status < 0) { - struct fsa_dev_info *fsa_dev_ptr = ((struct aac_dev *)(scsicmd->device->host->hostdata))->fsa_dev; - if (fsa_dev_ptr) { - fsa_dev_ptr += scmd_id(scsicmd); - if ((fsa_dev_ptr->valid & 1) == 0) { - fsa_dev_ptr->valid = 0; - return (*callback)(scsicmd); - } - } - } - return status; -} + if (aac_fib_send(ContainerCommand, + fibptr, + sizeof(struct aac_query_mount), + FsaNormal, + 1, 1, + NULL, NULL) < 0) + goto error; + } else + dresp->mnt[0].capacityhigh = 0; -/** - * aac_probe_container - query a logical volume - * @dev: device to query - * @cid: container identifier - * - * Queries the controller about the given volume. The volume information - * is updated in the struct fsa_dev_info structure rather than returned. - */ -static int aac_probe_container_callback1(struct scsi_cmnd * scsicmd) -{ - scsicmd->device = NULL; - return 0; -} + if ((le32_to_cpu(dresp->status) == ST_OK) && + (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && + (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { + fsa_dev_ptr[cid].valid = 1; + fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol); + fsa_dev_ptr[cid].size + = ((u64)le32_to_cpu(dresp->mnt[0].capacity)) + + (((u64)le32_to_cpu(dresp->mnt[0].capacityhigh)) << 32); + if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) + fsa_dev_ptr[cid].ro = 1; + } -int aac_probe_container(struct aac_dev *dev, int cid) -{ - struct scsi_cmnd *scsicmd = kmalloc(sizeof(*scsicmd), GFP_KERNEL); - struct scsi_device *scsidev = kmalloc(sizeof(*scsidev), GFP_KERNEL); - int status; +error: + aac_fib_complete(fibptr); + aac_fib_free(fibptr); - if (!scsicmd || !scsidev) { - kfree(scsicmd); - kfree(scsidev); - return -ENOMEM; - } - scsicmd->list.next = NULL; - scsicmd->scsi_done = (void (*)(struct scsi_cmnd*))_aac_probe_container1; - - scsicmd->device = scsidev; - scsidev->sdev_state = 0; - scsidev->id = cid; - scsidev->host = dev->scsi_host_ptr; - - if (_aac_probe_container(scsicmd, aac_probe_container_callback1) == 0) - while (scsicmd->device == scsidev) - schedule(); - kfree(scsidev); - status = scsicmd->SCp.Status; - kfree(scsicmd); return status; } @@ -1193,12 +1115,6 @@ int aac_get_adapter_info(struct aac_dev* dev) printk(KERN_INFO "%s%d: serial %x\n", dev->name, dev->id, le32_to_cpu(dev->adapter_info.serial[0])); - if (dev->supplement_adapter_info.VpdInfo.Tsid[0]) { - printk(KERN_INFO "%s%d: TSID %.*s\n", - dev->name, dev->id, - (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), - dev->supplement_adapter_info.VpdInfo.Tsid); - } } dev->nondasd_support = 0; @@ -1325,9 +1241,7 @@ static void io_callback(void *context, struct fib * fibptr) u32 cid; scsicmd = (struct scsi_cmnd *) context; - - if (!aac_valid_context(scsicmd, fibptr)) - return; + scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dev = (struct aac_dev *)scsicmd->device->host->hostdata; cid = scmd_id(scsicmd); @@ -1403,7 +1317,7 @@ static void io_callback(void *context, struct fib * fibptr) scsicmd->scsi_done(scsicmd); } -static int aac_read(struct scsi_cmnd * scsicmd) +static int aac_read(struct scsi_cmnd * scsicmd, int cid) { u64 lba; u32 count; @@ -1417,7 +1331,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) */ switch (scsicmd->cmnd[0]) { case READ_6: - dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid)); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; @@ -1427,7 +1341,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) count = 256; break; case READ_16: - dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a read(16) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 56) | ((u64)scsicmd->cmnd[3] << 48) | @@ -1441,7 +1355,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; break; case READ_12: - dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a read(12) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | @@ -1451,7 +1365,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; break; default: - dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | @@ -1491,7 +1405,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) return 0; } -static int aac_write(struct scsi_cmnd * scsicmd) +static int aac_write(struct scsi_cmnd * scsicmd, int cid) { u64 lba; u32 count; @@ -1510,7 +1424,7 @@ static int aac_write(struct scsi_cmnd * scsicmd) if (count == 0) count = 256; } else if (scsicmd->cmnd[0] == WRITE_16) { /* 16 byte command */ - dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a write(16) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 56) | ((u64)scsicmd->cmnd[3] << 48) | @@ -1522,14 +1436,14 @@ static int aac_write(struct scsi_cmnd * scsicmd) count = (scsicmd->cmnd[10] << 24) | (scsicmd->cmnd[11] << 16) | (scsicmd->cmnd[12] << 8) | scsicmd->cmnd[13]; } else if (scsicmd->cmnd[0] == WRITE_12) { /* 12 byte command */ - dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a write(12) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[6] << 24) | (scsicmd->cmnd[7] << 16) | (scsicmd->cmnd[8] << 8) | scsicmd->cmnd[9]; } else { - dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", scmd_id(scsicmd))); + dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid)); lba = ((u64)scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; } @@ -1574,9 +1488,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) struct scsi_cmnd *cmd; cmd = context; - - if (!aac_valid_context(cmd, fibptr)) - return; + cmd->SCp.phase = AAC_OWNER_MIDLEVEL; dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); @@ -1611,7 +1523,7 @@ static void synchronize_callback(void *context, struct fib *fibptr) cmd->scsi_done(cmd); } -static int aac_synchronize(struct scsi_cmnd *scsicmd) +static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid) { int status; struct fib *cmd_fibcontext; @@ -1656,7 +1568,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd) synchronizecmd = fib_data(cmd_fibcontext); synchronizecmd->command = cpu_to_le32(VM_ContainerConfig); synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE); - synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd)); + synchronizecmd->cid = cpu_to_le32(cid); synchronizecmd->count = cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data)); @@ -1734,12 +1646,29 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) case TEST_UNIT_READY: if (dev->in_reset) return -1; - return _aac_probe_container(scsicmd, - aac_probe_container_callback2); + spin_unlock_irq(host->host_lock); + aac_probe_container(dev, cid); + if ((fsa_dev_ptr[cid].valid & 1) == 0) + fsa_dev_ptr[cid].valid = 0; + spin_lock_irq(host->host_lock); + if (fsa_dev_ptr[cid].valid == 0) { + scsicmd->result = DID_NO_CONNECT << 16; + scsicmd->scsi_done(scsicmd); + return 0; + } default: break; } } + /* + * If the target container still doesn't exist, + * return failure + */ + if (fsa_dev_ptr[cid].valid == 0) { + scsicmd->result = DID_BAD_TARGET << 16; + scsicmd->scsi_done(scsicmd); + return 0; + } } else { /* check for physical non-dasd devices */ if ((dev->nondasd_support == 1) || expose_physicals) { if (dev->in_reset) @@ -1804,7 +1733,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); - return aac_get_container_name(scsicmd); + return aac_get_container_name(scsicmd, cid); } case SERVICE_ACTION_IN: if (!(dev->raw_io_interface) || @@ -1970,7 +1899,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) min(sizeof(fsa_dev_ptr[cid].devname), sizeof(scsicmd->request->rq_disk->disk_name) + 1)); - return aac_read(scsicmd); + return aac_read(scsicmd, cid); case WRITE_6: case WRITE_10: @@ -1978,11 +1907,11 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) case WRITE_16: if (dev->in_reset) return -1; - return aac_write(scsicmd); + return aac_write(scsicmd, cid); case SYNCHRONIZE_CACHE: /* Issue FIB to tell Firmware to flush it's cache */ - return aac_synchronize(scsicmd); + return aac_synchronize(scsicmd, cid); default: /* @@ -2129,10 +2058,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr) struct scsi_cmnd *scsicmd; scsicmd = (struct scsi_cmnd *) context; - - if (!aac_valid_context(scsicmd, fibptr)) - return; - + scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; dev = (struct aac_dev *)scsicmd->device->host->hostdata; BUG_ON(fibptr == NULL); diff --git a/trunk/drivers/scsi/aacraid/aacraid.h b/trunk/drivers/scsi/aacraid/aacraid.h index 45ca3e801619..39ecd0d22eb0 100644 --- a/trunk/drivers/scsi/aacraid/aacraid.h +++ b/trunk/drivers/scsi/aacraid/aacraid.h @@ -12,8 +12,8 @@ *----------------------------------------------------------------------------*/ #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 2437 -# define AAC_DRIVER_BRANCH "-mh4" +# define AAC_DRIVER_BUILD 2423 +# define AAC_DRIVER_BRANCH "-mh3" #endif #define MAXIMUM_NUM_CONTAINERS 32 @@ -48,13 +48,49 @@ struct diskparm /* - * Firmware constants + * DON'T CHANGE THE ORDER, this is set by the firmware */ #define CT_NONE 0 +#define CT_VOLUME 1 +#define CT_MIRROR 2 +#define CT_STRIPE 3 +#define CT_RAID5 4 +#define CT_SSRW 5 +#define CT_SSRO 6 +#define CT_MORPH 7 +#define CT_PASSTHRU 8 +#define CT_RAID4 9 +#define CT_RAID10 10 /* stripe of mirror */ +#define CT_RAID00 11 /* stripe of stripe */ +#define CT_VOLUME_OF_MIRRORS 12 /* volume of mirror */ +#define CT_PSEUDO_RAID 13 /* really raid4 */ +#define CT_LAST_VOLUME_TYPE 14 #define CT_OK 218 + +/* + * Types of objects addressable in some fashion by the client. + * This is a superset of those objects handled just by the filesystem + * and includes "raw" objects that an administrator would use to + * configure containers and filesystems. + */ + +#define FT_REG 1 /* regular file */ +#define FT_DIR 2 /* directory */ +#define FT_BLK 3 /* "block" device - reserved */ +#define FT_CHR 4 /* "character special" device - reserved */ +#define FT_LNK 5 /* symbolic link */ +#define FT_SOCK 6 /* socket */ +#define FT_FIFO 7 /* fifo */ #define FT_FILESYS 8 /* ADAPTEC's "FSA"(tm) filesystem */ #define FT_DRIVE 9 /* physical disk - addressable in scsi by bus/id/lun */ +#define FT_SLICE 10 /* virtual disk - raw volume - slice */ +#define FT_PARTITION 11 /* FSA partition - carved out of a slice - building block for containers */ +#define FT_VOLUME 12 /* Container - Volume Set */ +#define FT_STRIPE 13 /* Container - Stripe Set */ +#define FT_MIRROR 14 /* Container - Mirror Set */ +#define FT_RAID5 15 /* Container - Raid 5 Set */ +#define FT_DATABASE 16 /* Storage object with "foreign" content manager */ /* * Host side memory scatter gather list @@ -461,7 +497,6 @@ struct adapter_ops void (*adapter_enable_int)(struct aac_dev *dev); int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); int (*adapter_check_health)(struct aac_dev *dev); - int (*adapter_restart)(struct aac_dev *dev, int bled); /* Transport operations */ int (*adapter_ioremap)(struct aac_dev * dev, u32 size); irqreturn_t (*adapter_intr)(int irq, void *dev_id); @@ -798,7 +833,7 @@ struct fib { */ struct list_head fiblink; void *data; - struct hw_fib *hw_fib_va; /* Actual shared object */ + struct hw_fib *hw_fib; /* Actual shared object */ dma_addr_t hw_fib_pa; /* physical address of hw_fib*/ }; @@ -843,25 +878,10 @@ struct aac_supplement_adapter_info __le32 Version; __le32 FeatureBits; u8 SlotNumber; - u8 ReservedPad0[3]; + u8 ReservedPad0[0]; u8 BuildDate[12]; __le32 CurrentNumberPorts; - struct { - u8 AssemblyPn[8]; - u8 FruPn[8]; - u8 BatteryFruPn[8]; - u8 EcVersionString[8]; - u8 Tsid[12]; - } VpdInfo; - __le32 FlashFirmwareRevision; - __le32 FlashFirmwareBuild; - __le32 RaidTypeMorphOptions; - __le32 FlashFirmwareBootRevision; - __le32 FlashFirmwareBootBuild; - u8 MfgPcbaSerialNo[12]; - u8 MfgWWNName[8]; - __le32 MoreFeatureBits; - __le32 ReservedGrowth[1]; + __le32 ReservedGrowth[24]; }; #define AAC_FEATURE_FALCON 0x00000010 #define AAC_SIS_VERSION_V3 3 @@ -950,6 +970,7 @@ struct aac_dev struct fib *fibs; struct fib *free_fib; + struct fib *timeout_fib; spinlock_t fib_lock; struct aac_queue_block *queues; @@ -1039,9 +1060,6 @@ struct aac_dev #define aac_adapter_check_health(dev) \ (dev)->a_ops.adapter_check_health(dev) -#define aac_adapter_restart(dev,bled) \ - (dev)->a_ops.adapter_restart(dev,bled) - #define aac_adapter_ioremap(dev, size) \ (dev)->a_ops.adapter_ioremap(dev, size) @@ -1498,7 +1516,8 @@ struct aac_mntent { struct creation_info create_info; /* if applicable */ __le32 capacity; __le32 vol; /* substrate structure */ - __le32 obj; /* FT_FILESYS, etc. */ + __le32 obj; /* FT_FILESYS, + FT_DATABASE, etc. */ __le32 state; /* unready for mounting, readonly, etc. */ union aac_contentinfo fileinfo; /* Info specific to content @@ -1798,7 +1817,7 @@ int aac_fib_send(u16 command, struct fib * context, unsigned long size, int prio int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry); void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum); int aac_fib_complete(struct fib * context); -#define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data) +#define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) struct aac_dev *aac_init_adapter(struct aac_dev *dev); int aac_get_config_status(struct aac_dev *dev, int commit_flag); int aac_get_containers(struct aac_dev *dev); @@ -1821,11 +1840,8 @@ struct aac_driver_ident* aac_get_driver_ident(int devtype); int aac_get_adapter_info(struct aac_dev* dev); int aac_send_shutdown(struct aac_dev *dev); int aac_probe_container(struct aac_dev *dev, int cid); -int _aac_rx_init(struct aac_dev *dev); -int aac_rx_select_comm(struct aac_dev *dev, int comm); extern int numacb; extern int acbsize; extern char aac_driver_version[]; extern int startup_timeout; extern int aif_timeout; -extern int expose_physicals; diff --git a/trunk/drivers/scsi/aacraid/commctrl.c b/trunk/drivers/scsi/aacraid/commctrl.c index 72b0393b4596..e21070f4eac1 100644 --- a/trunk/drivers/scsi/aacraid/commctrl.c +++ b/trunk/drivers/scsi/aacraid/commctrl.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * 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 @@ -64,15 +64,12 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) unsigned size; int retval; - if (dev->in_reset) { - return -EBUSY; - } fibptr = aac_fib_alloc(dev); if(fibptr == NULL) { return -ENOMEM; } - kfib = fibptr->hw_fib_va; + kfib = fibptr->hw_fib; /* * First copy in the header so that we can check the size field. */ @@ -94,9 +91,9 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) goto cleanup; } /* Highjack the hw_fib */ - hw_fib = fibptr->hw_fib_va; + hw_fib = fibptr->hw_fib; hw_fib_pa = fibptr->hw_fib_pa; - fibptr->hw_fib_va = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); + fibptr->hw_fib = kfib = pci_alloc_consistent(dev->pdev, size, &fibptr->hw_fib_pa); memset(((char *)kfib) + dev->max_fib_size, 0, size - dev->max_fib_size); memcpy(kfib, hw_fib, dev->max_fib_size); } @@ -140,7 +137,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) if (hw_fib) { pci_free_consistent(dev->pdev, size, kfib, fibptr->hw_fib_pa); fibptr->hw_fib_pa = hw_fib_pa; - fibptr->hw_fib_va = hw_fib; + fibptr->hw_fib = hw_fib; } if (retval != -EINTR) aac_fib_free(fibptr); @@ -285,15 +282,15 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg) fib = list_entry(entry, struct fib, fiblink); fibctx->count--; spin_unlock_irqrestore(&dev->fib_lock, flags); - if (copy_to_user(f.fib, fib->hw_fib_va, sizeof(struct hw_fib))) { - kfree(fib->hw_fib_va); + if (copy_to_user(f.fib, fib->hw_fib, sizeof(struct hw_fib))) { + kfree(fib->hw_fib); kfree(fib); return -EFAULT; } /* * Free the space occupied by this copy of the fib. */ - kfree(fib->hw_fib_va); + kfree(fib->hw_fib); kfree(fib); status = 0; } else { @@ -343,7 +340,7 @@ int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context * fibctx) /* * Free the space occupied by this copy of the fib. */ - kfree(fib->hw_fib_va); + kfree(fib->hw_fib); kfree(fib); } /* @@ -391,8 +388,10 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg) /* * Extract the fibctx from the input parameters */ - if (fibctx->unique == (u32)(ptrdiff_t)arg) /* We found a winner */ + if (fibctx->unique == (u32)(unsigned long)arg) { + /* We found a winner */ break; + } entry = entry->next; fibctx = NULL; } @@ -466,20 +465,16 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) void *sg_list[32]; u32 sg_indx = 0; u32 byte_count = 0; - u32 actual_fibsize64, actual_fibsize = 0; + u32 actual_fibsize = 0; int i; - if (dev->in_reset) { - dprintk((KERN_DEBUG"aacraid: send raw srb -EBUSY\n")); - return -EBUSY; - } if (!capable(CAP_SYS_ADMIN)){ dprintk((KERN_DEBUG"aacraid: No permission to send raw srb\n")); return -EPERM; } /* - * Allocate and initialize a Fib then setup a SRB command + * Allocate and initialize a Fib then setup a BlockWrite command */ if (!(srbfib = aac_fib_alloc(dev))) { return -ENOMEM; @@ -546,183 +541,129 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) rcode = -EINVAL; goto cleanup; } - actual_fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) + - ((user_srbcmd->sg.count & 0xff) * sizeof(struct sgentry)); - actual_fibsize64 = actual_fibsize + (user_srbcmd->sg.count & 0xff) * - (sizeof(struct sgentry64) - sizeof(struct sgentry)); - /* User made a mistake - should not continue */ - if ((actual_fibsize != fibsize) && (actual_fibsize64 != fibsize)) { - dprintk((KERN_DEBUG"aacraid: Bad Size specified in " - "Raw SRB command calculated fibsize=%lu;%lu " - "user_srbcmd->sg.count=%d aac_srb=%lu sgentry=%lu;%lu " - "issued fibsize=%d\n", - actual_fibsize, actual_fibsize64, user_srbcmd->sg.count, - sizeof(struct aac_srb), sizeof(struct sgentry), - sizeof(struct sgentry64), fibsize)); - rcode = -EINVAL; - goto cleanup; - } - if ((data_dir == DMA_NONE) && user_srbcmd->sg.count) { - dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); - rcode = -EINVAL; - goto cleanup; - } - byte_count = 0; - if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) { + if (dev->dac_support == 1) { struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg; struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg; + struct user_sgmap* usg; + byte_count = 0; /* * This should also catch if user used the 32 bit sgmap */ - if (actual_fibsize64 == fibsize) { - actual_fibsize = actual_fibsize64; - for (i = 0; i < upsg->count; i++) { - u64 addr; - void* p; - /* Does this really need to be GFP_DMA? */ - p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA); - if(p == 0) { - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - upsg->sg[i].count,i,upsg->count)); - rcode = -ENOMEM; - goto cleanup; - } - addr = (u64)upsg->sg[i].addr[0]; - addr += ((u64)upsg->sg[i].addr[1]) << 32; - sg_user[i] = (void __user *)(ptrdiff_t)addr; - sg_list[i] = p; // save so we can clean up later - sg_indx = i; - - if( flags & SRB_DataOut ){ - if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ - dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); - rcode = -EFAULT; - goto cleanup; - } - } - addr = pci_map_single(dev->pdev, p, upsg->sg[i].count, data_dir); + actual_fibsize = sizeof(struct aac_srb) - + sizeof(struct sgentry) + + ((upsg->count & 0xff) * + sizeof(struct sgentry)); + if(actual_fibsize != fibsize){ // User made a mistake - should not continue + dprintk((KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n")); + rcode = -EINVAL; + goto cleanup; + } + usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) + + sizeof(struct sgmap), GFP_KERNEL); + if (!usg) { + dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); + rcode = -ENOMEM; + goto cleanup; + } + memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) + + sizeof(struct sgmap)); + actual_fibsize = sizeof(struct aac_srb) - + sizeof(struct sgentry) + ((usg->count & 0xff) * + sizeof(struct sgentry64)); + if ((data_dir == DMA_NONE) && upsg->count) { + kfree (usg); + dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); + rcode = -EINVAL; + goto cleanup; + } - psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); - psg->sg[i].addr[1] = cpu_to_le32(addr>>32); - byte_count += upsg->sg[i].count; - psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); - } - } else { - struct user_sgmap* usg; - usg = kmalloc(actual_fibsize - sizeof(struct aac_srb) - + sizeof(struct sgmap), GFP_KERNEL); - if (!usg) { - dprintk((KERN_DEBUG"aacraid: Allocation error in Raw SRB command\n")); + for (i = 0; i < usg->count; i++) { + u64 addr; + void* p; + /* Does this really need to be GFP_DMA? */ + p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); + if(p == 0) { + kfree (usg); + dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + usg->sg[i].count,i,usg->count)); rcode = -ENOMEM; goto cleanup; } - memcpy (usg, upsg, actual_fibsize - sizeof(struct aac_srb) - + sizeof(struct sgmap)); - actual_fibsize = actual_fibsize64; - - for (i = 0; i < usg->count; i++) { - u64 addr; - void* p; - /* Does this really need to be GFP_DMA? */ - p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); - if(p == 0) { + sg_user[i] = (void __user *)(long)usg->sg[i].addr; + sg_list[i] = p; // save so we can clean up later + sg_indx = i; + + if( flags & SRB_DataOut ){ + if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ kfree (usg); - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - usg->sg[i].count,i,usg->count)); - rcode = -ENOMEM; + dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); + rcode = -EFAULT; goto cleanup; } - sg_user[i] = (void __user *)(ptrdiff_t)usg->sg[i].addr; - sg_list[i] = p; // save so we can clean up later - sg_indx = i; - - if( flags & SRB_DataOut ){ - if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){ - kfree (usg); - dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); - rcode = -EFAULT; - goto cleanup; - } - } - addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); - - psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); - psg->sg[i].addr[1] = cpu_to_le32(addr>>32); - byte_count += usg->sg[i].count; - psg->sg[i].count = cpu_to_le32(usg->sg[i].count); } - kfree (usg); + addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); + + psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff); + psg->sg[i].addr[1] = cpu_to_le32(addr>>32); + psg->sg[i].count = cpu_to_le32(usg->sg[i].count); + byte_count += usg->sg[i].count; } + kfree (usg); + srbcmd->count = cpu_to_le32(byte_count); psg->count = cpu_to_le32(sg_indx+1); status = aac_fib_send(ScsiPortCommand64, srbfib, actual_fibsize, FsaNormal, 1, 1,NULL,NULL); } else { struct user_sgmap* upsg = &user_srbcmd->sg; struct sgmap* psg = &srbcmd->sg; - - if (actual_fibsize64 == fibsize) { - struct user_sgmap64* usg = (struct user_sgmap64 *)upsg; - for (i = 0; i < upsg->count; i++) { - u64 addr; - void* p; - /* Does this really need to be GFP_DMA? */ - p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA); - if(p == 0) { - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - usg->sg[i].count,i,usg->count)); - rcode = -ENOMEM; - goto cleanup; - } - addr = (u64)usg->sg[i].addr[0]; - addr += ((u64)usg->sg[i].addr[1]) << 32; - sg_user[i] = (void __user *)(ptrdiff_t)addr; - sg_list[i] = p; // save so we can clean up later - sg_indx = i; - - if( flags & SRB_DataOut ){ - if(copy_from_user(p,sg_user[i],usg->sg[i].count)){ - dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); - rcode = -EFAULT; - goto cleanup; - } - } - addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir); - - psg->sg[i].addr = cpu_to_le32(addr & 0xffffffff); - byte_count += usg->sg[i].count; - psg->sg[i].count = cpu_to_le32(usg->sg[i].count); + byte_count = 0; + + actual_fibsize = sizeof (struct aac_srb) + (((user_srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry)); + if(actual_fibsize != fibsize){ // User made a mistake - should not continue + dprintk((KERN_DEBUG"aacraid: Bad Size specified in " + "Raw SRB command calculated fibsize=%d " + "user_srbcmd->sg.count=%d aac_srb=%d sgentry=%d " + "issued fibsize=%d\n", + actual_fibsize, user_srbcmd->sg.count, + sizeof(struct aac_srb), sizeof(struct sgentry), + fibsize)); + rcode = -EINVAL; + goto cleanup; + } + if ((data_dir == DMA_NONE) && upsg->count) { + dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n")); + rcode = -EINVAL; + goto cleanup; + } + for (i = 0; i < upsg->count; i++) { + dma_addr_t addr; + void* p; + p = kmalloc(upsg->sg[i].count, GFP_KERNEL); + if(p == 0) { + dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", + upsg->sg[i].count, i, upsg->count)); + rcode = -ENOMEM; + goto cleanup; } - } else { - for (i = 0; i < upsg->count; i++) { - dma_addr_t addr; - void* p; - p = kmalloc(upsg->sg[i].count, GFP_KERNEL); - if(p == 0) { - dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n", - upsg->sg[i].count, i, upsg->count)); - rcode = -ENOMEM; + sg_user[i] = (void __user *)(long)upsg->sg[i].addr; + sg_list[i] = p; // save so we can clean up later + sg_indx = i; + + if( flags & SRB_DataOut ){ + if(copy_from_user(p, sg_user[i], + upsg->sg[i].count)) { + dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); + rcode = -EFAULT; goto cleanup; } - sg_user[i] = (void __user *)(ptrdiff_t)upsg->sg[i].addr; - sg_list[i] = p; // save so we can clean up later - sg_indx = i; - - if( flags & SRB_DataOut ){ - if(copy_from_user(p, sg_user[i], - upsg->sg[i].count)) { - dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n")); - rcode = -EFAULT; - goto cleanup; - } - } - addr = pci_map_single(dev->pdev, p, - upsg->sg[i].count, data_dir); - - psg->sg[i].addr = cpu_to_le32(addr); - byte_count += upsg->sg[i].count; - psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); } + addr = pci_map_single(dev->pdev, p, + upsg->sg[i].count, data_dir); + + psg->sg[i].addr = cpu_to_le32(addr); + psg->sg[i].count = cpu_to_le32(upsg->sg[i].count); + byte_count += upsg->sg[i].count; } srbcmd->count = cpu_to_le32(byte_count); psg->count = cpu_to_le32(sg_indx+1); @@ -741,8 +682,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) if( flags & SRB_DataIn ) { for(i = 0 ; i <= sg_indx; i++){ - byte_count = le32_to_cpu( - (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) + byte_count = le32_to_cpu((dev->dac_support == 1) ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count : srbcmd->sg.sg[i].count); if(copy_to_user(sg_user[i], sg_list[i], byte_count)){ diff --git a/trunk/drivers/scsi/aacraid/comminit.c b/trunk/drivers/scsi/aacraid/comminit.c index 3009ad8c4073..ae34768987a4 100644 --- a/trunk/drivers/scsi/aacraid/comminit.c +++ b/trunk/drivers/scsi/aacraid/comminit.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * 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 @@ -110,7 +110,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co /* * Align the beginning of Headers to commalign */ - align = (commalign - ((ptrdiff_t)(base) & (commalign - 1))); + align = (commalign - ((unsigned long)(base) & (commalign - 1))); base = base + align; phys = phys + align; /* @@ -387,11 +387,12 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) * Ok now init the communication subsystem */ - dev->queues = kzalloc(sizeof(struct aac_queue_block), GFP_KERNEL); + dev->queues = kmalloc(sizeof(struct aac_queue_block), GFP_KERNEL); if (dev->queues == NULL) { printk(KERN_ERR "Error could not allocate comm region.\n"); return NULL; } + memset(dev->queues, 0, sizeof(struct aac_queue_block)); if (aac_comm_init(dev)<0){ kfree(dev->queues); diff --git a/trunk/drivers/scsi/aacraid/commsup.c b/trunk/drivers/scsi/aacraid/commsup.c index 9aca57eda943..1b97f60652ba 100644 --- a/trunk/drivers/scsi/aacraid/commsup.c +++ b/trunk/drivers/scsi/aacraid/commsup.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * 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 @@ -94,7 +94,7 @@ void aac_fib_map_free(struct aac_dev *dev) int aac_fib_setup(struct aac_dev * dev) { struct fib *fibptr; - struct hw_fib *hw_fib; + struct hw_fib *hw_fib_va; dma_addr_t hw_fib_pa; int i; @@ -106,24 +106,24 @@ int aac_fib_setup(struct aac_dev * dev) if (i<0) return -ENOMEM; - hw_fib = dev->hw_fib_va; + hw_fib_va = dev->hw_fib_va; hw_fib_pa = dev->hw_fib_pa; - memset(hw_fib, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); + memset(hw_fib_va, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); /* * Initialise the fibs */ for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++) { fibptr->dev = dev; - fibptr->hw_fib_va = hw_fib; - fibptr->data = (void *) fibptr->hw_fib_va->data; + fibptr->hw_fib = hw_fib_va; + fibptr->data = (void *) fibptr->hw_fib->data; fibptr->next = fibptr+1; /* Forward chain the fibs */ init_MUTEX_LOCKED(&fibptr->event_wait); spin_lock_init(&fibptr->event_lock); - hw_fib->header.XferState = cpu_to_le32(0xffffffff); - hw_fib->header.SenderSize = cpu_to_le16(dev->max_fib_size); + hw_fib_va->header.XferState = cpu_to_le32(0xffffffff); + hw_fib_va->header.SenderSize = cpu_to_le16(dev->max_fib_size); fibptr->hw_fib_pa = hw_fib_pa; - hw_fib = (struct hw_fib *)((unsigned char *)hw_fib + dev->max_fib_size); + hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + dev->max_fib_size); hw_fib_pa = hw_fib_pa + dev->max_fib_size; } /* @@ -166,7 +166,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) * Null out fields that depend on being zero at the start of * each I/O */ - fibptr->hw_fib_va->header.XferState = 0; + fibptr->hw_fib->header.XferState = 0; fibptr->callback = NULL; fibptr->callback_data = NULL; @@ -178,6 +178,7 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) * @fibptr: fib to free up * * Frees up a fib and places it on the appropriate queue + * (either free or timed out) */ void aac_fib_free(struct fib *fibptr) @@ -185,15 +186,19 @@ void aac_fib_free(struct fib *fibptr) unsigned long flags; spin_lock_irqsave(&fibptr->dev->fib_lock, flags); - if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) + if (fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT) { aac_config.fib_timeouts++; - if (fibptr->hw_fib_va->header.XferState != 0) { - printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", - (void*)fibptr, - le32_to_cpu(fibptr->hw_fib_va->header.XferState)); - } - fibptr->next = fibptr->dev->free_fib; - fibptr->dev->free_fib = fibptr; + fibptr->next = fibptr->dev->timeout_fib; + fibptr->dev->timeout_fib = fibptr; + } else { + if (fibptr->hw_fib->header.XferState != 0) { + printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", + (void*)fibptr, + le32_to_cpu(fibptr->hw_fib->header.XferState)); + } + fibptr->next = fibptr->dev->free_fib; + fibptr->dev->free_fib = fibptr; + } spin_unlock_irqrestore(&fibptr->dev->fib_lock, flags); } @@ -206,7 +211,7 @@ void aac_fib_free(struct fib *fibptr) void aac_fib_init(struct fib *fibptr) { - struct hw_fib *hw_fib = fibptr->hw_fib_va; + struct hw_fib *hw_fib = fibptr->hw_fib; hw_fib->header.StructType = FIB_MAGIC; hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size); @@ -226,7 +231,7 @@ void aac_fib_init(struct fib *fibptr) static void fib_dealloc(struct fib * fibptr) { - struct hw_fib *hw_fib = fibptr->hw_fib_va; + struct hw_fib *hw_fib = fibptr->hw_fib; BUG_ON(hw_fib->header.StructType != FIB_MAGIC); hw_fib->header.XferState = 0; } @@ -381,7 +386,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, void *callback_data) { struct aac_dev * dev = fibptr->dev; - struct hw_fib * hw_fib = fibptr->hw_fib_va; + struct hw_fib * hw_fib = fibptr->hw_fib; unsigned long flags = 0; unsigned long qflags; @@ -425,7 +430,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, */ hw_fib->header.Command = cpu_to_le16(command); hw_fib->header.XferState |= cpu_to_le32(SentFromHost); - fibptr->hw_fib_va->header.Flags = 0; /* 0 the flags field - internal only*/ + fibptr->hw_fib->header.Flags = 0; /* 0 the flags field - internal only*/ /* * Set the size of the Fib we want to send to the adapter */ @@ -457,7 +462,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command))); dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command))); dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState))); - dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib_va)); + dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib)); dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); @@ -508,20 +513,22 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, } udelay(5); } - } else - (void)down_interruptible(&fibptr->event_wait); - spin_lock_irqsave(&fibptr->event_lock, flags); - if (fibptr->done == 0) { - fibptr->done = 2; /* Tell interrupt we aborted */ + } else if (down_interruptible(&fibptr->event_wait)) { + spin_lock_irqsave(&fibptr->event_lock, flags); + if (fibptr->done == 0) { + fibptr->done = 2; /* Tell interrupt we aborted */ + spin_unlock_irqrestore(&fibptr->event_lock, flags); + return -EINTR; + } spin_unlock_irqrestore(&fibptr->event_lock, flags); - return -EINTR; } - spin_unlock_irqrestore(&fibptr->event_lock, flags); BUG_ON(fibptr->done == 0); - if(unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) + if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ return -ETIMEDOUT; - return 0; + } else { + return 0; + } } /* * If the user does not want a response than return success otherwise @@ -617,7 +624,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) { - struct hw_fib * hw_fib = fibptr->hw_fib_va; + struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_dev * dev = fibptr->dev; struct aac_queue * q; unsigned long nointr = 0; @@ -681,7 +688,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) int aac_fib_complete(struct fib *fibptr) { - struct hw_fib * hw_fib = fibptr->hw_fib_va; + struct hw_fib * hw_fib = fibptr->hw_fib; /* * Check for a fib which has already been completed @@ -767,8 +774,9 @@ void aac_printf(struct aac_dev *dev, u32 val) #define AIF_SNIFF_TIMEOUT (30*HZ) static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) { - struct hw_fib * hw_fib = fibptr->hw_fib_va; + struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data; + int busy; u32 container; struct scsi_device *device; enum { @@ -980,6 +988,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) * behind you. */ + busy = 0; + + /* * Find the scsi_device associated with the SCSI address, * and mark it as changed, invalidating the cache. This deals @@ -1024,6 +1035,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) static int _aac_reset_adapter(struct aac_dev *aac) { int index, quirks; + u32 ret; int retval; struct Scsi_Host *host; struct scsi_device *dev; @@ -1047,29 +1059,35 @@ static int _aac_reset_adapter(struct aac_dev *aac) * If a positive health, means in a known DEAD PANIC * state and the adapter could be reset to `try again'. */ - retval = aac_adapter_restart(aac, aac_adapter_check_health(aac)); + retval = aac_adapter_check_health(aac); + if (retval == 0) + retval = aac_adapter_sync_cmd(aac, IOP_RESET_ALWAYS, + 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL); + if (retval) + retval = aac_adapter_sync_cmd(aac, IOP_RESET, + 0, 0, 0, 0, 0, 0, &ret, NULL, NULL, NULL, NULL); if (retval) goto out; + if (ret != 0x00000001) { + retval = -ENODEV; + goto out; + } /* * Loop through the fibs, close the synchronous FIBS */ - for (retval = 1, index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { + for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { struct fib *fib = &aac->fibs[index]; - if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && - (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) { + if (!(fib->hw_fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && + (fib->hw_fib->header.XferState & cpu_to_le32(ResponseExpected))) { unsigned long flagv; spin_lock_irqsave(&fib->event_lock, flagv); up(&fib->event_wait); spin_unlock_irqrestore(&fib->event_lock, flagv); schedule(); - retval = 0; } } - /* Give some extra time for ioctls to complete. */ - if (retval == 0) - ssleep(2); index = aac->cardtype; /* @@ -1223,12 +1241,14 @@ int aac_check_health(struct aac_dev * aac) * Warning: no sleep allowed while * holding spinlock */ - hw_fib = kzalloc(sizeof(struct hw_fib), GFP_ATOMIC); - fib = kzalloc(sizeof(struct fib), GFP_ATOMIC); + hw_fib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC); + fib = kmalloc(sizeof(struct fib), GFP_ATOMIC); if (fib && hw_fib) { struct aac_aifcmd * aif; - fib->hw_fib_va = hw_fib; + memset(hw_fib, 0, sizeof(struct hw_fib)); + memset(fib, 0, sizeof(struct fib)); + fib->hw_fib = hw_fib; fib->dev = aac; aac_fib_init(fib); fib->type = FSAFS_NTC_FIB_CONTEXT; @@ -1334,11 +1354,11 @@ int aac_command_thread(void *data) * do anything at this point since we don't have * anything defined for this thread to do. */ - hw_fib = fib->hw_fib_va; + hw_fib = fib->hw_fib; memset(fib, 0, sizeof(struct fib)); fib->type = FSAFS_NTC_FIB_CONTEXT; fib->size = sizeof( struct fib ); - fib->hw_fib_va = hw_fib; + fib->hw_fib = hw_fib; fib->data = hw_fib->data; fib->dev = dev; /* @@ -1465,7 +1485,7 @@ int aac_command_thread(void *data) */ memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib)); memcpy(newfib, fib, sizeof(struct fib)); - newfib->hw_fib_va = hw_newfib; + newfib->hw_fib = hw_newfib; /* * Put the FIB onto the * fibctx's fibs diff --git a/trunk/drivers/scsi/aacraid/dpcsup.c b/trunk/drivers/scsi/aacraid/dpcsup.c index fcd25f7d0bc6..d38b628be1ad 100644 --- a/trunk/drivers/scsi/aacraid/dpcsup.c +++ b/trunk/drivers/scsi/aacraid/dpcsup.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * 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 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -72,7 +73,7 @@ unsigned int aac_response_normal(struct aac_queue * q) u32 index = le32_to_cpu(entry->addr); fast = index & 0x01; fib = &dev->fibs[index >> 2]; - hwfib = fib->hw_fib_va; + hwfib = fib->hw_fib; aac_consumer_free(dev, q, HostNormRespQueue); /* @@ -83,13 +84,11 @@ unsigned int aac_response_normal(struct aac_queue * q) * continue. The caller has already been notified that * the fib timed out. */ - dev->queues->queue[AdapNormCmdQueue].numpending--; - - if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { - spin_unlock_irqrestore(q->lock, flags); - aac_fib_complete(fib); - aac_fib_free(fib); - spin_lock_irqsave(q->lock, flags); + if (!(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) + dev->queues->queue[AdapNormCmdQueue].numpending--; + else { + printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); + printk(KERN_DEBUG"aacraid: hwfib=%p fib index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); continue; } spin_unlock_irqrestore(q->lock, flags); @@ -194,7 +193,7 @@ unsigned int aac_command_normal(struct aac_queue *q) INIT_LIST_HEAD(&fib->fiblink); fib->type = FSAFS_NTC_FIB_CONTEXT; fib->size = sizeof(struct fib); - fib->hw_fib_va = hw_fib; + fib->hw_fib = hw_fib; fib->data = hw_fib->data; fib->dev = dev; @@ -248,18 +247,19 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) * manage the linked lists. */ if ((!dev->aif_thread) - || (!(fib = kzalloc(sizeof(struct fib),GFP_ATOMIC)))) + || (!(fib = kmalloc(sizeof(struct fib),GFP_ATOMIC)))) return 1; - if (!(hw_fib = kzalloc(sizeof(struct hw_fib),GFP_ATOMIC))) { + if (!(hw_fib = kmalloc(sizeof(struct hw_fib),GFP_ATOMIC))) { kfree (fib); return 1; } - memcpy(hw_fib, (struct hw_fib *)(((ptrdiff_t)(dev->regs.sa)) + - (index & ~0x00000002L)), sizeof(struct hw_fib)); + memset(hw_fib, 0, sizeof(struct hw_fib)); + memcpy(hw_fib, (struct hw_fib *)(((unsigned long)(dev->regs.sa)) + (index & ~0x00000002L)), sizeof(struct hw_fib)); + memset(fib, 0, sizeof(struct fib)); INIT_LIST_HEAD(&fib->fiblink); fib->type = FSAFS_NTC_FIB_CONTEXT; fib->size = sizeof(struct fib); - fib->hw_fib_va = hw_fib; + fib->hw_fib = hw_fib; fib->data = hw_fib->data; fib->dev = dev; @@ -271,7 +271,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) } else { int fast = index & 0x01; struct fib * fib = &dev->fibs[index >> 2]; - struct hw_fib * hwfib = fib->hw_fib_va; + struct hw_fib * hwfib = fib->hw_fib; /* * Remove this fib from the Outstanding I/O queue. @@ -281,14 +281,14 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index) * continue. The caller has already been notified that * the fib timed out. */ - dev->queues->queue[AdapNormCmdQueue].numpending--; - - if (unlikely(fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { - aac_fib_complete(fib); - aac_fib_free(fib); + if ((fib->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) { + printk(KERN_WARNING "aacraid: FIB timeout (%x).\n", fib->flags); + printk(KERN_DEBUG"aacraid: hwfib=%p index=%i fib=%p\n",hwfib, hwfib->header.SenderData,fib); return 0; } + dev->queues->queue[AdapNormCmdQueue].numpending--; + if (fast) { /* * Doctor the fib diff --git a/trunk/drivers/scsi/aacraid/linit.c b/trunk/drivers/scsi/aacraid/linit.c index 350ea7feb61d..0f948c2fb609 100644 --- a/trunk/drivers/scsi/aacraid/linit.c +++ b/trunk/drivers/scsi/aacraid/linit.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * 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 @@ -82,6 +82,8 @@ static LIST_HEAD(aac_devices); static int aac_cfg_major = -1; char aac_driver_version[] = AAC_DRIVER_FULL_VERSION; +extern int expose_physicals; + /* * Because of the way Linux names scsi devices, the order in this table has * become important. Check for on-board Raid first, add-in cards second. @@ -245,19 +247,7 @@ static struct aac_driver_ident aac_drivers[] = { static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { - struct Scsi_Host *host = cmd->device->host; - struct aac_dev *dev = (struct aac_dev *)host->hostdata; - u32 count = 0; cmd->scsi_done = done; - for (; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - struct fib * fib = &dev->fibs[count]; - struct scsi_cmnd * command; - if (fib->hw_fib_va->header.XferState && - ((command = fib->callback_data)) && - (command == cmd) && - (cmd->SCp.phase == AAC_OWNER_FIRMWARE)) - return 0; /* Already owned by Adapter */ - } cmd->SCp.phase = AAC_OWNER_LOWLEVEL; return (aac_scsi_cmd(cmd) ? FAILED : 0); } @@ -456,40 +446,6 @@ static int aac_ioctl(struct scsi_device *sdev, int cmd, void __user * arg) return aac_do_ioctl(dev, cmd, arg); } -static int aac_eh_abort(struct scsi_cmnd* cmd) -{ - struct scsi_device * dev = cmd->device; - struct Scsi_Host * host = dev->host; - struct aac_dev * aac = (struct aac_dev *)host->hostdata; - int count; - int ret = FAILED; - - printk(KERN_ERR "%s: Host adapter abort request (%d,%d,%d,%d)\n", - AAC_DRIVERNAME, - host->host_no, sdev_channel(dev), sdev_id(dev), dev->lun); - switch (cmd->cmnd[0]) { - case SERVICE_ACTION_IN: - if (!(aac->raw_io_interface) || - !(aac->raw_io_64) || - ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16)) - break; - case INQUIRY: - case READ_CAPACITY: - case TEST_UNIT_READY: - /* Mark associated FIB to not complete, eh handler does this */ - for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - struct fib * fib = &aac->fibs[count]; - if (fib->hw_fib_va->header.XferState && - (fib->callback_data == cmd)) { - fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; - cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; - ret = SUCCESS; - } - } - } - return ret; -} - /* * aac_eh_reset - Reset command handling * @scsi_cmd: SCSI command block causing the reset @@ -501,20 +457,12 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) struct Scsi_Host * host = dev->host; struct scsi_cmnd * command; int count; - struct aac_dev * aac = (struct aac_dev *)host->hostdata; + struct aac_dev * aac; unsigned long flags; - /* Mark the associated FIB to not complete, eh handler does this */ - for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - struct fib * fib = &aac->fibs[count]; - if (fib->hw_fib_va->header.XferState && - (fib->callback_data == cmd)) { - fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; - cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; - } - } printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n", AAC_DRIVERNAME); + aac = (struct aac_dev *)host->hostdata; if ((count = aac_check_health(aac))) return count; @@ -548,7 +496,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd) ssleep(1); } printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME); - return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */ + return -ETIMEDOUT; } /** @@ -848,7 +796,6 @@ static struct scsi_host_template aac_driver_template = { .bios_param = aac_biosparm, .shost_attrs = aac_attrs, .slave_configure = aac_slave_configure, - .eh_abort_handler = aac_eh_abort, .eh_host_reset_handler = aac_eh_reset, .can_queue = AAC_NUM_IO_FIB, .this_id = MAXIMUM_NUM_CONTAINERS, diff --git a/trunk/drivers/scsi/aacraid/nark.c b/trunk/drivers/scsi/aacraid/nark.c index a8ace5677813..c76b611b6afb 100644 --- a/trunk/drivers/scsi/aacraid/nark.c +++ b/trunk/drivers/scsi/aacraid/nark.c @@ -74,6 +74,9 @@ static int aac_nark_ioremap(struct aac_dev * dev, u32 size) int aac_nark_init(struct aac_dev * dev) { + extern int _aac_rx_init(struct aac_dev *dev); + extern int aac_rx_select_comm(struct aac_dev *dev, int comm); + /* * Fill in the function dispatch table. */ diff --git a/trunk/drivers/scsi/aacraid/rkt.c b/trunk/drivers/scsi/aacraid/rkt.c index 9c5fcfb398c2..d953c3fe998a 100644 --- a/trunk/drivers/scsi/aacraid/rkt.c +++ b/trunk/drivers/scsi/aacraid/rkt.c @@ -45,6 +45,7 @@ static int aac_rkt_select_comm(struct aac_dev *dev, int comm) { int retval; + extern int aac_rx_select_comm(struct aac_dev *dev, int comm); retval = aac_rx_select_comm(dev, comm); if (comm == AAC_COMM_MESSAGE) { /* @@ -96,6 +97,8 @@ static int aac_rkt_ioremap(struct aac_dev * dev, u32 size) int aac_rkt_init(struct aac_dev *dev) { + extern int _aac_rx_init(struct aac_dev *dev); + /* * Fill in the function dispatch table. */ diff --git a/trunk/drivers/scsi/aacraid/rx.c b/trunk/drivers/scsi/aacraid/rx.c index 291cd14f4e98..d242e2611d67 100644 --- a/trunk/drivers/scsi/aacraid/rx.c +++ b/trunk/drivers/scsi/aacraid/rx.c @@ -5,7 +5,7 @@ * based on the old aacraid driver that is.. * Adaptec aacraid device driver for Linux. * - * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) * * 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 @@ -57,25 +57,25 @@ static irqreturn_t aac_rx_intr_producer(int irq, void *dev_id) * been enabled. * Check to see if this is our interrupt. If it isn't just return */ - if (likely(intstat & ~(dev->OIMR))) { + if (intstat & ~(dev->OIMR)) { bellbits = rx_readl(dev, OutboundDoorbellReg); - if (unlikely(bellbits & DoorBellPrintfReady)) { + if (bellbits & DoorBellPrintfReady) { aac_printf(dev, readl (&dev->IndexRegs->Mailbox[5])); rx_writel(dev, MUnit.ODR,DoorBellPrintfReady); rx_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); } - else if (unlikely(bellbits & DoorBellAdapterNormCmdReady)) { + else if (bellbits & DoorBellAdapterNormCmdReady) { rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); } - else if (likely(bellbits & DoorBellAdapterNormRespReady)) { + else if (bellbits & DoorBellAdapterNormRespReady) { rx_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); aac_response_normal(&dev->queues->queue[HostNormRespQueue]); } - else if (unlikely(bellbits & DoorBellAdapterNormCmdNotFull)) { + else if (bellbits & DoorBellAdapterNormCmdNotFull) { rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); } - else if (unlikely(bellbits & DoorBellAdapterNormRespNotFull)) { + else if (bellbits & DoorBellAdapterNormRespNotFull) { rx_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); } @@ -88,11 +88,11 @@ static irqreturn_t aac_rx_intr_message(int irq, void *dev_id) { struct aac_dev *dev = dev_id; u32 Index = rx_readl(dev, MUnit.OutboundQueue); - if (unlikely(Index == 0xFFFFFFFFL)) + if (Index == 0xFFFFFFFFL) Index = rx_readl(dev, MUnit.OutboundQueue); - if (likely(Index != 0xFFFFFFFFL)) { + if (Index != 0xFFFFFFFFL) { do { - if (unlikely(aac_intr_normal(dev, Index))) { + if (aac_intr_normal(dev, Index)) { rx_writel(dev, MUnit.OutboundQueue, Index); rx_writel(dev, MUnit.ODR, DoorBellAdapterNormRespReady); } @@ -204,7 +204,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command, */ msleep(1); } - if (unlikely(ok != 1)) { + if (ok != 1) { /* * Restore interrupt mask even though we timed out */ @@ -294,7 +294,7 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event) * Start up processing on an i960 based AAC adapter */ -static void aac_rx_start_adapter(struct aac_dev *dev) +void aac_rx_start_adapter(struct aac_dev *dev) { struct aac_init *init; @@ -319,12 +319,12 @@ static int aac_rx_check_health(struct aac_dev *dev) /* * Check to see if the board failed any self tests. */ - if (unlikely(status & SELF_TEST_FAILED)) + if (status & SELF_TEST_FAILED) return -1; /* * Check to see if the board panic'd. */ - if (unlikely(status & KERNEL_PANIC)) { + if (status & KERNEL_PANIC) { char * buffer; struct POSTSTATUS { __le32 Post_Command; @@ -333,15 +333,15 @@ static int aac_rx_check_health(struct aac_dev *dev) dma_addr_t paddr, baddr; int ret; - if (likely((status & 0xFF000000L) == 0xBC000000L)) + if ((status & 0xFF000000L) == 0xBC000000L) return (status >> 16) & 0xFF; buffer = pci_alloc_consistent(dev->pdev, 512, &baddr); ret = -2; - if (unlikely(buffer == NULL)) + if (buffer == NULL) return ret; post = pci_alloc_consistent(dev->pdev, sizeof(struct POSTSTATUS), &paddr); - if (unlikely(post == NULL)) { + if (post == NULL) { pci_free_consistent(dev->pdev, 512, buffer, baddr); return ret; } @@ -353,7 +353,7 @@ static int aac_rx_check_health(struct aac_dev *dev) NULL, NULL, NULL, NULL, NULL); pci_free_consistent(dev->pdev, sizeof(struct POSTSTATUS), post, paddr); - if (likely((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X')))) { + if ((buffer[0] == '0') && ((buffer[1] == 'x') || (buffer[1] == 'X'))) { ret = (buffer[2] <= '9') ? (buffer[2] - '0') : (buffer[2] - 'A' + 10); ret <<= 4; ret += (buffer[3] <= '9') ? (buffer[3] - '0') : (buffer[3] - 'A' + 10); @@ -364,7 +364,7 @@ static int aac_rx_check_health(struct aac_dev *dev) /* * Wait for the adapter to be up and running. */ - if (unlikely(!(status & KERNEL_UP_AND_RUNNING))) + if (!(status & KERNEL_UP_AND_RUNNING)) return -3; /* * Everything is OK @@ -387,7 +387,7 @@ static int aac_rx_deliver_producer(struct fib * fib) unsigned long nointr = 0; spin_lock_irqsave(q->lock, qflags); - aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib_va, 1, fib, &nointr); + aac_queue_get( dev, &Index, AdapNormCmdQueue, fib->hw_fib, 1, fib, &nointr); q->numpending++; *(q->headers.producer) = cpu_to_le32(Index + 1); @@ -419,9 +419,9 @@ static int aac_rx_deliver_message(struct fib * fib) spin_unlock_irqrestore(q->lock, qflags); for(;;) { Index = rx_readl(dev, MUnit.InboundQueue); - if (unlikely(Index == 0xFFFFFFFFL)) + if (Index == 0xFFFFFFFFL) Index = rx_readl(dev, MUnit.InboundQueue); - if (likely(Index != 0xFFFFFFFFL)) + if (Index != 0xFFFFFFFFL) break; if (--count == 0) { spin_lock_irqsave(q->lock, qflags); @@ -437,7 +437,7 @@ static int aac_rx_deliver_message(struct fib * fib) device += sizeof(u32); writel((u32)(addr >> 32), device); device += sizeof(u32); - writel(le16_to_cpu(fib->hw_fib_va->header.Size), device); + writel(le16_to_cpu(fib->hw_fib->header.Size), device); rx_writel(dev, MUnit.InboundQueue, Index); return 0; } @@ -460,34 +460,22 @@ static int aac_rx_ioremap(struct aac_dev * dev, u32 size) return 0; } -static int aac_rx_restart_adapter(struct aac_dev *dev, int bled) +static int aac_rx_restart_adapter(struct aac_dev *dev) { u32 var; - if (bled) - printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n", - dev->name, dev->id, bled); - else { - bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS, - 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); - if (!bled && (var != 0x00000001)) - bled = -EINVAL; - } - if (bled && (bled != -ETIMEDOUT)) - bled = aac_adapter_sync_cmd(dev, IOP_RESET, - 0, 0, 0, 0, 0, 0, &var, NULL, NULL, NULL, NULL); - - if (bled && (bled != -ETIMEDOUT)) - return -EINVAL; - if (bled || (var == 0x3803000F)) { /* USE_OTHER_METHOD */ - rx_writel(dev, MUnit.reserved2, 3); - msleep(5000); /* Delay 5 seconds */ - var = 0x00000001; - } + printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", + dev->name, dev->id); + + if (aac_rx_check_health(dev) <= 0) + return 1; + if (rx_sync_cmd(dev, IOP_RESET, 0, 0, 0, 0, 0, 0, + &var, NULL, NULL, NULL, NULL)) + return 1; if (var != 0x00000001) - return -EINVAL; + return 1; if (rx_readl(dev, MUnit.OMRx[0]) & KERNEL_PANIC) - return -ENODEV; + return 1; return 0; } @@ -529,31 +517,24 @@ int _aac_rx_init(struct aac_dev *dev) { unsigned long start; unsigned long status; - int restart = 0; - int instance = dev->id; - const char * name = dev->name; + int instance; + const char * name; + + instance = dev->id; + name = dev->name; if (aac_adapter_ioremap(dev, dev->base_size)) { printk(KERN_WARNING "%s: unable to map adapter.\n", name); goto error_iounmap; } - /* Failure to reset here is an option ... */ - dev->a_ops.adapter_sync_cmd = rx_sync_cmd; - dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt; - dev->OIMR = status = rx_readb (dev, MUnit.OIMR); - if ((((status & 0x0c) != 0x0c) || reset_devices) && - !aac_rx_restart_adapter(dev, 0)) - ++restart; /* * Check to see if the board panic'd while booting. */ status = rx_readl(dev, MUnit.OMRx[0]); - if (status & KERNEL_PANIC) { - if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev))) + if (status & KERNEL_PANIC) + if (aac_rx_restart_adapter(dev)) goto error_iounmap; - ++restart; - } /* * Check to see if the board failed any self tests. */ @@ -575,23 +556,12 @@ int _aac_rx_init(struct aac_dev *dev) */ while (!((status = rx_readl(dev, MUnit.OMRx[0])) & KERNEL_UP_AND_RUNNING)) { - if ((restart && - (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || - time_after(jiffies, start+HZ*startup_timeout)) { + if(time_after(jiffies, start+startup_timeout*HZ)) + { printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %lx.\n", dev->name, instance, status); goto error_iounmap; } - if (!restart && - ((status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC)) || - time_after(jiffies, start + HZ * - ((startup_timeout > 60) - ? (startup_timeout - 60) - : (startup_timeout / 2))))) { - if (likely(!aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))) - start = jiffies; - ++restart; - } msleep(1); } /* @@ -602,7 +572,6 @@ int _aac_rx_init(struct aac_dev *dev) dev->a_ops.adapter_notify = aac_rx_notify_adapter; dev->a_ops.adapter_sync_cmd = rx_sync_cmd; dev->a_ops.adapter_check_health = aac_rx_check_health; - dev->a_ops.adapter_restart = aac_rx_restart_adapter; /* * First clear out all interrupts. Then enable the one's that we diff --git a/trunk/drivers/scsi/aacraid/sa.c b/trunk/drivers/scsi/aacraid/sa.c index f4b5e9742ab0..6f1a1780efce 100644 --- a/trunk/drivers/scsi/aacraid/sa.c +++ b/trunk/drivers/scsi/aacraid/sa.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/scsi/aha1542.c b/trunk/drivers/scsi/aha1542.c index cbbfbc9f3e0f..1d239f6c0103 100644 --- a/trunk/drivers/scsi/aha1542.c +++ b/trunk/drivers/scsi/aha1542.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/scsi/aic7xxx/Kconfig.aic79xx b/trunk/drivers/scsi/aic7xxx/Kconfig.aic79xx index 5e6620f8dabc..911ea1756e55 100644 --- a/trunk/drivers/scsi/aic7xxx/Kconfig.aic79xx +++ b/trunk/drivers/scsi/aic7xxx/Kconfig.aic79xx @@ -57,6 +57,18 @@ config AIC79XX_BUILD_FIRMWARE or modify the assembler Makefile or the files it includes if your build environment is different than that of the author. +config AIC79XX_ENABLE_RD_STRM + bool "Enable Read Streaming for All Targets" + depends on SCSI_AIC79XX + default n + help + Read Streaming is a U320 protocol option that should enhance + performance. Early U320 drive firmware actually performs slower + with read streaming enabled so it is disabled by default. Read + Streaming can be configured in much the same way as tagged queueing + using the "rd_strm" command line option. See + drivers/scsi/aic7xxx/README.aic79xx for details. + config AIC79XX_DEBUG_ENABLE bool "Compile in Debugging Code" depends on SCSI_AIC79XX diff --git a/trunk/drivers/scsi/aic7xxx/Kconfig.aic7xxx b/trunk/drivers/scsi/aic7xxx/Kconfig.aic7xxx index 88da670a7915..cd93f9a8611f 100644 --- a/trunk/drivers/scsi/aic7xxx/Kconfig.aic7xxx +++ b/trunk/drivers/scsi/aic7xxx/Kconfig.aic7xxx @@ -50,6 +50,16 @@ config AIC7XXX_RESET_DELAY_MS Default: 5000 (5 seconds) +config AIC7XXX_PROBE_EISA_VL + bool "Probe for EISA and VL AIC7XXX Adapters" + depends on SCSI_AIC7XXX && EISA + help + Probe for EISA and VLB Aic7xxx controllers. In many newer systems, + the invasive probes necessary to detect these controllers can cause + other devices to fail. For this reason, the non-PCI probe code is + disabled by default. The current value of this option can be "toggled" + via the no_probe kernel command line option. + config AIC7XXX_BUILD_FIRMWARE bool "Build Adapter Firmware with Kernel Build" depends on SCSI_AIC7XXX && !PREVENT_FIRMWARE_BUILD diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c index 6054881f21f1..2be03e975d97 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -363,8 +363,6 @@ static int ahd_linux_run_command(struct ahd_softc*, struct scsi_cmnd *); static void ahd_linux_setup_tag_info_global(char *p); static int aic79xx_setup(char *c); -static void ahd_freeze_simq(struct ahd_softc *ahd); -static void ahd_release_simq(struct ahd_softc *ahd); static int ahd_linux_unit; @@ -2018,13 +2016,13 @@ ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd) cmd->scsi_done(cmd); } -static void +void ahd_freeze_simq(struct ahd_softc *ahd) { scsi_block_requests(ahd->platform_data->host); } -static void +void ahd_release_simq(struct ahd_softc *ahd) { scsi_unblock_requests(ahd->platform_data->host); diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h index ad9761b237dc..147c83c456a5 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -836,6 +837,8 @@ int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg); void ahd_platform_free(struct ahd_softc *ahd); void ahd_platform_init(struct ahd_softc *ahd); void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb); +void ahd_freeze_simq(struct ahd_softc *ahd); +void ahd_release_simq(struct ahd_softc *ahd); static __inline void ahd_freeze_scb(struct scb *scb) diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx.h b/trunk/drivers/scsi/aic7xxx/aic7xxx.h index e1bd57b9f23d..954c7c24501d 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx.h +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx.h @@ -1278,6 +1278,11 @@ typedef enum { AHC_QUEUE_TAGGED } ahc_queue_alg; +void ahc_set_tags(struct ahc_softc *ahc, + struct scsi_cmnd *cmd, + struct ahc_devinfo *devinfo, + ahc_queue_alg alg); + /**************************** Target Mode *************************************/ #ifdef AHC_TARGET_MODE void ahc_send_lstate_events(struct ahc_softc *, diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c index 75733b09f27a..50ef785224de 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -2073,7 +2073,7 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, /* * Update the current state of tagged queuing for a given target. */ -static void +void ahc_set_tags(struct ahc_softc *ahc, struct scsi_cmnd *cmd, struct ahc_devinfo *devinfo, ahc_queue_alg alg) { diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h index 8fee7edc6eb3..85ae5d836fa4 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_scb.c b/trunk/drivers/scsi/aic94xx/aic94xx_scb.c index db6ab1a3b81e..8f43ff772f23 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_scb.c @@ -24,6 +24,7 @@ * */ +#include #include #include "aic94xx.h" diff --git a/trunk/drivers/scsi/arcmsr/arcmsr_attr.c b/trunk/drivers/scsi/arcmsr/arcmsr_attr.c index 03bfed61bffc..12497da5529d 100644 --- a/trunk/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/trunk/drivers/scsi/arcmsr/arcmsr_attr.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/scsi/atari_NCR5380.c b/trunk/drivers/scsi/atari_NCR5380.c index eff846ae0aff..0f920c84ac0f 100644 --- a/trunk/drivers/scsi/atari_NCR5380.c +++ b/trunk/drivers/scsi/atari_NCR5380.c @@ -1,19 +1,19 @@ -/* +/* * NCR 5380 generic driver routines. These should make it *trivial* - * to implement 5380 SCSI drivers under Linux with a non-trantor + * to implement 5380 SCSI drivers under Linux with a non-trantor * architecture. * * Note that these routines also work with NR53c400 family chips. * * Copyright 1993, Drew Eckhardt - * Visionary Computing + * Visionary Computing * (Unix and Linux consulting and custom programming) - * drew@colorado.edu + * drew@colorado.edu * +1 (303) 666-5836 * - * DISTRIBUTION RELEASE 6. + * DISTRIBUTION RELEASE 6. * - * For more information, please consult + * For more information, please consult * * NCR 5380 Family * SCSI Protocol Controller @@ -57,7 +57,7 @@ * - I've deleted all the stuff for AUTOPROBE_IRQ, REAL_DMA_POLL, PSEUDO_DMA * and USLEEP, because these were messing up readability and will never be * needed for Atari SCSI. - * + * * - I've revised the NCR5380_main() calling scheme (relax the 'main_running' * stuff), and 'main' is executed in a bottom half if awoken by an * interrupt. @@ -69,29 +69,21 @@ */ /* - * Further development / testing that should be done : - * 1. Test linked command handling code after Eric is ready with + * Further development / testing that should be done : + * 1. Test linked command handling code after Eric is ready with * the high level code. */ #include #include #if (NDEBUG & NDEBUG_LISTS) -#define LIST(x, y) \ - do { \ - printk("LINE:%d Adding %p to %p\n", \ - __LINE__, (void*)(x), (void*)(y)); \ - if ((x) == (y)) \ - udelay(5); \ - } while (0) -#define REMOVE(w, x, y, z) \ - do { \ - printk("LINE:%d Removing: %p->%p %p->%p \n", \ - __LINE__, (void*)(w), (void*)(x), \ - (void*)(y), (void*)(z)); \ - if ((x) == (y)) \ - udelay(5); \ - } while (0) +#define LIST(x,y) \ + { printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); \ + if ((x)==(y)) udelay(5); } +#define REMOVE(w,x,y,z) \ + { printk("LINE:%d Removing: %p->%p %p->%p \n", __LINE__, \ + (void*)(w), (void*)(x), (void*)(y), (void*)(z)); \ + if ((x)==(y)) udelay(5); } #else #define LIST(x,y) #define REMOVE(w,x,y,z) @@ -111,62 +103,62 @@ * more difficult than it has to be. * * Also, many of the SCSI drivers were written before the command queuing - * routines were implemented, meaning their implementations of queued + * routines were implemented, meaning their implementations of queued * commands were hacked on rather than designed in from the start. * - * When I designed the Linux SCSI drivers I figured that + * When I designed the Linux SCSI drivers I figured that * while having two different SCSI boards in a system might be useful * for debugging things, two of the same type wouldn't be used. * Well, I was wrong and a number of users have mailed me about running * multiple high-performance SCSI boards in a server. * - * Finally, when I get questions from users, I have no idea what + * Finally, when I get questions from users, I have no idea what * revision of my driver they are running. * * This driver attempts to address these problems : - * This is a generic 5380 driver. To use it on a different platform, + * This is a generic 5380 driver. To use it on a different platform, * one simply writes appropriate system specific macros (ie, data - * transfer - some PC's will use the I/O bus, 68K's must use + * transfer - some PC's will use the I/O bus, 68K's must use * memory mapped) and drops this file in their 'C' wrapper. * - * As far as command queueing, two queues are maintained for + * As far as command queueing, two queues are maintained for * each 5380 in the system - commands that haven't been issued yet, - * and commands that are currently executing. This means that an - * unlimited number of commands may be queued, letting - * more commands propagate from the higher driver levels giving higher - * throughput. Note that both I_T_L and I_T_L_Q nexuses are supported, - * allowing multiple commands to propagate all the way to a SCSI-II device + * and commands that are currently executing. This means that an + * unlimited number of commands may be queued, letting + * more commands propagate from the higher driver levels giving higher + * throughput. Note that both I_T_L and I_T_L_Q nexuses are supported, + * allowing multiple commands to propagate all the way to a SCSI-II device * while a command is already executing. * - * To solve the multiple-boards-in-the-same-system problem, + * To solve the multiple-boards-in-the-same-system problem, * there is a separate instance structure for each instance * of a 5380 in the system. So, multiple NCR5380 drivers will * be able to coexist with appropriate changes to the high level - * SCSI code. + * SCSI code. * * A NCR5380_PUBLIC_REVISION macro is provided, with the release - * number (updated for each public release) printed by the - * NCR5380_print_options command, which should be called from the + * number (updated for each public release) printed by the + * NCR5380_print_options command, which should be called from the * wrapper detect function, so that I know what release of the driver * users are using. * - * Issues specific to the NCR5380 : + * Issues specific to the NCR5380 : * - * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead - * piece of hardware that requires you to sit in a loop polling for - * the REQ signal as long as you are connected. Some devices are - * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect + * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead + * piece of hardware that requires you to sit in a loop polling for + * the REQ signal as long as you are connected. Some devices are + * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect * while doing long seek operations. - * + * * The workaround for this is to keep track of devices that have * disconnected. If the device hasn't disconnected, for commands that - * should disconnect, we do something like + * should disconnect, we do something like * * while (!REQ is asserted) { sleep for N usecs; poll for M usecs } - * - * Some tweaking of N and M needs to be done. An algorithm based + * + * Some tweaking of N and M needs to be done. An algorithm based * on "time to data" would give the best results as long as short time - * to datas (ie, on the same track) were considered, however these + * to datas (ie, on the same track) were considered, however these * broken devices are the exception rather than the rule and I'd rather * spend my time optimizing for the normal case. * @@ -175,9 +167,9 @@ * At the heart of the design is a coroutine, NCR5380_main, * which is started when not running by the interrupt handler, * timer, and queue command function. It attempts to establish - * I_T_L or I_T_L_Q nexuses by removing the commands from the - * issue queue and calling NCR5380_select() if a nexus - * is not established. + * I_T_L or I_T_L_Q nexuses by removing the commands from the + * issue queue and calling NCR5380_select() if a nexus + * is not established. * * Once a nexus is established, the NCR5380_information_transfer() * phase goes through the various phases as instructed by the target. @@ -191,10 +183,10 @@ * calling NCR5380_intr() which will in turn call NCR5380_reselect * to reestablish a nexus. This will run main if necessary. * - * On command termination, the done function will be called as + * On command termination, the done function will be called as * appropriate. * - * SCSI pointers are maintained in the SCp field of SCSI command + * SCSI pointers are maintained in the SCp field of SCSI command * structures, being initialized after the command is connected * in NCR5380_select, and set as appropriate in NCR5380_information_transfer. * Note that in violation of the standard, an implicit SAVE POINTERS operation @@ -204,12 +196,12 @@ /* * Using this file : * This file a skeleton Linux SCSI driver for the NCR 5380 series - * of chips. To use it, you write an architecture specific functions + * of chips. To use it, you write an architecture specific functions * and macros and include this file in your driver. * - * These macros control options : + * These macros control options : * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically - * for commands that return with a CHECK CONDITION status. + * for commands that return with a CHECK CONDITION status. * * LINKED - if defined, linked commands are supported. * @@ -218,18 +210,18 @@ * SUPPORT_TAGS - if defined, SCSI-2 tagged queuing is used where possible * * These macros MUST be defined : - * + * * NCR5380_read(register) - read from the specified register * - * NCR5380_write(register, value) - write to the specific register + * NCR5380_write(register, value) - write to the specific register * * Either real DMA *or* pseudo DMA may be implemented - * REAL functions : + * REAL functions : * NCR5380_REAL_DMA should be defined if real DMA is to be used. - * Note that the DMA setup functions should return the number of bytes + * Note that the DMA setup functions should return the number of bytes * that they were able to program the controller for. * - * Also note that generic i386/PC versions of these macros are + * Also note that generic i386/PC versions of these macros are * available as NCR5380_i386_dma_write_setup, * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual. * @@ -242,14 +234,14 @@ * NCR5380_pread(instance, dst, count); * * If nothing specific to this implementation needs doing (ie, with external - * hardware), you must also define - * + * hardware), you must also define + * * NCR5380_queue_command * NCR5380_reset * NCR5380_abort * NCR5380_proc_info * - * to be the global entry points into the specific driver, ie + * to be the global entry points into the specific driver, ie * #define NCR5380_queue_command t128_queue_command. * * If this is not done, the routines will be defined as static functions @@ -257,7 +249,7 @@ * accessible wrapper function. * * The generic driver is initialized by calling NCR5380_init(instance), - * after setting the appropriate host specific fields and ID. If the + * after setting the appropriate host specific fields and ID. If the * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance, * possible) function may be used. Before the specific driver initialization * code finishes, NCR5380_print_options should be called. @@ -272,9 +264,8 @@ static struct scsi_host_template *the_template = NULL; (struct NCR5380_hostdata *)(in)->hostdata #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) -#define NEXT(cmd) ((Scsi_Cmnd *)(cmd)->host_scribble) -#define SET_NEXT(cmd,next) ((cmd)->host_scribble = (void *)(next)) -#define NEXTADDR(cmd) ((Scsi_Cmnd **)&(cmd)->host_scribble) +#define NEXT(cmd) ((Scsi_Cmnd *)((cmd)->host_scribble)) +#define NEXTADDR(cmd) ((Scsi_Cmnd **)&((cmd)->host_scribble)) #define HOSTNO instance->host_no #define H_NO(cmd) (cmd)->device->host->host_no @@ -321,34 +312,34 @@ static struct scsi_host_template *the_template = NULL; #define TAG_NONE 0xff typedef struct { - DECLARE_BITMAP(allocated, MAX_TAGS); - int nr_allocated; - int queue_size; + DECLARE_BITMAP(allocated, MAX_TAGS); + int nr_allocated; + int queue_size; } TAG_ALLOC; -static TAG_ALLOC TagAlloc[8][8]; /* 8 targets and 8 LUNs */ +static TAG_ALLOC TagAlloc[8][8]; /* 8 targets and 8 LUNs */ -static void __init init_tags(void) +static void __init init_tags( void ) { - int target, lun; - TAG_ALLOC *ta; - - if (!setup_use_tagged_queuing) - return; - - for (target = 0; target < 8; ++target) { - for (lun = 0; lun < 8; ++lun) { - ta = &TagAlloc[target][lun]; - bitmap_zero(ta->allocated, MAX_TAGS); - ta->nr_allocated = 0; - /* At the beginning, assume the maximum queue size we could - * support (MAX_TAGS). This value will be decreased if the target - * returns QUEUE_FULL status. - */ - ta->queue_size = MAX_TAGS; - } + int target, lun; + TAG_ALLOC *ta; + + if (!setup_use_tagged_queuing) + return; + + for( target = 0; target < 8; ++target ) { + for( lun = 0; lun < 8; ++lun ) { + ta = &TagAlloc[target][lun]; + bitmap_zero(ta->allocated, MAX_TAGS); + ta->nr_allocated = 0; + /* At the beginning, assume the maximum queue size we could + * support (MAX_TAGS). This value will be decreased if the target + * returns QUEUE_FULL status. + */ + ta->queue_size = MAX_TAGS; } + } } @@ -357,24 +348,24 @@ static void __init init_tags(void) * check that there is a free tag and the target's queue won't overflow. This * function should be called with interrupts disabled to avoid race * conditions. - */ + */ -static int is_lun_busy(Scsi_Cmnd *cmd, int should_be_tagged) +static int is_lun_busy( Scsi_Cmnd *cmd, int should_be_tagged ) { - SETUP_HOSTDATA(cmd->device->host); - - if (hostdata->busy[cmd->device->id] & (1 << cmd->device->lun)) - return 1; - if (!should_be_tagged || - !setup_use_tagged_queuing || !cmd->device->tagged_supported) - return 0; - if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >= - TagAlloc[cmd->device->id][cmd->device->lun].queue_size) { - TAG_PRINTK("scsi%d: target %d lun %d: no free tags\n", - H_NO(cmd), cmd->device->id, cmd->device->lun); - return 1; - } - return 0; + SETUP_HOSTDATA(cmd->device->host); + + if (hostdata->busy[cmd->device->id] & (1 << cmd->device->lun)) + return( 1 ); + if (!should_be_tagged || + !setup_use_tagged_queuing || !cmd->device->tagged_supported) + return( 0 ); + if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >= + TagAlloc[cmd->device->id][cmd->device->lun].queue_size ) { + TAG_PRINTK( "scsi%d: target %d lun %d: no free tags\n", + H_NO(cmd), cmd->device->id, cmd->device->lun ); + return( 1 ); + } + return( 0 ); } @@ -383,30 +374,31 @@ static int is_lun_busy(Scsi_Cmnd *cmd, int should_be_tagged) * untagged. */ -static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged) +static void cmd_get_tag( Scsi_Cmnd *cmd, int should_be_tagged ) { - SETUP_HOSTDATA(cmd->device->host); - - /* If we or the target don't support tagged queuing, allocate the LUN for - * an untagged command. - */ - if (!should_be_tagged || - !setup_use_tagged_queuing || !cmd->device->tagged_supported) { - cmd->tag = TAG_NONE; - hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); - TAG_PRINTK("scsi%d: target %d lun %d now allocated by untagged " - "command\n", H_NO(cmd), cmd->device->id, cmd->device->lun); - } else { - TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun]; - - cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS); - set_bit(cmd->tag, ta->allocated); - ta->nr_allocated++; - TAG_PRINTK("scsi%d: using tag %d for target %d lun %d " - "(now %d tags in use)\n", - H_NO(cmd), cmd->tag, cmd->device->id, - cmd->device->lun, ta->nr_allocated); - } + SETUP_HOSTDATA(cmd->device->host); + + /* If we or the target don't support tagged queuing, allocate the LUN for + * an untagged command. + */ + if (!should_be_tagged || + !setup_use_tagged_queuing || !cmd->device->tagged_supported) { + cmd->tag = TAG_NONE; + hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); + TAG_PRINTK( "scsi%d: target %d lun %d now allocated by untagged " + "command\n", H_NO(cmd), cmd->device->id, cmd->device->lun ); + } + else { + TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun]; + + cmd->tag = find_first_zero_bit( ta->allocated, MAX_TAGS ); + set_bit( cmd->tag, ta->allocated ); + ta->nr_allocated++; + TAG_PRINTK( "scsi%d: using tag %d for target %d lun %d " + "(now %d tags in use)\n", + H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun, + ta->nr_allocated ); + } } @@ -414,42 +406,44 @@ static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged) * unlock the LUN. */ -static void cmd_free_tag(Scsi_Cmnd *cmd) +static void cmd_free_tag( Scsi_Cmnd *cmd ) { - SETUP_HOSTDATA(cmd->device->host); - - if (cmd->tag == TAG_NONE) { - hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); - TAG_PRINTK("scsi%d: target %d lun %d untagged cmd finished\n", - H_NO(cmd), cmd->device->id, cmd->device->lun); - } else if (cmd->tag >= MAX_TAGS) { - printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n", - H_NO(cmd), cmd->tag); - } else { - TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun]; - clear_bit(cmd->tag, ta->allocated); - ta->nr_allocated--; - TAG_PRINTK("scsi%d: freed tag %d for target %d lun %d\n", - H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun); - } + SETUP_HOSTDATA(cmd->device->host); + + if (cmd->tag == TAG_NONE) { + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); + TAG_PRINTK( "scsi%d: target %d lun %d untagged cmd finished\n", + H_NO(cmd), cmd->device->id, cmd->device->lun ); + } + else if (cmd->tag >= MAX_TAGS) { + printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n", + H_NO(cmd), cmd->tag ); + } + else { + TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun]; + clear_bit( cmd->tag, ta->allocated ); + ta->nr_allocated--; + TAG_PRINTK( "scsi%d: freed tag %d for target %d lun %d\n", + H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun ); + } } -static void free_all_tags(void) +static void free_all_tags( void ) { - int target, lun; - TAG_ALLOC *ta; - - if (!setup_use_tagged_queuing) - return; - - for (target = 0; target < 8; ++target) { - for (lun = 0; lun < 8; ++lun) { - ta = &TagAlloc[target][lun]; - bitmap_zero(ta->allocated, MAX_TAGS); - ta->nr_allocated = 0; - } + int target, lun; + TAG_ALLOC *ta; + + if (!setup_use_tagged_queuing) + return; + + for( target = 0; target < 8; ++target ) { + for( lun = 0; lun < 8; ++lun ) { + ta = &TagAlloc[target][lun]; + bitmap_zero(ta->allocated, MAX_TAGS); + ta->nr_allocated = 0; } + } } #endif /* SUPPORT_TAGS */ @@ -467,94 +461,89 @@ static void free_all_tags(void) * assumed to be already transfered into ptr/this_residual. */ -static void merge_contiguous_buffers(Scsi_Cmnd *cmd) +static void merge_contiguous_buffers( Scsi_Cmnd *cmd ) { - unsigned long endaddr; + unsigned long endaddr; #if (NDEBUG & NDEBUG_MERGING) - unsigned long oldlen = cmd->SCp.this_residual; - int cnt = 1; + unsigned long oldlen = cmd->SCp.this_residual; + int cnt = 1; #endif - for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1; - cmd->SCp.buffers_residual && - virt_to_phys(page_address(cmd->SCp.buffer[1].page) + - cmd->SCp.buffer[1].offset) == endaddr;) { - MER_PRINTK("VTOP(%p) == %08lx -> merging\n", - page_address(cmd->SCp.buffer[1].page), endaddr); + for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1; + cmd->SCp.buffers_residual && + virt_to_phys(page_address(cmd->SCp.buffer[1].page)+ + cmd->SCp.buffer[1].offset) == endaddr; ) { + MER_PRINTK("VTOP(%p) == %08lx -> merging\n", + cmd->SCp.buffer[1].address, endaddr); #if (NDEBUG & NDEBUG_MERGING) - ++cnt; + ++cnt; #endif - ++cmd->SCp.buffer; - --cmd->SCp.buffers_residual; - cmd->SCp.this_residual += cmd->SCp.buffer->length; - endaddr += cmd->SCp.buffer->length; - } + ++cmd->SCp.buffer; + --cmd->SCp.buffers_residual; + cmd->SCp.this_residual += cmd->SCp.buffer->length; + endaddr += cmd->SCp.buffer->length; + } #if (NDEBUG & NDEBUG_MERGING) - if (oldlen != cmd->SCp.this_residual) - MER_PRINTK("merged %d buffers from %p, new length %08x\n", - cnt, cmd->SCp.ptr, cmd->SCp.this_residual); + if (oldlen != cmd->SCp.this_residual) + MER_PRINTK("merged %d buffers from %p, new length %08x\n", + cnt, cmd->SCp.ptr, cmd->SCp.this_residual); #endif } /* * Function : void initialize_SCp(Scsi_Cmnd *cmd) * - * Purpose : initialize the saved data pointers for cmd to point to the + * Purpose : initialize the saved data pointers for cmd to point to the * start of the buffer. * * Inputs : cmd - Scsi_Cmnd structure to have pointers reset. */ -static inline void initialize_SCp(Scsi_Cmnd *cmd) +static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) { - /* - * Initialize the Scsi Pointer field so that all of the commands in the - * various queues are valid. + /* + * Initialize the Scsi Pointer field so that all of the commands in the + * various queues are valid. + */ + + if (cmd->use_sg) { + cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; + cmd->SCp.buffers_residual = cmd->use_sg - 1; + cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+ + cmd->SCp.buffer->offset; + cmd->SCp.this_residual = cmd->SCp.buffer->length; + /* ++roman: Try to merge some scatter-buffers if they are at + * contiguous physical addresses. */ - - if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *)cmd->request_buffer; - cmd->SCp.buffers_residual = cmd->use_sg - 1; - cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page) + - cmd->SCp.buffer->offset; - cmd->SCp.this_residual = cmd->SCp.buffer->length; - /* ++roman: Try to merge some scatter-buffers if they are at - * contiguous physical addresses. - */ - merge_contiguous_buffers(cmd); - } else { - cmd->SCp.buffer = NULL; - cmd->SCp.buffers_residual = 0; - cmd->SCp.ptr = (char *)cmd->request_buffer; - cmd->SCp.this_residual = cmd->request_bufflen; - } + merge_contiguous_buffers( cmd ); + } else { + cmd->SCp.buffer = NULL; + cmd->SCp.buffers_residual = 0; + cmd->SCp.ptr = (char *) cmd->request_buffer; + cmd->SCp.this_residual = cmd->request_bufflen; + } } #include #if NDEBUG static struct { - unsigned char mask; - const char *name; -} signals[] = { - { SR_DBP, "PARITY"}, { SR_RST, "RST" }, { SR_BSY, "BSY" }, - { SR_REQ, "REQ" }, { SR_MSG, "MSG" }, { SR_CD, "CD" }, { SR_IO, "IO" }, - { SR_SEL, "SEL" }, {0, NULL} -}, basrs[] = { - {BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL} -}, icrs[] = { - {ICR_ASSERT_RST, "ASSERT RST"},{ICR_ASSERT_ACK, "ASSERT ACK"}, - {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"}, - {ICR_ASSERT_ATN, "ASSERT ATN"}, {ICR_ASSERT_DATA, "ASSERT DATA"}, - {0, NULL} -}, mrs[] = { - {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {MR_TARGET, "MODE TARGET"}, - {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {MR_ENABLE_PAR_INTR, - "MODE PARITY INTR"}, {MR_ENABLE_EOP_INTR,"MODE EOP INTR"}, - {MR_MONITOR_BSY, "MODE MONITOR BSY"}, - {MR_DMA_MODE, "MODE DMA"}, {MR_ARBITRATE, "MODE ARBITRATION"}, - {0, NULL} -}; + unsigned char mask; + const char * name;} +signals[] = {{ SR_DBP, "PARITY"}, { SR_RST, "RST" }, { SR_BSY, "BSY" }, + { SR_REQ, "REQ" }, { SR_MSG, "MSG" }, { SR_CD, "CD" }, { SR_IO, "IO" }, + { SR_SEL, "SEL" }, {0, NULL}}, +basrs[] = {{BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL}}, +icrs[] = {{ICR_ASSERT_RST, "ASSERT RST"},{ICR_ASSERT_ACK, "ASSERT ACK"}, + {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"}, + {ICR_ASSERT_ATN, "ASSERT ATN"}, {ICR_ASSERT_DATA, "ASSERT DATA"}, + {0, NULL}}, +mrs[] = {{MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {MR_TARGET, "MODE TARGET"}, + {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {MR_ENABLE_PAR_INTR, + "MODE PARITY INTR"}, {MR_ENABLE_EOP_INTR,"MODE EOP INTR"}, + {MR_MONITOR_BSY, "MODE MONITOR BSY"}, + {MR_DMA_MODE, "MODE DMA"}, {MR_ARBITRATE, "MODE ARBITRATION"}, + {0, NULL}}; /* * Function : void NCR5380_print(struct Scsi_Host *instance) @@ -564,47 +553,45 @@ static struct { * Input : instance - which NCR5380 */ -static void NCR5380_print(struct Scsi_Host *instance) -{ - unsigned char status, data, basr, mr, icr, i; - unsigned long flags; - - local_irq_save(flags); - data = NCR5380_read(CURRENT_SCSI_DATA_REG); - status = NCR5380_read(STATUS_REG); - mr = NCR5380_read(MODE_REG); - icr = NCR5380_read(INITIATOR_COMMAND_REG); - basr = NCR5380_read(BUS_AND_STATUS_REG); - local_irq_restore(flags); - printk("STATUS_REG: %02x ", status); - for (i = 0; signals[i].mask; ++i) - if (status & signals[i].mask) - printk(",%s", signals[i].name); - printk("\nBASR: %02x ", basr); - for (i = 0; basrs[i].mask; ++i) - if (basr & basrs[i].mask) - printk(",%s", basrs[i].name); - printk("\nICR: %02x ", icr); - for (i = 0; icrs[i].mask; ++i) - if (icr & icrs[i].mask) - printk(",%s", icrs[i].name); - printk("\nMODE: %02x ", mr); - for (i = 0; mrs[i].mask; ++i) - if (mr & mrs[i].mask) - printk(",%s", mrs[i].name); - printk("\n"); +static void NCR5380_print(struct Scsi_Host *instance) { + unsigned char status, data, basr, mr, icr, i; + unsigned long flags; + + local_irq_save(flags); + data = NCR5380_read(CURRENT_SCSI_DATA_REG); + status = NCR5380_read(STATUS_REG); + mr = NCR5380_read(MODE_REG); + icr = NCR5380_read(INITIATOR_COMMAND_REG); + basr = NCR5380_read(BUS_AND_STATUS_REG); + local_irq_restore(flags); + printk("STATUS_REG: %02x ", status); + for (i = 0; signals[i].mask ; ++i) + if (status & signals[i].mask) + printk(",%s", signals[i].name); + printk("\nBASR: %02x ", basr); + for (i = 0; basrs[i].mask ; ++i) + if (basr & basrs[i].mask) + printk(",%s", basrs[i].name); + printk("\nICR: %02x ", icr); + for (i = 0; icrs[i].mask; ++i) + if (icr & icrs[i].mask) + printk(",%s", icrs[i].name); + printk("\nMODE: %02x ", mr); + for (i = 0; mrs[i].mask; ++i) + if (mr & mrs[i].mask) + printk(",%s", mrs[i].name); + printk("\n"); } static struct { - unsigned char value; - const char *name; + unsigned char value; + const char *name; } phases[] = { - {PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"}, - {PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"}, - {PHASE_UNKNOWN, "UNKNOWN"} -}; + {PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"}, + {PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"}, + {PHASE_UNKNOWN, "UNKNOWN"}}; -/* +/* * Function : void NCR5380_print_phase(struct Scsi_Host *instance) * * Purpose : print the current SCSI phase for debugging purposes @@ -614,35 +601,30 @@ static struct { static void NCR5380_print_phase(struct Scsi_Host *instance) { - unsigned char status; - int i; - - status = NCR5380_read(STATUS_REG); - if (!(status & SR_REQ)) - printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO); - else { - for (i = 0; (phases[i].value != PHASE_UNKNOWN) && - (phases[i].value != (status & PHASE_MASK)); ++i) - ; - printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name); - } + unsigned char status; + int i; + + status = NCR5380_read(STATUS_REG); + if (!(status & SR_REQ)) + printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO); + else { + for (i = 0; (phases[i].value != PHASE_UNKNOWN) && + (phases[i].value != (status & PHASE_MASK)); ++i); + printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name); + } } #else /* !NDEBUG */ /* dummies... */ -static inline void NCR5380_print(struct Scsi_Host *instance) -{ -}; -static inline void NCR5380_print_phase(struct Scsi_Host *instance) -{ -}; +__inline__ void NCR5380_print(struct Scsi_Host *instance) { }; +__inline__ void NCR5380_print_phase(struct Scsi_Host *instance) { }; #endif /* * ++roman: New scheme of calling NCR5380_main() - * + * * If we're not in an interrupt, we can call our main directly, it cannot be * already running. Else, we queue it on a task queue, if not 'main_running' * tells us that a lower level is already executing it. This way, @@ -656,33 +638,33 @@ static inline void NCR5380_print_phase(struct Scsi_Host *instance) #include #include -static volatile int main_running; -static DECLARE_WORK(NCR5380_tqueue, NCR5380_main); +static volatile int main_running = 0; +static DECLARE_WORK(NCR5380_tqueue, (void (*)(void*))NCR5380_main, NULL); -static inline void queue_main(void) +static __inline__ void queue_main(void) { - if (!main_running) { - /* If in interrupt and NCR5380_main() not already running, - queue it on the 'immediate' task queue, to be processed - immediately after the current interrupt processing has - finished. */ - schedule_work(&NCR5380_tqueue); - } - /* else: nothing to do: the running NCR5380_main() will pick up - any newly queued command. */ + if (!main_running) { + /* If in interrupt and NCR5380_main() not already running, + queue it on the 'immediate' task queue, to be processed + immediately after the current interrupt processing has + finished. */ + schedule_work(&NCR5380_tqueue); + } + /* else: nothing to do: the running NCR5380_main() will pick up + any newly queued command. */ } -static inline void NCR5380_all_init(void) +static inline void NCR5380_all_init (void) { - static int done = 0; - if (!done) { - INI_PRINTK("scsi : NCR5380_all_init()\n"); - done = 1; - } + static int done = 0; + if (!done) { + INI_PRINTK("scsi : NCR5380_all_init()\n"); + done = 1; + } } - + /* * Function : void NCR58380_print_options (struct Scsi_Host *instance) * @@ -692,23 +674,23 @@ static inline void NCR5380_all_init(void) * Inputs : instance, pointer to this instance. Unused. */ -static void __init NCR5380_print_options(struct Scsi_Host *instance) +static void __init NCR5380_print_options (struct Scsi_Host *instance) { - printk(" generic options" -#ifdef AUTOSENSE - " AUTOSENSE" + printk(" generic options" +#ifdef AUTOSENSE + " AUTOSENSE" #endif #ifdef REAL_DMA - " REAL DMA" + " REAL DMA" #endif #ifdef PARITY - " PARITY" + " PARITY" #endif #ifdef SUPPORT_TAGS - " SCSI-2 TAGGED QUEUING" + " SCSI-2 TAGGED QUEUING" #endif - ); - printk(" generic release=%d", NCR5380_PUBLIC_RELEASE); + ); + printk(" generic release=%d", NCR5380_PUBLIC_RELEASE); } /* @@ -717,27 +699,27 @@ static void __init NCR5380_print_options(struct Scsi_Host *instance) * Purpose : print commands in the various queues, called from * NCR5380_abort and NCR5380_debug to aid debugging. * - * Inputs : instance, pointer to this instance. + * Inputs : instance, pointer to this instance. */ -static void NCR5380_print_status(struct Scsi_Host *instance) +static void NCR5380_print_status (struct Scsi_Host *instance) { - char *pr_bfr; - char *start; - int len; - - NCR_PRINT(NDEBUG_ANY); - NCR_PRINT_PHASE(NDEBUG_ANY); - - pr_bfr = (char *)__get_free_page(GFP_ATOMIC); - if (!pr_bfr) { - printk("NCR5380_print_status: no memory for print buffer\n"); - return; - } - len = NCR5380_proc_info(instance, pr_bfr, &start, 0, PAGE_SIZE, 0); - pr_bfr[len] = 0; - printk("\n%s\n", pr_bfr); - free_page((unsigned long)pr_bfr); + char *pr_bfr; + char *start; + int len; + + NCR_PRINT(NDEBUG_ANY); + NCR_PRINT_PHASE(NDEBUG_ANY); + + pr_bfr = (char *) __get_free_page(GFP_ATOMIC); + if (!pr_bfr) { + printk("NCR5380_print_status: no memory for print buffer\n"); + return; + } + len = NCR5380_proc_info(pr_bfr, &start, 0, PAGE_SIZE, HOSTNO, 0); + pr_bfr[len] = 0; + printk("\n%s\n", pr_bfr); + free_page((unsigned long) pr_bfr); } @@ -756,478 +738,443 @@ static void NCR5380_print_status(struct Scsi_Host *instance) */ #undef SPRINTF -#define SPRINTF(fmt,args...) \ - do { \ - if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \ - pos += sprintf(pos, fmt , ## args); \ - } while(0) -static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int length); - -static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, - char **start, off_t offset, int length, int inout) +#define SPRINTF(fmt,args...) \ + do { if (pos + strlen(fmt) + 20 /* slop */ < buffer + length) \ + pos += sprintf(pos, fmt , ## args); } while(0) +static +char *lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length); + +static +int NCR5380_proc_info (struct Scsi_Host *instance, char *buffer, char **start, off_t offset, + int length, int inout) { - char *pos = buffer; - struct NCR5380_hostdata *hostdata; - Scsi_Cmnd *ptr; - unsigned long flags; - off_t begin = 0; -#define check_offset() \ - do { \ - if (pos - buffer < offset - begin) { \ - begin += pos - buffer; \ - pos = buffer; \ - } \ - } while (0) - - hostdata = (struct NCR5380_hostdata *)instance->hostdata; - - if (inout) /* Has data been written to the file ? */ - return -ENOSYS; /* Currently this is a no-op */ - SPRINTF("NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE); + char *pos = buffer; + struct NCR5380_hostdata *hostdata; + Scsi_Cmnd *ptr; + unsigned long flags; + off_t begin = 0; +#define check_offset() \ + do { \ + if (pos - buffer < offset - begin) { \ + begin += pos - buffer; \ + pos = buffer; \ + } \ + } while (0) + + hostdata = (struct NCR5380_hostdata *)instance->hostdata; + + if (inout) { /* Has data been written to the file ? */ + return(-ENOSYS); /* Currently this is a no-op */ + } + SPRINTF("NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE); + check_offset(); + local_irq_save(flags); + SPRINTF("NCR5380: coroutine is%s running.\n", main_running ? "" : "n't"); + check_offset(); + if (!hostdata->connected) + SPRINTF("scsi%d: no currently connected command\n", HOSTNO); + else + pos = lprint_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected, + pos, buffer, length); + SPRINTF("scsi%d: issue_queue\n", HOSTNO); + check_offset(); + for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr; ptr = NEXT(ptr)) { + pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); check_offset(); - local_irq_save(flags); - SPRINTF("NCR5380: coroutine is%s running.\n", - main_running ? "" : "n't"); - check_offset(); - if (!hostdata->connected) - SPRINTF("scsi%d: no currently connected command\n", HOSTNO); - else - pos = lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, - pos, buffer, length); - SPRINTF("scsi%d: issue_queue\n", HOSTNO); - check_offset(); - for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr)) { - pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length); - check_offset(); - } + } - SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); + SPRINTF("scsi%d: disconnected_queue\n", HOSTNO); + check_offset(); + for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; + ptr = NEXT(ptr)) { + pos = lprint_Scsi_Cmnd (ptr, pos, buffer, length); check_offset(); - for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; - ptr = NEXT(ptr)) { - pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length); - check_offset(); - } + } - local_irq_restore(flags); - *start = buffer + (offset - begin); - if (pos - buffer < offset - begin) - return 0; - else if (pos - buffer - (offset - begin) < length) - return pos - buffer - (offset - begin); - return length; + local_irq_restore(flags); + *start = buffer + (offset - begin); + if (pos - buffer < offset - begin) + return 0; + else if (pos - buffer - (offset - begin) < length) + return pos - buffer - (offset - begin); + return length; } -static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int length) +static char * +lprint_Scsi_Cmnd (Scsi_Cmnd *cmd, char *pos, char *buffer, int length) { - int i, s; - unsigned char *command; - SPRINTF("scsi%d: destination target %d, lun %d\n", - H_NO(cmd), cmd->device->id, cmd->device->lun); - SPRINTF(" command = "); - command = cmd->cmnd; - SPRINTF("%2d (0x%02x)", command[0], command[0]); - for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) - SPRINTF(" %02x", command[i]); - SPRINTF("\n"); - return pos; + int i, s; + unsigned char *command; + SPRINTF("scsi%d: destination target %d, lun %d\n", + H_NO(cmd), cmd->device->id, cmd->device->lun); + SPRINTF(" command = "); + command = cmd->cmnd; + SPRINTF("%2d (0x%02x)", command[0], command[0]); + for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) + SPRINTF(" %02x", command[i]); + SPRINTF("\n"); + return pos; } -/* +/* * Function : void NCR5380_init (struct Scsi_Host *instance) * * Purpose : initializes *instance and corresponding 5380 chip. * - * Inputs : instance - instantiation of the 5380 driver. + * Inputs : instance - instantiation of the 5380 driver. * * Notes : I assume that the host, hostno, and id bits have been - * set correctly. I don't care about the irq and other fields. - * + * set correctly. I don't care about the irq and other fields. + * */ -static int NCR5380_init(struct Scsi_Host *instance, int flags) +static int NCR5380_init (struct Scsi_Host *instance, int flags) { - int i; - SETUP_HOSTDATA(instance); - - NCR5380_all_init(); - - hostdata->aborted = 0; - hostdata->id_mask = 1 << instance->this_id; - hostdata->id_higher_mask = 0; - for (i = hostdata->id_mask; i <= 0x80; i <<= 1) - if (i > hostdata->id_mask) - hostdata->id_higher_mask |= i; - for (i = 0; i < 8; ++i) - hostdata->busy[i] = 0; + int i; + SETUP_HOSTDATA(instance); + + NCR5380_all_init(); + + hostdata->aborted = 0; + hostdata->id_mask = 1 << instance->this_id; + hostdata->id_higher_mask = 0; + for (i = hostdata->id_mask; i <= 0x80; i <<= 1) + if (i > hostdata->id_mask) + hostdata->id_higher_mask |= i; + for (i = 0; i < 8; ++i) + hostdata->busy[i] = 0; #ifdef SUPPORT_TAGS - init_tags(); + init_tags(); #endif #if defined (REAL_DMA) - hostdata->dma_len = 0; + hostdata->dma_len = 0; #endif - hostdata->targets_present = 0; - hostdata->connected = NULL; - hostdata->issue_queue = NULL; - hostdata->disconnected_queue = NULL; - hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT; - - if (!the_template) { - the_template = instance->hostt; - first_instance = instance; - } + hostdata->targets_present = 0; + hostdata->connected = NULL; + hostdata->issue_queue = NULL; + hostdata->disconnected_queue = NULL; + hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT; + + if (!the_template) { + the_template = instance->hostt; + first_instance = instance; + } + #ifndef AUTOSENSE - if ((instance->cmd_per_lun > 1) || (instance->can_queue > 1)) - printk("scsi%d: WARNING : support for multiple outstanding commands enabled\n" - " without AUTOSENSE option, contingent allegiance conditions may\n" - " be incorrectly cleared.\n", HOSTNO); + if ((instance->cmd_per_lun > 1) || (instance->can_queue > 1)) + printk("scsi%d: WARNING : support for multiple outstanding commands enabled\n" + " without AUTOSENSE option, contingent allegiance conditions may\n" + " be incorrectly cleared.\n", HOSTNO); #endif /* def AUTOSENSE */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - NCR5380_write(MODE_REG, MR_BASE); - NCR5380_write(TARGET_COMMAND_REG, 0); - NCR5380_write(SELECT_ENABLE_REG, 0); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + NCR5380_write(MODE_REG, MR_BASE); + NCR5380_write(TARGET_COMMAND_REG, 0); + NCR5380_write(SELECT_ENABLE_REG, 0); - return 0; + return 0; } -/* - * our own old-style timeout update - */ -/* - * The strategy is to cause the timer code to call scsi_times_out() - * when the soonest timeout is pending. - * The arguments are used when we are queueing a new command, because - * we do not want to subtract the time used from this time, but when we - * set the timer, we want to take this value into account. - */ - -int atari_scsi_update_timeout(Scsi_Cmnd * SCset, int timeout) -{ - int rtn; - - /* - * We are using the new error handling code to actually register/deregister - * timers for timeout. - */ - - if (!timer_pending(&SCset->eh_timeout)) - rtn = 0; - else - rtn = SCset->eh_timeout.expires - jiffies; - - if (timeout == 0) { - del_timer(&SCset->eh_timeout); - SCset->eh_timeout.data = (unsigned long)NULL; - SCset->eh_timeout.expires = 0; - } else { - if (SCset->eh_timeout.data != (unsigned long)NULL) - del_timer(&SCset->eh_timeout); - SCset->eh_timeout.data = (unsigned long)SCset; - SCset->eh_timeout.expires = jiffies + timeout; - add_timer(&SCset->eh_timeout); - } - return rtn; -} - -/* - * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, - * void (*done)(Scsi_Cmnd *)) +/* + * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, + * void (*done)(Scsi_Cmnd *)) * * Purpose : enqueues a SCSI command * * Inputs : cmd - SCSI command, done - function called on completion, with * a pointer to the command descriptor. - * + * * Returns : 0 * - * Side effects : - * cmd is added to the per instance issue_queue, with minor - * twiddling done to the host specific fields of cmd. If the + * Side effects : + * cmd is added to the per instance issue_queue, with minor + * twiddling done to the host specific fields of cmd. If the * main coroutine is not running, it is restarted. * */ -static int NCR5380_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) +static +int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { - SETUP_HOSTDATA(cmd->device->host); - Scsi_Cmnd *tmp; - int oldto; - unsigned long flags; - // extern int update_timeout(Scsi_Cmnd * SCset, int timeout); + SETUP_HOSTDATA(cmd->device->host); + Scsi_Cmnd *tmp; + int oldto; + unsigned long flags; + extern int update_timeout(Scsi_Cmnd * SCset, int timeout); #if (NDEBUG & NDEBUG_NO_WRITE) - switch (cmd->cmnd[0]) { - case WRITE_6: - case WRITE_10: - printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n", - H_NO(cmd)); - cmd->result = (DID_ERROR << 16); - done(cmd); - return 0; - } + switch (cmd->cmnd[0]) { + case WRITE_6: + case WRITE_10: + printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n", + H_NO(cmd)); + cmd->result = (DID_ERROR << 16); + done(cmd); + return 0; + } #endif /* (NDEBUG & NDEBUG_NO_WRITE) */ + #ifdef NCR5380_STATS # if 0 - if (!hostdata->connected && !hostdata->issue_queue && - !hostdata->disconnected_queue) { - hostdata->timebase = jiffies; - } + if (!hostdata->connected && !hostdata->issue_queue && + !hostdata->disconnected_queue) { + hostdata->timebase = jiffies; + } # endif # ifdef NCR5380_STAT_LIMIT - if (cmd->request_bufflen > NCR5380_STAT_LIMIT) + if (cmd->request_bufflen > NCR5380_STAT_LIMIT) # endif - switch (cmd->cmnd[0]) { - case WRITE: - case WRITE_6: - case WRITE_10: - hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase); - hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen; - hostdata->pendingw++; - break; - case READ: - case READ_6: - case READ_10: - hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase); - hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen; - hostdata->pendingr++; - break; - } -#endif - - /* - * We use the host_scribble field as a pointer to the next command - * in a queue - */ - - SET_NEXT(cmd, NULL); - cmd->scsi_done = done; - - cmd->result = 0; - - /* - * Insert the cmd into the issue queue. Note that REQUEST SENSE - * commands are added to the head of the queue since any command will - * clear the contingent allegiance condition that exists and the - * sense data is only guaranteed to be valid while the condition exists. - */ - - local_irq_save(flags); - /* ++guenther: now that the issue queue is being set up, we can lock ST-DMA. - * Otherwise a running NCR5380_main may steal the lock. - * Lock before actually inserting due to fairness reasons explained in - * atari_scsi.c. If we insert first, then it's impossible for this driver - * to release the lock. - * Stop timer for this command while waiting for the lock, or timeouts - * may happen (and they really do), and it's no good if the command doesn't - * appear in any of the queues. - * ++roman: Just disabling the NCR interrupt isn't sufficient here, - * because also a timer int can trigger an abort or reset, which would - * alter queues and touch the lock. - */ - if (!IS_A_TT()) { - oldto = atari_scsi_update_timeout(cmd, 0); - falcon_get_lock(); - atari_scsi_update_timeout(cmd, oldto); - } - if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { - LIST(cmd, hostdata->issue_queue); - SET_NEXT(cmd, hostdata->issue_queue); - hostdata->issue_queue = cmd; - } else { - for (tmp = (Scsi_Cmnd *)hostdata->issue_queue; - NEXT(tmp); tmp = NEXT(tmp)) - ; - LIST(cmd, tmp); - SET_NEXT(tmp, cmd); + switch (cmd->cmnd[0]) + { + case WRITE: + case WRITE_6: + case WRITE_10: + hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase); + hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen; + hostdata->pendingw++; + break; + case READ: + case READ_6: + case READ_10: + hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase); + hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen; + hostdata->pendingr++; + break; } - local_irq_restore(flags); - - QU_PRINTK("scsi%d: command added to %s of queue\n", H_NO(cmd), - (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"); +#endif - /* If queue_command() is called from an interrupt (real one or bottom - * half), we let queue_main() do the job of taking care about main. If it - * is already running, this is a no-op, else main will be queued. - * - * If we're not in an interrupt, we can call NCR5380_main() - * unconditionally, because it cannot be already running. - */ - if (in_interrupt() || ((flags >> 8) & 7) >= 6) - queue_main(); - else - NCR5380_main(NULL); - return 0; + /* + * We use the host_scribble field as a pointer to the next command + * in a queue + */ + + NEXT(cmd) = NULL; + cmd->scsi_done = done; + + cmd->result = 0; + + + /* + * Insert the cmd into the issue queue. Note that REQUEST SENSE + * commands are added to the head of the queue since any command will + * clear the contingent allegiance condition that exists and the + * sense data is only guaranteed to be valid while the condition exists. + */ + + local_irq_save(flags); + /* ++guenther: now that the issue queue is being set up, we can lock ST-DMA. + * Otherwise a running NCR5380_main may steal the lock. + * Lock before actually inserting due to fairness reasons explained in + * atari_scsi.c. If we insert first, then it's impossible for this driver + * to release the lock. + * Stop timer for this command while waiting for the lock, or timeouts + * may happen (and they really do), and it's no good if the command doesn't + * appear in any of the queues. + * ++roman: Just disabling the NCR interrupt isn't sufficient here, + * because also a timer int can trigger an abort or reset, which would + * alter queues and touch the lock. + */ + if (!IS_A_TT()) { + oldto = update_timeout(cmd, 0); + falcon_get_lock(); + update_timeout(cmd, oldto); + } + if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { + LIST(cmd, hostdata->issue_queue); + NEXT(cmd) = hostdata->issue_queue; + hostdata->issue_queue = cmd; + } else { + for (tmp = (Scsi_Cmnd *)hostdata->issue_queue; + NEXT(tmp); tmp = NEXT(tmp)) + ; + LIST(cmd, tmp); + NEXT(tmp) = cmd; + } + local_irq_restore(flags); + + QU_PRINTK("scsi%d: command added to %s of queue\n", H_NO(cmd), + (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"); + + /* If queue_command() is called from an interrupt (real one or bottom + * half), we let queue_main() do the job of taking care about main. If it + * is already running, this is a no-op, else main will be queued. + * + * If we're not in an interrupt, we can call NCR5380_main() + * unconditionally, because it cannot be already running. + */ + if (in_interrupt() || ((flags >> 8) & 7) >= 6) + queue_main(); + else + NCR5380_main(NULL); + return 0; } /* - * Function : NCR5380_main (void) + * Function : NCR5380_main (void) * - * Purpose : NCR5380_main is a coroutine that runs as long as more work can - * be done on the NCR5380 host adapters in a system. Both - * NCR5380_queue_command() and NCR5380_intr() will try to start it + * Purpose : NCR5380_main is a coroutine that runs as long as more work can + * be done on the NCR5380 host adapters in a system. Both + * NCR5380_queue_command() and NCR5380_intr() will try to start it * in case it is not running. - * - * NOTE : NCR5380_main exits with interrupts *disabled*, the caller should + * + * NOTE : NCR5380_main exits with interrupts *disabled*, the caller should * reenable them. This prevents reentrancy and kernel stack overflow. - */ - -static void NCR5380_main(struct work_struct *work) + */ + +static void NCR5380_main (void *bl) { - Scsi_Cmnd *tmp, *prev; - struct Scsi_Host *instance = first_instance; - struct NCR5380_hostdata *hostdata = HOSTDATA(instance); - int done; - unsigned long flags; - - /* - * We run (with interrupts disabled) until we're sure that none of - * the host adapters have anything that can be done, at which point - * we set main_running to 0 and exit. - * - * Interrupts are enabled before doing various other internal - * instructions, after we've decided that we need to run through - * the loop again. - * - * this should prevent any race conditions. - * - * ++roman: Just disabling the NCR interrupt isn't sufficient here, - * because also a timer int can trigger an abort or reset, which can - * alter queues and touch the Falcon lock. - */ - - /* Tell int handlers main() is now already executing. Note that - no races are possible here. If an int comes in before - 'main_running' is set here, and queues/executes main via the - task queue, it doesn't do any harm, just this instance of main - won't find any work left to do. */ - if (main_running) - return; - main_running = 1; - - local_save_flags(flags); - do { - local_irq_disable(); /* Freeze request queues */ - done = 1; - - if (!hostdata->connected) { - MAIN_PRINTK("scsi%d: not connected\n", HOSTNO); - /* - * Search through the issue_queue for a command destined - * for a target that's not busy. - */ + Scsi_Cmnd *tmp, *prev; + struct Scsi_Host *instance = first_instance; + struct NCR5380_hostdata *hostdata = HOSTDATA(instance); + int done; + unsigned long flags; + + /* + * We run (with interrupts disabled) until we're sure that none of + * the host adapters have anything that can be done, at which point + * we set main_running to 0 and exit. + * + * Interrupts are enabled before doing various other internal + * instructions, after we've decided that we need to run through + * the loop again. + * + * this should prevent any race conditions. + * + * ++roman: Just disabling the NCR interrupt isn't sufficient here, + * because also a timer int can trigger an abort or reset, which can + * alter queues and touch the Falcon lock. + */ + + /* Tell int handlers main() is now already executing. Note that + no races are possible here. If an int comes in before + 'main_running' is set here, and queues/executes main via the + task queue, it doesn't do any harm, just this instance of main + won't find any work left to do. */ + if (main_running) + return; + main_running = 1; + + local_save_flags(flags); + do { + local_irq_disable(); /* Freeze request queues */ + done = 1; + + if (!hostdata->connected) { + MAIN_PRINTK( "scsi%d: not connected\n", HOSTNO ); + /* + * Search through the issue_queue for a command destined + * for a target that's not busy. + */ #if (NDEBUG & NDEBUG_LISTS) - for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; - tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp)) - ; - /*printk("%p ", tmp);*/ - if ((tmp == prev) && tmp) - printk(" LOOP\n"); - /* else printk("\n"); */ + for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL; + tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp)) + ; + /*printk("%p ", tmp);*/ + if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/ #endif - for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, - prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) { + for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, + prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) { #if (NDEBUG & NDEBUG_LISTS) - if (prev != tmp) - printk("MAIN tmp=%p target=%d busy=%d lun=%d\n", - tmp, tmp->device->id, hostdata->busy[tmp->device->id], - tmp->device->lun); + if (prev != tmp) + printk("MAIN tmp=%p target=%d busy=%d lun=%d\n", + tmp, tmp->device->id, hostdata->busy[tmp->device->id], + tmp->device->lun); #endif - /* When we find one, remove it from the issue queue. */ - /* ++guenther: possible race with Falcon locking */ - if ( + /* When we find one, remove it from the issue queue. */ + /* ++guenther: possible race with Falcon locking */ + if ( #ifdef SUPPORT_TAGS - !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE) + !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE) #else - !(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun)) + !(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun)) #endif - ) { - /* ++guenther: just to be sure, this must be atomic */ - local_irq_disable(); - if (prev) { - REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); - SET_NEXT(prev, NEXT(tmp)); - } else { - REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp)); - hostdata->issue_queue = NEXT(tmp); - } - SET_NEXT(tmp, NULL); - falcon_dont_release++; - - /* reenable interrupts after finding one */ - local_irq_restore(flags); - - /* - * Attempt to establish an I_T_L nexus here. - * On success, instance->hostdata->connected is set. - * On failure, we must add the command back to the - * issue queue so we can keep trying. - */ - MAIN_PRINTK("scsi%d: main(): command for target %d " - "lun %d removed from issue_queue\n", - HOSTNO, tmp->device->id, tmp->device->lun); - /* - * REQUEST SENSE commands are issued without tagged - * queueing, even on SCSI-II devices because the - * contingent allegiance condition exists for the - * entire unit. - */ - /* ++roman: ...and the standard also requires that - * REQUEST SENSE command are untagged. - */ - + ) { + /* ++guenther: just to be sure, this must be atomic */ + local_irq_disable(); + if (prev) { + REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); + NEXT(prev) = NEXT(tmp); + } else { + REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp)); + hostdata->issue_queue = NEXT(tmp); + } + NEXT(tmp) = NULL; + falcon_dont_release++; + + /* reenable interrupts after finding one */ + local_irq_restore(flags); + + /* + * Attempt to establish an I_T_L nexus here. + * On success, instance->hostdata->connected is set. + * On failure, we must add the command back to the + * issue queue so we can keep trying. + */ + MAIN_PRINTK("scsi%d: main(): command for target %d " + "lun %d removed from issue_queue\n", + HOSTNO, tmp->device->id, tmp->device->lun); + /* + * REQUEST SENSE commands are issued without tagged + * queueing, even on SCSI-II devices because the + * contingent allegiance condition exists for the + * entire unit. + */ + /* ++roman: ...and the standard also requires that + * REQUEST SENSE command are untagged. + */ + #ifdef SUPPORT_TAGS - cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE); + cmd_get_tag( tmp, tmp->cmnd[0] != REQUEST_SENSE ); #endif - if (!NCR5380_select(instance, tmp, - (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : - TAG_NEXT)) { - falcon_dont_release--; - /* release if target did not response! */ - falcon_release_lock_if_possible(hostdata); - break; - } else { - local_irq_disable(); - LIST(tmp, hostdata->issue_queue); - SET_NEXT(tmp, hostdata->issue_queue); - hostdata->issue_queue = tmp; + if (!NCR5380_select(instance, tmp, + (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE : + TAG_NEXT)) { + falcon_dont_release--; + /* release if target did not response! */ + falcon_release_lock_if_possible( hostdata ); + break; + } else { + local_irq_disable(); + LIST(tmp, hostdata->issue_queue); + NEXT(tmp) = hostdata->issue_queue; + hostdata->issue_queue = tmp; #ifdef SUPPORT_TAGS - cmd_free_tag(tmp); + cmd_free_tag( tmp ); #endif - falcon_dont_release--; - local_irq_restore(flags); - MAIN_PRINTK("scsi%d: main(): select() failed, " - "returned to issue_queue\n", HOSTNO); - if (hostdata->connected) - break; - } - } /* if target/lun/target queue is not busy */ - } /* for issue_queue */ - } /* if (!hostdata->connected) */ - - if (hostdata->connected + falcon_dont_release--; + local_irq_restore(flags); + MAIN_PRINTK("scsi%d: main(): select() failed, " + "returned to issue_queue\n", HOSTNO); + if (hostdata->connected) + break; + } + } /* if target/lun/target queue is not busy */ + } /* for issue_queue */ + } /* if (!hostdata->connected) */ + + if (hostdata->connected #ifdef REAL_DMA - && !hostdata->dma_len + && !hostdata->dma_len #endif - ) { - local_irq_restore(flags); - MAIN_PRINTK("scsi%d: main: performing information transfer\n", - HOSTNO); - NCR5380_information_transfer(instance); - MAIN_PRINTK("scsi%d: main: done set false\n", HOSTNO); - done = 0; - } - } while (!done); + ) { + local_irq_restore(flags); + MAIN_PRINTK("scsi%d: main: performing information transfer\n", + HOSTNO); + NCR5380_information_transfer(instance); + MAIN_PRINTK("scsi%d: main: done set false\n", HOSTNO); + done = 0; + } + } while (!done); - /* Better allow ints _after_ 'main_running' has been cleared, else - an interrupt could believe we'll pick up the work it left for - us, but we won't see it anymore here... */ - main_running = 0; - local_irq_restore(flags); + /* Better allow ints _after_ 'main_running' has been cleared, else + an interrupt could believe we'll pick up the work it left for + us, but we won't see it anymore here... */ + main_running = 0; + local_irq_restore(flags); } @@ -1236,1439 +1183,1441 @@ static void NCR5380_main(struct work_struct *work) * Function : void NCR5380_dma_complete (struct Scsi_Host *instance) * * Purpose : Called by interrupt handler when DMA finishes or a phase - * mismatch occurs (which would finish the DMA transfer). + * mismatch occurs (which would finish the DMA transfer). * * Inputs : instance - this instance of the NCR5380. * */ -static void NCR5380_dma_complete(struct Scsi_Host *instance) +static void NCR5380_dma_complete( struct Scsi_Host *instance ) { - SETUP_HOSTDATA(instance); - int transfered, saved_data = 0, overrun = 0, cnt, toPIO; - unsigned char **data, p; - volatile int *count; - - if (!hostdata->connected) { - printk(KERN_WARNING "scsi%d: received end of DMA interrupt with " - "no connected cmd\n", HOSTNO); - return; + SETUP_HOSTDATA(instance); + int transfered, saved_data = 0, overrun = 0, cnt, toPIO; + unsigned char **data, p; + volatile int *count; + + if (!hostdata->connected) { + printk(KERN_WARNING "scsi%d: received end of DMA interrupt with " + "no connected cmd\n", HOSTNO); + return; + } + + if (atari_read_overruns) { + p = hostdata->connected->SCp.phase; + if (p & SR_IO) { + udelay(10); + if ((((NCR5380_read(BUS_AND_STATUS_REG)) & + (BASR_PHASE_MATCH|BASR_ACK)) == + (BASR_PHASE_MATCH|BASR_ACK))) { + saved_data = NCR5380_read(INPUT_DATA_REG); + overrun = 1; + DMA_PRINTK("scsi%d: read overrun handled\n", HOSTNO); + } } - - if (atari_read_overruns) { - p = hostdata->connected->SCp.phase; - if (p & SR_IO) { - udelay(10); - if ((NCR5380_read(BUS_AND_STATUS_REG) & - (BASR_PHASE_MATCH|BASR_ACK)) == - (BASR_PHASE_MATCH|BASR_ACK)) { - saved_data = NCR5380_read(INPUT_DATA_REG); - overrun = 1; - DMA_PRINTK("scsi%d: read overrun handled\n", HOSTNO); - } - } - } - - DMA_PRINTK("scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n", - HOSTNO, NCR5380_read(BUS_AND_STATUS_REG), - NCR5380_read(STATUS_REG)); - - (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); - NCR5380_write(MODE_REG, MR_BASE); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - - transfered = hostdata->dma_len - NCR5380_dma_residual(instance); - hostdata->dma_len = 0; - - data = (unsigned char **)&hostdata->connected->SCp.ptr; - count = &hostdata->connected->SCp.this_residual; - *data += transfered; - *count -= transfered; - - if (atari_read_overruns) { - if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) { - cnt = toPIO = atari_read_overruns; - if (overrun) { - DMA_PRINTK("Got an input overrun, using saved byte\n"); - *(*data)++ = saved_data; - (*count)--; - cnt--; - toPIO--; - } - DMA_PRINTK("Doing %d-byte PIO to 0x%08lx\n", cnt, (long)*data); - NCR5380_transfer_pio(instance, &p, &cnt, data); - *count -= toPIO - cnt; - } + } + + DMA_PRINTK("scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n", + HOSTNO, NCR5380_read(BUS_AND_STATUS_REG), + NCR5380_read(STATUS_REG)); + + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + NCR5380_write(MODE_REG, MR_BASE); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + + transfered = hostdata->dma_len - NCR5380_dma_residual(instance); + hostdata->dma_len = 0; + + data = (unsigned char **) &(hostdata->connected->SCp.ptr); + count = &(hostdata->connected->SCp.this_residual); + *data += transfered; + *count -= transfered; + + if (atari_read_overruns) { + if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) { + cnt = toPIO = atari_read_overruns; + if (overrun) { + DMA_PRINTK("Got an input overrun, using saved byte\n"); + *(*data)++ = saved_data; + (*count)--; + cnt--; + toPIO--; + } + DMA_PRINTK("Doing %d-byte PIO to 0x%08lx\n", cnt, (long)*data); + NCR5380_transfer_pio(instance, &p, &cnt, data); + *count -= toPIO - cnt; } + } } #endif /* REAL_DMA */ /* * Function : void NCR5380_intr (int irq) - * + * * Purpose : handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses - * from the disconnected queue, and restarting NCR5380_main() + * from the disconnected queue, and restarting NCR5380_main() * as required. * * Inputs : int irq, irq that caused this interrupt. * */ -static irqreturn_t NCR5380_intr(int irq, void *dev_id) +static irqreturn_t NCR5380_intr (int irq, void *dev_id) { - struct Scsi_Host *instance = first_instance; - int done = 1, handled = 0; - unsigned char basr; - - INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO); - - /* Look for pending interrupts */ - basr = NCR5380_read(BUS_AND_STATUS_REG); - INT_PRINTK("scsi%d: BASR=%02x\n", HOSTNO, basr); - /* dispatch to appropriate routine if found and done=0 */ - if (basr & BASR_IRQ) { - NCR_PRINT(NDEBUG_INTR); - if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) { - done = 0; - ENABLE_IRQ(); - INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO); - NCR5380_reselect(instance); - (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); - } else if (basr & BASR_PARITY_ERROR) { - INT_PRINTK("scsi%d: PARITY interrupt\n", HOSTNO); - (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); - } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) { - INT_PRINTK("scsi%d: RESET interrupt\n", HOSTNO); - (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); - } else { - /* - * The rest of the interrupt conditions can occur only during a - * DMA transfer - */ + struct Scsi_Host *instance = first_instance; + int done = 1, handled = 0; + unsigned char basr; + + INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO); + + /* Look for pending interrupts */ + basr = NCR5380_read(BUS_AND_STATUS_REG); + INT_PRINTK("scsi%d: BASR=%02x\n", HOSTNO, basr); + /* dispatch to appropriate routine if found and done=0 */ + if (basr & BASR_IRQ) { + NCR_PRINT(NDEBUG_INTR); + if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) { + done = 0; + ENABLE_IRQ(); + INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO); + NCR5380_reselect(instance); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + } + else if (basr & BASR_PARITY_ERROR) { + INT_PRINTK("scsi%d: PARITY interrupt\n", HOSTNO); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + } + else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) { + INT_PRINTK("scsi%d: RESET interrupt\n", HOSTNO); + (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); + } + else { + /* + * The rest of the interrupt conditions can occur only during a + * DMA transfer + */ #if defined(REAL_DMA) - /* - * We should only get PHASE MISMATCH and EOP interrupts if we have - * DMA enabled, so do a sanity check based on the current setting - * of the MODE register. - */ - - if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) && - ((basr & BASR_END_DMA_TRANSFER) || - !(basr & BASR_PHASE_MATCH))) { - - INT_PRINTK("scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO); - NCR5380_dma_complete( instance ); - done = 0; - ENABLE_IRQ(); - } else + /* + * We should only get PHASE MISMATCH and EOP interrupts if we have + * DMA enabled, so do a sanity check based on the current setting + * of the MODE register. + */ + + if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) && + ((basr & BASR_END_DMA_TRANSFER) || + !(basr & BASR_PHASE_MATCH))) { + + INT_PRINTK("scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO); + NCR5380_dma_complete( instance ); + done = 0; + ENABLE_IRQ(); + } else #endif /* REAL_DMA */ - { + { /* MS: Ignore unknown phase mismatch interrupts (caused by EOP interrupt) */ - if (basr & BASR_PHASE_MATCH) - printk(KERN_NOTICE "scsi%d: unknown interrupt, " - "BASR 0x%x, MR 0x%x, SR 0x%x\n", - HOSTNO, basr, NCR5380_read(MODE_REG), - NCR5380_read(STATUS_REG)); - (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); - } - } /* if !(SELECTION || PARITY) */ - handled = 1; - } /* BASR & IRQ */ else { - printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, " - "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr, - NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG)); - (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); - } - - if (!done) { - INT_PRINTK("scsi%d: in int routine, calling main\n", HOSTNO); - /* Put a call to NCR5380_main() on the queue... */ - queue_main(); - } - return IRQ_RETVAL(handled); + if (basr & BASR_PHASE_MATCH) + printk(KERN_NOTICE "scsi%d: unknown interrupt, " + "BASR 0x%x, MR 0x%x, SR 0x%x\n", + HOSTNO, basr, NCR5380_read(MODE_REG), + NCR5380_read(STATUS_REG)); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + } + } /* if !(SELECTION || PARITY) */ + handled = 1; + } /* BASR & IRQ */ + else { + printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, " + "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr, + NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG)); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + } + + if (!done) { + INT_PRINTK("scsi%d: in int routine, calling main\n", HOSTNO); + /* Put a call to NCR5380_main() on the queue... */ + queue_main(); + } + return IRQ_RETVAL(handled); } #ifdef NCR5380_STATS -static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd *cmd) +static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd* cmd) { # ifdef NCR5380_STAT_LIMIT - if (cmd->request_bufflen > NCR5380_STAT_LIMIT) + if (cmd->request_bufflen > NCR5380_STAT_LIMIT) # endif - switch (cmd->cmnd[0]) { - case WRITE: - case WRITE_6: - case WRITE_10: - hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase); - /*hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen;*/ - hostdata->pendingw--; - break; - case READ: - case READ_6: - case READ_10: - hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase); - /*hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen;*/ - hostdata->pendingr--; - break; - } + switch (cmd->cmnd[0]) + { + case WRITE: + case WRITE_6: + case WRITE_10: + hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase); + /*hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen;*/ + hostdata->pendingw--; + break; + case READ: + case READ_6: + case READ_10: + hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase); + /*hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen;*/ + hostdata->pendingr--; + break; + } } #endif -/* - * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, +/* + * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, * int tag); * * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command, - * including ARBITRATION, SELECTION, and initial message out for - * IDENTIFY and queue messages. + * including ARBITRATION, SELECTION, and initial message out for + * IDENTIFY and queue messages. * - * Inputs : instance - instantiation of the 5380 driver on which this - * target lives, cmd - SCSI command to execute, tag - set to TAG_NEXT for - * new tag, TAG_NONE for untagged queueing, otherwise set to the tag for + * Inputs : instance - instantiation of the 5380 driver on which this + * target lives, cmd - SCSI command to execute, tag - set to TAG_NEXT for + * new tag, TAG_NONE for untagged queueing, otherwise set to the tag for * the command that is presently connected. - * + * * Returns : -1 if selection could not execute for some reason, - * 0 if selection succeeded or failed because the target - * did not respond. + * 0 if selection succeeded or failed because the target + * did not respond. * - * Side effects : - * If bus busy, arbitration failed, etc, NCR5380_select() will exit + * Side effects : + * If bus busy, arbitration failed, etc, NCR5380_select() will exit * with registers as they should have been on entry - ie * SELECT_ENABLE will be set appropriately, the NCR5380 * will cease to drive any SCSI bus signals. * - * If successful : I_T_L or I_T_L_Q nexus will be established, - * instance->connected will be set to cmd. - * SELECT interrupt will be disabled. + * If successful : I_T_L or I_T_L_Q nexus will be established, + * instance->connected will be set to cmd. + * SELECT interrupt will be disabled. * - * If failed (no target) : cmd->scsi_done() will be called, and the + * If failed (no target) : cmd->scsi_done() will be called, and the * cmd->result host byte set to DID_BAD_TARGET. */ -static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag) +static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag) { - SETUP_HOSTDATA(instance); - unsigned char tmp[3], phase; - unsigned char *data; - int len; - unsigned long timeout; - unsigned long flags; - - hostdata->restart_select = 0; - NCR_PRINT(NDEBUG_ARBITRATION); - ARB_PRINTK("scsi%d: starting arbitration, id = %d\n", HOSTNO, - instance->this_id); - - /* - * Set the phase bits to 0, otherwise the NCR5380 won't drive the - * data bus during SELECTION. - */ - - local_irq_save(flags); - if (hostdata->connected) { - local_irq_restore(flags); - return -1; - } - NCR5380_write(TARGET_COMMAND_REG, 0); - - /* - * Start arbitration. - */ - - NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); - NCR5380_write(MODE_REG, MR_ARBITRATE); - + SETUP_HOSTDATA(instance); + unsigned char tmp[3], phase; + unsigned char *data; + int len; + unsigned long timeout; + unsigned long flags; + + hostdata->restart_select = 0; + NCR_PRINT(NDEBUG_ARBITRATION); + ARB_PRINTK("scsi%d: starting arbitration, id = %d\n", HOSTNO, + instance->this_id); + + /* + * Set the phase bits to 0, otherwise the NCR5380 won't drive the + * data bus during SELECTION. + */ + + local_irq_save(flags); + if (hostdata->connected) { local_irq_restore(flags); - - /* Wait for arbitration logic to complete */ -#if defined(NCR_TIMEOUT) - { - unsigned long timeout = jiffies + 2*NCR_TIMEOUT; - - while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) && - time_before(jiffies, timeout) && !hostdata->connected) - ; - 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); - return -1; - } - } + return -1; + } + NCR5380_write(TARGET_COMMAND_REG, 0); + + + /* + * Start arbitration. + */ + + NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); + NCR5380_write(MODE_REG, MR_ARBITRATE); + + local_irq_restore(flags); + + /* Wait for arbitration logic to complete */ +#if NCR_TIMEOUT + { + unsigned long timeout = jiffies + 2*NCR_TIMEOUT; + + while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) + && time_before(jiffies, timeout) && !hostdata->connected) + ; + 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); + return -1; + } + } #else /* NCR_TIMEOUT */ - while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) && - !hostdata->connected) - ; + while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) + && !hostdata->connected); #endif - ARB_PRINTK("scsi%d: arbitration complete\n", HOSTNO); - - if (hostdata->connected) { - NCR5380_write(MODE_REG, MR_BASE); - return -1; - } - /* - * The arbitration delay is 2.2us, but this is a minimum and there is - * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate - * the integral nature of udelay(). - * - */ - - udelay(3); - - /* Check for lost arbitration */ - if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || - (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || - (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || - hostdata->connected) { - NCR5380_write(MODE_REG, MR_BASE); - ARB_PRINTK("scsi%d: lost arbitration, deasserting MR_ARBITRATE\n", - HOSTNO); - return -1; - } + ARB_PRINTK("scsi%d: arbitration complete\n", HOSTNO); + + if (hostdata->connected) { + NCR5380_write(MODE_REG, MR_BASE); + return -1; + } + /* + * The arbitration delay is 2.2us, but this is a minimum and there is + * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate + * the integral nature of udelay(). + * + */ + + udelay(3); + + /* Check for lost arbitration */ + if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || + (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || + (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || + hostdata->connected) { + NCR5380_write(MODE_REG, MR_BASE); + ARB_PRINTK("scsi%d: lost arbitration, deasserting MR_ARBITRATE\n", + HOSTNO); + return -1; + } + + /* after/during arbitration, BSY should be asserted. + IBM DPES-31080 Version S31Q works now */ + /* Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman) */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL | + ICR_ASSERT_BSY ) ; + + if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || + hostdata->connected) { + NCR5380_write(MODE_REG, MR_BASE); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + ARB_PRINTK("scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n", + HOSTNO); + return -1; + } - /* after/during arbitration, BSY should be asserted. - IBM DPES-31080 Version S31Q works now */ - /* Tnx to Thomas_Roesch@m2.maus.de for finding this! (Roman) */ - NCR5380_write(INITIATOR_COMMAND_REG, - ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY); - - if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || - hostdata->connected) { - NCR5380_write(MODE_REG, MR_BASE); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - ARB_PRINTK("scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n", - HOSTNO); - return -1; - } - - /* - * Again, bus clear + bus settle time is 1.2us, however, this is - * a minimum so we'll udelay ceil(1.2) - */ + /* + * Again, bus clear + bus settle time is 1.2us, however, this is + * a minimum so we'll udelay ceil(1.2) + */ #ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY - /* ++roman: But some targets (see above :-) seem to need a bit more... */ - udelay(15); + /* ++roman: But some targets (see above :-) seem to need a bit more... */ + udelay(15); #else - udelay(2); + udelay(2); #endif - - if (hostdata->connected) { - NCR5380_write(MODE_REG, MR_BASE); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - return -1; - } - - ARB_PRINTK("scsi%d: won arbitration\n", HOSTNO); - - /* - * Now that we have won arbitration, start Selection process, asserting - * the host and target ID's on the SCSI bus. - */ - - NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id))); - - /* - * Raise ATN while SEL is true before BSY goes false from arbitration, - * since this is the only way to guarantee that we'll get a MESSAGE OUT - * phase immediately after selection. - */ - - NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | - ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL )); + + if (hostdata->connected) { NCR5380_write(MODE_REG, MR_BASE); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + return -1; + } - /* - * Reselect interrupts must be turned off prior to the dropping of BSY, - * otherwise we will trigger an interrupt. - */ - - if (hostdata->connected) { - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - return -1; - } - - NCR5380_write(SELECT_ENABLE_REG, 0); + ARB_PRINTK("scsi%d: won arbitration\n", HOSTNO); - /* - * The initiator shall then wait at least two deskew delays and release - * the BSY signal. - */ - udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */ - - /* Reset BSY */ - NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | - ICR_ASSERT_ATN | ICR_ASSERT_SEL)); - - /* - * Something weird happens when we cease to drive BSY - looks - * like the board/chip is letting us do another read before the - * appropriate propagation delay has expired, and we're confusing - * a BSY signal from ourselves as the target's response to SELECTION. - * - * A small delay (the 'C++' frontend breaks the pipeline with an - * unnecessary jump, making it work on my 386-33/Trantor T128, the - * tighter 'C' code breaks and requires this) solves the problem - - * the 1 us delay is arbitrary, and only used because this delay will - * be the same on other platforms and since it works here, it should - * work there. - * - * wingel suggests that this could be due to failing to wait - * one deskew delay. - */ + /* + * Now that we have won arbitration, start Selection process, asserting + * the host and target ID's on the SCSI bus. + */ - udelay(1); + NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id))); - SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->device->id); + /* + * Raise ATN while SEL is true before BSY goes false from arbitration, + * since this is the only way to guarantee that we'll get a MESSAGE OUT + * phase immediately after selection. + */ - /* - * The SCSI specification calls for a 250 ms timeout for the actual - * selection. - */ + NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | + ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL )); + NCR5380_write(MODE_REG, MR_BASE); - timeout = jiffies + 25; + /* + * Reselect interrupts must be turned off prior to the dropping of BSY, + * otherwise we will trigger an interrupt. + */ - /* - * XXX very interesting - we're seeing a bounce where the BSY we - * asserted is being reflected / still asserted (propagation delay?) - * and it's detecting as true. Sigh. - */ + if (hostdata->connected) { + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + return -1; + } + + NCR5380_write(SELECT_ENABLE_REG, 0); + + /* + * The initiator shall then wait at least two deskew delays and release + * the BSY signal. + */ + udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */ + + /* Reset BSY */ + NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | + ICR_ASSERT_ATN | ICR_ASSERT_SEL)); + + /* + * Something weird happens when we cease to drive BSY - looks + * like the board/chip is letting us do another read before the + * appropriate propagation delay has expired, and we're confusing + * a BSY signal from ourselves as the target's response to SELECTION. + * + * A small delay (the 'C++' frontend breaks the pipeline with an + * unnecessary jump, making it work on my 386-33/Trantor T128, the + * tighter 'C' code breaks and requires this) solves the problem - + * the 1 us delay is arbitrary, and only used because this delay will + * be the same on other platforms and since it works here, it should + * work there. + * + * wingel suggests that this could be due to failing to wait + * one deskew delay. + */ + + udelay(1); + + SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->device->id); + + /* + * The SCSI specification calls for a 250 ms timeout for the actual + * selection. + */ + + timeout = jiffies + 25; + + /* + * XXX very interesting - we're seeing a bounce where the BSY we + * asserted is being reflected / still asserted (propagation delay?) + * and it's detecting as true. Sigh. + */ #if 0 - /* ++roman: If a target conformed to the SCSI standard, it wouldn't assert - * IO while SEL is true. But again, there are some disks out the in the - * world that do that nevertheless. (Somebody claimed that this announces - * reselection capability of the target.) So we better skip that test and - * only wait for BSY... (Famous german words: Der Klügere gibt nach :-) - */ - - while (time_before(jiffies, timeout) && - !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO))) - ; - - if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - NCR5380_reselect(instance); - printk(KERN_ERR "scsi%d: reselection after won arbitration?\n", - HOSTNO); - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - return -1; - } + /* ++roman: If a target conformed to the SCSI standard, it wouldn't assert + * IO while SEL is true. But again, there are some disks out the in the + * world that do that nevertheless. (Somebody claimed that this announces + * reselection capability of the target.) So we better skip that test and + * only wait for BSY... (Famous german words: Der Klügere gibt nach :-) + */ + + while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & + (SR_BSY | SR_IO))); + + if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == + (SR_SEL | SR_IO)) { + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + NCR5380_reselect(instance); + printk (KERN_ERR "scsi%d: reselection after won arbitration?\n", + HOSTNO); + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + return -1; + } #else - while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY)) - ; + while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY)); #endif - /* - * No less than two deskew delays after the initiator detects the - * BSY signal is true, it shall release the SEL signal and may - * change the DATA BUS. -wingel - */ + /* + * No less than two deskew delays after the initiator detects the + * BSY signal is true, it shall release the SEL signal and may + * change the DATA BUS. -wingel + */ - udelay(1); + udelay(1); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); - if (!(NCR5380_read(STATUS_REG) & SR_BSY)) { - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - if (hostdata->targets_present & (1 << cmd->device->id)) { - printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO); - if (hostdata->restart_select) - printk(KERN_NOTICE "\trestart select\n"); - NCR_PRINT(NDEBUG_ANY); - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - return -1; - } - cmd->result = DID_BAD_TARGET << 16; + if (!(NCR5380_read(STATUS_REG) & SR_BSY)) { + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + if (hostdata->targets_present & (1 << cmd->device->id)) { + printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO); + if (hostdata->restart_select) + printk(KERN_NOTICE "\trestart select\n"); + NCR_PRINT(NDEBUG_ANY); + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + return -1; + } + cmd->result = DID_BAD_TARGET << 16; #ifdef NCR5380_STATS - collect_stats(hostdata, cmd); + collect_stats(hostdata, cmd); #endif #ifdef SUPPORT_TAGS - cmd_free_tag(cmd); + cmd_free_tag( cmd ); #endif - cmd->scsi_done(cmd); - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - SEL_PRINTK("scsi%d: target did not respond within 250ms\n", HOSTNO); - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - return 0; - } - - hostdata->targets_present |= (1 << cmd->device->id); - - /* - * Since we followed the SCSI spec, and raised ATN while SEL - * was true but before BSY was false during selection, the information - * transfer phase should be a MESSAGE OUT phase so that we can send the - * IDENTIFY message. - * - * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG - * message (2 bytes) with a tag ID that we increment with every command - * until it wraps back to 0. - * - * XXX - it turns out that there are some broken SCSI-II devices, - * which claim to support tagged queuing but fail when more than - * some number of commands are issued at once. - */ - - /* Wait for start of REQ/ACK handshake */ - while (!(NCR5380_read(STATUS_REG) & SR_REQ)) - ; - - SEL_PRINTK("scsi%d: target %d selected, going into MESSAGE OUT phase.\n", - HOSTNO, cmd->device->id); - tmp[0] = IDENTIFY(1, cmd->device->lun); + cmd->scsi_done(cmd); + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + SEL_PRINTK("scsi%d: target did not respond within 250ms\n", HOSTNO); + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + return 0; + } + + hostdata->targets_present |= (1 << cmd->device->id); + + /* + * Since we followed the SCSI spec, and raised ATN while SEL + * was true but before BSY was false during selection, the information + * transfer phase should be a MESSAGE OUT phase so that we can send the + * IDENTIFY message. + * + * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG + * message (2 bytes) with a tag ID that we increment with every command + * until it wraps back to 0. + * + * XXX - it turns out that there are some broken SCSI-II devices, + * which claim to support tagged queuing but fail when more than + * some number of commands are issued at once. + */ + + /* Wait for start of REQ/ACK handshake */ + while (!(NCR5380_read(STATUS_REG) & SR_REQ)); + + SEL_PRINTK("scsi%d: target %d selected, going into MESSAGE OUT phase.\n", + HOSTNO, cmd->device->id); + tmp[0] = IDENTIFY(1, cmd->device->lun); #ifdef SUPPORT_TAGS - if (cmd->tag != TAG_NONE) { - tmp[1] = hostdata->last_message = SIMPLE_QUEUE_TAG; - tmp[2] = cmd->tag; - len = 3; - } else - len = 1; -#else + if (cmd->tag != TAG_NONE) { + tmp[1] = hostdata->last_message = SIMPLE_QUEUE_TAG; + tmp[2] = cmd->tag; + len = 3; + } else len = 1; - cmd->tag = 0; +#else + len = 1; + cmd->tag=0; #endif /* SUPPORT_TAGS */ - /* Send message(s) */ - data = tmp; - phase = PHASE_MSGOUT; - NCR5380_transfer_pio(instance, &phase, &len, &data); - SEL_PRINTK("scsi%d: nexus established.\n", HOSTNO); - /* XXX need to handle errors here */ - hostdata->connected = cmd; + /* Send message(s) */ + data = tmp; + phase = PHASE_MSGOUT; + NCR5380_transfer_pio(instance, &phase, &len, &data); + SEL_PRINTK("scsi%d: nexus established.\n", HOSTNO); + /* XXX need to handle errors here */ + hostdata->connected = cmd; #ifndef SUPPORT_TAGS - hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); -#endif + hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); +#endif - initialize_SCp(cmd); + initialize_SCp(cmd); - return 0; + + return 0; } -/* - * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, +/* + * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance, * unsigned char *phase, int *count, unsigned char **data) * * Purpose : transfers data in given phase using polled I/O * - * Inputs : instance - instance of driver, *phase - pointer to - * what phase is expected, *count - pointer to number of + * Inputs : instance - instance of driver, *phase - pointer to + * what phase is expected, *count - pointer to number of * bytes to transfer, **data - pointer to data pointer. - * + * * Returns : -1 when different phase is entered without transferring * maximum number of bytes, 0 if all bytes are transfered or exit * is in same phase. * - * Also, *phase, *count, *data are modified in place. + * Also, *phase, *count, *data are modified in place. * * XXX Note : handling for bus free may be useful. */ /* - * Note : this code is not as quick as it could be, however it + * Note : this code is not as quick as it could be, however it * IS 100% reliable, and for the actual data transfer where speed * counts, we will always do a pseudo DMA or DMA transfer. */ -static int NCR5380_transfer_pio(struct Scsi_Host *instance, - unsigned char *phase, int *count, - unsigned char **data) +static int NCR5380_transfer_pio( struct Scsi_Host *instance, + unsigned char *phase, int *count, + unsigned char **data) { - register unsigned char p = *phase, tmp; - register int c = *count; - register unsigned char *d = *data; - - /* - * The NCR5380 chip will only drive the SCSI bus when the - * phase specified in the appropriate bits of the TARGET COMMAND - * REGISTER match the STATUS REGISTER + register unsigned char p = *phase, tmp; + register int c = *count; + register unsigned char *d = *data; + + /* + * The NCR5380 chip will only drive the SCSI bus when the + * phase specified in the appropriate bits of the TARGET COMMAND + * REGISTER match the STATUS REGISTER + */ + + NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); + + do { + /* + * Wait for assertion of REQ, after which the phase bits will be + * valid */ + while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ)); - NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); - - do { - /* - * Wait for assertion of REQ, after which the phase bits will be - * valid - */ - while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ)) - ; - - HSH_PRINTK("scsi%d: REQ detected\n", HOSTNO); - - /* Check for phase mismatch */ - if ((tmp & PHASE_MASK) != p) { - PIO_PRINTK("scsi%d: phase mismatch\n", HOSTNO); - NCR_PRINT_PHASE(NDEBUG_PIO); - break; - } + HSH_PRINTK("scsi%d: REQ detected\n", HOSTNO); - /* Do actual transfer from SCSI bus to / from memory */ - if (!(p & SR_IO)) - NCR5380_write(OUTPUT_DATA_REG, *d); - else - *d = NCR5380_read(CURRENT_SCSI_DATA_REG); + /* Check for phase mismatch */ + if ((tmp & PHASE_MASK) != p) { + PIO_PRINTK("scsi%d: phase mismatch\n", HOSTNO); + NCR_PRINT_PHASE(NDEBUG_PIO); + break; + } - ++d; + /* Do actual transfer from SCSI bus to / from memory */ + if (!(p & SR_IO)) + NCR5380_write(OUTPUT_DATA_REG, *d); + else + *d = NCR5380_read(CURRENT_SCSI_DATA_REG); - /* - * The SCSI standard suggests that in MSGOUT phase, the initiator - * should drop ATN on the last byte of the message phase - * after REQ has been asserted for the handshake but before - * the initiator raises ACK. - */ + ++d; - if (!(p & SR_IO)) { - if (!((p & SR_MSG) && c > 1)) { - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA); - NCR_PRINT(NDEBUG_PIO); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | - ICR_ASSERT_DATA | ICR_ASSERT_ACK); - } else { - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | - ICR_ASSERT_DATA | ICR_ASSERT_ATN); - NCR_PRINT(NDEBUG_PIO); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | - ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK); - } - } else { - NCR_PRINT(NDEBUG_PIO); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK); - } - - while (NCR5380_read(STATUS_REG) & SR_REQ) - ; + /* + * The SCSI standard suggests that in MSGOUT phase, the initiator + * should drop ATN on the last byte of the message phase + * after REQ has been asserted for the handshake but before + * the initiator raises ACK. + */ - HSH_PRINTK("scsi%d: req false, handshake complete\n", HOSTNO); + if (!(p & SR_IO)) { + if (!((p & SR_MSG) && c > 1)) { + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | + ICR_ASSERT_DATA); + NCR_PRINT(NDEBUG_PIO); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | + ICR_ASSERT_DATA | ICR_ASSERT_ACK); + } else { + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | + ICR_ASSERT_DATA | ICR_ASSERT_ATN); + NCR_PRINT(NDEBUG_PIO); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | + ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK); + } + } else { + NCR_PRINT(NDEBUG_PIO); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK); + } - /* - * We have several special cases to consider during REQ/ACK handshaking : - * 1. We were in MSGOUT phase, and we are on the last byte of the - * message. ATN must be dropped as ACK is dropped. - * - * 2. We are in a MSGIN phase, and we are on the last byte of the - * message. We must exit with ACK asserted, so that the calling - * code may raise ATN before dropping ACK to reject the message. - * - * 3. ACK and ATN are clear and the target may proceed as normal. - */ - if (!(p == PHASE_MSGIN && c == 1)) { - if (p == PHASE_MSGOUT && c > 1) - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); - else - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - } - } while (--c); + while (NCR5380_read(STATUS_REG) & SR_REQ); - PIO_PRINTK("scsi%d: residual %d\n", HOSTNO, c); + HSH_PRINTK("scsi%d: req false, handshake complete\n", HOSTNO); - *count = c; - *data = d; - tmp = NCR5380_read(STATUS_REG); - /* The phase read from the bus is valid if either REQ is (already) - * asserted or if ACK hasn't been released yet. The latter is the case if - * we're in MSGIN and all wanted bytes have been received. - */ - if ((tmp & SR_REQ) || (p == PHASE_MSGIN && c == 0)) - *phase = tmp & PHASE_MASK; - else - *phase = PHASE_UNKNOWN; - - if (!c || (*phase == p)) - return 0; - else - return -1; +/* + * We have several special cases to consider during REQ/ACK handshaking : + * 1. We were in MSGOUT phase, and we are on the last byte of the + * message. ATN must be dropped as ACK is dropped. + * + * 2. We are in a MSGIN phase, and we are on the last byte of the + * message. We must exit with ACK asserted, so that the calling + * code may raise ATN before dropping ACK to reject the message. + * + * 3. ACK and ATN are clear and the target may proceed as normal. + */ + if (!(p == PHASE_MSGIN && c == 1)) { + if (p == PHASE_MSGOUT && c > 1) + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); + else + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + } + } while (--c); + + PIO_PRINTK("scsi%d: residual %d\n", HOSTNO, c); + + *count = c; + *data = d; + tmp = NCR5380_read(STATUS_REG); + /* The phase read from the bus is valid if either REQ is (already) + * asserted or if ACK hasn't been released yet. The latter is the case if + * we're in MSGIN and all wanted bytes have been received. */ + if ((tmp & SR_REQ) || (p == PHASE_MSGIN && c == 0)) + *phase = tmp & PHASE_MASK; + else + *phase = PHASE_UNKNOWN; + + if (!c || (*phase == p)) + return 0; + else + return -1; } /* * Function : do_abort (Scsi_Host *host) - * - * Purpose : abort the currently established nexus. Should only be - * called from a routine which can drop into a - * + * + * Purpose : abort the currently established nexus. Should only be + * called from a routine which can drop into a + * * Returns : 0 on success, -1 on failure. */ -static int do_abort(struct Scsi_Host *host) +static int do_abort (struct Scsi_Host *host) { - unsigned char tmp, *msgptr, phase; - int len; - - /* Request message out phase */ + unsigned char tmp, *msgptr, phase; + int len; + + /* Request message out phase */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); + + /* + * Wait for the target to indicate a valid phase by asserting + * REQ. Once this happens, we'll have either a MSGOUT phase + * and can immediately send the ABORT message, or we'll have some + * other phase and will have to source/sink data. + * + * We really don't care what value was on the bus or what value + * the target sees, so we just handshake. + */ + + while (!(tmp = NCR5380_read(STATUS_REG)) & SR_REQ); + + NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); + + if ((tmp & PHASE_MASK) != PHASE_MSGOUT) { + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | + ICR_ASSERT_ACK); + while (NCR5380_read(STATUS_REG) & SR_REQ); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); - - /* - * Wait for the target to indicate a valid phase by asserting - * REQ. Once this happens, we'll have either a MSGOUT phase - * and can immediately send the ABORT message, or we'll have some - * other phase and will have to source/sink data. - * - * We really don't care what value was on the bus or what value - * the target sees, so we just handshake. - */ - - while (!(tmp = NCR5380_read(STATUS_REG)) & SR_REQ) - ; - - NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); - - if ((tmp & PHASE_MASK) != PHASE_MSGOUT) { - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | - ICR_ASSERT_ACK); - while (NCR5380_read(STATUS_REG) & SR_REQ) - ; - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); - } - - tmp = ABORT; - msgptr = &tmp; - len = 1; - phase = PHASE_MSGOUT; - NCR5380_transfer_pio(host, &phase, &len, &msgptr); - - /* - * If we got here, and the command completed successfully, - * we're about to go into bus free state. - */ - - return len ? -1 : 0; + } + + tmp = ABORT; + msgptr = &tmp; + len = 1; + phase = PHASE_MSGOUT; + NCR5380_transfer_pio (host, &phase, &len, &msgptr); + + /* + * If we got here, and the command completed successfully, + * we're about to go into bus free state. + */ + + return len ? -1 : 0; } #if defined(REAL_DMA) -/* - * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, +/* + * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance, * unsigned char *phase, int *count, unsigned char **data) * * Purpose : transfers data in given phase using either real * or pseudo DMA. * - * Inputs : instance - instance of driver, *phase - pointer to - * what phase is expected, *count - pointer to number of + * Inputs : instance - instance of driver, *phase - pointer to + * what phase is expected, *count - pointer to number of * bytes to transfer, **data - pointer to data pointer. - * + * * Returns : -1 when different phase is entered without transferring * maximum number of bytes, 0 if all bytes or transfered or exit * is in same phase. * - * Also, *phase, *count, *data are modified in place. + * Also, *phase, *count, *data are modified in place. * */ -static int NCR5380_transfer_dma(struct Scsi_Host *instance, - unsigned char *phase, int *count, - unsigned char **data) +static int NCR5380_transfer_dma( struct Scsi_Host *instance, + unsigned char *phase, int *count, + unsigned char **data) { - SETUP_HOSTDATA(instance); - register int c = *count; - register unsigned char p = *phase; - register unsigned char *d = *data; - unsigned char tmp; - unsigned long flags; - - if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) { - *phase = tmp; - return -1; - } + SETUP_HOSTDATA(instance); + register int c = *count; + register unsigned char p = *phase; + register unsigned char *d = *data; + unsigned char tmp; + unsigned long flags; + + if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) { + *phase = tmp; + return -1; + } - if (atari_read_overruns && (p & SR_IO)) - c -= atari_read_overruns; + if (atari_read_overruns && (p & SR_IO)) { + c -= atari_read_overruns; + } - DMA_PRINTK("scsi%d: initializing DMA for %s, %d bytes %s %p\n", - HOSTNO, (p & SR_IO) ? "reading" : "writing", - c, (p & SR_IO) ? "to" : "from", d); + DMA_PRINTK("scsi%d: initializing DMA for %s, %d bytes %s %p\n", + HOSTNO, (p & SR_IO) ? "reading" : "writing", + c, (p & SR_IO) ? "to" : "from", d); - NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); + NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p)); #ifdef REAL_DMA - NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY); + NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY); #endif /* def REAL_DMA */ - if (IS_A_TT()) { - /* On the Medusa, it is a must to initialize the DMA before - * starting the NCR. This is also the cleaner way for the TT. - */ - local_irq_save(flags); - hostdata->dma_len = (p & SR_IO) ? - NCR5380_dma_read_setup(instance, d, c) : - NCR5380_dma_write_setup(instance, d, c); - local_irq_restore(flags); - } - - if (p & SR_IO) - NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0); - else { - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA); - NCR5380_write(START_DMA_SEND_REG, 0); - } - - if (!IS_A_TT()) { - /* On the Falcon, the DMA setup must be done after the last */ - /* NCR access, else the DMA setup gets trashed! - */ - local_irq_save(flags); - hostdata->dma_len = (p & SR_IO) ? - NCR5380_dma_read_setup(instance, d, c) : - NCR5380_dma_write_setup(instance, d, c); - local_irq_restore(flags); - } - return 0; + if (IS_A_TT()) { + /* On the Medusa, it is a must to initialize the DMA before + * starting the NCR. This is also the cleaner way for the TT. + */ + local_irq_save(flags); + hostdata->dma_len = (p & SR_IO) ? + NCR5380_dma_read_setup(instance, d, c) : + NCR5380_dma_write_setup(instance, d, c); + local_irq_restore(flags); + } + + if (p & SR_IO) + NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0); + else { + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA); + NCR5380_write(START_DMA_SEND_REG, 0); + } + + if (!IS_A_TT()) { + /* On the Falcon, the DMA setup must be done after the last */ + /* NCR access, else the DMA setup gets trashed! + */ + local_irq_save(flags); + hostdata->dma_len = (p & SR_IO) ? + NCR5380_dma_read_setup(instance, d, c) : + NCR5380_dma_write_setup(instance, d, c); + local_irq_restore(flags); + } + return 0; } #endif /* defined(REAL_DMA) */ /* * Function : NCR5380_information_transfer (struct Scsi_Host *instance) * - * Purpose : run through the various SCSI phases and do as the target - * directs us to. Operates on the currently connected command, + * Purpose : run through the various SCSI phases and do as the target + * directs us to. Operates on the currently connected command, * instance->connected. * * Inputs : instance, instance for which we are doing commands * - * Side effects : SCSI things happen, the disconnected queue will be + * Side effects : SCSI things happen, the disconnected queue will be * modified if a command disconnects, *instance->connected will * change. * - * XXX Note : we need to watch for bus free or a reset condition here - * to recover from an unexpected bus free condition. + * XXX Note : we need to watch for bus free or a reset condition here + * to recover from an unexpected bus free condition. */ - -static void NCR5380_information_transfer(struct Scsi_Host *instance) + +static void NCR5380_information_transfer (struct Scsi_Host *instance) { - SETUP_HOSTDATA(instance); - unsigned long flags; - unsigned char msgout = NOP; - int sink = 0; - int len; + SETUP_HOSTDATA(instance); + unsigned long flags; + unsigned char msgout = NOP; + int sink = 0; + int len; #if defined(REAL_DMA) - int transfersize; + int transfersize; #endif - unsigned char *data; - unsigned char phase, tmp, extended_msg[10], old_phase = 0xff; - Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected; - - while (1) { - tmp = NCR5380_read(STATUS_REG); - /* We only have a valid SCSI phase when REQ is asserted */ - if (tmp & SR_REQ) { - phase = (tmp & PHASE_MASK); - if (phase != old_phase) { - old_phase = phase; - NCR_PRINT_PHASE(NDEBUG_INFORMATION); - } - - if (sink && (phase != PHASE_MSGOUT)) { - NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); - - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | - ICR_ASSERT_ACK); - while (NCR5380_read(STATUS_REG) & SR_REQ) - ; - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | - ICR_ASSERT_ATN); - sink = 0; - continue; - } + unsigned char *data; + unsigned char phase, tmp, extended_msg[10], old_phase=0xff; + Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected; - switch (phase) { - case PHASE_DATAOUT: + while (1) { + tmp = NCR5380_read(STATUS_REG); + /* We only have a valid SCSI phase when REQ is asserted */ + if (tmp & SR_REQ) { + phase = (tmp & PHASE_MASK); + if (phase != old_phase) { + old_phase = phase; + NCR_PRINT_PHASE(NDEBUG_INFORMATION); + } + + if (sink && (phase != PHASE_MSGOUT)) { + NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); + + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | + ICR_ASSERT_ACK); + while (NCR5380_read(STATUS_REG) & SR_REQ); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | + ICR_ASSERT_ATN); + sink = 0; + continue; + } + + switch (phase) { + case PHASE_DATAOUT: #if (NDEBUG & NDEBUG_NO_DATAOUT) - printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT " - "aborted\n", HOSTNO); - sink = 1; - do_abort(instance); - cmd->result = DID_ERROR << 16; - cmd->done(cmd); - return; + printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT " + "aborted\n", HOSTNO); + sink = 1; + do_abort(instance); + cmd->result = DID_ERROR << 16; + cmd->done(cmd); + return; #endif - case PHASE_DATAIN: - /* - * If there is no room left in the current buffer in the - * scatter-gather list, move onto the next one. - */ - - if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) { - ++cmd->SCp.buffer; - --cmd->SCp.buffers_residual; - cmd->SCp.this_residual = cmd->SCp.buffer->length; - cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + - cmd->SCp.buffer->offset; - /* ++roman: Try to merge some scatter-buffers if - * they are at contiguous physical addresses. - */ - merge_contiguous_buffers(cmd); - INF_PRINTK("scsi%d: %d bytes and %d buffers left\n", - HOSTNO, cmd->SCp.this_residual, - cmd->SCp.buffers_residual); - } - - /* - * The preferred transfer method is going to be - * PSEUDO-DMA for systems that are strictly PIO, - * since we can let the hardware do the handshaking. - * - * For this to work, we need to know the transfersize - * ahead of time, since the pseudo-DMA code will sit - * in an unconditional loop. - */ - - /* ++roman: I suggest, this should be - * #if def(REAL_DMA) - * instead of leaving REAL_DMA out. - */ + case PHASE_DATAIN: + /* + * If there is no room left in the current buffer in the + * scatter-gather list, move onto the next one. + */ + + if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) { + ++cmd->SCp.buffer; + --cmd->SCp.buffers_residual; + cmd->SCp.this_residual = cmd->SCp.buffer->length; + cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+ + cmd->SCp.buffer->offset; + /* ++roman: Try to merge some scatter-buffers if + * they are at contiguous physical addresses. + */ + merge_contiguous_buffers( cmd ); + INF_PRINTK("scsi%d: %d bytes and %d buffers left\n", + HOSTNO, cmd->SCp.this_residual, + cmd->SCp.buffers_residual); + } + + /* + * The preferred transfer method is going to be + * PSEUDO-DMA for systems that are strictly PIO, + * since we can let the hardware do the handshaking. + * + * For this to work, we need to know the transfersize + * ahead of time, since the pseudo-DMA code will sit + * in an unconditional loop. + */ + +/* ++roman: I suggest, this should be + * #if def(REAL_DMA) + * instead of leaving REAL_DMA out. + */ #if defined(REAL_DMA) - if (!cmd->device->borken && - (transfersize = NCR5380_dma_xfer_len(instance,cmd,phase)) > 31) { - len = transfersize; - cmd->SCp.phase = phase; - if (NCR5380_transfer_dma(instance, &phase, - &len, (unsigned char **)&cmd->SCp.ptr)) { - /* - * If the watchdog timer fires, all future - * accesses to this device will use the - * polled-IO. */ - printk(KERN_NOTICE "scsi%d: switching target %d " - "lun %d to slow handshake\n", HOSTNO, - cmd->device->id, cmd->device->lun); - cmd->device->borken = 1; - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | - ICR_ASSERT_ATN); - sink = 1; - do_abort(instance); - cmd->result = DID_ERROR << 16; - cmd->done(cmd); - /* XXX - need to source or sink data here, as appropriate */ - } else { + if (!cmd->device->borken && + (transfersize = NCR5380_dma_xfer_len(instance,cmd,phase)) > 31) { + len = transfersize; + cmd->SCp.phase = phase; + if (NCR5380_transfer_dma(instance, &phase, + &len, (unsigned char **) &cmd->SCp.ptr)) { + /* + * If the watchdog timer fires, all future + * accesses to this device will use the + * polled-IO. */ + printk(KERN_NOTICE "scsi%d: switching target %d " + "lun %d to slow handshake\n", HOSTNO, + cmd->device->id, cmd->device->lun); + cmd->device->borken = 1; + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | + ICR_ASSERT_ATN); + sink = 1; + do_abort(instance); + cmd->result = DID_ERROR << 16; + cmd->done(cmd); + /* XXX - need to source or sink data here, as appropriate */ + } else { #ifdef REAL_DMA - /* ++roman: When using real DMA, - * information_transfer() should return after - * starting DMA since it has nothing more to - * do. - */ - return; -#else - cmd->SCp.this_residual -= transfersize - len; + /* ++roman: When using real DMA, + * information_transfer() should return after + * starting DMA since it has nothing more to + * do. + */ + return; +#else + cmd->SCp.this_residual -= transfersize - len; #endif - } - } else + } + } else #endif /* defined(REAL_DMA) */ - NCR5380_transfer_pio(instance, &phase, - (int *)&cmd->SCp.this_residual, - (unsigned char **)&cmd->SCp.ptr); - break; - case PHASE_MSGIN: - len = 1; - data = &tmp; - NCR5380_write(SELECT_ENABLE_REG, 0); /* disable reselects */ - NCR5380_transfer_pio(instance, &phase, &len, &data); - cmd->SCp.Message = tmp; - - switch (tmp) { - /* - * Linking lets us reduce the time required to get the - * next command out to the device, hopefully this will - * mean we don't waste another revolution due to the delays - * required by ARBITRATION and another SELECTION. - * - * In the current implementation proposal, low level drivers - * merely have to start the next command, pointed to by - * next_link, done() is called as with unlinked commands. - */ + NCR5380_transfer_pio(instance, &phase, + (int *) &cmd->SCp.this_residual, (unsigned char **) + &cmd->SCp.ptr); + break; + case PHASE_MSGIN: + len = 1; + data = &tmp; + NCR5380_write(SELECT_ENABLE_REG, 0); /* disable reselects */ + NCR5380_transfer_pio(instance, &phase, &len, &data); + cmd->SCp.Message = tmp; + + switch (tmp) { + /* + * Linking lets us reduce the time required to get the + * next command out to the device, hopefully this will + * mean we don't waste another revolution due to the delays + * required by ARBITRATION and another SELECTION. + * + * In the current implementation proposal, low level drivers + * merely have to start the next command, pointed to by + * next_link, done() is called as with unlinked commands. + */ #ifdef LINKED - case LINKED_CMD_COMPLETE: - case LINKED_FLG_CMD_COMPLETE: - /* Accept message by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - - LNK_PRINTK("scsi%d: target %d lun %d linked command " - "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun); - - /* Enable reselect interrupts */ - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - /* - * Sanity check : A linked command should only terminate - * with one of these messages if there are more linked - * commands available. - */ - - if (!cmd->next_link) { - printk(KERN_NOTICE "scsi%d: target %d lun %d " - "linked command complete, no next_link\n", - HOSTNO, cmd->device->id, cmd->device->lun); - sink = 1; - do_abort(instance); - return; - } - - initialize_SCp(cmd->next_link); - /* The next command is still part of this process; copy it - * and don't free it! */ - cmd->next_link->tag = cmd->tag; - cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); - LNK_PRINTK("scsi%d: target %d lun %d linked request " - "done, calling scsi_done().\n", - HOSTNO, cmd->device->id, cmd->device->lun); + case LINKED_CMD_COMPLETE: + case LINKED_FLG_CMD_COMPLETE: + /* Accept message by clearing ACK */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + + LNK_PRINTK("scsi%d: target %d lun %d linked command " + "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun); + + /* Enable reselect interrupts */ + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + /* + * Sanity check : A linked command should only terminate + * with one of these messages if there are more linked + * commands available. + */ + + if (!cmd->next_link) { + printk(KERN_NOTICE "scsi%d: target %d lun %d " + "linked command complete, no next_link\n", + HOSTNO, cmd->device->id, cmd->device->lun); + sink = 1; + do_abort (instance); + return; + } + + initialize_SCp(cmd->next_link); + /* The next command is still part of this process; copy it + * and don't free it! */ + cmd->next_link->tag = cmd->tag; + cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); + LNK_PRINTK("scsi%d: target %d lun %d linked request " + "done, calling scsi_done().\n", + HOSTNO, cmd->device->id, cmd->device->lun); #ifdef NCR5380_STATS - collect_stats(hostdata, cmd); + collect_stats(hostdata, cmd); #endif - cmd->scsi_done(cmd); - cmd = hostdata->connected; - break; + cmd->scsi_done(cmd); + cmd = hostdata->connected; + break; #endif /* def LINKED */ - case ABORT: - case COMMAND_COMPLETE: - /* Accept message by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - /* ++guenther: possible race with Falcon locking */ - falcon_dont_release++; - hostdata->connected = NULL; - QU_PRINTK("scsi%d: command for target %d, lun %d " - "completed\n", HOSTNO, cmd->device->id, cmd->device->lun); + case ABORT: + case COMMAND_COMPLETE: + /* Accept message by clearing ACK */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + /* ++guenther: possible race with Falcon locking */ + falcon_dont_release++; + hostdata->connected = NULL; + QU_PRINTK("scsi%d: command for target %d, lun %d " + "completed\n", HOSTNO, cmd->device->id, cmd->device->lun); #ifdef SUPPORT_TAGS - cmd_free_tag(cmd); - if (status_byte(cmd->SCp.Status) == QUEUE_FULL) { - /* Turn a QUEUE FULL status into BUSY, I think the - * mid level cannot handle QUEUE FULL :-( (The - * command is retried after BUSY). Also update our - * queue size to the number of currently issued - * commands now. - */ - /* ++Andreas: the mid level code knows about - QUEUE_FULL now. */ - TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun]; - TAG_PRINTK("scsi%d: target %d lun %d returned " - "QUEUE_FULL after %d commands\n", - HOSTNO, cmd->device->id, cmd->device->lun, - ta->nr_allocated); - if (ta->queue_size > ta->nr_allocated) - ta->nr_allocated = ta->queue_size; - } + cmd_free_tag( cmd ); + if (status_byte(cmd->SCp.Status) == QUEUE_FULL) { + /* Turn a QUEUE FULL status into BUSY, I think the + * mid level cannot handle QUEUE FULL :-( (The + * command is retried after BUSY). Also update our + * queue size to the number of currently issued + * commands now. + */ + /* ++Andreas: the mid level code knows about + QUEUE_FULL now. */ + TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun]; + TAG_PRINTK("scsi%d: target %d lun %d returned " + "QUEUE_FULL after %d commands\n", + HOSTNO, cmd->device->id, cmd->device->lun, + ta->nr_allocated); + if (ta->queue_size > ta->nr_allocated) + ta->nr_allocated = ta->queue_size; + } #else - hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); #endif - /* Enable reselect interrupts */ - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - - /* - * I'm not sure what the correct thing to do here is : - * - * If the command that just executed is NOT a request - * sense, the obvious thing to do is to set the result - * code to the values of the stored parameters. - * - * If it was a REQUEST SENSE command, we need some way to - * differentiate between the failure code of the original - * and the failure code of the REQUEST sense - the obvious - * case is success, where we fall through and leave the - * result code unchanged. - * - * The non-obvious place is where the REQUEST SENSE failed - */ - - if (cmd->cmnd[0] != REQUEST_SENSE) - cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); - else if (status_byte(cmd->SCp.Status) != GOOD) - cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); - + /* Enable reselect interrupts */ + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + + /* + * I'm not sure what the correct thing to do here is : + * + * If the command that just executed is NOT a request + * sense, the obvious thing to do is to set the result + * code to the values of the stored parameters. + * + * If it was a REQUEST SENSE command, we need some way to + * differentiate between the failure code of the original + * and the failure code of the REQUEST sense - the obvious + * case is success, where we fall through and leave the + * result code unchanged. + * + * The non-obvious place is where the REQUEST SENSE failed + */ + + if (cmd->cmnd[0] != REQUEST_SENSE) + cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8); + else if (status_byte(cmd->SCp.Status) != GOOD) + cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); + #ifdef AUTOSENSE - if ((cmd->cmnd[0] != REQUEST_SENSE) && - (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { - ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO); - cmd->cmnd[0] = REQUEST_SENSE; - cmd->cmnd[1] &= 0xe0; - cmd->cmnd[2] = 0; - cmd->cmnd[3] = 0; - cmd->cmnd[4] = sizeof(cmd->sense_buffer); - cmd->cmnd[5] = 0; - cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); - - cmd->use_sg = 0; - /* this is initialized from initialize_SCp - cmd->SCp.buffer = NULL; - cmd->SCp.buffers_residual = 0; - */ - cmd->request_buffer = (char *) cmd->sense_buffer; - cmd->request_bufflen = sizeof(cmd->sense_buffer); - - local_irq_save(flags); - LIST(cmd,hostdata->issue_queue); - SET_NEXT(cmd, hostdata->issue_queue); - hostdata->issue_queue = (Scsi_Cmnd *) cmd; - local_irq_restore(flags); - QU_PRINTK("scsi%d: REQUEST SENSE added to head of " - "issue queue\n", H_NO(cmd)); - } else + if ((cmd->cmnd[0] != REQUEST_SENSE) && + (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { + ASEN_PRINTK("scsi%d: performing request sense\n", + HOSTNO); + cmd->cmnd[0] = REQUEST_SENSE; + cmd->cmnd[1] &= 0xe0; + cmd->cmnd[2] = 0; + cmd->cmnd[3] = 0; + cmd->cmnd[4] = sizeof(cmd->sense_buffer); + cmd->cmnd[5] = 0; + cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); + + cmd->use_sg = 0; + /* this is initialized from initialize_SCp + cmd->SCp.buffer = NULL; + cmd->SCp.buffers_residual = 0; + */ + cmd->request_buffer = (char *) cmd->sense_buffer; + cmd->request_bufflen = sizeof(cmd->sense_buffer); + + local_irq_save(flags); + LIST(cmd,hostdata->issue_queue); + NEXT(cmd) = hostdata->issue_queue; + hostdata->issue_queue = (Scsi_Cmnd *) cmd; + local_irq_restore(flags); + QU_PRINTK("scsi%d: REQUEST SENSE added to head of " + "issue queue\n", H_NO(cmd)); + } else #endif /* def AUTOSENSE */ - { + { #ifdef NCR5380_STATS - collect_stats(hostdata, cmd); + collect_stats(hostdata, cmd); #endif - cmd->scsi_done(cmd); - } - - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - /* - * Restore phase bits to 0 so an interrupted selection, - * arbitration can resume. - */ - NCR5380_write(TARGET_COMMAND_REG, 0); - - while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) - barrier(); - - falcon_dont_release--; - /* ++roman: For Falcon SCSI, release the lock on the - * ST-DMA here if no other commands are waiting on the - * disconnected queue. - */ - falcon_release_lock_if_possible(hostdata); - return; - case MESSAGE_REJECT: - /* Accept message by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - /* Enable reselect interrupts */ - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - switch (hostdata->last_message) { - case HEAD_OF_QUEUE_TAG: - case ORDERED_QUEUE_TAG: - case SIMPLE_QUEUE_TAG: - /* The target obviously doesn't support tagged - * queuing, even though it announced this ability in - * its INQUIRY data ?!? (maybe only this LUN?) Ok, - * clear 'tagged_supported' and lock the LUN, since - * the command is treated as untagged further on. - */ - cmd->device->tagged_supported = 0; - hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); - cmd->tag = TAG_NONE; - TAG_PRINTK("scsi%d: target %d lun %d rejected " - "QUEUE_TAG message; tagged queuing " - "disabled\n", - HOSTNO, cmd->device->id, cmd->device->lun); - break; - } - break; - case DISCONNECT: - /* Accept message by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - local_irq_save(flags); - cmd->device->disconnect = 1; - LIST(cmd,hostdata->disconnected_queue); - SET_NEXT(cmd, hostdata->disconnected_queue); - hostdata->connected = NULL; - hostdata->disconnected_queue = cmd; - local_irq_restore(flags); - QU_PRINTK("scsi%d: command for target %d lun %d was " - "moved from connected to the " - "disconnected_queue\n", HOSTNO, - cmd->device->id, cmd->device->lun); - /* - * Restore phase bits to 0 so an interrupted selection, - * arbitration can resume. - */ - NCR5380_write(TARGET_COMMAND_REG, 0); - - /* Enable reselect interrupts */ - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - /* Wait for bus free to avoid nasty timeouts */ - while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) - barrier(); - return; - /* - * The SCSI data pointer is *IMPLICITLY* saved on a disconnect - * operation, in violation of the SCSI spec so we can safely - * ignore SAVE/RESTORE pointers calls. - * - * Unfortunately, some disks violate the SCSI spec and - * don't issue the required SAVE_POINTERS message before - * disconnecting, and we have to break spec to remain - * compatible. - */ - case SAVE_POINTERS: - case RESTORE_POINTERS: - /* Accept message by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - /* Enable reselect interrupts */ - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - break; - case EXTENDED_MESSAGE: - /* - * Extended messages are sent in the following format : - * Byte - * 0 EXTENDED_MESSAGE == 1 - * 1 length (includes one byte for code, doesn't - * include first two bytes) - * 2 code - * 3..length+1 arguments - * - * Start the extended message buffer with the EXTENDED_MESSAGE - * byte, since spi_print_msg() wants the whole thing. - */ - extended_msg[0] = EXTENDED_MESSAGE; - /* Accept first byte by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - - EXT_PRINTK("scsi%d: receiving extended message\n", HOSTNO); - - len = 2; - data = extended_msg + 1; - phase = PHASE_MSGIN; - NCR5380_transfer_pio(instance, &phase, &len, &data); - EXT_PRINTK("scsi%d: length=%d, code=0x%02x\n", HOSTNO, - (int)extended_msg[1], (int)extended_msg[2]); - - if (!len && extended_msg[1] <= - (sizeof(extended_msg) - 1)) { - /* Accept third byte by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - len = extended_msg[1] - 1; - data = extended_msg + 3; - phase = PHASE_MSGIN; - - NCR5380_transfer_pio(instance, &phase, &len, &data); - EXT_PRINTK("scsi%d: message received, residual %d\n", - HOSTNO, len); - - switch (extended_msg[2]) { - case EXTENDED_SDTR: - case EXTENDED_WDTR: - case EXTENDED_MODIFY_DATA_POINTER: - case EXTENDED_EXTENDED_IDENTIFY: - tmp = 0; - } - } else if (len) { - printk(KERN_NOTICE "scsi%d: error receiving " - "extended message\n", HOSTNO); - tmp = 0; - } else { - printk(KERN_NOTICE "scsi%d: extended message " - "code %02x length %d is too long\n", - HOSTNO, extended_msg[2], extended_msg[1]); - tmp = 0; - } - /* Fall through to reject message */ - - /* - * If we get something weird that we aren't expecting, - * reject it. - */ - default: - if (!tmp) { - printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO); - spi_print_msg(extended_msg); - printk("\n"); - } else if (tmp != EXTENDED_MESSAGE) - printk(KERN_DEBUG "scsi%d: rejecting unknown " - "message %02x from target %d, lun %d\n", - HOSTNO, tmp, cmd->device->id, cmd->device->lun); - else - printk(KERN_DEBUG "scsi%d: rejecting unknown " - "extended message " - "code %02x, length %d from target %d, lun %d\n", - HOSTNO, extended_msg[1], extended_msg[0], - cmd->device->id, cmd->device->lun); - - - msgout = MESSAGE_REJECT; - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); - break; - } /* switch (tmp) */ - break; - case PHASE_MSGOUT: - len = 1; - data = &msgout; - hostdata->last_message = msgout; - NCR5380_transfer_pio(instance, &phase, &len, &data); - if (msgout == ABORT) { + cmd->scsi_done(cmd); + } + + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + /* + * Restore phase bits to 0 so an interrupted selection, + * arbitration can resume. + */ + NCR5380_write(TARGET_COMMAND_REG, 0); + + while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) + barrier(); + + falcon_dont_release--; + /* ++roman: For Falcon SCSI, release the lock on the + * ST-DMA here if no other commands are waiting on the + * disconnected queue. + */ + falcon_release_lock_if_possible( hostdata ); + return; + case MESSAGE_REJECT: + /* Accept message by clearing ACK */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + /* Enable reselect interrupts */ + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + switch (hostdata->last_message) { + case HEAD_OF_QUEUE_TAG: + case ORDERED_QUEUE_TAG: + case SIMPLE_QUEUE_TAG: + /* The target obviously doesn't support tagged + * queuing, even though it announced this ability in + * its INQUIRY data ?!? (maybe only this LUN?) Ok, + * clear 'tagged_supported' and lock the LUN, since + * the command is treated as untagged further on. + */ + cmd->device->tagged_supported = 0; + hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); + cmd->tag = TAG_NONE; + TAG_PRINTK("scsi%d: target %d lun %d rejected " + "QUEUE_TAG message; tagged queuing " + "disabled\n", + HOSTNO, cmd->device->id, cmd->device->lun); + break; + } + break; + case DISCONNECT: + /* Accept message by clearing ACK */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + local_irq_save(flags); + cmd->device->disconnect = 1; + LIST(cmd,hostdata->disconnected_queue); + NEXT(cmd) = hostdata->disconnected_queue; + hostdata->connected = NULL; + hostdata->disconnected_queue = cmd; + local_irq_restore(flags); + QU_PRINTK("scsi%d: command for target %d lun %d was " + "moved from connected to the " + "disconnected_queue\n", HOSTNO, + cmd->device->id, cmd->device->lun); + /* + * Restore phase bits to 0 so an interrupted selection, + * arbitration can resume. + */ + NCR5380_write(TARGET_COMMAND_REG, 0); + + /* Enable reselect interrupts */ + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + /* Wait for bus free to avoid nasty timeouts */ + while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) + barrier(); + return; + /* + * The SCSI data pointer is *IMPLICITLY* saved on a disconnect + * operation, in violation of the SCSI spec so we can safely + * ignore SAVE/RESTORE pointers calls. + * + * Unfortunately, some disks violate the SCSI spec and + * don't issue the required SAVE_POINTERS message before + * disconnecting, and we have to break spec to remain + * compatible. + */ + case SAVE_POINTERS: + case RESTORE_POINTERS: + /* Accept message by clearing ACK */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + /* Enable reselect interrupts */ + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + break; + case EXTENDED_MESSAGE: +/* + * Extended messages are sent in the following format : + * Byte + * 0 EXTENDED_MESSAGE == 1 + * 1 length (includes one byte for code, doesn't + * include first two bytes) + * 2 code + * 3..length+1 arguments + * + * Start the extended message buffer with the EXTENDED_MESSAGE + * byte, since spi_print_msg() wants the whole thing. + */ + extended_msg[0] = EXTENDED_MESSAGE; + /* Accept first byte by clearing ACK */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + + EXT_PRINTK("scsi%d: receiving extended message\n", HOSTNO); + + len = 2; + data = extended_msg + 1; + phase = PHASE_MSGIN; + NCR5380_transfer_pio(instance, &phase, &len, &data); + EXT_PRINTK("scsi%d: length=%d, code=0x%02x\n", HOSTNO, + (int)extended_msg[1], (int)extended_msg[2]); + + if (!len && extended_msg[1] <= + (sizeof (extended_msg) - 1)) { + /* Accept third byte by clearing ACK */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + len = extended_msg[1] - 1; + data = extended_msg + 3; + phase = PHASE_MSGIN; + + NCR5380_transfer_pio(instance, &phase, &len, &data); + EXT_PRINTK("scsi%d: message received, residual %d\n", + HOSTNO, len); + + switch (extended_msg[2]) { + case EXTENDED_SDTR: + case EXTENDED_WDTR: + case EXTENDED_MODIFY_DATA_POINTER: + case EXTENDED_EXTENDED_IDENTIFY: + tmp = 0; + } + } else if (len) { + printk(KERN_NOTICE "scsi%d: error receiving " + "extended message\n", HOSTNO); + tmp = 0; + } else { + printk(KERN_NOTICE "scsi%d: extended message " + "code %02x length %d is too long\n", + HOSTNO, extended_msg[2], extended_msg[1]); + tmp = 0; + } + /* Fall through to reject message */ + + /* + * If we get something weird that we aren't expecting, + * reject it. + */ + default: + if (!tmp) { + printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO); + spi_print_msg(extended_msg); + printk("\n"); + } else if (tmp != EXTENDED_MESSAGE) + printk(KERN_DEBUG "scsi%d: rejecting unknown " + "message %02x from target %d, lun %d\n", + HOSTNO, tmp, cmd->device->id, cmd->device->lun); + else + printk(KERN_DEBUG "scsi%d: rejecting unknown " + "extended message " + "code %02x, length %d from target %d, lun %d\n", + HOSTNO, extended_msg[1], extended_msg[0], + cmd->device->id, cmd->device->lun); + + + msgout = MESSAGE_REJECT; + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | + ICR_ASSERT_ATN); + break; + } /* switch (tmp) */ + break; + case PHASE_MSGOUT: + len = 1; + data = &msgout; + hostdata->last_message = msgout; + NCR5380_transfer_pio(instance, &phase, &len, &data); + if (msgout == ABORT) { #ifdef SUPPORT_TAGS - cmd_free_tag(cmd); + cmd_free_tag( cmd ); #else - hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); #endif - hostdata->connected = NULL; - cmd->result = DID_ERROR << 16; + hostdata->connected = NULL; + cmd->result = DID_ERROR << 16; #ifdef NCR5380_STATS - collect_stats(hostdata, cmd); + collect_stats(hostdata, cmd); #endif - cmd->scsi_done(cmd); - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - falcon_release_lock_if_possible(hostdata); - return; - } - msgout = NOP; - break; - case PHASE_CMDOUT: - len = cmd->cmd_len; - data = cmd->cmnd; - /* - * XXX for performance reasons, on machines with a - * PSEUDO-DMA architecture we should probably - * use the dma transfer function. - */ - NCR5380_transfer_pio(instance, &phase, &len, &data); - break; - case PHASE_STATIN: - len = 1; - data = &tmp; - NCR5380_transfer_pio(instance, &phase, &len, &data); - cmd->SCp.Status = tmp; - break; - default: - printk("scsi%d: unknown phase\n", HOSTNO); - NCR_PRINT(NDEBUG_ANY); - } /* switch(phase) */ - } /* if (tmp * SR_REQ) */ - } /* while (1) */ + cmd->scsi_done(cmd); + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + falcon_release_lock_if_possible( hostdata ); + return; + } + msgout = NOP; + break; + case PHASE_CMDOUT: + len = cmd->cmd_len; + data = cmd->cmnd; + /* + * XXX for performance reasons, on machines with a + * PSEUDO-DMA architecture we should probably + * use the dma transfer function. + */ + NCR5380_transfer_pio(instance, &phase, &len, + &data); + break; + case PHASE_STATIN: + len = 1; + data = &tmp; + NCR5380_transfer_pio(instance, &phase, &len, &data); + cmd->SCp.Status = tmp; + break; + default: + printk("scsi%d: unknown phase\n", HOSTNO); + NCR_PRINT(NDEBUG_ANY); + } /* switch(phase) */ + } /* if (tmp * SR_REQ) */ + } /* while (1) */ } /* * Function : void NCR5380_reselect (struct Scsi_Host *instance) * - * Purpose : does reselection, initializing the instance->connected - * field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q + * Purpose : does reselection, initializing the instance->connected + * field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q * nexus has been reestablished, - * + * * Inputs : instance - this instance of the NCR5380. * */ -static void NCR5380_reselect(struct Scsi_Host *instance) +static void NCR5380_reselect (struct Scsi_Host *instance) { - SETUP_HOSTDATA(instance); - unsigned char target_mask; - unsigned char lun, phase; - int len; + SETUP_HOSTDATA(instance); + unsigned char target_mask; + unsigned char lun, phase; + int len; #ifdef SUPPORT_TAGS - unsigned char tag; + unsigned char tag; #endif - unsigned char msg[3]; - unsigned char *data; - Scsi_Cmnd *tmp = NULL, *prev; -/* unsigned long flags; */ - - /* - * Disable arbitration, etc. since the host adapter obviously - * lost, and tell an interrupted NCR5380_select() to restart. - */ - - NCR5380_write(MODE_REG, MR_BASE); - hostdata->restart_select = 1; - - target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask); - - RSL_PRINTK("scsi%d: reselect\n", HOSTNO); - - /* - * At this point, we have detected that our SCSI ID is on the bus, - * SEL is true and BSY was false for at least one bus settle delay - * (400 ns). - * - * We must assert BSY ourselves, until the target drops the SEL - * signal. - */ - - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY); - - while (NCR5380_read(STATUS_REG) & SR_SEL) - ; - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - - /* - * Wait for target to go into MSGIN. - */ - - while (!(NCR5380_read(STATUS_REG) & SR_REQ)) - ; - - len = 1; - data = msg; - phase = PHASE_MSGIN; - NCR5380_transfer_pio(instance, &phase, &len, &data); - - if (!(msg[0] & 0x80)) { - printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO); - spi_print_msg(msg); - do_abort(instance); - return; - } - lun = (msg[0] & 0x07); + unsigned char msg[3]; + unsigned char *data; + Scsi_Cmnd *tmp = NULL, *prev; +/* unsigned long flags; */ + + /* + * Disable arbitration, etc. since the host adapter obviously + * lost, and tell an interrupted NCR5380_select() to restart. + */ + + NCR5380_write(MODE_REG, MR_BASE); + hostdata->restart_select = 1; + + target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask); + + RSL_PRINTK("scsi%d: reselect\n", HOSTNO); + + /* + * At this point, we have detected that our SCSI ID is on the bus, + * SEL is true and BSY was false for at least one bus settle delay + * (400 ns). + * + * We must assert BSY ourselves, until the target drops the SEL + * signal. + */ + + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY); + + while (NCR5380_read(STATUS_REG) & SR_SEL); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + + /* + * Wait for target to go into MSGIN. + */ + + while (!(NCR5380_read(STATUS_REG) & SR_REQ)); + + len = 1; + data = msg; + phase = PHASE_MSGIN; + NCR5380_transfer_pio(instance, &phase, &len, &data); + + if (!(msg[0] & 0x80)) { + printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO); + spi_print_msg(msg); + do_abort(instance); + return; + } + lun = (msg[0] & 0x07); #ifdef SUPPORT_TAGS - /* If the phase is still MSGIN, the target wants to send some more - * messages. In case it supports tagged queuing, this is probably a - * SIMPLE_QUEUE_TAG for the I_T_L_Q nexus. - */ - tag = TAG_NONE; - if (phase == PHASE_MSGIN && setup_use_tagged_queuing) { - /* Accept previous IDENTIFY message by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - len = 2; - data = msg + 1; - if (!NCR5380_transfer_pio(instance, &phase, &len, &data) && - msg[1] == SIMPLE_QUEUE_TAG) - tag = msg[2]; - TAG_PRINTK("scsi%d: target mask %02x, lun %d sent tag %d at " - "reselection\n", HOSTNO, target_mask, lun, tag); - } + /* If the phase is still MSGIN, the target wants to send some more + * messages. In case it supports tagged queuing, this is probably a + * SIMPLE_QUEUE_TAG for the I_T_L_Q nexus. + */ + tag = TAG_NONE; + if (phase == PHASE_MSGIN && setup_use_tagged_queuing) { + /* Accept previous IDENTIFY message by clearing ACK */ + NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); + len = 2; + data = msg+1; + if (!NCR5380_transfer_pio(instance, &phase, &len, &data) && + msg[1] == SIMPLE_QUEUE_TAG) + tag = msg[2]; + TAG_PRINTK("scsi%d: target mask %02x, lun %d sent tag %d at " + "reselection\n", HOSTNO, target_mask, lun, tag); + } #endif - - /* - * Find the command corresponding to the I_T_L or I_T_L_Q nexus we - * just reestablished, and remove it from the disconnected queue. - */ - - for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; - tmp; prev = tmp, tmp = NEXT(tmp)) { - if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) + + /* + * Find the command corresponding to the I_T_L or I_T_L_Q nexus we + * just reestablished, and remove it from the disconnected queue. + */ + + for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL; + tmp; prev = tmp, tmp = NEXT(tmp) ) { + if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) #ifdef SUPPORT_TAGS - && (tag == tmp->tag) + && (tag == tmp->tag) #endif - ) { - /* ++guenther: prevent race with falcon_release_lock */ - falcon_dont_release++; - if (prev) { - REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); - SET_NEXT(prev, NEXT(tmp)); - } else { - REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp)); - hostdata->disconnected_queue = NEXT(tmp); - } - SET_NEXT(tmp, NULL); - break; - } + ) { + /* ++guenther: prevent race with falcon_release_lock */ + falcon_dont_release++; + if (prev) { + REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); + NEXT(prev) = NEXT(tmp); + } else { + REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp)); + hostdata->disconnected_queue = NEXT(tmp); + } + NEXT(tmp) = NULL; + break; } - - if (!tmp) { - printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d " + } + + if (!tmp) { + printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d " #ifdef SUPPORT_TAGS - "tag %d " + "tag %d " #endif - "not in disconnected_queue.\n", - HOSTNO, target_mask, lun + "not in disconnected_queue.\n", + HOSTNO, target_mask, lun #ifdef SUPPORT_TAGS - , tag + , tag #endif - ); - /* - * Since we have an established nexus that we can't do anything - * with, we must abort it. - */ - do_abort(instance); - return; - } + ); + /* + * Since we have an established nexus that we can't do anything + * with, we must abort it. + */ + do_abort(instance); + return; + } - /* Accept message by clearing ACK */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + /* Accept message by clearing ACK */ + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - hostdata->connected = tmp; - RSL_PRINTK("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n", - HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag); - falcon_dont_release--; + hostdata->connected = tmp; + RSL_PRINTK("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n", + HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag); + falcon_dont_release--; } @@ -2677,361 +2626,362 @@ static void NCR5380_reselect(struct Scsi_Host *instance) * * Purpose : abort a command * - * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the - * host byte of the result field to, if zero DID_ABORTED is + * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the + * host byte of the result field to, if zero DID_ABORTED is * used. * * Returns : 0 - success, -1 on failure. * - * XXX - there is no way to abort the command that is currently - * connected, you have to wait for it to complete. If this is + * XXX - there is no way to abort the command that is currently + * connected, you have to wait for it to complete. If this is * a problem, we could implement longjmp() / setjmp(), setjmp() - * called where the loop started in NCR5380_main(). + * called where the loop started in NCR5380_main(). */ static -int NCR5380_abort(Scsi_Cmnd *cmd) +int NCR5380_abort (Scsi_Cmnd *cmd) { - struct Scsi_Host *instance = cmd->device->host; - SETUP_HOSTDATA(instance); - Scsi_Cmnd *tmp, **prev; - unsigned long flags; - - printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO); - scsi_print_command(cmd); + struct Scsi_Host *instance = cmd->device->host; + SETUP_HOSTDATA(instance); + Scsi_Cmnd *tmp, **prev; + unsigned long flags; - NCR5380_print_status(instance); + printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO); + scsi_print_command(cmd); - local_irq_save(flags); + NCR5380_print_status (instance); - if (!IS_A_TT() && !falcon_got_lock) - printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_abort\n", - HOSTNO); + local_irq_save(flags); + + if (!IS_A_TT() && !falcon_got_lock) + printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_abort\n", + HOSTNO); - ABRT_PRINTK("scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO, - NCR5380_read(BUS_AND_STATUS_REG), - NCR5380_read(STATUS_REG)); + ABRT_PRINTK("scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO, + NCR5380_read(BUS_AND_STATUS_REG), + NCR5380_read(STATUS_REG)); #if 1 - /* - * Case 1 : If the command is the currently executing command, - * we'll set the aborted flag and return control so that - * information transfer routine can exit cleanly. - */ +/* + * Case 1 : If the command is the currently executing command, + * we'll set the aborted flag and return control so that + * information transfer routine can exit cleanly. + */ - if (hostdata->connected == cmd) { + if (hostdata->connected == cmd) { - ABRT_PRINTK("scsi%d: aborting connected command\n", HOSTNO); - /* - * We should perform BSY checking, and make sure we haven't slipped - * into BUS FREE. - */ + ABRT_PRINTK("scsi%d: aborting connected command\n", HOSTNO); +/* + * We should perform BSY checking, and make sure we haven't slipped + * into BUS FREE. + */ - /* NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); */ - /* - * Since we can't change phases until we've completed the current - * handshake, we have to source or sink a byte of data if the current - * phase is not MSGOUT. - */ +/* NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN); */ +/* + * Since we can't change phases until we've completed the current + * handshake, we have to source or sink a byte of data if the current + * phase is not MSGOUT. + */ - /* - * Return control to the executing NCR drive so we can clear the - * aborted flag and get back into our main loop. - */ +/* + * Return control to the executing NCR drive so we can clear the + * aborted flag and get back into our main loop. + */ - if (do_abort(instance) == 0) { - hostdata->aborted = 1; - hostdata->connected = NULL; - cmd->result = DID_ABORT << 16; + if (do_abort(instance) == 0) { + hostdata->aborted = 1; + hostdata->connected = NULL; + cmd->result = DID_ABORT << 16; #ifdef SUPPORT_TAGS - cmd_free_tag(cmd); + cmd_free_tag( cmd ); #else - hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); #endif - local_irq_restore(flags); - cmd->scsi_done(cmd); - falcon_release_lock_if_possible(hostdata); - return SCSI_ABORT_SUCCESS; - } else { -/* local_irq_restore(flags); */ - printk("scsi%d: abort of connected command failed!\n", HOSTNO); - return SCSI_ABORT_ERROR; - } - } + local_irq_restore(flags); + cmd->scsi_done(cmd); + falcon_release_lock_if_possible( hostdata ); + return SCSI_ABORT_SUCCESS; + } else { +/* local_irq_restore(flags); */ + printk("scsi%d: abort of connected command failed!\n", HOSTNO); + return SCSI_ABORT_ERROR; + } + } #endif - /* - * Case 2 : If the command hasn't been issued yet, we simply remove it - * from the issue queue. - */ - for (prev = (Scsi_Cmnd **)&(hostdata->issue_queue), - tmp = (Scsi_Cmnd *)hostdata->issue_queue; - tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) { - if (cmd == tmp) { - REMOVE(5, *prev, tmp, NEXT(tmp)); - (*prev) = NEXT(tmp); - SET_NEXT(tmp, NULL); - tmp->result = DID_ABORT << 16; - local_irq_restore(flags); - ABRT_PRINTK("scsi%d: abort removed command from issue queue.\n", - HOSTNO); - /* Tagged queuing note: no tag to free here, hasn't been assigned - * yet... */ - tmp->scsi_done(tmp); - falcon_release_lock_if_possible(hostdata); - return SCSI_ABORT_SUCCESS; - } - } - - /* - * Case 3 : If any commands are connected, we're going to fail the abort - * and let the high level SCSI driver retry at a later time or - * issue a reset. - * - * Timeouts, and therefore aborted commands, will be highly unlikely - * and handling them cleanly in this situation would make the common - * case of noresets less efficient, and would pollute our code. So, - * we fail. - */ - - if (hostdata->connected) { - local_irq_restore(flags); - ABRT_PRINTK("scsi%d: abort failed, command connected.\n", HOSTNO); - return SCSI_ABORT_SNOOZE; +/* + * Case 2 : If the command hasn't been issued yet, we simply remove it + * from the issue queue. + */ + for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue), + tmp = (Scsi_Cmnd *) hostdata->issue_queue; + tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) + if (cmd == tmp) { + REMOVE(5, *prev, tmp, NEXT(tmp)); + (*prev) = NEXT(tmp); + NEXT(tmp) = NULL; + tmp->result = DID_ABORT << 16; + local_irq_restore(flags); + ABRT_PRINTK("scsi%d: abort removed command from issue queue.\n", + HOSTNO); + /* Tagged queuing note: no tag to free here, hasn't been assigned + * yet... */ + tmp->scsi_done(tmp); + falcon_release_lock_if_possible( hostdata ); + return SCSI_ABORT_SUCCESS; } - /* - * Case 4: If the command is currently disconnected from the bus, and - * there are no connected commands, we reconnect the I_T_L or - * I_T_L_Q nexus associated with it, go into message out, and send - * an abort message. - * - * This case is especially ugly. In order to reestablish the nexus, we - * need to call NCR5380_select(). The easiest way to implement this - * function was to abort if the bus was busy, and let the interrupt - * handler triggered on the SEL for reselect take care of lost arbitrations - * where necessary, meaning interrupts need to be enabled. - * - * When interrupts are enabled, the queues may change - so we - * can't remove it from the disconnected queue before selecting it - * because that could cause a failure in hashing the nexus if that - * device reselected. - * - * Since the queues may change, we can't use the pointers from when we - * first locate it. - * - * So, we must first locate the command, and if NCR5380_select() - * succeeds, then issue the abort, relocate the command and remove - * it from the disconnected queue. - */ - - for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; - tmp = NEXT(tmp)) { - if (cmd == tmp) { - local_irq_restore(flags); - ABRT_PRINTK("scsi%d: aborting disconnected command.\n", HOSTNO); - - if (NCR5380_select(instance, cmd, (int)cmd->tag)) - return SCSI_ABORT_BUSY; +/* + * Case 3 : If any commands are connected, we're going to fail the abort + * and let the high level SCSI driver retry at a later time or + * issue a reset. + * + * Timeouts, and therefore aborted commands, will be highly unlikely + * and handling them cleanly in this situation would make the common + * case of noresets less efficient, and would pollute our code. So, + * we fail. + */ - ABRT_PRINTK("scsi%d: nexus reestablished.\n", HOSTNO); + if (hostdata->connected) { + local_irq_restore(flags); + ABRT_PRINTK("scsi%d: abort failed, command connected.\n", HOSTNO); + return SCSI_ABORT_SNOOZE; + } - do_abort(instance); +/* + * Case 4: If the command is currently disconnected from the bus, and + * there are no connected commands, we reconnect the I_T_L or + * I_T_L_Q nexus associated with it, go into message out, and send + * an abort message. + * + * This case is especially ugly. In order to reestablish the nexus, we + * need to call NCR5380_select(). The easiest way to implement this + * function was to abort if the bus was busy, and let the interrupt + * handler triggered on the SEL for reselect take care of lost arbitrations + * where necessary, meaning interrupts need to be enabled. + * + * When interrupts are enabled, the queues may change - so we + * can't remove it from the disconnected queue before selecting it + * because that could cause a failure in hashing the nexus if that + * device reselected. + * + * Since the queues may change, we can't use the pointers from when we + * first locate it. + * + * So, we must first locate the command, and if NCR5380_select() + * succeeds, then issue the abort, relocate the command and remove + * it from the disconnected queue. + */ - local_irq_save(flags); - for (prev = (Scsi_Cmnd **)&(hostdata->disconnected_queue), - tmp = (Scsi_Cmnd *)hostdata->disconnected_queue; - tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) { - if (cmd == tmp) { - REMOVE(5, *prev, tmp, NEXT(tmp)); - *prev = NEXT(tmp); - SET_NEXT(tmp, NULL); - tmp->result = DID_ABORT << 16; - /* We must unlock the tag/LUN immediately here, since the - * target goes to BUS FREE and doesn't send us another - * message (COMMAND_COMPLETE or the like) - */ + for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp; + tmp = NEXT(tmp)) + if (cmd == tmp) { + local_irq_restore(flags); + ABRT_PRINTK("scsi%d: aborting disconnected command.\n", HOSTNO); + + if (NCR5380_select (instance, cmd, (int) cmd->tag)) + return SCSI_ABORT_BUSY; + + ABRT_PRINTK("scsi%d: nexus reestablished.\n", HOSTNO); + + do_abort (instance); + + local_irq_save(flags); + for (prev = (Scsi_Cmnd **) &(hostdata->disconnected_queue), + tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; + tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) ) + if (cmd == tmp) { + REMOVE(5, *prev, tmp, NEXT(tmp)); + *prev = NEXT(tmp); + NEXT(tmp) = NULL; + tmp->result = DID_ABORT << 16; + /* We must unlock the tag/LUN immediately here, since the + * target goes to BUS FREE and doesn't send us another + * message (COMMAND_COMPLETE or the like) + */ #ifdef SUPPORT_TAGS - cmd_free_tag(tmp); + cmd_free_tag( tmp ); #else - hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); + hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); #endif - local_irq_restore(flags); - tmp->scsi_done(tmp); - falcon_release_lock_if_possible(hostdata); - return SCSI_ABORT_SUCCESS; - } - } + local_irq_restore(flags); + tmp->scsi_done(tmp); + falcon_release_lock_if_possible( hostdata ); + return SCSI_ABORT_SUCCESS; } } - /* - * Case 5 : If we reached this point, the command was not found in any of - * the queues. - * - * We probably reached this point because of an unlikely race condition - * between the command completing successfully and the abortion code, - * so we won't panic, but we will notify the user in case something really - * broke. - */ +/* + * Case 5 : If we reached this point, the command was not found in any of + * the queues. + * + * We probably reached this point because of an unlikely race condition + * between the command completing successfully and the abortion code, + * so we won't panic, but we will notify the user in case something really + * broke. + */ - local_irq_restore(flags); - printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully\n" - KERN_INFO " before abortion\n", HOSTNO); + local_irq_restore(flags); + printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully\n" + KERN_INFO " before abortion\n", HOSTNO); - /* Maybe it is sufficient just to release the ST-DMA lock... (if - * possible at all) At least, we should check if the lock could be - * released after the abort, in case it is kept due to some bug. - */ - falcon_release_lock_if_possible(hostdata); +/* Maybe it is sufficient just to release the ST-DMA lock... (if + * possible at all) At least, we should check if the lock could be + * released after the abort, in case it is kept due to some bug. + */ + falcon_release_lock_if_possible( hostdata ); - return SCSI_ABORT_NOT_RUNNING; + return SCSI_ABORT_NOT_RUNNING; } -/* +/* * Function : int NCR5380_reset (Scsi_Cmnd *cmd) - * + * * Purpose : reset the SCSI bus. * * Returns : SCSI_RESET_WAKEUP * - */ + */ -static int NCR5380_bus_reset(Scsi_Cmnd *cmd) +static int NCR5380_bus_reset( Scsi_Cmnd *cmd) { - SETUP_HOSTDATA(cmd->device->host); - int i; - unsigned long flags; + SETUP_HOSTDATA(cmd->device->host); + int i; + unsigned long flags; #if 1 - Scsi_Cmnd *connected, *disconnected_queue; + Scsi_Cmnd *connected, *disconnected_queue; #endif - if (!IS_A_TT() && !falcon_got_lock) - printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_reset\n", - H_NO(cmd)); - - NCR5380_print_status(cmd->device->host); - - /* get in phase */ - NCR5380_write(TARGET_COMMAND_REG, - PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG))); - /* assert RST */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST); - udelay(40); - /* reset NCR registers */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - NCR5380_write(MODE_REG, MR_BASE); - NCR5380_write(TARGET_COMMAND_REG, 0); - NCR5380_write(SELECT_ENABLE_REG, 0); - /* ++roman: reset interrupt condition! otherwise no interrupts don't get - * through anymore ... */ - (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG); - -#if 1 /* XXX Should now be done by midlevel code, but it's broken XXX */ - /* XXX see below XXX */ - - /* MSch: old-style reset: actually abort all command processing here */ - - /* After the reset, there are no more connected or disconnected commands - * and no busy units; to avoid problems with re-inserting the commands - * into the issue_queue (via scsi_done()), the aborted commands are - * remembered in local variables first. - */ - local_irq_save(flags); - connected = (Scsi_Cmnd *)hostdata->connected; - hostdata->connected = NULL; - disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue; - hostdata->disconnected_queue = NULL; + if (!IS_A_TT() && !falcon_got_lock) + printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_reset\n", + H_NO(cmd) ); + + NCR5380_print_status (cmd->device->host); + + /* get in phase */ + NCR5380_write( TARGET_COMMAND_REG, + PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); + /* assert RST */ + NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); + udelay (40); + /* reset NCR registers */ + NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); + NCR5380_write( MODE_REG, MR_BASE ); + NCR5380_write( TARGET_COMMAND_REG, 0 ); + NCR5380_write( SELECT_ENABLE_REG, 0 ); + /* ++roman: reset interrupt condition! otherwise no interrupts don't get + * through anymore ... */ + (void)NCR5380_read( RESET_PARITY_INTERRUPT_REG ); + +#if 1 /* XXX Should now be done by midlevel code, but it's broken XXX */ + /* XXX see below XXX */ + + /* MSch: old-style reset: actually abort all command processing here */ + + /* After the reset, there are no more connected or disconnected commands + * and no busy units; to avoid problems with re-inserting the commands + * into the issue_queue (via scsi_done()), the aborted commands are + * remembered in local variables first. + */ + local_irq_save(flags); + connected = (Scsi_Cmnd *)hostdata->connected; + hostdata->connected = NULL; + disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue; + hostdata->disconnected_queue = NULL; #ifdef SUPPORT_TAGS - free_all_tags(); + free_all_tags(); #endif - for (i = 0; i < 8; ++i) - hostdata->busy[i] = 0; + for( i = 0; i < 8; ++i ) + hostdata->busy[i] = 0; #ifdef REAL_DMA - hostdata->dma_len = 0; + hostdata->dma_len = 0; #endif - local_irq_restore(flags); - - /* In order to tell the mid-level code which commands were aborted, - * set the command status to DID_RESET and call scsi_done() !!! - * This ultimately aborts processing of these commands in the mid-level. - */ - - if ((cmd = connected)) { - ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd)); - cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16); - cmd->scsi_done(cmd); - } - - for (i = 0; (cmd = disconnected_queue); ++i) { - disconnected_queue = NEXT(cmd); - SET_NEXT(cmd, NULL); - cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16); - cmd->scsi_done(cmd); - } - if (i > 0) - ABRT_PRINTK("scsi: reset aborted %d disconnected command(s)\n", i); - - /* The Falcon lock should be released after a reset... - */ - /* ++guenther: moved to atari_scsi_reset(), to prevent a race between - * unlocking and enabling dma interrupt. - */ -/* falcon_release_lock_if_possible( hostdata );*/ + local_irq_restore(flags); + + /* In order to tell the mid-level code which commands were aborted, + * set the command status to DID_RESET and call scsi_done() !!! + * This ultimately aborts processing of these commands in the mid-level. + */ + + if ((cmd = connected)) { + ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd)); + cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16); + cmd->scsi_done( cmd ); + } + + for (i = 0; (cmd = disconnected_queue); ++i) { + disconnected_queue = NEXT(cmd); + NEXT(cmd) = NULL; + cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16); + cmd->scsi_done( cmd ); + } + if (i > 0) + ABRT_PRINTK("scsi: reset aborted %d disconnected command(s)\n", i); + +/* The Falcon lock should be released after a reset... + */ +/* ++guenther: moved to atari_scsi_reset(), to prevent a race between + * unlocking and enabling dma interrupt. + */ +/* falcon_release_lock_if_possible( hostdata );*/ - /* since all commands have been explicitly terminated, we need to tell - * the midlevel code that the reset was SUCCESSFUL, and there is no - * need to 'wake up' the commands by a request_sense - */ - return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET; + /* since all commands have been explicitly terminated, we need to tell + * the midlevel code that the reset was SUCCESSFUL, and there is no + * need to 'wake up' the commands by a request_sense + */ + return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET; #else /* 1 */ - /* MSch: new-style reset handling: let the mid-level do what it can */ - - /* ++guenther: MID-LEVEL IS STILL BROKEN. - * Mid-level is supposed to requeue all commands that were active on the - * various low-level queues. In fact it does this, but that's not enough - * because all these commands are subject to timeout. And if a timeout - * happens for any removed command, *_abort() is called but all queues - * are now empty. Abort then gives up the falcon lock, which is fatal, - * since the mid-level will queue more commands and must have the lock - * (it's all happening inside timer interrupt handler!!). - * Even worse, abort will return NOT_RUNNING for all those commands not - * on any queue, so they won't be retried ... - * - * Conclusion: either scsi.c disables timeout for all resetted commands - * immediately, or we lose! As of linux-2.0.20 it doesn't. - */ - - /* After the reset, there are no more connected or disconnected commands - * and no busy units; so clear the low-level status here to avoid - * conflicts when the mid-level code tries to wake up the affected - * commands! - */ - - if (hostdata->issue_queue) - ABRT_PRINTK("scsi%d: reset aborted issued command(s)\n", H_NO(cmd)); - if (hostdata->connected) - ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd)); - if (hostdata->disconnected_queue) - ABRT_PRINTK("scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd)); - - local_irq_save(flags); - hostdata->issue_queue = NULL; - hostdata->connected = NULL; - hostdata->disconnected_queue = NULL; + /* MSch: new-style reset handling: let the mid-level do what it can */ + + /* ++guenther: MID-LEVEL IS STILL BROKEN. + * Mid-level is supposed to requeue all commands that were active on the + * various low-level queues. In fact it does this, but that's not enough + * because all these commands are subject to timeout. And if a timeout + * happens for any removed command, *_abort() is called but all queues + * are now empty. Abort then gives up the falcon lock, which is fatal, + * since the mid-level will queue more commands and must have the lock + * (it's all happening inside timer interrupt handler!!). + * Even worse, abort will return NOT_RUNNING for all those commands not + * on any queue, so they won't be retried ... + * + * Conclusion: either scsi.c disables timeout for all resetted commands + * immediately, or we lose! As of linux-2.0.20 it doesn't. + */ + + /* After the reset, there are no more connected or disconnected commands + * and no busy units; so clear the low-level status here to avoid + * conflicts when the mid-level code tries to wake up the affected + * commands! + */ + + if (hostdata->issue_queue) + ABRT_PRINTK("scsi%d: reset aborted issued command(s)\n", H_NO(cmd)); + if (hostdata->connected) + ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd)); + if (hostdata->disconnected_queue) + ABRT_PRINTK("scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd)); + + local_irq_save(flags); + hostdata->issue_queue = NULL; + hostdata->connected = NULL; + hostdata->disconnected_queue = NULL; #ifdef SUPPORT_TAGS - free_all_tags(); + free_all_tags(); #endif - for (i = 0; i < 8; ++i) - hostdata->busy[i] = 0; + for( i = 0; i < 8; ++i ) + hostdata->busy[i] = 0; #ifdef REAL_DMA - hostdata->dma_len = 0; + hostdata->dma_len = 0; #endif - local_irq_restore(flags); + local_irq_restore(flags); - /* we did no complete reset of all commands, so a wakeup is required */ - return SCSI_RESET_WAKEUP | SCSI_RESET_BUS_RESET; + /* we did no complete reset of all commands, so a wakeup is required */ + return SCSI_RESET_WAKEUP | SCSI_RESET_BUS_RESET; #endif /* 1 */ } + +/* Local Variables: */ +/* tab-width: 8 */ +/* End: */ diff --git a/trunk/drivers/scsi/atari_scsi.c b/trunk/drivers/scsi/atari_scsi.c index 6f8403b82ba1..642de7b2b7a2 100644 --- a/trunk/drivers/scsi/atari_scsi.c +++ b/trunk/drivers/scsi/atari_scsi.c @@ -69,9 +69,9 @@ #define NDEBUG (0) -#define NDEBUG_ABORT 0x00100000 -#define NDEBUG_TAGS 0x00200000 -#define NDEBUG_MERGING 0x00400000 +#define NDEBUG_ABORT 0x800000 +#define NDEBUG_TAGS 0x1000000 +#define NDEBUG_MERGING 0x2000000 #define AUTOSENSE /* For the Atari version, use only polled IO or REAL_DMA */ @@ -186,37 +186,38 @@ static inline void DISABLE_IRQ(void) /***************************** Prototypes *****************************/ #ifdef REAL_DMA -static int scsi_dma_is_ignored_buserr(unsigned char dma_stat); -static void atari_scsi_fetch_restbytes(void); -static long atari_scsi_dma_residual(struct Scsi_Host *instance); -static int falcon_classify_cmd(Scsi_Cmnd *cmd); -static unsigned long atari_dma_xfer_len(unsigned long wanted_len, - Scsi_Cmnd *cmd, int write_flag); +static int scsi_dma_is_ignored_buserr( unsigned char dma_stat ); +static void atari_scsi_fetch_restbytes( void ); +static long atari_scsi_dma_residual( struct Scsi_Host *instance ); +static int falcon_classify_cmd( Scsi_Cmnd *cmd ); +static unsigned long atari_dma_xfer_len( unsigned long wanted_len, + Scsi_Cmnd *cmd, int write_flag ); #endif -static irqreturn_t scsi_tt_intr(int irq, void *dummy); -static irqreturn_t scsi_falcon_intr(int irq, void *dummy); -static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata); -static void falcon_get_lock(void); +static irqreturn_t scsi_tt_intr( int irq, void *dummy); +static irqreturn_t scsi_falcon_intr( int irq, void *dummy); +static void falcon_release_lock_if_possible( struct NCR5380_hostdata * + hostdata ); +static void falcon_get_lock( void ); #ifdef CONFIG_ATARI_SCSI_RESET_BOOT -static void atari_scsi_reset_boot(void); +static void atari_scsi_reset_boot( void ); #endif -static unsigned char atari_scsi_tt_reg_read(unsigned char reg); -static void atari_scsi_tt_reg_write(unsigned char reg, unsigned char value); -static unsigned char atari_scsi_falcon_reg_read(unsigned char reg); -static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value); +static unsigned char atari_scsi_tt_reg_read( unsigned char reg ); +static void atari_scsi_tt_reg_write( unsigned char reg, unsigned char value); +static unsigned char atari_scsi_falcon_reg_read( unsigned char reg ); +static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char value ); /************************* End of Prototypes **************************/ -static struct Scsi_Host *atari_scsi_host; -static unsigned char (*atari_scsi_reg_read)(unsigned char reg); -static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value); +static struct Scsi_Host *atari_scsi_host = NULL; +static unsigned char (*atari_scsi_reg_read)( unsigned char reg ); +static void (*atari_scsi_reg_write)( unsigned char reg, unsigned char value ); #ifdef REAL_DMA static unsigned long atari_dma_residual, atari_dma_startaddr; static short atari_dma_active; /* pointer to the dribble buffer */ -static char *atari_dma_buffer; +static char *atari_dma_buffer = NULL; /* precalculated physical address of the dribble buffer */ static unsigned long atari_dma_phys_buffer; /* != 0 tells the Falcon int handler to copy data from the dribble buffer */ @@ -232,7 +233,7 @@ static char *atari_dma_orig_addr; static unsigned long atari_dma_stram_mask; #define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0) /* number of bytes to cut from a transfer to handle NCR overruns */ -static int atari_read_overruns; +static int atari_read_overruns = 0; #endif static int setup_can_queue = -1; @@ -255,10 +256,10 @@ module_param(setup_hostid, int, 0); #if defined(REAL_DMA) -static int scsi_dma_is_ignored_buserr(unsigned char dma_stat) +static int scsi_dma_is_ignored_buserr( unsigned char dma_stat ) { int i; - unsigned long addr = SCSI_DMA_READ_P(dma_addr), end_addr; + unsigned long addr = SCSI_DMA_READ_P( dma_addr ), end_addr; if (dma_stat & 0x01) { @@ -266,14 +267,15 @@ static int scsi_dma_is_ignored_buserr(unsigned char dma_stat) * physical memory chunk (DMA prefetch!), but that doesn't hurt. * Check for this case: */ - - for (i = 0; i < m68k_num_memory; ++i) { - end_addr = m68k_memory[i].addr + m68k_memory[i].size; + + for( i = 0; i < m68k_num_memory; ++i ) { + end_addr = m68k_memory[i].addr + + m68k_memory[i].size; if (end_addr <= addr && addr <= end_addr + 4) - return 1; + return( 1 ); } } - return 0; + return( 0 ); } @@ -282,27 +284,28 @@ static int scsi_dma_is_ignored_buserr(unsigned char dma_stat) * end-of-DMA, both SCSI ints are triggered simultaneously, so the NCR int has * to clear the DMA int pending bit before it allows other level 6 interrupts. */ -static void scsi_dma_buserr(int irq, void *dummy) +static void scsi_dma_buserr (int irq, void *dummy) { - unsigned char dma_stat = tt_scsi_dma.dma_ctrl; + unsigned char dma_stat = tt_scsi_dma.dma_ctrl; /* Don't do anything if a NCR interrupt is pending. Probably it's just * masked... */ - if (atari_irq_pending(IRQ_TT_MFP_SCSI)) + if (atari_irq_pending( IRQ_TT_MFP_SCSI )) return; - + printk("Bad SCSI DMA interrupt! dma_addr=0x%08lx dma_stat=%02x dma_cnt=%08lx\n", SCSI_DMA_READ_P(dma_addr), dma_stat, SCSI_DMA_READ_P(dma_cnt)); if (dma_stat & 0x80) { - if (!scsi_dma_is_ignored_buserr(dma_stat)) - printk("SCSI DMA bus error -- bad DMA programming!\n"); - } else { + if (!scsi_dma_is_ignored_buserr( dma_stat )) + printk( "SCSI DMA bus error -- bad DMA programming!\n" ); + } + else { /* Under normal circumstances we never should get to this point, * since both interrupts are triggered simultaneously and the 5380 * int has higher priority. When this irq is handled, that DMA * interrupt is cleared. So a warning message is printed here. */ - printk("SCSI DMA intr ?? -- this shouldn't happen!\n"); + printk( "SCSI DMA intr ?? -- this shouldn't happen!\n" ); } } #endif @@ -310,7 +313,7 @@ static void scsi_dma_buserr(int irq, void *dummy) #endif -static irqreturn_t scsi_tt_intr(int irq, void *dummy) +static irqreturn_t scsi_tt_intr (int irq, void *dummy) { #ifdef REAL_DMA int dma_stat; @@ -324,7 +327,7 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy) * is that a bus error occurred... */ if (dma_stat & 0x80) { - if (!scsi_dma_is_ignored_buserr(dma_stat)) { + if (!scsi_dma_is_ignored_buserr( dma_stat )) { printk(KERN_ERR "SCSI DMA caused bus error near 0x%08lx\n", SCSI_DMA_READ_P(dma_addr)); printk(KERN_CRIT "SCSI DMA bus error -- bad DMA programming!"); @@ -341,7 +344,8 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy) * data reg! */ if ((dma_stat & 0x02) && !(dma_stat & 0x40)) { - atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P(dma_addr) - atari_dma_startaddr); + atari_dma_residual = HOSTDATA_DMALEN - (SCSI_DMA_READ_P( dma_addr ) - + atari_dma_startaddr); DMA_PRINTK("SCSI DMA: There are %ld residual bytes.\n", atari_dma_residual); @@ -349,30 +353,28 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy) if ((signed int)atari_dma_residual < 0) atari_dma_residual = 0; if ((dma_stat & 1) == 0) { - /* - * After read operations, we maybe have to - * transport some rest bytes - */ + /* After read operations, we maybe have to + transport some rest bytes */ atari_scsi_fetch_restbytes(); - } else { - /* - * There seems to be a nasty bug in some SCSI-DMA/NCR - * combinations: If a target disconnects while a write - * operation is going on, the address register of the - * DMA may be a few bytes farer than it actually read. - * This is probably due to DMA prefetching and a delay - * between DMA and NCR. Experiments showed that the - * dma_addr is 9 bytes to high, but this could vary. - * The problem is, that the residual is thus calculated - * wrong and the next transfer will start behind where - * it should. So we round up the residual to the next - * multiple of a sector size, if it isn't already a - * multiple and the originally expected transfer size - * was. The latter condition is there to ensure that - * the correction is taken only for "real" data - * transfers and not for, e.g., the parameters of some - * other command. These shouldn't disconnect anyway. - */ + } + else { + /* There seems to be a nasty bug in some SCSI-DMA/NCR + combinations: If a target disconnects while a write + operation is going on, the address register of the + DMA may be a few bytes farer than it actually read. + This is probably due to DMA prefetching and a delay + between DMA and NCR. Experiments showed that the + dma_addr is 9 bytes to high, but this could vary. + The problem is, that the residual is thus calculated + wrong and the next transfer will start behind where + it should. So we round up the residual to the next + multiple of a sector size, if it isn't already a + multiple and the originally expected transfer size + was. The latter condition is there to ensure that + the correction is taken only for "real" data + transfers and not for, e.g., the parameters of some + other command. These shouldn't disconnect anyway. + */ if (atari_dma_residual & 0x1ff) { DMA_PRINTK("SCSI DMA: DMA bug corrected, " "difference %ld bytes\n", @@ -392,18 +394,18 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy) } #endif /* REAL_DMA */ - - NCR5380_intr(0, 0); + + NCR5380_intr (0, 0, 0); #if 0 /* To be sure the int is not masked */ - atari_enable_irq(IRQ_TT_MFP_SCSI); + atari_enable_irq( IRQ_TT_MFP_SCSI ); #endif return IRQ_HANDLED; } -static irqreturn_t scsi_falcon_intr(int irq, void *dummy) +static irqreturn_t scsi_falcon_intr (int irq, void *dummy) { #ifdef REAL_DMA int dma_stat; @@ -428,7 +430,7 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy) * bytes are stuck in the ST-DMA fifo (there's no way to reach them!) */ if (atari_dma_active && (dma_stat & 0x02)) { - unsigned long transferred; + unsigned long transferred; transferred = SCSI_DMA_GETADR() - atari_dma_startaddr; /* The ST-DMA address is incremented in 2-byte steps, but the @@ -443,7 +445,8 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy) atari_dma_residual = HOSTDATA_DMALEN - transferred; DMA_PRINTK("SCSI DMA: There are %ld residual bytes.\n", atari_dma_residual); - } else + } + else atari_dma_residual = 0; atari_dma_active = 0; @@ -458,13 +461,13 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dummy) #endif /* REAL_DMA */ - NCR5380_intr(0, 0); + NCR5380_intr (0, 0, 0); return IRQ_HANDLED; } #ifdef REAL_DMA -static void atari_scsi_fetch_restbytes(void) +static void atari_scsi_fetch_restbytes( void ) { int nr; char *src, *dst; @@ -502,17 +505,19 @@ static int falcon_dont_release = 0; * again (but others waiting longer more probably will win). */ -static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata) +static void +falcon_release_lock_if_possible( struct NCR5380_hostdata * hostdata ) { unsigned long flags; - - if (IS_A_TT()) - return; - + + if (IS_A_TT()) return; + local_irq_save(flags); - if (falcon_got_lock && !hostdata->disconnected_queue && - !hostdata->issue_queue && !hostdata->connected) { + if (falcon_got_lock && + !hostdata->disconnected_queue && + !hostdata->issue_queue && + !hostdata->connected) { if (falcon_dont_release) { #if 0 @@ -523,7 +528,7 @@ static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata) } falcon_got_lock = 0; stdma_release(); - wake_up(&falcon_fairness_wait); + wake_up( &falcon_fairness_wait ); } local_irq_restore(flags); @@ -544,31 +549,31 @@ static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata) * Complicated, complicated.... Sigh... */ -static void falcon_get_lock(void) +static void falcon_get_lock( void ) { unsigned long flags; - if (IS_A_TT()) - return; + if (IS_A_TT()) return; local_irq_save(flags); - while (!in_irq() && falcon_got_lock && stdma_others_waiting()) - sleep_on(&falcon_fairness_wait); + while( !in_interrupt() && falcon_got_lock && stdma_others_waiting() ) + sleep_on( &falcon_fairness_wait ); while (!falcon_got_lock) { - if (in_irq()) - panic("Falcon SCSI hasn't ST-DMA lock in interrupt"); + if (in_interrupt()) + panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" ); if (!falcon_trying_lock) { falcon_trying_lock = 1; stdma_lock(scsi_falcon_intr, NULL); falcon_got_lock = 1; falcon_trying_lock = 0; - wake_up(&falcon_try_wait); - } else { - sleep_on(&falcon_try_wait); + wake_up( &falcon_try_wait ); } - } + else { + sleep_on( &falcon_try_wait ); + } + } local_irq_restore(flags); if (!falcon_got_lock) @@ -582,18 +587,18 @@ static void falcon_get_lock(void) */ #if 0 -int atari_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) +int atari_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { /* falcon_get_lock(); * ++guenther: moved to NCR5380_queue_command() to prevent * race condition, see there for an explanation. */ - return NCR5380_queue_command(cmd, done); + return( NCR5380_queue_command( cmd, done ) ); } #endif -int atari_scsi_detect(struct scsi_host_template *host) +int atari_scsi_detect (struct scsi_host_template *host) { static int called = 0; struct Scsi_Host *instance; @@ -601,7 +606,7 @@ int atari_scsi_detect(struct scsi_host_template *host) if (!MACH_IS_ATARI || (!ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(TT_SCSI)) || called) - return 0; + return( 0 ); host->proc_name = "Atari"; @@ -650,33 +655,32 @@ int atari_scsi_detect(struct scsi_host_template *host) !ATARIHW_PRESENT(EXTD_DMA) && m68k_num_memory > 1) { atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI"); if (!atari_dma_buffer) { - printk(KERN_ERR "atari_scsi_detect: can't allocate ST-RAM " - "double buffer\n"); - return 0; + printk( KERN_ERR "atari_scsi_detect: can't allocate ST-RAM " + "double buffer\n" ); + return( 0 ); } - atari_dma_phys_buffer = virt_to_phys(atari_dma_buffer); + atari_dma_phys_buffer = virt_to_phys( atari_dma_buffer ); atari_dma_orig_addr = 0; } #endif - instance = scsi_register(host, sizeof(struct NCR5380_hostdata)); - if (instance == NULL) { + instance = scsi_register (host, sizeof (struct NCR5380_hostdata)); + if(instance == NULL) + { atari_stram_free(atari_dma_buffer); atari_dma_buffer = 0; return 0; } atari_scsi_host = instance; - /* - * Set irq to 0, to avoid that the mid-level code disables our interrupt - * during queue_command calls. This is completely unnecessary, and even - * worse causes bad problems on the Falcon, where the int is shared with - * IDE and floppy! - */ + /* Set irq to 0, to avoid that the mid-level code disables our interrupt + * during queue_command calls. This is completely unnecessary, and even + * worse causes bad problems on the Falcon, where the int is shared with + * IDE and floppy! */ instance->irq = 0; #ifdef CONFIG_ATARI_SCSI_RESET_BOOT atari_scsi_reset_boot(); #endif - NCR5380_init(instance, 0); + NCR5380_init (instance, 0); if (IS_A_TT()) { @@ -723,10 +727,11 @@ int atari_scsi_detect(struct scsi_host_template *host) * the rest data bug is fixed, this can be lowered to 1. */ atari_read_overruns = 4; - } + } #endif /*REAL_DMA*/ - } else { /* ! IS_A_TT */ - + } + else { /* ! IS_A_TT */ + /* Nothing to do for the interrupt: the ST-DMA is initialized * already by atari_init_INTS() */ @@ -751,21 +756,23 @@ int atari_scsi_detect(struct scsi_host_template *host) setup_use_tagged_queuing ? "yes" : "no", #endif instance->hostt->this_id ); - NCR5380_print_options(instance); - printk("\n"); + NCR5380_print_options (instance); + printk ("\n"); called = 1; - return 1; + return( 1 ); } -int atari_scsi_release(struct Scsi_Host *sh) +#ifdef MODULE +int atari_scsi_release (struct Scsi_Host *sh) { if (IS_A_TT()) free_irq(IRQ_TT_MFP_SCSI, scsi_tt_intr); if (atari_dma_buffer) - atari_stram_free(atari_dma_buffer); + atari_stram_free (atari_dma_buffer); return 1; } +#endif void __init atari_scsi_setup(char *str, int *ints) { @@ -774,9 +781,9 @@ void __init atari_scsi_setup(char *str, int *ints) * Defaults depend on TT or Falcon, hostid determined at run time. * Negative values mean don't change. */ - + if (ints[0] < 1) { - printk("atari_scsi_setup: no arguments!\n"); + printk( "atari_scsi_setup: no arguments!\n" ); return; } @@ -802,7 +809,7 @@ void __init atari_scsi_setup(char *str, int *ints) if (ints[4] >= 0 && ints[4] <= 7) setup_hostid = ints[4]; else if (ints[4] > 7) - printk("atari_scsi_setup: invalid host ID %d !\n", ints[4]); + printk( "atari_scsi_setup: invalid host ID %d !\n", ints[4] ); } #ifdef SUPPORT_TAGS if (ints[0] >= 5) { @@ -814,7 +821,7 @@ void __init atari_scsi_setup(char *str, int *ints) int atari_scsi_bus_reset(Scsi_Cmnd *cmd) { - int rv; + int rv; struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)cmd->device->host->hostdata; @@ -824,12 +831,13 @@ int atari_scsi_bus_reset(Scsi_Cmnd *cmd) */ /* And abort a maybe active DMA transfer */ if (IS_A_TT()) { - atari_turnoff_irq(IRQ_TT_MFP_SCSI); + atari_turnoff_irq( IRQ_TT_MFP_SCSI ); #ifdef REAL_DMA tt_scsi_dma.dma_ctrl = 0; #endif /* REAL_DMA */ - } else { - atari_turnoff_irq(IRQ_MFP_FSCSI); + } + else { + atari_turnoff_irq( IRQ_MFP_FSCSI ); #ifdef REAL_DMA st_dma.dma_mode_status = 0x90; atari_dma_active = 0; @@ -841,51 +849,52 @@ int atari_scsi_bus_reset(Scsi_Cmnd *cmd) /* Re-enable ints */ if (IS_A_TT()) { - atari_turnon_irq(IRQ_TT_MFP_SCSI); - } else { - atari_turnon_irq(IRQ_MFP_FSCSI); + atari_turnon_irq( IRQ_TT_MFP_SCSI ); + } + else { + atari_turnon_irq( IRQ_MFP_FSCSI ); } if ((rv & SCSI_RESET_ACTION) == SCSI_RESET_SUCCESS) falcon_release_lock_if_possible(hostdata); - return rv; + return( rv ); } - + #ifdef CONFIG_ATARI_SCSI_RESET_BOOT static void __init atari_scsi_reset_boot(void) { unsigned long end; - + /* * Do a SCSI reset to clean up the bus during initialization. No messing * with the queues, interrupts, or locks necessary here. */ - printk("Atari SCSI: resetting the SCSI bus..."); + printk( "Atari SCSI: resetting the SCSI bus..." ); /* get in phase */ - NCR5380_write(TARGET_COMMAND_REG, - PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG))); + NCR5380_write( TARGET_COMMAND_REG, + PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); /* assert RST */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST); + NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); /* The min. reset hold time is 25us, so 40us should be enough */ - udelay(50); + udelay( 50 ); /* reset RST and interrupt */ - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - NCR5380_read(RESET_PARITY_INTERRUPT_REG); + NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); + NCR5380_read( RESET_PARITY_INTERRUPT_REG ); end = jiffies + AFTER_RESET_DELAY; while (time_before(jiffies, end)) barrier(); - printk(" done\n"); + printk( " done\n" ); } #endif -const char *atari_scsi_info(struct Scsi_Host *host) +const char * atari_scsi_info (struct Scsi_Host *host) { /* atari_scsi_detect() is verbose enough... */ static const char string[] = "Atari native SCSI"; @@ -895,10 +904,10 @@ const char *atari_scsi_info(struct Scsi_Host *host) #if defined(REAL_DMA) -unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, void *data, - unsigned long count, int dir) +unsigned long atari_scsi_dma_setup( struct Scsi_Host *instance, void *data, + unsigned long count, int dir ) { - unsigned long addr = virt_to_phys(data); + unsigned long addr = virt_to_phys( data ); DMA_PRINTK("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, " "dir = %d\n", instance->host_no, data, addr, count, dir); @@ -910,37 +919,38 @@ unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, void *data, * wanted address. */ if (dir) - memcpy(atari_dma_buffer, data, count); + memcpy( atari_dma_buffer, data, count ); else atari_dma_orig_addr = data; addr = atari_dma_phys_buffer; } - + atari_dma_startaddr = addr; /* Needed for calculating residual later. */ - + /* Cache cleanup stuff: On writes, push any dirty cache out before sending * it to the peripheral. (Must be done before DMA setup, since at least * the ST-DMA begins to fill internal buffers right after setup. For * reads, invalidate any cache, may be altered after DMA without CPU * knowledge. - * + * * ++roman: For the Medusa, there's no need at all for that cache stuff, * because the hardware does bus snooping (fine!). */ - dma_cache_maintenance(addr, count, dir); + dma_cache_maintenance( addr, count, dir ); if (count == 0) printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !\n"); if (IS_A_TT()) { tt_scsi_dma.dma_ctrl = dir; - SCSI_DMA_WRITE_P(dma_addr, addr); - SCSI_DMA_WRITE_P(dma_cnt, count); + SCSI_DMA_WRITE_P( dma_addr, addr ); + SCSI_DMA_WRITE_P( dma_cnt, count ); tt_scsi_dma.dma_ctrl = dir | 2; - } else { /* ! IS_A_TT */ - + } + else { /* ! IS_A_TT */ + /* set address */ - SCSI_DMA_SETADR(addr); + SCSI_DMA_SETADR( addr ); /* toggle direction bit to clear FIFO and set DMA direction */ dir <<= 8; @@ -958,13 +968,13 @@ unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, void *data, atari_dma_active = 1; } - return count; + return( count ); } -static long atari_scsi_dma_residual(struct Scsi_Host *instance) +static long atari_scsi_dma_residual( struct Scsi_Host *instance ) { - return atari_dma_residual; + return( atari_dma_residual ); } @@ -972,13 +982,13 @@ static long atari_scsi_dma_residual(struct Scsi_Host *instance) #define CMD_SURELY_BYTE_MODE 1 #define CMD_MODE_UNKNOWN 2 -static int falcon_classify_cmd(Scsi_Cmnd *cmd) +static int falcon_classify_cmd( Scsi_Cmnd *cmd ) { unsigned char opcode = cmd->cmnd[0]; - + if (opcode == READ_DEFECT_DATA || opcode == READ_LONG || - opcode == READ_BUFFER) - return CMD_SURELY_BYTE_MODE; + opcode == READ_BUFFER) + return( CMD_SURELY_BYTE_MODE ); else if (opcode == READ_6 || opcode == READ_10 || opcode == 0xa8 /* READ_12 */ || opcode == READ_REVERSE || opcode == RECOVER_BUFFERED_DATA) { @@ -986,11 +996,12 @@ static int falcon_classify_cmd(Scsi_Cmnd *cmd) * needed here: The transfer is block-mode only if the 'fixed' bit is * set! */ if (cmd->device->type == TYPE_TAPE && !(cmd->cmnd[1] & 1)) - return CMD_SURELY_BYTE_MODE; + return( CMD_SURELY_BYTE_MODE ); else - return CMD_SURELY_BLOCK_MODE; - } else - return CMD_MODE_UNKNOWN; + return( CMD_SURELY_BLOCK_MODE ); + } + else + return( CMD_MODE_UNKNOWN ); } @@ -1003,18 +1014,19 @@ static int falcon_classify_cmd(Scsi_Cmnd *cmd) * the overrun problem, so this question is academic :-) */ -static unsigned long atari_dma_xfer_len(unsigned long wanted_len, - Scsi_Cmnd *cmd, int write_flag) +static unsigned long atari_dma_xfer_len( unsigned long wanted_len, + Scsi_Cmnd *cmd, + int write_flag ) { unsigned long possible_len, limit; #ifndef CONFIG_TT_DMA_EMUL if (MACH_IS_HADES) /* Hades has no SCSI DMA at all :-( Always force use of PIO */ - return 0; -#endif + return( 0 ); +#endif if (IS_A_TT()) /* TT SCSI DMA can transfer arbitrary #bytes */ - return wanted_len; + return( wanted_len ); /* ST DMA chip is stupid -- only multiples of 512 bytes! (and max. * 255*512 bytes, but this should be enough) @@ -1050,7 +1062,8 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, * this). */ possible_len = wanted_len; - } else { + } + else { /* Read operations: if the wanted transfer length is not a multiple of * 512, we cannot use DMA, since the ST-DMA cannot split transfers * (no interrupt on DMA finished!) @@ -1060,15 +1073,15 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, else { /* Now classify the command (see above) and decide whether it is * allowed to do DMA at all */ - switch (falcon_classify_cmd(cmd)) { - case CMD_SURELY_BLOCK_MODE: + switch( falcon_classify_cmd( cmd )) { + case CMD_SURELY_BLOCK_MODE: possible_len = wanted_len; break; - case CMD_SURELY_BYTE_MODE: + case CMD_SURELY_BYTE_MODE: possible_len = 0; /* DMA prohibited */ break; - case CMD_MODE_UNKNOWN: - default: + case CMD_MODE_UNKNOWN: + default: /* For unknown commands assume block transfers if the transfer * size/allocation length is >= 1024 */ possible_len = (wanted_len < 1024) ? 0 : wanted_len; @@ -1076,9 +1089,9 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, } } } - + /* Last step: apply the hard limit on DMA transfers */ - limit = (atari_dma_buffer && !STRAM_ADDR(virt_to_phys(cmd->SCp.ptr))) ? + limit = (atari_dma_buffer && !STRAM_ADDR( virt_to_phys(cmd->SCp.ptr) )) ? STRAM_BUFFER_SIZE : 255*512; if (possible_len > limit) possible_len = limit; @@ -1087,7 +1100,7 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, DMA_PRINTK("Sorry, must cut DMA transfer size to %ld bytes " "instead of %ld\n", possible_len, wanted_len); - return possible_len; + return( possible_len ); } @@ -1101,23 +1114,23 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, * NCR5380_write call these functions via function pointers. */ -static unsigned char atari_scsi_tt_reg_read(unsigned char reg) +static unsigned char atari_scsi_tt_reg_read( unsigned char reg ) { - return tt_scsi_regp[reg * 2]; + return( tt_scsi_regp[reg * 2] ); } -static void atari_scsi_tt_reg_write(unsigned char reg, unsigned char value) +static void atari_scsi_tt_reg_write( unsigned char reg, unsigned char value ) { tt_scsi_regp[reg * 2] = value; } -static unsigned char atari_scsi_falcon_reg_read(unsigned char reg) +static unsigned char atari_scsi_falcon_reg_read( unsigned char reg ) { dma_wd.dma_mode_status= (u_short)(0x88 + reg); - return (u_char)dma_wd.fdc_acces_seccount; + return( (u_char)dma_wd.fdc_acces_seccount ); } -static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value) +static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char value ) { dma_wd.dma_mode_status = (u_short)(0x88 + reg); dma_wd.fdc_acces_seccount = (u_short)value; diff --git a/trunk/drivers/scsi/atari_scsi.h b/trunk/drivers/scsi/atari_scsi.h index efadb8d567c2..f917bdd09b41 100644 --- a/trunk/drivers/scsi/atari_scsi.h +++ b/trunk/drivers/scsi/atari_scsi.h @@ -21,7 +21,11 @@ int atari_scsi_detect (struct scsi_host_template *); const char *atari_scsi_info (struct Scsi_Host *); int atari_scsi_reset (Scsi_Cmnd *, unsigned int); +#ifdef MODULE int atari_scsi_release (struct Scsi_Host *); +#else +#define atari_scsi_release NULL +#endif /* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher * values should work, too; try it! (but cmd_per_lun costs memory!) */ @@ -59,32 +63,6 @@ int atari_scsi_release (struct Scsi_Host *); #define NCR5380_dma_xfer_len(i,cmd,phase) \ atari_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1) -/* former generic SCSI error handling stuff */ - -#define SCSI_ABORT_SNOOZE 0 -#define SCSI_ABORT_SUCCESS 1 -#define SCSI_ABORT_PENDING 2 -#define SCSI_ABORT_BUSY 3 -#define SCSI_ABORT_NOT_RUNNING 4 -#define SCSI_ABORT_ERROR 5 - -#define SCSI_RESET_SNOOZE 0 -#define SCSI_RESET_PUNT 1 -#define SCSI_RESET_SUCCESS 2 -#define SCSI_RESET_PENDING 3 -#define SCSI_RESET_WAKEUP 4 -#define SCSI_RESET_NOT_RUNNING 5 -#define SCSI_RESET_ERROR 6 - -#define SCSI_RESET_SYNCHRONOUS 0x01 -#define SCSI_RESET_ASYNCHRONOUS 0x02 -#define SCSI_RESET_SUGGEST_BUS_RESET 0x04 -#define SCSI_RESET_SUGGEST_HOST_RESET 0x08 - -#define SCSI_RESET_BUS_RESET 0x100 -#define SCSI_RESET_HOST_RESET 0x200 -#define SCSI_RESET_ACTION 0xff - /* Debugging printk definitions: * * ARB -> arbitration @@ -113,58 +91,144 @@ int atari_scsi_release (struct Scsi_Host *); * */ -#define dprint(flg, format...) \ -({ \ - if (NDEBUG & (flg)) \ - printk(KERN_DEBUG format); \ -}) - +#if NDEBUG & NDEBUG_ARBITRATION #define ARB_PRINTK(format, args...) \ - dprint(NDEBUG_ARBITRATION, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define ARB_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_AUTOSENSE #define ASEN_PRINTK(format, args...) \ - dprint(NDEBUG_AUTOSENSE, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define ASEN_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_DMA #define DMA_PRINTK(format, args...) \ - dprint(NDEBUG_DMA, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define DMA_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_HANDSHAKE #define HSH_PRINTK(format, args...) \ - dprint(NDEBUG_HANDSHAKE, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define HSH_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_INFORMATION #define INF_PRINTK(format, args...) \ - dprint(NDEBUG_INFORMATION, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define INF_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_INIT #define INI_PRINTK(format, args...) \ - dprint(NDEBUG_INIT, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define INI_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_INTR #define INT_PRINTK(format, args...) \ - dprint(NDEBUG_INTR, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define INT_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_LINKED #define LNK_PRINTK(format, args...) \ - dprint(NDEBUG_LINKED, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define LNK_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_MAIN #define MAIN_PRINTK(format, args...) \ - dprint(NDEBUG_MAIN, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define MAIN_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_NO_DATAOUT #define NDAT_PRINTK(format, args...) \ - dprint(NDEBUG_NO_DATAOUT, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define NDAT_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_NO_WRITE #define NWR_PRINTK(format, args...) \ - dprint(NDEBUG_NO_WRITE, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define NWR_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_PIO #define PIO_PRINTK(format, args...) \ - dprint(NDEBUG_PIO, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define PIO_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_PSEUDO_DMA #define PDMA_PRINTK(format, args...) \ - dprint(NDEBUG_PSEUDO_DMA, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define PDMA_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_QUEUES #define QU_PRINTK(format, args...) \ - dprint(NDEBUG_QUEUES, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define QU_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_RESELECTION #define RSL_PRINTK(format, args...) \ - dprint(NDEBUG_RESELECTION, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define RSL_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_SELECTION #define SEL_PRINTK(format, args...) \ - dprint(NDEBUG_SELECTION, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define SEL_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_USLEEP #define USL_PRINTK(format, args...) \ - dprint(NDEBUG_USLEEP, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define USL_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_LAST_BYTE_SENT #define LBS_PRINTK(format, args...) \ - dprint(NDEBUG_LAST_BYTE_SENT, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define LBS_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_RESTART_SELECT #define RSS_PRINTK(format, args...) \ - dprint(NDEBUG_RESTART_SELECT, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define RSS_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_EXTENDED #define EXT_PRINTK(format, args...) \ - dprint(NDEBUG_EXTENDED, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define EXT_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_ABORT #define ABRT_PRINTK(format, args...) \ - dprint(NDEBUG_ABORT, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define ABRT_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_TAGS #define TAG_PRINTK(format, args...) \ - dprint(NDEBUG_TAGS, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define TAG_PRINTK(format, args...) +#endif +#if NDEBUG & NDEBUG_MERGING #define MER_PRINTK(format, args...) \ - dprint(NDEBUG_MERGING, format , ## args) + printk(KERN_DEBUG format , ## args) +#else +#define MER_PRINTK(format, args...) +#endif /* conditional macros for NCR5380_print_{,phase,status} */ diff --git a/trunk/drivers/scsi/ch.c b/trunk/drivers/scsi/ch.c index 2311019304c0..2a2cc6cf1182 100644 --- a/trunk/drivers/scsi/ch.c +++ b/trunk/drivers/scsi/ch.c @@ -319,9 +319,10 @@ ch_readconfig(scsi_changer *ch) int result,id,lun,i; u_int elem; - buffer = kzalloc(512, GFP_KERNEL | GFP_DMA); + buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); if (!buffer) return -ENOMEM; + memset(buffer,0,512); memset(cmd,0,sizeof(cmd)); cmd[0] = MODE_SENSE; @@ -529,9 +530,10 @@ ch_set_voltag(scsi_changer *ch, u_int elem, u_char *buffer; int result; - buffer = kzalloc(512, GFP_KERNEL); + buffer = kmalloc(512, GFP_KERNEL); if (!buffer) return -ENOMEM; + memset(buffer,0,512); dprintk("%s %s voltag: 0x%x => \"%s\"\n", clear ? "clear" : "set", @@ -920,10 +922,11 @@ static int ch_probe(struct device *dev) if (sd->type != TYPE_MEDIUM_CHANGER) return -ENODEV; - ch = kzalloc(sizeof(*ch), GFP_KERNEL); + ch = kmalloc(sizeof(*ch), GFP_KERNEL); if (NULL == ch) return -ENOMEM; + memset(ch,0,sizeof(*ch)); ch->minor = ch_devcount; sprintf(ch->name,"ch%d",ch->minor); mutex_init(&ch->lock); diff --git a/trunk/drivers/scsi/constants.c b/trunk/drivers/scsi/constants.c index 2a458d66b6ff..61f6024b61ba 100644 --- a/trunk/drivers/scsi/constants.c +++ b/trunk/drivers/scsi/constants.c @@ -202,29 +202,31 @@ static const char * get_sa_name(const struct value_name_pair * arr, } /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ -static void print_opcode_name(unsigned char * cdbp, int cdb_len) +static void print_opcode_name(unsigned char * cdbp, int cdb_len, + int start_of_line) { int sa, len, cdb0; const char * name; + const char * leadin = start_of_line ? KERN_INFO : ""; cdb0 = cdbp[0]; switch(cdb0) { case VARIABLE_LENGTH_CMD: len = cdbp[7] + 8; if (len < 10) { - printk("short variable length command, " - "len=%d ext_len=%d", len, cdb_len); + printk("%sshort variable length command, " + "len=%d ext_len=%d", leadin, len, cdb_len); break; } sa = (cdbp[8] << 8) + cdbp[9]; name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); if (name) { - printk("%s", name); + printk("%s%s", leadin, name); if ((cdb_len > 0) && (len != cdb_len)) printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); } else { - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); if ((cdb_len > 0) && (len != cdb_len)) printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); @@ -234,80 +236,83 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) sa = cdbp[1] & 0x1f; name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case MAINTENANCE_OUT: sa = cdbp[1] & 0x1f; name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case SERVICE_ACTION_IN_12: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case SERVICE_ACTION_OUT_12: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case SERVICE_ACTION_IN_16: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; case SERVICE_ACTION_OUT_16: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa); if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; default: if (cdb0 < 0xc0) { name = cdb_byte0_names[cdb0]; if (name) - printk("%s", name); + printk("%s%s", leadin, name); else - printk("cdb[0]=0x%x (reserved)", cdb0); + printk("%scdb[0]=0x%x (reserved)", + leadin, cdb0); } else - printk("cdb[0]=0x%x (vendor)", cdb0); + printk("%scdb[0]=0x%x (vendor)", leadin, cdb0); break; } } #else /* ifndef CONFIG_SCSI_CONSTANTS */ -static void print_opcode_name(unsigned char * cdbp, int cdb_len) +static void print_opcode_name(unsigned char * cdbp, int cdb_len, + int start_of_line) { int sa, len, cdb0; + const char * leadin = start_of_line ? KERN_INFO : ""; cdb0 = cdbp[0]; switch(cdb0) { case VARIABLE_LENGTH_CMD: len = cdbp[7] + 8; if (len < 10) { - printk("short opcode=0x%x command, len=%d " - "ext_len=%d", cdb0, len, cdb_len); + printk("%sshort opcode=0x%x command, len=%d " + "ext_len=%d", leadin, cdb0, len, cdb_len); break; } sa = (cdbp[8] << 8) + cdbp[9]; - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); if (len != cdb_len) printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); break; @@ -318,48 +323,49 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) case SERVICE_ACTION_IN_16: case SERVICE_ACTION_OUT_16: sa = cdbp[1] & 0x1f; - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); break; default: if (cdb0 < 0xc0) - printk("cdb[0]=0x%x", cdb0); + printk("%scdb[0]=0x%x", leadin, cdb0); else - printk("cdb[0]=0x%x (vendor)", cdb0); + printk("%scdb[0]=0x%x (vendor)", leadin, cdb0); break; } } #endif -void __scsi_print_command(unsigned char *cdb) +void __scsi_print_command(unsigned char *command) { int k, len; - print_opcode_name(cdb, 0); - if (VARIABLE_LENGTH_CMD == cdb[0]) - len = cdb[7] + 8; + print_opcode_name(command, 0, 1); + if (VARIABLE_LENGTH_CMD == command[0]) + len = command[7] + 8; else - len = COMMAND_SIZE(cdb[0]); + len = COMMAND_SIZE(command[0]); /* print out all bytes in cdb */ for (k = 0; k < len; ++k) - printk(" %02x", cdb[k]); + printk(" %02x", command[k]); printk("\n"); } EXPORT_SYMBOL(__scsi_print_command); -void scsi_print_command(struct scsi_cmnd *cmd) +/* This function (perhaps with the addition of peripheral device type) + * is more approriate than __scsi_print_command(). Perhaps that static + * can be dropped later if it replaces the __scsi_print_command version. + */ +static void scsi_print_cdb(unsigned char *cdb, int cdb_len, int start_of_line) { int k; - scmd_printk(KERN_INFO, cmd, "CDB: "); - print_opcode_name(cmd->cmnd, cmd->cmd_len); - + print_opcode_name(cdb, cdb_len, start_of_line); /* print out all bytes in cdb */ printk(":"); - for (k = 0; k < cmd->cmd_len; ++k) - printk(" %02x", cmd->cmnd[k]); + for (k = 0; k < cdb_len; ++k) + printk(" %02x", cdb[k]); printk("\n"); } -EXPORT_SYMBOL(scsi_print_command); /** * @@ -404,11 +410,7 @@ struct error_info { const char * text; }; -/* - * The canonical list of T10 Additional Sense Codes is available at: - * http://www.t10.org/lists/asc-num.txt - */ -static const struct error_info additional[] = +static struct error_info additional[] = { {0x0000, "No additional sense information"}, {0x0001, "Filemark detected"}, @@ -712,7 +714,6 @@ static const struct error_info additional[] = {0x2F00, "Commands cleared by another initiator"}, {0x2F01, "Commands cleared by power loss notification"}, - {0x2F02, "Commands cleared by device server"}, {0x3000, "Incompatible medium installed"}, {0x3001, "Cannot read medium - unknown format"}, @@ -1175,77 +1176,67 @@ scsi_extd_sense_format(unsigned char asc, unsigned char ascq) { } EXPORT_SYMBOL(scsi_extd_sense_format); -void +/* Print extended sense information; no leadin, no linefeed */ +static void scsi_show_extd_sense(unsigned char asc, unsigned char ascq) { - const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq); + const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq); if (extd_sense_fmt) { if (strstr(extd_sense_fmt, "%x")) { - printk("Add. Sense: "); + printk("Additional sense: "); printk(extd_sense_fmt, ascq); } else - printk("Add. Sense: %s", extd_sense_fmt); + printk("Additional sense: %s", extd_sense_fmt); } else { if (asc >= 0x80) - printk("<> ASC=0x%x ASCQ=0x%x", asc, - ascq); + printk("<> ASC=0x%x ASCQ=0x%x", asc, ascq); if (ascq >= 0x80) - printk("ASC=0x%x <> ASCQ=0x%x", asc, - ascq); + printk("ASC=0x%x <> ASCQ=0x%x", asc, ascq); else printk("ASC=0x%x ASCQ=0x%x", asc, ascq); } - - printk("\n"); } -EXPORT_SYMBOL(scsi_show_extd_sense); void -scsi_show_sense_hdr(struct scsi_sense_hdr *sshdr) +scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) { const char *sense_txt; + /* An example of deferred is when an earlier write to disk cache + * succeeded, but now the disk discovers that it cannot write the + * data to the magnetic media. + */ + const char *error = scsi_sense_is_deferred(sshdr) ? + "<>" : "Current"; + printk(KERN_INFO "%s: %s", name, error); + if (sshdr->response_code >= 0x72) + printk(" [descriptor]"); sense_txt = scsi_sense_key_string(sshdr->sense_key); if (sense_txt) - printk("Sense Key : %s ", sense_txt); + printk(": sense key: %s\n", sense_txt); else - printk("Sense Key : 0x%x ", sshdr->sense_key); - - printk("%s", scsi_sense_is_deferred(sshdr) ? "[deferred] " : - "[current] "); - - if (sshdr->response_code >= 0x72) - printk("[descriptor]"); - - printk("\n"); -} -EXPORT_SYMBOL(scsi_show_sense_hdr); - -/* - * Print normalized SCSI sense header with a prefix. - */ -void -scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) -{ - printk(KERN_INFO "%s: ", name); - scsi_show_sense_hdr(sshdr); - printk(KERN_INFO "%s: ", name); + printk(": sense key=0x%x\n", sshdr->sense_key); + printk(KERN_INFO " "); scsi_show_extd_sense(sshdr->asc, sshdr->ascq); + printk("\n"); } EXPORT_SYMBOL(scsi_print_sense_hdr); +/* Print sense information */ void -scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, - struct scsi_sense_hdr *sshdr) +__scsi_print_sense(const char *name, const unsigned char *sense_buffer, + int sense_len) { int k, num, res; + unsigned int info; + struct scsi_sense_hdr ssh; - res = scsi_normalize_sense(sense_buffer, sense_len, sshdr); + res = scsi_normalize_sense(sense_buffer, sense_len, &ssh); if (0 == res) { /* this may be SCSI-1 sense data */ num = (sense_len < 32) ? sense_len : 32; - printk("Unrecognized sense data (in hex):"); + printk(KERN_INFO "Unrecognized sense data (in hex):"); for (k = 0; k < num; ++k) { if (0 == (k % 16)) { printk("\n"); @@ -1256,20 +1247,11 @@ scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, printk("\n"); return; } -} - -void -scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, - struct scsi_sense_hdr *sshdr) -{ - int k, num, res; - - if (sshdr->response_code < 0x72) - { + scsi_print_sense_hdr(name, &ssh); + if (ssh.response_code < 0x72) { /* only decode extras for "fixed" format now */ char buff[80]; int blen, fixed_valid; - unsigned int info; fixed_valid = sense_buffer[0] & 0x80; info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) | @@ -1299,13 +1281,13 @@ scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, res += snprintf(buff + res, blen - res, "ILI"); } if (res > 0) - printk("%s\n", buff); - } else if (sshdr->additional_length > 0) { + printk(KERN_INFO "%s\n", buff); + } else if (ssh.additional_length > 0) { /* descriptor format with sense descriptors */ - num = 8 + sshdr->additional_length; + num = 8 + ssh.additional_length; num = (sense_len < num) ? sense_len : num; - printk("Descriptor sense data with sense descriptors " - "(in hex):"); + printk(KERN_INFO "Descriptor sense data with sense " + "descriptors (in hex):"); for (k = 0; k < num; ++k) { if (0 == (k % 16)) { printk("\n"); @@ -1313,42 +1295,29 @@ scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, } printk("%02x ", sense_buffer[k]); } - printk("\n"); } - } +EXPORT_SYMBOL(__scsi_print_sense); -/* Normalize and print sense buffer with name prefix */ -void __scsi_print_sense(const char *name, const unsigned char *sense_buffer, - int sense_len) +void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd) { - struct scsi_sense_hdr sshdr; - - printk(KERN_INFO "%s: ", name); - scsi_decode_sense_buffer(sense_buffer, sense_len, &sshdr); - scsi_show_sense_hdr(&sshdr); - scsi_decode_sense_extras(sense_buffer, sense_len, &sshdr); - printk(KERN_INFO "%s: ", name); - scsi_show_extd_sense(sshdr.asc, sshdr.ascq); + const char *name = devclass; + + if (cmd->request->rq_disk) + name = cmd->request->rq_disk->disk_name; + __scsi_print_sense(name, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); } -EXPORT_SYMBOL(__scsi_print_sense); +EXPORT_SYMBOL(scsi_print_sense); -/* Normalize and print sense buffer in SCSI command */ -void scsi_print_sense(char *name, struct scsi_cmnd *cmd) +void scsi_print_command(struct scsi_cmnd *cmd) { - struct scsi_sense_hdr sshdr; - - scmd_printk(KERN_INFO, cmd, ""); - scsi_decode_sense_buffer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, - &sshdr); - scsi_show_sense_hdr(&sshdr); - scsi_decode_sense_extras(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, - &sshdr); - scmd_printk(KERN_INFO, cmd, ""); - scsi_show_extd_sense(sshdr.asc, sshdr.ascq); + /* Assume appended output (i.e. not at start of line) */ + sdev_printk("", cmd->device, "\n"); + printk(KERN_INFO " command: "); + scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0); } -EXPORT_SYMBOL(scsi_print_sense); +EXPORT_SYMBOL(scsi_print_command); #ifdef CONFIG_SCSI_CONSTANTS @@ -1358,6 +1327,25 @@ static const char * const hostbyte_table[]={ "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"}; #define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) +void scsi_print_hostbyte(int scsiresult) +{ + int hb = host_byte(scsiresult); + + printk("Hostbyte=0x%02x", hb); + if (hb < NUM_HOSTBYTE_STRS) + printk("(%s) ", hostbyte_table[hb]); + else + printk("is invalid "); +} +#else +void scsi_print_hostbyte(int scsiresult) +{ + printk("Hostbyte=0x%02x ", host_byte(scsiresult)); +} +#endif + +#ifdef CONFIG_SCSI_CONSTANTS + static const char * const driverbyte_table[]={ "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; @@ -1368,35 +1356,19 @@ static const char * const driversuggest_table[]={"SUGGEST_OK", "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"}; #define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table) -void scsi_show_result(int result) +void scsi_print_driverbyte(int scsiresult) { - int hb = host_byte(result); - int db = (driver_byte(result) & DRIVER_MASK); - int su = ((driver_byte(result) & SUGGEST_MASK) >> 4); + int dr = (driver_byte(scsiresult) & DRIVER_MASK); + int su = ((driver_byte(scsiresult) & SUGGEST_MASK) >> 4); - printk("Result: hostbyte=%s driverbyte=%s,%s\n", - (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb] : "invalid"), - (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"), + printk("Driverbyte=0x%02x ", driver_byte(scsiresult)); + printk("(%s,%s) ", + (dr < NUM_DRIVERBYTE_STRS ? driverbyte_table[dr] : "invalid"), (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid")); } - #else - -void scsi_show_result(int result) +void scsi_print_driverbyte(int scsiresult) { - printk("Result: hostbyte=0x%02x driverbyte=0x%02x\n", - host_byte(result), driver_byte(result)); + printk("Driverbyte=0x%02x ", driver_byte(scsiresult)); } - #endif -EXPORT_SYMBOL(scsi_show_result); - - -void scsi_print_result(struct scsi_cmnd *cmd) -{ - scmd_printk(KERN_INFO, cmd, ""); - scsi_show_result(cmd->result); -} -EXPORT_SYMBOL(scsi_print_result); - - diff --git a/trunk/drivers/scsi/dpt/dpti_i2o.h b/trunk/drivers/scsi/dpt/dpti_i2o.h index 100b49baca7f..5a49216fe4cf 100644 --- a/trunk/drivers/scsi/dpt/dpti_i2o.h +++ b/trunk/drivers/scsi/dpt/dpti_i2o.h @@ -31,7 +31,7 @@ * Tunable parameters first */ -/* How many different OSM's are we allowing */ +/* How many different OSM's are we allowing */ #define MAX_I2O_MODULES 64 #define I2O_EVT_CAPABILITY_OTHER 0x01 @@ -63,7 +63,7 @@ struct i2o_message u16 size; u32 target_tid:12; u32 init_tid:12; - u32 function:8; + u32 function:8; u32 initiator_context; /* List follows */ }; @@ -77,7 +77,7 @@ struct i2o_device char dev_name[8]; /* linux /dev name if available */ i2o_lct_entry lct_data;/* Device LCT information */ - u32 flags; + u32 flags; struct proc_dir_entry* proc_entry; /* /proc dir */ struct adpt_device *owner; struct _adpt_hba *controller; /* Controlling IOP */ @@ -86,7 +86,7 @@ struct i2o_device /* * Each I2O controller has one of these objects */ - + struct i2o_controller { char name[16]; @@ -111,9 +111,9 @@ struct i2o_sys_tbl_entry u32 iop_id:12; u32 reserved2:20; u16 seg_num:12; - u16 i2o_version:4; - u8 iop_state; - u8 msg_type; + u16 i2o_version:4; + u8 iop_state; + u8 msg_type; u16 frame_size; u16 reserved3; u32 last_changed; @@ -124,14 +124,14 @@ struct i2o_sys_tbl_entry struct i2o_sys_tbl { - u8 num_entries; - u8 version; - u16 reserved1; + u8 num_entries; + u8 version; + u16 reserved1; u32 change_ind; u32 reserved2; u32 reserved3; struct i2o_sys_tbl_entry iops[0]; -}; +}; /* * I2O classes / subclasses @@ -146,7 +146,7 @@ struct i2o_sys_tbl /* Class code names * (from v1.5 Table 6-1 Class Code Assignments.) */ - + #define I2O_CLASS_EXECUTIVE 0x000 #define I2O_CLASS_DDM 0x001 #define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010 @@ -166,7 +166,7 @@ struct i2o_sys_tbl /* Rest of 0x092 - 0x09f reserved for peer-to-peer classes */ - + #define I2O_CLASS_MATCH_ANYCLASS 0xffffffff /* Subclasses @@ -175,7 +175,7 @@ struct i2o_sys_tbl #define I2O_SUBCLASS_i960 0x001 #define I2O_SUBCLASS_HDM 0x020 #define I2O_SUBCLASS_ISM 0x021 - + /* Operation functions */ #define I2O_PARAMS_FIELD_GET 0x0001 @@ -219,7 +219,7 @@ struct i2o_sys_tbl /* * Messaging API values */ - + #define I2O_CMD_ADAPTER_ASSIGN 0xB3 #define I2O_CMD_ADAPTER_READ 0xB2 #define I2O_CMD_ADAPTER_RELEASE 0xB5 @@ -284,16 +284,16 @@ struct i2o_sys_tbl #define I2O_PRIVATE_MSG 0xFF /* - * Init Outbound Q status + * Init Outbound Q status */ - + #define I2O_CMD_OUTBOUND_INIT_IN_PROGRESS 0x01 #define I2O_CMD_OUTBOUND_INIT_REJECTED 0x02 #define I2O_CMD_OUTBOUND_INIT_FAILED 0x03 #define I2O_CMD_OUTBOUND_INIT_COMPLETE 0x04 /* - * I2O Get Status State values + * I2O Get Status State values */ #define ADAPTER_STATE_INITIALIZING 0x01 @@ -303,7 +303,7 @@ struct i2o_sys_tbl #define ADAPTER_STATE_OPERATIONAL 0x08 #define ADAPTER_STATE_FAILED 0x10 #define ADAPTER_STATE_FAULTED 0x11 - + /* I2O API function return values */ #define I2O_RTN_NO_ERROR 0 @@ -321,9 +321,9 @@ struct i2o_sys_tbl /* Reply message status defines for all messages */ -#define I2O_REPLY_STATUS_SUCCESS 0x00 -#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01 -#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02 +#define I2O_REPLY_STATUS_SUCCESS 0x00 +#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01 +#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02 #define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03 #define I2O_REPLY_STATUS_ERROR_DIRTY 0x04 #define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05 @@ -338,7 +338,7 @@ struct i2o_sys_tbl #define I2O_PARAMS_STATUS_SUCCESS 0x00 #define I2O_PARAMS_STATUS_BAD_KEY_ABORT 0x01 -#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE 0x02 +#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE 0x02 #define I2O_PARAMS_STATUS_BUFFER_FULL 0x03 #define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL 0x04 #define I2O_PARAMS_STATUS_FIELD_UNREADABLE 0x05 @@ -390,7 +390,7 @@ struct i2o_sys_tbl #define I2O_CLAIM_MANAGEMENT 0x02000000 #define I2O_CLAIM_AUTHORIZED 0x03000000 #define I2O_CLAIM_SECONDARY 0x04000000 - + /* Message header defines for VersionOffset */ #define I2OVER15 0x0001 #define I2OVER20 0x0002 diff --git a/trunk/drivers/scsi/dpt/dpti_ioctl.h b/trunk/drivers/scsi/dpt/dpti_ioctl.h index cc784e8f6e9d..82d24864be0c 100644 --- a/trunk/drivers/scsi/dpt/dpti_ioctl.h +++ b/trunk/drivers/scsi/dpt/dpti_ioctl.h @@ -99,7 +99,7 @@ typedef struct { uCHAR eataVersion; /* EATA Version */ uLONG cpLength; /* EATA Command Packet Length */ uLONG spLength; /* EATA Status Packet Length */ - uCHAR drqNum; /* DRQ Index (0,5,6,7) */ + uCHAR drqNum; /* DRQ Index (0,5,6,7) */ uCHAR flag1; /* EATA Flags 1 (Byte 9) */ uCHAR flag2; /* EATA Flags 2 (Byte 30) */ } CtrlInfo; diff --git a/trunk/drivers/scsi/dpt/dptsig.h b/trunk/drivers/scsi/dpt/dptsig.h index 94bc894d1200..4bf447792129 100644 --- a/trunk/drivers/scsi/dpt/dptsig.h +++ b/trunk/drivers/scsi/dpt/dptsig.h @@ -145,8 +145,8 @@ typedef unsigned long sigLONG; #define FT_LOGGER 12 /* Event Logger */ #define FT_INSTALL 13 /* An Install Program */ #define FT_LIBRARY 14 /* Storage Manager Real-Mode Calls */ -#define FT_RESOURCE 15 /* Storage Manager Resource File */ -#define FT_MODEM_DB 16 /* Storage Manager Modem Database */ +#define FT_RESOURCE 15 /* Storage Manager Resource File */ +#define FT_MODEM_DB 16 /* Storage Manager Modem Database */ /* Filetype flags - sigBYTE dsFiletypeFlags; FLAG BITS */ /* ------------------------------------------------------------------ */ diff --git a/trunk/drivers/scsi/dpt_i2o.c b/trunk/drivers/scsi/dpt_i2o.c index 8c7d2bbf9b1a..cd36e81b2d93 100644 --- a/trunk/drivers/scsi/dpt_i2o.c +++ b/trunk/drivers/scsi/dpt_i2o.c @@ -55,6 +55,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver"); #include #include #include +#include #include #include @@ -194,6 +195,8 @@ static int adpt_detect(struct scsi_host_template* sht) pci_dev_get(pDev); } } + if (pDev) + pci_dev_put(pDev); /* In INIT state, Activate IOPs */ for (pHba = hba_chain; pHba; pHba = pHba->next) { @@ -1308,12 +1311,13 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) schedule_timeout_uninterruptible(1); } while (m == EMPTY_QUEUE); - status = kzalloc(4, GFP_KERNEL|ADDR32); + status = kmalloc(4, GFP_KERNEL|ADDR32); if(status == NULL) { adpt_send_nop(pHba, m); printk(KERN_ERR"IOP reset failed - no free memory.\n"); return -ENOMEM; } + memset(status,0,4); msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0; msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID; @@ -1503,19 +1507,21 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba) continue; } if( pHba->channel[bus_no].device[scsi_id] == NULL){ - pDev = kzalloc(sizeof(struct adpt_device),GFP_KERNEL); + pDev = kmalloc(sizeof(struct adpt_device),GFP_KERNEL); if(pDev == NULL) { return -ENOMEM; } pHba->channel[bus_no].device[scsi_id] = pDev; + memset(pDev,0,sizeof(struct adpt_device)); } else { for( pDev = pHba->channel[bus_no].device[scsi_id]; pDev->next_lun; pDev = pDev->next_lun){ } - pDev->next_lun = kzalloc(sizeof(struct adpt_device),GFP_KERNEL); + pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL); if(pDev->next_lun == NULL) { return -ENOMEM; } + memset(pDev->next_lun,0,sizeof(struct adpt_device)); pDev = pDev->next_lun; } pDev->tid = tid; @@ -1664,11 +1670,12 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg) reply_size = REPLY_FRAME_SIZE; } reply_size *= 4; - reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL); + reply = kmalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL); if(reply == NULL) { printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name); return -ENOMEM; } + memset(reply,0,REPLY_FRAME_SIZE*4); sg_offset = (msg[0]>>4)&0xf; msg[2] = 0x40000000; // IOCTL context msg[3] = (u32)reply; @@ -2440,7 +2447,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba) } pDev = pHba->channel[bus_no].device[scsi_id]; if( pDev == NULL){ - pDev = kzalloc(sizeof(struct adpt_device),GFP_KERNEL); + pDev = kmalloc(sizeof(struct adpt_device),GFP_KERNEL); if(pDev == NULL) { return -ENOMEM; } @@ -2449,11 +2456,12 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba) while (pDev->next_lun) { pDev = pDev->next_lun; } - pDev = pDev->next_lun = kzalloc(sizeof(struct adpt_device),GFP_KERNEL); + pDev = pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL); if(pDev == NULL) { return -ENOMEM; } } + memset(pDev,0,sizeof(struct adpt_device)); pDev->tid = d->lct_data.tid; pDev->scsi_channel = bus_no; pDev->scsi_id = scsi_id; diff --git a/trunk/drivers/scsi/eata_generic.h b/trunk/drivers/scsi/eata_generic.h index 5016af5cf860..635c14861f86 100644 --- a/trunk/drivers/scsi/eata_generic.h +++ b/trunk/drivers/scsi/eata_generic.h @@ -18,6 +18,13 @@ * Misc. definitions * *********************************************/ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + #define R_LIMIT 0x20000 #define MAXISA 4 diff --git a/trunk/drivers/scsi/esp_scsi.c b/trunk/drivers/scsi/esp_scsi.c index ec71061aef61..99ce03331b64 100644 --- a/trunk/drivers/scsi/esp_scsi.c +++ b/trunk/drivers/scsi/esp_scsi.c @@ -2212,7 +2212,7 @@ static void __devinit esp_init_swstate(struct esp *esp) } /* This places the ESP into a known state at boot time. */ -static void esp_bootup_reset(struct esp *esp) +static void __devinit esp_bootup_reset(struct esp *esp) { u8 val; diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index b10eefe735c5..fbc1d5c3b0a7 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -85,7 +85,7 @@ static int max_id = 64; static int max_channel = 3; static int init_timeout = 5; -static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; +static int max_requests = 50; #define IBMVSCSI_VERSION "1.5.8" @@ -538,8 +538,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, int request_status; int rc; - /* If we have exhausted our request limit, just fail this request, - * unless it is for a reset or abort. + /* If we have exhausted our request limit, just fail this request. * Note that there are rare cases involving driver generated requests * (such as task management requests) that the mid layer may think we * can handle more requests (can_queue) when we actually can't @@ -552,30 +551,9 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, */ if (request_status < -1) goto send_error; - /* Otherwise, we may have run out of requests. */ - /* Abort and reset calls should make it through. - * Nothing except abort and reset should use the last two - * slots unless we had two or less to begin with. - */ - else if (request_status < 2 && - evt_struct->iu.srp.cmd.opcode != SRP_TSK_MGMT) { - /* In the case that we have less than two requests - * available, check the server limit as a combination - * of the request limit and the number of requests - * in-flight (the size of the send list). If the - * server limit is greater than 2, return busy so - * that the last two are reserved for reset and abort. - */ - int server_limit = request_status; - struct srp_event_struct *tmp_evt; - - list_for_each_entry(tmp_evt, &hostdata->sent, list) { - server_limit++; - } - - if (server_limit > 2) - goto send_busy; - } + /* Otherwise, if we have run out of requests */ + else if (request_status < 0) + goto send_busy; } /* Copy the IU into the transfer area */ @@ -594,7 +572,6 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, printk(KERN_ERR "ibmvscsi: send error %d\n", rc); - atomic_inc(&hostdata->request_limit); goto send_error; } @@ -604,8 +581,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); free_event_struct(&hostdata->pool, evt_struct); - atomic_inc(&hostdata->request_limit); - return SCSI_MLQUEUE_HOST_BUSY; + return SCSI_MLQUEUE_HOST_BUSY; send_error: unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); @@ -855,16 +831,23 @@ static void login_rsp(struct srp_event_struct *evt_struct) printk(KERN_INFO "ibmvscsi: SRP_LOGIN succeeded\n"); - if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta < 0) - printk(KERN_ERR "ibmvscsi: Invalid request_limit.\n"); + if (evt_struct->xfer_iu->srp.login_rsp.req_lim_delta > + (max_requests - 2)) + evt_struct->xfer_iu->srp.login_rsp.req_lim_delta = + max_requests - 2; - /* Now we know what the real request-limit is. - * This value is set rather than added to request_limit because - * request_limit could have been set to -1 by this client. - */ + /* Now we know what the real request-limit is */ atomic_set(&hostdata->request_limit, evt_struct->xfer_iu->srp.login_rsp.req_lim_delta); + hostdata->host->can_queue = + evt_struct->xfer_iu->srp.login_rsp.req_lim_delta - 2; + + if (hostdata->host->can_queue < 1) { + printk(KERN_ERR "ibmvscsi: Invalid request_limit_delta\n"); + return; + } + /* If we had any pending I/Os, kick them */ scsi_unblock_requests(hostdata->host); @@ -1354,27 +1337,6 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, return rc; } -/** - * ibmvscsi_slave_configure: Set the "allow_restart" flag for each disk. - * @sdev: struct scsi_device device to configure - * - * Enable allow_restart for a device if it is a disk. Adjust the - * queue_depth here also as is required by the documentation for - * struct scsi_host_template. - */ -static int ibmvscsi_slave_configure(struct scsi_device *sdev) -{ - struct Scsi_Host *shost = sdev->host; - unsigned long lock_flags = 0; - - spin_lock_irqsave(shost->host_lock, lock_flags); - if (sdev->type == TYPE_DISK) - sdev->allow_restart = 1; - scsi_adjust_queue_depth(sdev, 0, shost->cmd_per_lun); - spin_unlock_irqrestore(shost->host_lock, lock_flags); - return 0; -} - /* ------------------------------------------------------------ * sysfs attributes */ @@ -1520,9 +1482,8 @@ static struct scsi_host_template driver_template = { .queuecommand = ibmvscsi_queuecommand, .eh_abort_handler = ibmvscsi_eh_abort_handler, .eh_device_reset_handler = ibmvscsi_eh_device_reset_handler, - .slave_configure = ibmvscsi_slave_configure, .cmd_per_lun = 16, - .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, + .can_queue = 1, /* Updated after SRP_LOGIN */ .this_id = -1, .sg_tablesize = SG_ALL, .use_clustering = ENABLE_CLUSTERING, @@ -1542,7 +1503,6 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) vdev->dev.driver_data = NULL; - driver_template.can_queue = max_requests; host = scsi_host_alloc(&driver_template, sizeof(*hostdata)); if (!host) { printk(KERN_ERR "ibmvscsi: couldn't allocate host data\n"); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.h b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.h index 77cc1d40f5bb..5c6d93582929 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -44,8 +44,6 @@ struct Scsi_Host; */ #define MAX_INDIRECT_BUFS 10 -#define IBMVSCSI_MAX_REQUESTS_DEFAULT 100 - /* ------------------------------------------------------------ * Data Structures */ diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c b/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c index 8ba7dd09d01d..a39a478bb39a 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -35,7 +35,7 @@ #include "ibmvscsi.h" #define INITIAL_SRP_LIMIT 16 -#define DEFAULT_MAX_SECTORS 256 +#define DEFAULT_MAX_SECTORS 512 #define TGT_NAME "ibmvstgt" @@ -248,8 +248,8 @@ static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg, md[i].va + mdone); if (err != H_SUCCESS) { - eprintk("rdma error %d %d %ld\n", dir, slen, err); - return -EIO; + eprintk("rdma error %d %d\n", dir, slen); + goto out; } mlen -= slen; @@ -265,35 +265,45 @@ static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg, if (sidx > nsg) { eprintk("out of sg %p %d %d\n", iue, sidx, nsg); - return -EIO; + goto out; } } }; rest -= mlen; } +out: + return 0; } +static int ibmvstgt_transfer_data(struct scsi_cmnd *sc, + void (*done)(struct scsi_cmnd *)) +{ + struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; + int err; + + err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); + + done(sc); + + return err; +} + static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) { unsigned long flags; struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; struct srp_target *target = iue->target; - int err = 0; - - dprintk("%p %p %x %u\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0], - cmd->usg_sg); - if (sc->use_sg) - err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); + dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); spin_lock_irqsave(&target->lock, flags); list_del(&iue->ilist); spin_unlock_irqrestore(&target->lock, flags); - if (err|| sc->result != SAM_STAT_GOOD) { + if (sc->result != SAM_STAT_GOOD) { eprintk("operation failed %p %d %x\n", iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]); send_rsp(iue, sc, HARDWARE_ERROR, 0x00); @@ -493,8 +503,7 @@ static void process_iu(struct viosrp_crq *crq, struct srp_target *target) { struct vio_port *vport = target_to_port(target); struct iu_entry *iue; - long err; - int done = 1; + long err, done; iue = srp_iu_get(target); if (!iue) { @@ -509,6 +518,7 @@ static void process_iu(struct viosrp_crq *crq, struct srp_target *target) if (err != H_SUCCESS) { eprintk("%ld transferring data error %p\n", err, iue); + done = 1; goto out; } @@ -784,6 +794,7 @@ static struct scsi_host_template ibmvstgt_sht = { .use_clustering = DISABLE_CLUSTERING, .max_sectors = DEFAULT_MAX_SECTORS, .transfer_response = ibmvstgt_cmd_done, + .transfer_data = ibmvstgt_transfer_data, .eh_abort_handler = ibmvstgt_eh_abort_handler, .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, .shost_attrs = ibmvstgt_attrs, @@ -892,16 +903,16 @@ static int get_system_info(void) if (!rootdn) return -ENOENT; - model = of_get_property(rootdn, "model", NULL); - id = of_get_property(rootdn, "system-id", NULL); + model = get_property(rootdn, "model", NULL); + id = get_property(rootdn, "system-id", NULL); if (model && id) snprintf(system_id, sizeof(system_id), "%s-%s", model, id); - name = of_get_property(rootdn, "ibm,partition-name", NULL); + name = get_property(rootdn, "ibm,partition-name", NULL); if (name) strncpy(partition_name, name, sizeof(partition_name)); - num = of_get_property(rootdn, "ibm,partition-no", NULL); + num = get_property(rootdn, "ibm,partition-no", NULL); if (num) partition_number = *num; diff --git a/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c b/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c index d8700aaa6114..0a533f398f52 100644 --- a/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -162,11 +162,11 @@ static void gather_partition_info(void) return; } - ppartition_name = of_get_property(rootdn, "ibm,partition-name", NULL); + ppartition_name = get_property(rootdn, "ibm,partition-name", NULL); if (ppartition_name) strncpy(partition_name, ppartition_name, sizeof(partition_name)); - p_number_ptr = of_get_property(rootdn, "ibm,partition-no", NULL); + p_number_ptr = get_property(rootdn, "ibm,partition-no", NULL); if (p_number_ptr) partition_number = *p_number_ptr; of_node_put(rootdn); diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 4baa79e68679..e9bd29975db4 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -89,10 +89,10 @@ static unsigned int ipr_log_level = IPR_DEFAULT_LOG_LEVEL; static unsigned int ipr_max_speed = 1; static int ipr_testmode = 0; static unsigned int ipr_fastfail = 0; -static unsigned int ipr_transop_timeout = 0; +static unsigned int ipr_transop_timeout = IPR_OPERATIONAL_TIMEOUT; static unsigned int ipr_enable_cache = 1; static unsigned int ipr_debug = 0; -static unsigned int ipr_dual_ioa_raid = 1; +static int ipr_auto_create = 1; static DEFINE_SPINLOCK(ipr_driver_lock); /* This table describes the differences between DMA controller chips */ @@ -159,15 +159,15 @@ module_param_named(enable_cache, ipr_enable_cache, int, 0); MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); module_param_named(debug, ipr_debug, int, 0); MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); -module_param_named(dual_ioa_raid, ipr_dual_ioa_raid, int, 0); -MODULE_PARM_DESC(dual_ioa_raid, "Enable dual adapter RAID support. Set to 1 to enable. (default: 1)"); +module_param_named(auto_create, ipr_auto_create, int, 0); +MODULE_PARM_DESC(auto_create, "Auto-create single device RAID 0 arrays when initialized (default: 1)"); MODULE_LICENSE("GPL"); MODULE_VERSION(IPR_DRIVER_VERSION); /* A constant array of IOASCs/URCs/Error Messages */ static const struct ipr_error_table_t ipr_error_table[] = { - {0x00000000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x00000000, 1, 1, "8155: An unknown error was received"}, {0x00330000, 0, 0, "Soft underlength error"}, @@ -175,127 +175,125 @@ struct ipr_error_table_t ipr_error_table[] = { "Command to be cancelled not found"}, {0x00808000, 0, 0, "Qualified success"}, - {0x01080000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x01080000, 1, 1, "FFFE: Soft device bus error recovered by the IOA"}, - {0x01088100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01088100, 0, 1, "4101: Soft device bus fabric error"}, - {0x01170600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01170600, 0, 1, "FFF9: Device sector reassign successful"}, - {0x01170900, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01170900, 0, 1, "FFF7: Media error recovered by device rewrite procedures"}, - {0x01180200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01180200, 0, 1, "7001: IOA sector reassignment successful"}, - {0x01180500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01180500, 0, 1, "FFF9: Soft media error. Sector reassignment recommended"}, - {0x01180600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01180600, 0, 1, "FFF7: Media error recovered by IOA rewrite procedures"}, - {0x01418000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01418000, 0, 1, "FF3D: Soft PCI bus error recovered by the IOA"}, - {0x01440000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x01440000, 1, 1, "FFF6: Device hardware error recovered by the IOA"}, - {0x01448100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01448100, 0, 1, "FFF6: Device hardware error recovered by the device"}, - {0x01448200, 1, IPR_DEFAULT_LOG_LEVEL, + {0x01448200, 1, 1, "FF3D: Soft IOA error recovered by the IOA"}, - {0x01448300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x01448300, 0, 1, "FFFA: Undefined device response recovered by the IOA"}, - {0x014A0000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x014A0000, 1, 1, "FFF6: Device bus error, message or command phase"}, - {0x014A8000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x014A8000, 0, 1, "FFFE: Task Management Function failed"}, - {0x015D0000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x015D0000, 0, 1, "FFF6: Failure prediction threshold exceeded"}, - {0x015D9200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x015D9200, 0, 1, "8009: Impending cache battery pack failure"}, {0x02040400, 0, 0, "34FF: Disk device format in progress"}, - {0x02048000, 0, IPR_DEFAULT_LOG_LEVEL, - "9070: IOA requested reset"}, {0x023F0000, 0, 0, "Synchronization required"}, {0x024E0000, 0, 0, "No ready, IOA shutdown"}, {0x025A0000, 0, 0, "Not ready, IOA has been shutdown"}, - {0x02670100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x02670100, 0, 1, "3020: Storage subsystem configuration error"}, {0x03110B00, 0, 0, "FFF5: Medium error, data unreadable, recommend reassign"}, {0x03110C00, 0, 0, "7000: Medium error, data unreadable, do not reassign"}, - {0x03310000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x03310000, 0, 1, "FFF3: Disk media format bad"}, - {0x04050000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04050000, 0, 1, "3002: Addressed device failed to respond to selection"}, - {0x04080000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04080000, 1, 1, "3100: Device bus error"}, - {0x04080100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04080100, 0, 1, "3109: IOA timed out a device command"}, {0x04088000, 0, 0, "3120: SCSI bus is not operational"}, - {0x04088100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04088100, 0, 1, "4100: Hard device bus fabric error"}, - {0x04118000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04118000, 0, 1, "9000: IOA reserved area data check"}, - {0x04118100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04118100, 0, 1, "9001: IOA reserved area invalid data pattern"}, - {0x04118200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04118200, 0, 1, "9002: IOA reserved area LRC error"}, - {0x04320000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04320000, 0, 1, "102E: Out of alternate sectors for disk storage"}, - {0x04330000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04330000, 1, 1, "FFF4: Data transfer underlength error"}, - {0x04338000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04338000, 1, 1, "FFF4: Data transfer overlength error"}, - {0x043E0100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x043E0100, 0, 1, "3400: Logical unit failure"}, - {0x04408500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04408500, 0, 1, "FFF4: Device microcode is corrupt"}, - {0x04418000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04418000, 1, 1, "8150: PCI bus error"}, {0x04430000, 1, 0, "Unsupported device bus message received"}, - {0x04440000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04440000, 1, 1, "FFF4: Disk device problem"}, - {0x04448200, 1, IPR_DEFAULT_LOG_LEVEL, + {0x04448200, 1, 1, "8150: Permanent IOA failure"}, - {0x04448300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04448300, 0, 1, "3010: Disk device returned wrong response to IOA"}, - {0x04448400, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04448400, 0, 1, "8151: IOA microcode error"}, {0x04448500, 0, 0, "Device bus status error"}, - {0x04448600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04448600, 0, 1, "8157: IOA error requiring IOA reset to recover"}, {0x04448700, 0, 0, "ATA device status error"}, {0x04490000, 0, 0, "Message reject received from the device"}, - {0x04449200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04449200, 0, 1, "8008: A permanent cache battery pack failure occurred"}, - {0x0444A000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x0444A000, 0, 1, "9090: Disk unit has been modified after the last known status"}, - {0x0444A200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x0444A200, 0, 1, "9081: IOA detected device error"}, - {0x0444A300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x0444A300, 0, 1, "9082: IOA detected device error"}, - {0x044A0000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x044A0000, 1, 1, "3110: Device bus error, message or command phase"}, - {0x044A8000, 1, IPR_DEFAULT_LOG_LEVEL, + {0x044A8000, 1, 1, "3110: SAS Command / Task Management Function failed"}, - {0x04670400, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04670400, 0, 1, "9091: Incorrect hardware configuration change has been detected"}, - {0x04678000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04678000, 0, 1, "9073: Invalid multi-adapter configuration"}, - {0x04678100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04678100, 0, 1, "4010: Incorrect connection between cascaded expanders"}, - {0x04678200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04678200, 0, 1, "4020: Connections exceed IOA design limits"}, - {0x04678300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04678300, 0, 1, "4030: Incorrect multipath connection"}, - {0x04679000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x04679000, 0, 1, "4110: Unsupported enclosure function"}, - {0x046E0000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x046E0000, 0, 1, "FFF4: Command to logical unit failed"}, {0x05240000, 1, 0, "Illegal request, invalid request type or request packet"}, @@ -315,103 +313,101 @@ struct ipr_error_table_t ipr_error_table[] = { "Illegal request, command sequence error"}, {0x052C8000, 1, 0, "Illegal request, dual adapter support not enabled"}, - {0x06040500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06040500, 0, 1, "9031: Array protection temporarily suspended, protection resuming"}, - {0x06040600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06040600, 0, 1, "9040: Array protection temporarily suspended, protection resuming"}, - {0x06288000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06288000, 0, 1, "3140: Device bus not ready to ready transition"}, - {0x06290000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06290000, 0, 1, "FFFB: SCSI bus was reset"}, {0x06290500, 0, 0, "FFFE: SCSI bus transition to single ended"}, {0x06290600, 0, 0, "FFFE: SCSI bus transition to LVD"}, - {0x06298000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06298000, 0, 1, "FFFB: SCSI bus was reset by another initiator"}, - {0x063F0300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x063F0300, 0, 1, "3029: A device replacement has occurred"}, - {0x064C8000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x064C8000, 0, 1, "9051: IOA cache data exists for a missing or failed device"}, - {0x064C8100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x064C8100, 0, 1, "9055: Auxiliary cache IOA contains cache data needed by the primary IOA"}, - {0x06670100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06670100, 0, 1, "9025: Disk unit is not supported at its physical location"}, - {0x06670600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06670600, 0, 1, "3020: IOA detected a SCSI bus configuration error"}, - {0x06678000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678000, 0, 1, "3150: SCSI bus configuration error"}, - {0x06678100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678100, 0, 1, "9074: Asymmetric advanced function disk configuration"}, - {0x06678300, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678300, 0, 1, "4040: Incomplete multipath connection between IOA and enclosure"}, - {0x06678400, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678400, 0, 1, "4041: Incomplete multipath connection between enclosure and device"}, - {0x06678500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678500, 0, 1, "9075: Incomplete multipath connection between IOA and remote IOA"}, - {0x06678600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06678600, 0, 1, "9076: Configuration error, missing remote IOA"}, - {0x06679100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06679100, 0, 1, "4050: Enclosure does not support a required multipath function"}, - {0x06690200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06690200, 0, 1, "9041: Array protection temporarily suspended"}, - {0x06698200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x06698200, 0, 1, "9042: Corrupt array parity detected on specified device"}, - {0x066B0200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B0200, 0, 1, "9030: Array no longer protected due to missing or failed disk unit"}, - {0x066B8000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B8000, 0, 1, "9071: Link operational transition"}, - {0x066B8100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B8100, 0, 1, "9072: Link not operational transition"}, - {0x066B8200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B8200, 0, 1, "9032: Array exposed but still protected"}, - {0x066B8300, 0, IPR_DEFAULT_LOG_LEVEL + 1, - "70DD: Device forced failed by disrupt device command"}, - {0x066B9100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B9100, 0, 1, "4061: Multipath redundancy level got better"}, - {0x066B9200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x066B9200, 0, 1, "4060: Multipath redundancy level got worse"}, {0x07270000, 0, 0, "Failure due to other device"}, - {0x07278000, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278000, 0, 1, "9008: IOA does not support functions expected by devices"}, - {0x07278100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278100, 0, 1, "9010: Cache data associated with attached devices cannot be found"}, - {0x07278200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278200, 0, 1, "9011: Cache data belongs to devices other than those attached"}, - {0x07278400, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278400, 0, 1, "9020: Array missing 2 or more devices with only 1 device present"}, - {0x07278500, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278500, 0, 1, "9021: Array missing 2 or more devices with 2 or more devices present"}, - {0x07278600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278600, 0, 1, "9022: Exposed array is missing a required device"}, - {0x07278700, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278700, 0, 1, "9023: Array member(s) not at required physical locations"}, - {0x07278800, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278800, 0, 1, "9024: Array not functional due to present hardware configuration"}, - {0x07278900, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278900, 0, 1, "9026: Array not functional due to present hardware configuration"}, - {0x07278A00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278A00, 0, 1, "9027: Array is missing a device and parity is out of sync"}, - {0x07278B00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278B00, 0, 1, "9028: Maximum number of arrays already exist"}, - {0x07278C00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278C00, 0, 1, "9050: Required cache data cannot be located for a disk unit"}, - {0x07278D00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278D00, 0, 1, "9052: Cache data exists for a device that has been modified"}, - {0x07278F00, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07278F00, 0, 1, "9054: IOA resources not available due to previous problems"}, - {0x07279100, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279100, 0, 1, "9092: Disk unit requires initialization before use"}, - {0x07279200, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279200, 0, 1, "9029: Incorrect hardware configuration change has been detected"}, - {0x07279600, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279600, 0, 1, "9060: One or more disk pairs are missing from an array"}, - {0x07279700, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279700, 0, 1, "9061: One or more disks are missing from an array"}, - {0x07279800, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279800, 0, 1, "9062: One or more disks are missing from an array"}, - {0x07279900, 0, IPR_DEFAULT_LOG_LEVEL, + {0x07279900, 0, 1, "9063: Maximum number of functional arrays has been exceeded"}, {0x0B260000, 0, 0, "Aborted command, invalid descriptor"}, @@ -485,16 +481,12 @@ static void ipr_reinit_ipr_cmnd(struct ipr_cmnd *ipr_cmd) { struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; - dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); ioarcb->write_data_transfer_length = 0; ioarcb->read_data_transfer_length = 0; ioarcb->write_ioadl_len = 0; ioarcb->read_ioadl_len = 0; - ioarcb->write_ioadl_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; ioasa->ioasc = 0; ioasa->residual_data_len = 0; ioasa->u.gata.status = 0; @@ -955,53 +947,6 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) } } -/** - * strip_and_pad_whitespace - Strip and pad trailing whitespace. - * @i: index into buffer - * @buf: string to modify - * - * This function will strip all trailing whitespace, pad the end - * of the string with a single space, and NULL terminate the string. - * - * Return value: - * new length of string - **/ -static int strip_and_pad_whitespace(int i, char *buf) -{ - while (i && buf[i] == ' ') - i--; - buf[i+1] = ' '; - buf[i+2] = '\0'; - return i + 2; -} - -/** - * ipr_log_vpd_compact - Log the passed extended VPD compactly. - * @prefix: string to print at start of printk - * @hostrcb: hostrcb pointer - * @vpd: vendor/product id/sn struct - * - * Return value: - * none - **/ -static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb, - struct ipr_vpd *vpd) -{ - char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN + 3]; - int i = 0; - - memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN); - i = strip_and_pad_whitespace(IPR_VENDOR_ID_LEN - 1, buffer); - - memcpy(&buffer[i], vpd->vpids.product_id, IPR_PROD_ID_LEN); - i = strip_and_pad_whitespace(i + IPR_PROD_ID_LEN - 1, buffer); - - memcpy(&buffer[i], vpd->sn, IPR_SERIAL_NUM_LEN); - buffer[IPR_SERIAL_NUM_LEN + i] = '\0'; - - ipr_hcam_err(hostrcb, "%s VPID/SN: %s\n", prefix, buffer); -} - /** * ipr_log_vpd - Log the passed VPD to the error log. * @vpd: vendor/product id/sn struct @@ -1025,23 +970,6 @@ static void ipr_log_vpd(struct ipr_vpd *vpd) ipr_err(" Serial Number: %s\n", buffer); } -/** - * ipr_log_ext_vpd_compact - Log the passed extended VPD compactly. - * @prefix: string to print at start of printk - * @hostrcb: hostrcb pointer - * @vpd: vendor/product id/sn/wwn struct - * - * Return value: - * none - **/ -static void ipr_log_ext_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb, - struct ipr_ext_vpd *vpd) -{ - ipr_log_vpd_compact(prefix, hostrcb, &vpd->vpd); - ipr_hcam_err(hostrcb, "%s WWN: %08X%08X\n", prefix, - be32_to_cpu(vpd->wwid[0]), be32_to_cpu(vpd->wwid[1])); -} - /** * ipr_log_ext_vpd - Log the passed extended VPD to the error log. * @vpd: vendor/product id/sn/wwn struct @@ -1356,11 +1284,10 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, error = &hostrcb->hcam.u.error.u.type_17_error; error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; - strstrip(error->failure_reason); - ipr_hcam_err(hostrcb, "%s [PRC: %08X]\n", error->failure_reason, - be32_to_cpu(hostrcb->hcam.u.error.prc)); - ipr_log_ext_vpd_compact("Remote IOA", hostrcb, &error->vpd); + ipr_err("%s\n", error->failure_reason); + ipr_err("Remote Adapter VPD:\n"); + ipr_log_ext_vpd(&error->vpd); ipr_log_hex_data(ioa_cfg, error->data, be32_to_cpu(hostrcb->hcam.length) - (offsetof(struct ipr_hostrcb_error, u) + @@ -1382,11 +1309,10 @@ static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, error = &hostrcb->hcam.u.error.u.type_07_error; error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; - strstrip(error->failure_reason); - ipr_hcam_err(hostrcb, "%s [PRC: %08X]\n", error->failure_reason, - be32_to_cpu(hostrcb->hcam.u.error.prc)); - ipr_log_vpd_compact("Remote IOA", hostrcb, &error->vpd); + ipr_err("%s\n", error->failure_reason); + ipr_err("Remote Adapter VPD:\n"); + ipr_log_vpd(&error->vpd); ipr_log_hex_data(ioa_cfg, error->data, be32_to_cpu(hostrcb->hcam.length) - (offsetof(struct ipr_hostrcb_error, u) + @@ -1684,7 +1610,7 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, /* Set indication we have logged an error */ ioa_cfg->errors_logged++; - if (ioa_cfg->log_level < ipr_error_table[error_index].log_hcam) + if (ioa_cfg->log_level < IPR_DEFAULT_LOG_LEVEL) return; if (be32_to_cpu(hostrcb->hcam.length) > sizeof(hostrcb->hcam.u.raw)) hostrcb->hcam.length = cpu_to_be32(sizeof(hostrcb->hcam.u.raw)); @@ -1743,15 +1669,12 @@ static void ipr_process_error(struct ipr_cmnd *ipr_cmd) struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_hostrcb *hostrcb = ipr_cmd->u.hostrcb; u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); - u32 fd_ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); list_del(&hostrcb->queue); list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); if (!ioasc) { ipr_handle_log_data(ioa_cfg, hostrcb); - if (fd_ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED) - ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_ABBREV); } else if (ioasc != IPR_IOASC_IOA_WAS_RESET) { dev_err(&ioa_cfg->pdev->dev, "Host RCB failed with IOASC: 0x%08X\n", ioasc); @@ -2709,13 +2632,8 @@ static ssize_t ipr_store_diagnostics(struct class_device *class_dev, if (!capable(CAP_SYS_ADMIN)) return -EACCES; + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - while(ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - } - ioa_cfg->errors_logged = 0; ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); @@ -3037,11 +2955,6 @@ static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg, unsigned long lock_flags; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - while(ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - } if (ioa_cfg->ucode_sglist) { spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); @@ -3937,8 +3850,6 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { if (ipr_cmd->scsi_cmd) ipr_cmd->done = ipr_scsi_eh_done; - if (ipr_cmd->qc) - ipr_cmd->done = ipr_sata_eh_done; if (ipr_cmd->qc && !(ipr_cmd->qc->flags & ATA_QCFLAG_FAILED)) { ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT; ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED; @@ -4319,14 +4230,6 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, sglist = scsi_cmd->request_buffer; - if (ipr_cmd->dma_use_sg <= ARRAY_SIZE(ioarcb->add_data.u.ioadl)) { - ioadl = ioarcb->add_data.u.ioadl; - ioarcb->write_ioadl_addr = - cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) + - offsetof(struct ipr_ioarcb, add_data)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; - } - for (i = 0; i < ipr_cmd->dma_use_sg; i++) { ioadl[i].flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(&sglist[i])); @@ -4357,11 +4260,6 @@ static int ipr_build_ioadl(struct ipr_ioa_cfg *ioa_cfg, scsi_cmd->sc_data_direction); if (likely(!pci_dma_mapping_error(ipr_cmd->dma_handle))) { - ioadl = ioarcb->add_data.u.ioadl; - ioarcb->write_ioadl_addr = - cpu_to_be32(be32_to_cpu(ioarcb->ioarcb_host_pci_addr) + - offsetof(struct ipr_ioarcb, add_data)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; ipr_cmd->dma_use_sg = 1; ioadl[0].flags_and_data_len = cpu_to_be32(ioadl_flags | length | IPR_IOADL_FLAGS_LAST); @@ -4448,9 +4346,11 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) **/ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) { - struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; - dma_addr_t dma_addr = be32_to_cpu(ioarcb->ioarcb_host_pci_addr); + struct ipr_ioarcb *ioarcb; + struct ipr_ioasa *ioasa; + + ioarcb = &ipr_cmd->ioarcb; + ioasa = &ipr_cmd->ioasa; memset(&ioarcb->cmd_pkt, 0, sizeof(struct ipr_cmd_pkt)); ioarcb->write_data_transfer_length = 0; @@ -4459,9 +4359,6 @@ static void ipr_reinit_ipr_cmnd_for_erp(struct ipr_cmnd *ipr_cmd) ioarcb->read_ioadl_len = 0; ioasa->ioasc = 0; ioasa->residual_data_len = 0; - ioarcb->write_ioadl_addr = - cpu_to_be32(dma_addr + offsetof(struct ipr_cmnd, ioadl)); - ioarcb->read_ioadl_addr = ioarcb->write_ioadl_addr; } /** @@ -4560,13 +4457,12 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, { int i; u16 data_len; - u32 ioasc, fd_ioasc; + u32 ioasc; struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; __be32 *ioasa_data = (__be32 *)ioasa; int error_index; ioasc = be32_to_cpu(ioasa->ioasc) & IPR_IOASC_IOASC_MASK; - fd_ioasc = be32_to_cpu(ioasa->fd_ioasc) & IPR_IOASC_IOASC_MASK; if (0 == ioasc) return; @@ -4574,19 +4470,13 @@ static void ipr_dump_ioasa(struct ipr_ioa_cfg *ioa_cfg, if (ioa_cfg->log_level < IPR_DEFAULT_LOG_LEVEL) return; - if (ioasc == IPR_IOASC_BUS_WAS_RESET && fd_ioasc) - error_index = ipr_get_error(fd_ioasc); - else - error_index = ipr_get_error(ioasc); + error_index = ipr_get_error(ioasc); if (ioa_cfg->log_level < IPR_MAX_LOG_LEVEL) { /* Don't log an error if the IOA already logged one */ if (ioasa->ilid != 0) return; - if (!ipr_is_gscsi(res)) - return; - if (ipr_error_table[error_index].log_ioasa == 0) return; } @@ -4740,19 +4630,18 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, struct scsi_cmnd *scsi_cmd = ipr_cmd->scsi_cmd; struct ipr_resource_entry *res = scsi_cmd->device->hostdata; u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); - u32 masked_ioasc = ioasc & IPR_IOASC_IOASC_MASK; if (!res) { ipr_scsi_eh_done(ipr_cmd); return; } - if (!ipr_is_gscsi(res) && masked_ioasc != IPR_IOASC_HW_DEV_BUS_STATUS) + if (ipr_is_gscsi(res)) + ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); + else ipr_gen_sense(ipr_cmd); - ipr_dump_ioasa(ioa_cfg, ipr_cmd, res); - - switch (masked_ioasc) { + switch (ioasc & IPR_IOASC_IOASC_MASK) { case IPR_IOASC_ABORTED_CMD_TERM_BY_HOST: if (ipr_is_naca_model(res)) scsi_cmd->result |= (DID_ABORT << 16); @@ -5232,7 +5121,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) struct ipr_ioarcb_ata_regs *regs; if (unlikely(!ioa_cfg->allow_cmds || ioa_cfg->ioa_is_dead)) - return AC_ERR_SYSTEM; + return -EIO; ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); ioarcb = &ipr_cmd->ioarcb; @@ -5277,7 +5166,7 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc) default: WARN_ON(1); - return AC_ERR_INVALID; + return -1; } mb(); @@ -5448,7 +5337,6 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd) ipr_send_hcam(ioa_cfg, IPR_HCAM_CDB_OP_CODE_CONFIG_CHANGE, hostrcb); } - scsi_report_bus_reset(ioa_cfg->host, IPR_VSET_BUS); dev_info(&ioa_cfg->pdev->dev, "IOA initialized.\n"); ioa_cfg->reset_retries = 0; @@ -5884,94 +5772,6 @@ static int ipr_ioafp_mode_sense_page28(struct ipr_cmnd *ipr_cmd) return IPR_RC_JOB_RETURN; } -/** - * ipr_ioafp_mode_select_page24 - Issue Mode Select to IOA - * @ipr_cmd: ipr command struct - * - * This function enables dual IOA RAID support if possible. - * - * Return value: - * IPR_RC_JOB_RETURN - **/ -static int ipr_ioafp_mode_select_page24(struct ipr_cmnd *ipr_cmd) -{ - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - struct ipr_mode_pages *mode_pages = &ioa_cfg->vpd_cbs->mode_pages; - struct ipr_mode_page24 *mode_page; - int length; - - ENTER; - mode_page = ipr_get_mode_page(mode_pages, 0x24, - sizeof(struct ipr_mode_page24)); - - if (mode_page) - mode_page->flags |= IPR_ENABLE_DUAL_IOA_AF; - - length = mode_pages->hdr.length + 1; - mode_pages->hdr.length = 0; - - ipr_build_mode_select(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), 0x11, - ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), - length); - - ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; - ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); - - LEAVE; - return IPR_RC_JOB_RETURN; -} - -/** - * ipr_reset_mode_sense_page24_failed - Handle failure of IOAFP mode sense - * @ipr_cmd: ipr command struct - * - * This function handles the failure of a Mode Sense to the IOAFP. - * Some adapters do not handle all mode pages. - * - * Return value: - * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN - **/ -static int ipr_reset_mode_sense_page24_failed(struct ipr_cmnd *ipr_cmd) -{ - u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); - - if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { - ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; - return IPR_RC_JOB_CONTINUE; - } - - return ipr_reset_cmd_failed(ipr_cmd); -} - -/** - * ipr_ioafp_mode_sense_page24 - Issue Page 24 Mode Sense to IOA - * @ipr_cmd: ipr command struct - * - * This function send a mode sense to the IOA to retrieve - * the IOA Advanced Function Control mode page. - * - * Return value: - * IPR_RC_JOB_RETURN - **/ -static int ipr_ioafp_mode_sense_page24(struct ipr_cmnd *ipr_cmd) -{ - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - - ENTER; - ipr_build_mode_sense(ipr_cmd, cpu_to_be32(IPR_IOA_RES_HANDLE), - 0x24, ioa_cfg->vpd_cbs_dma + - offsetof(struct ipr_misc_cbs, mode_pages), - sizeof(struct ipr_mode_pages)); - - ipr_cmd->job_step = ipr_ioafp_mode_select_page24; - ipr_cmd->job_step_failed = ipr_reset_mode_sense_page24_failed; - - ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); - - LEAVE; - return IPR_RC_JOB_RETURN; -} - /** * ipr_init_res_table - Initialize the resource table * @ipr_cmd: ipr command struct @@ -6040,10 +5840,7 @@ static int ipr_init_res_table(struct ipr_cmnd *ipr_cmd) } } - if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) - ipr_cmd->job_step = ipr_ioafp_mode_sense_page24; - else - ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; + ipr_cmd->job_step = ipr_ioafp_mode_sense_page28; LEAVE; return IPR_RC_JOB_CONTINUE; @@ -6065,11 +5862,8 @@ static int ipr_ioafp_query_ioa_cfg(struct ipr_cmnd *ipr_cmd) struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct ipr_inquiry_page3 *ucode_vpd = &ioa_cfg->vpd_cbs->page3_data; - struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; ENTER; - if (cap->cap & IPR_CAP_DUAL_IOA_RAID) - ioa_cfg->dual_raid = 1; dev_info(&ioa_cfg->pdev->dev, "Adapter firmware version: %02X%02X%02X%02X\n", ucode_vpd->major_release, ucode_vpd->card_type, ucode_vpd->minor_release[0], ucode_vpd->minor_release[1]); @@ -6152,37 +5946,6 @@ static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page) return 0; } -/** - * ipr_ioafp_cap_inquiry - Send a Page 0xD0 Inquiry to the adapter. - * @ipr_cmd: ipr command struct - * - * This function sends a Page 0xD0 inquiry to the adapter - * to retrieve adapter capabilities. - * - * Return value: - * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN - **/ -static int ipr_ioafp_cap_inquiry(struct ipr_cmnd *ipr_cmd) -{ - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data; - struct ipr_inquiry_cap *cap = &ioa_cfg->vpd_cbs->cap; - - ENTER; - ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; - memset(cap, 0, sizeof(*cap)); - - if (ipr_inquiry_page_supported(page0, 0xD0)) { - ipr_ioafp_inquiry(ipr_cmd, 1, 0xD0, - ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, cap), - sizeof(struct ipr_inquiry_cap)); - return IPR_RC_JOB_RETURN; - } - - LEAVE; - return IPR_RC_JOB_CONTINUE; -} - /** * ipr_ioafp_page3_inquiry - Send a Page 3 Inquiry to the adapter. * @ipr_cmd: ipr command struct @@ -6203,7 +5966,7 @@ static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) if (!ipr_inquiry_page_supported(page0, 1)) ioa_cfg->cache_state = CACHE_NONE; - ipr_cmd->job_step = ipr_ioafp_cap_inquiry; + ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; ipr_ioafp_inquiry(ipr_cmd, 1, 3, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page3_data), @@ -6425,7 +6188,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) dev_info(&ioa_cfg->pdev->dev, "Initializing IOA.\n"); ipr_cmd->timer.data = (unsigned long) ipr_cmd; - ipr_cmd->timer.expires = jiffies + (ioa_cfg->transop_timeout * HZ); + ipr_cmd->timer.expires = jiffies + (ipr_transop_timeout * HZ); ipr_cmd->timer.function = (void (*)(unsigned long))ipr_oper_timeout; ipr_cmd->done = ipr_reset_ioa_job; add_timer(&ipr_cmd->timer); @@ -6489,7 +6252,6 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) struct ipr_hostrcb *hostrcb; struct ipr_uc_sdt sdt; int rc, length; - u32 ioasc; mailbox = readl(ioa_cfg->ioa_mailbox); @@ -6522,13 +6284,9 @@ static void ipr_get_unit_check_buffer(struct ipr_ioa_cfg *ioa_cfg) (__be32 *)&hostrcb->hcam, min(length, (int)sizeof(hostrcb->hcam)) / sizeof(__be32)); - if (!rc) { + if (!rc) ipr_handle_log_data(ioa_cfg, hostrcb); - ioasc = be32_to_cpu(hostrcb->hcam.u.error.failing_dev_ioasc); - if (ioasc == IPR_IOASC_NR_IOA_RESET_REQUIRED && - ioa_cfg->sdt_state == GET_DUMP) - ioa_cfg->sdt_state = WAIT_FOR_DUMP; - } else + else ipr_unit_check_no_data(ioa_cfg); list_add_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); @@ -6627,7 +6385,6 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START); if (rc != PCIBIOS_SUCCESSFUL) { - pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev); ipr_cmd->ioasa.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); rc = IPR_RC_JOB_CONTINUE; } else { @@ -6640,48 +6397,6 @@ static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd) return rc; } -/** - * ipr_reset_slot_reset_done - Clear PCI reset to the adapter - * @ipr_cmd: ipr command struct - * - * Description: This clears PCI reset to the adapter and delays two seconds. - * - * Return value: - * IPR_RC_JOB_RETURN - **/ -static int ipr_reset_slot_reset_done(struct ipr_cmnd *ipr_cmd) -{ - ENTER; - pci_set_pcie_reset_state(ipr_cmd->ioa_cfg->pdev, pcie_deassert_reset); - ipr_cmd->job_step = ipr_reset_bist_done; - ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT); - LEAVE; - return IPR_RC_JOB_RETURN; -} - -/** - * ipr_reset_slot_reset - Reset the PCI slot of the adapter. - * @ipr_cmd: ipr command struct - * - * Description: This asserts PCI reset to the adapter. - * - * Return value: - * IPR_RC_JOB_RETURN - **/ -static int ipr_reset_slot_reset(struct ipr_cmnd *ipr_cmd) -{ - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - struct pci_dev *pdev = ioa_cfg->pdev; - - ENTER; - pci_block_user_cfg_access(pdev); - pci_set_pcie_reset_state(pdev, pcie_warm_reset); - ipr_cmd->job_step = ipr_reset_slot_reset_done; - ipr_reset_start_timer(ipr_cmd, IPR_PCI_RESET_TIMEOUT); - LEAVE; - return IPR_RC_JOB_RETURN; -} - /** * ipr_reset_allowed - Query whether or not IOA can be reset * @ioa_cfg: ioa config struct @@ -6721,7 +6436,7 @@ static int ipr_reset_wait_to_start_bist(struct ipr_cmnd *ipr_cmd) ipr_cmd->u.time_left -= IPR_CHECK_FOR_RESET_TIMEOUT; ipr_reset_start_timer(ipr_cmd, IPR_CHECK_FOR_RESET_TIMEOUT); } else { - ipr_cmd->job_step = ioa_cfg->reset; + ipr_cmd->job_step = ipr_reset_start_bist; rc = IPR_RC_JOB_CONTINUE; } @@ -6754,7 +6469,7 @@ static int ipr_reset_alert(struct ipr_cmnd *ipr_cmd) writel(IPR_UPROCI_RESET_ALERT, ioa_cfg->regs.set_uproc_interrupt_reg); ipr_cmd->job_step = ipr_reset_wait_to_start_bist; } else { - ipr_cmd->job_step = ioa_cfg->reset; + ipr_cmd->job_step = ipr_reset_start_bist; } ipr_cmd->u.time_left = IPR_WAIT_FOR_RESET_TIMEOUT; @@ -6849,14 +6564,12 @@ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd) ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; ipr_cmd->ioarcb.cmd_pkt.cdb[1] = shutdown_type; - if (shutdown_type == IPR_SHUTDOWN_NORMAL) - timeout = IPR_SHUTDOWN_TIMEOUT; + if (shutdown_type == IPR_SHUTDOWN_ABBREV) + timeout = IPR_ABBREV_SHUTDOWN_TIMEOUT; else if (shutdown_type == IPR_SHUTDOWN_PREPARE_FOR_NORMAL) timeout = IPR_INTERNAL_TIMEOUT; - else if (ioa_cfg->dual_raid && ipr_dual_ioa_raid) - timeout = IPR_DUAL_IOA_ABBR_SHUTDOWN_TO; else - timeout = IPR_ABBREV_SHUTDOWN_TIMEOUT; + timeout = IPR_SHUTDOWN_TIMEOUT; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, timeout); @@ -7036,11 +6749,8 @@ static pci_ers_result_t ipr_pci_slot_reset(struct pci_dev *pdev) struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); spin_lock_irqsave(ioa_cfg->host->host_lock, flags); - if (ioa_cfg->needs_warm_reset) - ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); - else - _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_restore_cfg_space, - IPR_SHUTDOWN_NONE); + _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_restore_cfg_space, + IPR_SHUTDOWN_NONE); spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); return PCI_ERS_RESULT_RECOVERED; } @@ -7407,6 +7117,8 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, ioa_cfg->pdev = pdev; ioa_cfg->log_level = ipr_log_level; ioa_cfg->doorbell = IPR_DOORBELL; + if (!ipr_auto_create) + ioa_cfg->doorbell |= IPR_RUNTIME_RESET; sprintf(ioa_cfg->eye_catcher, IPR_EYECATCHER); sprintf(ioa_cfg->trace_start, IPR_TRACE_START_LABEL); sprintf(ioa_cfg->ipr_free_label, IPR_FREEQ_LABEL); @@ -7489,7 +7201,7 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, unsigned long ipr_regs_pci; void __iomem *ipr_regs; int rc = PCIBIOS_SUCCESSFUL; - volatile u32 mask, uproc, interrupts; + volatile u32 mask, uproc; ENTER; @@ -7521,21 +7233,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, goto out_scsi_host_put; } - if (ipr_transop_timeout) - ioa_cfg->transop_timeout = ipr_transop_timeout; - else if (dev_id->driver_data & IPR_USE_LONG_TRANSOP_TIMEOUT) - ioa_cfg->transop_timeout = IPR_LONG_OPERATIONAL_TIMEOUT; - else - ioa_cfg->transop_timeout = IPR_OPERATIONAL_TIMEOUT; - - rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &ioa_cfg->revid); - - if (rc != PCIBIOS_SUCCESSFUL) { - dev_err(&pdev->dev, "Failed to read PCI revision ID\n"); - rc = -EIO; - goto out_scsi_host_put; - } - ipr_regs_pci = pci_resource_start(pdev, 0); rc = pci_request_regions(pdev, IPR_NAME); @@ -7604,14 +7301,9 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, * the card is in an unknown state and needs a hard reset */ mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg); - interrupts = readl(ioa_cfg->regs.sense_interrupt_reg); uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg); if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT)) ioa_cfg->needs_hard_reset = 1; - if (interrupts & IPR_PCII_ERROR_INTERRUPTS) - ioa_cfg->needs_hard_reset = 1; - if (interrupts & IPR_PCII_IOA_UNIT_CHECKED) - ioa_cfg->ioa_unit_checked = 1; ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); rc = request_irq(pdev->irq, ipr_isr, IRQF_SHARED, IPR_NAME, ioa_cfg); @@ -7622,13 +7314,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, goto cleanup_nolog; } - if ((dev_id->driver_data & IPR_USE_PCI_WARM_RESET) || - (dev_id->device == PCI_DEVICE_ID_IBM_OBSIDIAN_E && !ioa_cfg->revid)) { - ioa_cfg->needs_warm_reset = 1; - ioa_cfg->reset = ipr_reset_slot_reset; - } else - ioa_cfg->reset = ipr_reset_start_bist; - spin_lock(&ipr_driver_lock); list_add_tail(&ioa_cfg->queue, &ipr_ioa_head); spin_unlock(&ipr_driver_lock); @@ -7711,12 +7396,6 @@ static void __ipr_remove(struct pci_dev *pdev) ENTER; spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); - while(ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); - } - ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL); spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); @@ -7840,12 +7519,6 @@ static void ipr_shutdown(struct pci_dev *pdev) unsigned long lock_flags = 0; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - while(ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - } - ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL); spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); @@ -7867,48 +7540,29 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571A, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT}, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574E, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575D, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B3, 0, 0, 0 }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT | IPR_USE_PCI_WARM_RESET }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, 0, 0, 0 }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571E, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, 0, 0, 0 }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, - { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SCAMP_E, - PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_574D, 0, 0, - IPR_USE_LONG_TRANSOP_TIMEOUT }, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, 0, 0, 0 }, { } }; MODULE_DEVICE_TABLE(pci, ipr_pci_table); @@ -7925,7 +7579,6 @@ static struct pci_driver ipr_driver = { .remove = ipr_remove, .shutdown = ipr_shutdown, .err_handler = &ipr_err_handler, - .dynids.use_driver_data = 1 }; /** diff --git a/trunk/drivers/scsi/ipr.h b/trunk/drivers/scsi/ipr.h index d93156671e93..88f285de97bb 100644 --- a/trunk/drivers/scsi/ipr.h +++ b/trunk/drivers/scsi/ipr.h @@ -37,8 +37,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.4.1" -#define IPR_DRIVER_DATE "(April 24, 2007)" +#define IPR_DRIVER_VERSION "2.3.1" +#define IPR_DRIVER_DATE "(January 23, 2007)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -55,7 +55,6 @@ #define IPR_NUM_BASE_CMD_BLKS 100 #define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 -#define PCI_DEVICE_ID_IBM_SCAMP_E 0x034A #define IPR_SUBS_DEV_ID_2780 0x0264 #define IPR_SUBS_DEV_ID_5702 0x0266 @@ -70,12 +69,8 @@ #define IPR_SUBS_DEV_ID_572A 0x02C1 #define IPR_SUBS_DEV_ID_572B 0x02C2 #define IPR_SUBS_DEV_ID_572F 0x02C3 -#define IPR_SUBS_DEV_ID_574D 0x030B -#define IPR_SUBS_DEV_ID_574E 0x030A #define IPR_SUBS_DEV_ID_575B 0x030D #define IPR_SUBS_DEV_ID_575C 0x0338 -#define IPR_SUBS_DEV_ID_575D 0x033E -#define IPR_SUBS_DEV_ID_57B3 0x033A #define IPR_SUBS_DEV_ID_57B7 0x0360 #define IPR_SUBS_DEV_ID_57B8 0x02C2 @@ -91,7 +86,6 @@ * IOASCs */ #define IPR_IOASC_NR_INIT_CMD_REQUIRED 0x02040200 -#define IPR_IOASC_NR_IOA_RESET_REQUIRED 0x02048000 #define IPR_IOASC_SYNC_REQUIRED 0x023f0000 #define IPR_IOASC_MED_DO_NOT_REALLOC 0x03110C00 #define IPR_IOASC_HW_SEL_TIMEOUT 0x04050000 @@ -110,10 +104,6 @@ #define IPR_IOASC_IOA_WAS_RESET 0x10000001 #define IPR_IOASC_PCI_ACCESS_ERROR 0x10000002 -/* Driver data flags */ -#define IPR_USE_LONG_TRANSOP_TIMEOUT 0x00000001 -#define IPR_USE_PCI_WARM_RESET 0x00000002 - #define IPR_DEFAULT_MAX_ERROR_DUMP 984 #define IPR_NUM_LOG_HCAMS 2 #define IPR_NUM_CFG_CHG_HCAMS 2 @@ -181,7 +171,6 @@ #define IPR_SHUTDOWN_TIMEOUT (ipr_fastfail ? 60 * HZ : 10 * 60 * HZ) #define IPR_VSET_RW_TIMEOUT (ipr_fastfail ? 30 * HZ : 2 * 60 * HZ) #define IPR_ABBREV_SHUTDOWN_TIMEOUT (10 * HZ) -#define IPR_DUAL_IOA_ABBR_SHUTDOWN_TO (2 * 60 * HZ) #define IPR_DEVICE_RESET_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) #define IPR_CANCEL_ALL_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) #define IPR_ABORT_TASK_TIMEOUT (ipr_fastfail ? 10 * HZ : 30 * HZ) @@ -190,11 +179,9 @@ #define IPR_SET_SUP_DEVICE_TIMEOUT (2 * 60 * HZ) #define IPR_REQUEST_SENSE_TIMEOUT (10 * HZ) #define IPR_OPERATIONAL_TIMEOUT (5 * 60) -#define IPR_LONG_OPERATIONAL_TIMEOUT (12 * 60) #define IPR_WAIT_FOR_RESET_TIMEOUT (2 * HZ) #define IPR_CHECK_FOR_RESET_TIMEOUT (HZ / 10) #define IPR_WAIT_FOR_BIST_TIMEOUT (2 * HZ) -#define IPR_PCI_RESET_TIMEOUT (HZ / 2) #define IPR_DUMP_TIMEOUT (15 * HZ) /* @@ -426,25 +413,9 @@ struct ipr_ioarcb_ata_regs { u8 ctl; }__attribute__ ((packed, aligned(4))); -struct ipr_ioadl_desc { - __be32 flags_and_data_len; -#define IPR_IOADL_FLAGS_MASK 0xff000000 -#define IPR_IOADL_GET_FLAGS(x) (be32_to_cpu(x) & IPR_IOADL_FLAGS_MASK) -#define IPR_IOADL_DATA_LEN_MASK 0x00ffffff -#define IPR_IOADL_GET_DATA_LEN(x) (be32_to_cpu(x) & IPR_IOADL_DATA_LEN_MASK) -#define IPR_IOADL_FLAGS_READ 0x48000000 -#define IPR_IOADL_FLAGS_READ_LAST 0x49000000 -#define IPR_IOADL_FLAGS_WRITE 0x68000000 -#define IPR_IOADL_FLAGS_WRITE_LAST 0x69000000 -#define IPR_IOADL_FLAGS_LAST 0x01000000 - - __be32 address; -}__attribute__((packed, aligned (8))); - struct ipr_ioarcb_add_data { union { struct ipr_ioarcb_ata_regs regs; - struct ipr_ioadl_desc ioadl[5]; __be32 add_cmd_parms[10]; }u; }__attribute__ ((packed, aligned(4))); @@ -476,6 +447,21 @@ struct ipr_ioarcb { struct ipr_ioarcb_add_data add_data; }__attribute__((packed, aligned (4))); +struct ipr_ioadl_desc { + __be32 flags_and_data_len; +#define IPR_IOADL_FLAGS_MASK 0xff000000 +#define IPR_IOADL_GET_FLAGS(x) (be32_to_cpu(x) & IPR_IOADL_FLAGS_MASK) +#define IPR_IOADL_DATA_LEN_MASK 0x00ffffff +#define IPR_IOADL_GET_DATA_LEN(x) (be32_to_cpu(x) & IPR_IOADL_DATA_LEN_MASK) +#define IPR_IOADL_FLAGS_READ 0x48000000 +#define IPR_IOADL_FLAGS_READ_LAST 0x49000000 +#define IPR_IOADL_FLAGS_WRITE 0x68000000 +#define IPR_IOADL_FLAGS_WRITE_LAST 0x69000000 +#define IPR_IOADL_FLAGS_LAST 0x01000000 + + __be32 address; +}__attribute__((packed, aligned (8))); + struct ipr_ioasa_vset { __be32 failing_lba_hi; __be32 failing_lba_lo; @@ -606,12 +592,6 @@ struct ipr_mode_page28 { struct ipr_dev_bus_entry bus[0]; }__attribute__((packed)); -struct ipr_mode_page24 { - struct ipr_mode_page_hdr hdr; - u8 flags; -#define IPR_ENABLE_DUAL_IOA_AF 0x80 -}__attribute__((packed)); - struct ipr_ioa_vpd { struct ipr_std_inq_data std_inq_data; u8 ascii_part_num[12]; @@ -634,19 +614,6 @@ struct ipr_inquiry_page3 { u8 patch_number[4]; }__attribute__((packed)); -struct ipr_inquiry_cap { - u8 peri_qual_dev_type; - u8 page_code; - u8 reserved1; - u8 page_length; - u8 ascii_len; - u8 reserved2; - u8 sis_version[2]; - u8 cap; -#define IPR_CAP_DUAL_IOA_RAID 0x80 - u8 reserved3[15]; -}__attribute__((packed)); - #define IPR_INQUIRY_PAGE0_ENTRIES 20 struct ipr_inquiry_page0 { u8 peri_qual_dev_type; @@ -985,7 +952,6 @@ struct ipr_misc_cbs { struct ipr_ioa_vpd ioa_vpd; struct ipr_inquiry_page0 page0_data; struct ipr_inquiry_page3 page3_data; - struct ipr_inquiry_cap cap; struct ipr_mode_pages mode_pages; struct ipr_supported_device supp_dev; }; @@ -1092,10 +1058,6 @@ struct ipr_ioa_cfg { u8 allow_cmds:1; u8 allow_ml_add_del:1; u8 needs_hard_reset:1; - u8 dual_raid:1; - u8 needs_warm_reset:1; - - u8 revid; enum ipr_cache_state cache_state; u16 type; /* CCIN of the card */ @@ -1157,7 +1119,6 @@ struct ipr_ioa_cfg { struct ipr_bus_attributes bus_attr[IPR_MAX_NUM_BUSES]; - unsigned int transop_timeout; const struct ipr_chip_cfg_t *chip_cfg; void __iomem *hdw_dma_regs; /* iomapped PCI memory space */ @@ -1189,7 +1150,6 @@ struct ipr_ioa_cfg { struct pci_pool *ipr_cmd_pool; struct ipr_cmnd *reset_cmd; - int (*reset) (struct ipr_cmnd *); struct ata_host ata_host; char ipr_cmd_label[8]; diff --git a/trunk/drivers/scsi/iscsi_tcp.c b/trunk/drivers/scsi/iscsi_tcp.c index c9a3abf9e7b6..8f55e1431433 100644 --- a/trunk/drivers/scsi/iscsi_tcp.c +++ b/trunk/drivers/scsi/iscsi_tcp.c @@ -527,12 +527,12 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *conn) * than 8K, but there are no targets that currently do this. * For now we fail until we find a vendor that needs it */ - if (ISCSI_DEF_MAX_RECV_SEG_LEN < + if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH < tcp_conn->in.datalen) { printk(KERN_ERR "iscsi_tcp: received buffer of len %u " "but conn buffer is only %u (opcode %0x)\n", tcp_conn->in.datalen, - ISCSI_DEF_MAX_RECV_SEG_LEN, opcode); + DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, opcode); rc = ISCSI_ERR_PROTO; break; } @@ -1762,7 +1762,7 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) * due to strange issues with iser these are not set * in iscsi_conn_setup */ - conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN; + conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH; tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL); if (!tcp_conn) @@ -1777,24 +1777,14 @@ iscsi_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0, CRYPTO_ALG_ASYNC); tcp_conn->tx_hash.flags = 0; - if (IS_ERR(tcp_conn->tx_hash.tfm)) { - printk(KERN_ERR "Could not create connection due to crc32c " - "loading error %ld. Make sure the crc32c module is " - "built as a module or into the kernel\n", - PTR_ERR(tcp_conn->tx_hash.tfm)); + if (IS_ERR(tcp_conn->tx_hash.tfm)) goto free_tcp_conn; - } tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0, CRYPTO_ALG_ASYNC); tcp_conn->rx_hash.flags = 0; - if (IS_ERR(tcp_conn->rx_hash.tfm)) { - printk(KERN_ERR "Could not create connection due to crc32c " - "loading error %ld. Make sure the crc32c module is " - "built as a module or into the kernel\n", - PTR_ERR(tcp_conn->rx_hash.tfm)); + if (IS_ERR(tcp_conn->rx_hash.tfm)) goto free_tx_tfm; - } return cls_conn; @@ -2148,7 +2138,6 @@ static struct scsi_host_template iscsi_sht = { .change_queue_depth = iscsi_change_queue_depth, .can_queue = ISCSI_XMIT_CMDS_MAX - 1, .sg_tablesize = ISCSI_SG_TABLESIZE, - .max_sectors = 0xFFFF, .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_host_reset_handler = iscsi_eh_host_reset, diff --git a/trunk/drivers/scsi/libiscsi.c b/trunk/drivers/scsi/libiscsi.c index 3f5b9b445b29..7c75771c77ff 100644 --- a/trunk/drivers/scsi/libiscsi.c +++ b/trunk/drivers/scsi/libiscsi.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -270,14 +269,14 @@ static int iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, goto out; } - senselen = be16_to_cpu(get_unaligned((__be16 *) data)); + senselen = be16_to_cpu(*(__be16 *)data); if (datalen < senselen) goto invalid_datalen; memcpy(sc->sense_buffer, data + 2, min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); debug_scsi("copied %d bytes of sense\n", - min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); + min(senselen, SCSI_SENSE_BUFFERSIZE)); } if (sc->sc_data_direction == DMA_TO_DEVICE) @@ -578,7 +577,7 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) } EXPORT_SYMBOL_GPL(iscsi_conn_failure); -static int iscsi_xmit_mtask(struct iscsi_conn *conn) +static int iscsi_xmit_imm_task(struct iscsi_conn *conn) { struct iscsi_hdr *hdr = conn->mtask->hdr; int rc, was_logout = 0; @@ -592,9 +591,6 @@ static int iscsi_xmit_mtask(struct iscsi_conn *conn) if (rc) return rc; - /* done with this in-progress mtask */ - conn->mtask = NULL; - if (was_logout) { set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); return -ENODATA; @@ -647,9 +643,11 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) conn->ctask = NULL; } if (conn->mtask) { - rc = iscsi_xmit_mtask(conn); + rc = iscsi_xmit_imm_task(conn); if (rc) goto again; + /* done with this in-progress mtask */ + conn->mtask = NULL; } /* process immediate first */ @@ -660,10 +658,12 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) list_add_tail(&conn->mtask->running, &conn->mgmt_run_list); spin_unlock_bh(&conn->session->lock); - rc = iscsi_xmit_mtask(conn); + rc = iscsi_xmit_imm_task(conn); if (rc) goto again; } + /* done with this mtask */ + conn->mtask = NULL; } /* process command queue */ @@ -701,10 +701,12 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) list_add_tail(&conn->mtask->running, &conn->mgmt_run_list); spin_unlock_bh(&conn->session->lock); - rc = iscsi_xmit_mtask(conn); - if (rc) + rc = tt->xmit_mgmt_task(conn, conn->mtask); + if (rc) goto again; } + /* done with this mtask */ + conn->mtask = NULL; } return -ENODATA; @@ -1521,7 +1523,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) } spin_unlock_bh(&session->lock); - data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL); + data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL); if (!data) goto login_mtask_data_alloc_fail; conn->login_mtask->data = conn->data = data; @@ -1595,9 +1597,6 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) wake_up(&conn->ehwait); } - /* flush queued up work because we free the connection below */ - scsi_flush_work(session->host); - spin_lock_bh(&session->lock); kfree(conn->data); kfree(conn->persistent_address); diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index e34442e405e8..dc70c180e115 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -22,6 +22,7 @@ * */ +#include #include #include "sas_internal.h" diff --git a/trunk/drivers/scsi/libsas/sas_scsi_host.c b/trunk/drivers/scsi/libsas/sas_scsi_host.c index b4b52694497c..897a5e2c55e4 100644 --- a/trunk/drivers/scsi/libsas/sas_scsi_host.c +++ b/trunk/drivers/scsi/libsas/sas_scsi_host.c @@ -23,8 +23,6 @@ * */ -#include - #include "sas_internal.h" #include @@ -186,7 +184,7 @@ static int sas_queue_up(struct sas_task *task) list_add_tail(&task->list, &core->task_queue); core->task_queue_size += 1; spin_unlock_irqrestore(&core->task_queue_lock, flags); - wake_up_process(core->queue_thread); + up(&core->queue_thread_sema); return 0; } @@ -821,7 +819,7 @@ static void sas_queue(struct sas_ha_struct *sas_ha) struct sas_internal *i = to_sas_internal(core->shost->transportt); spin_lock_irqsave(&core->task_queue_lock, flags); - while (!kthread_should_stop() && + while (!core->queue_thread_kill && !list_empty(&core->task_queue)) { can_queue = sas_ha->lldd_queue_size - core->task_queue_size; @@ -860,6 +858,8 @@ static void sas_queue(struct sas_ha_struct *sas_ha) spin_unlock_irqrestore(&core->task_queue_lock, flags); } +static DECLARE_COMPLETION(queue_th_comp); + /** * sas_queue_thread -- The Task Collector thread * @_sas_ha: pointer to struct sas_ha @@ -867,33 +867,40 @@ static void sas_queue(struct sas_ha_struct *sas_ha) static int sas_queue_thread(void *_sas_ha) { struct sas_ha_struct *sas_ha = _sas_ha; + struct scsi_core *core = &sas_ha->core; + daemonize("sas_queue_%d", core->shost->host_no); current->flags |= PF_NOFREEZE; + complete(&queue_th_comp); + while (1) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); + down_interruptible(&core->queue_thread_sema); sas_queue(sas_ha); - if (kthread_should_stop()) + if (core->queue_thread_kill) break; } + complete(&queue_th_comp); + return 0; } int sas_init_queue(struct sas_ha_struct *sas_ha) { + int res; struct scsi_core *core = &sas_ha->core; spin_lock_init(&core->task_queue_lock); core->task_queue_size = 0; INIT_LIST_HEAD(&core->task_queue); + init_MUTEX_LOCKED(&core->queue_thread_sema); - core->queue_thread = kthread_run(sas_queue_thread, sas_ha, - "sas_queue_%d", core->shost->host_no); - if (IS_ERR(core->queue_thread)) - return PTR_ERR(core->queue_thread); - return 0; + res = kernel_thread(sas_queue_thread, sas_ha, 0); + if (res >= 0) + wait_for_completion(&queue_th_comp); + + return res < 0 ? res : 0; } void sas_shutdown_queue(struct sas_ha_struct *sas_ha) @@ -902,7 +909,10 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha) struct scsi_core *core = &sas_ha->core; struct sas_task *task, *n; - kthread_stop(core->queue_thread); + init_completion(&queue_th_comp); + core->queue_thread_kill = 1; + up(&core->queue_thread_sema); + wait_for_completion(&queue_th_comp); if (!list_empty(&core->task_queue)) SAS_DPRINTK("HA: %llx: scsi core task queue is NOT empty!?\n", diff --git a/trunk/drivers/scsi/libsrp.c b/trunk/drivers/scsi/libsrp.c index 5631c199a8eb..89403b00e042 100644 --- a/trunk/drivers/scsi/libsrp.c +++ b/trunk/drivers/scsi/libsrp.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -224,7 +225,8 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, struct srp_direct_buf *md = NULL; struct scatterlist dummy, *sg = NULL; dma_addr_t token = 0; - int err = 0; + long err; + unsigned int done = 0; int nmd, nsg = 0, len; if (dma_map || ext_desc) { @@ -256,8 +258,8 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, sg_dma_address(&dummy) = token; err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE, id->table_desc.len); - if (err) { - eprintk("Error copying indirect table %d\n", err); + if (err < 0) { + eprintk("Error copying indirect table %ld\n", err); goto free_mem; } } else { @@ -270,7 +272,6 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, DMA_BIDIRECTIONAL); if (!nsg) { eprintk("fail to map %p %d\n", iue, sc->use_sg); - err = -EIO; goto free_mem; } len = min(sc->request_bufflen, id->len); @@ -286,7 +287,7 @@ static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, if (token && dma_map) dma_free_coherent(iue->target->dev, id->table_desc.len, md, token); - return err; + return done; } static int data_out_desc_size(struct srp_cmd *cmd) @@ -351,7 +352,7 @@ int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, break; default: eprintk("Unknown format %d %x\n", dir, format); - err = -EINVAL; + break; } return err; diff --git a/trunk/drivers/scsi/lpfc/lpfc.h b/trunk/drivers/scsi/lpfc/lpfc.h index 82e8f90c4617..a7de0bca5bdd 100644 --- a/trunk/drivers/scsi/lpfc/lpfc.h +++ b/trunk/drivers/scsi/lpfc/lpfc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -27,6 +27,10 @@ struct lpfc_sli2_slim; requests */ #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact the NameServer before giving up. */ +#define LPFC_DFT_HBA_Q_DEPTH 2048 /* max cmds per hba */ +#define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */ +#define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */ + #define LPFC_CMD_PER_LUN 3 /* max outstanding cmds per lun */ #define LPFC_SG_SEG_CNT 64 /* sg element count per scsi cmnd */ #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ @@ -240,23 +244,28 @@ struct lpfc_hba { #define FC_FABRIC 0x100 /* We are fabric attached */ #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ #define FC_RSCN_DISCOVERY 0x400 /* Authenticate all devices after RSCN*/ -#define FC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */ #define FC_LOADING 0x1000 /* HBA in process of loading drvr */ #define FC_UNLOADING 0x2000 /* HBA in process of unloading drvr */ #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ #define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ #define FC_BYPASSED_MODE 0x20000 /* NPort is in bypassed mode */ -#define FC_LOOPBACK_MODE 0x40000 /* NPort is in Loopback mode */ - /* This flag is set while issuing */ - /* INIT_LINK mailbox command */ -#define FC_IGNORE_ERATT 0x80000 /* intr handler should ignore ERATT */ uint32_t fc_topology; /* link topology, from LINK INIT */ struct lpfc_stats fc_stat; - struct list_head fc_nodes; + /* These are the head/tail pointers for the bind, plogi, adisc, unmap, + * and map lists. Their counters are immediately following. + */ + struct list_head fc_plogi_list; + struct list_head fc_adisc_list; + struct list_head fc_reglogin_list; + struct list_head fc_prli_list; + struct list_head fc_nlpunmap_list; + struct list_head fc_nlpmap_list; + struct list_head fc_npr_list; + struct list_head fc_unused_list; /* Keep counters for the number of entries in each list. */ uint16_t fc_plogi_cnt; @@ -378,17 +387,13 @@ struct lpfc_hba { mempool_t *mbox_mem_pool; mempool_t *nlp_mem_pool; + struct list_head freebufList; + struct list_head ctrspbuflist; + struct list_head rnidrspbuflist; struct fc_host_statistics link_stats; }; -static inline void -lpfc_set_loopback_flag(struct lpfc_hba *phba) { - if (phba->cfg_topology == FLAGS_LOCAL_LB) - phba->fc_flag |= FC_LOOPBACK_MODE; - else - phba->fc_flag &= ~FC_LOOPBACK_MODE; -} struct rnidrsp { void *buf; diff --git a/trunk/drivers/scsi/lpfc/lpfc_attr.c b/trunk/drivers/scsi/lpfc/lpfc_attr.c index 95fe77e816f8..f247e786af99 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_attr.c +++ b/trunk/drivers/scsi/lpfc/lpfc_attr.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -20,7 +20,6 @@ *******************************************************************/ #include -#include #include #include @@ -214,7 +213,6 @@ lpfc_issue_lip(struct Scsi_Host *host) int mbxstatus = MBXERR_ERROR; if ((phba->fc_flag & FC_OFFLINE_MODE) || - (phba->fc_flag & FC_BLOCK_MGMT_IO) || (phba->hba_state != LPFC_HBA_READY)) return -EPERM; @@ -237,7 +235,6 @@ lpfc_issue_lip(struct Scsi_Host *host) phba->fc_ratov * 2); } - lpfc_set_loopback_flag(phba); if (mbxstatus == MBX_TIMEOUT) pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; else @@ -250,62 +247,19 @@ lpfc_issue_lip(struct Scsi_Host *host) } static int -lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) +lpfc_selective_reset(struct lpfc_hba *phba) { struct completion online_compl; - struct lpfc_sli_ring *pring; - struct lpfc_sli *psli; int status = 0; - int cnt = 0; - int i; init_completion(&online_compl); lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_OFFLINE_PREP); - wait_for_completion(&online_compl); - - if (status != 0) - return -EIO; - - psli = &phba->sli; - - for (i = 0; i < psli->num_rings; i++) { - pring = &psli->ring[i]; - /* The linkdown event takes 30 seconds to timeout. */ - while (pring->txcmplq_cnt) { - msleep(10); - if (cnt++ > 3000) { - lpfc_printf_log(phba, - KERN_WARNING, LOG_INIT, - "%d:0466 Outstanding IO when " - "bringing Adapter offline\n", - phba->brd_no); - break; - } - } - } - - init_completion(&online_compl); - lpfc_workq_post_event(phba, &status, &online_compl, type); + LPFC_EVT_OFFLINE); wait_for_completion(&online_compl); if (status != 0) return -EIO; - return 0; -} - -static int -lpfc_selective_reset(struct lpfc_hba *phba) -{ - struct completion online_compl; - int status = 0; - - status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); - - if (status != 0) - return status; - init_completion(&online_compl); lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_ONLINE); @@ -370,19 +324,23 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) init_completion(&online_compl); - if(strncmp(buf, "online", sizeof("online") - 1) == 0) { + if(strncmp(buf, "online", sizeof("online") - 1) == 0) lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_ONLINE); - wait_for_completion(&online_compl); - } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) - status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); + else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) + lpfc_workq_post_event(phba, &status, &online_compl, + LPFC_EVT_OFFLINE); else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0) - status = lpfc_do_offline(phba, LPFC_EVT_WARM_START); - else if (strncmp(buf, "error", sizeof("error") - 1) == 0) - status = lpfc_do_offline(phba, LPFC_EVT_KILL); + lpfc_workq_post_event(phba, &status, &online_compl, + LPFC_EVT_WARM_START); + else if (strncmp(buf, "error", sizeof("error") - 1) == 0) + lpfc_workq_post_event(phba, &status, &online_compl, + LPFC_EVT_KILL); else return -EINVAL; + wait_for_completion(&online_compl); + if (!status) return strlen(buf); else @@ -687,7 +645,9 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) dev_printk(KERN_NOTICE, &phba->pcidev->dev, "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); - stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); + init_completion(&online_compl); + lpfc_workq_post_event(phba, &stat1, &online_compl, LPFC_EVT_OFFLINE); + wait_for_completion(&online_compl); if (stat1) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "%d:0463 lpfc_soft_wwpn attribute set failed to reinit " @@ -829,18 +789,6 @@ lpfc_nodev_tmo_init(struct lpfc_hba *phba, int val) return -EINVAL; } -static void -lpfc_update_rport_devloss_tmo(struct lpfc_hba *phba) -{ - struct lpfc_nodelist *ndlp; - - spin_lock_irq(phba->host->host_lock); - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) - if (ndlp->rport) - ndlp->rport->dev_loss_tmo = phba->cfg_devloss_tmo; - spin_unlock_irq(phba->host->host_lock); -} - static int lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) { @@ -856,7 +804,6 @@ lpfc_nodev_tmo_set(struct lpfc_hba *phba, int val) if (val >= LPFC_MIN_DEVLOSS_TMO && val <= LPFC_MAX_DEVLOSS_TMO) { phba->cfg_nodev_tmo = val; phba->cfg_devloss_tmo = val; - lpfc_update_rport_devloss_tmo(phba); return 0; } @@ -892,7 +839,6 @@ lpfc_devloss_tmo_set(struct lpfc_hba *phba, int val) phba->cfg_nodev_tmo = val; phba->cfg_devloss_tmo = val; phba->dev_loss_tmo_changed = 1; - lpfc_update_rport_devloss_tmo(phba); return 0; } @@ -985,10 +931,9 @@ LPFC_ATTR_RW(topology, 0, 0, 6, "Select Fibre Channel topology"); # 1 = 1 Gigabaud # 2 = 2 Gigabaud # 4 = 4 Gigabaud -# 8 = 8 Gigabaud -# Value range is [0,8]. Default value is 0. +# Value range is [0,4]. Default value is 0. */ -LPFC_ATTR_R(link_speed, 0, 0, 8, "Select link speed"); +LPFC_ATTR_R(link_speed, 0, 0, 4, "Select link speed"); /* # lpfc_fcp_class: Determines FC class to use for the FCP protocol. @@ -1013,7 +958,7 @@ LPFC_ATTR_R(ack0, 0, 0, 1, "Enable ACK0 support"); /* # lpfc_cr_delay & lpfc_cr_count: Default values for I/O colaesing # cr_delay (msec) or cr_count outstanding commands. cr_delay can take -# value [0,63]. cr_count can take value [1,255]. Default value of cr_delay +# value [0,63]. cr_count can take value [0,255]. Default value of cr_delay # is 0. Default value of cr_count is 1. The cr_count feature is disabled if # cr_delay is set to 0. */ @@ -1282,11 +1227,11 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; int rc; - if (off > MAILBOX_CMD_SIZE) + if (off > sizeof(MAILBOX_t)) return -ERANGE; - if ((count + off) > MAILBOX_CMD_SIZE) - count = MAILBOX_CMD_SIZE - off; + if ((count + off) > sizeof(MAILBOX_t)) + count = sizeof(MAILBOX_t) - off; if (off % 4 || count % 4 || (unsigned long)buf % 4) return -EINVAL; @@ -1362,12 +1307,6 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) return -EPERM; } - if (phba->fc_flag & FC_BLOCK_MGMT_IO) { - sysfs_mbox_idle(phba); - spin_unlock_irq(host->host_lock); - return -EAGAIN; - } - if ((phba->fc_flag & FC_OFFLINE_MODE) || (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){ @@ -1387,11 +1326,6 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) } if (rc != MBX_SUCCESS) { - if (rc == MBX_TIMEOUT) { - phba->sysfs_mbox.mbox->mbox_cmpl = - lpfc_sli_def_mbox_cmpl; - phba->sysfs_mbox.mbox = NULL; - } sysfs_mbox_idle(phba); spin_unlock_irq(host->host_lock); return (rc == MBX_TIMEOUT) ? -ETIME : -ENODEV; @@ -1410,7 +1344,7 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) phba->sysfs_mbox.offset = off + count; - if (phba->sysfs_mbox.offset == MAILBOX_CMD_SIZE) + if (phba->sysfs_mbox.offset == sizeof(MAILBOX_t)) sysfs_mbox_idle(phba); spin_unlock_irq(phba->host->host_lock); @@ -1424,7 +1358,7 @@ static struct bin_attribute sysfs_mbox_attr = { .mode = S_IRUSR | S_IWUSR, .owner = THIS_MODULE, }, - .size = MAILBOX_CMD_SIZE, + .size = sizeof(MAILBOX_t), .read = sysfs_mbox_read, .write = sysfs_mbox_write, }; @@ -1560,9 +1494,6 @@ lpfc_get_host_speed(struct Scsi_Host *shost) case LA_4GHZ_LINK: fc_host_speed(shost) = FC_PORTSPEED_4GBIT; break; - case LA_8GHZ_LINK: - fc_host_speed(shost) = FC_PORTSPEED_8GBIT; - break; default: fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; break; @@ -1615,9 +1546,6 @@ lpfc_get_stats(struct Scsi_Host *shost) unsigned long seconds; int rc = 0; - if (phba->fc_flag & FC_BLOCK_MGMT_IO) - return NULL; - pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) return NULL; @@ -1703,8 +1631,6 @@ lpfc_get_stats(struct Scsi_Host *shost) else hs->seconds_since_last_reset = seconds - psli->stats_start; - mempool_free(pmboxq, phba->mbox_mem_pool); - return hs; } @@ -1718,9 +1644,6 @@ lpfc_reset_stats(struct Scsi_Host *shost) MAILBOX_t *pmb; int rc = 0; - if (phba->fc_flag & FC_BLOCK_MGMT_IO) - return; - pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) return; @@ -1776,8 +1699,6 @@ lpfc_reset_stats(struct Scsi_Host *shost) psli->stats_start = get_seconds(); - mempool_free(pmboxq, phba->mbox_mem_pool); - return; } @@ -1785,51 +1706,67 @@ lpfc_reset_stats(struct Scsi_Host *shost) * The LPFC driver treats linkdown handling as target loss events so there * are no sysfs handlers for link_down_tmo. */ - -static struct lpfc_nodelist * -lpfc_get_node_by_target(struct scsi_target *starget) +static void +lpfc_get_starget_port_id(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; - struct lpfc_nodelist *ndlp; + uint32_t did = -1; + struct lpfc_nodelist *ndlp = NULL; spin_lock_irq(shost->host_lock); - /* Search for this, mapped, target ID */ - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && - starget->id == ndlp->nlp_sid) { - spin_unlock_irq(shost->host_lock); - return ndlp; + /* Search the mapped list for this target ID */ + list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { + if (starget->id == ndlp->nlp_sid) { + did = ndlp->nlp_DID; + break; } } spin_unlock_irq(shost->host_lock); - return NULL; -} - -static void -lpfc_get_starget_port_id(struct scsi_target *starget) -{ - struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget); - fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1; + fc_starget_port_id(starget) = did; } static void lpfc_get_starget_node_name(struct scsi_target *starget) { - struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; + u64 node_name = 0; + struct lpfc_nodelist *ndlp = NULL; + + spin_lock_irq(shost->host_lock); + /* Search the mapped list for this target ID */ + list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { + if (starget->id == ndlp->nlp_sid) { + node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn); + break; + } + } + spin_unlock_irq(shost->host_lock); - fc_starget_node_name(starget) = - ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0; + fc_starget_node_name(starget) = node_name; } static void lpfc_get_starget_port_name(struct scsi_target *starget) { - struct lpfc_nodelist *ndlp = lpfc_get_node_by_target(starget); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct lpfc_hba *phba = (struct lpfc_hba *) shost->hostdata; + u64 port_name = 0; + struct lpfc_nodelist *ndlp = NULL; + + spin_lock_irq(shost->host_lock); + /* Search the mapped list for this target ID */ + list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { + if (starget->id == ndlp->nlp_sid) { + port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn); + break; + } + } + spin_unlock_irq(shost->host_lock); - fc_starget_port_name(starget) = - ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0; + fc_starget_port_name(starget) = port_name; } static void @@ -1958,8 +1895,25 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) sizeof(struct fcp_rsp) + (phba->cfg_sg_seg_cnt * sizeof(struct ulp_bde64)); + switch (phba->pcidev->device) { + case PCI_DEVICE_ID_LP101: + case PCI_DEVICE_ID_BSMB: + case PCI_DEVICE_ID_ZSMB: + phba->cfg_hba_queue_depth = LPFC_LP101_HBA_Q_DEPTH; + break; + case PCI_DEVICE_ID_RFLY: + case PCI_DEVICE_ID_PFLY: + case PCI_DEVICE_ID_BMID: + case PCI_DEVICE_ID_ZMID: + case PCI_DEVICE_ID_TFLY: + phba->cfg_hba_queue_depth = LPFC_LC_HBA_Q_DEPTH; + break; + default: + phba->cfg_hba_queue_depth = LPFC_DFT_HBA_Q_DEPTH; + } - lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); + if (phba->cfg_hba_queue_depth > lpfc_hba_queue_depth) + lpfc_hba_queue_depth_init(phba, lpfc_hba_queue_depth); return; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_crtn.h b/trunk/drivers/scsi/lpfc/lpfc_crtn.h index b8c2a8862d8c..1251788ce2a3 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_crtn.h +++ b/trunk/drivers/scsi/lpfc/lpfc_crtn.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -18,8 +18,6 @@ * included with this package. * *******************************************************************/ -typedef int (*node_filter)(struct lpfc_nodelist *ndlp, void *param); - struct fc_rport; void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t); void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *); @@ -45,24 +43,20 @@ void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *); -void lpfc_dequeue_node(struct lpfc_hba *, struct lpfc_nodelist *); -void lpfc_nlp_set_state(struct lpfc_hba *, struct lpfc_nodelist *, int); -void lpfc_drop_node(struct lpfc_hba *, struct lpfc_nodelist *); +int lpfc_nlp_list(struct lpfc_hba *, struct lpfc_nodelist *, int); void lpfc_set_disctmo(struct lpfc_hba *); int lpfc_can_disctmo(struct lpfc_hba *); int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *); int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *, struct lpfc_nodelist *); +int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *); void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t); -struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); -int lpfc_nlp_put(struct lpfc_nodelist *); struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t); void lpfc_disc_list_loopmap(struct lpfc_hba *); void lpfc_disc_start(struct lpfc_hba *); void lpfc_disc_flush_list(struct lpfc_hba *); void lpfc_disc_timeout(unsigned long); -struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); struct lpfc_nodelist *lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi); int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t); @@ -72,7 +66,8 @@ int lpfc_disc_state_machine(struct lpfc_hba *, struct lpfc_nodelist *, void *, int lpfc_check_sparm(struct lpfc_hba *, struct lpfc_nodelist *, struct serv_parm *, uint32_t); -int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp); +int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist * ndlp, + int); int lpfc_els_abort_flogi(struct lpfc_hba *); int lpfc_initial_flogi(struct lpfc_hba *); int lpfc_issue_els_plogi(struct lpfc_hba *, uint32_t, uint8_t); @@ -118,10 +113,7 @@ void lpfc_hba_init(struct lpfc_hba *, uint32_t *); int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); int lpfc_online(struct lpfc_hba *); -void lpfc_block_mgmt_io(struct lpfc_hba *); -void lpfc_unblock_mgmt_io(struct lpfc_hba *); -void lpfc_offline_prep(struct lpfc_hba *); -void lpfc_offline(struct lpfc_hba *); +int lpfc_offline(struct lpfc_hba *); int lpfc_sli_setup(struct lpfc_hba *); int lpfc_sli_queue_setup(struct lpfc_hba *); @@ -170,8 +162,8 @@ int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *, struct lpfc_sli_ring *, dma_addr_t); -int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, - struct lpfc_iocbq *); +int lpfc_sli_issue_abort_iotag32(struct lpfc_hba *, struct lpfc_sli_ring *, + struct lpfc_iocbq *); int lpfc_sli_sum_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, uint64_t, lpfc_ctx_cmd); int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, @@ -180,8 +172,9 @@ int lpfc_sli_abort_iocb(struct lpfc_hba *, struct lpfc_sli_ring *, uint16_t, void lpfc_mbox_timeout(unsigned long); void lpfc_mbox_timeout_handler(struct lpfc_hba *); -struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t); -struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, struct lpfc_name *); +struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_hba *, uint32_t, uint32_t); +struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_hba *, uint32_t, + struct lpfc_name *); int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, uint32_t timeout); @@ -200,9 +193,6 @@ void lpfc_mbuf_free(struct lpfc_hba *, void *, dma_addr_t); /* Function prototypes. */ const char* lpfc_info(struct Scsi_Host *); -void lpfc_scan_start(struct Scsi_Host *); -int lpfc_scan_finished(struct Scsi_Host *, unsigned long); - void lpfc_get_cfgparam(struct lpfc_hba *); int lpfc_alloc_sysfs_attr(struct lpfc_hba *); void lpfc_free_sysfs_attr(struct lpfc_hba *); diff --git a/trunk/drivers/scsi/lpfc/lpfc_ct.c b/trunk/drivers/scsi/lpfc/lpfc_ct.c index 34a9e3bb2614..a51a41b7f15d 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_ct.c +++ b/trunk/drivers/scsi/lpfc/lpfc_ct.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -334,22 +334,21 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) lpfc_set_disctmo(phba); + Cnt = Size > FCELSSIZE ? FCELSSIZE : Size; list_add_tail(&head, &mp->list); list_for_each_entry_safe(mp, next_mp, &head, list) { mlast = mp; - Cnt = Size > FCELSSIZE ? FCELSSIZE : Size; - Size -= Cnt; - if (!ctptr) { + if (!ctptr) ctptr = (uint32_t *) mlast->virt; - } else + else Cnt -= 16; /* subtract length of CT header */ /* Loop through entire NameServer list of DIDs */ - while (Cnt >= sizeof (uint32_t)) { + while (Cnt) { /* Get next DID from NameServer List */ CTentry = *ctptr++; @@ -443,8 +442,10 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { phba->fc_ns_retry++; /* CT command is being retried */ - ndlp = lpfc_findnode_did(phba, NameServer_DID); - if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { + ndlp = + lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, + NameServer_DID); + if (ndlp) { if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { goto out; @@ -728,7 +729,7 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; - ndlp = lpfc_findnode_did(phba, FDMI_DID); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { /* FDMI rsp failed */ lpfc_printf_log(phba, @@ -1038,9 +1039,6 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) case LA_4GHZ_LINK: ae->un.PortSpeed = HBA_PORTSPEED_4GBIT; break; - case LA_8GHZ_LINK: - ae->un.PortSpeed = HBA_PORTSPEED_8GBIT; - break; default: ae->un.PortSpeed = HBA_PORTSPEED_UNKNOWN; @@ -1163,7 +1161,7 @@ lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) { struct lpfc_nodelist *ndlp; - ndlp = lpfc_findnode_did(phba, FDMI_DID); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, FDMI_DID); if (ndlp) { if (init_utsname()->nodename[0] != '\0') { lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA); diff --git a/trunk/drivers/scsi/lpfc/lpfc_disc.h b/trunk/drivers/scsi/lpfc/lpfc_disc.h index 498059f3f7f4..9766f909c9c6 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_disc.h +++ b/trunk/drivers/scsi/lpfc/lpfc_disc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -31,7 +31,6 @@ /* worker thread events */ enum lpfc_work_type { LPFC_EVT_ONLINE, - LPFC_EVT_OFFLINE_PREP, LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL, @@ -69,6 +68,7 @@ struct lpfc_nodelist { uint16_t nlp_maxframe; /* Max RCV frame size */ uint8_t nlp_class_sup; /* Supported Classes */ uint8_t nlp_retry; /* used for ELS retries */ + uint8_t nlp_disc_refcnt; /* used for DSM */ uint8_t nlp_fcp_info; /* class info, bits 0-3 */ #define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ @@ -79,10 +79,20 @@ struct lpfc_nodelist { struct lpfc_work_evt els_retry_evt; unsigned long last_ramp_up_time; /* jiffy of last ramp up */ unsigned long last_q_full_time; /* jiffy of last queue full */ - struct kref kref; }; /* Defines for nlp_flag (uint32) */ +#define NLP_NO_LIST 0x0 /* Indicates immediately free node */ +#define NLP_UNUSED_LIST 0x1 /* Flg to indicate node will be freed */ +#define NLP_PLOGI_LIST 0x2 /* Flg to indicate sent PLOGI */ +#define NLP_ADISC_LIST 0x3 /* Flg to indicate sent ADISC */ +#define NLP_REGLOGIN_LIST 0x4 /* Flg to indicate sent REG_LOGIN */ +#define NLP_PRLI_LIST 0x5 /* Flg to indicate sent PRLI */ +#define NLP_UNMAPPED_LIST 0x6 /* Node is now unmapped */ +#define NLP_MAPPED_LIST 0x7 /* Node is now mapped */ +#define NLP_NPR_LIST 0x8 /* Node is in NPort Recovery state */ +#define NLP_JUST_DQ 0x9 /* just deque ndlp in lpfc_nlp_list */ +#define NLP_LIST_MASK 0xf /* mask to see what list node is on */ #define NLP_PLOGI_SND 0x20 /* sent PLOGI request for this entry */ #define NLP_PRLI_SND 0x40 /* sent PRLI request for this entry */ #define NLP_ADISC_SND 0x80 /* sent ADISC request for this entry */ @@ -98,8 +108,20 @@ struct lpfc_nodelist { ACC */ #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from NPR list */ +#define NLP_DELAY_REMOVE 0x4000000 /* Defer removal till end of DSM */ #define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ +/* Defines for list searchs */ +#define NLP_SEARCH_MAPPED 0x1 /* search mapped */ +#define NLP_SEARCH_UNMAPPED 0x2 /* search unmapped */ +#define NLP_SEARCH_PLOGI 0x4 /* search plogi */ +#define NLP_SEARCH_ADISC 0x8 /* search adisc */ +#define NLP_SEARCH_REGLOGIN 0x10 /* search reglogin */ +#define NLP_SEARCH_PRLI 0x20 /* search prli */ +#define NLP_SEARCH_NPR 0x40 /* search npr */ +#define NLP_SEARCH_UNUSED 0x80 /* search mapped */ +#define NLP_SEARCH_ALL 0xff /* search all lists */ + /* There are 4 different double linked lists nodelist entries can reside on. * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used * when Link Up discovery or Registered State Change Notification (RSCN) diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index 638b3cd677bd..a5f33a0dd4e7 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -182,7 +182,6 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64)); icmd->un.elsreq64.remoteID = did; /* DID */ icmd->ulpCommand = CMD_ELS_REQUEST64_CR; - icmd->ulpTimeout = phba->fc_ratov * 2; } else { icmd->un.elsreq64.bdl.bdeSize = sizeof (struct ulp_bde64); icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX; @@ -209,9 +208,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, } /* Save for completion so we can release these resources */ - elsiocb->context1 = lpfc_nlp_get(ndlp); - elsiocb->context2 = pcmd; - elsiocb->context3 = pbuflist; + elsiocb->context1 = (uint8_t *) ndlp; + elsiocb->context2 = (uint8_t *) pcmd; + elsiocb->context3 = (uint8_t *) pbuflist; elsiocb->retry = retry; elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT; @@ -223,16 +222,16 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, /* Xmit ELS command to remote NPORT */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0116 Xmit ELS command x%x to remote " - "NPORT x%x I/O tag: x%x, HBA state: x%x\n", + "NPORT x%x Data: x%x x%x\n", phba->brd_no, elscmd, - did, elsiocb->iotag, phba->hba_state); + did, icmd->ulpIoTag, phba->hba_state); } else { /* Xmit ELS response to remote NPORT */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0117 Xmit ELS response x%x to remote " - "NPORT x%x I/O tag: x%x, size: x%x\n", + "NPORT x%x Data: x%x x%x\n", phba->brd_no, elscmd, - ndlp->nlp_DID, elsiocb->iotag, cmdSize); + ndlp->nlp_DID, icmd->ulpIoTag, cmdSize); } return elsiocb; @@ -305,7 +304,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, goto fail_free_mbox; mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; - mbox->context2 = lpfc_nlp_get(ndlp); + mbox->context2 = ndlp; rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); if (rc == MBX_NOT_FINISHED) @@ -314,7 +313,6 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, return 0; fail_issue_reg_login: - lpfc_nlp_put(ndlp); mp = (struct lpfc_dmabuf *) mbox->context1; lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); @@ -370,9 +368,9 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto fail; } - lpfc_nlp_put(ndlp); + mempool_free(ndlp, phba->nlp_mem_pool); - ndlp = lpfc_findnode_did(phba, PT2PT_RemoteID); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, PT2PT_RemoteID); if (!ndlp) { /* * Cannot find existing Fabric ndlp, so allocate a @@ -389,11 +387,12 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, sizeof(struct lpfc_name)); memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof(struct lpfc_name)); - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); ndlp->nlp_flag |= NLP_NPR_2B_DISC; } else { /* This side will wait for the PLOGI */ - lpfc_nlp_put(ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); } spin_lock_irq(phba->host->host_lock); @@ -408,8 +407,8 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, } static void -lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_iocbq *rspiocb) +lpfc_cmpl_els_flogi(struct lpfc_hba * phba, + struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) { IOCB_t *irsp = &rspiocb->iocb; struct lpfc_nodelist *ndlp = cmdiocb->context1; @@ -419,7 +418,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(phba)) { - lpfc_nlp_put(ndlp); + lpfc_nlp_remove(phba, ndlp); goto out; } @@ -434,12 +433,13 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); spin_unlock_irq(phba->host->host_lock); - /* If private loop, then allow max outstanding els to be + /* If private loop, then allow max outstandting els to be * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no * alpa map would take too long otherwise. */ if (phba->alpa_map[0] == 0) { - phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; + phba->cfg_discovery_threads = + LPFC_MAX_DISC_THREADS; } /* FLOGI failure */ @@ -484,7 +484,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } flogifail: - lpfc_nlp_put(ndlp); + lpfc_nlp_remove(phba, ndlp); if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED && @@ -582,8 +582,24 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba) icmd = &iocb->iocb; if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) { ndlp = (struct lpfc_nodelist *)(iocb->context1); - if (ndlp && (ndlp->nlp_DID == Fabric_DID)) - lpfc_sli_issue_abort_iotag(phba, pring, iocb); + if (ndlp && (ndlp->nlp_DID == Fabric_DID)) { + list_del(&iocb->list); + pring->txcmplq_cnt--; + + if ((icmd->un.elsreq64.bdl.ulpIoTag32)) { + lpfc_sli_issue_abort_iotag32 + (phba, pring, iocb); + } + if (iocb->iocb_cmpl) { + icmd->ulpStatus = IOSTAT_LOCAL_REJECT; + icmd->un.ulpWord[4] = + IOERR_SLI_ABORTED; + spin_unlock_irq(phba->host->host_lock); + (iocb->iocb_cmpl) (phba, iocb, iocb); + spin_lock_irq(phba->host->host_lock); + } else + lpfc_sli_release_iocbq(phba, iocb); + } } } spin_unlock_irq(phba->host->host_lock); @@ -592,12 +608,12 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba) } int -lpfc_initial_flogi(struct lpfc_hba *phba) +lpfc_initial_flogi(struct lpfc_hba * phba) { struct lpfc_nodelist *ndlp; /* First look for the Fabric ndlp */ - ndlp = lpfc_findnode_did(phba, Fabric_DID); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, Fabric_DID); if (!ndlp) { /* Cannot find existing Fabric ndlp, so allocate a new one */ ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); @@ -605,10 +621,10 @@ lpfc_initial_flogi(struct lpfc_hba *phba) return 0; lpfc_nlp_init(phba, ndlp, Fabric_DID); } else { - lpfc_dequeue_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ); } if (lpfc_issue_els_flogi(phba, ndlp, 0)) { - lpfc_nlp_put(ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); } return 1; } @@ -637,7 +653,7 @@ lpfc_more_plogi(struct lpfc_hba * phba) } static struct lpfc_nodelist * -lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp, +lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, struct lpfc_nodelist *ndlp) { struct lpfc_nodelist *new_ndlp; @@ -654,12 +670,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp, lp = (uint32_t *) prsp->virt; sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); - memset(name, 0, sizeof(struct lpfc_name)); + memset(name, 0, sizeof (struct lpfc_name)); - /* Now we find out if the NPort we are logging into, matches the WWPN + /* Now we to find out if the NPort we are logging into, matches the WWPN * we have for that ndlp. If not, we have some work to do. */ - new_ndlp = lpfc_findnode_wwpn(phba, &sp->portName); + new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); if (new_ndlp == ndlp) return ndlp; @@ -679,15 +695,18 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp, lpfc_unreg_rpi(phba, new_ndlp); new_ndlp->nlp_DID = ndlp->nlp_DID; new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; - lpfc_nlp_set_state(phba, new_ndlp, ndlp->nlp_state); + new_ndlp->nlp_state = ndlp->nlp_state; + lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK); /* Move this back to NPR list */ - if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) - lpfc_drop_node(phba, ndlp); + if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } else { lpfc_unreg_rpi(phba, ndlp); ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); } return new_ndlp; } @@ -701,11 +720,13 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_dmabuf *prsp; int disc, rc, did, type; + /* we pass cmdiocb to state machine which needs rspiocb as well */ cmdiocb->context_un.rsp_iocb = rspiocb; irsp = &rspiocb->iocb; - ndlp = lpfc_findnode_did(phba, irsp->un.elsreq64.remoteID); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, + irsp->un.elsreq64.remoteID); if (!ndlp) goto out; @@ -1333,7 +1354,7 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, ndlp->nlp_DID, ELS_CMD_SCR); if (!elsiocb) { - lpfc_nlp_put(ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); return 1; } @@ -1352,12 +1373,12 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) spin_lock_irq(phba->host->host_lock); if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { spin_unlock_irq(phba->host->host_lock); - lpfc_nlp_put(ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); lpfc_els_free_iocb(phba, elsiocb); return 1; } spin_unlock_irq(phba->host->host_lock); - lpfc_nlp_put(ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); return 0; } @@ -1386,7 +1407,7 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, ndlp->nlp_DID, ELS_CMD_RNID); if (!elsiocb) { - lpfc_nlp_put(ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); return 1; } @@ -1407,7 +1428,7 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) memcpy(&fp->RportName, &phba->fc_portname, sizeof (struct lpfc_name)); memcpy(&fp->RnodeName, &phba->fc_nodename, sizeof (struct lpfc_name)); - if ((ondlp = lpfc_findnode_did(phba, nportid))) { + if ((ondlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, nportid))) { memcpy(&fp->OportName, &ondlp->nlp_portname, sizeof (struct lpfc_name)); memcpy(&fp->OnodeName, &ondlp->nlp_nodename, @@ -1419,12 +1440,12 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) spin_lock_irq(phba->host->host_lock); if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { spin_unlock_irq(phba->host->host_lock); - lpfc_nlp_put(ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); lpfc_els_free_iocb(phba, elsiocb); return 1; } spin_unlock_irq(phba->host->host_lock); - lpfc_nlp_put(ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); return 0; } @@ -1533,25 +1554,29 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) case ELS_CMD_PLOGI: if(!lpfc_issue_els_plogi(phba, ndlp->nlp_DID, retry)) { ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); } break; case ELS_CMD_ADISC: if (!lpfc_issue_els_adisc(phba, ndlp, retry)) { ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); + ndlp->nlp_state = NLP_STE_ADISC_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); } break; case ELS_CMD_PRLI: if (!lpfc_issue_els_prli(phba, ndlp, retry)) { ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE); + ndlp->nlp_state = NLP_STE_PRLI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); } break; case ELS_CMD_LOGO: if (!lpfc_issue_els_logo(phba, ndlp, retry)) { ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); } break; } @@ -1589,12 +1614,12 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, cmd = *elscmd++; } - if (ndlp) + if(ndlp) did = ndlp->nlp_DID; else { /* We should only hit this case for retrying PLOGI */ did = irsp->un.elsreq64.remoteID; - ndlp = lpfc_findnode_did(phba, did); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); if (!ndlp && (cmd != ELS_CMD_PLOGI)) return 1; } @@ -1721,7 +1746,8 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, ndlp->nlp_flag |= NLP_DELAY_TMO; ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); ndlp->nlp_last_elscmd = cmd; return 1; @@ -1733,24 +1759,27 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, case ELS_CMD_PLOGI: if (ndlp) { ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, - NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); } lpfc_issue_els_plogi(phba, did, cmdiocb->retry); return 1; case ELS_CMD_ADISC: ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); + ndlp->nlp_state = NLP_STE_ADISC_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry); return 1; case ELS_CMD_PRLI: ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE); + ndlp->nlp_state = NLP_STE_PRLI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry); return 1; case ELS_CMD_LOGO: ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry); return 1; } @@ -1767,14 +1796,10 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } int -lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) +lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb) { struct lpfc_dmabuf *buf_ptr, *buf_ptr1; - if (elsiocb->context1) { - lpfc_nlp_put(elsiocb->context1); - elsiocb->context1 = NULL; - } /* context2 = cmd, context2->next = rsp, context3 = bpl */ if (elsiocb->context2) { buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; @@ -1818,7 +1843,7 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, switch (ndlp->nlp_state) { case NLP_STE_UNUSED_NODE: /* node is just allocated */ - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); break; case NLP_STE_NPR_NODE: /* NPort Recovery mode */ lpfc_unreg_rpi(phba, ndlp); @@ -1831,8 +1856,8 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } static void -lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_iocbq *rspiocb) +lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, + struct lpfc_iocbq * rspiocb) { IOCB_t *irsp; struct lpfc_nodelist *ndlp; @@ -1847,14 +1872,14 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* Check to see if link went down during discovery */ - if (lpfc_els_chk_latt(phba) || !ndlp) { + if ((lpfc_els_chk_latt(phba)) || !ndlp) { if (mbox) { mp = (struct lpfc_dmabuf *) mbox->context1; if (mp) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); } - mempool_free(mbox, phba->mbox_mem_pool); + mempool_free( mbox, phba->mbox_mem_pool); } goto out; } @@ -1874,15 +1899,15 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { lpfc_unreg_rpi(phba, ndlp); mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; - mbox->context2 = lpfc_nlp_get(ndlp); + mbox->context2 = ndlp; ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); + ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST); if (lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { goto out; } - lpfc_nlp_put(ndlp); /* NOTE: we should have messages for unsuccessful reglogin */ } else { @@ -1892,7 +1917,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) { if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); ndlp = NULL; } } @@ -1987,16 +2012,15 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, return 1; } - if (newnode) { - lpfc_nlp_put(ndlp); + if (newnode) elsiocb->context1 = NULL; - } /* Xmit ELS ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0128 Xmit ELS ACC response tag x%x, XRI: x%x, " - "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n", - phba->brd_no, elsiocb->iotag, + "%d:0128 Xmit ELS ACC response tag x%x " + "Data: x%x x%x x%x x%x x%x\n", + phba->brd_no, + elsiocb->iocb.ulpIoTag, elsiocb->iocb.ulpContext, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); @@ -2053,9 +2077,10 @@ lpfc_els_rsp_reject(struct lpfc_hba * phba, uint32_t rejectError, /* Xmit ELS RJT response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0129 Xmit ELS RJT x%x response tag x%x xri x%x, " - "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n", - phba->brd_no, rejectError, elsiocb->iotag, + "%d:0129 Xmit ELS RJT x%x response tag x%x " + "Data: x%x x%x x%x x%x x%x\n", + phba->brd_no, + rejectError, elsiocb->iocb.ulpIoTag, elsiocb->iocb.ulpContext, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); @@ -2094,18 +2119,18 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, if (!elsiocb) return 1; - icmd = &elsiocb->iocb; - oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri */ - /* Xmit ADISC ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0130 Xmit ADISC ACC response iotag x%x xri: " - "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n", - phba->brd_no, elsiocb->iotag, + "%d:0130 Xmit ADISC ACC response tag x%x " + "Data: x%x x%x x%x x%x x%x\n", + phba->brd_no, + elsiocb->iocb.ulpIoTag, elsiocb->iocb.ulpContext, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); + icmd = &elsiocb->iocb; + oldcmd = &oldiocb->iocb; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = ELS_CMD_ACC; @@ -2130,8 +2155,8 @@ lpfc_els_rsp_adisc_acc(struct lpfc_hba * phba, } int -lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, - struct lpfc_nodelist *ndlp) +lpfc_els_rsp_prli_acc(struct lpfc_hba * phba, + struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp) { PRLI *npr; lpfc_vpd_t *vpd; @@ -2153,18 +2178,18 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, if (!elsiocb) return 1; - icmd = &elsiocb->iocb; - oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri */ - /* Xmit PRLI ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0131 Xmit PRLI ACC response tag x%x xri x%x, " - "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n", - phba->brd_no, elsiocb->iotag, + "%d:0131 Xmit PRLI ACC response tag x%x " + "Data: x%x x%x x%x x%x x%x\n", + phba->brd_no, + elsiocb->iocb.ulpIoTag, elsiocb->iocb.ulpContext, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); + icmd = &elsiocb->iocb; + oldcmd = &oldiocb->iocb; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)); @@ -2207,8 +2232,9 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, } static int -lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, - struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) +lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, + uint8_t format, + struct lpfc_iocbq * oldiocb, struct lpfc_nodelist * ndlp) { RNID *rn; IOCB_t *icmd; @@ -2233,17 +2259,17 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, if (!elsiocb) return 1; - icmd = &elsiocb->iocb; - oldcmd = &oldiocb->iocb; - icmd->ulpContext = oldcmd->ulpContext; /* Xri */ - /* Xmit RNID ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:0132 Xmit RNID ACC response tag x%x " - "xri x%x\n", - phba->brd_no, elsiocb->iotag, + "Data: x%x\n", + phba->brd_no, + elsiocb->iocb.ulpIoTag, elsiocb->iocb.ulpContext); + icmd = &elsiocb->iocb; + oldcmd = &oldiocb->iocb; + icmd->ulpContext = oldcmd->ulpContext; /* Xri */ pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); *((uint32_t *) (pcmd)) = ELS_CMD_ACC; @@ -2275,7 +2301,6 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, phba->fc_stat.elsXmitACC++; elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; - lpfc_nlp_put(ndlp); elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, * it could be freed */ @@ -2290,31 +2315,32 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, } int -lpfc_els_disc_adisc(struct lpfc_hba *phba) +lpfc_els_disc_adisc(struct lpfc_hba * phba) { int sentadisc; struct lpfc_nodelist *ndlp, *next_ndlp; sentadisc = 0; - /* go thru NPR nodes and issue any remaining ELS ADISCs */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state == NLP_STE_NPR_NODE && - (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && - (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) { - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - spin_unlock_irq(phba->host->host_lock); - ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); - lpfc_issue_els_adisc(phba, ndlp, 0); - sentadisc++; - phba->num_disc_nodes++; - if (phba->num_disc_nodes >= - phba->cfg_discovery_threads) { - spin_lock_irq(phba->host->host_lock); - phba->fc_flag |= FC_NLP_MORE; - spin_unlock_irq(phba->host->host_lock); - break; + /* go thru NPR list and issue any remaining ELS ADISCs */ + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, + nlp_listp) { + if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { + if (ndlp->nlp_flag & NLP_NPR_ADISC) { + ndlp->nlp_flag &= ~NLP_NPR_ADISC; + ndlp->nlp_prev_state = ndlp->nlp_state; + ndlp->nlp_state = NLP_STE_ADISC_ISSUE; + lpfc_nlp_list(phba, ndlp, + NLP_ADISC_LIST); + lpfc_issue_els_adisc(phba, ndlp, 0); + sentadisc++; + phba->num_disc_nodes++; + if (phba->num_disc_nodes >= + phba->cfg_discovery_threads) { + spin_lock_irq(phba->host->host_lock); + phba->fc_flag |= FC_NLP_MORE; + spin_unlock_irq(phba->host->host_lock); + break; + } } } } @@ -2334,22 +2360,24 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) sentplogi = 0; /* go thru NPR list and issue any remaining ELS PLOGIs */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state == NLP_STE_NPR_NODE && - (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && - (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 && - (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) { - ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); - lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); - sentplogi++; - phba->num_disc_nodes++; - if (phba->num_disc_nodes >= - phba->cfg_discovery_threads) { - spin_lock_irq(phba->host->host_lock); - phba->fc_flag |= FC_NLP_MORE; - spin_unlock_irq(phba->host->host_lock); - break; + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, + nlp_listp) { + if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && + (!(ndlp->nlp_flag & NLP_DELAY_TMO))) { + if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { + ndlp->nlp_prev_state = ndlp->nlp_state; + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); + lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); + sentplogi++; + phba->num_disc_nodes++; + if (phba->num_disc_nodes >= + phba->cfg_discovery_threads) { + spin_lock_irq(phba->host->host_lock); + phba->fc_flag |= FC_NLP_MORE; + spin_unlock_irq(phba->host->host_lock); + break; + } } } } @@ -2451,30 +2479,42 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) } static int -lpfc_rscn_recovery_check(struct lpfc_hba *phba) +lpfc_rscn_recovery_check(struct lpfc_hba * phba) { - struct lpfc_nodelist *ndlp = NULL; + struct lpfc_nodelist *ndlp = NULL, *next_ndlp; + struct list_head *listp; + struct list_head *node_list[7]; + int i; /* Look at all nodes effected by pending RSCNs and move - * them to NPR state. + * them to NPR list. */ - - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state == NLP_STE_UNUSED_NODE || - lpfc_rscn_payload_check(phba, ndlp->nlp_DID) == 0) + node_list[0] = &phba->fc_npr_list; /* MUST do this list first */ + node_list[1] = &phba->fc_nlpmap_list; + node_list[2] = &phba->fc_nlpunmap_list; + node_list[3] = &phba->fc_prli_list; + node_list[4] = &phba->fc_reglogin_list; + node_list[5] = &phba->fc_adisc_list; + node_list[6] = &phba->fc_plogi_list; + for (i = 0; i < 7; i++) { + listp = node_list[i]; + if (list_empty(listp)) continue; - lpfc_disc_state_machine(phba, ndlp, NULL, + list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { + if (!(lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) + continue; + + lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RECOVERY); - /* - * Make sure NLP_DELAY_TMO is NOT running after a device - * recovery event. - */ - if (ndlp->nlp_flag & NLP_DELAY_TMO) - lpfc_cancel_retry_delay_tmo(phba, ndlp); + /* Make sure NLP_DELAY_TMO is NOT running + * after a device recovery event. + */ + if (ndlp->nlp_flag & NLP_DELAY_TMO) + lpfc_cancel_retry_delay_tmo(phba, ndlp); + } } - return 0; } @@ -2599,8 +2639,8 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) /* To process RSCN, first compare RSCN data with NameServer */ phba->fc_ns_retry = 0; - ndlp = lpfc_findnode_did(phba, NameServer_DID); - if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, NameServer_DID); + if (ndlp) { /* Good ndlp, issue CT Request to NameServer */ if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { /* Wait for NameServer query cmpl before we can @@ -2610,7 +2650,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) } else { /* If login to NameServer does not exist, issue one */ /* Good status, issue PLOGI to NameServer */ - ndlp = lpfc_findnode_did(phba, NameServer_DID); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); if (ndlp) { /* Wait for NameServer login cmpl before we can continue */ @@ -2624,7 +2664,8 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) lpfc_nlp_init(phba, ndlp, NameServer_DID); ndlp->nlp_type |= NLP_FABRIC; ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_issue_els_plogi(phba, NameServer_DID, 0); /* Wait for NameServer login cmpl before we can continue */ @@ -2693,9 +2734,8 @@ lpfc_els_rcv_flogi(struct lpfc_hba * phba, mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; rc = lpfc_sli_issue_mbox (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)); - lpfc_set_loopback_flag(phba); if (rc == MBX_NOT_FINISHED) { - mempool_free(mbox, phba->mbox_mem_pool); + mempool_free( mbox, phba->mbox_mem_pool); } return 1; } else if (rc > 0) { /* greater than */ @@ -2760,8 +2800,8 @@ lpfc_els_rcv_rnid(struct lpfc_hba * phba, } static int -lpfc_els_rcv_lirr(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, - struct lpfc_nodelist *ndlp) +lpfc_els_rcv_lirr(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, + struct lpfc_nodelist * ndlp) { struct ls_rjt stat; @@ -2775,7 +2815,7 @@ lpfc_els_rcv_lirr(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } static void -lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) +lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { struct lpfc_sli *psli; struct lpfc_sli_ring *pring; @@ -2798,15 +2838,14 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) pmb->context2 = NULL; if (mb->mbxStatus) { - mempool_free(pmb, phba->mbox_mem_pool); + mempool_free( pmb, phba->mbox_mem_pool); return; } cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t); - mempool_free(pmb, phba->mbox_mem_pool); + mempool_free( pmb, phba->mbox_mem_pool); elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, ndlp->nlp_DID, ELS_CMD_ACC); - lpfc_nlp_put(ndlp); if (!elsiocb) return; @@ -2836,15 +2875,15 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) /* Xmit ELS RPS ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0118 Xmit ELS RPS ACC response tag x%x xri x%x, " - "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n", - phba->brd_no, elsiocb->iotag, + "%d:0118 Xmit ELS RPS ACC response tag x%x " + "Data: x%x x%x x%x x%x x%x\n", + phba->brd_no, + elsiocb->iocb.ulpIoTag, elsiocb->iocb.ulpContext, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; phba->fc_stat.elsXmitACC++; - if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { lpfc_els_free_iocb(phba, elsiocb); } @@ -2884,14 +2923,13 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, lpfc_read_lnk_stat(phba, mbox); mbox->context1 = (void *)((unsigned long)cmdiocb->iocb.ulpContext); - mbox->context2 = lpfc_nlp_get(ndlp); + mbox->context2 = ndlp; mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; if (lpfc_sli_issue_mbox (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { /* Mbox completion will send ELS Response */ return 0; } - lpfc_nlp_put(ndlp); mempool_free(mbox, phba->mbox_mem_pool); } } @@ -2946,9 +2984,10 @@ lpfc_els_rsp_rpl_acc(struct lpfc_hba * phba, uint16_t cmdsize, /* Xmit ELS RPL ACC response tag */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "%d:0120 Xmit ELS RPL ACC response tag x%x xri x%x, " - "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n", - phba->brd_no, elsiocb->iotag, + "%d:0120 Xmit ELS RPL ACC response tag x%x " + "Data: x%x x%x x%x x%x x%x\n", + phba->brd_no, + elsiocb->iocb.ulpIoTag, elsiocb->iocb.ulpContext, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); @@ -3052,8 +3091,8 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, /* Log back into the node before sending the FARP. */ if (fp->Rflags & FARP_REQUEST_PLOGI) { ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, - NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); } @@ -3130,15 +3169,14 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, */ list_for_each_entry_safe(ndlp, next_ndlp, - &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state != NLP_STE_NPR_NODE) - continue; + &phba->fc_npr_list, nlp_listp) { + if (ndlp->nlp_type & NLP_FABRIC) { /* * Clean up old Fabric, Nameserver and * other NLP_FABRIC logins */ - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { /* Fail outstanding I/O now since this * device is marked for PLOGI @@ -3155,22 +3193,20 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, /* Discovery not needed, * move the nodes to their original state. */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, - nlp_listp) { - if (ndlp->nlp_state != NLP_STE_NPR_NODE) - continue; + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, + nlp_listp) { switch (ndlp->nlp_prev_state) { case NLP_STE_UNMAPPED_NODE: ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(phba, ndlp, - NLP_STE_UNMAPPED_NODE); + ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); break; case NLP_STE_MAPPED_NODE: ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(phba, ndlp, - NLP_STE_MAPPED_NODE); + ndlp->nlp_state = NLP_STE_MAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); break; default: @@ -3210,8 +3246,9 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) struct lpfc_iocbq *tmp_iocb, *piocb; IOCB_t *cmd = NULL; struct lpfc_dmabuf *pcmd; + struct list_head *dlp; uint32_t *elscmd; - uint32_t els_command=0; + uint32_t els_command; uint32_t timeout; uint32_t remote_ID; @@ -3226,20 +3263,17 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) timeout = (uint32_t)(phba->fc_ratov << 1); pring = &phba->sli.ring[LPFC_ELS_RING]; + dlp = &pring->txcmplq; list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { cmd = &piocb->iocb; - if ((piocb->iocb_flag & LPFC_IO_LIBDFC) || - (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN) || - (piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)) { + if (piocb->iocb_flag & LPFC_IO_LIBDFC) { continue; } pcmd = (struct lpfc_dmabuf *) piocb->context2; - if (pcmd) { - elscmd = (uint32_t *) (pcmd->virt); - els_command = *elscmd; - } + elscmd = (uint32_t *) (pcmd->virt); + els_command = *elscmd; if ((els_command == ELS_CMD_FARP) || (els_command == ELS_CMD_FARPR)) { @@ -3255,10 +3289,19 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) continue; } + list_del(&piocb->list); + pring->txcmplq_cnt--; + if (cmd->ulpCommand == CMD_GEN_REQUEST64_CR) { struct lpfc_nodelist *ndlp; - ndlp = __lpfc_findnode_rpi(phba, cmd->ulpContext); + spin_unlock_irq(phba->host->host_lock); + ndlp = lpfc_findnode_rpi(phba, cmd->ulpContext); + spin_lock_irq(phba->host->host_lock); remote_ID = ndlp->nlp_DID; + if (cmd->un.elsreq64.bdl.ulpIoTag32) { + lpfc_sli_issue_abort_iotag32(phba, + pring, piocb); + } } else { remote_ID = cmd->un.elsreq64.remoteID; } @@ -3270,7 +3313,17 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) phba->brd_no, els_command, remote_ID, cmd->ulpCommand, cmd->ulpIoTag); - lpfc_sli_issue_abort_iotag(phba, pring, piocb); + /* + * The iocb has timed out; abort it. + */ + if (piocb->iocb_cmpl) { + cmd->ulpStatus = IOSTAT_LOCAL_REJECT; + cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; + spin_unlock_irq(phba->host->host_lock); + (piocb->iocb_cmpl) (phba, piocb, piocb); + spin_lock_irq(phba->host->host_lock); + } else + lpfc_sli_release_iocbq(phba, piocb); } if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); @@ -3279,13 +3332,16 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) } void -lpfc_els_flush_cmd(struct lpfc_hba *phba) +lpfc_els_flush_cmd(struct lpfc_hba * phba) { - LIST_HEAD(completions); - struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; + struct lpfc_sli_ring *pring; struct lpfc_iocbq *tmp_iocb, *piocb; IOCB_t *cmd = NULL; + struct lpfc_dmabuf *pcmd; + uint32_t *elscmd; + uint32_t els_command; + pring = &phba->sli.ring[LPFC_ELS_RING]; spin_lock_irq(phba->host->host_lock); list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { cmd = &piocb->iocb; @@ -3295,15 +3351,29 @@ lpfc_els_flush_cmd(struct lpfc_hba *phba) } /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */ - if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN || - cmd->ulpCommand == CMD_QUE_RING_BUF64_CN || - cmd->ulpCommand == CMD_CLOSE_XRI_CN || - cmd->ulpCommand == CMD_ABORT_XRI_CN) + if ((cmd->ulpCommand == CMD_QUE_RING_BUF_CN) || + (cmd->ulpCommand == CMD_QUE_RING_BUF64_CN) || + (cmd->ulpCommand == CMD_CLOSE_XRI_CN) || + (cmd->ulpCommand == CMD_ABORT_XRI_CN)) { continue; + } - list_move_tail(&piocb->list, &completions); - pring->txq_cnt--; + pcmd = (struct lpfc_dmabuf *) piocb->context2; + elscmd = (uint32_t *) (pcmd->virt); + els_command = *elscmd; + list_del(&piocb->list); + pring->txcmplq_cnt--; + + cmd->ulpStatus = IOSTAT_LOCAL_REJECT; + cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; + + if (piocb->iocb_cmpl) { + spin_unlock_irq(phba->host->host_lock); + (piocb->iocb_cmpl) (phba, piocb, piocb); + spin_lock_irq(phba->host->host_lock); + } else + lpfc_sli_release_iocbq(phba, piocb); } list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { @@ -3312,24 +3382,24 @@ lpfc_els_flush_cmd(struct lpfc_hba *phba) if (piocb->iocb_flag & LPFC_IO_LIBDFC) { continue; } + pcmd = (struct lpfc_dmabuf *) piocb->context2; + elscmd = (uint32_t *) (pcmd->virt); + els_command = *elscmd; - lpfc_sli_issue_abort_iotag(phba, pring, piocb); - } - spin_unlock_irq(phba->host->host_lock); - - while(!list_empty(&completions)) { - piocb = list_get_first(&completions, struct lpfc_iocbq, list); - cmd = &piocb->iocb; list_del(&piocb->list); + pring->txcmplq_cnt--; + + cmd->ulpStatus = IOSTAT_LOCAL_REJECT; + cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; if (piocb->iocb_cmpl) { - cmd->ulpStatus = IOSTAT_LOCAL_REJECT; - cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; + spin_unlock_irq(phba->host->host_lock); (piocb->iocb_cmpl) (phba, piocb, piocb); + spin_lock_irq(phba->host->host_lock); } else lpfc_sli_release_iocbq(phba, piocb); } - + spin_unlock_irq(phba->host->host_lock); return; } @@ -3398,7 +3468,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, } did = icmd->un.rcvels.remoteID; - ndlp = lpfc_findnode_did(phba, did); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); if (!ndlp) { /* Cannot find existing Fabric ndlp, so allocate a new one */ ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); @@ -3414,13 +3484,12 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { ndlp->nlp_type |= NLP_FABRIC; } - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); + ndlp->nlp_state = NLP_STE_UNUSED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); } phba->fc_stat.elsRcvFrame++; - if (elsiocb->context1) - lpfc_nlp_put(elsiocb->context1); - elsiocb->context1 = lpfc_nlp_get(ndlp); + elsiocb->context1 = ndlp; elsiocb->context2 = mp; if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) { @@ -3444,8 +3513,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, case ELS_CMD_FLOGI: phba->fc_stat.elsRcvFLOGI++; lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); - if (newnode) - lpfc_drop_node(phba, ndlp); + if (newnode) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } break; case ELS_CMD_LOGO: phba->fc_stat.elsRcvLOGO++; @@ -3466,8 +3536,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, case ELS_CMD_RSCN: phba->fc_stat.elsRcvRSCN++; lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); - if (newnode) - lpfc_drop_node(phba, ndlp); + if (newnode) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } break; case ELS_CMD_ADISC: phba->fc_stat.elsRcvADISC++; @@ -3508,26 +3579,30 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, case ELS_CMD_LIRR: phba->fc_stat.elsRcvLIRR++; lpfc_els_rcv_lirr(phba, elsiocb, ndlp); - if (newnode) - lpfc_drop_node(phba, ndlp); + if (newnode) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } break; case ELS_CMD_RPS: phba->fc_stat.elsRcvRPS++; lpfc_els_rcv_rps(phba, elsiocb, ndlp); - if (newnode) - lpfc_drop_node(phba, ndlp); + if (newnode) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } break; case ELS_CMD_RPL: phba->fc_stat.elsRcvRPL++; lpfc_els_rcv_rpl(phba, elsiocb, ndlp); - if (newnode) - lpfc_drop_node(phba, ndlp); + if (newnode) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } break; case ELS_CMD_RNID: phba->fc_stat.elsRcvRNID++; lpfc_els_rcv_rnid(phba, elsiocb, ndlp); - if (newnode) - lpfc_drop_node(phba, ndlp); + if (newnode) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } break; default: /* Unsupported ELS command, reject */ @@ -3537,8 +3612,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, lpfc_printf_log(phba, KERN_ERR, LOG_ELS, "%d:0115 Unknown ELS command x%x received from " "NPORT x%x\n", phba->brd_no, cmd, did); - if (newnode) - lpfc_drop_node(phba, ndlp); + if (newnode) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } break; } @@ -3551,8 +3627,6 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, lpfc_els_rsp_reject(phba, stat.un.lsRjtError, elsiocb, ndlp); } - lpfc_nlp_put(elsiocb->context1); - elsiocb->context1 = NULL; if (elsiocb->context2) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index 61caa8d379e2..c39564e85e94 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -109,9 +109,6 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) return; } - if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) - return; - name = (uint8_t *)&ndlp->nlp_portname; phba = ndlp->nlp_phba; @@ -150,17 +147,11 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) ndlp->nlp_state, ndlp->nlp_rpi); } - if (!(phba->fc_flag & FC_UNLOADING) && - !(ndlp->nlp_flag & NLP_DELAY_TMO) && - !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && - (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) + ndlp->rport = NULL; + rdata->pnode = NULL; + + if (!(phba->fc_flag & FC_UNLOADING)) lpfc_disc_state_machine(phba, ndlp, NULL, NLP_EVT_DEVICE_RM); - else { - rdata->pnode = NULL; - ndlp->rport = NULL; - lpfc_nlp_put(ndlp); - put_device(&rport->dev); - } return; } @@ -191,35 +182,29 @@ lpfc_work_list_done(struct lpfc_hba * phba) *(int *)(evtp->evt_arg1) = 0; complete((struct completion *)(evtp->evt_arg2)); break; - case LPFC_EVT_OFFLINE_PREP: - if (phba->hba_state >= LPFC_LINK_DOWN) - lpfc_offline_prep(phba); - *(int *)(evtp->evt_arg1) = 0; - complete((struct completion *)(evtp->evt_arg2)); - break; case LPFC_EVT_OFFLINE: - lpfc_offline(phba); + if (phba->hba_state >= LPFC_LINK_DOWN) + lpfc_offline(phba); lpfc_sli_brdrestart(phba); *(int *)(evtp->evt_arg1) = - lpfc_sli_brdready(phba, HS_FFRDY | HS_MBRDY); - lpfc_unblock_mgmt_io(phba); + lpfc_sli_brdready(phba,HS_FFRDY | HS_MBRDY); complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_WARM_START: - lpfc_offline(phba); + if (phba->hba_state >= LPFC_LINK_DOWN) + lpfc_offline(phba); lpfc_reset_barrier(phba); lpfc_sli_brdreset(phba); lpfc_hba_down_post(phba); *(int *)(evtp->evt_arg1) = lpfc_sli_brdready(phba, HS_MBRDY); - lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_KILL: - lpfc_offline(phba); + if (phba->hba_state >= LPFC_LINK_DOWN) + lpfc_offline(phba); *(int *)(evtp->evt_arg1) = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba); - lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; } @@ -374,12 +359,13 @@ lpfc_workq_post_event(struct lpfc_hba * phba, void *arg1, void *arg2, } int -lpfc_linkdown(struct lpfc_hba *phba) +lpfc_linkdown(struct lpfc_hba * phba) { struct lpfc_sli *psli; struct lpfc_nodelist *ndlp, *next_ndlp; - LPFC_MBOXQ_t *mb; - int rc; + struct list_head *listp, *node_list[7]; + LPFC_MBOXQ_t *mb; + int rc, i; psli = &phba->sli; /* sysfs or selective reset may call this routine to clean up */ @@ -411,16 +397,31 @@ lpfc_linkdown(struct lpfc_hba *phba) /* Cleanup any outstanding ELS commands */ lpfc_els_flush_cmd(phba); - /* - * Issue a LINK DOWN event to all nodes. - */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { - /* free any ndlp's on unused list */ - if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) - lpfc_drop_node(phba, ndlp); - else /* otherwise, force node recovery. */ + /* Issue a LINK DOWN event to all nodes */ + node_list[0] = &phba->fc_npr_list; /* MUST do this list first */ + node_list[1] = &phba->fc_nlpmap_list; + node_list[2] = &phba->fc_nlpunmap_list; + node_list[3] = &phba->fc_prli_list; + node_list[4] = &phba->fc_reglogin_list; + node_list[5] = &phba->fc_adisc_list; + node_list[6] = &phba->fc_plogi_list; + for (i = 0; i < 7; i++) { + listp = node_list[i]; + if (list_empty(listp)) + continue; + + list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { + rc = lpfc_disc_state_machine(phba, ndlp, NULL, - NLP_EVT_DEVICE_RECOVERY); + NLP_EVT_DEVICE_RECOVERY); + + } + } + + /* free any ndlp's on unused list */ + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list, + nlp_listp) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } /* Setup myDID for link up if we are in pt2pt mode */ @@ -451,9 +452,11 @@ lpfc_linkdown(struct lpfc_hba *phba) } static int -lpfc_linkup(struct lpfc_hba *phba) +lpfc_linkup(struct lpfc_hba * phba) { struct lpfc_nodelist *ndlp, *next_ndlp; + struct list_head *listp, *node_list[7]; + int i; fc_host_post_event(phba->host, fc_get_event_number(), FCH_EVT_LINKUP, 0); @@ -467,20 +470,29 @@ lpfc_linkup(struct lpfc_hba *phba) spin_unlock_irq(phba->host->host_lock); - if (phba->fc_flag & FC_LBIT) { - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) { + node_list[0] = &phba->fc_plogi_list; + node_list[1] = &phba->fc_adisc_list; + node_list[2] = &phba->fc_reglogin_list; + node_list[3] = &phba->fc_prli_list; + node_list[4] = &phba->fc_nlpunmap_list; + node_list[5] = &phba->fc_nlpmap_list; + node_list[6] = &phba->fc_npr_list; + for (i = 0; i < 7; i++) { + listp = node_list[i]; + if (list_empty(listp)) + continue; + + list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { + if (phba->fc_flag & FC_LBIT) { if (ndlp->nlp_type & NLP_FABRIC) { - /* - * On Linkup its safe to clean up the + /* On Linkup its safe to clean up the * ndlp from Fabric connections. */ - lpfc_nlp_set_state(phba, ndlp, - NLP_STE_UNUSED_NODE); + lpfc_nlp_list(phba, ndlp, + NLP_UNUSED_LIST); } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { - /* - * Fail outstanding IO now since - * device is marked for PLOGI. + /* Fail outstanding IO now since device + * is marked for PLOGI. */ lpfc_unreg_rpi(phba, ndlp); } @@ -489,10 +501,9 @@ lpfc_linkup(struct lpfc_hba *phba) } /* free any ndlp's on unused list */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, - nlp_listp) { - if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) - lpfc_drop_node(phba, ndlp); + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list, + nlp_listp) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } return 0; @@ -723,9 +734,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) case LA_4GHZ_LINK: phba->fc_linkspeed = LA_4GHZ_LINK; break; - case LA_8GHZ_LINK: - phba->fc_linkspeed = LA_8GHZ_LINK; - break; default: phba->fc_linkspeed = LA_UNKNW_LINK; break; @@ -881,21 +889,12 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) if (la->attType == AT_LINK_UP) { phba->fc_stat.LinkUp++; - if (phba->fc_flag & FC_LOOPBACK_MODE) { - lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, - "%d:1306 Link Up Event in loop back mode " - "x%x received Data: x%x x%x x%x x%x\n", - phba->brd_no, la->eventTag, phba->fc_eventTag, - la->granted_AL_PA, la->UlnkSpeed, - phba->alpa_map[0]); - } else { - lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, + lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, "%d:1303 Link Up Event x%x received " "Data: x%x x%x x%x x%x\n", phba->brd_no, la->eventTag, phba->fc_eventTag, la->granted_AL_PA, la->UlnkSpeed, phba->alpa_map[0]); - } lpfc_mbx_process_link_up(phba, la); } else { phba->fc_stat.LinkDown++; @@ -941,7 +940,6 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free( pmb, phba->mbox_mem_pool); - lpfc_nlp_put(ndlp); return; } @@ -968,14 +966,11 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ndlp = (struct lpfc_nodelist *) pmb->context2; mp = (struct lpfc_dmabuf *) (pmb->context1); - pmb->context1 = NULL; - pmb->context2 = NULL; - if (mb->mbxStatus) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); - mempool_free(pmb, phba->mbox_mem_pool); - lpfc_nlp_put(ndlp); + mempool_free( pmb, phba->mbox_mem_pool); + mempool_free( ndlp, phba->nlp_mem_pool); /* FLOGI failed, so just use loop map to make discovery list */ lpfc_disc_list_loopmap(phba); @@ -985,11 +980,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } + pmb->context1 = NULL; + ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_type |= NLP_FABRIC; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); - - lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ + ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { /* This NPort has been assigned an NPort_ID by the fabric as a @@ -1000,7 +996,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) */ lpfc_issue_els_scr(phba, SCR_DID, 0); - ndlp = lpfc_findnode_did(phba, NameServer_DID); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); if (!ndlp) { /* Allocate a new node instance. If the pool is empty, * start the discovery process and skip the Nameserver @@ -1012,14 +1008,15 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_disc_start(phba); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); - mempool_free(pmb, phba->mbox_mem_pool); + mempool_free( pmb, phba->mbox_mem_pool); return; } else { lpfc_nlp_init(phba, ndlp, NameServer_DID); ndlp->nlp_type |= NLP_FABRIC; } } - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_issue_els_plogi(phba, NameServer_DID, 0); if (phba->cfg_fdmi_on) { ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool, @@ -1035,7 +1032,7 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); - mempool_free(pmb, phba->mbox_mem_pool); + mempool_free( pmb, phba->mbox_mem_pool); return; } @@ -1060,11 +1057,10 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) mp = (struct lpfc_dmabuf *) (pmb->context1); if (mb->mbxStatus) { - lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); - mempool_free(pmb, phba->mbox_mem_pool); - lpfc_drop_node(phba, ndlp); + mempool_free( pmb, phba->mbox_mem_pool); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); /* RegLogin failed, so just use loop map to make discovery list */ @@ -1079,7 +1075,8 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_type |= NLP_FABRIC; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); + ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); if (phba->hba_state < LPFC_HBA_READY) { /* Link up discovery requires Fabrib registration. */ @@ -1096,7 +1093,6 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_disc_start(phba); } - lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free( pmb, phba->mbox_mem_pool); @@ -1105,7 +1101,8 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) } static void -lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) +lpfc_register_remote_port(struct lpfc_hba * phba, + struct lpfc_nodelist * ndlp) { struct fc_rport *rport; struct lpfc_rport_data *rdata; @@ -1117,19 +1114,8 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) rport_ids.port_id = ndlp->nlp_DID; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; - /* - * We leave our node pointer in rport->dd_data when we unregister a - * FCP target port. But fc_remote_port_add zeros the space to which - * rport->dd_data points. So, if we're reusing a previously - * registered port, drop the reference that we took the last time we - * registered the port. - */ - if (ndlp->rport && ndlp->rport->dd_data && - *(struct lpfc_rport_data **) ndlp->rport->dd_data) { - lpfc_nlp_put(ndlp); - } ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); - if (!rport || !get_device(&rport->dev)) { + if (!rport) { dev_printk(KERN_WARNING, &phba->pcidev->dev, "Warning: fc_remote_port_add failed\n"); return; @@ -1139,7 +1125,7 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) rport->maxframe_size = ndlp->nlp_maxframe; rport->supported_classes = ndlp->nlp_class_sup; rdata = rport->dd_data; - rdata->pnode = lpfc_nlp_get(ndlp); + rdata->pnode = ndlp; if (ndlp->nlp_type & NLP_FCP_TARGET) rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; @@ -1159,7 +1145,8 @@ lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) } static void -lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) +lpfc_unregister_remote_port(struct lpfc_hba * phba, + struct lpfc_nodelist * ndlp) { struct fc_rport *rport = ndlp->rport; struct lpfc_rport_data *rdata = rport->dd_data; @@ -1167,8 +1154,6 @@ lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) if (rport->scsi_target_id == -1) { ndlp->rport = NULL; rdata->pnode = NULL; - lpfc_nlp_put(ndlp); - put_device(&rport->dev); } fc_remote_port_delete(rport); @@ -1176,70 +1161,178 @@ lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) return; } -static void -lpfc_nlp_counters(struct lpfc_hba *phba, int state, int count) +int +lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) { + enum { none, unmapped, mapped } rport_add = none, rport_del = none; + struct lpfc_sli *psli; + + psli = &phba->sli; + /* Sanity check to ensure we are not moving to / from the same list */ + if ((nlp->nlp_flag & NLP_LIST_MASK) == list) + if (list != NLP_NO_LIST) + return 0; + spin_lock_irq(phba->host->host_lock); - switch (state) { - case NLP_STE_UNUSED_NODE: - phba->fc_unused_cnt += count; + switch (nlp->nlp_flag & NLP_LIST_MASK) { + case NLP_NO_LIST: /* Not on any list */ break; - case NLP_STE_PLOGI_ISSUE: - phba->fc_plogi_cnt += count; + case NLP_UNUSED_LIST: + phba->fc_unused_cnt--; + list_del(&nlp->nlp_listp); break; - case NLP_STE_ADISC_ISSUE: - phba->fc_adisc_cnt += count; + case NLP_PLOGI_LIST: + phba->fc_plogi_cnt--; + list_del(&nlp->nlp_listp); break; - case NLP_STE_REG_LOGIN_ISSUE: - phba->fc_reglogin_cnt += count; + case NLP_ADISC_LIST: + phba->fc_adisc_cnt--; + list_del(&nlp->nlp_listp); break; - case NLP_STE_PRLI_ISSUE: - phba->fc_prli_cnt += count; + case NLP_REGLOGIN_LIST: + phba->fc_reglogin_cnt--; + list_del(&nlp->nlp_listp); break; - case NLP_STE_UNMAPPED_NODE: - phba->fc_unmap_cnt += count; + case NLP_PRLI_LIST: + phba->fc_prli_cnt--; + list_del(&nlp->nlp_listp); break; - case NLP_STE_MAPPED_NODE: - phba->fc_map_cnt += count; + case NLP_UNMAPPED_LIST: + phba->fc_unmap_cnt--; + list_del(&nlp->nlp_listp); + nlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; + nlp->nlp_type &= ~NLP_FC_NODE; + phba->nport_event_cnt++; + if (nlp->rport) + rport_del = unmapped; break; - case NLP_STE_NPR_NODE: - phba->fc_npr_cnt += count; + case NLP_MAPPED_LIST: + phba->fc_map_cnt--; + list_del(&nlp->nlp_listp); + phba->nport_event_cnt++; + if (nlp->rport) + rport_del = mapped; + break; + case NLP_NPR_LIST: + phba->fc_npr_cnt--; + list_del(&nlp->nlp_listp); + /* Stop delay tmo if taking node off NPR list */ + if ((nlp->nlp_flag & NLP_DELAY_TMO) && + (list != NLP_NPR_LIST)) { + spin_unlock_irq(phba->host->host_lock); + lpfc_cancel_retry_delay_tmo(phba, nlp); + spin_lock_irq(phba->host->host_lock); + } break; } - spin_unlock_irq(phba->host->host_lock); -} -static void -lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, - int old_state, int new_state) -{ - if (new_state == NLP_STE_UNMAPPED_NODE) { - ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); - ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; - ndlp->nlp_type |= NLP_FC_NODE; - } - if (new_state == NLP_STE_MAPPED_NODE) - ndlp->nlp_flag &= ~NLP_NODEV_REMOVE; - if (new_state == NLP_STE_NPR_NODE) - ndlp->nlp_flag &= ~NLP_RCV_PLOGI; - - /* Transport interface */ - if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE || - old_state == NLP_STE_UNMAPPED_NODE)) { + nlp->nlp_flag &= ~NLP_LIST_MASK; + + /* Add NPort to list */ + lpfc_printf_log(phba, + KERN_INFO, + LOG_NODE, + "%d:0904 Add NPort x%x to %d list Data: x%x\n", + phba->brd_no, + nlp->nlp_DID, list, nlp->nlp_flag); + + switch (list) { + case NLP_NO_LIST: /* No list, just remove it */ + spin_unlock_irq(phba->host->host_lock); + lpfc_nlp_remove(phba, nlp); + spin_lock_irq(phba->host->host_lock); + /* as node removed - stop further transport calls */ + rport_del = none; + break; + case NLP_UNUSED_LIST: + nlp->nlp_flag |= list; + /* Put it at the end of the unused list */ + list_add_tail(&nlp->nlp_listp, &phba->fc_unused_list); + phba->fc_unused_cnt++; + break; + case NLP_PLOGI_LIST: + nlp->nlp_flag |= list; + /* Put it at the end of the plogi list */ + list_add_tail(&nlp->nlp_listp, &phba->fc_plogi_list); + phba->fc_plogi_cnt++; + break; + case NLP_ADISC_LIST: + nlp->nlp_flag |= list; + /* Put it at the end of the adisc list */ + list_add_tail(&nlp->nlp_listp, &phba->fc_adisc_list); + phba->fc_adisc_cnt++; + break; + case NLP_REGLOGIN_LIST: + nlp->nlp_flag |= list; + /* Put it at the end of the reglogin list */ + list_add_tail(&nlp->nlp_listp, &phba->fc_reglogin_list); + phba->fc_reglogin_cnt++; + break; + case NLP_PRLI_LIST: + nlp->nlp_flag |= list; + /* Put it at the end of the prli list */ + list_add_tail(&nlp->nlp_listp, &phba->fc_prli_list); + phba->fc_prli_cnt++; + break; + case NLP_UNMAPPED_LIST: + rport_add = unmapped; + /* ensure all vestiges of "mapped" significance are gone */ + nlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR); + nlp->nlp_flag |= list; + /* Put it at the end of the unmap list */ + list_add_tail(&nlp->nlp_listp, &phba->fc_nlpunmap_list); + phba->fc_unmap_cnt++; phba->nport_event_cnt++; - lpfc_unregister_remote_port(phba, ndlp); + nlp->nlp_flag &= ~NLP_NODEV_REMOVE; + nlp->nlp_type |= NLP_FC_NODE; + break; + case NLP_MAPPED_LIST: + rport_add = mapped; + nlp->nlp_flag |= list; + /* Put it at the end of the map list */ + list_add_tail(&nlp->nlp_listp, &phba->fc_nlpmap_list); + phba->fc_map_cnt++; + phba->nport_event_cnt++; + nlp->nlp_flag &= ~NLP_NODEV_REMOVE; + break; + case NLP_NPR_LIST: + nlp->nlp_flag |= list; + /* Put it at the end of the npr list */ + list_add_tail(&nlp->nlp_listp, &phba->fc_npr_list); + phba->fc_npr_cnt++; + + nlp->nlp_flag &= ~NLP_RCV_PLOGI; + break; + case NLP_JUST_DQ: + break; } - if (new_state == NLP_STE_MAPPED_NODE || - new_state == NLP_STE_UNMAPPED_NODE) { - phba->nport_event_cnt++; + spin_unlock_irq(phba->host->host_lock); + + /* + * We make all the calls into the transport after we have + * moved the node between lists. This so that we don't + * release the lock while in-between lists. + */ + + /* Don't upcall midlayer if we're unloading */ + if (!(phba->fc_flag & FC_UNLOADING)) { + /* + * We revalidate the rport pointer as the "add" function + * may have removed the remote port. + */ + if ((rport_del != none) && nlp->rport) + lpfc_unregister_remote_port(phba, nlp); + + if (rport_add != none) { /* * Tell the fc transport about the port, if we haven't * already. If we have, and it's a scsi entity, be * sure to unblock any attached scsi devices */ - lpfc_register_remote_port(phba, ndlp); - } + if ((!nlp->rport) || (nlp->rport->port_state == + FC_PORTSTATE_BLOCKED)) + lpfc_register_remote_port(phba, nlp); /* * if we added to Mapped list, but the remote port @@ -1247,95 +1340,19 @@ lpfc_nlp_state_cleanup(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, * our presentable range - move the node to the * Unmapped List */ - if (new_state == NLP_STE_MAPPED_NODE && - (!ndlp->rport || - ndlp->rport->scsi_target_id == -1 || - ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) { - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag |= NLP_TGT_NO_SCSIID; - spin_unlock_irq(phba->host->host_lock); - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); - } -} - -static char * -lpfc_nlp_state_name(char *buffer, size_t size, int state) -{ - static char *states[] = { - [NLP_STE_UNUSED_NODE] = "UNUSED", - [NLP_STE_PLOGI_ISSUE] = "PLOGI", - [NLP_STE_ADISC_ISSUE] = "ADISC", - [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN", - [NLP_STE_PRLI_ISSUE] = "PRLI", - [NLP_STE_UNMAPPED_NODE] = "UNMAPPED", - [NLP_STE_MAPPED_NODE] = "MAPPED", - [NLP_STE_NPR_NODE] = "NPR", - }; - - if (state < ARRAY_SIZE(states) && states[state]) - strlcpy(buffer, states[state], size); - else - snprintf(buffer, size, "unknown (%d)", state); - return buffer; -} - -void -lpfc_nlp_set_state(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, int state) -{ - int old_state = ndlp->nlp_state; - char name1[16], name2[16]; - - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d:0904 NPort state transition x%06x, %s -> %s\n", - phba->brd_no, - ndlp->nlp_DID, - lpfc_nlp_state_name(name1, sizeof(name1), old_state), - lpfc_nlp_state_name(name2, sizeof(name2), state)); - if (old_state == NLP_STE_NPR_NODE && - (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 && - state != NLP_STE_NPR_NODE) - lpfc_cancel_retry_delay_tmo(phba, ndlp); - if (old_state == NLP_STE_UNMAPPED_NODE) { - ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID; - ndlp->nlp_type &= ~NLP_FC_NODE; + if ((rport_add == mapped) && + ((!nlp->rport) || + (nlp->rport->scsi_target_id == -1) || + (nlp->rport->scsi_target_id >= LPFC_MAX_TARGET))) { + nlp->nlp_state = NLP_STE_UNMAPPED_NODE; + spin_lock_irq(phba->host->host_lock); + nlp->nlp_flag |= NLP_TGT_NO_SCSIID; + spin_unlock_irq(phba->host->host_lock); + lpfc_nlp_list(phba, nlp, NLP_UNMAPPED_LIST); + } + } } - - if (list_empty(&ndlp->nlp_listp)) { - spin_lock_irq(phba->host->host_lock); - list_add_tail(&ndlp->nlp_listp, &phba->fc_nodes); - spin_unlock_irq(phba->host->host_lock); - } else if (old_state) - lpfc_nlp_counters(phba, old_state, -1); - - ndlp->nlp_state = state; - lpfc_nlp_counters(phba, state, 1); - lpfc_nlp_state_cleanup(phba, ndlp, old_state, state); -} - -void -lpfc_dequeue_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) -{ - if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) - lpfc_cancel_retry_delay_tmo(phba, ndlp); - if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) - lpfc_nlp_counters(phba, ndlp->nlp_state, -1); - spin_lock_irq(phba->host->host_lock); - list_del_init(&ndlp->nlp_listp); - spin_unlock_irq(phba->host->host_lock); - lpfc_nlp_state_cleanup(phba, ndlp, ndlp->nlp_state, 0); -} - -void -lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) -{ - if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0) - lpfc_cancel_retry_delay_tmo(phba, ndlp); - if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp)) - lpfc_nlp_counters(phba, ndlp->nlp_state, -1); - spin_lock_irq(phba->host->host_lock); - list_del_init(&ndlp->nlp_listp); - spin_unlock_irq(phba->host->host_lock); - lpfc_nlp_put(ndlp); + return 0; } /* @@ -1447,7 +1464,6 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, static int lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) { - LIST_HEAD(completions); struct lpfc_sli *psli; struct lpfc_sli_ring *pring; struct lpfc_iocbq *iocb, *next_iocb; @@ -1476,29 +1492,29 @@ lpfc_no_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) (phba, pring, iocb, ndlp))) { /* It matches, so deque and call compl with an error */ - list_move_tail(&iocb->list, - &completions); + list_del(&iocb->list); pring->txq_cnt--; + if (iocb->iocb_cmpl) { + icmd = &iocb->iocb; + icmd->ulpStatus = + IOSTAT_LOCAL_REJECT; + icmd->un.ulpWord[4] = + IOERR_SLI_ABORTED; + spin_unlock_irq(phba->host-> + host_lock); + (iocb->iocb_cmpl) (phba, + iocb, iocb); + spin_lock_irq(phba->host-> + host_lock); + } else + lpfc_sli_release_iocbq(phba, + iocb); } } spin_unlock_irq(phba->host->host_lock); } } - - while (!list_empty(&completions)) { - iocb = list_get_first(&completions, struct lpfc_iocbq, list); - list_del(&iocb->list); - - if (iocb->iocb_cmpl) { - icmd = &iocb->iocb; - icmd->ulpStatus = IOSTAT_LOCAL_REJECT; - icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; - (iocb->iocb_cmpl) (phba, iocb, iocb); - } else - lpfc_sli_release_iocbq(phba, iocb); - } - return 0; } @@ -1538,7 +1554,7 @@ lpfc_unreg_rpi(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) * so it can be freed. */ static int -lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) +lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) { LPFC_MBOXQ_t *mb; LPFC_MBOXQ_t *nextmb; @@ -1551,7 +1567,17 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - lpfc_dequeue_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_JUST_DQ); + + /* + * if unloading the driver - just leave the remote port in place. + * The driver unload will force the attached devices to detach + * and flush cache's w/o generating flush errors. + */ + if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { + lpfc_unregister_remote_port(phba, ndlp); + ndlp->nlp_sid = NLP_NO_SID; + } /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ if ((mb = phba->sli.mbox_active)) { @@ -1573,12 +1599,11 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) } list_del(&mb->list); mempool_free(mb, phba->mbox_mem_pool); - lpfc_nlp_put(ndlp); } } spin_unlock_irq(phba->host->host_lock); - lpfc_els_abort(phba,ndlp); + lpfc_els_abort(phba,ndlp,0); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag &= ~NLP_DELAY_TMO; spin_unlock_irq(phba->host->host_lock); @@ -1599,27 +1624,27 @@ lpfc_cleanup_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) * If we are in the middle of using the nlp in the discovery state * machine, defer the free till we reach the end of the state machine. */ -static void -lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) +int +lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) { - struct lpfc_rport_data *rdata; if (ndlp->nlp_flag & NLP_DELAY_TMO) { lpfc_cancel_retry_delay_tmo(phba, ndlp); } - lpfc_cleanup_node(phba, ndlp); - - if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { - put_device(&ndlp->rport->dev); - rdata = ndlp->rport->dd_data; - rdata->pnode = NULL; - ndlp->rport = NULL; + if (ndlp->nlp_disc_refcnt) { + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag |= NLP_DELAY_REMOVE; + spin_unlock_irq(phba->host->host_lock); + } else { + lpfc_freenode(phba, ndlp); + mempool_free( ndlp, phba->nlp_mem_pool); } + return 0; } static int -lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) +lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) { D_ID mydid; D_ID ndlpdid; @@ -1668,36 +1693,57 @@ lpfc_matchdid(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) return 0; } -/* Search for a nodelist entry */ +/* Search for a nodelist entry on a specific list */ struct lpfc_nodelist * -lpfc_findnode_did(struct lpfc_hba *phba, uint32_t did) +lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) { struct lpfc_nodelist *ndlp; + struct list_head *lists[]={&phba->fc_nlpunmap_list, + &phba->fc_nlpmap_list, + &phba->fc_plogi_list, + &phba->fc_adisc_list, + &phba->fc_reglogin_list, + &phba->fc_prli_list, + &phba->fc_npr_list, + &phba->fc_unused_list}; + uint32_t search[]={NLP_SEARCH_UNMAPPED, + NLP_SEARCH_MAPPED, + NLP_SEARCH_PLOGI, + NLP_SEARCH_ADISC, + NLP_SEARCH_REGLOGIN, + NLP_SEARCH_PRLI, + NLP_SEARCH_NPR, + NLP_SEARCH_UNUSED}; + int i; uint32_t data1; spin_lock_irq(phba->host->host_lock); - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { - if (lpfc_matchdid(phba, ndlp, did)) { - data1 = (((uint32_t) ndlp->nlp_state << 24) | - ((uint32_t) ndlp->nlp_xri << 16) | - ((uint32_t) ndlp->nlp_type << 8) | - ((uint32_t) ndlp->nlp_rpi & 0xff)); - lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d:0929 FIND node DID " - " Data: x%p x%x x%x x%x\n", - phba->brd_no, - ndlp, ndlp->nlp_DID, - ndlp->nlp_flag, data1); - spin_unlock_irq(phba->host->host_lock); - return ndlp; + for (i = 0; i < ARRAY_SIZE(lists); i++ ) { + if (!(order & search[i])) + continue; + list_for_each_entry(ndlp, lists[i], nlp_listp) { + if (lpfc_matchdid(phba, ndlp, did)) { + data1 = (((uint32_t) ndlp->nlp_state << 24) | + ((uint32_t) ndlp->nlp_xri << 16) | + ((uint32_t) ndlp->nlp_type << 8) | + ((uint32_t) ndlp->nlp_rpi & 0xff)); + lpfc_printf_log(phba, KERN_INFO, LOG_NODE, + "%d:0929 FIND node DID " + " Data: x%p x%x x%x x%x\n", + phba->brd_no, + ndlp, ndlp->nlp_DID, + ndlp->nlp_flag, data1); + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } } } spin_unlock_irq(phba->host->host_lock); /* FIND node did NOT FOUND */ lpfc_printf_log(phba, KERN_INFO, LOG_NODE, - "%d:0932 FIND node did x%x NOT FOUND.\n", - phba->brd_no, did); + "%d:0932 FIND node did x%x NOT FOUND Data: x%x\n", + phba->brd_no, did, order); return NULL; } @@ -1705,8 +1751,9 @@ struct lpfc_nodelist * lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) { struct lpfc_nodelist *ndlp; + uint32_t flg; - ndlp = lpfc_findnode_did(phba, did); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); if (!ndlp) { if ((phba->fc_flag & FC_RSCN_MODE) && ((lpfc_rscn_payload_check(phba, did) == 0))) @@ -1716,7 +1763,8 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) if (!ndlp) return NULL; lpfc_nlp_init(phba, ndlp, did); - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); ndlp->nlp_flag |= NLP_NPR_2B_DISC; return ndlp; } @@ -1732,10 +1780,11 @@ lpfc_setup_disc_node(struct lpfc_hba * phba, uint32_t did) } else ndlp = NULL; } else { - if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE || - ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) + flg = ndlp->nlp_flag & NLP_LIST_MASK; + if ((flg == NLP_ADISC_LIST) || (flg == NLP_PLOGI_LIST)) return NULL; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); ndlp->nlp_flag |= NLP_NPR_2B_DISC; } return ndlp; @@ -1793,9 +1842,8 @@ lpfc_disc_start(struct lpfc_hba * phba) struct lpfc_sli *psli; LPFC_MBOXQ_t *mbox; struct lpfc_nodelist *ndlp, *next_ndlp; - uint32_t num_sent; + uint32_t did_changed, num_sent; uint32_t clear_la_pending; - int did_changed; int rc; psli = &phba->sli; @@ -1829,13 +1877,14 @@ lpfc_disc_start(struct lpfc_hba * phba) phba->fc_plogi_cnt, phba->fc_adisc_cnt); /* If our did changed, we MUST do PLOGI */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state == NLP_STE_NPR_NODE && - (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && - did_changed) { - spin_lock_irq(phba->host->host_lock); - ndlp->nlp_flag &= ~NLP_NPR_ADISC; - spin_unlock_irq(phba->host->host_lock); + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, + nlp_listp) { + if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { + if (did_changed) { + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_NPR_ADISC; + spin_unlock_irq(phba->host->host_lock); + } } } @@ -1895,11 +1944,11 @@ lpfc_disc_start(struct lpfc_hba * phba) static void lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) { - LIST_HEAD(completions); struct lpfc_sli *psli; IOCB_t *icmd; struct lpfc_iocbq *iocb, *next_iocb; struct lpfc_sli_ring *pring; + struct lpfc_dmabuf *mp; psli = &phba->sli; pring = &psli->ring[LPFC_ELS_RING]; @@ -1907,7 +1956,6 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) /* Error matching iocb on txq or txcmplq * First check the txq. */ - spin_lock_irq(phba->host->host_lock); list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { if (iocb->context1 != ndlp) { continue; @@ -1916,8 +1964,9 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { - list_move_tail(&iocb->list, &completions); + list_del(&iocb->list); pring->txq_cnt--; + lpfc_els_free_iocb(phba, iocb); } } @@ -1929,22 +1978,43 @@ lpfc_free_tx(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) icmd = &iocb->iocb; if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) || (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) { - lpfc_sli_issue_abort_iotag(phba, pring, iocb); - } - } - spin_unlock_irq(phba->host->host_lock); - while (!list_empty(&completions)) { - iocb = list_get_first(&completions, struct lpfc_iocbq, list); - list_del(&iocb->list); + iocb->iocb_cmpl = NULL; + /* context2 = cmd, context2->next = rsp, context3 = + bpl */ + if (iocb->context2) { + /* Free the response IOCB before handling the + command. */ + + mp = (struct lpfc_dmabuf *) (iocb->context2); + mp = list_get_first(&mp->list, + struct lpfc_dmabuf, + list); + if (mp) { + /* Delay before releasing rsp buffer to + * give UNREG mbox a chance to take + * effect. + */ + list_add(&mp->list, + &phba->freebufList); + } + lpfc_mbuf_free(phba, + ((struct lpfc_dmabuf *) + iocb->context2)->virt, + ((struct lpfc_dmabuf *) + iocb->context2)->phys); + kfree(iocb->context2); + } - if (iocb->iocb_cmpl) { - icmd = &iocb->iocb; - icmd->ulpStatus = IOSTAT_LOCAL_REJECT; - icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; - (iocb->iocb_cmpl) (phba, iocb, iocb); - } else - lpfc_sli_release_iocbq(phba, iocb); + if (iocb->context3) { + lpfc_mbuf_free(phba, + ((struct lpfc_dmabuf *) + iocb->context3)->virt, + ((struct lpfc_dmabuf *) + iocb->context3)->phys); + kfree(iocb->context3); + } + } } return; @@ -1955,16 +2025,21 @@ lpfc_disc_flush_list(struct lpfc_hba * phba) { struct lpfc_nodelist *ndlp, *next_ndlp; - if (phba->fc_plogi_cnt || phba->fc_adisc_cnt) { - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, - nlp_listp) { - if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE || - ndlp->nlp_state == NLP_STE_ADISC_ISSUE) { - lpfc_free_tx(phba, ndlp); - lpfc_nlp_put(ndlp); - } + if (phba->fc_plogi_cnt) { + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, + nlp_listp) { + lpfc_free_tx(phba, ndlp); + lpfc_nlp_remove(phba, ndlp); + } + } + if (phba->fc_adisc_cnt) { + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, + nlp_listp) { + lpfc_free_tx(phba, ndlp); + lpfc_nlp_remove(phba, ndlp); } } + return; } /*****************************************************************************/ @@ -2033,13 +2108,11 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) phba->brd_no); /* Start discovery by sending FLOGI, clean up old rpis */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, - nlp_listp) { - if (ndlp->nlp_state != NLP_STE_NPR_NODE) - continue; + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, + nlp_listp) { if (ndlp->nlp_type & NLP_FABRIC) { /* Clean up the ndlp on Fabric connections */ - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { /* Fail outstanding IO now since device * is marked for PLOGI. @@ -2080,9 +2153,9 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) "login\n", phba->brd_no); /* Next look for NameServer ndlp */ - ndlp = lpfc_findnode_did(phba, NameServer_DID); + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); if (ndlp) - lpfc_nlp_put(ndlp); + lpfc_nlp_remove(phba, ndlp); /* Start discovery */ lpfc_disc_start(phba); break; @@ -2095,8 +2168,9 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) phba->brd_no, phba->fc_ns_retry, LPFC_MAX_NS_RETRY); - ndlp = lpfc_findnode_did(phba, NameServer_DID); - if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { + ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, + NameServer_DID); + if (ndlp) { if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { /* Try it one more time */ rc = lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT); @@ -2146,7 +2220,6 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0; rc = lpfc_sli_issue_mbox(phba, initlinkmbox, (MBX_NOWAIT | MBX_STOP_IOCB)); - lpfc_set_loopback_flag(phba); if (rc == MBX_NOT_FINISHED) mempool_free(initlinkmbox, phba->mbox_mem_pool); @@ -2244,7 +2317,8 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_type |= NLP_FABRIC; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); + ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); /* Start issuing Fabric-Device Management Interface (FDMI) * command to 0xfffffa (FDMI well known port) @@ -2259,100 +2333,87 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); } - /* Mailbox took a reference to the node */ - lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); - mempool_free(pmb, phba->mbox_mem_pool); + mempool_free( pmb, phba->mbox_mem_pool); return; } -static int -lpfc_filter_by_rpi(struct lpfc_nodelist *ndlp, void *param) -{ - uint16_t *rpi = param; - - return ndlp->nlp_rpi == *rpi; -} - -static int -lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param) -{ - return memcmp(&ndlp->nlp_portname, param, - sizeof(ndlp->nlp_portname)) == 0; -} - -/* - * Search node lists for a remote port matching filter criteria - * Caller needs to hold host_lock before calling this routine. - */ -struct lpfc_nodelist * -__lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param) -{ - struct lpfc_nodelist *ndlp; - - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state != NLP_STE_UNUSED_NODE && - filter(ndlp, param)) - return ndlp; - } - return NULL; -} - /* - * Search node lists for a remote port matching filter criteria - * This routine is used when the caller does NOT have host_lock. + * This routine looks up the ndlp lists + * for the given RPI. If rpi found + * it return the node list pointer + * else return NULL. */ -struct lpfc_nodelist * -lpfc_find_node(struct lpfc_hba *phba, node_filter filter, void *param) -{ - struct lpfc_nodelist *ndlp; - - spin_lock_irq(phba->host->host_lock); - ndlp = __lpfc_find_node(phba, filter, param); - spin_unlock_irq(phba->host->host_lock); - return ndlp; -} - -/* - * This routine looks up the ndlp lists for the given RPI. If rpi found it - * returns the node list pointer else return NULL. - */ -struct lpfc_nodelist * -__lpfc_findnode_rpi(struct lpfc_hba *phba, uint16_t rpi) -{ - return __lpfc_find_node(phba, lpfc_filter_by_rpi, &rpi); -} - struct lpfc_nodelist * lpfc_findnode_rpi(struct lpfc_hba * phba, uint16_t rpi) { struct lpfc_nodelist *ndlp; + struct list_head * lists[]={&phba->fc_nlpunmap_list, + &phba->fc_nlpmap_list, + &phba->fc_plogi_list, + &phba->fc_adisc_list, + &phba->fc_reglogin_list}; + int i; spin_lock_irq(phba->host->host_lock); - ndlp = __lpfc_findnode_rpi(phba, rpi); + for (i = 0; i < ARRAY_SIZE(lists); i++ ) + list_for_each_entry(ndlp, lists[i], nlp_listp) + if (ndlp->nlp_rpi == rpi) { + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } spin_unlock_irq(phba->host->host_lock); - return ndlp; + return NULL; } /* - * This routine looks up the ndlp lists for the given WWPN. If WWPN found it - * returns the node list pointer else return NULL. + * This routine looks up the ndlp lists + * for the given WWPN. If WWPN found + * it return the node list pointer + * else return NULL. */ struct lpfc_nodelist * -lpfc_findnode_wwpn(struct lpfc_hba *phba, struct lpfc_name *wwpn) +lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order, + struct lpfc_name * wwpn) { struct lpfc_nodelist *ndlp; + struct list_head * lists[]={&phba->fc_nlpunmap_list, + &phba->fc_nlpmap_list, + &phba->fc_npr_list, + &phba->fc_plogi_list, + &phba->fc_adisc_list, + &phba->fc_reglogin_list, + &phba->fc_prli_list}; + uint32_t search[]={NLP_SEARCH_UNMAPPED, + NLP_SEARCH_MAPPED, + NLP_SEARCH_NPR, + NLP_SEARCH_PLOGI, + NLP_SEARCH_ADISC, + NLP_SEARCH_REGLOGIN, + NLP_SEARCH_PRLI}; + int i; spin_lock_irq(phba->host->host_lock); - ndlp = __lpfc_find_node(phba, lpfc_filter_by_wwpn, wwpn); + for (i = 0; i < ARRAY_SIZE(lists); i++ ) { + if (!(order & search[i])) + continue; + list_for_each_entry(ndlp, lists[i], nlp_listp) { + if (memcmp(&ndlp->nlp_portname, wwpn, + sizeof(struct lpfc_name)) == 0) { + spin_unlock_irq(phba->host->host_lock); + return ndlp; + } + } + } spin_unlock_irq(phba->host->host_lock); return NULL; } void -lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) +lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, + uint32_t did) { memset(ndlp, 0, sizeof (struct lpfc_nodelist)); INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); @@ -2362,30 +2423,5 @@ lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) ndlp->nlp_DID = did; ndlp->nlp_phba = phba; ndlp->nlp_sid = NLP_NO_SID; - INIT_LIST_HEAD(&ndlp->nlp_listp); - kref_init(&ndlp->kref); return; } - -void -lpfc_nlp_release(struct kref *kref) -{ - struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, - kref); - lpfc_nlp_remove(ndlp->nlp_phba, ndlp); - mempool_free(ndlp, ndlp->nlp_phba->nlp_mem_pool); -} - -struct lpfc_nodelist * -lpfc_nlp_get(struct lpfc_nodelist *ndlp) -{ - if (ndlp) - kref_get(&ndlp->kref); - return ndlp; -} - -int -lpfc_nlp_put(struct lpfc_nodelist *ndlp) -{ - return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0; -} diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw.h b/trunk/drivers/scsi/lpfc/lpfc_hw.h index 2623a9bc7775..f79cb6136906 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -1078,8 +1078,6 @@ typedef struct { /* Start FireFly Register definitions */ #define PCI_VENDOR_ID_EMULEX 0x10df #define PCI_DEVICE_ID_FIREFLY 0x1ae5 -#define PCI_DEVICE_ID_SAT_SMB 0xf011 -#define PCI_DEVICE_ID_SAT_MID 0xf015 #define PCI_DEVICE_ID_RFLY 0xf095 #define PCI_DEVICE_ID_PFLY 0xf098 #define PCI_DEVICE_ID_LP101 0xf0a1 @@ -1091,9 +1089,6 @@ typedef struct { #define PCI_DEVICE_ID_NEPTUNE 0xf0f5 #define PCI_DEVICE_ID_NEPTUNE_SCSP 0xf0f6 #define PCI_DEVICE_ID_NEPTUNE_DCSP 0xf0f7 -#define PCI_DEVICE_ID_SAT 0xf100 -#define PCI_DEVICE_ID_SAT_SCSP 0xf111 -#define PCI_DEVICE_ID_SAT_DCSP 0xf112 #define PCI_DEVICE_ID_SUPERFLY 0xf700 #define PCI_DEVICE_ID_DRAGONFLY 0xf800 #define PCI_DEVICE_ID_CENTAUR 0xf900 @@ -1103,7 +1098,6 @@ typedef struct { #define PCI_DEVICE_ID_LP10000S 0xfc00 #define PCI_DEVICE_ID_LP11000S 0xfc10 #define PCI_DEVICE_ID_LPE11000S 0xfc20 -#define PCI_DEVICE_ID_SAT_S 0xfc40 #define PCI_DEVICE_ID_HELIOS 0xfd00 #define PCI_DEVICE_ID_HELIOS_SCSP 0xfd11 #define PCI_DEVICE_ID_HELIOS_DCSP 0xfd12 @@ -1124,7 +1118,6 @@ typedef struct { #define HELIOS_JEDEC_ID 0x0364 #define ZEPHYR_JEDEC_ID 0x0577 #define VIPER_JEDEC_ID 0x4838 -#define SATURN_JEDEC_ID 0x1004 #define JEDEC_ID_MASK 0x0FFFF000 #define JEDEC_ID_SHIFT 12 @@ -1572,7 +1565,7 @@ typedef struct { #define LINK_SPEED_1G 1 /* 1 Gigabaud */ #define LINK_SPEED_2G 2 /* 2 Gigabaud */ #define LINK_SPEED_4G 4 /* 4 Gigabaud */ -#define LINK_SPEED_8G 8 /* 8 Gigabaud */ +#define LINK_SPEED_8G 8 /* 4 Gigabaud */ #define LINK_SPEED_10G 16 /* 10 Gigabaud */ } INIT_LINK_VAR; diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index dcb4ba0ecee1..057fd7e0e379 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -386,12 +386,12 @@ lpfc_config_port_post(struct lpfc_hba * phba) * Setup the ring 0 (els) timeout handler */ timeout = phba->fc_ratov << 1; - mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); + phba->els_tmofunc.expires = jiffies + HZ * timeout; + add_timer(&phba->els_tmofunc); lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); - lpfc_set_loopback_flag(phba); if (rc != MBX_SUCCESS) { lpfc_printf_log(phba, KERN_ERR, @@ -418,6 +418,33 @@ lpfc_config_port_post(struct lpfc_hba * phba) return (0); } +static int +lpfc_discovery_wait(struct lpfc_hba *phba) +{ + int i = 0; + + while ((phba->hba_state != LPFC_HBA_READY) || + (phba->num_disc_nodes) || (phba->fc_prli_sent) || + ((phba->fc_map_cnt == 0) && (i<2)) || + (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) { + /* Check every second for 30 retries. */ + i++; + if (i > 30) { + return -ETIMEDOUT; + } + if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) { + /* The link is down. Set linkdown timeout */ + return -ETIMEDOUT; + } + + /* Delay for 1 second to give discovery time to complete. */ + msleep(1000); + + } + + return 0; +} + /************************************************************************/ /* */ /* lpfc_hba_down_prep */ @@ -523,15 +550,12 @@ lpfc_handle_eratt(struct lpfc_hba * phba) * There was a firmware error. Take the hba offline and then * attempt to restart it. */ - lpfc_offline_prep(phba); lpfc_offline(phba); lpfc_sli_brdrestart(phba); if (lpfc_online(phba) == 0) { /* Initialize the HBA */ mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); - lpfc_unblock_mgmt_io(phba); return; } - lpfc_unblock_mgmt_io(phba); } else { /* The if clause above forces this code path when the status * failure is a value other than FFER6. Do not call the offline @@ -549,9 +573,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba) SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX); psli->sli_flag &= ~LPFC_SLI2_ACTIVE; - lpfc_offline_prep(phba); lpfc_offline(phba); - lpfc_unblock_mgmt_io(phba); phba->hba_state = LPFC_HBA_ERROR; lpfc_hba_down_post(phba); } @@ -611,7 +633,7 @@ lpfc_handle_latt(struct lpfc_hba * phba) lpfc_handle_latt_free_mp: kfree(mp); lpfc_handle_latt_free_pmb: - mempool_free(pmb, phba->mbox_mem_pool); + kfree(pmb); lpfc_handle_latt_err_exit: /* Enable Link attention interrupts */ spin_lock_irq(phba->host->host_lock); @@ -649,7 +671,7 @@ static int lpfc_parse_vpd(struct lpfc_hba * phba, uint8_t * vpd, int len) { uint8_t lenlo, lenhi; - int Length; + uint32_t Length; int i, j; int finished = 0; int index = 0; @@ -903,24 +925,6 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) m = (typeof(m)){"LPe11000-S", max_speed, "PCIe"}; break; - case PCI_DEVICE_ID_SAT: - m = (typeof(m)){"LPe12000", max_speed, "PCIe"}; - break; - case PCI_DEVICE_ID_SAT_MID: - m = (typeof(m)){"LPe1250", max_speed, "PCIe"}; - break; - case PCI_DEVICE_ID_SAT_SMB: - m = (typeof(m)){"LPe121", max_speed, "PCIe"}; - break; - case PCI_DEVICE_ID_SAT_DCSP: - m = (typeof(m)){"LPe12002-SP", max_speed, "PCIe"}; - break; - case PCI_DEVICE_ID_SAT_SCSP: - m = (typeof(m)){"LPe12000-SP", max_speed, "PCIe"}; - break; - case PCI_DEVICE_ID_SAT_S: - m = (typeof(m)){"LPe12000-S", max_speed, "PCIe"}; - break; default: m = (typeof(m)){ NULL }; break; @@ -1170,17 +1174,69 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) } static void -lpfc_cleanup(struct lpfc_hba * phba) +lpfc_cleanup(struct lpfc_hba * phba, uint32_t save_bind) { struct lpfc_nodelist *ndlp, *next_ndlp; /* clean up phba - lpfc specific */ lpfc_can_disctmo(phba); - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) - lpfc_nlp_put(ndlp); + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, + nlp_listp) { + lpfc_nlp_remove(phba, ndlp); + } - INIT_LIST_HEAD(&phba->fc_nodes); + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list, + nlp_listp) { + lpfc_nlp_remove(phba, ndlp); + } + + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list, + nlp_listp) { + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + } + + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, + nlp_listp) { + lpfc_nlp_remove(phba, ndlp); + } + + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, + nlp_listp) { + lpfc_nlp_remove(phba, ndlp); + } + + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_reglogin_list, + nlp_listp) { + lpfc_nlp_remove(phba, ndlp); + } + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list, + nlp_listp) { + lpfc_nlp_remove(phba, ndlp); + } + + list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, + nlp_listp) { + lpfc_nlp_remove(phba, ndlp); + } + + INIT_LIST_HEAD(&phba->fc_nlpmap_list); + INIT_LIST_HEAD(&phba->fc_nlpunmap_list); + INIT_LIST_HEAD(&phba->fc_unused_list); + INIT_LIST_HEAD(&phba->fc_plogi_list); + INIT_LIST_HEAD(&phba->fc_adisc_list); + INIT_LIST_HEAD(&phba->fc_reglogin_list); + INIT_LIST_HEAD(&phba->fc_prli_list); + INIT_LIST_HEAD(&phba->fc_npr_list); + + phba->fc_map_cnt = 0; + phba->fc_unmap_cnt = 0; + phba->fc_plogi_cnt = 0; + phba->fc_adisc_cnt = 0; + phba->fc_reglogin_cnt = 0; + phba->fc_prli_cnt = 0; + phba->fc_npr_cnt = 0; + phba->fc_unused_cnt= 0; return; } @@ -1206,6 +1262,21 @@ lpfc_stop_timer(struct lpfc_hba * phba) { struct lpfc_sli *psli = &phba->sli; + /* Instead of a timer, this has been converted to a + * deferred procedding list. + */ + while (!list_empty(&phba->freebufList)) { + + struct lpfc_dmabuf *mp = NULL; + + list_remove_head((&phba->freebufList), mp, + struct lpfc_dmabuf, list); + if (mp) { + lpfc_mbuf_free(phba, mp->virt, mp->phys); + kfree(mp); + } + } + del_timer_sync(&phba->fcp_poll_timer); del_timer_sync(&phba->fc_estabtmo); del_timer_sync(&phba->fc_disctmo); @@ -1231,76 +1302,60 @@ lpfc_online(struct lpfc_hba * phba) "%d:0458 Bring Adapter online\n", phba->brd_no); - lpfc_block_mgmt_io(phba); - - if (!lpfc_sli_queue_setup(phba)) { - lpfc_unblock_mgmt_io(phba); + if (!lpfc_sli_queue_setup(phba)) return 1; - } - if (lpfc_sli_hba_setup(phba)) { /* Initialize the HBA */ - lpfc_unblock_mgmt_io(phba); + if (lpfc_sli_hba_setup(phba)) /* Initialize the HBA */ return 1; - } spin_lock_irq(phba->host->host_lock); phba->fc_flag &= ~FC_OFFLINE_MODE; spin_unlock_irq(phba->host->host_lock); - lpfc_unblock_mgmt_io(phba); return 0; } -void -lpfc_block_mgmt_io(struct lpfc_hba * phba) -{ - unsigned long iflag; - - spin_lock_irqsave(phba->host->host_lock, iflag); - phba->fc_flag |= FC_BLOCK_MGMT_IO; - spin_unlock_irqrestore(phba->host->host_lock, iflag); -} - -void -lpfc_unblock_mgmt_io(struct lpfc_hba * phba) +int +lpfc_offline(struct lpfc_hba * phba) { + struct lpfc_sli_ring *pring; + struct lpfc_sli *psli; unsigned long iflag; + int i; + int cnt = 0; - spin_lock_irqsave(phba->host->host_lock, iflag); - phba->fc_flag &= ~FC_BLOCK_MGMT_IO; - spin_unlock_irqrestore(phba->host->host_lock, iflag); -} - -void -lpfc_offline_prep(struct lpfc_hba * phba) -{ - struct lpfc_nodelist *ndlp, *next_ndlp; + if (!phba) + return 0; if (phba->fc_flag & FC_OFFLINE_MODE) - return; + return 0; - lpfc_block_mgmt_io(phba); + psli = &phba->sli; lpfc_linkdown(phba); - - /* Issue an unreg_login to all nodes */ - list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) - if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) - lpfc_unreg_rpi(phba, ndlp); - lpfc_sli_flush_mbox_queue(phba); -} -void -lpfc_offline(struct lpfc_hba * phba) -{ - unsigned long iflag; + for (i = 0; i < psli->num_rings; i++) { + pring = &psli->ring[i]; + /* The linkdown event takes 30 seconds to timeout. */ + while (pring->txcmplq_cnt) { + mdelay(10); + if (cnt++ > 3000) { + lpfc_printf_log(phba, + KERN_WARNING, LOG_INIT, + "%d:0466 Outstanding IO when " + "bringing Adapter offline\n", + phba->brd_no); + break; + } + } + } - if (phba->fc_flag & FC_OFFLINE_MODE) - return; /* stop all timers associated with this hba */ lpfc_stop_timer(phba); + phba->work_hba_events = 0; + phba->work_ha = 0; lpfc_printf_log(phba, KERN_WARNING, @@ -1311,12 +1366,11 @@ lpfc_offline(struct lpfc_hba * phba) /* Bring down the SLI Layer and cleanup. The HBA is offline now. */ lpfc_sli_hba_down(phba); - lpfc_cleanup(phba); + lpfc_cleanup(phba, 1); spin_lock_irqsave(phba->host->host_lock, iflag); - phba->work_hba_events = 0; - phba->work_ha = 0; phba->fc_flag |= FC_OFFLINE_MODE; spin_unlock_irqrestore(phba->host->host_lock, iflag); + return 0; } /****************************************************************************** @@ -1353,156 +1407,6 @@ lpfc_scsi_free(struct lpfc_hba * phba) return 0; } -void lpfc_remove_device(struct lpfc_hba *phba) -{ - unsigned long iflag; - - lpfc_free_sysfs_attr(phba); - - spin_lock_irqsave(phba->host->host_lock, iflag); - phba->fc_flag |= FC_UNLOADING; - - spin_unlock_irqrestore(phba->host->host_lock, iflag); - - fc_remove_host(phba->host); - scsi_remove_host(phba->host); - - kthread_stop(phba->worker_thread); - - /* - * Bring down the SLI Layer. This step disable all interrupts, - * clears the rings, discards all mailbox commands, and resets - * the HBA. - */ - lpfc_sli_hba_down(phba); - lpfc_sli_brdrestart(phba); - - /* Release the irq reservation */ - free_irq(phba->pcidev->irq, phba); - pci_disable_msi(phba->pcidev); - - lpfc_cleanup(phba); - lpfc_stop_timer(phba); - phba->work_hba_events = 0; - - /* - * Call scsi_free before mem_free since scsi bufs are released to their - * corresponding pools here. - */ - lpfc_scsi_free(phba); - lpfc_mem_free(phba); - - /* Free resources associated with SLI2 interface */ - dma_free_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE, - phba->slim2p, phba->slim2p_mapping); - - /* unmap adapter SLIM and Control Registers */ - iounmap(phba->ctrl_regs_memmap_p); - iounmap(phba->slim_memmap_p); - - pci_release_regions(phba->pcidev); - pci_disable_device(phba->pcidev); - - idr_remove(&lpfc_hba_index, phba->brd_no); - scsi_host_put(phba->host); -} - -void lpfc_scan_start(struct Scsi_Host *host) -{ - struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - - if (lpfc_alloc_sysfs_attr(phba)) - goto error; - - phba->MBslimaddr = phba->slim_memmap_p; - phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET; - phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET; - phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; - phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; - - if (lpfc_sli_hba_setup(phba)) - goto error; - - /* - * hba setup may have changed the hba_queue_depth so we need to adjust - * the value of can_queue. - */ - host->can_queue = phba->cfg_hba_queue_depth - 10; - return; - -error: - lpfc_remove_device(phba); -} - -int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) -{ - struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; - - if (!phba->host) - return 1; - if (time >= 30 * HZ) - goto finished; - - if (phba->hba_state != LPFC_HBA_READY) - return 0; - if (phba->num_disc_nodes || phba->fc_prli_sent) - return 0; - if ((phba->fc_map_cnt == 0) && (time < 2 * HZ)) - return 0; - if (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) - return 0; - if ((phba->hba_state > LPFC_LINK_DOWN) || (time < 15 * HZ)) - return 0; - -finished: - if (phba->cfg_poll & DISABLE_FCP_RING_INT) { - spin_lock_irq(shost->host_lock); - lpfc_poll_start_timer(phba); - spin_unlock_irq(shost->host_lock); - } - - /* - * set fixed host attributes - * Must done after lpfc_sli_hba_setup() - */ - - fc_host_node_name(shost) = wwn_to_u64(phba->fc_nodename.u.wwn); - fc_host_port_name(shost) = wwn_to_u64(phba->fc_portname.u.wwn); - fc_host_supported_classes(shost) = FC_COS_CLASS3; - - memset(fc_host_supported_fc4s(shost), 0, - sizeof(fc_host_supported_fc4s(shost))); - fc_host_supported_fc4s(shost)[2] = 1; - fc_host_supported_fc4s(shost)[7] = 1; - - lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(shost)); - - fc_host_supported_speeds(shost) = 0; - if (phba->lmt & LMT_10Gb) - fc_host_supported_speeds(shost) |= FC_PORTSPEED_10GBIT; - if (phba->lmt & LMT_4Gb) - fc_host_supported_speeds(shost) |= FC_PORTSPEED_4GBIT; - if (phba->lmt & LMT_2Gb) - fc_host_supported_speeds(shost) |= FC_PORTSPEED_2GBIT; - if (phba->lmt & LMT_1Gb) - fc_host_supported_speeds(shost) |= FC_PORTSPEED_1GBIT; - - fc_host_maxframe_size(shost) = - ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | - (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb); - - /* This value is also unchanging */ - memset(fc_host_active_fc4s(shost), 0, - sizeof(fc_host_active_fc4s(shost))); - fc_host_active_fc4s(shost)[2] = 1; - fc_host_active_fc4s(shost)[7] = 1; - - spin_lock_irq(shost->host_lock); - phba->fc_flag &= ~FC_LOADING; - spin_unlock_irq(shost->host_lock); - - return 1; -} static int __devinit lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) @@ -1541,6 +1445,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_put_host; host->unique_id = phba->brd_no; + INIT_LIST_HEAD(&phba->ctrspbuflist); + INIT_LIST_HEAD(&phba->rnidrspbuflist); + INIT_LIST_HEAD(&phba->freebufList); /* Initialize timers used by driver */ init_timer(&phba->fc_estabtmo); @@ -1575,7 +1482,16 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) host->max_lun = phba->cfg_max_luns; host->this_id = -1; - INIT_LIST_HEAD(&phba->fc_nodes); + /* Initialize all internally managed lists. */ + INIT_LIST_HEAD(&phba->fc_nlpmap_list); + INIT_LIST_HEAD(&phba->fc_nlpunmap_list); + INIT_LIST_HEAD(&phba->fc_unused_list); + INIT_LIST_HEAD(&phba->fc_plogi_list); + INIT_LIST_HEAD(&phba->fc_adisc_list); + INIT_LIST_HEAD(&phba->fc_reglogin_list); + INIT_LIST_HEAD(&phba->fc_prli_list); + INIT_LIST_HEAD(&phba->fc_npr_list); + pci_set_master(pdev); retval = pci_set_mwi(pdev); @@ -1693,6 +1609,13 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) host->transportt = lpfc_transport_template; pci_set_drvdata(pdev, host); + error = scsi_add_host(host, &pdev->dev); + if (error) + goto out_kthread_stop; + + error = lpfc_alloc_sysfs_attr(phba); + if (error) + goto out_remove_host; if (phba->cfg_use_msi) { error = pci_enable_msi(phba->pcidev); @@ -1708,15 +1631,73 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "%d:0451 Enable interrupt handler failed\n", phba->brd_no); - goto out_kthread_stop; + goto out_free_sysfs_attr; } + phba->MBslimaddr = phba->slim_memmap_p; + phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET; + phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET; + phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; + phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; - error = scsi_add_host(host, &pdev->dev); - if (error) + error = lpfc_sli_hba_setup(phba); + if (error) { + error = -ENODEV; goto out_free_irq; + } + + /* + * hba setup may have changed the hba_queue_depth so we need to adjust + * the value of can_queue. + */ + host->can_queue = phba->cfg_hba_queue_depth - 10; + + lpfc_discovery_wait(phba); - scsi_scan_host(host); + if (phba->cfg_poll & DISABLE_FCP_RING_INT) { + spin_lock_irq(phba->host->host_lock); + lpfc_poll_start_timer(phba); + spin_unlock_irq(phba->host->host_lock); + } + /* + * set fixed host attributes + * Must done after lpfc_sli_hba_setup() + */ + + fc_host_node_name(host) = wwn_to_u64(phba->fc_nodename.u.wwn); + fc_host_port_name(host) = wwn_to_u64(phba->fc_portname.u.wwn); + fc_host_supported_classes(host) = FC_COS_CLASS3; + + memset(fc_host_supported_fc4s(host), 0, + sizeof(fc_host_supported_fc4s(host))); + fc_host_supported_fc4s(host)[2] = 1; + fc_host_supported_fc4s(host)[7] = 1; + + lpfc_get_hba_sym_node_name(phba, fc_host_symbolic_name(host)); + + fc_host_supported_speeds(host) = 0; + if (phba->lmt & LMT_10Gb) + fc_host_supported_speeds(host) |= FC_PORTSPEED_10GBIT; + if (phba->lmt & LMT_4Gb) + fc_host_supported_speeds(host) |= FC_PORTSPEED_4GBIT; + if (phba->lmt & LMT_2Gb) + fc_host_supported_speeds(host) |= FC_PORTSPEED_2GBIT; + if (phba->lmt & LMT_1Gb) + fc_host_supported_speeds(host) |= FC_PORTSPEED_1GBIT; + + fc_host_maxframe_size(host) = + ((((uint32_t) phba->fc_sparam.cmn.bbRcvSizeMsb & 0x0F) << 8) | + (uint32_t) phba->fc_sparam.cmn.bbRcvSizeLsb); + + /* This value is also unchanging */ + memset(fc_host_active_fc4s(host), 0, + sizeof(fc_host_active_fc4s(host))); + fc_host_active_fc4s(host)[2] = 1; + fc_host_active_fc4s(host)[7] = 1; + + spin_lock_irq(phba->host->host_lock); + phba->fc_flag &= ~FC_LOADING; + spin_unlock_irq(phba->host->host_lock); return 0; out_free_irq: @@ -1724,6 +1705,11 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) phba->work_hba_events = 0; free_irq(phba->pcidev->irq, phba); pci_disable_msi(phba->pcidev); +out_free_sysfs_attr: + lpfc_free_sysfs_attr(phba); +out_remove_host: + fc_remove_host(phba->host); + scsi_remove_host(phba->host); out_kthread_stop: kthread_stop(phba->worker_thread); out_free_iocbq: @@ -1761,8 +1747,56 @@ lpfc_pci_remove_one(struct pci_dev *pdev) { struct Scsi_Host *host = pci_get_drvdata(pdev); struct lpfc_hba *phba = (struct lpfc_hba *)host->hostdata; + unsigned long iflag; + + lpfc_free_sysfs_attr(phba); + + spin_lock_irqsave(phba->host->host_lock, iflag); + phba->fc_flag |= FC_UNLOADING; + + spin_unlock_irqrestore(phba->host->host_lock, iflag); - lpfc_remove_device(phba); + fc_remove_host(phba->host); + scsi_remove_host(phba->host); + + kthread_stop(phba->worker_thread); + + /* + * Bring down the SLI Layer. This step disable all interrupts, + * clears the rings, discards all mailbox commands, and resets + * the HBA. + */ + lpfc_sli_hba_down(phba); + lpfc_sli_brdrestart(phba); + + /* Release the irq reservation */ + free_irq(phba->pcidev->irq, phba); + pci_disable_msi(phba->pcidev); + + lpfc_cleanup(phba, 0); + lpfc_stop_timer(phba); + phba->work_hba_events = 0; + + /* + * Call scsi_free before mem_free since scsi bufs are released to their + * corresponding pools here. + */ + lpfc_scsi_free(phba); + lpfc_mem_free(phba); + + /* Free resources associated with SLI2 interface */ + dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, + phba->slim2p, phba->slim2p_mapping); + + /* unmap adapter SLIM and Control Registers */ + iounmap(phba->ctrl_regs_memmap_p); + iounmap(phba->slim_memmap_p); + + pci_release_regions(phba->pcidev); + pci_disable_device(phba->pcidev); + + idr_remove(&lpfc_hba_index, phba->brd_no); + scsi_host_put(phba->host); pci_set_drvdata(pdev, NULL); } @@ -1907,18 +1941,6 @@ static struct pci_device_id lpfc_id_table[] = { PCI_ANY_ID, PCI_ANY_ID, }, {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LPE11000S, PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT, - PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_MID, - PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_SMB, - PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_DCSP, - PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_SCSP, - PCI_ANY_ID, PCI_ANY_ID, }, - {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_S, - PCI_ANY_ID, PCI_ANY_ID, }, { 0 } }; diff --git a/trunk/drivers/scsi/lpfc/lpfc_mbox.c b/trunk/drivers/scsi/lpfc/lpfc_mbox.c index 8041c3f06f7b..4d016c2a1b26 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_mbox.c +++ b/trunk/drivers/scsi/lpfc/lpfc_mbox.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -212,7 +212,6 @@ lpfc_init_link(struct lpfc_hba * phba, case LINK_SPEED_1G: case LINK_SPEED_2G: case LINK_SPEED_4G: - case LINK_SPEED_8G: mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; mb->un.varInitLnk.link_speed = linkspeed; diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index b309841e3846..0c7e731dc45a 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -168,13 +168,14 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, * routine effectively results in a "software abort". */ int -lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) +lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, + int send_abts) { - LIST_HEAD(completions); struct lpfc_sli *psli; struct lpfc_sli_ring *pring; struct lpfc_iocbq *iocb, *next_iocb; - IOCB_t *cmd; + IOCB_t *icmd; + int found = 0; /* Abort outstanding I/O on NPort */ lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, @@ -187,39 +188,75 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) pring = &psli->ring[LPFC_ELS_RING]; /* First check the txq */ - spin_lock_irq(phba->host->host_lock); - list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { - /* Check to see if iocb matches the nport we are looking - for */ - if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) { - /* It matches, so deque and call compl with an - error */ - list_move_tail(&iocb->list, &completions); - pring->txq_cnt--; + do { + found = 0; + spin_lock_irq(phba->host->host_lock); + list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { + /* Check to see if iocb matches the nport we are looking + for */ + if ((lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))) { + found = 1; + /* It matches, so deque and call compl with an + error */ + list_del(&iocb->list); + pring->txq_cnt--; + if (iocb->iocb_cmpl) { + icmd = &iocb->iocb; + icmd->ulpStatus = IOSTAT_LOCAL_REJECT; + icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; + spin_unlock_irq(phba->host->host_lock); + (iocb->iocb_cmpl) (phba, iocb, iocb); + spin_lock_irq(phba->host->host_lock); + } else + lpfc_sli_release_iocbq(phba, iocb); + break; + } } - } + spin_unlock_irq(phba->host->host_lock); + } while (found); + /* Everything on txcmplq will be returned by firmware + * with a no rpi / linkdown / abort error. For ring 0, + * ELS discovery, we want to get rid of it right here. + */ /* Next check the txcmplq */ - list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { - /* Check to see if iocb matches the nport we are looking - for */ - if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) - lpfc_sli_issue_abort_iotag(phba, pring, iocb); - } - spin_unlock_irq(phba->host->host_lock); - - while (!list_empty(&completions)) { - iocb = list_get_first(&completions, struct lpfc_iocbq, list); - cmd = &iocb->iocb; - list_del(&iocb->list); - - if (iocb->iocb_cmpl) { - cmd->ulpStatus = IOSTAT_LOCAL_REJECT; - cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; - (iocb->iocb_cmpl) (phba, iocb, iocb); - } else - lpfc_sli_release_iocbq(phba, iocb); - } + do { + found = 0; + spin_lock_irq(phba->host->host_lock); + list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, + list) { + /* Check to see if iocb matches the nport we are looking + for */ + if ((lpfc_check_sli_ndlp (phba, pring, iocb, ndlp))) { + found = 1; + /* It matches, so deque and call compl with an + error */ + list_del(&iocb->list); + pring->txcmplq_cnt--; + + icmd = &iocb->iocb; + /* If the driver is completing an ELS + * command early, flush it out of the firmware. + */ + if (send_abts && + (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) && + (icmd->un.elsreq64.bdl.ulpIoTag32)) { + lpfc_sli_issue_abort_iotag32(phba, + pring, iocb); + } + if (iocb->iocb_cmpl) { + icmd->ulpStatus = IOSTAT_LOCAL_REJECT; + icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; + spin_unlock_irq(phba->host->host_lock); + (iocb->iocb_cmpl) (phba, iocb, iocb); + spin_lock_irq(phba->host->host_lock); + } else + lpfc_sli_release_iocbq(phba, iocb); + break; + } + } + spin_unlock_irq(phba->host->host_lock); + } while(found); /* If we are delaying issuing an ELS command, cancel it */ if (ndlp->nlp_flag & NLP_DELAY_TMO) @@ -353,10 +390,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, * queue this mbox command to be processed later. */ mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; - /* - * mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox - * command issued in lpfc_cmpl_els_acc(). - */ + mbox->context2 = ndlp; ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); /* @@ -370,7 +404,7 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, */ if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) { /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); } lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); @@ -437,7 +471,8 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, spin_unlock_irq(phba->host->host_lock); ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); return 0; } @@ -467,10 +502,12 @@ lpfc_rcv_logo(struct lpfc_hba * phba, ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); } else { ndlp->nlp_prev_state = ndlp->nlp_state; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); + ndlp->nlp_state = NLP_STE_UNUSED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); } spin_lock_irq(phba->host->host_lock); @@ -564,10 +601,11 @@ lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); + ndlp->nlp_state = NLP_STE_UNUSED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); return ndlp->nlp_state; } - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } @@ -576,7 +614,7 @@ lpfc_rcv_els_unused_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { lpfc_issue_els_logo(phba, ndlp, 0); - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); + lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); return ndlp->nlp_state; } @@ -592,7 +630,7 @@ lpfc_rcv_logo_unused_node(struct lpfc_hba * phba, ndlp->nlp_flag |= NLP_LOGO_ACC; spin_unlock_irq(phba->host->host_lock); lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); + lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); return ndlp->nlp_state; } @@ -601,7 +639,7 @@ static uint32_t lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } @@ -609,7 +647,7 @@ static uint32_t lpfc_device_rm_unused_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } @@ -659,7 +697,7 @@ lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); return ndlp->nlp_state; @@ -674,7 +712,7 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); if (evt == NLP_EVT_RCV_LOGO) { lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); @@ -689,7 +727,8 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, spin_unlock_irq(phba->host->host_lock); ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); return ndlp->nlp_state; } @@ -764,26 +803,32 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, goto out; lpfc_unreg_rpi(phba, ndlp); - if (lpfc_reg_login(phba, irsp->un.elsreq64.remoteID, (uint8_t *) sp, - mbox, 0) == 0) { + if (lpfc_reg_login + (phba, irsp->un.elsreq64.remoteID, + (uint8_t *) sp, mbox, 0) == 0) { switch (ndlp->nlp_DID) { case NameServer_DID: - mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login; + mbox->mbox_cmpl = + lpfc_mbx_cmpl_ns_reg_login; break; case FDMI_DID: - mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login; + mbox->mbox_cmpl = + lpfc_mbx_cmpl_fdmi_reg_login; break; default: - mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; + mbox->mbox_cmpl = + lpfc_mbx_cmpl_reg_login; } - mbox->context2 = lpfc_nlp_get(ndlp); + mbox->context2 = ndlp; if (lpfc_sli_issue_mbox(phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { - lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); + ndlp->nlp_state = + NLP_STE_REG_LOGIN_ISSUE; + lpfc_nlp_list(phba, ndlp, + NLP_REGLOGIN_LIST); return ndlp->nlp_state; } - lpfc_nlp_put(ndlp); mp = (struct lpfc_dmabuf *)mbox->context1; lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); @@ -796,7 +841,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, out: /* Free this node since the driver cannot login or has the wrong sparm */ - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } @@ -810,9 +855,9 @@ lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, } else { /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } } @@ -823,10 +868,11 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, uint32_t evt) { /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); spin_unlock_irq(phba->host->host_lock); @@ -842,7 +888,7 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, struct lpfc_iocbq *cmdiocb; /* software abort outstanding ADISC */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); cmdiocb = (struct lpfc_iocbq *) arg; @@ -850,7 +896,8 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, return ndlp->nlp_state; } ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); return ndlp->nlp_state; @@ -879,7 +926,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; /* software abort outstanding ADISC */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 0); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); return ndlp->nlp_state; @@ -940,17 +987,20 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); lpfc_unreg_rpi(phba, ndlp); return ndlp->nlp_state; } if (ndlp->nlp_type & NLP_FCP_TARGET) { ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_MAPPED_NODE); + ndlp->nlp_state = NLP_STE_MAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); } else { ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); + ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); } return ndlp->nlp_state; } @@ -966,9 +1016,9 @@ lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, } else { /* software abort outstanding ADISC */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } } @@ -979,10 +1029,11 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, uint32_t evt) { /* software abort outstanding ADISC */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); ndlp->nlp_flag |= NLP_NPR_ADISC; @@ -1023,36 +1074,9 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, uint32_t evt) { struct lpfc_iocbq *cmdiocb; - LPFC_MBOXQ_t *mb; - LPFC_MBOXQ_t *nextmb; - struct lpfc_dmabuf *mp; cmdiocb = (struct lpfc_iocbq *) arg; - /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ - if ((mb = phba->sli.mbox_active)) { - if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && - (ndlp == (struct lpfc_nodelist *) mb->context2)) { - mb->context2 = NULL; - mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; - } - } - - spin_lock_irq(phba->host->host_lock); - list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { - if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && - (ndlp == (struct lpfc_nodelist *) mb->context2)) { - mp = (struct lpfc_dmabuf *) (mb->context1); - if (mp) { - lpfc_mbuf_free(phba, mp->virt, mp->phys); - kfree(mp); - } - list_del(&mb->list); - mempool_free(mb, phba->mbox_mem_pool); - } - } - spin_unlock_irq(phba->host->host_lock); - lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); return ndlp->nlp_state; } @@ -1109,7 +1133,8 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, */ if (mb->mbxStatus == MBXERR_RPI_FULL) { ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); + ndlp->nlp_state = NLP_STE_UNUSED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); return ndlp->nlp_state; } @@ -1122,7 +1147,8 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, lpfc_issue_els_logo(phba, ndlp, 0); ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); return ndlp->nlp_state; } @@ -1131,11 +1157,13 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, /* Only if we are not a fabric nport do we issue PRLI */ if (!(ndlp->nlp_type & NLP_FABRIC)) { ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE); + ndlp->nlp_state = NLP_STE_PRLI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); lpfc_issue_els_prli(phba, ndlp, 0); } else { ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); + ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); } return ndlp->nlp_state; } @@ -1150,7 +1178,7 @@ lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, return ndlp->nlp_state; } else { - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } } @@ -1161,7 +1189,8 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, uint32_t evt) { ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); spin_unlock_irq(phba->host->host_lock); @@ -1201,7 +1230,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, cmdiocb = (struct lpfc_iocbq *) arg; /* Software abort outstanding PRLI before sending acc */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); return ndlp->nlp_state; @@ -1250,7 +1279,8 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, irsp = &rspiocb->iocb; if (irsp->ulpStatus) { ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); + ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); return ndlp->nlp_state; } @@ -1268,7 +1298,8 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, } ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_MAPPED_NODE); + ndlp->nlp_state = NLP_STE_MAPPED_NODE; + lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); return ndlp->nlp_state; } @@ -1299,9 +1330,9 @@ lpfc_device_rm_prli_issue(struct lpfc_hba * phba, } else { /* software abort outstanding PLOGI */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } } @@ -1328,10 +1359,11 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { /* software abort outstanding PRLI */ - lpfc_els_abort(phba, ndlp); + lpfc_els_abort(phba, ndlp, 1); ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); spin_unlock_irq(phba->host->host_lock); @@ -1404,7 +1436,8 @@ lpfc_device_recov_unmap_node(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) { ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); lpfc_disc_set_adisc(phba, ndlp); @@ -1485,7 +1518,8 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, uint32_t evt) { ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); spin_unlock_irq(phba->host->host_lock); @@ -1517,7 +1551,8 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, /* send PLOGI immediately, move to PLOGI issue state */ if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); } @@ -1545,13 +1580,16 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, ndlp->nlp_flag &= ~NLP_NPR_ADISC; spin_unlock_irq(phba->host->host_lock); ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); + ndlp->nlp_state = NLP_STE_ADISC_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); lpfc_issue_els_adisc(phba, ndlp, 0); } else { ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); } + } return ndlp->nlp_state; } @@ -1589,11 +1627,13 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){ if (ndlp->nlp_flag & NLP_NPR_ADISC) { ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); + ndlp->nlp_state = NLP_STE_ADISC_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); lpfc_issue_els_adisc(phba, ndlp, 0); } else { ndlp->nlp_prev_state = NLP_STE_NPR_NODE; - lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); + ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); } } @@ -1642,7 +1682,7 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, irsp = &rspiocb->iocb; if (irsp->ulpStatus) { - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } return ndlp->nlp_state; @@ -1660,7 +1700,7 @@ lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, irsp = &rspiocb->iocb; if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } return ndlp->nlp_state; @@ -1688,7 +1728,7 @@ lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, irsp = &rspiocb->iocb; if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } return ndlp->nlp_state; @@ -1709,7 +1749,7 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, ndlp->nlp_rpi = mb->un.varWords[0]; else { if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } } @@ -1725,7 +1765,7 @@ lpfc_device_rm_npr_node(struct lpfc_hba * phba, ndlp->nlp_flag |= NLP_NODEV_REMOVE; return ndlp->nlp_state; } - lpfc_drop_node(phba, ndlp); + lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); return NLP_STE_FREED_NODE; } @@ -1924,7 +1964,7 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, uint32_t(*func) (struct lpfc_hba *, struct lpfc_nodelist *, void *, uint32_t); - lpfc_nlp_get(ndlp); + ndlp->nlp_disc_refcnt++; cur_state = ndlp->nlp_state; /* DSM in event on NPort in state */ @@ -1947,7 +1987,18 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, phba->brd_no, rc, ndlp->nlp_DID, ndlp->nlp_flag); - lpfc_nlp_put(ndlp); + ndlp->nlp_disc_refcnt--; + /* Check to see if ndlp removal is deferred */ + if ((ndlp->nlp_disc_refcnt == 0) + && (ndlp->nlp_flag & NLP_DELAY_REMOVE)) { + spin_lock_irq(phba->host->host_lock); + ndlp->nlp_flag &= ~NLP_DELAY_REMOVE; + spin_unlock_irq(phba->host->host_lock); + lpfc_nlp_remove(phba, ndlp); + return NLP_STE_FREED_NODE; + } + if (rc == NLP_STE_FREED_NODE) + return NLP_STE_FREED_NODE; return rc; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index 9a12d05e99e4..c3e68e0d8f74 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -146,10 +146,6 @@ lpfc_get_scsi_buf(struct lpfc_hba * phba) spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); - if (lpfc_cmd) { - lpfc_cmd->seg_cnt = 0; - lpfc_cmd->nonsg_phys = 0; - } spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); return lpfc_cmd; } @@ -292,13 +288,13 @@ lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) } static void -lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb) +lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) { struct scsi_cmnd *cmnd = lpfc_cmd->pCmd; struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd; struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp; struct lpfc_hba *phba = lpfc_cmd->scsi_hba; - uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm; + uint32_t fcpi_parm = lpfc_cmd->cur_iocbq.iocb.un.fcpi.fcpi_parm; uint32_t resp_info = fcprsp->rspStatus2; uint32_t scsi_status = fcprsp->rspStatus3; uint32_t *lp; @@ -359,24 +355,6 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb) be32_to_cpu(fcpcmd->fcpDl), cmnd->resid, fcpi_parm, cmnd->cmnd[0], cmnd->underflow); - /* - * If there is an under run check if under run reported by - * storage array is same as the under run reported by HBA. - * If this is not same, there is a dropped frame. - */ - if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) && - fcpi_parm && - (cmnd->resid != fcpi_parm)) { - lpfc_printf_log(phba, KERN_WARNING, - LOG_FCP | LOG_FCP_ERROR, - "%d:0735 FCP Read Check Error and Underrun " - "Data: x%x x%x x%x x%x\n", phba->brd_no, - be32_to_cpu(fcpcmd->fcpDl), - cmnd->resid, - fcpi_parm, cmnd->cmnd[0]); - cmnd->resid = cmnd->request_bufflen; - host_status = DID_ERROR; - } /* * The cmnd->underflow is the minimum number of bytes that must * be transfered for this command. Provided a sense condition @@ -457,7 +435,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, switch (lpfc_cmd->status) { case IOSTAT_FCP_RSP_ERROR: /* Call FCP RSP handler to determine result */ - lpfc_handle_fcp_err(lpfc_cmd,pIocbOut); + lpfc_handle_fcp_err(lpfc_cmd); break; case IOSTAT_NPORT_BSY: case IOSTAT_FABRIC_BSY: @@ -488,10 +466,10 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, result = cmd->result; sdev = cmd->device; - lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); cmd->scsi_done(cmd); if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { + lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); return; } @@ -549,6 +527,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, } } + lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); } @@ -691,18 +670,6 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, return (1); } -static void -lpfc_tskmgmt_def_cmpl(struct lpfc_hba *phba, - struct lpfc_iocbq *cmdiocbq, - struct lpfc_iocbq *rspiocbq) -{ - struct lpfc_scsi_buf *lpfc_cmd = - (struct lpfc_scsi_buf *) cmdiocbq->context1; - if (lpfc_cmd) - lpfc_release_scsi_buf(phba, lpfc_cmd); - return; -} - static int lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, unsigned tgt_id, unsigned int lun, @@ -739,9 +706,8 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); if (ret != IOCB_SUCCESS) { - if (ret == IOCB_TIMEDOUT) - iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; lpfc_cmd->status = IOSTAT_DRIVER_REJECT; + ret = FAILED; } else { ret = SUCCESS; lpfc_cmd->result = iocbqrsp->iocb.un.ulpWord[4]; @@ -1008,7 +974,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) } static int -lpfc_device_reset_handler(struct scsi_cmnd *cmnd) +lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; @@ -1018,7 +984,6 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) struct lpfc_nodelist *pnode = rdata->pnode; uint32_t cmd_result = 0, cmd_status = 0; int ret = FAILED; - int iocb_status = IOCB_SUCCESS; int cnt, loopcnt; lpfc_block_error_handler(cmnd); @@ -1030,7 +995,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) */ while ( 1 ) { if (!pnode) - goto out; + return FAILED; if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { spin_unlock_irq(phba->host->host_lock); @@ -1048,7 +1013,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) } pnode = rdata->pnode; if (!pnode) - goto out; + return FAILED; } if (pnode->nlp_state == NLP_STE_MAPPED_NODE) break; @@ -1063,7 +1028,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) lpfc_cmd->rdata = rdata; ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun, - FCP_TARGET_RESET); + FCP_LUN_RESET); if (!ret) goto out_free_scsi_buf; @@ -1075,21 +1040,16 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) goto out_free_scsi_buf; lpfc_printf_log(phba, KERN_INFO, LOG_FCP, - "%d:0703 Issue target reset to TGT %d LUN %d rpi x%x " - "nlp_flag x%x\n", phba->brd_no, cmnd->device->id, + "%d:0703 Issue LUN Reset to TGT %d LUN %d " + "Data: x%x x%x\n", phba->brd_no, cmnd->device->id, cmnd->device->lun, pnode->nlp_rpi, pnode->nlp_flag); - iocb_status = lpfc_sli_issue_iocb_wait(phba, + ret = lpfc_sli_issue_iocb_wait(phba, &phba->sli.ring[phba->sli.fcp_ring], iocbq, iocbqrsp, lpfc_cmd->timeout); - - if (iocb_status == IOCB_TIMEDOUT) - iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl; - - if (iocb_status == IOCB_SUCCESS) + if (ret == IOCB_SUCCESS) ret = SUCCESS; - else - ret = iocb_status; + cmd_result = iocbqrsp->iocb.un.ulpWord[4]; cmd_status = iocbqrsp->iocb.ulpStatus; @@ -1127,19 +1087,18 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) if (cnt) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d:0719 device reset I/O flush failure: cnt x%x\n", + "%d:0719 LUN Reset I/O flush failure: cnt x%x\n", phba->brd_no, cnt); ret = FAILED; } out_free_scsi_buf: - if (iocb_status != IOCB_TIMEDOUT) { - lpfc_release_scsi_buf(phba, lpfc_cmd); - } + lpfc_release_scsi_buf(phba, lpfc_cmd); + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "%d:0713 SCSI layer issued device reset (%d, %d) " - "return x%x status x%x result x%x\n", - phba->brd_no, cmnd->device->id, cmnd->device->lun, + "%d:0713 SCSI layer issued LUN reset (%d, %d) " + "Data: x%x x%x x%x\n", + phba->brd_no, cmnd->device->id,cmnd->device->lun, ret, cmd_status, cmd_result); out: @@ -1148,7 +1107,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) } static int -lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) +lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) { struct Scsi_Host *shost = cmnd->device->host; struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata; @@ -1175,12 +1134,10 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) * fail, this routine returns failure to the midlayer. */ for (i = 0; i < LPFC_MAX_TARGET; i++) { - /* Search for mapped node by target ID */ + /* Search the mapped list for this target ID */ match = 0; - list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { - if (ndlp->nlp_state == NLP_STE_MAPPED_NODE && - i == ndlp->nlp_sid && - ndlp->rport) { + list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { + if ((i == ndlp->nlp_sid) && ndlp->rport) { match = 1; break; } @@ -1195,17 +1152,13 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd) "%d:0700 Bus Reset on target %d failed\n", phba->brd_no, i); err_count++; - break; } } - if (ret != IOCB_TIMEDOUT) - lpfc_release_scsi_buf(phba, lpfc_cmd); - if (err_count == 0) ret = SUCCESS; - else - ret = FAILED; + + lpfc_release_scsi_buf(phba, lpfc_cmd); /* * All outstanding txcmplq I/Os should have been aborted by @@ -1346,13 +1299,11 @@ struct scsi_host_template lpfc_template = { .info = lpfc_info, .queuecommand = lpfc_queuecommand, .eh_abort_handler = lpfc_abort_handler, - .eh_device_reset_handler= lpfc_device_reset_handler, - .eh_bus_reset_handler = lpfc_bus_reset_handler, + .eh_device_reset_handler= lpfc_reset_lun_handler, + .eh_bus_reset_handler = lpfc_reset_bus_handler, .slave_alloc = lpfc_slave_alloc, .slave_configure = lpfc_slave_configure, .slave_destroy = lpfc_slave_destroy, - .scan_finished = lpfc_scan_finished, - .scan_start = lpfc_scan_start, .this_id = -1, .sg_tablesize = LPFC_SG_SEG_CNT, .cmd_per_lun = LPFC_CMD_PER_LUN, diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index a1e721459e2b..9fb6960a8ada 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * Portions Copyright (C) 2004-2005 Christoph Hellwig * @@ -528,7 +528,6 @@ lpfc_sli_wake_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) * If pdone_q is empty, the driver thread gave up waiting and * continued running. */ - pmboxq->mbox_flag |= LPFC_MBX_WAKE; pdone_q = (wait_queue_head_t *) pmboxq->context1; if (pdone_q) wake_up_interruptible(pdone_q); @@ -539,32 +538,11 @@ void lpfc_sli_def_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) { struct lpfc_dmabuf *mp; - uint16_t rpi; - int rc; - mp = (struct lpfc_dmabuf *) (pmb->context1); - if (mp) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); } - - /* - * If a REG_LOGIN succeeded after node is destroyed or node - * is in re-discovery driver need to cleanup the RPI. - */ - if (!(phba->fc_flag & FC_UNLOADING) && - (pmb->mb.mbxCommand == MBX_REG_LOGIN64) && - (!pmb->mb.mbxStatus)) { - - rpi = pmb->mb.un.varWords[0]; - lpfc_unreg_login(phba, rpi, pmb); - pmb->mbox_cmpl=lpfc_sli_def_mbox_cmpl; - rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); - if (rc != MBX_NOT_FINISHED) - return; - } - mempool_free( pmb, phba->mbox_mem_pool); return; } @@ -715,8 +693,25 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) } else { spin_unlock_irq(phba->host->host_lock); /* Turn on IOCB processing */ - for (i = 0; i < phba->sli.num_rings; i++) + for (i = 0; i < phba->sli.num_rings; i++) { lpfc_sli_turn_on_ring(phba, i); + } + + /* Free any lpfc_dmabuf's waiting for mbox cmd cmpls */ + while (!list_empty(&phba->freebufList)) { + struct lpfc_dmabuf *mp; + + mp = NULL; + list_remove_head((&phba->freebufList), + mp, + struct lpfc_dmabuf, + list); + if (mp) { + lpfc_mbuf_free(phba, mp->virt, + mp->phys); + kfree(mp); + } + } } } while (process_next); @@ -838,14 +833,6 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, * All other are passed to the completion callback. */ if (pring->ringno == LPFC_ELS_RING) { - if (cmdiocbp->iocb_flag & LPFC_DRIVER_ABORTED) { - cmdiocbp->iocb_flag &= - ~LPFC_DRIVER_ABORTED; - saveq->iocb.ulpStatus = - IOSTAT_LOCAL_REJECT; - saveq->iocb.un.ulpWord[4] = - IOERR_SLI_ABORTED; - } spin_unlock_irqrestore(phba->host->host_lock, iflag); (cmdiocbp->iocb_cmpl) (phba, cmdiocbp, saveq); @@ -1477,9 +1464,8 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba * phba, int lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) { - LIST_HEAD(completions); struct lpfc_iocbq *iocb, *next_iocb; - IOCB_t *cmd = NULL; + IOCB_t *icmd = NULL, *cmd = NULL; int errcnt; errcnt = 0; @@ -1488,28 +1474,46 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring) * First do the txq. */ spin_lock_irq(phba->host->host_lock); - list_splice_init(&pring->txq, &completions); + list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { + list_del_init(&iocb->list); + if (iocb->iocb_cmpl) { + icmd = &iocb->iocb; + icmd->ulpStatus = IOSTAT_LOCAL_REJECT; + icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; + spin_unlock_irq(phba->host->host_lock); + (iocb->iocb_cmpl) (phba, iocb, iocb); + spin_lock_irq(phba->host->host_lock); + } else + lpfc_sli_release_iocbq(phba, iocb); + } pring->txq_cnt = 0; + INIT_LIST_HEAD(&(pring->txq)); /* Next issue ABTS for everything on the txcmplq */ - list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) - lpfc_sli_issue_abort_iotag(phba, pring, iocb); + list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { + cmd = &iocb->iocb; - spin_unlock_irq(phba->host->host_lock); + /* + * Imediate abort of IOCB, deque and call compl + */ - while (!list_empty(&completions)) { - iocb = list_get_first(&completions, struct lpfc_iocbq, list); - cmd = &iocb->iocb; - list_del(&iocb->list); + list_del_init(&iocb->list); + pring->txcmplq_cnt--; if (iocb->iocb_cmpl) { cmd->ulpStatus = IOSTAT_LOCAL_REJECT; cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; + spin_unlock_irq(phba->host->host_lock); (iocb->iocb_cmpl) (phba, iocb, iocb); + spin_lock_irq(phba->host->host_lock); } else lpfc_sli_release_iocbq(phba, iocb); } + INIT_LIST_HEAD(&pring->txcmplq); + pring->txcmplq_cnt = 0; + spin_unlock_irq(phba->host->host_lock); + return errcnt; } @@ -1584,7 +1588,6 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) hc_copy = readl(phba->HCregaddr); writel((hc_copy & ~HC_ERINT_ENA), phba->HCregaddr); readl(phba->HCregaddr); /* flush */ - phba->fc_flag |= FC_IGNORE_ERATT; if (readl(phba->HAregaddr) & HA_ERATT) { /* Clear Chip error bit */ @@ -1627,7 +1630,6 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) } restore_hc: - phba->fc_flag &= ~FC_IGNORE_ERATT; writel(hc_copy, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ } @@ -1663,7 +1665,6 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) status &= ~HC_ERINT_ENA; writel(status, phba->HCregaddr); readl(phba->HCregaddr); /* flush */ - phba->fc_flag |= FC_IGNORE_ERATT; spin_unlock_irq(phba->host->host_lock); lpfc_kill_board(phba, pmb); @@ -1673,9 +1674,6 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) if (retval != MBX_SUCCESS) { if (retval != MBX_BUSY) mempool_free(pmb, phba->mbox_mem_pool); - spin_lock_irq(phba->host->host_lock); - phba->fc_flag &= ~FC_IGNORE_ERATT; - spin_unlock_irq(phba->host->host_lock); return 1; } @@ -1702,7 +1700,6 @@ lpfc_sli_brdkill(struct lpfc_hba * phba) } spin_lock_irq(phba->host->host_lock); psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; - phba->fc_flag &= ~FC_IGNORE_ERATT; spin_unlock_irq(phba->host->host_lock); psli->mbox_active = NULL; @@ -1988,6 +1985,42 @@ lpfc_sli_hba_setup(struct lpfc_hba * phba) return rc; } +static void +lpfc_mbox_abort(struct lpfc_hba * phba) +{ + LPFC_MBOXQ_t *pmbox; + MAILBOX_t *mb; + + if (phba->sli.mbox_active) { + del_timer_sync(&phba->sli.mbox_tmo); + phba->work_hba_events &= ~WORKER_MBOX_TMO; + pmbox = phba->sli.mbox_active; + mb = &pmbox->mb; + phba->sli.mbox_active = NULL; + if (pmbox->mbox_cmpl) { + mb->mbxStatus = MBX_NOT_FINISHED; + (pmbox->mbox_cmpl) (phba, pmbox); + } + phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; + } + + /* Abort all the non active mailbox commands. */ + spin_lock_irq(phba->host->host_lock); + pmbox = lpfc_mbox_get(phba); + while (pmbox) { + mb = &pmbox->mb; + if (pmbox->mbox_cmpl) { + mb->mbxStatus = MBX_NOT_FINISHED; + spin_unlock_irq(phba->host->host_lock); + (pmbox->mbox_cmpl) (phba, pmbox); + spin_lock_irq(phba->host->host_lock); + } + pmbox = lpfc_mbox_get(phba); + } + spin_unlock_irq(phba->host->host_lock); + return; +} + /*! lpfc_mbox_timeout * * \pre @@ -2022,8 +2055,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) { LPFC_MBOXQ_t *pmbox; MAILBOX_t *mb; - struct lpfc_sli *psli = &phba->sli; - struct lpfc_sli_ring *pring; spin_lock_irq(phba->host->host_lock); if (!(phba->work_hba_events & WORKER_MBOX_TMO)) { @@ -2031,6 +2062,8 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) return; } + phba->work_hba_events &= ~WORKER_MBOX_TMO; + pmbox = phba->sli.mbox_active; mb = &pmbox->mb; @@ -2045,32 +2078,17 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) phba->sli.sli_flag, phba->sli.mbox_active); - /* Setting state unknown so lpfc_sli_abort_iocb_ring - * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing - * it to fail all oustanding SCSI IO. - */ - phba->hba_state = LPFC_STATE_UNKNOWN; - phba->work_hba_events &= ~WORKER_MBOX_TMO; - phba->fc_flag |= FC_ESTABLISH_LINK; - psli->sli_flag &= ~LPFC_SLI2_ACTIVE; - spin_unlock_irq(phba->host->host_lock); - - pring = &psli->ring[psli->fcp_ring]; - lpfc_sli_abort_iocb_ring(phba, pring); + phba->sli.mbox_active = NULL; + if (pmbox->mbox_cmpl) { + mb->mbxStatus = MBX_NOT_FINISHED; + spin_unlock_irq(phba->host->host_lock); + (pmbox->mbox_cmpl) (phba, pmbox); + spin_lock_irq(phba->host->host_lock); + } + phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "%d:0316 Resetting board due to mailbox timeout\n", - phba->brd_no); - /* - * lpfc_offline calls lpfc_sli_hba_down which will clean up - * on oustanding mailbox commands. - */ - lpfc_offline_prep(phba); - lpfc_offline(phba); - lpfc_sli_brdrestart(phba); - if (lpfc_online(phba) == 0) /* Initialize the HBA */ - mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); - lpfc_unblock_mgmt_io(phba); + spin_unlock_irq(phba->host->host_lock); + lpfc_mbox_abort(phba); return; } @@ -2302,7 +2320,9 @@ lpfc_sli_issue_mbox(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmbox, uint32_t flag) spin_unlock_irqrestore(phba->host->host_lock, drvr_flag); - msleep(1); + /* Can be in interrupt context, do not sleep */ + /* (or might be called with interrupts disabled) */ + mdelay(1); spin_lock_irqsave(phba->host->host_lock, drvr_flag); @@ -2410,7 +2430,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, if (unlikely(phba->hba_state == LPFC_LINK_DOWN)) { /* - * Only CREATE_XRI, CLOSE_XRI, and QUE_RING_BUF + * Only CREATE_XRI, CLOSE_XRI, ABORT_XRI, and QUE_RING_BUF * can be issued if the link is not up. */ switch (piocb->iocb.ulpCommand) { @@ -2424,8 +2444,6 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, piocb->iocb_cmpl = NULL; /*FALLTHROUGH*/ case CMD_CREATE_XRI_CR: - case CMD_CLOSE_XRI_CN: - case CMD_CLOSE_XRI_CX: break; default: goto iocb_busy; @@ -2619,12 +2637,11 @@ lpfc_sli_queue_setup(struct lpfc_hba * phba) int lpfc_sli_hba_down(struct lpfc_hba * phba) { - LIST_HEAD(completions); struct lpfc_sli *psli; struct lpfc_sli_ring *pring; LPFC_MBOXQ_t *pmb; - struct lpfc_iocbq *iocb; - IOCB_t *cmd = NULL; + struct lpfc_iocbq *iocb, *next_iocb; + IOCB_t *icmd = NULL; int i; unsigned long flags = 0; @@ -2632,6 +2649,7 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) lpfc_hba_down_prep(phba); spin_lock_irqsave(phba->host->host_lock, flags); + for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; pring->flag |= LPFC_DEFERRED_RING_EVENT; @@ -2640,25 +2658,28 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) * Error everything on the txq since these iocbs have not been * given to the FW yet. */ - list_splice_init(&pring->txq, &completions); pring->txq_cnt = 0; - } - spin_unlock_irqrestore(phba->host->host_lock, flags); + list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { + list_del_init(&iocb->list); + if (iocb->iocb_cmpl) { + icmd = &iocb->iocb; + icmd->ulpStatus = IOSTAT_LOCAL_REJECT; + icmd->un.ulpWord[4] = IOERR_SLI_DOWN; + spin_unlock_irqrestore(phba->host->host_lock, + flags); + (iocb->iocb_cmpl) (phba, iocb, iocb); + spin_lock_irqsave(phba->host->host_lock, flags); + } else + lpfc_sli_release_iocbq(phba, iocb); + } - while (!list_empty(&completions)) { - iocb = list_get_first(&completions, struct lpfc_iocbq, list); - cmd = &iocb->iocb; - list_del(&iocb->list); + INIT_LIST_HEAD(&(pring->txq)); - if (iocb->iocb_cmpl) { - cmd->ulpStatus = IOSTAT_LOCAL_REJECT; - cmd->un.ulpWord[4] = IOERR_SLI_DOWN; - (iocb->iocb_cmpl) (phba, iocb, iocb); - } else - lpfc_sli_release_iocbq(phba, iocb); } + spin_unlock_irqrestore(phba->host->host_lock, flags); + /* Return any active mbox cmds */ del_timer_sync(&psli->mbox_tmo); spin_lock_irqsave(phba->host->host_lock, flags); @@ -2747,138 +2768,85 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, } static void -lpfc_sli_abort_els_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, - struct lpfc_iocbq * rspiocb) +lpfc_sli_abort_elsreq_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, + struct lpfc_iocbq * rspiocb) { - IOCB_t *irsp; - uint16_t abort_iotag, abort_context; - struct lpfc_iocbq *abort_iocb, *rsp_ab_iocb; - struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; - - abort_iocb = NULL; - irsp = &rspiocb->iocb; - - spin_lock_irq(phba->host->host_lock); - - if (irsp->ulpStatus) { - abort_context = cmdiocb->iocb.un.acxri.abortContextTag; - abort_iotag = cmdiocb->iocb.un.acxri.abortIoTag; - - if (abort_iotag != 0 && abort_iotag <= phba->sli.last_iotag) - abort_iocb = phba->sli.iocbq_lookup[abort_iotag]; - - lpfc_printf_log(phba, KERN_ERR, LOG_SLI, - "%d:0327 Cannot abort els iocb %p" - " with tag %x context %x\n", - phba->brd_no, abort_iocb, - abort_iotag, abort_context); - - /* - * make sure we have the right iocbq before taking it - * off the txcmplq and try to call completion routine. - */ - if (abort_iocb && - abort_iocb->iocb.ulpContext == abort_context && - abort_iocb->iocb_flag & LPFC_DRIVER_ABORTED) { - list_del(&abort_iocb->list); - pring->txcmplq_cnt--; - - rsp_ab_iocb = lpfc_sli_get_iocbq(phba); - if (rsp_ab_iocb == NULL) - lpfc_sli_release_iocbq(phba, abort_iocb); - else { - abort_iocb->iocb_flag &= - ~LPFC_DRIVER_ABORTED; - rsp_ab_iocb->iocb.ulpStatus = - IOSTAT_LOCAL_REJECT; - rsp_ab_iocb->iocb.un.ulpWord[4] = - IOERR_SLI_ABORTED; - spin_unlock_irq(phba->host->host_lock); - (abort_iocb->iocb_cmpl) - (phba, abort_iocb, rsp_ab_iocb); - spin_lock_irq(phba->host->host_lock); - lpfc_sli_release_iocbq(phba, rsp_ab_iocb); - } + struct lpfc_dmabuf *buf_ptr, *buf_ptr1; + /* Free the resources associated with the ELS_REQUEST64 IOCB the driver + * just aborted. + * In this case, context2 = cmd, context2->next = rsp, context3 = bpl + */ + if (cmdiocb->context2) { + buf_ptr1 = (struct lpfc_dmabuf *) cmdiocb->context2; + + /* Free the response IOCB before completing the abort + command. */ + buf_ptr = NULL; + list_remove_head((&buf_ptr1->list), buf_ptr, + struct lpfc_dmabuf, list); + if (buf_ptr) { + lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); + kfree(buf_ptr); } + lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys); + kfree(buf_ptr1); + } + + if (cmdiocb->context3) { + buf_ptr = (struct lpfc_dmabuf *) cmdiocb->context3; + lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); + kfree(buf_ptr); } lpfc_sli_release_iocbq(phba, cmdiocb); - spin_unlock_irq(phba->host->host_lock); return; } int -lpfc_sli_issue_abort_iotag(struct lpfc_hba * phba, - struct lpfc_sli_ring * pring, - struct lpfc_iocbq * cmdiocb) +lpfc_sli_issue_abort_iotag32(struct lpfc_hba * phba, + struct lpfc_sli_ring * pring, + struct lpfc_iocbq * cmdiocb) { struct lpfc_iocbq *abtsiocbp; IOCB_t *icmd = NULL; IOCB_t *iabt = NULL; - int retval = IOCB_ERROR; - - /* There are certain command types we don't want - * to abort. - */ - icmd = &cmdiocb->iocb; - if ((icmd->ulpCommand == CMD_ABORT_XRI_CN) || - (icmd->ulpCommand == CMD_CLOSE_XRI_CN)) - return 0; - - /* If we're unloading, interrupts are disabled so we - * need to cleanup the iocb here. - */ - if (phba->fc_flag & FC_UNLOADING) - goto abort_iotag_exit; /* issue ABTS for this IOCB based on iotag */ abtsiocbp = lpfc_sli_get_iocbq(phba); if (abtsiocbp == NULL) return 0; - /* This signals the response to set the correct status - * before calling the completion handler. - */ - cmdiocb->iocb_flag |= LPFC_DRIVER_ABORTED; - iabt = &abtsiocbp->iocb; - iabt->un.acxri.abortType = ABORT_TYPE_ABTS; - iabt->un.acxri.abortContextTag = icmd->ulpContext; - iabt->un.acxri.abortIoTag = icmd->ulpIoTag; - iabt->ulpLe = 1; - iabt->ulpClass = icmd->ulpClass; - - if (phba->hba_state >= LPFC_LINK_UP) - iabt->ulpCommand = CMD_ABORT_XRI_CN; - else - iabt->ulpCommand = CMD_CLOSE_XRI_CN; - - abtsiocbp->iocb_cmpl = lpfc_sli_abort_els_cmpl; - - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0339 Abort xri x%x, original iotag x%x, abort " - "cmd iotag x%x\n", - phba->brd_no, iabt->un.acxri.abortContextTag, - iabt->un.acxri.abortIoTag, abtsiocbp->iotag); - retval = lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0); + icmd = &cmdiocb->iocb; + switch (icmd->ulpCommand) { + case CMD_ELS_REQUEST64_CR: + /* Even though we abort the ELS command, the firmware may access + * the BPL or other resources before it processes our + * ABORT_MXRI64. Thus we must delay reusing the cmdiocb + * resources till the actual abort request completes. + */ + abtsiocbp->context1 = (void *)((unsigned long)icmd->ulpCommand); + abtsiocbp->context2 = cmdiocb->context2; + abtsiocbp->context3 = cmdiocb->context3; + cmdiocb->context2 = NULL; + cmdiocb->context3 = NULL; + abtsiocbp->iocb_cmpl = lpfc_sli_abort_elsreq_cmpl; + break; + default: + lpfc_sli_release_iocbq(phba, abtsiocbp); + return 0; + } -abort_iotag_exit: + iabt->un.amxri.abortType = ABORT_TYPE_ABTS; + iabt->un.amxri.iotag32 = icmd->un.elsreq64.bdl.ulpIoTag32; - /* If we could not issue an abort dequeue the iocb and handle - * the completion here. - */ - if (retval == IOCB_ERROR) { - list_del(&cmdiocb->list); - pring->txcmplq_cnt--; + iabt->ulpLe = 1; + iabt->ulpClass = CLASS3; + iabt->ulpCommand = CMD_ABORT_MXRI64_CN; - if (cmdiocb->iocb_cmpl) { - icmd->ulpStatus = IOSTAT_LOCAL_REJECT; - icmd->un.ulpWord[4] = IOERR_SLI_ABORTED; - spin_unlock_irq(phba->host->host_lock); - (cmdiocb->iocb_cmpl) (phba, cmdiocb, cmdiocb); - spin_lock_irq(phba->host->host_lock); - } else - lpfc_sli_release_iocbq(phba, cmdiocb); + if (lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0) == IOCB_ERROR) { + lpfc_sli_release_iocbq(phba, abtsiocbp); + return 0; } return 1; @@ -2950,11 +2918,9 @@ void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) { - unsigned long iflags; - - spin_lock_irqsave(phba->host->host_lock, iflags); + spin_lock_irq(phba->host->host_lock); lpfc_sli_release_iocbq(phba, cmdiocb); - spin_unlock_irqrestore(phba->host->host_lock, iflags); + spin_unlock_irq(phba->host->host_lock); return; } @@ -3077,22 +3043,22 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba, timeout_req); spin_lock_irq(phba->host->host_lock); - if (piocb->iocb_flag & LPFC_IO_WAKE) { - lpfc_printf_log(phba, KERN_INFO, LOG_SLI, - "%d:0331 IOCB wake signaled\n", - phba->brd_no); - } else if (timeleft == 0) { + if (timeleft == 0) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "%d:0338 IOCB wait timeout error - no " "wake response Data x%x\n", phba->brd_no, timeout); retval = IOCB_TIMEDOUT; - } else { + } else if (!(piocb->iocb_flag & LPFC_IO_WAKE)) { lpfc_printf_log(phba, KERN_ERR, LOG_SLI, "%d:0330 IOCB wake NOT set, " "Data x%x x%lx\n", phba->brd_no, timeout, (timeleft / jiffies)); retval = IOCB_TIMEDOUT; + } else { + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "%d:0331 IOCB wake signaled\n", + phba->brd_no); } } else { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, @@ -3121,6 +3087,8 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, uint32_t timeout) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); + DECLARE_WAITQUEUE(wq_entry, current); + uint32_t timeleft = 0; int retval; /* The caller must leave context1 empty. */ @@ -3133,25 +3101,27 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, /* setup context field to pass wait_queue pointer to wake function */ pmboxq->context1 = &done_q; + /* start to sleep before we wait, to avoid races */ + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&done_q, &wq_entry); + /* now issue the command */ retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); if (retval == MBX_BUSY || retval == MBX_SUCCESS) { - wait_event_interruptible_timeout(done_q, - pmboxq->mbox_flag & LPFC_MBX_WAKE, - timeout * HZ); - + timeleft = schedule_timeout(timeout * HZ); pmboxq->context1 = NULL; - /* - * if LPFC_MBX_WAKE flag is set the mailbox is completed - * else do not free the resources. - */ - if (pmboxq->mbox_flag & LPFC_MBX_WAKE) - retval = MBX_SUCCESS; - else + /* if schedule_timeout returns 0, we timed out and were not + woken up */ + if ((timeleft == 0) || signal_pending(current)) retval = MBX_TIMEOUT; + else + retval = MBX_SUCCESS; } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&done_q, &wq_entry); return retval; } @@ -3214,11 +3184,6 @@ lpfc_intr_handler(int irq, void *dev_id) */ spin_lock(phba->host->host_lock); ha_copy = readl(phba->HAregaddr); - /* If somebody is waiting to handle an eratt don't process it - * here. The brdkill function will do this. - */ - if (phba->fc_flag & FC_IGNORE_ERATT) - ha_copy &= ~HA_ERATT; writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr); readl(phba->HAregaddr); /* flush */ spin_unlock(phba->host->host_lock); diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.h b/trunk/drivers/scsi/lpfc/lpfc_sli.h index 41c38d324ab0..a43549959dc7 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.h +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -39,10 +39,9 @@ struct lpfc_iocbq { IOCB_t iocb; /* IOCB cmd */ uint8_t retry; /* retry counter for IOCB cmd - if needed */ uint8_t iocb_flag; -#define LPFC_IO_LIBDFC 1 /* libdfc iocb */ -#define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */ -#define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */ -#define LPFC_DRIVER_ABORTED 8 /* driver aborted this request */ +#define LPFC_IO_LIBDFC 1 /* libdfc iocb */ +#define LPFC_IO_WAKE 2 /* High Priority Queue signal flag */ +#define LPFC_IO_FCP 4 /* FCP command -- iocbq in scsi_buf */ uint8_t abort_count; uint8_t rsvd2; @@ -68,8 +67,6 @@ struct lpfc_iocbq { #define IOCB_ERROR 2 #define IOCB_TIMEDOUT 3 -#define LPFC_MBX_WAKE 1 - typedef struct lpfcMboxq { /* MBOXQs are used in single linked lists */ struct list_head list; /* ptr to next mailbox command */ @@ -78,7 +75,6 @@ typedef struct lpfcMboxq { void *context2; /* caller context information */ void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *); - uint8_t mbox_flag; } LPFC_MBOXQ_t; diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index 92a9107019d2..a61ef3d1e7f1 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2004-2007 Emulex. All rights reserved. * + * Copyright (C) 2004-2006 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.emulex.com * * * @@ -18,12 +18,12 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.1.12" +#define LPFC_DRIVER_VERSION "8.1.11" #define LPFC_DRIVER_NAME "lpfc" #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ LPFC_DRIVER_VERSION -#define LPFC_COPYRIGHT "Copyright(c) 2004-2007 Emulex. All rights reserved." +#define LPFC_COPYRIGHT "Copyright(c) 2004-2006 Emulex. All rights reserved." #define DFC_API_VERSION "0.0.0" diff --git a/trunk/drivers/scsi/mac53c94.c b/trunk/drivers/scsi/mac53c94.c index 5806ede120a4..753d88306cd1 100644 --- a/trunk/drivers/scsi/mac53c94.c +++ b/trunk/drivers/scsi/mac53c94.c @@ -471,7 +471,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat goto out_free; } - clkprop = of_get_property(node, "clock-frequency", &proplen); + clkprop = get_property(node, "clock-frequency", &proplen); if (clkprop == NULL || proplen != sizeof(int)) { printk(KERN_ERR "%s: can't get clock frequency, " "assuming 25MHz\n", node->full_name); diff --git a/trunk/drivers/scsi/megaraid.c b/trunk/drivers/scsi/megaraid.c index 3cce75d70263..0aa3304f6b9b 100644 --- a/trunk/drivers/scsi/megaraid.c +++ b/trunk/drivers/scsi/megaraid.c @@ -1754,8 +1754,7 @@ __mega_busywait_mbox (adapter_t *adapter) for (counter = 0; counter < 10000; counter++) { if (!mbox->m_in.busy) return 0; - udelay(100); - cond_resched(); + udelay(100); yield(); } return -1; /* give up after 1 second */ } @@ -2089,7 +2088,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor) static inline int make_local_pdev(adapter_t *adapter, struct pci_dev **pdev) { - *pdev = alloc_pci_dev(); + *pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); if( *pdev == NULL ) return -1; @@ -3178,10 +3177,7 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) return len; } -#else -static inline void mega_create_proc_entry(int index, struct proc_dir_entry *parent) -{ -} + #endif @@ -4346,7 +4342,7 @@ mega_support_cluster(adapter_t *adapter) return 0; } -#ifdef CONFIG_PROC_FS + /** * mega_adapinq() * @adapter - pointer to our soft state @@ -4451,7 +4447,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, return rval; } -#endif + /** * mega_internal_command() @@ -4969,6 +4965,7 @@ megaraid_remove_one(struct pci_dev *pdev) { struct Scsi_Host *host = pci_get_drvdata(pdev); adapter_t *adapter = (adapter_t *)host->hostdata; + char buf[12] = { 0 }; scsi_remove_host(host); @@ -5014,11 +5011,8 @@ megaraid_remove_one(struct pci_dev *pdev) remove_proc_entry("raiddrives-30-39", adapter->controller_proc_dir_entry); #endif - { - char buf[12] = { 0 }; - sprintf(buf, "hba%d", adapter->host->host_no); - remove_proc_entry(buf, mega_proc_dir_entry); - } + sprintf(buf, "hba%d", adapter->host->host_no); + remove_proc_entry(buf, mega_proc_dir_entry); } #endif diff --git a/trunk/drivers/scsi/megaraid.h b/trunk/drivers/scsi/megaraid.h index ee70bd4ae4ba..c6e74643abe2 100644 --- a/trunk/drivers/scsi/megaraid.h +++ b/trunk/drivers/scsi/megaraid.h @@ -1002,6 +1002,7 @@ static int megaraid_reset(Scsi_Cmnd *); static int megaraid_abort_and_reset(adapter_t *, Scsi_Cmnd *, int); static int megaraid_biosparam(struct scsi_device *, struct block_device *, sector_t, int []); +static int mega_print_inquiry(char *, char *); static int mega_build_sglist (adapter_t *adapter, scb_t *scb, u32 *buffer, u32 *length); @@ -1023,7 +1024,6 @@ static int mega_init_scb (adapter_t *); static int mega_is_bios_enabled (adapter_t *); #ifdef CONFIG_PROC_FS -static int mega_print_inquiry(char *, char *); static void mega_create_proc_entry(int, struct proc_dir_entry *); static int proc_read_config(char *, char **, off_t, int, int *, void *); static int proc_read_stat(char *, char **, off_t, int, int *, void *); @@ -1040,10 +1040,10 @@ static int proc_rdrv_20(char *, char **, off_t, int, int *, void *); static int proc_rdrv_30(char *, char **, off_t, int, int *, void *); static int proc_rdrv_40(char *, char **, off_t, int, int *, void *); static int proc_rdrv(adapter_t *, char *, int, int); +#endif static int mega_adapinq(adapter_t *, dma_addr_t); static int mega_internal_dev_inquiry(adapter_t *, u8, u8, dma_addr_t); -#endif static int mega_support_ext_cdb(adapter_t *); static mega_passthru* mega_prepare_passthru(adapter_t *, scb_t *, diff --git a/trunk/drivers/scsi/megaraid/megaraid_mm.c b/trunk/drivers/scsi/megaraid/megaraid_mm.c index e075a52ac104..f33a678f0897 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_mm.c +++ b/trunk/drivers/scsi/megaraid/megaraid_mm.c @@ -60,7 +60,7 @@ EXPORT_SYMBOL(mraid_mm_unregister_adp); EXPORT_SYMBOL(mraid_mm_adapter_app_handle); static int majorno; -static uint32_t drvr_ver = 0x02200207; +static uint32_t drvr_ver = 0x02200206; static int adapters_count_g; static struct list_head adapters_list_g; diff --git a/trunk/drivers/scsi/mesh.c b/trunk/drivers/scsi/mesh.c index e64d1a19d8d7..1fd3c7590d31 100644 --- a/trunk/drivers/scsi/mesh.c +++ b/trunk/drivers/scsi/mesh.c @@ -185,7 +185,7 @@ struct mesh_state { * Driver is too messy, we need a few prototypes... */ static void mesh_done(struct mesh_state *ms, int start_next); -static void mesh_interrupt(struct mesh_state *ms); +static void mesh_interrupt(int irq, void *dev_id); static void cmd_complete(struct mesh_state *ms); static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd); static void halt_dma(struct mesh_state *ms); @@ -466,7 +466,7 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd) dlog(ms, "intr b4 arb, intr/exc/err/fc=%.8x", MKWORD(mr->interrupt, mr->exception, mr->error, mr->fifo_count)); - mesh_interrupt(ms); + mesh_interrupt(0, (void *)ms); if (ms->phase != arbitrating) return; } @@ -504,7 +504,7 @@ static void mesh_start_cmd(struct mesh_state *ms, struct scsi_cmnd *cmd) dlog(ms, "intr after disresel, intr/exc/err/fc=%.8x", MKWORD(mr->interrupt, mr->exception, mr->error, mr->fifo_count)); - mesh_interrupt(ms); + mesh_interrupt(0, (void *)ms); if (ms->phase != arbitrating) return; dlog(ms, "after intr after disresel, intr/exc/err/fc=%.8x", @@ -1018,11 +1018,10 @@ static void handle_reset(struct mesh_state *ms) static irqreturn_t do_mesh_interrupt(int irq, void *dev_id) { unsigned long flags; - struct mesh_state *ms = dev_id; - struct Scsi_Host *dev = ms->host; + struct Scsi_Host *dev = ((struct mesh_state *)dev_id)->host; spin_lock_irqsave(dev->host_lock, flags); - mesh_interrupt(ms); + mesh_interrupt(irq, dev_id); spin_unlock_irqrestore(dev->host_lock, flags); return IRQ_HANDLED; } @@ -1662,8 +1661,9 @@ static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) * handler (do_mesh_interrupt) or by other functions in * exceptional circumstances */ -static void mesh_interrupt(struct mesh_state *ms) +static void mesh_interrupt(int irq, void *dev_id) { + struct mesh_state *ms = (struct mesh_state *) dev_id; volatile struct mesh_regs __iomem *mr = ms->mesh; int intr; @@ -1947,7 +1947,7 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match) ms->tgts[tgt].current_req = NULL; } - if ((cfp = of_get_property(mesh, "clock-frequency", NULL))) + if ((cfp = get_property(mesh, "clock-frequency", NULL))) ms->clk_freq = *cfp; else { printk(KERN_INFO "mesh: assuming 50MHz clock frequency\n"); diff --git a/trunk/drivers/scsi/osst.c b/trunk/drivers/scsi/osst.c index 08060fb478b6..a967fadb7439 100644 --- a/trunk/drivers/scsi/osst.c +++ b/trunk/drivers/scsi/osst.c @@ -87,7 +87,6 @@ MODULE_AUTHOR("Willem Riede"); MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(OSST_MAJOR); -MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE); module_param(max_dev, int, 0444); MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); diff --git a/trunk/drivers/scsi/pci2000.h b/trunk/drivers/scsi/pci2000.h new file mode 100644 index 000000000000..0ebd8ce9e1de --- /dev/null +++ b/trunk/drivers/scsi/pci2000.h @@ -0,0 +1,197 @@ +/**************************************************************************** + * Perceptive Solutions, Inc. PCI-2000 device driver for Linux. + * + * pci2000.h - Linux Host Driver for PCI-2000 IntelliCache SCSI Adapters + * + * Copyright (c) 1997-1999 Perceptive Solutions, Inc. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that redistributions of source + * code retain the above copyright notice and this comment without + * modification. + * + * Technical updates and product information at: + * http://www.psidisk.com + * + * Please send questions, comments, bug reports to: + * tech@psidisk.com Technical Support + * + ****************************************************************************/ +#ifndef _PCI2000_H +#define _PCI2000_H + +#include + +#ifndef PSI_EIDE_SCSIOP +#define PSI_EIDE_SCSIOP 1 + +#define LINUXVERSION(v,p,s) (((v)<<16) + ((p)<<8) + (s)) + +/************************************************/ +/* definition of standard data types */ +/************************************************/ +#define CHAR char +#define UCHAR unsigned char +#define SHORT short +#define USHORT unsigned short +#define BOOL long +#define LONG long +#define ULONG unsigned long +#define VOID void + +typedef CHAR *PCHAR; +typedef UCHAR *PUCHAR; +typedef SHORT *PSHORT; +typedef USHORT *PUSHORT; +typedef BOOL *PBOOL; +typedef LONG *PLONG; +typedef ULONG *PULONG; +typedef VOID *PVOID; + + +/************************************************/ +/* Misc. macros */ +/************************************************/ +#define ANY2SCSI(up, p) \ +((UCHAR *)up)[0] = (((ULONG)(p)) >> 8); \ +((UCHAR *)up)[1] = ((ULONG)(p)); + +#define SCSI2LONG(up) \ +( (((long)*(((UCHAR *)up))) << 16) \ ++ (((long)(((UCHAR *)up)[1])) << 8) \ ++ ((long)(((UCHAR *)up)[2])) ) + +#define XANY2SCSI(up, p) \ +((UCHAR *)up)[0] = ((long)(p)) >> 24; \ +((UCHAR *)up)[1] = ((long)(p)) >> 16; \ +((UCHAR *)up)[2] = ((long)(p)) >> 8; \ +((UCHAR *)up)[3] = ((long)(p)); + +#define XSCSI2LONG(up) \ +( (((long)(((UCHAR *)up)[0])) << 24) \ ++ (((long)(((UCHAR *)up)[1])) << 16) \ ++ (((long)(((UCHAR *)up)[2])) << 8) \ ++ ((long)(((UCHAR *)up)[3])) ) + +/************************************************/ +/* SCSI CDB operation codes */ +/************************************************/ +#define SCSIOP_TEST_UNIT_READY 0x00 +#define SCSIOP_REZERO_UNIT 0x01 +#define SCSIOP_REWIND 0x01 +#define SCSIOP_REQUEST_BLOCK_ADDR 0x02 +#define SCSIOP_REQUEST_SENSE 0x03 +#define SCSIOP_FORMAT_UNIT 0x04 +#define SCSIOP_READ_BLOCK_LIMITS 0x05 +#define SCSIOP_REASSIGN_BLOCKS 0x07 +#define SCSIOP_READ6 0x08 +#define SCSIOP_RECEIVE 0x08 +#define SCSIOP_WRITE6 0x0A +#define SCSIOP_PRINT 0x0A +#define SCSIOP_SEND 0x0A +#define SCSIOP_SEEK6 0x0B +#define SCSIOP_TRACK_SELECT 0x0B +#define SCSIOP_SLEW_PRINT 0x0B +#define SCSIOP_SEEK_BLOCK 0x0C +#define SCSIOP_PARTITION 0x0D +#define SCSIOP_READ_REVERSE 0x0F +#define SCSIOP_WRITE_FILEMARKS 0x10 +#define SCSIOP_FLUSH_BUFFER 0x10 +#define SCSIOP_SPACE 0x11 +#define SCSIOP_INQUIRY 0x12 +#define SCSIOP_VERIFY6 0x13 +#define SCSIOP_RECOVER_BUF_DATA 0x14 +#define SCSIOP_MODE_SELECT 0x15 +#define SCSIOP_RESERVE_UNIT 0x16 +#define SCSIOP_RELEASE_UNIT 0x17 +#define SCSIOP_COPY 0x18 +#define SCSIOP_ERASE 0x19 +#define SCSIOP_MODE_SENSE 0x1A +#define SCSIOP_START_STOP_UNIT 0x1B +#define SCSIOP_STOP_PRINT 0x1B +#define SCSIOP_LOAD_UNLOAD 0x1B +#define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C +#define SCSIOP_SEND_DIAGNOSTIC 0x1D +#define SCSIOP_MEDIUM_REMOVAL 0x1E +#define SCSIOP_READ_CAPACITY 0x25 +#define SCSIOP_READ 0x28 +#define SCSIOP_WRITE 0x2A +#define SCSIOP_SEEK 0x2B +#define SCSIOP_LOCATE 0x2B +#define SCSIOP_WRITE_VERIFY 0x2E +#define SCSIOP_VERIFY 0x2F +#define SCSIOP_SEARCH_DATA_HIGH 0x30 +#define SCSIOP_SEARCH_DATA_EQUAL 0x31 +#define SCSIOP_SEARCH_DATA_LOW 0x32 +#define SCSIOP_SET_LIMITS 0x33 +#define SCSIOP_READ_POSITION 0x34 +#define SCSIOP_SYNCHRONIZE_CACHE 0x35 +#define SCSIOP_COMPARE 0x39 +#define SCSIOP_COPY_COMPARE 0x3A +#define SCSIOP_WRITE_DATA_BUFF 0x3B +#define SCSIOP_READ_DATA_BUFF 0x3C +#define SCSIOP_CHANGE_DEFINITION 0x40 +#define SCSIOP_READ_SUB_CHANNEL 0x42 +#define SCSIOP_READ_TOC 0x43 +#define SCSIOP_READ_HEADER 0x44 +#define SCSIOP_PLAY_AUDIO 0x45 +#define SCSIOP_PLAY_AUDIO_MSF 0x47 +#define SCSIOP_PLAY_TRACK_INDEX 0x48 +#define SCSIOP_PLAY_TRACK_RELATIVE 0x49 +#define SCSIOP_PAUSE_RESUME 0x4B +#define SCSIOP_LOG_SELECT 0x4C +#define SCSIOP_LOG_SENSE 0x4D +#define SCSIOP_MODE_SELECT10 0x55 +#define SCSIOP_MODE_SENSE10 0x5A +#define SCSIOP_LOAD_UNLOAD_SLOT 0xA6 +#define SCSIOP_MECHANISM_STATUS 0xBD +#define SCSIOP_READ_CD 0xBE + +// SCSI read capacity structure +typedef struct _READ_CAPACITY_DATA + { + ULONG blks; /* total blocks (converted to little endian) */ + ULONG blksiz; /* size of each (converted to little endian) */ + } READ_CAPACITY_DATA, *PREAD_CAPACITY_DATA; + +// SCSI inquiry data +typedef struct _INQUIRYDATA + { + UCHAR DeviceType :5; + UCHAR DeviceTypeQualifier :3; + UCHAR DeviceTypeModifier :7; + UCHAR RemovableMedia :1; + UCHAR Versions; + UCHAR ResponseDataFormat; + UCHAR AdditionalLength; + UCHAR Reserved[2]; + UCHAR SoftReset :1; + UCHAR CommandQueue :1; + UCHAR Reserved2 :1; + UCHAR LinkedCommands :1; + UCHAR Synchronous :1; + UCHAR Wide16Bit :1; + UCHAR Wide32Bit :1; + UCHAR RelativeAddressing :1; + UCHAR VendorId[8]; + UCHAR ProductId[16]; + UCHAR ProductRevisionLevel[4]; + UCHAR VendorSpecific[20]; + UCHAR Reserved3[40]; + } INQUIRYDATA, *PINQUIRYDATA; + +#endif + +// function prototypes +int Pci2000_Detect (struct scsi_host_template *tpnt); +int Pci2000_Command (Scsi_Cmnd *SCpnt); +int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)); +int Pci2000_Abort (Scsi_Cmnd *SCpnt); +int Pci2000_Reset (Scsi_Cmnd *SCpnt, unsigned int flags); +int Pci2000_Release (struct Scsi_Host *pshost); +int Pci2000_BiosParam (struct scsi_device *sdev, + struct block_device *bdev, + sector_t capacity, int geom[]); + +#endif diff --git a/trunk/drivers/scsi/pcmcia/Kconfig b/trunk/drivers/scsi/pcmcia/Kconfig index 7dd787f6ab27..eac8e179cfff 100644 --- a/trunk/drivers/scsi/pcmcia/Kconfig +++ b/trunk/drivers/scsi/pcmcia/Kconfig @@ -3,11 +3,11 @@ # menu "PCMCIA SCSI adapter support" - depends on SCSI!=n && PCMCIA!=n + depends on SCSI!=n && PCMCIA!=n && MODULES config PCMCIA_AHA152X tristate "Adaptec AHA152X PCMCIA support" - depends on !64BIT + depends on m && !64BIT select SCSI_SPI_ATTRS help Say Y here if you intend to attach this type of PCMCIA SCSI host @@ -18,6 +18,7 @@ config PCMCIA_AHA152X config PCMCIA_FDOMAIN tristate "Future Domain PCMCIA support" + depends on m help Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. @@ -27,7 +28,7 @@ config PCMCIA_FDOMAIN config PCMCIA_NINJA_SCSI tristate "NinjaSCSI-3 / NinjaSCSI-32Bi (16bit) PCMCIA support" - depends on !64BIT + depends on m && !64BIT help If you intend to attach this type of PCMCIA SCSI host adapter to your computer, say Y here and read @@ -61,6 +62,7 @@ config PCMCIA_NINJA_SCSI config PCMCIA_QLOGIC tristate "Qlogic PCMCIA support" + depends on m help Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. @@ -70,6 +72,7 @@ config PCMCIA_QLOGIC config PCMCIA_SYM53C500 tristate "Symbios 53c500 PCMCIA support" + depends on m help Say Y here if you have a New Media Bus Toaster or other PCMCIA SCSI adapter based on the Symbios 53c500 controller. diff --git a/trunk/drivers/scsi/qla1280.c b/trunk/drivers/scsi/qla1280.c index 54d8bdf86852..6777e8a69153 100644 --- a/trunk/drivers/scsi/qla1280.c +++ b/trunk/drivers/scsi/qla1280.c @@ -4293,7 +4293,7 @@ qla1280_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->devnum = devnum; /* specifies microcode load address */ #ifdef QLA_64BIT_PTR - if (pci_set_dma_mask(ha->pdev, DMA_64BIT_MASK)) { + if (pci_set_dma_mask(ha->pdev, (dma_addr_t) ~ 0ULL)) { if (pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK)) { printk(KERN_WARNING "scsi(%li): Unable to set a " "suitable DMA mask - aborting\n", ha->host_no); diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index e8948b679f5b..05f4f2a378eb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -1478,17 +1478,14 @@ typedef union { uint32_t b24 : 24; struct { -#ifdef __BIG_ENDIAN - uint8_t domain; - uint8_t area; - uint8_t al_pa; -#elif __LITTLE_ENDIAN + uint8_t d_id[3]; + uint8_t rsvd_1; + } r; + + struct { uint8_t al_pa; uint8_t area; uint8_t domain; -#else -#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!" -#endif uint8_t rsvd_1; } b; } port_id_t; diff --git a/trunk/drivers/scsi/qla2xxx/qla_init.c b/trunk/drivers/scsi/qla2xxx/qla_init.c index 2a45aec4ff29..98c01cd5e1a8 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_init.c +++ b/trunk/drivers/scsi/qla2xxx/qla_init.c @@ -11,10 +11,6 @@ #include "qla_devtbl.h" -#ifdef CONFIG_SPARC -#include -#endif - /* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */ #ifndef EXT_IS_LUN_BIT_SET #define EXT_IS_LUN_BIT_SET(P,L) \ @@ -92,7 +88,12 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) qla_printk(KERN_INFO, ha, "Configure NVRAM parameters...\n"); - ha->isp_ops.nvram_config(ha); + rval = ha->isp_ops.nvram_config(ha); + if (rval) { + DEBUG2(printk("scsi(%ld): Unable to verify NVRAM data.\n", + ha->host_no)); + return rval; + } if (ha->flags.disable_serdes) { /* Mask HBA via NVRAM settings? */ @@ -129,17 +130,18 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) int qla2100_pci_config(scsi_qla_host_t *ha) { - int ret; - uint16_t w; + uint16_t w, mwi; uint32_t d; unsigned long flags; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; pci_set_master(ha->pdev); - ret = pci_set_mwi(ha->pdev); + mwi = 0; + if (pci_set_mwi(ha->pdev)) + mwi = PCI_COMMAND_INVALIDATE; pci_read_config_word(ha->pdev, PCI_COMMAND, &w); - w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); pci_write_config_word(ha->pdev, PCI_COMMAND, w); /* Reset expansion ROM address decode enable */ @@ -164,22 +166,22 @@ qla2100_pci_config(scsi_qla_host_t *ha) int qla2300_pci_config(scsi_qla_host_t *ha) { - int ret; - uint16_t w; + uint16_t w, mwi; uint32_t d; unsigned long flags = 0; uint32_t cnt; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; pci_set_master(ha->pdev); - ret = pci_set_mwi(ha->pdev); + mwi = 0; + if (pci_set_mwi(ha->pdev)) + mwi = PCI_COMMAND_INVALIDATE; pci_read_config_word(ha->pdev, PCI_COMMAND, &w); - w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); if (IS_QLA2322(ha) || IS_QLA6322(ha)) w &= ~PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(ha->pdev, PCI_COMMAND, w); /* * If this is a 2300 card and not 2312, reset the @@ -208,7 +210,7 @@ qla2300_pci_config(scsi_qla_host_t *ha) ha->fb_rev = RD_FB_CMD_REG(ha, reg); if (ha->fb_rev == FPM_2300) - pci_clear_mwi(ha->pdev); + w &= ~PCI_COMMAND_INVALIDATE; /* Deselect FPM registers. */ WRT_REG_WORD(®->ctrl_status, 0x0); @@ -225,6 +227,7 @@ qla2300_pci_config(scsi_qla_host_t *ha) spin_unlock_irqrestore(&ha->hardware_lock, flags); } + pci_write_config_word(ha->pdev, PCI_COMMAND, w); pci_write_config_byte(ha->pdev, PCI_LATENCY_TIMER, 0x80); @@ -250,18 +253,19 @@ qla2300_pci_config(scsi_qla_host_t *ha) int qla24xx_pci_config(scsi_qla_host_t *ha) { - int ret; - uint16_t w; + uint16_t w, mwi; uint32_t d; unsigned long flags = 0; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; int pcix_cmd_reg, pcie_dctl_reg; pci_set_master(ha->pdev); - ret = pci_set_mwi(ha->pdev); + mwi = 0; + if (pci_set_mwi(ha->pdev)) + mwi = PCI_COMMAND_INVALIDATE; pci_read_config_word(ha->pdev, PCI_COMMAND, &w); - w |= (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); + w |= mwi | (PCI_COMMAND_PARITY | PCI_COMMAND_SERR); w &= ~PCI_COMMAND_INTX_DISABLE; pci_write_config_word(ha->pdev, PCI_COMMAND, w); @@ -1389,27 +1393,6 @@ qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *de } } -/* On sparc systems, obtain port and node WWN from firmware - * properties. - */ -static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, nvram_t *nv) -{ -#ifdef CONFIG_SPARC - struct pci_dev *pdev = ha->pdev; - struct device_node *dp = pci_device_to_OF_node(pdev); - const u8 *val; - int len; - - val = of_get_property(dp, "port-wwn", &len); - if (val && len >= WWN_SIZE) - memcpy(nv->port_name, val, WWN_SIZE); - - val = of_get_property(dp, "node-wwn", &len); - if (val && len >= WWN_SIZE) - memcpy(nv->node_name, val, WWN_SIZE); -#endif -} - /* * NVRAM configuration for ISP 2xxx * @@ -1426,7 +1409,6 @@ static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, nvram_t *nv) int qla2x00_nvram_config(scsi_qla_host_t *ha) { - int rval; uint8_t chksum = 0; uint16_t cnt; uint8_t *dptr1, *dptr2; @@ -1435,8 +1417,6 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) uint8_t *ptr = (uint8_t *)ha->request_ring; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; - rval = QLA_SUCCESS; - /* Determine NVRAM starting address. */ ha->nvram_size = sizeof(nvram_t); ha->nvram_base = 0; @@ -1460,57 +1440,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], nv->nvram_version); - qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " - "invalid -- WWPN) defaults.\n"); - - /* - * Set default initialization control block. - */ - memset(nv, 0, ha->nvram_size); - nv->parameter_block_version = ICB_VERSION; - - if (IS_QLA23XX(ha)) { - nv->firmware_options[0] = BIT_2 | BIT_1; - nv->firmware_options[1] = BIT_7 | BIT_5; - nv->add_firmware_options[0] = BIT_5; - nv->add_firmware_options[1] = BIT_5 | BIT_4; - nv->frame_payload_size = __constant_cpu_to_le16(2048); - nv->special_options[1] = BIT_7; - } else if (IS_QLA2200(ha)) { - nv->firmware_options[0] = BIT_2 | BIT_1; - nv->firmware_options[1] = BIT_7 | BIT_5; - nv->add_firmware_options[0] = BIT_5; - nv->add_firmware_options[1] = BIT_5 | BIT_4; - nv->frame_payload_size = __constant_cpu_to_le16(1024); - } else if (IS_QLA2100(ha)) { - nv->firmware_options[0] = BIT_3 | BIT_1; - nv->firmware_options[1] = BIT_5; - nv->frame_payload_size = __constant_cpu_to_le16(1024); - } - - nv->max_iocb_allocation = __constant_cpu_to_le16(256); - nv->execution_throttle = __constant_cpu_to_le16(16); - nv->retry_count = 8; - nv->retry_delay = 1; - - nv->port_name[0] = 33; - nv->port_name[3] = 224; - nv->port_name[4] = 139; - - qla2xxx_nvram_wwn_from_ofw(ha, nv); - - nv->login_timeout = 4; - - /* - * Set default host adapter parameters - */ - nv->host_p[1] = BIT_2; - nv->reset_delay = 5; - nv->port_down_retry_count = 8; - nv->max_luns_per_target = __constant_cpu_to_le16(8); - nv->link_down_timeout = 60; - - rval = 1; + return QLA_FUNCTION_FAILED; } #if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) @@ -1723,11 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) } } - if (rval) { - DEBUG2_3(printk(KERN_WARNING - "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); - } - return (rval); + return QLA_SUCCESS; } static void @@ -3145,7 +3071,9 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) ha->isp_ops.get_flash_version(ha, ha->request_ring); - ha->isp_ops.nvram_config(ha); + rval = ha->isp_ops.nvram_config(ha); + if (rval) + goto isp_abort_retry; if (!qla2x00_restart_isp(ha)) { clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); @@ -3175,6 +3103,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) } } } else { /* failed the ISP abort */ +isp_abort_retry: ha->flags.online = 1; if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { if (ha->isp_abort_cnt == 0) { @@ -3361,31 +3290,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *ha) spin_unlock_irqrestore(&ha->hardware_lock, flags); } -/* On sparc systems, obtain port and node WWN from firmware - * properties. - */ -static void qla24xx_nvram_wwn_from_ofw(scsi_qla_host_t *ha, struct nvram_24xx *nv) -{ -#ifdef CONFIG_SPARC - struct pci_dev *pdev = ha->pdev; - struct device_node *dp = pci_device_to_OF_node(pdev); - const u8 *val; - int len; - - val = of_get_property(dp, "port-wwn", &len); - if (val && len >= WWN_SIZE) - memcpy(nv->port_name, val, WWN_SIZE); - - val = of_get_property(dp, "node-wwn", &len); - if (val && len >= WWN_SIZE) - memcpy(nv->node_name, val, WWN_SIZE); -#endif -} - int qla24xx_nvram_config(scsi_qla_host_t *ha) { - int rval; struct init_cb_24xx *icb; struct nvram_24xx *nv; uint32_t *dptr; @@ -3393,7 +3300,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) uint32_t chksum; uint16_t cnt; - rval = QLA_SUCCESS; icb = (struct init_cb_24xx *)ha->init_cb; nv = (struct nvram_24xx *)ha->request_ring; @@ -3426,52 +3332,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) qla_printk(KERN_WARNING, ha, "Inconsistent NVRAM detected: " "checksum=0x%x id=%c version=0x%x.\n", chksum, nv->id[0], le16_to_cpu(nv->nvram_version)); - qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " - "invalid -- WWPN) defaults.\n"); - - /* - * Set default initialization control block. - */ - memset(nv, 0, ha->nvram_size); - nv->nvram_version = __constant_cpu_to_le16(ICB_VERSION); - nv->version = __constant_cpu_to_le16(ICB_VERSION); - nv->frame_payload_size = __constant_cpu_to_le16(2048); - nv->execution_throttle = __constant_cpu_to_le16(0xFFFF); - nv->exchange_count = __constant_cpu_to_le16(0); - nv->hard_address = __constant_cpu_to_le16(124); - nv->port_name[0] = 0x21; - nv->port_name[1] = 0x00 + PCI_FUNC(ha->pdev->devfn); - nv->port_name[2] = 0x00; - nv->port_name[3] = 0xe0; - nv->port_name[4] = 0x8b; - nv->port_name[5] = 0x1c; - nv->port_name[6] = 0x55; - nv->port_name[7] = 0x86; - nv->node_name[0] = 0x20; - nv->node_name[1] = 0x00; - nv->node_name[2] = 0x00; - nv->node_name[3] = 0xe0; - nv->node_name[4] = 0x8b; - nv->node_name[5] = 0x1c; - nv->node_name[6] = 0x55; - nv->node_name[7] = 0x86; - qla24xx_nvram_wwn_from_ofw(ha, nv); - nv->login_retry_count = __constant_cpu_to_le16(8); - nv->interrupt_delay_timer = __constant_cpu_to_le16(0); - nv->login_timeout = __constant_cpu_to_le16(0); - nv->firmware_options_1 = - __constant_cpu_to_le32(BIT_14|BIT_13|BIT_2|BIT_1); - nv->firmware_options_2 = __constant_cpu_to_le32(2 << 4); - nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12); - nv->firmware_options_3 = __constant_cpu_to_le32(2 << 13); - nv->host_p = __constant_cpu_to_le32(BIT_11|BIT_10); - nv->efi_parameters = __constant_cpu_to_le32(0); - nv->reset_delay = 5; - nv->max_luns_per_target = __constant_cpu_to_le16(128); - nv->port_down_retry_count = __constant_cpu_to_le16(30); - nv->link_down_timeout = __constant_cpu_to_le16(30); - - rval = 1; + return QLA_FUNCTION_FAILED; } /* Reset Initialization control block */ @@ -3618,11 +3479,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) ha->flags.process_response_queue = 1; } - if (rval) { - DEBUG2_3(printk(KERN_WARNING - "scsi(%ld): NVRAM configuration failed!\n", ha->host_no)); - } - return (rval); + return QLA_SUCCESS; } static int @@ -3925,8 +3782,6 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) return; - if (!ha->fw_major_version) - return; ret = qla2x00_stop_firmware(ha); for (retries = 5; ret != QLA_SUCCESS && retries ; retries--) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index ca463469063d..d4885616cd39 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -1726,17 +1726,6 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) qla_printk(KERN_WARNING, ha, "MSI-X: Falling back-to INTa mode -- %d.\n", ret); skip_msix: - - if (!IS_QLA24XX(ha)) - goto skip_msi; - - ret = pci_enable_msi(ha->pdev); - if (!ret) { - DEBUG2(qla_printk(KERN_INFO, ha, "MSI: Enabled.\n")); - ha->flags.msi_enabled = 1; - } -skip_msi: - ret = request_irq(ha->pdev->irq, ha->isp_ops.intr_handler, IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha); if (!ret) { @@ -1757,8 +1746,6 @@ qla2x00_free_irqs(scsi_qla_host_t *ha) if (ha->flags.msix_enabled) qla24xx_disable_msix(ha); - else if (ha->flags.inta_enabled) { + else if (ha->flags.inta_enabled) free_irq(ha->host->irq, ha); - pci_disable_msi(ha->pdev); - } } diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index 71e32a248528..83376f6ac3db 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -1280,14 +1280,14 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, } else { if (name != NULL) { /* This function returns name in big endian. */ - name[0] = MSB(mcp->mb[2]); - name[1] = LSB(mcp->mb[2]); - name[2] = MSB(mcp->mb[3]); - name[3] = LSB(mcp->mb[3]); - name[4] = MSB(mcp->mb[6]); - name[5] = LSB(mcp->mb[6]); - name[6] = MSB(mcp->mb[7]); - name[7] = LSB(mcp->mb[7]); + name[0] = LSB(mcp->mb[2]); + name[1] = MSB(mcp->mb[2]); + name[2] = LSB(mcp->mb[3]); + name[3] = MSB(mcp->mb[3]); + name[4] = LSB(mcp->mb[6]); + name[5] = MSB(mcp->mb[6]); + name[6] = LSB(mcp->mb[7]); + name[7] = MSB(mcp->mb[7]); } DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index dd076da86a46..68f5d24b938b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -36,7 +36,7 @@ module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xlogintimeout, "Login timeout value in seconds."); -int qlport_down_retry; +int qlport_down_retry = 30; module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(qlport_down_retry, "Maximum number of command retries to a port that returns " @@ -62,7 +62,7 @@ MODULE_PARM_DESC(ql2xallocfwdump, "vary by ISP type. Default is 1 - allocate memory."); int ql2xextended_error_logging; -module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR); +module_param(ql2xextended_error_logging, int, S_IRUGO|S_IRUSR); MODULE_PARM_DESC(ql2xextended_error_logging, "Option to enable extended error logging, " "Default is 0 - no logging. 1 - log errors."); @@ -157,8 +157,6 @@ static struct scsi_host_template qla24xx_driver_template = { .slave_alloc = qla2xxx_slave_alloc, .slave_destroy = qla2xxx_slave_destroy, - .scan_finished = qla2xxx_scan_finished, - .scan_start = qla2xxx_scan_start, .change_queue_depth = qla2x00_change_queue_depth, .change_queue_type = qla2x00_change_queue_type, .this_id = -1, @@ -1577,7 +1575,9 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) goto probe_failed; } - if (qla2x00_initialize_adapter(ha)) { + if (qla2x00_initialize_adapter(ha) && + !(ha->device_flags & DFLG_NO_CABLE)) { + qla_printk(KERN_WARNING, ha, "Failed to initialize adapter\n"); @@ -1705,7 +1705,6 @@ qla2x00_remove_one(struct pci_dev *pdev) scsi_host_put(ha->host); - pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); } @@ -1748,6 +1747,8 @@ qla2x00_free_device(scsi_qla_host_t *ha) if (ha->iobase) iounmap(ha->iobase); pci_release_regions(ha->pdev); + + pci_disable_device(ha->pdev); } static inline void diff --git a/trunk/drivers/scsi/qla2xxx/qla_sup.c b/trunk/drivers/scsi/qla2xxx/qla_sup.c index 206bda093da2..ff1dd4175a7f 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_sup.c +++ b/trunk/drivers/scsi/qla2xxx/qla_sup.c @@ -466,7 +466,6 @@ qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr) udelay(10); else rval = QLA_FUNCTION_TIMEOUT; - cond_resched(); } /* TODO: What happens if we time out? */ @@ -509,7 +508,6 @@ qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) udelay(10); else rval = QLA_FUNCTION_TIMEOUT; - cond_resched(); } return rval; } @@ -1257,7 +1255,6 @@ qla2x00_poll_flash(scsi_qla_host_t *ha, uint32_t addr, uint8_t poll_data, } udelay(10); barrier(); - cond_resched(); } return status; } @@ -1406,7 +1403,6 @@ qla2x00_read_flash_data(scsi_qla_host_t *ha, uint8_t *tmp_buf, uint32_t saddr, if (saddr % 100) udelay(10); *tmp_buf = data; - cond_resched(); } } @@ -1453,6 +1449,7 @@ uint8_t * qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, uint32_t offset, uint32_t length) { + unsigned long flags; uint32_t addr, midpoint; uint8_t *data; struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; @@ -1461,6 +1458,7 @@ qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, qla2x00_suspend_hba(ha); /* Go with read. */ + spin_lock_irqsave(&ha->hardware_lock, flags); midpoint = ha->optrom_size / 2; qla2x00_flash_enable(ha); @@ -1475,6 +1473,7 @@ qla2x00_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, *data = qla2x00_read_flash_byte(ha, addr); } qla2x00_flash_disable(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Resume HBA. */ qla2x00_resume_hba(ha); @@ -1488,6 +1487,7 @@ qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, { int rval; + unsigned long flags; uint8_t man_id, flash_id, sec_number, data; uint16_t wd; uint32_t addr, liter, sec_mask, rest_addr; @@ -1500,6 +1500,7 @@ qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, sec_number = 0; /* Reset ISP chip. */ + spin_lock_irqsave(&ha->hardware_lock, flags); WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); @@ -1688,10 +1689,10 @@ qla2x00_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, rval = QLA_FUNCTION_FAILED; break; } - cond_resched(); } } while (0); qla2x00_flash_disable(ha); + spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Resume HBA. */ qla2x00_resume_hba(ha); diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index c375a4efbc71..61347aee55ce 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.07-k7" +#define QLA2XXX_VERSION "8.01.07-k5" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 diff --git a/trunk/drivers/scsi/qla4xxx/ql4_dbg.c b/trunk/drivers/scsi/qla4xxx/ql4_dbg.c index 6437d024b0dd..7b4e077a39c1 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_dbg.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_dbg.c @@ -8,8 +8,6 @@ #include "ql4_def.h" #include -#if 0 - static void qla4xxx_print_srb_info(struct srb * srb) { printk("%s: srb = 0x%p, flags=0x%02x\n", __func__, srb, srb->flags); @@ -197,5 +195,3 @@ void qla4xxx_dump_buffer(void *b, uint32_t size) if (cnt % 16) printk(KERN_DEBUG "\n"); } - -#endif /* 0 */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h index 5b00cb04e7c0..e021eb5db2b2 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_glbl.h @@ -43,6 +43,8 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha, uint16_t *tcp_source_port_num, uint16_t *connection_id); +struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host * ha, + uint32_t fw_ddb_index); int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index, dma_addr_t fw_ddb_entry_dma); @@ -53,11 +55,18 @@ void qla4xxx_get_crash_record(struct scsi_qla_host * ha); struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha); int qla4xxx_add_sess(struct ddb_entry *); void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry); +int qla4xxx_conn_close_sess_logout(struct scsi_qla_host * ha, + uint16_t fw_ddb_index, + uint16_t connection_id, + uint16_t option); +int qla4xxx_clear_database_entry(struct scsi_qla_host * ha, + uint16_t fw_ddb_index); int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host * ha); int qla4xxx_get_fw_version(struct scsi_qla_host * ha); void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha, uint32_t intr_status); int qla4xxx_init_rings(struct scsi_qla_host * ha); +void qla4xxx_dump_buffer(void *b, uint32_t size); struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t index); void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb); int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_init.c b/trunk/drivers/scsi/qla4xxx/ql4_init.c index 6365df268612..b907b06d72ab 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_init.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_init.c @@ -7,8 +7,9 @@ #include "ql4_def.h" -static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, - uint32_t fw_ddb_index); +/* + * QLogic ISP4xxx Hardware Support Function Prototypes. + */ static void ql4xxx_set_mac_number(struct scsi_qla_host *ha) { @@ -47,8 +48,7 @@ static void ql4xxx_set_mac_number(struct scsi_qla_host *ha) * This routine deallocates and unlinks the specified ddb_entry from the * adapter's **/ -static void qla4xxx_free_ddb(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry) +void qla4xxx_free_ddb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry) { /* Remove device entry from list */ list_del_init(&ddb_entry->list); @@ -370,9 +370,9 @@ static struct ddb_entry* qla4xxx_get_ddb_entry(struct scsi_qla_host *ha, * must be initialized prior to calling this routine * **/ -static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry, - uint32_t fw_ddb_index) +int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, + struct ddb_entry *ddb_entry, + uint32_t fw_ddb_index) { struct dev_db_entry *fw_ddb_entry = NULL; dma_addr_t fw_ddb_entry_dma; @@ -450,8 +450,8 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha, * This routine allocates a ddb_entry, ititializes some values, and * inserts it into the ddb list. **/ -static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, - uint32_t fw_ddb_index) +struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha, + uint32_t fw_ddb_index) { struct ddb_entry *ddb_entry; diff --git a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c index a216a1781afb..d41ce380eedc 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c @@ -19,8 +19,8 @@ * - advances the request_in pointer * - checks for queue full **/ -static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, - struct queue_entry **queue_entry) +int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, + struct queue_entry **queue_entry) { uint16_t request_in; uint8_t status = QLA_SUCCESS; @@ -62,8 +62,8 @@ static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, * * This routine issues a marker IOCB. **/ -static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, - struct ddb_entry *ddb_entry, int lun) +int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, + struct ddb_entry *ddb_entry, int lun) { struct marker_entry *marker_entry; unsigned long flags = 0; @@ -96,7 +96,7 @@ static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, return status; } -static struct continuation_t1_entry* qla4xxx_alloc_cont_entry( +struct continuation_t1_entry* qla4xxx_alloc_cont_entry( struct scsi_qla_host *ha) { struct continuation_t1_entry *cont_entry; @@ -120,7 +120,7 @@ static struct continuation_t1_entry* qla4xxx_alloc_cont_entry( return cont_entry; } -static uint16_t qla4xxx_calc_request_entries(uint16_t dsds) +uint16_t qla4xxx_calc_request_entries(uint16_t dsds) { uint16_t iocbs; @@ -133,9 +133,9 @@ static uint16_t qla4xxx_calc_request_entries(uint16_t dsds) return iocbs; } -static void qla4xxx_build_scsi_iocbs(struct srb *srb, - struct command_t3_entry *cmd_entry, - uint16_t tot_dsds) +void qla4xxx_build_scsi_iocbs(struct srb *srb, + struct command_t3_entry *cmd_entry, + uint16_t tot_dsds) { struct scsi_qla_host *ha; uint16_t avail_dsds; diff --git a/trunk/drivers/scsi/qla4xxx/ql4_mbx.c b/trunk/drivers/scsi/qla4xxx/ql4_mbx.c index f116ff917237..7f28657eef3f 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_mbx.c @@ -20,9 +20,9 @@ * If outCount is 0, this routine completes successfully WITHOUT waiting * for the mailbox command to complete. **/ -static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, - uint8_t outCount, uint32_t *mbx_cmd, - uint32_t *mbx_sts) +int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, + uint8_t outCount, uint32_t *mbx_cmd, + uint32_t *mbx_sts) { int status = QLA_ERROR; uint8_t i; @@ -170,8 +170,6 @@ static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, } -#if 0 - /** * qla4xxx_issue_iocb - issue mailbox iocb command * @ha: adapter state pointer. @@ -245,8 +243,6 @@ int qla4xxx_clear_database_entry(struct scsi_qla_host * ha, return QLA_SUCCESS; } -#endif /* 0 */ - /** * qla4xxx_initialize_fw_cb - initializes firmware control block. * @ha: Pointer to host adapter structure. @@ -574,7 +570,6 @@ int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index, return qla4xxx_mailbox_command(ha, 4, 1, &mbox_cmd[0], &mbox_sts[0]); } -#if 0 int qla4xxx_conn_open_session_login(struct scsi_qla_host * ha, uint16_t fw_ddb_index) { @@ -599,7 +594,6 @@ int qla4xxx_conn_open_session_login(struct scsi_qla_host * ha, return status; } -#endif /* 0 */ /** * qla4xxx_get_crash_record - retrieves crash record. @@ -655,7 +649,6 @@ void qla4xxx_get_crash_record(struct scsi_qla_host * ha) crash_record, crash_record_dma); } -#if 0 /** * qla4xxx_get_conn_event_log - retrieves connection event log * @ha: Pointer to host adapter structure. @@ -745,7 +738,6 @@ void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha) dma_free_coherent(&ha->pdev->dev, event_log_size, event_log, event_log_dma); } -#endif /* 0 */ /** * qla4xxx_reset_lun - issues LUN Reset @@ -842,8 +834,7 @@ int qla4xxx_get_fw_version(struct scsi_qla_host * ha) return QLA_SUCCESS; } -static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, - dma_addr_t dma_addr) +int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, dma_addr_t dma_addr) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; @@ -864,7 +855,7 @@ static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, return QLA_SUCCESS; } -static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index) +int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index) { uint32_t mbox_cmd[MBOX_REG_COUNT]; uint32_t mbox_sts[MBOX_REG_COUNT]; diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index da21f5fbbf87..0bfddf893ed0 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -14,7 +14,7 @@ /* * Driver version */ -static char qla4xxx_version_str[40]; +char qla4xxx_version_str[40]; /* * SRB allocation cache @@ -45,7 +45,8 @@ int ql4_mod_unload = 0; /* * SCSI host template entry points */ -static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha); + +void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha); /* * iSCSI template entry points @@ -1351,7 +1352,7 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) * At exit, the @ha's flags.enable_64bit_addressing set to indicated * supported addressing method. */ -static void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha) +void qla4xxx_config_dma_addressing(struct scsi_qla_host *ha) { int retval; @@ -1626,7 +1627,7 @@ static struct pci_device_id qla4xxx_pci_tbl[] = { }; MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); -static struct pci_driver qla4xxx_pci_driver = { +struct pci_driver qla4xxx_pci_driver = { .name = DRIVER_NAME, .id_table = qla4xxx_pci_tbl, .probe = qla4xxx_probe_adapter, diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index 4c1e31334765..1c89ee3e69ba 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -344,6 +344,7 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost) void scsi_log_send(struct scsi_cmnd *cmd) { unsigned int level; + struct scsi_device *sdev; /* * If ML QUEUE log level is greater than or equal to: @@ -360,17 +361,22 @@ void scsi_log_send(struct scsi_cmnd *cmd) level = SCSI_LOG_LEVEL(SCSI_LOG_MLQUEUE_SHIFT, SCSI_LOG_MLQUEUE_BITS); if (level > 1) { - scmd_printk(KERN_INFO, cmd, "Send: "); + sdev = cmd->device; + sdev_printk(KERN_INFO, sdev, "send "); if (level > 2) printk("0x%p ", cmd); - printk("\n"); + /* + * spaces to match disposition and cmd->result + * output in scsi_log_completion. + */ + printk(" "); scsi_print_command(cmd); if (level > 3) { printk(KERN_INFO "buffer = 0x%p, bufflen = %d," " done = 0x%p, queuecommand 0x%p\n", cmd->request_buffer, cmd->request_bufflen, cmd->done, - cmd->device->host->hostt->queuecommand); + sdev->host->hostt->queuecommand); } } @@ -380,6 +386,7 @@ void scsi_log_send(struct scsi_cmnd *cmd) void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) { unsigned int level; + struct scsi_device *sdev; /* * If ML COMPLETE log level is greater than or equal to: @@ -398,7 +405,8 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) SCSI_LOG_MLCOMPLETE_BITS); if (((level > 0) && (cmd->result || disposition != SUCCESS)) || (level > 1)) { - scmd_printk(KERN_INFO, cmd, "Done: "); + sdev = cmd->device; + sdev_printk(KERN_INFO, sdev, "done "); if (level > 2) printk("0x%p ", cmd); /* @@ -407,35 +415,40 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) */ switch (disposition) { case SUCCESS: - printk("SUCCESS\n"); + printk("SUCCESS"); break; case NEEDS_RETRY: - printk("RETRY\n"); + printk("RETRY "); break; case ADD_TO_MLQUEUE: - printk("MLQUEUE\n"); + printk("MLQUEUE"); break; case FAILED: - printk("FAILED\n"); + printk("FAILED "); break; case TIMEOUT_ERROR: /* * If called via scsi_times_out. */ - printk("TIMEOUT\n"); + printk("TIMEOUT"); break; default: - printk("UNKNOWN\n"); + printk("UNKNOWN"); } - scsi_print_result(cmd); + printk(" %8x ", cmd->result); scsi_print_command(cmd); - if (status_byte(cmd->result) & CHECK_CONDITION) + if (status_byte(cmd->result) & CHECK_CONDITION) { + /* + * XXX The scsi_print_sense formatting/prefix + * doesn't match this function. + */ scsi_print_sense("", cmd); - if (level > 3) - scmd_printk(KERN_INFO, cmd, - "scsi host busy %d failed %d\n", - cmd->device->host->host_busy, - cmd->device->host->host_failed); + } + if (level > 3) { + printk(KERN_INFO "scsi host busy %d failed %d\n", + sdev->host->host_busy, + sdev->host->host_failed); + } } } } diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c index 06229f225ee9..3e2930b7ee23 100644 --- a/trunk/drivers/scsi/scsi_debug.c +++ b/trunk/drivers/scsi/scsi_debug.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index e8350c562d24..918bb6019540 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -38,6 +38,7 @@ #include "scsi_logging.h" #define SENSE_TIMEOUT (10*HZ) +#define START_UNIT_TIMEOUT (30*HZ) /* * These should *probably* be handled by the host itself. @@ -183,19 +184,10 @@ int scsi_delete_timer(struct scsi_cmnd *scmd) **/ void scsi_times_out(struct scsi_cmnd *scmd) { - enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *); - scsi_log_completion(scmd, TIMEOUT_ERROR); if (scmd->device->host->transportt->eh_timed_out) - eh_timed_out = scmd->device->host->transportt->eh_timed_out; - else if (scmd->device->host->hostt->eh_timed_out) - eh_timed_out = scmd->device->host->hostt->eh_timed_out; - else - eh_timed_out = NULL; - - if (eh_timed_out) - switch (eh_timed_out(scmd)) { + switch (scmd->device->host->transportt->eh_timed_out(scmd)) { case EH_HANDLED: __scsi_done(scmd); return; @@ -931,12 +923,10 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd) static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0}; if (scmd->device->allow_restart) { - int i, rtn = NEEDS_RETRY; - - for (i = 0; rtn == NEEDS_RETRY && i < 2; i++) - rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, - scmd->device->timeout, 0); + int rtn; + rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, + START_UNIT_TIMEOUT, 0); if (rtn == SUCCESS) return 0; } diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 61fbcdcbb009..05d79af5ab90 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -848,8 +848,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) memcpy(req->sense, cmd->sense_buffer, len); req->sense_len = len; } - } - req->data_len = cmd->resid; + } else + req->data_len = cmd->resid; } /* @@ -968,7 +968,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) } if (result) { if (!(req->cmd_flags & REQ_QUIET)) { - scsi_print_result(cmd); + scmd_printk(KERN_INFO, cmd, + "SCSI error: return code = 0x%08x\n", + result); if (driver_byte(result) & DRIVER_SENSE) scsi_print_sense("", cmd); } diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index a67f315244d7..0949145304ea 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -181,8 +181,10 @@ int scsi_complete_async_scans(void) return 0; } +#ifdef MODULE /* Only exported for the benefit of scsi_wait_scan */ EXPORT_SYMBOL_GPL(scsi_complete_async_scans); +#endif /** * scsi_unlock_floptical - unlock device via a special MODE SENSE command diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index 67a38a1409ba..939de0de18bc 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -276,22 +276,8 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; } -static int scsi_bus_uevent(struct device *dev, char **envp, int num_envp, - char *buffer, int buffer_size) -{ - struct scsi_device *sdev = to_scsi_device(dev); - int i = 0; - int length = 0; - - add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, - "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); - envp[i] = NULL; - return 0; -} - static int scsi_bus_suspend(struct device * dev, pm_message_t state) { - struct device_driver *drv = dev->driver; struct scsi_device *sdev = to_scsi_device(dev); struct scsi_host_template *sht = sdev->host->hostt; int err; @@ -300,51 +286,28 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state) if (err) return err; - /* call HLD suspend first */ - if (drv && drv->suspend) { - err = drv->suspend(dev, state); - if (err) - return err; - } - - /* then, call host suspend */ - if (sht->suspend) { + if (sht->suspend) err = sht->suspend(sdev, state); - if (err) { - if (drv && drv->resume) - drv->resume(dev); - return err; - } - } - return 0; + return err; } static int scsi_bus_resume(struct device * dev) { - struct device_driver *drv = dev->driver; struct scsi_device *sdev = to_scsi_device(dev); struct scsi_host_template *sht = sdev->host->hostt; - int err = 0, err2 = 0; + int err = 0; - /* call host resume first */ if (sht->resume) err = sht->resume(sdev); - /* then, call HLD resume */ - if (drv && drv->resume) - err2 = drv->resume(dev); - scsi_device_resume(sdev); - - /* favor LLD failure */ - return err ? err : err2;; + return err; } struct bus_type scsi_bus_type = { .name = "scsi", .match = scsi_bus_match, - .uevent = scsi_bus_uevent, .suspend = scsi_bus_suspend, .resume = scsi_bus_resume, }; @@ -584,14 +547,6 @@ show_sdev_iostat(iorequest_cnt); show_sdev_iostat(iodone_cnt); show_sdev_iostat(ioerr_cnt); -static ssize_t -sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct scsi_device *sdev; - sdev = to_scsi_device(dev); - return snprintf (buf, 20, SCSI_DEVICE_MODALIAS_FMT "\n", sdev->type); -} -static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL); /* Default template for device attributes. May NOT be modified */ static struct device_attribute *scsi_sysfs_sdev_attrs[] = { @@ -611,7 +566,6 @@ static struct device_attribute *scsi_sysfs_sdev_attrs[] = { &dev_attr_iorequest_cnt, &dev_attr_iodone_cnt, &dev_attr_ioerr_cnt, - &dev_attr_modalias, NULL }; diff --git a/trunk/drivers/scsi/scsi_tgt_if.c b/trunk/drivers/scsi/scsi_tgt_if.c index ca22ddf81746..0e08817fdecf 100644 --- a/trunk/drivers/scsi/scsi_tgt_if.c +++ b/trunk/drivers/scsi/scsi_tgt_if.c @@ -179,12 +179,10 @@ static int event_recv_msg(struct tgt_event *ev) switch (ev->hdr.type) { case TGT_UEVENT_CMD_RSP: err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no, - ev->p.cmd_rsp.result, ev->p.cmd_rsp.tag, - ev->p.cmd_rsp.uaddr, + ev->p.cmd_rsp.result, ev->p.cmd_rsp.len, - ev->p.cmd_rsp.sense_uaddr, - ev->p.cmd_rsp.sense_len, + ev->p.cmd_rsp.uaddr, ev->p.cmd_rsp.rw); break; case TGT_UEVENT_TSK_MGMT_RSP: diff --git a/trunk/drivers/scsi/scsi_tgt_lib.c b/trunk/drivers/scsi/scsi_tgt_lib.c index 2570f48a69c7..d402aff5f314 100644 --- a/trunk/drivers/scsi/scsi_tgt_lib.c +++ b/trunk/drivers/scsi/scsi_tgt_lib.c @@ -28,6 +28,7 @@ #include #include #include +#include <../drivers/md/dm-bio-list.h> #include "scsi_tgt_priv.h" @@ -41,12 +42,16 @@ static struct kmem_cache *scsi_tgt_cmd_cache; struct scsi_tgt_cmd { /* TODO replace work with James b's code */ struct work_struct work; - /* TODO fix limits of some drivers */ - struct bio *bio; + /* TODO replace the lists with a large bio */ + struct bio_list xfer_done_list; + struct bio_list xfer_list; struct list_head hash_list; struct request *rq; u64 tag; + + void *buffer; + unsigned bufflen; }; #define TGT_HASH_ORDER 4 @@ -88,12 +93,7 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, if (!tcmd) goto put_dev; - /* - * The blk helpers are used to the READ/WRITE requests - * transfering data from a initiator point of view. Since - * we are in target mode we want the opposite. - */ - rq = blk_get_request(shost->uspace_req_q, !write, gfp_mask); + rq = blk_get_request(shost->uspace_req_q, write, gfp_mask); if (!rq) goto free_tcmd; @@ -111,6 +111,8 @@ struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, rq->cmd_flags |= REQ_TYPE_BLOCK_PC; rq->end_io_data = tcmd; + bio_list_init(&tcmd->xfer_list); + bio_list_init(&tcmd->xfer_done_list); tcmd->rq = rq; return cmd; @@ -155,6 +157,22 @@ void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) } EXPORT_SYMBOL_GPL(scsi_host_put_command); +static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) +{ + struct bio *bio; + + /* must call bio_endio in case bio was bounced */ + while ((bio = bio_list_pop(&tcmd->xfer_done_list))) { + bio_endio(bio, bio->bi_size, 0); + bio_unmap_user(bio); + } + + while ((bio = bio_list_pop(&tcmd->xfer_list))) { + bio_endio(bio, bio->bi_size, 0); + bio_unmap_user(bio); + } +} + static void cmd_hashlist_del(struct scsi_cmnd *cmd) { struct request_queue *q = cmd->request->q; @@ -167,11 +185,6 @@ static void cmd_hashlist_del(struct scsi_cmnd *cmd) spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); } -static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) -{ - blk_rq_unmap_user(tcmd->bio); -} - static void scsi_tgt_cmd_destroy(struct work_struct *work) { struct scsi_tgt_cmd *tcmd = @@ -180,6 +193,16 @@ static void scsi_tgt_cmd_destroy(struct work_struct *work) dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, rq_data_dir(cmd->request)); + /* + * We fix rq->cmd_flags here since when we told bio_map_user + * to write vm for WRITE commands, blk_rq_bio_prep set + * rq_data_dir the flags to READ. + */ + if (cmd->sc_data_direction == DMA_TO_DEVICE) + cmd->request->cmd_flags |= REQ_RW; + else + cmd->request->cmd_flags &= ~REQ_RW; + scsi_unmap_user_pages(tcmd); scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd); } @@ -192,7 +215,6 @@ static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, struct list_head *head; tcmd->tag = tag; - tcmd->bio = NULL; INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); spin_lock_irqsave(&qdata->cmd_hash_lock, flags); head = &qdata->cmd_hash[cmd_hashfn(tag)]; @@ -327,14 +349,10 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); scsi_tgt_uspace_send_status(cmd, tcmd->tag); - - if (cmd->request_buffer) - scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); - queue_work(scsi_tgtd, &tcmd->work); } -static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd) +static int __scsi_tgt_transfer_response(struct scsi_cmnd *cmd) { struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); int err; @@ -347,12 +365,30 @@ static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd) case SCSI_MLQUEUE_DEVICE_BUSY: return -EAGAIN; } + return 0; } +static void scsi_tgt_transfer_response(struct scsi_cmnd *cmd) +{ + struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; + int err; + + err = __scsi_tgt_transfer_response(cmd); + if (!err) + return; + + cmd->result = DID_BUS_BUSY << 16; + err = scsi_tgt_uspace_send_status(cmd, tcmd->tag); + if (err <= 0) + /* the eh will have to pick this up */ + printk(KERN_ERR "Could not send cmd %p status\n", cmd); +} + static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) { struct request *rq = cmd->request; + struct scsi_tgt_cmd *tcmd = rq->end_io_data; int count; cmd->use_sg = rq->nr_phys_segments; @@ -362,54 +398,143 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) cmd->request_bufflen = rq->data_len; - dprintk("cmd %p cnt %d %lu\n", cmd, cmd->use_sg, rq_data_dir(rq)); + dprintk("cmd %p addr %p cnt %d %lu\n", cmd, tcmd->buffer, cmd->use_sg, + rq_data_dir(rq)); count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer); if (likely(count <= cmd->use_sg)) { cmd->use_sg = count; return 0; } - eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg); + eprintk("cmd %p addr %p cnt %d\n", cmd, tcmd->buffer, cmd->use_sg); scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); return -EINVAL; } /* TODO: test this crap and replace bio_map_user with new interface maybe */ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd, - unsigned long uaddr, unsigned int len, int rw) + int rw) { struct request_queue *q = cmd->request->q; struct request *rq = cmd->request; + void *uaddr = tcmd->buffer; + unsigned int len = tcmd->bufflen; + struct bio *bio; int err; - dprintk("%lx %u\n", uaddr, len); - err = blk_rq_map_user(q, rq, (void *)uaddr, len); - if (err) { + while (len > 0) { + dprintk("%lx %u\n", (unsigned long) uaddr, len); + bio = bio_map_user(q, NULL, (unsigned long) uaddr, len, rw); + if (IS_ERR(bio)) { + err = PTR_ERR(bio); + dprintk("fail to map %lx %u %d %x\n", + (unsigned long) uaddr, len, err, cmd->cmnd[0]); + goto unmap_bios; + } + + uaddr += bio->bi_size; + len -= bio->bi_size; + /* - * TODO: need to fixup sg_tablesize, max_segment_size, - * max_sectors, etc for modern HW and software drivers - * where this value is bogus. - * - * TODO2: we can alloc a reserve buffer of max size - * we can handle and do the slow copy path for really large - * IO. + * The first bio is added and merged. We could probably + * try to add others using scsi_merge_bio() but for now + * we keep it simple. The first bio should be pretty large + * (either hitting the 1 MB bio pages limit or a queue limit) + * already but for really large IO we may want to try and + * merge these. */ - eprintk("Could not handle request of size %u.\n", len); - return err; + if (!rq->bio) { + blk_rq_bio_prep(q, rq, bio); + rq->data_len = bio->bi_size; + } else + /* put list of bios to transfer in next go around */ + bio_list_add(&tcmd->xfer_list, bio); } - tcmd->bio = rq->bio; + cmd->offset = 0; err = scsi_tgt_init_cmd(cmd, GFP_KERNEL); if (err) - goto unmap_rq; + goto unmap_bios; return 0; -unmap_rq: - scsi_unmap_user_pages(tcmd); +unmap_bios: + if (rq->bio) { + bio_unmap_user(rq->bio); + while ((bio = bio_list_pop(&tcmd->xfer_list))) + bio_unmap_user(bio); + } + return err; } +static int scsi_tgt_transfer_data(struct scsi_cmnd *); + +static void scsi_tgt_data_transfer_done(struct scsi_cmnd *cmd) +{ + struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; + struct bio *bio; + int err; + + /* should we free resources here on error ? */ + if (cmd->result) { +send_uspace_err: + err = scsi_tgt_uspace_send_status(cmd, tcmd->tag); + if (err <= 0) + /* the tgt uspace eh will have to pick this up */ + printk(KERN_ERR "Could not send cmd %p status\n", cmd); + return; + } + + dprintk("cmd %p request_bufflen %u bufflen %u\n", + cmd, cmd->request_bufflen, tcmd->bufflen); + + scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); + bio_list_add(&tcmd->xfer_done_list, cmd->request->bio); + + tcmd->buffer += cmd->request_bufflen; + cmd->offset += cmd->request_bufflen; + + if (!tcmd->xfer_list.head) { + scsi_tgt_transfer_response(cmd); + return; + } + + dprintk("cmd2 %p request_bufflen %u bufflen %u\n", + cmd, cmd->request_bufflen, tcmd->bufflen); + + bio = bio_list_pop(&tcmd->xfer_list); + BUG_ON(!bio); + + blk_rq_bio_prep(cmd->request->q, cmd->request, bio); + cmd->request->data_len = bio->bi_size; + err = scsi_tgt_init_cmd(cmd, GFP_ATOMIC); + if (err) { + cmd->result = DID_ERROR << 16; + goto send_uspace_err; + } + + if (scsi_tgt_transfer_data(cmd)) { + cmd->result = DID_NO_CONNECT << 16; + goto send_uspace_err; + } +} + +static int scsi_tgt_transfer_data(struct scsi_cmnd *cmd) +{ + int err; + struct Scsi_Host *host = scsi_tgt_cmd_to_host(cmd); + + err = host->hostt->transfer_data(cmd, scsi_tgt_data_transfer_done); + switch (err) { + case SCSI_MLQUEUE_HOST_BUSY: + case SCSI_MLQUEUE_DEVICE_BUSY: + return -EAGAIN; + default: + return 0; + } +} + static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr, unsigned len) { @@ -459,9 +584,8 @@ static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag) return rq; } -int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, - unsigned long uaddr, u32 len, unsigned long sense_uaddr, - u32 sense_len, u8 rw) +int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len, + unsigned long uaddr, u8 rw) { struct Scsi_Host *shost; struct scsi_cmnd *cmd; @@ -493,9 +617,8 @@ int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, } cmd = rq->special; - dprintk("cmd %p scb %x result %d len %d bufflen %u %lu %x\n", - cmd, cmd->cmnd[0], result, len, cmd->request_bufflen, - rq_data_dir(rq), cmd->cmnd[0]); + dprintk("cmd %p result %d len %d bufflen %u %lu %x\n", cmd, + result, len, cmd->request_bufflen, rq_data_dir(rq), cmd->cmnd[0]); if (result == TASK_ABORTED) { scsi_tgt_abort_cmd(shost, cmd); @@ -506,36 +629,36 @@ int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, * in the request_* values */ tcmd = cmd->request->end_io_data; + tcmd->buffer = (void *)uaddr; + tcmd->bufflen = len; cmd->result = result; - if (cmd->result == SAM_STAT_CHECK_CONDITION) - scsi_tgt_copy_sense(cmd, sense_uaddr, sense_len); - - if (len) { - err = scsi_map_user_pages(rq->end_io_data, cmd, uaddr, len, rw); - if (err) { - /* - * user-space daemon bugs or OOM - * TODO: we can do better for OOM. - */ - struct scsi_tgt_queuedata *qdata; - struct list_head *head; - unsigned long flags; - - eprintk("cmd %p ret %d uaddr %lx len %d rw %d\n", - cmd, err, uaddr, len, rw); - - qdata = shost->uspace_req_q->queuedata; - head = &qdata->cmd_hash[cmd_hashfn(tcmd->tag)]; + if (!tcmd->bufflen || cmd->request_buffer) { + err = __scsi_tgt_transfer_response(cmd); + goto done; + } - spin_lock_irqsave(&qdata->cmd_hash_lock, flags); - list_add(&tcmd->hash_list, head); - spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); + /* + * TODO: Do we need to handle case where request does not + * align with LLD. + */ + err = scsi_map_user_pages(rq->end_io_data, cmd, rw); + if (err) { + eprintk("%p %d\n", cmd, err); + err = -EAGAIN; + goto done; + } - goto done; - } + /* userspace failure */ + if (cmd->result) { + if (status_byte(cmd->result) == CHECK_CONDITION) + scsi_tgt_copy_sense(cmd, uaddr, len); + err = __scsi_tgt_transfer_response(cmd); + goto done; } - err = scsi_tgt_transfer_response(cmd); + /* ask the target LLD to transfer the data to the buffer */ + err = scsi_tgt_transfer_data(cmd); + done: scsi_host_put(shost); return err; diff --git a/trunk/drivers/scsi/scsi_tgt_priv.h b/trunk/drivers/scsi/scsi_tgt_priv.h index e9e6db1c417f..84488c51ff62 100644 --- a/trunk/drivers/scsi/scsi_tgt_priv.h +++ b/trunk/drivers/scsi/scsi_tgt_priv.h @@ -18,9 +18,8 @@ extern int scsi_tgt_if_init(void); extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 tag); extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag); -extern int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, - unsigned long uaddr, u32 len, unsigned long sense_uaddr, - u32 sense_len, u8 rw); +extern int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len, + unsigned long uaddr, u8 rw); extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, struct scsi_lun *scsilun, void *data); extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result); diff --git a/trunk/drivers/scsi/scsi_transport_fc.c b/trunk/drivers/scsi/scsi_transport_fc.c index b4d1ece46f78..58afdb401703 100644 --- a/trunk/drivers/scsi/scsi_transport_fc.c +++ b/trunk/drivers/scsi/scsi_transport_fc.c @@ -200,8 +200,6 @@ static const struct { { FC_PORTSPEED_2GBIT, "2 Gbit" }, { FC_PORTSPEED_4GBIT, "4 Gbit" }, { FC_PORTSPEED_10GBIT, "10 Gbit" }, - { FC_PORTSPEED_8GBIT, "8 Gbit" }, - { FC_PORTSPEED_16GBIT, "16 Gbit" }, { FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" }, }; fc_bitfield_name_search(port_speed, fc_port_speed_names) @@ -1718,12 +1716,31 @@ fc_starget_delete(struct work_struct *work) struct fc_rport *rport = container_of(work, struct fc_rport, stgt_delete_work); struct Scsi_Host *shost = rport_to_shost(rport); + unsigned long flags; struct fc_internal *i = to_fc_internal(shost->transportt); - /* Involve the LLDD if possible to terminate all io on the rport. */ - if (i->f->terminate_rport_io) + /* + * Involve the LLDD if possible. All io on the rport is to + * be terminated, either as part of the dev_loss_tmo callback + * processing, or via the terminate_rport_io function. + */ + if (i->f->dev_loss_tmo_callbk) + i->f->dev_loss_tmo_callbk(rport); + else if (i->f->terminate_rport_io) i->f->terminate_rport_io(rport); + spin_lock_irqsave(shost->host_lock, flags); + if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { + spin_unlock_irqrestore(shost->host_lock, flags); + if (!cancel_delayed_work(&rport->fail_io_work)) + fc_flush_devloss(shost); + if (!cancel_delayed_work(&rport->dev_loss_work)) + fc_flush_devloss(shost); + spin_lock_irqsave(shost->host_lock, flags); + rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; + } + spin_unlock_irqrestore(shost->host_lock, flags); + scsi_remove_target(&rport->dev); } @@ -1741,7 +1758,6 @@ fc_rport_final_delete(struct work_struct *work) struct device *dev = &rport->dev; struct Scsi_Host *shost = rport_to_shost(rport); struct fc_internal *i = to_fc_internal(shost->transportt); - unsigned long flags; /* * if a scan is pending, flush the SCSI Host work_q so that @@ -1750,37 +1766,13 @@ fc_rport_final_delete(struct work_struct *work) if (rport->flags & FC_RPORT_SCAN_PENDING) scsi_flush_work(shost); - /* involve the LLDD to terminate all pending i/o */ - if (i->f->terminate_rport_io) - i->f->terminate_rport_io(rport); - - /* - * Cancel any outstanding timers. These should really exist - * only when rmmod'ing the LLDD and we're asking for - * immediate termination of the rports - */ - spin_lock_irqsave(shost->host_lock, flags); - if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { - spin_unlock_irqrestore(shost->host_lock, flags); - if (!cancel_delayed_work(&rport->fail_io_work)) - fc_flush_devloss(shost); - if (!cancel_delayed_work(&rport->dev_loss_work)) - fc_flush_devloss(shost); - spin_lock_irqsave(shost->host_lock, flags); - rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; - } - spin_unlock_irqrestore(shost->host_lock, flags); - /* Delete SCSI target and sdevs */ if (rport->scsi_target_id != -1) fc_starget_delete(&rport->stgt_delete_work); - - /* - * Notify the driver that the rport is now dead. The LLDD will - * also guarantee that any communication to the rport is terminated - */ - if (i->f->dev_loss_tmo_callbk) + else if (i->f->dev_loss_tmo_callbk) i->f->dev_loss_tmo_callbk(rport); + else if (i->f->terminate_rport_io) + i->f->terminate_rport_io(rport); transport_remove_device(dev); device_del(dev); @@ -1969,6 +1961,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, } if (match) { + struct delayed_work *work = + &rport->dev_loss_work; memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name)); @@ -1986,61 +1980,46 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, fci->f->dd_fcrport_size); /* - * If we were not a target, cancel the - * io terminate and rport timers, and - * we're done. - * - * If we were a target, but our new role - * doesn't indicate a target, leave the - * timers running expecting the role to - * change as the target fully logs in. If - * it doesn't, the target will be torn down. - * - * If we were a target, and our role shows - * we're still a target, cancel the timers - * and kick off a scan. + * If we were blocked, we were a target. + * If no longer a target, we leave the timer + * running in case the port changes roles + * prior to the timer expiring. If the timer + * fires, the target will be torn down. */ - - /* was a target, not in roles */ - if ((rport->scsi_target_id != -1) && - (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET))) + if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET)) return rport; + /* restart the target */ + /* - * Stop the fail io and dev_loss timers. - * If they flush, the port_state will - * be checked and will NOOP the function. + * Stop the target timers first. Take no action + * on the del_timer failure as the state + * machine state change will validate the + * transaction. */ if (!cancel_delayed_work(&rport->fail_io_work)) fc_flush_devloss(shost); - if (!cancel_delayed_work(&rport->dev_loss_work)) + if (!cancel_delayed_work(work)) fc_flush_devloss(shost); spin_lock_irqsave(shost->host_lock, flags); rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; - /* if target, initiate a scan */ - if (rport->scsi_target_id != -1) { - rport->flags |= FC_RPORT_SCAN_PENDING; - scsi_queue_work(shost, - &rport->scan_work); - spin_unlock_irqrestore(shost->host_lock, - flags); - scsi_target_unblock(&rport->dev); - } else - spin_unlock_irqrestore(shost->host_lock, - flags); + /* initiate a scan of the target */ + rport->flags |= FC_RPORT_SCAN_PENDING; + scsi_queue_work(shost, &rport->scan_work); + + spin_unlock_irqrestore(shost->host_lock, flags); + + scsi_target_unblock(&rport->dev); return rport; } } } - /* - * Search the bindings array - * Note: if never a FCP target, you won't be on this list - */ + /* Search the bindings array */ if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) { /* search for a matching consistent binding */ @@ -2177,24 +2156,15 @@ fc_remote_port_delete(struct fc_rport *rport) spin_lock_irqsave(shost->host_lock, flags); - if (rport->port_state != FC_PORTSTATE_ONLINE) { + /* If no scsi target id mapping, delete it */ + if (rport->scsi_target_id == -1) { + list_del(&rport->peers); + rport->port_state = FC_PORTSTATE_DELETED; + fc_queue_work(shost, &rport->rport_delete_work); spin_unlock_irqrestore(shost->host_lock, flags); return; } - /* - * In the past, we if this was not an FCP-Target, we would - * unconditionally just jump to deleting the rport. - * However, rports can be used as node containers by the LLDD, - * and its not appropriate to just terminate the rport at the - * first sign of a loss in connectivity. The LLDD may want to - * send ELS traffic to re-validate the login. If the rport is - * immediately deleted, it makes it inappropriate for a node - * container. - * So... we now unconditionally wait dev_loss_tmo before - * destroying an rport. - */ - rport->port_state = FC_PORTSTATE_BLOCKED; rport->flags |= FC_RPORT_DEVLOSS_PENDING; @@ -2291,11 +2261,11 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) EXPORT_SYMBOL(fc_remote_port_rolechg); /** - * fc_timeout_deleted_rport - Timeout handler for a deleted remote port, - * which we blocked, and has now failed to return - * in the allotted time. + * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that + * was a SCSI target (thus was blocked), and failed + * to return in the alloted time. * - * @work: rport target that failed to reappear in the allotted time. + * @work: rport target that failed to reappear in the alloted time. **/ static void fc_timeout_deleted_rport(struct work_struct *work) @@ -2311,12 +2281,10 @@ fc_timeout_deleted_rport(struct work_struct *work) rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; /* - * If the port is ONLINE, then it came back. If it was a SCSI - * target, validate it still is. If not, tear down the - * scsi_target on it. + * If the port is ONLINE, then it came back. Validate it's still an + * FCP target. If not, tear down the scsi_target on it. */ if ((rport->port_state == FC_PORTSTATE_ONLINE) && - (rport->scsi_target_id != -1) && !(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { dev_printk(KERN_ERR, &rport->dev, "blocked FC remote port time out: no longer" @@ -2327,24 +2295,18 @@ fc_timeout_deleted_rport(struct work_struct *work) return; } - /* NOOP state - we're flushing workq's */ if (rport->port_state != FC_PORTSTATE_BLOCKED) { spin_unlock_irqrestore(shost->host_lock, flags); dev_printk(KERN_ERR, &rport->dev, - "blocked FC remote port time out: leaving" - " rport%s alone\n", - (rport->scsi_target_id != -1) ? " and starget" : ""); + "blocked FC remote port time out: leaving target alone\n"); return; } - if ((fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) || - (rport->scsi_target_id == -1)) { + if (fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) { list_del(&rport->peers); rport->port_state = FC_PORTSTATE_DELETED; dev_printk(KERN_ERR, &rport->dev, - "blocked FC remote port time out: removing" - " rport%s\n", - (rport->scsi_target_id != -1) ? " and starget" : ""); + "blocked FC remote port time out: removing target\n"); fc_queue_work(shost, &rport->rport_delete_work); spin_unlock_irqrestore(shost->host_lock, flags); return; diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index caf1836bbeca..aabaa0576ab4 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -49,7 +49,7 @@ struct iscsi_internal { struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; }; -static atomic_t iscsi_session_nr; /* sysfs session id for next new session */ +static int iscsi_session_nr; /* sysfs session id for next new session */ /* * list of registered transports and lock that must @@ -300,7 +300,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) int err; ihost = shost->shost_data; - session->sid = atomic_add_return(1, &iscsi_session_nr); + session->sid = iscsi_session_nr++; session->target_id = target_id; snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", @@ -1419,8 +1419,6 @@ static __init int iscsi_transport_init(void) printk(KERN_INFO "Loading iSCSI transport class v%s.\n", ISCSI_TRANSPORT_VERSION); - atomic_set(&iscsi_session_nr, 0); - err = class_register(&iscsi_transport_class); if (err) return err; diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 00e46662296f..5a8f55fea5ff 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -58,10 +58,16 @@ #include #include #include -#include #include "scsi_logging.h" +/* + * More than enough for everybody ;) The huge number of majors + * is a leftover from 16bit dev_t days, we don't really need that + * much numberspace. + */ +#define SD_MAJORS 16 + MODULE_AUTHOR("Eric Youngdale"); MODULE_DESCRIPTION("SCSI disk (sd) driver"); MODULE_LICENSE("GPL"); @@ -82,9 +88,45 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK12_MAJOR); MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR); MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR); MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR); -MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); -MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); -MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); + +/* + * This is limited by the naming scheme enforced in sd_probe, + * add another character to it if you really need more disks. + */ +#define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26) + +/* + * Time out in seconds for disks and Magneto-opticals (which are slower). + */ +#define SD_TIMEOUT (30 * HZ) +#define SD_MOD_TIMEOUT (75 * HZ) + +/* + * Number of allowed retries + */ +#define SD_MAX_RETRIES 5 +#define SD_PASSTHROUGH_RETRIES 1 + +/* + * Size of the initial data buffer for mode and read capacity data + */ +#define SD_BUF_SIZE 512 + +struct scsi_disk { + struct scsi_driver *driver; /* always &sd_template */ + struct scsi_device *device; + struct class_device cdev; + struct gendisk *disk; + unsigned int openers; /* protected by BKL for now, yuck */ + sector_t capacity; /* size in 512-byte sectors */ + u32 index; + u8 media_present; + u8 write_prot; + unsigned WCE : 1; /* state of disk WCE bit */ + unsigned RCD : 1; /* state of disk RCD bit, unused */ + unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ +}; +#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev) static DEFINE_IDR(sd_index_idr); static DEFINE_SPINLOCK(sd_index_lock); @@ -94,6 +136,20 @@ static DEFINE_SPINLOCK(sd_index_lock); * object after last put) */ static DEFINE_MUTEX(sd_ref_mutex); +static int sd_revalidate_disk(struct gendisk *disk); +static void sd_rw_intr(struct scsi_cmnd * SCpnt); + +static int sd_probe(struct device *); +static int sd_remove(struct device *); +static void sd_shutdown(struct device *dev); +static void sd_rescan(struct device *); +static int sd_init_command(struct scsi_cmnd *); +static int sd_issue_flush(struct device *, sector_t *); +static void sd_prepare_flush(request_queue_t *, struct request *); +static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname, + unsigned char *buffer); +static void scsi_disk_release(struct class_device *cdev); + static const char *sd_cache_types[] = { "write through", "none", "write back", "write back, no read (daft)" @@ -143,27 +199,13 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT, SD_MAX_RETRIES, &data, &sshdr)) { if (scsi_sense_valid(&sshdr)) - sd_print_sense_hdr(sdkp, &sshdr); + scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr); return -EINVAL; } sd_revalidate_disk(sdkp->disk); return count; } -static ssize_t sd_store_manage_start_stop(struct class_device *cdev, - const char *buf, size_t count) -{ - struct scsi_disk *sdkp = to_scsi_disk(cdev); - struct scsi_device *sdp = sdkp->device; - - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - - sdp->manage_start_stop = simple_strtoul(buf, NULL, 10); - - return count; -} - static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf, size_t count) { @@ -196,14 +238,6 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf) return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); } -static ssize_t sd_show_manage_start_stop(struct class_device *cdev, char *buf) -{ - struct scsi_disk *sdkp = to_scsi_disk(cdev); - struct scsi_device *sdp = sdkp->device; - - return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); -} - static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(cdev); @@ -217,8 +251,6 @@ static struct class_device_attribute sd_disk_attrs[] = { __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, sd_store_allow_restart), - __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, - sd_store_manage_start_stop), __ATTR_NULL, }; @@ -235,8 +267,6 @@ static struct scsi_driver sd_template = { .name = "sd", .probe = sd_probe, .remove = sd_remove, - .suspend = sd_suspend, - .resume = sd_resume, .shutdown = sd_shutdown, }, .rescan = sd_rescan, @@ -341,19 +371,15 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) unsigned int this_count = SCpnt->request_bufflen >> 9; unsigned int timeout = sdp->timeout; - SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, - "sd_init_command: block=%llu, " - "count=%d\n", - (unsigned long long)block, - this_count)); + SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, " + "count=%d\n", disk->disk_name, + (unsigned long long)block, this_count)); if (!sdp || !scsi_device_online(sdp) || block + rq->nr_sectors > get_capacity(disk)) { - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "Finishing %ld sectors\n", - rq->nr_sectors)); - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "Retry with 0x%p\n", SCpnt)); + SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", + rq->nr_sectors)); + SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); return 0; } @@ -365,8 +391,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ return 0; } - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", - (unsigned long long)block)); + SCSI_LOG_HLQUEUE(2, printk("%s : block=%llu\n", + disk->disk_name, (unsigned long long)block)); /* * If we have a 1K hardware sectorsize, prevent access to single @@ -381,8 +407,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) */ if (sdp->sector_size == 1024) { if ((block & 1) || (rq->nr_sectors & 1)) { - scmd_printk(KERN_ERR, SCpnt, - "Bad block number requested\n"); + printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 1; @@ -391,8 +416,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) } if (sdp->sector_size == 2048) { if ((block & 3) || (rq->nr_sectors & 3)) { - scmd_printk(KERN_ERR, SCpnt, - "Bad block number requested\n"); + printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 2; @@ -401,8 +425,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) } if (sdp->sector_size == 4096) { if ((block & 7) || (rq->nr_sectors & 7)) { - scmd_printk(KERN_ERR, SCpnt, - "Bad block number requested\n"); + printk(KERN_ERR "sd: Bad block number requested"); return 0; } else { block = block >> 3; @@ -419,15 +442,13 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) SCpnt->cmnd[0] = READ_6; SCpnt->sc_data_direction = DMA_FROM_DEVICE; } else { - scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); + printk(KERN_ERR "sd: Unknown command %x\n", rq->cmd_flags); return 0; } - SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, - "%s %d/%ld 512 byte blocks.\n", - (rq_data_dir(rq) == WRITE) ? - "writing" : "reading", this_count, - rq->nr_sectors)); + SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", + disk->disk_name, (rq_data_dir(rq) == WRITE) ? + "writing" : "reading", this_count, rq->nr_sectors)); SCpnt->cmnd[1] = 0; @@ -469,8 +490,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) * during operation and thus turned off * use_10_for_rw. */ - scmd_printk(KERN_ERR, SCpnt, - "FUA write on READ/WRITE(6) drive\n"); + printk(KERN_ERR "sd: FUA write on READ/WRITE(6) drive\n"); return 0; } @@ -529,7 +549,7 @@ static int sd_open(struct inode *inode, struct file *filp) return -ENXIO; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n")); + SCSI_LOG_HLQUEUE(3, printk("sd_open: disk=%s\n", disk->disk_name)); sdev = sdkp->device; @@ -599,7 +619,7 @@ static int sd_release(struct inode *inode, struct file *filp) struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_device *sdev = sdkp->device; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n")); + SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name)); if (!--sdkp->openers && sdev->removable) { if (scsi_block_when_processing_errors(sdev)) @@ -712,7 +732,8 @@ static int sd_media_changed(struct gendisk *disk) struct scsi_device *sdp = sdkp->device; int retval; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); + SCSI_LOG_HLQUEUE(3, printk("sd_media_changed: disk=%s\n", + disk->disk_name)); if (!sdp->removable) return 0; @@ -765,10 +786,9 @@ static int sd_media_changed(struct gendisk *disk) return 1; } -static int sd_sync_cache(struct scsi_disk *sdkp) +static int sd_sync_cache(struct scsi_device *sdp) { int retries, res; - struct scsi_device *sdp = sdkp->device; struct scsi_sense_hdr sshdr; if (!scsi_device_online(sdp)) @@ -789,27 +809,28 @@ static int sd_sync_cache(struct scsi_disk *sdkp) break; } - if (res) { - sd_print_result(sdkp, res); - if (driver_byte(res) & DRIVER_SENSE) - sd_print_sense_hdr(sdkp, &sshdr); + if (res) { printk(KERN_WARNING "FAILED\n status = %x, message = %02x, " + "host = %d, driver = %02x\n ", + status_byte(res), msg_byte(res), + host_byte(res), driver_byte(res)); + if (driver_byte(res) & DRIVER_SENSE) + scsi_print_sense_hdr("sd", &sshdr); } - if (res) - return -EIO; - return 0; + return res; } static int sd_issue_flush(struct device *dev, sector_t *error_sector) { int ret = 0; + struct scsi_device *sdp = to_scsi_device(dev); struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); if (!sdkp) return -ENODEV; if (sdkp->WCE) - ret = sd_sync_cache(sdkp); + ret = sd_sync_cache(sdp); scsi_disk_put(sdkp); return ret; } @@ -907,14 +928,12 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) sense_deferred = scsi_sense_is_deferred(&sshdr); } #ifdef CONFIG_SCSI_LOGGING - SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); + SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", + SCpnt->request->rq_disk->disk_name, result)); if (sense_valid) { - SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, - "sd_rw_intr: sb[respc,sk,asc," - "ascq]=%x,%x,%x,%x\n", - sshdr.response_code, - sshdr.sense_key, sshdr.asc, - sshdr.ascq)); + SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: sb[respc,sk,asc," + "ascq]=%x,%x,%x,%x\n", sshdr.response_code, + sshdr.sense_key, sshdr.asc, sshdr.ascq)); } #endif if (driver_byte(result) != DRIVER_SENSE && @@ -1006,7 +1025,7 @@ static int media_not_present(struct scsi_disk *sdkp, * spinup disk - called only in sd_revalidate_disk() */ static void -sd_spinup_disk(struct scsi_disk *sdkp) +sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) { unsigned char cmd[10]; unsigned long spintime_expire = 0; @@ -1050,10 +1069,9 @@ sd_spinup_disk(struct scsi_disk *sdkp) if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { /* no sense, TUR either succeeded or failed * with a status error */ - if(!spintime && !scsi_status_is_good(the_result)) { - sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n"); - sd_print_result(sdkp, the_result); - } + if(!spintime && !scsi_status_is_good(the_result)) + printk(KERN_NOTICE "%s: Unit Not Ready, " + "error = 0x%x\n", diskname, the_result); break; } @@ -1078,7 +1096,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) */ } else if (sense_valid && sshdr.sense_key == NOT_READY) { if (!spintime) { - sd_printk(KERN_NOTICE, sdkp, "Spinning up disk..."); + printk(KERN_NOTICE "%s: Spinning up disk...", + diskname); cmd[0] = START_STOP; cmd[1] = 1; /* Return immediately */ memset((void *) &cmd[2], 0, 8); @@ -1111,8 +1130,9 @@ sd_spinup_disk(struct scsi_disk *sdkp) /* we don't understand the sense code, so it's * probably pointless to loop */ if(!spintime) { - sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n"); - sd_print_sense_hdr(sdkp, &sshdr); + printk(KERN_NOTICE "%s: Unit Not Ready, " + "sense:\n", diskname); + scsi_print_sense_hdr("", &sshdr); } break; } @@ -1131,7 +1151,8 @@ sd_spinup_disk(struct scsi_disk *sdkp) * read disk capacity */ static void -sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) +sd_read_capacity(struct scsi_disk *sdkp, char *diskname, + unsigned char *buffer) { unsigned char cmd[16]; int the_result, retries; @@ -1170,12 +1191,18 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) } while (the_result && retries); if (the_result && !longrc) { - sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY failed\n"); - sd_print_result(sdkp, the_result); + printk(KERN_NOTICE "%s : READ CAPACITY failed.\n" + "%s : status=%x, message=%02x, host=%d, driver=%02x \n", + diskname, diskname, + status_byte(the_result), + msg_byte(the_result), + host_byte(the_result), + driver_byte(the_result)); + if (driver_byte(the_result) & DRIVER_SENSE) - sd_print_sense_hdr(sdkp, &sshdr); + scsi_print_sense_hdr("sd", &sshdr); else - sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n"); + printk("%s : sense not available. \n", diskname); /* Set dirty bit for removable devices if not ready - * sometimes drives will not report this properly. */ @@ -1191,10 +1218,16 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) return; } else if (the_result && longrc) { /* READ CAPACITY(16) has been failed */ - sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY(16) failed\n"); - sd_print_result(sdkp, the_result); - sd_printk(KERN_NOTICE, sdkp, "Use 0xffffffff as device size\n"); - + printk(KERN_NOTICE "%s : READ CAPACITY(16) failed.\n" + "%s : status=%x, message=%02x, host=%d, driver=%02x \n", + diskname, diskname, + status_byte(the_result), + msg_byte(the_result), + host_byte(the_result), + driver_byte(the_result)); + printk(KERN_NOTICE "%s : use 0xffffffff as device size\n", + diskname); + sdkp->capacity = 1 + (sector_t) 0xffffffff; goto got_data; } @@ -1205,14 +1238,14 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) if (buffer[0] == 0xff && buffer[1] == 0xff && buffer[2] == 0xff && buffer[3] == 0xff) { if(sizeof(sdkp->capacity) > 4) { - sd_printk(KERN_NOTICE, sdkp, "Very big device. " - "Trying to use READ CAPACITY(16).\n"); + printk(KERN_NOTICE "%s : very big device. try to use" + " READ CAPACITY(16).\n", diskname); longrc = 1; goto repeat; } - sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use " - "a kernel compiled with support for large " - "block devices.\n"); + printk(KERN_ERR "%s: too big for this kernel. Use a " + "kernel compiled with support for large block " + "devices.\n", diskname); sdkp->capacity = 0; goto got_data; } @@ -1251,8 +1284,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) got_data: if (sector_size == 0) { sector_size = 512; - sd_printk(KERN_NOTICE, sdkp, "Sector size 0 reported, " - "assuming 512.\n"); + printk(KERN_NOTICE "%s : sector size 0 reported, " + "assuming 512.\n", diskname); } if (sector_size != 512 && @@ -1260,8 +1293,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) sector_size != 2048 && sector_size != 4096 && sector_size != 256) { - sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n", - sector_size); + printk(KERN_NOTICE "%s : unsupported sector size " + "%d.\n", diskname, sector_size); /* * The user might want to re-format the drive with * a supported sectorsize. Once this happens, it @@ -1294,10 +1327,10 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) mb -= sz - 974; sector_div(mb, 1950); - sd_printk(KERN_NOTICE, sdkp, - "%llu %d-byte hardware sectors (%llu MB)\n", - (unsigned long long)sdkp->capacity, - hard_sector, (unsigned long long)mb); + printk(KERN_NOTICE "SCSI device %s: " + "%llu %d-byte hdwr sectors (%llu MB)\n", + diskname, (unsigned long long)sdkp->capacity, + hard_sector, (unsigned long long)mb); } /* Rescale capacity to 512-byte units */ @@ -1329,7 +1362,8 @@ sd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage, * called with buffer of length SD_BUF_SIZE */ static void -sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) +sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, + unsigned char *buffer) { int res; struct scsi_device *sdp = sdkp->device; @@ -1337,7 +1371,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) set_disk_ro(sdkp->disk, 0); if (sdp->skip_ms_page_3f) { - sd_printk(KERN_NOTICE, sdkp, "Assuming Write Enabled\n"); + printk(KERN_NOTICE "%s: assuming Write Enabled\n", diskname); return; } @@ -1369,16 +1403,15 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) } if (!scsi_status_is_good(res)) { - sd_printk(KERN_WARNING, sdkp, - "Test WP failed, assume Write Enabled\n"); + printk(KERN_WARNING + "%s: test WP failed, assume Write Enabled\n", diskname); } else { sdkp->write_prot = ((data.device_specific & 0x80) != 0); set_disk_ro(sdkp->disk, sdkp->write_prot); - sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n", - sdkp->write_prot ? "on" : "off"); - sd_printk(KERN_DEBUG, sdkp, - "Mode Sense: %02x %02x %02x %02x\n", - buffer[0], buffer[1], buffer[2], buffer[3]); + printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname, + sdkp->write_prot ? "on" : "off"); + printk(KERN_DEBUG "%s: Mode Sense: %02x %02x %02x %02x\n", + diskname, buffer[0], buffer[1], buffer[2], buffer[3]); } } @@ -1387,7 +1420,8 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) * called with buffer of length SD_BUF_SIZE */ static void -sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) +sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, + unsigned char *buffer) { int len = 0, res; struct scsi_device *sdp = sdkp->device; @@ -1416,7 +1450,8 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) if (!data.header_length) { modepage = 6; - sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response\n"); + printk(KERN_ERR "%s: missing header in MODE_SENSE response\n", + diskname); } /* that went OK, now ask for the proper length */ @@ -1443,12 +1478,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) int offset = data.header_length + data.block_descriptor_length; if (offset >= SD_BUF_SIZE - 2) { - sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n"); + printk(KERN_ERR "%s: malformed MODE SENSE response", + diskname); goto defaults; } if ((buffer[offset] & 0x3f) != modepage) { - sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); + printk(KERN_ERR "%s: got wrong page\n", diskname); goto defaults; } @@ -1462,13 +1498,14 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) sdkp->DPOFUA = (data.device_specific & 0x10) != 0; if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) { - sd_printk(KERN_NOTICE, sdkp, - "Uses READ/WRITE(6), disabling FUA\n"); + printk(KERN_NOTICE "SCSI device %s: uses " + "READ/WRITE(6), disabling FUA\n", diskname); sdkp->DPOFUA = 0; } - sd_printk(KERN_NOTICE, sdkp, - "Write cache: %s, read cache: %s, %s\n", + printk(KERN_NOTICE "SCSI device %s: " + "write cache: %s, read cache: %s, %s\n", + diskname, sdkp->WCE ? "enabled" : "disabled", sdkp->RCD ? "disabled" : "enabled", sdkp->DPOFUA ? "supports DPO and FUA" @@ -1481,13 +1518,15 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) if (scsi_sense_valid(&sshdr) && sshdr.sense_key == ILLEGAL_REQUEST && sshdr.asc == 0x24 && sshdr.ascq == 0x0) - /* Invalid field in CDB */ - sd_printk(KERN_NOTICE, sdkp, "Cache data unavailable\n"); + printk(KERN_NOTICE "%s: cache data unavailable\n", + diskname); /* Invalid field in CDB */ else - sd_printk(KERN_ERR, sdkp, "Asking for cache data failed\n"); + printk(KERN_ERR "%s: asking for cache data failed\n", + diskname); defaults: - sd_printk(KERN_ERR, sdkp, "Assuming drive cache: write through\n"); + printk(KERN_ERR "%s: assuming drive cache: write through\n", + diskname); sdkp->WCE = 0; sdkp->RCD = 0; sdkp->DPOFUA = 0; @@ -1505,8 +1544,7 @@ static int sd_revalidate_disk(struct gendisk *disk) unsigned char *buffer; unsigned ordered; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, - "sd_revalidate_disk\n")); + SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name)); /* * If the device is offline, don't try and read capacity or any @@ -1517,8 +1555,8 @@ static int sd_revalidate_disk(struct gendisk *disk) buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL | __GFP_DMA); if (!buffer) { - sd_printk(KERN_WARNING, sdkp, "sd_revalidate_disk: Memory " - "allocation failure.\n"); + printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation " + "failure.\n"); goto out; } @@ -1530,16 +1568,16 @@ static int sd_revalidate_disk(struct gendisk *disk) sdkp->WCE = 0; sdkp->RCD = 0; - sd_spinup_disk(sdkp); + sd_spinup_disk(sdkp, disk->disk_name); /* * Without media there is no reason to ask; moreover, some devices * react badly if we do. */ if (sdkp->media_present) { - sd_read_capacity(sdkp, buffer); - sd_read_write_protect_flag(sdkp, buffer); - sd_read_cache_type(sdkp, buffer); + sd_read_capacity(sdkp, disk->disk_name, buffer); + sd_read_write_protect_flag(sdkp, disk->disk_name, buffer); + sd_read_cache_type(sdkp, disk->disk_name, buffer); } /* @@ -1671,8 +1709,8 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); add_disk(gd); - sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", - sdp->removable ? "removable " : ""); + sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n", + sdp->removable ? "removable " : "", gd->disk_name); return 0; @@ -1736,31 +1774,6 @@ static void scsi_disk_release(struct class_device *cdev) kfree(sdkp); } -static int sd_start_stop_device(struct scsi_disk *sdkp, int start) -{ - unsigned char cmd[6] = { START_STOP }; /* START_VALID */ - struct scsi_sense_hdr sshdr; - struct scsi_device *sdp = sdkp->device; - int res; - - if (start) - cmd[4] |= 1; /* START */ - - if (!scsi_device_online(sdp)) - return -ENODEV; - - res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, - SD_TIMEOUT, SD_MAX_RETRIES); - if (res) { - sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n"); - sd_print_result(sdkp, res); - if (driver_byte(res) & DRIVER_SENSE) - sd_print_sense_hdr(sdkp, &sshdr); - } - - return res; -} - /* * Send a SYNCHRONIZE CACHE instruction down to the device through * the normal SCSI command structure. Wait for the command to @@ -1768,62 +1781,20 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) */ static void sd_shutdown(struct device *dev) { + struct scsi_device *sdp = to_scsi_device(dev); struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); if (!sdkp) return; /* this can happen */ if (sdkp->WCE) { - sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); - sd_sync_cache(sdkp); - } - - if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - sd_start_stop_device(sdkp, 0); + printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n", + sdkp->disk->disk_name); + sd_sync_cache(sdp); } - scsi_disk_put(sdkp); } -static int sd_suspend(struct device *dev, pm_message_t mesg) -{ - struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); - int ret; - - if (!sdkp) - return 0; /* this can happen */ - - if (sdkp->WCE) { - sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n"); - ret = sd_sync_cache(sdkp); - if (ret) - return ret; - } - - if (mesg.event == PM_EVENT_SUSPEND && - sdkp->device->manage_start_stop) { - sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); - ret = sd_start_stop_device(sdkp, 0); - if (ret) - return ret; - } - - return 0; -} - -static int sd_resume(struct device *dev) -{ - struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); - - if (!sdkp->device->manage_start_stop) - return 0; - - sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); - - return sd_start_stop_device(sdkp, 1); -} - /** * init_sd - entry point for this driver (both when built in or when * a module). @@ -1881,19 +1852,3 @@ static void __exit exit_sd(void) module_init(init_sd); module_exit(exit_sd); - -static void sd_print_sense_hdr(struct scsi_disk *sdkp, - struct scsi_sense_hdr *sshdr) -{ - sd_printk(KERN_INFO, sdkp, ""); - scsi_show_sense_hdr(sshdr); - sd_printk(KERN_INFO, sdkp, ""); - scsi_show_extd_sense(sshdr->asc, sshdr->ascq); -} - -static void sd_print_result(struct scsi_disk *sdkp, int result) -{ - sd_printk(KERN_INFO, sdkp, ""); - scsi_show_result(result); -} - diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 0c691a60a756..81e3bc7b02a1 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -41,6 +41,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ #include #include #include +#include #include #include #include @@ -916,8 +917,6 @@ sg_ioctl(struct inode *inode, struct file *filp, return result; if (val < 0) return -EINVAL; - val = min_t(int, val, - sdp->device->request_queue->max_sectors * 512); if (val != sfp->reserve.bufflen) { if (sg_res_in_use(sfp) || sfp->mmap_called) return -EBUSY; @@ -926,8 +925,7 @@ sg_ioctl(struct inode *inode, struct file *filp, } return 0; case SG_GET_RESERVED_SIZE: - val = min_t(int, sfp->reserve.bufflen, - sdp->device->request_queue->max_sectors * 512); + val = (int) sfp->reserve.bufflen; return put_user(val, ip); case SG_SET_COMMAND_Q: result = get_user(val, ip); @@ -1063,9 +1061,6 @@ sg_ioctl(struct inode *inode, struct file *filp, if (sdp->detached) return -ENODEV; return scsi_ioctl(sdp->device, cmd_in, p); - case BLKSECTGET: - return put_user(sdp->device->request_queue->max_sectors * 512, - ip); default: if (read_only) return -EPERM; /* don't know so take safe approach */ @@ -2344,7 +2339,6 @@ sg_add_sfp(Sg_device * sdp, int dev) { Sg_fd *sfp; unsigned long iflags; - int bufflen; sfp = kzalloc(sizeof(*sfp), GFP_ATOMIC | __GFP_NOWARN); if (!sfp) @@ -2375,9 +2369,7 @@ sg_add_sfp(Sg_device * sdp, int dev) if (unlikely(sg_big_buff != def_reserved_size)) sg_big_buff = def_reserved_size; - bufflen = min_t(int, sg_big_buff, - sdp->device->request_queue->max_sectors * 512); - sg_build_reserve(sfp, bufflen); + sg_build_reserve(sfp, sg_big_buff); SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: bufflen=%d, k_use_sg=%d\n", sfp->reserve.bufflen, sfp->reserve.k_use_sg)); return sfp; diff --git a/trunk/drivers/scsi/sni_53c710.c b/trunk/drivers/scsi/sni_53c710.c index a7dfb65fb842..6bc505115841 100644 --- a/trunk/drivers/scsi/sni_53c710.c +++ b/trunk/drivers/scsi/sni_53c710.c @@ -98,7 +98,7 @@ static int __init snirm710_probe(struct platform_device *dev) host->this_id = 7; host->base = base; host->irq = platform_get_irq(dev, 0); - if(request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "snirm710", host)) { + if(request_irq(host->irq, NCR_700_intr, SA_SHIRQ, "snirm710", host)) { printk(KERN_ERR "snirm710: request_irq failed!\n"); goto out_put_host; } diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c index f9a52af7f5b4..1857d68e7195 100644 --- a/trunk/drivers/scsi/sr.c +++ b/trunk/drivers/scsi/sr.c @@ -62,8 +62,6 @@ MODULE_DESCRIPTION("SCSI cdrom (sr) driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR); -MODULE_ALIAS_SCSI_DEVICE(TYPE_ROM); -MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); #define SR_DISKS 256 diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index 55bfeccf68a2..98d8411bbccc 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -89,7 +89,6 @@ MODULE_AUTHOR("Kai Makisara"); MODULE_DESCRIPTION("SCSI tape (st) driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR); -MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE); /* Set 'perm' (4th argument) to 0 to disable module_param's definition * of sysfs parameters (which module_param doesn't yet support). diff --git a/trunk/drivers/scsi/sun_esp.c b/trunk/drivers/scsi/sun_esp.c index bbeb2451d32f..8c766bcd1095 100644 --- a/trunk/drivers/scsi/sun_esp.c +++ b/trunk/drivers/scsi/sun_esp.c @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/trunk/drivers/scsi/tmscsim.c b/trunk/drivers/scsi/tmscsim.c index e7b85e832eb5..a583e89238fc 100644 --- a/trunk/drivers/scsi/tmscsim.c +++ b/trunk/drivers/scsi/tmscsim.c @@ -351,27 +351,6 @@ static u8 dc390_clock_speed[] = {100,80,67,57,50, 40, 31, 20}; * (DCBs, SRBs, Queueing) * **********************************************************************/ -static void inline dc390_start_segment(struct dc390_srb* pSRB) -{ - struct scatterlist *psgl = pSRB->pSegmentList; - - /* start new sg segment */ - pSRB->SGBusAddr = sg_dma_address(psgl); - pSRB->SGToBeXferLen = sg_dma_len(psgl); -} - -static unsigned long inline dc390_advance_segment(struct dc390_srb* pSRB, u32 residue) -{ - unsigned long xfer = pSRB->SGToBeXferLen - residue; - - /* xfer more bytes transferred */ - pSRB->SGBusAddr += xfer; - pSRB->TotalXferredLen += xfer; - pSRB->SGToBeXferLen = residue; - - return xfer; -} - static struct dc390_dcb __inline__ *dc390_findDCB ( struct dc390_acb* pACB, u8 id, u8 lun) { struct dc390_dcb* pDCB = pACB->pLinkDCB; if (!pDCB) return NULL; @@ -646,6 +625,70 @@ dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_sr return 0; } +//#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/ +#define DMA_INT 0 + +#if DMA_INT +/* This is similar to AM53C974.c ... */ +static u8 +dc390_dma_intr (struct dc390_acb* pACB) +{ + struct dc390_srb* pSRB; + u8 dstate; + DEBUG0(u16 pstate; struct pci_dev *pdev = pACB->pdev); + + DEBUG0(pci_read_config_word(pdev, PCI_STATUS, &pstate)); + DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY))\ + { printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); \ + pci_write_config_word(pdev, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));}); + + dstate = DC390_read8 (DMA_Status); + + if (! pACB->pActiveDCB || ! pACB->pActiveDCB->pActiveSRB) return dstate; + else pSRB = pACB->pActiveDCB->pActiveSRB; + + if (dstate & (DMA_XFER_ABORT | DMA_XFER_ERROR | POWER_DOWN | PCI_MS_ABORT)) + { + printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate); + return dstate; + } + if (dstate & DMA_XFER_DONE) + { + u32 residual, xferCnt; int ctr = 6000000; + if (! (DC390_read8 (DMA_Cmd) & READ_DIRECTION)) + { + do + { + DEBUG1(printk (KERN_DEBUG "DC390: read residual bytes ... \n")); + dstate = DC390_read8 (DMA_Status); + residual = DC390_read8 (CtcReg_Low) | DC390_read8 (CtcReg_Mid) << 8 | + DC390_read8 (CtcReg_High) << 16; + residual += DC390_read8 (Current_Fifo) & 0x1f; + } while (residual && ! (dstate & SCSI_INTERRUPT) && --ctr); + if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr)); + /* residual = ... */ + } + else + residual = 0; + + /* ??? */ + + xferCnt = pSRB->SGToBeXferLen - residual; + pSRB->SGBusAddr += xferCnt; + pSRB->TotalXferredLen += xferCnt; + pSRB->SGToBeXferLen = residual; +# ifdef DC390_DEBUG0 + printk (KERN_INFO "DC390: DMA: residual = %i, xfer = %i\n", + (unsigned int)residual, (unsigned int)xferCnt); +# endif + + DC390_write8 (DMA_Cmd, DMA_IDLE_CMD); + } + dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24; + return dstate; +} +#endif + static void __inline__ dc390_InvalidCmd(struct dc390_acb* pACB) @@ -665,6 +708,9 @@ DC390_Interrupt(void *dev_id) u8 phase; void (*stateV)( struct dc390_acb*, struct dc390_srb*, u8 *); u8 istate, istatus; +#if DMA_INT + u8 dstatus; +#endif sstatus = DC390_read8 (Scsi_Status); if( !(sstatus & INTERRUPT) ) @@ -672,9 +718,22 @@ DC390_Interrupt(void *dev_id) DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus)); +#if DMA_INT + spin_lock_irq(pACB->pScsiHost->host_lock); + dstatus = dc390_dma_intr (pACB); + spin_unlock_irq(pACB->pScsiHost->host_lock); + + DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus)); + if (! (dstatus & SCSI_INTERRUPT)) + { + DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n")); + return IRQ_NONE; + } +#else //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT); //dstatus = DC390_read8 (DMA_Status); //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT); +#endif spin_lock_irq(pACB->pScsiHost->host_lock); @@ -762,10 +821,11 @@ static irqreturn_t do_DC390_Interrupt(int irq, void *dev_id) } static void -dc390_DataOut_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) +dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) { u8 sstatus; - u32 ResidCnt; + struct scatterlist *psgl; + u32 ResidCnt, xferCnt; u8 dstate = 0; sstatus = *psstatus; @@ -796,35 +856,42 @@ dc390_DataOut_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; + psgl = pSRB->pSegmentList; - dc390_start_segment(pSRB); + pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl))); + pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl)); } else pSRB->SGToBeXferLen = 0; } else { - ResidCnt = ((u32) DC390_read8 (Current_Fifo) & 0x1f) + - (((u32) DC390_read8 (CtcReg_High) << 16) | - ((u32) DC390_read8 (CtcReg_Mid) << 8) | - (u32) DC390_read8 (CtcReg_Low)); - - dc390_advance_segment(pSRB, ResidCnt); + ResidCnt = (u32) DC390_read8 (Current_Fifo) & 0x1f; + ResidCnt |= (u32) DC390_read8 (CtcReg_High) << 16; + ResidCnt |= (u32) DC390_read8 (CtcReg_Mid) << 8; + ResidCnt += (u32) DC390_read8 (CtcReg_Low); + + xferCnt = pSRB->SGToBeXferLen - ResidCnt; + pSRB->SGBusAddr += xferCnt; + pSRB->TotalXferredLen += xferCnt; + pSRB->SGToBeXferLen = ResidCnt; } } if ((*psstatus & 7) != SCSI_DATA_OUT) { - DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD); + DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */ DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); } } static void -dc390_DataIn_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) +dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) { u8 sstatus, residual, bval; - u32 ResidCnt, i; + struct scatterlist *psgl; + u32 ResidCnt, i; unsigned long xferCnt; + u8 *ptr; sstatus = *psstatus; @@ -855,17 +922,19 @@ dc390_DataIn_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) DEBUG1(ResidCnt = ((unsigned long) DC390_read8 (CtcReg_High) << 16) \ + ((unsigned long) DC390_read8 (CtcReg_Mid) << 8) \ + ((unsigned long) DC390_read8 (CtcReg_Low))); - DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%u,ToBeXfer=%lu),", ResidCnt, pSRB->SGToBeXferLen)); + DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%i,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen)); - DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); + DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */ pSRB->TotalXferredLen += pSRB->SGToBeXferLen; pSRB->SGIndex++; if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; + psgl = pSRB->pSegmentList; - dc390_start_segment(pSRB); + pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl))); + pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl)); } else pSRB->SGToBeXferLen = 0; @@ -904,45 +973,47 @@ dc390_DataIn_0(struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) } /* It seems a DMA Blast abort isn't that bad ... */ if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n"); - //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); - dc390_laststatus &= ~0xff000000; - dc390_laststatus |= bval << 24; + //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */ + dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24; DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval)); - ResidCnt = (((u32) DC390_read8 (CtcReg_High) << 16) | - ((u32) DC390_read8 (CtcReg_Mid) << 8)) | - (u32) DC390_read8 (CtcReg_Low); - - xferCnt = dc390_advance_segment(pSRB, ResidCnt); - - if (residual) { - size_t count = 1; - size_t offset = pSRB->SGBusAddr - sg_dma_address(pSRB->pSegmentList); - unsigned long flags; - u8 *ptr; - + ResidCnt = (u32) DC390_read8 (CtcReg_High); + ResidCnt <<= 8; + ResidCnt |= (u32) DC390_read8 (CtcReg_Mid); + ResidCnt <<= 8; + ResidCnt |= (u32) DC390_read8 (CtcReg_Low); + + xferCnt = pSRB->SGToBeXferLen - ResidCnt; + pSRB->SGBusAddr += xferCnt; + pSRB->TotalXferredLen += xferCnt; + pSRB->SGToBeXferLen = ResidCnt; + + if( residual ) + { + static int feedback_requested; bval = DC390_read8 (ScsiFifo); /* get one residual byte */ - local_irq_save(flags); - ptr = scsi_kmap_atomic_sg(pSRB->pSegmentList, pSRB->SGcount, &offset, &count); - if (likely(ptr)) { - *(ptr + offset) = bval; - scsi_kunmap_atomic_sg(ptr); + if (!feedback_requested) { + feedback_requested = 1; + printk(KERN_WARNING "%s: Please, contact " + "to help improve support for your system.\n", __FILE__); } - local_irq_restore(flags); - WARN_ON(!ptr); - /* 1 more byte read */ - xferCnt += dc390_advance_segment(pSRB, pSRB->SGToBeXferLen - 1); + ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr ); + *ptr = bval; + pSRB->SGBusAddr++; xferCnt++; + pSRB->TotalXferredLen++; + pSRB->SGToBeXferLen--; } - DEBUG1(printk (KERN_DEBUG "Xfered: %lu, Total: %lu, Remaining: %lu\n", xferCnt,\ + DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\ pSRB->TotalXferredLen, pSRB->SGToBeXferLen)); + } } if ((*psstatus & 7) != SCSI_DATA_IN) { DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); - DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); + DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */ } } @@ -1145,7 +1216,7 @@ dc390_MsgIn_set_sync (struct dc390_acb* pACB, struct dc390_srb* pSRB) /* handle RESTORE_PTR */ -/* This doesn't look very healthy... to-be-fixed */ +/* I presume, this command is already mapped, so, have to remap. */ static void dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) { @@ -1154,7 +1225,6 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) pSRB->TotalXferredLen = 0; pSRB->SGIndex = 0; if (pcmd->use_sg) { - size_t saved; pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer; psgl = pSRB->pSegmentList; //dc390_pci_sync(pSRB); @@ -1166,16 +1236,15 @@ dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB) if( pSRB->SGIndex < pSRB->SGcount ) { pSRB->pSegmentList++; - - dc390_start_segment(pSRB); + psgl = pSRB->pSegmentList; + pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl))); + pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl)); } else pSRB->SGToBeXferLen = 0; } - - saved = pSRB->Saved_Ptr - pSRB->TotalXferredLen; - pSRB->SGToBeXferLen -= saved; - pSRB->SGBusAddr += saved; + pSRB->SGToBeXferLen -= (pSRB->Saved_Ptr - pSRB->TotalXferredLen); + pSRB->SGBusAddr += (pSRB->Saved_Ptr - pSRB->TotalXferredLen); printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n", pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr); @@ -1296,6 +1365,7 @@ dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus) static void dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir) { + struct scatterlist *psgl; unsigned long lval; struct dc390_dcb* pDCB = pACB->pActiveDCB; @@ -1321,11 +1391,12 @@ dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir) if( pSRB->SGIndex < pSRB->SGcount ) { - DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); + DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */); if( !pSRB->SGToBeXferLen ) { - dc390_start_segment(pSRB); - + psgl = pSRB->pSegmentList; + pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl))); + pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl)); DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment.")); } lval = pSRB->SGToBeXferLen; @@ -1339,12 +1410,12 @@ dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir) DC390_write32 (DMA_XferCnt, pSRB->SGToBeXferLen); DC390_write32 (DMA_XferAddr, pSRB->SGBusAddr); - //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); + //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */ pSRB->SRBState = SRB_DATA_XFER; DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD); - DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir); + DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT); //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT)); //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status))); //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT)); @@ -1365,8 +1436,8 @@ dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir) pSRB->SRBState |= SRB_XFERPAD; DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE); /* - DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); - DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir); + DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT; + DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT); */ } } @@ -2609,7 +2680,7 @@ static int __init dc390_module_init(void) printk (KERN_INFO "DC390: Using safe settings.\n"); } - return pci_register_driver(&dc390_driver); + return pci_module_init(&dc390_driver); } static void __exit dc390_module_exit(void) diff --git a/trunk/drivers/scsi/tmscsim.h b/trunk/drivers/scsi/tmscsim.h index c3d8c80cfb38..9b66fa8d38d9 100644 --- a/trunk/drivers/scsi/tmscsim.h +++ b/trunk/drivers/scsi/tmscsim.h @@ -19,6 +19,14 @@ #define SEL_TIMEOUT 153 /* 250 ms selection timeout (@ 40 MHz) */ +#define pci_dma_lo32(a) (a & 0xffffffff) + +typedef u8 UCHAR; /* 8 bits */ +typedef u16 USHORT; /* 16 bits */ +typedef u32 UINT; /* 32 bits */ +typedef unsigned long ULONG; /* 32/64 bits */ + + /* ;----------------------------------------------------------------------- ; SCSI Request Block @@ -35,9 +43,7 @@ struct scatterlist *pSegmentList; struct scatterlist Segmentx; /* make a one entry of S/G list table */ -unsigned long SGBusAddr; /*;a segment starting address as seen by AM53C974A - in CPU endianness. We're only getting 32-bit bus - addresses by default */ +unsigned long SGBusAddr; /*;a segment starting address as seen by AM53C974A*/ unsigned long SGToBeXferLen; /*; to be xfer length */ unsigned long TotalXferredLen; unsigned long SavedTotXLen; diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index 48e259a0167d..90621c3312bc 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -251,16 +251,9 @@ static const struct serial8250_config uart_config[] = { .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_CAP_UUE, }, - [PORT_RM9000] = { - .name = "RM9000", - .fifo_size = 16, - .tx_loadsz = 16, - .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - .flags = UART_CAP_FIFO, - }, }; -#if defined (CONFIG_SERIAL_8250_AU1X00) +#ifdef CONFIG_SERIAL_8250_AU1X00 /* Au1x00 UART hardware has a weird register layout */ static const u8 au_io_in_map[] = { @@ -296,44 +289,6 @@ static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) return au_io_out_map[offset]; } -#elif defined (CONFIG_SERIAL_8250_RM9K) - -static const u8 - regmap_in[8] = { - [UART_RX] = 0x00, - [UART_IER] = 0x0c, - [UART_IIR] = 0x14, - [UART_LCR] = 0x1c, - [UART_MCR] = 0x20, - [UART_LSR] = 0x24, - [UART_MSR] = 0x28, - [UART_SCR] = 0x2c - }, - regmap_out[8] = { - [UART_TX] = 0x04, - [UART_IER] = 0x0c, - [UART_FCR] = 0x18, - [UART_LCR] = 0x1c, - [UART_MCR] = 0x20, - [UART_LSR] = 0x24, - [UART_MSR] = 0x28, - [UART_SCR] = 0x2c - }; - -static inline int map_8250_in_reg(struct uart_8250_port *up, int offset) -{ - if (up->port.iotype != UPIO_RM9000) - return offset; - return regmap_in[offset]; -} - -static inline int map_8250_out_reg(struct uart_8250_port *up, int offset) -{ - if (up->port.iotype != UPIO_RM9000) - return offset; - return regmap_out[offset]; -} - #else /* sane hardware needs no mapping */ @@ -353,10 +308,8 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) return inb(up->port.iobase + 1); case UPIO_MEM: - case UPIO_DWAPB: return readb(up->port.membase + offset); - case UPIO_RM9000: case UPIO_MEM32: return readl(up->port.membase + offset); @@ -380,8 +333,6 @@ static unsigned int serial_in(struct uart_8250_port *up, int offset) static void serial_out(struct uart_8250_port *up, int offset, int value) { - /* Save the offset before it's remapped */ - int save_offset = offset; offset = map_8250_out_reg(up, offset) << up->port.regshift; switch (up->port.iotype) { @@ -394,7 +345,6 @@ serial_out(struct uart_8250_port *up, int offset, int value) writeb(value, up->port.membase + offset); break; - case UPIO_RM9000: case UPIO_MEM32: writel(value, up->port.membase + offset); break; @@ -409,18 +359,6 @@ serial_out(struct uart_8250_port *up, int offset, int value) writeb(value, up->port.membase + offset); break; - case UPIO_DWAPB: - /* Save the LCR value so it can be re-written when a - * Busy Detect interrupt occurs. */ - if (save_offset == UART_LCR) - up->lcr = value; - writeb(value, up->port.membase + offset); - /* Read the IER to ensure any interrupt is cleared before - * returning from ISR. */ - if (save_offset == UART_TX || save_offset == UART_IER) - value = serial_in(up, UART_IER); - break; - default: outb(value, up->port.iobase + offset); } @@ -435,7 +373,6 @@ serial_out_sync(struct uart_8250_port *up, int offset, int value) #ifdef CONFIG_SERIAL_8250_AU1X00 case UPIO_AU: #endif - case UPIO_DWAPB: serial_out(up, offset, value); serial_in(up, UART_LCR); /* safe, no side-effects */ break; @@ -466,7 +403,7 @@ static inline void _serial_dl_write(struct uart_8250_port *up, int value) serial_outp(up, UART_DLM, value >> 8 & 0xff); } -#if defined (CONFIG_SERIAL_8250_AU1X00) +#ifdef CONFIG_SERIAL_8250_AU1X00 /* Au1x00 haven't got a standard divisor latch */ static int serial_dl_read(struct uart_8250_port *up) { @@ -483,24 +420,6 @@ static void serial_dl_write(struct uart_8250_port *up, int value) else _serial_dl_write(up, value); } -#elif defined (CONFIG_SERIAL_8250_RM9K) -static int serial_dl_read(struct uart_8250_port *up) -{ - return (up->port.iotype == UPIO_RM9000) ? - (((__raw_readl(up->port.membase + 0x10) << 8) | - (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff) : - _serial_dl_read(up); -} - -static void serial_dl_write(struct uart_8250_port *up, int value) -{ - if (up->port.iotype == UPIO_RM9000) { - __raw_writel(value, up->port.membase + 0x08); - __raw_writel(value >> 8, up->port.membase + 0x10); - } else { - _serial_dl_write(up, value); - } -} #else #define serial_dl_read(up) _serial_dl_read(up) #define serial_dl_write(up, value) _serial_dl_write(up, value) @@ -702,7 +621,7 @@ static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p) * its clones. (We treat the broken original StarTech 16650 V1 as a * 16550, and why not? Startech doesn't seem to even acknowledge its * existence.) - * + * * What evil have men's minds wrought... */ static void autoconfig_has_efr(struct uart_8250_port *up) @@ -755,7 +674,7 @@ static void autoconfig_has_efr(struct uart_8250_port *up) up->bugs |= UART_BUG_QUOT; return; } - + /* * We check for a XR16C850 by setting DLL and DLM to 0, and then * reading back DLL and DLM. The chip type depends on the DLM @@ -898,7 +817,7 @@ static void autoconfig_16550a(struct uart_8250_port *up) status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ serial_outp(up, 0x04, status1); - + serial_dl_write(up, quot); serial_outp(up, UART_LCR, 0); @@ -994,6 +913,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) * be frobbing the chips IRQ enable register to see if it exists. */ spin_lock_irqsave(&up->port.lock, flags); +// save_flags(flags); cli(); up->capabilities = 0; up->bugs = 0; @@ -1002,7 +922,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) /* * Do a simple existence test first; if we fail this, * there's no point trying anything else. - * + * * 0x80 is used as a nonsense port to prevent against * false positives due to ISA bus float. The * assumption is that 0x80 is a non-existent port; @@ -1041,7 +961,7 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) save_mcr = serial_in(up, UART_MCR); save_lcr = serial_in(up, UART_LCR); - /* + /* * Check to see if a UART is really there. Certain broken * internal modems based on the Rockwell chipset fail this * test, because they apparently don't implement the loopback @@ -1148,8 +1068,9 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags) else serial_outp(up, UART_IER, 0); - out: + out: spin_unlock_irqrestore(&up->port.lock, flags); +// restore_flags(flags); DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); } @@ -1173,7 +1094,7 @@ static void autoconfig_irq(struct uart_8250_port *up) save_mcr = serial_inp(up, UART_MCR); save_ier = serial_inp(up, UART_IER); serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2); - + irqs = probe_irq_on(); serial_outp(up, UART_MCR, 0); udelay (10); @@ -1238,11 +1159,8 @@ static void serial8250_start_tx(struct uart_port *port) if (up->bugs & UART_BUG_TXEN) { unsigned char lsr, iir; lsr = serial_in(up, UART_LSR); - iir = serial_in(up, UART_IIR) & 0x0f; - if ((up->port.type == PORT_RM9000) ? - (lsr & UART_LSR_THRE && - (iir == UART_IIR_NO_INT || iir == UART_IIR_THRI)) : - (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT)) + iir = serial_in(up, UART_IIR); + if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) transmit_chars(up); } } @@ -1470,19 +1388,6 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) handled = 1; - end = NULL; - } else if (up->port.iotype == UPIO_DWAPB && - (iir & UART_IIR_BUSY) == UART_IIR_BUSY) { - /* The DesignWare APB UART has an Busy Detect (0x07) - * interrupt meaning an LCR write attempt occured while the - * UART was busy. The interrupt must be cleared by reading - * the UART status register (USR) and the LCR re-written. */ - unsigned int status; - status = *(volatile u32 *)up->port.private_data; - serial_out(up, UART_LCR, up->lcr); - - handled = 1; - end = NULL; } else if (end == NULL) end = l; @@ -2023,7 +1928,7 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios, /* * Ask the core to calculate the divisor for us. */ - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = serial8250_get_divisor(port, baud); /* @@ -2185,7 +2090,6 @@ static int serial8250_request_std_resource(struct uart_8250_port *up) case UPIO_TSI: case UPIO_MEM32: case UPIO_MEM: - case UPIO_DWAPB: if (!up->port.mapbase) break; @@ -2223,7 +2127,6 @@ static void serial8250_release_std_resource(struct uart_8250_port *up) case UPIO_TSI: case UPIO_MEM32: case UPIO_MEM: - case UPIO_DWAPB: if (!up->port.mapbase) break; diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index e8efe938c4e7..ad9f321968e1 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -73,21 +73,17 @@ config SERIAL_8250_PCI depends on SERIAL_8250 && PCI default SERIAL_8250 help - Say Y here if you have PCI serial ports. - - To compile this driver as a module, choose M here: the module - will be called 8250_pci. + This builds standard PCI serial support. You may be able to + disable this feature if you only need legacy serial support. + Saves about 9K. config SERIAL_8250_PNP tristate "8250/16550 PNP device support" if EMBEDDED depends on SERIAL_8250 && PNP default SERIAL_8250 help - Say Y here if you have serial ports described by PNPBIOS or ACPI. - These are typically ports built into the system board. - - To compile this driver as a module, choose M here: the module - will be called 8250_pnp. + This builds standard PNP serial support. You may be able to + disable this feature if you only need legacy serial support. config SERIAL_8250_HP300 tristate @@ -258,15 +254,6 @@ config SERIAL_8250_AU1X00 to this option. The driver can handle 1 or 2 serial ports. If unsure, say N. -config SERIAL_8250_RM9K - bool "Support for MIPS RM9xxx integrated serial port" - depends on SERIAL_8250 != n && SERIAL_RM9000 - select SERIAL_8250_SHARE_IRQ - help - Selecting this option will add support for the integrated serial - port hardware found on MIPS RM9122 and similar processors. - If unsure, say N. - comment "Non-8250 serial port support" config SERIAL_AMBA_PL010 @@ -512,100 +499,6 @@ config SERIAL_SA1100_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) -config SERIAL_BFIN - tristate "Blackfin serial port support" - depends on BFIN - select SERIAL_CORE - select SERIAL_BFIN_UART0 if (BF531 || BF532 || BF533 || BF561) - help - Add support for the built-in UARTs on the Blackfin. - - To compile this driver as a module, choose M here: the - module will be called bfin_5xx. - -config SERIAL_BFIN_CONSOLE - bool "Console on Blackfin serial port" - depends on SERIAL_BFIN - select SERIAL_CORE_CONSOLE - -choice - prompt "UART Mode" - depends on SERIAL_BFIN - default SERIAL_BFIN_DMA - help - This driver supports the built-in serial ports of the Blackfin family - of CPUs - -config SERIAL_BFIN_DMA - bool "DMA mode" - depends on DMA_UNCACHED_1M - help - This driver works under DMA mode. If this option is selected, the - blackfin simple dma driver is also enabled. - -config SERIAL_BFIN_PIO - bool "PIO mode" - help - This driver works under PIO mode. - -endchoice - -config SERIAL_BFIN_UART0 - bool "Enable UART0" - depends on SERIAL_BFIN - help - Enable UART0 - -config BFIN_UART0_CTSRTS - bool "Enable UART0 hardware flow control" - depends on SERIAL_BFIN_UART0 - help - Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS - signal. - -config UART0_CTS_PIN - int "UART0 CTS pin" - depends on BFIN_UART0_CTSRTS - default 23 - help - The default pin is GPIO_GP7. - Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. - -config UART0_RTS_PIN - int "UART0 RTS pin" - depends on BFIN_UART0_CTSRTS - default 22 - help - The default pin is GPIO_GP6. - Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. - -config SERIAL_BFIN_UART1 - bool "Enable UART1" - depends on SERIAL_BFIN && (BF534 || BF536 || BF537) - help - Enable UART1 - -config BFIN_UART1_CTSRTS - bool "Enable UART1 hardware flow control" - depends on SERIAL_BFIN_UART1 - help - Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS - signal. - -config UART1_CTS_PIN - int "UART1 CTS pin" - depends on BFIN_UART1_CTSRTS - default -1 - help - Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. - -config UART1_RTS_PIN - int "UART1 RTS pin" - depends on BFIN_UART1_CTSRTS - default -1 - help - Refer to ./include/asm-blackfin/gpio.h to see the GPIO map. - config SERIAL_IMX bool "IMX serial port support" depends on ARM && ARCH_IMX diff --git a/trunk/drivers/serial/Makefile b/trunk/drivers/serial/Makefile index 4959bcb8d1ef..6b3560c5749a 100644 --- a/trunk/drivers/serial/Makefile +++ b/trunk/drivers/serial/Makefile @@ -27,7 +27,6 @@ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o obj-$(CONFIG_SERIAL_PXA) += pxa.o obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o -obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o obj-$(CONFIG_SERIAL_SUNHV) += sunhv.o diff --git a/trunk/drivers/serial/amba-pl010.c b/trunk/drivers/serial/amba-pl010.c index 1a9a24b82636..f69bd097166e 100644 --- a/trunk/drivers/serial/amba-pl010.c +++ b/trunk/drivers/serial/amba-pl010.c @@ -48,7 +48,6 @@ #include #include #include -#include #include @@ -71,7 +70,6 @@ */ struct uart_amba_port { struct uart_port port; - struct clk *clk; struct amba_device *dev; struct amba_pl010_data *data; unsigned int old_status; @@ -79,77 +77,73 @@ struct uart_amba_port { static void pl010_stop_tx(struct uart_port *port) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; - cr = readb(uap->port.membase + UART010_CR); + cr = readb(port->membase + UART010_CR); cr &= ~UART010_CR_TIE; - writel(cr, uap->port.membase + UART010_CR); + writel(cr, port->membase + UART010_CR); } static void pl010_start_tx(struct uart_port *port) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; - cr = readb(uap->port.membase + UART010_CR); + cr = readb(port->membase + UART010_CR); cr |= UART010_CR_TIE; - writel(cr, uap->port.membase + UART010_CR); + writel(cr, port->membase + UART010_CR); } static void pl010_stop_rx(struct uart_port *port) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; - cr = readb(uap->port.membase + UART010_CR); + cr = readb(port->membase + UART010_CR); cr &= ~(UART010_CR_RIE | UART010_CR_RTIE); - writel(cr, uap->port.membase + UART010_CR); + writel(cr, port->membase + UART010_CR); } static void pl010_enable_ms(struct uart_port *port) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; - cr = readb(uap->port.membase + UART010_CR); + cr = readb(port->membase + UART010_CR); cr |= UART010_CR_MSIE; - writel(cr, uap->port.membase + UART010_CR); + writel(cr, port->membase + UART010_CR); } -static void pl010_rx_chars(struct uart_amba_port *uap) +static void pl010_rx_chars(struct uart_port *port) { - struct tty_struct *tty = uap->port.info->tty; + struct tty_struct *tty = port->info->tty; unsigned int status, ch, flag, rsr, max_count = 256; - status = readb(uap->port.membase + UART01x_FR); + status = readb(port->membase + UART01x_FR); while (UART_RX_DATA(status) && max_count--) { - ch = readb(uap->port.membase + UART01x_DR); + ch = readb(port->membase + UART01x_DR); flag = TTY_NORMAL; - uap->port.icount.rx++; + port->icount.rx++; /* * Note that the error handling code is * out of the main execution path */ - rsr = readb(uap->port.membase + UART01x_RSR) | UART_DUMMY_RSR_RX; + rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX; if (unlikely(rsr & UART01x_RSR_ANY)) { - writel(0, uap->port.membase + UART01x_ECR); + writel(0, port->membase + UART01x_ECR); if (rsr & UART01x_RSR_BE) { rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); - uap->port.icount.brk++; - if (uart_handle_break(&uap->port)) + port->icount.brk++; + if (uart_handle_break(port)) goto ignore_char; } else if (rsr & UART01x_RSR_PE) - uap->port.icount.parity++; + port->icount.parity++; else if (rsr & UART01x_RSR_FE) - uap->port.icount.frame++; + port->icount.frame++; if (rsr & UART01x_RSR_OE) - uap->port.icount.overrun++; + port->icount.overrun++; - rsr &= uap->port.read_status_mask; + rsr &= port->read_status_mask; if (rsr & UART01x_RSR_BE) flag = TTY_BREAK; @@ -159,52 +153,53 @@ static void pl010_rx_chars(struct uart_amba_port *uap) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(&uap->port, ch)) + if (uart_handle_sysrq_char(port, ch)) goto ignore_char; - uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag); + uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag); ignore_char: - status = readb(uap->port.membase + UART01x_FR); + status = readb(port->membase + UART01x_FR); } tty_flip_buffer_push(tty); return; } -static void pl010_tx_chars(struct uart_amba_port *uap) +static void pl010_tx_chars(struct uart_port *port) { - struct circ_buf *xmit = &uap->port.info->xmit; + struct circ_buf *xmit = &port->info->xmit; int count; - if (uap->port.x_char) { - writel(uap->port.x_char, uap->port.membase + UART01x_DR); - uap->port.icount.tx++; - uap->port.x_char = 0; + if (port->x_char) { + writel(port->x_char, port->membase + UART01x_DR); + port->icount.tx++; + port->x_char = 0; return; } - if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { - pl010_stop_tx(&uap->port); + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + pl010_stop_tx(port); return; } - count = uap->port.fifosize >> 1; + count = port->fifosize >> 1; do { - writel(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); + writel(xmit->buf[xmit->tail], port->membase + UART01x_DR); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - uap->port.icount.tx++; + port->icount.tx++; if (uart_circ_empty(xmit)) break; } while (--count > 0); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&uap->port); + uart_write_wakeup(port); if (uart_circ_empty(xmit)) - pl010_stop_tx(&uap->port); + pl010_stop_tx(port); } -static void pl010_modem_status(struct uart_amba_port *uap) +static void pl010_modem_status(struct uart_port *port) { + struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int status, delta; writel(0, uap->port.membase + UART010_ICR); @@ -231,50 +226,47 @@ static void pl010_modem_status(struct uart_amba_port *uap) static irqreturn_t pl010_int(int irq, void *dev_id) { - struct uart_amba_port *uap = dev_id; + struct uart_port *port = dev_id; unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; int handled = 0; - spin_lock(&uap->port.lock); + spin_lock(&port->lock); - status = readb(uap->port.membase + UART010_IIR); + status = readb(port->membase + UART010_IIR); if (status) { do { if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) - pl010_rx_chars(uap); + pl010_rx_chars(port); if (status & UART010_IIR_MIS) - pl010_modem_status(uap); + pl010_modem_status(port); if (status & UART010_IIR_TIS) - pl010_tx_chars(uap); + pl010_tx_chars(port); if (pass_counter-- == 0) break; - status = readb(uap->port.membase + UART010_IIR); + status = readb(port->membase + UART010_IIR); } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS | UART010_IIR_TIS)); handled = 1; } - spin_unlock(&uap->port.lock); + spin_unlock(&port->lock); return IRQ_RETVAL(handled); } static unsigned int pl010_tx_empty(struct uart_port *port) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; - unsigned int status = readb(uap->port.membase + UART01x_FR); - return status & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; + return readb(port->membase + UART01x_FR) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; } static unsigned int pl010_get_mctrl(struct uart_port *port) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int result = 0; unsigned int status; - status = readb(uap->port.membase + UART01x_FR); + status = readb(port->membase + UART01x_FR); if (status & UART01x_FR_DCD) result |= TIOCM_CAR; if (status & UART01x_FR_DSR) @@ -295,18 +287,17 @@ static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl) static void pl010_break_ctl(struct uart_port *port, int break_state) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned long flags; unsigned int lcr_h; - spin_lock_irqsave(&uap->port.lock, flags); - lcr_h = readb(uap->port.membase + UART010_LCRH); + spin_lock_irqsave(&port->lock, flags); + lcr_h = readb(port->membase + UART010_LCRH); if (break_state == -1) lcr_h |= UART01x_LCRH_BRK; else lcr_h &= ~UART01x_LCRH_BRK; - writel(lcr_h, uap->port.membase + UART010_LCRH); - spin_unlock_irqrestore(&uap->port.lock, flags); + writel(lcr_h, port->membase + UART010_LCRH); + spin_unlock_irqrestore(&port->lock, flags); } static int pl010_startup(struct uart_port *port) @@ -314,71 +305,49 @@ static int pl010_startup(struct uart_port *port) struct uart_amba_port *uap = (struct uart_amba_port *)port; int retval; - /* - * Try to enable the clock producer. - */ - retval = clk_enable(uap->clk); - if (retval) - goto out; - - uap->port.uartclk = clk_get_rate(uap->clk); - /* * Allocate the IRQ */ - retval = request_irq(uap->port.irq, pl010_int, 0, "uart-pl010", uap); + retval = request_irq(port->irq, pl010_int, 0, "uart-pl010", port); if (retval) - goto clk_dis; + return retval; /* * initialise the old status of the modem signals */ - uap->old_status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; + uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY; /* * Finally, enable interrupts */ writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE, - uap->port.membase + UART010_CR); + port->membase + UART010_CR); return 0; - - clk_dis: - clk_disable(uap->clk); - out: - return retval; } static void pl010_shutdown(struct uart_port *port) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; - /* * Free the interrupt */ - free_irq(uap->port.irq, uap); + free_irq(port->irq, port); /* * disable all interrupts, disable the port */ - writel(0, uap->port.membase + UART010_CR); + writel(0, port->membase + UART010_CR); /* disable break condition and fifos */ - writel(readb(uap->port.membase + UART010_LCRH) & + writel(readb(port->membase + UART010_LCRH) & ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN), - uap->port.membase + UART010_LCRH); - - /* - * Shut down the clock producer - */ - clk_disable(uap->clk); + port->membase + UART010_LCRH); } static void pl010_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int lcr_h, old_cr; unsigned long flags; unsigned int baud, quot; @@ -386,7 +355,7 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, /* * Ask the core to calculate the divisor for us. */ - baud = uart_get_baud_rate(port, termios, old, 0, uap->port.uartclk/16); + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); switch (termios->c_cflag & CSIZE) { @@ -410,66 +379,66 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, if (!(termios->c_cflag & PARODD)) lcr_h |= UART01x_LCRH_EPS; } - if (uap->port.fifosize > 1) + if (port->fifosize > 1) lcr_h |= UART01x_LCRH_FEN; - spin_lock_irqsave(&uap->port.lock, flags); + spin_lock_irqsave(&port->lock, flags); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); - uap->port.read_status_mask = UART01x_RSR_OE; + port->read_status_mask = UART01x_RSR_OE; if (termios->c_iflag & INPCK) - uap->port.read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; + port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; if (termios->c_iflag & (BRKINT | PARMRK)) - uap->port.read_status_mask |= UART01x_RSR_BE; + port->read_status_mask |= UART01x_RSR_BE; /* * Characters to ignore */ - uap->port.ignore_status_mask = 0; + port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) - uap->port.ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; + port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; if (termios->c_iflag & IGNBRK) { - uap->port.ignore_status_mask |= UART01x_RSR_BE; + port->ignore_status_mask |= UART01x_RSR_BE; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) - uap->port.ignore_status_mask |= UART01x_RSR_OE; + port->ignore_status_mask |= UART01x_RSR_OE; } /* * Ignore all characters if CREAD is not set. */ if ((termios->c_cflag & CREAD) == 0) - uap->port.ignore_status_mask |= UART_DUMMY_RSR_RX; + port->ignore_status_mask |= UART_DUMMY_RSR_RX; /* first, disable everything */ - old_cr = readb(uap->port.membase + UART010_CR) & ~UART010_CR_MSIE; + old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE; if (UART_ENABLE_MS(port, termios->c_cflag)) old_cr |= UART010_CR_MSIE; - writel(0, uap->port.membase + UART010_CR); + writel(0, port->membase + UART010_CR); /* Set baud rate */ quot -= 1; - writel((quot & 0xf00) >> 8, uap->port.membase + UART010_LCRM); - writel(quot & 0xff, uap->port.membase + UART010_LCRL); + writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM); + writel(quot & 0xff, port->membase + UART010_LCRL); /* * ----------v----------v----------v----------v----- * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L * ----------^----------^----------^----------^----- */ - writel(lcr_h, uap->port.membase + UART010_LCRH); - writel(old_cr, uap->port.membase + UART010_CR); + writel(lcr_h, port->membase + UART010_LCRH); + writel(old_cr, port->membase + UART010_CR); - spin_unlock_irqrestore(&uap->port.lock, flags); + spin_unlock_irqrestore(&port->lock, flags); } static const char *pl010_type(struct uart_port *port) @@ -545,52 +514,47 @@ static struct uart_amba_port *amba_ports[UART_NR]; static void pl010_console_putchar(struct uart_port *port, int ch) { - struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int status; do { - status = readb(uap->port.membase + UART01x_FR); + status = readb(port->membase + UART01x_FR); barrier(); } while (!UART_TX_READY(status)); - writel(ch, uap->port.membase + UART01x_DR); + writel(ch, port->membase + UART01x_DR); } static void pl010_console_write(struct console *co, const char *s, unsigned int count) { - struct uart_amba_port *uap = amba_ports[co->index]; + struct uart_port *port = &amba_ports[co->index]->port; unsigned int status, old_cr; - clk_enable(uap->clk); - /* * First save the CR then disable the interrupts */ - old_cr = readb(uap->port.membase + UART010_CR); - writel(UART01x_CR_UARTEN, uap->port.membase + UART010_CR); + old_cr = readb(port->membase + UART010_CR); + writel(UART01x_CR_UARTEN, port->membase + UART010_CR); - uart_console_write(&uap->port, s, count, pl010_console_putchar); + uart_console_write(port, s, count, pl010_console_putchar); /* * Finally, wait for transmitter to become empty * and restore the TCR */ do { - status = readb(uap->port.membase + UART01x_FR); + status = readb(port->membase + UART01x_FR); barrier(); } while (status & UART01x_FR_BUSY); - writel(old_cr, uap->port.membase + UART010_CR); - - clk_disable(uap->clk); + writel(old_cr, port->membase + UART010_CR); } static void __init -pl010_console_get_options(struct uart_amba_port *uap, int *baud, +pl010_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits) { - if (readb(uap->port.membase + UART010_CR) & UART01x_CR_UARTEN) { + if (readb(port->membase + UART010_CR) & UART01x_CR_UARTEN) { unsigned int lcr_h, quot; - lcr_h = readb(uap->port.membase + UART010_LCRH); + lcr_h = readb(port->membase + UART010_LCRH); *parity = 'n'; if (lcr_h & UART01x_LCRH_PEN) { @@ -605,15 +569,14 @@ pl010_console_get_options(struct uart_amba_port *uap, int *baud, else *bits = 8; - quot = readb(uap->port.membase + UART010_LCRL) | - readb(uap->port.membase + UART010_LCRM) << 8; - *baud = uap->port.uartclk / (16 * (quot + 1)); + quot = readb(port->membase + UART010_LCRL) | readb(port->membase + UART010_LCRM) << 8; + *baud = port->uartclk / (16 * (quot + 1)); } } static int __init pl010_console_setup(struct console *co, char *options) { - struct uart_amba_port *uap; + struct uart_port *port; int baud = 38400; int bits = 8; int parity = 'n'; @@ -626,18 +589,16 @@ static int __init pl010_console_setup(struct console *co, char *options) */ if (co->index >= UART_NR) co->index = 0; - uap = amba_ports[co->index]; - if (!uap) + if (!amba_ports[co->index]) return -ENODEV; - - uap->port.uartclk = clk_get_rate(uap->clk); + port = &amba_ports[co->index]->port; if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else - pl010_console_get_options(uap, &baud, &parity, &bits); + pl010_console_get_options(port, &baud, &parity, &bits); - return uart_set_options(&uap->port, co, baud, parity, bits, flow); + return uart_set_options(port, co, baud, parity, bits, flow); } static struct uart_driver amba_reg; @@ -668,7 +629,7 @@ static struct uart_driver amba_reg = { static int pl010_probe(struct amba_device *dev, void *id) { - struct uart_amba_port *uap; + struct uart_amba_port *port; void __iomem *base; int i, ret; @@ -681,8 +642,8 @@ static int pl010_probe(struct amba_device *dev, void *id) goto out; } - uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); - if (!uap) { + port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); + if (!port) { ret = -ENOMEM; goto out; } @@ -693,57 +654,51 @@ static int pl010_probe(struct amba_device *dev, void *id) goto free; } - uap->clk = clk_get(&dev->dev, "UARTCLK"); - if (IS_ERR(uap->clk)) { - ret = PTR_ERR(uap->clk); - goto unmap; - } - - uap->port.dev = &dev->dev; - uap->port.mapbase = dev->res.start; - uap->port.membase = base; - uap->port.iotype = UPIO_MEM; - uap->port.irq = dev->irq[0]; - uap->port.fifosize = 16; - uap->port.ops = &amba_pl010_pops; - uap->port.flags = UPF_BOOT_AUTOCONF; - uap->port.line = i; - uap->dev = dev; - uap->data = dev->dev.platform_data; - - amba_ports[i] = uap; - - amba_set_drvdata(dev, uap); - ret = uart_add_one_port(&amba_reg, &uap->port); + port->port.dev = &dev->dev; + port->port.mapbase = dev->res.start; + port->port.membase = base; + port->port.iotype = UPIO_MEM; + port->port.irq = dev->irq[0]; + port->port.uartclk = 14745600; + port->port.fifosize = 16; + port->port.ops = &amba_pl010_pops; + port->port.flags = UPF_BOOT_AUTOCONF; + port->port.line = i; + port->dev = dev; + port->data = dev->dev.platform_data; + + amba_ports[i] = port; + + amba_set_drvdata(dev, port); + ret = uart_add_one_port(&amba_reg, &port->port); if (ret) { amba_set_drvdata(dev, NULL); amba_ports[i] = NULL; - clk_put(uap->clk); - unmap: iounmap(base); free: - kfree(uap); + kfree(port); } + out: return ret; } static int pl010_remove(struct amba_device *dev) { - struct uart_amba_port *uap = amba_get_drvdata(dev); + struct uart_amba_port *port = amba_get_drvdata(dev); int i; amba_set_drvdata(dev, NULL); - uart_remove_one_port(&amba_reg, &uap->port); + uart_remove_one_port(&amba_reg, &port->port); for (i = 0; i < ARRAY_SIZE(amba_ports); i++) - if (amba_ports[i] == uap) + if (amba_ports[i] == port) amba_ports[i] = NULL; - iounmap(uap->port.membase); - clk_put(uap->clk); - kfree(uap); + iounmap(port->port.membase); + kfree(port); + return 0; } diff --git a/trunk/drivers/serial/atmel_serial.c b/trunk/drivers/serial/atmel_serial.c index 3320bcd92c0a..935f48fa501d 100644 --- a/trunk/drivers/serial/atmel_serial.c +++ b/trunk/drivers/serial/atmel_serial.c @@ -484,16 +484,11 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios * termios, unsigned long flags; unsigned int mode, imr, quot, baud; - /* Get current mode register */ - mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR); - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); - if (quot > 65535) { /* BRGR is 16-bit, so switch to slower clock */ - quot /= 8; - mode |= ATMEL_US_USCLKS_MCK_DIV8; - } + /* Get current mode register */ + mode = UART_GET_MR(port) & ~(ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR); /* byte size */ switch (termios->c_cflag & CSIZE) { diff --git a/trunk/drivers/serial/atmel_serial.h b/trunk/drivers/serial/atmel_serial.h index e0141776517c..11b44360e108 100644 --- a/trunk/drivers/serial/atmel_serial.h +++ b/trunk/drivers/serial/atmel_serial.h @@ -46,9 +46,6 @@ #define ATMEL_US_USMODE_ISO7816_T1 6 #define ATMEL_US_USMODE_IRDA 8 #define ATMEL_US_USCLKS (3 << 4) /* Clock Selection */ -#define ATMEL_US_USCLKS_MCK (0 << 4) -#define ATMEL_US_USCLKS_MCK_DIV8 (1 << 4) -#define ATMEL_US_USCLKS_SCK (3 << 4) #define ATMEL_US_CHRL (3 << 6) /* Character Length */ #define ATMEL_US_CHRL_5 (0 << 6) #define ATMEL_US_CHRL_6 (1 << 6) diff --git a/trunk/drivers/serial/bfin_5xx.c b/trunk/drivers/serial/bfin_5xx.c deleted file mode 100644 index 408390f93db9..000000000000 --- a/trunk/drivers/serial/bfin_5xx.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * File: drivers/serial/bfin_5xx.c - * Based on: Based on drivers/serial/sa1100.c - * Author: Aubrey Li - * - * Created: - * Description: Driver for blackfin 5xx serial ports - * - * Rev: $Id: bfin_5xx.c,v 1.19 2006/09/24 02:33:53 aubrey Exp $ - * - * Modified: - * Copyright 2006 Analog Devices Inc. - * - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see the file COPYING, or write - * to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if defined(CONFIG_SERIAL_BFIN_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef CONFIG_SERIAL_BFIN_DMA -#include -#include -#include -#include -#endif - -/* UART name and device definitions */ -#define BFIN_SERIAL_NAME "ttyBF" -#define BFIN_SERIAL_MAJOR 204 -#define BFIN_SERIAL_MINOR 64 - -/* - * Setup for console. Argument comes from the menuconfig - */ -#define DMA_RX_XCOUNT 512 -#define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT) - -#define DMA_RX_FLUSH_JIFFIES 5 - -#ifdef CONFIG_SERIAL_BFIN_DMA -static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart); -#else -static void bfin_serial_do_work(struct work_struct *work); -static void bfin_serial_tx_chars(struct bfin_serial_port *uart); -static void local_put_char(struct bfin_serial_port *uart, char ch); -#endif - -static void bfin_serial_mctrl_check(struct bfin_serial_port *uart); - -/* - * interrupts are disabled on entry - */ -static void bfin_serial_stop_tx(struct uart_port *port) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - -#ifdef CONFIG_SERIAL_BFIN_DMA - disable_dma(uart->tx_dma_channel); -#else - unsigned short ier; - - ier = UART_GET_IER(uart); - ier &= ~ETBEI; - UART_PUT_IER(uart, ier); -#endif -} - -/* - * port is locked and interrupts are disabled - */ -static void bfin_serial_start_tx(struct uart_port *port) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - -#ifdef CONFIG_SERIAL_BFIN_DMA - bfin_serial_dma_tx_chars(uart); -#else - unsigned short ier; - ier = UART_GET_IER(uart); - ier |= ETBEI; - UART_PUT_IER(uart, ier); - bfin_serial_tx_chars(uart); -#endif -} - -/* - * Interrupts are enabled - */ -static void bfin_serial_stop_rx(struct uart_port *port) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - unsigned short ier; - - ier = UART_GET_IER(uart); - ier &= ~ERBFI; - UART_PUT_IER(uart, ier); -} - -/* - * Set the modem control timer to fire immediately. - */ -static void bfin_serial_enable_ms(struct uart_port *port) -{ -} - -#ifdef CONFIG_SERIAL_BFIN_PIO -static void local_put_char(struct bfin_serial_port *uart, char ch) -{ - unsigned short status; - int flags = 0; - - spin_lock_irqsave(&uart->port.lock, flags); - - do { - status = UART_GET_LSR(uart); - } while (!(status & THRE)); - - UART_PUT_CHAR(uart, ch); - SSYNC(); - - spin_unlock_irqrestore(&uart->port.lock, flags); -} - -static void bfin_serial_rx_chars(struct bfin_serial_port *uart) -{ - struct tty_struct *tty = uart->port.info?uart->port.info->tty:0; - unsigned int status, ch, flg; -#ifdef BF533_FAMILY - static int in_break = 0; -#endif - - status = UART_GET_LSR(uart); - ch = UART_GET_CHAR(uart); - uart->port.icount.rx++; - -#ifdef BF533_FAMILY - /* The BF533 family of processors have a nice misbehavior where - * they continuously generate characters for a "single" break. - * We have to basically ignore this flood until the "next" valid - * character comes across. All other Blackfin families operate - * properly though. - */ - if (in_break) { - if (ch != 0) { - in_break = 0; - ch = UART_GET_CHAR(uart); - } - return; - } -#endif - - if (status & BI) { -#ifdef BF533_FAMILY - in_break = 1; -#endif - uart->port.icount.brk++; - if (uart_handle_break(&uart->port)) - goto ignore_char; - flg = TTY_BREAK; - } else if (status & PE) { - flg = TTY_PARITY; - uart->port.icount.parity++; - } else if (status & OE) { - flg = TTY_OVERRUN; - uart->port.icount.overrun++; - } else if (status & FE) { - flg = TTY_FRAME; - uart->port.icount.frame++; - } else - flg = TTY_NORMAL; - - if (uart_handle_sysrq_char(&uart->port, ch)) - goto ignore_char; - if (tty) - uart_insert_char(&uart->port, status, 2, ch, flg); - -ignore_char: - if (tty) - tty_flip_buffer_push(tty); -} - -static void bfin_serial_tx_chars(struct bfin_serial_port *uart) -{ - struct circ_buf *xmit = &uart->port.info->xmit; - - if (uart->port.x_char) { - UART_PUT_CHAR(uart, uart->port.x_char); - uart->port.icount.tx++; - uart->port.x_char = 0; - return; - } - /* - * Check the modem control lines before - * transmitting anything. - */ - bfin_serial_mctrl_check(uart); - - if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { - bfin_serial_stop_tx(&uart->port); - return; - } - - local_put_char(uart, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - uart->port.icount.tx++; - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&uart->port); - - if (uart_circ_empty(xmit)) - bfin_serial_stop_tx(&uart->port); -} - -static irqreturn_t bfin_serial_int(int irq, void *dev_id) -{ - struct bfin_serial_port *uart = dev_id; - unsigned short status; - - spin_lock(&uart->port.lock); - status = UART_GET_IIR(uart); - do { - if ((status & IIR_STATUS) == IIR_TX_READY) - bfin_serial_tx_chars(uart); - if ((status & IIR_STATUS) == IIR_RX_READY) - bfin_serial_rx_chars(uart); - status = UART_GET_IIR(uart); - } while (status & (IIR_TX_READY | IIR_RX_READY)); - spin_unlock(&uart->port.lock); - return IRQ_HANDLED; -} - -static void bfin_serial_do_work(struct work_struct *work) -{ - struct bfin_serial_port *uart = container_of(work, struct bfin_serial_port, cts_workqueue); - - bfin_serial_mctrl_check(uart); -} - -#endif - -#ifdef CONFIG_SERIAL_BFIN_DMA -static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart) -{ - struct circ_buf *xmit = &uart->port.info->xmit; - unsigned short ier; - int flags = 0; - - if (!uart->tx_done) - return; - - uart->tx_done = 0; - - if (uart->port.x_char) { - UART_PUT_CHAR(uart, uart->port.x_char); - uart->port.icount.tx++; - uart->port.x_char = 0; - uart->tx_done = 1; - return; - } - /* - * Check the modem control lines before - * transmitting anything. - */ - bfin_serial_mctrl_check(uart); - - if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) { - bfin_serial_stop_tx(&uart->port); - uart->tx_done = 1; - return; - } - - spin_lock_irqsave(&uart->port.lock, flags); - uart->tx_count = CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE); - if (uart->tx_count > (UART_XMIT_SIZE - xmit->tail)) - uart->tx_count = UART_XMIT_SIZE - xmit->tail; - blackfin_dcache_flush_range((unsigned long)(xmit->buf+xmit->tail), - (unsigned long)(xmit->buf+xmit->tail+uart->tx_count)); - set_dma_config(uart->tx_dma_channel, - set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP, - INTR_ON_BUF, - DIMENSION_LINEAR, - DATA_SIZE_8)); - set_dma_start_addr(uart->tx_dma_channel, (unsigned long)(xmit->buf+xmit->tail)); - set_dma_x_count(uart->tx_dma_channel, uart->tx_count); - set_dma_x_modify(uart->tx_dma_channel, 1); - enable_dma(uart->tx_dma_channel); - ier = UART_GET_IER(uart); - ier |= ETBEI; - UART_PUT_IER(uart, ier); - spin_unlock_irqrestore(&uart->port.lock, flags); -} - -static void bfin_serial_dma_rx_chars(struct bfin_serial_port * uart) -{ - struct tty_struct *tty = uart->port.info->tty; - int i, flg, status; - - status = UART_GET_LSR(uart); - uart->port.icount.rx += CIRC_CNT(uart->rx_dma_buf.head, uart->rx_dma_buf.tail, UART_XMIT_SIZE);; - - if (status & BI) { - uart->port.icount.brk++; - if (uart_handle_break(&uart->port)) - goto dma_ignore_char; - flg = TTY_BREAK; - } else if (status & PE) { - flg = TTY_PARITY; - uart->port.icount.parity++; - } else if (status & OE) { - flg = TTY_OVERRUN; - uart->port.icount.overrun++; - } else if (status & FE) { - flg = TTY_FRAME; - uart->port.icount.frame++; - } else - flg = TTY_NORMAL; - - for (i = uart->rx_dma_buf.head; i < uart->rx_dma_buf.tail; i++) { - if (uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i])) - goto dma_ignore_char; - uart_insert_char(&uart->port, status, 2, uart->rx_dma_buf.buf[i], flg); - } -dma_ignore_char: - tty_flip_buffer_push(tty); -} - -void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart) -{ - int x_pos, pos; - int flags = 0; - - bfin_serial_dma_tx_chars(uart); - - spin_lock_irqsave(&uart->port.lock, flags); - x_pos = DMA_RX_XCOUNT - get_dma_curr_xcount(uart->rx_dma_channel); - if (x_pos == DMA_RX_XCOUNT) - x_pos = 0; - - pos = uart->rx_dma_nrows * DMA_RX_XCOUNT + x_pos; - - if (pos>uart->rx_dma_buf.tail) { - uart->rx_dma_buf.tail = pos; - bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.head = uart->rx_dma_buf.tail; - } - spin_unlock_irqrestore(&uart->port.lock, flags); - uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; - add_timer(&(uart->rx_dma_timer)); -} - -static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) -{ - struct bfin_serial_port *uart = dev_id; - struct circ_buf *xmit = &uart->port.info->xmit; - unsigned short ier; - - spin_lock(&uart->port.lock); - if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { - clear_dma_irqstat(uart->tx_dma_channel); - disable_dma(uart->tx_dma_channel); - ier = UART_GET_IER(uart); - ier &= ~ETBEI; - UART_PUT_IER(uart, ier); - xmit->tail = (xmit->tail+uart->tx_count) &(UART_XMIT_SIZE -1); - uart->port.icount.tx+=uart->tx_count; - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(&uart->port); - - if (uart_circ_empty(xmit)) - bfin_serial_stop_tx(&uart->port); - uart->tx_done = 1; - } - - spin_unlock(&uart->port.lock); - return IRQ_HANDLED; -} - -static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id) -{ - struct bfin_serial_port *uart = dev_id; - unsigned short irqstat; - - uart->rx_dma_nrows++; - if (uart->rx_dma_nrows == DMA_RX_YCOUNT) { - uart->rx_dma_nrows = 0; - uart->rx_dma_buf.tail = DMA_RX_XCOUNT*DMA_RX_YCOUNT; - bfin_serial_dma_rx_chars(uart); - uart->rx_dma_buf.head = uart->rx_dma_buf.tail = 0; - } - spin_lock(&uart->port.lock); - irqstat = get_dma_curr_irqstat(uart->rx_dma_channel); - clear_dma_irqstat(uart->rx_dma_channel); - - spin_unlock(&uart->port.lock); - return IRQ_HANDLED; -} -#endif - -/* - * Return TIOCSER_TEMT when transmitter is not busy. - */ -static unsigned int bfin_serial_tx_empty(struct uart_port *port) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - unsigned short lsr; - - lsr = UART_GET_LSR(uart); - if (lsr & TEMT) - return TIOCSER_TEMT; - else - return 0; -} - -static unsigned int bfin_serial_get_mctrl(struct uart_port *port) -{ -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - if (uart->cts_pin < 0) - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - - if (gpio_get_value(uart->cts_pin)) - return TIOCM_DSR | TIOCM_CAR; - else -#endif - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; -} - -static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) -{ -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - if (uart->rts_pin < 0) - return; - - if (mctrl & TIOCM_RTS) - gpio_set_value(uart->rts_pin, 0); - else - gpio_set_value(uart->rts_pin, 1); -#endif -} - -/* - * Handle any change of modem status signal since we were last called. - */ -static void bfin_serial_mctrl_check(struct bfin_serial_port *uart) -{ -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - unsigned int status; -# ifdef CONFIG_SERIAL_BFIN_DMA - struct uart_info *info = uart->port.info; - struct tty_struct *tty = info->tty; - - status = bfin_serial_get_mctrl(&uart->port); - if (!(status & TIOCM_CTS)) { - tty->hw_stopped = 1; - } else { - tty->hw_stopped = 0; - } -# else - status = bfin_serial_get_mctrl(&uart->port); - uart_handle_cts_change(&uart->port, status & TIOCM_CTS); - if (!(status & TIOCM_CTS)) - schedule_work(&uart->cts_workqueue); -# endif -#endif -} - -/* - * Interrupts are always disabled. - */ -static void bfin_serial_break_ctl(struct uart_port *port, int break_state) -{ -} - -static int bfin_serial_startup(struct uart_port *port) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - -#ifdef CONFIG_SERIAL_BFIN_DMA - dma_addr_t dma_handle; - - if (request_dma(uart->rx_dma_channel, "BFIN_UART_RX") < 0) { - printk(KERN_NOTICE "Unable to attach Blackfin UART RX DMA channel\n"); - return -EBUSY; - } - - if (request_dma(uart->tx_dma_channel, "BFIN_UART_TX") < 0) { - printk(KERN_NOTICE "Unable to attach Blackfin UART TX DMA channel\n"); - free_dma(uart->rx_dma_channel); - return -EBUSY; - } - - set_dma_callback(uart->rx_dma_channel, bfin_serial_dma_rx_int, uart); - set_dma_callback(uart->tx_dma_channel, bfin_serial_dma_tx_int, uart); - - uart->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA); - uart->rx_dma_buf.head = 0; - uart->rx_dma_buf.tail = 0; - uart->rx_dma_nrows = 0; - - set_dma_config(uart->rx_dma_channel, - set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO, - INTR_ON_ROW, DIMENSION_2D, - DATA_SIZE_8)); - set_dma_x_count(uart->rx_dma_channel, DMA_RX_XCOUNT); - set_dma_x_modify(uart->rx_dma_channel, 1); - set_dma_y_count(uart->rx_dma_channel, DMA_RX_YCOUNT); - set_dma_y_modify(uart->rx_dma_channel, 1); - set_dma_start_addr(uart->rx_dma_channel, (unsigned long)uart->rx_dma_buf.buf); - enable_dma(uart->rx_dma_channel); - - uart->rx_dma_timer.data = (unsigned long)(uart); - uart->rx_dma_timer.function = (void *)bfin_serial_rx_dma_timeout; - uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; - add_timer(&(uart->rx_dma_timer)); -#else - if (request_irq - (uart->port.irq, bfin_serial_int, IRQF_DISABLED, - "BFIN_UART_RX", uart)) { - printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); - return -EBUSY; - } - - if (request_irq - (uart->port.irq+1, bfin_serial_int, IRQF_DISABLED, - "BFIN_UART_TX", uart)) { - printk(KERN_NOTICE "Unable to attach BlackFin UART TX interrupt\n"); - free_irq(uart->port.irq, uart); - return -EBUSY; - } -#endif - UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI); - return 0; -} - -static void bfin_serial_shutdown(struct uart_port *port) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - -#ifdef CONFIG_SERIAL_BFIN_DMA - disable_dma(uart->tx_dma_channel); - free_dma(uart->tx_dma_channel); - disable_dma(uart->rx_dma_channel); - free_dma(uart->rx_dma_channel); - del_timer(&(uart->rx_dma_timer)); -#else - free_irq(uart->port.irq, uart); - free_irq(uart->port.irq+1, uart); -#endif -} - -static void -bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, - struct ktermios *old) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - unsigned long flags; - unsigned int baud, quot; - unsigned short val, ier, lsr, lcr = 0; - - switch (termios->c_cflag & CSIZE) { - case CS8: - lcr = WLS(8); - break; - case CS7: - lcr = WLS(7); - break; - case CS6: - lcr = WLS(6); - break; - case CS5: - lcr = WLS(5); - break; - default: - printk(KERN_ERR "%s: word lengh not supported\n", - __FUNCTION__); - } - - if (termios->c_cflag & CSTOPB) - lcr |= STB; - if (termios->c_cflag & PARENB) { - lcr |= PEN; - if (!(termios->c_cflag & PARODD)) - lcr |= EPS; - } - - /* These controls are not implemented for this port */ - termios->c_iflag |= INPCK | BRKINT | PARMRK; - termios->c_iflag &= ~(IGNPAR | IGNBRK); - - /* These controls are not implemented for this port */ - termios->c_iflag |= INPCK | BRKINT | PARMRK; - termios->c_iflag &= ~(IGNPAR | IGNBRK); - - baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); - quot = uart_get_divisor(port, baud); - spin_lock_irqsave(&uart->port.lock, flags); - - do { - lsr = UART_GET_LSR(uart); - } while (!(lsr & TEMT)); - - /* Disable UART */ - ier = UART_GET_IER(uart); - UART_PUT_IER(uart, 0); - - /* Set DLAB in LCR to Access DLL and DLH */ - val = UART_GET_LCR(uart); - val |= DLAB; - UART_PUT_LCR(uart, val); - SSYNC(); - - UART_PUT_DLL(uart, quot & 0xFF); - SSYNC(); - UART_PUT_DLH(uart, (quot >> 8) & 0xFF); - SSYNC(); - - /* Clear DLAB in LCR to Access THR RBR IER */ - val = UART_GET_LCR(uart); - val &= ~DLAB; - UART_PUT_LCR(uart, val); - SSYNC(); - - UART_PUT_LCR(uart, lcr); - - /* Enable UART */ - UART_PUT_IER(uart, ier); - - val = UART_GET_GCTL(uart); - val |= UCEN; - UART_PUT_GCTL(uart, val); - - spin_unlock_irqrestore(&uart->port.lock, flags); -} - -static const char *bfin_serial_type(struct uart_port *port) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - - return uart->port.type == PORT_BFIN ? "BFIN-UART" : NULL; -} - -/* - * Release the memory region(s) being used by 'port'. - */ -static void bfin_serial_release_port(struct uart_port *port) -{ -} - -/* - * Request the memory region(s) being used by 'port'. - */ -static int bfin_serial_request_port(struct uart_port *port) -{ - return 0; -} - -/* - * Configure/autoconfigure the port. - */ -static void bfin_serial_config_port(struct uart_port *port, int flags) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - - if (flags & UART_CONFIG_TYPE && - bfin_serial_request_port(&uart->port) == 0) - uart->port.type = PORT_BFIN; -} - -/* - * Verify the new serial_struct (for TIOCSSERIAL). - * The only change we allow are to the flags and type, and - * even then only between PORT_BFIN and PORT_UNKNOWN - */ -static int -bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - return 0; -} - -static struct uart_ops bfin_serial_pops = { - .tx_empty = bfin_serial_tx_empty, - .set_mctrl = bfin_serial_set_mctrl, - .get_mctrl = bfin_serial_get_mctrl, - .stop_tx = bfin_serial_stop_tx, - .start_tx = bfin_serial_start_tx, - .stop_rx = bfin_serial_stop_rx, - .enable_ms = bfin_serial_enable_ms, - .break_ctl = bfin_serial_break_ctl, - .startup = bfin_serial_startup, - .shutdown = bfin_serial_shutdown, - .set_termios = bfin_serial_set_termios, - .type = bfin_serial_type, - .release_port = bfin_serial_release_port, - .request_port = bfin_serial_request_port, - .config_port = bfin_serial_config_port, - .verify_port = bfin_serial_verify_port, -}; - -static void __init bfin_serial_init_ports(void) -{ - static int first = 1; - int i; - - if (!first) - return; - first = 0; - - for (i = 0; i < nr_ports; i++) { - bfin_serial_ports[i].port.uartclk = get_sclk(); - bfin_serial_ports[i].port.ops = &bfin_serial_pops; - bfin_serial_ports[i].port.line = i; - bfin_serial_ports[i].port.iotype = UPIO_MEM; - bfin_serial_ports[i].port.membase = - (void __iomem *)bfin_serial_resource[i].uart_base_addr; - bfin_serial_ports[i].port.mapbase = - bfin_serial_resource[i].uart_base_addr; - bfin_serial_ports[i].port.irq = - bfin_serial_resource[i].uart_irq; - bfin_serial_ports[i].port.flags = UPF_BOOT_AUTOCONF; -#ifdef CONFIG_SERIAL_BFIN_DMA - bfin_serial_ports[i].tx_done = 1; - bfin_serial_ports[i].tx_count = 0; - bfin_serial_ports[i].tx_dma_channel = - bfin_serial_resource[i].uart_tx_dma_channel; - bfin_serial_ports[i].rx_dma_channel = - bfin_serial_resource[i].uart_rx_dma_channel; - init_timer(&(bfin_serial_ports[i].rx_dma_timer)); -#else - INIT_WORK(&bfin_serial_ports[i].cts_workqueue, bfin_serial_do_work); -#endif -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - bfin_serial_ports[i].cts_pin = - bfin_serial_resource[i].uart_cts_pin; - bfin_serial_ports[i].rts_pin = - bfin_serial_resource[i].uart_rts_pin; -#endif - bfin_serial_hw_init(&bfin_serial_ports[i]); - - } -} - -#ifdef CONFIG_SERIAL_BFIN_CONSOLE -static void bfin_serial_console_putchar(struct uart_port *port, int ch) -{ - struct bfin_serial_port *uart = (struct bfin_serial_port *)port; - while (!(UART_GET_LSR(uart))) - barrier(); - UART_PUT_CHAR(uart, ch); - SSYNC(); -} - -/* - * Interrupts are disabled on entering - */ -static void -bfin_serial_console_write(struct console *co, const char *s, unsigned int count) -{ - struct bfin_serial_port *uart = &bfin_serial_ports[co->index]; - int flags = 0; - - spin_lock_irqsave(&uart->port.lock, flags); - uart_console_write(&uart->port, s, count, bfin_serial_console_putchar); - spin_unlock_irqrestore(&uart->port.lock, flags); - -} - -/* - * If the port was already initialised (eg, by a boot loader), - * try to determine the current setup. - */ -static void __init -bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, - int *parity, int *bits) -{ - unsigned short status; - - status = UART_GET_IER(uart) & (ERBFI | ETBEI); - if (status == (ERBFI | ETBEI)) { - /* ok, the port was enabled */ - unsigned short lcr, val; - unsigned short dlh, dll; - - lcr = UART_GET_LCR(uart); - - *parity = 'n'; - if (lcr & PEN) { - if (lcr & EPS) - *parity = 'e'; - else - *parity = 'o'; - } - switch (lcr & 0x03) { - case 0: *bits = 5; break; - case 1: *bits = 6; break; - case 2: *bits = 7; break; - case 3: *bits = 8; break; - } - /* Set DLAB in LCR to Access DLL and DLH */ - val = UART_GET_LCR(uart); - val |= DLAB; - UART_PUT_LCR(uart, val); - - dll = UART_GET_DLL(uart); - dlh = UART_GET_DLH(uart); - - /* Clear DLAB in LCR to Access THR RBR IER */ - val = UART_GET_LCR(uart); - val &= ~DLAB; - UART_PUT_LCR(uart, val); - - *baud = get_sclk() / (16*(dll | dlh << 8)); - } - pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits); -} - -static int __init -bfin_serial_console_setup(struct console *co, char *options) -{ - struct bfin_serial_port *uart; - int baud = 57600; - int bits = 8; - int parity = 'n'; -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - int flow = 'r'; -#else - int flow = 'n'; -#endif - - /* - * Check whether an invalid uart number has been specified, and - * if so, search for the first available port that does have - * console support. - */ - if (co->index == -1 || co->index >= nr_ports) - co->index = 0; - uart = &bfin_serial_ports[co->index]; - - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - else - bfin_serial_console_get_options(uart, &baud, &parity, &bits); - - return uart_set_options(&uart->port, co, baud, parity, bits, flow); -} - -static struct uart_driver bfin_serial_reg; -static struct console bfin_serial_console = { - .name = BFIN_SERIAL_NAME, - .write = bfin_serial_console_write, - .device = uart_console_device, - .setup = bfin_serial_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, - .data = &bfin_serial_reg, -}; - -static int __init bfin_serial_rs_console_init(void) -{ - bfin_serial_init_ports(); - register_console(&bfin_serial_console); - return 0; -} -console_initcall(bfin_serial_rs_console_init); - -#define BFIN_SERIAL_CONSOLE &bfin_serial_console -#else -#define BFIN_SERIAL_CONSOLE NULL -#endif - -static struct uart_driver bfin_serial_reg = { - .owner = THIS_MODULE, - .driver_name = "bfin-uart", - .dev_name = BFIN_SERIAL_NAME, - .major = BFIN_SERIAL_MAJOR, - .minor = BFIN_SERIAL_MINOR, - .nr = NR_PORTS, - .cons = BFIN_SERIAL_CONSOLE, -}; - -static int bfin_serial_suspend(struct platform_device *dev, pm_message_t state) -{ - struct bfin_serial_port *uart = platform_get_drvdata(dev); - - if (uart) - uart_suspend_port(&bfin_serial_reg, &uart->port); - - return 0; -} - -static int bfin_serial_resume(struct platform_device *dev) -{ - struct bfin_serial_port *uart = platform_get_drvdata(dev); - - if (uart) - uart_resume_port(&bfin_serial_reg, &uart->port); - - return 0; -} - -static int bfin_serial_probe(struct platform_device *dev) -{ - struct resource *res = dev->resource; - int i; - - for (i = 0; i < dev->num_resources; i++, res++) - if (res->flags & IORESOURCE_MEM) - break; - - if (i < dev->num_resources) { - for (i = 0; i < nr_ports; i++, res++) { - if (bfin_serial_ports[i].port.mapbase != res->start) - continue; - bfin_serial_ports[i].port.dev = &dev->dev; - uart_add_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port); - platform_set_drvdata(dev, &bfin_serial_ports[i]); - } - } - - return 0; -} - -static int bfin_serial_remove(struct platform_device *pdev) -{ - struct bfin_serial_port *uart = platform_get_drvdata(pdev); - - -#ifdef CONFIG_SERIAL_BFIN_CTSRTS - gpio_free(uart->cts_pin); - gpio_free(uart->rts_pin); -#endif - - platform_set_drvdata(pdev, NULL); - - if (uart) - uart_remove_one_port(&bfin_serial_reg, &uart->port); - - return 0; -} - -static struct platform_driver bfin_serial_driver = { - .probe = bfin_serial_probe, - .remove = bfin_serial_remove, - .suspend = bfin_serial_suspend, - .resume = bfin_serial_resume, - .driver = { - .name = "bfin-uart", - }, -}; - -static int __init bfin_serial_init(void) -{ - int ret; - - pr_info("Serial: Blackfin serial driver\n"); - - bfin_serial_init_ports(); - - ret = uart_register_driver(&bfin_serial_reg); - if (ret == 0) { - ret = platform_driver_register(&bfin_serial_driver); - if (ret) { - pr_debug("uart register failed\n"); - uart_unregister_driver(&bfin_serial_reg); - } - } - return ret; -} - -static void __exit bfin_serial_exit(void) -{ - platform_driver_unregister(&bfin_serial_driver); - uart_unregister_driver(&bfin_serial_reg); -} - -module_init(bfin_serial_init); -module_exit(bfin_serial_exit); - -MODULE_AUTHOR("Aubrey.Li "); -MODULE_DESCRIPTION("Blackfin generic serial port driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR); diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c index f23972bc00c0..7a3b97fdf8d1 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c @@ -934,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .irq = SMC1_IRQ, .ops = &cpm_uart_pops, .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock), + .lock = SPIN_LOCK_UNLOCKED, }, .flags = FLAG_SMC, .tx_nrfifos = TX_NUM_FIFO, @@ -948,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .irq = SMC2_IRQ, .ops = &cpm_uart_pops, .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock), + .lock = SPIN_LOCK_UNLOCKED, }, .flags = FLAG_SMC, .tx_nrfifos = TX_NUM_FIFO, @@ -965,7 +965,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .irq = SCC1_IRQ, .ops = &cpm_uart_pops, .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock), + .lock = SPIN_LOCK_UNLOCKED, }, .tx_nrfifos = TX_NUM_FIFO, .tx_fifosize = TX_BUF_SIZE, @@ -979,7 +979,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .irq = SCC2_IRQ, .ops = &cpm_uart_pops, .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock), + .lock = SPIN_LOCK_UNLOCKED, }, .tx_nrfifos = TX_NUM_FIFO, .tx_fifosize = TX_BUF_SIZE, @@ -993,7 +993,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .irq = SCC3_IRQ, .ops = &cpm_uart_pops, .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock), + .lock = SPIN_LOCK_UNLOCKED, }, .tx_nrfifos = TX_NUM_FIFO, .tx_fifosize = TX_BUF_SIZE, @@ -1007,7 +1007,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { .irq = SCC4_IRQ, .ops = &cpm_uart_pops, .iotype = UPIO_MEM, - .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock), + .lock = SPIN_LOCK_UNLOCKED, }, .tx_nrfifos = TX_NUM_FIFO, .tx_fifosize = TX_BUF_SIZE, diff --git a/trunk/drivers/serial/crisv10.h b/trunk/drivers/serial/crisv10.h new file mode 100644 index 000000000000..4a23340663aa --- /dev/null +++ b/trunk/drivers/serial/crisv10.h @@ -0,0 +1,136 @@ +/* + * serial.h: Arch-dep definitions for the Etrax100 serial driver. + * + * Copyright (C) 1998, 1999, 2000 Axis Communications AB + */ + +#ifndef _ETRAX_SERIAL_H +#define _ETRAX_SERIAL_H + +#include +#include + +/* Software state per channel */ + +#ifdef __KERNEL__ +/* + * This is our internal structure for each serial port's state. + * + * Many fields are paralleled by the structure used by the serial_struct + * structure. + * + * For definitions of the flags field, see tty.h + */ + +#define SERIAL_RECV_DESCRIPTORS 8 + +struct etrax_recv_buffer { + struct etrax_recv_buffer *next; + unsigned short length; + unsigned char error; + unsigned char pad; + + unsigned char buffer[0]; +}; + +struct e100_serial { + int baud; + volatile u8 *port; /* R_SERIALx_CTRL */ + u32 irq; /* bitnr in R_IRQ_MASK2 for dmaX_descr */ + + /* Output registers */ + volatile u8 *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR */ + volatile u32 *ofirstadr; /* adr to R_DMA_CHx_FIRST */ + volatile u8 *ocmdadr; /* adr to R_DMA_CHx_CMD */ + const volatile u8 *ostatusadr; /* adr to R_DMA_CHx_STATUS */ + + /* Input registers */ + volatile u8 *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR */ + volatile u32 *ifirstadr; /* adr to R_DMA_CHx_FIRST */ + volatile u8 *icmdadr; /* adr to R_DMA_CHx_CMD */ + volatile u32 *idescradr; /* adr to R_DMA_CHx_DESCR */ + + int flags; /* defined in tty.h */ + + u8 rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */ + u8 tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */ + u8 iseteop; /* bit number for R_SET_EOP for the input dma */ + int enabled; /* Set to 1 if the port is enabled in HW config */ + + u8 dma_out_enabled:1; /* Set to 1 if DMA should be used */ + u8 dma_in_enabled:1; /* Set to 1 if DMA should be used */ + + /* end of fields defined in rs_table[] in .c-file */ + u8 uses_dma_in; /* Set to 1 if DMA is used */ + u8 uses_dma_out; /* Set to 1 if DMA is used */ + u8 forced_eop; /* a fifo eop has been forced */ + int baud_base; /* For special baudrates */ + int custom_divisor; /* For special baudrates */ + struct etrax_dma_descr tr_descr; + struct etrax_dma_descr rec_descr[SERIAL_RECV_DESCRIPTORS]; + int cur_rec_descr; + + volatile int tr_running; /* 1 if output is running */ + + struct tty_struct *tty; + int read_status_mask; + int ignore_status_mask; + int x_char; /* xon/xoff character */ + int close_delay; + unsigned short closing_wait; + unsigned short closing_wait2; + unsigned long event; + unsigned long last_active; + int line; + int type; /* PORT_ETRAX */ + int count; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + struct circ_buf xmit; + struct etrax_recv_buffer *first_recv_buffer; + struct etrax_recv_buffer *last_recv_buffer; + unsigned int recv_cnt; + unsigned int max_recv_cnt; + + struct work_struct work; + struct async_icount icount; /* error-statistics etc.*/ + struct ktermios normal_termios; + struct ktermios callout_termios; +#ifdef DECLARE_WAITQUEUE + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; +#else + struct wait_queue *open_wait; + struct wait_queue *close_wait; +#endif + + unsigned long char_time_usec; /* The time for 1 char, in usecs */ + unsigned long flush_time_usec; /* How often we should flush */ + unsigned long last_tx_active_usec; /* Last tx usec in the jiffies */ + unsigned long last_tx_active; /* Last tx time in jiffies */ + unsigned long last_rx_active_usec; /* Last rx usec in the jiffies */ + unsigned long last_rx_active; /* Last rx time in jiffies */ + + int break_detected_cnt; + int errorcode; + +#ifdef CONFIG_ETRAX_RS485 + struct rs485_control rs485; /* RS-485 support */ +#endif +}; + +/* this PORT is not in the standard serial.h. it's not actually used for + * anything since we only have one type of async serial-port anyway in this + * system. + */ + +#define PORT_ETRAX 1 + +/* + * Events are used to schedule things to happen at timer-interrupt + * time, instead of at rs interrupt time. + */ +#define RS_EVENT_WRITE_WAKEUP 0 + +#endif /* __KERNEL__ */ + +#endif /* !_ETRAX_SERIAL_H */ diff --git a/trunk/drivers/serial/icom.c b/trunk/drivers/serial/icom.c index 6202995e8211..246c5572667b 100644 --- a/trunk/drivers/serial/icom.c +++ b/trunk/drivers/serial/icom.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/serial/imx.c b/trunk/drivers/serial/imx.c index e42faa4e4282..04cc88cc528c 100644 --- a/trunk/drivers/serial/imx.c +++ b/trunk/drivers/serial/imx.c @@ -46,122 +46,6 @@ #include #include -/* Register definitions */ -#define URXD0 0x0 /* Receiver Register */ -#define URTX0 0x40 /* Transmitter Register */ -#define UCR1 0x80 /* Control Register 1 */ -#define UCR2 0x84 /* Control Register 2 */ -#define UCR3 0x88 /* Control Register 3 */ -#define UCR4 0x8c /* Control Register 4 */ -#define UFCR 0x90 /* FIFO Control Register */ -#define USR1 0x94 /* Status Register 1 */ -#define USR2 0x98 /* Status Register 2 */ -#define UESC 0x9c /* Escape Character Register */ -#define UTIM 0xa0 /* Escape Timer Register */ -#define UBIR 0xa4 /* BRM Incremental Register */ -#define UBMR 0xa8 /* BRM Modulator Register */ -#define UBRC 0xac /* Baud Rate Count Register */ -#define BIPR1 0xb0 /* Incremental Preset Register 1 */ -#define BIPR2 0xb4 /* Incremental Preset Register 2 */ -#define BIPR3 0xb8 /* Incremental Preset Register 3 */ -#define BIPR4 0xbc /* Incremental Preset Register 4 */ -#define BMPR1 0xc0 /* BRM Modulator Register 1 */ -#define BMPR2 0xc4 /* BRM Modulator Register 2 */ -#define BMPR3 0xc8 /* BRM Modulator Register 3 */ -#define BMPR4 0xcc /* BRM Modulator Register 4 */ -#define UTS 0xd0 /* UART Test Register */ - -/* UART Control Register Bit Fields.*/ -#define URXD_CHARRDY (1<<15) -#define URXD_ERR (1<<14) -#define URXD_OVRRUN (1<<13) -#define URXD_FRMERR (1<<12) -#define URXD_BRK (1<<11) -#define URXD_PRERR (1<<10) -#define UCR1_ADEN (1<<15) /* Auto dectect interrupt */ -#define UCR1_ADBR (1<<14) /* Auto detect baud rate */ -#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */ -#define UCR1_IDEN (1<<12) /* Idle condition interrupt */ -#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */ -#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */ -#define UCR1_IREN (1<<7) /* Infrared interface enable */ -#define UCR1_TXMPTYEN (1<<6) /* Transimitter empty interrupt enable */ -#define UCR1_RTSDEN (1<<5) /* RTS delta interrupt enable */ -#define UCR1_SNDBRK (1<<4) /* Send break */ -#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */ -#define UCR1_UARTCLKEN (1<<2) /* UART clock enabled */ -#define UCR1_DOZE (1<<1) /* Doze */ -#define UCR1_UARTEN (1<<0) /* UART enabled */ -#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */ -#define UCR2_IRTS (1<<14) /* Ignore RTS pin */ -#define UCR2_CTSC (1<<13) /* CTS pin control */ -#define UCR2_CTS (1<<12) /* Clear to send */ -#define UCR2_ESCEN (1<<11) /* Escape enable */ -#define UCR2_PREN (1<<8) /* Parity enable */ -#define UCR2_PROE (1<<7) /* Parity odd/even */ -#define UCR2_STPB (1<<6) /* Stop */ -#define UCR2_WS (1<<5) /* Word size */ -#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */ -#define UCR2_TXEN (1<<2) /* Transmitter enabled */ -#define UCR2_RXEN (1<<1) /* Receiver enabled */ -#define UCR2_SRST (1<<0) /* SW reset */ -#define UCR3_DTREN (1<<13) /* DTR interrupt enable */ -#define UCR3_PARERREN (1<<12) /* Parity enable */ -#define UCR3_FRAERREN (1<<11) /* Frame error interrupt enable */ -#define UCR3_DSR (1<<10) /* Data set ready */ -#define UCR3_DCD (1<<9) /* Data carrier detect */ -#define UCR3_RI (1<<8) /* Ring indicator */ -#define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */ -#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ -#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ -#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ -#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */ -#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */ -#define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ -#define UCR3_BPEN (1<<0) /* Preset registers enable */ -#define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ -#define UCR4_INVR (1<<9) /* Inverted infrared reception */ -#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */ -#define UCR4_WKEN (1<<7) /* Wake interrupt enable */ -#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */ -#define UCR4_IRSC (1<<5) /* IR special case */ -#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */ -#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */ -#define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ -#define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ -#define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ -#define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ -#define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ -#define USR1_PARITYERR (1<<15) /* Parity error interrupt flag */ -#define USR1_RTSS (1<<14) /* RTS pin status */ -#define USR1_TRDY (1<<13) /* Transmitter ready interrupt/dma flag */ -#define USR1_RTSD (1<<12) /* RTS delta */ -#define USR1_ESCF (1<<11) /* Escape seq interrupt flag */ -#define USR1_FRAMERR (1<<10) /* Frame error interrupt flag */ -#define USR1_RRDY (1<<9) /* Receiver ready interrupt/dma flag */ -#define USR1_TIMEOUT (1<<7) /* Receive timeout interrupt status */ -#define USR1_RXDS (1<<6) /* Receiver idle interrupt flag */ -#define USR1_AIRINT (1<<5) /* Async IR wake interrupt flag */ -#define USR1_AWAKE (1<<4) /* Aysnc wake interrupt flag */ -#define USR2_ADET (1<<15) /* Auto baud rate detect complete */ -#define USR2_TXFE (1<<14) /* Transmit buffer FIFO empty */ -#define USR2_DTRF (1<<13) /* DTR edge interrupt flag */ -#define USR2_IDLE (1<<12) /* Idle condition */ -#define USR2_IRINT (1<<8) /* Serial infrared interrupt flag */ -#define USR2_WAKE (1<<7) /* Wake */ -#define USR2_RTSF (1<<4) /* RTS edge interrupt flag */ -#define USR2_TXDC (1<<3) /* Transmitter complete */ -#define USR2_BRCD (1<<2) /* Break condition */ -#define USR2_ORE (1<<1) /* Overrun error */ -#define USR2_RDR (1<<0) /* Recv data ready */ -#define UTS_FRCPERR (1<<13) /* Force parity error */ -#define UTS_LOOP (1<<12) /* Loop tx and rx */ -#define UTS_TXEMPTY (1<<6) /* TxFIFO empty */ -#define UTS_RXEMPTY (1<<5) /* RxFIFO empty */ -#define UTS_TXFULL (1<<4) /* TxFIFO full */ -#define UTS_RXFULL (1<<3) /* RxFIFO full */ -#define UTS_SOFTRST (1<<0) /* Software reset */ - /* We've been assigned a range on the "Low-density serial ports" major */ #define SERIAL_IMX_MAJOR 204 #define MINOR_START 41 @@ -244,10 +128,7 @@ static void imx_timeout(unsigned long data) static void imx_stop_tx(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; - unsigned long temp; - - temp = readl(sport->port.membase + UCR1); - writel(temp & ~UCR1_TXMPTYEN, sport->port.membase + UCR1); + UCR1((u32)sport->port.membase) &= ~UCR1_TXMPTYEN; } /* @@ -256,10 +137,7 @@ static void imx_stop_tx(struct uart_port *port) static void imx_stop_rx(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; - unsigned long temp; - - temp = readl(sport->port.membase + UCR2); - writel(temp &~ UCR2_RXEN, sport->port.membase + UCR2); + UCR2((u32)sport->port.membase) &= ~UCR2_RXEN; } /* @@ -276,10 +154,10 @@ static inline void imx_transmit_buffer(struct imx_port *sport) { struct circ_buf *xmit = &sport->port.info->xmit; - while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) { + while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)) { /* send xmit->buf[xmit->tail] * out the port here */ - writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); + URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); sport->port.icount.tx++; @@ -297,24 +175,21 @@ static inline void imx_transmit_buffer(struct imx_port *sport) static void imx_start_tx(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; - unsigned long temp; - temp = readl(sport->port.membase + UCR1); - writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1); + UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN; - if (readl(sport->port.membase + UTS) & UTS_TXEMPTY) - imx_transmit_buffer(sport); + imx_transmit_buffer(sport); } static irqreturn_t imx_rtsint(int irq, void *dev_id) { struct imx_port *sport = (struct imx_port *)dev_id; - unsigned int val = readl(sport->port.membase + USR1) & USR1_RTSS; + unsigned int val = USR1((u32)sport->port.membase)&USR1_RTSS; unsigned long flags; spin_lock_irqsave(&sport->port.lock, flags); - writel(USR1_RTSD, sport->port.membase + USR1); + USR1((u32)sport->port.membase) = USR1_RTSD; uart_handle_cts_change(&sport->port, !!val); wake_up_interruptible(&sport->port.info->delta_msr_wait); @@ -332,7 +207,7 @@ static irqreturn_t imx_txint(int irq, void *dev_id) if (sport->port.x_char) { /* Send next char */ - writel(sport->port.x_char, sport->port.membase + URTX0); + URTX0((u32)sport->port.membase) = sport->port.x_char; goto out; } @@ -356,18 +231,17 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) struct imx_port *sport = dev_id; unsigned int rx,flg,ignored = 0; struct tty_struct *tty = sport->port.info->tty; - unsigned long flags, temp; + unsigned long flags; - rx = readl(sport->port.membase + URXD0); + rx = URXD0((u32)sport->port.membase); spin_lock_irqsave(&sport->port.lock,flags); do { flg = TTY_NORMAL; sport->port.icount.rx++; - temp = readl(sport->port.membase + USR2); - if( temp & USR2_BRCD ) { - writel(temp | USR2_BRCD, sport->port.membase + USR2); + if( USR2((u32)sport->port.membase) & USR2_BRCD ) { + USR2((u32)sport->port.membase) |= USR2_BRCD; if(uart_handle_break(&sport->port)) goto ignore_char; } @@ -383,7 +257,7 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) tty_insert_flip_char(tty, rx, flg); ignore_char: - rx = readl(sport->port.membase + URXD0); + rx = URXD0((u32)sport->port.membase); } while(rx & URXD_CHARRDY); out: @@ -427,7 +301,7 @@ static unsigned int imx_tx_empty(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; - return (readl(sport->port.membase + USR2) & USR2_TXDC) ? TIOCSER_TEMT : 0; + return USR2((u32)sport->port.membase) & USR2_TXDC ? TIOCSER_TEMT : 0; } /* @@ -438,10 +312,10 @@ static unsigned int imx_get_mctrl(struct uart_port *port) struct imx_port *sport = (struct imx_port *)port; unsigned int tmp = TIOCM_DSR | TIOCM_CAR; - if (readl(sport->port.membase + USR1) & USR1_RTSS) + if (USR1((u32)sport->port.membase) & USR1_RTSS) tmp |= TIOCM_CTS; - if (readl(sport->port.membase + UCR2) & UCR2_CTS) + if (UCR2((u32)sport->port.membase) & UCR2_CTS) tmp |= TIOCM_RTS; return tmp; @@ -450,14 +324,11 @@ static unsigned int imx_get_mctrl(struct uart_port *port) static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct imx_port *sport = (struct imx_port *)port; - unsigned long temp; - - temp = readl(sport->port.membase + UCR2) & ~UCR2_CTS; if (mctrl & TIOCM_RTS) - temp |= UCR2_CTS; - - writel(temp, sport->port.membase + UCR2); + UCR2((u32)sport->port.membase) |= UCR2_CTS; + else + UCR2((u32)sport->port.membase) &= ~UCR2_CTS; } /* @@ -466,16 +337,14 @@ static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) static void imx_break_ctl(struct uart_port *port, int break_state) { struct imx_port *sport = (struct imx_port *)port; - unsigned long flags, temp; + unsigned long flags; spin_lock_irqsave(&sport->port.lock, flags); - temp = readl(sport->port.membase + UCR1) & ~UCR1_SNDBRK; - if ( break_state != 0 ) - temp |= UCR1_SNDBRK; - - writel(temp, sport->port.membase + UCR1); + UCR1((u32)sport->port.membase) |= UCR1_SNDBRK; + else + UCR1((u32)sport->port.membase) &= ~UCR1_SNDBRK; spin_unlock_irqrestore(&sport->port.lock, flags); } @@ -491,7 +360,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) /* set receiver / transmitter trigger level. * RFDIV is set such way to satisfy requested uartclk value */ - val = TXTL << 10 | RXTL; + val = TXTL<<10 | RXTL; ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; if(!ufcr_rfdiv) @@ -504,7 +373,7 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) val |= UFCR_RFDIV & (ufcr_rfdiv << 7); - writel(val, sport->port.membase + UFCR); + UFCR((u32)sport->port.membase) = val; return 0; } @@ -513,15 +382,14 @@ static int imx_startup(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; int retval; - unsigned long flags, temp; + unsigned long flags; imx_setup_ufcr(sport, 0); /* disable the DREN bit (Data Ready interrupt enable) before * requesting IRQs */ - temp = readl(sport->port.membase + UCR4); - writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); + UCR4((u32)sport->port.membase) &= ~UCR4_DREN; /* * Allocate the IRQ @@ -543,16 +411,12 @@ static int imx_startup(struct uart_port *port) /* * Finally, clear and enable interrupts */ - writel(USR1_RTSD, sport->port.membase + USR1); - - temp = readl(sport->port.membase + UCR1); - temp |= (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); - writel(temp, sport->port.membase + UCR1); - temp = readl(sport->port.membase + UCR2); - temp |= (UCR2_RXEN | UCR2_TXEN); - writel(temp, sport->port.membase + UCR2); + USR1((u32)sport->port.membase) = USR1_RTSD; + UCR1((u32)sport->port.membase) |= + (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); + UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN); /* * Enable modem status interrupts */ @@ -573,7 +437,6 @@ static int imx_startup(struct uart_port *port) static void imx_shutdown(struct uart_port *port) { struct imx_port *sport = (struct imx_port *)port; - unsigned long temp; /* * Stop our timer. @@ -591,9 +454,8 @@ static void imx_shutdown(struct uart_port *port) * Disable all interrupts, port and break condition. */ - temp = readl(sport->port.membase + UCR1); - temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); - writel(temp, sport->port.membase + UCR1); + UCR1((u32)sport->port.membase) &= + ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); } static void @@ -686,18 +548,18 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, /* * disable interrupts and drain transmitter */ - old_ucr1 = readl(sport->port.membase + UCR1); - writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), - sport->port.membase + UCR1); + old_ucr1 = UCR1((u32)sport->port.membase); + UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); - while ( !(readl(sport->port.membase + USR2) & USR2_TXDC)) + while ( !(USR2((u32)sport->port.membase) & USR2_TXDC)) barrier(); /* then, disable everything */ - old_txrxen = readl(sport->port.membase + UCR2); - writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN), - sport->port.membase + UCR2); - old_txrxen &= (UCR2_TXEN | UCR2_RXEN); + old_txrxen = UCR2((u32)sport->port.membase) & ( UCR2_TXEN | UCR2_RXEN ); + UCR2((u32)sport->port.membase) &= ~( UCR2_TXEN | UCR2_RXEN); + + /* set the parity, stop bits and data size */ + UCR2((u32)sport->port.membase) = ucr2; /* set the baud rate. We assume uartclk = 16 MHz * @@ -705,13 +567,11 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios, * --------- = -------- * uartclk UBMR - 1 */ - writel((baud / 100) - 1, sport->port.membase + UBIR); - writel(10000 - 1, sport->port.membase + UBMR); - - writel(old_ucr1, sport->port.membase + UCR1); + UBIR((u32)sport->port.membase) = (baud / 100) - 1; + UBMR((u32)sport->port.membase) = 10000 - 1; - /* set the parity, stop bits and data size */ - writel(ucr2 | old_txrxen, sport->port.membase + UCR2); + UCR1((u32)sport->port.membase) = old_ucr1; + UCR2((u32)sport->port.membase) |= old_txrxen; if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) imx_enable_ms(&sport->port); @@ -870,11 +730,9 @@ static void __init imx_init_ports(void) static void imx_console_putchar(struct uart_port *port, int ch) { struct imx_port *sport = (struct imx_port *)port; - - while (readl(sport->port.membase + UTS) & UTS_TXFULL) + while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) barrier(); - - writel(ch, sport->port.membase + URTX0); + URTX0((u32)sport->port.membase) = ch; } /* @@ -889,14 +747,13 @@ imx_console_write(struct console *co, const char *s, unsigned int count) /* * First, save UCR1/2 and then disable interrupts */ - old_ucr1 = readl(sport->port.membase + UCR1); - old_ucr2 = readl(sport->port.membase + UCR2); + old_ucr1 = UCR1((u32)sport->port.membase); + old_ucr2 = UCR2((u32)sport->port.membase); - writel((old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) & - ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), - sport->port.membase + UCR1); - - writel(old_ucr2 | UCR2_TXEN, sport->port.membase + UCR2); + UCR1((u32)sport->port.membase) = + (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) + & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN); + UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; uart_console_write(&sport->port, s, count, imx_console_putchar); @@ -904,10 +761,10 @@ imx_console_write(struct console *co, const char *s, unsigned int count) * Finally, wait for transmitter to become empty * and restore UCR1/2 */ - while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); + while (!(USR2((u32)sport->port.membase) & USR2_TXDC)); - writel(old_ucr1, sport->port.membase + UCR1); - writel(old_ucr2, sport->port.membase + UCR2); + UCR1((u32)sport->port.membase) = old_ucr1; + UCR2((u32)sport->port.membase) = old_ucr2; } /* @@ -919,13 +776,13 @@ imx_console_get_options(struct imx_port *sport, int *baud, int *parity, int *bits) { - if ( readl(sport->port.membase + UCR1) | UCR1_UARTEN ) { + if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) { /* ok, the port was enabled */ unsigned int ucr2, ubir,ubmr, uartclk; unsigned int baud_raw; unsigned int ucfr_rfdiv; - ucr2 = readl(sport->port.membase + UCR2); + ucr2 = UCR2((u32)sport->port.membase); *parity = 'n'; if (ucr2 & UCR2_PREN) { @@ -940,10 +797,11 @@ imx_console_get_options(struct imx_port *sport, int *baud, else *bits = 7; - ubir = readl(sport->port.membase + UBIR) & 0xffff; - ubmr = readl(sport->port.membase + UBMR) & 0xffff; + ubir = UBIR((u32)sport->port.membase) & 0xffff; + ubmr = UBMR((u32)sport->port.membase) & 0xffff; + - ucfr_rfdiv = (readl(sport->port.membase + UFCR) & UFCR_RFDIV) >> 7; + ucfr_rfdiv = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) >> 7; if (ucfr_rfdiv == 6) ucfr_rfdiv = 7; else diff --git a/trunk/drivers/serial/jsm/jsm_neo.c b/trunk/drivers/serial/jsm/jsm_neo.c index b2d6f5b1a7c2..8be8da37f629 100644 --- a/trunk/drivers/serial/jsm/jsm_neo.c +++ b/trunk/drivers/serial/jsm/jsm_neo.c @@ -581,13 +581,8 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals) return; /* Scrub off lower bits. They signify delta's, which I don't care about */ - /* Keep DDCD and DDSR though */ - msignals &= 0xf8; + msignals &= 0xf0; - if (msignals & UART_MSR_DDCD) - uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD); - if (msignals & UART_MSR_DDSR) - uart_handle_cts_change(&ch->uart_port, msignals & UART_MSR_CTS); if (msignals & UART_MSR_DCD) ch->ch_mistat |= UART_MSR_DCD; else diff --git a/trunk/drivers/serial/jsm/jsm_tty.c b/trunk/drivers/serial/jsm/jsm_tty.c index 281f23a371b2..be22bbdbc8e5 100644 --- a/trunk/drivers/serial/jsm/jsm_tty.c +++ b/trunk/drivers/serial/jsm/jsm_tty.c @@ -448,7 +448,6 @@ int jsm_uart_port_init(struct jsm_board *brd) continue; brd->channels[i]->uart_port.irq = brd->irq; - brd->channels[i]->uart_port.uartclk = 14745600; brd->channels[i]->uart_port.type = PORT_JSM; brd->channels[i]->uart_port.iotype = UPIO_MEM; brd->channels[i]->uart_port.membase = brd->re_map_membase; diff --git a/trunk/drivers/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index 35f8b86cc78f..8d24cd521056 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/drivers/serial/mpc52xx_uart.c @@ -257,10 +257,9 @@ mpc52xx_uart_shutdown(struct uart_port *port) { struct mpc52xx_psc __iomem *psc = PSC(port); - /* Shut down the port. Leave TX active if on a console port */ + /* Shut down the port, interrupt and all */ out_8(&psc->command,MPC52xx_PSC_RST_RX); - if (!uart_console(port)) - out_8(&psc->command,MPC52xx_PSC_RST_TX); + out_8(&psc->command,MPC52xx_PSC_RST_TX); port->read_status_mask = 0; out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); @@ -1070,7 +1069,7 @@ mpc52xx_uart_of_enumerate(void) continue; /* Is a particular device number requested? */ - devno = of_get_property(np, "port-number", NULL); + devno = get_property(np, "port-number", NULL); mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1); } diff --git a/trunk/drivers/serial/mpsc.c b/trunk/drivers/serial/mpsc.c index d09f2097d5b0..3d2fcc57b1ce 100644 --- a/trunk/drivers/serial/mpsc.c +++ b/trunk/drivers/serial/mpsc.c @@ -183,7 +183,6 @@ struct mpsc_port_info { u8 *txb_p; /* Phys addr of txb */ int txr_head; /* Where new data goes */ int txr_tail; /* Where sent data comes off */ - spinlock_t tx_lock; /* transmit lock */ /* Mirrored values of regs we can't read (if 'mirror_regs' set) */ u32 MPSC_MPCR_m; @@ -1213,9 +1212,6 @@ mpsc_tx_intr(struct mpsc_port_info *pi) { struct mpsc_tx_desc *txre; int rc = 0; - unsigned long iflags; - - spin_lock_irqsave(&pi->tx_lock, iflags); if (!mpsc_sdma_tx_active(pi)) { txre = (struct mpsc_tx_desc *)(pi->txr + @@ -1252,7 +1248,6 @@ mpsc_tx_intr(struct mpsc_port_info *pi) mpsc_sdma_start_tx(pi); /* start next desc if ready */ } - spin_unlock_irqrestore(&pi->tx_lock, iflags); return rc; } @@ -1343,16 +1338,11 @@ static void mpsc_start_tx(struct uart_port *port) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; - unsigned long iflags; - - spin_lock_irqsave(&pi->tx_lock, iflags); mpsc_unfreeze(pi); mpsc_copy_tx_data(pi); mpsc_sdma_start_tx(pi); - spin_unlock_irqrestore(&pi->tx_lock, iflags); - pr_debug("mpsc_start_tx[%d]\n", port->line); return; } @@ -1635,16 +1625,6 @@ mpsc_console_write(struct console *co, const char *s, uint count) struct mpsc_port_info *pi = &mpsc_ports[co->index]; u8 *bp, *dp, add_cr = 0; int i; - unsigned long iflags; - - spin_lock_irqsave(&pi->tx_lock, iflags); - - while (pi->txr_head != pi->txr_tail) { - while (mpsc_sdma_tx_active(pi)) - udelay(100); - mpsc_sdma_intr_ack(pi); - mpsc_tx_intr(pi); - } while (mpsc_sdma_tx_active(pi)) udelay(100); @@ -1688,7 +1668,6 @@ mpsc_console_write(struct console *co, const char *s, uint count) pi->txr_tail = (pi->txr_tail + 1) & (MPSC_TXR_ENTRIES - 1); } - spin_unlock_irqrestore(&pi->tx_lock, iflags); return; } @@ -2026,8 +2005,7 @@ mpsc_drv_probe(struct platform_device *dev) if (!(rc = mpsc_drv_map_regs(pi, dev))) { mpsc_drv_get_platform_data(pi, dev, dev->id); - if (!(rc = mpsc_make_ready(pi))) { - spin_lock_init(&pi->tx_lock); + if (!(rc = mpsc_make_ready(pi))) if (!(rc = uart_add_one_port(&mpsc_reg, &pi->port))) rc = 0; @@ -2036,7 +2014,6 @@ mpsc_drv_probe(struct platform_device *dev) (struct uart_port *)pi); mpsc_drv_unmap_regs(pi); } - } else mpsc_drv_unmap_regs(pi); } diff --git a/trunk/drivers/serial/of_serial.c b/trunk/drivers/serial/of_serial.c index 7ffdaeaf0545..09b0b736a751 100644 --- a/trunk/drivers/serial/of_serial.c +++ b/trunk/drivers/serial/of_serial.c @@ -29,8 +29,8 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, int ret; memset(port, 0, sizeof *port); - spd = of_get_property(np, "current-speed", NULL); - clk = of_get_property(np, "clock-frequency", NULL); + spd = get_property(np, "current-speed", NULL); + clk = get_property(np, "clock-frequency", NULL); if (!clk) { dev_warn(&ofdev->dev, "no clock-frequency property set\n"); return -ENODEV; @@ -48,8 +48,7 @@ static int __devinit of_platform_serial_setup(struct of_device *ofdev, port->iotype = UPIO_MEM; port->type = type; port->uartclk = *clk; - port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP - | UPF_FIXED_PORT; + port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP; port->dev = &ofdev->dev; port->custom_divisor = *clk / (16 * (*spd)); diff --git a/trunk/drivers/serial/pmac_zilog.c b/trunk/drivers/serial/pmac_zilog.c index 0fa9f6761763..be8d75721a85 100644 --- a/trunk/drivers/serial/pmac_zilog.c +++ b/trunk/drivers/serial/pmac_zilog.c @@ -1450,14 +1450,14 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) /* * Detect port type */ - if (of_device_is_compatible(np, "cobalt")) + if (device_is_compatible(np, "cobalt")) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; - conn = of_get_property(np, "AAPL,connector", &len); + conn = get_property(np, "AAPL,connector", &len); if (conn && (strcmp(conn, "infrared") == 0)) uap->flags |= PMACZILOG_FLAG_IS_IRDA; uap->port_type = PMAC_SCC_ASYNC; /* 1999 Powerbook G3 has slot-names property instead */ - slots = of_get_property(np, "slot-names", &len); + slots = get_property(np, "slot-names", &len); if (slots && slots->count > 0) { if (strcmp(slots->name, "IrDA") == 0) uap->flags |= PMACZILOG_FLAG_IS_IRDA; @@ -1471,7 +1471,7 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) of_find_node_by_name(NULL, "i2c-modem"); if (i2c_modem) { const char* mid = - of_get_property(i2c_modem, "modem-id", NULL); + get_property(i2c_modem, "modem-id", NULL); if (mid) switch(*mid) { case 0x04 : case 0x05 : diff --git a/trunk/drivers/serial/pxa.c b/trunk/drivers/serial/pxa.c index e9c6cb391a23..d403aaa55092 100644 --- a/trunk/drivers/serial/pxa.c +++ b/trunk/drivers/serial/pxa.c @@ -717,7 +717,7 @@ struct uart_ops serial_pxa_pops = { static struct uart_pxa_port serial_pxa_ports[] = { { /* FFUART */ .name = "FFUART", - .cken = CKEN_FFUART, + .cken = CKEN6_FFUART, .port = { .type = PORT_PXA, .iotype = UPIO_MEM, @@ -731,7 +731,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { }, }, { /* BTUART */ .name = "BTUART", - .cken = CKEN_BTUART, + .cken = CKEN7_BTUART, .port = { .type = PORT_PXA, .iotype = UPIO_MEM, @@ -745,7 +745,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { }, }, { /* STUART */ .name = "STUART", - .cken = CKEN_STUART, + .cken = CKEN5_STUART, .port = { .type = PORT_PXA, .iotype = UPIO_MEM, @@ -759,7 +759,7 @@ static struct uart_pxa_port serial_pxa_ports[] = { }, }, { /* HWUART */ .name = "HWUART", - .cken = CKEN_HWUART, + .cken = CKEN4_HWUART, .port = { .type = PORT_PXA, .iotype = UPIO_MEM, diff --git a/trunk/drivers/serial/s3c2410.c b/trunk/drivers/serial/s3c2410.c index 10bc0209cd66..3ba9208ebd0c 100644 --- a/trunk/drivers/serial/s3c2410.c +++ b/trunk/drivers/serial/s3c2410.c @@ -957,7 +957,7 @@ static struct uart_driver s3c24xx_uart_drv = { static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { [0] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock), + .lock = SPIN_LOCK_UNLOCKED, .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX0, .uartclk = 0, @@ -969,7 +969,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { }, [1] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock), + .lock = SPIN_LOCK_UNLOCKED, .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX1, .uartclk = 0, @@ -983,7 +983,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { [2] = { .port = { - .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock), + .lock = SPIN_LOCK_UNLOCKED, .iotype = UPIO_MEM, .irq = IRQ_S3CUART_RX2, .uartclk = 0, diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index 326020f86f75..0422c0f1f852 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -37,6 +37,13 @@ #include #include +#undef DEBUG +#ifdef DEBUG +#define DPRINTK(x...) printk(x) +#else +#define DPRINTK(x...) do { } while (0) +#endif + /* * This is used to lock changes in serial line configuration. */ @@ -545,7 +552,7 @@ static void uart_flush_buffer(struct tty_struct *tty) return; } - pr_debug("uart_flush_buffer(%d) called\n", tty->index); + DPRINTK("uart_flush_buffer(%d) called\n", tty->index); spin_lock_irqsave(&port->lock, flags); uart_circ_clear(&state->info->xmit); @@ -665,21 +672,19 @@ static int uart_set_info(struct uart_state *state, */ mutex_lock(&state->mutex); - change_irq = !(port->flags & UPF_FIXED_PORT) - && new_serial.irq != port->irq; + change_irq = new_serial.irq != port->irq; /* * Since changing the 'type' of the port changes its resource * allocations, we should treat type changes the same as * IO port changes. */ - change_port = !(port->flags & UPF_FIXED_PORT) - && (new_port != port->iobase || - (unsigned long)new_serial.iomem_base != port->mapbase || - new_serial.hub6 != port->hub6 || - new_serial.io_type != port->iotype || - new_serial.iomem_reg_shift != port->regshift || - new_serial.type != port->type); + change_port = new_port != port->iobase || + (unsigned long)new_serial.iomem_base != port->mapbase || + new_serial.hub6 != port->hub6 || + new_serial.io_type != port->iotype || + new_serial.iomem_reg_shift != port->regshift || + new_serial.type != port->type; old_flags = port->flags; new_flags = new_serial.flags; @@ -791,10 +796,8 @@ static int uart_set_info(struct uart_state *state, } } - if (change_irq) - port->irq = new_serial.irq; - if (!(port->flags & UPF_FIXED_PORT)) - port->uartclk = new_serial.baud_base * 16; + port->irq = new_serial.irq; + port->uartclk = new_serial.baud_base * 16; port->flags = (port->flags & ~UPF_CHANGE_MASK) | (new_flags & UPF_CHANGE_MASK); port->custom_divisor = new_serial.custom_divisor; @@ -1217,7 +1220,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) port = state->port; - pr_debug("uart_close(%d) called\n", port->line); + DPRINTK("uart_close(%d) called\n", port->line); mutex_lock(&state->mutex); @@ -1336,7 +1339,7 @@ static void uart_wait_until_sent(struct tty_struct *tty, int timeout) expire = jiffies + timeout; - pr_debug("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n", + DPRINTK("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n", port->line, jiffies, expire); /* @@ -1365,7 +1368,7 @@ static void uart_hangup(struct tty_struct *tty) struct uart_state *state = tty->driver_data; BUG_ON(!kernel_locked()); - pr_debug("uart_hangup(%d)\n", state->port->line); + DPRINTK("uart_hangup(%d)\n", state->port->line); mutex_lock(&state->mutex); if (state->info && state->info->flags & UIF_NORMAL_ACTIVE) { @@ -1563,7 +1566,7 @@ static int uart_open(struct tty_struct *tty, struct file *filp) int retval, line = tty->index; BUG_ON(!kernel_locked()); - pr_debug("uart_open(%d) called\n", line); + DPRINTK("uart_open(%d) called\n", line); /* * tty->driver->num won't change, so we won't fail here with @@ -2061,7 +2064,6 @@ uart_report_port(struct uart_driver *drv, struct uart_port *port) case UPIO_MEM32: case UPIO_AU: case UPIO_TSI: - case UPIO_DWAPB: snprintf(address, sizeof(address), "MMIO 0x%lx", port->mapbase); break; @@ -2407,7 +2409,6 @@ int uart_match_port(struct uart_port *port1, struct uart_port *port2) case UPIO_MEM32: case UPIO_AU: case UPIO_TSI: - case UPIO_DWAPB: return (port1->mapbase == port2->mapbase); } return 0; diff --git a/trunk/drivers/serial/serial_txx9.c b/trunk/drivers/serial/serial_txx9.c index 1deb5764326d..509ace7e6881 100644 --- a/trunk/drivers/serial/serial_txx9.c +++ b/trunk/drivers/serial/serial_txx9.c @@ -15,6 +15,31 @@ * published by the Free Software Foundation. * * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller + * + * Revision History: + * 0.30 Initial revision. (Renamed from serial_txx927.c) + * 0.31 Use save_flags instead of local_irq_save. + * 0.32 Support SCLK. + * 0.33 Switch TXX9_TTY_NAME by CONFIG_SERIAL_TXX9_STDSERIAL. + * Support TIOCSERGETLSR. + * 0.34 Support slow baudrate. + * 0.40 Merge codes from mainstream kernel (2.4.22). + * 0.41 Fix console checking in rs_shutdown_port(). + * Disable flow-control in serial_console_write(). + * 0.42 Fix minor compiler warning. + * 1.00 Kernel 2.6. Converted to new serial core (based on 8250.c). + * 1.01 Set fifosize to make tx_empry called properly. + * Use standard uart_get_divisor. + * 1.02 Cleanup. (import 8250.c changes) + * 1.03 Fix low-latency mode. (import 8250.c changes) + * 1.04 Remove usage of deprecated functions, cleanup. + * 1.05 More strict check in verify_port. Cleanup. + * 1.06 Do not insert a char caused previous overrun. + * Fix some spin_locks. + * Do not call uart_add_one_port for absent ports. + * 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup. + * 1.08 Use platform_device. + * Fix and cleanup suspend/resume/initialization codes. */ #if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) @@ -37,7 +62,7 @@ #include -static char *serial_version = "1.09"; +static char *serial_version = "1.08"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -45,14 +70,13 @@ static char *serial_name = "TX39/49 Serial driver"; #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL) /* "ttyS" is used for standard serial driver */ #define TXX9_TTY_NAME "ttyTX" -#define TXX9_TTY_MINOR_START 196 -#define TXX9_TTY_MAJOR 204 +#define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */ #else /* acts like standard serial driver */ #define TXX9_TTY_NAME "ttyS" #define TXX9_TTY_MINOR_START 64 -#define TXX9_TTY_MAJOR TTY_MAJOR #endif +#define TXX9_TTY_MAJOR TTY_MAJOR /* flag aliases */ #define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART diff --git a/trunk/drivers/serial/sh-sci.c b/trunk/drivers/serial/sh-sci.c index 1f89496d530e..46c40bbc4bc6 100644 --- a/trunk/drivers/serial/sh-sci.c +++ b/trunk/drivers/serial/sh-sci.c @@ -46,7 +46,6 @@ #endif #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) -#include #include #include #include @@ -62,7 +61,7 @@ struct sci_port { unsigned int type; /* Port IRQs: ERI, RXI, TXI, BRI (optional) */ - unsigned int irqs[SCIx_NR_IRQS]; + unsigned int irqs[SCIx_NR_IRQS]; /* Port pin configuration */ void (*init_pins)(struct uart_port *port, @@ -77,11 +76,6 @@ struct sci_port { /* Break timer */ struct timer_list break_timer; int break_flag; - -#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) - /* Port clock */ - struct clk *clk; -#endif }; #ifdef CONFIG_SH_KGDB @@ -169,7 +163,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) usegdb |= sh_bios_in_gdb_mode(); #endif #ifdef CONFIG_SH_KGDB - usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port)); + usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port)); #endif if (usegdb) { @@ -210,7 +204,7 @@ static int kgdb_sci_getchar(void) int c; /* Keep trying to read a character, this could be neater */ - while ((c = get_char(&kgdb_sci_port->port)) < 0) + while ((c = get_char(kgdb_sci_port)) < 0) cpu_relax(); return c; @@ -218,7 +212,7 @@ static int kgdb_sci_getchar(void) static inline void kgdb_sci_putchar(int c) { - put_char(&kgdb_sci_port->port, c); + put_char(kgdb_sci_port, c); } #endif /* CONFIG_SH_KGDB */ @@ -289,23 +283,12 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag) #endif #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF) -#if defined(CONFIG_CPU_SUBTYPE_SH7300) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7710) /* SH7300 doesn't use RTS/CTS */ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) { sci_out(port, SCFCR, 0); } -#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) -static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag) -{ - unsigned int fcr_val = 0; - - set_sh771x_scif_pfc(port); - if (cflag & CRTSCTS) { - fcr_val |= SCFCR_MCE; - } - sci_out(port, SCFCR, fcr_val); -} #elif defined(CONFIG_CPU_SH3) /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) @@ -367,7 +350,7 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) } else { #ifdef CONFIG_CPU_SUBTYPE_SH7343 /* Nothing */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785) +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */ #else ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */ @@ -377,9 +360,7 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) } #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ - defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) +#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) static inline int scif_txroom(struct uart_port *port) { return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f); @@ -754,6 +735,12 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) /* Handle BREAKs */ sci_handle_breaks(port); + +#ifdef CONFIG_SH_KGDB + /* Break into the debugger if a break is detected */ + BREAKPOINT(); +#endif + sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); return IRQ_HANDLED; @@ -960,10 +947,6 @@ static int sci_startup(struct uart_port *port) if (s->enable) s->enable(port); -#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) - s->clk = clk_get(NULL, "module_clk"); -#endif - sci_request_irq(s); sci_start_tx(port); sci_start_rx(port, 1); @@ -981,11 +964,6 @@ static void sci_shutdown(struct uart_port *port) if (s->disable) s->disable(port); - -#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) - clk_put(s->clk); - s->clk = NULL; -#endif } static void sci_set_termios(struct uart_port *port, struct ktermios *termios, @@ -993,6 +971,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, { struct sci_port *s = &sci_ports[port->line]; unsigned int status, baud, smr_val; + unsigned long flags; int t; baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); @@ -1004,14 +983,18 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, default: { #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) - t = SCBRR_VALUE(baud, clk_get_rate(s->clk)); + struct clk *clk = clk_get(NULL, "module_clk"); + t = SCBRR_VALUE(baud, clk_get_rate(clk)); + clk_put(clk); #else t = SCBRR_VALUE(baud); #endif - break; } + break; } + spin_lock_irqsave(&port->lock, flags); + do { status = sci_in(port, SCxSR); } while (!(status & SCxSR_TEND(port))); @@ -1055,6 +1038,8 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, if ((termios->c_cflag & CREAD) != 0) sci_start_rx(port,0); + + spin_unlock_irqrestore(&port->lock, flags); } static const char *sci_type(struct uart_port *port) @@ -1235,12 +1220,9 @@ static int __init serial_console_setup(struct console *co, char *options) if (!port->membase || !port->mapbase) return -ENODEV; - port->type = serial_console_port->type; + spin_lock_init(&port->lock); -#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) - if (!serial_console_port->clk) - serial_console_port->clk = clk_get(NULL, "module_clk"); -#endif + port->type = serial_console_port->type; if (port->flags & UPF_IOREMAP) sci_config_port(port, 0); @@ -1265,7 +1247,7 @@ static struct console serial_console = { .device = uart_console_device, .write = serial_console_write, .setup = serial_console_setup, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER, .index = -1, .data = &sci_uart_driver, }; @@ -1310,23 +1292,11 @@ int __init kgdb_console_setup(struct console *co, char *options) int parity = 'n'; int flow = 'n'; + spin_lock_init(&port->lock); + if (co->index != kgdb_portnum) co->index = kgdb_portnum; - kgdb_sci_port = &sci_ports[co->index]; - port = &kgdb_sci_port->port; - - /* - * Also need to check port->type, we don't actually have any - * UPIO_PORT ports, but uart_report_port() handily misreports - * it anyways if we don't have a port available by the time this is - * called. - */ - if (!port->type) - return -ENODEV; - if (!port->membase || !port->mapbase) - return -ENODEV; - if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); else @@ -1341,12 +1311,11 @@ int __init kgdb_console_setup(struct console *co, char *options) #ifdef CONFIG_SH_KGDB_CONSOLE static struct console kgdb_console = { - .name = "ttySC", - .device = uart_console_device, - .write = kgdb_console_write, - .setup = kgdb_console_setup, - .flags = CON_PRINTBUFFER, - .index = -1, + .name = "ttySC", + .write = kgdb_console_write, + .setup = kgdb_console_setup, + .flags = CON_PRINTBUFFER | CON_ENABLED, + .index = -1, .data = &sci_uart_driver, }; @@ -1392,19 +1361,9 @@ static int __devinit sci_probe(struct platform_device *dev) struct plat_sci_port *p = dev->dev.platform_data; int i; - for (i = 0; p && p->flags != 0; p++, i++) { + for (i = 0; p && p->flags != 0 && i < SCI_NPORTS; p++, i++) { struct sci_port *sciport = &sci_ports[i]; - /* Sanity check */ - if (unlikely(i == SCI_NPORTS)) { - dev_notice(&dev->dev, "Attempting to register port " - "%d when only %d are available.\n", - i+1, SCI_NPORTS); - dev_notice(&dev->dev, "Consider bumping " - "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n"); - break; - } - sciport->port.mapbase = p->mapbase; /* @@ -1427,12 +1386,6 @@ static int __devinit sci_probe(struct platform_device *dev) uart_add_one_port(&sci_uart_driver, &sciport->port); } -#if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE) - kgdb_sci_port = &sci_ports[kgdb_portnum]; - kgdb_getchar = kgdb_sci_getchar; - kgdb_putchar = kgdb_sci_putchar; -#endif - #ifdef CONFIG_CPU_FREQ cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); dev_info(&dev->dev, "sci: CPU frequency notifier registered\n"); diff --git a/trunk/drivers/serial/sh-sci.h b/trunk/drivers/serial/sh-sci.h index fb04fb5f9843..77f7d6351ab1 100644 --- a/trunk/drivers/serial/sh-sci.h +++ b/trunk/drivers/serial/sh-sci.h @@ -73,13 +73,9 @@ # define SCPDR 0xA4050136 /* 16 bit SCIF */ # define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ # define SCIF_ONLY -#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ -# define SCI_NPORTS 2 -# define SCIF_ORER 0x0001 /* overrun error bit */ -# define PACR 0xa4050100 -# define PBCR 0xa4050102 -# define SCSCR_INIT(port) 0x3B +# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ # define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH73180) # define SCPDR 0xA4050138 /* 16 bit SCIF */ @@ -144,16 +140,6 @@ # define SCIF_ORER 0x0001 /* Overrun error bit */ # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY -#elif defined(CONFIG_CPU_SUBTYPE_SH7785) -# define SCSPTR0 0xffea0024 /* 16 bit SCIF */ -# define SCSPTR1 0xffeb0024 /* 16 bit SCIF */ -# define SCSPTR2 0xffec0024 /* 16 bit SCIF */ -# define SCSPTR3 0xffed0024 /* 16 bit SCIF */ -# define SCSPTR4 0xffee0024 /* 16 bit SCIF */ -# define SCSPTR5 0xffef0024 /* 16 bit SCIF */ -# define SCIF_OPER 0x0001 /* Overrun error bit */ -# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ -# define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH7206) # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ # define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ @@ -177,10 +163,7 @@ #define SCI_CTRL_FLAGS_RIE 0x40 /* all */ #define SCI_CTRL_FLAGS_TE 0x20 /* all */ #define SCI_CTRL_FLAGS_RE 0x10 /* all */ -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ - defined(CONFIG_CPU_SUBTYPE_SH7751) || \ - defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) +#if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7780) #define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ #else #define SCI_CTRL_FLAGS_REIE 0 @@ -350,15 +333,9 @@ } #ifdef CONFIG_CPU_SH3 -#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) -#define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ - sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ - h8_sci_offset, h8_sci_size) \ - CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size) -#define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ - CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) -#elif defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ + defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7710) #define SCIF_FNS(name, scif_offset, scif_size) \ CPU_SCIF_FNS(name, scif_offset, scif_size) #else @@ -385,8 +362,8 @@ #endif #if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) - + defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7710) SCIF_FNS(SCSMR, 0x00, 16) SCIF_FNS(SCBRR, 0x04, 8) SCIF_FNS(SCSCR, 0x08, 16) @@ -408,9 +385,7 @@ SCIx_FNS(SCxTDR, 0x06, 8, 0x0c, 8, 0x06, 8, 0x0C, 8, 0x03, 8) SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8) SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) -#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \ - defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) +#if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) @@ -496,24 +471,13 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inb(SCPDR)&0x10 ? 1 : 0; /* SCIF */ return 1; } -#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) +#elif defined(CONFIG_CPU_SUBTYPE_SH7710) static inline int sci_rxd_in(struct uart_port *port) { - return sci_in(port,SCxSR)&0x0010 ? 1 : 0; -} -static inline void set_sh771x_scif_pfc(struct uart_port *port) -{ - if (port->mapbase == 0xA4400000){ - ctrl_outw(ctrl_inw(PACR)&0xffc0,PACR); - ctrl_outw(ctrl_inw(PBCR)&0x0fff,PBCR); - return; - } - if (port->mapbase == 0xA4410000){ - ctrl_outw(ctrl_inw(PBCR)&0xf003,PBCR); - return; - } + if (port->mapbase == SCSPTR0) + return ctrl_inw(SCSPTR0 + 0x10) & 0x01 ? 1 : 0; + return 1; } - #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ defined(CONFIG_CPU_SUBTYPE_SH7751) || \ defined(CONFIG_CPU_SUBTYPE_SH4_202) @@ -612,23 +576,6 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ return 1; } -#elif defined(CONFIG_CPU_SUBTYPE_SH7785) -static inline int sci_rxd_in(struct uart_port *port) -{ - if (port->mapbase == 0xffea0000) - return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ - if (port->mapbase == 0xffeb0000) - return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ - if (port->mapbase == 0xffec0000) - return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ - if (port->mapbase == 0xffed0000) - return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ - if (port->mapbase == 0xffee0000) - return ctrl_inw(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF */ - if (port->mapbase == 0xffef0000) - return ctrl_inw(SCSPTR5) & 0x0001 ? 1 : 0; /* SCIF */ - return 1; -} #elif defined(CONFIG_CPU_SUBTYPE_SH7206) static inline int sci_rxd_in(struct uart_port *port) { @@ -687,9 +634,7 @@ static inline int sci_rxd_in(struct uart_port *port) * -- Mitch Davis - 15 Jul 2000 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) +#if defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7780) #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) #elif defined(CONFIG_CPU_SUBTYPE_SH7705) #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) diff --git a/trunk/drivers/serial/sunsu.c b/trunk/drivers/serial/sunsu.c index 2a63cdba3208..bfd44177a215 100644 --- a/trunk/drivers/serial/sunsu.c +++ b/trunk/drivers/serial/sunsu.c @@ -1312,7 +1312,7 @@ static void sunsu_console_write(struct console *co, const char *s, * - initialize the serial port * Return non-zero if we didn't find a serial port. */ -static int __init sunsu_console_setup(struct console *co, char *options) +static int sunsu_console_setup(struct console *co, char *options) { struct uart_port *port; int baud = 9600; @@ -1343,7 +1343,7 @@ static int __init sunsu_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -static struct console sunsu_console = { +static struct console sunsu_cons = { .name = "ttyS", .write = sunsu_console_write, .device = uart_console_device, @@ -1373,9 +1373,9 @@ static inline struct console *SUNSU_CONSOLE(int num_uart) if (i == num_uart) return NULL; - sunsu_console.index = i; + sunsu_cons.index = i; - return &sunsu_console; + return &sunsu_cons; } #else #define SUNSU_CONSOLE(num_uart) (NULL) diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index 07c587ec71be..7e54e48efd5c 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -58,23 +58,6 @@ config SPI_ATMEL This selects a driver for the Atmel SPI Controller, present on many AT32 (AVR32) and AT91 (ARM) chips. -config SPI_BFIN - tristate "SPI controller driver for ADI Blackfin5xx" - depends on SPI_MASTER && BFIN - help - This is the SPI controller master driver for Blackfin 5xx processor. - -config SPI_AU1550 - tristate "Au1550/Au12x0 SPI Controller" - depends on SPI_MASTER && (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL - select SPI_BITBANG - help - If you say yes to this option, support will be included for the - Au1550 SPI controller (may also work with Au1200,Au1210,Au1250). - - This driver can also be built as a module. If so, the module - will be called au1550_spi. - config SPI_BITBANG tristate "Bitbanging SPI master" depends on SPI_MASTER && EXPERIMENTAL @@ -170,19 +153,11 @@ config SPI_AT25 This driver can also be built as a module. If so, the module will be called at25. -config SPI_SPIDEV - tristate "User mode SPI device driver support" - depends on SPI_MASTER && EXPERIMENTAL - help - This supports user mode SPI protocol drivers. - - Note that this application programming interface is EXPERIMENTAL - and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes. - # # Add new SPI protocol masters in alphabetical order above this line # + # (slave support would go here) endmenu # "SPI support" diff --git a/trunk/drivers/spi/Makefile b/trunk/drivers/spi/Makefile index 624b6363f490..3c280ad89202 100644 --- a/trunk/drivers/spi/Makefile +++ b/trunk/drivers/spi/Makefile @@ -11,10 +11,8 @@ endif obj-$(CONFIG_SPI_MASTER) += spi.o # SPI master controller drivers (bus) -obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o -obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o -obj-$(CONFIG_SPI_AU1550) += au1550_spi.o +obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o obj-$(CONFIG_SPI_IMX) += spi_imx.o obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o @@ -26,7 +24,6 @@ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o # SPI protocol drivers (device/link on bus) obj-$(CONFIG_SPI_AT25) += at25.o -obj-$(CONFIG_SPI_SPIDEV) += spidev.o # ... add above this line ... # SPI slave controller drivers (upstream link) diff --git a/trunk/drivers/spi/au1550_spi.c b/trunk/drivers/spi/au1550_spi.c deleted file mode 100644 index ae2b1af0dba4..000000000000 --- a/trunk/drivers/spi/au1550_spi.c +++ /dev/null @@ -1,974 +0,0 @@ -/* - * au1550_spi.c - au1550 psc spi controller driver - * may work also with au1200, au1210, au1250 - * will not work on au1000, au1100 and au1500 (no full spi controller there) - * - * Copyright (c) 2006 ATRON electronic GmbH - * Author: Jan Nikitenko - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static unsigned usedma = 1; -module_param(usedma, uint, 0644); - -/* -#define AU1550_SPI_DEBUG_LOOPBACK -*/ - - -#define AU1550_SPI_DBDMA_DESCRIPTORS 1 -#define AU1550_SPI_DMA_RXTMP_MINSIZE 2048U - -struct au1550_spi { - struct spi_bitbang bitbang; - - volatile psc_spi_t __iomem *regs; - int irq; - unsigned freq_max; - unsigned freq_min; - - unsigned len; - unsigned tx_count; - unsigned rx_count; - const u8 *tx; - u8 *rx; - - void (*rx_word)(struct au1550_spi *hw); - void (*tx_word)(struct au1550_spi *hw); - int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); - irqreturn_t (*irq_callback)(struct au1550_spi *hw); - - struct completion master_done; - - unsigned usedma; - u32 dma_tx_id; - u32 dma_rx_id; - u32 dma_tx_ch; - u32 dma_rx_ch; - - u8 *dma_rx_tmpbuf; - unsigned dma_rx_tmpbuf_size; - u32 dma_rx_tmpbuf_addr; - - struct spi_master *master; - struct device *dev; - struct au1550_spi_info *pdata; -}; - - -/* we use an 8-bit memory device for dma transfers to/from spi fifo */ -static dbdev_tab_t au1550_spi_mem_dbdev = -{ - .dev_id = DBDMA_MEM_CHAN, - .dev_flags = DEV_FLAGS_ANYUSE|DEV_FLAGS_SYNC, - .dev_tsize = 0, - .dev_devwidth = 8, - .dev_physaddr = 0x00000000, - .dev_intlevel = 0, - .dev_intpolarity = 0 -}; - -static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw); - - -/** - * compute BRG and DIV bits to setup spi clock based on main input clock rate - * that was specified in platform data structure - * according to au1550 datasheet: - * psc_tempclk = psc_mainclk / (2 << DIV) - * spiclk = psc_tempclk / (2 * (BRG + 1)) - * BRG valid range is 4..63 - * DIV valid range is 0..3 - */ -static u32 au1550_spi_baudcfg(struct au1550_spi *hw, unsigned speed_hz) -{ - u32 mainclk_hz = hw->pdata->mainclk_hz; - u32 div, brg; - - for (div = 0; div < 4; div++) { - brg = mainclk_hz / speed_hz / (4 << div); - /* now we have BRG+1 in brg, so count with that */ - if (brg < (4 + 1)) { - brg = (4 + 1); /* speed_hz too big */ - break; /* set lowest brg (div is == 0) */ - } - if (brg <= (63 + 1)) - break; /* we have valid brg and div */ - } - if (div == 4) { - div = 3; /* speed_hz too small */ - brg = (63 + 1); /* set highest brg and div */ - } - brg--; - return PSC_SPICFG_SET_BAUD(brg) | PSC_SPICFG_SET_DIV(div); -} - -static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw) -{ - hw->regs->psc_spimsk = - PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO - | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO - | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD; - au_sync(); - - hw->regs->psc_spievent = - PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO - | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO - | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD; - au_sync(); -} - -static void au1550_spi_reset_fifos(struct au1550_spi *hw) -{ - u32 pcr; - - hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC; - au_sync(); - do { - pcr = hw->regs->psc_spipcr; - au_sync(); - } while (pcr != 0); -} - -/* - * dma transfers are used for the most common spi word size of 8-bits - * we cannot easily change already set up dma channels' width, so if we wanted - * dma support for more than 8-bit words (up to 24 bits), we would need to - * setup dma channels from scratch on each spi transfer, based on bits_per_word - * instead we have pre set up 8 bit dma channels supporting spi 4 to 8 bits - * transfers, and 9 to 24 bits spi transfers will be done in pio irq based mode - * callbacks to handle dma or pio are set up in au1550_spi_bits_handlers_set() - */ -static void au1550_spi_chipsel(struct spi_device *spi, int value) -{ - struct au1550_spi *hw = spi_master_get_devdata(spi->master); - unsigned cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; - u32 cfg, stat; - - switch (value) { - case BITBANG_CS_INACTIVE: - if (hw->pdata->deactivate_cs) - hw->pdata->deactivate_cs(hw->pdata, spi->chip_select, - cspol); - break; - - case BITBANG_CS_ACTIVE: - au1550_spi_bits_handlers_set(hw, spi->bits_per_word); - - cfg = hw->regs->psc_spicfg; - au_sync(); - hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; - au_sync(); - - if (spi->mode & SPI_CPOL) - cfg |= PSC_SPICFG_BI; - else - cfg &= ~PSC_SPICFG_BI; - if (spi->mode & SPI_CPHA) - cfg &= ~PSC_SPICFG_CDE; - else - cfg |= PSC_SPICFG_CDE; - - if (spi->mode & SPI_LSB_FIRST) - cfg |= PSC_SPICFG_MLF; - else - cfg &= ~PSC_SPICFG_MLF; - - if (hw->usedma && spi->bits_per_word <= 8) - cfg &= ~PSC_SPICFG_DD_DISABLE; - else - cfg |= PSC_SPICFG_DD_DISABLE; - cfg = PSC_SPICFG_CLR_LEN(cfg); - cfg |= PSC_SPICFG_SET_LEN(spi->bits_per_word); - - cfg = PSC_SPICFG_CLR_BAUD(cfg); - cfg &= ~PSC_SPICFG_SET_DIV(3); - cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz); - - hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE; - au_sync(); - do { - stat = hw->regs->psc_spistat; - au_sync(); - } while ((stat & PSC_SPISTAT_DR) == 0); - - if (hw->pdata->activate_cs) - hw->pdata->activate_cs(hw->pdata, spi->chip_select, - cspol); - break; - } -} - -static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) -{ - struct au1550_spi *hw = spi_master_get_devdata(spi->master); - unsigned bpw, hz; - u32 cfg, stat; - - bpw = t ? t->bits_per_word : spi->bits_per_word; - hz = t ? t->speed_hz : spi->max_speed_hz; - - if (bpw < 4 || bpw > 24) { - dev_err(&spi->dev, "setupxfer: invalid bits_per_word=%d\n", - bpw); - return -EINVAL; - } - if (hz > spi->max_speed_hz || hz > hw->freq_max || hz < hw->freq_min) { - dev_err(&spi->dev, "setupxfer: clock rate=%d out of range\n", - hz); - return -EINVAL; - } - - au1550_spi_bits_handlers_set(hw, spi->bits_per_word); - - cfg = hw->regs->psc_spicfg; - au_sync(); - hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; - au_sync(); - - if (hw->usedma && bpw <= 8) - cfg &= ~PSC_SPICFG_DD_DISABLE; - else - cfg |= PSC_SPICFG_DD_DISABLE; - cfg = PSC_SPICFG_CLR_LEN(cfg); - cfg |= PSC_SPICFG_SET_LEN(bpw); - - cfg = PSC_SPICFG_CLR_BAUD(cfg); - cfg &= ~PSC_SPICFG_SET_DIV(3); - cfg |= au1550_spi_baudcfg(hw, hz); - - hw->regs->psc_spicfg = cfg; - au_sync(); - - if (cfg & PSC_SPICFG_DE_ENABLE) { - do { - stat = hw->regs->psc_spistat; - au_sync(); - } while ((stat & PSC_SPISTAT_DR) == 0); - } - - au1550_spi_reset_fifos(hw); - au1550_spi_mask_ack_all(hw); - return 0; -} - -static int au1550_spi_setup(struct spi_device *spi) -{ - struct au1550_spi *hw = spi_master_get_devdata(spi->master); - - if (spi->bits_per_word == 0) - spi->bits_per_word = 8; - if (spi->bits_per_word < 4 || spi->bits_per_word > 24) { - dev_err(&spi->dev, "setup: invalid bits_per_word=%d\n", - spi->bits_per_word); - return -EINVAL; - } - - if (spi->max_speed_hz == 0) - spi->max_speed_hz = hw->freq_max; - if (spi->max_speed_hz > hw->freq_max - || spi->max_speed_hz < hw->freq_min) - return -EINVAL; - /* - * NOTE: cannot change speed and other hw settings immediately, - * otherwise sharing of spi bus is not possible, - * so do not call setupxfer(spi, NULL) here - */ - return 0; -} - -/* - * for dma spi transfers, we have to setup rx channel, otherwise there is - * no reliable way how to recognize that spi transfer is done - * dma complete callbacks are called before real spi transfer is finished - * and if only tx dma channel is set up (and rx fifo overflow event masked) - * spi master done event irq is not generated unless rx fifo is empty (emptied) - * so we need rx tmp buffer to use for rx dma if user does not provide one - */ -static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size) -{ - hw->dma_rx_tmpbuf = kmalloc(size, GFP_KERNEL); - if (!hw->dma_rx_tmpbuf) - return -ENOMEM; - hw->dma_rx_tmpbuf_size = size; - hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf, - size, DMA_FROM_DEVICE); - if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) { - kfree(hw->dma_rx_tmpbuf); - hw->dma_rx_tmpbuf = 0; - hw->dma_rx_tmpbuf_size = 0; - return -EFAULT; - } - return 0; -} - -static void au1550_spi_dma_rxtmp_free(struct au1550_spi *hw) -{ - dma_unmap_single(hw->dev, hw->dma_rx_tmpbuf_addr, - hw->dma_rx_tmpbuf_size, DMA_FROM_DEVICE); - kfree(hw->dma_rx_tmpbuf); - hw->dma_rx_tmpbuf = 0; - hw->dma_rx_tmpbuf_size = 0; -} - -static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) -{ - struct au1550_spi *hw = spi_master_get_devdata(spi->master); - dma_addr_t dma_tx_addr; - dma_addr_t dma_rx_addr; - u32 res; - - hw->len = t->len; - hw->tx_count = 0; - hw->rx_count = 0; - - hw->tx = t->tx_buf; - hw->rx = t->rx_buf; - dma_tx_addr = t->tx_dma; - dma_rx_addr = t->rx_dma; - - /* - * check if buffers are already dma mapped, map them otherwise - * use rx buffer in place of tx if tx buffer was not provided - * use temp rx buffer (preallocated or realloc to fit) for rx dma - */ - if (t->rx_buf) { - if (t->rx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ - dma_rx_addr = dma_map_single(hw->dev, - (void *)t->rx_buf, - t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_rx_addr)) - dev_err(hw->dev, "rx dma map error\n"); - } - } else { - if (t->len > hw->dma_rx_tmpbuf_size) { - int ret; - - au1550_spi_dma_rxtmp_free(hw); - ret = au1550_spi_dma_rxtmp_alloc(hw, max(t->len, - AU1550_SPI_DMA_RXTMP_MINSIZE)); - if (ret < 0) - return ret; - } - hw->rx = hw->dma_rx_tmpbuf; - dma_rx_addr = hw->dma_rx_tmpbuf_addr; - dma_sync_single_for_device(hw->dev, dma_rx_addr, - t->len, DMA_FROM_DEVICE); - } - if (t->tx_buf) { - if (t->tx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ - dma_tx_addr = dma_map_single(hw->dev, - (void *)t->tx_buf, - t->len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_tx_addr)) - dev_err(hw->dev, "tx dma map error\n"); - } - } else { - dma_sync_single_for_device(hw->dev, dma_rx_addr, - t->len, DMA_BIDIRECTIONAL); - hw->tx = hw->rx; - } - - /* put buffers on the ring */ - res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, hw->rx, t->len); - if (!res) - dev_err(hw->dev, "rx dma put dest error\n"); - - res = au1xxx_dbdma_put_source(hw->dma_tx_ch, (void *)hw->tx, t->len); - if (!res) - dev_err(hw->dev, "tx dma put source error\n"); - - au1xxx_dbdma_start(hw->dma_rx_ch); - au1xxx_dbdma_start(hw->dma_tx_ch); - - /* by default enable nearly all events interrupt */ - hw->regs->psc_spimsk = PSC_SPIMSK_SD; - au_sync(); - - /* start the transfer */ - hw->regs->psc_spipcr = PSC_SPIPCR_MS; - au_sync(); - - wait_for_completion(&hw->master_done); - - au1xxx_dbdma_stop(hw->dma_tx_ch); - au1xxx_dbdma_stop(hw->dma_rx_ch); - - if (!t->rx_buf) { - /* using the temporal preallocated and premapped buffer */ - dma_sync_single_for_cpu(hw->dev, dma_rx_addr, t->len, - DMA_FROM_DEVICE); - } - /* unmap buffers if mapped above */ - if (t->rx_buf && t->rx_dma == 0 ) - dma_unmap_single(hw->dev, dma_rx_addr, t->len, - DMA_FROM_DEVICE); - if (t->tx_buf && t->tx_dma == 0 ) - dma_unmap_single(hw->dev, dma_tx_addr, t->len, - DMA_TO_DEVICE); - - return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count; -} - -static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) -{ - u32 stat, evnt; - - stat = hw->regs->psc_spistat; - evnt = hw->regs->psc_spievent; - au_sync(); - if ((stat & PSC_SPISTAT_DI) == 0) { - dev_err(hw->dev, "Unexpected IRQ!\n"); - return IRQ_NONE; - } - - if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO - | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO - | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD)) - != 0) { - /* - * due to an spi error we consider transfer as done, - * so mask all events until before next transfer start - * and stop the possibly running dma immediatelly - */ - au1550_spi_mask_ack_all(hw); - au1xxx_dbdma_stop(hw->dma_rx_ch); - au1xxx_dbdma_stop(hw->dma_tx_ch); - - /* get number of transfered bytes */ - hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch); - hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch); - - au1xxx_dbdma_reset(hw->dma_rx_ch); - au1xxx_dbdma_reset(hw->dma_tx_ch); - au1550_spi_reset_fifos(hw); - - dev_err(hw->dev, - "Unexpected SPI error: event=0x%x stat=0x%x!\n", - evnt, stat); - - complete(&hw->master_done); - return IRQ_HANDLED; - } - - if ((evnt & PSC_SPIEVNT_MD) != 0) { - /* transfer completed successfully */ - au1550_spi_mask_ack_all(hw); - hw->rx_count = hw->len; - hw->tx_count = hw->len; - complete(&hw->master_done); - } - return IRQ_HANDLED; -} - - -/* routines to handle different word sizes in pio mode */ -#define AU1550_SPI_RX_WORD(size, mask) \ -static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \ -{ \ - u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \ - au_sync(); \ - if (hw->rx) { \ - *(u##size *)hw->rx = (u##size)fifoword; \ - hw->rx += (size) / 8; \ - } \ - hw->rx_count += (size) / 8; \ -} - -#define AU1550_SPI_TX_WORD(size, mask) \ -static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \ -{ \ - u32 fifoword = 0; \ - if (hw->tx) { \ - fifoword = *(u##size *)hw->tx & (u32)(mask); \ - hw->tx += (size) / 8; \ - } \ - hw->tx_count += (size) / 8; \ - if (hw->tx_count >= hw->len) \ - fifoword |= PSC_SPITXRX_LC; \ - hw->regs->psc_spitxrx = fifoword; \ - au_sync(); \ -} - -AU1550_SPI_RX_WORD(8,0xff) -AU1550_SPI_RX_WORD(16,0xffff) -AU1550_SPI_RX_WORD(32,0xffffff) -AU1550_SPI_TX_WORD(8,0xff) -AU1550_SPI_TX_WORD(16,0xffff) -AU1550_SPI_TX_WORD(32,0xffffff) - -static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t) -{ - u32 stat, mask; - struct au1550_spi *hw = spi_master_get_devdata(spi->master); - - hw->tx = t->tx_buf; - hw->rx = t->rx_buf; - hw->len = t->len; - hw->tx_count = 0; - hw->rx_count = 0; - - /* by default enable nearly all events after filling tx fifo */ - mask = PSC_SPIMSK_SD; - - /* fill the transmit FIFO */ - while (hw->tx_count < hw->len) { - - hw->tx_word(hw); - - if (hw->tx_count >= hw->len) { - /* mask tx fifo request interrupt as we are done */ - mask |= PSC_SPIMSK_TR; - } - - stat = hw->regs->psc_spistat; - au_sync(); - if (stat & PSC_SPISTAT_TF) - break; - } - - /* enable event interrupts */ - hw->regs->psc_spimsk = mask; - au_sync(); - - /* start the transfer */ - hw->regs->psc_spipcr = PSC_SPIPCR_MS; - au_sync(); - - wait_for_completion(&hw->master_done); - - return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count; -} - -static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) -{ - int busy; - u32 stat, evnt; - - stat = hw->regs->psc_spistat; - evnt = hw->regs->psc_spievent; - au_sync(); - if ((stat & PSC_SPISTAT_DI) == 0) { - dev_err(hw->dev, "Unexpected IRQ!\n"); - return IRQ_NONE; - } - - if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO - | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO - | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD)) - != 0) { - dev_err(hw->dev, - "Unexpected SPI error: event=0x%x stat=0x%x!\n", - evnt, stat); - /* - * due to an error we consider transfer as done, - * so mask all events until before next transfer start - */ - au1550_spi_mask_ack_all(hw); - au1550_spi_reset_fifos(hw); - complete(&hw->master_done); - return IRQ_HANDLED; - } - - /* - * while there is something to read from rx fifo - * or there is a space to write to tx fifo: - */ - do { - busy = 0; - stat = hw->regs->psc_spistat; - au_sync(); - - if ((stat & PSC_SPISTAT_RE) == 0 && hw->rx_count < hw->len) { - hw->rx_word(hw); - /* ack the receive request event */ - hw->regs->psc_spievent = PSC_SPIEVNT_RR; - au_sync(); - busy = 1; - } - - if ((stat & PSC_SPISTAT_TF) == 0 && hw->tx_count < hw->len) { - hw->tx_word(hw); - /* ack the transmit request event */ - hw->regs->psc_spievent = PSC_SPIEVNT_TR; - au_sync(); - busy = 1; - } - } while (busy); - - evnt = hw->regs->psc_spievent; - au_sync(); - - if (hw->rx_count >= hw->len || (evnt & PSC_SPIEVNT_MD) != 0) { - /* transfer completed successfully */ - au1550_spi_mask_ack_all(hw); - complete(&hw->master_done); - } - return IRQ_HANDLED; -} - -static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) -{ - struct au1550_spi *hw = spi_master_get_devdata(spi->master); - return hw->txrx_bufs(spi, t); -} - -static irqreturn_t au1550_spi_irq(int irq, void *dev, struct pt_regs *regs) -{ - struct au1550_spi *hw = dev; - return hw->irq_callback(hw); -} - -static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw) -{ - if (bpw <= 8) { - if (hw->usedma) { - hw->txrx_bufs = &au1550_spi_dma_txrxb; - hw->irq_callback = &au1550_spi_dma_irq_callback; - } else { - hw->rx_word = &au1550_spi_rx_word_8; - hw->tx_word = &au1550_spi_tx_word_8; - hw->txrx_bufs = &au1550_spi_pio_txrxb; - hw->irq_callback = &au1550_spi_pio_irq_callback; - } - } else if (bpw <= 16) { - hw->rx_word = &au1550_spi_rx_word_16; - hw->tx_word = &au1550_spi_tx_word_16; - hw->txrx_bufs = &au1550_spi_pio_txrxb; - hw->irq_callback = &au1550_spi_pio_irq_callback; - } else { - hw->rx_word = &au1550_spi_rx_word_32; - hw->tx_word = &au1550_spi_tx_word_32; - hw->txrx_bufs = &au1550_spi_pio_txrxb; - hw->irq_callback = &au1550_spi_pio_irq_callback; - } -} - -static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) -{ - u32 stat, cfg; - - /* set up the PSC for SPI mode */ - hw->regs->psc_ctrl = PSC_CTRL_DISABLE; - au_sync(); - hw->regs->psc_sel = PSC_SEL_PS_SPIMODE; - au_sync(); - - hw->regs->psc_spicfg = 0; - au_sync(); - - hw->regs->psc_ctrl = PSC_CTRL_ENABLE; - au_sync(); - - do { - stat = hw->regs->psc_spistat; - au_sync(); - } while ((stat & PSC_SPISTAT_SR) == 0); - - - cfg = hw->usedma ? 0 : PSC_SPICFG_DD_DISABLE; - cfg |= PSC_SPICFG_SET_LEN(8); - cfg |= PSC_SPICFG_RT_FIFO8 | PSC_SPICFG_TT_FIFO8; - /* use minimal allowed brg and div values as initial setting: */ - cfg |= PSC_SPICFG_SET_BAUD(4) | PSC_SPICFG_SET_DIV(0); - -#ifdef AU1550_SPI_DEBUG_LOOPBACK - cfg |= PSC_SPICFG_LB; -#endif - - hw->regs->psc_spicfg = cfg; - au_sync(); - - au1550_spi_mask_ack_all(hw); - - hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE; - au_sync(); - - do { - stat = hw->regs->psc_spistat; - au_sync(); - } while ((stat & PSC_SPISTAT_DR) == 0); -} - - -static int __init au1550_spi_probe(struct platform_device *pdev) -{ - struct au1550_spi *hw; - struct spi_master *master; - int err = 0; - - master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi)); - if (master == NULL) { - dev_err(&pdev->dev, "No memory for spi_master\n"); - err = -ENOMEM; - goto err_nomem; - } - - hw = spi_master_get_devdata(master); - - hw->master = spi_master_get(master); - hw->pdata = pdev->dev.platform_data; - hw->dev = &pdev->dev; - - if (hw->pdata == NULL) { - dev_err(&pdev->dev, "No platform data supplied\n"); - err = -ENOENT; - goto err_no_pdata; - } - - platform_set_drvdata(pdev, hw); - - init_completion(&hw->master_done); - - hw->bitbang.master = hw->master; - hw->bitbang.setup_transfer = au1550_spi_setupxfer; - hw->bitbang.chipselect = au1550_spi_chipsel; - hw->bitbang.master->setup = au1550_spi_setup; - hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs; - - switch (hw->pdata->bus_num) { - case 0: - hw->irq = AU1550_PSC0_INT; - hw->regs = (volatile psc_spi_t *)PSC0_BASE_ADDR; - hw->dma_rx_id = DSCR_CMD0_PSC0_RX; - hw->dma_tx_id = DSCR_CMD0_PSC0_TX; - break; - case 1: - hw->irq = AU1550_PSC1_INT; - hw->regs = (volatile psc_spi_t *)PSC1_BASE_ADDR; - hw->dma_rx_id = DSCR_CMD0_PSC1_RX; - hw->dma_tx_id = DSCR_CMD0_PSC1_TX; - break; - case 2: - hw->irq = AU1550_PSC2_INT; - hw->regs = (volatile psc_spi_t *)PSC2_BASE_ADDR; - hw->dma_rx_id = DSCR_CMD0_PSC2_RX; - hw->dma_tx_id = DSCR_CMD0_PSC2_TX; - break; - case 3: - hw->irq = AU1550_PSC3_INT; - hw->regs = (volatile psc_spi_t *)PSC3_BASE_ADDR; - hw->dma_rx_id = DSCR_CMD0_PSC3_RX; - hw->dma_tx_id = DSCR_CMD0_PSC3_TX; - break; - default: - dev_err(&pdev->dev, "Wrong bus_num of SPI\n"); - err = -ENOENT; - goto err_no_pdata; - } - - if (request_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t), - pdev->name) == NULL) { - dev_err(&pdev->dev, "Cannot reserve iomem region\n"); - err = -ENXIO; - goto err_no_iores; - } - - - if (usedma) { - if (pdev->dev.dma_mask == NULL) - dev_warn(&pdev->dev, "no dma mask\n"); - else - hw->usedma = 1; - } - - if (hw->usedma) { - /* - * create memory device with 8 bits dev_devwidth - * needed for proper byte ordering to spi fifo - */ - int memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev); - if (!memid) { - dev_err(&pdev->dev, - "Cannot create dma 8 bit mem device\n"); - err = -ENXIO; - goto err_dma_add_dev; - } - - hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(memid, - hw->dma_tx_id, NULL, (void *)hw); - if (hw->dma_tx_ch == 0) { - dev_err(&pdev->dev, - "Cannot allocate tx dma channel\n"); - err = -ENXIO; - goto err_no_txdma; - } - au1xxx_dbdma_set_devwidth(hw->dma_tx_ch, 8); - if (au1xxx_dbdma_ring_alloc(hw->dma_tx_ch, - AU1550_SPI_DBDMA_DESCRIPTORS) == 0) { - dev_err(&pdev->dev, - "Cannot allocate tx dma descriptors\n"); - err = -ENXIO; - goto err_no_txdma_descr; - } - - - hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id, - memid, NULL, (void *)hw); - if (hw->dma_rx_ch == 0) { - dev_err(&pdev->dev, - "Cannot allocate rx dma channel\n"); - err = -ENXIO; - goto err_no_rxdma; - } - au1xxx_dbdma_set_devwidth(hw->dma_rx_ch, 8); - if (au1xxx_dbdma_ring_alloc(hw->dma_rx_ch, - AU1550_SPI_DBDMA_DESCRIPTORS) == 0) { - dev_err(&pdev->dev, - "Cannot allocate rx dma descriptors\n"); - err = -ENXIO; - goto err_no_rxdma_descr; - } - - err = au1550_spi_dma_rxtmp_alloc(hw, - AU1550_SPI_DMA_RXTMP_MINSIZE); - if (err < 0) { - dev_err(&pdev->dev, - "Cannot allocate initial rx dma tmp buffer\n"); - goto err_dma_rxtmp_alloc; - } - } - - au1550_spi_bits_handlers_set(hw, 8); - - err = request_irq(hw->irq, au1550_spi_irq, 0, pdev->name, hw); - if (err) { - dev_err(&pdev->dev, "Cannot claim IRQ\n"); - goto err_no_irq; - } - - master->bus_num = hw->pdata->bus_num; - master->num_chipselect = hw->pdata->num_chipselect; - - /* - * precompute valid range for spi freq - from au1550 datasheet: - * psc_tempclk = psc_mainclk / (2 << DIV) - * spiclk = psc_tempclk / (2 * (BRG + 1)) - * BRG valid range is 4..63 - * DIV valid range is 0..3 - * round the min and max frequencies to values that would still - * produce valid brg and div - */ - { - int min_div = (2 << 0) * (2 * (4 + 1)); - int max_div = (2 << 3) * (2 * (63 + 1)); - hw->freq_max = hw->pdata->mainclk_hz / min_div; - hw->freq_min = hw->pdata->mainclk_hz / (max_div + 1) + 1; - } - - au1550_spi_setup_psc_as_spi(hw); - - err = spi_bitbang_start(&hw->bitbang); - if (err) { - dev_err(&pdev->dev, "Failed to register SPI master\n"); - goto err_register; - } - - dev_info(&pdev->dev, - "spi master registered: bus_num=%d num_chipselect=%d\n", - master->bus_num, master->num_chipselect); - - return 0; - -err_register: - free_irq(hw->irq, hw); - -err_no_irq: - au1550_spi_dma_rxtmp_free(hw); - -err_dma_rxtmp_alloc: -err_no_rxdma_descr: - if (hw->usedma) - au1xxx_dbdma_chan_free(hw->dma_rx_ch); - -err_no_rxdma: -err_no_txdma_descr: - if (hw->usedma) - au1xxx_dbdma_chan_free(hw->dma_tx_ch); - -err_no_txdma: -err_dma_add_dev: - release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t)); - -err_no_iores: -err_no_pdata: - spi_master_put(hw->master); - -err_nomem: - return err; -} - -static int __exit au1550_spi_remove(struct platform_device *pdev) -{ - struct au1550_spi *hw = platform_get_drvdata(pdev); - - dev_info(&pdev->dev, "spi master remove: bus_num=%d\n", - hw->master->bus_num); - - spi_bitbang_stop(&hw->bitbang); - free_irq(hw->irq, hw); - release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t)); - - if (hw->usedma) { - au1550_spi_dma_rxtmp_free(hw); - au1xxx_dbdma_chan_free(hw->dma_rx_ch); - au1xxx_dbdma_chan_free(hw->dma_tx_ch); - } - - platform_set_drvdata(pdev, NULL); - - spi_master_put(hw->master); - return 0; -} - -static struct platform_driver au1550_spi_drv = { - .remove = __exit_p(au1550_spi_remove), - .driver = { - .name = "au1550-spi", - .owner = THIS_MODULE, - }, -}; - -static int __init au1550_spi_init(void) -{ - return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe); -} -module_init(au1550_spi_init); - -static void __exit au1550_spi_exit(void) -{ - platform_driver_unregister(&au1550_spi_drv); -} -module_exit(au1550_spi_exit); - -MODULE_DESCRIPTION("Au1550 PSC SPI Driver"); -MODULE_AUTHOR("Jan Nikitenko "); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index c3219b29b5ac..6657331eed93 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -152,11 +152,6 @@ static void spi_drv_shutdown(struct device *dev) sdrv->shutdown(to_spi_device(dev)); } -/** - * spi_register_driver - register a SPI driver - * @sdrv: the driver to register - * Context: can sleep - */ int spi_register_driver(struct spi_driver *sdrv) { sdrv->driver.bus = &spi_bus_type; @@ -188,13 +183,7 @@ static LIST_HEAD(board_list); static DECLARE_MUTEX(board_lock); -/** - * spi_new_device - instantiate one new SPI device - * @master: Controller to which device is connected - * @chip: Describes the SPI device - * Context: can sleep - * - * On typical mainboards, this is purely internal; and it's not needed +/* On typical mainboards, this is purely internal; and it's not needed * after board init creates the hard-wired devices. Some development * platforms may not be able to use spi_register_board_info though, and * this is exported so that for example a USB or parport based adapter @@ -262,12 +251,7 @@ struct spi_device *spi_new_device(struct spi_master *master, } EXPORT_SYMBOL_GPL(spi_new_device); -/** - * spi_register_board_info - register SPI devices for a given board - * @info: array of chip descriptors - * @n: how many descriptors are provided - * Context: can sleep - * +/* * Board-specific early init code calls this (probably during arch_initcall) * with segments of the SPI device table. Any device nodes are created later, * after the relevant parent SPI controller (bus_num) is defined. We keep @@ -353,10 +337,9 @@ static struct class spi_master_class = { /** * spi_alloc_master - allocate SPI master controller * @dev: the controller, possibly using the platform_bus - * @size: how much zeroed driver-private data to allocate; the pointer to this + * @size: how much driver-private data to preallocate; the pointer to this * memory is in the class_data field of the returned class_device, * accessible with spi_master_get_devdata(). - * Context: can sleep * * This call is used only by SPI master controller drivers, which are the * only ones directly touching chip registers. It's how they allocate @@ -392,7 +375,6 @@ EXPORT_SYMBOL_GPL(spi_alloc_master); /** * spi_register_master - register SPI master controller * @master: initialized master, originally from spi_alloc_master() - * Context: can sleep * * SPI master controllers connect to their drivers using some non-SPI bus, * such as the platform bus. The final stage of probe() in that code @@ -455,7 +437,6 @@ static int __unregister(struct device *dev, void *unused) /** * spi_unregister_master - unregister SPI master controller * @master: the master being unregistered - * Context: can sleep * * This call is used only by SPI master controller drivers, which are the * only ones directly touching chip registers. @@ -474,7 +455,6 @@ EXPORT_SYMBOL_GPL(spi_unregister_master); /** * spi_busnum_to_master - look up master associated with bus_num * @bus_num: the master's bus number - * Context: can sleep * * This call may be used with devices that are registered after * arch init time. It returns a refcounted pointer to the relevant @@ -512,7 +492,6 @@ static void spi_complete(void *arg) * spi_sync - blocking/synchronous SPI data transfers * @spi: device with which data will be exchanged * @message: describes the data transfers - * Context: can sleep * * This call may only be used from a context that may sleep. The sleep * is non-interruptible, and has no timeout. Low-overhead controller @@ -529,7 +508,7 @@ static void spi_complete(void *arg) * * The return value is a negative error code if the message could not be * submitted, else zero. When the value is zero, then message->status is - * also defined; it's the completion code for the transfer, either zero + * also defined: it's the completion code for the transfer, either zero * or a negative error code from the controller driver. */ int spi_sync(struct spi_device *spi, struct spi_message *message) @@ -559,7 +538,6 @@ static u8 *buf; * @n_tx: size of txbuf, in bytes * @rxbuf: buffer into which data will be read * @n_rx: size of rxbuf, in bytes (need not be dma-safe) - * Context: can sleep * * This performs a half duplex MicroWire style transaction with the * device, sending txbuf and then reading rxbuf. The return value @@ -567,8 +545,7 @@ static u8 *buf; * This call may only be used from a context that may sleep. * * Parameters to this routine are always copied using a small buffer; - * portable code should never use this for more than 32 bytes. - * Performance-sensitive or bulk transfer code should instead use + * performance-sensitive or bulk transfer code should instead use * spi_{async,sync}() calls with dma-safe buffers. */ int spi_write_then_read(struct spi_device *spi, diff --git a/trunk/drivers/spi/spi_bfin5xx.c b/trunk/drivers/spi/spi_bfin5xx.c deleted file mode 100644 index ce3c0ce2316e..000000000000 --- a/trunk/drivers/spi/spi_bfin5xx.c +++ /dev/null @@ -1,1313 +0,0 @@ -/* - * File: drivers/spi/bfin5xx_spi.c - * Based on: N/A - * Author: Luke Yang (Analog Devices Inc.) - * - * Created: March. 10th 2006 - * Description: SPI controller driver for Blackfin 5xx - * Bugs: Enter bugs at http://blackfin.uclinux.org/ - * - * Modified: - * March 10, 2006 bfin5xx_spi.c Created. (Luke Yang) - * August 7, 2006 added full duplex mode (Axel Weiss & Luke Yang) - * - * Copyright 2004-2006 Analog Devices Inc. - * - * 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, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY ; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program ; see the file COPYING. - * If not, write to the Free Software Foundation, - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -MODULE_AUTHOR("Luke Yang"); -MODULE_DESCRIPTION("Blackfin 5xx SPI Contoller"); -MODULE_LICENSE("GPL"); - -#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) - -#define DEFINE_SPI_REG(reg, off) \ -static inline u16 read_##reg(void) \ - { return *(volatile unsigned short*)(SPI0_REGBASE + off); } \ -static inline void write_##reg(u16 v) \ - {*(volatile unsigned short*)(SPI0_REGBASE + off) = v;\ - SSYNC();} - -DEFINE_SPI_REG(CTRL, 0x00) -DEFINE_SPI_REG(FLAG, 0x04) -DEFINE_SPI_REG(STAT, 0x08) -DEFINE_SPI_REG(TDBR, 0x0C) -DEFINE_SPI_REG(RDBR, 0x10) -DEFINE_SPI_REG(BAUD, 0x14) -DEFINE_SPI_REG(SHAW, 0x18) -#define START_STATE ((void*)0) -#define RUNNING_STATE ((void*)1) -#define DONE_STATE ((void*)2) -#define ERROR_STATE ((void*)-1) -#define QUEUE_RUNNING 0 -#define QUEUE_STOPPED 1 -int dma_requested; - -struct driver_data { - /* Driver model hookup */ - struct platform_device *pdev; - - /* SPI framework hookup */ - struct spi_master *master; - - /* BFIN hookup */ - struct bfin5xx_spi_master *master_info; - - /* Driver message queue */ - struct workqueue_struct *workqueue; - struct work_struct pump_messages; - spinlock_t lock; - struct list_head queue; - int busy; - int run; - - /* Message Transfer pump */ - struct tasklet_struct pump_transfers; - - /* Current message transfer state info */ - struct spi_message *cur_msg; - struct spi_transfer *cur_transfer; - struct chip_data *cur_chip; - size_t len_in_bytes; - size_t len; - void *tx; - void *tx_end; - void *rx; - void *rx_end; - int dma_mapped; - dma_addr_t rx_dma; - dma_addr_t tx_dma; - size_t rx_map_len; - size_t tx_map_len; - u8 n_bytes; - void (*write) (struct driver_data *); - void (*read) (struct driver_data *); - void (*duplex) (struct driver_data *); -}; - -struct chip_data { - u16 ctl_reg; - u16 baud; - u16 flag; - - u8 chip_select_num; - u8 n_bytes; - u32 width; /* 0 or 1 */ - u8 enable_dma; - u8 bits_per_word; /* 8 or 16 */ - u8 cs_change_per_word; - u8 cs_chg_udelay; - void (*write) (struct driver_data *); - void (*read) (struct driver_data *); - void (*duplex) (struct driver_data *); -}; - -void bfin_spi_enable(struct driver_data *drv_data) -{ - u16 cr; - - cr = read_CTRL(); - write_CTRL(cr | BIT_CTL_ENABLE); - SSYNC(); -} - -void bfin_spi_disable(struct driver_data *drv_data) -{ - u16 cr; - - cr = read_CTRL(); - write_CTRL(cr & (~BIT_CTL_ENABLE)); - SSYNC(); -} - -/* Caculate the SPI_BAUD register value based on input HZ */ -static u16 hz_to_spi_baud(u32 speed_hz) -{ - u_long sclk = get_sclk(); - u16 spi_baud = (sclk / (2 * speed_hz)); - - if ((sclk % (2 * speed_hz)) > 0) - spi_baud++; - - pr_debug("sclk = %ld, speed_hz = %d, spi_baud = %d\n", sclk, speed_hz, - spi_baud); - - return spi_baud; -} - -static int flush(struct driver_data *drv_data) -{ - unsigned long limit = loops_per_jiffy << 1; - - /* wait for stop and clear stat */ - while (!(read_STAT() & BIT_STAT_SPIF) && limit--) - continue; - - write_STAT(BIT_STAT_CLR); - - return limit; -} - -/* stop controller and re-config current chip*/ -static void restore_state(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - /* Clear status and disable clock */ - write_STAT(BIT_STAT_CLR); - bfin_spi_disable(drv_data); - pr_debug("restoring spi ctl state\n"); - -#if defined(CONFIG_BF534) || defined(CONFIG_BF536) || defined(CONFIG_BF537) - pr_debug("chip select number is %d\n", chip->chip_select_num); - - switch (chip->chip_select_num) { - case 1: - bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3c00); - SSYNC(); - break; - - case 2: - case 3: - bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PJSE_SPI); - SSYNC(); - bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3800); - SSYNC(); - break; - - case 4: - bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS4E_SPI); - SSYNC(); - bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3840); - SSYNC(); - break; - - case 5: - bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS5E_SPI); - SSYNC(); - bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3820); - SSYNC(); - break; - - case 6: - bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PFS6E_SPI); - SSYNC(); - bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3810); - SSYNC(); - break; - - case 7: - bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PJCE_SPI); - SSYNC(); - bfin_write_PORTF_FER(bfin_read_PORTF_FER() | 0x3800); - SSYNC(); - break; - } -#endif - - /* Load the registers */ - write_CTRL(chip->ctl_reg); - write_BAUD(chip->baud); - write_FLAG(chip->flag); -} - -/* used to kick off transfer in rx mode */ -static unsigned short dummy_read(void) -{ - unsigned short tmp; - tmp = read_RDBR(); - return tmp; -} - -static void null_writer(struct driver_data *drv_data) -{ - u8 n_bytes = drv_data->n_bytes; - - while (drv_data->tx < drv_data->tx_end) { - write_TDBR(0); - while ((read_STAT() & BIT_STAT_TXS)) - continue; - drv_data->tx += n_bytes; - } -} - -static void null_reader(struct driver_data *drv_data) -{ - u8 n_bytes = drv_data->n_bytes; - dummy_read(); - - while (drv_data->rx < drv_data->rx_end) { - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - dummy_read(); - drv_data->rx += n_bytes; - } -} - -static void u8_writer(struct driver_data *drv_data) -{ - pr_debug("cr8-s is 0x%x\n", read_STAT()); - while (drv_data->tx < drv_data->tx_end) { - write_TDBR(*(u8 *) (drv_data->tx)); - while (read_STAT() & BIT_STAT_TXS) - continue; - ++drv_data->tx; - } - - /* poll for SPI completion before returning */ - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; -} - -static void u8_cs_chg_writer(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - while (drv_data->tx < drv_data->tx_end) { - write_FLAG(chip->flag); - SSYNC(); - - write_TDBR(*(u8 *) (drv_data->tx)); - while (read_STAT() & BIT_STAT_TXS) - continue; - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; - write_FLAG(0xFF00 | chip->flag); - SSYNC(); - if (chip->cs_chg_udelay) - udelay(chip->cs_chg_udelay); - ++drv_data->tx; - } - write_FLAG(0xFF00); - SSYNC(); -} - -static void u8_reader(struct driver_data *drv_data) -{ - pr_debug("cr-8 is 0x%x\n", read_STAT()); - - /* clear TDBR buffer before read(else it will be shifted out) */ - write_TDBR(0xFFFF); - - dummy_read(); - - while (drv_data->rx < drv_data->rx_end - 1) { - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - *(u8 *) (drv_data->rx) = read_RDBR(); - ++drv_data->rx; - } - - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - *(u8 *) (drv_data->rx) = read_SHAW(); - ++drv_data->rx; -} - -static void u8_cs_chg_reader(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - while (drv_data->rx < drv_data->rx_end) { - write_FLAG(chip->flag); - SSYNC(); - - read_RDBR(); /* kick off */ - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; - *(u8 *) (drv_data->rx) = read_SHAW(); - write_FLAG(0xFF00 | chip->flag); - SSYNC(); - if (chip->cs_chg_udelay) - udelay(chip->cs_chg_udelay); - ++drv_data->rx; - } - write_FLAG(0xFF00); - SSYNC(); -} - -static void u8_duplex(struct driver_data *drv_data) -{ - /* in duplex mode, clk is triggered by writing of TDBR */ - while (drv_data->rx < drv_data->rx_end) { - write_TDBR(*(u8 *) (drv_data->tx)); - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - *(u8 *) (drv_data->rx) = read_RDBR(); - ++drv_data->rx; - ++drv_data->tx; - } -} - -static void u8_cs_chg_duplex(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - while (drv_data->rx < drv_data->rx_end) { - write_FLAG(chip->flag); - SSYNC(); - - write_TDBR(*(u8 *) (drv_data->tx)); - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - *(u8 *) (drv_data->rx) = read_RDBR(); - write_FLAG(0xFF00 | chip->flag); - SSYNC(); - if (chip->cs_chg_udelay) - udelay(chip->cs_chg_udelay); - ++drv_data->rx; - ++drv_data->tx; - } - write_FLAG(0xFF00); - SSYNC(); -} - -static void u16_writer(struct driver_data *drv_data) -{ - pr_debug("cr16 is 0x%x\n", read_STAT()); - while (drv_data->tx < drv_data->tx_end) { - write_TDBR(*(u16 *) (drv_data->tx)); - while ((read_STAT() & BIT_STAT_TXS)) - continue; - drv_data->tx += 2; - } - - /* poll for SPI completion before returning */ - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; -} - -static void u16_cs_chg_writer(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - while (drv_data->tx < drv_data->tx_end) { - write_FLAG(chip->flag); - SSYNC(); - - write_TDBR(*(u16 *) (drv_data->tx)); - while ((read_STAT() & BIT_STAT_TXS)) - continue; - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; - write_FLAG(0xFF00 | chip->flag); - SSYNC(); - if (chip->cs_chg_udelay) - udelay(chip->cs_chg_udelay); - drv_data->tx += 2; - } - write_FLAG(0xFF00); - SSYNC(); -} - -static void u16_reader(struct driver_data *drv_data) -{ - pr_debug("cr-16 is 0x%x\n", read_STAT()); - dummy_read(); - - while (drv_data->rx < (drv_data->rx_end - 2)) { - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - *(u16 *) (drv_data->rx) = read_RDBR(); - drv_data->rx += 2; - } - - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - *(u16 *) (drv_data->rx) = read_SHAW(); - drv_data->rx += 2; -} - -static void u16_cs_chg_reader(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - while (drv_data->rx < drv_data->rx_end) { - write_FLAG(chip->flag); - SSYNC(); - - read_RDBR(); /* kick off */ - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; - *(u16 *) (drv_data->rx) = read_SHAW(); - write_FLAG(0xFF00 | chip->flag); - SSYNC(); - if (chip->cs_chg_udelay) - udelay(chip->cs_chg_udelay); - drv_data->rx += 2; - } - write_FLAG(0xFF00); - SSYNC(); -} - -static void u16_duplex(struct driver_data *drv_data) -{ - /* in duplex mode, clk is triggered by writing of TDBR */ - while (drv_data->tx < drv_data->tx_end) { - write_TDBR(*(u16 *) (drv_data->tx)); - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - *(u16 *) (drv_data->rx) = read_RDBR(); - drv_data->rx += 2; - drv_data->tx += 2; - } -} - -static void u16_cs_chg_duplex(struct driver_data *drv_data) -{ - struct chip_data *chip = drv_data->cur_chip; - - while (drv_data->tx < drv_data->tx_end) { - write_FLAG(chip->flag); - SSYNC(); - - write_TDBR(*(u16 *) (drv_data->tx)); - while (!(read_STAT() & BIT_STAT_SPIF)) - continue; - while (!(read_STAT() & BIT_STAT_RXS)) - continue; - *(u16 *) (drv_data->rx) = read_RDBR(); - write_FLAG(0xFF00 | chip->flag); - SSYNC(); - if (chip->cs_chg_udelay) - udelay(chip->cs_chg_udelay); - drv_data->rx += 2; - drv_data->tx += 2; - } - write_FLAG(0xFF00); - SSYNC(); -} - -/* test if ther is more transfer to be done */ -static void *next_transfer(struct driver_data *drv_data) -{ - struct spi_message *msg = drv_data->cur_msg; - struct spi_transfer *trans = drv_data->cur_transfer; - - /* Move to next transfer */ - if (trans->transfer_list.next != &msg->transfers) { - drv_data->cur_transfer = - list_entry(trans->transfer_list.next, - struct spi_transfer, transfer_list); - return RUNNING_STATE; - } else - return DONE_STATE; -} - -/* - * caller already set message->status; - * dma and pio irqs are blocked give finished message back - */ -static void giveback(struct driver_data *drv_data) -{ - struct spi_transfer *last_transfer; - unsigned long flags; - struct spi_message *msg; - - spin_lock_irqsave(&drv_data->lock, flags); - msg = drv_data->cur_msg; - drv_data->cur_msg = NULL; - drv_data->cur_transfer = NULL; - drv_data->cur_chip = NULL; - queue_work(drv_data->workqueue, &drv_data->pump_messages); - spin_unlock_irqrestore(&drv_data->lock, flags); - - last_transfer = list_entry(msg->transfers.prev, - struct spi_transfer, transfer_list); - - msg->state = NULL; - - /* disable chip select signal. And not stop spi in autobuffer mode */ - if (drv_data->tx_dma != 0xFFFF) { - write_FLAG(0xFF00); - bfin_spi_disable(drv_data); - } - - if (msg->complete) - msg->complete(msg->context); -} - -static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - struct driver_data *drv_data = (struct driver_data *)dev_id; - struct spi_message *msg = drv_data->cur_msg; - - pr_debug("in dma_irq_handler\n"); - clear_dma_irqstat(CH_SPI); - - /* - * wait for the last transaction shifted out. yes, these two - * while loops are supposed to be the same (see the HRM). - */ - if (drv_data->tx != NULL) { - while (bfin_read_SPI_STAT() & TXS) - continue; - while (bfin_read_SPI_STAT() & TXS) - continue; - } - - while (!(bfin_read_SPI_STAT() & SPIF)) - continue; - - bfin_spi_disable(drv_data); - - msg->actual_length += drv_data->len_in_bytes; - - /* Move to next transfer */ - msg->state = next_transfer(drv_data); - - /* Schedule transfer tasklet */ - tasklet_schedule(&drv_data->pump_transfers); - - /* free the irq handler before next transfer */ - pr_debug("disable dma channel irq%d\n", CH_SPI); - dma_disable_irq(CH_SPI); - - return IRQ_HANDLED; -} - -static void pump_transfers(unsigned long data) -{ - struct driver_data *drv_data = (struct driver_data *)data; - struct spi_message *message = NULL; - struct spi_transfer *transfer = NULL; - struct spi_transfer *previous = NULL; - struct chip_data *chip = NULL; - u16 cr, width, dma_width, dma_config; - u32 tranf_success = 1; - - /* Get current state information */ - message = drv_data->cur_msg; - transfer = drv_data->cur_transfer; - chip = drv_data->cur_chip; - - /* - * if msg is error or done, report it back using complete() callback - */ - - /* Handle for abort */ - if (message->state == ERROR_STATE) { - message->status = -EIO; - giveback(drv_data); - return; - } - - /* Handle end of message */ - if (message->state == DONE_STATE) { - message->status = 0; - giveback(drv_data); - return; - } - - /* Delay if requested at end of transfer */ - if (message->state == RUNNING_STATE) { - previous = list_entry(transfer->transfer_list.prev, - struct spi_transfer, transfer_list); - if (previous->delay_usecs) - udelay(previous->delay_usecs); - } - - /* Setup the transfer state based on the type of transfer */ - if (flush(drv_data) == 0) { - dev_err(&drv_data->pdev->dev, "pump_transfers: flush failed\n"); - message->status = -EIO; - giveback(drv_data); - return; - } - - if (transfer->tx_buf != NULL) { - drv_data->tx = (void *)transfer->tx_buf; - drv_data->tx_end = drv_data->tx + transfer->len; - pr_debug("tx_buf is %p, tx_end is %p\n", transfer->tx_buf, - drv_data->tx_end); - } else { - drv_data->tx = NULL; - } - - if (transfer->rx_buf != NULL) { - drv_data->rx = transfer->rx_buf; - drv_data->rx_end = drv_data->rx + transfer->len; - pr_debug("rx_buf is %p, rx_end is %p\n", transfer->rx_buf, - drv_data->rx_end); - } else { - drv_data->rx = NULL; - } - - drv_data->rx_dma = transfer->rx_dma; - drv_data->tx_dma = transfer->tx_dma; - drv_data->len_in_bytes = transfer->len; - - width = chip->width; - if (width == CFG_SPI_WORDSIZE16) { - drv_data->len = (transfer->len) >> 1; - } else { - drv_data->len = transfer->len; - } - drv_data->write = drv_data->tx ? chip->write : null_writer; - drv_data->read = drv_data->rx ? chip->read : null_reader; - drv_data->duplex = chip->duplex ? chip->duplex : null_writer; - pr_debug - ("transfer: drv_data->write is %p, chip->write is %p, null_wr is %p\n", - drv_data->write, chip->write, null_writer); - - /* speed and width has been set on per message */ - message->state = RUNNING_STATE; - dma_config = 0; - - /* restore spi status for each spi transfer */ - if (transfer->speed_hz) { - write_BAUD(hz_to_spi_baud(transfer->speed_hz)); - } else { - write_BAUD(chip->baud); - } - write_FLAG(chip->flag); - - pr_debug("now pumping a transfer: width is %d, len is %d\n", width, - transfer->len); - - /* - * Try to map dma buffer and do a dma transfer if - * successful use different way to r/w according to - * drv_data->cur_chip->enable_dma - */ - if (drv_data->cur_chip->enable_dma && drv_data->len > 6) { - - write_STAT(BIT_STAT_CLR); - disable_dma(CH_SPI); - clear_dma_irqstat(CH_SPI); - bfin_spi_disable(drv_data); - - /* config dma channel */ - pr_debug("doing dma transfer\n"); - if (width == CFG_SPI_WORDSIZE16) { - set_dma_x_count(CH_SPI, drv_data->len); - set_dma_x_modify(CH_SPI, 2); - dma_width = WDSIZE_16; - } else { - set_dma_x_count(CH_SPI, drv_data->len); - set_dma_x_modify(CH_SPI, 1); - dma_width = WDSIZE_8; - } - - /* set transfer width,direction. And enable spi */ - cr = (read_CTRL() & (~BIT_CTL_TIMOD)); - - /* dirty hack for autobuffer DMA mode */ - if (drv_data->tx_dma == 0xFFFF) { - pr_debug("doing autobuffer DMA out.\n"); - - /* no irq in autobuffer mode */ - dma_config = - (DMAFLOW_AUTO | RESTART | dma_width | DI_EN); - set_dma_config(CH_SPI, dma_config); - set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx); - enable_dma(CH_SPI); - write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) | - (CFG_SPI_ENABLE << 14)); - - /* just return here, there can only be one transfer in this mode */ - message->status = 0; - giveback(drv_data); - return; - } - - /* In dma mode, rx or tx must be NULL in one transfer */ - if (drv_data->rx != NULL) { - /* set transfer mode, and enable SPI */ - pr_debug("doing DMA in.\n"); - - /* disable SPI before write to TDBR */ - write_CTRL(cr & ~BIT_CTL_ENABLE); - - /* clear tx reg soformer data is not shifted out */ - write_TDBR(0xFF); - - set_dma_x_count(CH_SPI, drv_data->len); - - /* start dma */ - dma_enable_irq(CH_SPI); - dma_config = (WNR | RESTART | dma_width | DI_EN); - set_dma_config(CH_SPI, dma_config); - set_dma_start_addr(CH_SPI, (unsigned long)drv_data->rx); - enable_dma(CH_SPI); - - cr |= - CFG_SPI_DMAREAD | (width << 8) | (CFG_SPI_ENABLE << - 14); - /* set transfer mode, and enable SPI */ - write_CTRL(cr); - } else if (drv_data->tx != NULL) { - pr_debug("doing DMA out.\n"); - - /* start dma */ - dma_enable_irq(CH_SPI); - dma_config = (RESTART | dma_width | DI_EN); - set_dma_config(CH_SPI, dma_config); - set_dma_start_addr(CH_SPI, (unsigned long)drv_data->tx); - enable_dma(CH_SPI); - - write_CTRL(cr | CFG_SPI_DMAWRITE | (width << 8) | - (CFG_SPI_ENABLE << 14)); - - } - } else { - /* IO mode write then read */ - pr_debug("doing IO transfer\n"); - - write_STAT(BIT_STAT_CLR); - - if (drv_data->tx != NULL && drv_data->rx != NULL) { - /* full duplex mode */ - BUG_ON((drv_data->tx_end - drv_data->tx) != - (drv_data->rx_end - drv_data->rx)); - cr = (read_CTRL() & (~BIT_CTL_TIMOD)); /* clear the TIMOD bits */ - cr |= - CFG_SPI_WRITE | (width << 8) | (CFG_SPI_ENABLE << - 14); - pr_debug("IO duplex: cr is 0x%x\n", cr); - - write_CTRL(cr); - SSYNC(); - - drv_data->duplex(drv_data); - - if (drv_data->tx != drv_data->tx_end) - tranf_success = 0; - } else if (drv_data->tx != NULL) { - /* write only half duplex */ - cr = (read_CTRL() & (~BIT_CTL_TIMOD)); /* clear the TIMOD bits */ - cr |= - CFG_SPI_WRITE | (width << 8) | (CFG_SPI_ENABLE << - 14); - pr_debug("IO write: cr is 0x%x\n", cr); - - write_CTRL(cr); - SSYNC(); - - drv_data->write(drv_data); - - if (drv_data->tx != drv_data->tx_end) - tranf_success = 0; - } else if (drv_data->rx != NULL) { - /* read only half duplex */ - cr = (read_CTRL() & (~BIT_CTL_TIMOD)); /* cleare the TIMOD bits */ - cr |= - CFG_SPI_READ | (width << 8) | (CFG_SPI_ENABLE << - 14); - pr_debug("IO read: cr is 0x%x\n", cr); - - write_CTRL(cr); - SSYNC(); - - drv_data->read(drv_data); - if (drv_data->rx != drv_data->rx_end) - tranf_success = 0; - } - - if (!tranf_success) { - pr_debug("IO write error!\n"); - message->state = ERROR_STATE; - } else { - /* Update total byte transfered */ - message->actual_length += drv_data->len; - - /* Move to next transfer of this msg */ - message->state = next_transfer(drv_data); - } - - /* Schedule next transfer tasklet */ - tasklet_schedule(&drv_data->pump_transfers); - - } -} - -/* pop a msg from queue and kick off real transfer */ -static void pump_messages(struct work_struct *work) -{ - struct driver_data *drv_data = container_of(work, struct driver_data, pump_messages); - unsigned long flags; - - /* Lock queue and check for queue work */ - spin_lock_irqsave(&drv_data->lock, flags); - if (list_empty(&drv_data->queue) || drv_data->run == QUEUE_STOPPED) { - /* pumper kicked off but no work to do */ - drv_data->busy = 0; - spin_unlock_irqrestore(&drv_data->lock, flags); - return; - } - - /* Make sure we are not already running a message */ - if (drv_data->cur_msg) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return; - } - - /* Extract head of queue */ - drv_data->cur_msg = list_entry(drv_data->queue.next, - struct spi_message, queue); - list_del_init(&drv_data->cur_msg->queue); - - /* Initial message state */ - drv_data->cur_msg->state = START_STATE; - drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next, - struct spi_transfer, transfer_list); - - /* Setup the SSP using the per chip configuration */ - drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); - restore_state(drv_data); - pr_debug - ("got a message to pump, state is set to: baud %d, flag 0x%x, ctl 0x%x\n", - drv_data->cur_chip->baud, drv_data->cur_chip->flag, - drv_data->cur_chip->ctl_reg); - pr_debug("the first transfer len is %d\n", drv_data->cur_transfer->len); - - /* Mark as busy and launch transfers */ - tasklet_schedule(&drv_data->pump_transfers); - - drv_data->busy = 1; - spin_unlock_irqrestore(&drv_data->lock, flags); -} - -/* - * got a msg to transfer, queue it in drv_data->queue. - * And kick off message pumper - */ -static int transfer(struct spi_device *spi, struct spi_message *msg) -{ - struct driver_data *drv_data = spi_master_get_devdata(spi->master); - unsigned long flags; - - spin_lock_irqsave(&drv_data->lock, flags); - - if (drv_data->run == QUEUE_STOPPED) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return -ESHUTDOWN; - } - - msg->actual_length = 0; - msg->status = -EINPROGRESS; - msg->state = START_STATE; - - pr_debug("adding an msg in transfer() \n"); - list_add_tail(&msg->queue, &drv_data->queue); - - if (drv_data->run == QUEUE_RUNNING && !drv_data->busy) - queue_work(drv_data->workqueue, &drv_data->pump_messages); - - spin_unlock_irqrestore(&drv_data->lock, flags); - - return 0; -} - -/* first setup for new devices */ -static int setup(struct spi_device *spi) -{ - struct bfin5xx_spi_chip *chip_info = NULL; - struct chip_data *chip; - struct driver_data *drv_data = spi_master_get_devdata(spi->master); - u8 spi_flg; - - /* Abort device setup if requested features are not supported */ - if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) { - dev_err(&spi->dev, "requested mode not fully supported\n"); - return -EINVAL; - } - - /* Zero (the default) here means 8 bits */ - if (!spi->bits_per_word) - spi->bits_per_word = 8; - - if (spi->bits_per_word != 8 && spi->bits_per_word != 16) - return -EINVAL; - - /* Only alloc (or use chip_info) on first setup */ - chip = spi_get_ctldata(spi); - if (chip == NULL) { - chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->enable_dma = 0; - chip_info = spi->controller_data; - } - - /* chip_info isn't always needed */ - if (chip_info) { - chip->enable_dma = chip_info->enable_dma != 0 - && drv_data->master_info->enable_dma; - chip->ctl_reg = chip_info->ctl_reg; - chip->bits_per_word = chip_info->bits_per_word; - chip->cs_change_per_word = chip_info->cs_change_per_word; - chip->cs_chg_udelay = chip_info->cs_chg_udelay; - } - - /* translate common spi framework into our register */ - if (spi->mode & SPI_CPOL) - chip->ctl_reg |= CPOL; - if (spi->mode & SPI_CPHA) - chip->ctl_reg |= CPHA; - if (spi->mode & SPI_LSB_FIRST) - chip->ctl_reg |= LSBF; - /* we dont support running in slave mode (yet?) */ - chip->ctl_reg |= MSTR; - - /* - * if any one SPI chip is registered and wants DMA, request the - * DMA channel for it - */ - if (chip->enable_dma && !dma_requested) { - /* register dma irq handler */ - if (request_dma(CH_SPI, "BF53x_SPI_DMA") < 0) { - pr_debug - ("Unable to request BlackFin SPI DMA channel\n"); - return -ENODEV; - } - if (set_dma_callback(CH_SPI, (void *)dma_irq_handler, drv_data) - < 0) { - pr_debug("Unable to set dma callback\n"); - return -EPERM; - } - dma_disable_irq(CH_SPI); - dma_requested = 1; - } - - /* - * Notice: for blackfin, the speed_hz is the value of register - * SPI_BAUD, not the real baudrate - */ - chip->baud = hz_to_spi_baud(spi->max_speed_hz); - spi_flg = ~(1 << (spi->chip_select)); - chip->flag = ((u16) spi_flg << 8) | (1 << (spi->chip_select)); - chip->chip_select_num = spi->chip_select; - - switch (chip->bits_per_word) { - case 8: - chip->n_bytes = 1; - chip->width = CFG_SPI_WORDSIZE8; - chip->read = chip->cs_change_per_word ? - u8_cs_chg_reader : u8_reader; - chip->write = chip->cs_change_per_word ? - u8_cs_chg_writer : u8_writer; - chip->duplex = chip->cs_change_per_word ? - u8_cs_chg_duplex : u8_duplex; - break; - - case 16: - chip->n_bytes = 2; - chip->width = CFG_SPI_WORDSIZE16; - chip->read = chip->cs_change_per_word ? - u16_cs_chg_reader : u16_reader; - chip->write = chip->cs_change_per_word ? - u16_cs_chg_writer : u16_writer; - chip->duplex = chip->cs_change_per_word ? - u16_cs_chg_duplex : u16_duplex; - break; - - default: - dev_err(&spi->dev, "%d bits_per_word is not supported\n", - chip->bits_per_word); - kfree(chip); - return -ENODEV; - } - - pr_debug("setup spi chip %s, width is %d, dma is %d,", - spi->modalias, chip->width, chip->enable_dma); - pr_debug("ctl_reg is 0x%x, flag_reg is 0x%x\n", - chip->ctl_reg, chip->flag); - - spi_set_ctldata(spi, chip); - - return 0; -} - -/* - * callback for spi framework. - * clean driver specific data - */ -static void cleanup(const struct spi_device *spi) -{ - struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi); - - kfree(chip); -} - -static inline int init_queue(struct driver_data *drv_data) -{ - INIT_LIST_HEAD(&drv_data->queue); - spin_lock_init(&drv_data->lock); - - drv_data->run = QUEUE_STOPPED; - drv_data->busy = 0; - - /* init transfer tasklet */ - tasklet_init(&drv_data->pump_transfers, - pump_transfers, (unsigned long)drv_data); - - /* init messages workqueue */ - INIT_WORK(&drv_data->pump_messages, pump_messages); - drv_data->workqueue = - create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id); - if (drv_data->workqueue == NULL) - return -EBUSY; - - return 0; -} - -static inline int start_queue(struct driver_data *drv_data) -{ - unsigned long flags; - - spin_lock_irqsave(&drv_data->lock, flags); - - if (drv_data->run == QUEUE_RUNNING || drv_data->busy) { - spin_unlock_irqrestore(&drv_data->lock, flags); - return -EBUSY; - } - - drv_data->run = QUEUE_RUNNING; - drv_data->cur_msg = NULL; - drv_data->cur_transfer = NULL; - drv_data->cur_chip = NULL; - spin_unlock_irqrestore(&drv_data->lock, flags); - - queue_work(drv_data->workqueue, &drv_data->pump_messages); - - return 0; -} - -static inline int stop_queue(struct driver_data *drv_data) -{ - unsigned long flags; - unsigned limit = 500; - int status = 0; - - spin_lock_irqsave(&drv_data->lock, flags); - - /* - * This is a bit lame, but is optimized for the common execution path. - * A wait_queue on the drv_data->busy could be used, but then the common - * execution path (pump_messages) would be required to call wake_up or - * friends on every SPI message. Do this instead - */ - drv_data->run = QUEUE_STOPPED; - while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { - spin_unlock_irqrestore(&drv_data->lock, flags); - msleep(10); - spin_lock_irqsave(&drv_data->lock, flags); - } - - if (!list_empty(&drv_data->queue) || drv_data->busy) - status = -EBUSY; - - spin_unlock_irqrestore(&drv_data->lock, flags); - - return status; -} - -static inline int destroy_queue(struct driver_data *drv_data) -{ - int status; - - status = stop_queue(drv_data); - if (status != 0) - return status; - - destroy_workqueue(drv_data->workqueue); - - return 0; -} - -static int __init bfin5xx_spi_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct bfin5xx_spi_master *platform_info; - struct spi_master *master; - struct driver_data *drv_data = 0; - int status = 0; - - platform_info = dev->platform_data; - - /* Allocate master with space for drv_data */ - master = spi_alloc_master(dev, sizeof(struct driver_data) + 16); - if (!master) { - dev_err(&pdev->dev, "can not alloc spi_master\n"); - return -ENOMEM; - } - drv_data = spi_master_get_devdata(master); - drv_data->master = master; - drv_data->master_info = platform_info; - drv_data->pdev = pdev; - - master->bus_num = pdev->id; - master->num_chipselect = platform_info->num_chipselect; - master->cleanup = cleanup; - master->setup = setup; - master->transfer = transfer; - - /* Initial and start queue */ - status = init_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem initializing queue\n"); - goto out_error_queue_alloc; - } - status = start_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem starting queue\n"); - goto out_error_queue_alloc; - } - - /* Register with the SPI framework */ - platform_set_drvdata(pdev, drv_data); - status = spi_register_master(master); - if (status != 0) { - dev_err(&pdev->dev, "problem registering spi master\n"); - goto out_error_queue_alloc; - } - pr_debug("controller probe successfully\n"); - return status; - - out_error_queue_alloc: - destroy_queue(drv_data); - spi_master_put(master); - return status; -} - -/* stop hardware and remove the driver */ -static int __devexit bfin5xx_spi_remove(struct platform_device *pdev) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int status = 0; - - if (!drv_data) - return 0; - - /* Remove the queue */ - status = destroy_queue(drv_data); - if (status != 0) - return status; - - /* Disable the SSP at the peripheral and SOC level */ - bfin_spi_disable(drv_data); - - /* Release DMA */ - if (drv_data->master_info->enable_dma) { - if (dma_channel_active(CH_SPI)) - free_dma(CH_SPI); - } - - /* Disconnect from the SPI framework */ - spi_unregister_master(drv_data->master); - - /* Prevent double remove */ - platform_set_drvdata(pdev, NULL); - - return 0; -} - -#ifdef CONFIG_PM -static int bfin5xx_spi_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int status = 0; - - status = stop_queue(drv_data); - if (status != 0) - return status; - - /* stop hardware */ - bfin_spi_disable(drv_data); - - return 0; -} - -static int bfin5xx_spi_resume(struct platform_device *pdev) -{ - struct driver_data *drv_data = platform_get_drvdata(pdev); - int status = 0; - - /* Enable the SPI interface */ - bfin_spi_enable(drv_data); - - /* Start the queue running */ - status = start_queue(drv_data); - if (status != 0) { - dev_err(&pdev->dev, "problem starting queue (%d)\n", status); - return status; - } - - return 0; -} -#else -#define bfin5xx_spi_suspend NULL -#define bfin5xx_spi_resume NULL -#endif /* CONFIG_PM */ - -static struct platform_driver bfin5xx_spi_driver = { - .driver = { - .name = "bfin-spi-master", - .bus = &platform_bus_type, - .owner = THIS_MODULE, - }, - .probe = bfin5xx_spi_probe, - .remove = __devexit_p(bfin5xx_spi_remove), - .suspend = bfin5xx_spi_suspend, - .resume = bfin5xx_spi_resume, -}; - -static int __init bfin5xx_spi_init(void) -{ - return platform_driver_register(&bfin5xx_spi_driver); -} - -module_init(bfin5xx_spi_init); - -static void __exit bfin5xx_spi_exit(void) -{ - platform_driver_unregister(&bfin5xx_spi_driver); -} - -module_exit(bfin5xx_spi_exit); diff --git a/trunk/drivers/spi/spi_butterfly.c b/trunk/drivers/spi/spi_butterfly.c index 0ee2b2090252..312987a03210 100644 --- a/trunk/drivers/spi/spi_butterfly.c +++ b/trunk/drivers/spi/spi_butterfly.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -40,6 +40,8 @@ * and use this custom parallel port cable. */ +#undef HAVE_USI /* nyet */ + /* DATA output bits (pins 2..9 == D0..D7) */ #define butterfly_nreset (1 << 1) /* pin 3 */ @@ -47,13 +49,19 @@ #define spi_sck_bit (1 << 0) /* pin 2 */ #define spi_mosi_bit (1 << 7) /* pin 9 */ +#define usi_sck_bit (1 << 3) /* pin 5 */ +#define usi_mosi_bit (1 << 4) /* pin 6 */ + #define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */ /* STATUS input bits */ #define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */ +#define usi_miso_bit PARPORT_STATUS_PAPEROUT /* pin 12 */ + /* CONTROL output bits */ #define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */ +/* USI uses no chipselect */ @@ -62,6 +70,15 @@ static inline struct butterfly *spidev_to_pp(struct spi_device *spi) return spi->controller_data; } +static inline int is_usidev(struct spi_device *spi) +{ +#ifdef HAVE_USI + return spi->chip_select != 1; +#else + return 0; +#endif +} + struct butterfly { /* REVISIT ... for now, this must be first */ @@ -80,13 +97,23 @@ struct butterfly { /*----------------------------------------------------------------------*/ +/* + * these routines may be slower than necessary because they're hiding + * the fact that there are two different SPI busses on this cable: one + * to the DataFlash chip (or AVR SPI controller), the other to the + * AVR USI controller. + */ + static inline void setsck(struct spi_device *spi, int is_on) { struct butterfly *pp = spidev_to_pp(spi); u8 bit, byte = pp->lastbyte; - bit = spi_sck_bit; + if (is_usidev(spi)) + bit = usi_sck_bit; + else + bit = spi_sck_bit; if (is_on) byte |= bit; @@ -102,7 +129,10 @@ setmosi(struct spi_device *spi, int is_on) struct butterfly *pp = spidev_to_pp(spi); u8 bit, byte = pp->lastbyte; - bit = spi_mosi_bit; + if (is_usidev(spi)) + bit = usi_mosi_bit; + else + bit = spi_mosi_bit; if (is_on) byte |= bit; @@ -118,7 +148,10 @@ static inline int getmiso(struct spi_device *spi) int value; u8 bit; - bit = spi_miso_bit; + if (is_usidev(spi)) + bit = usi_miso_bit; + else + bit = spi_miso_bit; /* only STATUS_BUSY is NOT negated */ value = !(parport_read_status(pp->port) & bit); @@ -133,6 +166,10 @@ static void butterfly_chipselect(struct spi_device *spi, int value) if (value != BITBANG_CS_INACTIVE) setsck(spi, spi->mode & SPI_CPOL); + /* no chipselect on this USI link config */ + if (is_usidev(spi)) + return; + /* here, value == "activate or not"; * most PARPORT_CONTROL_* bits are negated, so we must * morph it to value == "bit value to write in control register" @@ -200,16 +237,24 @@ static void butterfly_attach(struct parport *p) int status; struct butterfly *pp; struct spi_master *master; - struct device *dev = p->physport->dev; + struct platform_device *pdev; - if (butterfly || !dev) + if (butterfly) return; /* REVISIT: this just _assumes_ a butterfly is there ... no probe, * and no way to be selective about what it binds to. */ - master = spi_alloc_master(dev, sizeof *pp); + /* FIXME where should master->cdev.dev come from? + * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc + * setting up a platform device like this is an ugly kluge... + */ + pdev = platform_device_register_simple("butterfly", -1, NULL, 0); + if (IS_ERR(pdev)) + return; + + master = spi_alloc_master(&pdev->dev, sizeof *pp); if (!master) { status = -ENOMEM; goto done; @@ -255,7 +300,7 @@ static void butterfly_attach(struct parport *p) parport_frob_control(pp->port, spi_cs_bit, 0); /* stabilize power with chip in reset (nRESET), and - * spi_sck_bit clear (CPOL=0) + * both spi_sck_bit and usi_sck_bit clear (CPOL=0) */ pp->lastbyte |= vcc_bits; parport_write_data(pp->port, pp->lastbyte); @@ -289,6 +334,23 @@ static void butterfly_attach(struct parport *p) pr_debug("%s: dataflash at %s\n", p->name, pp->dataflash->dev.bus_id); +#ifdef HAVE_USI + /* Bus 2 is only for talking to the AVR, and it can work no + * matter who masters bus 1; needs appropriate AVR firmware. + */ + pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; + strcpy(pp->info[1].modalias, "butterfly"); + // pp->info[1].platform_data = ... TBD ... ; + pp->info[1].chip_select = 2, + pp->info[1].controller_data = pp; + pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]); + if (pp->butterfly) + pr_debug("%s: butterfly at %s\n", p->name, + pp->butterfly->dev.bus_id); + + /* FIXME setup ACK for the IRQ line ... */ +#endif + // dev_info(_what?_, ...) pr_info("%s: AVR Butterfly\n", p->name); butterfly = pp; @@ -304,12 +366,14 @@ static void butterfly_attach(struct parport *p) clean0: (void) spi_master_put(pp->bitbang.master); done: + platform_device_unregister(pdev); pr_debug("%s: butterfly probe, fail %d\n", p->name, status); } static void butterfly_detach(struct parport *p) { struct butterfly *pp; + struct platform_device *pdev; int status; /* FIXME this global is ugly ... but, how to quickly get from @@ -322,6 +386,7 @@ static void butterfly_detach(struct parport *p) butterfly = NULL; /* stop() unregisters child devices too */ + pdev = to_platform_device(pp->bitbang.master->cdev.dev); status = spi_bitbang_stop(&pp->bitbang); /* turn off VCC */ @@ -332,6 +397,8 @@ static void butterfly_detach(struct parport *p) parport_unregister_device(pp->pd); (void) spi_master_put(pp->bitbang.master); + + platform_device_unregister(pdev); } static struct parport_driver butterfly_driver = { diff --git a/trunk/drivers/spi/spi_s3c24xx.c b/trunk/drivers/spi/spi_s3c24xx.c index d5a710f6e445..b10211c420ef 100644 --- a/trunk/drivers/spi/spi_s3c24xx.c +++ b/trunk/drivers/spi/spi_s3c24xx.c @@ -342,6 +342,8 @@ static int s3c24xx_spi_probe(struct platform_device *pdev) goto err_register; } + dev_dbg(hw->dev, "shutdown=%d\n", hw->bitbang.shutdown); + /* register all the devices associated */ bi = &hw->pdata->board_info[0]; diff --git a/trunk/drivers/spi/spidev.c b/trunk/drivers/spi/spidev.c deleted file mode 100644 index c0a6dce800a3..000000000000 --- a/trunk/drivers/spi/spidev.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * spidev.c -- simple synchronous userspace interface to SPI devices - * - * Copyright (C) 2006 SWAPP - * Andrea Paterniani - * Copyright (C) 2007 David Brownell (simplification, cleanup) - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - - -/* - * This supports acccess to SPI devices using normal userspace I/O calls. - * Note that while traditional UNIX/POSIX I/O semantics are half duplex, - * and often mask message boundaries, full SPI support requires full duplex - * transfers. There are several kinds of of internal message boundaries to - * handle chipselect management and other protocol options. - * - * SPI has a character major number assigned. We allocate minor numbers - * dynamically using a bitmask. You must use hotplug tools, such as udev - * (or mdev with busybox) to create and destroy the /dev/spidevB.C device - * nodes, since there is no fixed association of minor numbers with any - * particular SPI bus or device. - */ -#define SPIDEV_MAJOR 153 /* assigned */ -#define N_SPI_MINORS 32 /* ... up to 256 */ - -static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; - - -/* Bit masks for spi_device.mode management */ -#define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL) - - -struct spidev_data { - struct device dev; - struct spi_device *spi; - struct list_head device_entry; - - struct mutex buf_lock; - unsigned users; - u8 *buffer; -}; - -static LIST_HEAD(device_list); -static DEFINE_MUTEX(device_list_lock); - -static unsigned bufsiz = 4096; -module_param(bufsiz, uint, S_IRUGO); -MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message"); - -/*-------------------------------------------------------------------------*/ - -/* Read-only message with current device setup */ -static ssize_t -spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) -{ - struct spidev_data *spidev; - struct spi_device *spi; - ssize_t status = 0; - - /* chipselect only toggles at start or end of operation */ - if (count > bufsiz) - return -EMSGSIZE; - - spidev = filp->private_data; - spi = spidev->spi; - - mutex_lock(&spidev->buf_lock); - status = spi_read(spi, spidev->buffer, count); - if (status == 0) { - unsigned long missing; - - missing = copy_to_user(buf, spidev->buffer, count); - if (count && missing == count) - status = -EFAULT; - else - status = count - missing; - } - mutex_unlock(&spidev->buf_lock); - - return status; -} - -/* Write-only message with current device setup */ -static ssize_t -spidev_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - struct spidev_data *spidev; - struct spi_device *spi; - ssize_t status = 0; - unsigned long missing; - - /* chipselect only toggles at start or end of operation */ - if (count > bufsiz) - return -EMSGSIZE; - - spidev = filp->private_data; - spi = spidev->spi; - - mutex_lock(&spidev->buf_lock); - missing = copy_from_user(spidev->buffer, buf, count); - if (missing == 0) { - status = spi_write(spi, spidev->buffer, count); - if (status == 0) - status = count; - } else - status = -EFAULT; - mutex_unlock(&spidev->buf_lock); - - return status; -} - -static int spidev_message(struct spidev_data *spidev, - struct spi_ioc_transfer *u_xfers, unsigned n_xfers) -{ - struct spi_message msg; - struct spi_transfer *k_xfers; - struct spi_transfer *k_tmp; - struct spi_ioc_transfer *u_tmp; - struct spi_device *spi = spidev->spi; - unsigned n, total; - u8 *buf; - int status = -EFAULT; - - spi_message_init(&msg); - k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL); - if (k_xfers == NULL) - return -ENOMEM; - - /* Construct spi_message, copying any tx data to bounce buffer. - * We walk the array of user-provided transfers, using each one - * to initialize a kernel version of the same transfer. - */ - mutex_lock(&spidev->buf_lock); - buf = spidev->buffer; - total = 0; - for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers; - n; - n--, k_tmp++, u_tmp++) { - k_tmp->len = u_tmp->len; - - if (u_tmp->rx_buf) { - k_tmp->rx_buf = buf; - if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len)) - goto done; - } - if (u_tmp->tx_buf) { - k_tmp->tx_buf = buf; - if (copy_from_user(buf, (const u8 __user *)u_tmp->tx_buf, - u_tmp->len)) - goto done; - } - - total += k_tmp->len; - if (total > bufsiz) { - status = -EMSGSIZE; - goto done; - } - buf += k_tmp->len; - - k_tmp->cs_change = !!u_tmp->cs_change; - k_tmp->bits_per_word = u_tmp->bits_per_word; - k_tmp->delay_usecs = u_tmp->delay_usecs; - k_tmp->speed_hz = u_tmp->speed_hz; -#ifdef VERBOSE - dev_dbg(&spi->dev, - " xfer len %zd %s%s%s%dbits %u usec %uHz\n", - u_tmp->len, - u_tmp->rx_buf ? "rx " : "", - u_tmp->tx_buf ? "tx " : "", - u_tmp->cs_change ? "cs " : "", - u_tmp->bits_per_word ? : spi->bits_per_word, - u_tmp->delay_usecs, - u_tmp->speed_hz ? : spi->max_speed_hz); -#endif - spi_message_add_tail(k_tmp, &msg); - } - - status = spi_sync(spi, &msg); - if (status < 0) - goto done; - - /* copy any rx data out of bounce buffer */ - buf = spidev->buffer; - for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) { - if (u_tmp->rx_buf) { - if (__copy_to_user((u8 __user *)u_tmp->rx_buf, buf, - u_tmp->len)) { - status = -EFAULT; - goto done; - } - } - buf += u_tmp->len; - } - status = total; - -done: - mutex_unlock(&spidev->buf_lock); - kfree(k_xfers); - return status; -} - -static int -spidev_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - int err = 0; - int retval = 0; - struct spidev_data *spidev; - struct spi_device *spi; - u32 tmp; - unsigned n_ioc; - struct spi_ioc_transfer *ioc; - - /* Check type and command number */ - if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC) - return -ENOTTY; - - /* Check access direction once here; don't repeat below. - * IOC_DIR is from the user perspective, while access_ok is - * from the kernel perspective; so they look reversed. - */ - if (_IOC_DIR(cmd) & _IOC_READ) - err = !access_ok(VERIFY_WRITE, - (void __user *)arg, _IOC_SIZE(cmd)); - if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE) - err = !access_ok(VERIFY_READ, - (void __user *)arg, _IOC_SIZE(cmd)); - if (err) - return -EFAULT; - - spidev = filp->private_data; - spi = spidev->spi; - - switch (cmd) { - /* read requests */ - case SPI_IOC_RD_MODE: - retval = __put_user(spi->mode & SPI_MODE_MASK, - (__u8 __user *)arg); - break; - case SPI_IOC_RD_LSB_FIRST: - retval = __put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0, - (__u8 __user *)arg); - break; - case SPI_IOC_RD_BITS_PER_WORD: - retval = __put_user(spi->bits_per_word, (__u8 __user *)arg); - break; - case SPI_IOC_RD_MAX_SPEED_HZ: - retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg); - break; - - /* write requests */ - case SPI_IOC_WR_MODE: - retval = __get_user(tmp, (u8 __user *)arg); - if (retval == 0) { - u8 save = spi->mode; - - if (tmp & ~SPI_MODE_MASK) { - retval = -EINVAL; - break; - } - - tmp |= spi->mode & ~SPI_MODE_MASK; - spi->mode = (u8)tmp; - retval = spi_setup(spi); - if (retval < 0) - spi->mode = save; - else - dev_dbg(&spi->dev, "spi mode %02x\n", tmp); - } - break; - case SPI_IOC_WR_LSB_FIRST: - retval = __get_user(tmp, (__u8 __user *)arg); - if (retval == 0) { - u8 save = spi->mode; - - if (tmp) - spi->mode |= SPI_LSB_FIRST; - else - spi->mode &= ~SPI_LSB_FIRST; - retval = spi_setup(spi); - if (retval < 0) - spi->mode = save; - else - dev_dbg(&spi->dev, "%csb first\n", - tmp ? 'l' : 'm'); - } - break; - case SPI_IOC_WR_BITS_PER_WORD: - retval = __get_user(tmp, (__u8 __user *)arg); - if (retval == 0) { - u8 save = spi->bits_per_word; - - spi->bits_per_word = tmp; - retval = spi_setup(spi); - if (retval < 0) - spi->bits_per_word = save; - else - dev_dbg(&spi->dev, "%d bits per word\n", tmp); - } - break; - case SPI_IOC_WR_MAX_SPEED_HZ: - retval = __get_user(tmp, (__u32 __user *)arg); - if (retval == 0) { - u32 save = spi->max_speed_hz; - - spi->max_speed_hz = tmp; - retval = spi_setup(spi); - if (retval < 0) - spi->max_speed_hz = save; - else - dev_dbg(&spi->dev, "%d Hz (max)\n", tmp); - } - break; - - default: - /* segmented and/or full-duplex I/O request */ - if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0)) - || _IOC_DIR(cmd) != _IOC_WRITE) - return -ENOTTY; - - tmp = _IOC_SIZE(cmd); - if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) { - retval = -EINVAL; - break; - } - n_ioc = tmp / sizeof(struct spi_ioc_transfer); - if (n_ioc == 0) - break; - - /* copy into scratch area */ - ioc = kmalloc(tmp, GFP_KERNEL); - if (!ioc) { - retval = -ENOMEM; - break; - } - if (__copy_from_user(ioc, (void __user *)arg, tmp)) { - retval = -EFAULT; - break; - } - - /* translate to spi_message, execute */ - retval = spidev_message(spidev, ioc, n_ioc); - kfree(ioc); - break; - } - return retval; -} - -static int spidev_open(struct inode *inode, struct file *filp) -{ - struct spidev_data *spidev; - int status = -ENXIO; - - mutex_lock(&device_list_lock); - - list_for_each_entry(spidev, &device_list, device_entry) { - if (spidev->dev.devt == inode->i_rdev) { - status = 0; - break; - } - } - if (status == 0) { - if (!spidev->buffer) { - spidev->buffer = kmalloc(bufsiz, GFP_KERNEL); - if (!spidev->buffer) { - dev_dbg(&spidev->spi->dev, "open/ENOMEM\n"); - status = -ENOMEM; - } - } - if (status == 0) { - spidev->users++; - filp->private_data = spidev; - nonseekable_open(inode, filp); - } - } else - pr_debug("spidev: nothing for minor %d\n", iminor(inode)); - - mutex_unlock(&device_list_lock); - return status; -} - -static int spidev_release(struct inode *inode, struct file *filp) -{ - struct spidev_data *spidev; - int status = 0; - - mutex_lock(&device_list_lock); - spidev = filp->private_data; - filp->private_data = NULL; - spidev->users--; - if (!spidev->users) { - kfree(spidev->buffer); - spidev->buffer = NULL; - } - mutex_unlock(&device_list_lock); - - return status; -} - -static struct file_operations spidev_fops = { - .owner = THIS_MODULE, - /* REVISIT switch to aio primitives, so that userspace - * gets more complete API coverage. It'll simplify things - * too, except for the locking. - */ - .write = spidev_write, - .read = spidev_read, - .ioctl = spidev_ioctl, - .open = spidev_open, - .release = spidev_release, -}; - -/*-------------------------------------------------------------------------*/ - -/* The main reason to have this class is to make mdev/udev create the - * /dev/spidevB.C character device nodes exposing our userspace API. - * It also simplifies memory management. - */ - -static void spidev_classdev_release(struct device *dev) -{ - struct spidev_data *spidev; - - spidev = container_of(dev, struct spidev_data, dev); - kfree(spidev); -} - -static struct class spidev_class = { - .name = "spidev", - .owner = THIS_MODULE, - .dev_release = spidev_classdev_release, -}; - -/*-------------------------------------------------------------------------*/ - -static int spidev_probe(struct spi_device *spi) -{ - struct spidev_data *spidev; - int status; - unsigned long minor; - - /* Allocate driver data */ - spidev = kzalloc(sizeof(*spidev), GFP_KERNEL); - if (!spidev) - return -ENOMEM; - - /* Initialize the driver data */ - spidev->spi = spi; - mutex_init(&spidev->buf_lock); - - INIT_LIST_HEAD(&spidev->device_entry); - - /* If we can allocate a minor number, hook up this device. - * Reusing minors is fine so long as udev or mdev is working. - */ - mutex_lock(&device_list_lock); - minor = find_first_zero_bit(minors, ARRAY_SIZE(minors)); - if (minor < N_SPI_MINORS) { - spidev->dev.parent = &spi->dev; - spidev->dev.class = &spidev_class; - spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor); - snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id, - "spidev%d.%d", - spi->master->bus_num, spi->chip_select); - status = device_register(&spidev->dev); - } else { - dev_dbg(&spi->dev, "no minor number available!\n"); - status = -ENODEV; - } - if (status == 0) { - set_bit(minor, minors); - dev_set_drvdata(&spi->dev, spidev); - list_add(&spidev->device_entry, &device_list); - } - mutex_unlock(&device_list_lock); - - if (status != 0) - kfree(spidev); - - return status; -} - -static int spidev_remove(struct spi_device *spi) -{ - struct spidev_data *spidev = dev_get_drvdata(&spi->dev); - - mutex_lock(&device_list_lock); - - list_del(&spidev->device_entry); - dev_set_drvdata(&spi->dev, NULL); - clear_bit(MINOR(spidev->dev.devt), minors); - device_unregister(&spidev->dev); - - mutex_unlock(&device_list_lock); - - return 0; -} - -static struct spi_driver spidev_spi = { - .driver = { - .name = "spidev", - .owner = THIS_MODULE, - }, - .probe = spidev_probe, - .remove = __devexit_p(spidev_remove), - - /* NOTE: suspend/resume methods are not necessary here. - * We don't do anything except pass the requests to/from - * the underlying controller. The refrigerator handles - * most issues; the controller driver handles the rest. - */ -}; - -/*-------------------------------------------------------------------------*/ - -static int __init spidev_init(void) -{ - int status; - - /* Claim our 256 reserved device numbers. Then register a class - * that will key udev/mdev to add/remove /dev nodes. Last, register - * the driver which manages those device numbers. - */ - BUILD_BUG_ON(N_SPI_MINORS > 256); - status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops); - if (status < 0) - return status; - - status = class_register(&spidev_class); - if (status < 0) { - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); - return status; - } - - status = spi_register_driver(&spidev_spi); - if (status < 0) { - class_unregister(&spidev_class); - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); - } - return status; -} -module_init(spidev_init); - -static void __exit spidev_exit(void) -{ - spi_unregister_driver(&spidev_spi); - class_unregister(&spidev_class); - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); -} -module_exit(spidev_exit); - -MODULE_AUTHOR("Andrea Paterniani, "); -MODULE_DESCRIPTION("User mode SPI device interface"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/telephony/ixj.c b/trunk/drivers/telephony/ixj.c index c7b0a357b04a..71cb64e41a1b 100644 --- a/trunk/drivers/telephony/ixj.c +++ b/trunk/drivers/telephony/ixj.c @@ -7692,7 +7692,7 @@ static int __init ixj_probe_pci(int *cnt) IXJ *j = NULL; for (i = 0; i < IXJMAX - *cnt; i++) { - pci = pci_get_device(PCI_VENDOR_ID_QUICKNET, + pci = pci_find_device(PCI_VENDOR_ID_QUICKNET, PCI_DEVICE_ID_QUICKNET_XJ, pci); if (!pci) break; @@ -7712,7 +7712,6 @@ static int __init ixj_probe_pci(int *cnt) printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase); ++*cnt; } - pci_dev_put(pci); return probe; } diff --git a/trunk/drivers/usb/Kconfig b/trunk/drivers/usb/Kconfig index b847bbc8b0e1..9980a4ddfed9 100644 --- a/trunk/drivers/usb/Kconfig +++ b/trunk/drivers/usb/Kconfig @@ -85,6 +85,8 @@ source "drivers/usb/class/Kconfig" source "drivers/usb/storage/Kconfig" +source "drivers/usb/input/Kconfig" + source "drivers/usb/image/Kconfig" source "drivers/usb/net/Kconfig" diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index 0ef090b1b37c..f5de58a63f2b 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -23,6 +23,15 @@ obj-$(CONFIG_USB_PRINTER) += class/ obj-$(CONFIG_USB_STORAGE) += storage/ obj-$(CONFIG_USB) += storage/ +obj-$(CONFIG_USB_ACECAD) += input/ +obj-$(CONFIG_USB_AIPTEK) += input/ +obj-$(CONFIG_USB_ATI_REMOTE) += input/ +obj-$(CONFIG_USB_KBTAB) += input/ +obj-$(CONFIG_USB_MTOUCH) += input/ +obj-$(CONFIG_USB_POWERMATE) += input/ +obj-$(CONFIG_USB_WACOM) += input/ +obj-$(CONFIG_USB_XPAD) += input/ + obj-$(CONFIG_USB_CATC) += net/ obj-$(CONFIG_USB_KAWETH) += net/ obj-$(CONFIG_USB_PEGASUS) += net/ diff --git a/trunk/drivers/usb/atm/usbatm.c b/trunk/drivers/usb/atm/usbatm.c index b082d95bbbaa..b3f779f5933a 100644 --- a/trunk/drivers/usb/atm/usbatm.c +++ b/trunk/drivers/usb/atm/usbatm.c @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 0081c1d12687..14de3b1b6a20 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/class/usblp.c b/trunk/drivers/usb/class/usblp.c index 15e740e3a5c4..6584cf00f7f3 100644 --- a/trunk/drivers/usb/class/usblp.c +++ b/trunk/drivers/usb/class/usblp.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index f6b74a678de5..bde29ab2b504 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/core/inode.c b/trunk/drivers/usb/core/inode.c index cd4f11157280..cddfc62c4611 100644 --- a/trunk/drivers/usb/core/inode.c +++ b/trunk/drivers/usb/core/inode.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/core/usb.c b/trunk/drivers/usb/core/usb.c index 18ddc5e67e39..dfd1b5c87ca3 100644 --- a/trunk/drivers/usb/core/usb.c +++ b/trunk/drivers/usb/core/usb.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/at91_udc.c b/trunk/drivers/usb/gadget/at91_udc.c index ba163f35bf21..2a6e3163d944 100644 --- a/trunk/drivers/usb/gadget/at91_udc.c +++ b/trunk/drivers/usb/gadget/at91_udc.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/dummy_hcd.c b/trunk/drivers/usb/gadget/dummy_hcd.c index fcb5526cb085..7d7909cf2558 100644 --- a/trunk/drivers/usb/gadget/dummy_hcd.c +++ b/trunk/drivers/usb/gadget/dummy_hcd.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index 325bf7cfb83f..1dd8b57f4420 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/goku_udc.c b/trunk/drivers/usb/gadget/goku_udc.c index ae931af05cef..65c91d3735de 100644 --- a/trunk/drivers/usb/gadget/goku_udc.c +++ b/trunk/drivers/usb/gadget/goku_udc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/net2280.c b/trunk/drivers/usb/gadget/net2280.c index 52779c52b56d..49d737725f70 100644 --- a/trunk/drivers/usb/gadget/net2280.c +++ b/trunk/drivers/usb/gadget/net2280.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/pxa2xx_udc.c b/trunk/drivers/usb/gadget/pxa2xx_udc.c index 84392e835d5f..2c043a1ea156 100644 --- a/trunk/drivers/usb/gadget/pxa2xx_udc.c +++ b/trunk/drivers/usb/gadget/pxa2xx_udc.c @@ -1483,7 +1483,7 @@ static void udc_disable(struct pxa2xx_udc *dev) #ifdef CONFIG_ARCH_PXA /* Disable clock for USB device */ - pxa_set_cken(CKEN_USB, 0); + pxa_set_cken(CKEN11_USB, 0); #endif ep0_idle (dev); @@ -1529,7 +1529,7 @@ static void udc_enable (struct pxa2xx_udc *dev) #ifdef CONFIG_ARCH_PXA /* Enable clock for USB device */ - pxa_set_cken(CKEN_USB, 1); + pxa_set_cken(CKEN11_USB, 1); udelay(5); #endif diff --git a/trunk/drivers/usb/gadget/serial.c b/trunk/drivers/usb/gadget/serial.c index f847c3414be3..e552668d36b3 100644 --- a/trunk/drivers/usb/gadget/serial.c +++ b/trunk/drivers/usb/gadget/serial.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/zero.c b/trunk/drivers/usb/gadget/zero.c index 7078374d0b79..8c85e33f74a4 100644 --- a/trunk/drivers/usb/gadget/zero.c +++ b/trunk/drivers/usb/gadget/zero.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 099aff64f536..c7458f7e56cc 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/host/ehci-ps3.c b/trunk/drivers/usb/host/ehci-ps3.c index 37b83ba09969..4d781a2a9807 100644 --- a/trunk/drivers/usb/host/ehci-ps3.c +++ b/trunk/drivers/usb/host/ehci-ps3.c @@ -73,6 +73,13 @@ static const struct hc_driver ps3_ehci_hc_driver = { #endif }; +#if !defined(DEBUG) +#undef dev_dbg +static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( + const struct device *_dev, const char *fmt, ...) {return 0;} +#endif + + static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) { int result; @@ -97,7 +104,7 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, __LINE__, dev->m_region->lpar_addr); - result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); + result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", @@ -155,7 +162,7 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) fail_ioremap: usb_put_hcd(hcd); fail_create_hcd: - ps3_io_irq_destroy(virq); + ps3_free_io_irq(virq); fail_irq: ps3_free_mmio_region(dev->m_region); fail_mmio: diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index a66637e725f3..e8bbe8bc2598 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/host/ohci-ppc-of.c b/trunk/drivers/usb/host/ohci-ppc-of.c index c43b66acd4d5..08e237c7bc43 100644 --- a/trunk/drivers/usb/host/ohci-ppc-of.c +++ b/trunk/drivers/usb/host/ohci-ppc-of.c @@ -97,8 +97,8 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) return -ENODEV; is_bigendian = - of_device_is_compatible(dn, "ohci-bigendian") || - of_device_is_compatible(dn, "ohci-be"); + device_is_compatible(dn, "ohci-bigendian") || + device_is_compatible(dn, "ohci-be"); dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n"); diff --git a/trunk/drivers/usb/host/ohci-ps3.c b/trunk/drivers/usb/host/ohci-ps3.c index d7cf07288b0b..62283a3926de 100644 --- a/trunk/drivers/usb/host/ohci-ps3.c +++ b/trunk/drivers/usb/host/ohci-ps3.c @@ -75,6 +75,14 @@ static const struct hc_driver ps3_ohci_hc_driver = { #endif }; +/* redefine dev_dbg to do a syntax check */ + +#if !defined(DEBUG) +#undef dev_dbg +static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( + const struct device *_dev, const char *fmt, ...) {return 0;} +#endif + static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) { int result; @@ -99,7 +107,7 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, __LINE__, dev->m_region->lpar_addr); - result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); + result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); if (result) { dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", @@ -157,7 +165,7 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) fail_ioremap: usb_put_hcd(hcd); fail_create_hcd: - ps3_io_irq_destroy(virq); + ps3_free_io_irq(virq); fail_irq: ps3_free_mmio_region(dev->m_region); fail_mmio: diff --git a/trunk/drivers/usb/host/ohci-pxa27x.c b/trunk/drivers/usb/host/ohci-pxa27x.c index 23d2fe5a62f4..f1563dc319d3 100644 --- a/trunk/drivers/usb/host/ohci-pxa27x.c +++ b/trunk/drivers/usb/host/ohci-pxa27x.c @@ -80,7 +80,7 @@ static int pxa27x_start_hc(struct device *dev) inf = dev->platform_data; - pxa_set_cken(CKEN_USBHOST, 1); + pxa_set_cken(CKEN10_USBHOST, 1); UHCHR |= UHCHR_FHR; udelay(11); @@ -123,7 +123,7 @@ static void pxa27x_stop_hc(struct device *dev) UHCCOMS |= 1; udelay(10); - pxa_set_cken(CKEN_USBHOST, 0); + pxa_set_cken(CKEN10_USBHOST, 0); } diff --git a/trunk/drivers/usb/host/sl811-hcd.c b/trunk/drivers/usb/host/sl811-hcd.c index 4cfa3ff2c993..5fa5647ea095 100644 --- a/trunk/drivers/usb/host/sl811-hcd.c +++ b/trunk/drivers/usb/host/sl811-hcd.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/host/u132-hcd.c b/trunk/drivers/usb/host/u132-hcd.c index ff0dba01f1c7..a7fa0d75567d 100644 --- a/trunk/drivers/usb/host/u132-hcd.c +++ b/trunk/drivers/usb/host/u132-hcd.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/image/mdc800.c b/trunk/drivers/usb/image/mdc800.c index 36502a06f73a..d308afd06935 100644 --- a/trunk/drivers/usb/image/mdc800.c +++ b/trunk/drivers/usb/image/mdc800.c @@ -94,6 +94,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/usb/image/microtek.c b/trunk/drivers/usb/image/microtek.c index 51bd80d2b8cc..896cb2b71020 100644 --- a/trunk/drivers/usb/image/microtek.c +++ b/trunk/drivers/usb/image/microtek.c @@ -128,6 +128,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/usb/input/Kconfig b/trunk/drivers/usb/input/Kconfig new file mode 100644 index 000000000000..a792e42f58af --- /dev/null +++ b/trunk/drivers/usb/input/Kconfig @@ -0,0 +1,225 @@ +# +# USB Input driver configuration +# +comment "USB Input Devices" + depends on USB + +config USB_AIPTEK + tristate "Aiptek 6000U/8000U tablet support" + depends on USB && INPUT + help + Say Y here if you want to use the USB version of the Aiptek 6000U + or Aiptek 8000U tablet. Make sure to say Y to "Mouse support" + (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" + (CONFIG_INPUT_EVDEV) as well. + + To compile this driver as a module, choose M here: the + module will be called aiptek. + +config USB_WACOM + tristate "Wacom Intuos/Graphire tablet support" + depends on USB && INPUT + help + Say Y here if you want to use the USB version of the Wacom Intuos + or Graphire tablet. Make sure to say Y to "Mouse support" + (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" + (CONFIG_INPUT_EVDEV) as well. + + To compile this driver as a module, choose M here: the + module will be called wacom. + +config USB_ACECAD + tristate "Acecad Flair tablet support" + depends on USB && INPUT + help + Say Y here if you want to use the USB version of the Acecad Flair + tablet. Make sure to say Y to "Mouse support" + (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" + (CONFIG_INPUT_EVDEV) as well. + + To compile this driver as a module, choose M here: the + module will be called acecad. + +config USB_KBTAB + tristate "KB Gear JamStudio tablet support" + depends on USB && INPUT + help + Say Y here if you want to use the USB version of the KB Gear + JamStudio tablet. Make sure to say Y to "Mouse support" + (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" + (CONFIG_INPUT_EVDEV) as well. + + To compile this driver as a module, choose M here: the + module will be called kbtab. + +config USB_POWERMATE + tristate "Griffin PowerMate and Contour Jog support" + depends on USB && INPUT + ---help--- + Say Y here if you want to use Griffin PowerMate or Contour Jog devices. + These are aluminum dials which can measure clockwise and anticlockwise + rotation. The dial also acts as a pushbutton. The base contains an LED + which can be instructed to pulse or to switch to a particular intensity. + + You can download userspace tools from + . + + To compile this driver as a module, choose M here: the + module will be called powermate. + +config USB_TOUCHSCREEN + tristate "USB Touchscreen Driver" + depends on USB && INPUT + ---help--- + USB Touchscreen driver for: + - eGalax Touchkit USB (also includes eTurboTouch CT-410/510/700) + - PanJit TouchSet USB + - 3M MicroTouch USB (EX II series) + - ITM + - some other eTurboTouch + - Gunze AHL61 + - DMC TSC-10/25 + + Have a look at for + a usage description and the required user-space stuff. + + To compile this driver as a module, choose M here: the + module will be called usbtouchscreen. + +config USB_TOUCHSCREEN_EGALAX + default y + bool "eGalax, eTurboTouch CT-410/510/700 device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_PANJIT + default y + bool "PanJit device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_3M + default y + bool "3M/Microtouch EX II series device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_ITM + default y + bool "ITM device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_ETURBO + default y + bool "eTurboTouch (non-eGalax compatible) device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_GUNZE + default y + bool "Gunze AHL61 device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_TOUCHSCREEN_DMC_TSC10 + default y + bool "DMC TSC-10/25 device support" if EMBEDDED + depends on USB_TOUCHSCREEN + +config USB_YEALINK + tristate "Yealink usb-p1k voip phone" + depends on USB && INPUT && EXPERIMENTAL + ---help--- + Say Y here if you want to enable keyboard and LCD functions of the + Yealink usb-p1k usb phones. The audio part is enabled by the generic + usb sound driver, so you might want to enable that as well. + + For information about how to use these additional functions, see + . + + To compile this driver as a module, choose M here: the module will be + called yealink. + +config USB_XPAD + tristate "X-Box gamepad support" + depends on USB && INPUT + ---help--- + Say Y here if you want to use the X-Box pad with your computer. + Make sure to say Y to "Joystick support" (CONFIG_INPUT_JOYDEV) + and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well. + + For information about how to connect the X-Box pad to USB, see + . + + To compile this driver as a module, choose M here: the + module will be called xpad. + +config USB_ATI_REMOTE + tristate "ATI / X10 USB RF remote control" + depends on USB && INPUT + ---help--- + Say Y here if you want to use an ATI or X10 "Lola" USB remote control. + These are RF remotes with USB receivers. + The ATI remote comes with many of ATI's All-In-Wonder video cards. + The X10 "Lola" remote is available at: + + This driver provides mouse pointer, left and right mouse buttons, + and maps all the other remote buttons to keypress events. + + To compile this driver as a module, choose M here: the module will be + called ati_remote. + +config USB_ATI_REMOTE2 + tristate "ATI / Philips USB RF remote control" + depends on USB && INPUT + ---help--- + Say Y here if you want to use an ATI or Philips USB RF remote control. + These are RF remotes with USB receivers. + ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards + and is also available as a separate product. + This driver provides mouse pointer, left and right mouse buttons, + and maps all the other remote buttons to keypress events. + + To compile this driver as a module, choose M here: the module will be + called ati_remote2. + +config USB_KEYSPAN_REMOTE + tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" + depends on USB && INPUT && EXPERIMENTAL + ---help--- + Say Y here if you want to use a Keyspan DMR USB remote control. + Currently only the UIA-11 type of receiver has been tested. The tag + on the receiver that connects to the USB port should have a P/N that + will tell you what type of DMR you have. The UIA-10 type is not + supported at this time. This driver maps all buttons to keypress + events. + + To compile this driver as a module, choose M here: the module will + be called keyspan_remote. + +config USB_APPLETOUCH + tristate "Apple USB Touchpad support" + depends on USB && INPUT + ---help--- + Say Y here if you want to use an Apple USB Touchpad. + + These are the touchpads that can be found on post-February 2005 + Apple Powerbooks (prior models have a Synaptics touchpad connected + to the ADB bus). + + This driver provides a basic mouse driver but can be interfaced + with the synaptics X11 driver to provide acceleration and + scrolling in X11. + + For further information, see + . + + To compile this driver as a module, choose M here: the + module will be called appletouch. + +config USB_GTCO + tristate "GTCO CalComp/InterWrite USB Support" + depends on USB && INPUT + ---help--- + Say Y here if you want to use the USB version of the GTCO + CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support" + (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" + (CONFIG_INPUT_EVDEV) as well. + + To compile this driver as a module, choose M here: the + module will be called gtco. diff --git a/trunk/drivers/usb/input/Makefile b/trunk/drivers/usb/input/Makefile new file mode 100644 index 000000000000..9bf420eef77f --- /dev/null +++ b/trunk/drivers/usb/input/Makefile @@ -0,0 +1,27 @@ +# +# Makefile for the USB input drivers +# + +# Multipart objects. +wacom-objs := wacom_wac.o wacom_sys.o + +obj-$(CONFIG_USB_AIPTEK) += aiptek.o +obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o +obj-$(CONFIG_USB_ATI_REMOTE2) += ati_remote2.o +obj-$(CONFIG_USB_KBTAB) += kbtab.o +obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o +obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o +obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o +obj-$(CONFIG_USB_EGALAX) += touchkitusb.o +obj-$(CONFIG_USB_TOUCHSCREEN) += usbtouchscreen.o +obj-$(CONFIG_USB_POWERMATE) += powermate.o +obj-$(CONFIG_USB_WACOM) += wacom.o +obj-$(CONFIG_USB_ACECAD) += acecad.o +obj-$(CONFIG_USB_YEALINK) += yealink.o +obj-$(CONFIG_USB_XPAD) += xpad.o +obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o +obj-$(CONFIG_USB_GTCO) += gtco.o + +ifeq ($(CONFIG_USB_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif diff --git a/trunk/drivers/input/tablet/acecad.c b/trunk/drivers/usb/input/acecad.c similarity index 94% rename from trunk/drivers/input/tablet/acecad.c rename to trunk/drivers/usb/input/acecad.c index dd2310458c46..909138e5aa04 100644 --- a/trunk/drivers/input/tablet/acecad.c +++ b/trunk/drivers/usb/input/acecad.c @@ -54,7 +54,7 @@ struct usb_acecad { struct input_dev *input; struct urb *irq; - unsigned char *data; + signed char *data; dma_addr_t data_dma; }; @@ -111,7 +111,7 @@ static void usb_acecad_irq(struct urb *urb) static int usb_acecad_open(struct input_dev *dev) { - struct usb_acecad *acecad = input_get_drvdata(dev); + struct usb_acecad *acecad = dev->private; acecad->irq->dev = acecad->usbdev; if (usb_submit_urb(acecad->irq, GFP_KERNEL)) @@ -122,7 +122,7 @@ static int usb_acecad_open(struct input_dev *dev) static void usb_acecad_close(struct input_dev *dev) { - struct usb_acecad *acecad = input_get_drvdata(dev); + struct usb_acecad *acecad = dev->private; usb_kill_urb(acecad->irq); } @@ -135,7 +135,6 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ struct usb_acecad *acecad; struct input_dev *input_dev; int pipe, maxp; - int err = -ENOMEM; if (interface->desc.bNumEndpoints != 1) return -ENODEV; @@ -150,22 +149,16 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL); input_dev = input_allocate_device(); - if (!acecad || !input_dev) { - err = -ENOMEM; + if (!acecad || !input_dev) goto fail1; - } acecad->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &acecad->data_dma); - if (!acecad->data) { - err= -ENOMEM; + if (!acecad->data) goto fail1; - } acecad->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!acecad->irq) { - err = -ENOMEM; + if (!acecad->irq) goto fail2; - } acecad->usbdev = dev; acecad->input = input_dev; @@ -185,9 +178,8 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ input_dev->name = acecad->name; input_dev->phys = acecad->phys; usb_to_input_id(dev, &input_dev->id); - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, acecad); + input_dev->cdev.dev = &intf->dev; + input_dev->private = acecad; input_dev->open = usb_acecad_open; input_dev->close = usb_acecad_close; @@ -229,9 +221,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ acecad->irq->transfer_dma = acecad->data_dma; acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - err = input_register_device(acecad->input); - if (err) - goto fail2; + input_register_device(acecad->input); usb_set_intfdata(intf, acecad); @@ -240,7 +230,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ fail2: usb_buffer_free(dev, 8, acecad->data, acecad->data_dma); fail1: input_free_device(input_dev); kfree(acecad); - return err; + return -ENOMEM; } static void usb_acecad_disconnect(struct usb_interface *intf) diff --git a/trunk/drivers/input/tablet/aiptek.c b/trunk/drivers/usb/input/aiptek.c similarity index 99% rename from trunk/drivers/input/tablet/aiptek.c rename to trunk/drivers/usb/input/aiptek.c index cc0a498763d8..f857935e615c 100644 --- a/trunk/drivers/input/tablet/aiptek.c +++ b/trunk/drivers/usb/input/aiptek.c @@ -798,7 +798,7 @@ MODULE_DEVICE_TABLE(usb, aiptek_ids); */ static int aiptek_open(struct input_dev *inputdev) { - struct aiptek *aiptek = input_get_drvdata(inputdev); + struct aiptek *aiptek = inputdev->private; aiptek->urb->dev = aiptek->usbdev; if (usb_submit_urb(aiptek->urb, GFP_KERNEL) != 0) @@ -812,7 +812,7 @@ static int aiptek_open(struct input_dev *inputdev) */ static void aiptek_close(struct input_dev *inputdev) { - struct aiptek *aiptek = input_get_drvdata(inputdev); + struct aiptek *aiptek = inputdev->private; usb_kill_urb(aiptek->urb); } @@ -1972,7 +1972,6 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) AIPTEK_PROGRAMMABLE_DELAY_200, AIPTEK_PROGRAMMABLE_DELAY_300 }; - int err = -ENOMEM; /* programmableDelay is where the command-line specified * delay is kept. We make it the first element of speeds[], @@ -2044,10 +2043,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) inputdev->name = "Aiptek"; inputdev->phys = aiptek->features.usbPath; usb_to_input_id(usbdev, &inputdev->id); - inputdev->dev.parent = &intf->dev; - - input_set_drvdata(inputdev, aiptek); - + inputdev->cdev.dev = &intf->dev; + inputdev->private = aiptek; inputdev->open = aiptek_open; inputdev->close = aiptek_close; @@ -2136,9 +2133,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Register the tablet as an Input Device */ - err = input_register_device(aiptek->inputdev); - if (err) - goto fail2; + input_register_device(aiptek->inputdev); /* We now will look for the evdev device which is mapped to * the tablet. The partial name is kept in the link list of @@ -2170,13 +2165,23 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) return 0; - fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, +fail2: usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data, aiptek->data_dma); - fail1: input_free_device(inputdev); +fail1: input_free_device(inputdev); kfree(aiptek); - return err; + return -ENOMEM; } +/* Forward declaration */ +static void aiptek_disconnect(struct usb_interface *intf); + +static struct usb_driver aiptek_driver = { + .name = "aiptek", + .probe = aiptek_probe, + .disconnect = aiptek_disconnect, + .id_table = aiptek_ids, +}; + /*********************************************************************** * Deal with tablet disconnecting from the system. */ @@ -2201,13 +2206,6 @@ static void aiptek_disconnect(struct usb_interface *intf) } } -static struct usb_driver aiptek_driver = { - .name = "aiptek", - .probe = aiptek_probe, - .disconnect = aiptek_disconnect, - .id_table = aiptek_ids, -}; - static int __init aiptek_init(void) { int result = usb_register(&aiptek_driver); diff --git a/trunk/drivers/input/mouse/appletouch.c b/trunk/drivers/usb/input/appletouch.c similarity index 97% rename from trunk/drivers/input/mouse/appletouch.c rename to trunk/drivers/usb/input/appletouch.c index e3215267db11..c77291d3d063 100644 --- a/trunk/drivers/input/mouse/appletouch.c +++ b/trunk/drivers/usb/input/appletouch.c @@ -466,7 +466,7 @@ static void atp_complete(struct urb* urb) static int atp_open(struct input_dev *input) { - struct atp *dev = input_get_drvdata(input); + struct atp *dev = input->private; if (usb_submit_urb(dev->urb, GFP_ATOMIC)) return -EIO; @@ -477,7 +477,7 @@ static int atp_open(struct input_dev *input) static void atp_close(struct input_dev *input) { - struct atp *dev = input_get_drvdata(input); + struct atp *dev = input->private; usb_kill_urb(dev->urb); dev->open = 0; @@ -491,7 +491,8 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int int_in_endpointAddr = 0; - int i, error = -ENOMEM; + int i, retval = -ENOMEM; + /* set up the endpoint information */ /* use only the first interrupt-in endpoint */ @@ -566,13 +567,17 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id } dev->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!dev->urb) + if (!dev->urb) { + retval = -ENOMEM; goto err_free_devs; + } dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL, &dev->urb->transfer_dma); - if (!dev->data) + if (!dev->data) { + retval = -ENOMEM; goto err_free_urb; + } usb_fill_int_urb(dev->urb, udev, usb_rcvintpipe(udev, int_in_endpointAddr), @@ -584,10 +589,9 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id input_dev->name = "appletouch"; input_dev->phys = dev->phys; usb_to_input_id(dev->udev, &input_dev->id); - input_dev->dev.parent = &iface->dev; - - input_set_drvdata(input_dev, dev); + input_dev->cdev.dev = &iface->dev; + input_dev->private = dev; input_dev->open = atp_open; input_dev->close = atp_close; @@ -629,25 +633,20 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); set_bit(BTN_LEFT, input_dev->keybit); - error = input_register_device(dev->input); - if (error) - goto err_free_buffer; + input_register_device(dev->input); /* save our data pointer in this interface device */ usb_set_intfdata(iface, dev); return 0; - err_free_buffer: - usb_buffer_free(dev->udev, dev->datalen, - dev->data, dev->urb->transfer_dma); err_free_urb: usb_free_urb(dev->urb); err_free_devs: usb_set_intfdata(iface, NULL); kfree(dev); input_free_device(input_dev); - return error; + return retval; } static void atp_disconnect(struct usb_interface *iface) diff --git a/trunk/drivers/input/misc/ati_remote.c b/trunk/drivers/usb/input/ati_remote.c similarity index 95% rename from trunk/drivers/input/misc/ati_remote.c rename to trunk/drivers/usb/input/ati_remote.c index 471aab206443..b724e36f7b92 100644 --- a/trunk/drivers/input/misc/ati_remote.c +++ b/trunk/drivers/usb/input/ati_remote.c @@ -120,7 +120,6 @@ * behaviour. */ #define FILTER_TIME 60 /* msec */ -#define REPEAT_DELAY 500 /* msec */ static unsigned long channel_mask; module_param(channel_mask, ulong, 0644); @@ -134,10 +133,6 @@ static int repeat_filter = FILTER_TIME; module_param(repeat_filter, int, 0644); MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec"); -static int repeat_delay = REPEAT_DELAY; -module_param(repeat_delay, int, 0644); -MODULE_PARM_DESC(repeat_delay, "Delay before sending repeats, default = 500 msec"); - #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) #undef err #define err(format, arg...) printk(KERN_ERR format , ## arg) @@ -179,8 +174,6 @@ struct ati_remote { unsigned char old_data[2]; /* Detect duplicate events */ unsigned long old_jiffies; unsigned long acc_jiffies; /* handle acceleration */ - unsigned long first_jiffies; - unsigned int repeat_count; char name[NAME_BUFSIZE]; @@ -325,7 +318,7 @@ static void ati_remote_dump(unsigned char *data, unsigned int len) */ static int ati_remote_open(struct input_dev *inputdev) { - struct ati_remote *ati_remote = input_get_drvdata(inputdev); + struct ati_remote *ati_remote = inputdev->private; /* On first open, submit the read urb which was set up previously. */ ati_remote->irq_urb->dev = ati_remote->udev; @@ -343,7 +336,7 @@ static int ati_remote_open(struct input_dev *inputdev) */ static void ati_remote_close(struct input_dev *inputdev) { - struct ati_remote *ati_remote = input_get_drvdata(inputdev); + struct ati_remote *ati_remote = inputdev->private; usb_kill_urb(ati_remote->irq_urb); } @@ -508,31 +501,21 @@ static void ati_remote_input_report(struct urb *urb) } if (ati_remote_tbl[index].kind == KIND_FILTERED) { - unsigned long now = jiffies; - /* Filter duplicate events which happen "too close" together. */ if (ati_remote->old_data[0] == data[1] && ati_remote->old_data[1] == data[2] && - time_before(now, ati_remote->old_jiffies + - msecs_to_jiffies(repeat_filter))) { + time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) { ati_remote->repeat_count++; } else { ati_remote->repeat_count = 0; - ati_remote->first_jiffies = now; } ati_remote->old_data[0] = data[1]; ati_remote->old_data[1] = data[2]; - ati_remote->old_jiffies = now; + ati_remote->old_jiffies = jiffies; - /* Ensure we skip at least the 4 first duplicate events (generated - * by a single keypress), and continue skipping until repeat_delay - * msecs have passed - */ if (ati_remote->repeat_count > 0 && - (ati_remote->repeat_count < 5 || - time_before(now, ati_remote->first_jiffies + - msecs_to_jiffies(repeat_delay)))) + ati_remote->repeat_count < 5) return; @@ -670,8 +653,7 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) if (ati_remote_tbl[i].type == EV_KEY) set_bit(ati_remote_tbl[i].code, idev->keybit); - input_set_drvdata(idev, ati_remote); - + idev->private = ati_remote; idev->open = ati_remote_open; idev->close = ati_remote_close; @@ -679,7 +661,7 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) idev->phys = ati_remote->phys; usb_to_input_id(ati_remote->udev, &idev->id); - idev->dev.parent = &ati_remote->udev->dev; + idev->cdev.dev = &ati_remote->udev->dev; } static int ati_remote_initialize(struct ati_remote *ati_remote) @@ -790,17 +772,15 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de goto fail3; /* Set up and register input device */ - err = input_register_device(ati_remote->idev); - if (err) - goto fail3; + input_register_device(ati_remote->idev); usb_set_intfdata(interface, ati_remote); return 0; - fail3: usb_kill_urb(ati_remote->irq_urb); +fail3: usb_kill_urb(ati_remote->irq_urb); usb_kill_urb(ati_remote->out_urb); - fail2: ati_remote_free_buffers(ati_remote); - fail1: input_free_device(input_dev); +fail2: ati_remote_free_buffers(ati_remote); +fail1: input_free_device(input_dev); kfree(ati_remote); return err; } diff --git a/trunk/drivers/input/misc/ati_remote2.c b/trunk/drivers/usb/input/ati_remote2.c similarity index 97% rename from trunk/drivers/input/misc/ati_remote2.c rename to trunk/drivers/usb/input/ati_remote2.c index 1031543e5c3f..6459be90599c 100644 --- a/trunk/drivers/input/misc/ati_remote2.c +++ b/trunk/drivers/usb/input/ati_remote2.c @@ -131,7 +131,7 @@ static struct usb_driver ati_remote2_driver = { static int ati_remote2_open(struct input_dev *idev) { - struct ati_remote2 *ar2 = input_get_drvdata(idev); + struct ati_remote2 *ar2 = idev->private; int r; r = usb_submit_urb(ar2->urb[0], GFP_KERNEL); @@ -153,7 +153,7 @@ static int ati_remote2_open(struct input_dev *idev) static void ati_remote2_close(struct input_dev *idev) { - struct ati_remote2 *ar2 = input_get_drvdata(idev); + struct ati_remote2 *ar2 = idev->private; usb_kill_urb(ar2->urb[0]); usb_kill_urb(ar2->urb[1]); @@ -337,14 +337,14 @@ static void ati_remote2_complete_key(struct urb *urb) static int ati_remote2_input_init(struct ati_remote2 *ar2) { struct input_dev *idev; - int i, retval; + int i; idev = input_allocate_device(); if (!idev) return -ENOMEM; ar2->idev = idev; - input_set_drvdata(idev, ar2); + idev->private = ar2; idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); @@ -362,13 +362,13 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) idev->phys = ar2->phys; usb_to_input_id(ar2->udev, &idev->id); - idev->dev.parent = &ar2->udev->dev; + idev->cdev.dev = &ar2->udev->dev; - retval = input_register_device(idev); - if (retval) + i = input_register_device(idev); + if (i) input_free_device(idev); - return retval; + return i; } static int ati_remote2_urb_init(struct ati_remote2 *ar2) @@ -405,7 +405,9 @@ static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2) for (i = 0; i < 2; i++) { usb_free_urb(ar2->urb[i]); - usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]); + + if (ar2->buf[i]) + usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]); } } diff --git a/trunk/drivers/input/tablet/gtco.c b/trunk/drivers/usb/input/gtco.c similarity index 65% rename from trunk/drivers/input/tablet/gtco.c rename to trunk/drivers/usb/input/gtco.c index b2ca10f2fe0e..ae756e0afc99 100644 --- a/trunk/drivers/input/tablet/gtco.c +++ b/trunk/drivers/usb/input/gtco.c @@ -187,6 +187,7 @@ struct hid_descriptor /* + * * This is an abbreviated parser for the HID Report Descriptor. We * know what devices we are talking to, so this is by no means meant * to be generic. We can make some safe assumptions: @@ -203,7 +204,7 @@ struct hid_descriptor static void parse_hid_report_descriptor(struct gtco *device, char * report, int length) { - int x, i = 0; + int x,i=0; /* Tag primitive vars */ __u8 prefix; @@ -214,6 +215,7 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, __u16 data16 = 0; __u32 data32 = 0; + /* For parsing logic */ int inputnum = 0; __u32 usage = 0; @@ -223,46 +225,46 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, __u32 oldval[TAG_GLOB_MAX]; /* Debug stuff */ - char maintype = 'x'; + char maintype='x'; char globtype[12]; - int indent = 0; - char indentstr[10] = ""; + int indent=0; + char indentstr[10]=""; + dbg("======>>>>>>PARSE<<<<<<======"); /* Walk this report and pull out the info we need */ - while (i < length) { - prefix = report[i]; + while (imax_X == 0) { + dbg("GER: X Usage: 0x%x",usage); + if (device->max_X == 0){ device->max_X = globalval[TAG_GLOB_LOG_MAX]; device->min_X = globalval[TAG_GLOB_LOG_MIN]; } - break; + break; case 1: /* Y coord */ - dbg("GER: Y Usage: 0x%x", usage); - if (device->max_Y == 0) { + dbg("GER: Y Usage: 0x%x",usage); + if (device->max_Y == 0){ device->max_Y = globalval[TAG_GLOB_LOG_MAX]; device->min_Y = globalval[TAG_GLOB_LOG_MIN]; } break; - default: /* Tilt X */ - if (usage == DIGITIZER_USAGE_TILT_X) { - if (device->maxtilt_X == 0) { + if (usage == DIGITIZER_USAGE_TILT_X){ + if (device->maxtilt_X == 0){ device->maxtilt_X = globalval[TAG_GLOB_LOG_MAX]; device->mintilt_X = globalval[TAG_GLOB_LOG_MIN]; } } /* Tilt Y */ - if (usage == DIGITIZER_USAGE_TILT_Y) { - if (device->maxtilt_Y == 0) { + if (usage == DIGITIZER_USAGE_TILT_Y){ + if (device->maxtilt_Y == 0){ device->maxtilt_Y = globalval[TAG_GLOB_LOG_MAX]; device->mintilt_Y = globalval[TAG_GLOB_LOG_MIN]; } } + /* Pressure */ - if (usage == DIGITIZER_USAGE_TIP_PRESSURE) { - if (device->maxpressure == 0) { + if (usage == DIGITIZER_USAGE_TIP_PRESSURE){ + if (device->maxpressure == 0){ device->maxpressure = globalval[TAG_GLOB_LOG_MAX]; device->minpressure = globalval[TAG_GLOB_LOG_MIN]; } @@ -337,226 +341,214 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report, } inputnum++; - break; + + break; case TAG_MAIN_OUTPUT: - maintype = 'O'; + maintype='O'; break; - case TAG_MAIN_FEATURE: - maintype = 'F'; + maintype='F'; break; - case TAG_MAIN_COL_START: - maintype = 'S'; + maintype='S'; - if (data == 0) { + if (data==0){ dbg("======>>>>>> Physical"); - strcpy(globtype, "Physical"); - } else + strcpy(globtype,"Physical"); + }else{ dbg("======>>>>>>"); + } /* Indent the debug output */ indent++; - for (x = 0; x < indent; x++) - indentstr[x] = '-'; - indentstr[x] = 0; + for (x=0;xusage == 0) + if (device->usage == 0){ device->usage = data; - - strcpy(globtype, "USAGE"); + } + strcpy(globtype,"USAGE"); break; - - case TAG_GLOB_LOG_MIN: - strcpy(globtype, "LOG_MIN"); + case TAG_GLOB_LOG_MIN : + strcpy(globtype,"LOG_MIN"); break; - - case TAG_GLOB_LOG_MAX: - strcpy(globtype, "LOG_MAX"); + case TAG_GLOB_LOG_MAX : + strcpy(globtype,"LOG_MAX"); break; - - case TAG_GLOB_PHYS_MIN: - strcpy(globtype, "PHYS_MIN"); + case TAG_GLOB_PHYS_MIN : + strcpy(globtype,"PHYS_MIN"); break; - - case TAG_GLOB_PHYS_MAX: - strcpy(globtype, "PHYS_MAX"); + case TAG_GLOB_PHYS_MAX : + strcpy(globtype,"PHYS_MAX"); break; - - case TAG_GLOB_UNIT_EXP: - strcpy(globtype, "EXP"); + case TAG_GLOB_UNIT_EXP : + strcpy(globtype,"EXP"); break; - - case TAG_GLOB_UNIT: - strcpy(globtype, "UNIT"); + case TAG_GLOB_UNIT : + strcpy(globtype,"UNIT"); break; - - case TAG_GLOB_REPORT_SZ: - strcpy(globtype, "REPORT_SZ"); + case TAG_GLOB_REPORT_SZ : + strcpy(globtype,"REPORT_SZ"); break; - - case TAG_GLOB_REPORT_ID: - strcpy(globtype, "REPORT_ID"); + case TAG_GLOB_REPORT_ID : + strcpy(globtype,"REPORT_ID"); /* New report, restart numbering */ - inputnum = 0; + inputnum=0; break; - case TAG_GLOB_REPORT_CNT: - strcpy(globtype, "REPORT_CNT"); + strcpy(globtype,"REPORT_CNT"); break; - - case TAG_GLOB_PUSH: - strcpy(globtype, "PUSH"); + case TAG_GLOB_PUSH : + strcpy(globtype,"PUSH"); break; - case TAG_GLOB_POP: - strcpy(globtype, "POP"); + strcpy(globtype,"POP"); break; } + /* Check to make sure we have a good tag number so we don't overflow array */ - if (tag < TAG_GLOB_MAX) { - switch (size) { + if (tag < TAG_GLOB_MAX){ + switch (size){ case 1: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x", - indentstr, globtype, tag, size, data); - globalval[tag] = data; + dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data); + globalval[tag]=data; break; - case 2: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x", - indentstr, globtype, tag, size, data16); - globalval[tag] = data16; + dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data16); + globalval[tag]=data16; break; - case 4: - dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x", - indentstr, globtype, tag, size, data32); - globalval[tag] = data32; + dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data32); + globalval[tag]=data32; break; } - } else { + }else{ dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ", - indentstr, tag, size); + indentstr,tag,size); } + + break; case TYPE_LOCAL: - switch (tag) { + switch(tag){ case TAG_GLOB_USAGE: - strcpy(globtype, "USAGE"); + strcpy(globtype,"USAGE"); /* Always 1 byte */ usage = data; break; - - case TAG_GLOB_LOG_MIN: - strcpy(globtype, "MIN"); + case TAG_GLOB_LOG_MIN : + strcpy(globtype,"MIN"); break; - - case TAG_GLOB_LOG_MAX: - strcpy(globtype, "MAX"); + case TAG_GLOB_LOG_MAX : + strcpy(globtype,"MAX"); break; - default: - strcpy(globtype, "UNKNOWN"); - break; + strcpy(globtype,"UNKNOWN"); } - switch (size) { + switch (size){ case 1: dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr, tag, globtype, size, data); + indentstr,tag,globtype,size,data); break; - case 2: dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr, tag, globtype, size, data16); + indentstr,tag,globtype,size,data16); break; - case 4: dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", - indentstr, tag, globtype, size, data32); + indentstr,tag,globtype,size,data32); break; } break; } + } + } + + /* INPUT DRIVER Routines */ + /* - * Called when opening the input device. This will submit the URB to - * the usb system so we start getting reports + * Called when opening the input device. This will submit the URB to + * the usb system so we start getting reports */ static int gtco_input_open(struct input_dev *inputdev) { - struct gtco *device = input_get_drvdata(inputdev); + struct gtco *device; + device = inputdev->private; device->urbinfo->dev = device->usbdev; - if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) + if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) { return -EIO; - + } return 0; } -/* - * Called when closing the input device. This will unlink the URB - */ +/** + Called when closing the input device. This will unlink the URB +*/ static void gtco_input_close(struct input_dev *inputdev) { - struct gtco *device = input_get_drvdata(inputdev); + struct gtco *device = inputdev->private; usb_kill_urb(device->urbinfo); + } @@ -568,16 +560,19 @@ static void gtco_input_close(struct input_dev *inputdev) * placed in the struct gtco structure * */ -static void gtco_setup_caps(struct input_dev *inputdev) +static void gtco_setup_caps(struct input_dev *inputdev) { - struct gtco *device = input_get_drvdata(inputdev); + struct gtco *device = inputdev->private; + /* Which events */ inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); + /* Misc event menu block */ inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ; + /* Absolute values based on HID report info */ input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X, 0, 0); @@ -595,12 +590,17 @@ static void gtco_setup_caps(struct input_dev *inputdev) input_set_abs_params(inputdev, ABS_PRESSURE, device->minpressure, device->maxpressure, 0, 0); + /* Transducer */ - input_set_abs_params(inputdev, ABS_MISC, 0, 0xFF, 0, 0); + input_set_abs_params(inputdev, ABS_MISC, 0,0xFF, 0, 0); + } + + /* USB Routines */ + /* * URB callback routine. Called when we get IRQ reports from the * digitizer. @@ -610,7 +610,9 @@ static void gtco_setup_caps(struct input_dev *inputdev) */ static void gtco_urb_callback(struct urb *urbinfo) { - struct gtco *device = urbinfo->context; + + + struct gtco *device = urbinfo->context; struct input_dev *inputdev; int rc; u32 val = 0; @@ -619,20 +621,19 @@ static void gtco_urb_callback(struct urb *urbinfo) inputdev = device->inputdevice; + /* Was callback OK? */ - if (urbinfo->status == -ECONNRESET || - urbinfo->status == -ENOENT || - urbinfo->status == -ESHUTDOWN) { + if ((urbinfo->status == -ECONNRESET ) || + (urbinfo->status == -ENOENT ) || + (urbinfo->status == -ESHUTDOWN )){ /* Shutdown is occurring. Return and don't queue up any more */ return; } - if (urbinfo->status != 0) { - /* - * Some unknown error. Hopefully temporary. Just go and - * requeue an URB - */ + if (urbinfo->status != 0 ) { + /* Some unknown error. Hopefully temporary. Just go and */ + /* requeue an URB */ goto resubmit; } @@ -641,9 +642,10 @@ static void gtco_urb_callback(struct urb *urbinfo) */ /* PID dependent when we interpret the report */ - if (inputdev->id.product == PID_1000 || - inputdev->id.product == PID_1001 || - inputdev->id.product == PID_1002) { + if ((inputdev->id.product == PID_1000 )|| + (inputdev->id.product == PID_1001 )|| + (inputdev->id.product == PID_1002 )) + { /* * Switch on the report ID @@ -651,10 +653,10 @@ static void gtco_urb_callback(struct urb *urbinfo) * the report number. We can just fall through the case * statements if we start with the highest number report */ - switch (device->buffer[0]) { + switch(device->buffer[0]){ case 5: /* Pressure is 9 bits */ - val = ((u16)(device->buffer[8]) << 1); + val = ((u16)(device->buffer[8]) << 1); val |= (u16)(device->buffer[7] >> 7); input_report_abs(inputdev, ABS_PRESSURE, device->buffer[8]); @@ -662,6 +664,7 @@ static void gtco_urb_callback(struct urb *urbinfo) /* Mask out the Y tilt value used for pressure */ device->buffer[7] = (u8)((device->buffer[7]) & 0x7F); + /* Fall thru */ case 4: /* Tilt */ @@ -681,10 +684,11 @@ static void gtco_urb_callback(struct urb *urbinfo) input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned); /* Fall thru */ + case 2: case 3: /* Convert buttons, only 5 bits possible */ - val = (device->buffer[5]) & MASK_BUTTON; + val = (device->buffer[5])&MASK_BUTTON; /* We don't apply any meaning to the bitmask, just report */ @@ -692,109 +696,132 @@ static void gtco_urb_callback(struct urb *urbinfo) /* Fall thru */ case 1: + /* All reports have X and Y coords in the same place */ - val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[1])); + val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[1]))); input_report_abs(inputdev, ABS_X, val); - val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[3])); + val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[3]))); input_report_abs(inputdev, ABS_Y, val); + /* Ditto for proximity bit */ - val = device->buffer[5] & MASK_INRANGE ? 1 : 0; + if (device->buffer[5]& MASK_INRANGE){ + val = 1; + }else{ + val=0; + } input_report_abs(inputdev, ABS_DISTANCE, val); + /* Report 1 is an exception to how we handle buttons */ /* Buttons are an index, not a bitmask */ - if (device->buffer[0] == 1) { + if (device->buffer[0] == 1){ - /* - * Convert buttons, 5 bit index - * Report value of index set as one, - * the rest as 0 - */ - val = device->buffer[5] & MASK_BUTTON; + /* Convert buttons, 5 bit index */ + /* Report value of index set as one, + the rest as 0 */ + val = device->buffer[5]& MASK_BUTTON; dbg("======>>>>>>REPORT 1: val 0x%X(%d)", - val, val); + val,val); /* * We don't apply any meaning to the button * index, just report it */ input_event(inputdev, EV_MSC, MSC_SERIAL, val); + + } - break; + break; case 7: /* Menu blocks */ input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]); + + break; + } - } + + } /* Other pid class */ - if (inputdev->id.product == PID_400 || - inputdev->id.product == PID_401) { + if ((inputdev->id.product == PID_400 )|| + (inputdev->id.product == PID_401 )) + { /* Report 2 */ - if (device->buffer[0] == 2) { + if (device->buffer[0] == 2){ /* Menu blocks */ - input_event(inputdev, EV_MSC, MSC_SCAN, device->buffer[1]); + input_event(inputdev, EV_MSC, MSC_SCAN, + device->buffer[1]); } /* Report 1 */ - if (device->buffer[0] == 1) { + if (device->buffer[0] == 1){ char buttonbyte; + /* IF X max > 64K, we still a bit from the y report */ - if (device->max_X > 0x10000) { + if (device->max_X > 0x10000){ - val = (u16)(((u16)(device->buffer[2] << 8)) | (u8)device->buffer[1]); - val |= (u32)(((u8)device->buffer[3] & 0x1) << 16); + val = (u16)(((u16)(device->buffer[2]<<8))|((u8)(device->buffer[1]))); + val |= (u32)(((u8)device->buffer[3]&0x1)<< 16); input_report_abs(inputdev, ABS_X, val); - le_buffer[0] = (u8)((u8)(device->buffer[3]) >> 1); - le_buffer[0] |= (u8)((device->buffer[3] & 0x1) << 7); + le_buffer[0] = (u8)((u8)(device->buffer[3])>>1); + le_buffer[0] |= (u8)((device->buffer[3]&0x1)<<7); + + le_buffer[1] = (u8)(device->buffer[4]>>1); + le_buffer[1] |= (u8)((device->buffer[5]&0x1)<<7); - le_buffer[1] = (u8)(device->buffer[4] >> 1); - le_buffer[1] |= (u8)((device->buffer[5] & 0x1) << 7); + val = le16_to_cpu(get_unaligned((__le16 *)(le_buffer))); - val = le16_to_cpu(get_unaligned((__le16 *)le_buffer)); input_report_abs(inputdev, ABS_Y, val); + /* * Shift the button byte right by one to * make it look like the standard report */ - buttonbyte = device->buffer[5] >> 1; - } else { + buttonbyte = (device->buffer[5])>>1; + }else{ - val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[1])); + val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[1])))); input_report_abs(inputdev, ABS_X, val); - val = le16_to_cpu(get_unaligned((__le16 *)&device->buffer[3])); + val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[3])))); input_report_abs(inputdev, ABS_Y, val); buttonbyte = device->buffer[5]; + } + /* BUTTONS and PROXIMITY */ - val = buttonbyte & MASK_INRANGE ? 1 : 0; + if (buttonbyte& MASK_INRANGE){ + val = 1; + }else{ + val=0; + } input_report_abs(inputdev, ABS_DISTANCE, val); /* Convert buttons, only 4 bits possible */ - val = buttonbyte & 0x0F; + val = buttonbyte&0x0F; #ifdef USE_BUTTONS - for (i = 0; i < 5; i++) - input_report_key(inputdev, BTN_DIGI + i, val & (1 << i)); + for ( i=0;i<5;i++){ + input_report_key(inputdev, BTN_DIGI+i,val&(1<buffer[6]); + } } @@ -806,8 +833,10 @@ static void gtco_urb_callback(struct urb *urbinfo) resubmit: rc = usb_submit_urb(urbinfo, GFP_ATOMIC); - if (rc != 0) - err("usb_submit_urb failed rc=0x%x", rc); + if (rc != 0) { + err("usb_submit_urb failed rc=0x%x",rc); + } + } /* @@ -825,46 +854,58 @@ static int gtco_probe(struct usb_interface *usbinterface, const struct usb_device_id *id) { - struct gtco *gtco; - struct input_dev *input_dev; + struct gtco *device = NULL; + char path[PATHLENGTH]; + struct input_dev *inputdev; struct hid_descriptor *hid_desc; - char *report = NULL; - int result = 0, retry; - int error; + char *report; + int result=0, retry; struct usb_endpoint_descriptor *endpoint; /* Allocate memory for device structure */ - gtco = kzalloc(sizeof(struct gtco), GFP_KERNEL); - input_dev = input_allocate_device(); - if (!gtco || !input_dev) { + device = kzalloc(sizeof(struct gtco), GFP_KERNEL); + if (device == NULL) { err("No more memory"); - error = -ENOMEM; - goto err_free_devs; + return -ENOMEM; } - /* Set pointer to the input device */ - gtco->inputdevice = input_dev; + + device->inputdevice = input_allocate_device(); + if (!device->inputdevice){ + kfree(device); + err("No more memory"); + return -ENOMEM; + } + + /* Get pointer to the input device */ + inputdev = device->inputdevice; /* Save interface information */ - gtco->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); + device->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); + /* Allocate some data for incoming reports */ - gtco->buffer = usb_buffer_alloc(gtco->usbdev, REPORT_MAX_SIZE, - GFP_KERNEL, >co->buf_dma); - if (!gtco->buffer) { - err("No more memory for us buffers"); - error = -ENOMEM; - goto err_free_devs; + device->buffer = usb_buffer_alloc(device->usbdev, REPORT_MAX_SIZE, + GFP_KERNEL, &(device->buf_dma)); + if (!device->buffer){ + input_free_device(device->inputdevice); + kfree(device); + err("No more memory"); + return -ENOMEM; } /* Allocate URB for reports */ - gtco->urbinfo = usb_alloc_urb(0, GFP_KERNEL); - if (!gtco->urbinfo) { - err("Failed to allocate URB"); + device->urbinfo = usb_alloc_urb(0, GFP_KERNEL); + if (!device->urbinfo) { + usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, + device->buffer, device->buf_dma); + input_free_device(device->inputdevice); + kfree(device); + err("No more memory"); return -ENOMEM; - goto err_free_buf; } + /* * The endpoint is always altsetting 0, we know this since we know * this device only has one interrupt endpoint @@ -872,43 +913,51 @@ static int gtco_probe(struct usb_interface *usbinterface, endpoint = &usbinterface->altsetting[0].endpoint[0].desc; /* Some debug */ - dbg("gtco # interfaces: %d", usbinterface->num_altsetting); - dbg("num endpoints: %d", usbinterface->cur_altsetting->desc.bNumEndpoints); - dbg("interface class: %d", usbinterface->cur_altsetting->desc.bInterfaceClass); - dbg("endpoint: attribute:0x%x type:0x%x", endpoint->bmAttributes, endpoint->bDescriptorType); + dbg("gtco # interfaces: %d",usbinterface->num_altsetting); + dbg("num endpoints: %d",usbinterface->cur_altsetting->desc.bNumEndpoints); + dbg("interface class: %d",usbinterface->cur_altsetting->desc.bInterfaceClass); + dbg("endpoint: attribute:0x%x type:0x%x",endpoint->bmAttributes,endpoint->bDescriptorType); if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) dbg("endpoint: we have interrupt endpoint\n"); - dbg("endpoint extra len:%d ", usbinterface->altsetting[0].extralen); + dbg("endpoint extra len:%d ",usbinterface->altsetting[0].extralen); + + /* * Find the HID descriptor so we can find out the size of the * HID report descriptor */ if (usb_get_extra_descriptor(usbinterface->cur_altsetting, - HID_DEVICE_TYPE, &hid_desc) != 0){ + HID_DEVICE_TYPE,&hid_desc) != 0){ err("Can't retrieve exta USB descriptor to get hid report descriptor length"); - error = -EIO; - goto err_free_urb; + usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, + device->buffer, device->buf_dma); + input_free_device(device->inputdevice); + kfree(device); + return -EIO; } dbg("Extra descriptor success: type:%d len:%d", hid_desc->bDescriptorType, hid_desc->wDescriptorLength); - report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); - if (!report) { - err("No more memory for report"); - error = -ENOMEM; - goto err_free_urb; + if (!(report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL))) { + usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, + device->buffer, device->buf_dma); + + input_free_device(device->inputdevice); + kfree(device); + err("No more memory"); + return -ENOMEM; } /* Couple of tries to get reply */ - for (retry = 0; retry < 3; retry++) { - result = usb_control_msg(gtco->usbdev, - usb_rcvctrlpipe(gtco->usbdev, 0), + for (retry=0;retry<3;retry++) { + result = usb_control_msg(device->usbdev, + usb_rcvctrlpipe(device->usbdev, 0), USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN, - REPORT_DEVICE_TYPE << 8, + (REPORT_DEVICE_TYPE << 8), 0, /* interface */ report, hid_desc->wDescriptorLength, @@ -920,76 +969,72 @@ static int gtco_probe(struct usb_interface *usbinterface, /* If we didn't get the report, fail */ dbg("usb_control_msg result: :%d", result); - if (result != hid_desc->wDescriptorLength) { + if (result != hid_desc->wDescriptorLength){ + kfree(report); + usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, + device->buffer, device->buf_dma); + input_free_device(device->inputdevice); + kfree(device); err("Failed to get HID Report Descriptor of size: %d", hid_desc->wDescriptorLength); - error = -EIO; - goto err_free_urb; + return -EIO; } + /* Now we parse the report */ - parse_hid_report_descriptor(gtco, report, result); + parse_hid_report_descriptor(device,report,result); /* Now we delete it */ kfree(report); /* Create a device file node */ - usb_make_path(gtco->usbdev, gtco->usbpath, sizeof(gtco->usbpath)); - strlcat(gtco->usbpath, "/input0", sizeof(gtco->usbpath)); + usb_make_path(device->usbdev, path, PATHLENGTH); + sprintf(device->usbpath, "%s/input0", path); + /* Set Input device functions */ - input_dev->open = gtco_input_open; - input_dev->close = gtco_input_close; + inputdev->open = gtco_input_open; + inputdev->close = gtco_input_close; /* Set input device information */ - input_dev->name = "GTCO_CalComp"; - input_dev->phys = gtco->usbpath; + inputdev->name = "GTCO_CalComp"; + inputdev->phys = device->usbpath; + inputdev->private = device; - input_set_drvdata(input_dev, gtco); /* Now set up all the input device capabilities */ - gtco_setup_caps(input_dev); + gtco_setup_caps(inputdev); /* Set input device required ID information */ - usb_to_input_id(gtco->usbdev, &input_dev->id); - input_dev->dev.parent = &usbinterface->dev; + usb_to_input_id(device->usbdev, &device->inputdevice->id); + inputdev->cdev.dev = &usbinterface->dev; /* Setup the URB, it will be posted later on open of input device */ endpoint = &usbinterface->altsetting[0].endpoint[0].desc; - usb_fill_int_urb(gtco->urbinfo, - gtco->usbdev, - usb_rcvintpipe(gtco->usbdev, + usb_fill_int_urb(device->urbinfo, + device->usbdev, + usb_rcvintpipe(device->usbdev, endpoint->bEndpointAddress), - gtco->buffer, + device->buffer, REPORT_MAX_SIZE, gtco_urb_callback, - gtco, + device, endpoint->bInterval); - gtco->urbinfo->transfer_dma = gtco->buf_dma; - gtco->urbinfo->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + device->urbinfo->transfer_dma = device->buf_dma; + device->urbinfo->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + - /* Save gtco pointer in USB interface gtco */ - usb_set_intfdata(usbinterface, gtco); + /* Save device pointer in USB interface device */ + usb_set_intfdata(usbinterface, device); /* All done, now register the input device */ - error = input_register_device(input_dev); - if (error) - goto err_free_urb; + input_register_device(inputdev); + info( "gtco driver created usb: %s\n", path); return 0; - err_free_urb: - usb_free_urb(gtco->urbinfo); - err_free_buf: - usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE, - gtco->buffer, gtco->buf_dma); - err_free_devs: - kfree(report); - input_free_device(input_dev); - kfree(gtco); - return error; } /* @@ -999,46 +1044,47 @@ static int gtco_probe(struct usb_interface *usbinterface, */ static void gtco_disconnect(struct usb_interface *interface) { + /* Grab private device ptr */ - struct gtco *gtco = usb_get_intfdata(interface); + struct gtco *device = usb_get_intfdata (interface); /* Now reverse all the registration stuff */ - if (gtco) { - input_unregister_device(gtco->inputdevice); - usb_kill_urb(gtco->urbinfo); - usb_free_urb(gtco->urbinfo); - usb_buffer_free(gtco->usbdev, REPORT_MAX_SIZE, - gtco->buffer, gtco->buf_dma); - kfree(gtco); + if (device) { + input_unregister_device(device->inputdevice); + usb_kill_urb(device->urbinfo); + usb_free_urb(device->urbinfo); + usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, + device->buffer, device->buf_dma); + kfree(device); } info("gtco driver disconnected"); } + /* STANDARD MODULE LOAD ROUTINES */ static struct usb_driver gtco_driverinfo_table = { - .name = "gtco", - .id_table = gtco_usbid_table, - .probe = gtco_probe, - .disconnect = gtco_disconnect, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) + .owner = THIS_MODULE, +#endif + .name = "gtco", + .id_table = gtco_usbid_table, + .probe = gtco_probe, + .disconnect = gtco_disconnect, }; - /* * Register this module with the USB subsystem */ static int __init gtco_init(void) { - int error; - - error = usb_register(>co_driverinfo_table); - if (error) { - err("usb_register() failed rc=0x%x", error); - return error; + int rc; + rc = usb_register(>co_driverinfo_table); + if (rc) { + err("usb_register() failed rc=0x%x", rc); } - - printk("GTCO usb driver version: %s", GTCO_VERSION); - return 0; + printk("GTCO usb driver version: %s",GTCO_VERSION); + return rc; } /* @@ -1049,7 +1095,7 @@ static void __exit gtco_exit(void) usb_deregister(>co_driverinfo_table); } -module_init(gtco_init); -module_exit(gtco_exit); +module_init (gtco_init); +module_exit (gtco_exit); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/input/itmtouch.c b/trunk/drivers/usb/input/itmtouch.c new file mode 100644 index 000000000000..aac968aab860 --- /dev/null +++ b/trunk/drivers/usb/input/itmtouch.c @@ -0,0 +1,271 @@ +/****************************************************************************** + * itmtouch.c -- Driver for ITM touchscreen panel + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based upon original work by Chris Collins . + * + * Kudos to ITM for providing me with the datasheet for the panel, + * even though it was a day later than I had finished writing this + * driver. + * + * It has meant that I've been able to correct my interpretation of the + * protocol packets however. + * + * CC -- 2003/9/29 + * + * History + * 1.0 & 1.1 2003 (CC) vojtech@suse.cz + * Original version for 2.4.x kernels + * + * 1.2 02/03/2005 (HCE) hc@mivu.no + * Complete rewrite to support Linux 2.6.10, thanks to mtouchusb.c for hints. + * Unfortunately no calibration support at this time. + * + * 1.2.1 09/03/2005 (HCE) hc@mivu.no + * Code cleanup and adjusting syntax to start matching kernel standards + * + * 1.2.2 10/05/2006 (MJA) massad@gmail.com + * Flag for detecting if the screen was being touch was incorrectly + * inverted, so no touch events were being detected. + * + *****************************************************************************/ + +#include +#include +#include +#include +#include + +/* only an 8 byte buffer necessary for a single packet */ +#define ITM_BUFSIZE 8 +#define PATH_SIZE 64 + +#define USB_VENDOR_ID_ITMINC 0x0403 +#define USB_PRODUCT_ID_TOUCHPANEL 0xf9e9 + +#define DRIVER_AUTHOR "Hans-Christian Egtvedt " +#define DRIVER_VERSION "v1.2.2" +#define DRIVER_DESC "USB ITM Inc Touch Panel Driver" +#define DRIVER_LICENSE "GPL" + +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_LICENSE( DRIVER_LICENSE ); + +struct itmtouch_dev { + struct usb_device *usbdev; /* usb device */ + struct input_dev *inputdev; /* input device */ + struct urb *readurb; /* urb */ + char rbuf[ITM_BUFSIZE]; /* data */ + int users; + char name[128]; + char phys[64]; +}; + +static struct usb_device_id itmtouch_ids [] = { + { USB_DEVICE(USB_VENDOR_ID_ITMINC, USB_PRODUCT_ID_TOUCHPANEL) }, + { } +}; + +static void itmtouch_irq(struct urb *urb) +{ + struct itmtouch_dev *itmtouch = urb->context; + unsigned char *data = urb->transfer_buffer; + struct input_dev *dev = itmtouch->inputdev; + int retval; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ETIME: + /* this urb is timing out */ + dbg("%s - urb timed out - was the device unplugged?", + __FUNCTION__); + return; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", + __FUNCTION__, urb->status); + goto exit; + } + + /* if pressure has been released, then don't report X/Y */ + if (!(data[7] & 0x20)) { + input_report_abs(dev, ABS_X, (data[0] & 0x1F) << 7 | (data[3] & 0x7F)); + input_report_abs(dev, ABS_Y, (data[1] & 0x1F) << 7 | (data[4] & 0x7F)); + } + + input_report_abs(dev, ABS_PRESSURE, (data[2] & 1) << 7 | (data[5] & 0x7F)); + input_report_key(dev, BTN_TOUCH, ~data[7] & 0x20); + input_sync(dev); + +exit: + retval = usb_submit_urb (urb, GFP_ATOMIC); + if (retval) + printk(KERN_ERR "%s - usb_submit_urb failed with result: %d", + __FUNCTION__, retval); +} + +static int itmtouch_open(struct input_dev *input) +{ + struct itmtouch_dev *itmtouch = input->private; + + itmtouch->readurb->dev = itmtouch->usbdev; + + if (usb_submit_urb(itmtouch->readurb, GFP_KERNEL)) + return -EIO; + + return 0; +} + +static void itmtouch_close(struct input_dev *input) +{ + struct itmtouch_dev *itmtouch = input->private; + + usb_kill_urb(itmtouch->readurb); +} + +static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct itmtouch_dev *itmtouch; + struct input_dev *input_dev; + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + struct usb_device *udev = interface_to_usbdev(intf); + unsigned int pipe; + unsigned int maxp; + + interface = intf->cur_altsetting; + endpoint = &interface->endpoint[0].desc; + + itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!itmtouch || !input_dev) { + err("%s - Out of memory.", __FUNCTION__); + goto fail; + } + + itmtouch->usbdev = udev; + itmtouch->inputdev = input_dev; + + if (udev->manufacturer) + strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(itmtouch->name, " ", sizeof(itmtouch->name)); + strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name)); + } + + if (!strlen(itmtouch->name)) + sprintf(itmtouch->name, "USB ITM touchscreen"); + + usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys)); + strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys)); + + input_dev->name = itmtouch->name; + input_dev->phys = itmtouch->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = itmtouch; + + input_dev->open = itmtouch_open; + input_dev->close = itmtouch_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + + /* device limits */ + /* as specified by the ITM datasheet, X and Y are 12bit, + * Z (pressure) is 8 bit. However, the fields are defined up + * to 14 bits for future possible expansion. + */ + input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0); + input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0); + + /* initialise the URB so we can read from the transport stream */ + pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress); + maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); + + if (maxp > ITM_BUFSIZE) + maxp = ITM_BUFSIZE; + + itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL); + if (!itmtouch->readurb) { + dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__); + goto fail; + } + + usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf, + maxp, itmtouch_irq, itmtouch, endpoint->bInterval); + + input_register_device(itmtouch->inputdev); + + usb_set_intfdata(intf, itmtouch); + + return 0; + + fail: input_free_device(input_dev); + kfree(itmtouch); + return -ENOMEM; +} + +static void itmtouch_disconnect(struct usb_interface *intf) +{ + struct itmtouch_dev *itmtouch = usb_get_intfdata(intf); + + usb_set_intfdata(intf, NULL); + + if (itmtouch) { + input_unregister_device(itmtouch->inputdev); + usb_kill_urb(itmtouch->readurb); + usb_free_urb(itmtouch->readurb); + kfree(itmtouch); + } +} + +MODULE_DEVICE_TABLE(usb, itmtouch_ids); + +static struct usb_driver itmtouch_driver = { + .name = "itmtouch", + .probe = itmtouch_probe, + .disconnect = itmtouch_disconnect, + .id_table = itmtouch_ids, +}; + +static int __init itmtouch_init(void) +{ + info(DRIVER_DESC " " DRIVER_VERSION); + info(DRIVER_AUTHOR); + return usb_register(&itmtouch_driver); +} + +static void __exit itmtouch_exit(void) +{ + usb_deregister(&itmtouch_driver); +} + +module_init(itmtouch_init); +module_exit(itmtouch_exit); diff --git a/trunk/drivers/input/tablet/kbtab.c b/trunk/drivers/usb/input/kbtab.c similarity index 92% rename from trunk/drivers/input/tablet/kbtab.c rename to trunk/drivers/usb/input/kbtab.c index 91e6d00d4a43..fedbcb127c21 100644 --- a/trunk/drivers/input/tablet/kbtab.c +++ b/trunk/drivers/usb/input/kbtab.c @@ -29,7 +29,7 @@ module_param(kb_pressure_click, int, 0); MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks"); struct kbtab { - unsigned char *data; + signed char *data; dma_addr_t data_dma; struct input_dev *dev; struct usb_device *usbdev; @@ -100,7 +100,7 @@ MODULE_DEVICE_TABLE(usb, kbtab_ids); static int kbtab_open(struct input_dev *dev) { - struct kbtab *kbtab = input_get_drvdata(dev); + struct kbtab *kbtab = dev->private; kbtab->irq->dev = kbtab->usbdev; if (usb_submit_urb(kbtab->irq, GFP_KERNEL)) @@ -111,7 +111,7 @@ static int kbtab_open(struct input_dev *dev) static void kbtab_close(struct input_dev *dev) { - struct kbtab *kbtab = input_get_drvdata(dev); + struct kbtab *kbtab = dev->private; usb_kill_urb(kbtab->irq); } @@ -122,7 +122,6 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_endpoint_descriptor *endpoint; struct kbtab *kbtab; struct input_dev *input_dev; - int error = -ENOMEM; kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL); input_dev = input_allocate_device(); @@ -146,9 +145,8 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i input_dev->name = "KB Gear Tablet"; input_dev->phys = kbtab->phys; usb_to_input_id(dev, &input_dev->id); - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, kbtab); + input_dev->cdev.dev = &intf->dev; + input_dev->private = kbtab; input_dev->open = kbtab_open; input_dev->close = kbtab_close; @@ -170,19 +168,15 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i kbtab->irq->transfer_dma = kbtab->data_dma; kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - error = input_register_device(kbtab->dev); - if (error) - goto fail3; + input_register_device(kbtab->dev); usb_set_intfdata(intf, kbtab); - return 0; - fail3: usb_free_urb(kbtab->irq); - fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); - fail1: input_free_device(input_dev); +fail2: usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma); +fail1: input_free_device(input_dev); kfree(kbtab); - return error; + return -ENOMEM; } static void kbtab_disconnect(struct usb_interface *intf) diff --git a/trunk/drivers/input/misc/keyspan_remote.c b/trunk/drivers/usb/input/keyspan_remote.c similarity index 97% rename from trunk/drivers/input/misc/keyspan_remote.c rename to trunk/drivers/usb/input/keyspan_remote.c index 1bffc9fa98c2..98bd323369c7 100644 --- a/trunk/drivers/input/misc/keyspan_remote.c +++ b/trunk/drivers/usb/input/keyspan_remote.c @@ -394,7 +394,7 @@ static void keyspan_irq_recv(struct urb *urb) static int keyspan_open(struct input_dev *dev) { - struct usb_keyspan *remote = input_get_drvdata(dev); + struct usb_keyspan *remote = dev->private; remote->irq_urb->dev = remote->udev; if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) @@ -405,7 +405,7 @@ static int keyspan_open(struct input_dev *dev) static void keyspan_close(struct input_dev *dev) { - struct usb_keyspan *remote = input_get_drvdata(dev); + struct usb_keyspan *remote = dev->private; usb_kill_urb(remote->irq_urb); } @@ -437,7 +437,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic struct usb_endpoint_descriptor *endpoint; struct usb_keyspan *remote; struct input_dev *input_dev; - int i, error; + int i, retval; endpoint = keyspan_get_in_endpoint(interface->cur_altsetting); if (!endpoint) @@ -446,7 +446,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic remote = kzalloc(sizeof(*remote), GFP_KERNEL); input_dev = input_allocate_device(); if (!remote || !input_dev) { - error = -ENOMEM; + retval = -ENOMEM; goto fail1; } @@ -458,19 +458,19 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, GFP_ATOMIC, &remote->in_dma); if (!remote->in_buffer) { - error = -ENOMEM; + retval = -ENOMEM; goto fail1; } remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); if (!remote->irq_urb) { - error = -ENOMEM; + retval = -ENOMEM; goto fail2; } - error = keyspan_setup(udev); - if (error) { - error = -ENODEV; + retval = keyspan_setup(udev); + if (retval) { + retval = -ENODEV; goto fail3; } @@ -495,15 +495,14 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic input_dev->name = remote->name; input_dev->phys = remote->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->dev.parent = &interface->dev; + input_dev->cdev.dev = &interface->dev; input_dev->evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */ for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++) if (keyspan_key_table[i] != KEY_RESERVED) set_bit(keyspan_key_table[i], input_dev->keybit); - input_set_drvdata(input_dev, remote); - + input_dev->private = remote; input_dev->open = keyspan_open; input_dev->close = keyspan_close; @@ -518,9 +517,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* we can register the device now, as it is ready */ - error = input_register_device(remote->input); - if (error) - goto fail3; + input_register_device(remote->input); /* save our data pointer in this interface device */ usb_set_intfdata(interface, remote); @@ -532,7 +529,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic fail1: kfree(remote); input_free_device(input_dev); - return error; + return retval; } /* diff --git a/trunk/drivers/input/misc/map_to_7segment.h b/trunk/drivers/usb/input/map_to_7segment.h similarity index 100% rename from trunk/drivers/input/misc/map_to_7segment.h rename to trunk/drivers/usb/input/map_to_7segment.h diff --git a/trunk/drivers/usb/input/mtouchusb.c b/trunk/drivers/usb/input/mtouchusb.c new file mode 100644 index 000000000000..92c4e07da4c8 --- /dev/null +++ b/trunk/drivers/usb/input/mtouchusb.c @@ -0,0 +1,332 @@ +/****************************************************************************** + * mtouchusb.c -- Driver for Microtouch (Now 3M) USB Touchscreens + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based upon original work by Radoslaw Garbacz (usb-support@ite.pl) + * (http://freshmeat.net/projects/3mtouchscreendriver) + * + * History + * + * 0.3 & 0.4 2002 (TEJ) tejohnson@yahoo.com + * Updated to 2.4.18, then 2.4.19 + * Old version still relied on stealing a minor + * + * 0.5 02/26/2004 (TEJ) tejohnson@yahoo.com + * Complete rewrite using Linux Input in 2.6.3 + * Unfortunately no calibration support at this time + * + * 1.4 04/25/2004 (TEJ) tejohnson@yahoo.com + * Changed reset from standard USB dev reset to vendor reset + * Changed data sent to host from compensated to raw coordinates + * Eliminated vendor/product module params + * Performed multiple successful tests with an EXII-5010UC + * + * 1.5 02/27/2005 ddstreet@ieee.org + * Added module parameter to select raw or hw-calibrated coordinate reporting + * + *****************************************************************************/ + +#include +#include +#include +#include +#include + +#define MTOUCHUSB_MIN_XC 0x0 +#define MTOUCHUSB_MAX_RAW_XC 0x4000 +#define MTOUCHUSB_MAX_CALIB_XC 0xffff +#define MTOUCHUSB_XC_FUZZ 0x0 +#define MTOUCHUSB_XC_FLAT 0x0 +#define MTOUCHUSB_MIN_YC 0x0 +#define MTOUCHUSB_MAX_RAW_YC 0x4000 +#define MTOUCHUSB_MAX_CALIB_YC 0xffff +#define MTOUCHUSB_YC_FUZZ 0x0 +#define MTOUCHUSB_YC_FLAT 0x0 + +#define MTOUCHUSB_ASYNC_REPORT 1 +#define MTOUCHUSB_RESET 7 +#define MTOUCHUSB_REPORT_DATA_SIZE 11 +#define MTOUCHUSB_REQ_CTRLLR_ID 10 + +#define MTOUCHUSB_GET_RAW_XC(data) (data[8]<<8 | data[7]) +#define MTOUCHUSB_GET_CALIB_XC(data) (data[4]<<8 | data[3]) +#define MTOUCHUSB_GET_RAW_YC(data) (data[10]<<8 | data[9]) +#define MTOUCHUSB_GET_CALIB_YC(data) (data[6]<<8 | data[5]) +#define MTOUCHUSB_GET_XC(data) (raw_coordinates ? \ + MTOUCHUSB_GET_RAW_XC(data) : \ + MTOUCHUSB_GET_CALIB_XC(data)) +#define MTOUCHUSB_GET_YC(data) (raw_coordinates ? \ + MTOUCHUSB_GET_RAW_YC(data) : \ + MTOUCHUSB_GET_CALIB_YC(data)) +#define MTOUCHUSB_GET_TOUCHED(data) ((data[2] & 0x40) ? 1:0) + +#define DRIVER_VERSION "v1.5" +#define DRIVER_AUTHOR "Todd E. Johnson, tejohnson@yahoo.com" +#define DRIVER_DESC "3M USB Touchscreen Driver" +#define DRIVER_LICENSE "GPL" + +static int raw_coordinates = 1; + +module_param(raw_coordinates, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(raw_coordinates, "report raw coordinate values (y, default) or hardware-calibrated coordinate values (n)"); + +struct mtouch_usb { + unsigned char *data; + dma_addr_t data_dma; + struct urb *irq; + struct usb_device *udev; + struct input_dev *input; + char name[128]; + char phys[64]; +}; + +static struct usb_device_id mtouchusb_devices[] = { + { USB_DEVICE(0x0596, 0x0001) }, + { } +}; + +static void mtouchusb_irq(struct urb *urb) +{ + struct mtouch_usb *mtouch = urb->context; + int retval; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ETIME: + /* this urb is timing out */ + dbg("%s - urb timed out - was the device unplugged?", + __FUNCTION__); + return; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", + __FUNCTION__, urb->status); + goto exit; + } + + input_report_key(mtouch->input, BTN_TOUCH, + MTOUCHUSB_GET_TOUCHED(mtouch->data)); + input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data)); + input_report_abs(mtouch->input, ABS_Y, + (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC) + - MTOUCHUSB_GET_YC(mtouch->data)); + input_sync(mtouch->input); + +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + err("%s - usb_submit_urb failed with result: %d", + __FUNCTION__, retval); +} + +static int mtouchusb_open(struct input_dev *input) +{ + struct mtouch_usb *mtouch = input->private; + + mtouch->irq->dev = mtouch->udev; + + if (usb_submit_urb(mtouch->irq, GFP_ATOMIC)) + return -EIO; + + return 0; +} + +static void mtouchusb_close(struct input_dev *input) +{ + struct mtouch_usb *mtouch = input->private; + + usb_kill_urb(mtouch->irq); +} + +static int mtouchusb_alloc_buffers(struct usb_device *udev, struct mtouch_usb *mtouch) +{ + dbg("%s - called", __FUNCTION__); + + mtouch->data = usb_buffer_alloc(udev, MTOUCHUSB_REPORT_DATA_SIZE, + GFP_ATOMIC, &mtouch->data_dma); + + if (!mtouch->data) + return -1; + + return 0; +} + +static void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *mtouch) +{ + dbg("%s - called", __FUNCTION__); + + if (mtouch->data) + usb_buffer_free(udev, MTOUCHUSB_REPORT_DATA_SIZE, + mtouch->data, mtouch->data_dma); +} + +static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct mtouch_usb *mtouch; + struct input_dev *input_dev; + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + struct usb_device *udev = interface_to_usbdev(intf); + int nRet; + + dbg("%s - called", __FUNCTION__); + + dbg("%s - setting interface", __FUNCTION__); + interface = intf->cur_altsetting; + + dbg("%s - setting endpoint", __FUNCTION__); + endpoint = &interface->endpoint[0].desc; + + mtouch = kzalloc(sizeof(struct mtouch_usb), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!mtouch || !input_dev) { + err("%s - Out of memory.", __FUNCTION__); + goto fail1; + } + + dbg("%s - allocating buffers", __FUNCTION__); + if (mtouchusb_alloc_buffers(udev, mtouch)) + goto fail2; + + mtouch->udev = udev; + mtouch->input = input_dev; + + if (udev->manufacturer) + strlcpy(mtouch->name, udev->manufacturer, sizeof(mtouch->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(mtouch->name, " ", sizeof(mtouch->name)); + strlcat(mtouch->name, udev->product, sizeof(mtouch->name)); + } + + if (!strlen(mtouch->name)) + snprintf(mtouch->name, sizeof(mtouch->name), + "USB Touchscreen %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + usb_make_path(udev, mtouch->phys, sizeof(mtouch->phys)); + strlcpy(mtouch->phys, "/input0", sizeof(mtouch->phys)); + + input_dev->name = mtouch->name; + input_dev->phys = mtouch->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = mtouch; + + input_dev->open = mtouchusb_open; + input_dev->close = mtouchusb_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, MTOUCHUSB_MIN_XC, + raw_coordinates ? MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC, + MTOUCHUSB_XC_FUZZ, MTOUCHUSB_XC_FLAT); + input_set_abs_params(input_dev, ABS_Y, MTOUCHUSB_MIN_YC, + raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC, + MTOUCHUSB_YC_FUZZ, MTOUCHUSB_YC_FLAT); + + nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), + MTOUCHUSB_RESET, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); + dbg("%s - usb_control_msg - MTOUCHUSB_RESET - bytes|err: %d", + __FUNCTION__, nRet); + + dbg("%s - usb_alloc_urb: mtouch->irq", __FUNCTION__); + mtouch->irq = usb_alloc_urb(0, GFP_KERNEL); + if (!mtouch->irq) { + dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__); + goto fail2; + } + + dbg("%s - usb_fill_int_urb", __FUNCTION__); + usb_fill_int_urb(mtouch->irq, mtouch->udev, + usb_rcvintpipe(mtouch->udev, 0x81), + mtouch->data, MTOUCHUSB_REPORT_DATA_SIZE, + mtouchusb_irq, mtouch, endpoint->bInterval); + + dbg("%s - input_register_device", __FUNCTION__); + input_register_device(mtouch->input); + + nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0), + MTOUCHUSB_ASYNC_REPORT, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); + dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d", + __FUNCTION__, nRet); + + usb_set_intfdata(intf, mtouch); + return 0; + +fail2: mtouchusb_free_buffers(udev, mtouch); +fail1: input_free_device(input_dev); + kfree(mtouch); + return -ENOMEM; +} + +static void mtouchusb_disconnect(struct usb_interface *intf) +{ + struct mtouch_usb *mtouch = usb_get_intfdata(intf); + + dbg("%s - called", __FUNCTION__); + usb_set_intfdata(intf, NULL); + if (mtouch) { + dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__); + usb_kill_urb(mtouch->irq); + input_unregister_device(mtouch->input); + usb_free_urb(mtouch->irq); + mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch); + kfree(mtouch); + } +} + +MODULE_DEVICE_TABLE(usb, mtouchusb_devices); + +static struct usb_driver mtouchusb_driver = { + .name = "mtouchusb", + .probe = mtouchusb_probe, + .disconnect = mtouchusb_disconnect, + .id_table = mtouchusb_devices, +}; + +static int __init mtouchusb_init(void) +{ + dbg("%s - called", __FUNCTION__); + return usb_register(&mtouchusb_driver); +} + +static void __exit mtouchusb_cleanup(void) +{ + dbg("%s - called", __FUNCTION__); + usb_deregister(&mtouchusb_driver); +} + +module_init(mtouchusb_init); +module_exit(mtouchusb_cleanup); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/misc/powermate.c b/trunk/drivers/usb/input/powermate.c similarity index 96% rename from trunk/drivers/input/misc/powermate.c rename to trunk/drivers/usb/input/powermate.c index 448a470d28f2..fea97e5437f8 100644 --- a/trunk/drivers/input/misc/powermate.c +++ b/trunk/drivers/usb/input/powermate.c @@ -252,7 +252,7 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne static int powermate_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int _value) { unsigned int command = (unsigned int)_value; - struct powermate_device *pm = input_get_drvdata(dev); + struct powermate_device *pm = dev->private; if (type == EV_MSC && code == MSC_PULSELED){ /* @@ -291,10 +291,12 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev static void powermate_free_buffers(struct usb_device *udev, struct powermate_device *pm) { - usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX, - pm->data, pm->data_dma); - usb_buffer_free(udev, sizeof(*(pm->configcr)), - pm->configcr, pm->configcr_dma); + if (pm->data) + usb_buffer_free(udev, POWERMATE_PAYLOAD_SIZE_MAX, + pm->data, pm->data_dma); + if (pm->configcr) + usb_buffer_free(udev, sizeof(*(pm->configcr)), + pm->configcr, pm->configcr_dma); } /* Called whenever a USB device matching one in our supported devices table is connected */ @@ -306,7 +308,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i struct powermate_device *pm; struct input_dev *input_dev; int pipe, maxp; - int error = -ENOMEM; + int err = -ENOMEM; interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; @@ -357,9 +359,8 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i input_dev->phys = pm->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, pm); + input_dev->cdev.dev = &intf->dev; + input_dev->private = pm; input_dev->event = powermate_input_event; @@ -386,14 +387,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i /* register our interrupt URB with the USB system */ if (usb_submit_urb(pm->irq, GFP_KERNEL)) { - error = -EIO; + err = -EIO; goto fail4; } - error = input_register_device(pm->input); - if (error) - goto fail5; - + input_register_device(pm->input); /* force an update of everything */ pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS; @@ -402,13 +400,12 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i usb_set_intfdata(intf, pm); return 0; - fail5: usb_kill_urb(pm->irq); - fail4: usb_free_urb(pm->config); - fail3: usb_free_urb(pm->irq); - fail2: powermate_free_buffers(udev, pm); - fail1: input_free_device(input_dev); +fail4: usb_free_urb(pm->config); +fail3: usb_free_urb(pm->irq); +fail2: powermate_free_buffers(udev, pm); +fail1: input_free_device(input_dev); kfree(pm); - return error; + return err; } /* Called when a USB device we've accepted ownership of is removed */ diff --git a/trunk/drivers/usb/input/touchkitusb.c b/trunk/drivers/usb/input/touchkitusb.c new file mode 100644 index 000000000000..2a314b065922 --- /dev/null +++ b/trunk/drivers/usb/input/touchkitusb.c @@ -0,0 +1,392 @@ +/****************************************************************************** + * touchkitusb.c -- Driver for eGalax TouchKit USB Touchscreens + * + * Copyright (C) 2004-2005 by Daniel Ritz + * Copyright (C) by Todd E. Johnson (mtouchusb.c) + * + * 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Based upon mtouchusb.c + * + *****************************************************************************/ + +//#define DEBUG + +#include +#include +#include +#include +#include + +#define TOUCHKIT_MIN_XC 0x0 +#define TOUCHKIT_MAX_XC 0x07ff +#define TOUCHKIT_XC_FUZZ 0x0 +#define TOUCHKIT_XC_FLAT 0x0 +#define TOUCHKIT_MIN_YC 0x0 +#define TOUCHKIT_MAX_YC 0x07ff +#define TOUCHKIT_YC_FUZZ 0x0 +#define TOUCHKIT_YC_FLAT 0x0 +#define TOUCHKIT_REPORT_DATA_SIZE 16 + +#define TOUCHKIT_DOWN 0x01 + +#define TOUCHKIT_PKT_TYPE_MASK 0xFE +#define TOUCHKIT_PKT_TYPE_REPT 0x80 +#define TOUCHKIT_PKT_TYPE_DIAG 0x0A + +#define DRIVER_VERSION "v0.1" +#define DRIVER_AUTHOR "Daniel Ritz " +#define DRIVER_DESC "eGalax TouchKit USB HID Touchscreen Driver" + +static int swap_xy; +module_param(swap_xy, bool, 0644); +MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped."); + +struct touchkit_usb { + unsigned char *data; + dma_addr_t data_dma; + char buffer[TOUCHKIT_REPORT_DATA_SIZE]; + int buf_len; + struct urb *irq; + struct usb_device *udev; + struct input_dev *input; + char name[128]; + char phys[64]; +}; + +static struct usb_device_id touchkit_devices[] = { + {USB_DEVICE(0x3823, 0x0001)}, + {USB_DEVICE(0x0123, 0x0001)}, + {USB_DEVICE(0x0eef, 0x0001)}, + {USB_DEVICE(0x0eef, 0x0002)}, + {} +}; + +/* helpers to read the data */ +static inline int touchkit_get_touched(char *data) +{ + return (data[0] & TOUCHKIT_DOWN) ? 1 : 0; +} + +static inline int touchkit_get_x(char *data) +{ + return ((data[3] & 0x0F) << 7) | (data[4] & 0x7F); +} + +static inline int touchkit_get_y(char *data) +{ + return ((data[1] & 0x0F) << 7) | (data[2] & 0x7F); +} + + +/* processes one input packet. */ +static void touchkit_process_pkt(struct touchkit_usb *touchkit, char *pkt) +{ + int x, y; + + /* only process report packets */ + if ((pkt[0] & TOUCHKIT_PKT_TYPE_MASK) != TOUCHKIT_PKT_TYPE_REPT) + return; + + if (swap_xy) { + y = touchkit_get_x(pkt); + x = touchkit_get_y(pkt); + } else { + x = touchkit_get_x(pkt); + y = touchkit_get_y(pkt); + } + + input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt)); + input_report_abs(touchkit->input, ABS_X, x); + input_report_abs(touchkit->input, ABS_Y, y); + input_sync(touchkit->input); +} + + +static int touchkit_get_pkt_len(char *buf) +{ + switch (buf[0] & TOUCHKIT_PKT_TYPE_MASK) { + case TOUCHKIT_PKT_TYPE_REPT: + return 5; + + case TOUCHKIT_PKT_TYPE_DIAG: + return buf[1] + 2; + } + + return 0; +} + +static void touchkit_process(struct touchkit_usb *touchkit, int len) +{ + char *buffer; + int pkt_len, buf_len, pos; + + /* if the buffer contains data, append */ + if (unlikely(touchkit->buf_len)) { + int tmp; + + /* if only 1 byte in buffer, add another one to get length */ + if (touchkit->buf_len == 1) + touchkit->buffer[1] = touchkit->data[0]; + + pkt_len = touchkit_get_pkt_len(touchkit->buffer); + + /* unknown packet: drop everything */ + if (!pkt_len) + return; + + /* append, process */ + tmp = pkt_len - touchkit->buf_len; + memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp); + touchkit_process_pkt(touchkit, touchkit->buffer); + + buffer = touchkit->data + tmp; + buf_len = len - tmp; + } else { + buffer = touchkit->data; + buf_len = len; + } + + /* only one byte left in buffer */ + if (unlikely(buf_len == 1)) { + touchkit->buffer[0] = buffer[0]; + touchkit->buf_len = 1; + return; + } + + /* loop over the buffer */ + pos = 0; + while (pos < buf_len) { + /* get packet len */ + pkt_len = touchkit_get_pkt_len(buffer + pos); + + /* unknown packet: drop everything */ + if (unlikely(!pkt_len)) + return; + + /* full packet: process */ + if (likely(pkt_len <= buf_len)) { + touchkit_process_pkt(touchkit, buffer + pos); + } else { + /* incomplete packet: save in buffer */ + memcpy(touchkit->buffer, buffer + pos, buf_len - pos); + touchkit->buf_len = buf_len - pos; + } + pos += pkt_len; + } +} + + +static void touchkit_irq(struct urb *urb) +{ + struct touchkit_usb *touchkit = urb->context; + int retval; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ETIME: + /* this urb is timing out */ + dbg("%s - urb timed out - was the device unplugged?", + __FUNCTION__); + return; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", + __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", + __FUNCTION__, urb->status); + goto exit; + } + + touchkit_process(touchkit, urb->actual_length); + +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + err("%s - usb_submit_urb failed with result: %d", + __FUNCTION__, retval); +} + +static int touchkit_open(struct input_dev *input) +{ + struct touchkit_usb *touchkit = input->private; + + touchkit->irq->dev = touchkit->udev; + + if (usb_submit_urb(touchkit->irq, GFP_ATOMIC)) + return -EIO; + + return 0; +} + +static void touchkit_close(struct input_dev *input) +{ + struct touchkit_usb *touchkit = input->private; + + usb_kill_urb(touchkit->irq); +} + +static int touchkit_alloc_buffers(struct usb_device *udev, + struct touchkit_usb *touchkit) +{ + touchkit->data = usb_buffer_alloc(udev, TOUCHKIT_REPORT_DATA_SIZE, + GFP_ATOMIC, &touchkit->data_dma); + + if (!touchkit->data) + return -1; + + return 0; +} + +static void touchkit_free_buffers(struct usb_device *udev, + struct touchkit_usb *touchkit) +{ + if (touchkit->data) + usb_buffer_free(udev, TOUCHKIT_REPORT_DATA_SIZE, + touchkit->data, touchkit->data_dma); +} + +static int touchkit_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct touchkit_usb *touchkit; + struct input_dev *input_dev; + struct usb_host_interface *interface; + struct usb_endpoint_descriptor *endpoint; + struct usb_device *udev = interface_to_usbdev(intf); + + interface = intf->cur_altsetting; + endpoint = &interface->endpoint[0].desc; + + touchkit = kzalloc(sizeof(struct touchkit_usb), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!touchkit || !input_dev) + goto out_free; + + if (touchkit_alloc_buffers(udev, touchkit)) + goto out_free; + + touchkit->irq = usb_alloc_urb(0, GFP_KERNEL); + if (!touchkit->irq) { + dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__); + goto out_free_buffers; + } + + touchkit->udev = udev; + touchkit->input = input_dev; + + if (udev->manufacturer) + strlcpy(touchkit->name, udev->manufacturer, sizeof(touchkit->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(touchkit->name, " ", sizeof(touchkit->name)); + strlcat(touchkit->name, udev->product, sizeof(touchkit->name)); + } + + if (!strlen(touchkit->name)) + snprintf(touchkit->name, sizeof(touchkit->name), + "USB Touchscreen %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + usb_make_path(udev, touchkit->phys, sizeof(touchkit->phys)); + strlcpy(touchkit->phys, "/input0", sizeof(touchkit->phys)); + + input_dev->name = touchkit->name; + input_dev->phys = touchkit->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &intf->dev; + input_dev->private = touchkit; + input_dev->open = touchkit_open; + input_dev->close = touchkit_close; + + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_set_abs_params(input_dev, ABS_X, TOUCHKIT_MIN_XC, TOUCHKIT_MAX_XC, + TOUCHKIT_XC_FUZZ, TOUCHKIT_XC_FLAT); + input_set_abs_params(input_dev, ABS_Y, TOUCHKIT_MIN_YC, TOUCHKIT_MAX_YC, + TOUCHKIT_YC_FUZZ, TOUCHKIT_YC_FLAT); + + usb_fill_int_urb(touchkit->irq, touchkit->udev, + usb_rcvintpipe(touchkit->udev, 0x81), + touchkit->data, TOUCHKIT_REPORT_DATA_SIZE, + touchkit_irq, touchkit, endpoint->bInterval); + + touchkit->irq->transfer_dma = touchkit->data_dma; + touchkit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + input_register_device(touchkit->input); + + usb_set_intfdata(intf, touchkit); + return 0; + +out_free_buffers: + touchkit_free_buffers(udev, touchkit); +out_free: + input_free_device(input_dev); + kfree(touchkit); + return -ENOMEM; +} + +static void touchkit_disconnect(struct usb_interface *intf) +{ + struct touchkit_usb *touchkit = usb_get_intfdata(intf); + + dbg("%s - called", __FUNCTION__); + + if (!touchkit) + return; + + dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__); + usb_set_intfdata(intf, NULL); + usb_kill_urb(touchkit->irq); + input_unregister_device(touchkit->input); + usb_free_urb(touchkit->irq); + touchkit_free_buffers(interface_to_usbdev(intf), touchkit); + kfree(touchkit); +} + +MODULE_DEVICE_TABLE(usb, touchkit_devices); + +static struct usb_driver touchkit_driver = { + .name = "touchkitusb", + .probe = touchkit_probe, + .disconnect = touchkit_disconnect, + .id_table = touchkit_devices, +}; + +static int __init touchkit_init(void) +{ + return usb_register(&touchkit_driver); +} + +static void __exit touchkit_cleanup(void) +{ + usb_deregister(&touchkit_driver); +} + +module_init(touchkit_init); +module_exit(touchkit_cleanup); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/input/touchscreen/usbtouchscreen.c b/trunk/drivers/usb/input/usbtouchscreen.c similarity index 98% rename from trunk/drivers/input/touchscreen/usbtouchscreen.c rename to trunk/drivers/usb/input/usbtouchscreen.c index 8e18e6c64777..86e37a20f8e5 100644 --- a/trunk/drivers/input/touchscreen/usbtouchscreen.c +++ b/trunk/drivers/usb/input/usbtouchscreen.c @@ -647,7 +647,7 @@ static void usbtouch_irq(struct urb *urb) static int usbtouch_open(struct input_dev *input) { - struct usbtouch_usb *usbtouch = input_get_drvdata(input); + struct usbtouch_usb *usbtouch = input->private; usbtouch->irq->dev = usbtouch->udev; @@ -659,7 +659,7 @@ static int usbtouch_open(struct input_dev *input) static void usbtouch_close(struct input_dev *input) { - struct usbtouch_usb *usbtouch = input_get_drvdata(input); + struct usbtouch_usb *usbtouch = input->private; usb_kill_urb(usbtouch->irq); } @@ -668,8 +668,9 @@ static void usbtouch_close(struct input_dev *input) static void usbtouch_free_buffers(struct usb_device *udev, struct usbtouch_usb *usbtouch) { - usb_buffer_free(udev, usbtouch->type->rept_size, - usbtouch->data, usbtouch->data_dma); + if (usbtouch->data) + usb_buffer_free(udev, usbtouch->type->rept_size, + usbtouch->data, usbtouch->data_dma); kfree(usbtouch->buffer); } @@ -739,10 +740,8 @@ static int usbtouch_probe(struct usb_interface *intf, input_dev->name = usbtouch->name; input_dev->phys = usbtouch->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, usbtouch); - + input_dev->cdev.dev = &intf->dev; + input_dev->private = usbtouch; input_dev->open = usbtouch_open; input_dev->close = usbtouch_close; diff --git a/trunk/drivers/input/tablet/wacom.h b/trunk/drivers/usb/input/wacom.h similarity index 99% rename from trunk/drivers/input/tablet/wacom.h rename to trunk/drivers/usb/input/wacom.h index ef01a807ec0f..d85abfc5ab58 100644 --- a/trunk/drivers/input/tablet/wacom.h +++ b/trunk/drivers/usb/input/wacom.h @@ -1,5 +1,5 @@ /* - * drivers/input/tablet/wacom.h + * drivers/usb/input/wacom.h * * USB Wacom Graphire and Wacom Intuos tablet support * diff --git a/trunk/drivers/input/tablet/wacom_sys.c b/trunk/drivers/usb/input/wacom_sys.c similarity index 95% rename from trunk/drivers/input/tablet/wacom_sys.c rename to trunk/drivers/usb/input/wacom_sys.c index 83bddef66067..12b42746ded8 100644 --- a/trunk/drivers/input/tablet/wacom_sys.c +++ b/trunk/drivers/usb/input/wacom_sys.c @@ -1,5 +1,5 @@ /* - * drivers/input/tablet/wacom_sys.c + * drivers/usb/input/wacom_sys.c * * USB Wacom Graphire and Wacom Intuos tablet support - system specific code */ @@ -122,7 +122,7 @@ void wacom_input_sync(void *wcombo) static int wacom_open(struct input_dev *dev) { - struct wacom *wacom = input_get_drvdata(dev); + struct wacom *wacom = dev->private; wacom->irq->dev = wacom->usbdev; if (usb_submit_urb(wacom->irq, GFP_KERNEL)) @@ -133,7 +133,7 @@ static int wacom_open(struct input_dev *dev) static void wacom_close(struct input_dev *dev) { - struct wacom *wacom = input_get_drvdata(dev); + struct wacom *wacom = dev->private; usb_kill_urb(wacom->irq); } @@ -201,7 +201,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i struct wacom *wacom; struct wacom_wac *wacom_wac; struct input_dev *input_dev; - int error = -ENOMEM; char rep_data[2], limit = 0; wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); @@ -230,10 +229,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->wacom_wac = wacom_wac; usb_to_input_id(dev, &input_dev->id); - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, wacom); - + input_dev->cdev.dev = &intf->dev; + input_dev->private = wacom; input_dev->open = wacom_open; input_dev->close = wacom_close; @@ -255,9 +252,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i wacom->irq->transfer_dma = wacom->data_dma; wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - error = input_register_device(wacom->dev); - if (error) - goto fail3; + input_register_device(wacom->dev); /* Ask the tablet to report tablet data. Repeat until it succeeds */ do { @@ -270,12 +265,11 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i usb_set_intfdata(intf, wacom); return 0; - fail3: usb_free_urb(wacom->irq); - fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); - fail1: input_free_device(input_dev); +fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); +fail1: input_free_device(input_dev); kfree(wacom); kfree(wacom_wac); - return error; + return -ENOMEM; } static void wacom_disconnect(struct usb_interface *intf) diff --git a/trunk/drivers/input/tablet/wacom_wac.c b/trunk/drivers/usb/input/wacom_wac.c similarity index 99% rename from trunk/drivers/input/tablet/wacom_wac.c rename to trunk/drivers/usb/input/wacom_wac.c index 7661f03a2db2..4f3e9bc7177d 100644 --- a/trunk/drivers/input/tablet/wacom_wac.c +++ b/trunk/drivers/usb/input/wacom_wac.c @@ -1,5 +1,5 @@ /* - * drivers/input/tablet/wacom_wac.c + * drivers/usb/input/wacom_wac.c * * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code * diff --git a/trunk/drivers/input/tablet/wacom_wac.h b/trunk/drivers/usb/input/wacom_wac.h similarity index 93% rename from trunk/drivers/input/tablet/wacom_wac.h rename to trunk/drivers/usb/input/wacom_wac.h index a5e12e8756de..a23022287248 100644 --- a/trunk/drivers/input/tablet/wacom_wac.h +++ b/trunk/drivers/usb/input/wacom_wac.h @@ -1,5 +1,5 @@ /* - * drivers/input/tablet/wacom_wac.h + * drivers/usb/input/wacom_wac.h * * 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 @@ -39,7 +39,7 @@ struct wacom_features { }; struct wacom_wac { - unsigned char *data; + signed char *data; int tool[2]; int id[2]; __u32 serial[2]; diff --git a/trunk/drivers/input/joystick/xpad.c b/trunk/drivers/usb/input/xpad.c similarity index 96% rename from trunk/drivers/input/joystick/xpad.c rename to trunk/drivers/usb/input/xpad.c index 8c8cd95a6989..e4bc76ebc835 100644 --- a/trunk/drivers/input/joystick/xpad.c +++ b/trunk/drivers/usb/input/xpad.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #define DRIVER_VERSION "v0.0.6" @@ -266,7 +267,7 @@ static void xpad_irq_in(struct urb *urb) static int xpad_open (struct input_dev *dev) { - struct usb_xpad *xpad = input_get_drvdata(dev); + struct usb_xpad *xpad = dev->private; xpad->irq_in->dev = xpad->udev; if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) @@ -277,7 +278,7 @@ static int xpad_open (struct input_dev *dev) static void xpad_close (struct input_dev *dev) { - struct usb_xpad *xpad = input_get_drvdata(dev); + struct usb_xpad *xpad = dev->private; usb_kill_urb(xpad->irq_in); } @@ -311,7 +312,6 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id struct input_dev *input_dev; struct usb_endpoint_descriptor *ep_irq_in; int i; - int error = -ENOMEM; for (i = 0; xpad_device[i].idVendor; i++) { if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) && @@ -344,10 +344,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id input_dev->name = xpad_device[i].name; input_dev->phys = xpad->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, xpad); - + input_dev->cdev.dev = &intf->dev; + input_dev->private = xpad; input_dev->open = xpad_open; input_dev->close = xpad_close; @@ -375,18 +373,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id xpad->irq_in->transfer_dma = xpad->idata_dma; xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - error = input_register_device(xpad->dev); - if (error) - goto fail3; + input_register_device(xpad->dev); usb_set_intfdata(intf, xpad); return 0; - fail3: usb_free_urb(xpad->irq_in); - fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); - fail1: input_free_device(input_dev); +fail2: usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma); +fail1: input_free_device(input_dev); kfree(xpad); - return error; + return -ENOMEM; } diff --git a/trunk/drivers/input/misc/yealink.c b/trunk/drivers/usb/input/yealink.c similarity index 97% rename from trunk/drivers/input/misc/yealink.c rename to trunk/drivers/usb/input/yealink.c index ab15880fd566..caff8e6d7448 100644 --- a/trunk/drivers/input/misc/yealink.c +++ b/trunk/drivers/usb/input/yealink.c @@ -29,7 +29,7 @@ * This driver is based on: * - the usbb2k-api http://savannah.nongnu.org/projects/usbb2k-api/ * - information from http://memeteau.free.fr/usbb2k - * - the xpad-driver drivers/input/joystick/xpad.c + * - the xpad-driver drivers/usb/input/xpad.c * * Thanks to: * - Olivier Vandorpe, for providing the usbb2k-api. @@ -502,7 +502,7 @@ static int input_ev(struct input_dev *dev, unsigned int type, static int input_open(struct input_dev *dev) { - struct yealink_dev *yld = input_get_drvdata(dev); + struct yealink_dev *yld = dev->private; int i, ret; dbg("%s", __FUNCTION__); @@ -529,7 +529,7 @@ static int input_open(struct input_dev *dev) static void input_close(struct input_dev *dev) { - struct yealink_dev *yld = input_get_drvdata(dev); + struct yealink_dev *yld = dev->private; usb_kill_urb(yld->urb_ctl); usb_kill_urb(yld->urb_irq); @@ -818,17 +818,18 @@ static int usb_cleanup(struct yealink_dev *yld, int err) else input_unregister_device(yld->idev); } - - usb_free_urb(yld->urb_irq); - usb_free_urb(yld->urb_ctl); - - usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)), - yld->ctl_req, yld->ctl_req_dma); - usb_buffer_free(yld->udev, USB_PKT_LEN, - yld->ctl_data, yld->ctl_dma); - usb_buffer_free(yld->udev, USB_PKT_LEN, - yld->irq_data, yld->irq_dma); - + if (yld->ctl_req) + usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)), + yld->ctl_req, yld->ctl_req_dma); + if (yld->ctl_data) + usb_buffer_free(yld->udev, USB_PKT_LEN, + yld->ctl_data, yld->ctl_dma); + if (yld->irq_data) + usb_buffer_free(yld->udev, USB_PKT_LEN, + yld->irq_data, yld->irq_dma); + + usb_free_urb(yld->urb_irq); /* parameter validation in core/urb */ + usb_free_urb(yld->urb_ctl); /* parameter validation in core/urb */ kfree(yld); return err; } @@ -936,10 +937,9 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) input_dev->name = nfo->name; input_dev->phys = yld->phys; usb_to_input_id(udev, &input_dev->id); - input_dev->dev.parent = &intf->dev; - - input_set_drvdata(input_dev, yld); + input_dev->cdev.dev = &intf->dev; + input_dev->private = yld; input_dev->open = input_open; input_dev->close = input_close; /* input_dev->event = input_ev; TODO */ @@ -955,9 +955,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) } } - ret = input_register_device(yld->idev); - if (ret) - return usb_cleanup(yld, ret); + input_register_device(yld->idev); usb_set_intfdata(intf, yld); diff --git a/trunk/drivers/input/misc/yealink.h b/trunk/drivers/usb/input/yealink.h similarity index 100% rename from trunk/drivers/input/misc/yealink.h rename to trunk/drivers/usb/input/yealink.h diff --git a/trunk/drivers/usb/misc/idmouse.c b/trunk/drivers/usb/misc/idmouse.c index 8d0e360636e6..15c70bd048c4 100644 --- a/trunk/drivers/usb/misc/idmouse.c +++ b/trunk/drivers/usb/misc/idmouse.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/misc/legousbtower.c b/trunk/drivers/usb/misc/legousbtower.c index 1713e19a7899..5dce797bddb7 100644 --- a/trunk/drivers/usb/misc/legousbtower.c +++ b/trunk/drivers/usb/misc/legousbtower.c @@ -80,6 +80,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/misc/rio500.c b/trunk/drivers/usb/misc/rio500.c index 88f6abe73624..fdf68479a166 100644 --- a/trunk/drivers/usb/misc/rio500.c +++ b/trunk/drivers/usb/misc/rio500.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "rio500_usb.h" diff --git a/trunk/drivers/usb/misc/sisusbvga/sisusb_con.c b/trunk/drivers/usb/misc/sisusbvga/sisusb_con.c index 5947afb0017e..1730d8642a47 100644 --- a/trunk/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/trunk/drivers/usb/misc/sisusbvga/sisusb_con.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -321,7 +322,7 @@ sisusbcon_deinit(struct vc_data *c) /* interface routine */ static u8 sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity, - u8 blink, u8 underline, u8 reverse, u8 unused) + u8 blink, u8 underline, u8 reverse) { u8 attr = color; diff --git a/trunk/drivers/usb/mon/mon_main.c b/trunk/drivers/usb/mon/mon_main.c index 8977ec0d0f99..8a1df2c9c73e 100644 --- a/trunk/drivers/usb/mon/mon_main.c +++ b/trunk/drivers/usb/mon/mon_main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/usb/net/kaweth.c b/trunk/drivers/usb/net/kaweth.c index 60d29440f316..a0cc05d21a6a 100644 --- a/trunk/drivers/usb/net/kaweth.c +++ b/trunk/drivers/usb/net/kaweth.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 87f378806db6..7639022cdf84 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/storage/usb.h b/trunk/drivers/usb/storage/usb.h index 6dac1ffdde86..21f3ddbc9080 100644 --- a/trunk/drivers/usb/storage/usb.h +++ b/trunk/drivers/usb/storage/usb.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 1132ba5ff391..b1cb72c3780f 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -5,11 +5,6 @@ menu "Graphics support" source "drivers/video/backlight/Kconfig" -source "drivers/video/display/Kconfig" - -config VGASTATE - tristate - default n config FB tristate "Support for frame buffer devices" @@ -95,43 +90,6 @@ config FB_CFB_IMAGEBLIT blitting. This is used by drivers that don't provide their own (accelerated) version. -config FB_SYS_FILLRECT - tristate - depends on FB - default n - ---help--- - Include the sys_fillrect function for generic software rectangle - filling. This is used by drivers that don't provide their own - (accelerated) version and the framebuffer is in system RAM. - -config FB_SYS_COPYAREA - tristate - depends on FB - default n - ---help--- - Include the sys_copyarea function for generic software area copying. - This is used by drivers that don't provide their own (accelerated) - version and the framebuffer is in system RAM. - -config FB_SYS_IMAGEBLIT - tristate - depends on FB - default n - ---help--- - Include the sys_imageblit function for generic software image - blitting. This is used by drivers that don't provide their own - (accelerated) version and the framebuffer is in system RAM. - -config FB_SYS_FOPS - tristate - depends on FB - default n - -config FB_DEFERRED_IO - bool - depends on FB - default y - config FB_SVGALIB tristate depends on FB @@ -233,7 +191,7 @@ config FB_ARMCLCD If you want to compile this as a module (=code which can be inserted into and removed from the running kernel), say M - here and read . The module + here and read . The module will be called amba-clcd. choice @@ -417,10 +375,9 @@ config FB_FM2 config FB_ARC tristate "Arc Monochrome LCD board support" depends on FB && X86 - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT help This enables support for the Arc Monochrome LCD board. The board is based on the KS-108 lcd controller and is typically a matrix @@ -432,10 +389,7 @@ config FB_ARC config FB_ATARI bool "Atari native chipset support" - depends on (FB = y) && ATARI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + depends on (FB = y) && ATARI && BROKEN help This is the frame buffer device driver for the builtin graphics chipset found in Ataris. @@ -518,8 +472,6 @@ config FB_VGA16 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select VGASTATE - select FONT_8x16 if FRAMEBUFFER_CONSOLE help This is the frame buffer device driver for VGA 16 color graphic cards. Say Y if you have such a card. @@ -564,25 +516,15 @@ config FB_HP300 default y config FB_TGA - tristate "TGA/SFB+ framebuffer support" - depends on FB && (ALPHA || TC) + tristate "TGA framebuffer support" + depends on FB && ALPHA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select BITREVERSE - ---help--- - This is the frame buffer device driver for generic TGA and SFB+ - graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards, - also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3 - TURBOchannel cards, also known as PMAGD-A, -B and -C. - - Due to hardware limitations ZLX-E2 and E3 cards are not supported - for DECstation 5000/200 systems. Additionally due to firmware - limitations these cards may cause troubles with booting DECstation - 5000/240 and /260 systems, but are fully supported under Linux if - you manage to get it going. ;-) - - Say Y if you have one of those. + help + This is the frame buffer device driver for generic TGA graphic + cards. Say Y if you have one of those. config FB_VESA bool "VESA VGA graphics support" @@ -606,21 +548,6 @@ config FB_IMAC help This is the frame buffer device driver for the Intel-based Macintosh -config FB_HECUBA - tristate "Hecuba board support" - depends on FB && X86 && MMU - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - help - This enables support for the Hecuba board. This driver was tested - with an E-Ink 800x600 display and x86 SBCs through a 16 bit GPIO - interface (8 bit data, 4 bit control). If you anticpate using - this driver, say Y or M; otherwise say N. You must specify the - GPIO IO address to be used for setting control and data. - config FB_HGA tristate "Hercules mono graphics support" depends on FB && X86 @@ -756,7 +683,6 @@ config FB_NVIDIA select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select BITREVERSE - select VGASTATE help This driver supports graphics boards with the nVidia chips, TNT and newer. For very old chipsets, such as the RIVA128, then use @@ -795,7 +721,6 @@ config FB_RIVA select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select BITREVERSE - select VGASTATE help This driver supports graphics boards with the nVidia Riva/Geforce chips. @@ -842,7 +767,6 @@ config FB_I810 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select VGASTATE help This driver supports the on-board graphics built in to the Intel 810 and 815 chipsets. Say Y if you have and plan to use such a board. @@ -882,22 +806,6 @@ config FB_I810_I2C select FB_DDC help -config FB_LE80578 - tristate "Intel LE80578 (Vermilion) support" - depends on FB && PCI && X86 - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This driver supports the LE80578 (Vermilion Range) chipset - -config FB_CARILLO_RANCH - tristate "Intel Carillo Ranch support" - depends on FB_LE80578 && FB && PCI && X86 - help - This driver supports the LE80578 (Carillo Ranch) board - config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)" depends on FB && EXPERIMENTAL && PCI && X86 @@ -1209,8 +1117,6 @@ config FB_S3 select FB_CFB_IMAGEBLIT select FB_TILEBLITTING select FB_SVGALIB - select VGASTATE - select FONT_8x16 if FRAMEBUFFER_CONSOLE ---help--- Driver for graphics boards with S3 Trio / S3 Virge chip. @@ -1221,7 +1127,6 @@ config FB_SAVAGE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select VGASTATE help This driver supports notebooks and computers with S3 Savage PCI/AGP chips. @@ -1288,7 +1193,6 @@ config FB_NEOMAGIC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select VGASTATE help This driver supports notebooks with NeoMagic PCI chips. Say Y if you have such a graphics card. @@ -1476,32 +1380,6 @@ config FB_LEO This is the frame buffer device driver for the SBUS-based Sun ZX (leo) frame buffer cards. -config FB_XVR500 - bool "Sun XVR-500 3DLABS Wildcat support" - depends on FB && PCI && SPARC64 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the Sun XVR-500 and similar - graphics cards based upon the 3DLABS Wildcat chipset. The driver - only works on sparc64 systems where the system firwmare has - mostly initialized the card already. It is treated as a - completely dumb framebuffer device. - -config FB_XVR2500 - bool "Sun XVR-2500 3DLABS Wildcat support" - depends on FB && PCI && SPARC64 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the Sun XVR-2500 and similar - graphics cards based upon the 3DLABS Wildcat chipset. The driver - only works on sparc64 systems where the system firwmare has - mostly initialized the card already. It is treated as a - completely dumb framebuffer device. - config FB_PCI bool "PCI framebuffers" depends on (FB = y) && PCI && SPARC @@ -1613,7 +1491,7 @@ config FB_PXA This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The module will be called pxafb. If you want to compile it as a module, - say M here and read . + say M here and read . If unsure, say N. @@ -1666,7 +1544,7 @@ config FB_W100 This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The module will be called w100fb. If you want to compile it as a module, - say M here and read . + say M here and read . If unsure, say N. @@ -1683,7 +1561,7 @@ config FB_S3C2410 This driver is also available as a module ( = code which can be inserted and removed from the running kernel whenever you want). The module will be called s3c2410fb. If you want to compile it as a module, - say M here and read . + say M here and read . If unsure, say N. config FB_S3C2410_DEBUG @@ -1755,24 +1633,12 @@ config FB_PS3_DEFAULT_SIZE_M The default value can be overridden on the kernel command line using the "ps3fb" option (e.g. "ps3fb=9M"); -config FB_XILINX - tristate "Xilinx frame buffer support" - depends on FB && XILINX_VIRTEX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Include support for the Xilinx ML300/ML403 reference design - framebuffer. ML300 carries a 640*480 LCD display on the board, - ML403 uses a standard DB15 VGA connector. - config FB_VIRTUAL tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" depends on FB - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT ---help--- This is a `virtual' frame buffer device. It operates on a chunk of unswappable kernel memory instead of on the memory of a graphics diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index a916c204274f..760305c8a841 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -4,7 +4,6 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_VGASTATE) += vgastate.o obj-y += fb_notify.o obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ @@ -13,19 +12,14 @@ fb-objs := $(fb-y) obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/ -obj-y += backlight/ display/ +obj-y += backlight/ obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o -obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o -obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o -obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o -obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o obj-$(CONFIG_FB_SVGALIB) += svgalib.o obj-$(CONFIG_FB_MACMODES) += macmodes.o obj-$(CONFIG_FB_DDC) += fb_ddc.o -obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o # Hardware specific drivers go first obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o @@ -36,7 +30,7 @@ obj-$(CONFIG_FB_PM2) += pm2fb.o obj-$(CONFIG_FB_PM3) += pm3fb.o obj-$(CONFIG_FB_MATROX) += matrox/ -obj-$(CONFIG_FB_RIVA) += riva/ +obj-$(CONFIG_FB_RIVA) += riva/ vgastate.o obj-$(CONFIG_FB_NVIDIA) += nvidia/ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o @@ -46,7 +40,8 @@ obj-$(CONFIG_FB_KYRO) += kyro/ obj-$(CONFIG_FB_SAVAGE) += savage/ obj-$(CONFIG_FB_GEODE) += geode/ obj-$(CONFIG_FB_MBX) += mbx/ -obj-$(CONFIG_FB_NEOMAGIC) += neofb.o +obj-$(CONFIG_FB_I810) += vgastate.o +obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o obj-$(CONFIG_FB_CONTROL) += controlfb.o obj-$(CONFIG_FB_PLATINUM) += platinumfb.o @@ -56,8 +51,7 @@ obj-$(CONFIG_FB_IMSTT) += imsttfb.o obj-$(CONFIG_FB_FM2) += fm2fb.o obj-$(CONFIG_FB_CYBLA) += cyblafb.o obj-$(CONFIG_FB_TRIDENT) += tridentfb.o -obj-$(CONFIG_FB_LE80578) += vermilion/ -obj-$(CONFIG_FB_S3) += s3fb.o +obj-$(CONFIG_FB_S3) += s3fb.o vgastate.o obj-$(CONFIG_FB_STI) += stifb.o obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o @@ -69,13 +63,9 @@ obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o obj-$(CONFIG_FB_ACORN) += acornfb.o -obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \ - atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o +obj-$(CONFIG_FB_ATARI) += atafb.o obj-$(CONFIG_FB_MAC) += macfb.o -obj-$(CONFIG_FB_HECUBA) += hecubafb.o obj-$(CONFIG_FB_HGA) += hgafb.o -obj-$(CONFIG_FB_XVR500) += sunxvr500.o -obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o obj-$(CONFIG_FB_IGA) += igafb.o obj-$(CONFIG_FB_APOLLO) += dnfb.o obj-$(CONFIG_FB_Q40) += q40fb.o @@ -109,12 +99,11 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o obj-$(CONFIG_FB_PS3) += ps3fb.o obj-$(CONFIG_FB_SM501) += sm501fb.o -obj-$(CONFIG_FB_XILINX) += xilinxfb.o # Platform or fallback drivers go here obj-$(CONFIG_FB_VESA) += vesafb.o obj-$(CONFIG_FB_IMAC) += imacfb.o -obj-$(CONFIG_FB_VGA16) += vga16fb.o +obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o obj-$(CONFIG_FB_OF) += offb.o # the test framebuffer is last diff --git a/trunk/drivers/video/arcfb.c b/trunk/drivers/video/arcfb.c index db15baca3f7b..30a8369757e7 100644 --- a/trunk/drivers/video/arcfb.c +++ b/trunk/drivers/video/arcfb.c @@ -262,8 +262,7 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper, ks108_set_yaddr(par, chipindex, upper/8); linesize = par->info->var.xres/8; - src = (unsigned char __force *) par->info->screen_base + (left/8) + - (upper * linesize); + src = par->info->screen_base + (left/8) + (upper * linesize); ks108_set_xaddr(par, chipindex, left); bitmask=1; @@ -369,7 +368,7 @@ static void arcfb_fillrect(struct fb_info *info, { struct arcfb_par *par = info->par; - sys_fillrect(info, rect); + cfb_fillrect(info, rect); /* update the physical lcd */ arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); @@ -380,7 +379,7 @@ static void arcfb_copyarea(struct fb_info *info, { struct arcfb_par *par = info->par; - sys_copyarea(info, area); + cfb_copyarea(info, area); /* update the physical lcd */ arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); @@ -390,7 +389,7 @@ static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct arcfb_par *par = info->par; - sys_imageblit(info, image); + cfb_imageblit(info, image); /* update the physical lcd */ arcfb_lcd_update(par, image->dx, image->dy, image->width, @@ -440,11 +439,14 @@ static int arcfb_ioctl(struct fb_info *info, * the fb. it's inefficient for them to do anything less than 64*8 * writes since we update the lcd in each write() anyway. */ -static ssize_t arcfb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos) +static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t count, + loff_t *ppos) { /* modded from epson 1355 */ + struct inode *inode; + int fbidx; + struct fb_info *info; unsigned long p; int err=-EINVAL; unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount; @@ -452,6 +454,13 @@ static ssize_t arcfb_write(struct fb_info *info, const char __user *buf, unsigned int xres; p = *ppos; + inode = file->f_path.dentry->d_inode; + fbidx = iminor(inode); + info = registered_fb[fbidx]; + + if (!info || !info->screen_base) + return -ENODEV; + par = info->par; xres = info->var.xres; fbmemlength = (xres * info->var.yres)/8; @@ -468,7 +477,7 @@ static ssize_t arcfb_write(struct fb_info *info, const char __user *buf, if (count) { char *base_addr; - base_addr = (char __force *)info->screen_base; + base_addr = info->screen_base; count -= copy_from_user(base_addr + p, buf, count); *ppos += count; err = -EFAULT; @@ -494,7 +503,6 @@ static ssize_t arcfb_write(struct fb_info *info, const char __user *buf, static struct fb_ops arcfb_ops = { .owner = THIS_MODULE, .fb_open = arcfb_open, - .fb_read = fb_sys_read, .fb_write = arcfb_write, .fb_release = arcfb_release, .fb_pan_display = arcfb_pan_display, @@ -595,7 +603,7 @@ static int arcfb_remove(struct platform_device *dev) if (info) { unregister_framebuffer(info); - vfree((void __force *)info->screen_base); + vfree(info->screen_base); framebuffer_release(info); } return 0; diff --git a/trunk/drivers/video/atafb.c b/trunk/drivers/video/atafb.c index 0038a0541c7e..bffe2b946344 100644 --- a/trunk/drivers/video/atafb.c +++ b/trunk/drivers/video/atafb.c @@ -2,7 +2,7 @@ * linux/drivers/video/atafb.c -- Atari builtin chipset frame buffer device * * Copyright (C) 1994 Martin Schaller & Roman Hodek - * + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive * for more details. @@ -70,8 +70,14 @@ #include #include -#include "c2p.h" -#include "atafb.h" +#include

"; @@ -328,21 +326,12 @@ while ($ARGV[0] =~ m/^-(.*)/) { } } -# get kernel version from env -sub get_kernel_version() { - my $version; - - if (defined($ENV{'KERNELVERSION'})) { - $version = $ENV{'KERNELVERSION'}; - } - return $version; -} # generate a sequence of code that will splice in highlighting information # using the s// operator. my $dohighlight = ""; foreach my $pattern (keys %highlights) { -# print STDERR "scanning pattern:$pattern, highlight:($highlights{$pattern})\n"; +# print "scanning pattern $pattern ($highlights{$pattern})\n"; $dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n"; } @@ -389,19 +378,13 @@ sub output_highlight { # confess "output_highlight got called with no args?\n"; # } -# print STDERR "contents b4:$contents\n"; eval $dohighlight; die $@ if $@; - if ($output_mode eq "html") { - $contents =~ s/\\\\//; - } -# print STDERR "contents af:$contents\n"; - foreach $line (split "\n", $contents) { - if ($line eq ""){ + if ($line eq ""){ print $lineprefix, $blankline; } else { - $line =~ s/\\\\\\/\&/g; + $line =~ s/\\\\\\/\&/g; print $lineprefix, $line; } print "\n"; @@ -431,7 +414,7 @@ sub output_enum_html(%) { print "enum ".$args{'enum'}." {
\n"; $count = 0; foreach $parameter (@{$args{'parameterlist'}}) { - print " ".$parameter.""; + print " ".$parameter.""; if ($count != $#{$args{'parameterlist'}}) { $count++; print ",\n"; @@ -479,16 +462,15 @@ sub output_struct_html(%) { my $parameter_name = $parameter; $parameter_name =~ s/\[.*//; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; $type = $args{'parametertypes'}{$parameter}; if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { # pointer-to-function - print "    $1$parameter) ($2);
\n"; + print " $1$parameter) ($2);
\n"; } elsif ($type =~ m/^(.*?)\s*(:.*)/) { - # bitfield - print "    $1 $parameter$2;
\n"; + print " $1 $parameter$2;
\n"; } else { - print "    $type $parameter;
\n"; + print " $type $parameter;
\n"; } } print "};
\n"; @@ -501,7 +483,7 @@ sub output_struct_html(%) { my $parameter_name = $parameter; $parameter_name =~ s/\[.*//; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; print "

".$parameter."\n"; print "
"; output_highlight($args{'parameterdescs'}{$parameter_name}); @@ -543,7 +525,7 @@ sub output_function_html(%) { my $parameter_name = $parameter; $parameter_name =~ s/\[.*//; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; print "
".$parameter."\n"; print "
"; output_highlight($args{'parameterdescs'}{$parameter_name}); @@ -610,7 +592,6 @@ sub output_function_xml(%) { print "\n"; print " ".$args{'function'}."\n"; print " 9\n"; - print " " . get_kernel_version() . "\n"; print "\n"; print "\n"; print " ".$args{'function'}."\n"; @@ -687,7 +668,6 @@ sub output_struct_xml(%) { print "\n"; print " ".$args{'type'}." ".$args{'struct'}."\n"; print " 9\n"; - print " " . get_kernel_version() . "\n"; print "\n"; print "\n"; print " ".$args{'type'}." ".$args{'struct'}."\n"; @@ -711,7 +691,7 @@ sub output_struct_xml(%) { $parameter_name =~ s/\[.*//; defined($args{'parameterdescs'}{$parameter_name}) || next; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; $type = $args{'parametertypes'}{$parameter}; if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { # pointer-to-function @@ -772,7 +752,6 @@ sub output_enum_xml(%) { print "\n"; print " enum ".$args{'enum'}."\n"; print " 9\n"; - print " " . get_kernel_version() . "\n"; print "\n"; print "\n"; print " enum ".$args{'enum'}."\n"; @@ -788,11 +767,11 @@ sub output_enum_xml(%) { print "enum ".$args{'enum'}." {\n"; $count = 0; foreach $parameter (@{$args{'parameterlist'}}) { - print " $parameter"; - if ($count != $#{$args{'parameterlist'}}) { + print " $parameter"; + if ($count != $#{$args{'parameterlist'}}) { $count++; print ","; - } + } print "\n"; } print "};"; @@ -1028,7 +1007,7 @@ sub output_enum_man(%) { print "enum ".$args{'enum'}." {\n"; $count = 0; foreach my $parameter (@{$args{'parameterlist'}}) { - print ".br\n.BI \" $parameter\"\n"; + print ".br\n.BI \" $parameter\"\n"; if ($count == $#{$args{'parameterlist'}}) { print "\n};\n"; last; @@ -1075,7 +1054,7 @@ sub output_struct_man(%) { my $parameter_name = $parameter; $parameter_name =~ s/\[.*//; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; $type = $args{'parametertypes'}{$parameter}; if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { # pointer-to-function @@ -1098,7 +1077,7 @@ sub output_struct_man(%) { my $parameter_name = $parameter; $parameter_name =~ s/\[.*//; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; print ".IP \"".$parameter."\" 12\n"; output_highlight($args{'parameterdescs'}{$parameter_name}); } @@ -1208,7 +1187,7 @@ sub output_enum_text(%) { print "enum ".$args{'enum'}." {\n"; $count = 0; foreach $parameter (@{$args{'parameterlist'}}) { - print "\t$parameter"; + print "\t$parameter"; if ($count != $#{$args{'parameterlist'}}) { $count++; print ","; @@ -1253,7 +1232,7 @@ sub output_struct_text(%) { my $parameter_name = $parameter; $parameter_name =~ s/\[.*//; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; $type = $args{'parametertypes'}{$parameter}; if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { # pointer-to-function @@ -1273,7 +1252,7 @@ sub output_struct_text(%) { my $parameter_name = $parameter; $parameter_name =~ s/\[.*//; - ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; + ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; print "$parameter\n\t"; print $args{'parameterdescs'}{$parameter_name}."\n"; } @@ -1305,7 +1284,7 @@ sub output_declaration { ( $function_only == 1 && defined($function_table{$name})) || ( $function_only == 2 && !defined($function_table{$name}))) { - &$func(@_); + &$func(@_); $section_counter++; } } @@ -1338,8 +1317,8 @@ sub dump_struct($$) { my $file = shift; if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) { - $declaration_name = $2; - my $members = $3; + $declaration_name = $2; + my $members = $3; # ignore embedded structs or unions $members =~ s/{.*?}//g; @@ -1366,7 +1345,7 @@ sub dump_struct($$) { }); } else { - print STDERR "Error(${file}:$.): Cannot parse struct or union!\n"; + print STDERR "Error(${file}:$.): Cannot parse struct or union!\n"; ++$errors; } } @@ -1377,15 +1356,15 @@ sub dump_enum($$) { $x =~ s@/\*.*?\*/@@gos; # strip comments. if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { - $declaration_name = $1; - my $members = $2; + $declaration_name = $1; + my $members = $2; foreach my $arg (split ',', $members) { $arg =~ s/^\s*(\w+).*/$1/; push @parameterlist, $arg; if (!$parameterdescs{$arg}) { - $parameterdescs{$arg} = $undescribed; - print STDERR "Warning(${file}:$.): Enum value '$arg' ". + $parameterdescs{$arg} = $undescribed; + print STDERR "Warning(${file}:$.): Enum value '$arg' ". "not described in enum '$declaration_name'\n"; } @@ -1403,7 +1382,7 @@ sub dump_enum($$) { }); } else { - print STDERR "Error(${file}:$.): Cannot parse enum!\n"; + print STDERR "Error(${file}:$.): Cannot parse enum!\n"; ++$errors; } } @@ -1414,12 +1393,12 @@ sub dump_typedef($$) { $x =~ s@/\*.*?\*/@@gos; # strip comments. while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { - $x =~ s/\(*.\)\s*;$/;/; + $x =~ s/\(*.\)\s*;$/;/; $x =~ s/\[*.\]\s*;$/;/; } if ($x =~ /typedef.*\s+(\w+)\s*;/) { - $declaration_name = $1; + $declaration_name = $1; output_declaration($declaration_name, 'typedef', @@ -1431,7 +1410,7 @@ sub dump_typedef($$) { }); } else { - print STDERR "Error(${file}:$.): Cannot parse typedef!\n"; + print STDERR "Error(${file}:$.): Cannot parse typedef!\n"; ++$errors; } } @@ -1445,14 +1424,14 @@ sub create_parameterlist($$$) { # temporarily replace commas inside function pointer definition while ($args =~ /(\([^\),]+),/) { - $args =~ s/(\([^\),]+),/$1#/g; + $args =~ s/(\([^\),]+),/$1#/g; } foreach my $arg (split($splitter, $args)) { # strip comments $arg =~ s/\/\*.*\*\///; - # strip leading/trailing spaces - $arg =~ s/^\s*//; + # strip leading/trailing spaces + $arg =~ s/^\s*//; $arg =~ s/\s*$//; $arg =~ s/\s+/ /; @@ -1477,16 +1456,7 @@ sub create_parameterlist($$$) { if ($args[0] =~ m/\*/) { $args[0] =~ s/(\*+)\s*/ $1/; } - - my @first_arg; - if ($args[0] =~ /^(.*\s+)(.*?\[.*\].*)$/) { - shift @args; - push(@first_arg, split('\s+', $1)); - push(@first_arg, $2); - } else { - @first_arg = split('\s+', shift @args); - } - + my @first_arg = split('\s+', shift @args); unshift(@args, pop @first_arg); $type = join " ", @first_arg; @@ -1544,15 +1514,15 @@ sub push_parameter($$$) { $parameterdescs{$param_name} = $undescribed; if (($type eq 'function') || ($type eq 'enum')) { - print STDERR "Warning(${file}:$.): Function parameter ". + print STDERR "Warning(${file}:$.): Function parameter ". "or member '$param' not " . "described in '$declaration_name'\n"; } print STDERR "Warning(${file}:$.):". - " No description found for parameter '$param'\n"; + " No description found for parameter '$param'\n"; ++$warnings; - } - } + } + } push @parameterlist, $param; $parametertypes{$param} = $type; @@ -1694,10 +1664,10 @@ sub process_state3_function($$) { # do nothing } elsif ($x =~ /([^\{]*)/) { - $prototype .= $1; + $prototype .= $1; } if (($x =~ /\{/) || ($x =~ /\#define/) || ($x =~ /;/)) { - $prototype =~ s@/\*.*?\*/@@gos; # strip comments. + $prototype =~ s@/\*.*?\*/@@gos; # strip comments. $prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. $prototype =~ s@^\s+@@gos; # strip leading spaces dump_function($prototype,$file); @@ -1718,17 +1688,17 @@ sub process_state3_type($$) { } while (1) { - if ( $x =~ /([^{};]*)([{};])(.*)/ ) { + if ( $x =~ /([^{};]*)([{};])(.*)/ ) { $prototype .= $1 . $2; ($2 eq '{') && $brcount++; ($2 eq '}') && $brcount--; if (($2 eq ';') && ($brcount == 0)) { - dump_declaration($prototype,$file); + dump_declaration($prototype,$file); reset_state(); - last; + last; } $x = $3; - } else { + } else { $prototype .= $x; last; } @@ -1786,7 +1756,7 @@ sub process_file($) { } else { $section = $1; } - } + } elsif (/$doc_decl/o) { $identifier = $1; if (/\s*([\w\s]+?)\s*-/) { @@ -1879,13 +1849,13 @@ sub process_file($) { } } elsif ($state == 3) { # scanning for function '{' (end of prototype) if ($decl_type eq 'function') { - process_state3_function($_, $file); + process_state3_function($_, $file); } else { - process_state3_type($_, $file); + process_state3_type($_, $file); } } elsif ($state == 4) { # Documentation block - if (/$doc_block/) { + if (/$doc_block/) { dump_section($section, $contents); output_intro({'sectionlist' => \@sectionlist, 'sections' => \%sections }); @@ -1903,7 +1873,7 @@ sub process_file($) { } else { $section = $1; } - } + } elsif (/$doc_end/) { dump_section($section, $contents); @@ -1930,8 +1900,8 @@ sub process_file($) { { $contents .= $1 . "\n"; } - } - } + } + } } if ($initial_section_counter == $section_counter) { print STDERR "Warning(${file}): no structured comments found\n"; diff --git a/trunk/scripts/mkcompile_h b/trunk/scripts/mkcompile_h index a8740df07b09..82d0af46f0ef 100755 --- a/trunk/scripts/mkcompile_h +++ b/trunk/scripts/mkcompile_h @@ -18,32 +18,19 @@ fi # Do not expand names set -f -# Fix the language to get consistent output -LC_ALL=C -export LC_ALL - -if [ -z "$KBUILD_BUILD_VERSION" ]; then - if [ -r .version ]; then - VERSION=`cat .version` - else - VERSION=0 - echo 0 > .version - fi +if [ -r .version ]; then + VERSION=`cat .version` else - VERSION=$KBUILD_BUILD_VERSION + VERSION=0 + echo 0 > .version fi -if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then - TIMESTAMP=`date` -else - TIMESTAMP=$KBUILD_BUILD_TIMESTAMP -fi UTS_VERSION="#$VERSION" CONFIG_FLAGS="" if [ -n "$SMP" ] ; then CONFIG_FLAGS="SMP"; fi if [ -n "$PREEMPT" ] ; then CONFIG_FLAGS="$CONFIG_FLAGS PREEMPT"; fi -UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP" +UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS `LC_ALL=C LANG=C date`" # Truncate to maximum length @@ -59,7 +46,7 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/" echo \#define UTS_VERSION \"`echo $UTS_VERSION | $UTS_TRUNCATE`\" - echo \#define LINUX_COMPILE_TIME \"`date +%T`\" + echo \#define LINUX_COMPILE_TIME \"`LC_ALL=C LANG=C date +%T`\" echo \#define LINUX_COMPILE_BY \"`whoami`\" echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" @@ -71,7 +58,7 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/" echo \#define LINUX_COMPILE_DOMAIN fi - echo \#define LINUX_COMPILER \"`$CC -v 2>&1 | tail -n 1`\" + echo \#define LINUX_COMPILER \"`LC_ALL=C LANG=C $CC -v 2>&1 | tail -n 1`\" ) > .tmpcompile # Only replace the real compile.h if the new one is different, diff --git a/trunk/scripts/mkuboot.sh b/trunk/scripts/mkuboot.sh index 2e3d3cd916b8..4b06c5eea728 100755 --- a/trunk/scripts/mkuboot.sh +++ b/trunk/scripts/mkuboot.sh @@ -4,7 +4,7 @@ # Build U-Boot image when `mkimage' tool is available. # -MKIMAGE=$(type -path "${CROSS_COMPILE}mkimage") +MKIMAGE=$(type -path ${CROSS_COMPILE}mkimage) if [ -z "${MKIMAGE}" ]; then MKIMAGE=$(type -path mkimage) diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index ed1244dd58d0..b2f73ffb40bd 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -37,6 +37,7 @@ typedef unsigned char __u8; * even potentially has different endianness and word sizes, since * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" +#include "../../include/linux/input.h" #define ADD(str, sep, cond, field) \ do { \ @@ -415,33 +416,31 @@ static int do_input_entry(const char *filename, struct input_device_id *id, sprintf(alias + strlen(alias), "-e*"); if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT) - do_input(alias, id->evbit, 0, INPUT_DEVICE_ID_EV_MAX); + do_input(alias, id->evbit, 0, EV_MAX); sprintf(alias + strlen(alias), "k*"); if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT) - do_input(alias, id->keybit, - INPUT_DEVICE_ID_KEY_MIN_INTERESTING, - INPUT_DEVICE_ID_KEY_MAX); + do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX); sprintf(alias + strlen(alias), "r*"); if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT) - do_input(alias, id->relbit, 0, INPUT_DEVICE_ID_REL_MAX); + do_input(alias, id->relbit, 0, REL_MAX); sprintf(alias + strlen(alias), "a*"); if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT) - do_input(alias, id->absbit, 0, INPUT_DEVICE_ID_ABS_MAX); + do_input(alias, id->absbit, 0, ABS_MAX); sprintf(alias + strlen(alias), "m*"); if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT) - do_input(alias, id->mscbit, 0, INPUT_DEVICE_ID_MSC_MAX); + do_input(alias, id->mscbit, 0, MSC_MAX); sprintf(alias + strlen(alias), "l*"); if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT) - do_input(alias, id->ledbit, 0, INPUT_DEVICE_ID_LED_MAX); + do_input(alias, id->ledbit, 0, LED_MAX); sprintf(alias + strlen(alias), "s*"); if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT) - do_input(alias, id->sndbit, 0, INPUT_DEVICE_ID_SND_MAX); + do_input(alias, id->sndbit, 0, SND_MAX); sprintf(alias + strlen(alias), "f*"); if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT) - do_input(alias, id->ffbit, 0, INPUT_DEVICE_ID_FF_MAX); + do_input(alias, id->ffbit, 0, FF_MAX); sprintf(alias + strlen(alias), "w*"); if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT) - do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX); + do_input(alias, id->swbit, 0, SW_MAX); return 1; } diff --git a/trunk/scripts/mod/mk_elfconfig.c b/trunk/scripts/mod/mk_elfconfig.c index db3881f14c2d..725d61c0fb43 100644 --- a/trunk/scripts/mod/mk_elfconfig.c +++ b/trunk/scripts/mod/mk_elfconfig.c @@ -55,8 +55,7 @@ main(int argc, char **argv) else exit(1); - if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0) - || (strcmp(argv[1], "blackfin") == 0)) + if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); else printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index 480e18b00aa6..65bdfdb56877 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -55,17 +55,6 @@ void warn(const char *fmt, ...) va_end(arglist); } -void merror(const char *fmt, ...) -{ - va_list arglist; - - fprintf(stderr, "ERROR: "); - - va_start(arglist, fmt); - vfprintf(stderr, fmt, arglist); - va_end(arglist); -} - static int is_vmlinux(const char *modname) { const char *myname; @@ -344,10 +333,10 @@ void release_file(void *file, unsigned long size) munmap(file, size); } -static int parse_elf(struct elf_info *info, const char *filename) +static void parse_elf(struct elf_info *info, const char *filename) { unsigned int i; - Elf_Ehdr *hdr; + Elf_Ehdr *hdr = info->hdr; Elf_Shdr *sechdrs; Elf_Sym *sym; @@ -357,18 +346,9 @@ static int parse_elf(struct elf_info *info, const char *filename) exit(1); } info->hdr = hdr; - if (info->size < sizeof(*hdr)) { - /* file too small, assume this is an empty .o file */ - return 0; - } - /* Is this a valid ELF file? */ - if ((hdr->e_ident[EI_MAG0] != ELFMAG0) || - (hdr->e_ident[EI_MAG1] != ELFMAG1) || - (hdr->e_ident[EI_MAG2] != ELFMAG2) || - (hdr->e_ident[EI_MAG3] != ELFMAG3)) { - /* Not an ELF file - silently ignore it */ - return 0; - } + if (info->size < sizeof(*hdr)) + goto truncated; + /* Fix endianness in ELF header */ hdr->e_shoff = TO_NATIVE(hdr->e_shoff); hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); @@ -391,10 +371,8 @@ static int parse_elf(struct elf_info *info, const char *filename) = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; const char *secname; - if (sechdrs[i].sh_offset > info->size) { - fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr)); - return 0; - } + if (sechdrs[i].sh_offset > info->size) + goto truncated; secname = secstrings + sechdrs[i].sh_name; if (strcmp(secname, ".modinfo") == 0) { info->modinfo = (void *)hdr + sechdrs[i].sh_offset; @@ -429,7 +407,10 @@ static int parse_elf(struct elf_info *info, const char *filename) sym->st_value = TO_NATIVE(sym->st_value); sym->st_size = TO_NATIVE(sym->st_size); } - return 1; + return; + + truncated: + fatal("%s is truncated.\n", filename); } static void parse_elf_finish(struct elf_info *info) @@ -600,17 +581,9 @@ static int strrcmp(const char *s, const char *sub) * the pattern is identified by: * tosec = .init.text | .exit.text | .init.data * fromsec = .data - * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console + * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one * * Pattern 3: - * Whitelist all references from .pci_fixup* section to .init.text - * This is part of the PCI init when built-in - * - * Pattern 4: - * Whitelist all refereces from .text.head to .init.data - * Whitelist all refereces from .text.head to .init.text - * - * Pattern 5: * Some symbols belong to init section but still it is ok to reference * these from non-init sections as these symbols don't have any memory * allocated for them and symbol address and value are same. So even @@ -618,40 +591,6 @@ static int strrcmp(const char *s, const char *sub) * For ex. symbols marking the init section boundaries. * This pattern is identified by * refsymname = __init_begin, _sinittext, _einittext - * - * Pattern 6: - * During the early init phase we have references from .init.text to - * .text we have an intended section mismatch - do not warn about it. - * See kernel_init() in init/main.c - * tosec = .init.text - * fromsec = .text - * atsym = kernel_init - * - * Pattern 7: - * Logos used in drivers/video/logo reside in __initdata but the - * funtion that references them are EXPORT_SYMBOL() so cannot be - * marker __init. So we whitelist them here. - * The pattern is: - * tosec = .init.data - * fromsec = .text* - * refsymname = logo_ - * - * Pattern 8: - * Symbols contained in .paravirtprobe may safely reference .init.text. - * The pattern is: - * tosec = .init.text - * fromsec = .paravirtprobe - * - * Pattern 9: - * Some of functions are common code between boot time and hotplug - * time. The bootmem allocater is called only boot time in its - * functions. So it's ok to reference. - * tosec = .init.text - * - * Pattern 10: - * ia64 has machvec table for each platform. It is mixture of function - * pointer of .init.text and .text. - * fromsec = .machvec **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, @@ -667,7 +606,6 @@ static int secref_whitelist(const char *modname, const char *tosec, "_probe", "_probe_one", "_console", - "apic_es7000", NULL }; @@ -678,12 +616,6 @@ static int secref_whitelist(const char *modname, const char *tosec, NULL }; - const char *pat4sym[] = { - "sparse_index_alloc", - "zone_wait_table_init", - NULL - }; - /* Check for pattern 1 */ if (strcmp(tosec, ".init.data") != 0) f1 = 0; @@ -709,50 +641,25 @@ static int secref_whitelist(const char *modname, const char *tosec, if (f1 && f2) return 1; - /* Check for pattern 3 */ - if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) && - (strcmp(tosec, ".init.text") == 0)) - return 1; - - /* Check for pattern 4 */ - if ((strcmp(fromsec, ".text.head") == 0) && - ((strcmp(tosec, ".init.data") == 0) || - (strcmp(tosec, ".init.text") == 0))) - return 1; - - /* Check for pattern 5 */ - for (s = pat3refsym; *s; s++) - if (strcmp(refsymname, *s) == 0) - return 1; - - /* Check for pattern 6 */ - if ((strcmp(tosec, ".init.text") == 0) && - (strcmp(fromsec, ".text") == 0) && - (strcmp(refsymname, "kernel_init") == 0)) - return 1; - - /* Check for pattern 7 */ - if ((strcmp(tosec, ".init.data") == 0) && - (strncmp(fromsec, ".text", strlen(".text")) == 0) && - (strncmp(refsymname, "logo_", strlen("logo_")) == 0)) + /* Whitelist all references from .pci_fixup section if vmlinux + * Whitelist all refereces from .text.head to .init.data if vmlinux + * Whitelist all refereces from .text.head to .init.text if vmlinux + */ + if (is_vmlinux(modname)) { + if ((strcmp(fromsec, ".pci_fixup") == 0) && + (strcmp(tosec, ".init.text") == 0)) return 1; - /* Check for pattern 8 */ - if ((strcmp(tosec, ".init.text") == 0) && - (strcmp(fromsec, ".paravirtprobe") == 0)) + if ((strcmp(fromsec, ".text.head") == 0) && + ((strcmp(tosec, ".init.data") == 0) || + (strcmp(tosec, ".init.text") == 0))) return 1; - /* Check for pattern 9 */ - if ((strcmp(tosec, ".init.text") == 0) && - (strcmp(fromsec, ".text") == 0)) - for (s = pat4sym; *s; s++) - if (strcmp(atsym, *s) == 0) + /* Check for pattern 3 */ + for (s = pat3refsym; *s; s++) + if (strcmp(refsymname, *s) == 0) return 1; - - /* Check for pattern 10 */ - if (strcmp(fromsec, ".machvec") == 0) - return 1; - + } return 0; } @@ -1182,8 +1089,7 @@ static void read_symbols(char *modname) struct elf_info info = { }; Elf_Sym *sym; - if (!parse_elf(&info, modname)) - return; + parse_elf(&info, modname); mod = new_module(modname); @@ -1358,14 +1264,9 @@ static int add_versions(struct buffer *b, struct module *mod) exp = find_symbol(s->name); if (!exp || exp->module == mod) { if (have_vmlinux && !s->weak) { - if (warn_unresolved) { - warn("\"%s\" [%s.ko] undefined!\n", - s->name, mod->name); - } else { - merror("\"%s\" [%s.ko] undefined!\n", - s->name, mod->name); - err = 1; - } + warn("\"%s\" [%s.ko] undefined!\n", + s->name, mod->name); + err = warn_unresolved ? 0 : 1; } continue; } @@ -1416,7 +1317,6 @@ static void add_depends(struct buffer *b, struct module *mod, buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); buf_printf(b, "\"depends="); for (s = mod->unres; s; s = s->next) { - const char *p; if (!s->module) continue; @@ -1424,11 +1324,8 @@ static void add_depends(struct buffer *b, struct module *mod, continue; s->module->seen = 1; - if ((p = strrchr(s->module->name, '/')) != NULL) - p++; - else - p = s->module->name; - buf_printf(b, "%s%s", first ? "" : ",", p); + buf_printf(b, "%s%s", first ? "" : ",", + strrchr(s->module->name, '/') + 1); first = 0; } buf_printf(b, "\";\n"); diff --git a/trunk/scripts/mod/modpost.h b/trunk/scripts/mod/modpost.h index 0858caa9c03f..d398c61e55ef 100644 --- a/trunk/scripts/mod/modpost.h +++ b/trunk/scripts/mod/modpost.h @@ -145,4 +145,3 @@ void release_file(void *file, unsigned long size); void fatal(const char *fmt, ...); void warn(const char *fmt, ...); -void merror(const char *fmt, ...); diff --git a/trunk/scripts/mod/sumversion.c b/trunk/scripts/mod/sumversion.c index 6873d5af80d5..8a2875689e4d 100644 --- a/trunk/scripts/mod/sumversion.c +++ b/trunk/scripts/mod/sumversion.c @@ -397,9 +397,10 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) (int) strlen(basename) - 2, basename); file = grab_file(filelist, &len); - if (!file) - /* not a module or .mod file missing - ignore */ + if (!file) { + warn("could not find versions for %s\n", filelist); return; + } sources = strchr(file, '\n'); if (!sources) { diff --git a/trunk/security/capability.c b/trunk/security/capability.c index 38296a005465..b868e7eda5f0 100644 --- a/trunk/security/capability.c +++ b/trunk/security/capability.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index 384379ede4fd..5a5ef5ca7ea9 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/security/inode.c b/trunk/security/inode.c index 307211ac7346..d7ecf89fbc74 100644 --- a/trunk/security/inode.c +++ b/trunk/security/inode.c @@ -321,7 +321,7 @@ static int __init securityfs_init(void) { int retval; - kobj_set_kset_s(&security_subsys, kernel_subsys); + kset_set_kset_s(&security_subsys, kernel_subsys); retval = subsystem_register(&security_subsys); if (retval) return retval; diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index ad8dd4e8657e..885a9a958b8d 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1757,11 +1758,12 @@ static inline void flush_unauthorized_files(struct files_struct * files) } } file_list_unlock(); + + /* Reset controlling tty. */ + if (drop_tty) + proc_set_tty(current, NULL); } mutex_unlock(&tty_mutex); - /* Reset controlling tty. */ - if (drop_tty) - no_tty(); /* Revalidate access to inherited open files. */ diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c index e91f9f66f395..7f980be5d060 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-onyx.c @@ -1061,7 +1061,7 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter) busnode = pmac_i2c_get_bus_node(bus); while ((dev = of_get_next_child(busnode, dev)) != NULL) { - if (of_device_is_compatible(dev, "pcm3052")) { + if (device_is_compatible(dev, "pcm3052")) { const u32 *addr; printk(KERN_DEBUG PFX "found pcm3052\n"); addr = of_get_property(dev, "reg", NULL); @@ -1074,7 +1074,7 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter) /* if that didn't work, try desperate mode for older * machines that have stuff missing from the device tree */ - if (!of_device_is_compatible(busnode, "k2-i2c")) + if (!device_is_compatible(busnode, "k2-i2c")) return -ENODEV; printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n"); diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c b/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c index 041fe52cbf29..ceca38486eae 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-tas.c @@ -938,7 +938,7 @@ static int tas_i2c_attach(struct i2c_adapter *adapter) busnode = pmac_i2c_get_bus_node(bus); while ((dev = of_get_next_child(busnode, dev)) != NULL) { - if (of_device_is_compatible(dev, "tas3004")) { + if (device_is_compatible(dev, "tas3004")) { const u32 *addr; printk(KERN_DEBUG PFX "found tas3004\n"); addr = of_get_property(dev, "reg", NULL); diff --git a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c index 0fccdbf51663..79fc4bc09e5e 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c +++ b/trunk/sound/aoa/soundbus/i2sbus/i2sbus-core.c @@ -336,8 +336,8 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match) } while ((np = of_get_next_child(dev->ofdev.node, np))) { - if (of_device_is_compatible(np, "i2sbus") || - of_device_is_compatible(np, "i2s-modem")) { + if (device_is_compatible(np, "i2sbus") || + device_is_compatible(np, "i2s-modem")) { got += i2sbus_add_dev(dev, control, np); } } diff --git a/trunk/sound/arm/pxa2xx-ac97.c b/trunk/sound/arm/pxa2xx-ac97.c index 19c65a8d86a7..28db4be7a16f 100644 --- a/trunk/sound/arm/pxa2xx-ac97.c +++ b/trunk/sound/arm/pxa2xx-ac97.c @@ -260,7 +260,7 @@ static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state) if (platform_ops && platform_ops->suspend) platform_ops->suspend(platform_ops->priv); GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN_AC97, 0); + pxa_set_cken(CKEN2_AC97, 0); return 0; } @@ -269,7 +269,7 @@ static int pxa2xx_ac97_do_resume(struct snd_card *card) { pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; - pxa_set_cken(CKEN_AC97, 1); + pxa_set_cken(CKEN2_AC97, 1); if (platform_ops && platform_ops->resume) platform_ops->resume(platform_ops->priv); snd_ac97_resume(pxa2xx_ac97_ac97); @@ -337,7 +337,7 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif - pxa_set_cken(CKEN_AC97, 1); + pxa_set_cken(CKEN2_AC97, 1); ret = snd_ac97_bus(card, 0, &pxa2xx_ac97_ops, NULL, &ac97_bus); if (ret) @@ -361,10 +361,10 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) err: if (card) snd_card_free(card); - if (CKEN & CKEN_AC97) { + if (CKEN & CKEN2_AC97) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + pxa_set_cken(CKEN2_AC97, 0); } return ret; } @@ -378,7 +378,7 @@ static int __devexit pxa2xx_ac97_remove(struct platform_device *dev) platform_set_drvdata(dev, NULL); GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + pxa_set_cken(CKEN2_AC97, 0); } return 0; diff --git a/trunk/sound/core/control.c b/trunk/sound/core/control.c index 1f1ab9c1b668..86de7258b76d 100644 --- a/trunk/sound/core/control.c +++ b/trunk/sound/core/control.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/core/hwdep.c b/trunk/sound/core/hwdep.c index 51ad95b7c894..96ffdf18c3fe 100644 --- a/trunk/sound/core/hwdep.c +++ b/trunk/sound/core/hwdep.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/core/init.c b/trunk/sound/core/init.c index f2fe35737186..4a431e3ea3a2 100644 --- a/trunk/sound/core/init.c +++ b/trunk/sound/core/init.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/trunk/sound/core/oss/mixer_oss.c b/trunk/sound/core/oss/mixer_oss.c index fccad8f0a6bb..74a2923eb401 100644 --- a/trunk/sound/core/oss/mixer_oss.c +++ b/trunk/sound/core/oss/mixer_oss.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index fc11572c48cf..c4744bb07f41 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index 905234817c89..3e276fcf3336 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include diff --git a/trunk/sound/core/rawmidi.c b/trunk/sound/core/rawmidi.c index e470c3c7d611..d14dcbb6dbca 100644 --- a/trunk/sound/core/rawmidi.c +++ b/trunk/sound/core/rawmidi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/core/seq/oss/seq_oss.c b/trunk/sound/core/seq/oss/seq_oss.c index bc0992398461..2eb987308b53 100644 --- a/trunk/sound/core/seq/oss/seq_oss.c +++ b/trunk/sound/core/seq/oss/seq_oss.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/trunk/sound/core/seq/seq_clientmgr.c b/trunk/sound/core/seq/seq_clientmgr.c index b31b5282a2c8..694efe832b67 100644 --- a/trunk/sound/core/seq/seq_clientmgr.c +++ b/trunk/sound/core/seq/seq_clientmgr.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/trunk/sound/core/timer.c b/trunk/sound/core/timer.c index 67520b3c0042..160e40ede723 100644 --- a/trunk/sound/core/timer.c +++ b/trunk/sound/core/timer.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/oss/Kconfig b/trunk/sound/oss/Kconfig index 4b30ae6d8ba5..4c419300305d 100644 --- a/trunk/sound/oss/Kconfig +++ b/trunk/sound/oss/Kconfig @@ -5,22 +5,23 @@ # # Prompt user for primary drivers. -config OSS_OBSOLETE +config OBSOLETE_OSS bool "Obsolete OSS drivers" depends on SOUND_PRIME help This option enables support for obsolete OSS drivers that - are scheduled for removal in the near future. + are scheduled for removal in the near future since there + are ALSA drivers for the same hardware. Please contact Adrian Bunk if you had to - say Y here because your hardware is not properly supported + say Y here because your soundcard is not properly supported by ALSA. If unsure, say N. config SOUND_BT878 tristate "BT878 audio dma" - depends on SOUND_PRIME && PCI && OSS_OBSOLETE + depends on SOUND_PRIME && PCI ---help--- Audio DMA support for bt878 based grabber boards. As you might have already noticed, bt878 is listed with two functions in /proc/pci. @@ -44,9 +45,22 @@ config SOUND_BCM_CS4297A note that CONFIG_KGDB should not be enabled at the same time, since it also attempts to use this UART port. +config SOUND_ES1371 + tristate "Creative Ensoniq AudioPCI 97 (ES1371)" + depends on SOUND_PRIME && PCI && OBSOLETE_OSS + help + Say Y or M if you have a PCI sound card utilizing the Ensoniq + ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if + your sound card uses an ES1371 without removing your computer's + cover, use lspci -n and look for the PCI ID 1274:1371. Since + Ensoniq was bought by Creative Labs, Sound Blaster 64/PCI + models are either ES1370 or ES1371 based. This driver differs + slightly from OSS/Free, so PLEASE READ + . + config SOUND_ICH tristate "Intel ICH (i8xx) audio support" - depends on SOUND_PRIME && PCI && OSS_OBSOLETE + depends on SOUND_PRIME && PCI help Support for integral audio in Intel's I/O Controller Hub (ICH) chipset, as used on the 810/820/840 motherboards. @@ -348,7 +362,7 @@ config MSND_FIFOSIZE config SOUND_VIA82CXXX tristate "VIA 82C686 Audio Codec" - depends on SOUND_PRIME && PCI && OSS_OBSOLETE + depends on SOUND_PRIME && PCI help Say Y here to include support for the audio codec found on VIA 82Cxxx-based chips. Typically these are built into a motherboard. @@ -402,7 +416,7 @@ config SOUND_DMAP config SOUND_CS4232 tristate "Crystal CS4232 based (PnP) cards" - depends on SOUND_OSS && OSS_OBSOLETE + depends on SOUND_OSS help Say Y here if you have a card based on the Crystal CS4232 chip set, which uses its own Plug and Play protocol. @@ -721,7 +735,7 @@ config SOUND_WAVEARTIST config SOUND_TVMIXER tristate "TV card (bt848) mixer support" - depends on SOUND_PRIME && I2C && VIDEO_V4L1 && OSS_OBSOLETE + depends on SOUND_PRIME && I2C && VIDEO_V4L1 help Support for audio mixer facilities on the BT848 TV frame-grabber card. diff --git a/trunk/sound/oss/au1550_ac97.c b/trunk/sound/oss/au1550_ac97.c index 23018a7c063a..a339f0c0d512 100644 --- a/trunk/sound/oss/au1550_ac97.c +++ b/trunk/sound/oss/au1550_ac97.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/oss/btaudio.c b/trunk/sound/oss/btaudio.c index 4d5cf05b8922..f813ae9c2134 100644 --- a/trunk/sound/oss/btaudio.c +++ b/trunk/sound/oss/btaudio.c @@ -344,7 +344,7 @@ static int btaudio_mixer_ioctl(struct inode *inode, struct file *file, if (cmd == SOUND_OLD_MIXER_INFO) { _old_mixer_info info; memset(&info,0,sizeof(info)); - strlcpy(info.id, "bt878", sizeof(info.id)); + strlcpy(info.id,"bt878",sizeof(info.id)-1); strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)); if (copy_to_user(argp, &info, sizeof(info))) return -EFAULT; diff --git a/trunk/sound/oss/dmasound/Kconfig b/trunk/sound/oss/dmasound/Kconfig index 71b313479f83..18e149f52a88 100644 --- a/trunk/sound/oss/dmasound/Kconfig +++ b/trunk/sound/oss/dmasound/Kconfig @@ -12,6 +12,20 @@ config DMASOUND_ATARI want). If you want to compile it as a module, say M here and read . +config DMASOUND_PMAC + tristate "PowerMac DMA sound support" + depends on PPC32 && PPC_PMAC && SOUND && I2C && OBSOLETE_OSS + select DMASOUND + help + If you want to use the internal audio of your PowerMac in Linux, + answer Y to this question. This will provide a Sun-like /dev/audio, + compatible with the Linux/i386 sound system. Otherwise, say N. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you + want). If you want to compile it as a module, say M here and read + . + config DMASOUND_PAULA tristate "Amiga DMA sound support" depends on (AMIGA || APUS) && SOUND diff --git a/trunk/sound/oss/dmasound/dmasound_awacs.c b/trunk/sound/oss/dmasound/dmasound_awacs.c index 8f6388004f44..730fa1d001a5 100644 --- a/trunk/sound/oss/dmasound/dmasound_awacs.c +++ b/trunk/sound/oss/dmasound/dmasound_awacs.c @@ -362,7 +362,7 @@ setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* of_get_property(np,"audio-gpio",NULL); if (property != 0 && strcmp(property,name) == 0) break; - } else if (compatible && of_device_is_compatible(np, compatible)) + } else if (compatible && device_is_compatible(np, compatible)) break; np = of_get_next_child(gpiop, np); } @@ -2620,17 +2620,17 @@ get_codec_type(struct device_node *info) if (info) { /* must do awacs first to allow screamer to overide it */ - if (of_device_is_compatible(info, "awacs")) + if (device_is_compatible(info, "awacs")) codec = AWACS_AWACS ; - if (of_device_is_compatible(info, "screamer")) + if (device_is_compatible(info, "screamer")) codec = AWACS_SCREAMER; - if (of_device_is_compatible(info, "burgundy")) + if (device_is_compatible(info, "burgundy")) codec = AWACS_BURGUNDY ; - if (of_device_is_compatible(info, "daca")) + if (device_is_compatible(info, "daca")) codec = AWACS_DACA; - if (of_device_is_compatible(info, "tumbler")) + if (device_is_compatible(info, "tumbler")) codec = AWACS_TUMBLER; - if (of_device_is_compatible(info, "snapper")) + if (device_is_compatible(info, "snapper")) codec = AWACS_SNAPPER; } return codec ; @@ -2772,7 +2772,7 @@ set_hw_byteswap(struct device_node *io) for (mio = io->parent; mio ; mio = mio->parent) { if (strcmp(mio->name, "mac-io") == 0) { - if (of_device_is_compatible(mio, "Keylargo")) + if (device_is_compatible(mio, "Keylargo")) kl = 1; break; } diff --git a/trunk/sound/oss/dmasound/tas_ioctl.h b/trunk/sound/oss/dmasound/tas_ioctl.h index 9d12b373b4a9..dccae3a40e01 100644 --- a/trunk/sound/oss/dmasound/tas_ioctl.h +++ b/trunk/sound/oss/dmasound/tas_ioctl.h @@ -1,6 +1,7 @@ #ifndef _TAS_IOCTL_H_ #define _TAS_IOCTL_H_ +#include #include diff --git a/trunk/sound/oss/sh_dac_audio.c b/trunk/sound/oss/sh_dac_audio.c index b493660deb36..7ea9accc2ba4 100644 --- a/trunk/sound/oss/sh_dac_audio.c +++ b/trunk/sound/oss/sh_dac_audio.c @@ -104,7 +104,7 @@ static void dac_audio_set_rate(void) unsigned long interval; struct clk *clk; - clk = clk_get(NULL, "module_clk"); + clk = clk_get("module_clk"); interval = (clk_get_rate(clk) / 4) / rate; clk_put(clk); ctrl_outl(interval, TMU1_TCOR); diff --git a/trunk/sound/oss/soundcard.c b/trunk/sound/oss/soundcard.c index a9c23b2502ad..dcd8d6d2f56f 100644 --- a/trunk/sound/oss/soundcard.c +++ b/trunk/sound/oss/soundcard.c @@ -44,7 +44,6 @@ #include #include #include -#include /* * This ought to be moved into include/asm/dma.h diff --git a/trunk/sound/oss/swarm_cs4297a.c b/trunk/sound/oss/swarm_cs4297a.c index a8057f259553..016b918329ad 100644 --- a/trunk/sound/oss/swarm_cs4297a.c +++ b/trunk/sound/oss/swarm_cs4297a.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include diff --git a/trunk/sound/oss/trident.c b/trunk/sound/oss/trident.c index d98d311542ed..72a8a0ed36a2 100644 --- a/trunk/sound/oss/trident.c +++ b/trunk/sound/oss/trident.c @@ -207,6 +207,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/oss/via82cxxx_audio.c b/trunk/sound/oss/via82cxxx_audio.c index 5d3c0372df32..7ab3a732e184 100644 --- a/trunk/sound/oss/via82cxxx_audio.c +++ b/trunk/sound/oss/via82cxxx_audio.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/pci/ca0106/ca0106_mixer.c b/trunk/sound/pci/ca0106/ca0106_mixer.c index 9c3a9c8d1dc2..b913a1fb8c21 100644 --- a/trunk/sound/pci/ca0106/ca0106_mixer.c +++ b/trunk/sound/pci/ca0106/ca0106_mixer.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -70,7 +71,6 @@ #include #include #include -#include #include "ca0106.h" diff --git a/trunk/sound/pci/ca0106/ca0106_proc.c b/trunk/sound/pci/ca0106/ca0106_proc.c index ae80f51d8c4f..75ca421eb3a1 100644 --- a/trunk/sound/pci/ca0106/ca0106_proc.c +++ b/trunk/sound/pci/ca0106/ca0106_proc.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -72,7 +73,6 @@ #include #include #include -#include #include "ca0106.h" diff --git a/trunk/sound/pci/cs46xx/dsp_spos.c b/trunk/sound/pci/cs46xx/dsp_spos.c index 336e77e2600c..89c402770a1d 100644 --- a/trunk/sound/pci/cs46xx/dsp_spos.c +++ b/trunk/sound/pci/cs46xx/dsp_spos.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/pci/cs46xx/dsp_spos_scb_lib.c b/trunk/sound/pci/cs46xx/dsp_spos_scb_lib.c index 57e357de1500..343f51d5311b 100644 --- a/trunk/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/trunk/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/sound/pci/hda/hda_generic.c b/trunk/sound/pci/hda/hda_generic.c index 1e5ff0cd3709..1589d2f2917f 100644 --- a/trunk/sound/pci/hda/hda_generic.c +++ b/trunk/sound/pci/hda/hda_generic.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/trunk/sound/pci/hda/hda_proc.c b/trunk/sound/pci/hda/hda_proc.c index e313e685f161..17df4d0fe135 100644 --- a/trunk/sound/pci/hda/hda_proc.c +++ b/trunk/sound/pci/hda/hda_proc.c @@ -23,6 +23,7 @@ #include #include +#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/trunk/sound/pci/hda/patch_atihdmi.c b/trunk/sound/pci/hda/patch_atihdmi.c index 831469d3a923..7333f275decd 100644 --- a/trunk/sound/pci/hda/patch_atihdmi.c +++ b/trunk/sound/pci/hda/patch_atihdmi.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/trunk/sound/pci/hda/patch_si3054.c b/trunk/sound/pci/hda/patch_si3054.c index 6fcda9bcf0cf..ed5e45e35963 100644 --- a/trunk/sound/pci/hda/patch_si3054.c +++ b/trunk/sound/pci/hda/patch_si3054.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index 2b11ac8689b9..4c839b031729 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/trunk/sound/ppc/pmac.c b/trunk/sound/ppc/pmac.c index 5a2bef44a2f5..2bae9c1a2b54 100644 --- a/trunk/sound/ppc/pmac.c +++ b/trunk/sound/ppc/pmac.c @@ -843,7 +843,7 @@ static void __init detect_byte_swap(struct snd_pmac *chip) /* if seems that Keylargo can't byte-swap */ for (mio = chip->node->parent; mio; mio = mio->parent) { if (strcmp(mio->name, "mac-io") == 0) { - if (of_device_is_compatible(mio, "Keylargo")) + if (device_is_compatible(mio, "Keylargo")) chip->can_byte_swap = 0; break; } @@ -910,7 +910,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip) chip->node = of_find_node_by_name(NULL, "i2s-a"); if (chip->node && chip->node->parent && chip->node->parent->parent) { - if (of_device_is_compatible(chip->node->parent->parent, + if (device_is_compatible(chip->node->parent->parent, "K2-Keylargo")) chip->is_k2 = 1; } @@ -941,22 +941,22 @@ static int __init snd_pmac_detect(struct snd_pmac *chip) return -ENODEV; } /* This should be verified on older screamers */ - if (of_device_is_compatible(sound, "screamer")) { + if (device_is_compatible(sound, "screamer")) { chip->model = PMAC_SCREAMER; // chip->can_byte_swap = 0; /* FIXME: check this */ } - if (of_device_is_compatible(sound, "burgundy")) { + if (device_is_compatible(sound, "burgundy")) { chip->model = PMAC_BURGUNDY; chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ } - if (of_device_is_compatible(sound, "daca")) { + if (device_is_compatible(sound, "daca")) { chip->model = PMAC_DACA; chip->can_capture = 0; /* no capture */ chip->can_duplex = 0; // chip->can_byte_swap = 0; /* FIXME: check this */ chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ } - if (of_device_is_compatible(sound, "tumbler")) { + if (device_is_compatible(sound, "tumbler")) { chip->model = PMAC_TUMBLER; chip->can_capture = 0; /* no capture */ chip->can_duplex = 0; @@ -965,7 +965,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip) chip->freq_table = tumbler_freqs; chip->control_mask = MASK_IEPC | 0x11; /* disable IEE */ } - if (of_device_is_compatible(sound, "snapper")) { + if (device_is_compatible(sound, "snapper")) { chip->model = PMAC_SNAPPER; // chip->can_byte_swap = 0; /* FIXME: check this */ chip->num_freqs = ARRAY_SIZE(tumbler_freqs); diff --git a/trunk/sound/ppc/tumbler.c b/trunk/sound/ppc/tumbler.c index 5821cdd0bec9..54e333fbb1d0 100644 --- a/trunk/sound/ppc/tumbler.c +++ b/trunk/sound/ppc/tumbler.c @@ -1060,7 +1060,7 @@ static struct device_node *find_compatible_audio_device(const char *name) for (np = of_get_next_child(gpiop, NULL); np; np = of_get_next_child(gpiop, np)) { - if (of_device_is_compatible(np, name)) + if (device_is_compatible(np, name)) break; } of_node_put(gpiop); diff --git a/trunk/sound/soc/pxa/pxa2xx-ac97.c b/trunk/sound/soc/pxa/pxa2xx-ac97.c index b222755763e7..1bbbeff84ef0 100644 --- a/trunk/sound/soc/pxa/pxa2xx-ac97.c +++ b/trunk/sound/soc/pxa/pxa2xx-ac97.c @@ -256,7 +256,7 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev, struct snd_soc_cpu_dai *dai) { GCR |= GCR_ACLINK_OFF; - pxa_set_cken(CKEN_AC97, 0); + pxa_set_cken(CKEN2_AC97, 0); return 0; } @@ -271,7 +271,7 @@ static int pxa2xx_ac97_resume(struct platform_device *pdev, /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif - pxa_set_cken(CKEN_AC97, 1); + pxa_set_cken(CKEN2_AC97, 1); return 0; } @@ -296,14 +296,14 @@ static int pxa2xx_ac97_probe(struct platform_device *pdev) /* Use GPIO 113 as AC97 Reset on Bulverde */ pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); #endif - pxa_set_cken(CKEN_AC97, 1); + pxa_set_cken(CKEN2_AC97, 1); return 0; err: - if (CKEN & CKEN_AC97) { + if (CKEN & CKEN2_AC97) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + pxa_set_cken(CKEN2_AC97, 0); } return ret; } @@ -312,7 +312,7 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev) { GCR |= GCR_ACLINK_OFF; free_irq(IRQ_AC97, NULL); - pxa_set_cken(CKEN_AC97, 0); + pxa_set_cken(CKEN2_AC97, 0); } static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, diff --git a/trunk/sound/soc/pxa/pxa2xx-i2s.c b/trunk/sound/soc/pxa/pxa2xx-i2s.c index 50c5c83f67db..575a6137c040 100644 --- a/trunk/sound/soc/pxa/pxa2xx-i2s.c +++ b/trunk/sound/soc/pxa/pxa2xx-i2s.c @@ -149,7 +149,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, pxa_gpio_mode(gpio_bus[pxa_i2s.master].tx); pxa_gpio_mode(gpio_bus[pxa_i2s.master].frm); pxa_gpio_mode(gpio_bus[pxa_i2s.master].clk); - pxa_set_cken(CKEN_I2S, 1); + pxa_set_cken(CKEN8_I2S, 1); pxa_i2s_wait(); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) @@ -234,7 +234,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream) if (SACR1 & (SACR1_DREC | SACR1_DRPL)) { SACR0 &= ~SACR0_ENB; pxa_i2s_wait(); - pxa_set_cken(CKEN_I2S, 0); + pxa_set_cken(CKEN8_I2S, 0); } } diff --git a/trunk/usr/Kconfig b/trunk/usr/Kconfig index 86cecb59dd07..07727f3c7cea 100644 --- a/trunk/usr/Kconfig +++ b/trunk/usr/Kconfig @@ -17,7 +17,7 @@ config INITRAMFS_SOURCE When multiple directories and files are specified then the initramfs image will be the aggregate of all of them. - See for more details. + See