diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/Documentation/filesystems/pramfs.txt linux-current/Documentation/filesystems/pramfs.txt *** linux-2.6.10/Documentation/filesystems/pramfs.txt Thu Jan 1 09:00:00 1970 --- linux-current/Documentation/filesystems/pramfs.txt Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,183 ---- + PRAMFS Overview + =============== + + Many embedded systems have a block of non-volatile RAM seperate from + normal system memory, i.e. of which the kernel maintains no memory page + descriptors. For such systems it would be beneficial to mount a + fast read/write filesystem over this "I/O memory", for storing frequently + accessed data that must survive system reboots and power cycles. An + example usage might be system logs under /var/log, or a user address + book in a cell phone or PDA. + + Linux traditionally had no support for a persistent, non-volatile RAM-based + filesystem, persistent meaning the filesystem survives a system reboot + or power cycle intact. The RAM-based filesystems such as tmpfs and ramfs + have no actual backing store but exist entirely in the page and buffer + caches, hence the filesystem disappears after a system reboot or + power cycle. + + A relatively straight-forward solution is to write a simple block driver + for the non-volatile RAM, and mount over it any disk-based filesystem such + as ext2/ext3, reiserfs, etc. + + But the disk-based fs over non-volatile RAM block driver approach has + some drawbacks: + + 1. Disk-based filesystems such as ext2/ext3 were designed for optimum + performance on spinning disk media, so they implement features such + as block groups, which attempts to group inode data into a contiguous + set of data blocks to minimize disk seeking when accessing files. For + RAM there is no such concern; a file's data blocks can be scattered + throughout the media with no access speed penalty at all. So block + groups in a filesystem mounted over RAM just adds unnecessary + complexity. A better approach is to use a filesystem specifically + tailored to RAM media which does away with these disk-based features. + This increases the efficient use of space on the media, i.e. more + space is dedicated to actual file data storage and less to meta-data + needed to maintain that file data. + + 2. If the backing-store RAM is comparable in access speed to system memory, + there's really no point in caching the file I/O data in the page + cache. Better to move file data directly between the user buffers + and the backing store RAM, i.e. use direct I/O. This prevents the + unnecessary populating of the page cache with dirty pages. However + direct I/O has to be enabled at every file open. To enable direct + I/O at all times for all regular files requires either that + applications be modified to include the O_DIRECT flag on all file + opens, or that a new filesystem be used that always performs direct + I/O by default. + + The Persistent/Protected RAM Special Filesystem (PRAMFS) is a + full-featured read/write filesystem that has been designed to address + these issues. PRAMFS is targeted to fast I/O memory, and if the memory + is non-volatile, the filesystem will be persistent. + + In PRAMFS, direct I/O is enabled across all files in the filesystem, in + other words the O_DIRECT flag is forced on every open of a PRAMFS file. + Also, file I/O in the PRAMFS is always synchronous. There is no need + to block the current process while the transfer to/from the PRAMFS + is in progress, since one of the requirements of the PRAMFS is that the + filesystem exist in fast RAM. So file I/O in PRAMFS is always direct, + synchronous, and never blocks. + + The data organization in PRAMFS can be thought of as an extremely + simplified version of ext2, such that the ratio of data to meta-data is + very high. + + PRAMFS is also write protected. The page table entries that map the + backing-store RAM are normally marked read-only. Write operations into + the filesystem temporarily mark the affected pages as writeable, the + write operation is carried out with locks held, and then the pte is + marked read-only again. This feature provides some protection against + filesystem corruption caused by errant writes into the RAM due to + kernel bugs for instance. In case there are systems where the write + protection is not possible (for instance the RAM cannot be mapped + with page tables), this feature can be disabled with the CONFIG_PRAMFS_NOWP + config option. + + In summary, PRAMFS is a light-weight, full-featured, and space-efficient + special filesystem that is ideal for systems with a block of fast + non-volatile RAM that need to access data on it using a standard + filesytem interface. + + + Supported mount options + ======================= + + The PRAMFS currently requires one mount option, and there are several + optional mount options: + + physaddr= Required. It tells PRAMFS the physical address of the + start of the RAM that makes up the filesystem. The + physical address must be located on a page boundary. + + init= Optional. It is used to initialize the memory to an + empty filesystem. Any data in an existing filesystem + will be lost if this option is given. The parameter to + "init=" is the RAM size in bytes. + + bs= Optional. It is used to specify a block size. It is + ignored if the "init=" option is not specified, since + otherwise the block size is read from the PRAMFS + super-block. The default blocksize is 2048 bytes, + and the allowed block sizes are 512, 1024, 2048, and + 4096. + + bpi= Optional. It is used to specify the bytes per inode + ratio, i.e. For every N bytes in the filesystem, an + inode will be created. This behaves the same as the "-i" + option to mke2fs. It is ignored if the "init=" option is + not specified. + + N= Optional. It is used to specify the number of inodes to + allocate in the inode table. If the option is not + specified, the bytes-per-inode ratio is used the + calculate the number of inodes. If neither the "N=" or + "bpi=" options are specified, the default behavior is to + reserve 5% of the total space in the filesystem for the + inode table. This option behaves the same as the "-N" + option to mke2fs. It is ignored if the "init=" option is + not specified. + + Examples: + + mount -t pramfs -o physaddr=0x20000000,init=0x2F000,bs=1024 none /mnt/pram + + This example locates the filesystem at physical address 0x20000000, and + also requests an empty filesystem be initialized, of total size 0x2f000 + bytes and blocksize 1024. The mount point is /mnt/pram. + + mount -t pramfs -o physaddr=0x20000000 none /mnt/pram + + This example locates the filesystem at physical address 0x20000000 as in + the first example, but uses the intact filesystem that already exists. + + + Current Limitations + =================== + + - The RAM used for PRAMFS must be directly addressable. + + - PRAMFS does not support hard links. + + - PRAMFS supports only private memory mappings. This allows most + executables to run, but programs that attempt shared memory + mappings, such as X apps that use X shared memory, will fail. + + Further Documentation + ===================== + + If you are interested in the internal design of PRAMFS, there is + documentation available at the Sourceforge PRAMFS home page at + http://pramfs.sourceforge.net. + + Please send bug reports/comments/feed back to the pramfs development + list at sourceforge: pramfs-devel@lists.sourceforge.net. + + + ChangeLog + ========= + + 1.0.3: + - kernel 2.6.9. + - __ioremap() definition not consistent across archs, use + ioremap() instead. + - flush_tlb_kernel_page() is only available on some archs. + - fixed bug in pram_fill_super(): root inode pointer needs + to be recalculated after remapping whole fs. + 1.0.2: + - kernel 2.6.4. + - use pram_truncate() in pram_delete_inode(). + - dangling pram_lock_inode() removed in pram_truncate_blocks(). + - edits to this README + + 1.0.1: + - port to kernel 2.6.3. + - implement direct_IO() method instead of custom file read/write + methods. + - do away with __ioremap_readonly() requirement. + - implement inode truncate() method. + + 1.0.0: + - Started ChangeLog (kernel 2.4.22). + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/Documentation/filesystems/relayfs.txt linux-current/Documentation/filesystems/relayfs.txt *** linux-2.6.10/Documentation/filesystems/relayfs.txt Thu Jan 1 09:00:00 1970 --- linux-current/Documentation/filesystems/relayfs.txt Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,812 ---- + + relayfs - a high-speed data relay filesystem + ============================================ + + relayfs is a filesystem designed to provide an efficient mechanism for + tools and facilities to relay large amounts of data from kernel space + to user space. + + The main idea behind relayfs is that every data flow is put into a + separate "channel" and each channel is a file. In practice, each + channel is a separate memory buffer allocated from within kernel space + upon channel instantiation. Software needing to relay data to user + space would open a channel or a number of channels, depending on its + needs, and would log data to that channel. All the buffering and + locking mechanics are taken care of by relayfs. The actual format and + protocol used for each channel is up to relayfs' clients. + + relayfs makes no provisions for copying the same data to more than a + single channel. This is for the clients of the relay to take care of, + and so is any form of data filtering. The purpose is to keep relayfs + as simple as possible. + + + Usage + ===== + + In addition to the relayfs kernel API described below, relayfs + implements basic file operations. Here are the file operations that + are available and some comments regarding their behavior: + + open() enables user to open an _existing_ channel. A channel can be + opened in blocking or non-blocking mode, and can be opened + for reading as well as for writing. Readers will by default + be auto-consuming. + + mmap() results in channel's memory buffer being mmapped into the + caller's memory space. + + read() since we are dealing with circular buffers, the user is only + allowed to read forward. Some apps may want to loop around + read() waiting for incoming data - if there is no data + available, read will put the reader on a wait queue until + data is available (blocking mode). Non-blocking reads return + -EAGAIN if data is not available. + + + write() writing from user space operates exactly as relay_write() does + (described below). + + poll() POLLIN/POLLRDNORM/POLLOUT/POLLWRNORM/POLLERR supported. + + close() decrements the channel's refcount. When the refcount reaches + 0 i.e. when no process or kernel client has the file open + (see relay_close() below), the channel buffer is freed. + + + In order for a user application to make use of relayfs files, the + relayfs filesystem must be mounted. For example, + + mount -t relayfs relayfs /mountpoint + + + The relayfs kernel API + ====================== + + relayfs channels are implemented as circular buffers subdivided into + 'sub-buffers'. kernel clients write data into the channel using + relay_write(), and are notified via a set of callbacks when + significant events occur within the channel. 'Significant events' + include: + + - a sub-buffer has been filled i.e. the current write won't fit into the + current sub-buffer, and a 'buffer-switch' is triggered, after which + the data is written into the next buffer (if the next buffer is + empty). The client is notified of this condition via two callbacks, + one providing an opportunity to perform start-of-buffer tasks, the + other end-of-buffer tasks. + + - data is ready for the client to process. The client can choose to + be notified either on a per-sub-buffer basis (bulk delivery) or + per-write basis (packet delivery). + + - data has been written to the channel from user space. The client can + use this notification to accept and process 'commands' sent to the + channel via write(2). + + - the channel has been opened/closed/mapped/unmapped from user space. + The client can use this notification to trigger actions within the + kernel application, such as enabling/disabling logging to the + channel. It can also return result codes from the callback, + indicating that the operation should fail e.g. in order to restrict + more than one user space open or mmap. + + - the channel needs resizing, or needs to update its + state based on the results of the resize. Resizing the channel is + up to the kernel client to actually perform. If the channel is + configured for resizing, the client is notified when the unread data + in the channel passes a preset threshold, giving it the opportunity + to allocate a new channel buffer and replace the old one. + + Reader objects + -------------- + + Channel readers use an opaque rchan_reader object to read from + channels. For VFS readers (those using read(2) to read from a + channel), these objects are automatically created and used internally; + only kernel clients that need to directly read from channels, or whose + userspace applications use mmap to access channel data, need to know + anything about rchan_readers - others may skip this section. + + A relay channel can have any number of readers, each represented by an + rchan_reader instance, which is used to encapsulate reader settings + and state. rchan_reader objects should be treated as opaque by kernel + clients. To create a reader object for directly accessing a channel + from kernel space, call the add_rchan_reader() kernel API function: + + rchan_reader *add_rchan_reader(rchan_id, auto_consume) + + This function returns an rchan_reader instance if successful, which + should then be passed to relay_read() when the kernel client is + interested in reading from the channel. + + The auto_consume parameter indicates whether a read done by this + reader will automatically 'consume' that portion of the unread channel + buffer when relay_read() is called (see below for more details). + + To close the reader, call + + remove_rchan_reader(reader) + + which will remove the reader from the list of current readers. + + + To create a reader object representing a userspace mmap reader in the + kernel application, call the add_map_reader() kernel API function: + + rchan_reader *add_map_reader(rchan_id) + + This function returns an rchan_reader instance if successful, whose + main purpose is as an argument to be passed into + relay_buffers_consumed() when the kernel client becomes aware that + data has been read by a user application using mmap to read from the + channel buffer. There is no auto_consume option in this case, since + only the kernel client/user application knows when data has been read. + + To close the map reader, call + + remove_map_reader(reader) + + which will remove the reader from the list of current readers. + + Consumed count + -------------- + + A relayfs channel is a circular buffer, which means that if there is + no reader reading from it or a reader reading too slowly, at some + point the channel writer will 'lap' the reader and data will be lost. + In normal use, readers will always be able to keep up with writers and + the buffer is thus never in danger of becoming full. In many + applications, it's sufficient to ensure that this is practically + speaking always the case, by making the buffers large enough. These + types of applications can basically open the channel as + RELAY_MODE_CONTINOUS (the default anyway) and not worry about the + meaning of 'consume' and skip the rest of this section. + + If it's important for the application that a kernel client never allow + writers to overwrite unread data, the channel should be opened using + RELAY_MODE_NO_OVERWRITE and must be kept apprised of the count of + bytes actually read by the (typically) user-space channel readers. + This count is referred to as the 'consumed count'. read(2) channel + readers automatically update the channel's 'consumed count' as they + read. If the usage mode is to have only read(2) readers, which is + typically the case, the kernel client doesn't need to worry about any + of the relayfs functions having to do with 'bytes consumed' and can + skip the rest of this section. (Note that it is possible to have + multiple read(2) or auto-consuming readers, but like having multiple + readers on a pipe, these readers will race with each other i.e. it's + supported, but doesn't make much sense). + + If the kernel client cannot rely on an auto-consuming reader to keep + the 'consumed count' up-to-date, then it must do so manually, by + making the appropriate calls to relay_buffers_consumed() or + relay_bytes_consumed(). In most cases, this should only be necessary + for bulk mmap clients - almost all packet clients should be covered by + having auto-consuming read(2) readers. For mmapped bulk clients, for + instance, there are no auto-consuming VFS readers, so the kernel + client needs to make the call to relay_buffers_consumed() after + sub-buffers are read. + + Kernel API + ---------- + + Here's a summary of the API relayfs provides to in-kernel clients: + + int relay_open(channel_path, bufsize, nbufs, channel_flags, + channel_callbacks, start_reserve, end_reserve, + rchan_start_reserve, resize_min, resize_max, mode, + init_buf, init_buf_size) + int relay_write(channel_id, *data_ptr, count, time_delta_offset, **wrote) + rchan_reader *add_rchan_reader(channel_id, auto_consume) + int remove_rchan_reader(rchan_reader *reader) + rchan_reader *add_map_reader(channel_id) + int remove_map_reader(rchan_reader *reader) + int relay_read(reader, buf, count, wait, *actual_read_offset) + void relay_buffers_consumed(reader, buffers_consumed) + void relay_bytes_consumed(reader, bytes_consumed, read_offset) + int relay_bytes_avail(reader) + int rchan_full(reader) + int rchan_empty(reader) + int relay_info(channel_id, *channel_info) + int relay_close(channel_id) + int relay_realloc_buffer(channel_id, nbufs, async) + int relay_replace_buffer(channel_id) + int relay_reset(int rchan_id) + + ---------- + int relay_open(channel_path, bufsize, nbufs, + channel_flags, channel_callbacks, start_reserve, + end_reserve, rchan_start_reserve, resize_min, resize_max, mode) + + relay_open() is used to create a new entry in relayfs. This new entry + is created according to channel_path. channel_path contains the + absolute path to the channel file on relayfs. If, for example, the + caller sets channel_path to "/xlog/9", a "xlog/9" entry will appear + within relayfs automatically and the "xlog" directory will be created + in the filesystem's root. relayfs does not implement any policy on + its content, except to disallow the opening of two channels using the + same file. There are, nevertheless a set of guidelines for using + relayfs. Basically, each facility using relayfs should use a top-level + directory identifying it. The entry created above, for example, + presumably belongs to the "xlog" software. + + The remaining parameters for relay_open() are as follows: + + - channel_flags - an ORed combination of attribute values controlling + common channel characteristics: + + - logging scheme - relayfs use 2 mutually exclusive schemes + for logging data to a channel. The 'lockless scheme' + reserves and writes data to a channel without the need of + any type of locking on the channel. This is the preferred + scheme, but may not be available on a given architecture (it + relies on the presence of a cmpxchg instruction). It's + specified by the RELAY_SCHEME_LOCKLESS flag. The 'locking + scheme' either obtains a lock on the channel for writing or + disables interrupts, depending on whether the channel was + opened for SMP or global usage (see below). It's specified + by the RELAY_SCHEME_LOCKING flag. While a client may want + to explicitly specify a particular scheme to use, it's more + convenient to specify RELAY_SCHEME_ANY for this flag, which + will allow relayfs to choose the best available scheme i.e. + lockless if supported. + + - overwrite mode (default is RELAY_MODE_CONTINUOUS) - + If RELAY_MODE_CONTINUOUS is specified, writes to the channel + will succeed regardless of whether there are up-to-date + consumers or not. If RELAY_MODE_NO_OVERWRITE is specified, + the channel becomes 'full' when the total amount of buffer + space unconsumed by readers equals or exceeds the total + buffer size. With the buffer in this state, writes to the + buffer will fail - clients need to check the return code from + relay_write() to determine if this is the case and act + accordingly - 0 or a negative value indicate the write failed. + + - SMP usage - this applies only when the locking scheme is in + use. If RELAY_USAGE_SMP is specified, it's assumed that the + channel will be used in a per-CPU fashion and consequently, + the only locking that will be done for writes is to disable + local irqs. If RELAY_USAGE_GLOBAL is specified, it's assumed + that writes to the buffer can occur within any CPU context, + and spinlock_irq_save will be used to lock the buffer. + + - delivery mode - if RELAY_DELIVERY_BULK is specified, the + client will be notified via its deliver() callback whenever a + sub-buffer has been filled. Alternatively, + RELAY_DELIVERY_PACKET will cause delivery to occur after the + completion of each write. See the description of the channel + callbacks below for more details. + + - timestamping - if RELAY_TIMESTAMP_TSC is specified and the + architecture supports it, efficient TSC 'timestamps' can be + associated with each write, otherwise more expensive + gettimeofday() timestamping is used. At the beginning of + each sub-buffer, a gettimeofday() timestamp and the current + TSC, if supported, are read, and are passed on to the client + via the buffer_start() callback. This allows correlation of + the current time with the current TSC for subsequent writes. + Each subsequent write is associated with a 'time delta', + which is either the current TSC, if the channel is using + TSCs, or the difference between the buffer_start gettimeofday + timestamp and the gettimeofday time read for the current + write. Note that relayfs never writes either a timestamp or + time delta into the buffer unless explicitly asked to (see + the description of relay_write() for details). + + - bufsize - the size of the 'sub-buffers' making up the circular channel + buffer. For the lockless scheme, this must be a power of 2. + + - nbufs - the number of 'sub-buffers' making up the circular + channel buffer. This must be a power of 2. + + The total size of the channel buffer is bufsize * nbufs rounded up + to the next kernel page size. If the lockless scheme is used, both + bufsize and nbufs must be a power of 2. If the locking scheme is + used, the bufsize can be anything and nbufs must be a power of 2. If + RELAY_SCHEME_ANY is used, the bufsize and nbufs should be a power of 2. + + NOTE: if nbufs is 1, relayfs will bypass the normal size + checks and will allocate an rvmalloced buffer of size bufsize. + This buffer will be freed when relay_close() is called, if the channel + isn't still being referenced. + + - callbacks - a table of callback functions called when events occur + within the data relay that clients need to know about: + + - int buffer_start(channel_id, current_write_pos, buffer_id, + start_time, start_tsc, using_tsc) - + + called at the beginning of a new sub-buffer, the + buffer_start() callback gives the client an opportunity to + write data into space reserved at the beginning of a + sub-buffer. The client should only write into the buffer + if it specified a value for start_reserve and/or + channel_start_reserve (see below) when the channel was + opened. In the latter case, the client can determine + whether to write its one-time rchan_start_reserve data by + examining the value of buffer_id, which will be 0 for the + first sub-buffer. The address that the client can write + to is contained in current_write_pos (the client by + definition knows how much it can write i.e. the value it + passed to relay_open() for start_reserve/ + channel_start_reserve). start_time contains the + gettimeofday() value for the start of the buffer and start + TSC contains the TSC read at the same time. The using_tsc + param indicates whether or not start_tsc is valid (it + wouldn't be if TSC timestamping isn't being used). + + The client should return the number of bytes it wrote to + the channel, 0 if none. + + - int buffer_end(channel_id, current_write_pos, end_of_buffer, + end_time, end_tsc, using_tsc) + + called at the end of a sub-buffer, the buffer_end() + callback gives the client an opportunity to perform + end-of-buffer processing. Note that the current_write_pos + is the position where the next write would occur, but + since the current write wouldn't fit (which is the trigger + for the buffer_end event), the buffer is considered full + even though there may be unused space at the end. The + end_of_buffer param pointer value can be used to determine + exactly the size of the unused space. The client should + only write into the buffer if it specified a value for + end_reserve when the channel was opened. If the client + doesn't write anything i.e. returns 0, the unused space at + the end of the sub-buffer is available via relay_info() - + this data may be needed by the client later if it needs to + process raw sub-buffers (an alternative would be to save + the unused bytes count value in end_reserve space at the + end of each sub-buffer during buffer_end processing and + read it when needed at a later time. The other + alternative would be to use read(2), which makes the + unused count invisible to the caller). end_time contains + the gettimeofday() value for the end of the buffer and end + TSC contains the TSC read at the same time. The using_tsc + param indicates whether or not end_tsc is valid (it + wouldn't be if TSC timestamping isn't being used). + + The client should return the number of bytes it wrote to + the channel, 0 if none. + + - void deliver(channel_id, from, len) + + called when data is ready for the client. This callback + is used to notify a client when a sub-buffer is complete + (in the case of bulk delivery) or a single write is + complete (packet delivery). A bulk delivery client might + wish to then signal a daemon that a sub-buffer is ready. + A packet delivery client might wish to process the packet + or send it elsewhere. The from param is a pointer to the + delivered data and len specifies how many bytes are ready. + + - void user_deliver(channel_id, from, len) + + called when data has been written to the channel from user + space. This callback is used to notify a client when a + successful write from userspace has occurred, independent + of whether bulk or packet delivery is in use. This can be + used to allow userspace programs to communicate with the + kernel client through the channel via out-of-band write(2) + 'commands' instead of via ioctls, for instance. The from + param is a pointer to the delivered data and len specifies + how many bytes are ready. Note that this callback occurs + after the bytes have been successfully written into the + channel, which means that channel readers must be able to + deal with the 'command' data which will appear in the + channel data stream just as any other userspace or + non-userspace write would. + + - int needs_resize(channel_id, resize_type, + suggested_buf_size, suggested_n_bufs) + + called when a channel's buffers are in danger of becoming + full i.e. the number of unread bytes in the channel passes + a preset threshold, or when the current capacity of a + channel's buffer is no longer needed. Also called to + notify the client when a channel's buffer has been + replaced. If resize_type is RELAY_RESIZE_EXPAND or + RELAY_RESIZE_SHRINK, the kernel client should arrange to + call relay_realloc_buffer() with the suggested buffer size + and buffer count, which will allocate (but will not + replace the old one) a new buffer of the recommended size + for the channel. When the allocation has completed, + needs_resize() is again called, this time with a + resize_type of RELAY_RESIZE_REPLACE. The kernel client + should then arrange to call relay_replace_buffer() to + actually replace the old channel buffer with the newly + allocated buffer. Finally, once the buffer replacement + has completed, needs_resize() is again called, this time + with a resize_type of RELAY_RESIZE_REPLACED, to inform the + client that the replacement is complete and additionally + confirming the current sub-buffer size and number of + sub-buffers. Note that a resize can be canceled if + relay_realloc_buffer() is called with the async param + non-zero and the resize conditions no longer hold. In + this case, the RELAY_RESIZE_REPLACED suggested number of + sub-buffers will be the same as the number of sub-buffers + that existed before the RELAY_RESIZE_SHRINK or EXPAND i.e. + values indicating that the resize didn't actually occur. + + - int fileop_notify(channel_id, struct file *filp, enum relay_fileop) + + called when a userspace file operation has occurred or + will occur on a relayfs channel file. These notifications + can be used by the kernel client to trigger actions within + the kernel client when the corresponding event occurs, + such as enabling logging only when a userspace application + opens or mmaps a relayfs file and disabling it again when + the file is closed or unmapped. The kernel client can + also return its own return value, which can affect the + outcome of file operation - returning 0 indicates that the + operation should succeed, and returning a negative value + indicates that the operation should be failed, and that + the returned value should be returned to the ultimate + caller e.g. returning -EPERM from the open fileop will + cause the open to fail with -EPERM. Among other things, + the return value can be used to restrict a relayfs file + from being opened or mmap'ed more than once. The currently + implemented fileops are: + + RELAY_FILE_OPEN - a relayfs file is being opened. Return + 0 to allow it to succeed, negative to + have it fail. A negative return value will + be passed on unmodified to the open fileop. + RELAY_FILE_CLOSE- a relayfs file is being closed. The return + value is ignored. + RELAY_FILE_MAP - a relayfs file is being mmap'ed. Return 0 + to allow it to succeed, negative to have + it fail. A negative return value will be + passed on unmodified to the mmap fileop. + RELAY_FILE_UNMAP- a relayfs file is being unmapped. The return + value is ignored. + + - void ioctl(rchan_id, cmd, arg) + + called when an ioctl call is made using a relayfs file + descriptor. The cmd and arg are passed along to this + callback unmodified for it to do as it wishes with. The + return value from this callback is used as the return value + of the ioctl call. + + If the callbacks param passed to relay_open() is NULL, a set of + default do-nothing callbacks will be defined for the channel. + Likewise, any NULL rchan_callback function contained in a non-NULL + callbacks struct will be filled in with a default callback function + that does nothing. + + - start_reserve - the number of bytes to be reserved at the start of + each sub-buffer. The client can do what it wants with this number + of bytes when the buffer_start() callback is invoked. Typically + clients would use this to write per-sub-buffer header data. + + - end_reserve - the number of bytes to be reserved at the end of each + sub-buffer. The client can do what it wants with this number of + bytes when the buffer_end() callback is invoked. Typically clients + would use this to write per-sub-buffer footer data. + + - channel_start_reserve - the number of bytes to be reserved, in + addition to start_reserve, at the beginning of the first sub-buffer + in the channel. The client can do what it wants with this number of + bytes when the buffer_start() callback is invoked. Typically + clients would use this to write per-channel header data. + + - resize_min - if set, this signifies that the channel is + auto-resizeable. The value specifies the size that the channel will + try to maintain as a normal working size, and that it won't go + below. The client makes use of the resizing callbacks and + relay_realloc_buffer() and relay_replace_buffer() to actually effect + the resize. + + - resize_max - if set, this signifies that the channel is + auto-resizeable. The value specifies the maximum size the channel + can have as a result of resizing. + + - mode - if non-zero, specifies the file permissions that will be given + to the channel file. If 0, the default rw user perms will be used. + + - init_buf - if non-NULL, rather than allocating the channel buffer, + this buffer will be used as the initial channel buffer. The kernel + API function relay_discard_init_buf() can later be used to have + relayfs allocate a normal mmappable channel buffer and switch over + to using it after copying the init_buf contents into it. Currently, + the size of init_buf must be exactly buf_size * n_bufs. The caller + is responsible for managing the init_buf memory. This feature is + typically used for init-time channel use and should normally be + specified as NULL. + + - init_buf_size - the total size of init_buf, if init_buf is specified + as non-NULL. Currently, the size of init_buf must be exactly + buf_size * n_bufs. + + Upon successful completion, relay_open() returns a channel id + to be used for all other operations with the relay. All buffers + managed by the relay are allocated using rvmalloc/rvfree to allow + for easy mmapping to user-space. + + ---------- + int relay_write(channel_id, *data_ptr, count, time_delta_offset, **wrote_pos) + + relay_write() reserves space in the channel and writes count bytes of + data pointed to by data_ptr to it. Automatically performs any + necessary locking, depending on the scheme and SMP usage in effect (no + locking is done for the lockless scheme regardless of usage). It + returns the number of bytes written, or 0/negative on failure. If + time_delta_offset is >= 0, the internal time delta, the internal time + delta calculated when the slot was reserved will be written at that + offset. This is the TSC or gettimeofday() delta between the current + write and the beginning of the buffer, whichever method is being used + by the channel. Trying to write a count larger than the bufsize + specified to relay_open() (taking into account the reserved + start-of-buffer and end-of-buffer space as well) will fail. If + wrote_pos is non-NULL, it will receive the location the data was + written to, which may be needed for some applications but is not + normally interesting. Most applications should pass in NULL for this + param. + + ---------- + struct rchan_reader *add_rchan_reader(int rchan_id, int auto_consume) + + add_rchan_reader creates and initializes a reader object for a + channel. An opaque rchan_reader object is returned on success, and is + passed to relay_read() when reading the channel. If the boolean + auto_consume parameter is 1, the reader is defined to be + auto-consuming. auto-consuming reader objects are automatically + created and used for VFS read(2) readers. + + ---------- + void remove_rchan_reader(struct rchan_reader *reader) + + remove_rchan_reader finds and removes the given reader from the + channel. This function is used only by non-VFS read(2) readers. VFS + read(2) readers are automatically removed when the corresponding file + object is closed. + + ---------- + reader add_map_reader(int rchan_id) + + Creates and initializes an rchan_reader object for channel map + readers, and is needed for updating relay_bytes/buffers_consumed() + when kernel clients become aware of the need to do so by their mmap + user clients. + + ---------- + int remove_map_reader(reader) + + Finds and removes the given map reader from the channel. This function + is useful only for map readers. + + ---------- + int relay_read(reader, buf, count, wait, *actual_read_offset) + + Reads count bytes from the channel, or as much as is available within + the sub-buffer currently being read. The read offset that will be + read from is the position contained within the reader object. If the + wait flag is set, buf is non-NULL, and there is nothing available, it + will wait until there is. If the wait flag is 0 and there is nothing + available, -EAGAIN is returned. If buf is NULL, the value returned is + the number of bytes that would have been read. actual_read_offset is + the value that should be passed as the read offset to + relay_bytes_consumed, needed only if the reader is not auto-consuming + and the channel is MODE_NO_OVERWRITE, but in any case, it must not be + NULL. + + ---------- + + int relay_bytes_avail(reader) + + Returns the number of bytes available relative to the reader's current + read position within the corresponding sub-buffer, 0 if there is + nothing available. Note that this doesn't return the total bytes + available in the channel buffer - this is enough though to know if + anything is available, however, or how many bytes might be returned + from the next read. + + ---------- + void relay_buffers_consumed(reader, buffers_consumed) + + Adds to the channel's consumed buffer count. buffers_consumed should + be the number of buffers newly consumed, not the total number + consumed. NOTE: kernel clients don't need to call this function if + the reader is auto-consuming or the channel is MODE_CONTINUOUS. + + In order for the relay to detect the 'buffers full' condition for a + channel, it must be kept up-to-date with respect to the number of + buffers consumed by the client. If the addition of the value of the + bufs_consumed param to the current bufs_consumed count for the channel + would exceed the bufs_produced count for the channel, the channel's + bufs_consumed count will be set to the bufs_produced count for the + channel. This allows clients to 'catch up' if necessary. + + ---------- + void relay_bytes_consumed(reader, bytes_consumed, read_offset) + + Adds to the channel's consumed count. bytes_consumed should be the + number of bytes actually read e.g. return value of relay_read() and + the read_offset should be the actual offset the bytes were read from + e.g. the actual_read_offset set by relay_read(). NOTE: kernel clients + don't need to call this function if the reader is auto-consuming or + the channel is MODE_CONTINUOUS. + + In order for the relay to detect the 'buffers full' condition for a + channel, it must be kept up-to-date with respect to the number of + bytes consumed by the client. For packet clients, it makes more sense + to update after each read rather than after each complete sub-buffer + read. The bytes_consumed count updates bufs_consumed when a buffer + has been consumed so this count remains consistent. + + ---------- + int relay_info(channel_id, *channel_info) + + relay_info() fills in an rchan_info struct with channel status and + attribute information such as usage modes, sub-buffer size and count, + the allocated size of the entire buffer, buffers produced and + consumed, current buffer id, count of writes lost due to buffers full + condition. + + The virtual address of the channel buffer is also available here, for + those clients that need it. + + Clients may need to know how many 'unused' bytes there are at the end + of a given sub-buffer. This would only be the case if the client 1) + didn't either write this count to the end of the sub-buffer or + otherwise note it (it's available as the difference between the buffer + end and current write pos params in the buffer_end callback) (if the + client returned 0 from the buffer_end callback, it's assumed that this + is indeed the case) 2) isn't using the read() system call to read the + buffer. In other words, if the client isn't annotating the stream and + is reading the buffer by mmaping it, this information would be needed + in order for the client to 'skip over' the unused bytes at the ends of + sub-buffers. + + Additionally, for the lockless scheme, clients may need to know + whether a particular sub-buffer is actually complete. An array of + boolean values, one per sub-buffer, contains non-zero if the buffer is + complete, non-zero otherwise. + + ---------- + int relay_close(channel_id) + + relay_close() is used to close the channel. It finalizes the last + sub-buffer (the one currently being written to) and marks the channel + as finalized. The channel buffer and channel data structure are then + freed automatically when the last reference to the channel is given + up. + + ---------- + int relay_realloc_buffer(channel_id, nbufs, async) + + Allocates a new channel buffer using the specified sub-buffer count + (note that resizing can't change sub-buffer sizes). If async is + non-zero, the allocation is done in the background using a work queue. + When the allocation has completed, the needs_resize() callback is + called with a resize_type of RELAY_RESIZE_REPLACE. This function + doesn't replace the old buffer with the new - see + relay_replace_buffer(). + + This function is called by kernel clients in response to a + needs_resize() callback call with a resize type of RELAY_RESIZE_EXPAND + or RELAY_RESIZE_SHRINK. That callback also includes a suggested + new_bufsize and new_nbufs which should be used when calling this + function. + + Returns 0 on success, or errcode if the channel is busy or if + the allocation couldn't happen for some reason. + + NOTE: if async is not set, this function should not be called with a + lock held, as it may sleep. + + ---------- + int relay_replace_buffer(channel_id) + + Replaces the current channel buffer with the new buffer allocated by + relay_realloc_buffer and contained in the channel struct. When the + replacement is complete, the needs_resize() callback is called with + RELAY_RESIZE_REPLACED. This function is called by kernel clients in + response to a needs_resize() callback having a resize type of + RELAY_RESIZE_REPLACE. + + Returns 0 on success, or errcode if the channel is busy or if the + replacement or previous allocation didn't happen for some reason. + + NOTE: This function will not sleep, so can called in any context and + with locks held. The client should, however, ensure that the channel + isn't actively being read from or written to. + + ---------- + int relay_reset(rchan_id) + + relay_reset() has the effect of erasing all data from the buffer and + restarting the channel in its initial state. The buffer itself is not + freed, so any mappings are still in effect. NOTE: Care should be + taken that the channnel isn't actually being used by anything when + this call is made. + + ---------- + int rchan_full(reader) + + returns 1 if the channel is full with respect to the reader, 0 if not. + + ---------- + int rchan_empty(reader) + + returns 1 if the channel is empty with respect to the reader, 0 if not. + + ---------- + int relay_discard_init_buf(rchan_id) + + allocates an mmappable channel buffer, copies the contents of init_buf + into it, and sets the current channel buffer to the newly allocated + buffer. This function is used only in conjunction with the init_buf + and init_buf_size params to relay_open(), and is typically used when + the ability to write into the channel at init-time is needed. The + basic usage is to specify an init_buf and init_buf_size to relay_open, + then call this function when it's safe to switch over to a normally + allocated channel buffer. 'Safe' means that the caller is in a + context that can sleep and that nothing is actively writing to the + channel. Returns 0 if successful, negative otherwise. + + + Writing directly into the channel + ================================= + + Using the relay_write() API function as described above is the + preferred means of writing into a channel. In some cases, however, + in-kernel clients might want to write directly into a relay channel + rather than have relay_write() copy it into the buffer on the client's + behalf. Clients wishing to do this should follow the model used to + implement relay_write itself. The general sequence is: + + - get a pointer to the channel via rchan_get(). This increments the + channel's reference count. + - call relay_lock_channel(). This will perform the proper locking for + the channel given the scheme in use and the SMP usage. + - reserve a slot in the channel via relay_reserve() + - write directly to the reserved address + - call relay_commit() to commit the write + - call relay_unlock_channel() + - call rchan_put() to release the channel reference + + In particular, clients should make sure they call rchan_get() and + rchan_put() and not hold on to references to the channel pointer. + Also, forgetting to use relay_lock_channel()/relay_unlock_channel() + has no effect if the lockless scheme is being used, but could result + in corrupted buffer contents if the locking scheme is used. + + + Limitations + =========== + + Writes made via the write() system call are currently limited to 2 + pages worth of data. There is no such limit on the in-kernel API + function relay_write(). + + User applications can currently only mmap the complete buffer (it + doesn't really make sense to mmap only part of it, given its purpose). + + + Latest version + ============== + + The latest version can be found at: + + http://www.opersys.com/relayfs + + Example relayfs clients, such as dynamic printk and the Linux Trace + Toolkit, can also be found there. + + + Credits + ======= + + The ideas and specs for relayfs came about as a result of discussions + on tracing involving the following: + + Michel Dagenais + Richard Moore + Bob Wisniewski + Karim Yaghmour + Tom Zanussi + + Also thanks to Hubertus Franke for a lot of useful suggestions and bug + reports, and for contributing the klog code. diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/MAINTAINERS linux-current/MAINTAINERS *** linux-2.6.10/MAINTAINERS Sat Dec 25 06:35:00 2004 --- linux-current/MAINTAINERS Wed Jun 14 21:12:58 2006 *************** *** 1363,1368 **** --- 1363,1375 ---- W: http://lsm.immunix.org S: Supported + LINUX TRACE TOOLKIT + P: Karim Yaghmour + M: karim@opersys.com + W: http://www.opersys.com/LTT + L: ltt-dev@listserv.shafik.org + S: Maintained + LM83 HARDWARE MONITOR DRIVER P: Jean Delvare M: khali@linux-fr.org diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/Makefile linux-current/Makefile *** linux-2.6.10/Makefile Sat Dec 25 06:35:01 2004 --- linux-current/Makefile Wed Jun 14 21:12:58 2006 *************** *** 167,175 **** # then ARCH is assigned, getting whatever value it gets normally, and # SUBARCH is subsequently ignored. ! SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ ! -e s/arm.*/arm/ -e s/sa110/arm/ \ ! -e s/s390x/s390/ -e s/parisc64/parisc/ ) # Cross compiling and selecting different set of gcc/bin-utils # --------------------------------------------------------------------------- --- 167,173 ---- # then ARCH is assigned, getting whatever value it gets normally, and # SUBARCH is subsequently ignored. ! SUBARCH := mips # Cross compiling and selecting different set of gcc/bin-utils # --------------------------------------------------------------------------- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/i386/kernel/entry.S linux-current/arch/i386/kernel/entry.S *** linux-2.6.10/arch/i386/kernel/entry.S Sat Dec 25 06:34:27 2004 --- linux-current/arch/i386/kernel/entry.S Wed Jun 14 21:12:58 2006 *************** *** 251,259 **** --- 251,277 ---- cmpl $(nr_syscalls), %eax jae syscall_badsys syscall_call: + #if (CONFIG_LTT) + movl syscall_entry_trace_active, %eax + cmpl $1, %eax # are we tracing system call entries + jne no_syscall_entry_trace + movl %esp, %eax # copy the stack pointer + pushl %eax # pass the stack pointer copy + call trace_real_syscall_entry + addl $4,%esp # return stack to state before pass + no_syscall_entry_trace: + movl ORIG_EAX(%esp),%eax # restore eax to it's original content + #endif call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) # store the return value syscall_exit: + #if (CONFIG_LTT) + movl syscall_exit_trace_active, %eax + cmpl $1, %eax # are we tracing system call exits + jne no_syscall_exit_trace + call trace_real_syscall_exit + no_syscall_exit_trace: + #endif cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/i386/kernel/process.c linux-current/arch/i386/kernel/process.c *** linux-2.6.10/arch/i386/kernel/process.c Sat Dec 25 06:33:47 2004 --- linux-current/arch/i386/kernel/process.c Wed Jun 14 21:12:58 2006 *************** *** 36,41 **** --- 36,42 ---- #include #include #include + #include #include #include *************** *** 281,286 **** --- 282,288 ---- int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { struct pt_regs regs; + long pid; memset(®s, 0, sizeof(regs)); *************** *** 295,301 **** regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; /* Ok, create the new process.. */ ! return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } /* --- 297,308 ---- regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; /* Ok, create the new process.. */ ! pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); ! #if (CONFIG_LTT) ! if(pid >= 0) ! ltt_ev_process(LTT_EV_PROCESS_KTHREAD, pid, (int) fn); ! #endif ! return pid; } /* diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/i386/kernel/sys_i386.c linux-current/arch/i386/kernel/sys_i386.c *** linux-2.6.10/arch/i386/kernel/sys_i386.c Sat Dec 25 06:35:39 2004 --- linux-current/arch/i386/kernel/sys_i386.c Wed Jun 14 21:12:58 2006 *************** *** 19,24 **** --- 19,25 ---- #include #include #include + #include #include #include *************** *** 136,141 **** --- 137,144 ---- version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; + ltt_ev_ipc(LTT_EV_IPC_CALL, call, first); + switch (call) { case SEMOP: return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/i386/kernel/traps.c linux-current/arch/i386/kernel/traps.c *** linux-2.6.10/arch/i386/kernel/traps.c Sat Dec 25 06:34:01 2004 --- linux-current/arch/i386/kernel/traps.c Wed Jun 14 21:12:58 2006 *************** *** 27,32 **** --- 27,33 ---- #include #include #include + #include #ifdef CONFIG_EISA #include *************** *** 293,298 **** --- 294,366 ---- printk("Kernel BUG\n"); } + /* Trace related code */ + #if (CONFIG_LTT) + asmlinkage void trace_real_syscall_entry(struct pt_regs *regs) + { + int use_depth; + int use_bounds; + int depth = 0; + int seek_depth; + unsigned long lower_bound; + unsigned long upper_bound; + unsigned long addr; + unsigned long *stack; + ltt_syscall_entry trace_syscall_event; + + /* Set the syscall ID */ + trace_syscall_event.syscall_id = (uint8_t) regs->orig_eax; + + /* Set the address in any case */ + trace_syscall_event.address = regs->eip; + + /* Are we in the kernel (This is a kernel thread)? */ + if (!(regs->xcs & 3)) + /* Don't go digining anywhere */ + goto trace_syscall_end; + + /* Get the trace configuration */ + if (ltt_get_trace_config(&use_depth, &use_bounds, &seek_depth, + (void *) &lower_bound, (void *) &upper_bound) < 0) + goto trace_syscall_end; + + /* Do we have to search for an eip address range */ + if ((use_depth == 1) || (use_bounds == 1)) { + /* Start at the top of the stack (bottom address since stacks grow downward) */ + stack = (unsigned long *) regs->esp; + + /* Keep on going until we reach the end of the process' stack limit (wherever it may be) */ + while (!get_user(addr, stack)) { + /* Does this LOOK LIKE an address in the program */ + if ((addr > current->mm->start_code) + && (addr < current->mm->end_code)) { + /* Does this address fit the description */ + if (((use_depth == 1) && (depth == seek_depth)) + || ((use_bounds == 1) && (addr > lower_bound) && (addr < upper_bound))) { + /* Set the address */ + trace_syscall_event.address = addr; + + /* We're done */ + goto trace_syscall_end; + } else + /* We're one depth more */ + depth++; + } + /* Go on to the next address */ + stack++; + } + } + trace_syscall_end: + /* Trace the event */ + ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event); + } + + asmlinkage void trace_real_syscall_exit(void) + { + ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL); + } + #endif /* (CONFIG_LTT) */ + void die(const char * str, struct pt_regs * regs, long err) { static struct { *************** *** 361,366 **** --- 429,436 ---- static void do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs * regs, long error_code, siginfo_t *info) { + ltt_ev_trap_entry(trapnr, regs->eip); + if (regs->eflags & VM_MASK) { if (vm86) goto vm86_trap; *************** *** 378,397 **** --- 448,471 ---- force_sig_info(signr, info, tsk); else force_sig(signr, tsk); + ltt_ev_trap_exit(); return; } kernel_trap: { if (!fixup_exception(regs)) die(str, regs, error_code); + ltt_ev_trap_exit(); return; } vm86_trap: { int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr); if (ret) goto trap_signal; + ltt_ev_trap_exit(); return; } + ltt_ev_trap_exit(); } #define DO_ERROR(trapnr, signr, str, name) \ *************** *** 493,504 **** --- 567,582 ---- current->thread.error_code = error_code; current->thread.trap_no = 13; + ltt_ev_trap_entry(13, regs->eip); force_sig(SIGSEGV, current); + ltt_ev_trap_exit(); return; gp_in_vm86: local_irq_enable(); + ltt_ev_trap_entry(13, regs->eip); handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); + ltt_ev_trap_exit(); return; gp_in_kernel: *************** *** 579,584 **** --- 657,668 ---- /* Only the BSP gets external NMIs from the system. */ if (!smp_processor_id()) reason = get_nmi_reason(); + + #ifndef CONFIG_X86_LOCAL_APIC + /* On machines with APIC enabled, NMIs are used to implement a watchdog + and will hang the machine if traced. */ + ltt_ev_trap_entry(2, regs->eip); + #endif if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) *************** *** 595,600 **** --- 679,687 ---- } #endif unknown_nmi_error(reason, regs); + #ifndef CONFIG_X86_LOCAL_APIC + ltt_ev_trap_exit(); + #endif return; } if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP) *************** *** 608,613 **** --- 695,704 ---- * as it's edge-triggered. */ reassert_nmi(); + + #ifndef CONFIG_X86_LOCAL_APIC + ltt_ev_trap_exit(); + #endif } static int dummy_nmi_callback(struct pt_regs * regs, int cpu) *************** *** 734,740 **** --- 825,833 ---- */ info.si_addr = ((regs->xcs & 3) == 0) ? (void __user *)tsk->thread.eip : (void __user *)regs->eip; + ltt_ev_trap_entry(1, regs->eip); force_sig_info(SIGTRAP, &info, tsk); + ltt_ev_trap_exit(); /* Disable additional traps. They'll be re-enabled when * the signal is delivered. *************** *** 746,752 **** --- 839,847 ---- return; debug_vm86: + ltt_ev_trap_entry(1, regs->eip); handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1); + ltt_ev_trap_exit(); return; clear_TF_reenable: *************** *** 898,907 **** --- 993,1004 ---- fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, long error_code) { + ltt_ev_trap_entry(16, regs->eip); #if 0 /* No need to warn about this any longer. */ printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n"); #endif + ltt_ev_trap_exit(); } /* *************** *** 932,939 **** --- 1029,1038 ---- { printk("math-emulation not enabled and no coprocessor found.\n"); printk("killing %s.\n",current->comm); + ltt_ev_trap_entry(7, 0); force_sig(SIGFPE,current); schedule(); + ltt_ev_trap_exit(); } #endif /* CONFIG_MATH_EMULATION */ *************** *** 965,971 **** "3" ((char *) (addr)),"2" ((seg) << 16)); \ } while (0) - /* * This needs to use 'idt_table' rather than 'idt', and * thus use the _nonmapped_ version of the IDT, as the --- 1064,1069 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/i386/mm/fault.c linux-current/arch/i386/mm/fault.c *** linux-2.6.10/arch/i386/mm/fault.c Sat Dec 25 06:33:48 2004 --- linux-current/arch/i386/mm/fault.c Wed Jun 14 21:12:58 2006 *************** *** 21,26 **** --- 21,27 ---- #include /* For unblank_screen() */ #include #include + #include #include #include *************** *** 269,274 **** --- 270,277 ---- if (in_atomic() || !mm) goto bad_area_nosemaphore; + ltt_ev_trap_entry(14, regs->eip); + /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the * kernel and should generate an OOPS. Unfortunatly, in the case of an *************** *** 366,371 **** --- 369,375 ---- tsk->thread.screen_bitmap |= 1 << bit; } up_read(&mm->mmap_sem); + ltt_ev_trap_exit(); return; /* *************** *** 408,413 **** --- 412,418 ---- if (nr == 6) { do_invalid_op(regs, 0); + ltt_ev_trap_exit(); return; } } *************** *** 415,430 **** no_context: /* Are we prepared to handle this kernel fault? */ ! if (fixup_exception(regs)) return; /* * Valid to do another page fault here, because if this fault * had been triggered by is_prefetch fixup_exception would have * handled it. */ ! if (is_prefetch(regs, address, error_code)) return; /* * Oops. The kernel tried to access some bad page. We'll have to --- 420,439 ---- no_context: /* Are we prepared to handle this kernel fault? */ ! if (fixup_exception(regs)) { ! ltt_ev_trap_exit(); return; + } /* * Valid to do another page fault here, because if this fault * had been triggered by is_prefetch fixup_exception would have * handled it. */ ! if (is_prefetch(regs, address, error_code)) { ! ltt_ev_trap_exit(); return; + } /* * Oops. The kernel tried to access some bad page. We'll have to *************** *** 493,500 **** goto no_context; /* User space => ok to do another page fault */ ! if (is_prefetch(regs, address, error_code)) return; tsk->thread.cr2 = address; tsk->thread.error_code = error_code; --- 502,511 ---- goto no_context; /* User space => ok to do another page fault */ ! if (is_prefetch(regs, address, error_code)) { ! ltt_ev_trap_exit(); return; + } tsk->thread.cr2 = address; tsk->thread.error_code = error_code; *************** *** 504,509 **** --- 515,521 ---- info.si_code = BUS_ADRERR; info.si_addr = (void __user *)address; force_sig_info(SIGBUS, &info, tsk); + ltt_ev_trap_exit(); return; vmalloc_fault: *************** *** 542,547 **** --- 554,562 ---- pte_k = pte_offset_kernel(pmd_k, address); if (!pte_present(*pte_k)) goto no_context; + ltt_ev_trap_entry(14, regs->eip); + ltt_ev_trap_exit(); return; } + ltt_ev_trap_exit(); } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/Kconfig linux-current/arch/mips/Kconfig *** linux-2.6.10/arch/mips/Kconfig Sat Dec 25 06:34:45 2004 --- linux-current/arch/mips/Kconfig Fri Jul 7 22:07:31 2006 *************** *** 215,220 **** --- 215,229 ---- select HW_HAS_PCI select R5000_CPU_SCACHE + config EMMA + bool "Support for EMMA" + select SWAP_IO_SPACE + select HW_HAS_PCI + select DMA_NONCOHERENT + select IRQ_CPU + select PCIMEM_PHYSOFFSET + select MMAP_NOHIMEMCHECK + config PICVUE tristate "PICVUE LCD display driver" depends on LASAT *************** *** 845,850 **** --- 854,920 ---- bool "FPCIB0 Backplane Support" depends on TOSHIBA_RBTX4927 + config TX_RBTX4927 + bool "Support for TX RBTX4927" + + config TX_RBTX4938 + bool "Support for TX RBTX4938" + + config TOSHIBA_CHIP0S + bool "Support for Toshiba CHIP0S Board (3000, 4000, BOARD8L/150, etc.)" + select TOSHIBA_TSBLDADR + + config TOSHIBA_CHIP1S + bool "Support for Toshiba CHIP1S Board" + select TOSHIBA_TSBLDADR + + config TOSHIBA_CHIP1S_SHARP1 + bool "Enable CHIP1S #1 Chip Workaround" + depends on TOSHIBA_CHIP1S + + config TOSHIBA_CHIP1S_USBHC_WORKAROUND + bool "Enable CHIP1S USBHC Workaround" + depends on TOSHIBA_CHIP1S + + config ADJUST_MONOTONIC_TIME + bool "Adjust monotonic time to real boot time" + depends on TOSHIBA_CHIP1S + + config TOSHIBA_BOARD3A + bool "Support for Toshiba BOARD3A" + select TOSHIBA_TSBLDADR + + config TOSHIBA_TSBLDADR + bool + depends on TOSHIBA_CHIP0S || TOSHIBA_CHIP1S || TOSHIBA_BOARD3A + + config PMON_RAMBOOT + bool "Use PMON booting from RAM (load address 0x80200000)" + depends on TOSHIBA_TSBLDADR + + config REMOTE_PCI + bool "Support remote PCI on BOARD3A" + depends on TOSHIBA_CHIP1S || TOSHIBA_BOARD3A + + config TX_BOARDS + bool + depends on TX_RBTX4927 || TX_RBTX4938 || TOSHIBA_CHIP0S || TOSHIBA_CHIP1S + default y + select BOOT_ELF32 + select IRQ_CPU + select DMA_NONCOHERENT + select HW_HAS_PCI + select ISA + select SWAP_IO_SPACE + + config PCI_NOPROBE_OFFBOARD + bool "Do not probe offboard PCI devices by default" + depends on TOSHIBA_CHIP0S || TOSHIBA_BOARD3A + + config PICMG_PCI_BACKPLANE_DEFAULT + bool "Support for PICMG PCI Backplane" + depends on TX_BOARDS + config RWSEM_GENERIC_SPINLOCK bool default y *************** *** 872,881 **** config DMA_NONCOHERENT bool config EARLY_PRINTK bool ! depends on MACH_DECSTATION default y config GENERIC_ISA_DMA --- 942,955 ---- config DMA_NONCOHERENT bool + select DMA_NEED_PCI_MAP_STATE + + config DMA_NEED_PCI_MAP_STATE + bool config EARLY_PRINTK bool ! depends on MACH_DECSTATION || TX_BOARDS default y config GENERIC_ISA_DMA *************** *** 964,969 **** --- 1038,1051 ---- config SWAP_IO_SPACE bool + config PCIMEM_PHYSOFFSET + bool + default n + + config MMAP_NOHIMEMCHECK + bool + default n + # # Unfortunately not all GT64120 systems run the chip at the same clock. # As the user for the clock rate and try to minimize the available options. *************** *** 1011,1017 **** config BOOT_ELF32 bool ! depends on MACH_DECSTATION || MIPS_ATLAS || MIPS_MALTA || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3 || SIBYTE_SB1xxx_SOC || SGI_IP32 || SGI_IP22 || SNI_RM200_PCI default y config MIPS_L1_CACHE_SHIFT --- 1093,1099 ---- config BOOT_ELF32 bool ! depends on MACH_DECSTATION || MIPS_ATLAS || MIPS_MALTA || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3 || SIBYTE_SB1xxx_SOC || SGI_IP32 || SGI_IP22 || SNI_RM200_PCI || TX_BOARDS default y config MIPS_L1_CACHE_SHIFT *************** *** 1025,1065 **** depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32 default y - config FB - bool - depends on MIPS_MAGNUM_4000 || OLIVETTI_M700 - default y - ---help--- - The frame buffer device provides an abstraction for the graphics - hardware. It represents the frame buffer of some video hardware and - allows application software to access the graphics hardware through - a well-defined interface, so the software doesn't need to know - anything about the low-level (hardware register) stuff. - - Frame buffer devices work identically across the different - architectures supported by Linux and make the implementation of - application programs easier and more portable; at this point, an X - server exists which uses the frame buffer device exclusively. - On several non-X86 architectures, the frame buffer device is the - only way to use the graphics hardware. - - The device is accessed through special device nodes, usually located - in the /dev directory, i.e. /dev/fb*. - - You need an utility program called fbset to make full use of frame - buffer devices. Please read - and the Framebuffer-HOWTO at - for more information. - - Say Y here and to the driver for your graphics board below if you - are compiling a kernel for a non-x86 architecture. - - If you are compiling for the x86 architecture, you can say Y if you - want to play with it, but it is not essential. Please note that - running graphical applications that directly touch the hardware - (e.g. an accelerated X server) and that are not frame buffer - device-aware may cause unexpected results. If unsure, say N. - config HAVE_STD_PC_SERIAL_PORT bool --- 1107,1112 ---- *************** *** 1111,1116 **** --- 1158,1175 ---- bool "Added TANBAC TB0219 Base board support" depends on TANBAC_TB0229 + config HEARTBEAT + bool "Use power LED as a heartbeat" + 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 FREE_PROM_MEMORY + bool "Free prom memory" + default n + help + Say Y here if hope to free prom memory at the end of booting. endmenu menu "CPU selection" *************** *** 1394,1399 **** --- 1453,1467 ---- This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image. + config XIP_KERNEL + bool "Kernel Execute-In-Place from ROM" + default n + + config XIP_VIRT_ADDR + hex "Kernel .text virtual address" + depends on XIP_KERNEL + default 0 + config PREEMPT bool "Preemptible Kernel" help *************** *** 1587,1592 **** --- 1655,1662 ---- source "lib/Kconfig" + source "tsb_modules/Kconfig" + # # Use the generic interrupt handling code in kernel/irq/: # diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/Kconfig.debug linux-current/arch/mips/Kconfig.debug *** linux-2.6.10/arch/mips/Kconfig.debug Sat Dec 25 06:35:14 2004 --- linux-current/arch/mips/Kconfig.debug Thu Aug 17 19:01:37 2006 *************** *** 8,13 **** --- 8,17 ---- Say Y here if you are compiling the kernel on a different architecture than the one it is intended to run on. + config CELINUX2TOOL + bool "Do you use CE Linux 2.0 tool chain" + depends on CROSSCOMPILE + config CMDLINE string "Default kernel command string" default "" *************** *** 73,76 **** --- 77,95 ---- hardware debugging with a logic analyzer and need to see all traffic on the bus. + config PTRACE_MMAPENABLE + bool "Enable gdb to access mmap area." + default n + help + The range is less than (physical address)0x20000000 (except 0). + + config SHARED_TIMER_INT + bool "Timer Interrupt shared" + + config DUMP_DEFLATE_CORE + bool "Support for zlib deflated core dump" + depends on EMMA + select ZLIB_DEFLATE + endmenu + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/Makefile linux-current/arch/mips/Makefile *** linux-2.6.10/arch/mips/Makefile Sat Dec 25 06:33:49 2004 --- linux-current/arch/mips/Makefile Fri Jul 7 22:07:31 2006 *************** *** 52,57 **** --- 52,65 ---- CROSS_COMPILE := $(tool-prefix) endif + ifdef CONFIG_CELINUX2TOOL + ifdef CONFIG_CPU_LITTLE_ENDIAN + CROSS_COMPILE := mipsel-ce2-linux- + else + CROSS_COMPILE := mips-ce2-linux- + endif + endif + ifdef CONFIG_BUILD_ELF64 gas-abi = 64 ld-emul = $(64bit-emul) *************** *** 633,638 **** --- 641,658 ---- core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/tx4927/common/ load-$(CONFIG_TOSHIBA_RBTX4927) += 0xffffffff80020000 + # + # NEC EMMA based systems + # + ifdef CONFIG_EMMA + cflags-$(CONFIG_EMMA) += -Iinclude/asm-mips/mach-emma + load-$(CONFIG_EMMA) += 0x80040000 + core-$(CONFIG_EMMA) += arch/mips/emma/generic/ + core-$(CONFIG_EMMA) += arch/mips/emma/emma3/ + core-$(CONFIG_EMMA) += arch/mips/emma/emma2rh/ + endif + + cflags-y += -Iinclude/asm-mips/mach-generic drivers-$(CONFIG_PCI) += arch/mips/pci/ *************** *** 659,669 **** --- 679,698 ---- # none has been choosen above. # + ifeq ($(CONFIG_XIP_KERNEL),y) + CPPFLAGS_vmlinux.lds := \ + $(CFLAGS) \ + -D"LOADADDR=$(CONFIG_XIP_VIRT_ADDR)" \ + -D"DATAADDR=$(load-y)" \ + -D"JIFFIES=$(JIFFIES)" \ + -D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)" + else CPPFLAGS_vmlinux.lds := \ $(CFLAGS) \ -D"LOADADDR=$(load-y)" \ -D"JIFFIES=$(JIFFIES)" \ -D"DATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)" + endif head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o *************** *** 673,678 **** --- 702,709 ---- core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/ + drivers-y += tsb_modules/ + ifdef CONFIG_LASAT rom.bin rom.sw: vmlinux $(call descend,arch/mips/lasat/image,$@) *************** *** 707,713 **** all: vmlinux.ecoff endif ! vmlinux.ecoff vmlinux.rm200: $(vmlinux-32) +@$(call makeboot,$@) vmlinux.srec: $(vmlinux-32) --- 738,748 ---- all: vmlinux.ecoff endif ! ifdef CONFIG_TX_BOARDS ! all: vmlinux.elf ! endif ! ! vmlinux.ecoff vmlinux.rm200 vmlinux.elf xipImage: $(vmlinux-32) +@$(call makeboot,$@) vmlinux.srec: $(vmlinux-32) *************** *** 744,779 **** echo "#endif /* _ASM_OFFSET_H */" ) endef ! define filechk_gen-asm-reg.h ! (set -e; \ ! echo "#ifndef _ASM_REG_H"; \ ! echo "#define _ASM_REG_H"; \ ! echo "/*"; \ ! echo " * DO NOT MODIFY."; \ ! echo " *"; \ ! echo " * This file was generated by arch/$(ARCH)/Makefile"; \ ! echo " *"; \ ! echo " */"; \ ! echo ""; \ ! sed -ne "/^@@@/s///p"; \ ! echo "#endif /* _ASM_REG_H */" ) ! endef ! ! prepare: include/asm-$(ARCH)/offset.h \ ! include/asm-$(ARCH)/reg.h arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \ include/config/MARKER include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s $(call filechk,gen-asm-offset.h) - include/asm-$(ARCH)/reg.h: arch/$(ARCH)/kernel/reg.s - $(call filechk,gen-asm-reg.h) CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \ include/asm-$(ARCH)/offset.h \ - include/asm-$(ARCH)/reg.h.tmp \ - include/asm-$(ARCH)/reg.h \ vmlinux.32 \ vmlinux.64 \ vmlinux.ecoff --- 779,794 ---- echo "#endif /* _ASM_OFFSET_H */" ) endef ! prepare: include/asm-$(ARCH)/offset.h arch/$(ARCH)/kernel/offset.s: include/asm include/linux/version.h \ include/config/MARKER include/asm-$(ARCH)/offset.h: arch/$(ARCH)/kernel/offset.s $(call filechk,gen-asm-offset.h) CLEAN_FILES += include/asm-$(ARCH)/offset.h.tmp \ include/asm-$(ARCH)/offset.h \ vmlinux.32 \ vmlinux.64 \ vmlinux.ecoff diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/boot/Makefile linux-current/arch/mips/boot/Makefile *** linux-2.6.10/arch/mips/boot/Makefile Sat Dec 25 06:35:24 2004 --- linux-current/arch/mips/boot/Makefile Wed Jun 14 21:12:58 2006 *************** *** 33,49 **** $(obj)/elf2ecoff: $(obj)/elf2ecoff.c $(HOSTCC) -o $@ $^ vmlinux.srec: $(VMLINUX) $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec $(obj)/addinitrd: $(obj)/addinitrd.c $(HOSTCC) -o $@ $^ archhelp: @echo '* vmlinux.ecoff - ECOFF boot image' @echo '* vmlinux.srec - SREC boot image' clean-files += addinitrd \ elf2ecoff \ vmlinux.ecoff \ ! vmlinux.srec --- 33,67 ---- $(obj)/elf2ecoff: $(obj)/elf2ecoff.c $(HOSTCC) -o $@ $^ + vmlinux.elf: $(VMLINUX) + $(STRIP) -o $(obj)/vmlinux.elf $(VMLINUX) + vmlinux.srec: $(VMLINUX) $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec $(obj)/addinitrd: $(obj)/addinitrd.c $(HOSTCC) -o $@ $^ + # + # Create XIP image + # + ifeq ($(CONFIG_XIP_KERNEL),y) + xipImage: $(VMLINUX) + $(OBJCOPY) -O binary -R .data $(strip-flags) vmlinux vmlinux-text.bin + $(OBJCOPY) -O binary -j .data vmlinux vmlinux-data.bin + cat vmlinux-text.bin vmlinux-data.bin > $@ + $(RM) -f vmlinux-text.bin vmlinux-data.bin + @echo ' kernel: $@ is ready' + endif archhelp: @echo '* vmlinux.ecoff - ECOFF boot image' + @echo '* vmlinux.elf - ELF boot image' @echo '* vmlinux.srec - SREC boot image' + @echo '* xipImage - XIP image' clean-files += addinitrd \ elf2ecoff \ vmlinux.ecoff \ ! vmlinux.elf \ ! vmlinux.srec \ ! xipImage diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/configs/emma_debug_defconfig linux-current/arch/mips/configs/emma_debug_defconfig *** linux-2.6.10/arch/mips/configs/emma_debug_defconfig Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/configs/emma_debug_defconfig Thu Jan 25 20:14:32 2007 *************** *** 0 **** --- 1,1165 ---- + # + # Automatically generated make config: don't edit + # Linux kernel version: 2.6.10-TSB20060731N + # Fri Aug 18 22:29:51 2006 + # + CONFIG_MIPS=y + # CONFIG_MIPS64 is not set + # CONFIG_64BIT is not set + CONFIG_MIPS32=y + + # + # Code maturity level options + # + CONFIG_EXPERIMENTAL=y + CONFIG_CLEAN_COMPILE=y + CONFIG_BROKEN_ON_SMP=y + CONFIG_LOCK_KERNEL=y + + # + # General setup + # + CONFIG_LOCALVERSION="" + # CONFIG_SWAP is not set + CONFIG_SYSVIPC=y + # CONFIG_POSIX_MQUEUE is not set + # CONFIG_BSD_PROCESS_ACCT is not set + CONFIG_SYSCTL=y + # CONFIG_AUDIT is not set + CONFIG_LOG_BUF_SHIFT=14 + CONFIG_HOTPLUG=y + CONFIG_HOTPLUG_DEFAULT_PATH="/sbin/hotplug" + CONFIG_KOBJECT_UEVENT=y + # CONFIG_IKCONFIG is not set + CONFIG_EMBEDDED=y + CONFIG_KALLSYMS=y + # CONFIG_KALLSYMS_ALL is not set + # CONFIG_KALLSYMS_EXTRA_PASS is not set + CONFIG_FUTEX=y + CONFIG_EPOLL=y + # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + # CONFIG_LTT is not set + CONFIG_SHMEM=y + CONFIG_CC_ALIGN_FUNCTIONS=0 + CONFIG_CC_ALIGN_LABELS=0 + CONFIG_CC_ALIGN_LOOPS=0 + CONFIG_CC_ALIGN_JUMPS=0 + # CONFIG_TINY_SHMEM is not set + + # + # Loadable module support + # + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + # CONFIG_MODULE_FORCE_UNLOAD is not set + CONFIG_OBSOLETE_MODPARM=y + CONFIG_MODVERSIONS=y + # CONFIG_MODULE_SRCVERSION_ALL is not set + CONFIG_KMOD=y + + # + # Machine selection + # + # CONFIG_MACH_JAZZ is not set + # CONFIG_MACH_VR41XX is not set + # CONFIG_TOSHIBA_JMR3927 is not set + # CONFIG_MIPS_COBALT is not set + # CONFIG_MACH_DECSTATION is not set + # CONFIG_MIPS_EV64120 is not set + # CONFIG_MIPS_EV96100 is not set + # CONFIG_MIPS_IVR is not set + # CONFIG_LASAT is not set + CONFIG_EMMA=y + # CONFIG_MIPS_ITE8172 is not set + # CONFIG_MIPS_ATLAS is not set + # CONFIG_MIPS_MALTA is not set + # CONFIG_MIPS_SEAD is not set + # CONFIG_MOMENCO_OCELOT is not set + # CONFIG_MOMENCO_OCELOT_G is not set + # CONFIG_MOMENCO_OCELOT_C is not set + # CONFIG_MOMENCO_OCELOT_3 is not set + # CONFIG_MOMENCO_JAGUAR_ATX is not set + # CONFIG_PMC_YOSEMITE is not set + # CONFIG_DDB5074 is not set + # CONFIG_DDB5476 is not set + # CONFIG_DDB5477 is not set + # CONFIG_NEC_OSPREY is not set + # CONFIG_SGI_IP22 is not set + # CONFIG_SOC_AU1X00 is not set + # CONFIG_SIBYTE_SB1xxx_SOC is not set + # CONFIG_SNI_RM200_PCI is not set + # CONFIG_TOSHIBA_RBTX4927 is not set + # CONFIG_TX_RBTX4927 is not set + # CONFIG_TX_RBTX4938 is not set + # CONFIG_TOSHIBA_CHIP0S is not set + # CONFIG_TOSHIBA_CHIP1S is not set + # CONFIG_TOSHIBA_BOARD3A is not set + CONFIG_RWSEM_GENERIC_SPINLOCK=y + CONFIG_HAVE_DEC_LOCK=y + CONFIG_DMA_NONCOHERENT=y + CONFIG_DMA_NEED_PCI_MAP_STATE=y + # CONFIG_CPU_LITTLE_ENDIAN is not set + CONFIG_IRQ_CPU=y + CONFIG_SWAP_IO_SPACE=y + CONFIG_PCIMEM_PHYSOFFSET=y + CONFIG_MMAP_NOHIMEMCHECK=y + CONFIG_MIPS_L1_CACHE_SHIFT=5 + # CONFIG_HEARTBEAT is not set + # CONFIG_FREE_PROM_MEMORY is not set + + # + # CPU selection + # + # CONFIG_CPU_MIPS32 is not set + # CONFIG_CPU_MIPS64 is not set + # CONFIG_CPU_R3000 is not set + # CONFIG_CPU_TX39XX is not set + # CONFIG_CPU_VR41XX is not set + # CONFIG_CPU_R4300 is not set + # CONFIG_CPU_R4X00 is not set + # CONFIG_CPU_TX49XX is not set + # CONFIG_CPU_R5000 is not set + CONFIG_CPU_R5432=y + # CONFIG_CPU_R6000 is not set + # CONFIG_CPU_NEVADA is not set + # CONFIG_CPU_R8000 is not set + # CONFIG_CPU_R10000 is not set + # CONFIG_CPU_RM7000 is not set + # CONFIG_CPU_RM9000 is not set + # CONFIG_CPU_SB1 is not set + CONFIG_PAGE_SIZE_4KB=y + # CONFIG_PAGE_SIZE_8KB is not set + # CONFIG_PAGE_SIZE_16KB is not set + # CONFIG_PAGE_SIZE_64KB is not set + # CONFIG_CPU_ADVANCED is not set + CONFIG_CPU_HAS_LLSC=y + CONFIG_CPU_HAS_LLDSCD=y + CONFIG_CPU_HAS_SYNC=y + # CONFIG_XIP_KERNEL is not set + CONFIG_PREEMPT=y + + # + # Bus options (PCI, PCMCIA, EISA, ISA, TC) + # + CONFIG_HW_HAS_PCI=y + CONFIG_PCI=y + # CONFIG_PCI_LEGACY_PROC is not set + # CONFIG_PCI_NAMES is not set + CONFIG_MMU=y + + # + # PCCARD (PCMCIA/CardBus) support + # + # CONFIG_PCCARD is not set + + # + # PC-card bridges + # + + # + # PCI Hotplug Support + # + # CONFIG_HOTPLUG_PCI is not set + + # + # Executable file formats + # + CONFIG_BINFMT_ELF=y + # CONFIG_BINFMT_MISC is not set + CONFIG_TRAD_SIGNALS=y + + # + # 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 + + # + # Memory Technology Devices (MTD) + # + CONFIG_MTD=m + # CONFIG_MTD_DEBUG is not set + # CONFIG_MTD_PARTITIONS is not set + # CONFIG_MTD_CONCAT is not set + + # + # User Modules And Translation Layers + # + CONFIG_MTD_CHAR=m + # CONFIG_MTD_BLOCK is not set + # CONFIG_MTD_BLOCK_RO is not set + # CONFIG_FTL is not set + # CONFIG_NFTL is not set + # CONFIG_INFTL is not set + + # + # RAM/ROM/Flash chip drivers + # + CONFIG_MTD_CFI=m + # CONFIG_MTD_JEDECPROBE is not set + 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=m + CONFIG_MTD_CFI_AMDSTD_RETRY=0 + # CONFIG_MTD_CFI_STAA is not set + CONFIG_MTD_CFI_UTIL=m + # CONFIG_MTD_RAM is not set + # CONFIG_MTD_ROM is not set + # CONFIG_MTD_ABSENT is not set + + # + # Mapping drivers for chip access + # + CONFIG_MTD_COMPLEX_MAPPINGS=y + CONFIG_MTD_PHYSMAP=m + CONFIG_MTD_PHYSMAP_START=0x1f000000 + CONFIG_MTD_PHYSMAP_LEN=0x1000000 + CONFIG_MTD_PHYSMAP_BANKWIDTH=2 + # CONFIG_MTD_PCI 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_BLKMTD 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 + + # + # Parallel port support + # + # CONFIG_PARPORT is not set + + # + # Plug and Play support + # + + # + # 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_LOOP=m + # 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_BLK_DEV_RAM_COUNT=16 + CONFIG_INITRAMFS_SOURCE="" + # CONFIG_LBD is not set + # CONFIG_CDROM_PKTCDVD is not set + + # + # IO Schedulers + # + CONFIG_IOSCHED_NOOP=y + CONFIG_IOSCHED_AS=y + # CONFIG_IOSCHED_DEADLINE is not set + # CONFIG_IOSCHED_CFQ is not set + + # + # ATA/ATAPI/MFM/RLL support + # + # CONFIG_IDE is not set + + # + # SCSI device support + # + CONFIG_SCSI=y + 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 + + # + # Some SCSI devices (e.g. CD jukebox) support multiple LUNs + # + CONFIG_SCSI_MULTI_LUN=y + # CONFIG_SCSI_CONSTANTS is not set + # CONFIG_SCSI_LOGGING is not set + + # + # SCSI Transport Attributes + # + # CONFIG_SCSI_SPI_ATTRS is not set + # CONFIG_SCSI_FC_ATTRS is not set + + # + # SCSI low-level drivers + # + # 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_DPT_I2O is not set + # CONFIG_MEGARAID_NEWGEN is not set + # CONFIG_MEGARAID_LEGACY is not set + # CONFIG_SCSI_SATA is not set + # CONFIG_SCSI_BUSLOGIC is not set + # CONFIG_SCSI_DMX3191D is not set + # CONFIG_SCSI_EATA is not set + # CONFIG_SCSI_EATA_PIO 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_SYM53C8XX_2 is not set + # CONFIG_SCSI_IPR is not set + # CONFIG_SCSI_QLOGIC_ISP is not set + # CONFIG_SCSI_QLOGIC_FC is not set + # CONFIG_SCSI_QLOGIC_1280 is not set + CONFIG_SCSI_QLA2XXX=y + # CONFIG_SCSI_QLA21XX is not set + # CONFIG_SCSI_QLA22XX is not set + # CONFIG_SCSI_QLA2300 is not set + # CONFIG_SCSI_QLA2322 is not set + # CONFIG_SCSI_QLA6312 is not set + # CONFIG_SCSI_QLA6322 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 + + # + # 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 + + # + # Networking support + # + CONFIG_NET=y + + # + # Networking options + # + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + # CONFIG_NETLINK_DEV is not set + CONFIG_UNIX=y + # CONFIG_NET_KEY is not set + CONFIG_INET=y + CONFIG_IP_MULTICAST=y + # CONFIG_IP_ADVANCED_ROUTER is not set + 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 is not set + # CONFIG_INET_AH is not set + # CONFIG_INET_ESP is not set + # CONFIG_INET_IPCOMP is not set + # CONFIG_INET_TUNNEL is not set + # CONFIG_IP_TCPDIAG is not set + # CONFIG_IP_TCPDIAG_IPV6 is not set + + # + # IP: Virtual Server Configuration + # + # CONFIG_IP_VS is not set + # CONFIG_IPV6 is not set + CONFIG_NETFILTER=y + # CONFIG_NETFILTER_DEBUG is not set + + # + # IP: Netfilter Configuration + # + CONFIG_IP_NF_CONNTRACK=m + # CONFIG_IP_NF_CT_ACCT is not set + # CONFIG_IP_NF_CONNTRACK_MARK is not set + # CONFIG_IP_NF_CT_PROTO_SCTP is not set + CONFIG_IP_NF_FTP=m + CONFIG_IP_NF_IRC=m + CONFIG_IP_NF_TFTP=m + CONFIG_IP_NF_AMANDA=m + CONFIG_IP_NF_QUEUE=m + CONFIG_IP_NF_IPTABLES=m + CONFIG_IP_NF_MATCH_LIMIT=m + CONFIG_IP_NF_MATCH_IPRANGE=m + CONFIG_IP_NF_MATCH_MAC=m + CONFIG_IP_NF_MATCH_PKTTYPE=m + CONFIG_IP_NF_MATCH_MARK=m + CONFIG_IP_NF_MATCH_MULTIPORT=m + CONFIG_IP_NF_MATCH_TOS=m + CONFIG_IP_NF_MATCH_RECENT=m + CONFIG_IP_NF_MATCH_ECN=m + CONFIG_IP_NF_MATCH_DSCP=m + CONFIG_IP_NF_MATCH_AH_ESP=m + CONFIG_IP_NF_MATCH_LENGTH=m + CONFIG_IP_NF_MATCH_TTL=m + CONFIG_IP_NF_MATCH_TCPMSS=m + CONFIG_IP_NF_MATCH_HELPER=m + CONFIG_IP_NF_MATCH_STATE=m + CONFIG_IP_NF_MATCH_CONNTRACK=m + CONFIG_IP_NF_MATCH_OWNER=m + CONFIG_IP_NF_MATCH_ADDRTYPE=m + CONFIG_IP_NF_MATCH_REALM=m + # CONFIG_IP_NF_MATCH_SCTP is not set + # CONFIG_IP_NF_MATCH_COMMENT is not set + # CONFIG_IP_NF_MATCH_HASHLIMIT is not set + CONFIG_IP_NF_FILTER=m + CONFIG_IP_NF_TARGET_REJECT=m + CONFIG_IP_NF_TARGET_LOG=m + CONFIG_IP_NF_TARGET_ULOG=m + CONFIG_IP_NF_TARGET_TCPMSS=m + CONFIG_IP_NF_NAT=m + CONFIG_IP_NF_NAT_NEEDED=y + CONFIG_IP_NF_TARGET_MASQUERADE=m + CONFIG_IP_NF_TARGET_REDIRECT=m + CONFIG_IP_NF_TARGET_NETMAP=m + CONFIG_IP_NF_TARGET_SAME=m + CONFIG_IP_NF_NAT_LOCAL=y + CONFIG_IP_NF_NAT_SNMP_BASIC=m + CONFIG_IP_NF_NAT_IRC=m + CONFIG_IP_NF_NAT_FTP=m + CONFIG_IP_NF_NAT_TFTP=m + CONFIG_IP_NF_NAT_AMANDA=m + CONFIG_IP_NF_MANGLE=m + CONFIG_IP_NF_TARGET_TOS=m + CONFIG_IP_NF_TARGET_ECN=m + CONFIG_IP_NF_TARGET_DSCP=m + CONFIG_IP_NF_TARGET_MARK=m + CONFIG_IP_NF_TARGET_CLASSIFY=m + CONFIG_IP_NF_RAW=m + CONFIG_IP_NF_TARGET_NOTRACK=m + CONFIG_IP_NF_ARPTABLES=m + CONFIG_IP_NF_ARPFILTER=m + CONFIG_IP_NF_ARP_MANGLE=m + CONFIG_IP_NF_COMPAT_IPCHAINS=m + # CONFIG_IP_NF_COMPAT_IPFWADM is not set + + # + # SCTP Configuration (EXPERIMENTAL) + # + # CONFIG_IP_SCTP 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_NET_DIVERT 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 + CONFIG_NET_CLS_ROUTE=y + + # + # Network testing + # + # CONFIG_NET_PKTGEN is not set + # CONFIG_NETPOLL is not set + # CONFIG_NET_POLL_CONTROLLER is not set + # CONFIG_HAMRADIO is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set + CONFIG_NETDEVICES=y + # CONFIG_DUMMY is not set + # CONFIG_BONDING is not set + # CONFIG_EQUALIZER is not set + CONFIG_TUN=y + + # + # ARCnet devices + # + # CONFIG_ARCNET 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_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_TC35815_1 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=y + # CONFIG_NE2K_PCI is not set + # CONFIG_8139CP is not set + CONFIG_8139TOO=y + # CONFIG_8139TOO_PIO is not set + # CONFIG_8139TOO_TUNE_TWISTER is not set + # 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_LAN_SAA9730 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_SK98LIN is not set + # CONFIG_VIA_VELOCITY is not set + # CONFIG_TIGON3 is not set + + # + # Ethernet (10000 Mbit) + # + # CONFIG_IXGB is not set + # CONFIG_S2IO 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_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 + + # + # ISDN subsystem + # + # CONFIG_ISDN is not set + + # + # Telephony Support + # + # CONFIG_PHONE is not set + + # + # Input device support + # + CONFIG_INPUT=y + + # + # Userland interfaces + # + # CONFIG_INPUT_MOUSEDEV is not set + # CONFIG_INPUT_JOYDEV is not set + # CONFIG_INPUT_TSDEV is not set + CONFIG_INPUT_EVDEV=y + # CONFIG_INPUT_EVBUG is not set + + # + # Input I/O drivers + # + # CONFIG_GAMEPORT is not set + CONFIG_SOUND_GAMEPORT=y + CONFIG_SERIO=y + # CONFIG_SERIO_I8042 is not set + CONFIG_SERIO_SERPORT=y + # CONFIG_SERIO_CT82C710 is not set + # CONFIG_SERIO_PCIPS2 is not set + # CONFIG_SERIO_RAW 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 + + # + # 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_NR_UARTS=2 + # CONFIG_SERIAL_8250_EXTENDED is not set + + # + # Non-8250 serial port support + # + CONFIG_SERIAL_CORE=y + CONFIG_SERIAL_CORE_CONSOLE=y + # CONFIG_SERIAL_TXX9 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_RTC is not set + CONFIG_GEN_RTC=y + CONFIG_GEN_RTC_X=y + # CONFIG_DTLK is not set + # CONFIG_R3964 is not set + # CONFIG_APPLICOM is not set + + # + # Ftape, the floppy tape device driver + # + # CONFIG_AGP is not set + # CONFIG_DRM is not set + # CONFIG_RAW_DRIVER is not set + + # + # I2C support + # + CONFIG_I2C=y + CONFIG_I2C_CHARDEV=y + + # + # I2C Algorithms + # + # CONFIG_I2C_ALGOBIT is not set + # CONFIG_I2C_ALGOPCF is not set + # CONFIG_I2C_ALGOPCA is not set + CONFIG_I2C_ALGOEMMA=y + + # + # 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_ISA is not set + # CONFIG_I2C_NFORCE2 is not set + # CONFIG_I2C_PARPORT_LIGHT is not set + # CONFIG_I2C_PIIX4 is not set + # CONFIG_I2C_PROSAVAGE is not set + # CONFIG_I2C_SAVAGE4 is not set + # CONFIG_SCx200_ACB 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 + CONFIG_I2C_EMMA=y + CONFIG_I2C_EMMA_EXIOCTL=y + CONFIG_I2C_EMMA3=m + + # + # Hardware Sensors Chip support + # + # CONFIG_I2C_SENSOR 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_ASB100 is not set + # CONFIG_SENSORS_DS1621 is not set + # CONFIG_SENSORS_FSCHER is not set + # CONFIG_SENSORS_GL518SM 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_MAX1619 is not set + # CONFIG_SENSORS_PC87360 is not set + # CONFIG_SENSORS_SMSC47M1 is not set + # CONFIG_SENSORS_VIA686A is not set + # CONFIG_SENSORS_W83781D is not set + # CONFIG_SENSORS_W83L785TS is not set + # CONFIG_SENSORS_W83627HF is not set + + # + # Other I2C Chip support + # + # CONFIG_SENSORS_EEPROM is not set + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_SENSORS_PCF8591 is not set + # CONFIG_SENSORS_RTC8564 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 + + # + # Dallas's 1-wire bus + # + # CONFIG_W1 is not set + + # + # Misc devices + # + + # + # Multimedia devices + # + # CONFIG_VIDEO_DEV is not set + + # + # Digital Video Broadcasting Devices + # + # CONFIG_DVB is not set + + # + # Graphics support + # + # CONFIG_FB is not set + + # + # Sound + # + # CONFIG_SOUND is not set + + # + # USB support + # + CONFIG_USB=y + # CONFIG_USB_DEBUG is not set + + # + # Miscellaneous USB options + # + # 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 + CONFIG_USB_HUB_ENHANCEMENT=y + CONFIG_USB_RTSCHED=y + CONFIG_USB_RTSCHED_PRIO=49 + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y + + # + # USB Host Controller Drivers + # + CONFIG_USB_EHCI_HCD=m + # CONFIG_USB_EHCI_SPLIT_ISO is not set + # CONFIG_USB_EHCI_ROOT_HUB_TT is not set + CONFIG_USB_OHCI_HCD=m + # CONFIG_USB_UHCI_HCD is not set + # CONFIG_USB_SL811_HCD is not set + + # + # USB Device Class drivers + # + # CONFIG_USB_BLUETOOTH_TTY is not set + # 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_RW_DETECT 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_HP8200e 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_REMOVABLE_ENHANCEMENT=y + + # + # USB Input Devices + # + CONFIG_USB_HID=y + CONFIG_USB_HIDINPUT=y + # 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_KBTAB is not set + # CONFIG_USB_POWERMATE is not set + # CONFIG_USB_MTOUCH is not set + # CONFIG_USB_EGALAX is not set + # CONFIG_USB_XPAD is not set + # CONFIG_USB_ATI_REMOTE is not set + + # + # USB Imaging devices + # + # CONFIG_USB_MDC800 is not set + # CONFIG_USB_MICROTEK is not set + # CONFIG_USB_HPUSBSCSI is not set + + # + # USB Multimedia devices + # + # CONFIG_USB_DABUSB is not set + + # + # Video4Linux support is needed for USB Multimedia device support + # + + # + # USB Network Adapters + # + # CONFIG_USB_CATC is not set + # CONFIG_USB_KAWETH is not set + # CONFIG_USB_PEGASUS is not set + # CONFIG_USB_RTL8150 is not set + # CONFIG_USB_USBNET is not set + + # + # 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_TIGL 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_LED is not set + # CONFIG_USB_CYTHERM is not set + # CONFIG_USB_PHIDGETKIT is not set + # CONFIG_USB_PHIDGETSERVO is not set + + # + # USB ATM/DSL drivers + # + + # + # USB Gadget Support + # + # CONFIG_USB_GADGET is not set + + # + # MMC/SD Card support + # + # CONFIG_MMC is not set + + # + # File systems + # + CONFIG_EXT2_FS=m + # CONFIG_EXT2_FS_XATTR is not set + # CONFIG_EXT3_FS is not set + # CONFIG_JBD is not set + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + # CONFIG_XFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_ROMFS_FS is not set + # CONFIG_QUOTA is not set + CONFIG_DNOTIFY=y + # CONFIG_AUTOFS_FS is not set + # CONFIG_AUTOFS4_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=y + CONFIG_SYSFS=y + # CONFIG_DEVFS_FS is not set + # CONFIG_DEVPTS_FS_XATTR is not set + CONFIG_TMPFS=y + # CONFIG_TMPFS_XATTR is not set + # CONFIG_HUGETLB_PAGE is not set + CONFIG_RAMFS=y + CONFIG_PRAMFS=y + CONFIG_PRAMFS_NOWP=y + # CONFIG_ROOT_PRAMFS is not set + CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA=y + CONFIG_RELAYFS_FS=y + # CONFIG_KLOG_CHANNEL 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_JFFS_FS is not set + # CONFIG_JFFS2_FS is not set + CONFIG_CRAMFS=y + CONFIG_CRAMFS_EXPAND_SIZE=y + CONFIG_CRAMFS_SIZE_WIDTH=25 + CONFIG_CRAMFS_LINEAR=y + CONFIG_CRAMFS_LINEAR_XIP=y + CONFIG_ROOT_CRAMFS_LINEAR=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_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_EXPORTFS is not set + CONFIG_SUNRPC=y + # 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 + + # + # 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_NOMBR_PARTITION=y + # 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_EFI_PARTITION is not set + + # + # Native Language Support + # + CONFIG_NLS=y + CONFIG_NLS_DEFAULT="sjis" + 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 + + # + # Kernel hacking + # + CONFIG_DEBUG_KERNEL=y + CONFIG_MAGIC_SYSRQ=y + # CONFIG_SCHEDSTATS is not set + # CONFIG_DEBUG_SLAB is not set + # CONFIG_DEBUG_SPINLOCK is not set + # CONFIG_DEBUG_SPINLOCK_SLEEP is not set + # CONFIG_DEBUG_KOBJECT is not set + # CONFIG_DEBUG_INFO is not set + CONFIG_CROSSCOMPILE=y + CONFIG_CELINUX2TOOL=y + CONFIG_CMDLINE="" + # CONFIG_DEBUG_STACK_USAGE is not set + # CONFIG_KGDB is not set + # CONFIG_RUNTIME_DEBUG is not set + # CONFIG_MIPS_UNCACHED is not set + CONFIG_PTRACE_MMAPENABLE=y + CONFIG_SHARED_TIMER_INT=y + CONFIG_DUMP_DEFLATE_CORE=y + + # + # Security options + # + # CONFIG_KEYS is not set + # CONFIG_SECURITY is not set + + # + # Cryptographic options + # + # CONFIG_CRYPTO is not set + + # + # Library routines + # + # CONFIG_CRC_CCITT is not set + CONFIG_CRC32=y + # CONFIG_LIBCRC32C is not set + CONFIG_ZLIB_INFLATE=y + CONFIG_ZLIB_DEFLATE=y + + # + # Toshiba Module + # + CONFIG_TOSHIBA_SSFDC_DRV=m + CONFIG_GENERIC_HARDIRQS=y + CONFIG_GENERIC_IRQ_PROBE=y diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/configs/emma_defconfig linux-current/arch/mips/configs/emma_defconfig *** linux-2.6.10/arch/mips/configs/emma_defconfig Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/configs/emma_defconfig Thu Jan 25 20:14:32 2007 *************** *** 0 **** --- 1,1138 ---- + # + # Automatically generated make config: don't edit + # Linux kernel version: 2.6.10-TSB20060731N + # Fri Aug 18 22:44:54 2006 + # + CONFIG_MIPS=y + # CONFIG_MIPS64 is not set + # CONFIG_64BIT is not set + CONFIG_MIPS32=y + + # + # Code maturity level options + # + CONFIG_EXPERIMENTAL=y + CONFIG_CLEAN_COMPILE=y + CONFIG_BROKEN_ON_SMP=y + CONFIG_LOCK_KERNEL=y + + # + # General setup + # + CONFIG_LOCALVERSION="" + # CONFIG_SWAP is not set + CONFIG_SYSVIPC=y + # CONFIG_POSIX_MQUEUE is not set + # CONFIG_BSD_PROCESS_ACCT is not set + CONFIG_SYSCTL=y + # CONFIG_AUDIT is not set + CONFIG_LOG_BUF_SHIFT=14 + CONFIG_HOTPLUG=y + CONFIG_HOTPLUG_DEFAULT_PATH="" + CONFIG_KOBJECT_UEVENT=y + # CONFIG_IKCONFIG is not set + CONFIG_EMBEDDED=y + CONFIG_KALLSYMS=y + # CONFIG_KALLSYMS_EXTRA_PASS is not set + CONFIG_FUTEX=y + CONFIG_EPOLL=y + # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set + CONFIG_SHMEM=y + CONFIG_CC_ALIGN_FUNCTIONS=0 + CONFIG_CC_ALIGN_LABELS=0 + CONFIG_CC_ALIGN_LOOPS=0 + CONFIG_CC_ALIGN_JUMPS=0 + # CONFIG_TINY_SHMEM is not set + + # + # Loadable module support + # + CONFIG_MODULES=y + CONFIG_MODULE_UNLOAD=y + # CONFIG_MODULE_FORCE_UNLOAD is not set + CONFIG_OBSOLETE_MODPARM=y + CONFIG_MODVERSIONS=y + # CONFIG_MODULE_SRCVERSION_ALL is not set + CONFIG_KMOD=y + + # + # Machine selection + # + # CONFIG_MACH_JAZZ is not set + # CONFIG_MACH_VR41XX is not set + # CONFIG_TOSHIBA_JMR3927 is not set + # CONFIG_MIPS_COBALT is not set + # CONFIG_MACH_DECSTATION is not set + # CONFIG_MIPS_EV64120 is not set + # CONFIG_MIPS_EV96100 is not set + # CONFIG_MIPS_IVR is not set + # CONFIG_LASAT is not set + CONFIG_EMMA=y + # CONFIG_MIPS_ITE8172 is not set + # CONFIG_MIPS_ATLAS is not set + # CONFIG_MIPS_MALTA is not set + # CONFIG_MIPS_SEAD is not set + # CONFIG_MOMENCO_OCELOT is not set + # CONFIG_MOMENCO_OCELOT_G is not set + # CONFIG_MOMENCO_OCELOT_C is not set + # CONFIG_MOMENCO_OCELOT_3 is not set + # CONFIG_MOMENCO_JAGUAR_ATX is not set + # CONFIG_PMC_YOSEMITE is not set + # CONFIG_DDB5074 is not set + # CONFIG_DDB5476 is not set + # CONFIG_DDB5477 is not set + # CONFIG_NEC_OSPREY is not set + # CONFIG_SGI_IP22 is not set + # CONFIG_SOC_AU1X00 is not set + # CONFIG_SIBYTE_SB1xxx_SOC is not set + # CONFIG_SNI_RM200_PCI is not set + # CONFIG_TOSHIBA_RBTX4927 is not set + # CONFIG_TX_RBTX4927 is not set + # CONFIG_TX_RBTX4938 is not set + # CONFIG_TOSHIBA_CHIP0S is not set + # CONFIG_TOSHIBA_CHIP1S is not set + # CONFIG_TOSHIBA_BOARD3A is not set + CONFIG_RWSEM_GENERIC_SPINLOCK=y + CONFIG_HAVE_DEC_LOCK=y + CONFIG_DMA_NONCOHERENT=y + CONFIG_DMA_NEED_PCI_MAP_STATE=y + # CONFIG_CPU_LITTLE_ENDIAN is not set + CONFIG_IRQ_CPU=y + CONFIG_SWAP_IO_SPACE=y + CONFIG_PCIMEM_PHYSOFFSET=y + CONFIG_MMAP_NOHIMEMCHECK=y + CONFIG_MIPS_L1_CACHE_SHIFT=5 + # CONFIG_HEARTBEAT is not set + # CONFIG_FREE_PROM_MEMORY is not set + + # + # CPU selection + # + # CONFIG_CPU_MIPS32 is not set + # CONFIG_CPU_MIPS64 is not set + # CONFIG_CPU_R3000 is not set + # CONFIG_CPU_TX39XX is not set + # CONFIG_CPU_VR41XX is not set + # CONFIG_CPU_R4300 is not set + # CONFIG_CPU_R4X00 is not set + # CONFIG_CPU_TX49XX is not set + # CONFIG_CPU_R5000 is not set + CONFIG_CPU_R5432=y + # CONFIG_CPU_R6000 is not set + # CONFIG_CPU_NEVADA is not set + # CONFIG_CPU_R8000 is not set + # CONFIG_CPU_R10000 is not set + # CONFIG_CPU_RM7000 is not set + # CONFIG_CPU_RM9000 is not set + # CONFIG_CPU_SB1 is not set + CONFIG_PAGE_SIZE_4KB=y + # CONFIG_PAGE_SIZE_8KB is not set + # CONFIG_PAGE_SIZE_16KB is not set + # CONFIG_PAGE_SIZE_64KB is not set + # CONFIG_CPU_ADVANCED is not set + CONFIG_CPU_HAS_LLSC=y + CONFIG_CPU_HAS_LLDSCD=y + CONFIG_CPU_HAS_SYNC=y + # CONFIG_XIP_KERNEL is not set + CONFIG_PREEMPT=y + + # + # Bus options (PCI, PCMCIA, EISA, ISA, TC) + # + CONFIG_HW_HAS_PCI=y + CONFIG_PCI=y + # CONFIG_PCI_LEGACY_PROC is not set + # CONFIG_PCI_NAMES is not set + CONFIG_MMU=y + + # + # PCCARD (PCMCIA/CardBus) support + # + # CONFIG_PCCARD is not set + + # + # PC-card bridges + # + + # + # PCI Hotplug Support + # + # CONFIG_HOTPLUG_PCI is not set + + # + # Executable file formats + # + CONFIG_BINFMT_ELF=y + # CONFIG_BINFMT_MISC is not set + CONFIG_TRAD_SIGNALS=y + + # + # Device Drivers + # + + # + # Generic Driver Options + # + CONFIG_STANDALONE=y + CONFIG_PREVENT_FIRMWARE_BUILD=y + # CONFIG_FW_LOADER is not set + + # + # Memory Technology Devices (MTD) + # + CONFIG_MTD=m + # CONFIG_MTD_DEBUG is not set + # CONFIG_MTD_PARTITIONS is not set + # CONFIG_MTD_CONCAT is not set + + # + # User Modules And Translation Layers + # + CONFIG_MTD_CHAR=m + # CONFIG_MTD_BLOCK is not set + # CONFIG_MTD_BLOCK_RO is not set + # CONFIG_FTL is not set + # CONFIG_NFTL is not set + # CONFIG_INFTL is not set + + # + # RAM/ROM/Flash chip drivers + # + CONFIG_MTD_CFI=m + # CONFIG_MTD_JEDECPROBE is not set + 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=m + CONFIG_MTD_CFI_AMDSTD_RETRY=0 + # CONFIG_MTD_CFI_STAA is not set + CONFIG_MTD_CFI_UTIL=m + # CONFIG_MTD_RAM is not set + # CONFIG_MTD_ROM is not set + # CONFIG_MTD_ABSENT is not set + + # + # Mapping drivers for chip access + # + CONFIG_MTD_COMPLEX_MAPPINGS=y + CONFIG_MTD_PHYSMAP=m + CONFIG_MTD_PHYSMAP_START=0x1f000000 + CONFIG_MTD_PHYSMAP_LEN=0x1000000 + CONFIG_MTD_PHYSMAP_BANKWIDTH=2 + # CONFIG_MTD_PCI 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_BLKMTD 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 + + # + # Parallel port support + # + # CONFIG_PARPORT is not set + + # + # Plug and Play support + # + + # + # 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_LOOP=m + # 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_BLK_DEV_RAM_COUNT=16 + CONFIG_INITRAMFS_SOURCE="" + # CONFIG_LBD is not set + # CONFIG_CDROM_PKTCDVD is not set + + # + # IO Schedulers + # + CONFIG_IOSCHED_NOOP=y + CONFIG_IOSCHED_AS=y + # CONFIG_IOSCHED_DEADLINE is not set + # CONFIG_IOSCHED_CFQ is not set + + # + # ATA/ATAPI/MFM/RLL support + # + # CONFIG_IDE is not set + + # + # SCSI device support + # + CONFIG_SCSI=y + 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 + + # + # Some SCSI devices (e.g. CD jukebox) support multiple LUNs + # + CONFIG_SCSI_MULTI_LUN=y + # CONFIG_SCSI_CONSTANTS is not set + # CONFIG_SCSI_LOGGING is not set + + # + # SCSI Transport Attributes + # + # CONFIG_SCSI_SPI_ATTRS is not set + # CONFIG_SCSI_FC_ATTRS is not set + + # + # SCSI low-level drivers + # + # 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_DPT_I2O is not set + # CONFIG_MEGARAID_NEWGEN is not set + # CONFIG_MEGARAID_LEGACY is not set + # CONFIG_SCSI_SATA is not set + # CONFIG_SCSI_BUSLOGIC is not set + # CONFIG_SCSI_DMX3191D is not set + # CONFIG_SCSI_EATA is not set + # CONFIG_SCSI_EATA_PIO 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_SYM53C8XX_2 is not set + # CONFIG_SCSI_IPR is not set + # CONFIG_SCSI_QLOGIC_ISP is not set + # CONFIG_SCSI_QLOGIC_FC is not set + # CONFIG_SCSI_QLOGIC_1280 is not set + CONFIG_SCSI_QLA2XXX=y + # CONFIG_SCSI_QLA21XX is not set + # CONFIG_SCSI_QLA22XX is not set + # CONFIG_SCSI_QLA2300 is not set + # CONFIG_SCSI_QLA2322 is not set + # CONFIG_SCSI_QLA6312 is not set + # CONFIG_SCSI_QLA6322 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 + + # + # 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 + + # + # Networking support + # + CONFIG_NET=y + + # + # Networking options + # + CONFIG_PACKET=y + # CONFIG_PACKET_MMAP is not set + # CONFIG_NETLINK_DEV is not set + CONFIG_UNIX=y + # CONFIG_NET_KEY is not set + CONFIG_INET=y + CONFIG_IP_MULTICAST=y + # CONFIG_IP_ADVANCED_ROUTER is not set + # CONFIG_IP_PNP 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 is not set + # CONFIG_INET_AH is not set + # CONFIG_INET_ESP is not set + # CONFIG_INET_IPCOMP is not set + # CONFIG_INET_TUNNEL is not set + # CONFIG_IP_TCPDIAG is not set + # CONFIG_IP_TCPDIAG_IPV6 is not set + + # + # IP: Virtual Server Configuration + # + # CONFIG_IP_VS is not set + # CONFIG_IPV6 is not set + CONFIG_NETFILTER=y + # CONFIG_NETFILTER_DEBUG is not set + + # + # IP: Netfilter Configuration + # + CONFIG_IP_NF_CONNTRACK=m + # CONFIG_IP_NF_CT_ACCT is not set + # CONFIG_IP_NF_CONNTRACK_MARK is not set + # CONFIG_IP_NF_CT_PROTO_SCTP is not set + CONFIG_IP_NF_FTP=m + CONFIG_IP_NF_IRC=m + CONFIG_IP_NF_TFTP=m + CONFIG_IP_NF_AMANDA=m + CONFIG_IP_NF_QUEUE=m + CONFIG_IP_NF_IPTABLES=m + CONFIG_IP_NF_MATCH_LIMIT=m + CONFIG_IP_NF_MATCH_IPRANGE=m + CONFIG_IP_NF_MATCH_MAC=m + CONFIG_IP_NF_MATCH_PKTTYPE=m + CONFIG_IP_NF_MATCH_MARK=m + CONFIG_IP_NF_MATCH_MULTIPORT=m + CONFIG_IP_NF_MATCH_TOS=m + CONFIG_IP_NF_MATCH_RECENT=m + CONFIG_IP_NF_MATCH_ECN=m + CONFIG_IP_NF_MATCH_DSCP=m + CONFIG_IP_NF_MATCH_AH_ESP=m + CONFIG_IP_NF_MATCH_LENGTH=m + CONFIG_IP_NF_MATCH_TTL=m + CONFIG_IP_NF_MATCH_TCPMSS=m + CONFIG_IP_NF_MATCH_HELPER=m + CONFIG_IP_NF_MATCH_STATE=m + CONFIG_IP_NF_MATCH_CONNTRACK=m + CONFIG_IP_NF_MATCH_OWNER=m + CONFIG_IP_NF_MATCH_ADDRTYPE=m + CONFIG_IP_NF_MATCH_REALM=m + # CONFIG_IP_NF_MATCH_SCTP is not set + # CONFIG_IP_NF_MATCH_COMMENT is not set + # CONFIG_IP_NF_MATCH_HASHLIMIT is not set + CONFIG_IP_NF_FILTER=m + CONFIG_IP_NF_TARGET_REJECT=m + CONFIG_IP_NF_TARGET_LOG=m + CONFIG_IP_NF_TARGET_ULOG=m + CONFIG_IP_NF_TARGET_TCPMSS=m + CONFIG_IP_NF_NAT=m + CONFIG_IP_NF_NAT_NEEDED=y + CONFIG_IP_NF_TARGET_MASQUERADE=m + CONFIG_IP_NF_TARGET_REDIRECT=m + CONFIG_IP_NF_TARGET_NETMAP=m + CONFIG_IP_NF_TARGET_SAME=m + CONFIG_IP_NF_NAT_LOCAL=y + CONFIG_IP_NF_NAT_SNMP_BASIC=m + CONFIG_IP_NF_NAT_IRC=m + CONFIG_IP_NF_NAT_FTP=m + CONFIG_IP_NF_NAT_TFTP=m + CONFIG_IP_NF_NAT_AMANDA=m + CONFIG_IP_NF_MANGLE=m + CONFIG_IP_NF_TARGET_TOS=m + CONFIG_IP_NF_TARGET_ECN=m + CONFIG_IP_NF_TARGET_DSCP=m + CONFIG_IP_NF_TARGET_MARK=m + CONFIG_IP_NF_TARGET_CLASSIFY=m + CONFIG_IP_NF_RAW=m + CONFIG_IP_NF_TARGET_NOTRACK=m + CONFIG_IP_NF_ARPTABLES=m + CONFIG_IP_NF_ARPFILTER=m + CONFIG_IP_NF_ARP_MANGLE=m + CONFIG_IP_NF_COMPAT_IPCHAINS=m + # CONFIG_IP_NF_COMPAT_IPFWADM is not set + + # + # SCTP Configuration (EXPERIMENTAL) + # + # CONFIG_IP_SCTP 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_NET_DIVERT 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 + CONFIG_NET_CLS_ROUTE=y + + # + # Network testing + # + # CONFIG_NET_PKTGEN is not set + # CONFIG_NETPOLL is not set + # CONFIG_NET_POLL_CONTROLLER is not set + # CONFIG_HAMRADIO is not set + # CONFIG_IRDA is not set + # CONFIG_BT is not set + CONFIG_NETDEVICES=y + # CONFIG_DUMMY is not set + # CONFIG_BONDING is not set + # CONFIG_EQUALIZER is not set + CONFIG_TUN=y + + # + # ARCnet devices + # + # CONFIG_ARCNET 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_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=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_TC35815_1 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=y + # CONFIG_NE2K_PCI is not set + # CONFIG_8139CP is not set + CONFIG_8139TOO=y + # CONFIG_8139TOO_PIO is not set + # CONFIG_8139TOO_TUNE_TWISTER is not set + # 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_LAN_SAA9730 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_SK98LIN is not set + # CONFIG_VIA_VELOCITY is not set + # CONFIG_TIGON3 is not set + + # + # Ethernet (10000 Mbit) + # + # CONFIG_IXGB is not set + # CONFIG_S2IO 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_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 + + # + # ISDN subsystem + # + # CONFIG_ISDN is not set + + # + # Telephony Support + # + # CONFIG_PHONE is not set + + # + # Input device support + # + CONFIG_INPUT=y + + # + # Userland interfaces + # + # CONFIG_INPUT_MOUSEDEV is not set + # CONFIG_INPUT_JOYDEV is not set + # CONFIG_INPUT_TSDEV is not set + CONFIG_INPUT_EVDEV=y + # CONFIG_INPUT_EVBUG is not set + + # + # Input I/O drivers + # + # CONFIG_GAMEPORT is not set + CONFIG_SOUND_GAMEPORT=y + CONFIG_SERIO=y + # CONFIG_SERIO_I8042 is not set + CONFIG_SERIO_SERPORT=y + # CONFIG_SERIO_CT82C710 is not set + # CONFIG_SERIO_PCIPS2 is not set + # CONFIG_SERIO_RAW 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 + + # + # 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_NR_UARTS=2 + # CONFIG_SERIAL_8250_EXTENDED is not set + + # + # Non-8250 serial port support + # + CONFIG_SERIAL_CORE=y + CONFIG_SERIAL_CORE_CONSOLE=y + # CONFIG_SERIAL_TXX9 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_RTC is not set + CONFIG_GEN_RTC=y + CONFIG_GEN_RTC_X=y + # CONFIG_DTLK is not set + # CONFIG_R3964 is not set + # CONFIG_APPLICOM is not set + + # + # Ftape, the floppy tape device driver + # + # CONFIG_AGP is not set + # CONFIG_DRM is not set + # CONFIG_RAW_DRIVER is not set + + # + # I2C support + # + CONFIG_I2C=y + CONFIG_I2C_CHARDEV=y + + # + # I2C Algorithms + # + # CONFIG_I2C_ALGOBIT is not set + # CONFIG_I2C_ALGOPCF is not set + # CONFIG_I2C_ALGOPCA is not set + CONFIG_I2C_ALGOEMMA=y + + # + # 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_ISA is not set + # CONFIG_I2C_NFORCE2 is not set + # CONFIG_I2C_PARPORT_LIGHT is not set + # CONFIG_I2C_PIIX4 is not set + # CONFIG_I2C_PROSAVAGE is not set + # CONFIG_I2C_SAVAGE4 is not set + # CONFIG_SCx200_ACB 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 + CONFIG_I2C_EMMA=y + CONFIG_I2C_EMMA_EXIOCTL=y + CONFIG_I2C_EMMA3=m + + # + # Hardware Sensors Chip support + # + # CONFIG_I2C_SENSOR 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_ASB100 is not set + # CONFIG_SENSORS_DS1621 is not set + # CONFIG_SENSORS_FSCHER is not set + # CONFIG_SENSORS_GL518SM 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_MAX1619 is not set + # CONFIG_SENSORS_PC87360 is not set + # CONFIG_SENSORS_SMSC47M1 is not set + # CONFIG_SENSORS_VIA686A is not set + # CONFIG_SENSORS_W83781D is not set + # CONFIG_SENSORS_W83L785TS is not set + # CONFIG_SENSORS_W83627HF is not set + + # + # Other I2C Chip support + # + # CONFIG_SENSORS_EEPROM is not set + # CONFIG_SENSORS_PCF8574 is not set + # CONFIG_SENSORS_PCF8591 is not set + # CONFIG_SENSORS_RTC8564 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 + + # + # Dallas's 1-wire bus + # + # CONFIG_W1 is not set + + # + # Misc devices + # + + # + # Multimedia devices + # + # CONFIG_VIDEO_DEV is not set + + # + # Digital Video Broadcasting Devices + # + # CONFIG_DVB is not set + + # + # Graphics support + # + # CONFIG_FB is not set + + # + # Sound + # + # CONFIG_SOUND is not set + + # + # USB support + # + CONFIG_USB=y + # CONFIG_USB_DEBUG is not set + + # + # Miscellaneous USB options + # + # 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 + CONFIG_USB_HUB_ENHANCEMENT=y + CONFIG_USB_RTSCHED=y + CONFIG_USB_RTSCHED_PRIO=49 + CONFIG_USB_ARCH_HAS_HCD=y + CONFIG_USB_ARCH_HAS_OHCI=y + + # + # USB Host Controller Drivers + # + CONFIG_USB_EHCI_HCD=m + # CONFIG_USB_EHCI_SPLIT_ISO is not set + # CONFIG_USB_EHCI_ROOT_HUB_TT is not set + CONFIG_USB_OHCI_HCD=m + # CONFIG_USB_UHCI_HCD is not set + # CONFIG_USB_SL811_HCD is not set + + # + # USB Device Class drivers + # + # CONFIG_USB_BLUETOOTH_TTY is not set + # 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_RW_DETECT 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_HP8200e 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_REMOVABLE_ENHANCEMENT=y + + # + # USB Input Devices + # + CONFIG_USB_HID=y + CONFIG_USB_HIDINPUT=y + # 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_KBTAB is not set + # CONFIG_USB_POWERMATE is not set + # CONFIG_USB_MTOUCH is not set + # CONFIG_USB_EGALAX is not set + # CONFIG_USB_XPAD is not set + # CONFIG_USB_ATI_REMOTE is not set + + # + # USB Imaging devices + # + # CONFIG_USB_MDC800 is not set + # CONFIG_USB_MICROTEK is not set + # CONFIG_USB_HPUSBSCSI is not set + + # + # USB Multimedia devices + # + # CONFIG_USB_DABUSB is not set + + # + # Video4Linux support is needed for USB Multimedia device support + # + + # + # USB Network Adapters + # + # CONFIG_USB_CATC is not set + # CONFIG_USB_KAWETH is not set + # CONFIG_USB_PEGASUS is not set + # CONFIG_USB_RTL8150 is not set + # CONFIG_USB_USBNET is not set + + # + # 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_TIGL 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_LED is not set + # CONFIG_USB_CYTHERM is not set + # CONFIG_USB_PHIDGETKIT is not set + # CONFIG_USB_PHIDGETSERVO is not set + + # + # USB ATM/DSL drivers + # + + # + # USB Gadget Support + # + # CONFIG_USB_GADGET is not set + + # + # MMC/SD Card support + # + # CONFIG_MMC is not set + + # + # File systems + # + CONFIG_EXT2_FS=m + # CONFIG_EXT2_FS_XATTR is not set + # CONFIG_EXT3_FS is not set + # CONFIG_JBD is not set + # CONFIG_REISERFS_FS is not set + # CONFIG_JFS_FS is not set + # CONFIG_XFS_FS is not set + # CONFIG_MINIX_FS is not set + # CONFIG_ROMFS_FS is not set + # CONFIG_QUOTA is not set + CONFIG_DNOTIFY=y + # CONFIG_AUTOFS_FS is not set + # CONFIG_AUTOFS4_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=y + CONFIG_SYSFS=y + # CONFIG_DEVFS_FS is not set + # CONFIG_DEVPTS_FS_XATTR is not set + CONFIG_TMPFS=y + # CONFIG_TMPFS_XATTR is not set + # CONFIG_HUGETLB_PAGE is not set + CONFIG_RAMFS=y + CONFIG_PRAMFS=y + CONFIG_PRAMFS_NOWP=y + # CONFIG_ROOT_PRAMFS is not set + CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA=y + # CONFIG_RELAYFS_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_JFFS_FS is not set + # CONFIG_JFFS2_FS is not set + CONFIG_CRAMFS=y + CONFIG_CRAMFS_EXPAND_SIZE=y + CONFIG_CRAMFS_SIZE_WIDTH=25 + CONFIG_CRAMFS_LINEAR=y + CONFIG_CRAMFS_LINEAR_XIP=y + CONFIG_ROOT_CRAMFS_LINEAR=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_EXPORTFS 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 + + # + # 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_NOMBR_PARTITION=y + # 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_EFI_PARTITION is not set + + # + # Native Language Support + # + CONFIG_NLS=y + CONFIG_NLS_DEFAULT="sjis" + 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 + + # + # Kernel hacking + # + # CONFIG_DEBUG_KERNEL is not set + CONFIG_CROSSCOMPILE=y + CONFIG_CELINUX2TOOL=y + CONFIG_CMDLINE="" + # CONFIG_PTRACE_MMAPENABLE is not set + CONFIG_SHARED_TIMER_INT=y + CONFIG_DUMP_DEFLATE_CORE=y + + # + # Security options + # + # CONFIG_KEYS is not set + # CONFIG_SECURITY is not set + + # + # Cryptographic options + # + # CONFIG_CRYPTO is not set + + # + # Library routines + # + # CONFIG_CRC_CCITT is not set + CONFIG_CRC32=y + # CONFIG_LIBCRC32C is not set + CONFIG_ZLIB_INFLATE=y + CONFIG_ZLIB_DEFLATE=y + + # + # Toshiba Module + # + CONFIG_TOSHIBA_SSFDC_DRV=m + CONFIG_GENERIC_HARDIRQS=y + CONFIG_GENERIC_IRQ_PROBE=y diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma2rh/Makefile linux-current/arch/mips/emma/emma2rh/Makefile *** linux-2.6.10/arch/mips/emma/emma2rh/Makefile Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma2rh/Makefile Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,10 ---- + # + # Makefile for the common code of EMMA2RH + # + # Note! Dependencies are done automagically by 'make dep', which also + # removes any old dependencies. DON'T put your own dependencies here + # unless it's something special (ie not a .c file). + # + obj-y += setup.o + obj-y += int-handler.o irq.o irq_emma2rh.o + obj-y += pci.o pci_ops.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma2rh/int-handler.S linux-current/arch/mips/emma/emma2rh/int-handler.S *** linux-2.6.10/arch/mips/emma/emma2rh/int-handler.S Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma2rh/int-handler.S Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,94 ---- + /* + * arch/mips/emma2/emma2rh/int-handler.S + * first level dispatcher for EMMA2RH Alpha8. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/int-handler.S + * + * Copyright 2001 MontaVista Software 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 + */ + + /* + * (C) Copyright TOSHIBA CORPORATION 2005 + * All Rights Reserved. + */ + + #include + #include + #include + #include + #include + + #include + + /* + * first level interrupt dispatcher for ocelot board - + * We check for the timer first, then check PCI ints A and D. + * Then check for serial IRQ and fall through. + */ + .align 5 + NESTED(emma2rh_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + .set noreorder + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_cputimer_irq + andi t1, t0, STATUSF_IP2 /* emma2rh int 2 */ + bnez t1, ll_emma2rh_irq + andi t1, t0, STATUSF_IP1 /* software int 1 */ + bnez t1, ll_cpu_ip1 + andi t1, t0, STATUSF_IP0 /* software int 0 */ + bnez t1, ll_cpu_ip0 + nop + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(emma2rh_handle_int) + + .align 5 + + ll_emma2rh_irq: + move a0, sp + jal emma2rh_irq_dispatch + j ret_from_irq + + ll_cputimer_irq: + li a0, CPU_IRQ_BASE + 7 + move a1, sp + jal do_IRQ + j ret_from_irq + + ll_cpu_ip0: + li a0, CPU_IRQ_BASE + 0 + move a1, sp + jal do_IRQ + j ret_from_irq + + ll_cpu_ip1: + li a0, CPU_IRQ_BASE + 1 + move a1, sp + jal do_IRQ + j ret_from_irq diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma2rh/irq.c linux-current/arch/mips/emma/emma2rh/irq.c *** linux-2.6.10/arch/mips/emma/emma2rh/irq.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma2rh/irq.c Mon Jul 10 18:24:34 2006 *************** *** 0 **** --- 1,116 ---- + /* + * arch/mips/emma2hl/common/irq.c + * This file is common irq dispatcher. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/common/ + * + * Copyright 2001 MontaVista Software 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 + */ + /* + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * arch/mips/ddb5xxx/common/irq.c + * Common irq code for DDB boards. This really should belong + * arch/mips/kernel/irq.c. Need to talk to Ralf. + * + * 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. + */ + /* + * (C) Copyright TOSHIBA CORPORATION 2005 + * All Rights Reserved. + */ + + #include + #include + #include + #include + + #include + + /* + * the first level int-handler will jump here if it is a emma2hl irq + */ + asmlinkage void + emma2rh_irq_dispatch(struct pt_regs *regs) + { + u32 intStatus, gpiointStatus, swintStatus; + u32 bitmask, gpiobitmask, swintbitmask; + u32 i, j; + + /* INT 0 */ + intStatus = emma2rh_in32(EMMA2RH_BHIF_MAIN_INT_ST0) + & emma2rh_in32(EMMA2RH_BHIF_MAIN_INT0_EN0); + + for(i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { + if(intStatus & bitmask) { + if (bitmask == EMMA2RH_INT0_SW0) { + /* SWINT Cascade */ + swintStatus = emma2rh_in32(EMMA2RH_BHIF_SW_INT0) + & emma2rh_in32(EMMA2RH_BHIF_SW_INT0_EN); + for (j = 0, swintbitmask = 1; j < 32; j++, swintbitmask <<= 1) { + if (swintStatus & swintbitmask) { + do_IRQ(EMMA2RH_SWINT_IRQ_BASE + j, regs); + return; + } + } + } else { + do_IRQ(EMMA2RH_IRQ_BASE + i, regs); + return; + } + } + } + + /* INT 1 */ + intStatus = emma2rh_in32(EMMA2RH_BHIF_MAIN_INT_ST1) + & emma2rh_in32(EMMA2RH_BHIF_MAIN_INT0_EN1); + + for(i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) { + if(intStatus & bitmask) { + if (bitmask == EMMA2RH_INT1_GPIO1) { + /* GPIO Cascade */ + gpiointStatus = emma2rh_in32(EMMA2RH_ZPIO_INT_ST) + & emma2rh_in32(EMMA2RH_ZPIO_INT_MASK_MAIN); + for (j = 0, gpiobitmask = 1; j < 32; j++, gpiobitmask <<= 1) { + if (gpiointStatus & gpiobitmask) { + do_IRQ(EMMA2RH_GPIO_IRQ_BASE + j, regs); + return; + } + } + } else { + do_IRQ(EMMA2RH_IRQ_BASE + i, regs); + return; + } + } + } + + /* INT 2 */ + intStatus = emma2rh_in32(EMMA2RH_BHIF_MAIN_INT_ST2) + & emma2rh_in32(EMMA2RH_BHIF_MAIN_INT0_EN2); + + for(i = 32, bitmask = 1; i < 96; i++, bitmask <<= 1) { + if(intStatus & bitmask) { + do_IRQ(EMMA2RH_IRQ_BASE + i, regs); + return; + } + } + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma2rh/irq_emma2rh.c linux-current/arch/mips/emma/emma2rh/irq_emma2rh.c *** linux-2.6.10/arch/mips/emma/emma2rh/irq_emma2rh.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma2rh/irq_emma2rh.c Thu Jul 27 10:47:26 2006 *************** *** 0 **** --- 1,376 ---- + /* + * arch/mips/emma2hl/common/irq_emma2hl.c + * This file defines the irq handler for EMMA2HL. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/irq_5477.c + * + * Copyright 2001 MontaVista Software 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 + */ + + /* + * (C) Copyright TOSHIBA CORPORATION 2005 + * All Rights Reserved. + */ + + #include + #include + #include + + #include + + #include + + /* + * EMMA2RH IRQ + */ + void ll_emma2rh_irq_enable(int emma2rh_irq); + void ll_emma2rh_irq_disable(int emma2rh_irq); + + static int emma2rh_irq_base = -1; + + static void + emma2rh_irq_enable(unsigned int irq) + { + ll_emma2rh_irq_enable(irq - emma2rh_irq_base); + } + + static void + emma2rh_irq_disable(unsigned int irq) + { + ll_emma2rh_irq_disable(irq - emma2rh_irq_base); + } + + static unsigned int emma2rh_irq_startup(unsigned int irq) + { + emma2rh_irq_enable(irq); + return 0; + } + + #define emma2rh_irq_shutdown emma2rh_irq_disable + + static void + emma2rh_irq_ack(unsigned int irq) + { + /* disable interrupt - some handler will re-enable the irq + * and if the interrupt is leveled, we will have infinite loop + */ + ll_emma2rh_irq_disable(irq - emma2rh_irq_base); + } + + static void + emma2rh_irq_end(unsigned int irq) + { + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_emma2rh_irq_enable( irq - emma2rh_irq_base); + } + + hw_irq_controller emma2rh_irq_controller = { + "emma2rh_irq", + emma2rh_irq_startup, + emma2rh_irq_shutdown, + emma2rh_irq_enable, + emma2rh_irq_disable, + emma2rh_irq_ack, + emma2rh_irq_end, + NULL /* no affinity stuff for UP */ + }; + + void + emma2rh_irq_init(u32 irq_base) + { + extern irq_desc_t irq_desc[]; + u32 i; + + for (i= irq_base; i< irq_base+ NUM_EMMA2RH_IRQ; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &emma2rh_irq_controller; + } + + emma2rh_irq_base = irq_base; + } + + void ll_emma2rh_irq_enable(int emma2rh_irq) + { + u32 reg_value; + u32 reg_bitmask; + u32 reg_index; + + reg_index = EMMA2RH_BHIF_MAIN_INT0_EN0 + + 4 * (emma2rh_irq / 32); + reg_value = emma2rh_in32(reg_index); + reg_bitmask = 0x1 << (emma2rh_irq % 32); + db_assert((reg_value & reg_bitmask) == 0); + emma2rh_out32(reg_index, reg_value | reg_bitmask); + } + + void ll_emma2rh_irq_disable(int emma2rh_irq) + { + u32 reg_value; + u32 reg_bitmask; + u32 reg_index; + + reg_index = EMMA2RH_BHIF_MAIN_INT0_EN0 + + 4 * (emma2rh_irq / 32); + + reg_value = emma2rh_in32(reg_index); + reg_bitmask = 0x1 << (emma2rh_irq % 32); + db_assert((reg_value & reg_bitmask) != 0); + emma2rh_out32(reg_index, reg_value & ~reg_bitmask); + } + + /* + * EMMA2RH GPIO IRQ + */ + static int emma2rh_gpio_irq_base = -1; + + void ll_emma2rh_gpio_irq_enable(int reg); + void ll_emma2rh_gpio_irq_disable(int reg); + + static void emma2rh_gpio_irq_enable(unsigned int irq) + { + ll_emma2rh_gpio_irq_enable(irq - emma2rh_gpio_irq_base); + } + + static void emma2rh_gpio_irq_disable(unsigned int irq) + { + ll_emma2rh_gpio_irq_disable(irq - emma2rh_gpio_irq_base); + } + + static unsigned int emma2rh_gpio_irq_startup(unsigned int irq) + { + emma2rh_gpio_irq_enable(irq); + return 0; + } + + #define emma2rh_gpio_irq_shutdown emma2rh_gpio_irq_disable + + static void emma2rh_gpio_irq_ack(unsigned int irq) + { + irq -= emma2rh_gpio_irq_base; + emma2rh_out32(EMMA2RH_ZPIO_INT_ST, ~(1 << irq)); + ll_emma2rh_gpio_irq_disable(irq); + } + + static void emma2rh_gpio_irq_end(unsigned int irq) + { + unsigned int tirq; + + tirq = irq - emma2rh_gpio_irq_base; + emma2rh_out32(EMMA2RH_ZPIO_INT_ST, ~(1 << tirq)); + + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_emma2rh_gpio_irq_enable(irq - emma2rh_gpio_irq_base); + } + + hw_irq_controller emma2rh_gpio_irq_controller = { + "emma2rh_gpio_irq", + emma2rh_gpio_irq_startup, + emma2rh_gpio_irq_shutdown, + emma2rh_gpio_irq_enable, + emma2rh_gpio_irq_disable, + emma2rh_gpio_irq_ack, + emma2rh_gpio_irq_end, + NULL, + }; + + void emma2rh_gpio_irq_init(u32 irq_base) + { + extern irq_desc_t irq_desc[]; + u32 i; + + for(i=irq_base; i= 0); + db_assert(irq < 32); + + reg = emma2rh_in32(EMMA2RH_ZPIO_INT_MASK_MAIN); + reg |= 1 << irq; + emma2rh_out32(EMMA2RH_ZPIO_INT_MASK_MAIN, reg); + } + + void ll_emma2rh_gpio_irq_disable(int irq) + { + u32 reg; + + db_assert(irq >= 0); + db_assert(irq < 32); + + reg = emma2rh_in32(EMMA2RH_ZPIO_INT_MASK_MAIN); + reg &= ~(1 << irq); + emma2rh_out32(EMMA2RH_ZPIO_INT_MASK_MAIN, reg); + } + + /* + * EMMA2RH SWINT IRQ + */ + static int emma2rh_swint_irq_base = -1; + + void ll_emma2rh_swint_irq_enable(int reg); + void ll_emma2rh_swint_irq_disable(int reg); + + static void emma2rh_swint_irq_enable(unsigned int irq) + { + ll_emma2rh_swint_irq_enable(irq - emma2rh_swint_irq_base); + } + + static void emma2rh_swint_irq_disable(unsigned int irq) + { + ll_emma2rh_swint_irq_disable(irq - emma2rh_swint_irq_base); + } + + static unsigned int emma2rh_swint_irq_startup(unsigned int irq) + { + emma2rh_swint_irq_enable(irq); + return 0; + } + + #define emma2rh_swint_irq_shutdown emma2rh_swint_irq_disable + + static void emma2rh_swint_irq_ack(unsigned int irq) + { + irq -= emma2rh_swint_irq_base; + emma2rh_out32(EMMA2RH_BHIF_SW_INT0_CLR, (1 << irq)); + ll_emma2rh_swint_irq_disable(irq); + } + + static void emma2rh_swint_irq_end(unsigned int irq) + { + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_emma2rh_swint_irq_enable(irq - emma2rh_swint_irq_base); + } + + hw_irq_controller emma2rh_swint_irq_controller = { + "emma2rh_swint_irq", + emma2rh_swint_irq_startup, + emma2rh_swint_irq_shutdown, + emma2rh_swint_irq_enable, + emma2rh_swint_irq_disable, + emma2rh_swint_irq_ack, + emma2rh_swint_irq_end, + NULL, + }; + + void emma2rh_swint_irq_init(u32 irq_base) + { + extern irq_desc_t irq_desc[]; + u32 i; + + for(i=irq_base; i= 0); + db_assert(irq < 32); + + reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT0_EN); + reg |= 1 << irq; + emma2rh_out32(EMMA2RH_BHIF_SW_INT0_EN, reg); + } + + void ll_emma2rh_swint_irq_disable(int irq) + { + u32 reg; + + db_assert(irq >= 0); + db_assert(irq < 32); + + reg = emma2rh_in32(EMMA2RH_BHIF_SW_INT0_EN); + reg &= ~(1 << irq); + emma2rh_out32(EMMA2RH_BHIF_SW_INT0_EN, reg); + } + + /* + * IRQ mapping + * + * 0-7: 8 CPU interrupts + * 0 - software interrupt 0 + * 1 - software interrupt 1 + * 2 - most EMMA2RH interrupts are routed to this pin + * 3 - (optional) + * 4 - not used + * 5 - not used + * 6 - not used + * 7 - cpu timer (used by default) + * + * 8 - 103: 96 EMMA2RH interrupt sources + * 104 - 135: 32 EMMA2RH SWINT interrupt sources + * 136 - 167: 32 EMMA2RH GPIO interrupt sources + * (refer to the EMMA2RH manual) + */ + + extern void mips_cpu_irq_init(u32 base); + extern asmlinkage void emma2rh_handle_int(void); + extern int setup_irq(unsigned int irq, struct irqaction *irqaction); + static struct irqaction irq_cascade = { .handler = no_action, .name = "cascade"}; + + void __init emma2rh_arch_init_irq(void) + { + /* by default, interrupts are disabled. */ + emma2rh_out32(EMMA2RH_BHIF_MAIN_INT0_EN0, 0); + emma2rh_out32(EMMA2RH_BHIF_MAIN_INT0_EN1, 0); + emma2rh_out32(EMMA2RH_BHIF_MAIN_INT0_EN2, 0); + emma2rh_out32(EMMA2RH_BHIF_MAIN_INT1_EN0, 0); + emma2rh_out32(EMMA2RH_BHIF_MAIN_INT1_EN1, 0); + emma2rh_out32(EMMA2RH_BHIF_MAIN_INT1_EN2, 0); + + clear_c0_status(0xff00); + set_c0_status(0x0400); + + /* init all controllers */ + emma2rh_irq_init(EMMA2RH_IRQ_BASE); + emma2rh_swint_irq_init(EMMA2RH_SWINT_IRQ_BASE); + + emma2rh_gpio_irq_init(EMMA2RH_GPIO_IRQ_BASE); + + mips_cpu_irq_init(CPU_IRQ_BASE); + + /* setup cascade interrupts */ + setup_irq(EMMA2RH_SWINT_CASCADE, &irq_cascade); + + setup_irq(EMMA2RH_GPIO_CASCADE, &irq_cascade); + + setup_irq(EMMA2RH_CPU_CASCADE, &irq_cascade); + + /* hook up the first-level interrupt handler */ + set_except_vector(0, emma2rh_handle_int); + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma2rh/pci.c linux-current/arch/mips/emma/emma2rh/pci.c *** linux-2.6.10/arch/mips/emma/emma2rh/pci.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma2rh/pci.c Tue Aug 29 22:54:58 2006 *************** *** 0 **** --- 1,140 ---- + /* + * arch/mips/emma2hl/alpha8/pci.c + * This file defines the PCI configration. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/pci.c + * + * Copyright 2001 MontaVista Software 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 + */ + + /* + * (C) Copyright TOSHIBA CORPORATION 2005 + * All Rights Reserved. + */ + + #include + #include + #include + #include + #include + + #include + #include + + #include + + #ifdef CONFIG_PCI + + //#define PCIMB_DEBUG + + static struct resource pci_io_resource = { + "pci IO space", + EMMA2RH_PCI_IO_BASE, + 0, + IORESOURCE_IO}; + + static struct resource pci_mem_resource = { + "pci memory space", + EMMA2RH_PCI_MEM_BASE, + EMMA2RH_PCI_MEM_BASE + EMMA2RH_PCI_MEM_SIZE -1, + IORESOURCE_MEM}; + + extern struct pci_ops emma2rh_pci_ops; + + static struct pci_controller emma2rh_pci_controller = { + .pci_ops = &emma2rh_pci_ops, + .mem_resource = &pci_mem_resource, + .mem_offset = EMMA2RH_PCI_MEM_BASE - EMMA2RH_PCI_MEM_PCIBASE, + .io_resource = &pci_io_resource, + .io_offset = EMMA2RH_PCI_IO_BASE - EMMA2RH_PCI_IO_PCIBASE + }; + + int emma2rh_pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) + { + switch (slot) { + case 3: + return EMMA2RH_PCI_USB_IRQ; + break; + case 4: + return EMMA2RH_PCI_ETHER_IRQ; + break; + default: + printk("pcibios_map_irq: Unknown Interrupt Slot %d\n", slot); + return 0; + break; + } + } + + void emma2rh_pcibios_fixup_resources(struct pci_dev *dev) + { + } + + /* Do platform specific device initialization at pci_enable_device() time */ + int emma2rh_pcibios_plat_dev_init(struct pci_dev *dev) + { + /* Configure on board USB controller. */ + if (dev->vendor == PCI_VENDOR_ID_NEC && dev->device == PCI_DEVICE_ID_NEC_USB) { + u32 ext; + + /* We don't use 2nd USB host controller. */ + if (PCI_FUNC(dev->devfn) == 1) { + return -PCIBIOS_FUNC_NOT_SUPPORTED; + } + + /* we support only one port. */ + pci_read_config_dword(dev, 0xe0, &ext); + ext &= ~0x7; + pci_write_config_dword(dev, 0xe0, ext | 1); + + /* we support only ohci. */ + pci_read_config_dword(dev, 0xe4, &ext); + pci_write_config_dword(dev, 0xe4, ext | 1 | (1 << 5)); + } + + return 0; + } + + void __init emma2rh_pci_init(void) + { + /* PCI SetUp */ + register_pci_controller(&emma2rh_pci_controller); + } + + /* + hook in pci_scan_device + + Return code: + 0: skip scan + 1: continue initialization + dev: initilaized in this function + */ + int emma2rh_pci_scan_hook(struct pci_dev *dev) + { + int slot = PCI_SLOT(dev->devfn); + + switch (slot) { + case 2: /* PCI Memory BUS */ + return 0; + break; + default: + break; + } + return 1; + } + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma2rh/pci_ops.c linux-current/arch/mips/emma/emma2rh/pci_ops.c *** linux-2.6.10/arch/mips/emma/emma2rh/pci_ops.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma2rh/pci_ops.c Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,216 ---- + /* + * arch/mips/emma2hl/alpha8/pci_ops.c + * This file defines the PCI operation for EMMA2HL. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/pci_ops.c + * + * Copyright 2001 MontaVista Software 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 + */ + + /* + * (C) Copyright TOSHIBA CORPORATION 2005 + * All Rights Reserved. + */ + + #include + #include + #include + #include + + #include + #include + + #include + + /* + * access config space + */ + static int read_config_dword(struct pci_bus *bus_ptr, unsigned int devfn, + int where, u32 *val) + { + u32 bus, slot_num, func_num; + u32 base = EMMA2RH_PCI_CONF_BASE; + u32 backup_win0, config_win0; + u32 backup_eswp; + unsigned long flags; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (bus_ptr->parent != NULL) { + bus = bus_ptr->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(devfn); + func_num = PCI_FUNC(devfn); + + if(slot_num > 8) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + + + backup_win0 = emma2rh_in32(EMMA2RH_PCI_IWIN0_CTR); + backup_eswp = emma2rh_in32(EMMA2RH_PCI_INIT_ESWP); + + local_irq_save(flags); + + emma2rh_out32(EMMA2RH_PCI_INT, ~(EMMA2RH_PCI_INT_RMABORT)); + + if (bus == 0) { + config_win0 = (1 << (22 + slot_num)) | (5 << 9); /* type 0 config */ + } else { + config_win0 = (1 << (26 + bus)) | (1 << (22 + slot_num)) + | (1 << 15) | (5 << 9); /* type 1 config */ + } + + emma2rh_out32(EMMA2RH_PCI_INIT_ESWP, backup_eswp & ~(7)); + emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, config_win0); + + *val = *(volatile u32*) (base + (func_num << 8) + where); + + emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0); + emma2rh_out32(EMMA2RH_PCI_INIT_ESWP, backup_eswp); + + if (emma2rh_in32(EMMA2RH_PCI_INT) & EMMA2RH_PCI_INT_RMABORT) { + local_irq_restore(flags); + return PCIBIOS_DEVICE_NOT_FOUND; + } + + local_irq_restore(flags); + return PCIBIOS_SUCCESSFUL; + } + + static int write_config_dword(struct pci_bus *bus_ptr, unsigned int devfn, + int where, u32 val) + { + u32 bus, slot_num, func_num; + u32 base = EMMA2RH_PCI_CONF_BASE; + u32 backup_win0, config_win0; + u32 backup_eswp; + unsigned long flags; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (bus_ptr->parent != NULL) { + bus = bus_ptr->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(devfn); + func_num = PCI_FUNC(devfn); + + if(slot_num > 8) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + + backup_win0 = emma2rh_in32(EMMA2RH_PCI_IWIN0_CTR); + backup_eswp = emma2rh_in32(EMMA2RH_PCI_INIT_ESWP); + + local_irq_save(flags); + + emma2rh_out32(EMMA2RH_PCI_INT, ~(EMMA2RH_PCI_INT_RMABORT)); + + if (bus == 0) { + config_win0 = (1 << (22 + slot_num)) | (5 << 9); /* type 0 config */ + } else { + config_win0 = (1 << (26 + bus)) | (1 << (22 + slot_num)) + | (1 << 15) | (5 << 9); /* type 1 config */ + } + + emma2rh_out32(EMMA2RH_PCI_INIT_ESWP, backup_eswp & ~(7)); + emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, config_win0); + + *(volatile u32*) (base + (func_num << 8) + where) = val; + + emma2rh_out32(EMMA2RH_PCI_IWIN0_CTR, backup_win0); + emma2rh_out32(EMMA2RH_PCI_INIT_ESWP, backup_eswp); + + if (emma2rh_in32(EMMA2RH_PCI_INT) & EMMA2RH_PCI_INT_RMABORT) { + local_irq_restore(flags); + return PCIBIOS_DEVICE_NOT_FOUND; + } + + local_irq_restore(flags); + return PCIBIOS_SUCCESSFUL; + } + + static int emma2rh_pci_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) + { + int status; + u32 result; + + switch (size) { + case 1: + status = read_config_dword(bus, devfn, where & ~3, &result); + result >>= ((where & 3) * 8); + *val = result & 0xff; + break; + case 2: + status = read_config_dword(bus, devfn, where & ~3, &result); + result >>= ((where & 2) * 8); + *val = result & 0xffff; + break; + default: + status = read_config_dword(bus, devfn, where & ~3, &result); + *val = result; + } + return (status); + } + + static int emma2rh_pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) + { + int status, shift; + u32 result; + + switch (size) { + case 1: + status = read_config_dword(bus, devfn, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) return status; + shift = (where & 3) * 8; + result &= ~(0xff << shift); + result |= val << shift; + return(write_config_dword(bus, devfn, where & ~3, result)); + break; + case 2: + status = read_config_dword(bus, devfn, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) return status; + shift = (where & 2) * 8; + result &= ~(0xffff << shift); + result |= val << shift; + return (write_config_dword(bus, devfn, where & ~3, result)); + break; + default: + return (write_config_dword(bus, devfn, where & ~3, val)); + } + } + + struct pci_ops emma2rh_pci_ops ={ + .read = emma2rh_pci_config_read, + .write = emma2rh_pci_config_write, + }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma2rh/setup.c linux-current/arch/mips/emma/emma2rh/setup.c *** linux-2.6.10/arch/mips/emma/emma2rh/setup.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma2rh/setup.c Tue Aug 29 22:54:58 2006 *************** *** 0 **** --- 1,222 ---- + /* + * arch/mips/emma2hl/alpha8/setup.c + * This file is setup for EMMA2HL Alpha8. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/setup.c. + * + * Copyright 2001 MontaVista Software 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 + */ + /* + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include /* for ROOT_DEV */ + #include + #include /* for HZ */ + #include + + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + + extern int emma2rh_pci_scan_hook(struct pci_dev *dev); + extern int (*txboard_pci_scan_hook)(struct pci_dev *dev); + + unsigned char emma2rh_rev; + + #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ + + static int bus_frequency; + unsigned long pcimem_phys_offset; + + static struct resource emma2rh_reg_resource = { + "emma2rh", EMMA2RH_REG_PBASE, EMMA2RH_REG_PBASE+EMMA2RH_REG_SIZE-1, IORESOURCE_MEM + }; + + static void emma2rh_machine_restart(char *command) + { + printk("cannot restart.\n"); + while (1); + } + + static void emma2rh_machine_halt(void) + { + printk("halted.\n"); + while (1); + } + + static void emma2rh_machine_power_off(void) + { + printk("Please turn off the power.\n"); + while (1); + } + + static unsigned int __init detect_bus_frequency(unsigned long rtc_base) + { + unsigned int freq = 165500000; + /* detect from boot strap */ + switch((emma2rh_in32(EMMA2RH_BHIF_STRAP0) >> 4) & 3) { + case 0 : freq = 166500000 ; break; + case 1 : freq = 187312500 ; break; + case 2 : freq = 166500000 ; break; /* Reserved */ + case 3 : freq = 166500000 ; break; /* Reserved */ + } + return freq/2; + + } + + static void __init emma2rh_time_init(void) + { + if(bus_frequency == 0) + bus_frequency = detect_bus_frequency(0); + mips_hpt_frequency = bus_frequency; + } + + extern int setup_irq(unsigned int irq, struct irqaction *irqaction); + static void __init emma2rh_timer_setup(struct irqaction *irq) + { + /* we are using the cpu counter for timer interrupts */ + setup_irq(CPU_IRQ_BASE + 7, irq); + } + + static void emma2rh_board_init(void); + extern void emma2rh_irq_setup(void); + extern void emma2rh_pci_init(void); + + int __init emma2rh_setup(void) + { + extern int panic_timeout; + struct uart_port req; + char *board_envstr; + + emma2rh_rev = (unsigned char) (emma2rh_in32(EMMA2RH_BHIF_VERSION) & 0xff); + printk("EMMA2RH Rev Maj %1x, Min %1x\n", emma2rh_rev >> 4, emma2rh_rev & 0xf); + emma2rh_board_init(); + + /* EMMA2RH internal registers & CSx */ + request_resource(&iomem_resource, &emma2rh_reg_resource); + + set_io_port_base(0); + + board_time_init = emma2rh_time_init; + board_timer_setup = emma2rh_timer_setup; + + _machine_restart = emma2rh_machine_restart; + _machine_halt = emma2rh_machine_halt; + _machine_power_off = emma2rh_machine_power_off; + + /* Reboot on panic */ + panic_timeout = 180; + + #ifdef CONFIG_PCI + /* PCI SCAN HOOK */ + txboard_pci_scan_hook = emma2rh_pci_scan_hook; + + emma2rh_pci_init(); + #endif + /* serial setup */ + + #define EMMA2RH_BASE_BAUD (18544000) + /* TTY0 for debug console*/ + + board_envstr = pmon_getenv("board"); + + if (!board_envstr || (strncmp(board_envstr, "DVK", 3) != 0)) { + memset(&req, 0, sizeof(req)); + req.line = 0; + req.iotype = UPIO_MEM; + req.membase = (char *) (EMMA2RH_PFUR2_BASE + 3); + req.irq = EMMA2RH_PFUR2_IRQ; + req.flags = ASYNC_BOOT_AUTOCONF; + req.uartclk = EMMA2RH_BASE_BAUD; + req.regshift = 4; + early_serial_setup(&req); + } + + /* TTY1 for modem */ + memset(&req, 0, sizeof(req)); + req.line = 1; + req.iotype = UPIO_MEM; + req.membase = (char *) (EMMA2RH_PFUR1_BASE + 3); + req.irq = EMMA2RH_PFUR1_IRQ; + req.flags = ASYNC_BOOT_AUTOCONF; + req.uartclk = EMMA2RH_BASE_BAUD; + req.regshift = 4; + early_serial_setup(&req); + + return 0; + } + + static void __init emma2rh_board_init(void) + { + pcimem_phys_offset = emma2rh_in32(EMMA2RH_BHIF_MAIN_OFFSET_ADDRESS) & 0x1ffff800; + + /* setup resource limits */ + ioport_resource.start = 0; + ioport_resource.end = ~0UL; /* no limit */ + iomem_resource.start = 0; + iomem_resource.end = ~0UL; /* no limit */ + } + + #ifdef CONFIG_EMMA2RH_ON_EXC2 + static int __init + emma2rh_device_init(void) + { + struct resource res[3]; + + memset(res, 0, sizeof(res)); + res[0].start = EMMA2RH_ISA_LAN_ADDRESS; + res[0].end = res[0].start + 0x10 - 1; + res[0].flags = IORESOURCE_MEM; + res[1].start = EMMA2RH_ISA_LAN_IRQ; + res[1].flags = IORESOURCE_IRQ; + platform_device_register_simple("smc91x", -1, + res, ARRAY_SIZE(res)); + return 0; + } + + device_initcall(emma2rh_device_init); + #endif + + EXPORT_SYMBOL(pcimem_phys_offset); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma3/Makefile linux-current/arch/mips/emma/emma3/Makefile *** linux-2.6.10/arch/mips/emma/emma3/Makefile Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma3/Makefile Tue Aug 29 22:54:58 2006 *************** *** 0 **** --- 1,10 ---- + # + # Makefile for the common code of EMMA3 + # + # Note! Dependencies are done automagically by 'make dep', which also + # removes any old dependencies. DON'T put your own dependencies here + # unless it's something special (ie not a .c file). + # + obj-y += setup.o + obj-y += int-handler.o irq.o irq_emma3.o + obj-y += pci.o pci_ops.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma3/int-handler.S linux-current/arch/mips/emma/emma3/int-handler.S *** linux-2.6.10/arch/mips/emma/emma3/int-handler.S Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma3/int-handler.S Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,94 ---- + /* + * arch/mips/emma3/emma3/int-handler.S + * first level dispatcher for EMMA2RH Alpha8. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/int-handler.S + * + * Copyright 2001 MontaVista Software 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 + */ + + /* + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + */ + + #include + #include + #include + #include + #include + + #include + + /* + * first level interrupt dispatcher for ocelot board - + * We check for the timer first, then check PCI ints A and D. + * Then check for serial IRQ and fall through. + */ + .align 5 + NESTED(emma3_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + .set noreorder + mfc0 t0, CP0_CAUSE + mfc0 t2, CP0_STATUS + + and t0, t2 + + andi t1, t0, STATUSF_IP7 /* cpu timer */ + bnez t1, ll_cputimer_irq + andi t1, t0, STATUSF_IP2 /* emma3 int 2 */ + bnez t1, ll_emma3_irq + andi t1, t0, STATUSF_IP1 /* software int 1 */ + bnez t1, ll_cpu_ip1 + andi t1, t0, STATUSF_IP0 /* software int 0 */ + bnez t1, ll_cpu_ip0 + nop + .set reorder + + /* wrong alarm or masked ... */ + j spurious_interrupt + nop + END(emma3_handle_int) + + .align 5 + + ll_emma3_irq: + move a0, sp + jal emma3_irq_dispatch + j ret_from_irq + + ll_cputimer_irq: + li a0, CPU_IRQ_BASE + 7 + move a1, sp + jal do_IRQ + j ret_from_irq + + ll_cpu_ip0: + li a0, CPU_IRQ_BASE + 0 + move a1, sp + jal do_IRQ + j ret_from_irq + + ll_cpu_ip1: + li a0, CPU_IRQ_BASE + 1 + move a1, sp + jal do_IRQ + j ret_from_irq diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma3/irq.c linux-current/arch/mips/emma/emma3/irq.c *** linux-2.6.10/arch/mips/emma/emma3/irq.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma3/irq.c Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,124 ---- + /* + * arch/mips/emma2hl/common/irq.c + * This file is common irq dispatcher. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/common/ + * + * Copyright 2001 MontaVista Software 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 + */ + /* + * Copyright 2001 MontaVista Software Inc. + * Author: jsun@mvista.com or jsun@junsun.net + * + * arch/mips/ddb5xxx/common/irq.c + * Common irq code for DDB boards. This really should belong + * arch/mips/kernel/irq.c. Need to talk to Ralf. + * + * 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. + */ + /* + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + */ + + #include + #include + #include + #include + + #include + + /* + * the first level int-handler will jump here if it is a emma3 irq + */ + asmlinkage void + emma3_irq_dispatch(struct pt_regs *regs) + { + u32 intStatus, gpiointStatus, swintStatus; + u32 bitmask, gpiobitmask, swintbitmask; + u32 i, j; + + /* INT 0 */ + intStatus = emma3_in32(EMMA3_BHIF_MAIN_INT_ST0) + & emma3_in32(EMMA3_BHIF_MAIN_INT0_EN0); + + for(i = 0, bitmask = 1; i < 32; i++, bitmask <<= 1) { + if(intStatus & bitmask) { + if (bitmask == EMMA3_INT0_SW0) { + /* SWINT Cascade */ + swintStatus = emma3_in32(EMMA3_BHIF_SW_INT0) + & emma3_in32(EMMA3_BHIF_SW_INT0_EN); + for (j = 0, swintbitmask = 1; j < 32; j++, swintbitmask <<= 1) { + if (swintStatus & swintbitmask) { + do_IRQ(EMMA3_SWINT_IRQ_BASE + j, regs); + return; + } + } + } else { + do_IRQ(EMMA3_IRQ_BASE + i, regs); + return; + } + } + } + + /* INT 1 */ + intStatus = emma3_in32(EMMA3_BHIF_MAIN_INT_ST1) + & emma3_in32(EMMA3_BHIF_MAIN_INT0_EN1); + + for(i = 32, bitmask = 1; i < 64; i++, bitmask <<= 1) { + if(intStatus & bitmask) { + if (bitmask == EMMA3_INT1_GPIO) { + /* GPIO Cascade */ + gpiointStatus = emma3_in32(EMMA3_ZPIO0_INT) + & emma3_in32(EMMA3_ZPIO0_INT_CPUMEN); + for (j = 0, gpiobitmask = 1; j < 32; j++, gpiobitmask <<= 1) { + if (gpiointStatus & gpiobitmask) { + do_IRQ(EMMA3_GPIO0_IRQ_BASE + j, regs); + return; + } + } + gpiointStatus = emma3_in32(EMMA3_ZPIO1_INT) + & emma3_in32(EMMA3_ZPIO1_INT_CPUMEN); + for (j = 0, gpiobitmask = 1; j < 32; j++, gpiobitmask <<= 1) { + if (gpiointStatus & gpiobitmask) { + do_IRQ(EMMA3_GPIO1_IRQ_BASE + j, regs); + return; + } + } + } else { + do_IRQ(EMMA3_IRQ_BASE + i, regs); + return; + } + } + } + + /* INT 2 */ + intStatus = emma3_in32(EMMA3_BHIF_MAIN_INT_ST2) + & emma3_in32(EMMA3_BHIF_MAIN_INT0_EN2); + + for(i = 32, bitmask = 1; i < 96; i++, bitmask <<= 1) { + if(intStatus & bitmask) { + do_IRQ(EMMA3_IRQ_BASE + i, regs); + return; + } + } + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma3/irq_emma3.c linux-current/arch/mips/emma/emma3/irq_emma3.c *** linux-2.6.10/arch/mips/emma/emma3/irq_emma3.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma3/irq_emma3.c Thu Jul 27 10:47:26 2006 *************** *** 0 **** --- 1,397 ---- + /* + * arch/mips/emma2hl/common/irq_emma2hl.c + * This file defines the irq handler for EMMA2HL. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/irq_5477.c + * + * Copyright 2001 MontaVista Software 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 + */ + + /* + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + */ + + #include + #include + #include + + #include + + #include + + /* + * EMMA3 IRQ + */ + void ll_emma3_irq_enable(int emma3_irq); + void ll_emma3_irq_disable(int emma3_irq); + + static int emma3_irq_base = -1; + + static void + emma3_irq_enable(unsigned int irq) + { + ll_emma3_irq_enable(irq - emma3_irq_base); + } + + static void + emma3_irq_disable(unsigned int irq) + { + ll_emma3_irq_disable(irq - emma3_irq_base); + } + + static unsigned int emma3_irq_startup(unsigned int irq) + { + emma3_irq_enable(irq); + return 0; + } + + #define emma3_irq_shutdown emma3_irq_disable + + static void + emma3_irq_ack(unsigned int irq) + { + /* disable interrupt - some handler will re-enable the irq + * and if the interrupt is leveled, we will have infinite loop + */ + ll_emma3_irq_disable(irq - emma3_irq_base); + } + + static void + emma3_irq_end(unsigned int irq) + { + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_emma3_irq_enable( irq - emma3_irq_base); + } + + hw_irq_controller emma3_irq_controller = { + "emma3_irq", + emma3_irq_startup, + emma3_irq_shutdown, + emma3_irq_enable, + emma3_irq_disable, + emma3_irq_ack, + emma3_irq_end, + NULL /* no affinity stuff for UP */ + }; + + void + emma3_irq_init(u32 irq_base) + { + extern irq_desc_t irq_desc[]; + u32 i; + + for (i= irq_base; i< irq_base+ NUM_EMMA3_IRQ; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = NULL; + irq_desc[i].depth = 1; + irq_desc[i].handler = &emma3_irq_controller; + } + + emma3_irq_base = irq_base; + } + + void ll_emma3_irq_enable(int emma3_irq) + { + u32 reg_value; + u32 reg_bitmask; + u32 reg_index; + + reg_index = EMMA3_BHIF_MAIN_INT0_EN0 + + 4 * (emma3_irq / 32); + reg_value = emma3_in32(reg_index); + reg_bitmask = 0x1 << (emma3_irq % 32); + db_assert((reg_value & reg_bitmask) == 0); + emma3_out32(reg_index, reg_value | reg_bitmask); + } + + void ll_emma3_irq_disable(int emma3_irq) + { + u32 reg_value; + u32 reg_bitmask; + u32 reg_index; + + reg_index = EMMA3_BHIF_MAIN_INT0_EN0 + + 4 * (emma3_irq / 32); + + reg_value = emma3_in32(reg_index); + reg_bitmask = 0x1 << (emma3_irq % 32); + db_assert((reg_value & reg_bitmask) != 0); + emma3_out32(reg_index, reg_value & ~reg_bitmask); + } + + /* + * EMMA3 GPIO IRQ + */ + static int emma3_gpio_irq_base = -1; + + void ll_emma3_gpio_irq_enable(int reg); + void ll_emma3_gpio_irq_disable(int reg); + + static void emma3_gpio_irq_enable(unsigned int irq) + { + ll_emma3_gpio_irq_enable(irq - emma3_gpio_irq_base); + } + + static void emma3_gpio_irq_disable(unsigned int irq) + { + ll_emma3_gpio_irq_disable(irq - emma3_gpio_irq_base); + } + + static unsigned int emma3_gpio_irq_startup(unsigned int irq) + { + emma3_gpio_irq_enable(irq); + return 0; + } + + #define emma3_gpio_irq_shutdown emma3_gpio_irq_disable + + static void emma3_gpio_irq_ack(unsigned int irq) + { + irq -= emma3_gpio_irq_base; + + if (irq <32) { + emma3_out32(EMMA3_ZPIO0_INT, ~(1 << irq)); + } else { + emma3_out32(EMMA3_ZPIO1_INT, ~(1 << (irq-32))); + } + ll_emma3_gpio_irq_disable(irq); + } + + static void emma3_gpio_irq_end(unsigned int irq) + { + unsigned int tirq; + + tirq = irq - emma3_gpio_irq_base; + + if (tirq <32) { + emma3_out32(EMMA3_ZPIO0_INT, ~(1 << tirq)); + } else { + emma3_out32(EMMA3_ZPIO1_INT, ~(1 << (tirq-32))); + } + + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_emma3_gpio_irq_enable(irq - emma3_gpio_irq_base); + } + + hw_irq_controller emma3_gpio_irq_controller = { + "emma3_gpio_irq", + emma3_gpio_irq_startup, + emma3_gpio_irq_shutdown, + emma3_gpio_irq_enable, + emma3_gpio_irq_disable, + emma3_gpio_irq_ack, + emma3_gpio_irq_end, + NULL, + }; + + void emma3_gpio_irq_init(u32 irq_base) + { + extern irq_desc_t irq_desc[]; + u32 i; + + for(i=irq_base; i= 0); + db_assert(irq < 64); + + if (irq < 32) { + reg = emma3_in32(EMMA3_ZPIO0_INT_CPUMEN); + reg |= 1 << irq; + emma3_out32(EMMA3_ZPIO0_INT_CPUMEN, reg); + } else { + reg = emma3_in32(EMMA3_ZPIO1_INT_CPUMEN); + reg |= 1 << (irq-32); + emma3_out32(EMMA3_ZPIO1_INT_CPUMEN, reg); + } + } + + void ll_emma3_gpio_irq_disable(int irq) + { + u32 reg; + + db_assert(irq >= 0); + db_assert(irq < 64); + + if (irq < 32) { + reg = emma3_in32(EMMA3_ZPIO0_INT_CPUMEN); + reg &= ~(1 << irq); + emma3_out32(EMMA3_ZPIO0_INT_CPUMEN, reg); + } else { + reg = emma3_in32(EMMA3_ZPIO1_INT_CPUMEN); + reg &= ~(1 << (irq-32)); + emma3_out32(EMMA3_ZPIO1_INT_CPUMEN, reg); + } + } + + /* + * EMMA3 SWINT IRQ + */ + static int emma3_swint_irq_base = -1; + + void ll_emma3_swint_irq_enable(int reg); + void ll_emma3_swint_irq_disable(int reg); + + static void emma3_swint_irq_enable(unsigned int irq) + { + ll_emma3_swint_irq_enable(irq - emma3_swint_irq_base); + } + + static void emma3_swint_irq_disable(unsigned int irq) + { + ll_emma3_swint_irq_disable(irq - emma3_swint_irq_base); + } + + static unsigned int emma3_swint_irq_startup(unsigned int irq) + { + emma3_swint_irq_enable(irq); + return 0; + } + + #define emma3_swint_irq_shutdown emma3_swint_irq_disable + + static void emma3_swint_irq_ack(unsigned int irq) + { + irq -= emma3_swint_irq_base; + emma3_out32(EMMA3_BHIF_SW_INT0_CLR, (1 << irq)); + ll_emma3_swint_irq_disable(irq); + } + + static void emma3_swint_irq_end(unsigned int irq) + { + if(!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + ll_emma3_swint_irq_enable(irq - emma3_swint_irq_base); + } + + hw_irq_controller emma3_swint_irq_controller = { + "emma3_swint_irq", + emma3_swint_irq_startup, + emma3_swint_irq_shutdown, + emma3_swint_irq_enable, + emma3_swint_irq_disable, + emma3_swint_irq_ack, + emma3_swint_irq_end, + NULL, + }; + + void emma3_swint_irq_init(u32 irq_base) + { + extern irq_desc_t irq_desc[]; + u32 i; + + for(i=irq_base; i= 0); + db_assert(irq < 32); + + reg = emma3_in32(EMMA3_BHIF_SW_INT0_EN); + reg |= 1 << irq; + emma3_out32(EMMA3_BHIF_SW_INT0_EN, reg); + } + + void ll_emma3_swint_irq_disable(int irq) + { + u32 reg; + + db_assert(irq >= 0); + db_assert(irq < 32); + + reg = emma3_in32(EMMA3_BHIF_SW_INT0_EN); + reg &= ~(1 << irq); + emma3_out32(EMMA3_BHIF_SW_INT0_EN, reg); + } + + /* + * IRQ mapping + * + * 0-7: 8 CPU interrupts + * 0 - software interrupt 0 + * 1 - software interrupt 1 + * 2 - most EMMA3 interrupts are routed to this pin + * 3 - (optional) + * 4 - not used + * 5 - not used + * 6 - not used + * 7 - cpu timer (used by default) + * + * 8 - 103: 96 EMMA3 interrupt sources + * 104 - 135: 32 EMMA3 SWINT interrupt sources + * 136 - 167: 32 EMMA3 GPIO0 interrupt sources + * 138 - 199: 32 EMMA3 GPIO1 interrupt sources + * (refer to the EMMA3 manual) + */ + + extern void mips_cpu_irq_init(u32 base); + extern asmlinkage void emma3_handle_int(void); + extern int setup_irq(unsigned int irq, struct irqaction *irqaction); + static struct irqaction irq_cascade = { .handler = no_action, .name = "cascade"}; + + void __init emma3_arch_init_irq(void) + { + /* by default, interrupts are disabled. */ + emma3_out32(EMMA3_BHIF_MAIN_INT0_EN0, 0); + emma3_out32(EMMA3_BHIF_MAIN_INT0_EN1, 0); + emma3_out32(EMMA3_BHIF_MAIN_INT0_EN2, 0); + emma3_out32(EMMA3_BHIF_MAIN_INT1_EN0, 0); + emma3_out32(EMMA3_BHIF_MAIN_INT1_EN1, 0); + emma3_out32(EMMA3_BHIF_MAIN_INT1_EN2, 0); + + clear_c0_status(0xff00); + set_c0_status(0x0400); + + /* init all controllers */ + emma3_irq_init(EMMA3_IRQ_BASE); + emma3_swint_irq_init(EMMA3_SWINT_IRQ_BASE); + emma3_gpio_irq_init(EMMA3_GPIO0_IRQ_BASE); + + mips_cpu_irq_init(CPU_IRQ_BASE); + + /* setup cascade interrupts */ + setup_irq(EMMA3_SWINT_CASCADE, &irq_cascade); + setup_irq(EMMA3_GPIO_CASCADE, &irq_cascade); + + setup_irq(EMMA3_CPU_CASCADE, &irq_cascade); + + /* hook up the first-level interrupt handler */ + set_except_vector(0, emma3_handle_int); + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma3/pci.c linux-current/arch/mips/emma/emma3/pci.c *** linux-2.6.10/arch/mips/emma/emma3/pci.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma3/pci.c Thu Dec 14 11:17:27 2006 *************** *** 0 **** --- 1,147 ---- + /* + * arch/mips/emma/emma3/pci.c + * This file defines the PCI configration. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/pci.c + * + * Copyright 2001 MontaVista Software 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 + */ + + /* + * (C) Copyright TOSHIBA CORPORATION 2005-2006 + * All Rights Reserved. + */ + + #include + #include + #include + #include + #include + + #include + #include + + #include + + extern unsigned long pcimem_phys_offset; + extern int pci_probe_only; + + #ifdef CONFIG_PCI + + static struct resource pci_io_resource = { + "pci IO space", + EMMA3_PCI_IO_BASE, + 0, + IORESOURCE_IO}; + + static struct resource pci_mem_resource = { + "pci memory space", + EMMA3_PCI_MEM_BASE, + EMMA3_PCI_MEM_BASE + EMMA3_PCI_MEM_SIZE -1, + IORESOURCE_MEM}; + + extern struct pci_ops emma3_pci_ops; + + static struct pci_controller emma3_pci_controller = { + .pci_ops = &emma3_pci_ops, + .mem_resource = &pci_mem_resource, + .mem_offset = EMMA3_PCI_MEM_BASE - EMMA3_PCI_MEM_PCIBASE, + .io_resource = &pci_io_resource, + .io_offset = EMMA3_PCI_IO_BASE - EMMA3_PCI_IO_PCIBASE + }; + + int emma3_pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) + { + + switch (slot) { + case 3: + if (mips_machtype == MACH_EMMA3_TYPE3) + return EMMA3_PCI_USB_IRQ_A2; + else + return EMMA3_PCI_USB_IRQ; + break; + case 4: + if (mips_machtype == MACH_EMMA3_TYPE3) + return EMMA3_PCI_ETHER_IRQ_A2; + else + return EMMA3_PCI_ETHER_IRQ; + break; + default: + printk("pcibios_map_irq: Unknown Interrupt Slot %d\n", slot); + return 0; + break; + } + return 0; + } + + void emma3_pcibios_fixup_resources(struct pci_dev *dev) + { + } + + /* Do platform specific device initialization at pci_enable_device() time */ + int emma3_pcibios_plat_dev_init(struct pci_dev *dev) + { + /* Do nothing */ + return 0; + } + + /* + * local_emma3_read_config_dword are local emma3 PCI Config access functions. + */ + + static u32 local_emma3_read_config_dword(u32 slot_num, u32 func_num, int where, u32 *val) + { + u32 base = EMMA3_PCI_CONF_BASE; + u32 backup_win0, config_win0, backup_eswp; + + if (slot_num > 9) + return PCIBIOS_DEVICE_NOT_FOUND; + + backup_win0 = emma3_in32(EMMA3_PCI_IWIN0_CTR); + backup_eswp = emma3_in32(EMMA3_PCI_INIT_ESWP); + + emma3_out32(EMMA3_PCI_INT, ~(EMMA3_PCI_INT_RMABORT)); + config_win0 = (1 << (22 + slot_num)) | (5 << 8); /* type 0 config */ + + emma3_out32(EMMA3_PCI_INIT_ESWP, backup_eswp & ~(7)); + emma3_out32(EMMA3_PCI_IWIN0_CTR, config_win0); + + *val = *(volatile u32*) (base + (func_num << 8) + where); + + emma3_out32(EMMA3_PCI_IWIN0_CTR, backup_win0); + emma3_out32(EMMA3_PCI_INIT_ESWP, backup_eswp); + + if (emma3_in32(EMMA3_PCI_INT) & EMMA3_PCI_INT_RMABORT) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + return PCIBIOS_SUCCESSFUL; + } + + void __init emma3_pci_init(void) + { + int val; + register_pci_controller(&emma3_pci_controller); + + /* set pcimem_phys_offset */ + local_emma3_read_config_dword(5, 40, 0x14, &val); + pcimem_phys_offset = val; + pci_probe_only = 1; + + } + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma3/pci_ops.c linux-current/arch/mips/emma/emma3/pci_ops.c *** linux-2.6.10/arch/mips/emma/emma3/pci_ops.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma3/pci_ops.c Wed Sep 13 14:06:17 2006 *************** *** 0 **** --- 1,217 ---- + /* + * arch/mips/emma/emma3/pci_ops.c + * This file defines the PCI operation for EMMA3. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/pci_ops.c + * + * Copyright 2001 MontaVista Software 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 + */ + + /* + * (C) Copyright TOSHIBA CORPORATION 2005-2006 + * All Rights Reserved. + */ + + #include + #include + #include + #include + + #include + #include + + #include + + /* + * access config space + */ + static int read_config_dword(struct pci_bus *bus_ptr, unsigned int devfn, + int where, u32 *val) + { + u32 bus, slot_num, func_num; + u32 base = EMMA3_PCI_CONF_BASE; + u32 backup_win0, config_win0; + u32 backup_eswp; + unsigned long flags; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (bus_ptr->parent != NULL) { + bus = bus_ptr->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(devfn); + func_num = PCI_FUNC(devfn); + + if( !((slot_num == EMMA3_PCI_LAN_SLOT)||(slot_num == EMMA3_PCI_USB_SLOT)) ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + + + backup_win0 = emma3_in32(EMMA3_PCI_IWIN0_CTR); + backup_eswp = emma3_in32(EMMA3_PCI_INIT_ESWP); + + local_irq_save(flags); + + emma3_out32(EMMA3_PCI_INT, ~(EMMA3_PCI_INT_RMABORT)); + + if (bus == 0) { + config_win0 = (1 << (22 + slot_num)) | (5 << 8); /* type 0 config */ + } else { + config_win0 = (1 << (26 + bus)) | (1 << (22 + slot_num)) + | (1 << 15) | (5 << 8); /* type 1 config */ + } + + emma3_out32(EMMA3_PCI_INIT_ESWP, backup_eswp & ~(7)); + emma3_out32(EMMA3_PCI_IWIN0_CTR, config_win0); + + *val = *(volatile u32*) (base + (func_num << 8) + where); + + emma3_out32(EMMA3_PCI_IWIN0_CTR, backup_win0); + emma3_out32(EMMA3_PCI_INIT_ESWP, backup_eswp); + + if (emma3_in32(EMMA3_PCI_INT) & EMMA3_PCI_INT_RMABORT) { + local_irq_restore(flags); + return PCIBIOS_DEVICE_NOT_FOUND; + } + + local_irq_restore(flags); + return PCIBIOS_SUCCESSFUL; + } + + static int write_config_dword(struct pci_bus *bus_ptr, unsigned int devfn, + int where, u32 val) + { + u32 bus, slot_num, func_num; + u32 base = EMMA3_PCI_CONF_BASE; + u32 backup_win0, config_win0; + u32 backup_eswp; + unsigned long flags; + + db_assert((where & 3) == 0); + db_assert(where < (1 << 8)); + + /* check if the bus is top-level */ + if (bus_ptr->parent != NULL) { + bus = bus_ptr->number; + db_assert(bus != 0); + } else { + bus = 0; + } + + slot_num = PCI_SLOT(devfn); + func_num = PCI_FUNC(devfn); + + if( !((slot_num == EMMA3_PCI_LAN_SLOT)||(slot_num == EMMA3_PCI_USB_SLOT)) ) { + return PCIBIOS_DEVICE_NOT_FOUND; + } + + backup_win0 = emma3_in32(EMMA3_PCI_IWIN0_CTR); + backup_eswp = emma3_in32(EMMA3_PCI_INIT_ESWP); + + local_irq_save(flags); + + emma3_out32(EMMA3_PCI_INT, ~(EMMA3_PCI_INT_RMABORT)); + + if (bus == 0) { + config_win0 = (1 << (22 + slot_num)) | (5 << 8); /* type 0 config */ + } else { + config_win0 = (1 << (26 + bus)) | (1 << (22 + slot_num)) + | (1 << 15) | (5 << 8); /* type 1 config */ + } + + emma3_out32(EMMA3_PCI_INIT_ESWP, backup_eswp & ~(7)); + emma3_out32(EMMA3_PCI_IWIN0_CTR, config_win0); + + *(volatile u32*) (base + (func_num << 8) + where) = val; + + emma3_out32(EMMA3_PCI_IWIN0_CTR, backup_win0); + emma3_out32(EMMA3_PCI_INIT_ESWP, backup_eswp); + + if (emma3_in32(EMMA3_PCI_INT) & EMMA3_PCI_INT_RMABORT) { + local_irq_restore(flags); + return PCIBIOS_DEVICE_NOT_FOUND; + } + + local_irq_restore(flags); + return PCIBIOS_SUCCESSFUL; + } + + static int emma3_pci_config_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) + { + int status; + u32 result; + + switch (size) { + case 1: + status = read_config_dword(bus, devfn, where & ~3, &result); + result >>= ((where & 3) * 8); + *val = result & 0xff; + break; + case 2: + status = read_config_dword(bus, devfn, where & ~3, &result); + result >>= ((where & 2) * 8); + *val = result & 0xffff; + break; + default: + status = read_config_dword(bus, devfn, where & ~3, &result); + *val = result; + } + + return (status); + } + + static int emma3_pci_config_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) + { + int status, shift; + u32 result; + + switch (size) { + case 1: + status = read_config_dword(bus, devfn, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) return status; + shift = (where & 3) * 8; + result &= ~(0xff << shift); + result |= val << shift; + return(write_config_dword(bus, devfn, where & ~3, result)); + break; + case 2: + status = read_config_dword(bus, devfn, where & ~3, &result); + if (status != PCIBIOS_SUCCESSFUL) return status; + shift = (where & 2) * 8; + result &= ~(0xffff << shift); + result |= val << shift; + return (write_config_dword(bus, devfn, where & ~3, result)); + break; + default: + return (write_config_dword(bus, devfn, where & ~3, val)); + } + } + + struct pci_ops emma3_pci_ops ={ + .read = emma3_pci_config_read, + .write = emma3_pci_config_write, + }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/emma3/setup.c linux-current/arch/mips/emma/emma3/setup.c *** linux-2.6.10/arch/mips/emma/emma3/setup.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/emma3/setup.c Thu Dec 14 11:17:26 2006 *************** *** 0 **** --- 1,276 ---- + /* + * arch/mips/emma2hl/alpha8/setup.c + * This file is setup for EMMA2HL Alpha8. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/ddb5477/setup.c. + * + * Copyright 2001 MontaVista Software 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 + */ + /* + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include /* for ROOT_DEV */ + #include + #include /* for HZ */ + #include + + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + + #define PLAN_SETUP /* PLAN setup at emma3 initialize */ + + unsigned char EMMA3_rev; + + #define USE_CPU_COUNTER_TIMER /* whether we use cpu counter */ + + static int bus_frequency; + + static struct resource EMMA3_reg_resource = { + "EMMA3", EMMA3_REG_PBASE, EMMA3_REG_PBASE+EMMA3_REG_SIZE-1, IORESOURCE_MEM + }; + + static void EMMA3_machine_restart(char *command) + { + printk("cannot restart.\n"); + while (1); + } + + static void EMMA3_machine_halt(void) + { + printk("halted.\n"); + while (1); + } + + static void EMMA3_machine_power_off(void) + { + printk("Please turn off the power.\n"); + while (1); + } + + static unsigned int __init detect_bus_frequency(unsigned long rtc_base) + { + unsigned int freq = 163840000; + /* detect from boot strap */ + switch((emma3_in32(EMMA3_BHIF_STRAP0) >> 6) & 3) { + case 2 : freq = 163840000 ; break; + + case 0 : /* Reserved */ + case 1 : /* Reserved */ + case 3 : /* Reserved */ + freq = 163840000 ; break; + } + return freq; + + } + + static void __init EMMA3_time_init(void) + { + if(bus_frequency == 0) + bus_frequency = detect_bus_frequency(0); + mips_hpt_frequency = bus_frequency; + } + + extern int setup_irq(unsigned int irq, struct irqaction *irqaction); + static void __init EMMA3_timer_setup(struct irqaction *irq) + { + /* we are using the cpu counter for timer interrupts */ + setup_irq(CPU_IRQ_BASE + 7, irq); + } + + static void EMMA3_board_init(void); + extern void EMMA3_irq_setup(void); + extern void emma3_pci_init(void); + + int __init EMMA3_setup(void) + { + extern int panic_timeout; + struct uart_port req; + char *board_envstr; + + EMMA3_rev = (unsigned char) (emma3_in32(EMMA3_BHIF_VERSION) & 0xff); + printk("EMMA3 Rev Maj %1x, Min %1x\n", EMMA3_rev >> 4, EMMA3_rev & 0xf); + EMMA3_board_init(); + + /* EMMA3 internal registers & CSx */ + request_resource(&iomem_resource, &EMMA3_reg_resource); + + set_io_port_base(0); + + board_time_init = EMMA3_time_init; + board_timer_setup = EMMA3_timer_setup; + + _machine_restart = EMMA3_machine_restart; + _machine_halt = EMMA3_machine_halt; + _machine_power_off = EMMA3_machine_power_off; + + /* Reboot on panic */ + panic_timeout = 180; + + #ifdef CONFIG_PCI + /* wait PCI configuration at here */ + if (mips_machtype != MACH_EMMA3_TYPE0) + emma3_pci_init(); + #endif + /* serial setup */ + + #define EMMA3_BASE_BAUD (24576000) + /* TTY0 for debug console*/ + + board_envstr = pmon_getenv("board"); + + if (!board_envstr || (strncmp(board_envstr, "DVK", 3) != 0)) { + + switch ( mips_machtype ) + { + case MACH_EMMA3_TYPE0: + case MACH_EMMA3_TYPE1: + case MACH_EMMA3_TYPE2: + memset(&req, 0, sizeof(req)); + req.line = 0; + req.iotype = UPIO_MEM; + req.membase = (char *) (EMMA3_UART1_BASE + 3); + req.mapbase = (unsigned long) (EMMA3_UART1_BASE & 0x1fffffff); + req.irq = EMMA3_PFUR1_IRQ; + req.flags = ASYNC_BOOT_AUTOCONF; + req.uartclk = EMMA3_BASE_BAUD; + req.regshift = 2; + early_serial_setup(&req); + break; + case MACH_EMMA3_TYPE3: + memset(&req, 0, sizeof(req)); + req.line = 0; + req.iotype = UPIO_MEM; + req.membase = (char *) (EMMA3_UART2_BASE + 3); + req.mapbase = (unsigned long) (EMMA3_UART2_BASE & 0x1fffffff); + req.irq = EMMA3_PFUR2_IRQ; + req.flags = ASYNC_BOOT_AUTOCONF; + req.uartclk = EMMA3_BASE_BAUD; + req.regshift = 2; + early_serial_setup(&req); + memset(&req, 0, sizeof(req)); + req.line = 1; + req.iotype = UPIO_MEM; + req.membase = (char *) (EMMA3_UART1_BASE + 3); + req.mapbase = (unsigned long) (EMMA3_UART1_BASE & 0x1fffffff); + req.irq = EMMA3_PFUR1_IRQ; + req.flags = ASYNC_BOOT_AUTOCONF; + req.uartclk = EMMA3_BASE_BAUD; + req.regshift = 2; + early_serial_setup(&req); + break; + default: + break; + } + } + + + #ifdef PLAN_SETUP + { + unsigned long tmp; + #define INTERRUPT_TO_VR_NUM 13 + #define INTERRUPT_FROM_VR_NUM 14 + + if (mips_machtype == MACH_EMMA3_TYPE0) { + + memset((void *) 0xae000000, 0, 0x20000); + emma3_out32 (EMMA3_PCI_TWIN0_DADDR, 0x00000000); /* PCI_TWIN0_DADR */ + emma3_out32 (EMMA3_PCI_TWIN1_DADDR, 0x06000000); /* PCI_TWIN1_DADR */ + emma3_out32 (EMMA3_PCI_TWIN_BADR, 0x00000000); /* PCI_TWIN_BADR */ + emma3_out32 (EMMA3_PCI_TWIN_CTR, 0x00008000); /* PCI_TWIN_CTR */ + tmp = emma3_in32 (EMMA3_ZPIO0_DIR); /* Dir */ + tmp |= ((1 << INTERRUPT_FROM_VR_NUM) | (1 << INTERRUPT_TO_VR_NUM)); + emma3_out32 (EMMA3_ZPIO0_DIR, tmp); /* GPIO13, 14 ==> Output */ + + tmp = emma3_in32 (EMMA3_ZPIO0_INT_MODE); /* Mode */ + tmp |= (1 << INTERRUPT_FROM_VR_NUM); + emma3_out32 (EMMA3_ZPIO0_INT_MODE, tmp); + + tmp = emma3_in32 (EMMA3_ZPIO0_INT_CNDA); /* COND A */ + tmp |= (1 << INTERRUPT_FROM_VR_NUM); + emma3_out32 (EMMA3_ZPIO0_INT_CNDA, tmp); + + tmp = emma3_in32 (EMMA3_ZPIO0_INT_CNDB); /* COND B */ + tmp &= ~(1 << INTERRUPT_FROM_VR_NUM); + emma3_out32 (EMMA3_ZPIO0_INT_CNDB, tmp); + + printk ("Mode %8x, COND A %8x, COND B %8x\n", + emma3_in32 (EMMA3_ZPIO0_INT_MODE), + emma3_in32 (EMMA3_ZPIO0_INT_CNDA), + emma3_in32 (EMMA3_ZPIO0_INT_CNDB)); + } + + } + #endif + + return 0; + } + + static void __init EMMA3_board_init(void) + { + /* setup resource limits */ + ioport_resource.start = 0; + ioport_resource.end = ~0UL; /* no limit */ + iomem_resource.start = 0; + iomem_resource.end = ~0UL; /* no limit */ + } + + static int __init + EMMA3_device_init(void) + { + struct resource res[3]; + + if (mips_machtype != MACH_EMMA3_TYPE3) { + memset(res, 0, sizeof(res)); + res[0].start = EMMA3_ISA_LAN_ADDRESS; + res[0].end = res[0].start + 0x10 - 1; + res[0].flags = IORESOURCE_MEM; + res[1].start = EMMA3_ISA_LAN_IRQ; + res[1].flags = IORESOURCE_IRQ; + platform_device_register_simple("smc91x", -1, + res, ARRAY_SIZE(res)); + } + return 0; + } + device_initcall(EMMA3_device_init); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/generic/Makefile linux-current/arch/mips/emma/generic/Makefile *** linux-2.6.10/arch/mips/emma/generic/Makefile Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/generic/Makefile Tue Aug 29 22:54:58 2006 *************** *** 0 **** --- 1,8 ---- + # + # Makefile for the generic code of EMMA + # + # Note! Dependencies are done automagically by 'make dep', which also + # removes any old dependencies. DON'T put your own dependencies here + # unless it's something special (ie not a .c file). + # + obj-y += prom.o pmon.o pmon-low.o setup.o pci.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/generic/pci.c linux-current/arch/mips/emma/generic/pci.c *** linux-2.6.10/arch/mips/emma/generic/pci.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/generic/pci.c Tue Aug 29 22:54:58 2006 *************** *** 0 **** --- 1,58 ---- + /* + * (C) Copyright TOSHIBA CORPORATION 2006 + * All Rights Reserved. + */ + + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + + extern int emma2rh_pcibios_map_irq(struct pci_dev *, u8, u8); + extern int emma3_pcibios_map_irq(struct pci_dev *, u8, u8); + extern void emma2rh_pcibios_fixup_resources(struct pci_dev *dev); + extern void emma3_pcibios_fixup_resources(struct pci_dev *dev); + extern int emma2rh_pcibios_plat_dev_init(struct pci_dev *dev); + extern int emma3_pcibios_plat_dev_init(struct pci_dev *dev); + + int (*txboard_pci_scan_hook)(struct pci_dev *dev); + + int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) + { + switch (mips_machgroup) { + case MACH_GROUP_EMMA2RH: + return emma2rh_pcibios_map_irq(dev, slot, pin); + case MACH_GROUP_EMMA3: + return emma3_pcibios_map_irq(dev, slot, pin); + } + return 1; + } + + void __init pcibios_fixup_resources(struct pci_dev *dev) + { + switch (mips_machgroup) { + case MACH_GROUP_EMMA2RH: + return emma2rh_pcibios_fixup_resources(dev); + case MACH_GROUP_EMMA3: + return emma3_pcibios_fixup_resources(dev); + } + return; + } + + int pcibios_plat_dev_init(struct pci_dev *dev) + { + switch (mips_machgroup) { + case MACH_GROUP_EMMA2RH: + return emma2rh_pcibios_plat_dev_init(dev); + case MACH_GROUP_EMMA3: + return emma3_pcibios_plat_dev_init(dev); + } + return 1; + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/generic/pmon-low.S linux-current/arch/mips/emma/generic/pmon-low.S *** linux-2.6.10/arch/mips/emma/generic/pmon-low.S Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/generic/pmon-low.S Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,59 ---- + /* + * linux/arch/mips/emma/generic/pmon-low.S + * + * 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. + * + * (C) Copyright TOSHIBA CORPORATION 2004 + * All Rights Reserved. + * + */ + #include + #include + #include + #include + #include + #include + + .align 5 + NESTED(pmon_trap_low, PT_SIZE, sp) + .set noat + .set noreorder + mfc0 k0,CP0_STATUS + sll k0,3 /* extract cu0 bit */ + bltz k0,1f + nop + /* + * Trap from user mode - invoke user exception handler + * saved in pmon.c + */ + mfc0 k1,CP0_CAUSE + andi k1,k1,0x7c + #ifdef __mips64 + dsll k1,k1,1 + #endif + PTR_LA k0,pmon_user_exception_handler + PTR_ADDU k0,k1 + PTR_L k0,(k0) + nop + jr k0 + nop + 1: + /* If we're in pmon_breakpoint() increment the PC */ + PTR_LA k0, pmon_breakinst + MFC0 k1,CP0_EPC + bne k1,k0,1f + nop + PTR_ADD k1,4 + MTC0 k1,CP0_EPC + 1: + /* jump into PMON */ + PTR_LA k0, pmon_vector + PTR_L k0, (k0) + PTR_L k0, PTRSIZE*12(k0) /* 12:_exception */ + jr k0 + nop + .set at + .set reorder + END(pmon_trap_low) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/generic/pmon.c linux-current/arch/mips/emma/generic/pmon.c *** linux-2.6.10/arch/mips/emma/generic/pmon.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/generic/pmon.c Mon May 28 16:30:55 2007 *************** *** 0 **** --- 1,200 ---- + /* + * linux/arch/mips/emma/generic/pmon.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. + * + * (C) Copyright TOSHIBA CORPORATION 2004-2005 + * All Rights Reserved. + * + */ + #include + #include + #include + #include + #include /* for smp_processor_id() */ + #ifdef CONFIG_EARLY_PRINTK + #include + #endif /* CONFIG_EARLY_PRINTK */ + #include + #include + #include + #include + + struct pmon_vector *pmon_vector; + + /* simple check for PMON vector */ + static inline int pmon_simple_check( unsigned int addr, unsigned long vec ) + { + int i; + __u32 check_flag; + __u32 haddr; + + check_flag = 0; + haddr = ((*(__u32 *)vec) & 0xff000000); + for (i = 0; i < sizeof(*pmon_vector) / sizeof(void *); i++) { + __u32 p = *((__u32 *)vec + i); + check_flag |= p; + if ((p & 0xff000000) != haddr && p != 0) { + return 1; + } + } + if ( check_flag == 0 ) { + /* vector is all zero */ + return 1; + } + return 0; + } + + /* this function is executed 32-bit kernel mode even on mips64 */ + void __init pmon_setup_vector(void) + { + unsigned long vec,vec_base; + + vec = PMON_VECTOR; + vec_base = PMON_VECTOR_BASE; + if ( !pmon_simple_check( vec_base, vec) ) { + pmon_vector = (struct pmon_vector *)vec; + return; + } + + } + + void __init pmon_setup_args(int *argcp, char ***argvp, char ***envpp) + { + } + + void pmon_halt(void) + { + local_irq_disable(); + if (pmon_vector && pmon_vector->exit) + pmon_vector->exit(0); + while (1) + ; + } + + extern asmlinkage void pmon_trap_low(void); + void *pmon_user_exception_handler[32]; + static int pmon_debug_initialized; + void __init set_pmon_debug_traps(void) + { + unsigned long flags; + int tt = 9; /* beakpoint only */ + + if (!pmon_vector) + return; + local_irq_save(flags); + /* save original handlers (for user-mode exceptions) */ + pmon_user_exception_handler[tt] = set_except_vector(tt, pmon_trap_low); + local_irq_restore(flags); + pmon_debug_initialized = 1; + } + + void pmon_breakpoint(void) + { + if (!pmon_debug_initialized) + return; + pmon_printf("entering PMON. Type \"c\" to continue.\n"); + + __asm__ __volatile__( + ".globl pmon_breakinst\n\t" + ".set noreorder\n\t" + "nop\n" + "pmon_breakinst:\tbreak\n\t" + "nop\n\t" + ".set reorder" + ); + } + + char __init *pmon_getenv(const char *name) + { + unsigned long flags; + char *s; + if (!pmon_vector) { + return NULL; + } + local_irq_save(flags); + s = pmon_vector->getenv((char *)name); + local_irq_restore(flags); + return s; + } + + int pmon_interpret(const char *cmd, char *outbuf, int len) + { + unsigned long flags; + int ret; + if (!pmon_vector || !pmon_vector->interpret) + return -1; + local_irq_save(flags); + ret = pmon_vector->interpret(cmd, outbuf, len); + local_irq_restore(flags); + return ret; + } + + unsigned int __init get_pmon_clkfreq(void) + { + unsigned int cpu_clock = 0; + char *s, *endp; + if ((s = pmon_getenv("clkfreq")) != NULL) { + cpu_clock = simple_strtoul(s, &endp, 10) * 1000000; + if (*endp == '.') { + unsigned int sub; + s = endp + 1; + sub = simple_strtoul(s, &endp, 10); + while (endp++ < s + 6) + sub *= 10; + cpu_clock += sub; + } + } + return cpu_clock; + } + + /* promlib support routine */ + void prom_putchar(char c) + { + unsigned long flags; + if (!pmon_vector) + return; + local_irq_save(flags); + pmon_vector->write(1/*STDOUT*/, &c, 1); + local_irq_restore(flags); + } + + #ifdef CONFIG_EARLY_PRINTK + static void __init prom_console_write(struct console *con, const char *s, + unsigned int c) + { + int i; + for (i = 0; i < c; i++) { + if (*s == '\n') + prom_putchar('\r'); + prom_putchar(*s++); + } + } + + static struct console promcons __initdata = { + .name = "prom", + .write = prom_console_write, + .flags = CON_PRINTBUFFER, + .index = -1, + }; + + static int promcons_output __initdata = 0; + + void __init register_prom_console(void) + { + if (!promcons_output) { + promcons_output = 1; + register_console(&promcons); + } + } + + void __init unregister_prom_console(void) + { + if (promcons_output) { + unregister_console(&promcons); + promcons_output = 0; + } + } + #endif /* CONFIG_EARLY_PRINTK */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/generic/prom.c linux-current/arch/mips/emma/generic/prom.c *** linux-2.6.10/arch/mips/emma/generic/prom.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/generic/prom.c Thu Dec 14 11:17:26 2006 *************** *** 0 **** --- 1,178 ---- + /* + * arch/mips/emma2hl/common/prom.c + * This file is prom file. + * + * Copyright (C) NEC Electronics Corporation 2004 + * + * This file is based on the arch/mips/ddb5xxx/common/prom.c + * + * Copyright 2001 MontaVista Software 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 + */ + /* + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + * + */ + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + extern void pmon_setup_vector(void); + + const char *get_system_type(void) + { + switch (mips_machgroup) { + case MACH_GROUP_EMMA2RH: + switch (mips_machtype) { + case MACH_EMMA2RH_GENERIC: + return "EMMA2RH_GENERIC"; + break; + default: + return "EMMA2RH_UNKNOWN_TYPE"; + break; + } + break; + case MACH_GROUP_EMMA3: + switch (mips_machtype) { + case MACH_EMMA3_TYPE0: + return "EMMA3_TYPE0"; + break; + case MACH_EMMA3_TYPE1: + return "EMMA3_TYPE1"; + break; + case MACH_EMMA3_TYPE2: + return "EMMA3_TYPE2"; + break; + case MACH_EMMA3_TYPE3: + return "EMMA3_TYPE3"; + break; + default: + return "EMMA3_UNKNOWN_TYPE"; + break; + } + break; + } + return "Unknown board"; + } + + /* [jsun@junsun.net] PMON passes arguments in C main() style */ + void __init prom_init(void) + { + int i; + char *tmp_argv[32 /* max argc */]; + extern int _text; + char *builtin_cmdline = (char *)&_text + 128; + int argc = (int)fw_arg0; + char **argv = (char **)fw_arg1; + char *envstr; + struct cpuinfo_mips *c = ¤t_cpu_data; + + pmon_setup_vector(); + + if (builtin_cmdline[0]) { + if (builtin_cmdline[0] == '+') { + /* append to original arguments */ + for (i = 0; i < argc; i++) + tmp_argv[i] = argv[i]; + argv = tmp_argv; + builtin_cmdline++; + } else { + /* ignore argc and argv */ + argv = tmp_argv; + argv[0] = "linux"; + argc = 1; + } + while ((argv[argc] = strsep(&builtin_cmdline, " ")) != NULL) { + if (strcmp(argv[argc], "nopmon") == 0) { + argc--; + pmon_vector = NULL; + } + argc++; + } + } else { + /* always use tmp_argv so that we can append argv later. */ + for (i = 0; i < argc; i++) + tmp_argv[i] = argv[i]; + argv = tmp_argv; + } + + /* command from ROM Monitor */ + arcs_cmdline[0] = '\0'; + pmon_printf("boot:"); + /* argv[0] = "g" (go command) */ + for (i = 1; i < argc; i++) { + char *str = argv[i]; + pmon_printf(" %s", str); + if (arcs_cmdline[0]) + strcat(arcs_cmdline, " "); + strcat(arcs_cmdline, str); + } + + pmon_printf("\n"); + + if (arcs_cmdline[0]) + strcat(arcs_cmdline, " "); + + envstr = pmon_getenv("board"); + if (envstr) { + strcat(arcs_cmdline, "BOARD="); + strcat(arcs_cmdline, envstr); + } + + /* + * set machgroup & machtype + */ + switch (c->processor_id & 0xff00) { + case PRID_IMP_R5500: + mips_machgroup = MACH_GROUP_EMMA2RH; + mips_machtype = MACH_EMMA2RH_GENERIC; + break; + case PRID_IMP_VR5600: + mips_machgroup = MACH_GROUP_EMMA3; + mips_machtype = MACH_EMMA3_TYPE0; + break; + } + + envstr = pmon_getenv("machtype"); + + if (envstr) { + mips_machtype = simple_strtoul(envstr, NULL, 10); + } + + add_memory_region(0, EMMA3_SDRAM_SIZE, BOOT_MEM_RAM); + } + + void __init prom_free_prom_memory(void) + { + } + + #ifdef CONFIG_EARLY_PRINTK + extern void register_prom_console(void); + extern void unregister_prom_console(void); + void __init disable_early_printk(void) + { + unregister_prom_console(); + } + #endif /* CONFIG_EARLY_PRINTK */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/emma/generic/setup.c linux-current/arch/mips/emma/generic/setup.c *** linux-2.6.10/arch/mips/emma/generic/setup.c Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/emma/generic/setup.c Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,40 ---- + /* + * (C) Copyright TOSHIBA CORPORATION 2006 + * All Rights Reserved. + */ + + #include + #include + + extern void __init emma3_arch_init_irq(void); + extern void __init emma2rh_arch_init_irq(void); + + extern int __init emma2rh_setup(void); + extern int __init EMMA3_setup(void); + + void __init arch_init_irq(void) + { + switch (mips_machgroup) { + case MACH_GROUP_EMMA2RH: + emma2rh_arch_init_irq(); + break; + case MACH_GROUP_EMMA3: + emma3_arch_init_irq(); + break; + } + } + + static int __init emma_setup(void) + { + switch (mips_machgroup) { + case MACH_GROUP_EMMA2RH: + emma2rh_setup(); + break; + case MACH_GROUP_EMMA3: + EMMA3_setup(); + break; + } + return 0; + } + + early_initcall(emma_setup); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/Makefile linux-current/arch/mips/kernel/Makefile *** linux-2.6.10/arch/mips/kernel/Makefile Sat Dec 25 06:34:32 2004 --- linux-current/arch/mips/kernel/Makefile Wed Jun 14 21:12:58 2006 *************** *** 53,59 **** --- 53,62 ---- obj-$(CONFIG_MIPS64) += cpu-bugs64.o + ifndef CONFIG_TX_BOARDS + # use native get_rtc_time,set_rtc_time,etc. obj-$(CONFIG_GEN_RTC) += genrtc.o + endif CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) CFLAGS_ioctl32.o += -Ifs/ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/binfmt_elfo32.c linux-current/arch/mips/kernel/binfmt_elfo32.c *** linux-2.6.10/arch/mips/kernel/binfmt_elfo32.c Sat Dec 25 06:34:30 2004 --- linux-current/arch/mips/kernel/binfmt_elfo32.c Wed Jun 14 21:12:58 2006 *************** *** 54,60 **** #include #include - #include #include #include --- 54,59 ---- *************** *** 98,104 **** #define init_elf_binfmt init_elf32_binfmt #define jiffies_to_timeval jiffies_to_compat_timeval ! static __inline__ void jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) { /* --- 97,103 ---- #define init_elf_binfmt init_elf32_binfmt #define jiffies_to_timeval jiffies_to_compat_timeval ! static inline void jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) { /* *************** *** 113,133 **** #undef ELF_CORE_COPY_REGS #define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs); ! void elf32_core_copy_regs(elf_gregset_t _dest, struct pt_regs *_regs) { int i; ! memset(_dest, 0, sizeof(elf_gregset_t)); ! ! /* XXXKW the 6 is from EF_REG0 in gdb/gdb/mips-linux-tdep.c, include/asm-mips/reg.h */ ! for (i=6; i<38; i++) ! _dest[i] = (elf_greg_t) _regs->regs[i-6]; ! _dest[i++] = (elf_greg_t) _regs->lo; ! _dest[i++] = (elf_greg_t) _regs->hi; ! _dest[i++] = (elf_greg_t) _regs->cp0_epc; ! _dest[i++] = (elf_greg_t) _regs->cp0_badvaddr; ! _dest[i++] = (elf_greg_t) _regs->cp0_status; ! _dest[i++] = (elf_greg_t) _regs->cp0_cause; } MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); --- 112,137 ---- #undef ELF_CORE_COPY_REGS #define ELF_CORE_COPY_REGS(_dest,_regs) elf32_core_copy_regs(_dest,_regs); ! void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs) { int i; ! for (i = 0; i < EF_R0; i++) ! grp[i] = 0; ! grp[EF_R0] = 0; ! for (i = 1; i <= 31; i++) ! grp[EF_R0 + i] = (elf_greg_t) regs->regs[i]; ! grp[EF_R26] = 0; ! grp[EF_R27] = 0; ! grp[EF_LO] = (elf_greg_t) regs->lo; ! grp[EF_HI] = (elf_greg_t) regs->hi; ! grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc; ! grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr; ! grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status; ! grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause; ! #ifdef EF_UNUSED0 ! grp[EF_UNUSED0] = 0; ! #endif } MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); *************** *** 136,139 **** --- 140,146 ---- #undef MODULE_DESCRIPTION #undef MODULE_AUTHOR + #undef TASK_SIZE + #define TASK_SIZE TASK_SIZE32 + #include "../../../fs/binfmt_elf.c" diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/branch.c linux-current/arch/mips/kernel/branch.c *** linux-2.6.10/arch/mips/kernel/branch.c Sat Dec 25 06:34:45 2004 --- linux-current/arch/mips/kernel/branch.c Fri Mar 30 22:24:51 2007 *************** *** 12,17 **** --- 12,18 ---- #include #include #include + #include #include #include #include *************** *** 161,170 **** * And now the FPA/cp1 branch instructions. */ case cop1_op: ! if (!cpu_has_fpu) ! fcr31 = current->thread.fpu.soft.fcr31; ! else asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; --- 162,174 ---- * And now the FPA/cp1 branch instructions. */ case cop1_op: ! preempt_disable(); ! if (is_fpu_owner()) asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); + else + fcr31 = current->thread.fpu.hard.fcr31; + preempt_enable(); + bit = (insn.i_format.rt >> 2); bit += (bit != 0); bit += 23; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/cpu-probe.c linux-current/arch/mips/kernel/cpu-probe.c *** linux-2.6.10/arch/mips/kernel/cpu-probe.c Sat Dec 25 06:34:30 2004 --- linux-current/arch/mips/kernel/cpu-probe.c Wed Jun 14 21:12:58 2006 *************** *** 98,103 **** --- 98,105 ---- case CPU_R4650: case CPU_R4700: case CPU_R5000: + case CPU_R5500: + case CPU_VR5600: case CPU_NEVADA: case CPU_RM7000: case CPU_RM9000: *************** *** 348,353 **** --- 350,362 ---- MIPS_CPU_WATCH | MIPS_CPU_LLSC; c->tlbsize = 48; break; + case PRID_IMP_VR5600: + c->cputype = CPU_VR5600; + c->isa_level = MIPS_CPU_ISA_IV; + c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | + MIPS_CPU_WATCH | MIPS_CPU_LLSC; + c->tlbsize = 64; + break; case PRID_IMP_NEVADA: c->cputype = CPU_NEVADA; c->isa_level = MIPS_CPU_ISA_IV; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/entry.S linux-current/arch/mips/kernel/entry.S *** linux-2.6.10/arch/mips/kernel/entry.S Sat Dec 25 06:34:02 2004 --- linux-current/arch/mips/kernel/entry.S Wed Jun 14 21:12:58 2006 *************** *** 19,29 **** #include #ifdef CONFIG_PREEMPT ! .macro preempt_stop reg=t0 .endm #else ! .macro preempt_stop reg=t0 ! local_irq_disable \reg .endm #define resume_kernel restore_all #endif --- 19,29 ---- #include #ifdef CONFIG_PREEMPT ! .macro preempt_stop .endm #else ! .macro preempt_stop ! local_irq_disable .endm #define resume_kernel restore_all #endif *************** *** 37,53 **** andi t0, t0, KU_USER beqz t0, resume_kernel ! FEXPORT(resume_userspace) ! local_irq_disable t0 # make sure we dont miss an # interrupt setting need_resched # between sampling and return LONG_L a2, TI_FLAGS($28) # current->work ! andi a2, _TIF_WORK_MASK # (ignoring syscall_trace) ! bnez a2, work_pending j restore_all #ifdef CONFIG_PREEMPT ! ENTRY(resume_kernel) lw t0, TI_PRE_COUNT($28) bnez t0, restore_all need_resched: --- 37,53 ---- andi t0, t0, KU_USER beqz t0, resume_kernel ! resume_userspace: ! local_irq_disable # make sure we dont miss an # interrupt setting need_resched # between sampling and return LONG_L a2, TI_FLAGS($28) # current->work ! andi t0, a2, _TIF_WORK_MASK # (ignoring syscall_trace) ! bnez t0, work_pending j restore_all #ifdef CONFIG_PREEMPT ! resume_kernel: lw t0, TI_PRE_COUNT($28) bnez t0, restore_all need_resched: *************** *** 59,68 **** beqz t0, restore_all li t0, PREEMPT_ACTIVE sw t0, TI_PRE_COUNT($28) ! local_irq_enable t0 jal schedule sw zero, TI_PRE_COUNT($28) ! local_irq_disable t0 b need_resched #endif --- 59,68 ---- beqz t0, restore_all li t0, PREEMPT_ACTIVE sw t0, TI_PRE_COUNT($28) ! local_irq_enable jal schedule sw zero, TI_PRE_COUNT($28) ! local_irq_disable b need_resched #endif *************** *** 88,100 **** RESTORE_SP_AND_RET .set at ! FEXPORT(work_pending) ! andi t0, a2, _TIF_NEED_RESCHED beqz t0, work_notifysig work_resched: jal schedule ! local_irq_disable t0 # make sure need_resched and # signals dont change between # sampling and return LONG_L a2, TI_FLAGS($28) --- 88,100 ---- RESTORE_SP_AND_RET .set at ! work_pending: ! andi t0, a2, _TIF_NEED_RESCHED # a2 is preloaded with TI_FLAGS beqz t0, work_notifysig work_resched: jal schedule ! local_irq_disable # make sure need_resched and # signals dont change between # sampling and return LONG_L a2, TI_FLAGS($28) *************** *** 113,123 **** FEXPORT(syscall_exit_work_partial) SAVE_STATIC ! FEXPORT(syscall_exit_work) ! LONG_L t0, TI_FLAGS($28) ! li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT ! and t0, t1 ! beqz t0, work_pending # trace bit is set local_irq_enable # could let do_syscall_trace() # call schedule() instead move a0, sp --- 113,122 ---- FEXPORT(syscall_exit_work_partial) SAVE_STATIC ! syscall_exit_work: ! li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT ! and t0, a2 # a2 is preloaded with TI_FLAGS ! beqz t0, work_pending # trace bit set? local_irq_enable # could let do_syscall_trace() # call schedule() instead move a0, sp *************** *** 128,155 **** /* * Common spurious interrupt handler. */ - .text - .align 5 LEAF(spurious_interrupt) /* * Someone tried to fool us by sending an interrupt but we * couldn't find a cause for it. */ #ifdef CONFIG_SMP ! lui t1, %hi(irq_err_count) ! 1: ll t0, %lo(irq_err_count)(t1) addiu t0, 1 ! sc t0, %lo(irq_err_count)(t1) #if R10000_LLSC_WAR beqzl t0, 1b #else beqz t0, 1b #endif #else ! lui t1, %hi(irq_err_count) ! lw t0, %lo(irq_err_count)(t1) addiu t0, 1 ! sw t0, %lo(irq_err_count)(t1) #endif j ret_from_irq END(spurious_interrupt) --- 127,151 ---- /* * Common spurious interrupt handler. */ LEAF(spurious_interrupt) /* * Someone tried to fool us by sending an interrupt but we * couldn't find a cause for it. */ + PTR_LA t1, irq_err_count #ifdef CONFIG_SMP ! 1: ll t0, (t1) addiu t0, 1 ! sc t0, (t1) #if R10000_LLSC_WAR beqzl t0, 1b #else beqz t0, 1b #endif #else ! lw t0, (t1) addiu t0, 1 ! sw t0, (t1) #endif j ret_from_irq END(spurious_interrupt) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/gdb-stub.c linux-current/arch/mips/kernel/gdb-stub.c *** linux-2.6.10/arch/mips/kernel/gdb-stub.c Sat Dec 25 06:35:40 2004 --- linux-current/arch/mips/kernel/gdb-stub.c Wed Jun 14 21:12:58 2006 *************** *** 680,685 **** --- 680,688 ---- unsigned long *stack; int i; int bflag = 0; + #if CONFIG_MIPS32 && (_MIPS_ISA == _MIPS_ISA_MIPS3) + u64 tmp64; + #endif kgdb_started = 1; *************** *** 757,763 **** --- 760,771 ---- *ptr++ = hexchars[REG_EPC >> 4]; *ptr++ = hexchars[REG_EPC & 0xf]; *ptr++ = ':'; + #if CONFIG_MIPS32 && (_MIPS_ISA == _MIPS_ISA_MIPS3) /* for gdb 6.1 ... */ + tmp64 = regs->cp0_epc; + ptr = mem2hex((char *)&tmp64, ptr, sizeof(u64), 0); + #else ptr = mem2hex((char *)®s->cp0_epc, ptr, sizeof(long), 0); + #endif *ptr++ = ';'; /* *************** *** 766,772 **** --- 774,785 ---- *ptr++ = hexchars[REG_FP >> 4]; *ptr++ = hexchars[REG_FP & 0xf]; *ptr++ = ':'; + #if CONFIG_MIPS32 && (_MIPS_ISA == _MIPS_ISA_MIPS3) /* for gdb 6.1 ... */ + tmp64 = regs->reg30; + ptr = mem2hex((char *)&tmp64, ptr, sizeof(u64), 0); + #else ptr = mem2hex((char *)®s->reg30, ptr, sizeof(long), 0); + #endif *ptr++ = ';'; /* *************** *** 775,781 **** --- 788,799 ---- *ptr++ = hexchars[REG_SP >> 4]; *ptr++ = hexchars[REG_SP & 0xf]; *ptr++ = ':'; + #if CONFIG_MIPS32 && (_MIPS_ISA == _MIPS_ISA_MIPS3) /* for gdb 6.1 ... */ + tmp64 = regs->reg29; + ptr = mem2hex((char *)&tmp64, ptr, sizeof(u64), 0); + #else ptr = mem2hex((char *)®s->reg29, ptr, sizeof(long), 0); + #endif *ptr++ = ';'; *ptr++ = 0; *************** *** 814,825 **** --- 832,850 ---- */ case 'g': ptr = output_buffer; + #if CONFIG_MIPS32 && (_MIPS_ISA == _MIPS_ISA_MIPS3) /* for gdb 6.1 ... */ + for (i = 0; i < 32 + 6 + 32 + 2 + 2 + 16; i++) { + tmp64 = *(®s->reg0 + i); + ptr = mem2hex((char *)&tmp64, ptr, sizeof(u64), 0); + } + #else ptr = mem2hex((char *)®s->reg0, ptr, 32*sizeof(long), 0); /* r0...r31 */ ptr = mem2hex((char *)®s->cp0_status, ptr, 6*sizeof(long), 0); /* cp0 */ ptr = mem2hex((char *)®s->fpr0, ptr, 32*sizeof(long), 0); /* f0...31 */ ptr = mem2hex((char *)®s->cp1_fsr, ptr, 2*sizeof(long), 0); /* cp1 */ ptr = mem2hex((char *)®s->frame_ptr, ptr, 2*sizeof(long), 0); /* frp */ ptr = mem2hex((char *)®s->cp0_index, ptr, 16*sizeof(long), 0); /* cp0 */ + #endif break; /* *************** *** 828,833 **** --- 853,865 ---- case 'G': { ptr = &input_buffer[1]; + #if CONFIG_MIPS32 && (_MIPS_ISA == _MIPS_ISA_MIPS3) /* for gdb 6.1 ... */ + for (i = 0; i < 32 + 6 + 32 + 2 + 2 + 16; i++) { + hex2mem(ptr, (char *)&tmp64, sizeof(u64), 0, 0); + *(®s->reg0 + i) = (long)tmp64; + ptr += 2*sizeof(u64); + } + #else hex2mem(ptr, (char *)®s->reg0, 32*sizeof(long), 0, 0); ptr += 32*(2*sizeof(long)); hex2mem(ptr, (char *)®s->cp0_status, 6*sizeof(long), 0, 0); *************** *** 839,844 **** --- 871,877 ---- hex2mem(ptr, (char *)®s->frame_ptr, 2*sizeof(long), 0, 0); ptr += 2*(2*sizeof(long)); hex2mem(ptr, (char *)®s->cp0_index, 16*sizeof(long), 0, 0); + #endif strcpy(output_buffer,"OK"); } break; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/head.S linux-current/arch/mips/kernel/head.S *** linux-2.6.10/arch/mips/kernel/head.S Sat Dec 25 06:35:01 2004 --- linux-current/arch/mips/kernel/head.S Wed Jun 14 21:12:58 2006 *************** *** 136,141 **** --- 136,158 ---- NESTED(kernel_entry, 16, sp) # kernel entry point setup_c0_status_pri + #ifdef CONFIG_XIP_KERNEL + /* + * For xip from rom, copy initialized data from end of text + * in rom to _fdata though _edata in ram. + */ + la s0, _etext + la s1, _fdata + la s2, _edata + 1: + lw t0, (s0) + sw t0, (s1) + addi s1, 4 + addi s0, 4 + bne s1, s2, 1b + + #endif + #ifdef CONFIG_SGI_IP27 GET_NASID_ASM t1 move t2, t1 # text and data are here *************** *** 200,218 **** .comm fw_arg2, SZREG, SZREG .comm fw_arg3, SZREG, SZREG ! .macro page name, order=0 ! .globl \name ! \name: .size \name, (_PAGE_SIZE << \order) ! .org . + (_PAGE_SIZE << \order) ! .type \name, @object .endm - .data - .align PAGE_SHIFT - /* ! * ... but on 64-bit we've got three-level pagetables with a ! * slightly different layout ... */ page swapper_pg_dir, _PGD_ORDER #ifdef CONFIG_MIPS64 --- 217,229 ---- .comm fw_arg2, SZREG, SZREG .comm fw_arg3, SZREG, SZREG ! .macro page name, order ! .comm \name, (_PAGE_SIZE << \order), (_PAGE_SIZE << \order) .endm /* ! * On 64-bit we've got three-level pagetables with a slightly ! * different layout ... */ page swapper_pg_dir, _PGD_ORDER #ifdef CONFIG_MIPS64 diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/mips_ksyms.c linux-current/arch/mips/kernel/mips_ksyms.c *** linux-2.6.10/arch/mips/kernel/mips_ksyms.c Sat Dec 25 06:34:26 2004 --- linux-current/arch/mips/kernel/mips_ksyms.c Wed Jun 14 21:12:58 2006 *************** *** 60,62 **** --- 60,70 ---- EXPORT_SYMBOL(csum_partial); EXPORT_SYMBOL(invalid_pte_table); + + /* + * Functions to control caches. + */ + extern void (*flush_cache_all)(void); + extern void (*__flush_cache_all)(void); + EXPORT_SYMBOL(flush_cache_all); + EXPORT_SYMBOL(__flush_cache_all); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/proc.c linux-current/arch/mips/kernel/proc.c *** linux-2.6.10/arch/mips/kernel/proc.c Sat Dec 25 06:34:27 2004 --- linux-current/arch/mips/kernel/proc.c Wed Jun 14 21:12:58 2006 *************** *** 75,81 **** [CPU_VR4133] "NEC VR4133", [CPU_VR4181] "NEC VR4181", [CPU_VR4181A] "NEC VR4181A", ! [CPU_SR71000] "Sandcraft SR71000" }; --- 75,82 ---- [CPU_VR4133] "NEC VR4133", [CPU_VR4181] "NEC VR4181", [CPU_VR4181A] "NEC VR4181A", ! [CPU_SR71000] "Sandcraft SR71000", ! [CPU_VR5600] "VR5600" }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/process.c linux-current/arch/mips/kernel/process.c *** linux-2.6.10/arch/mips/kernel/process.c Sat Dec 25 06:34:32 2004 --- linux-current/arch/mips/kernel/process.c Wed Jun 14 21:12:58 2006 *************** *** 24,29 **** --- 24,30 ---- #include #include #include + #include #include #include *************** *** 153,158 **** --- 154,197 ---- int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { memcpy(r, ¤t->thread.fpu, sizeof(current->thread.fpu)); + + return 1; + } + + void dump_regs(elf_greg_t *gp, struct pt_regs *regs) + { + int i; + + for (i = 0; i < EF_R0; i++) + gp[i] = 0; + gp[EF_R0] = 0; + for (i = 1; i <= 31; i++) + gp[EF_R0 + i] = regs->regs[i]; + gp[EF_R26] = 0; + gp[EF_R27] = 0; + gp[EF_LO] = regs->lo; + gp[EF_HI] = regs->hi; + gp[EF_CP0_EPC] = regs->cp0_epc; + gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr; + gp[EF_CP0_STATUS] = regs->cp0_status; + gp[EF_CP0_CAUSE] = regs->cp0_cause; + #ifdef EF_UNUSED0 + gp[EF_UNUSED0] = 0; + #endif + } + + int dump_task_regs (struct task_struct *tsk, elf_gregset_t *regs) + { + struct thread_info *ti = tsk->thread_info; + long ksp = (unsigned long)ti + THREAD_SIZE - 32; + dump_regs(&(*regs)[0], (struct pt_regs *) ksp - 1); + return 1; + } + + int dump_task_fpu (struct task_struct *t, elf_fpregset_t *fpr) + { + memcpy(fpr, &t->thread.fpu, sizeof(current->thread.fpu)); + return 1; } *************** *** 167,172 **** --- 206,212 ---- long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { struct pt_regs regs; + long pid; memset(®s, 0, sizeof(regs)); *************** *** 182,188 **** #endif /* Ok, create the new process.. */ ! return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } struct mips_frame_info { --- 222,233 ---- #endif /* Ok, create the new process.. */ ! pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); ! #if (CONFIG_LTT) ! if(pid >= 0) ! ltt_ev_process(LTT_EV_PROCESS_KTHREAD, pid, (int) fn); ! #endif ! return pid; } struct mips_frame_info { *************** *** 190,200 **** int pc_offset; }; static struct mips_frame_info schedule_frame; - static struct mips_frame_info schedule_timeout_frame; - static struct mips_frame_info sleep_on_frame; - static struct mips_frame_info sleep_on_timeout_frame; - static struct mips_frame_info wait_for_completion_frame; - static int mips_frame_info_initialized; static int __init get_frame_info(struct mips_frame_info *info, void *func) { int i; --- 235,240 ---- *************** *** 246,259 **** static int __init frame_info_init(void) { ! mips_frame_info_initialized = ! !get_frame_info(&schedule_frame, schedule) && ! !get_frame_info(&schedule_timeout_frame, schedule_timeout) && ! !get_frame_info(&sleep_on_frame, sleep_on) && ! !get_frame_info(&sleep_on_timeout_frame, sleep_on_timeout) && ! !get_frame_info(&wait_for_completion_frame, wait_for_completion); ! ! return 0; } arch_initcall(frame_info_init); --- 286,292 ---- static int __init frame_info_init(void) { ! return get_frame_info(&schedule_frame, schedule); } arch_initcall(frame_info_init); *************** *** 263,269 **** */ unsigned long thread_saved_pc(struct task_struct *tsk) { - extern void ret_from_fork(void); struct thread_struct *t = &tsk->thread; /* New born processes are a special case */ --- 296,301 ---- *************** *** 275,333 **** return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; } - /* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ unsigned long get_wchan(struct task_struct *p) { ! unsigned long frame, pc; if (!p || p == current || p->state == TASK_RUNNING) return 0; - if (!mips_frame_info_initialized) - return 0; pc = thread_saved_pc(p); - if (!in_sched_functions(pc)) - goto out; - - if (pc >= (unsigned long) sleep_on_timeout) - goto schedule_timeout_caller; - if (pc >= (unsigned long) sleep_on) - goto schedule_caller; - if (pc >= (unsigned long) interruptible_sleep_on_timeout) - goto schedule_timeout_caller; - if (pc >= (unsigned long)interruptible_sleep_on) - goto schedule_caller; - if (pc >= (unsigned long)wait_for_completion) - goto schedule_caller; - goto schedule_timeout_caller; - - schedule_caller: - frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; - if (pc >= (unsigned long) sleep_on) - pc = ((unsigned long *)frame)[sleep_on_frame.pc_offset]; - else - pc = ((unsigned long *)frame)[wait_for_completion_frame.pc_offset]; - goto out; - - schedule_timeout_caller: - /* - * The schedule_timeout frame - */ - frame = ((unsigned long *)p->thread.reg30)[schedule_frame.frame_offset]; - - /* - * frame now points to sleep_on_timeout's frame - */ - pc = ((unsigned long *)frame)[schedule_timeout_frame.pc_offset]; - - if (in_sched_functions(pc)) { - /* schedule_timeout called by [interruptible_]sleep_on_timeout */ - frame = ((unsigned long *)frame)[schedule_timeout_frame.frame_offset]; - pc = ((unsigned long *)frame)[sleep_on_timeout_frame.pc_offset]; - } - - out: - #ifdef CONFIG_MIPS64 if (current->thread.mflags & MF_32BIT_REGS) /* Kludge for 32-bit ps */ pc &= 0xffffffffUL; --- 307,320 ---- return ((unsigned long *)t->reg29)[schedule_frame.pc_offset]; } unsigned long get_wchan(struct task_struct *p) { ! unsigned long pc; if (!p || p == current || p->state == TASK_RUNNING) return 0; pc = thread_saved_pc(p); #ifdef CONFIG_MIPS64 if (current->thread.mflags & MF_32BIT_REGS) /* Kludge for 32-bit ps */ pc &= 0xffffffffUL; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/ptrace.c linux-current/arch/mips/kernel/ptrace.c *** linux-2.6.10/arch/mips/kernel/ptrace.c Sat Dec 25 06:35:49 2004 --- linux-current/arch/mips/kernel/ptrace.c Wed Jun 14 21:12:58 2006 *************** *** 35,40 **** --- 35,81 ---- #include #include + #ifdef CONFIG_PTRACE_MMAPENABLE + #include + + static unsigned long get_kvirt_addr(struct task_struct * p, unsigned long ptr) + { + pgd_t *page_dir; + pmd_t *page_middle; + pte_t pte; + + if (!p || !p->mm || ptr >= TASK_SIZE) + return 0; + + /* Check for NULL pgd .. shouldn't happen! */ + if (!p->mm->pgd) { + return 0; + } + + page_dir = pgd_offset(p->mm,ptr); + if (pgd_none(*page_dir)) + return 0; + if (pgd_bad(*page_dir)) { + return 0; + } + + page_middle = pmd_offset(page_dir,ptr); + + + if (pmd_none(*page_middle)) + return 0; + if (pmd_bad(*page_middle)) { + return 0; + } + + pte = *pte_offset(page_middle,ptr); + if (!pte_present(pte)) + return 0; + + return (unsigned int)(pte_val(pte) & PAGE_MASK); + } + #endif + /* * Called by kernel/ptrace.c when detaching.. * *************** *** 99,106 **** copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); ret = -EIO; ! if (copied != sizeof(tmp)) break; ret = put_user(tmp,(unsigned long *) data); break; } --- 140,160 ---- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); ret = -EIO; ! if (copied != sizeof(tmp)) { ! #ifdef CONFIG_PTRACE_MMAPENABLE ! unsigned long tmpptr; ! tmpptr = get_kvirt_addr(child, addr); ! if ((0x00000000UL < tmpptr) && (0x20000000UL > tmpptr)) { ! flush_cache_all(); ! tmpptr = (tmpptr + KSEG1 + (addr & ~PAGE_MASK)); ! tmp = *(unsigned long *) (tmpptr); ! } else { ! break; ! } ! #else break; + #endif + } ret = put_user(tmp,(unsigned long *) data); break; } *************** *** 167,176 **** --- 221,232 ---- if (!cpu_has_fpu) break; + preempt_disable(); flags = read_c0_status(); __enable_fpu(); __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); write_c0_status(flags); + preempt_enable(); break; } default: diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/scall32-o32.S linux-current/arch/mips/kernel/scall32-o32.S *** linux-2.6.10/arch/mips/kernel/scall32-o32.S Sat Dec 25 06:33:59 2004 --- linux-current/arch/mips/kernel/scall32-o32.S Wed Jun 14 21:12:58 2006 *************** *** 5,10 **** --- 5,11 ---- * * Copyright (C) 1995, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle * Copyright (C) 2001 MIPS Technologies, Inc. + * Copyright (C) 2004 Thiemo Seufer */ #include #include *************** *** 32,57 **** lw t1, PT_EPC(sp) # skip syscall on return sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number addiu t1, 4 # skip to next instruction sw t1, PT_EPC(sp) beqz t0, illegal_syscall ! /* XXX Put both in one cacheline, should save a bit. */ ! sll t0, v0, 2 ! lw t2, sys_call_table(t0) # syscall routine ! lbu t3, sys_narg_table(v0) # number of arguments ! beqz t2, illegal_syscall; - subu t0, t3, 5 # 5 or more arguments? sw a3, PT_R26(sp) # save a3 for syscall restarting ! bgez t0, stackargs stack_done: ! sw a3, PT_R26(sp) # save for syscall restart ! LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT ! and t0, t1, t0 bnez t0, syscall_trace_entry # -> yes jalr t2 # Do The Real Thing (TM) --- 33,73 ---- lw t1, PT_EPC(sp) # skip syscall on return + #if defined(CONFIG_BINFMT_IRIX) sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number + #else + subu v0, v0, __NR_O32_Linux # check syscall number + sltiu t0, v0, __NR_O32_Linux_syscalls + 1 + #endif addiu t1, 4 # skip to next instruction sw t1, PT_EPC(sp) beqz t0, illegal_syscall ! sll t0, v0, 3 ! la t1, sys_call_table ! addu t1, t0 ! lw t2, (t1) # syscall routine ! lw t3, 4(t1) # >= 0 if we need stack arguments ! beqz t2, illegal_syscall sw a3, PT_R26(sp) # save a3 for syscall restarting ! bgez t3, stackargs stack_done: ! #if (CONFIG_LTT) ! sw t2, PT_R1(sp) ! move a0, sp ! jal trace_real_syscall_entry ! lw t2, PT_R1(sp) ! ! lw a0, PT_R4(sp) # Restore argument registers ! lw a1, PT_R5(sp) ! lw a2, PT_R6(sp) ! lw a3, PT_R7(sp) ! #endif /* (CONFIG_LTT) */ ! lw t0, TI_FLAGS($28) # syscall tracing enabled? li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT ! and t0, t1 bnez t0, syscall_trace_entry # -> yes jalr t2 # Do The Real Thing (TM) *************** *** 66,78 **** # restarting 1: sw v0, PT_R2(sp) # result o32_syscall_exit: local_irq_disable # make sure need_resched and # signals dont change between # sampling and return ! LONG_L a2, TI_FLAGS($28) # current->work li t0, _TIF_ALLWORK_MASK ! and t0, a2, t0 bnez t0, o32_syscall_exit_work j restore_partial --- 82,97 ---- # restarting 1: sw v0, PT_R2(sp) # result + #if (CONFIG_LTT) + jal trace_real_syscall_exit + #endif /* (CONFIG_LTT) */ o32_syscall_exit: local_irq_disable # make sure need_resched and # signals dont change between # sampling and return ! lw a2, TI_FLAGS($28) # current->work li t0, _TIF_ALLWORK_MASK ! and t0, a2 bnez t0, o32_syscall_exit_work j restore_partial *************** *** 84,90 **** syscall_trace_entry: SAVE_STATIC ! move s0, t2 move a0, sp li a1, 0 jal do_syscall_trace --- 103,109 ---- syscall_trace_entry: SAVE_STATIC ! move s1, t2 move a0, sp li a1, 0 jal do_syscall_trace *************** *** 93,99 **** lw a1, PT_R5(sp) lw a2, PT_R6(sp) lw a3, PT_R7(sp) ! jalr s0 li t0, -EMAXERRNO - 1 # error? sltu t0, t0, v0 --- 112,122 ---- lw a1, PT_R5(sp) lw a2, PT_R6(sp) lw a3, PT_R7(sp) ! .set push ! .set noreorder ! jalr s1 ! lw s1, PT_R17(sp) ! .set pop li t0, -EMAXERRNO - 1 # error? sltu t0, t0, v0 *************** *** 105,110 **** --- 128,136 ---- # restarting 1: sw v0, PT_R2(sp) # result + #if (CONFIG_LTT) + jal trace_real_syscall_exit + #endif /* (CONFIG_LTT) */ j syscall_exit /* ------------------------------------------------------------------------ */ *************** *** 116,164 **** */ stackargs: lw t0, PT_R29(sp) # get old user stack pointer - subu t3, 4 - sll t1, t3, 2 # stack valid? - addu t1, t0 # end address - or t0, t1 - bltz t0, bad_stack # -> sp is bad - - lw t0, PT_R29(sp) # get old user stack pointer - PTR_LA t1, 4f # copy 1 to 3 arguments - sll t3, t3, 4 - subu t1, t3 - jr t1 - - /* Ok, copy the args from the luser stack to the kernel stack */ /* ! * I know Ralf doesn't like nops but this avoids code ! * duplication for R3000 targets (and this is the ! * only place where ".set reorder" doesn't help). ! * Harald. */ .set push .set noreorder .set nomacro ! 1: lw t1, 24(t0) # argument #7 from usp ! nop ! sw t1, 24(sp) ! nop ! 2: lw t1, 20(t0) # argument #5 from usp ! nop ! sw t1, 20(sp) ! nop ! 3: lw t1, 16(t0) # argument #5 from usp ! nop ! sw t1, 16(sp) ! nop ! 4: .set pop ! j stack_done # go back .section __ex_table,"a" PTR 1b,bad_stack PTR 2b,bad_stack PTR 3b,bad_stack .previous /* --- 142,189 ---- */ stackargs: lw t0, PT_R29(sp) # get old user stack pointer /* ! * We intentionally keep the kernel stack a little below the top of ! * userspace so we don't have to do a slower byte accurate check here. */ + lw t5, TI_ADDR_LIMIT($28) + addu t4, t0, 32 + and t5, t4 + bltz t5, bad_stack # -> sp is bad + + /* Ok, copy the args from the luser stack to the kernel stack. + * t3 is the precomputed number of instruction bytes needed to + * load or store arguments 6-8. + */ + + la t1, 5f # load up to 3 arguments + subu t1, t3 + 1: lw t5, 16(t0) # argument #5 from usp .set push .set noreorder .set nomacro ! jr t1 ! addiu t1, 6f - 5f ! 2: lw t8, 28(t0) # argument #8 from usp ! 3: lw t7, 24(t0) # argument #7 from usp ! 4: lw t6, 20(t0) # argument #6 from usp ! 5: jr t1 ! sw t5, 16(sp) # argument #5 to ksp ! ! sw t8, 28(sp) # argument #8 to ksp ! sw t7, 24(sp) # argument #7 to ksp ! sw t6, 20(sp) # argument #6 to ksp ! 6: j stack_done # go back ! nop ! .set pop .section __ex_table,"a" PTR 1b,bad_stack PTR 2b,bad_stack PTR 3b,bad_stack + PTR 4b,bad_stack .previous /* *************** *** 177,183 **** * The system call does not exist in this kernel */ illegal_syscall: ! li v0, ENOSYS # error sw v0, PT_R2(sp) li t0, 1 # set error flag sw t0, PT_R7(sp) --- 202,208 ---- * The system call does not exist in this kernel */ illegal_syscall: ! li v0, -ENOSYS # error sw v0, PT_R2(sp) li t0, 1 # set error flag sw t0, PT_R7(sp) *************** *** 238,249 **** sw v0, PT_R2(sp) # result /* Success, so skip usual error handling garbage. */ ! LONG_L a2, TI_FLAGS($28) # syscall tracing enabled? li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT and t0, a2, t0 bnez t0, 1f ! b o32_syscall_exit 1: SAVE_STATIC move a0, sp --- 263,274 ---- sw v0, PT_R2(sp) # result /* Success, so skip usual error handling garbage. */ ! lw a2, TI_FLAGS($28) # syscall tracing enabled? li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT and t0, a2, t0 bnez t0, 1f ! j o32_syscall_exit 1: SAVE_STATIC move a0, sp *************** *** 269,337 **** END(sys_sysmips) LEAF(sys_syscall) ! lw t0, PT_R29(sp) # user sp ! ! sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1 ! beqz v0, enosys ! ! sll v0, a0, 2 ! la v1, sys_syscall ! lw t2, sys_call_table(v0) # function pointer ! lbu t4, sys_narg_table(a0) # number of arguments ! ! li v0, -EINVAL ! beq t2, v1, out # do not recurse ! beqz t2, enosys # null function pointer? ! andi v0, t0, 0x3 # unaligned stack pointer? ! bnez v0, sigsegv ! addu v0, t0, 16 # v0 = usp + 16 ! addu t1, v0, 12 # 3 32-bit arguments ! lw v1, TI_ADDR_LIMIT($28) ! or v0, v0, t1 ! and v1, v1, v0 ! bltz v1, efault move a0, a1 # shift argument registers move a1, a2 move a2, a3 ! ! 1: lw a3, 16(t0) ! 2: lw t3, 20(t0) ! 3: lw t4, 24(t0) ! ! .section __ex_table, "a" ! .word 1b, efault ! .word 2b, efault ! .word 3b, efault ! .previous ! ! sw t3, 16(sp) # put into new stackframe ! sw t4, 20(sp) ! ! bnez t4, 1f # zero arguments? ! addu a0, sp, 32 # then pass sp in a0 ! 1: ! ! sw t3, 16(sp) ! sw v1, 20(sp) jr t2 /* Unreached */ ! enosys: li v0, -ENOSYS ! b out ! ! sigsegv: ! li a0, _SIGSEGV ! move a1, $28 ! jal force_sig ! /* Fall through */ ! ! efault: li v0, -EFAULT ! ! out: jr ra END(sys_syscall) .macro fifty ptr, nargs, from=1, to=50 --- 294,342 ---- END(sys_sysmips) LEAF(sys_syscall) ! #if defined(CONFIG_BINFMT_IRIX) ! sltiu v0, a0, MAX_SYSCALL_NO + 1 # check syscall number ! #else ! subu t0, a0, __NR_O32_Linux # check syscall number ! sltiu v0, t0, __NR_O32_Linux_syscalls + 1 ! #endif ! sll t1, t0, 3 ! beqz v0, einval ! lw t2, sys_call_table(t1) # syscall routine ! #if defined(CONFIG_BINFMT_IRIX) ! li v1, 4000 # nr of sys_syscall ! #else ! li v1, 4000 - __NR_O32_Linux # index of sys_syscall ! #endif ! beq t0, v1, einval # do not recurse ! /* Some syscalls like execve get their arguments from struct pt_regs ! and claim zero arguments in the syscall table. Thus we have to ! assume the worst case and shuffle around all potential arguments. ! If you want performance, don't use indirect syscalls. */ move a0, a1 # shift argument registers move a1, a2 move a2, a3 ! lw a3, 16(sp) ! lw t4, 20(sp) ! lw t5, 24(sp) ! lw t6, 28(sp) ! sw t4, 16(sp) ! sw t5, 20(sp) ! sw t6, 24(sp) ! sw a0, PT_R4(sp) # .. and push back a0 - a3, some ! sw a1, PT_R5(sp) # syscalls expect them there ! sw a2, PT_R6(sp) ! sw a3, PT_R7(sp) ! sw a3, PT_R26(sp) # update a3 for syscall restarting jr t2 /* Unreached */ ! einval: li v0, -EINVAL ! jr ra END(sys_syscall) .macro fifty ptr, nargs, from=1, to=50 *************** *** 349,360 **** .endm .macro syscalltable mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */ ! #include "irix5sys.h" /* 1000 - 1999 32-bit IRIX */ mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */ mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */ ! sys sys_syscall 0 /* 4000 */ sys sys_exit 1 sys sys_fork 0 sys sys_read 3 --- 354,367 ---- .endm .macro syscalltable + #if defined(CONFIG_BINFMT_IRIX) mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */ ! mille sys_ni_syscall 0 /* 1000 - 1999 32-bit IRIX */ mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */ mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */ + #endif ! sys sys_syscall 8 /* 4000 */ sys sys_exit 1 sys sys_fork 0 sys sys_read 3 *************** *** 405,411 **** sys sys_ni_syscall 0 /* was signal(2) */ sys sys_geteuid 0 sys sys_getegid 0 /* 4050 */ ! sys sys_acct 0 sys sys_umount 2 sys sys_ni_syscall 0 sys sys_ioctl 3 --- 412,418 ---- sys sys_ni_syscall 0 /* was signal(2) */ sys sys_geteuid 0 sys sys_getegid 0 /* 4050 */ ! sys sys_acct 1 sys sys_umount 2 sys sys_ni_syscall 0 sys sys_ioctl 3 *************** *** 485,491 **** sys sys_init_module 5 sys sys_delete_module 1 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */ ! sys sys_quotactl 0 sys sys_getpgid 1 sys sys_fchdir 1 sys sys_bdflush 2 --- 492,498 ---- sys sys_init_module 5 sys sys_delete_module 1 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */ ! sys sys_quotactl 4 sys sys_getpgid 1 sys sys_fchdir 1 sys sys_bdflush 2 *************** *** 506,512 **** sys sys_sysmips 4 sys sys_ni_syscall 0 /* 4150 */ sys sys_getsid 1 ! sys sys_fdatasync 0 sys sys_sysctl 1 sys sys_mlock 2 sys sys_munlock 2 /* 4155 */ --- 513,519 ---- sys sys_sysmips 4 sys sys_ni_syscall 0 /* 4150 */ sys sys_getsid 1 ! sys sys_fdatasync 1 sys sys_sysctl 1 sys sys_mlock 2 sys sys_munlock 2 /* 4155 */ *************** *** 640,658 **** .endm .macro sys function, nargs PTR \function .endm .align 3 ! sys_call_table: syscalltable .size sys_call_table, . - sys_call_table - - .macro sys function, nargs - .byte \nargs - .endm - - sys_narg_table: - syscalltable - .size sys_narg_table, . - sys_narg_table --- 647,662 ---- .endm + /* We pre-compute the number of _instruction_ bytes needed to + load or store the arguments 6-8. Negative values are ignored. */ + .macro sys function, nargs PTR \function + LONG (\nargs << 2) - (5 << 2) .endm .align 3 ! .type sys_call_table,@object ! EXPORT(sys_call_table) syscalltable .size sys_call_table, . - sys_call_table diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/setup.c linux-current/arch/mips/kernel/setup.c *** linux-2.6.10/arch/mips/kernel/setup.c Sat Dec 25 06:34:02 2004 --- linux-current/arch/mips/kernel/setup.c Wed Jun 14 21:12:58 2006 *************** *** 76,82 **** --- 76,86 ---- * mips_io_port_base is the begin of the address space to which x86 style * I/O ports are mapped. */ + #ifdef CONFIG_XIP_KERNEL + unsigned long mips_io_port_base = -1; + #else const unsigned long mips_io_port_base = -1; + #endif EXPORT_SYMBOL(mips_io_port_base); /* *************** *** 296,301 **** --- 300,329 ---- } #endif /* CONFIG_BLK_DEV_INITRD */ + #if defined(CONFIG_ROOT_CRAMFS_LINEAR) + { + extern char * root_mount_data; + static __initdata char rootflags[32]; + unsigned long tmp; + unsigned long* root_header; + unsigned long root_start =0, root_end = 0; + + tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8; + if (tmp < (unsigned long)&_end) + tmp += PAGE_SIZE; + root_header = (unsigned long *)tmp; + if (root_header[0] == 0x494E5244){ + root_start = (unsigned long)&root_header[2]; + root_end = root_start + root_header[1]; + if(!root_mount_data){ + sprintf(rootflags,"physaddr=0x%lx",root_start & 0x1fffffff); + root_mount_data=rootflags; + } + reserved_end = max(reserved_end, root_end); + } + } + #endif + /* * Partially used pages are not usable - thus * we are rounding upwards. *************** *** 443,449 **** --- 471,481 ---- code_resource.start = virt_to_phys(&_text); code_resource.end = virt_to_phys(&_etext) - 1; + #ifdef CONFIG_XIP_KERNEL + data_resource.start = virt_to_phys(&_fdata); + #else data_resource.start = virt_to_phys(&_etext); + #endif data_resource.end = virt_to_phys(&_edata) - 1; /* *************** *** 482,489 **** --- 514,531 ---- * so we try it repeatedly and let the resource manager * test it. */ + #ifndef CONFIG_XIP_KERNEL request_resource(res, &code_resource); request_resource(res, &data_resource); + #else + if (code_resource.start >= res->start && + code_resource.end <= res->end) + request_resource(res, &code_resource); + if (data_resource.start >= res->start && + data_resource.end <= res->end) + request_resource(res, &data_resource); + + #endif } } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/signal-common.h linux-current/arch/mips/kernel/signal-common.h *** linux-2.6.10/arch/mips/kernel/signal-common.h Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/kernel/signal-common.h Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,147 ---- + /* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 1994 - 2000 Ralf Baechle + * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + */ + + static inline int + setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) + { + int err = 0; + struct sigcontext tmpsc; + + err |= __put_user(regs->cp0_epc, &sc->sc_pc); + err |= __put_user(regs->cp0_status, &sc->sc_status); + + #define save_gp_reg(i) do { \ + err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ + } while(0) + __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); + save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); + save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10); + save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14); + save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18); + save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22); + save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26); + save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30); + save_gp_reg(31); + #undef save_gp_reg + + err |= __put_user(regs->hi, &sc->sc_mdhi); + err |= __put_user(regs->lo, &sc->sc_mdlo); + err |= __put_user(regs->cp0_cause, &sc->sc_cause); + err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); + + err |= __put_user(current->used_math, &sc->sc_used_math); + + if (!current->used_math) + goto out; + + /* + * Save FPU state to signal context. Signal handler will "inherit" + * current FPU state. + */ + preempt_disable(); + + if (!is_fpu_owner()) { + own_fpu(); + restore_fp(current); + } + /* make sure save_fp_context not sleep */ + err |= save_fp_context(&tmpsc); + + preempt_enable(); + + err |= __copy_to_user(&sc->sc_fpregs, &tmpsc.sc_fpregs, + sizeof(tmpsc.sc_fpregs)); + err |= __put_user(tmpsc.sc_fpc_csr, &sc->sc_fpc_csr); + err |= __put_user(tmpsc.sc_fpc_eir, &sc->sc_fpc_eir); + + out: + return err; + } + + static inline int + restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) + { + int err = 0; + + /* Always make any pending restarted system calls return -EINTR */ + current_thread_info()->restart_block.fn = do_no_restart_syscall; + + err |= __get_user(regs->cp0_epc, &sc->sc_pc); + err |= __get_user(regs->hi, &sc->sc_mdhi); + err |= __get_user(regs->lo, &sc->sc_mdlo); + + #define restore_gp_reg(i) do { \ + err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ + } while(0) + restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); + restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); + restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9); + restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12); + restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15); + restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18); + restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21); + restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24); + restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27); + restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30); + restore_gp_reg(31); + #undef restore_gp_reg + + err |= __get_user(current->used_math, &sc->sc_used_math); + + if (current->used_math) { + /* make sure restore_fp_context not sleep */ + struct sigcontext tmpsc; + err |= __copy_from_user(&tmpsc.sc_fpregs, &sc->sc_fpregs, sizeof(tmpsc.sc_fpregs)); + err |= __get_user(tmpsc.sc_fpc_csr, &sc->sc_fpc_csr); + err |= __get_user(tmpsc.sc_fpc_eir, &sc->sc_fpc_eir); + preempt_disable(); + /* restore fpu context if we have used it before */ + own_fpu(); + err |= restore_fp_context(&tmpsc); + } else { + /* signal handler may have used FPU. Give it up. */ + preempt_disable(); + lose_fpu(); + } + + preempt_enable(); + + return err; + } + + /* + * Determine which stack to use.. + */ + extern inline void * + get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) + { + unsigned long sp, almask; + + /* Default to using normal stack */ + sp = regs->regs[29]; + + /* + * FPU emulator may have it's own trampoline active just + * above the user stack, 16-bytes before the next lowest + * 16 byte boundary. Try to avoid trashing it. + */ + sp -= 32; + + /* This is the X/Open sanctioned signal stack switching. */ + if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) + sp = current->sas_ss_sp + current->sas_ss_size; + + if (PLAT_TRAMPOLINE_STUFF_LINE) + almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1); + else + almask = ALMASK; + + return (void *)((sp - frame_size) & almask); + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/signal.c linux-current/arch/mips/kernel/signal.c *** linux-2.6.10/arch/mips/kernel/signal.c Sat Dec 25 06:35:59 2004 --- linux-current/arch/mips/kernel/signal.c Wed Jun 14 21:12:58 2006 *************** *** 21,26 **** --- 21,27 ---- #include #include #include + #include #include #include *************** *** 29,40 **** #include #include #include #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) ! extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); /* * Atomically swap in the new signal mask, and wait for a signal. --- 30,44 ---- #include #include #include + #include + + #include "signal-common.h" #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) ! static int do_signal(sigset_t *oldset, struct pt_regs *regs); /* * Atomically swap in the new signal mask, and wait for a signal. *************** *** 152,202 **** return do_sigaltstack(uss, uoss, usp); } - asmlinkage int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) - { - int err = 0; - - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - - err |= __get_user(regs->cp0_epc, &sc->sc_pc); - err |= __get_user(regs->hi, &sc->sc_mdhi); - err |= __get_user(regs->lo, &sc->sc_mdlo); - - #define restore_gp_reg(i) do { \ - err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ - } while(0) - restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3); - restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6); - restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9); - restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12); - restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15); - restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18); - restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21); - restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24); - restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27); - restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30); - restore_gp_reg(31); - #undef restore_gp_reg - - err |= __get_user(current->used_math, &sc->sc_used_math); - - preempt_disable(); - - if (current->used_math) { - /* restore fpu context if we have used it before */ - own_fpu(); - err |= restore_fp_context(sc); - } else { - /* signal handler may have used FPU. Give it up. */ - lose_fpu(); - } - - preempt_enable(); - - return err; - } - #if PLAT_TRAMPOLINE_STUFF_LINE #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE))) #else --- 156,161 ---- *************** *** 220,226 **** }; #ifdef CONFIG_TRAD_SIGNALS ! asmlinkage void sys_sigreturn(struct pt_regs regs) { struct sigframe *frame; sigset_t blocked; --- 179,187 ---- }; #ifdef CONFIG_TRAD_SIGNALS ! save_static_function(sys_sigreturn); ! __attribute_used__ noinline static void ! _sys_sigreturn(nabi_no_regargs struct pt_regs regs) { struct sigframe *frame; sigset_t blocked; *************** *** 245,250 **** --- 206,214 ---- */ if (current_thread_info()->flags & TIF_SYSCALL_TRACE) do_syscall_trace(®s, 1); + #if (CONFIG_LTT) + ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL); + #endif __asm__ __volatile__( "move\t$29, %0\n\t" "j\tsyscall_exit" *************** *** 257,263 **** } #endif ! asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) { struct rt_sigframe *frame; sigset_t set; --- 221,229 ---- } #endif ! save_static_function(sys_rt_sigreturn); ! __attribute_used__ noinline static void ! _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) { struct rt_sigframe *frame; sigset_t set; *************** *** 287,292 **** --- 253,261 ---- /* * Don't let your children do this ... */ + #if (CONFIG_LTT) + ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL); + #endif __asm__ __volatile__( "move\t$29, %0\n\t" "j\tsyscall_exit" *************** *** 298,385 **** force_sig(SIGSEGV, current); } ! inline int setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) ! { ! int err = 0; ! ! err |= __put_user(regs->cp0_epc, &sc->sc_pc); ! err |= __put_user(regs->cp0_status, &sc->sc_status); ! ! #define save_gp_reg(i) do { \ ! err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ ! } while(0) ! __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); ! save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); ! save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10); ! save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14); ! save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18); ! save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22); ! save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26); ! save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30); ! save_gp_reg(31); ! #undef save_gp_reg ! ! err |= __put_user(regs->hi, &sc->sc_mdhi); ! err |= __put_user(regs->lo, &sc->sc_mdlo); ! err |= __put_user(regs->cp0_cause, &sc->sc_cause); ! err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); ! ! err |= __put_user(current->used_math, &sc->sc_used_math); ! ! if (!current->used_math) ! goto out; ! ! /* ! * Save FPU state to signal context. Signal handler will "inherit" ! * current FPU state. ! */ ! preempt_disable(); ! ! if (!is_fpu_owner()) { ! own_fpu(); ! restore_fp(current); ! } ! err |= save_fp_context(sc); ! ! preempt_enable(); ! ! out: ! return err; ! } ! ! /* ! * Determine which stack to use.. ! */ ! static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, ! size_t frame_size) ! { ! unsigned long sp, almask; ! ! /* Default to using normal stack */ ! sp = regs->regs[29]; ! ! /* ! * FPU emulator may have it's own trampoline active just ! * above the user stack, 16-bytes before the next lowest ! * 16 byte boundary. Try to avoid trashing it. ! */ ! sp -= 32; ! ! /* This is the X/Open sanctioned signal stack switching. */ ! if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) ! sp = current->sas_ss_sp + current->sas_ss_size; ! ! if (PLAT_TRAMPOLINE_STUFF_LINE) ! almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1); ! else ! almask = ALMASK; ! ! return (void *)((sp - frame_size) & ~(PLAT_TRAMPOLINE_STUFF_LINE - 1)); ! } ! #ifdef CONFIG_TRAD_SIGNALS static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set) { struct sigframe *frame; int err = 0; --- 267,281 ---- force_sig(SIGSEGV, current); } ! #define CHECK_SETUP_FRAME_FAILURE #ifdef CONFIG_TRAD_SIGNALS + #ifdef CHECK_SETUP_FRAME_FAILURE + static int inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set) + #else static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set) + #endif { struct sigframe *frame; int err = 0; *************** *** 395,402 **** * syscall */ if (PLAT_TRAMPOLINE_STUFF_LINE) ! __builtin_memset(frame->sf_code, '0', ! PLAT_TRAMPOLINE_STUFF_LINE); err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0); err |= __put_user(0x0000000c , frame->sf_code + 1); flush_cache_sigtramp((unsigned long) frame->sf_code); --- 291,297 ---- * syscall */ if (PLAT_TRAMPOLINE_STUFF_LINE) ! __clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE); err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0); err |= __put_user(0x0000000c , frame->sf_code + 1); flush_cache_sigtramp((unsigned long) frame->sf_code); *************** *** 428,442 **** --- 323,349 ---- current->comm, current->pid, frame, regs->cp0_epc, frame->regs[31]); #endif + #ifdef CHECK_SETUP_FRAME_FAILURE + return 0; + #else return; + #endif give_sigsegv: force_sigsegv(signr, current); + #ifdef CHECK_SETUP_FRAME_FAILURE + return SIGSEGV; + #endif } #endif + #ifdef CHECK_SETUP_FRAME_FAILURE + static int inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, + int signr, sigset_t *set, siginfo_t *info) + #else static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) + #endif { struct rt_sigframe *frame; int err = 0; *************** *** 452,459 **** * syscall */ if (PLAT_TRAMPOLINE_STUFF_LINE) ! __builtin_memset(frame->rs_code, '0', ! PLAT_TRAMPOLINE_STUFF_LINE); err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); err |= __put_user(0x0000000c , frame->rs_code + 1); flush_cache_sigtramp((unsigned long) frame->rs_code); --- 359,365 ---- * syscall */ if (PLAT_TRAMPOLINE_STUFF_LINE) ! __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE); err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0); err |= __put_user(0x0000000c , frame->rs_code + 1); flush_cache_sigtramp((unsigned long) frame->rs_code); *************** *** 498,515 **** --- 404,437 ---- current->comm, current->pid, frame, regs->cp0_epc, regs->regs[31]); #endif + #ifdef CHECK_SETUP_FRAME_FAILURE + return 0; + #else return; + #endif give_sigsegv: force_sigsegv(signr, current); + #ifdef CHECK_SETUP_FRAME_FAILURE + return SIGSEGV; + #endif } extern void setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info); + #ifdef CHECK_SETUP_FRAME_FAILURE + static inline int handle_signal(unsigned long sig, siginfo_t *info, + struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) + #else static inline void handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) + #endif { + #ifdef CHECK_SETUP_FRAME_FAILURE + int newsig = 0; + #endif + switch(regs->regs[0]) { case ERESTART_RESTARTBLOCK: case ERESTARTNOHAND: *************** *** 538,549 **** --- 460,484 ---- setup_rt_frame_n32 (ka, regs, sig, oldset, info); else #endif + #ifdef CHECK_SETUP_FRAME_FAILURE + newsig = + #endif setup_rt_frame(ka, regs, sig, oldset, info); } #ifdef CONFIG_TRAD_SIGNALS else + #ifdef CHECK_SETUP_FRAME_FAILURE + newsig = + #endif setup_frame(ka, regs, sig, oldset); #endif + #ifdef CHECK_SETUP_FRAME_FAILURE + if (newsig) { + printk("Can not setup signal frame for %s (pc 0x%lx signal %ld).\n", + current->comm, regs->cp0_epc, sig); + return newsig; + } + #endif if (!(ka->sa.sa_flags & SA_NODEFER)) { spin_lock_irq(¤t->sighand->siglock); *************** *** 552,563 **** recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); } } extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); ! asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; --- 487,501 ---- recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); } + #ifdef CHECK_SETUP_FRAME_FAILURE + return 0; + #endif } extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); ! static int do_signal(sigset_t *oldset, struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; *************** *** 585,593 **** --- 523,539 ---- if (!oldset) oldset = ¤t->blocked; + #ifdef CHECK_SETUP_FRAME_FAILURE + checkagain: + #endif signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { + #ifdef CHECK_SETUP_FRAME_FAILURE + if (handle_signal(signr, &info, &ka, oldset, regs)) + goto checkagain; /* another signal queued. */ + #else handle_signal(signr, &info, &ka, oldset, regs); + #endif return 1; } *************** *** 613,620 **** return 0; } - extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); - /* * notification of userspace execution resumption * - triggered by current->work.notify_resume --- 559,564 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/syscall.c linux-current/arch/mips/kernel/syscall.c *** linux-2.6.10/arch/mips/kernel/syscall.c Sat Dec 25 06:35:24 2004 --- linux-current/arch/mips/kernel/syscall.c Wed Jun 14 21:12:58 2006 *************** *** 25,30 **** --- 25,31 ---- #include #include #include + #include #include #include *************** *** 116,122 **** } /* 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) { --- 117,123 ---- } /* common code for old and new mmaps */ ! static inline unsigned long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { *************** *** 140,147 **** return error; } ! asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot, ! int flags, int fd, off_t offset) { unsigned long result; --- 141,149 ---- return error; } ! asmlinkage unsigned long ! old_mmap(unsigned long addr, unsigned long len, int prot, ! int flags, int fd, off_t offset) { unsigned long result; *************** *** 155,161 **** return result; } ! asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { --- 157,163 ---- return result; } ! asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) { *************** *** 304,309 **** --- 306,313 ---- version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; + ltt_ev_ipc(LTT_EV_IPC_CALL, call, first); + switch (call) { case SEMOP: return sys_semtimedop (first, (struct sembuf *)ptr, second, diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/time.c linux-current/arch/mips/kernel/time.c *** linux-2.6.10/arch/mips/kernel/time.c Sat Dec 25 06:34:32 2004 --- linux-current/arch/mips/kernel/time.c Wed Jun 14 21:12:58 2006 *************** *** 161,167 **** unsigned long seq; unsigned long lost; unsigned long usec, sec; ! unsigned long max_ntp_tick = tick_usec - tickadj; do { seq = read_seqbegin(&xtime_lock); --- 161,167 ---- unsigned long seq; unsigned long lost; unsigned long usec, sec; ! unsigned long max_ntp_tick; do { seq = read_seqbegin(&xtime_lock); *************** *** 176,187 **** * Better to lose some accuracy than have time go backwards.. */ if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); if (lost) usec += lost * max_ntp_tick; } else if (unlikely(lost)) ! usec += lost * tick_usec; sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); --- 176,188 ---- * Better to lose some accuracy than have time go backwards.. */ if (unlikely(time_adjust < 0)) { + max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj; usec = min(usec, max_ntp_tick); if (lost) usec += lost * max_ntp_tick; } else if (unlikely(lost)) ! usec += lost * (USEC_PER_SEC / HZ); sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); *************** *** 556,562 **** --- 557,567 ---- static struct irqaction timer_irqaction = { .handler = timer_interrupt, + #ifdef CONFIG_SHARED_TIMER_INT + .flags = SA_INTERRUPT|SA_SHIRQ, + #else .flags = SA_INTERRUPT, + #endif .name = "timer", }; *************** *** 681,686 **** --- 686,704 ---- /* No timer interrupt ack (e.g. i8254). */ mips_timer_ack = null_timer_ack; + #ifdef CONFIG_ADJUST_MONOTONIC_TIME + { + int count = mips_hpt_read(); + int wsec,wnsec; + int sec = count/mips_hpt_frequency; + int nsec = (count-sec*mips_hpt_frequency)*(NSEC_PER_SEC/mips_hpt_frequency); + wsec = wall_to_monotonic.tv_sec + sec; + wnsec = wall_to_monotonic.tv_nsec + nsec; + set_normalized_timespec(&wall_to_monotonic, + wsec, wnsec); + printk("Adjust monotonic time %d.%09d sec @ count=0x%08x, freq=%d\n",sec,nsec,count,mips_hpt_frequency); + } + #endif /* This sets up the high precision timer for the first interrupt. */ mips_hpt_init(mips_hpt_read()); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/traps.c linux-current/arch/mips/kernel/traps.c *** linux-2.6.10/arch/mips/kernel/traps.c Sat Dec 25 06:34:32 2004 --- linux-current/arch/mips/kernel/traps.c Wed Jun 14 21:12:58 2006 *************** *** 20,25 **** --- 20,27 ---- #include #include #include + #include + #include #include #include *************** *** 38,49 **** #include #include ! extern asmlinkage void handle_mod(void); extern asmlinkage void handle_tlbl(void); extern asmlinkage void handle_tlbs(void); - extern asmlinkage void __xtlb_mod(void); - extern asmlinkage void __xtlb_tlbl(void); - extern asmlinkage void __xtlb_tlbs(void); extern asmlinkage void handle_adel(void); extern asmlinkage void handle_ades(void); extern asmlinkage void handle_ibe(void); --- 40,48 ---- #include #include ! extern asmlinkage void handle_tlbm(void); extern asmlinkage void handle_tlbl(void); extern asmlinkage void handle_tlbs(void); extern asmlinkage void handle_adel(void); extern asmlinkage void handle_ades(void); extern asmlinkage void handle_ibe(void); *************** *** 82,88 **** long stackdata; int i; ! sp = sp ? sp : (unsigned long *) &sp; printk("Stack :"); i = 0; --- 81,92 ---- long stackdata; int i; ! if (!sp) { ! if (task && task != current) ! sp = (unsigned long *) task->thread.reg29; ! else ! sp = (unsigned long *) &sp; ! } printk("Stack :"); i = 0; *************** *** 110,117 **** const int field = 2 * sizeof(unsigned long); unsigned long addr; ! if (!stack) ! stack = (unsigned long*)&stack; printk("Call Trace:"); #ifdef CONFIG_KALLSYMS --- 114,125 ---- const int field = 2 * sizeof(unsigned long); unsigned long addr; ! if (!stack) { ! if (task && task != current) ! stack = (unsigned long *) task->thread.reg29; ! else ! stack = (unsigned long *) &stack; ! } printk("Call Trace:"); #ifdef CONFIG_KALLSYMS *************** *** 155,160 **** --- 163,178 ---- } } + const char* mips_regname[]={ + "r0,at,v0,v1", + "a0,a1,a2,a3", + "t0,t1,t2,t3", + "t4,t5,t6,t7", + "s0,s1,s2,s3", + "s4,s5,s6,s7", + "t8,t9,k0,k1", + "gp,sp,fp,ra" + }; void show_regs(struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); *************** *** 178,184 **** i++; if ((i % 4) == 0) ! printk("\n"); } printk("Hi : %0*lx\n", field, regs->hi); --- 196,202 ---- i++; if ((i % 4) == 0) ! printk(" ; %s\n",mips_regname[i/4-1]); } printk("Hi : %0*lx\n", field, regs->hi); *************** *** 298,303 **** --- 316,323 ---- int data = regs->cp0_cause & 4; int action = MIPS_BE_FATAL; + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); + /* XXX For now. Fixme, this searches the wrong table ... */ if (data && !user_mode(regs)) fixup = search_dbe_tables(exception_epc(regs)); *************** *** 310,319 **** --- 330,341 ---- switch (action) { case MIPS_BE_DISCARD: + ltt_ev_trap_exit(); return; case MIPS_BE_FIXUP: if (fixup) { regs->cp0_epc = fixup->nextinsn; + ltt_ev_trap_exit(); return; } break; *************** *** 329,334 **** --- 351,357 ---- field, regs->cp0_epc, field, regs->regs[31]); die_if_kernel("Oops", regs); force_sig(SIGBUS, current); + ltt_ev_trap_exit(); } static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) *************** *** 489,499 **** --- 512,524 ---- { siginfo_t info; + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); info.si_code = FPE_INTOVF; info.si_signo = SIGFPE; info.si_errno = 0; info.si_addr = (void *)regs->cp0_epc; force_sig_info(SIGFPE, &info, current); + ltt_ev_trap_exit(); } /* *************** *** 501,511 **** --- 526,545 ---- */ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) { + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); if (fcr31 & FPU_CSR_UNI_X) { int sig; preempt_disable(); + #ifdef CONFIG_PREEMPT + if (!is_fpu_owner()) { + /* We might lose fpu before disabling preempt... */ + own_fpu(); + BUG_ON(!current->used_math); + restore_fp(current); + } + #endif /* * Unimplemented operation exception. If we've got the full * software emulator on-board, let's use it... *************** *** 517,526 **** --- 551,563 ---- * a bit extreme for what should be an infrequent event. */ save_fp(current); + /* Ensure 'resume' not overwrite saved fp context again. */ + lose_fpu(); /* Run the emulator */ sig = fpu_emulator_cop1Handler (0, regs, ¤t->thread.fpu.soft); + own_fpu(); /* Using the FPU again. */ /* * We can't allow the emulated instruction to leave any of *************** *** 537,546 **** --- 574,585 ---- if (sig) force_sig(sig, current); + ltt_ev_trap_exit(); return; } force_sig(SIGFPE, current); + ltt_ev_trap_exit(); } asmlinkage void do_bp(struct pt_regs *regs) *************** *** 548,557 **** unsigned int opcode, bcode; siginfo_t info; die_if_kernel("Break instruction in kernel code", regs); ! if (get_insn_opcode(regs, &opcode)) return; /* * There is the ancient bug in the MIPS assemblers that the break --- 587,599 ---- unsigned int opcode, bcode; siginfo_t info; + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); die_if_kernel("Break instruction in kernel code", regs); ! if (get_insn_opcode(regs, &opcode)) { ! ltt_ev_trap_exit(); return; + } /* * There is the ancient bug in the MIPS assemblers that the break *************** *** 584,589 **** --- 626,632 ---- default: force_sig(SIGTRAP, current); } + ltt_ev_trap_exit(); } asmlinkage void do_tr(struct pt_regs *regs) *************** *** 591,600 **** unsigned int opcode, tcode = 0; siginfo_t info; die_if_kernel("Trap instruction in kernel code", regs); ! if (get_insn_opcode(regs, &opcode)) return; /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) --- 634,646 ---- unsigned int opcode, tcode = 0; siginfo_t info; + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); die_if_kernel("Trap instruction in kernel code", regs); ! if (get_insn_opcode(regs, &opcode)) { ! ltt_ev_trap_exit(); return; + } /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) *************** *** 621,643 **** default: force_sig(SIGTRAP, current); } } asmlinkage void do_ri(struct pt_regs *regs) { die_if_kernel("Reserved instruction in kernel code", regs); if (!cpu_has_llsc) ! if (!simulate_llsc(regs)) return; force_sig(SIGILL, current); } asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int cpid; die_if_kernel("do_cpu invoked from kernel context!", regs); cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; --- 667,695 ---- default: force_sig(SIGTRAP, current); } + ltt_ev_trap_exit(); } asmlinkage void do_ri(struct pt_regs *regs) { + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); die_if_kernel("Reserved instruction in kernel code", regs); if (!cpu_has_llsc) ! if (!simulate_llsc(regs)) { ! ltt_ev_trap_exit(); return; + } force_sig(SIGILL, current); + ltt_ev_trap_exit(); } asmlinkage void do_cpu(struct pt_regs *regs) { unsigned int cpid; + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); die_if_kernel("do_cpu invoked from kernel context!", regs); cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; *************** *** 647,654 **** if (cpu_has_llsc) break; ! if (!simulate_llsc(regs)) return; break; case 1: --- 699,708 ---- if (cpu_has_llsc) break; ! if (!simulate_llsc(regs)) { ! ltt_ev_trap_exit(); return; + } break; case 1: *************** *** 671,676 **** --- 725,731 ---- preempt_enable(); + ltt_ev_trap_exit(); return; case 2: *************** *** 679,689 **** --- 734,747 ---- } force_sig(SIGILL, current); + ltt_ev_trap_exit(); } asmlinkage void do_mdmx(struct pt_regs *regs) { + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); force_sig(SIGILL, current); + ltt_ev_trap_exit(); } asmlinkage void do_watch(struct pt_regs *regs) *************** *** 1001,1016 **** if (board_be_init) board_be_init(); ! #ifdef CONFIG_MIPS32 ! set_except_vector(1, handle_mod); set_except_vector(2, handle_tlbl); set_except_vector(3, handle_tlbs); ! #endif ! #ifdef CONFIG_MIPS64 ! set_except_vector(1, __xtlb_mod); ! set_except_vector(2, __xtlb_tlbl); ! set_except_vector(3, __xtlb_tlbs); ! #endif set_except_vector(4, handle_adel); set_except_vector(5, handle_ades); --- 1059,1068 ---- if (board_be_init) board_be_init(); ! set_except_vector(1, handle_tlbm); set_except_vector(2, handle_tlbl); set_except_vector(3, handle_tlbs); ! set_except_vector(4, handle_adel); set_except_vector(5, handle_ades); *************** *** 1047,1053 **** * unaligned ldc1/sdc1 exception. The handlers have not been * written yet. Well, anyway there is no R6000 machine on the * current list of targets for Linux/MIPS. ! * (Duh, crap, there is someone with a tripple R6k machine) */ //set_except_vector(14, handle_mc); //set_except_vector(15, handle_ndc); --- 1099,1105 ---- * unaligned ldc1/sdc1 exception. The handlers have not been * written yet. Well, anyway there is no R6000 machine on the * current list of targets for Linux/MIPS. ! * (Duh, crap, there is someone with a triple R6k machine) */ //set_except_vector(14, handle_mc); //set_except_vector(15, handle_ndc); *************** *** 1060,1062 **** --- 1112,1180 ---- flush_icache_range(CAC_BASE, CAC_BASE + 0x400); } + + #if (CONFIG_LTT) + asmlinkage void trace_real_syscall_entry(struct pt_regs * regs) + { + unsigned long addr; + int depth = 0; + unsigned long end_code; + unsigned long lower_bound; + int seek_depth; + unsigned long *stack; + unsigned long start_code; + unsigned long *start_stack; + ltt_syscall_entry trace_syscall_event; + unsigned long upper_bound; + int use_bounds; + int use_depth; + + trace_syscall_event.syscall_id = regs->regs[2] - __NR_Linux; + + trace_syscall_event.address = regs->cp0_epc; + + if (!user_mode(regs)) + goto trace_syscall_end; + + if (ltt_get_trace_config(&use_depth, &use_bounds, &seek_depth, + (void*)&lower_bound, (void*)&upper_bound) < 0) + goto trace_syscall_end; + + /* Heuristic that might work: + * (BUT DOESN'T WORK for any of the cases I tested...) zzz + * Search through stack until a value is found that is within the + * range start_code .. end_code. (This is looking for a return + * pointer to where a shared library was called from.) If a stack + * variable contains a valid code address then an incorrect + * result will be generated. + */ + if ((use_depth == 1) || (use_bounds == 1)) { + stack = (unsigned long*) regs->regs[29]; + end_code = current->mm->end_code; + start_code = current->mm->start_code; + start_stack = (unsigned long *)current->mm->start_stack; + + while ((stack <= start_stack) && (!__get_user(addr, stack))) { + if ((addr > start_code) && (addr < end_code)) { + if (((use_depth == 1) && (depth == seek_depth)) || + ((use_bounds == 1) && (addr > lower_bound) && (addr < upper_bound))) { + trace_syscall_event.address = addr; + goto trace_syscall_end; + } else { + depth++; + } + } + stack++; + } + } + + trace_syscall_end: + ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event); + } + + asmlinkage void trace_real_syscall_exit(void) + { + ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL); + } + + #endif /* (CONFIG_LTT) */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/unaligned.c linux-current/arch/mips/kernel/unaligned.c *** linux-2.6.10/arch/mips/kernel/unaligned.c Sat Dec 25 06:35:50 2004 --- linux-current/arch/mips/kernel/unaligned.c Wed Jun 14 21:12:58 2006 *************** *** 78,83 **** --- 78,84 ---- #include #include #include + #include #include #include *************** *** 497,510 **** mm_segment_t seg; unsigned long pc; /* * Address errors may be deliberately induced by the FPU emulator to * retake control of the CPU after executing the instruction in the * delay slot of an emulated branch. */ /* Terminate if exception was recognized as a delay slot return */ ! if (do_dsemulret(regs)) return; /* Otherwise handle as normal */ --- 498,514 ---- mm_segment_t seg; unsigned long pc; + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); /* * Address errors may be deliberately induced by the FPU emulator to * retake control of the CPU after executing the instruction in the * delay slot of an emulated branch. */ /* Terminate if exception was recognized as a delay slot return */ ! if (do_dsemulret(regs)) { ! ltt_ev_trap_exit(); return; + } /* Otherwise handle as normal */ *************** *** 538,543 **** --- 542,548 ---- } set_fs(seg); + ltt_ev_trap_exit(); return; sigbus: *************** *** 547,550 **** --- 552,556 ---- /* * XXX On return from the signal handler we should advance the epc */ + ltt_ev_trap_exit(); } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/kernel/vmlinux.lds.S linux-current/arch/mips/kernel/vmlinux.lds.S *** linux-2.6.10/arch/mips/kernel/vmlinux.lds.S Sat Dec 25 06:34:30 2004 --- linux-current/arch/mips/kernel/vmlinux.lds.S Wed Jun 14 21:12:58 2006 *************** *** 8,13 **** --- 8,14 ---- jiffies = JIFFIES; SECTIONS { + #ifndef CONFIG_XIP_KERNEL #ifdef CONFIG_BOOT_ELF64 /* Read-only sections, merged into text segment: */ /* . = 0xc000000000000000; */ *************** *** 129,134 **** --- 130,236 ---- . = ALIGN(4096); __init_end = .; /* freed after init ends here */ + #else /* CONFIG_XIP_KERNEL */ + . = LOADADDR; + /* read-only */ + .init : { + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + _sinittext = .; + *(.init.text) + _einittext = .; + . = ALIGN(16); + __setup_start = .; + *(.init.setup) + __setup_end = .; + + __earlyinitcall_start = .; + *(.initcall.early1.init) + __earlyinitcall_end = .; + __initcall_start = .; + *(.initcall1.init) + *(.initcall2.init) + *(.initcall3.init) + *(.initcall4.init) + *(.initcall5.init) + *(.initcall6.init) + *(.initcall7.init) + __initcall_end = .; + __con_initcall_start = .; + *(.con_initcall.init) + __con_initcall_end = .; + . = ALIGN(4096); + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + . = ALIGN(4096); + __init_end = .; + } + + .text : { + _text = .; /* Text and read-only data */ + *(.text) + SCHED_TEXT + LOCK_TEXT + *(.fixup) + *(.gnu.warning) + } + + SECURITY_INIT + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___dbe_table = .; /* Exception table for data bus errors */ + __dbe_table : { *(__dbe_table) } + __stop___dbe_table = .; + + RODATA + _etext = .; /* End of text section */ + + /* writeable */ + . = DATAADDR ; + _sdata = . ; + . = . ; + .data : { /* Data */ + _fdata = . ; + . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ + *(.data.init_task) + *(.data) + CONSTRUCTORS + /* Align the initial ramdisk image (INITRD) on page boundaries. */ + . = ALIGN(4096); + __rd_start = .; + *(.initrd) + . = ALIGN(4096); + __rd_end = .; + _gp = . + 0x8000; + *(.lit8) + *(.lit4) + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + *(.sdata) + + . = ALIGN(4096); + __nosave_begin = .; + *(.data.nosave) + . = ALIGN(4096); + __nosave_end = .; + + . = ALIGN(32); + *(.data.cacheline_aligned) + . = ALIGN(32); + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; + *(.init.data) + + _edata = .; /* End of data section */ + } + #endif /* CONFIG_XIP_KERNEL */ __bss_start = .; /* BSS */ .sbss : { *************** *** 156,161 **** --- 258,264 ---- *(.options) *(.pdr) *(.reginfo) + *(.mdebug*) } /* This is the MIPS specific mdebug section. */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/math-emu/cp1emu.c linux-current/arch/mips/math-emu/cp1emu.c *** linux-2.6.10/arch/mips/math-emu/cp1emu.c Sat Dec 25 06:35:28 2004 --- linux-current/arch/mips/math-emu/cp1emu.c Wed Jun 14 21:12:58 2006 *************** *** 51,56 **** --- 51,78 ---- #include "ieee754.h" #include "dsemul.h" + #define math_put_user(x, ptr) \ + ({ \ + long math_pu_err; \ + struct ieee754_csr pu_csr_save; \ + pu_csr_save = ieee754_csr; \ + preempt_enable(); \ + math_pu_err = put_user(x, ptr); \ + preempt_disable(); \ + ieee754_csr = pu_csr_save; \ + math_pu_err; \ + }) + #define math_get_user(x, ptr) \ + ({ \ + long math_gu_err; \ + struct ieee754_csr gu_csr_save; \ + gu_csr_save = ieee754_csr; \ + preempt_enable(); \ + math_gu_err = get_user(x, ptr); \ + preempt_disable(); \ + ieee754_csr = gu_csr_save; \ + math_gu_err; \ + }) /* Strap kernel emulator for full MIPS IV emulation */ #ifdef __mips *************** *** 199,205 **** vaddr_t emulpc, contpc; unsigned int cond; ! if (get_user(ir, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 221,227 ---- vaddr_t emulpc, contpc; unsigned int cond; ! if (math_get_user(ir, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 230,236 **** #endif return SIGILL; } ! if (get_user(ir, (mips_instruction *) emulpc)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 252,258 ---- #endif return SIGILL; } ! if (math_get_user(ir, (mips_instruction *) emulpc)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 254,260 **** u64 val; fpuemuprivate.stats.loads++; ! if (get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 276,282 ---- u64 val; fpuemuprivate.stats.loads++; ! if (math_get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 269,275 **** fpuemuprivate.stats.stores++; DIFROMREG(val, MIPSInst_RT(ir)); ! if (put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 291,297 ---- fpuemuprivate.stats.stores++; DIFROMREG(val, MIPSInst_RT(ir)); ! if (math_put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 283,289 **** u32 val; fpuemuprivate.stats.loads++; ! if (get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 305,311 ---- u32 val; fpuemuprivate.stats.loads++; ! if (math_get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 310,316 **** } #endif SIFROMREG(val, MIPSInst_RT(ir)); ! if (put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 332,338 ---- } #endif SIFROMREG(val, MIPSInst_RT(ir)); ! if (math_put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 365,371 **** --- 387,401 ---- u32 value; if (ir == CP1UNDEF) { + #ifdef CONFIG_PREEMPT + int ret; + preempt_enable(); + ret = do_dsemulret(xcp); + preempt_disable(); + return ret; + #else return do_dsemulret(xcp); + #endif } if (MIPSInst_RD(ir) == FPCREG_CSR) { value = ctx->fcr31; *************** *** 449,455 **** (xcp->cp0_epc + (MIPSInst_SIMM(ir) << 2)); ! if (get_user(ir, (mips_instruction *) REG_TO_VA xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; --- 479,485 ---- (xcp->cp0_epc + (MIPSInst_SIMM(ir) << 2)); ! if (math_get_user(ir, (mips_instruction *) REG_TO_VA xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; *************** *** 480,486 **** --- 510,526 ---- * Single step the non-cp1 * instruction in the dslot */ + #ifdef CONFIG_PREEMPT + { + int ret; + preempt_enable(); + ret = mips_dsemul(xcp, ir, VA_TO_REG contpc); + preempt_disable(); + return ret; + } + #else return mips_dsemul(xcp, ir, VA_TO_REG contpc); + #endif } else { /* branch not taken */ *************** *** 632,638 **** xcp->regs[MIPSInst_FT(ir)]); fpuemuprivate.stats.loads++; ! if (get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 672,678 ---- xcp->regs[MIPSInst_FT(ir)]); fpuemuprivate.stats.loads++; ! if (math_get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 662,668 **** #endif SIFROMREG(val, MIPSInst_FS(ir)); ! if (put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 702,708 ---- #endif SIFROMREG(val, MIPSInst_FS(ir)); ! if (math_put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 728,734 **** xcp->regs[MIPSInst_FT(ir)]); fpuemuprivate.stats.loads++; ! if (get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 768,774 ---- xcp->regs[MIPSInst_FT(ir)]); fpuemuprivate.stats.loads++; ! if (math_get_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 741,747 **** fpuemuprivate.stats.stores++; DIFROMREG(val, MIPSInst_FS(ir)); ! if (put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 781,787 ---- fpuemuprivate.stats.stores++; DIFROMREG(val, MIPSInst_FS(ir)); ! if (math_put_user(val, va)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 1290,1296 **** do { prevepc = xcp->cp0_epc; ! if (get_user(insn, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } --- 1330,1336 ---- do { prevepc = xcp->cp0_epc; ! if (math_get_user(insn, (mips_instruction *) xcp->cp0_epc)) { fpuemuprivate.stats.errors++; return SIGBUS; } *************** *** 1310,1316 **** --- 1350,1358 ---- if (sig) break; + preempt_enable(); cond_resched(); + preempt_disable(); } while (xcp->cp0_epc > prevepc); /* SIGILL indicates a non-fpu instruction */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/math-emu/dp_simple.c linux-current/arch/mips/math-emu/dp_simple.c *** linux-2.6.10/arch/mips/math-emu/dp_simple.c Sat Dec 25 06:35:24 2004 --- linux-current/arch/mips/math-emu/dp_simple.c Wed Jun 14 21:12:58 2006 *************** *** 48,53 **** --- 48,67 ---- CLEARCX; FLUSHXDP; + #if 1 /* XXX: returning same sign causes stack overflow on pow() of libc 2.2.4 */ + /* quick fix up */ + DPSIGN(x) ^= 1; + + if (xc == IEEE754_CLASS_SNAN) { + ieee754dp y = ieee754dp_indef(); + SETCX(IEEE754_INVALID_OPERATION); + DPSIGN(y) = DPSIGN(x); + return ieee754dp_nanxcpt(y, "neg"); + } + + if (ieee754dp_isnan(x)) /* but not infinity */ + return ieee754dp_nanxcpt(x, "neg", x); + #else if (xc == IEEE754_CLASS_SNAN) { SETCX(IEEE754_INVALID_OPERATION); return ieee754dp_nanxcpt(ieee754dp_indef(), "neg"); *************** *** 58,63 **** --- 72,78 ---- /* quick fix up */ DPSIGN(x) ^= 1; + #endif return x; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/math-emu/sp_simple.c linux-current/arch/mips/math-emu/sp_simple.c *** linux-2.6.10/arch/mips/math-emu/sp_simple.c Sat Dec 25 06:34:58 2004 --- linux-current/arch/mips/math-emu/sp_simple.c Wed Jun 14 21:12:58 2006 *************** *** 48,53 **** --- 48,67 ---- CLEARCX; FLUSHXSP; + #if 1 /* XXX: returning same sign causes stack overflow on pow() of libc 2.2.4 */ + /* quick fix up */ + SPSIGN(x) ^= 1; + + if (xc == IEEE754_CLASS_SNAN) { + ieee754sp y = ieee754sp_indef(); + SETCX(IEEE754_INVALID_OPERATION); + SPSIGN(y) = SPSIGN(x); + return ieee754sp_nanxcpt(y, "neg"); + } + + if (ieee754sp_isnan(x)) /* but not infinity */ + return ieee754sp_nanxcpt(x, "neg", x); + #else if (xc == IEEE754_CLASS_SNAN) { SETCX(IEEE754_INVALID_OPERATION); return ieee754sp_nanxcpt(ieee754sp_indef(), "neg"); *************** *** 58,63 **** --- 72,78 ---- /* quick fix up */ SPSIGN(x) ^= 1; + #endif return x; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/Makefile linux-current/arch/mips/mm/Makefile *** linux-2.6.10/arch/mips/mm/Makefile Sat Dec 25 06:35:00 2004 --- linux-current/arch/mips/mm/Makefile Wed Jun 14 21:12:58 2006 *************** *** 3,9 **** # obj-y += cache.o extable.o fault.o init.o pgtable.o \ ! tlbex.o obj-$(CONFIG_MIPS32) += ioremap.o pgtable-32.o obj-$(CONFIG_MIPS64) += pgtable-64.o --- 3,9 ---- # obj-y += cache.o extable.o fault.o init.o pgtable.o \ ! tlbex.o tlbex-fault.o obj-$(CONFIG_MIPS32) += ioremap.o pgtable-32.o obj-$(CONFIG_MIPS64) += pgtable-64.o *************** *** 27,66 **** obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o pg-r4k.o tlb-r4k.o - # - # TLB exception handling code differs between 32-bit and 64-bit kernels. - # - ifdef CONFIG_MIPS32 - obj-$(CONFIG_CPU_R3000) += tlbex32-r3k.o - obj-$(CONFIG_CPU_TX49XX) += tlbex32-r4k.o - obj-$(CONFIG_CPU_R4300) += tlbex32-r4k.o - obj-$(CONFIG_CPU_R4X00) += tlbex32-r4k.o - obj-$(CONFIG_CPU_VR41XX) += tlbex32-r4k.o - obj-$(CONFIG_CPU_R5000) += tlbex32-r4k.o - obj-$(CONFIG_CPU_NEVADA) += tlbex32-r4k.o - obj-$(CONFIG_CPU_R5432) += tlbex32-r4k.o - obj-$(CONFIG_CPU_RM7000) += tlbex32-r4k.o - obj-$(CONFIG_CPU_RM9000) += tlbex32-r4k.o - obj-$(CONFIG_CPU_R10000) += tlbex32-r4k.o - obj-$(CONFIG_CPU_MIPS32) += tlbex32-mips32.o - obj-$(CONFIG_CPU_MIPS64) += tlbex32-r4k.o - obj-$(CONFIG_CPU_SB1) += tlbex32-r4k.o - obj-$(CONFIG_CPU_TX39XX) += tlbex32-r3k.o - endif - ifdef CONFIG_MIPS64 - obj-$(CONFIG_CPU_R4300) += tlb64-glue-r4k.o - obj-$(CONFIG_CPU_R4X00) += tlb64-glue-r4k.o - obj-$(CONFIG_CPU_R5000) += tlb64-glue-r4k.o - obj-$(CONFIG_CPU_NEVADA) += tlb64-glue-r4k.o - obj-$(CONFIG_CPU_R5432) += tlb64-glue-r4k.o - obj-$(CONFIG_CPU_RM7000) += tlb64-glue-r4k.o - obj-$(CONFIG_CPU_RM9000) += tlb64-glue-r4k.o - obj-$(CONFIG_CPU_R10000) += tlb64-glue-r4k.o - obj-$(CONFIG_CPU_SB1) += tlb64-glue-sb1.o - obj-$(CONFIG_CPU_MIPS64) += tlb64-glue-r4k.o - endif - - obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o --- 27,32 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/c-r4k.c linux-current/arch/mips/mm/c-r4k.c *** linux-2.6.10/arch/mips/mm/c-r4k.c Sat Dec 25 06:35:29 2004 --- linux-current/arch/mips/mm/c-r4k.c Wed Jun 14 21:12:58 2006 *************** *** 318,326 **** { struct mm_struct *mm = args; - if (!cpu_has_dc_aliases) - return; - if (!cpu_context(smp_processor_id(), mm)) return; --- 318,323 ---- *************** *** 340,345 **** --- 337,345 ---- static void r4k_flush_cache_mm(struct mm_struct *mm) { + if (!cpu_has_dc_aliases) + return; + on_each_cpu(local_r4k_flush_cache_mm, mm, 1, 1); } *************** *** 359,371 **** pmd_t *pmdp; pte_t *ptep; - /* - * If ownes no valid ASID yet, cannot possibly have gotten - * this page into the cache. - */ - if (cpu_context(smp_processor_id(), mm) == 0) - return; - page &= PAGE_MASK; pgdp = pgd_offset(mm, page); pmdp = pmd_offset(pgdp, page); --- 359,364 ---- *************** *** 416,421 **** --- 409,421 ---- { struct flush_cache_page_args args; + /* + * If ownes no valid ASID yet, cannot possibly have gotten + * this page into the cache. + */ + if (cpu_context(smp_processor_id(), vma->vm_mm) == 0) + return; + args.vma = vma; args.page = page; *************** *** 784,789 **** --- 784,803 ---- c->options |= MIPS_CPU_CACHE_CDEX_P; break; + case CPU_VR5600: + icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); + c->icache.linesz = 16 << ((config & CONF_IB) >> 5); + c->icache.ways = 4; + c->icache.waybit= 0; + + dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); + c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); + c->dcache.ways = 4; + c->dcache.waybit = 0; + + c->options |= MIPS_CPU_CACHE_CDEX_P; + break; + case CPU_TX49XX: icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); c->icache.linesz = 16 << ((config & CONF_IB) >> 5); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/cache.c linux-current/arch/mips/mm/cache.c *** linux-2.6.10/arch/mips/mm/cache.c Sat Dec 25 06:34:31 2004 --- linux-current/arch/mips/mm/cache.c Wed Jun 14 21:12:58 2006 *************** *** 45,54 **** #endif /* CONFIG_DMA_NONCOHERENT */ ! asmlinkage int sys_cacheflush(void *addr, int bytes, int cache) { ! /* This should flush more selectivly ... */ ! __flush_cache_all(); return 0; } --- 45,61 ---- #endif /* CONFIG_DMA_NONCOHERENT */ ! /* ! * We could optimize the case where the cache argument is not BCACHE but ! * that seems very atypical use ... ! */ ! asmlinkage int sys_cacheflush(unsigned long addr, unsigned long int bytes, ! unsigned int cache) { ! if (verify_area(VERIFY_WRITE, (void *) addr, bytes)) ! return -EFAULT; ! ! flush_icache_range(addr, addr + bytes); return 0; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/dma-noncoherent.c linux-current/arch/mips/mm/dma-noncoherent.c *** linux-2.6.10/arch/mips/mm/dma-noncoherent.c Sat Dec 25 06:34:26 2004 --- linux-current/arch/mips/mm/dma-noncoherent.c Tue Aug 29 22:54:58 2006 *************** *** 17,22 **** --- 17,59 ---- #include #include + #ifdef CONFIG_PCIMEM_PHYSOFFSET + #include + #include + + extern unsigned long pcimem_phys_offset; + + inline dma_addr_t PCIMEM_BUSM2PCIM(dma_addr_t addr) { + switch (mips_machgroup) { + case MACH_GROUP_EMMA2RH: + if (addr < 0x10000000) /* Main Memory */ + return (addr + pcimem_phys_offset); + else /* PCI BUS Memory */ + return (addr + EMMA2RH_PCI1_MEM_PCIBASE - EMMA2RH_PCI1_MEM_BASE); + break; + default: + return (addr + pcimem_phys_offset); + break; + } + } + + inline unsigned long PCIMEM_PCIM2BUSM(unsigned long addr) { + switch (mips_machgroup) { + case MACH_GROUP_EMMA2RH: + if (addr < EMMA2RH_PCI1_MEM_PCIBASE) /* Main Memory */ + return (addr - pcimem_phys_offset); + else /* PCI BUS Memory */ + return (addr - EMMA2RH_PCI1_MEM_PCIBASE + EMMA2RH_PCI1_MEM_BASE); + default: + return (addr - pcimem_phys_offset); + break; + } + } + #else + #define PCIMEM_BUSM2PCIM(a) (a) + #define PCIMEM_PCIM2BUSM(a) (a) + #endif + /* * Warning on the terminology - Linux calls an uncached area coherent; * MIPS terminology calls memory areas with hardware maintained coherency *************** *** 36,42 **** if (ret != NULL) { memset(ret, 0, size); ! *dma_handle = virt_to_phys(ret); } return ret; --- 73,79 ---- if (ret != NULL) { memset(ret, 0, size); ! *dma_handle = PCIMEM_BUSM2PCIM(virt_to_phys(ret)); } return ret; *************** *** 122,128 **** BUG(); } ! return virt_to_phys(ptr); } EXPORT_SYMBOL(dma_map_single); --- 159,165 ---- BUG(); } ! return PCIMEM_BUSM2PCIM(virt_to_phys(ptr)); } EXPORT_SYMBOL(dma_map_single); *************** *** 131,137 **** enum dma_data_direction direction) { unsigned long addr; ! addr = dma_addr + PAGE_OFFSET; switch (direction) { case DMA_TO_DEVICE: --- 168,174 ---- enum dma_data_direction direction) { unsigned long addr; ! addr = PCIMEM_PCIM2BUSM(dma_addr) + PAGE_OFFSET; switch (direction) { case DMA_TO_DEVICE: *************** *** 166,173 **** addr = (unsigned long) page_address(sg->page); if (addr) __dma_sync(addr + sg->offset, sg->length, direction); ! sg->dma_address = (dma_addr_t) ! (page_to_phys(sg->page) + sg->offset); } return nents; --- 203,210 ---- addr = (unsigned long) page_address(sg->page); if (addr) __dma_sync(addr + sg->offset, sg->length, direction); ! sg->dma_address = PCIMEM_BUSM2PCIM((dma_addr_t) ! (page_to_phys(sg->page) + sg->offset)); } return nents; *************** *** 185,191 **** addr = (unsigned long) page_address(page) + offset; dma_cache_wback_inv(addr, size); ! return page_to_phys(page) + offset; } EXPORT_SYMBOL(dma_map_page); --- 222,228 ---- addr = (unsigned long) page_address(page) + offset; dma_cache_wback_inv(addr, size); ! return PCIMEM_BUSM2PCIM(page_to_phys(page) + offset); } EXPORT_SYMBOL(dma_map_page); *************** *** 198,204 **** if (direction != DMA_TO_DEVICE) { unsigned long addr; ! addr = dma_address + PAGE_OFFSET; dma_cache_wback_inv(addr, size); } } --- 235,241 ---- if (direction != DMA_TO_DEVICE) { unsigned long addr; ! addr = PCIMEM_PCIM2BUSM(dma_address) + PAGE_OFFSET; dma_cache_wback_inv(addr, size); } } *************** *** 233,239 **** BUG_ON(direction == DMA_NONE); ! addr = dma_handle + PAGE_OFFSET; __dma_sync(addr, size, direction); } --- 270,276 ---- BUG_ON(direction == DMA_NONE); ! addr = PCIMEM_PCIM2BUSM(dma_handle) + PAGE_OFFSET; __dma_sync(addr, size, direction); } *************** *** 246,252 **** BUG_ON(direction == DMA_NONE); ! addr = dma_handle + PAGE_OFFSET; __dma_sync(addr, size, direction); } --- 283,289 ---- BUG_ON(direction == DMA_NONE); ! addr = PCIMEM_PCIM2BUSM(dma_handle) + PAGE_OFFSET; __dma_sync(addr, size, direction); } *************** *** 259,265 **** BUG_ON(direction == DMA_NONE); ! addr = dma_handle + offset + PAGE_OFFSET; __dma_sync(addr, size, direction); } --- 296,302 ---- BUG_ON(direction == DMA_NONE); ! addr = PCIMEM_PCIM2BUSM(dma_handle) + offset + PAGE_OFFSET; __dma_sync(addr, size, direction); } *************** *** 272,278 **** BUG_ON(direction == DMA_NONE); ! addr = dma_handle + offset + PAGE_OFFSET; __dma_sync(addr, size, direction); } --- 309,315 ---- BUG_ON(direction == DMA_NONE); ! addr = PCIMEM_PCIM2BUSM(dma_handle + offset) + PAGE_OFFSET; __dma_sync(addr, size, direction); } *************** *** 356,362 **** dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction) { ! return (dma64_addr_t)page_to_phys(page) + offset; } EXPORT_SYMBOL(pci_dac_page_to_dma); --- 393,399 ---- dma64_addr_t pci_dac_page_to_dma(struct pci_dev *pdev, struct page *page, unsigned long offset, int direction) { ! return PCIMEM_BUSM2PCIM((dma64_addr_t)page_to_phys(page) + offset); } EXPORT_SYMBOL(pci_dac_page_to_dma); *************** *** 382,388 **** { BUG_ON(direction == PCI_DMA_NONE); ! dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len); } EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu); --- 419,425 ---- { BUG_ON(direction == PCI_DMA_NONE); ! dma_cache_wback_inv(PCIMEM_PCIM2BUSM(dma_addr) + PAGE_OFFSET, len); } EXPORT_SYMBOL(pci_dac_dma_sync_single_for_cpu); *************** *** 392,398 **** { BUG_ON(direction == PCI_DMA_NONE); ! dma_cache_wback_inv(dma_addr + PAGE_OFFSET, len); } EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device); --- 429,435 ---- { BUG_ON(direction == PCI_DMA_NONE); ! dma_cache_wback_inv(PCIMEM_PCIM2BUSM(dma_addr) + PAGE_OFFSET, len); } EXPORT_SYMBOL(pci_dac_dma_sync_single_for_device); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/fault.c linux-current/arch/mips/mm/fault.c *** linux-2.6.10/arch/mips/mm/fault.c Sat Dec 25 06:34:29 2004 --- linux-current/arch/mips/mm/fault.c Wed Jun 14 21:12:58 2006 *************** *** 19,24 **** --- 19,25 ---- #include #include /* For unblank_screen() */ #include + #include #include #include *************** *** 60,65 **** --- 61,68 ---- if (unlikely(address >= VMALLOC_START)) goto vmalloc_fault; + ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs)); + /* * If we're in an interrupt or have no user * context, we must not take the fault.. *************** *** 114,119 **** --- 117,123 ---- } up_read(&mm->mmap_sem); + ltt_ev_trap_exit(); return; /* *************** *** 142,147 **** --- 146,152 ---- /* info.si_code has been set above */ info.si_addr = (void *) address; force_sig_info(SIGSEGV, &info, tsk); + ltt_ev_trap_exit(); return; } *************** *** 149,154 **** --- 154,160 ---- /* Are we prepared to handle this kernel fault? */ if (fixup_exception(regs)) { current->thread.cp0_baduaddr = address; + ltt_ev_trap_exit(); return; } *************** *** 199,204 **** --- 205,211 ---- info.si_addr = (void *) address; force_sig_info(SIGBUS, &info, tsk); + ltt_ev_trap_exit(); return; vmalloc_fault: diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/init.c linux-current/arch/mips/mm/init.c *** linux-2.6.10/arch/mips/mm/init.c Sat Dec 25 06:35:23 2004 --- linux-current/arch/mips/mm/init.c Wed Jun 14 21:12:58 2006 *************** *** 34,39 **** --- 34,40 ---- #include #include #include + #include DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); *************** *** 79,91 **** return 1UL << order; } - #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; pgprot_t kmap_prot; EXPORT_SYMBOL(kmap_prot); EXPORT_SYMBOL(kmap_pte); #define kmap_get_fixmap_pte(vaddr) \ pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) --- 80,164 ---- return 1UL << order; } pte_t *kmap_pte; pgprot_t kmap_prot; EXPORT_SYMBOL(kmap_prot); EXPORT_SYMBOL(kmap_pte); + /* + * These are almost like kmap_atomic / kunmap_atmic except they take an + * additional address argument as the hint. + */ + + static inline void *fixmap_atomic_coherent(void *kaddr, enum fixed_addresses idx, + unsigned long addr) + { + unsigned long vaddr, paddr; + + if (!cpu_has_dc_aliases) + return kaddr; + #ifdef CONFIG_HIGHMEM + if ((unsigned long)kaddr >= FIXADDR_START && + (unsigned long)kaddr < FIXADDR_TOP) { + /* see __kmap_atomic in arch/mips/mm/highmem.c */ + enum fixed_addresses km_idx = __virt_to_fix(kaddr); + paddr = pte_pfn(km_idx-idx) << PAGE_SIZE; + } else { + paddr = __pa(kaddr); + } + #else + paddr = __pa(kaddr); + #endif + if (!pages_do_alias(paddr, addr & PAGE_MASK)) + return kaddr; + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ + inc_preempt_count(); + + /* flush cache on kernel mapping */ + flush_data_cache_page((unsigned long)kaddr); + /* idx are assigned in reverse order */ + idx += FIX_N_COLOURS * smp_processor_id() + + ((FIX_N_COLOURS - ((addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1))) & (FIX_N_COLOURS - 1)); + vaddr = __fix_to_virt(idx); + set_pte(kmap_pte-idx, pfn_pte(paddr >> PAGE_SHIFT, kmap_prot)); + local_flush_tlb_one((unsigned long)vaddr); + + return (void*) vaddr; + } + + static inline void fixunmap_atomic_coherent(void *kaddr, enum fixed_addresses idx) + { + /* idx are assigned in reverse order */ + if ((unsigned long)kaddr > __fix_to_virt(idx) || + (unsigned long)kaddr <= __fix_to_virt(idx + FIX_N_COLOURS * NR_CPUS)) + return; + dec_preempt_count(); + preempt_check_resched(); + } + + void clear_user_page(void *addr, unsigned long vaddr, struct page *page) + { + void * kaddr; + + kaddr = fixmap_atomic_coherent(addr, FIX_COLOUR_0, vaddr); + clear_page(kaddr); + fixunmap_atomic_coherent(kaddr, FIX_COLOUR_0); + } + + void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, + struct page *to) + { + void *ktaddr, *kfaddr; + + ktaddr = fixmap_atomic_coherent(vto, FIX_COLOUR_0, vaddr); + kfaddr = fixmap_atomic_coherent(vfrom, FIX_COLOUR_1, vaddr); + copy_page(ktaddr, kfaddr); + flush_data_cache_page((unsigned long)ktaddr); + fixunmap_atomic_coherent(ktaddr, FIX_COLOUR_0); + fixunmap_atomic_coherent(kfaddr, FIX_COLOUR_1); + } + #define kmap_get_fixmap_pte(vaddr) \ pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) *************** *** 94,107 **** unsigned long kmap_vstart; /* cache the first kmap pte */ ! kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); kmap_pte = kmap_get_fixmap_pte(kmap_vstart); kmap_prot = PAGE_KERNEL; } ! #ifdef CONFIG_MIPS64 ! static void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { pgd_t *pgd; --- 167,180 ---- unsigned long kmap_vstart; /* cache the first kmap pte */ ! kmap_vstart = __fix_to_virt(0); kmap_pte = kmap_get_fixmap_pte(kmap_vstart); kmap_prot = PAGE_KERNEL; } ! #ifdef CONFIG_MIPS32 ! void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { pgd_t *pgd; *************** *** 120,126 **** for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); ! set_pmd(pmd, __pmd(pte)); if (pte != pte_offset_kernel(pmd, 0)) BUG(); } --- 193,199 ---- for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); ! set_pmd(pmd, __pmd((unsigned long)pte)); if (pte != pte_offset_kernel(pmd, 0)) BUG(); } *************** *** 129,136 **** j = 0; } } ! #endif /* CONFIG_MIPS64 */ ! #endif /* CONFIG_HIGHMEM */ #ifndef CONFIG_DISCONTIGMEM extern void pagetable_init(void); --- 202,208 ---- j = 0; } } ! #endif /* CONFIG_MIPS32 */ #ifndef CONFIG_DISCONTIGMEM extern void pagetable_init(void); *************** *** 142,150 **** pagetable_init(); - #ifdef CONFIG_HIGHMEM kmap_init(); - #endif max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; --- 214,220 ---- *************** *** 246,252 **** --- 316,326 ---- #endif codesize = (unsigned long) &_etext - (unsigned long) &_text; + #ifdef CONFIG_XIP_KERNEL + datasize = (unsigned long) &_edata - (unsigned long) &_fdata; + #else datasize = (unsigned long) &_edata - (unsigned long) &_etext; + #endif initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " *************** *** 269,274 **** --- 343,349 ---- start = (unsigned long)phys_to_virt(CPHYSADDR(start)); end = (unsigned long)phys_to_virt(CPHYSADDR(end)); #endif + #ifndef CONFIG_XIP_KERNEL if (start < end) printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); *************** *** 279,284 **** --- 354,360 ---- free_page(start); totalram_pages++; } + #endif } #endif *************** *** 290,295 **** --- 366,372 ---- freed = prom_free_prom_memory(); + #ifndef CONFIG_XIP_KERNEL addr = (unsigned long) &__init_begin; while (addr < (unsigned long) &__init_end) { #ifdef CONFIG_MIPS64 *************** *** 306,309 **** --- 383,387 ---- } printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n", freed >> 10); + #endif } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/pg-r4k.c linux-current/arch/mips/mm/pg-r4k.c *** linux-2.6.10/arch/mips/mm/pg-r4k.c Sat Dec 25 06:34:49 2004 --- linux-current/arch/mips/mm/pg-r4k.c Wed Jun 14 21:12:58 2006 *************** *** 39,45 **** --- 39,52 ---- static unsigned int clear_page_array[0x130 / 4]; + #ifdef CONFIG_XIP_KERNEL + void clear_page(void * page){ + static void (*clear_page_xip)(void *) = (void (*)(void *))clear_page_array; + clear_page_xip(page); + } + #else void clear_page(void * page) __attribute__((alias("clear_page_array"))); + #endif EXPORT_SYMBOL(clear_page); *************** *** 53,59 **** --- 60,74 ---- */ static unsigned int copy_page_array[0x148 / 4]; + #ifdef CONFIG_XIP_KERNEL + void copy_page(void *to, void *from){ + static void (*copy_page_xip)(void *,void *) = + (void (*)(void *,void *))copy_page_array; + copy_page_xip(to,from); + } + #else void copy_page(void *to, void *from) __attribute__((alias("copy_page_array"))); + #endif EXPORT_SYMBOL(copy_page); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/pgtable-32.c linux-current/arch/mips/mm/pgtable-32.c *** linux-2.6.10/arch/mips/mm/pgtable-32.c Sat Dec 25 06:34:00 2004 --- linux-current/arch/mips/mm/pgtable-32.c Wed Jun 14 21:12:58 2006 *************** *** 10,15 **** --- 10,16 ---- #include #include #include + #include #include void pgd_init(unsigned long page) *************** *** 29,80 **** } } - #ifdef CONFIG_HIGHMEM - static void __init fixrange_init (unsigned long start, unsigned long end, - pgd_t *pgd_base) - { - pgd_t *pgd; - pmd_t *pmd; - pte_t *pte; - int i, j; - unsigned long vaddr; - - vaddr = start; - i = __pgd_offset(vaddr); - j = __pmd_offset(vaddr); - pgd = pgd_base + i; - - for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { - pmd = (pmd_t *)pgd; - for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { - if (pmd_none(*pmd)) { - pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); - set_pmd(pmd, __pmd((unsigned long)pte)); - if (pte != pte_offset_kernel(pmd, 0)) - BUG(); - } - vaddr += PMD_SIZE; - } - j = 0; - } - } - #endif - void __init pagetable_init(void) { - #ifdef CONFIG_HIGHMEM unsigned long vaddr; ! pgd_t *pgd, *pgd_base; pmd_t *pmd; pte_t *pte; #endif /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); ! pgd_init((unsigned long)swapper_pg_dir + ! sizeof(pgd_t ) * USER_PTRS_PER_PGD); ! #ifdef CONFIG_HIGHMEM pgd_base = swapper_pg_dir; /* --- 30,52 ---- } } void __init pagetable_init(void) { unsigned long vaddr; ! pgd_t *pgd_base; ! #ifdef CONFIG_HIGHMEM ! pgd_t *pgd; pmd_t *pmd; pte_t *pte; #endif /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); ! pgd_init((unsigned long)swapper_pg_dir ! + sizeof(pgd_t) * USER_PTRS_PER_PGD); ! if (!__end_of_fixed_addresses) ! return; pgd_base = swapper_pg_dir; /* *************** *** 83,88 **** --- 55,61 ---- vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; fixrange_init(vaddr, 0, pgd_base); + #ifdef CONFIG_HIGHMEM /* * Permanent kmaps: */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/tlb-r4k.c linux-current/arch/mips/mm/tlb-r4k.c *** linux-2.6.10/arch/mips/mm/tlb-r4k.c Sat Dec 25 06:34:27 2004 --- linux-current/arch/mips/mm/tlb-r4k.c Wed Jun 14 21:12:58 2006 *************** *** 21,26 **** --- 21,32 ---- extern void build_tlb_refill_handler(void); + /* + * Make sure all entries differ. If they're not different + * MIPS32 will take revenge ... + */ + #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) + /* CP0 hazard avoidance. */ #define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ "nop; nop; nop; nop; nop; nop;\n\t" \ *************** *** 42,52 **** /* Blast 'em all away. */ while (entry < current_cpu_data.tlbsize) { ! /* ! * Make sure all entries differ. If they're not different ! * MIPS32 will take revenge ... ! */ ! write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1))); write_c0_index(entry); mtc0_tlbw_hazard(); tlb_write_indexed(); --- 48,55 ---- /* Blast 'em all away. */ while (entry < current_cpu_data.tlbsize) { ! /* Make sure all entries differ. */ ! write_c0_entryhi(UNIQUE_ENTRYHI(entry)); write_c0_index(entry); mtc0_tlbw_hazard(); tlb_write_indexed(); *************** *** 57,68 **** local_irq_restore(flags); } void local_flush_tlb_mm(struct mm_struct *mm) { ! int cpu = smp_processor_id(); ! if (cpu_context(cpu, mm) != 0) ! drop_mmu_context(mm,cpu); } void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, --- 60,80 ---- local_irq_restore(flags); } + /* All entries common to a mm share an asid. To effectively flush + these entries, we just bump the asid. */ void local_flush_tlb_mm(struct mm_struct *mm) { ! int cpu; ! ! preempt_disable(); ! cpu = smp_processor_id(); ! ! if (cpu_context(cpu, mm) != 0) { ! drop_mmu_context(mm, cpu); ! } ! ! preempt_enable(); } void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, *************** *** 75,83 **** unsigned long flags; int size; - local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; if (size <= current_cpu_data.tlbsize/2) { int oldpid = read_c0_entryhi(); int newpid = cpu_asid(cpu, mm); --- 87,95 ---- unsigned long flags; int size; size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; + local_irq_save(flags); if (size <= current_cpu_data.tlbsize/2) { int oldpid = read_c0_entryhi(); int newpid = cpu_asid(cpu, mm); *************** *** 99,106 **** if (idx < 0) continue; /* Make sure all entries differ. */ ! write_c0_entryhi(CKSEG0 + ! (idx << (PAGE_SHIFT + 1))); mtc0_tlbw_hazard(); tlb_write_indexed(); } --- 111,117 ---- if (idx < 0) continue; /* Make sure all entries differ. */ ! write_c0_entryhi(UNIQUE_ENTRYHI(idx)); mtc0_tlbw_hazard(); tlb_write_indexed(); } *************** *** 118,126 **** unsigned long flags; int size; - local_irq_save(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; if (size <= current_cpu_data.tlbsize / 2) { int pid = read_c0_entryhi(); --- 129,137 ---- unsigned long flags; int size; size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; + local_irq_save(flags); if (size <= current_cpu_data.tlbsize / 2) { int pid = read_c0_entryhi(); *************** *** 142,148 **** if (idx < 0) continue; /* Make sure all entries differ. */ ! write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); mtc0_tlbw_hazard(); tlb_write_indexed(); } --- 153,159 ---- if (idx < 0) continue; /* Make sure all entries differ. */ ! write_c0_entryhi(UNIQUE_ENTRYHI(idx)); mtc0_tlbw_hazard(); tlb_write_indexed(); } *************** *** 176,182 **** if (idx < 0) goto finish; /* Make sure all entries differ. */ ! write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); mtc0_tlbw_hazard(); tlb_write_indexed(); tlbw_use_hazard(); --- 187,193 ---- if (idx < 0) goto finish; /* Make sure all entries differ. */ ! write_c0_entryhi(UNIQUE_ENTRYHI(idx)); mtc0_tlbw_hazard(); tlb_write_indexed(); tlbw_use_hazard(); *************** *** 197,204 **** int oldpid, idx; local_irq_save(flags); - page &= (PAGE_MASK << 1); oldpid = read_c0_entryhi(); write_c0_entryhi(page); mtc0_tlbw_hazard(); tlb_probe(); --- 208,215 ---- int oldpid, idx; local_irq_save(flags); oldpid = read_c0_entryhi(); + page &= (PAGE_MASK << 1); write_c0_entryhi(page); mtc0_tlbw_hazard(); tlb_probe(); *************** *** 208,214 **** write_c0_entrylo1(0); if (idx >= 0) { /* Make sure all entries differ. */ ! write_c0_entryhi(CKSEG0 + (idx << (PAGE_SHIFT + 1))); mtc0_tlbw_hazard(); tlb_write_indexed(); tlbw_use_hazard(); --- 219,225 ---- write_c0_entrylo1(0); if (idx >= 0) { /* Make sure all entries differ. */ ! write_c0_entryhi(UNIQUE_ENTRYHI(idx)); mtc0_tlbw_hazard(); tlb_write_indexed(); tlbw_use_hazard(); *************** *** 237,245 **** if (current->active_mm != vma->vm_mm) return; - pid = read_c0_entryhi() & ASID_MASK; - local_irq_save(flags); address &= (PAGE_MASK << 1); write_c0_entryhi(address | pid); pgdp = pgd_offset(vma->vm_mm, address); --- 248,256 ---- if (current->active_mm != vma->vm_mm) return; local_irq_save(flags); + + pid = read_c0_entryhi() & ASID_MASK; address &= (PAGE_MASK << 1); write_c0_entryhi(address | pid); pgdp = pgd_offset(vma->vm_mm, address); *************** *** 258,271 **** write_c0_entrylo0(pte_val(*ptep++) >> 6); write_c0_entrylo1(pte_val(*ptep) >> 6); #endif - write_c0_entryhi(address | pid); mtc0_tlbw_hazard(); if (idx < 0) tlb_write_random(); else tlb_write_indexed(); tlbw_use_hazard(); - write_c0_entryhi(pid); local_irq_restore(flags); } --- 269,280 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/tlbex-fault.S linux-current/arch/mips/mm/tlbex-fault.S *** linux-2.6.10/arch/mips/mm/tlbex-fault.S Thu Jan 1 09:00:00 1970 --- linux-current/arch/mips/mm/tlbex-fault.S Wed Jun 14 21:12:58 2006 *************** *** 0 **** --- 1,28 ---- + /* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ + #include + #include + #include + #include + + .macro tlb_do_page_fault, write + NESTED(tlb_do_page_fault_\write, PT_SIZE, sp) + SAVE_ALL + MFC0 a2, CP0_BADVADDR + KMODE + move a0, sp + REG_S a2, PT_BVADDR(sp) + li a1, \write + jal do_page_fault + j ret_from_exception + END(tlb_do_page_fault_\write) + .endm + + tlb_do_page_fault 0 + tlb_do_page_fault 1 diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/mm/tlbex.c linux-current/arch/mips/mm/tlbex.c *** linux-2.6.10/arch/mips/mm/tlbex.c Sat Dec 25 06:34:01 2004 --- linux-current/arch/mips/mm/tlbex.c Wed Jun 14 21:12:58 2006 *************** *** 5,11 **** * * Synthesize TLB refill handlers at runtime. * ! * Copyright (C) 2004 by Thiemo Seufer */ #include --- 5,11 ---- * * Synthesize TLB refill handlers at runtime. * ! * Copyright (C) 2004,2005 by Thiemo Seufer */ #include *************** *** 19,29 **** #include #include - #include #include #include #include #include /* #define DEBUG_TLB */ --- 19,29 ---- #include #include #include #include #include #include + #include /* #define DEBUG_TLB */ *************** *** 44,49 **** --- 44,54 ---- return BCM1250_M3_WAR; } + static __init int __attribute__((unused)) r10000_llsc_war(void) + { + return R10000_LLSC_WAR; + } + /* * A little micro-assembler, intended for TLB refill handler * synthesizing. It is intentionally kept simple, does only support *************** *** 84,96 **** enum opcode { insn_invalid, insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, ! insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne, ! insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, ! insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe, ! insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw, ! insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori }; struct insn { --- 89,102 ---- enum opcode { insn_invalid, insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, ! insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, ! insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, ! insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, ! insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, ! insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi, ! insn_tlbwr, insn_xor, insn_xori }; struct insn { *************** *** 114,119 **** --- 120,126 ---- { insn_and, M(spec_op,0,0,0,0,and_op), RS | RT | RD }, { insn_andi, M(andi_op,0,0,0,0,0), RS | RT | UIMM }, { insn_beq, M(beq_op,0,0,0,0,0), RS | RT | BIMM }, + { insn_beql, M(beql_op,0,0,0,0,0), RS | RT | BIMM }, { insn_bgez, M(bcond_op,0,bgez_op,0,0,0), RS | BIMM }, { insn_bgezl, M(bcond_op,0,bgezl_op,0,0,0), RS | BIMM }, { insn_bltz, M(bcond_op,0,bltz_op,0,0,0), RS | BIMM }, *************** *** 134,145 **** --- 141,156 ---- { insn_jal, M(jal_op,0,0,0,0,0), JIMM }, { insn_jr, M(spec_op,0,0,0,0,jr_op), RS }, { insn_ld, M(ld_op,0,0,0,0,0), RS | RT | SIMM }, + { insn_ll, M(ll_op,0,0,0,0,0), RS | RT | SIMM }, + { insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM }, { insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM }, { insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM }, { insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD }, { insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD }, { insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM }, { insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 }, + { insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM }, + { insn_scd, M(scd_op,0,0,0,0,0), RS | RT | SIMM }, { insn_sd, M(sd_op,0,0,0,0,0), RS | RT | SIMM }, { insn_sll, M(spec_op,0,0,0,0,sll_op), RT | RD | RE }, { insn_sra, M(spec_op,0,0,0,0,sra_op), RT | RD | RE }, *************** *** 341,346 **** --- 352,358 ---- I_u2u1u3(_andi); I_u3u1u2(_and); I_u1u2s3(_beq); + I_u1u2s3(_beql); I_u1s2(_bgez); I_u1s2(_bgezl); I_u1s2(_bltz); *************** *** 361,372 **** --- 373,388 ---- I_u1(_jal); I_u1(_jr); I_u2s3u1(_ld); + I_u2s3u1(_ll); + I_u2s3u1(_lld); I_u1s2(_lui); I_u2s3u1(_lw); I_u1u2(_mfc0); I_u1u2(_mtc0); I_u2u1u3(_ori); I_0(_rfe); + I_u2s3u1(_sc); + I_u2s3u1(_scd); I_u2s3u1(_sd); I_u2u1u3(_sll); I_u2u1u3(_sra); *************** *** 389,396 **** label_leave, label_vmalloc, label_vmalloc_done, ! label_tlbwr_hazard, ! label_split }; struct label { --- 405,418 ---- label_leave, label_vmalloc, label_vmalloc_done, ! label_tlbw_hazard, ! label_split, ! label_nopage_tlbl, ! label_nopage_tlbs, ! label_nopage_tlbm, ! label_smp_pgtable_change, ! label_r3000_write_probe_fail, ! label_r3000_write_probe_ok }; struct label { *************** *** 416,423 **** L_LA(_leave) L_LA(_vmalloc) L_LA(_vmalloc_done) ! L_LA(_tlbwr_hazard) L_LA(_split) /* convenience macros for instructions */ #ifdef CONFIG_MIPS64 --- 438,451 ---- L_LA(_leave) L_LA(_vmalloc) L_LA(_vmalloc_done) ! L_LA(_tlbw_hazard) L_LA(_split) + L_LA(_nopage_tlbl) + L_LA(_nopage_tlbs) + L_LA(_nopage_tlbm) + L_LA(_smp_pgtable_change) + L_LA(_r3000_write_probe_fail) + L_LA(_r3000_write_probe_ok) /* convenience macros for instructions */ #ifdef CONFIG_MIPS64 *************** *** 431,436 **** --- 459,466 ---- # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val) # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd) # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd) + # define i_LL(buf, rs, rt, off) i_lld(buf, rs, rt, off) + # define i_SC(buf, rs, rt, off) i_scd(buf, rs, rt, off) #else # define i_LW(buf, rs, rt, off) i_lw(buf, rs, rt, off) # define i_SW(buf, rs, rt, off) i_sw(buf, rs, rt, off) *************** *** 442,469 **** # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val) # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd) # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd) #endif #define i_b(buf, off) i_beq(buf, 0, 0, off) #define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off) #define i_move(buf, a, b) i_ADDU(buf, a, 0, b) #define i_nop(buf) i_sll(buf, 0, 0, 0) #define i_ssnop(buf) i_sll(buf, 0, 0, 1) #define i_ehb(buf) i_sll(buf, 0, 0, 3) ! #if CONFIG_MIPS64 ! static __init int in_compat_space_p(long addr) { /* Is this address in 32bit compat space? */ return (((addr) & 0xffffffff00000000) == 0xffffffff00000000); } ! static __init int rel_highest(long val) { return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; } ! static __init int rel_higher(long val) { return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; } --- 472,504 ---- # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val) # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd) # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd) + # define i_LL(buf, rs, rt, off) i_ll(buf, rs, rt, off) + # define i_SC(buf, rs, rt, off) i_sc(buf, rs, rt, off) #endif #define i_b(buf, off) i_beq(buf, 0, 0, off) + #define i_beqz(buf, rs, off) i_beq(buf, rs, 0, off) + #define i_beqzl(buf, rs, off) i_beql(buf, rs, 0, off) #define i_bnez(buf, rs, off) i_bne(buf, rs, 0, off) + #define i_bnezl(buf, rs, off) i_bnel(buf, rs, 0, off) #define i_move(buf, a, b) i_ADDU(buf, a, 0, b) #define i_nop(buf) i_sll(buf, 0, 0, 0) #define i_ssnop(buf) i_sll(buf, 0, 0, 1) #define i_ehb(buf) i_sll(buf, 0, 0, 3) ! #ifdef CONFIG_MIPS64 ! static __init int __attribute__((unused)) in_compat_space_p(long addr) { /* Is this address in 32bit compat space? */ return (((addr) & 0xffffffff00000000) == 0xffffffff00000000); } ! static __init int __attribute__((unused)) rel_highest(long val) { return ((((val + 0x800080008000L) >> 48) & 0xffff) ^ 0x8000) - 0x8000; } ! static __init int __attribute__((unused)) rel_higher(long val) { return ((((val + 0x80008000L) >> 32) & 0xffff) ^ 0x8000) - 0x8000; } *************** *** 550,571 **** __resolve_relocs(rel, l); } ! static __init void copy_handler(struct reloc *rel, struct label *lab, ! u32 *first, u32 *end, u32* target) { - long off = (long)(target - first); - - memcpy(target, first, (end - first) * sizeof(u32)); - for (; rel->lab != label_invalid; rel++) if (rel->addr >= first && rel->addr < end) rel->addr += off; for (; lab->lab != label_invalid; lab++) if (lab->addr >= first && lab->addr < end) lab->addr += off; } static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel, u32 *addr) { --- 585,617 ---- __resolve_relocs(rel, l); } ! static __init void move_relocs(struct reloc *rel, u32 *first, u32 *end, ! long off) { for (; rel->lab != label_invalid; rel++) if (rel->addr >= first && rel->addr < end) rel->addr += off; + } + static __init void move_labels(struct label *lab, u32 *first, u32 *end, + long off) + { for (; lab->lab != label_invalid; lab++) if (lab->addr >= first && lab->addr < end) lab->addr += off; } + static __init void copy_handler(struct reloc *rel, struct label *lab, + u32 *first, u32 *end, u32 *target) + { + long off = (long)(target - first); + + memcpy(target, first, (end - first) * sizeof(u32)); + + move_relocs(rel, first, end, off); + move_labels(lab, first, end, off); + } + static __init int __attribute__((unused)) insn_has_bdelay(struct reloc *rel, u32 *addr) { *************** *** 594,599 **** --- 640,659 ---- i_b(p, 0); } + static void il_beqz(u32 **p, struct reloc **r, unsigned int reg, + enum label_id l) + { + r_mips_pc16(r, *p, l); + i_beqz(p, reg, 0); + } + + static void __attribute__((unused)) + il_beqzl(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) + { + r_mips_pc16(r, *p, l); + i_beqzl(p, reg, 0); + } + static void il_bnez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) { *************** *** 608,614 **** i_bgezl(p, reg, 0); } ! /* The only registers allowed in TLB handlers. */ #define K0 26 #define K1 27 --- 668,674 ---- i_bgezl(p, reg, 0); } ! /* The only general purpose registers allowed in TLB handlers. */ #define K0 26 #define K1 27 *************** *** 642,648 **** static __initdata struct label labels[128]; static __initdata struct reloc relocs[128]; - #ifdef CONFIG_MIPS32 /* * The R3000 TLB handler is simple. */ --- 702,707 ---- *************** *** 676,685 **** panic("TLB refill handler space exceeded"); printk("Synthesized TLB handler (%u instructions).\n", ! p - tlb_handler); #ifdef DEBUG_TLB { int i; for (i = 0; i < (p - tlb_handler); i++) printk("%08x\n", tlb_handler[i]); } --- 735,745 ---- panic("TLB refill handler space exceeded"); printk("Synthesized TLB handler (%u instructions).\n", ! (unsigned int)(p - tlb_handler)); #ifdef DEBUG_TLB { int i; + for (i = 0; i < (p - tlb_handler); i++) printk("%08x\n", tlb_handler[i]); } *************** *** 688,694 **** memcpy((void *)CAC_BASE, tlb_handler, 0x80); flush_icache_range(CAC_BASE, CAC_BASE + 0x80); } - #endif /* CONFIG_MIPS32 */ /* * The R4000 TLB handler is much more complicated. We have two --- 748,753 ---- *************** *** 738,749 **** } /* ! * Write random TLB entry, and care about the hazards from the ! * preceeding mtc0 and for the following eret. */ ! static __init void build_tlb_write_random_entry(u32 **p, struct label **l, ! struct reloc **r) { switch (current_cpu_data.cputype) { case CPU_R4000PC: case CPU_R4000SC: --- 797,818 ---- } /* ! * Write random or indexed TLB entry, and care about the hazards from ! * the preceeding mtc0 and for the following eret. */ ! enum tlb_write_entry { tlb_random, tlb_indexed }; ! ! static __init void build_tlb_write_entry(u32 **p, struct label **l, ! struct reloc **r, ! enum tlb_write_entry wmode) { + void(*tlbw)(u32 **) = NULL; + + switch (wmode) { + case tlb_random: tlbw = i_tlbwr; break; + case tlb_indexed: tlbw = i_tlbwi; break; + } + switch (current_cpu_data.cputype) { case CPU_R4000PC: case CPU_R4000SC: *************** *** 753,763 **** case CPU_R4400MC: /* * This branch uses up a mtc0 hazard nop slot and saves ! * two nops after the tlbwr. */ ! il_bgezl(p, r, 0, label_tlbwr_hazard); ! i_tlbwr(p); ! l_tlbwr_hazard(l, *p); i_nop(p); break; --- 822,832 ---- case CPU_R4400MC: /* * This branch uses up a mtc0 hazard nop slot and saves ! * two nops after the tlbw instruction. */ ! il_bgezl(p, r, 0, label_tlbw_hazard); ! tlbw(p); ! l_tlbw_hazard(l, *p); i_nop(p); break; *************** *** 765,777 **** case CPU_R4700: case CPU_R5000: case CPU_R5000A: case CPU_5KC: case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: case CPU_AU1550: i_nop(p); ! i_tlbwr(p); break; case CPU_R10000: --- 834,849 ---- case CPU_R4700: case CPU_R5000: case CPU_R5000A: + case CPU_R5500: + case CPU_VR5600: case CPU_5KC: + case CPU_TX49XX: case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: case CPU_AU1550: i_nop(p); ! tlbw(p); break; case CPU_R10000: *************** *** 781,804 **** case CPU_4KSC: case CPU_20KC: case CPU_25KF: ! i_tlbwr(p); break; case CPU_NEVADA: i_nop(p); /* QED specifies 2 nops hazard */ /* * This branch uses up a mtc0 hazard nop slot and saves ! * a nop after the tlbwr. */ ! il_bgezl(p, r, 0, label_tlbwr_hazard); ! i_tlbwr(p); ! l_tlbwr_hazard(l, *p); break; case CPU_4KEC: case CPU_24K: i_ehb(p); ! i_tlbwr(p); break; case CPU_RM9000: --- 853,884 ---- case CPU_4KSC: case CPU_20KC: case CPU_25KF: ! tlbw(p); break; case CPU_NEVADA: i_nop(p); /* QED specifies 2 nops hazard */ /* * This branch uses up a mtc0 hazard nop slot and saves ! * a nop after the tlbw instruction. */ ! il_bgezl(p, r, 0, label_tlbw_hazard); ! tlbw(p); ! l_tlbw_hazard(l, *p); ! break; ! ! case CPU_RM7000: ! i_nop(p); ! i_nop(p); ! i_nop(p); ! i_nop(p); ! tlbw(p); break; case CPU_4KEC: case CPU_24K: i_ehb(p); ! tlbw(p); break; case CPU_RM9000: *************** *** 812,824 **** i_ssnop(p); i_ssnop(p); i_ssnop(p); ! i_tlbwr(p); i_ssnop(p); i_ssnop(p); i_ssnop(p); i_ssnop(p); break; default: panic("No TLB refill handler yet (CPU type: %d)", current_cpu_data.cputype); --- 892,923 ---- i_ssnop(p); i_ssnop(p); i_ssnop(p); ! tlbw(p); i_ssnop(p); i_ssnop(p); i_ssnop(p); i_ssnop(p); break; + case CPU_VR4111: + case CPU_VR4121: + case CPU_VR4122: + case CPU_VR4181: + case CPU_VR4181A: + i_nop(p); + i_nop(p); + tlbw(p); + i_nop(p); + i_nop(p); + break; + + case CPU_VR4131: + case CPU_VR4133: + i_nop(p); + i_nop(p); + tlbw(p); + break; + default: panic("No TLB refill handler yet (CPU type: %d)", current_cpu_data.cputype); *************** *** 826,832 **** } } ! #if CONFIG_MIPS64 /* * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pmd entry. --- 925,931 ---- } } ! #ifdef CONFIG_MIPS64 /* * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pmd entry. *************** *** 844,850 **** il_bltz(p, r, tmp, label_vmalloc); /* No i_nop needed here, since the next insn doesn't touch TMP. */ ! # ifdef CONFIG_SMP /* * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()] * stored in CONTEXT. --- 943,949 ---- il_bltz(p, r, tmp, label_vmalloc); /* No i_nop needed here, since the next insn doesn't touch TMP. */ ! #ifdef CONFIG_SMP /* * 64 bit SMP has the lower part of &pgd_current[smp_processor_id()] * stored in CONTEXT. *************** *** 852,858 **** --- 951,967 ---- if (in_compat_space_p(pgdc)) { i_dmfc0(p, ptr, C0_CONTEXT); i_dsra(p, ptr, ptr, 23); + i_ld(p, ptr, 0, ptr); } else { + #ifdef CONFIG_BUILD_ELF64 + i_dmfc0(p, ptr, C0_CONTEXT); + i_dsrl(p, ptr, ptr, 23); + i_dsll(p, ptr, ptr, 3); + i_LA_mostly(p, tmp, pgdc); + i_daddu(p, ptr, ptr, tmp); + i_dmfc0(p, tmp, C0_BADVADDR); + i_ld(p, ptr, rel_lo(pgdc), ptr); + #else i_dmfc0(p, ptr, C0_CONTEXT); i_lui(p, tmp, rel_highest(pgdc)); i_dsll(p, ptr, ptr, 9); *************** *** 860,871 **** i_dsrl32(p, ptr, ptr, 0); i_and(p, ptr, ptr, tmp); i_dmfc0(p, tmp, C0_BADVADDR); } ! i_ld(p, ptr, 0, ptr); ! # else i_LA_mostly(p, ptr, pgdc); i_ld(p, ptr, rel_lo(pgdc), ptr); ! # endif l_vmalloc_done(l, *p); i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */ --- 969,981 ---- i_dsrl32(p, ptr, ptr, 0); i_and(p, ptr, ptr, tmp); i_dmfc0(p, tmp, C0_BADVADDR); + i_ld(p, ptr, 0, ptr); + #endif } ! #else i_LA_mostly(p, ptr, pgdc); i_ld(p, ptr, rel_lo(pgdc), ptr); ! #endif l_vmalloc_done(l, *p); i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */ *************** *** 902,914 **** } } ! #else /* CONFIG_MIPS32 */ /* * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pgd entry. */ ! static __init void build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) { long pgdc = (long)pgd_current; --- 1012,1025 ---- } } ! #else /* !CONFIG_MIPS64 */ /* * TMP and PTR are scratch. * TMP will be clobbered, PTR will hold the pgd entry. */ ! static __init void __attribute__((unused)) ! build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) { long pgdc = (long)pgd_current; *************** *** 928,944 **** i_sll(p, tmp, tmp, PGD_T_LOG2); i_addu(p, ptr, ptr, tmp); /* add in pgd offset */ } ! #endif /* CONFIG_MIPS32 */ static __init void build_adjust_context(u32 **p, unsigned int ctx) { ! unsigned int shift = 0; ! unsigned int mask = 0xff0; ! ! #if !defined(CONFIG_MIPS64) && !defined(CONFIG_64BIT_PHYS_ADDR) ! shift++; ! mask |= 0x008; ! #endif switch (current_cpu_data.cputype) { case CPU_VR41XX: --- 1039,1051 ---- i_sll(p, tmp, tmp, PGD_T_LOG2); i_addu(p, ptr, ptr, tmp); /* add in pgd offset */ } ! ! #endif /* !CONFIG_MIPS64 */ static __init void build_adjust_context(u32 **p, unsigned int ctx) { ! unsigned int shift = 4 - (PTE_T_LOG2 + 1); ! unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); switch (current_cpu_data.cputype) { case CPU_VR41XX: *************** *** 1049,1068 **** i_MFC0(&p, K0, C0_BADVADDR); i_MFC0(&p, K1, C0_ENTRYHI); i_xor(&p, K0, K0, K1); ! i_SRL(&p, K0, K0, PAGE_SHIFT+1); il_bnez(&p, &r, K0, label_leave); /* No need for i_nop */ } #ifdef CONFIG_MIPS64 ! build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd ptr in K1 */ #else ! build_get_pgde32(&p, K0, K1); /* get pgd ptr in K1 */ #endif build_get_ptep(&p, K0, K1); build_update_entries(&p, K0, K1); ! build_tlb_write_random_entry(&p, &l, &r); l_leave(&l, p); i_eret(&p); /* return from trap */ --- 1156,1175 ---- i_MFC0(&p, K0, C0_BADVADDR); i_MFC0(&p, K1, C0_ENTRYHI); i_xor(&p, K0, K0, K1); ! i_SRL(&p, K0, K0, PAGE_SHIFT + 1); il_bnez(&p, &r, K0, label_leave); /* No need for i_nop */ } #ifdef CONFIG_MIPS64 ! build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */ #else ! build_get_pgde32(&p, K0, K1); /* get pgd in K1 */ #endif build_get_ptep(&p, K0, K1); build_update_entries(&p, K0, K1); ! build_tlb_write_entry(&p, &l, &r, tlb_random); l_leave(&l, p); i_eret(&p); /* return from trap */ *************** *** 1121,1126 **** --- 1228,1234 ---- i_nop(&f); else { copy_handler(relocs, labels, split, split + 1, f); + move_labels(labels, f, f + 1, -1); f++; split++; } *************** *** 1132,1138 **** #endif /* CONFIG_MIPS64 */ resolve_relocs(relocs, labels); ! printk("Synthesized TLB handler (%u instructions).\n", final_len); #ifdef DEBUG_TLB { --- 1240,1247 ---- #endif /* CONFIG_MIPS64 */ resolve_relocs(relocs, labels); ! printk("Synthesized TLB refill handler (%u instructions).\n", ! final_len); #ifdef DEBUG_TLB { *************** *** 1147,1156 **** flush_icache_range(CAC_BASE, CAC_BASE + 0x100); } void __init build_tlb_refill_handler(void) { switch (current_cpu_data.cputype) { - #ifdef CONFIG_MIPS32 case CPU_R2000: case CPU_R3000: case CPU_R3000A: --- 1256,1821 ---- flush_icache_range(CAC_BASE, CAC_BASE + 0x100); } + /* + * TLB load/store/modify handlers. + * + * Only the fastpath gets synthesized at runtime, the slowpath for + * do_page_fault remains normal asm. + */ + extern void tlb_do_page_fault_0(void); + extern void tlb_do_page_fault_1(void); + + #define __tlb_handler_align \ + __attribute__((__aligned__(1 << CONFIG_MIPS_L1_CACHE_SHIFT))) + + /* + * 128 instructions for the fastpath handler is generous and should + * never be exceeded. + */ + #define FASTPATH_SIZE 128 + + u32 __tlb_handler_align handle_tlbl[FASTPATH_SIZE]; + u32 __tlb_handler_align handle_tlbs[FASTPATH_SIZE]; + u32 __tlb_handler_align handle_tlbm[FASTPATH_SIZE]; + + static void __init + iPTE_LW(u32 **p, struct label **l, unsigned int pte, int offset, + unsigned int ptr) + { + #ifdef CONFIG_SMP + # ifdef CONFIG_64BIT_PHYS_ADDR + if (cpu_has_64bit_gp_regs) + i_lld(p, pte, offset, ptr); + else + # endif + i_LL(p, pte, offset, ptr); + #else + # ifdef CONFIG_64BIT_PHYS_ADDR + if (cpu_has_64bit_gp_regs) + i_ld(p, pte, offset, ptr); + else + # endif + i_LW(p, pte, offset, ptr); + #endif + } + + static void __init + iPTE_SW(u32 **p, struct reloc **r, unsigned int pte, int offset, + unsigned int ptr) + { + #ifdef CONFIG_SMP + # ifdef CONFIG_64BIT_PHYS_ADDR + if (cpu_has_64bit_gp_regs) + i_scd(p, pte, offset, ptr); + else + # endif + i_SC(p, pte, offset, ptr); + + if (r10000_llsc_war()) + il_beqzl(p, r, pte, label_smp_pgtable_change); + else + il_beqz(p, r, pte, label_smp_pgtable_change); + + # ifdef CONFIG_64BIT_PHYS_ADDR + if (!cpu_has_64bit_gp_regs) { + /* no i_nop needed */ + i_ll(p, pte, sizeof(pte_t) / 2, ptr); + i_ori(p, pte, pte, _PAGE_VALID); + i_sc(p, pte, sizeof(pte_t) / 2, ptr); + il_beqz(p, r, pte, label_smp_pgtable_change); + /* no i_nop needed */ + i_lw(p, pte, 0, ptr); + } else + i_nop(p); + # else + i_nop(p); + # endif + #else + # ifdef CONFIG_64BIT_PHYS_ADDR + if (cpu_has_64bit_gp_regs) + i_sd(p, pte, offset, ptr); + else + # endif + i_SW(p, pte, offset, ptr); + + # ifdef CONFIG_64BIT_PHYS_ADDR + if (!cpu_has_64bit_gp_regs) { + i_lw(p, pte, sizeof(pte_t) / 2, ptr); + i_ori(p, pte, pte, _PAGE_VALID); + i_sw(p, pte, sizeof(pte_t) / 2, ptr); + i_lw(p, pte, 0, ptr); + } + # endif + #endif + } + + /* + * Check if PTE is present, if not then jump to LABEL. PTR points to + * the page table where this PTE is located, PTE will be re-loaded + * with it's original value. + */ + static void __init + build_pte_present(u32 **p, struct label **l, struct reloc **r, + unsigned int pte, unsigned int ptr, enum label_id lid) + { + i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); + i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_READ); + il_bnez(p, r, pte, lid); + iPTE_LW(p, l, pte, 0, ptr); + } + + /* Make PTE valid, store result in PTR. */ + static void __init + build_make_valid(u32 **p, struct reloc **r, unsigned int pte, + unsigned int ptr) + { + i_ori(p, pte, pte, _PAGE_VALID | _PAGE_ACCESSED); + iPTE_SW(p, r, pte, 0, ptr); + } + + /* + * Check if PTE can be written to, if not branch to LABEL. Regardless + * restore PTE with value from PTR when done. + */ + static void __init + build_pte_writable(u32 **p, struct label **l, struct reloc **r, + unsigned int pte, unsigned int ptr, enum label_id lid) + { + i_andi(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); + i_xori(p, pte, pte, _PAGE_PRESENT | _PAGE_WRITE); + il_bnez(p, r, pte, lid); + iPTE_LW(p, l, pte, 0, ptr); + } + + /* Make PTE writable, update software status bits as well, then store + * at PTR. + */ + static void __init + build_make_write(u32 **p, struct reloc **r, unsigned int pte, + unsigned int ptr) + { + i_ori(p, pte, pte, + _PAGE_ACCESSED | _PAGE_MODIFIED | _PAGE_VALID | _PAGE_DIRTY); + iPTE_SW(p, r, pte, 0, ptr); + } + + /* + * Check if PTE can be modified, if not branch to LABEL. Regardless + * restore PTE with value from PTR when done. + */ + static void __init + build_pte_modifiable(u32 **p, struct label **l, struct reloc **r, + unsigned int pte, unsigned int ptr, enum label_id lid) + { + i_andi(p, pte, pte, _PAGE_WRITE); + il_beqz(p, r, pte, lid); + iPTE_LW(p, l, pte, 0, ptr); + } + + /* + * R3000 style TLB load/store/modify handlers. + */ + + /* This places the pte in the page table at PTR into ENTRYLO0. */ + static void __init + build_r3000_pte_reload(u32 **p, unsigned int ptr) + { + i_lw(p, ptr, 0, ptr); + i_nop(p); /* load delay */ + i_mtc0(p, ptr, C0_ENTRYLO0); + i_nop(p); /* cp0 delay */ + } + + /* + * The index register may have the probe fail bit set, + * because we would trap on access kseg2, i.e. without refill. + */ + static void __init + build_r3000_tlb_write(u32 **p, struct label **l, struct reloc **r, + unsigned int tmp) + { + i_mfc0(p, tmp, C0_INDEX); + i_nop(p); /* cp0 delay */ + il_bltz(p, r, tmp, label_r3000_write_probe_fail); + i_nop(p); /* branch delay */ + i_tlbwi(p); + il_b(p, r, label_r3000_write_probe_ok); + i_nop(p); /* branch delay */ + l_r3000_write_probe_fail(l, *p); + i_tlbwr(p); + l_r3000_write_probe_ok(l, *p); + } + + static void __init + build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte, + unsigned int ptr) + { + long pgdc = (long)pgd_current; + + i_mfc0(p, pte, C0_BADVADDR); + i_lui(p, ptr, rel_hi(pgdc)); /* cp0 delay */ + i_lw(p, ptr, rel_lo(pgdc), ptr); + i_srl(p, pte, pte, 22); /* load delay */ + i_sll(p, pte, pte, 2); + i_addu(p, ptr, ptr, pte); + i_mfc0(p, pte, C0_CONTEXT); + i_lw(p, ptr, 0, ptr); /* cp0 delay */ + i_andi(p, pte, pte, 0xffc); /* load delay */ + i_addu(p, ptr, ptr, pte); + i_lw(p, pte, 0, ptr); + i_nop(p); /* load delay */ + i_tlbp(p); + } + + static void __init + build_r3000_tlbchange_handler_tail(u32 **p, unsigned int tmp) + { + i_mfc0(p, tmp, C0_EPC); + i_nop(p); /* cp0 delay */ + i_jr(p, tmp); + i_rfe(p); /* branch delay */ + } + + static void __init build_r3000_tlb_load_handler(void) + { + u32 *p = handle_tlbl; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbl, 0, sizeof(handle_tlbl)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r3000_tlbchange_handler_head(&p, K0, K1); + build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl); + build_make_valid(&p, &r, K0, K1); + build_r3000_pte_reload(&p, K1); + build_r3000_tlb_write(&p, &l, &r, K0); + build_r3000_tlbchange_handler_tail(&p, K0); + + l_nopage_tlbl(&l, p); + #ifdef CONFIG_XIP_KERNEL + i_lui(&p, K1, rel_hi((unsigned long)tlb_do_page_fault_0)); + i_addiu(&p,K1,K1,rel_lo((unsigned long)tlb_do_page_fault_0)); + i_jr(&p,K1); + #else + i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); + #endif + i_nop(&p); + + if ((p - handle_tlbl) > FASTPATH_SIZE) + panic("TLB load handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB load handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbl)); + + #ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbl[i]); + } + #endif + + flush_icache_range((unsigned long)handle_tlbl, + (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32)); + } + + static void __init build_r3000_tlb_store_handler(void) + { + u32 *p = handle_tlbs; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbs, 0, sizeof(handle_tlbs)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r3000_tlbchange_handler_head(&p, K0, K1); + build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs); + build_make_write(&p, &r, K0, K1); + build_r3000_pte_reload(&p, K1); + build_r3000_tlb_write(&p, &l, &r, K0); + build_r3000_tlbchange_handler_tail(&p, K0); + + l_nopage_tlbs(&l, p); + #ifdef CONFIG_XIP_KERNEL + i_lui(&p, K1, rel_hi((unsigned long)tlb_do_page_fault_1)); + i_addiu(&p,K1,K1,rel_lo((unsigned long)tlb_do_page_fault_1)); + i_jr(&p,K1); + #else + i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); + #endif + i_nop(&p); + + if ((p - handle_tlbs) > FASTPATH_SIZE) + panic("TLB store handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB store handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbs)); + + #ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbs[i]); + } + #endif + + flush_icache_range((unsigned long)handle_tlbs, + (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32)); + } + + static void __init build_r3000_tlb_modify_handler(void) + { + u32 *p = handle_tlbm; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbm, 0, sizeof(handle_tlbm)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r3000_tlbchange_handler_head(&p, K0, K1); + build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm); + build_make_write(&p, &r, K0, K1); + build_r3000_pte_reload(&p, K1); + i_tlbwi(&p); + build_r3000_tlbchange_handler_tail(&p, K0); + + l_nopage_tlbm(&l, p); + #ifdef CONFIG_XIP_KERNEL + i_lui(&p, K1, rel_hi((unsigned long)tlb_do_page_fault_1)); + i_addiu(&p,K1,K1,rel_lo((unsigned long)tlb_do_page_fault_1)); + i_jr(&p,K1); + #else + i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); + #endif + i_nop(&p); + + if ((p - handle_tlbm) > FASTPATH_SIZE) + panic("TLB modify handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB modify handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbm)); + + #ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbm[i]); + } + #endif + + flush_icache_range((unsigned long)handle_tlbm, + (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32)); + } + + /* + * R4000 style TLB load/store/modify handlers. + */ + static void __init + build_r4000_tlbchange_handler_head(u32 **p, struct label **l, + struct reloc **r, unsigned int pte, + unsigned int ptr) + { + #ifdef CONFIG_MIPS64 + build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */ + #else + build_get_pgde32(p, pte, ptr); /* get pgd in ptr */ + #endif + + i_MFC0(p, pte, C0_BADVADDR); + i_LW(p, ptr, 0, ptr); + i_SRL(p, pte, pte, PAGE_SHIFT + PTE_ORDER - PTE_T_LOG2); + i_andi(p, pte, pte, (PTRS_PER_PTE - 1) << PTE_T_LOG2); + i_ADDU(p, ptr, ptr, pte); + + #ifdef CONFIG_SMP + l_smp_pgtable_change(l, *p); + # endif + iPTE_LW(p, l, pte, 0, ptr); /* get even pte */ + build_tlb_probe_entry(p); + } + + static void __init + build_r4000_tlbchange_handler_tail(u32 **p, struct label **l, + struct reloc **r, unsigned int tmp, + unsigned int ptr) + { + i_ori(p, ptr, ptr, sizeof(pte_t)); + i_xori(p, ptr, ptr, sizeof(pte_t)); + build_update_entries(p, tmp, ptr); + build_tlb_write_entry(p, l, r, tlb_indexed); + l_leave(l, *p); + i_eret(p); /* return from trap */ + + #ifdef CONFIG_MIPS64 + build_get_pgd_vmalloc64(p, l, r, tmp, ptr); + #endif + } + + static void __init build_r4000_tlb_load_handler(void) + { + u32 *p = handle_tlbl; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbl, 0, sizeof(handle_tlbl)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + if (bcm1250_m3_war()) { + i_MFC0(&p, K0, C0_BADVADDR); + i_MFC0(&p, K1, C0_ENTRYHI); + i_xor(&p, K0, K0, K1); + i_SRL(&p, K0, K0, PAGE_SHIFT + 1); + il_bnez(&p, &r, K0, label_leave); + /* No need for i_nop */ + } + + build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); + build_pte_present(&p, &l, &r, K0, K1, label_nopage_tlbl); + build_make_valid(&p, &r, K0, K1); + build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + + l_nopage_tlbl(&l, p); + #ifdef CONFIG_XIP_KERNEL + i_lui(&p, K1, rel_hi((unsigned long)tlb_do_page_fault_0)); + i_addiu(&p,K1,K1,rel_lo((unsigned long)tlb_do_page_fault_0)); + i_jr(&p,K1); + #else + i_j(&p, (unsigned long)tlb_do_page_fault_0 & 0x0fffffff); + #endif + i_nop(&p); + + if ((p - handle_tlbl) > FASTPATH_SIZE) + panic("TLB load handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB load handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbl)); + + #ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbl[i]); + } + #endif + + flush_icache_range((unsigned long)handle_tlbl, + (unsigned long)handle_tlbl + FASTPATH_SIZE * sizeof(u32)); + } + + static void __init build_r4000_tlb_store_handler(void) + { + u32 *p = handle_tlbs; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbs, 0, sizeof(handle_tlbs)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); + build_pte_writable(&p, &l, &r, K0, K1, label_nopage_tlbs); + build_make_write(&p, &r, K0, K1); + build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + + l_nopage_tlbs(&l, p); + #ifdef CONFIG_XIP_KERNEL + i_lui(&p, K1, rel_hi((unsigned long)tlb_do_page_fault_1)); + i_addiu(&p,K1,K1,rel_lo((unsigned long)tlb_do_page_fault_1)); + i_jr(&p,K1); + #else + i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); + #endif + i_nop(&p); + + if ((p - handle_tlbs) > FASTPATH_SIZE) + panic("TLB store handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB store handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbs)); + + #ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbs[i]); + } + #endif + + flush_icache_range((unsigned long)handle_tlbs, + (unsigned long)handle_tlbs + FASTPATH_SIZE * sizeof(u32)); + } + + static void __init build_r4000_tlb_modify_handler(void) + { + u32 *p = handle_tlbm; + struct label *l = labels; + struct reloc *r = relocs; + + memset(handle_tlbm, 0, sizeof(handle_tlbm)); + memset(labels, 0, sizeof(labels)); + memset(relocs, 0, sizeof(relocs)); + + build_r4000_tlbchange_handler_head(&p, &l, &r, K0, K1); + build_pte_modifiable(&p, &l, &r, K0, K1, label_nopage_tlbm); + /* Present and writable bits set, set accessed and dirty bits. */ + build_make_write(&p, &r, K0, K1); + build_r4000_tlbchange_handler_tail(&p, &l, &r, K0, K1); + + l_nopage_tlbm(&l, p); + #ifdef CONFIG_XIP_KERNEL + i_lui(&p, K1, rel_hi((unsigned long)tlb_do_page_fault_1)); + i_addiu(&p,K1,K1,rel_lo((unsigned long)tlb_do_page_fault_1)); + i_jr(&p,K1); + #else + i_j(&p, (unsigned long)tlb_do_page_fault_1 & 0x0fffffff); + #endif + i_nop(&p); + + if ((p - handle_tlbm) > FASTPATH_SIZE) + panic("TLB modify handler fastpath space exceeded"); + + resolve_relocs(relocs, labels); + printk("Synthesized TLB modify handler fastpath (%u instructions).\n", + (unsigned int)(p - handle_tlbm)); + + #ifdef DEBUG_TLB + { + int i; + + for (i = 0; i < FASTPATH_SIZE; i++) + printk("%08x\n", handle_tlbm[i]); + } + #endif + + flush_icache_range((unsigned long)handle_tlbm, + (unsigned long)handle_tlbm + FASTPATH_SIZE * sizeof(u32)); + } + void __init build_tlb_refill_handler(void) { + /* + * The refill handler is generated per-CPU, multi-node systems + * may have local storage for it. The other handlers are only + * needed once. + */ + static int run_once = 0; + switch (current_cpu_data.cputype) { case CPU_R2000: case CPU_R3000: case CPU_R3000A: *************** *** 1159,1171 **** case CPU_TX3922: case CPU_TX3927: build_r3000_tlb_refill_handler(); break; case CPU_R6000: case CPU_R6000A: panic("No R6000 TLB refill handler yet"); break; - #endif case CPU_R8000: panic("No R8000 TLB refill handler yet"); --- 1824,1841 ---- case CPU_TX3922: case CPU_TX3927: build_r3000_tlb_refill_handler(); + if (!run_once) { + build_r3000_tlb_load_handler(); + build_r3000_tlb_store_handler(); + build_r3000_tlb_modify_handler(); + run_once++; + } break; case CPU_R6000: case CPU_R6000A: panic("No R6000 TLB refill handler yet"); break; case CPU_R8000: panic("No R8000 TLB refill handler yet"); *************** *** 1173,1177 **** --- 1843,1853 ---- default: build_r4000_tlb_refill_handler(); + if (!run_once) { + build_r4000_tlb_load_handler(); + build_r4000_tlb_store_handler(); + build_r4000_tlb_modify_handler(); + run_once++; + } } } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/mips/pci/pci.c linux-current/arch/mips/pci/pci.c *** linux-2.6.10/arch/mips/pci/pci.c Sat Dec 25 06:35:00 2004 --- linux-current/arch/mips/pci/pci.c Wed Jun 14 21:12:58 2006 *************** *** 59,65 **** if (res->flags & IORESOURCE_IO) { /* Make sure we start at our min on all hoses */ ! if (start - hose->io_resource->start < PCIBIOS_MIN_IO) start = PCIBIOS_MIN_IO + hose->io_resource->start; /* --- 59,65 ---- if (res->flags & IORESOURCE_IO) { /* Make sure we start at our min on all hoses */ ! if (start < PCIBIOS_MIN_IO + hose->io_resource->start) start = PCIBIOS_MIN_IO + hose->io_resource->start; /* *************** *** 69,75 **** start = (start + 0x3ff) & ~0x3ff; } else if (res->flags & IORESOURCE_MEM) { /* Make sure we start at our min on all hoses */ ! if (start - hose->mem_resource->start < PCIBIOS_MIN_MEM) start = PCIBIOS_MIN_MEM + hose->mem_resource->start; } --- 69,75 ---- start = (start + 0x3ff) & ~0x3ff; } else if (res->flags & IORESOURCE_MEM) { /* Make sure we start at our min on all hoses */ ! if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start) start = PCIBIOS_MIN_MEM + hose->mem_resource->start; } *************** *** 294,302 **** --- 294,306 ---- #ifdef CONFIG_HOTPLUG EXPORT_SYMBOL(pcibios_resource_to_bus); + EXPORT_SYMBOL(PCIBIOS_MIN_IO); + EXPORT_SYMBOL(PCIBIOS_MIN_MEM); #endif + #ifndef CONFIG_TX_BOARDS char *pcibios_setup(char *str) { return str; } + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/s390/kernel/entry.S linux-current/arch/s390/kernel/entry.S *** linux-2.6.10/arch/s390/kernel/entry.S Sat Dec 25 06:34:02 2004 --- linux-current/arch/s390/kernel/entry.S Wed Jun 14 21:12:58 2006 *************** *** 7,12 **** --- 7,13 ---- * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), * Hartmut Penner (hp@de.ibm.com), * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), + * Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM Corporation */ #include *************** *** 182,187 **** --- 183,195 ---- # ATTENTION: check sys_execve_glue before # changing anything here !! + #if (CONFIG_LTT) /* tjh - ltt port */ + /* add call to trace_real_syscall_exit */ + la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter + l %r1,BASED(.Ltracesysext) + basr %r14,%r1 + lm %r0,%r6,SP_R0(%r15) /* restore call clobbered regs */ + #endif sysc_return: tm SP_PSW+1(%r15),0x01 # returning to user ? bno BASED(sysc_leave) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/s390/kernel/sys_s390.c linux-current/arch/s390/kernel/sys_s390.c *** linux-2.6.10/arch/s390/kernel/sys_s390.c Sat Dec 25 06:34:31 2004 --- linux-current/arch/s390/kernel/sys_s390.c Wed Jun 14 21:12:58 2006 *************** *** 151,156 **** --- 151,158 ---- struct ipc_kludge tmp; int ret; + ltt_ev_ipc(LTT_EV_IPC_CALL, call, first); + switch (call) { case SEMOP: return sys_semtimedop (first, (struct sembuf __user *) ptr, second, diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/s390/kernel/traps.c linux-current/arch/s390/kernel/traps.c *** linux-2.6.10/arch/s390/kernel/traps.c Sat Dec 25 06:34:30 2004 --- linux-current/arch/s390/kernel/traps.c Wed Jun 14 21:12:58 2006 *************** *** 5,10 **** --- 5,11 ---- * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), + * Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM Corporation * * Derived from "arch/i386/kernel/traps.c" * Copyright (C) 1991, 1992 Linus Torvalds *************** *** 29,34 **** --- 30,36 ---- #include #include #include + #include #include #include *************** *** 311,316 **** --- 313,321 ---- static void inline do_trap(long interruption_code, int signr, char *str, struct pt_regs *regs, siginfo_t *info) { + trapid_t ltt_interruption_code; + char * ic_ptr = (char *) <t_interruption_code; + /* * We got all needed information from the lowcore and can * now safely switch on interrupts. *************** *** 318,323 **** --- 323,332 ---- if (regs->psw.mask & PSW_MASK_PSTATE) local_irq_enable(); + memset(<t_interruption_code,0,sizeof(ltt_interruption_code)); + memcpy(ic_ptr+4,&interruption_code,sizeof(interruption_code)); + ltt_ev_trap_entry(ltt_interruption_code, (regs->psw.addr & PSW_ADDR_INSN)); + if (regs->psw.mask & PSW_MASK_PSTATE) { struct task_struct *tsk = current; *************** *** 332,337 **** --- 341,347 ---- else die(str, regs, interruption_code); } + ltt_ev_trap_exit(); } static inline void *get_check_address(struct pt_regs *regs) *************** *** 428,433 **** --- 438,445 ---- siginfo_t info; __u8 opcode[6]; __u16 *location; + trapid_t ltt_interruption_code; + char * ic_ptr = (char *) <t_interruption_code; int signal = 0; location = (__u16 *) get_check_address(regs); *************** *** 490,495 **** --- 502,508 ---- do_trap(interruption_code, signal, "illegal operation", regs, &info); } + ltt_ev_trap_exit(); } *************** *** 499,504 **** --- 512,519 ---- { __u8 opcode[6]; __u16 *location = NULL; + trapid_t ltt_interruption_code; + char * ic_ptr = (char *) <t_interruption_code; int signal = 0; location = (__u16 *) get_check_address(regs); *************** *** 554,559 **** --- 569,575 ---- do_trap(interruption_code, signal, "specification exception", regs, &info); } + ltt_ev_trap_exit(); } #else DO_ERROR_INFO(SIGILL, "specification exception", specification_exception, *************** *** 563,568 **** --- 579,586 ---- asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) { __u16 *location; + trapid_t ltt_interruption_code; + char * ic_ptr = (char *) <t_interruption_code; int signal = 0; location = (__u16 *) get_check_address(regs); *************** *** 574,579 **** --- 592,601 ---- if (regs->psw.mask & PSW_MASK_PSTATE) local_irq_enable(); + memset(<t_interruption_code,0,sizeof(ltt_interruption_code)); + memcpy(ic_ptr+4,&interruption_code,sizeof(interruption_code)); + ltt_ev_trap_entry(ltt_interruption_code, (regs->psw.addr & PSW_ADDR_INSN)); + if (MACHINE_HAS_IEEE) __asm__ volatile ("stfpc %0\n\t" : "=m" (current->thread.fp_regs.fpc)); *************** *** 649,654 **** --- 671,677 ---- do_trap(interruption_code, signal, "data exception", regs, &info); } + ltt_ev_trap_exit(); } asmlinkage void space_switch_exception(struct pt_regs * regs, long int_code) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/s390/mm/fault.c linux-current/arch/s390/mm/fault.c *** linux-2.6.10/arch/s390/mm/fault.c Sat Dec 25 06:36:00 2004 --- linux-current/arch/s390/mm/fault.c Wed Jun 14 21:12:58 2006 *************** *** 5,10 **** --- 5,11 ---- * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Hartmut Penner (hp@de.ibm.com) * Ulrich Weigand (uweigand@de.ibm.com) + * Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM Corporation * * Derived from "arch/i386/mm/fault.c" * Copyright (C) 1995 Linus Torvalds *************** *** 169,174 **** --- 170,177 ---- int user_address; const struct exception_table_entry *fixup; int si_code = SEGV_MAPERR; + trapid_t ltt_interruption_code; + char * ic_ptr = (char *) <t_interruption_code; tsk = current; mm = tsk->mm; *************** *** 216,221 **** --- 219,227 ---- */ local_irq_enable(); + memset(<t_interruption_code,0,sizeof(ltt_interruption_code)); + memcpy(ic_ptr+4,&error_code,sizeof(error_code)); + ltt_ev_trap_entry(ltt_interruption_code,(regs->psw.addr & PSW_ADDR_INSN)); down_read(&mm->mmap_sem); vma = find_vma(mm, address); *************** *** 283,288 **** --- 289,295 ---- tsk->thread.prot_addr = address; tsk->thread.trap_no = error_code; do_sigsegv(regs, error_code, si_code, address); + ltt_ev_trap_exit(); return; } *************** *** 338,343 **** --- 345,352 ---- /* Kernel mode? Handle exceptions or die */ if (!(regs->psw.mask & PSW_MASK_PSTATE)) goto no_context; + + ltt_ev_trap_exit(); } void do_protection_exception(struct pt_regs *regs, unsigned long error_code) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/sh/kernel/irq.c linux-current/arch/sh/kernel/irq.c *** linux-2.6.10/arch/sh/kernel/irq.c Sat Dec 25 06:34:31 2004 --- linux-current/arch/sh/kernel/irq.c Wed Jun 14 21:12:58 2006 *************** *** 32,37 **** --- 32,38 ---- #include #include #include + #include #include #include diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/sh/kernel/process.c linux-current/arch/sh/kernel/process.c *** linux-2.6.10/arch/sh/kernel/process.c Sat Dec 25 06:35:23 2004 --- linux-current/arch/sh/kernel/process.c Wed Jun 14 21:12:58 2006 *************** *** 20,25 **** --- 20,26 ---- #include #include #include + #include #include #include diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/sh/kernel/sys_sh.c linux-current/arch/sh/kernel/sys_sh.c *** linux-2.6.10/arch/sh/kernel/sys_sh.c Sat Dec 25 06:35:50 2004 --- linux-current/arch/sh/kernel/sys_sh.c Wed Jun 14 21:12:58 2006 *************** *** 21,26 **** --- 21,27 ---- #include #include #include + #include #include #include *************** *** 166,171 **** --- 167,174 ---- version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; + ltt_ev_ipc(LTT_EV_IPC_CALL, call, first); + if (call <= SEMCTL) switch (call) { case SEMOP: diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/sh/kernel/traps.c linux-current/arch/sh/kernel/traps.c *** linux-2.6.10/arch/sh/kernel/traps.c Sat Dec 25 06:35:50 2004 --- linux-current/arch/sh/kernel/traps.c Wed Jun 14 21:12:58 2006 *************** *** 27,32 **** --- 27,33 ---- #include #include #include + #include #include #include *************** *** 500,505 **** --- 501,508 ---- asm volatile("stc r2_bank,%0": "=r" (error_code)); + ltt_ev_trap_entry(error_code >> 5, regs->pc); + oldfs = get_fs(); if (user_mode(regs)) { *************** *** 523,530 **** tmp = handle_unaligned_access(instruction, regs); set_fs(oldfs); ! if (tmp==0) ! return; /* sorted */ uspace_segv: printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm); --- 526,535 ---- tmp = handle_unaligned_access(instruction, regs); set_fs(oldfs); ! if (tmp==0) { ! ltt_ev_trap_exit(); ! return; /* sorted */ ! } uspace_segv: printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm); *************** *** 545,550 **** --- 550,556 ---- handle_unaligned_access(instruction, regs); set_fs(oldfs); } + ltt_ev_trap_exit(); } #ifdef CONFIG_SH_DSP *************** *** 704,709 **** --- 710,783 ---- { show_stack(NULL, sp); } + /* Trace related code */ + #if (CONFIG_LTT) + asmlinkage void trace_real_syscall_entry(struct pt_regs *regs) + { + int use_depth; + int use_bounds; + int depth = 0; + int seek_depth; + unsigned long lower_bound; + unsigned long upper_bound; + unsigned long addr; + unsigned long *stack; + ltt_syscall_entry trace_syscall_event; + + /* Set the syscall ID */ + trace_syscall_event.syscall_id = (uint8_t) regs->regs[REG_REG0 + 3]; + + /* Set the address in any case */ + trace_syscall_event.address = regs->pc; + + /* Are we in the kernel (This is a kernel thread)? */ + if (!user_mode(regs)) + /* Don't go digining anywhere */ + goto trace_syscall_end; + + /* Get the trace configuration */ + if (ltt_get_trace_config(&use_depth, &use_bounds, &seek_depth, + (void *) &lower_bound, (void *) &upper_bound) < 0) + goto trace_syscall_end; + + /* Do we have to search for an eip address range */ + if ((use_depth == 1) || (use_bounds == 1)) { + /* Start at the top of the stack (bottom address since stacks grow downward) */ + stack = (unsigned long *) regs->regs[REG_REG15]; + + /* Keep on going until we reach the end of the process' stack limit (wherever it may be) */ + while (!get_user(addr, stack)) { + /* Does this LOOK LIKE an address in the program */ + /* TODO: does this work with shared libraries?? - Greg Banks */ + if ((addr > current->mm->start_code) && (addr < current->mm->end_code)) { + /* Does this address fit the description */ + if (((use_depth == 1) && (depth == seek_depth)) + || ((use_bounds == 1) && (addr > lower_bound) + && (addr < upper_bound))) { + /* Set the address */ + trace_syscall_event.address = addr; + + /* We're done */ + goto trace_syscall_end; + } else + /* We're one depth more */ + depth++; + } + /* Go on to the next address */ + stack++; + } + } + trace_syscall_end: + /* Trace the event */ + ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event); + } + + asmlinkage void trace_real_syscall_exit(void) + { + ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL); + } + + #endif /* (CONFIG_LTT) */ void dump_stack(void) { diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/arch/sh/mm/fault.c linux-current/arch/sh/mm/fault.c *** linux-2.6.10/arch/sh/mm/fault.c Sat Dec 25 06:34:29 2004 --- linux-current/arch/sh/mm/fault.c Wed Jun 14 21:12:58 2006 *************** *** 21,26 **** --- 21,27 ---- #include #include #include + #include #include #include *************** *** 53,58 **** --- 54,67 ---- tsk = current; mm = tsk->mm; + #if (CONFIG_LTT) + { + unsigned long trapnr; + asm volatile("stc r2_bank,%0": "=r" (trapnr)); + ltt_ev_trap_entry(trapnr >> 5, regs->pc); /* trap 4,5 or 6 */ + } + #endif + /* * If we're in an interrupt or have no user * context, we must not take the fault.. *************** *** 106,111 **** --- 115,121 ---- } up_read(&mm->mmap_sem); + ltt_ev_trap_exit(); return; /* *************** *** 119,124 **** --- 129,135 ---- tsk->thread.address = address; tsk->thread.error_code = writeaccess; force_sig(SIGSEGV, tsk); + ltt_ev_trap_exit(); return; } *************** *** 185,190 **** --- 196,203 ---- /* Kernel mode? Handle exceptions or die */ if (!user_mode(regs)) goto no_context; + + ltt_ev_trap_exit(); } /* diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/base/platform.c linux-current/drivers/base/platform.c *** linux-2.6.10/drivers/base/platform.c Sat Dec 25 06:34:00 2004 --- linux-current/drivers/base/platform.c Wed Jun 14 21:12:58 2006 *************** *** 103,115 **** for (i = 0; i < pdev->num_resources; i++) { struct resource *p, *r = &pdev->resource[i]; ! r->name = pdev->dev.bus_id; ! p = NULL; ! if (r->flags & IORESOURCE_MEM) ! p = &iomem_resource; ! else if (r->flags & IORESOURCE_IO) ! p = &ioport_resource; if (p && request_resource(p, r)) { printk(KERN_ERR --- 103,118 ---- for (i = 0; i < pdev->num_resources; i++) { struct resource *p, *r = &pdev->resource[i]; ! if (r->name == NULL) ! r->name = pdev->dev.bus_id; ! p = r->parent; ! if (!p) { ! if (r->flags & IORESOURCE_MEM) ! p = &iomem_resource; ! else if (r->flags & IORESOURCE_IO) ! p = &ioport_resource; ! } if (p && request_resource(p, r)) { printk(KERN_ERR diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/char/mem.c linux-current/drivers/char/mem.c *** linux-2.6.10/drivers/char/mem.c Sat Dec 25 06:34:47 2004 --- linux-current/drivers/char/mem.c Wed Jun 14 21:12:58 2006 *************** *** 91,98 **** --- 91,102 ---- */ if (file->f_flags & O_SYNC) return 1; + #ifdef CONFIG_MMAP_NOHIMEMCHECK + return 0; + #else return addr >= __pa(high_memory); #endif + #endif } #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/i2c/algos/Kconfig linux-current/drivers/i2c/algos/Kconfig *** linux-2.6.10/drivers/i2c/algos/Kconfig Sat Dec 25 06:36:01 2004 --- linux-current/drivers/i2c/algos/Kconfig Wed Jun 14 21:12:58 2006 *************** *** 53,57 **** tristate "MPC8xx CPM I2C interface" depends on 8xx && I2C ! endmenu --- 53,64 ---- tristate "MPC8xx CPM I2C interface" depends on 8xx && I2C ! config I2C_ALGOCHIP0S ! tristate "chip0s I2C interface" ! depends on TOSHIBA_CHIP0S && I2C ! ! config I2C_ALGOEMMA ! tristate "EMMA I2C interface" ! depends on ( EMMA2RH || EMMA ) && I2C + endmenu diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/i2c/algos/Makefile linux-current/drivers/i2c/algos/Makefile *** linux-2.6.10/drivers/i2c/algos/Makefile Sat Dec 25 06:35:23 2004 --- linux-current/drivers/i2c/algos/Makefile Wed Jun 14 21:12:58 2006 *************** *** 6,11 **** --- 6,13 ---- obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o obj-$(CONFIG_I2C_ALGOITE) += i2c-algo-ite.o + obj-$(CONFIG_I2C_ALGOCHIP0S) += i2c-algo-chip0s.o + obj-$(CONFIG_I2C_ALGOEMMA) += i2c-algo-emma.o ifeq ($(CONFIG_I2C_DEBUG_ALGO),y) EXTRA_CFLAGS += -DDEBUG diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/i2c/algos/i2c-algo-emma.c linux-current/drivers/i2c/algos/i2c-algo-emma.c *** linux-2.6.10/drivers/i2c/algos/i2c-algo-emma.c Thu Jan 1 09:00:00 1970 --- linux-current/drivers/i2c/algos/i2c-algo-emma.c Wed Jun 28 12:17:43 2006 *************** *** 0 **** --- 1,806 ---- + /* + ------------------------------------------------------------------------- + i2c-algo-emma.c i2c driver algorithms for NEC EMMA2HL I2C adapters + ------------------------------------------------------------------------- + + Copyright (C) TOSHIBA Corporation 2005 + + Modfy for Linux 2.6.10 + + ------------------------------------------------------------------------- + + Shinya Kuribayashi, NEC Electronics Corporation + shinya.kuribayashi@necel.com + Takamitsu Honda, NEC Electronics Corporation + takamitsu.honda@necel.com + + Copyright (C) NEC Electronics Corporation 2002, 2003, 2004, 2005 + + Changes made to support the I2C peripheral on the NEC EMMA2HL + + + ------------------------------------------------------------------------- + This file was highly leveraged from i2c-algo-pcf.c, which was created + by Simon G. Vogl and Hans Berglund: + + + Copyright (C) 1995-1997 Simon G. Vogl + 1998-2000 Hans Berglund + + With some changes from Kyösti Mälkki and + Frodo Looijaard ,and also from Martin Bailey + + + Partially rewriten by Oleg I. Vdovikin to handle multiple + messages, proper stop/repstart signaling during receive, + added detect code + + 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 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + #include + #else + #include "i2c-emma.h" + #endif + #include + + #if defined(CONFIG_EMMA) + #define CONFIG_I2C_EMMA_DO_NOT_USE_FIFO + #endif + #ifdef CONFIG_I2C_EMMA_EXIOCTL + #define CONFIG_I2C_EMMA_DO_NOT_WAIT_ACK + #endif + + /* ----- global defines ----------------------------------------------- */ + #define DEB(x) if (i2c_debug>=1) x + #define DEB2(x) if (i2c_debug>=2) x + #define DEB3(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 */ + #define DEF_TIMEOUT 5 + + /* module parameters: + */ + static int i2c_debug=0; + + /* --- setting states on the bus with the right timing: --------------- */ + + #define set_emma(adap, ctl, val) adap->setemma(adap->data, ctl, val) + #define get_emma(adap, ctl) adap->getemma(adap->data, ctl) + #define get_own(adap) adap->getown(adap->data) + #define get_clock(adap) adap->getclock(adap->data) + #ifdef CONFIG_I2C_EMMA_EXIOCTL + #define set_busy(adap,busy) adap->setbusy(adap->data,busy) + #define get_busy(adap) adap->getbusy(adap->data) + #endif + + /* --- other auxiliary functions -------------------------------------- */ + + static void i2c_start(struct i2c_algo_emma_data *adap) + { + DEBPROTO(printk("S ")); + set_emma(adap, I2C_EMMA_CNT, I2C_EMMA_START); + #ifdef CONFIG_I2C_EMMA_EXIOCTL + set_busy(adap,1); + #endif + } + + static void i2c_repstart(struct i2c_algo_emma_data *adap) + { + DEBPROTO(printk(" Sr ")); + set_emma(adap, I2C_EMMA_CNT, I2C_EMMA_REPSTART); + #ifdef CONFIG_I2C_EMMA_EXIOCTL + set_busy(adap,1); + #endif + } + + static void i2c_stop(struct i2c_algo_emma_data *adap) + { + DEBPROTO(printk("P\n")); + set_emma(adap, I2C_EMMA_CNT, I2C_EMMA_STOP); + #ifdef CONFIG_I2C_EMMA_EXIOCTL + set_busy(adap,0); + #endif + } + + #ifdef CONFIG_I2C_EMMA_EXIOCTL + static int i2c_check_busy(struct i2c_algo_emma_data *adap) + { + int busy = get_busy(adap); + DEBPROTO(printk("busy=%d\n",busy)); + return busy; + } + + static int i2c_set_clock(struct i2c_algo_emma_data *adap, int csel) + { + DEBPROTO(printk("set CSEL=0x%x\n",csel)); + set_emma(adap, I2C_EMMA_CSEL, csel); + return 0; + } + + static int i2c_get_clock(struct i2c_algo_emma_data *adap) + { + int csel = get_emma(adap, I2C_EMMA_CSEL); + DEBPROTO(printk("get CSEL=0x%x\n",csel)); + return csel; + } + #endif + + static inline void emma_sleep(unsigned long timeout) + { + schedule_timeout(timeout * HZ); + } + + #ifdef CONFIG_I2C_EMMA_DO_NOT_USE_FIFO + static int wait_for_pin(struct i2c_algo_emma_data *adap, int *status, int ack_check) + { + int timeout = DEF_TIMEOUT; + + #ifdef CONFIG_I2C_EMMA_DO_NOT_WAIT_ACK + ack_check = 0; + #endif + do { + adap->waitforpin(adap->data); + *status = get_emma(adap, I2C_EMMA_STA); + } while (--timeout && (!(*status & ACKD) && ack_check)); + + if (timeout <= 0) + return (-1); + else + return 0; + } + #else + static int wait_for_pin(struct i2c_algo_emma_data *adap, int *status) + { + int timeout = DEF_TIMEOUT; + + do { + adap->waitforpin(adap->data); + *status = get_emma(adap, I2C_EMMA_FSTA); + } while (--timeout && !(*status & WAIT)); + + *status = get_emma(adap, I2C_EMMA_STA); + + if (timeout <= 0) + return (-1); + else + return 0; + } + + static int wait_for_ff(struct i2c_algo_emma_data *adap, int *status) + { + int timeout = DEF_TIMEOUT; + + do { + adap->waitforpin(adap->data); + *status = get_emma(adap, I2C_EMMA_FSTA); + } while (--timeout && !(*status & (INTRXLV | FULL))); + + if (timeout <= 0) + printk(KERN_ERR "Timeout waiting for FIFO Filled\n"); + + return (timeout <= 0); + } + + static int wait_for_fe(struct i2c_algo_emma_data *adap, int *status) + { + int timeout = DEF_TIMEOUT; + + do { + adap->waitforpin(adap->data); + *status = get_emma(adap, I2C_EMMA_FSTA); + } while (--timeout && !(*status & EMPTY)); + + if (timeout <= 0) + printk(KERN_ERR "Timeout waiting for FIFO Empty\n"); + + return (timeout <= 0); + } + #endif + + static int emma_init(struct i2c_algo_emma_data *adap) + { + unsigned char temp; + + /* serial interface off */ + set_emma(adap, I2C_EMMA_CNT, 0); + + #ifndef CONFIG_I2C_EMMA_DO_NOT_USE_FIFO + /* reset FIFO */ + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + #endif + + #if CONFIG_SLAVE_MODE + /* load own address in SVA, effective address is (own & 0xfe) */ + set_emma(adap, I2C_EMMA_SVA, get_own(adap)); + udelay(20); + /* check it's realy written */ + if ((temp = get_emma(adap, I2C_EMMA_SVA)) != get_own(adap)) { + DEB2(printk(KERN_ERR "i2c-algo-emma.o: EMMA detection failed -- can't set I2C_EMMA_SVA (0x%02x).\n", temp)); + return -ENXIO; + } + #endif + /* load clock register CS */ + set_emma(adap, I2C_EMMA_CSEL, get_clock(adap)); + udelay(20); /* wait awhile */ + /* check it's realy written, the only 4 lowest bits does matter */ + if (((temp = get_emma(adap, I2C_EMMA_CSEL)) & 0xf) != get_clock(adap)) { + DEB2(printk(KERN_ERR "i2c-algo-emma.o: EMMA detection failed -- can't set I2C_EMMA_CSEL (0x%02x).\n", temp)); + return -ENXIO; + } + + /* initialize interrupt mask */ + set_emma(adap, I2C_EMMA_INT, 0); + set_emma(adap, I2C_EMMA_INTM, INT_USUAL); + + /* Enable serial interface */ + set_emma(adap, I2C_EMMA_CNT, IICE); + + /* generate a STOP condition, first of all */ + i2c_stop(adap); + + printk(KERN_DEBUG "i2c-algo-emma.o: deteted and initialized NEC EMMA I2C adapter.\n"); + + return 0; + } + + static int emma_exit(struct i2c_algo_emma_data *adap) + { + set_emma(adap, I2C_EMMA_INTM, 0); + } + + /* ----- Utility functions + */ + + static inline int try_address(struct i2c_algo_emma_data *adap, + unsigned char addr, int retries) + { + int i, status, ret = -1; + for (i = 0; i < retries; i++) { + i2c_start(adap); + set_emma(adap, I2C_EMMA_SHR, addr); + if (wait_for_pin(adap, &status, 0) >= 0) { + if (status & ACKD) { + i2c_stop(adap); + ret = 1; + break; /* success! */ + } + } + i2c_stop(adap); + udelay(adap->udelay); + } + DEB2(if (i) printk(KERN_DEBUG "i2c-algo-emma.o: needed %d retries for %d\n",i, + addr)); + return ret; + } + + #ifdef CONFIG_I2C_EMMA_DO_NOT_USE_FIFO + static int emma_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, + int count, int last) + { + struct i2c_algo_emma_data *adap = i2c_adap->algo_data; + int wrcount, status, timeout; + + set_emma(adap, I2C_EMMA_CNT, IICE | WTIM); + for (wrcount = 0; wrcount < count; wrcount++) { + set_emma(adap, I2C_EMMA_INT, 0); + set_emma(adap, I2C_EMMA_SHR, buf[wrcount] & SR); + timeout = wait_for_pin(adap, &status, 1); + if (timeout) { + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: %s i2c_write: " + "error - timeout.\n", i2c_adap->name); + return -EREMOTEIO; /* got a better one ?? */ + } + if (!(status & ACKD)) { + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: %s i2c_write: " + "error - no ack.\n", i2c_adap->name); + return -EREMOTEIO; /* got a better one ?? */ + } + } + + if (last) + i2c_stop(adap); + else + i2c_repstart(adap); + + return (wrcount); + } + + static int emma_readbytes(struct i2c_adapter *i2c_adap, char *buf, + int count, int last) + { + struct i2c_algo_emma_data *adap = i2c_adap->algo_data; + int rdcount, status, timeout; + + for (rdcount = 0; rdcount < count; rdcount++) { + + /* we will suffer from unexpected interrupts if we + * use 8-clock-wait. + */ + + set_emma(adap, I2C_EMMA_INT, 0); + if (rdcount == count - 1) + /* last byte */ + set_emma(adap, I2C_EMMA_CNT, IICE | WREL | WTIM); + else + set_emma(adap, I2C_EMMA_CNT, IICE | WREL | WTIM |ACKE); + + timeout = wait_for_pin(adap, &status, (rdcount != count - 1)); + if (timeout) { + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: emma_readbytes timed out.\n"); + return (-1); + } + if (!(status & ACKD) && (rdcount != count-1)) { + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: i2c_read: i2c_inb, No ack.\n"); + return (-1); + } + buf[rdcount] = get_emma(adap, I2C_EMMA_SHR); + } + + if (last) + i2c_stop(adap); + else + i2c_repstart(adap); + + return (rdcount); + } + + #else /* CONFIG_I2C_EMMA_DO_NOT_USE_FIFO */ + + static int emma_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, + int count, int last) + { + struct i2c_algo_emma_data *adap = i2c_adap->algo_data; + int wrcount, status, timeout; + int loops, remainder, i, j; + + wrcount = 0; + loops = count / 63; + remainder = count % 63; + + set_emma(adap, I2C_EMMA_CNT, IICE | WTIM); + + /* set mask for FIFO tx */ + set_emma(adap, I2C_EMMA_INTM, INT_TXTH | INT_EMPTY); + + if (loops) { + for (i = 0; i < loops; i++) { + /* why do we have to reset fifo before sending? */ + set_emma(adap, I2C_EMMA_FCNT, FRST); + + set_emma(adap, I2C_EMMA_FCNT, FORCE | FSTOP | FENA); + for (j = 0; j < 63; j++) + set_emma(adap, I2C_EMMA_FWDAT, buf[wrcount++]); + + set_emma(adap, I2C_EMMA_INT, 0); + set_emma(adap, I2C_EMMA_FCNT, FORCE | FENA); + + timeout = wait_for_fe(adap, &status); + if (timeout) { + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: %s i2c_write: " + "error - timeout.\n", i2c_adap->name); + return -EREMOTEIO; /* got a better one ?? */ + } + if (status & POOL) { + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: %s i2c_write: " + "error - no ack.\n", i2c_adap->name); + return -EREMOTEIO; /* got a better one ?? */ + } + + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + } + } + + if (remainder) { + /* why do we have to reset fifo before sending? */ + set_emma(adap, I2C_EMMA_FCNT, FRST); + + set_emma(adap, I2C_EMMA_FCNT, FORCE | FSTOP | FENA); + for (i = 0; i < remainder; i++) + set_emma(adap, I2C_EMMA_FWDAT, buf[wrcount++]); + + set_emma(adap, I2C_EMMA_INT, 0); + set_emma(adap, I2C_EMMA_FCNT, FORCE | FENA); + + timeout = wait_for_fe(adap, &status); + if (timeout) { + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: %s i2c_write: " + "error - timeout.\n", i2c_adap->name); + return -EREMOTEIO; /* got a better one ?? */ + } + if (status & POOL) { + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: %s i2c_write: " + "error - no ack.\n", i2c_adap->name); + return -EREMOTEIO; /* got a better one ?? */ + } + + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + } + + /* set back to usual */ + set_emma(adap, I2C_EMMA_INTM, INT_USUAL); + + if (last) + i2c_stop(adap); + else + i2c_repstart(adap); + + return (wrcount); + } + + static int emma_readbytes(struct i2c_adapter *i2c_adap, char *buf, + int count, int last) + { + struct i2c_algo_emma_data *adap = i2c_adap->algo_data; + int rdcount, status, timeout; + int i; + + rdcount = 0; + + while (count > 0) { + if (count > 2) { + int rx_count; + + if (count > 63) + rx_count = 63; + else + rx_count = count; + + rx_count -= 1; /* reserved for last byte */ + #if 0 + /* snipped on 2004-12-09, to be set later */ + set_emma(adap, I2C_EMMA_CNT, IICE | WTIM | ACKE); + #endif + set_emma(adap, I2C_EMMA_FTH, RX_STOP_EN | ((rx_count-1)&RXLV)); + + /* set mask for FIFO rx */ + set_emma(adap, I2C_EMMA_INT, 0); + set_emma(adap, I2C_EMMA_INTM, INT_RXTH | INT_FULL); + + /* FIXME - cancel wait */ + set_emma(adap, I2C_EMMA_CNT, IICE | WREL | WTIM | ACKE); + + set_emma(adap, I2C_EMMA_FCNT, FORCE | ACKSTOP | FENA); + + timeout = wait_for_ff(adap, &status); + if (timeout) { + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: emma_readbytes timed out.\n"); + return (-1); + } + for (i = 0; i < rx_count; i++) + buf[rdcount++] = get_emma(adap, I2C_EMMA_FRDAT)&0xff; + count -= rx_count; + + set_emma(adap, I2C_EMMA_FCNT, FRST); + set_emma(adap, I2C_EMMA_FCNT, 0); + + } else { + /* set back to usual */ + set_emma(adap, I2C_EMMA_INT, 0); + set_emma(adap, I2C_EMMA_INTM, INT_USUAL); + + if (--count) + set_emma(adap, I2C_EMMA_CNT, IICE | WREL | WTIM | ACKE); + else + set_emma(adap, I2C_EMMA_CNT, IICE | WREL | WTIM); + + timeout = wait_for_pin(adap, &status); + if (timeout) { + i2c_stop(adap); + printk(KERN_ERR "i2c-algo-emma.o: emma_readbytes timed out.\n"); + return (-1); + } + buf[rdcount++] = get_emma(adap, I2C_EMMA_SHR); + } + } + + /* set back to usual */ + set_emma(adap, I2C_EMMA_INTM, INT_USUAL); + + if (last) + i2c_stop(adap); + else + i2c_repstart(adap); + + return (rdcount); + } + + #endif /* CONFIG_I2C_EMMA_DO_NOT_USE_FIFO */ + + + static inline int emma_doAddress(struct i2c_algo_emma_data *adap, + struct i2c_msg *msg, int retries) + { + unsigned short flags = msg->flags; + unsigned int addr; + int ret; + + set_emma(adap, I2C_EMMA_INT, 0); + + if (flags & I2C_M_TEN) { + /* a ten bit address */ + addr = 0xf0 | ((msg->addr >> 7) & 0x03); + DEB2(printk(KERN_DEBUG "addr0: %d\n", addr)); + /* try extended address code...*/ + ret = try_address(adap, addr, retries); + if (ret != 1) { + printk(KERN_ERR "died at extended address code.\n"); + return -EREMOTEIO; + } + /* the remaining 8 bit address */ + /* ...TBD */ + printk("10 bit addresses are not supported in this driver.\n"); + return -EREMOTEIO; + } else { /* normal 7bit address */ + addr = (msg->addr << 1); + if (flags & I2C_M_RD) + addr |= 1; + if (flags & I2C_M_REV_DIR_ADDR) + addr ^= 1; + set_emma(adap, I2C_EMMA_SHR, addr); + } + return 0; + } + + static int emma_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], + int num) + { + struct i2c_algo_emma_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg; + int i; + int ret = 0, timeout, status; + + for (i = 0; ret >= 0 && i < num; i++) { + pmsg = &msgs[i]; + + DEB2(printk(KERN_DEBUG "i2c-algo-emma.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", + pmsg->flags & I2C_M_RD ? "read" : "write", + pmsg->len, pmsg->addr, i + 1, num);) + + /* Send START */ + if (i == 0) { + i2c_start(adap); + } + + ret = emma_doAddress(adap, pmsg, i2c_adap->retries); + + /* Wait for PIN (pending interrupt NOT) */ + timeout = wait_for_pin(adap, &status, pmsg->len); + if (timeout) { + i2c_stop(adap); + DEB2(printk(KERN_ERR "i2c-algo-emma.o: Timeout waiting " + "for PIN(1) in emma_xfer\n");) + return (-EREMOTEIO); + } + + /* Check LRB (last rcvd bit - slave ack) */ + if (!(status & ACKD)) { + i2c_stop(adap); + DEB2(printk(KERN_ERR "i2c-algo-emma.o: No LRB(1) in emma_xfer\n");) + return (-EREMOTEIO); + } + + DEB3(printk(KERN_DEBUG "i2c-algo-emma.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", + i, msgs[i].addr, msgs[i].flags, msgs[i].len);) + + /* Read */ + if (pmsg->flags & I2C_M_RD) { + /* read bytes into buffer*/ + ret = emma_readbytes(i2c_adap, pmsg->buf, pmsg->len, + (i + 1 == num)); + + if (ret < 0) { + return ret; + } else if (ret != pmsg->len) { + DEB2(printk(KERN_DEBUG "i2c-algo-emma.o: fail: " + "only read %d bytes.\n", ret)); + } else { + DEB2(printk(KERN_DEBUG "i2c-algo-emma.o: read %d bytes.\n", ret)); + } + } else { /* Write */ + ret = emma_sendbytes(i2c_adap, pmsg->buf, pmsg->len, + (i + 1 == num)); + + if (ret < 0) { + return ret; + } else if (ret != pmsg->len) { + DEB2(printk(KERN_DEBUG "i2c-algo-emma.o: fail: " + "only wrote %d bytes.\n", ret)); + } else { + DEB2(printk(KERN_DEBUG "i2c-algo-emma.o: wrote %d bytes.\n", ret)); + } + } + } + + return (i); + } + + static int algo_control(struct i2c_adapter *adapter, + unsigned int cmd, unsigned long arg) + { + #ifdef CONFIG_I2C_EMMA_EXIOCTL + struct i2c_algo_emma_data *adap = adapter->algo_data; + int clock, status; + switch (cmd) { + case I2C_EMMA_RESET: + i2c_start(adap); + i2c_stop(adap); + break; + + case I2C_EMMA_CHECK_BUSY: + if (arg == 0) + return -EINVAL; + status = i2c_check_busy(adap); + if (copy_to_user((int *) arg, &status, sizeof(int))) + return -EFAULT; + break; + + case I2C_EMMA_SET_CLOCK: + return i2c_set_clock(adap, arg); + + case I2C_EMMA_GET_CLOCK: + if (arg == 0) + return -EINVAL; + clock = i2c_get_clock(adap); + if (copy_to_user((int *) arg, &clock, sizeof(int))) + return -EFAULT; + break; + + default: + return -EINVAL; + } + #endif + return 0; + } + + static u32 emma_func(struct i2c_adapter *adap) + { + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | + I2C_FUNC_PROTOCOL_MANGLING; + } + + /* -----exported algorithm data: ------------------------------------- */ + + static struct i2c_algorithm emma_algo = { + "NEC EMMA I2C algorithm", + I2C_ALGO_EXP, + emma_xfer, + NULL, + NULL, /* slave_send */ + NULL, /* slave_recv */ + algo_control, /* ioctl */ + emma_func, /* functionality */ + }; + + /* + * registering functions to load algorithms at routine + */ + int i2c_emma_add_bus(struct i2c_adapter *adap) + { + int i; + struct i2c_algo_emma_data *emma_adap = adap->algo_data; + + DEB2(printk(KERN_DEBUG "i2c-algo-emma.o: hw routines for %s registered.\n", + adap->name)); + + /* register new adapter to i2c module... */ + + adap->id |= emma_algo.id; + adap->algo = &emma_algo; + + adap->timeout = 100; /* default values, should */ + adap->retries = 3; /* be replaced by defines */ + + if ((i = emma_init(emma_adap))) { + return i; + } + + #ifdef MODULE + MOD_INC_USE_COUNT; + #endif + + i2c_add_adapter(adap); + + return 0; + } + + int i2c_emma_del_bus(struct i2c_adapter *adap) + { + int res; + struct i2c_algo_emma_data *emma_adap = adap->algo_data; + + emma_exit(emma_adap); + + if ((res = i2c_del_adapter(adap)) < 0) + return res; + DEB2(printk(KERN_DEBUG "i2c-algo-emma.o: adapter unregistered: %s\n", adap->name)); + + #ifdef MODULE + MOD_DEC_USE_COUNT; + #endif + return 0; + } + + int __init i2c_algo_emma_init(void) + { + #ifdef CONFIG_EMMA + if ( mips_machgroup != MACH_GROUP_EMMA2RH ) return 0; + #endif + printk(KERN_INFO "i2c-algo-emma.o: NEC EMMA i2c algorithm module\n"); + return 0; + } + + void i2c_algo_emma_exit(void) + { + return; + } + + + EXPORT_SYMBOL(i2c_emma_add_bus); + EXPORT_SYMBOL(i2c_emma_del_bus); + + /* The MODULE_* macros resolve to nothing if MODULES is not defined + * when this file is compiled. + */ + MODULE_AUTHOR("NEC Electronics Corporation "); + MODULE_DESCRIPTION("NEC EMMA I2C-Bus algorithm"); + #ifdef MODULE_LICENSE + MODULE_LICENSE("GPL"); + #endif + + MODULE_PARM(i2c_debug,"i"); + MODULE_PARM_DESC(i2c_debug, + "debug level - 0 off; 1 normal; 2,3 more verbose; 9 i2c-protocol"); + + module_init(i2c_algo_emma_init); + module_exit(i2c_algo_emma_exit); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/i2c/busses/Kconfig linux-current/drivers/i2c/busses/Kconfig *** linux-2.6.10/drivers/i2c/busses/Kconfig Sat Dec 25 06:35:25 2004 --- linux-current/drivers/i2c/busses/Kconfig Wed Jun 28 10:50:11 2006 *************** *** 466,469 **** --- 466,491 ---- This driver can also be built as a module. If so, the module will be called i2c-pca-isa. + config I2C_CHIP0S + tristate "chip0s I2C controller" + depends on I2C && TOSHIBA_CHIP0S + select I2C_ALGOCHIP0S + + config I2C_CHIP1S + tristate "Chip1s I2C controller" + depends on I2C && TOSHIBA_CHIP1S + + config I2C_EMMA + tristate "EMMA I2C controller" + depends on ( EMMA2RH || EMMA ) && I2C + select I2C_ALGOEMMA + + config I2C_EMMA_EXIOCTL + bool "EMMA I2C extended ioctls" + depends on I2C_EMMA + + config I2C_EMMA3 + tristate "EMMA3 I2C controller" + depends on I2C && EMMA + endmenu diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/i2c/busses/Makefile linux-current/drivers/i2c/busses/Makefile *** linux-2.6.10/drivers/i2c/busses/Makefile Sat Dec 25 06:33:51 2004 --- linux-current/drivers/i2c/busses/Makefile Wed Jun 28 10:50:11 2006 *************** *** 38,43 **** --- 38,47 ---- obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o obj-$(CONFIG_SCx200_ACB) += scx200_acb.o obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o + obj-$(CONFIG_I2C_CHIP0S) += i2c-chip0s.o + obj-$(CONFIG_I2C_CHIP1S) += i2c-chip1s.o + obj-$(CONFIG_I2C_EMMA) += i2c-emma.o + obj-$(CONFIG_I2C_EMMA3) += i2c-emma3.o ifeq ($(CONFIG_I2C_DEBUG_BUS),y) EXTRA_CFLAGS += -DDEBUG diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/i2c/busses/i2c-emma.c linux-current/drivers/i2c/busses/i2c-emma.c *** linux-2.6.10/drivers/i2c/busses/i2c-emma.c Thu Jan 1 09:00:00 1970 --- linux-current/drivers/i2c/busses/i2c-emma.c Wed Jun 28 12:17:43 2006 *************** *** 0 **** --- 1,411 ---- + /* + ------------------------------------------------------------------------- + i2c-adap-emma.c i2c-hw access for the I2C peripheral on the NEC EMMA2HL + ------------------------------------------------------------------------- + + Copyright (C) TOSHIBA Corporation 2005 + + Modfy for Linux 2.6.10 + + ------------------------------------------------------------------------- + + Shinya Kuribayashi, NEC Electronics Corporation + shinya.kuribayashi@necel.com + Takamitsu Honda, NEC Electronics Corporation + takamitsu.honda@necel.com + + Copyright (C) NEC Electronics Corporation 2002, 2003, 2004, 2005 + + Changes made to support the I2C peripheral on the NEC EMMA2HL + + + ------------------------------------------------------------------------- + This file was highly leveraged from i2c-elektor.c, which was created + by Simon G. Vogl and Hans Berglund: + + + Copyright (C) 1995-97 Simon G. Vogl + 1998-99 Hans Berglund + + With some changes from Kyösti Mälkki and even + Frodo Looijaard + + Partialy rewriten by Oleg I. Vdovikin for mmapped support of + for Alpha Processor Inc. UP-2000(+) boards + + + 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 + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + #include + #include + #else + #include "i2c-emma.h" + #endif + #include + + struct i2c_emma { + int base; + int irq; + int clock; + int own; + int index; + #ifdef CONFIG_I2C_EMMA_EXIOCTL + int busy; + #endif + }; + + #if defined(CONFIG_EMMA2HL) + #include + + #define MAX_NUM_DEVS 3 + + struct i2c_emma adaps[MAX_NUM_DEVS] = { + {0xbb011000, EMMA2HL_IRQ_PIIC0, FAST375, 0x40, 0}, + {0xbb012000, EMMA2HL_IRQ_PIIC1, FAST375, 0x44, 1}, + {0xbb019000, EMMA2HL_IRQ_PIIC2, FAST375, 0x48, 2}, + }; + #elif defined(CONFIG_EMMA) + #include + + #ifdef CONFIG_I2C_EMMA_EXIOCTL + #define MAX_NUM_DEVS 1 + #else + #define MAX_NUM_DEVS 3 + #endif + + struct i2c_emma adaps[MAX_NUM_DEVS] = { + #ifdef CONFIG_I2C_EMMA_EXIOCTL + {EMMA2RH_PIIC2_BASE|0xa0000000, EMMA2RH_IRQ_PIIC2, FAST375, 0x48, 0}, + #else + {EMMA2RH_PIIC0_BASE|0xa0000000, EMMA2RH_IRQ_PIIC0, FAST375, 0x40, 0}, + {EMMA2RH_PIIC1_BASE|0xa0000000, EMMA2RH_IRQ_PIIC1, FAST375, 0x44, 1}, + {EMMA2RH_PIIC2_BASE|0xa0000000, EMMA2RH_IRQ_PIIC2, FAST375, 0x48, 2}, + #endif + }; + #else + #error unkown EMMA architecture + #endif + + #ifdef CONFIG_I2C_EMMA_EXIOCTL + static struct i2c_emma *i2c_emma_adaps[MAX_NUM_DEVS] = {&adaps[0]}; + #else + static struct i2c_emma *i2c_emma_adaps[MAX_NUM_DEVS] = {&adaps[0], &adaps[1], &adaps[2],}; + #endif + static struct i2c_algo_emma_data *emma_algo_data[MAX_NUM_DEVS]; + static struct i2c_adapter *emma_ops[MAX_NUM_DEVS]; + + static int i2c_debug=0; + static wait_queue_head_t emma_wait[MAX_NUM_DEVS]; + static volatile int emma_pending[MAX_NUM_DEVS];; + static spinlock_t emma_lock[MAX_NUM_DEVS]; + + /* ----- global defines ----------------------------------------------- */ + #define DEB(x) if (i2c_debug>=1) x + #define DEB2(x) if (i2c_debug>=2) x + #define DEB3(x) if (i2c_debug>=3) x + #define DEBE(x) x /* error messages */ + + /* ----- local functions ---------------------------------------------- */ + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + #define writel(v,a) *(volatile int*)(a)=(v) + #define readl(a) *(volatile int*)(a) + #endif + + static void emma_pci_setbyte(void *data, int ctl, int val) + { + int address = ((struct i2c_emma *)data)->base + ctl; + + DEB3(printk(KERN_DEBUG "emma_pci_setbyte: Write 0x%08x 0x%08x\n", address, val)); + writel(val, address); + } + + static int emma_pci_getbyte(void *data, int ctl) + { + int address = ((struct i2c_emma *)data)->base + ctl; + int val = readl(address); + + DEB3(printk(KERN_DEBUG "emma_pci_getbyte: Read 0x%08x 0x%08x\n", address, val)); + return (val); + } + + static int emma_pci_getown(void *data) + { + return (((struct i2c_emma *)data)->own); + } + + static int emma_pci_getclock(void *data) + { + return (((struct i2c_emma *)data)->clock); + } + + static void emma_pci_waitforpin(void *data) + { + int timeout = 2; + struct i2c_emma *adap = (struct i2c_emma *)data; + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + unsigned long flags; + #endif + + if (adap->irq > 0) { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + timeout = wait_event_timeout(emma_wait[adap->index], + emma_pending[adap->index], + timeout*HZ); + emma_pending[adap->index] = 0; + #else + spin_lock_irqsave(&emma_lock[adap->index], flags); + if (emma_pending[adap->index] == 0) { + interruptible_sleep_on_timeout(&emma_wait[adap->index], timeout*HZ); + } + emma_pending[adap->index] = 0; + spin_unlock_irqrestore(&emma_lock[adap->index], flags); + #endif + } else { + udelay(100); + } + } + + #ifdef CONFIG_I2C_EMMA_EXIOCTL + static void emma_pci_setbusy(void *data, int busy) + { + (((struct i2c_emma *)data)->busy) = busy; + } + static int emma_pci_getbusy(void *data) + { + return (((struct i2c_emma *)data)->busy); + } + #endif + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + static irqreturn_t emma_pci_handler(int this_irq, void *dev_id, struct pt_regs *regs) + #else + static void emma_pci_handler(int this_irq, void *dev_id, struct pt_regs *regs) + #endif + { + struct i2c_emma *adap = (struct i2c_emma *)dev_id; + + DEB2(printk("emma_pci_handler: status = 0x%08x\n", + readl(adap->base + I2C_EMMA_INT))); + /* clear interrupt */ + writel(0, adap->base + I2C_EMMA_INT); + + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + emma_pending[adap->index] = 1; + wake_up(&emma_wait[adap->index]); + return IRQ_HANDLED; + #else + spin_lock(&emma_lock[adap->index]); + emma_pending[adap->index] = 1; + spin_unlock(&emma_lock[adap->index]); + wake_up_interruptible(&emma_wait[adap->index]); + #endif + } + + static int emma_pci_init(int instance) + { + struct i2c_emma *adap = i2c_emma_adaps[instance]; + + if (adap->irq > 0) { + if (request_irq(adap->irq, emma_pci_handler, 0, + "EMMA I2C", adap) < 0) { + printk(KERN_ERR "emma_pci_init: Request irq%d failed\n",adap->irq); + adap->irq = 0; + } else { + DEB3(printk("emma_pci_init: Enabled interrupt\n")); + } + } + + return 0; + } + + static void emma_release(void) + { + int i; + + for (i = 0; i < MAX_NUM_DEVS; i++) { + struct i2c_emma *adap = (struct i2c_emma *)emma_algo_data[i]->data; + if (adap->irq > 0) { + disable_irq(adap->irq); + free_irq(adap->irq, adap); + } + kfree(emma_algo_data[i]); + kfree(emma_ops[i]); + } + } + + static int emma_pci_reg(struct i2c_client *client) + { + return 0; + } + + static int emma_pci_unreg(struct i2c_client *client) + { + return 0; + } + + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + static void emma_pci_inc_use(struct i2c_adapter *adap) + { + #ifdef MODULE + MOD_INC_USE_COUNT; + #endif + } + + static void emma_pci_dec_use(struct i2c_adapter *adap) + { + #ifdef MODULE + MOD_DEC_USE_COUNT; + #endif + } + #endif + + /* ------------------------------------------------------------------------ + * Encapsulate the above functions in the correct operations structure. + * This is only done when more than one hardware adapter is supported. + */ + #if 0 + static struct i2c_algo_pcf_data pcf_isa_data = { + NULL, + pcf_isa_setbyte, + pcf_isa_getbyte, + pcf_isa_getown, + pcf_isa_getclock, + pcf_isa_waitforpin, + 10, 10, 100, /* waits, timeout */ + }; + + static struct i2c_adapter pcf_isa_ops = { + "PCF8584 ISA adapter", + I2C_HW_P_ELEK, + NULL, + &pcf_isa_data, + pcf_isa_inc_use, + pcf_isa_dec_use, + pcf_isa_reg, + pcf_isa_unreg, + }; + #endif + + static int __init i2c_emmapci_init(void) + { + int i; + + #ifdef CONFIG_EMMA + if ( mips_machgroup != MACH_GROUP_EMMA2RH ) return 0; + #endif + + printk(KERN_INFO "i2c_emmapci_init: EMMA I2C adapter module\n"); + + for (i = 0; i < MAX_NUM_DEVS; i++) { + emma_algo_data[i] = kmalloc(sizeof(struct i2c_algo_emma_data), GFP_KERNEL); + if(emma_algo_data[i] == NULL) { + return -ENOMEM; + } + memset(emma_algo_data[i], 0, sizeof(struct i2c_algo_emma_data)); + emma_algo_data[i]->data = i2c_emma_adaps[i]; + emma_algo_data[i]->setemma = emma_pci_setbyte; + emma_algo_data[i]->getemma = emma_pci_getbyte; + emma_algo_data[i]->getown = emma_pci_getown; + emma_algo_data[i]->getclock = emma_pci_getclock; + emma_algo_data[i]->waitforpin = emma_pci_waitforpin; + emma_algo_data[i]->udelay = 80; + emma_algo_data[i]->mdelay = 80; + emma_algo_data[i]->timeout = 100; + #ifdef CONFIG_I2C_EMMA_EXIOCTL + emma_algo_data[i]->setbusy = emma_pci_setbusy; + emma_algo_data[i]->getbusy = emma_pci_getbusy; + #endif + + emma_ops[i] = kmalloc(sizeof(struct i2c_adapter), GFP_KERNEL); + if (emma_ops[i] == NULL) { + return -ENOMEM; + } + memset(emma_ops[i], 0, sizeof(struct i2c_adapter)); + /* + * ftr revisit: add instance # to name + */ + strcpy(emma_ops[i]->name, "EMMA I2C adapter"); + emma_ops[i]->id = 0x00; + emma_ops[i]->algo = NULL; + emma_ops[i]->algo_data = emma_algo_data[i]; + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + emma_ops[i]->inc_use = emma_pci_inc_use; + emma_ops[i]->dec_use = emma_pci_dec_use; + #endif + emma_ops[i]->client_register = emma_pci_reg; + emma_ops[i]->client_unregister = emma_pci_unreg; + + init_waitqueue_head(&emma_wait[i]); + emma_pending[i] = 0; + spin_lock_init(&emma_lock[i]); + if (emma_pci_init(i) == 0) { + if (i2c_emma_add_bus(emma_ops[i]) < 0) { + /* FIXME : when add_bus() fails at i>=1, + * algorithm module is remaining 'used by + * adapter modules', therefore couldn't rmmod. + * We must success in add_bus() for now. + */ + return -ENODEV; + } + } else { + return -ENODEV; + } + DEB(printk(KERN_INFO "i2c_emmapci_init: found device at %#x.\n", i2c_emma_adaps[i]->base)); + } + + return 0; + } + + static void emma_pci_exit(void) + { + int i; + + for (i = 0; i < MAX_NUM_DEVS; i++) { + i2c_emma_del_bus(emma_ops[i]); + } + emma_release(); + } + + + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + EXPORT_NO_SYMBOLS; + #endif + + MODULE_AUTHOR("NEC Electronics Corporation "); + MODULE_DESCRIPTION("I2C-Bus adapter routines for EMMA I2C bus adapter"); + #ifdef MODULE_LICENSE + MODULE_LICENSE("GPL"); + #endif + + MODULE_PARM(i2c_debug,"i"); + + module_init(i2c_emmapci_init); + module_exit(emma_pci_exit); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/i2c/busses/i2c-emma3.c linux-current/drivers/i2c/busses/i2c-emma3.c *** linux-2.6.10/drivers/i2c/busses/i2c-emma3.c Thu Jan 1 09:00:00 1970 --- linux-current/drivers/i2c/busses/i2c-emma3.c Wed Apr 18 17:56:29 2007 *************** *** 0 **** --- 1,1193 ---- + /* + --------------------------------------------------------------------------- + i2c-emma3.c i2c driver bus & algorithms for NEC EMMA3 I2C adapters + --------------------------------------------------------------------------- + Copyright (C) TOSHIBA Corporation 2006, 2007 + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + + #ifdef CONFIG_I2C_EMMA_EXIOCTL + #define I2C_EMMA3_MAX_CH 1 /* MAX Channel */ + //#define DEBUG_SEEPROM /* Use SEEPROM */ + #else + #define I2C_EMMA3_MAX_CH 3 /* MAX Channel */ + #endif + + #define DEFAULT_STANDARD_SPEED + //#define DEBUG_TRACE + + /* CON - Control register (00H R/W) */ + #define CON_MASTER_MODE 0x00000001 + #define CON_MASTER_MODE_ENABLE 0x00000001 + #define CON_SPEED 0x00000006 + #define CON_SPEED_STANDARD 0x00000002 + #define CON_SPEED_FAST 0x00000004 + #define CON_ADDR10BIT_SLAVE 0x00000008 + #define CON_ADDR10BIT_MASTER 0x00000010 + #define CON_RESTART_EN 0x00000020 + #define CON_SLAVE_DISABLE 0x00000040 + + /* TAR - Target Address register (04H R/W) */ + #define TAR 0x000003FF + #define TAR_GC_OR_START 0x00000400 + #define TAR_SPECIAL 0x00000800 + + /* SAR - Slave Address register (08H R/W) */ + #define SAR 0x000003FF + + /* DATA_CMD - RX/TX Data Buffer and Command register (10H R/W) */ + #define DAT 0x000000FF + #define CMD 0x00000100 + #define CMD_READ 0x00000100 + + /* INTR STAT & MASK - Interrupt Stauts(2CH R) Mask(30H R/W) */ + #define INTR_RX_UNDER 0x00000001 + #define INTR_RX_OVER 0x00000002 + #define INTR_RX_FULL 0x00000004 + #define INTR_TX_OVER 0x00000008 + #define INTR_TX_EMPTY 0x00000010 + #define INTR_RD_REQ 0x00000020 + #define INTR_TX_ABRT 0x00000040 + #define INTR_RX_DONE 0x00000080 + #define INTR_ACTIVITY 0x00000100 + #define INTR_STOP_DET 0x00000200 + #define INTR_START_DET 0x00000400 + #define INTR_GEN_CALL 0x00000800 + + #define INTR_TX_WAIT_MASK (INTR_TX_EMPTY | INTR_TX_ABRT | INTR_STOP_DET) + #define INTR_RX_WAIT_MASK (INTR_RX_FULL | INTR_RX_OVER | INTR_STOP_DET) + #define INTR_END_WAIT_MASK (INTR_TX_ABRT | INTR_STOP_DET) + #define INTR_ALL 0xFFFFFFFF + + /* STATUS - Status register(70H R) */ + #define STS_ACTIVITY 0x00000001 + #define STS_TFNF 0x00000002 + #define STS_TFE 0x00000004 + #define STS_RFNE 0x00000008 + #define STS_RFF 0x00000010 + + /* ABRT SOURCE - Transmit Abort Status register(80H R) */ + #define ABRT_7B_ADDR_NOACK 0x00000001 + #define ABRT_10ADDR1_NOACK 0x00000002 + #define ABRT_10ADDR2_NOACK 0x00000004 + #define ABRT_TXDATA_NOACK 0x00000008 + #define ABRT_GCALL_NOACK 0x00000010 + #define ABRT_GCALL_READ 0x00000020 + #define ABRT_HS_ACKDET 0x00000040 + #define ABRT_SBYTE_ACKDET 0x00000080 + #define ABRT_HS_NORSTRT 0x00000100 + #define ABRT_SBYTE_NORSTRT 0x00000200 + #define ABRT_10B_RD_NORSTRT 0x00000400 + #define ARB_MASTER_DIS 0x00000800 + #define ARB_LOST 0x00001000 + #define ABRT_SLVFLUSH_TXFIFO 0x00002000 + #define ABRT_SLV_ARBLOST 0x00004000 + #define ABRT_SLVRD_INTX 0x00008000 + + /* I2C registers */ + #define I2C_EMMA3_CON 0x00 + #define I2C_EMMA3_TAR 0x04 + #define I2C_EMMA3_SAR 0x08 + #define I2C_EMMA3_DATA_CMD 0x10 + #define I2C_EMMA3_SS_SCL_HCNT 0x14 + #define I2C_EMMA3_SS_SCL_LCNT 0x18 + #define I2C_EMMA3_FS_SCL_HCNT 0x1C + #define I2C_EMMA3_FS_SCL_LCNT 0x20 + #define I2C_EMMA3_INTR_STAT 0x2C + #define I2C_EMMA3_INTR_MASK 0x30 + #define I2C_EMMA3_RAW_INTR_STAT 0x34 + #define I2C_EMMA3_RX_TL 0x38 + #define I2C_EMMA3_TX_TL 0x3C + #define I2C_EMMA3_CLR_INTR 0x40 + #define I2C_EMMA3_CLR_RX_UNDER 0x44 + #define I2C_EMMA3_CLR_RX_OVER 0x48 + #define I2C_EMMA3_CLR_TX_OVER 0x4C + #define I2C_EMMA3_CLR_RD_REQ 0x50 + #define I2C_EMMA3_CLR_TX_ABRT 0x54 + #define I2C_EMMA3_CLR_RX_DONE 0x58 + #define I2C_EMMA3_CLR_ACTIVITY 0x5C + #define I2C_EMMA3_CLR_STOP_DET 0x60 + #define I2C_EMMA3_CLR_START_DET 0x64 + #define I2C_EMMA3_CLR_GEN_CALL 0x68 + #define I2C_EMMA3_ENABLE 0x6C + #define I2C_EMMA3_STATUS 0x70 + #define I2C_EMMA3_TXFLR 0x74 + #define I2C_EMMA3_RXFLR 0x78 + #define I2C_EMMA3_TX_ABRT_SOURCE 0x80 + + /* FIFO */ + #define TX_FIFO_CNT 32 + #define TX_FIFO_THL 20 + #define RX_FIFO_CNT 32 + #define RX_FIFO_THL 16 + + /* EXIOCTL*/ + #ifdef CONFIG_I2C_EMMA_EXIOCTL + #define I2C_EMMA_RESET 730 + #define I2C_EMMA_CHECK_BUSY 731 + #define I2C_EMMA_SET_CLOCK 733 + #define I2C_EMMA_GET_CLOCK 734 + #endif + + /* Error Code */ + #define ERR_TOUT_TX (-1) + #define ERR_TOUT_RX (-2) + #define ERR_TOUT_STOP_DET (-3) + #define ERR_TX_ABRT (-4) + #define ERR_RX_OVER (-5) + #define ERR_PREEMPT (-6) + #define ERR_UNKNOWN (-7) + + /* struct */ + struct i2c_emma3_algo_data { + unsigned long baseaddr; + int irq; + wait_queue_head_t trx_wq; + spinlock_t emma3_lock; + + u32 rawintr; + u32 abrtsrc; + }; + + #ifdef CONFIG_I2C_EMMA_EXIOCTL + struct i2c_emma3_clock { + u32 mode; /* 1:standard 2:fast */ + u16 hcnt; + u16 lcnt; + }; + #endif + + #ifdef DEBUG_TRACE + #define MAX_DEBUG_CNT 150 + struct i2c_debug_dat { + int irq; + char rw; + u32 reg_addr; + u32 reg_val; + }; + static struct i2c_debug_dat debug_dat[MAX_DEBUG_CNT]; + static int debug_cnt; + + static void debug_print(void) + { + int i; + + printk("IRQ : R/W ADRRESS VALUE\n"); + printk("---------------------------------\n"); + + for (i = debug_cnt; i < MAX_DEBUG_CNT; i++) { + if (debug_dat[i].rw) { + printk("%01d : [%c] 0x%08x 0x%08x\n", + debug_dat[i].irq, + debug_dat[i].rw, + debug_dat[i].reg_addr, + debug_dat[i].reg_val); + } + } + + for (i = 0; i < debug_cnt; i++) { + if (debug_dat[i].rw) { + printk("%01d : [%c] 0x%08x 0x%08x\n", + debug_dat[i].irq, + debug_dat[i].rw, + debug_dat[i].reg_addr, + debug_dat[i].reg_val); + } + } + } + + static void set_debug_dat(char rw, u32 addr, u32 val) + { + debug_dat[debug_cnt].irq = in_interrupt() ? 1 : 0; + debug_dat[debug_cnt].rw = rw; + debug_dat[debug_cnt].reg_addr = addr; + debug_dat[debug_cnt].reg_val = val; + + debug_cnt = (debug_cnt + 1) % MAX_DEBUG_CNT; + } + #endif + + /* write */ + static inline void writel_emma3(struct i2c_emma3_algo_data *adap, + unsigned long reg, u32 val) + { + #ifdef DEBUG_TRACE + set_debug_dat('W', reg, val); + #endif + *(volatile u32 *)(adap->baseaddr + reg) = val; + #ifdef DEBUG_TRACE + if (reg != I2C_EMMA3_DATA_CMD) { + set_debug_dat('-', reg, + *(volatile u32 *)(adap->baseaddr + reg)); + } + #endif + } + + /* read */ + static inline u32 readl_emma3(struct i2c_emma3_algo_data *adap, + unsigned long reg) + { + u32 val; + + val = *(volatile u32 *)(adap->baseaddr + reg); + #ifdef DEBUG_TRACE + set_debug_dat('R', reg, val); + #endif + return val; + } + + static void i2c_snd(struct i2c_emma3_algo_data *adap, u32 data) + { + writel_emma3(adap, I2C_EMMA3_DATA_CMD, data); + } + + static u32 i2c_rcv(struct i2c_emma3_algo_data *adap) + { + return readl_emma3(adap, I2C_EMMA3_DATA_CMD); + } + + static void i2c_intclr(struct i2c_emma3_algo_data *adap, u32 rawintr) + { + /* Read clear */ + if (rawintr == INTR_ALL) + (void)readl_emma3(adap, I2C_EMMA3_CLR_INTR); + else { + if (rawintr & INTR_RX_UNDER) + (void)readl_emma3(adap, I2C_EMMA3_CLR_RX_UNDER); + if (rawintr & INTR_RX_OVER) + (void)readl_emma3(adap, I2C_EMMA3_CLR_RX_OVER); + if (rawintr & INTR_TX_OVER) + (void)readl_emma3(adap, I2C_EMMA3_CLR_TX_OVER); + if (rawintr & INTR_RD_REQ) + (void)readl_emma3(adap, I2C_EMMA3_CLR_RD_REQ); + if (rawintr & INTR_TX_ABRT) + (void)readl_emma3(adap, I2C_EMMA3_CLR_TX_ABRT); + if (rawintr & INTR_RX_DONE) + (void)readl_emma3(adap, I2C_EMMA3_CLR_RX_DONE); + if (rawintr & INTR_ACTIVITY) + (void)readl_emma3(adap, I2C_EMMA3_CLR_ACTIVITY); + if (rawintr & INTR_STOP_DET) + (void)readl_emma3(adap, I2C_EMMA3_CLR_STOP_DET); + if (rawintr & INTR_START_DET) + (void)readl_emma3(adap, I2C_EMMA3_CLR_START_DET); + if (rawintr & INTR_GEN_CALL) + (void)readl_emma3(adap, I2C_EMMA3_CLR_GEN_CALL); + } + } + + #if 0 + static void i2c_dump_reg(struct i2c_emma3_algo_data *adap) + { + printk(KERN_INFO "-- I2C Register Dump --------------------\n"); + + /* I2C Control */ + printk(KERN_INFO " CON : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_CON)); + + /* I2C Target Address */ + printk(KERN_INFO " TAR : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_TAR)); + + /* I2C Slave Address */ + printk(KERN_INFO " SAR : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_SAR)); + + /* Standard Speed I2C Clock SCL High Count */ + printk(KERN_INFO " SS_SCL_HCNT : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_SS_SCL_HCNT)); + + /* Standard Speed I2C Clock SCL Low Count */ + printk(KERN_INFO " SS_SCL_LCNT : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_SS_SCL_LCNT)); + + /* Fast Speed I2C Clock SCL High Count */ + printk(KERN_INFO " FS_SCL_HCNT : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_FS_SCL_HCNT)); + + /* Fast Speed I2C Clock SCL Low Count */ + printk(KERN_INFO " FS_SCL_LCNT : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_FS_SCL_LCNT)); + + /* I2C Interrupt Status */ + printk(KERN_INFO " INTR_STAT : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_INTR_STAT)); + + /* I2C Interrupt Mask */ + printk(KERN_INFO " INTR_MASK : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_INTR_MASK)); + + /* I2C Raw Interrupt Status */ + printk(KERN_INFO " RAW_INTR_STAT : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_RAW_INTR_STAT)); + + /* I2C Receive FIFO Threshold */ + printk(KERN_INFO " RX_TL : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_RX_TL)); + + /* I2C Transmit FIFO Threshold */ + printk(KERN_INFO " TX_TL : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_TX_TL)); + + /* I2C Enable */ + printk(KERN_INFO " ENABLE : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_ENABLE)); + + /* I2C Status Register */ + printk(KERN_INFO " STATUS : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_STATUS)); + + /* Transmit FIFO Level Register */ + printk(KERN_INFO " TXFLR : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_TXFLR)); + + /* Receive FIFO Level Register */ + printk(KERN_INFO " RXFLR : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_RXFLR)); + + /* I2C Transmit Abort Status Register */ + printk(KERN_INFO " TX_ABRT_SOURCE : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_TX_ABRT_SOURCE)); + } + #endif + + static void i2c_dump_abort(struct i2c_emma3_algo_data *adap) + { + u32 abrtsrc; + + abrtsrc = readl_emma3(adap, I2C_EMMA3_TX_ABRT_SOURCE); + printk(KERN_ERR " TX Abort Source: 0x%08x\n",abrtsrc | adap->abrtsrc); + + if (!abrtsrc && !adap->abrtsrc) { + printk(KERN_ERR " - What's happening??\n"); + return; + } + + if ((abrtsrc & ABRT_7B_ADDR_NOACK) || + (adap->abrtsrc & ABRT_7B_ADDR_NOACK)) + printk(KERN_ERR " - Noack 7bit address\n"); + + if ((abrtsrc & ABRT_10ADDR1_NOACK) || + (adap->abrtsrc & ABRT_10ADDR1_NOACK)) + printk(KERN_ERR " - Noack 10bit address1\n"); + + if ((abrtsrc & ABRT_10ADDR2_NOACK) || + (adap->abrtsrc & ABRT_10ADDR2_NOACK)) + printk(KERN_ERR " - Noack 10bit address2\n"); + + if ((abrtsrc & ABRT_TXDATA_NOACK) || + (adap->abrtsrc & ABRT_TXDATA_NOACK)) + printk(KERN_ERR " - Noack TX data\n"); + + if ((abrtsrc & ABRT_GCALL_NOACK) || + (adap->abrtsrc & ABRT_GCALL_NOACK)) + printk(KERN_ERR " - Noack GeneralCall\n"); + + if ((abrtsrc & ABRT_GCALL_READ) || + (adap->abrtsrc & ABRT_GCALL_READ)) + printk(KERN_ERR " - Read GeneralCall\n"); + + if ((abrtsrc & ABRT_HS_ACKDET) || + (adap->abrtsrc & ABRT_HS_ACKDET)) + printk(KERN_ERR " - Detect HighSpeed-ack\n"); + + if ((abrtsrc & ABRT_SBYTE_ACKDET) || + (adap->abrtsrc & ABRT_SBYTE_ACKDET)) + printk(KERN_ERR " - Detect StartByte-ack\n"); + + if ((abrtsrc & ABRT_HS_NORSTRT) || + (adap->abrtsrc & ABRT_HS_NORSTRT)) + printk(KERN_ERR " - Disable Restart (HighSpeed mode)\n"); + + if ((abrtsrc & ABRT_SBYTE_NORSTRT) || + (adap->abrtsrc & ABRT_SBYTE_NORSTRT)) + printk(KERN_ERR " - Disable Restart (StartByte send)\n"); + + if ((abrtsrc & ABRT_10B_RD_NORSTRT) || + (adap->abrtsrc & ABRT_10B_RD_NORSTRT)) + printk(KERN_ERR " - Disable Restart (10bit address mode)\n"); + + if ((abrtsrc & ARB_MASTER_DIS) || (adap->abrtsrc & ARB_MASTER_DIS)) + printk(KERN_ERR " - Disable Master\n"); + + if ((abrtsrc & ARB_LOST) || (adap->abrtsrc & ARB_LOST)) + printk(KERN_ERR " - Lost Arbitration (Master)\n"); + + if ((abrtsrc & ABRT_SLVFLUSH_TXFIFO) || + (adap->abrtsrc & ABRT_SLVFLUSH_TXFIFO)) + printk(KERN_ERR " - Flush TX FIFO (Slave)\n"); + + if ((abrtsrc & ABRT_SLV_ARBLOST) || (adap->abrtsrc & ABRT_SLV_ARBLOST)) + printk(KERN_ERR " - Lost Arbitration (Slave)\n"); + + if ((abrtsrc & ABRT_SLVRD_INTX) || (adap->abrtsrc & ABRT_SLVRD_INTX)) + printk(KERN_ERR " - Slave TX and Read-comannd Write FIFO\n"); + } + + static void i2c_disp_error(struct i2c_emma3_algo_data *adap, int err_flag) + { + switch (err_flag) { + case ERR_TOUT_TX: + printk(KERN_ERR "** Lost Interrupt (TX) **\n"); + printk(KERN_ERR " TX Th Level : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_TX_TL)); + printk(KERN_ERR " TX FIFO Level : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_TXFLR)); + break; + + case ERR_TOUT_RX: + printk(KERN_ERR "** Lost Interrupt (RX) **\n"); + printk(KERN_ERR " RX Th Level : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_RX_TL)); + printk(KERN_ERR " RX FIFO Level : 0x%08x\n", + readl_emma3(adap, I2C_EMMA3_RXFLR)); + break; + + case ERR_TOUT_STOP_DET: + printk(KERN_ERR "** Lost Interrupt (STOP_DET) **\n"); + break; + + case ERR_TX_ABRT: + printk(KERN_ERR "** TX Abort **\n"); + i2c_dump_abort(adap); + break; + + case ERR_RX_OVER: + printk(KERN_ERR "** RX Over **\n"); + break; + + case ERR_PREEMPT: + printk(KERN_ERR "** Probably Preempt Occurred **\n"); + break; + + case ERR_UNKNOWN: + printk(KERN_ERR "** Unknown Error **\n"); + break; + } + + } + + /* STOP_DET check */ + static inline int i2c_check_stop_det(struct i2c_emma3_algo_data *adap) + { + if ((readl_emma3(adap, I2C_EMMA3_RAW_INTR_STAT) & INTR_STOP_DET) || + (adap->rawintr & INTR_STOP_DET)) + return 1; + + return 0; + } + + /* TX_ABRT check */ + static inline int i2c_check_tx_abrt(struct i2c_emma3_algo_data *adap) + { + if ((readl_emma3(adap, I2C_EMMA3_RAW_INTR_STAT) & INTR_TX_ABRT) || + (adap->rawintr & INTR_TX_ABRT)) + return 1; + + return 0; + } + + static inline int i2c_wait_end(struct i2c_emma3_algo_data *adap) + { + if (i2c_check_stop_det(adap) || + i2c_check_tx_abrt(adap)) + return 1; + return 0; + } + + /* RX_OVER check */ + static inline int i2c_check_rx_over(struct i2c_emma3_algo_data *adap) + { + if ((readl_emma3(adap, I2C_EMMA3_RAW_INTR_STAT) & INTR_RX_OVER) || + (adap->rawintr & INTR_RX_OVER)) + return 1; + + return 0; + } + + /* TXTH level check */ + static inline int i2c_check_tx_thl(struct i2c_emma3_algo_data *adap, int tx_thl) + { + if (readl_emma3(adap, I2C_EMMA3_TXFLR) <= tx_thl) + return 1; + + return 0; + } + + /* RXTH level check */ + static inline int i2c_check_rx_thl(struct i2c_emma3_algo_data *adap, int rx_thl) + { + if (readl_emma3(adap, I2C_EMMA3_RXFLR) >= rx_thl) + return 1; + + return 0; + } + + static int i2c_wait_tx(struct i2c_emma3_algo_data *adap, int tx_thl) + { + if (i2c_check_tx_abrt(adap) || + i2c_check_tx_thl(adap, tx_thl)) + return 1; + + return 0; + } + + static int i2c_wait_rx(struct i2c_emma3_algo_data *adap, int rx_thl) + { + if (i2c_check_rx_over(adap) || + i2c_check_rx_thl(adap, rx_thl)) + return 1; + + return 0; + } + + static inline int i2c_set_cmd(struct i2c_emma3_algo_data *adap, u8 data, + int write, int loop_remain) + { + if (write) + i2c_snd(adap, (u32)data); + else + i2c_snd(adap, CMD_READ); + + if (i2c_check_tx_abrt(adap)) + return ERR_TX_ABRT; + + if ((loop_remain - 2) && + i2c_check_stop_det(adap)) + return ERR_PREEMPT; + + return 0; + } + + static int i2c_emma3_xfer_rw(struct i2c_emma3_algo_data *adap, + u8 *buf, int len, int write) + { + unsigned long flags; + int i; + + int cmd_len = len; + int cmd_txcnt = 0; + int cmd_end_flag = 0; + int tx_thl = -1; + + int dat_len = 0; + int dat_rxcnt = 0; + int rx_thl = -1; + + int ret; + int err_flag = 0; + + adap->rawintr = 0; + adap->abrtsrc = 0; + + if (write) + dat_len = 0; + else + dat_len = len; + + /* Enable I2C block */ + writel_emma3(adap, I2C_EMMA3_ENABLE, 0x1); + + spin_lock_irqsave(&adap->emma3_lock, flags); + /* TX/RX Start */ + for (dat_rxcnt = 0, cmd_txcnt = 0;;) { + int empty; + int remain; + + empty = TX_FIFO_CNT - readl_emma3(adap, I2C_EMMA3_TXFLR); + remain = cmd_len - cmd_txcnt; + + /* Set TX threshold level & cmd */ + if (empty <= remain) { /* continue */ + + /* Set TX threshold level */ + tx_thl = TX_FIFO_THL; + writel_emma3(adap, I2C_EMMA3_TX_TL, tx_thl); + + /* Set cmd */ + for (i = 0; i < empty; i++, cmd_txcnt++) { + err_flag = i2c_set_cmd(adap, buf[cmd_txcnt], + write, + cmd_len - cmd_txcnt); + if (err_flag) + goto end; + } + + } else if (remain) { /* last */ + + /* Set TX threshold level */ + tx_thl = 0; + writel_emma3(adap, I2C_EMMA3_TX_TL, tx_thl); + + /* Set cmd */ + for (i = 0; i < remain; i++, cmd_txcnt++) { + err_flag = i2c_set_cmd(adap, buf[cmd_txcnt], + write, + cmd_len - cmd_txcnt); + if (err_flag) + goto end; + } + + } else if (remain <= 0) /* end */ + cmd_end_flag = 1; + + + /* Wait for TX empty interrupt */ + if ((!cmd_end_flag) && + (readl_emma3(adap, I2C_EMMA3_RXFLR) < RX_FIFO_THL)) { + + /* Mask off */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, + INTR_TX_WAIT_MASK); + + spin_unlock_irqrestore(&adap->emma3_lock, flags); + ret = wait_event_timeout(adap->trx_wq, + i2c_wait_tx(adap, tx_thl), + msecs_to_jiffies(1000)); + spin_lock_irqsave(&adap->emma3_lock, flags); + + /* Mask on */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, 0); + + if (!ret && !i2c_wait_tx(adap, tx_thl)) { + err_flag = ERR_TOUT_TX; + goto end; + } else if (i2c_check_tx_abrt(adap)) { + err_flag = ERR_TX_ABRT; + goto end; + } else if (!i2c_check_tx_thl(adap, tx_thl)) { + err_flag = ERR_UNKNOWN; + goto end; + } + } + + /* Read data */ + if (dat_len) { + int read_cnt; + + read_cnt = readl_emma3(adap, I2C_EMMA3_RXFLR); + for (i = 0; i < read_cnt; i++, dat_rxcnt++, dat_len--) { + buf[dat_rxcnt] = (u8)i2c_rcv(adap); + } + + if (!dat_len) + break; + + if (dat_len && cmd_end_flag) { + + /* Set RX threshold level */ + if (dat_len <= RX_FIFO_CNT) + rx_thl = dat_len; + else + rx_thl = RX_FIFO_THL; + writel_emma3(adap, I2C_EMMA3_RX_TL, rx_thl - 1); + + /* Mask off */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, + INTR_RX_WAIT_MASK); + + spin_unlock_irqrestore(&adap->emma3_lock, flags); + ret = wait_event_timeout( + adap->trx_wq, + i2c_wait_rx(adap, rx_thl), + msecs_to_jiffies(1000)); + spin_lock_irqsave(&adap->emma3_lock, flags); + /* Mask on */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, 0); + + if (!ret && !i2c_wait_rx(adap, rx_thl)) { + err_flag = ERR_TOUT_RX; + goto end; + } else if (i2c_check_rx_over(adap)) { + err_flag = ERR_RX_OVER; + goto end; + } else if (!i2c_check_rx_thl(adap, rx_thl)) { + err_flag = ERR_UNKNOWN; + goto end; + } + } + + } else { + if (cmd_end_flag) + break; + } + } + + /* Check STOP_DET (and TX_ABRT) */ + if (!err_flag) { + /* Mask off */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, INTR_END_WAIT_MASK); + + spin_unlock_irqrestore(&adap->emma3_lock, flags); + ret = wait_event_timeout(adap->trx_wq, i2c_wait_end(adap), + msecs_to_jiffies(10)); + spin_lock_irqsave(&adap->emma3_lock, flags); + /* Mask on */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, 0); + + if (!ret && !i2c_wait_end(adap)) { + err_flag = ERR_TOUT_STOP_DET; + } else if (i2c_check_tx_abrt(adap)) { + err_flag = ERR_TX_ABRT; + } + } + + end: + spin_unlock_irqrestore(&adap->emma3_lock, flags); + + /* Display the Error */ + i2c_disp_error(adap, err_flag); + + /* Disable I2C block */ + writel_emma3(adap, I2C_EMMA3_ENABLE, 0x0); + + /* Mask on */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, 0x0); + + /* Clear interrupt */ + i2c_intclr(adap, INTR_ALL); + + /* Set TX threshold level */ + writel_emma3(adap, I2C_EMMA3_TX_TL, 0); + /* Set RX threshold level */ + writel_emma3(adap, I2C_EMMA3_RX_TL, 0xFF); + + adap->rawintr = 0; + adap->abrtsrc = 0; + + #ifdef DEBUG_TRACE + debug_print(); + #endif + + if (err_flag) + return -EIO; + if (write) + return cmd_txcnt; + else + return dat_rxcnt; + + } + + static int i2c_emma3_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], int num) + { + struct i2c_emma3_algo_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg = NULL; + int i; + u32 con; + u32 tar; + int ret = 0; + + #ifdef DEBUG_TRACE + memset(debug_dat, 0, sizeof(struct i2c_debug_dat) * MAX_DEBUG_CNT); + debug_cnt = 0; + #endif + for (i = 0; i < num; i++) { + pmsg = &msgs[i]; + + /* Set Addressing Mode */ + con = readl_emma3(adap, I2C_EMMA3_CON); + if (pmsg->flags & I2C_M_TEN) { + writel_emma3(adap, I2C_EMMA3_CON, + con | CON_ADDR10BIT_MASTER); + } else { + writel_emma3(adap, I2C_EMMA3_CON, + con & ~CON_ADDR10BIT_MASTER); + } + + /* Set Target Address */ + tar = pmsg->addr & 0x00003ff; + writel_emma3(adap, I2C_EMMA3_TAR, + tar/* | TAR_GC_OR_START | TAR_SPECIAL*/); + + if (pmsg->flags & I2C_M_RD) { /* Read */ + ret = i2c_emma3_xfer_rw(adap, pmsg->buf, pmsg->len, 0); + } else { /* Write */ + ret = i2c_emma3_xfer_rw(adap, pmsg->buf, pmsg->len, 1); + } + + if (ret < 0) + return ret; + } + + return i; + } + + #ifdef CONFIG_I2C_EMMA_EXIOCTL + static int i2c_emma3_set_clock(struct i2c_emma3_algo_data *adap, + struct i2c_emma3_clock *clock) + { + u32 con; + u32 speed = 0; + + /* Set Speed mode & clcok conut */ + switch (clock->mode) { + case 1: /* standard */ + speed = CON_SPEED_STANDARD; + writel_emma3(adap, I2C_EMMA3_SS_SCL_HCNT, clock->hcnt); + writel_emma3(adap, I2C_EMMA3_SS_SCL_LCNT, clock->lcnt); + break; + case 2: /* fast */ + speed = CON_SPEED_FAST; + writel_emma3(adap, I2C_EMMA3_FS_SCL_HCNT, clock->hcnt); + writel_emma3(adap, I2C_EMMA3_FS_SCL_LCNT, clock->lcnt); + break; + default: + return -EINVAL; + + } + con = readl_emma3(adap, I2C_EMMA3_CON); + con &= ~CON_SPEED; + con |= speed; + writel_emma3(adap, I2C_EMMA3_CON, con); + + return 0; + } + + static void i2c_emma3_get_clock(struct i2c_emma3_algo_data *adap, + struct i2c_emma3_clock *clock) + { + u32 con; + u32 speed = 0; + + con = readl_emma3(adap, I2C_EMMA3_CON); + speed = con & CON_SPEED; + + /* Get Speed mode & clcok conut */ + switch (speed) { + case CON_SPEED_STANDARD: + clock->mode = 1; + clock->hcnt = (u16)readl_emma3(adap, I2C_EMMA3_SS_SCL_HCNT); + clock->lcnt = (u16)readl_emma3(adap, I2C_EMMA3_SS_SCL_LCNT); + break; + case CON_SPEED_FAST: + clock->mode = 2; + clock->hcnt = (u16)readl_emma3(adap, I2C_EMMA3_FS_SCL_HCNT); + clock->lcnt = (u16)readl_emma3(adap, I2C_EMMA3_FS_SCL_LCNT); + break; + } + } + + static int i2c_emma3_check_busy(struct i2c_emma3_algo_data *adap) + { + u32 status; + + status = readl_emma3(adap, I2C_EMMA3_STATUS); + if (status & STS_ACTIVITY) + return 1; /* busy */ + else + return 0; /* not busy */ + } + + #endif /* CONFIG_I2C_EMMA_EXIOCTL */ + + static int i2c_emma3_algo_control(struct i2c_adapter *adapter, + unsigned int cmd, unsigned long arg) + { + #ifdef CONFIG_I2C_EMMA_EXIOCTL + struct i2c_emma3_algo_data *adap = adapter->algo_data; + int status; + struct i2c_emma3_clock clock; + + switch (cmd) { + case I2C_EMMA_RESET: + /* nothing to do; */ + break; + + case I2C_EMMA_CHECK_BUSY: + if (arg == 0) + return -EINVAL; + status = i2c_emma3_check_busy(adap); + if (copy_to_user((int *)arg, &status, sizeof(int))) + return -EFAULT; + break; + + case I2C_EMMA_SET_CLOCK: + if (arg == 0) + return -EINVAL; + if (copy_from_user(&clock, + (struct i2c_emma3_clock *)arg, + sizeof(struct i2c_emma3_clock))) + return -EFAULT; + + return i2c_emma3_set_clock(adap, &clock); + + case I2C_EMMA_GET_CLOCK: + if (arg == 0) + return -EINVAL; + memset(&clock ,0, sizeof(struct i2c_emma3_clock)); + i2c_emma3_get_clock(adap, &clock); + if (copy_to_user((struct i2c_emma3_clock *)arg, + &clock, + sizeof(struct i2c_emma3_clock))) + return -EFAULT; + break; + + default: + return -EINVAL; + } + #endif + return 0; + } + + + static u32 i2c_emma3_func(struct i2c_adapter *adap) + { + return I2C_FUNC_SMBUS_EMUL; + } + + struct i2c_algorithm i2c_emma3_algo = { + .name = "NEC EMMA3 I2C algorithm", + .id = I2C_ALGO_EXP, + .master_xfer = i2c_emma3_xfer, + .algo_control = i2c_emma3_algo_control, + .functionality = i2c_emma3_func, + }; + + static struct i2c_emma3_algo_data i2c_emma3_data[I2C_EMMA3_MAX_CH] = { + #ifdef CONFIG_I2C_EMMA_EXIOCTL + { + #ifdef DEBUG_SEEPROM + .baseaddr = EMMA3_I2C0_BASE, + #else + .baseaddr = EMMA3_I2C2_BASE, + #endif + }, + #else + #if I2C_EMMA3_MAX_CH >= 1 + { + .baseaddr = EMMA3_I2C0_BASE, + }, + #endif + #if I2C_EMMA3_MAX_CH >= 2 + { + .baseaddr = EMMA3_I2C1_BASE, + }, + #endif + #if I2C_EMMA3_MAX_CH >= 3 + { + .baseaddr = EMMA3_I2C2_BASE, + }, + #endif + #endif + }; + + static struct i2c_adapter i2c_emma3_ops[I2C_EMMA3_MAX_CH] = { + #if I2C_EMMA3_MAX_CH >= 1 + { + .owner = THIS_MODULE, + .name = "I2C-Ch0", + .id = I2C_ALGO_EXP, + .algo = &i2c_emma3_algo, + .algo_data = &i2c_emma3_data[0], + .retries = 2, + }, + #endif + #if I2C_EMMA3_MAX_CH >= 2 + { + .owner = THIS_MODULE, + .name = "I2C-Ch1", + .id = I2C_ALGO_EXP, + .algo = &i2c_emma3_algo, + .algo_data = &i2c_emma3_data[1], + .retries = 2, + }, + #endif + #if I2C_EMMA3_MAX_CH >= 3 + { + .owner = THIS_MODULE, + .name = "I2C-Ch2", + .id = I2C_ALGO_EXP, + .algo = &i2c_emma3_algo, + .algo_data = &i2c_emma3_data[2], + .retries = 2, + }, + #endif + }; + + static irqreturn_t i2c_emma3_handler(int irq, void *dev_id, + struct pt_regs *regs) + { + struct i2c_emma3_algo_data *adap = dev_id; + u32 rawintr; + u32 abrtsrc; + + rawintr = readl_emma3(adap, I2C_EMMA3_RAW_INTR_STAT); + abrtsrc = readl_emma3(adap, I2C_EMMA3_TX_ABRT_SOURCE); + + /* Clear interrupt */ + i2c_intclr(adap, rawintr); + + /* Save RAW_INTR & ABRTSRC */ + rawintr &= ~(INTR_TX_EMPTY | INTR_RX_FULL); + adap->rawintr |= rawintr; + adap->abrtsrc |= abrtsrc; + + /* Mask on */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, 0); + + wake_up(&adap->trx_wq); + return IRQ_HANDLED; + + } + + static int __init i2c_emma3_resource_init(void) + { + #ifdef CONFIG_I2C_EMMA_EXIOCTL + struct i2c_emma3_algo_data *adap; + + adap = i2c_emma3_ops[0].algo_data; + + spin_lock_init(&adap->emma3_lock); + init_waitqueue_head(&adap->trx_wq); + #ifdef DEBUG_SEEPROM + adap->irq = EMMA3_IRQ_PIIC0; + #else + adap->irq = EMMA3_IRQ_PIIC0 + 2; + #endif + if (request_irq(adap->irq, i2c_emma3_handler, SA_INTERRUPT, + i2c_emma3_ops[0].name, adap) < 0) { + adap->irq = 0; + return -ENODEV; + } + printk(KERN_DEBUG "register IRQ %d\n",adap->irq); + #else + int i; + struct i2c_emma3_algo_data *adap; + + for (i = 0; i < I2C_EMMA3_MAX_CH; i++) { + adap = i2c_emma3_ops[i].algo_data; + init_waitqueue_head(&adap->trx_wq); + adap->irq = EMMA3_IRQ_PIIC0 + i; + if (request_irq(adap->irq, i2c_emma3_handler, SA_INTERRUPT, + i2c_emma3_ops[i].name, adap) < 0) { + adap->irq = 0; + return -ENODEV; + } + printk(KERN_DEBUG "register IRQ %d\n",adap->irq); + } + #endif + return 0; + } + + static void i2c_emma3_resource_release(void) + { + int i; + struct i2c_emma3_algo_data *adap; + + for (i = 0; i < I2C_EMMA3_MAX_CH; i++) { + adap = i2c_emma3_ops[i].algo_data; + if (adap->irq > 0) { + free_irq(adap->irq, adap); + adap->irq = 0; + } + } + } + + static int __init i2c_emma3_init(struct i2c_emma3_algo_data *adap) + { + + /* Initialize control (Default: Master 7BitAddress) */ + writel_emma3(adap, I2C_EMMA3_CON, + #ifdef DEFAULT_STANDARD_SPEED + CON_SPEED_STANDARD | + #else + CON_SPEED_FAST | + #endif + CON_RESTART_EN | + CON_MASTER_MODE_ENABLE); + + /* Set interrupt mask */ + writel_emma3(adap, I2C_EMMA3_INTR_MASK, 0x0); + + /* Set clock count */ + #ifdef DEFAULT_STANDARD_SPEED + /* standard */ + writel_emma3(adap, I2C_EMMA3_SS_SCL_HCNT, 0x6E/*0x52*/); + writel_emma3(adap, I2C_EMMA3_SS_SCL_LCNT, 0x7F/*0x5F*/); + #else + /* fast */ + writel_emma3(adap, I2C_EMMA3_FS_SCL_HCNT, /*0x13*/0x0D); + writel_emma3(adap, I2C_EMMA3_FS_SCL_LCNT, /*0x22*/0x19); + #endif + /* Clear interrupt */ + i2c_intclr(adap, INTR_ALL); + + /* Set TX threshold level */ + writel_emma3(adap, I2C_EMMA3_TX_TL, 0); + /* Set RX threshold level */ + writel_emma3(adap, I2C_EMMA3_RX_TL, 0xFF); + + return 0; + } + + + static int __init i2c_emma3_add_bus(struct i2c_adapter *adap) + { + /* register new adapter to i2c module... */ + i2c_add_adapter(adap); + i2c_emma3_init(adap->algo_data); + + return 0; + } + + static int i2c_emma3_del_bus(struct i2c_adapter *adap) + { + int res; + + if ((res = i2c_del_adapter(adap)) < 0) + return res; + + return 0; + } + + int __init i2c_adap_emma3_init(void) + { + int i; + + if (mips_machgroup != MACH_GROUP_EMMA3) + return -ENODEV; + + printk(KERN_INFO "I2C Driver for EMMA3 \n"); + if (i2c_emma3_resource_init() != 0) { + i2c_emma3_resource_release(); + return -ENODEV; + } + for (i = 0; i < I2C_EMMA3_MAX_CH; i++) { + if (i2c_emma3_add_bus(&i2c_emma3_ops[i]) < 0) { + i2c_emma3_resource_release(); + return -ENODEV; + } + } + return 0; + } + + void __exit i2c_adap_emma3_exit(void) + { + int i; + + for (i = 0; i < I2C_EMMA3_MAX_CH; i++) { + i2c_emma3_del_bus(&i2c_emma3_ops[i]); + } + i2c_emma3_resource_release(); + + return; + } + + module_init(i2c_adap_emma3_init); + module_exit(i2c_adap_emma3_exit); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/i2c/i2c-dev.c linux-current/drivers/i2c/i2c-dev.c *** linux-2.6.10/drivers/i2c/i2c-dev.c Sat Dec 25 06:35:24 2004 --- linux-current/drivers/i2c/i2c-dev.c Wed Jun 14 21:12:58 2006 *************** *** 257,262 **** --- 257,272 ---- res = -ENOMEM; break; } + #ifdef CONFIG_I2C_CHIP1S + if(rdwr_pa[i].flags & I2C_M_RD) { + if(copy_from_user(rdwr_pa[i].buf, + data_ptrs[i],3)) { + ++i; /* Needs to be kfreed too */ + res = -EFAULT; + break; + } + }else + #endif if(copy_from_user(rdwr_pa[i].buf, data_ptrs[i], rdwr_pa[i].len)) { diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/mtd/cmdlinepart.c linux-current/drivers/mtd/cmdlinepart.c *** linux-2.6.10/drivers/mtd/cmdlinepart.c Sat Dec 25 06:35:23 2004 --- linux-current/drivers/mtd/cmdlinepart.c Wed Jun 14 21:12:58 2006 *************** *** 43,48 **** --- 43,49 ---- /* special size referring to all the remaining space in a partition */ #define SIZE_REMAINING 0xffffffff + #define OFFSET_CONTINUOUS 0xffffffff struct cmdline_mtd_partition { struct cmdline_mtd_partition *next; *************** *** 75,81 **** { struct mtd_partition *parts; unsigned long size; ! unsigned long offset = 0; char *name; int name_len; unsigned char *extra_mem; --- 76,82 ---- { struct mtd_partition *parts; unsigned long size; ! unsigned long offset = OFFSET_CONTINUOUS; char *name; int name_len; unsigned char *extra_mem; *************** *** 310,316 **** { for(i = 0, offset = 0; i < part->num_parts; i++) { ! if (!part->parts[i].offset) part->parts[i].offset = offset; else offset = part->parts[i].offset; --- 311,317 ---- { for(i = 0, offset = 0; i < part->num_parts; i++) { ! if (part->parts[i].offset == OFFSET_CONTINUOUS) part->parts[i].offset = offset; else offset = part->parts[i].offset; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/mtd/maps/Kconfig linux-current/drivers/mtd/maps/Kconfig *** linux-2.6.10/drivers/mtd/maps/Kconfig Sat Dec 25 06:35:39 2004 --- linux-current/drivers/mtd/maps/Kconfig Wed Jun 14 21:12:59 2006 *************** *** 449,454 **** --- 449,458 ---- NVRAM on the Momenco Ocelot board. If you have one of these boards and would like access to either of these, say 'Y'. + config MTD_TXBOARD + tristate "Flash chip mapping on TX board" + depends on MIPS && TX_BOARDS + config MTD_SOLUTIONENGINE tristate "CFI Flash device mapped on Hitachi SolutionEngine" depends on SUPERH && MTD_CFI && MTD_REDBOOT_PARTS diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/mtd/maps/Makefile linux-current/drivers/mtd/maps/Makefile *** linux-2.6.10/drivers/mtd/maps/Makefile Sat Dec 25 06:33:47 2004 --- linux-current/drivers/mtd/maps/Makefile Wed Jun 14 21:12:59 2006 *************** *** 42,47 **** --- 42,48 ---- obj-$(CONFIG_MTD_SCx200_DOCFLASH)+= scx200_docflash.o obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.o obj-$(CONFIG_MTD_OCELOT) += ocelot.o + obj-$(CONFIG_MTD_TXBOARD) += txboard-flash.o obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o obj-$(CONFIG_MTD_PCI) += pci.o obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/mtd/nand/Kconfig linux-current/drivers/mtd/nand/Kconfig *** linux-2.6.10/drivers/mtd/nand/Kconfig Sat Dec 25 06:35:24 2004 --- linux-current/drivers/mtd/nand/Kconfig Wed Jun 14 21:12:59 2006 *************** *** 73,78 **** --- 73,82 ---- This enables the driver for the NAND flash device found on the Toshiba RBTX4938 reference board. + config MTD_NAND_TXX9NDFMC + tristate "NAND Flash device on TXX9 NDFMC" + depends on MTD_NAND && TX_BOARDS && CPU_TX49XX + config MTD_NAND_AU1550 tristate "Au1550 NAND support" depends on SOC_AU1550 && MTD_NAND diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/mtd/nand/Makefile linux-current/drivers/mtd/nand/Makefile *** linux-2.6.10/drivers/mtd/nand/Makefile Sat Dec 25 06:33:49 2004 --- linux-current/drivers/mtd/nand/Makefile Wed Jun 14 21:12:59 2006 *************** *** 12,17 **** --- 12,18 ---- obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o obj-$(CONFIG_MTD_NAND_TX4925NDFMC) += tx4925ndfmc.o obj-$(CONFIG_MTD_NAND_TX4938NDFMC) += tx4938ndfmc.o + obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/net/8139too.c linux-current/drivers/net/8139too.c *** linux-2.6.10/drivers/net/8139too.c Sat Dec 25 06:33:47 2004 --- linux-current/drivers/net/8139too.c Wed Jan 24 17:58:01 2007 *************** *** 113,118 **** --- 113,120 ---- #include #include + #define WORKAROUND_RESUME + #define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION #define PFX DRV_NAME ": " *************** *** 121,126 **** --- 123,131 ---- NETIF_MSG_PROBE | \ NETIF_MSG_LINK) + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + #define BOARD3A_PCI_DMABASE 0x20000000 + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ /* enable PIO instead of MMIO, if CONFIG_8139TOO_PIO is selected */ #ifdef CONFIG_8139TOO_PIO *************** *** 631,636 **** --- 636,645 ---- static void __set_rx_mode (struct net_device *dev); static void rtl8139_hw_start (struct net_device *dev); static struct ethtool_ops rtl8139_ethtool_ops; + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + extern int rpci_check_device(struct pci_dev *pdev); + extern int rpci_module_init(struct pci_driver *pci_drv); + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ #ifdef USE_IO_OPS *************** *** 785,790 **** --- 794,802 ---- *dev_out = NULL; + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + if( rpci_check_device(pdev)!=1){ + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ /* dev and dev->priv zeroed in alloc_etherdev */ dev = alloc_etherdev (sizeof (*tp)); if (dev == NULL) { *************** *** 797,806 **** --- 809,831 ---- tp = dev->priv; tp->pci_dev = pdev; + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + } else { + dev = 0; + tp = 0; + } + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ + + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + if( rpci_check_device(pdev)==1){ + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ /* enable device (incl. PCI PM wakeup and hotplug setup) */ rc = pci_enable_device (pdev); if (rc) goto err_out; + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + } + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ pio_start = pci_resource_start (pdev, 0); pio_end = pci_resource_end (pdev, 0); *************** *** 848,856 **** --- 873,889 ---- if (rc) goto err_out; + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + if( rpci_check_device(pdev)==1) + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ /* enable PCI bus-mastering */ pci_set_master (pdev); + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + if( rpci_check_device(pdev)==1) + return 0; + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ + #ifdef USE_IO_OPS ioaddr = (void *) pio_start; dev->base_addr = pio_start; *************** *** 962,967 **** --- 995,1003 ---- } #endif + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + if( rpci_check_device(pdev)!=2){ + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ pci_read_config_byte(pdev, PCI_REVISION_ID, &pci_rev); if (pdev->vendor == PCI_VENDOR_ID_REALTEK && *************** *** 970,979 **** --- 1006,1022 ---- pci_name(pdev), pdev->vendor, pdev->device, pci_rev); printk(KERN_INFO PFX "Use the \"8139cp\" driver for improved performance and stability.\n"); } + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + } + #endif i = rtl8139_init_board (pdev, &dev); if (i < 0) return i; + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + if( rpci_check_device(pdev)==1) + return 0; + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ assert (dev != NULL); tp = dev->priv; *************** *** 985,991 **** --- 1028,1070 ---- for (i = 0; i < 3; i++) ((u16 *) (dev->dev_addr))[i] = le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len)); + #if !defined(MODULE) && (defined(CONFIG_TOSHIBA_CHIP0S) || defined(CONFIG_TOSHIBA_CHIP1S) || defined(CONFIG_EMMA)) + { + unsigned short id = read_eeprom (ioaddr, 0, 8); + if(id == 0x0000) + printk("WARNING: RTL8100 EEPROM seems not to be implemented.\n"); + else if((id == 0xffff)) + printk("WARNING: RTL8100 EEPROM seems not to be initilaized.\n"); + #if 0 + /* dump EEPROM */ + printk("EEPROM: "); + for (i = 0; i < 24; i++) + printk("%04x ",le16_to_cpu (read_eeprom (ioaddr, i, addr_len))); + printk("\n"); + #endif + } + { + int mac_and,mac_or; + mac_and = ((u16 *)(dev->dev_addr))[0] & ((u16 *)(dev->dev_addr))[1] & ((u16 *)(dev->dev_addr))[2]; + mac_or = ((u16 *)(dev->dev_addr))[0] | ((u16 *)(dev->dev_addr))[1] | ((u16 *)(dev->dev_addr))[2]; + if ((mac_and == 0xffff) || (mac_or == 0x0000)){ + extern char *pmon_getenv(const char *name) __init; + char *tmpstr = pmon_getenv("etheraddr"); + if (tmpstr) { + for (i = 0; i < 6; i++) { + dev->dev_addr[i] = simple_strtoul(tmpstr, &tmpstr, 16); + if (*tmpstr == ':') + tmpstr++; + } + } + } + } + #endif + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + if( rpci_check_device(pdev)==2) + strcpy( dev->name, "eth2" ); + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ /* The Rtl8139-specific entries in the device structure. */ dev->open = rtl8139_open; dev->hard_start_xmit = rtl8139_start_xmit; *************** *** 1344,1349 **** --- 1423,1435 ---- return -ENOMEM; } + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + if( rpci_check_device(tp->pci_dev)==2) { + tp->tx_bufs_dma += BOARD3A_PCI_DMABASE; + tp->rx_ring_dma += BOARD3A_PCI_DMABASE; + printk("tx_dma=0x%x,rx_dma=0x%x\n",tp->tx_bufs_dma,tp->rx_ring_dma); + } + #endif /* CONFIG_REMOTE_PCI && CONFIG_8139TOO_BOARD3A */ tp->mii.full_duplex = tp->mii.force_media; tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000; *************** *** 1388,1393 **** --- 1474,1483 ---- rtl8139_chip_reset (ioaddr); + #ifdef WORKAROUND_RESUME + /* init Rx ring buffer DMA address */ + RTL_W32_F (RxBuf, tp->rx_ring_dma); + #endif /* unlock Config[01234] and BMCR register writes */ RTL_W8_F (Cfg9346, Cfg9346_Unlock); /* Restore our idea of the MAC address. */ *************** *** 1419,1426 **** --- 1509,1518 ---- /* Lock Config[01234] and BMCR register writes */ RTL_W8 (Cfg9346, Cfg9346_Lock); + #ifndef WORKAROUND_RESUME /* init Rx ring buffer DMA address */ RTL_W32_F (RxBuf, tp->rx_ring_dma); + #endif /* init Tx buffer DMA addresses */ for (i = 0; i < NUM_TX_DESC; i++) *************** *** 2651,2657 **** --- 2743,2753 ---- printk (KERN_INFO RTL8139_DRIVER_NAME "\n"); #endif + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_8139TOO_BOARD3A) + return rpci_module_init (&rtl8139_pci_driver); + #else return pci_module_init (&rtl8139_pci_driver); + #endif } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/net/Kconfig linux-current/drivers/net/Kconfig *** linux-2.6.10/drivers/net/Kconfig Sat Dec 25 06:35:25 2004 --- linux-current/drivers/net/Kconfig Wed Jun 14 21:12:59 2006 *************** *** 817,823 **** tristate "SMC 91C9x/91C1xxx support" select CRC32 select MII ! depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R) 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 --- 817,823 ---- tristate "SMC 91C9x/91C1xxx support" select CRC32 select MII ! depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || MIPS) 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 *************** *** 1369,1374 **** --- 1369,1384 ---- tristate "TOSHIBA TC35815 Ethernet support" depends on NET_PCI && PCI && TOSHIBA_JMR3927 + config TC35815_1 + tristate "TOSHIBA TC35815 Version 1 Ethernet support" + depends on NET_PCI && PCI + select MII + + config TC35815_1_DLNA + bool " TC35815_1 DLNA support " + depends on TC35815_1 + default n + config DGRS tristate "Digi Intl. RightSwitch SE-X support" depends on NET_PCI && (PCI || EISA) *************** *** 1486,1491 **** --- 1496,1507 ---- More specific information and updates are available from . + config NATSEMI_BOARD3A + bool " Use DP8381x from BOARD3A" + depends on NATSEMI && TOSHIBA_CHIP1S + default n + select REMOTE_PCI + config NE2K_PCI tristate "PCI NE2000 and clones support (see help)" depends on NET_PCI && PCI *************** *** 1600,1605 **** --- 1616,1627 ---- experience problems, you can enable this option to restore the old RX-reset behavior. If unsure, say N. + config 8139TOO_BOARD3A + bool "Use 8139too from BOARD3A" + depends on 8139TOO && TOSHIBA_CHIP1S + default n + select REMOTE_PCI + config SIS900 tristate "SiS 900/7016 PCI Fast Ethernet Adapter support" depends on NET_PCI && PCI *************** *** 1816,1821 **** --- 1838,1847 ---- Say Y here if you want to use the NE2000 compatible controller on the Renesas H8/300 processor. + config TXBOARD_OBNE_NET + bool "TX onboard NE Ethernet support" + depends on NET_ETHERNET && TX_BOARDS + source "drivers/net/fec_8xx/Kconfig" endmenu diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/net/Makefile linux-current/drivers/net/Makefile *** linux-2.6.10/drivers/net/Makefile Sat Dec 25 06:34:29 2004 --- linux-current/drivers/net/Makefile Wed Jun 14 21:12:59 2006 *************** *** 57,62 **** --- 57,63 ---- obj-$(CONFIG_VIA_RHINE) += via-rhine.o obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o + obj-$(CONFIG_TXBOARD_OBNE_NET) += txboard-obne.o 8390.o # # end link order section *************** *** 182,187 **** --- 183,189 ---- obj-$(CONFIG_S2IO) += s2io.o obj-$(CONFIG_SMC91X) += smc91x.o obj-$(CONFIG_FEC_8XX) += fec_8xx/ + obj-$(CONFIG_TC35815_1) += tc35815_1.o obj-$(CONFIG_ARM) += arm/ obj-$(CONFIG_NET_FC) += fc/ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/net/natsemi.c linux-current/drivers/net/natsemi.c *** linux-2.6.10/drivers/net/natsemi.c Sat Dec 25 06:33:50 2004 --- linux-current/drivers/net/natsemi.c Wed Jun 14 22:41:34 2006 *************** *** 164,169 **** --- 164,176 ---- #include #include #include + #ifdef CONFIG_TOSHIBA_CHIP1S + #include + #endif + + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + #define BOARD3A_PCI_DMABASE 0x20000000 + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ #define DRV_NAME "natsemi" #define DRV_VERSION "1.07+LK1.0.17" *************** *** 171,176 **** --- 178,188 ---- #define RX_OFFSET 2 + #ifdef CONFIG_TOSHIBA_CHIP1S_SHARP1 + #define CHIP1S_DMA_WORKAROUND + #define DMABURST_ALIGN 64 + #endif + /* Updated to recommendations in pci-skeleton v2.03. */ /* The user-configurable values. *************** *** 193,199 **** --- 205,215 ---- /* Set the copy breakpoint for the copy-only-tiny-frames scheme. Setting to > 1518 effectively disables this feature. */ + #if defined(CONFIG_TOSHIBA_CHIP0S) || defined(CONFIG_TOSHIBA_CHIP1S) || defined(CONFIG_EMMA) + static int rx_copybreak = 1519; + #else static int rx_copybreak; + #endif /* Used to pass the media type, etc. Both 'options[]' and 'full_duplex[]' should exist for driver *************** *** 552,558 **** --- 568,578 ---- * */ #define TX_FLTH_VAL ((512/32) << 8) + #ifdef CHIP1S_DMA_WORKAROUND + #define TX_DRTH_VAL_START (1024/32) + #else #define TX_DRTH_VAL_START (64/32) + #endif #define TX_DRTH_VAL_INC 2 #define TX_DRTH_VAL_LIMIT (1472/32) *************** *** 769,774 **** --- 789,797 ---- static int netdev_get_regs(struct net_device *dev, u8 *buf); static int netdev_get_eeprom(struct net_device *dev, u8 *buf); static struct ethtool_ops ethtool_ops; + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + extern int rpci_check_device(struct pci_dev *pdev); + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ static inline void __iomem *ns_ioaddr(struct net_device *dev) { *************** *** 820,825 **** --- 843,851 ---- printk(version); #endif + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + if( rpci_check_device(pdev)!=2){ + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ i = pci_enable_device(pdev); if (i) return i; *************** *** 833,846 **** --- 859,882 ---- u32 newtmp = tmp & ~PCI_PM_CTRL_STATE_MASK; pci_write_config_dword(pdev, PCIPM, newtmp); } + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + } + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ find_cnt++; iostart = pci_resource_start(pdev, pcibar); iosize = pci_resource_len(pdev, pcibar); irq = pdev->irq; + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + if( rpci_check_device(pdev)!=2) + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ if (natsemi_pci_info[chip_idx].flags & PCI_USES_MASTER) pci_set_master(pdev); + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + if( rpci_check_device(pdev)==1) + return 0; + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ dev = alloc_etherdev(sizeof (struct netdev_private)); if (!dev) *************** *** 866,871 **** --- 902,929 ---- dev->dev_addr[i*2+1] = eedata >> 7; prev_eedata = eedata; } + #if !defined(MODULE) && (defined(CONFIG_TOSHIBA_CHIP0S) || defined(CONFIG_TOSHIBA_CHIP1S) || defined(CONFIG_EMMA)) + if ((dev->dev_addr[0] & dev->dev_addr[1] & dev->dev_addr[2] & + dev->dev_addr[3] & dev->dev_addr[4] & dev->dev_addr[5]) == 0xff) { + extern char *pmon_getenv(const char *name) __init; + char *tmpstr = pmon_getenv("etheraddr"); + if (tmpstr) { + for (i = 0; i < 6; i++) { + dev->dev_addr[i] = simple_strtoul(tmpstr, &tmpstr, 16); + if (*tmpstr == ':') + tmpstr++; + } + } + } + #endif + #ifdef CONFIG_TOSHIBA_CHIP1S + switch(mips_machtype){ + case MACH_CHIP1S_BOARD15C: + case MACH_CHIP1S_BOARD15H: + strcpy( dev->name, "eth1" ); + break; + } + #endif dev->base_addr = (unsigned long __force) ioaddr; dev->irq = irq; *************** *** 922,927 **** --- 980,989 ---- np->full_duplex = 1; /* The chip-specific entries in the device structure. */ + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + if( rpci_check_device(pdev)==2) + strcpy( dev->name, "eth2" ); + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ dev->open = &netdev_open; dev->hard_start_xmit = &start_tx; dev->stop = &netdev_close; *************** *** 1434,1439 **** --- 1496,1504 ---- for (i = 0; i < 3; i++) { writel(i*2, ioaddr + RxFilterAddr); pmatch[i] = readw(ioaddr + RxFilterData); + #ifdef CONFIG_TOSHIBA_CHIP0S + pmatch[i] = (dev->dev_addr[i*2+1] << 8) | dev->dev_addr[i*2]; + #endif } /* SOPAS */ for (i = 0; i < 3; i++) { *************** *** 1726,1739 **** --- 1791,1822 ---- * ECRETRY=1 * ATP=1 */ + #if defined(CONFIG_EMMA) + np->tx_config = TxAutoPad | TxCollRetry | TxMxdma_32 | (0x1020); + #else + #ifdef CHIP1S_DMA_WORKAROUND + np->tx_config = TxAutoPad | TxCollRetry | TxMxdma_4 | + TX_FLTH_VAL | TX_DRTH_VAL_START; + #else np->tx_config = TxAutoPad | TxCollRetry | TxMxdma_256 | TX_FLTH_VAL | TX_DRTH_VAL_START; + #endif + #endif /* CONFIG_EMMA */ writel(np->tx_config, ioaddr + TxConfig); /* DRTH 0x10: start copying to memory if 128 bytes are in the fifo * MXDMA 0: up to 256 byte bursts */ + #if defined(CONFIG_EMMA) + np->rx_config = RxMxdma_32 | 0x20; + #else + #ifdef CHIP1S_DMA_WORKAROUND + np->rx_config = RxMxdma_64 | RX_DRTH_VAL; + #else np->rx_config = RxMxdma_256 | RX_DRTH_VAL; + #endif + #endif /* CONFIG_EMMA */ + /* if receive ring now has bigger buffers than normal, enable jumbo */ if (np->rx_buf_sz > NATSEMI_LONGPKT) np->rx_config |= RxAcceptLong; *************** *** 1902,1907 **** --- 1985,1994 ---- np->rx_ring = pci_alloc_consistent(np->pci_dev, sizeof(struct netdev_desc) * (RX_RING_SIZE+TX_RING_SIZE), &np->ring_dma); + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + if( rpci_check_device(np->pci_dev)==2) + np->ring_dma = np->ring_dma + BOARD3A_PCI_DMABASE; + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ if (!np->rx_ring) return -ENOMEM; np->tx_ring = &np->rx_ring[RX_RING_SIZE]; *************** *** 1917,1931 **** --- 2004,2033 ---- struct sk_buff *skb; int entry = np->dirty_rx % RX_RING_SIZE; if (np->rx_skbuff[entry] == NULL) { + #ifdef CHIP1S_DMA_WORKAROUND + unsigned int buflen = np->rx_buf_sz+NATSEMI_PADDING + (DMABURST_ALIGN - 1); + #else unsigned int buflen = np->rx_buf_sz+NATSEMI_PADDING; + #endif skb = dev_alloc_skb(buflen); np->rx_skbuff[entry] = skb; if (skb == NULL) break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ + #ifdef CHIP1S_DMA_WORKAROUND + skb->tail = (unsigned char *) (((unsigned long) skb->tail + (DMABURST_ALIGN - 1)) + & (~(DMABURST_ALIGN - 1))); + #endif np->rx_dma[entry] = pci_map_single(np->pci_dev, skb->tail, buflen, PCI_DMA_FROMDEVICE); + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + if( rpci_check_device(np->pci_dev)==2) + np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry] + BOARD3A_PCI_DMABASE ); + else + np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); + #else /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ } np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz); } *************** *** 2080,2087 **** np->tx_skbuff[entry] = skb; np->tx_dma[entry] = pci_map_single(np->pci_dev, skb->data,skb->len, PCI_DMA_TODEVICE); ! np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]); spin_lock_irq(&np->lock); --- 2182,2195 ---- np->tx_skbuff[entry] = skb; np->tx_dma[entry] = pci_map_single(np->pci_dev, skb->data,skb->len, PCI_DMA_TODEVICE); ! #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) ! if( rpci_check_device(np->pci_dev)==2) ! np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry] + BOARD3A_PCI_DMABASE ); ! else ! np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]); ! #else /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ np->tx_ring[entry].addr = cpu_to_le32(np->tx_dma[entry]); + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ spin_lock_irq(&np->lock); *************** *** 3128,3138 **** --- 3236,3252 ---- struct net_device *dev = pci_get_drvdata(pdev); void __iomem * ioaddr = ns_ioaddr(dev); + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + if( rpci_check_device(pdev)!=2){ + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ unregister_netdev (dev); pci_release_regions (pdev); iounmap(ioaddr); free_netdev (dev); pci_set_drvdata(pdev, NULL); + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + } + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ } #ifdef CONFIG_PM *************** *** 3253,3264 **** --- 3367,3383 ---- static int __init natsemi_init_mod (void) { + extern int rpci_module_init(struct pci_driver *pci_drv); /* when a module, this is printed whether or not devices are found in probe */ #ifdef MODULE printk(version); #endif + #if defined(CONFIG_REMOTE_PCI) && defined(CONFIG_NATSEMI_BOARD3A) + return rpci_module_init (&natsemi_driver); + #else return pci_module_init (&natsemi_driver); + #endif /* CONFIG_REMOTE_PCI && CONFIG_NATSEMI_BOARD3A */ } static void __exit natsemi_exit_mod (void) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/net/ne.c linux-current/drivers/net/ne.c *** linux-2.6.10/drivers/net/ne.c Sat Dec 25 06:34:33 2004 --- linux-current/drivers/net/ne.c Wed Jun 14 21:12:59 2006 *************** *** 137,143 **** # define DCR_VAL 0x49 #endif ! 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); --- 137,143 ---- # define DCR_VAL 0x49 #endif ! static int ne_probe1(struct net_device *dev, unsigned long ioaddr); static int ne_probe_isapnp(struct net_device *dev); static int ne_open(struct net_device *dev); *************** *** 175,181 **** static int __init do_ne_probe(struct net_device *dev) { ! unsigned int base_addr = dev->base_addr; #ifndef MODULE int orig_irq = dev->irq; #endif --- 175,181 ---- static int __init do_ne_probe(struct net_device *dev) { ! unsigned long base_addr = dev->base_addr; #ifndef MODULE int orig_irq = dev->irq; #endif *************** *** 195,201 **** #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]; dev->irq = orig_irq; if (ne_probe1(dev, ioaddr) == 0) return 0; --- 195,201 ---- #ifndef MODULE /* Last resort. The semi-risky ISA auto-probe. */ for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { ! unsigned long ioaddr = netcard_portlist[base_addr]; dev->irq = orig_irq; if (ne_probe1(dev, ioaddr) == 0) return 0; *************** *** 286,292 **** return -ENODEV; } ! static int __init ne_probe1(struct net_device *dev, int ioaddr) { int i; unsigned char SA_prom[32]; --- 286,292 ---- return -ENODEV; } ! static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) { int i; unsigned char SA_prom[32]; *************** *** 325,331 **** if (ei_debug && version_printed++ == 0) printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); ! 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 --- 325,331 ---- 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); /* 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 *************** *** 334,339 **** --- 334,342 ---- cause the driver to skip these parts of the probe. */ bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad)); + #ifdef CONFIG_TX_BOARDS /* RBTX4927 */ + bad_card |= ((dev->base_addr != 0) && (dev->mem_end == 0xbad2)); + #endif /* Reset card. Who knows what dain-bramaged state it was left in. */ *************** *** 505,512 **** } #endif ! 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; --- 508,515 ---- } #endif ! printk("\nNE*000: %s found at %#lx, using IRQ %d.\n", ! name, ioaddr, dev->irq); ei_status.name = name; ei_status.tx_start_page = start_page; *************** *** 528,533 **** --- 531,547 ---- ei_status.block_output = &ne_block_output; ei_status.get_8390_hdr = &ne_get_8390_hdr; ei_status.priv = 0; + #ifdef CONFIG_TX_BOARDS /* RBTX4927 */ + if (dev->mem_end == 0xbad2 && ei_status.word16) { + /* override word16 */ + printk(KERN_INFO "NE*000: forcing byte access.\n"); + ei_status.word16 = 0; + /* override stop_page (RTL8019 byte-mdde limitation) */ + if (ei_status.stop_page > 0x60) + ei_status.stop_page = 0x60; + printk(KERN_INFO "NE*000: stop_page 0x%x.\n", ei_status.stop_page); + } + #endif dev->open = &ne_open; dev->stop = &ne_close; #ifdef CONFIG_NET_POLL_CONTROLLER diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/net/smc91x.h linux-current/drivers/net/smc91x.h *** linux-2.6.10/drivers/net/smc91x.h Sat Dec 25 06:35:23 2004 --- linux-current/drivers/net/smc91x.h Wed Jun 14 21:12:59 2006 *************** *** 55,60 **** --- 55,101 ---- #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_EMMA) + + #define SMC_CAN_USE_8BIT 0 + #define SMC_CAN_USE_16BIT 1 + #define SMC_CAN_USE_32BIT 0 + #define SMC_NOWAIT 0 + + #define SMC_IO_SHIFT 0 + + #define SMC_inb(a, r) __raw_inb((a) + (r)) + #define SMC_inw(a, r) __raw_inw((a) + (r)) + #define SMC_outb(v, a, r) __raw_outb(v, (a) + (r)) + #define SMC_outw(v, a, r) __raw_outw(v, (a) + (r)) + + static inline void __raw_outsw(unsigned long port, void *addr, + unsigned int count) + { + volatile unsigned short *__addr = addr; + + while (count--) { + outw(*__addr, port); + __addr++; + } + } + + static inline void __raw_insw(unsigned long port, void *addr, + unsigned int count) + { + volatile unsigned short *__addr = addr; + + while (count--) { + *__addr = inw(port); + __addr++; + } + } + + #define SMC_insw(a, r, p, l) __raw_insw((a) + (r), p, l) + #define SMC_outsw(a, r, p, l) __raw_outsw((a) + (r), p, l) + + #define set_irq_type(irq, type) do {} 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. */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/pci/pci.ids linux-current/drivers/pci/pci.ids *** linux-2.6.10/drivers/pci/pci.ids Sat Dec 25 06:34:57 2004 --- linux-current/drivers/pci/pci.ids Wed Jun 14 21:12:59 2006 *************** *** 1436,1443 **** --- 1436,1446 ---- 102e Olivetti Advanced Technology 102f Toshiba America 0009 r4x00 + 000a TX3927 0020 ATM Meteor 155 102f 00f8 ATM Meteor 155 + 0030 TC35815CF + 0031 TC35815 with Wake on LAN 0105 TC86C001 [goku-s] IDE 0106 TC86C001 [goku-s] USB 1.1 Host 0107 TC86C001 [goku-s] USB Device Controller diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/pci/probe.c linux-current/drivers/pci/probe.c *** linux-2.6.10/drivers/pci/probe.c Sat Dec 25 06:35:23 2004 --- linux-current/drivers/pci/probe.c Wed Jun 14 21:12:59 2006 *************** *** 8,13 **** --- 8,14 ---- #include #include + #undef DEBUG #ifdef DEBUG *************** *** 630,635 **** --- 631,653 ---- dev->device = (l >> 16) & 0xffff; dev->cfg_size = pci_cfg_space_size(dev); + #if defined(CONFIG_TOSHIBA_CHIP1S) || defined(CONFIG_EMMA) + { + extern int (*txboard_pci_scan_hook)(struct pci_dev *dev); + if (txboard_pci_scan_hook){ + int ret; + ret = txboard_pci_scan_hook(dev); + if(ret==0) { + printk("bus=%d,devfn=0x%x,vid=0x%x,did=0x%x, SKIPPED\n",bus->number,devfn,dev->vendor,dev->device); + kfree(dev); + return NULL; + }else if(ret != 1){ + return (struct pci_dev *)ret; + } + } + } + #endif + /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer) set this higher, assuming the system even supports it. */ dev->dma_mask = 0xffffffff; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/scsi/hosts.c linux-current/drivers/scsi/hosts.c *** linux-2.6.10/drivers/scsi/hosts.c Sat Dec 25 06:33:50 2004 --- linux-current/drivers/scsi/hosts.c Tue Sep 5 14:52:50 2006 *************** *** 73,80 **** **/ void scsi_remove_host(struct Scsi_Host *shost) { - scsi_forget_host(shost); scsi_host_cancel(shost, 0); scsi_proc_host_rm(shost); set_bit(SHOST_DEL, &shost->shost_state); --- 73,80 ---- **/ void scsi_remove_host(struct Scsi_Host *shost) { scsi_host_cancel(shost, 0); + scsi_forget_host(shost); scsi_proc_host_rm(shost); set_bit(SHOST_DEL, &shost->shost_state); *************** *** 289,294 **** --- 289,303 ---- rval = kernel_thread(scsi_error_handler, shost, 0); if (rval < 0) goto fail_destroy_freelist; + #ifdef CONFIG_USB_RTSCHED + { + struct sched_param scsi_error_handler_sched_param = { sched_priority: CONFIG_USB_RTSCHED_PRIO }; + mm_segment_t old_fs = get_fs(); + set_fs(get_ds()); + sched_setscheduler(rval, SCHED_FIFO, &scsi_error_handler_sched_param); + set_fs(old_fs); + } + #endif wait_for_completion(&complete); shost->eh_notify = NULL; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/scsi/sata_sil.c linux-current/drivers/scsi/sata_sil.c *** linux-2.6.10/drivers/scsi/sata_sil.c Sat Dec 25 06:33:48 2004 --- linux-current/drivers/scsi/sata_sil.c Wed Jun 14 21:12:59 2006 *************** *** 40,49 **** --- 40,63 ---- #define DRV_NAME "sata_sil" #define DRV_VERSION "0.8" + // Fix PCI retry issue. + #define CONFIG_SCSI_SATA_SIL_BUG_FIX + enum { sil_3112 = 0, sil_3114 = 1, + #ifdef CONFIG_SCSI_SATA_SIL_BUG_FIX + SIL_FIFO_R0 = 0x40, + SIL_FIFO_W0 = 0x41, + SIL_FIFO_R1 = 0x44, + SIL_FIFO_W1 = 0x45, + SIL_FIFO_R2 = 0x240, + SIL_FIFO_W2 = 0x241, + SIL_FIFO_R3 = 0x244, + SIL_FIFO_W3 = 0x245, + #endif + SIL_SYSCFG = 0x48, SIL_MASK_IDE0_INT = (1 << 22), SIL_MASK_IDE1_INT = (1 << 23), *************** *** 192,197 **** --- 206,220 ---- MODULE_DEVICE_TABLE(pci, sil_pci_tbl); MODULE_VERSION(DRV_VERSION); + #ifdef CONFIG_SCSI_SATA_SIL_BUG_FIX + static unsigned char sil_get_device_cache_line(struct pci_dev *pdev) + { + u8 cache_line = 0; + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line); + return cache_line; + } + #endif + static void sil_post_set_mode (struct ata_port *ap) { struct ata_host_set *host_set = ap->host_set; *************** *** 333,338 **** --- 356,364 ---- int rc; unsigned int i; u32 tmp, irq_mask; + #ifdef CONFIG_SCSI_SATA_SIL_BUG_FIX + u8 cls; + #endif if (!printed_version++) printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); *************** *** 395,400 **** --- 421,447 ---- ata_std_ports(&probe_ent->port[i]); } + #ifdef CONFIG_SCSI_SATA_SIL_BUG_FIX + /* Initialize FIFO PCI bus arbitration */ + cls = sil_get_device_cache_line(pdev); + if (cls) { + cls >>= 3; + cls++; /* cls = (line_size/8)+1 */ + writeb(cls, mmio_base + SIL_FIFO_R0); + writeb(cls, mmio_base + SIL_FIFO_W0); + writeb(cls, mmio_base + SIL_FIFO_R1); + writeb(cls, mmio_base + SIL_FIFO_W1); + if (ent->driver_data == sil_3114) { + writeb(cls, mmio_base + SIL_FIFO_R2); + writeb(cls, mmio_base + SIL_FIFO_W2); + writeb(cls, mmio_base + SIL_FIFO_R3); + writeb(cls, mmio_base + SIL_FIFO_W3); + } + } else + printk(KERN_WARNING DRV_NAME "(%s): cache line size not set. Driver may not function\n", + pci_name(pdev)); + #endif + if (ent->driver_data == sil_3114) { irq_mask = SIL_MASK_4PORT; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/scsi/scsi_error.c linux-current/drivers/scsi/scsi_error.c *** linux-2.6.10/drivers/scsi/scsi_error.c Sat Dec 25 06:33:48 2004 --- linux-current/drivers/scsi/scsi_error.c Fri May 25 17:14:30 2007 *************** *** 907,912 **** --- 907,913 ---- return 1; } + #ifndef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT /** * scsi_eh_stu - send START_UNIT if needed * @shost: scsi host being recovered. *************** *** 1018,1023 **** --- 1019,1025 ---- return list_empty(work_q); } + #endif /** * scsi_try_bus_reset - ask host to perform a bus reset *************** *** 1502,1509 **** --- 1504,1517 ---- struct list_head *work_q, struct list_head *done_q) { + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + // It is not necessary. + // Because, if the command is aborted, device reset has + // already issued. + #else if (!scsi_eh_stu(shost, work_q, done_q)) if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) + #endif if (!scsi_eh_bus_reset(shost, work_q, done_q)) if (!scsi_eh_host_reset(work_q, done_q)) scsi_eh_offline_sdevs(work_q, done_q); *************** *** 1522,1527 **** --- 1530,1543 ---- list_for_each_safe(lh, lh_sf, done_q) { scmd = list_entry(lh, struct scsi_cmnd, eh_entry); list_del_init(lh); + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + if ((scmd->sense_buffer[2] & 0xf) == NOT_READY) { + // Don't need to retry the command. + // Because, in this case, the media is not ready. + // So, I/O request to Media is meaningless. + scmd->allowed = 1; + } + #endif if (scsi_device_online(scmd->device) && !blk_noretry_request(scmd->request) && (++scmd->retries < scmd->allowed)) { *************** *** 1529,1534 **** --- 1545,1559 ---- " retry cmd: %p\n", current->comm, scmd)); + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + // The default timeout value might be shorten to detect + // the removal status. So modify timeout value for resending + // the command. + // For this feature, we use "timeout" field if "timeout" is specified. + // This value will set by SCSI Disk driver. + if (scmd->timeout) + scmd->timeout_per_command = scmd->timeout; + #endif scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY); } else { if (!scmd->result) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/scsi/scsi_proc.c linux-current/drivers/scsi/scsi_proc.c *** linux-2.6.10/drivers/scsi/scsi_proc.c Sat Dec 25 06:33:51 2004 --- linux-current/drivers/scsi/scsi_proc.c Wed Jun 14 21:12:59 2006 *************** *** 49,55 **** --- 49,66 ---- struct Scsi_Host *shost = data; int n; + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + down(&global_host_template_sem); + n = 0; + if (scsi_host_lookup(shost->host_no) == shost) { + if (shost->hostt->proc_info) + n = shost->hostt->proc_info(shost, buffer, start, offset, length, 0); + scsi_host_put(shost); + } + up(&global_host_template_sem); + #else n = shost->hostt->proc_info(shost, buffer, start, offset, length, 0); + #endif *eof = (n < length); return n; *************** *** 71,77 **** --- 82,98 ---- ret = -EFAULT; if (copy_from_user(page, buf, count)) goto out; + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + down(&global_host_template_sem); + if (scsi_host_lookup(shost->host_no) == shost) { + if (shost->hostt->proc_info) + ret = shost->hostt->proc_info(shost, page, &start, 0, count, 1); + scsi_host_put(shost); + } + up(&global_host_template_sem); + #else ret = shost->hostt->proc_info(shost, page, &start, 0, count, 1); + #endif } out: free_page((unsigned long)page); *************** *** 139,145 **** --- 160,172 ---- return; sprintf(name,"%d", shost->host_no); + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + down(&global_host_template_sem); + #endif remove_proc_entry(name, shost->hostt->proc_dir); + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + up(&global_host_template_sem); + #endif } static int proc_print_scsidevice(struct device *dev, void *data) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/scsi/sd.c linux-current/drivers/scsi/sd.c *** linux-2.6.10/drivers/scsi/sd.c Sat Dec 25 06:35:23 2004 --- linux-current/drivers/scsi/sd.c Wed Jun 14 21:12:59 2006 *************** *** 80,86 **** --- 80,91 ---- /* * Time out in seconds for disks and Magneto-opticals (which are slower). */ + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + #define SD_TIMEOUT (5 * HZ) + #define SD_TIMEOUT_RETRY (30 * HZ) + #else #define SD_TIMEOUT (30 * HZ) + #endif #define SD_MOD_TIMEOUT (75 * HZ) /* *************** *** 389,394 **** --- 394,402 ---- queue: SCpnt->allowed = SD_MAX_RETRIES; SCpnt->timeout_per_command = timeout; + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + SCpnt->timeout = SD_TIMEOUT_RETRY; + #endif /* * This is the completion routine we use. This is matched in terms *************** *** 734,741 **** --- 742,757 ---- static void sd_rescan(struct device *dev) { + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + struct scsi_disk *sdkp; + down(&sd_ref_sem); + sdkp = dev_get_drvdata(dev); + sd_revalidate_disk(sdkp->disk); + up(&sd_ref_sem); + #else struct scsi_disk *sdkp = dev_get_drvdata(dev); sd_revalidate_disk(sdkp->disk); + #endif } static struct block_device_operations sd_fops = { *************** *** 844,849 **** --- 860,875 ---- SCpnt->device->use_10_for_ms = 0; break; + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + case HARDWARE_ERROR: + case NOT_READY: /* Device is removed. */ + if (SCpnt->device->removable) { + struct scsi_disk *sdkp = dev_get_drvdata(&SCpnt->device->sdev_gendev); + set_media_not_present(sdkp); + } + break; + #endif + default: break; } *************** *** 1331,1337 **** struct scsi_device *sdp = sdkp->device; struct scsi_request *sreq; unsigned char *buffer; ! SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name)); /* --- 1357,1366 ---- struct scsi_device *sdp = sdkp->device; struct scsi_request *sreq; unsigned char *buffer; ! #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT ! u8 media_present; ! #endif ! SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name)); /* *************** *** 1355,1360 **** --- 1384,1393 ---- goto out_release_request; } + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + media_present = sdkp->media_present; + #endif + /* defaults, until the device tells us otherwise */ sdp->sector_size = 512; sdkp->capacity = 0; *************** *** 1369,1375 **** --- 1402,1412 ---- * Without media there is no reason to ask; moreover, some devices * react badly if we do. */ + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + if (sdkp->media_present != media_present || (sdkp->media_present && !disk->capacity)) { + #else if (sdkp->media_present) { + #endif sd_read_capacity(sdkp, disk->disk_name, sreq, buffer); if (sdp->removable) sd_read_write_protect_flag(sdkp, disk->disk_name, *************** *** 1377,1382 **** --- 1414,1422 ---- sd_read_cache_type(sdkp, disk->disk_name, sreq, buffer); } + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + if (sdkp->media_present != media_present || (sdkp->media_present && !disk->capacity)) + #endif set_capacity(disk, sdkp->capacity); kfree(buffer); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/serial/8250.c linux-current/drivers/serial/8250.c *** linux-2.6.10/drivers/serial/8250.c Sat Dec 25 06:33:50 2004 --- linux-current/drivers/serial/8250.c Wed Jun 6 11:40:44 2007 *************** *** 45,50 **** --- 45,53 ---- #include "8250.h" + #ifdef CONFIG_EMMA + #include + #endif /* * Configuration: * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option *************** *** 262,267 **** --- 265,279 ---- .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO, }, + #ifdef CONFIG_EMMA + [PORT_EMMA3] = { + .name = "EMMA3", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO, + }, + #endif }; static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset) *************** *** 287,292 **** --- 299,325 ---- static _INLINE_ void serial_out(struct uart_8250_port *up, int offset, int value) { + + #ifdef CONFIG_EMMA + if (up->port.type == PORT_EMMA3) { + if (offset == UART_LCR) { + int i; + offset <<= up->port.regshift; + + value &= ~(UART_LCR_SPAR); /* This bit is reserved. */ + + for (i=0; i<10000; i++) { /* 10 sec */ + writeb(value, up->port.membase + offset); + if (value == serial_in(up, UART_LCR)) + break; + udelay(1000); + } + readl(up->port.membase + 0x7c); + return; + } + } + #endif + offset <<= up->port.regshift; switch (up->port.iotype) { *************** *** 609,614 **** --- 642,655 ---- up->port.type = PORT_16550A; up->capabilities |= UART_CAP_FIFO; + #ifdef CONFIG_EMMA + { + if ( mips_machgroup==MACH_GROUP_EMMA3 ) { + up->port.type = PORT_EMMA3; + return; + } + } + #endif /* * Check for presence of the EFR when DLAB is set. * Only ST16C650V1 UARTs pass this test. *************** *** 955,960 **** --- 996,1016 ---- up->acr &= ~UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } + #ifdef CONFIG_EMMA + /* + * workaround: + * THRE Interrupt happen, + * only when tarnsmitter holding register becomes empty. + */ + if (up->port.type == PORT_EMMA3) { + static inline void + serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs); + + spin_lock(&up->port.lock); + serial8250_handle_port(up, NULL); + spin_unlock(&up->port.lock); + } + #endif } static void serial8250_stop_rx(struct uart_port *port) *************** *** 1174,1179 **** --- 1230,1242 ---- handled = 1; end = NULL; + #ifdef CONFIG_EMMA + } else if ( (up->port.type == PORT_EMMA3) && ((iir & 0xf) == 0x7) ) { + /* BUSY Interrupt, just clear it. */ + readl(up->port.membase + 0x7c); + handled = 1; + end = NULL; + #endif } else if (end == NULL) end = l; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/serial/Kconfig linux-current/drivers/serial/Kconfig *** linux-2.6.10/drivers/serial/Kconfig Sat Dec 25 06:35:28 2004 --- linux-current/drivers/serial/Kconfig Wed Jun 14 21:12:59 2006 *************** *** 779,782 **** --- 779,796 ---- If you use an M3T-M32700UT or an OPSPUT platform, please say Y. + config SERIAL_TXX9 + bool "TMPTX39XX/49XX SIO support" + depends on (MIPS && (TOSHIBA_BOARDS || TX_BOARDS)) || PCI + select SERIAL_CORE + + config SERIAL_TXX9_CONSOLE + bool "TMPTX39XX/49XX SIO Console support" + depends on SERIAL_TXX9=y + select SERIAL_CORE_CONSOLE + + config SERIAL_TXX9_STDSERIAL + bool "TX39XX/49XX SIO act as standard serial" + depends on !SERIAL_8250 && SERIAL_TXX9 + endmenu diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/serial/Makefile linux-current/drivers/serial/Makefile *** linux-2.6.10/drivers/serial/Makefile Sat Dec 25 06:34:45 2004 --- linux-current/drivers/serial/Makefile Wed Jun 14 21:12:59 2006 *************** *** 46,49 **** obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o obj-$(CONFIG_SERIAL_ICOM) += icom.o obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o ! obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o \ No newline at end of file --- 46,50 ---- obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o obj-$(CONFIG_SERIAL_ICOM) += icom.o obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o ! obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o ! obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/core/Kconfig linux-current/drivers/usb/core/Kconfig *** linux-2.6.10/drivers/usb/core/Kconfig Sat Dec 25 06:35:28 2004 --- linux-current/drivers/usb/core/Kconfig Wed Jun 14 21:12:59 2006 *************** *** 97,99 **** --- 97,117 ---- convenient for many stages of product development. + config USB_HUB_ENHANCEMENT + bool "USB power management enhancement" + depends on USB + ---help--- + If you say Y here, hotplug application will call when over-current + is occured and the power is not enough to configure the connected + device. + + + config USB_RTSCHED + bool "Enable real time schedule" + depends on USB + + + config USB_RTSCHED_PRIO + int "Priority setting (default is the lowest priority)" + depends on USB && USB_RTSCHED + default "1" diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/core/buffer.c linux-current/drivers/usb/core/buffer.c *** linux-2.6.10/drivers/usb/core/buffer.c Sat Dec 25 06:35:39 2004 --- linux-current/drivers/usb/core/buffer.c Wed Jun 14 21:12:59 2006 *************** *** 36,42 **** --- 36,46 ---- /* platforms without dma-friendly caches might need to * prevent cacheline sharing... */ + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + 64, + #else 32, + #endif 128, 512, PAGE_SIZE / 2 diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/core/hcd.h linux-current/drivers/usb/core/hcd.h *** linux-2.6.10/drivers/usb/core/hcd.h Sat Dec 25 06:34:30 2004 --- linux-current/drivers/usb/core/hcd.h Wed Jun 14 21:12:59 2006 *************** *** 19,24 **** --- 19,33 ---- #ifdef __KERNEL__ + #ifdef CONFIG_TOSHIBA_CHIP1S + #ifdef CONFIG_TOSHIBA_CHIP1S_SHARP1 + #define CHIP1S_PCIC_WORKAROUND + #define CHIP1S_EHCI_INTR_WORKAROUND + #define CHIP1S_EHCI_CHIRP_WORKAROUND + #endif + #define CHIP1S_EHCI_WORKAROUND + #endif + /* This file contains declarations of usbcore internals that are mostly * used or exposed by Host Controller Drivers. */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/core/hub.c linux-current/drivers/usb/core/hub.c *** linux-2.6.10/drivers/usb/core/hub.c Sat Dec 25 06:34:44 2004 --- linux-current/drivers/usb/core/hub.c Wed Jun 14 21:12:59 2006 *************** *** 36,41 **** --- 36,52 ---- #include "hcd.h" #include "hub.h" + #ifdef CONFIG_USB_HUB_ENHANCEMENT + // These definitions are for Helper Application. + #define HELPER_APPS_MAXPOWER 0 + #define HELPER_APPS_OVERCURRENT 1 + + static DECLARE_WAIT_QUEUE_HEAD(recover_wait); + + void hub_call_helper(int id); + void hub_overcurrent(struct usb_hub *hub); + #endif + /* Protect struct usb_device->state and ->children members * Note: Both are also protected by ->serialize, except that ->state can * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ *************** *** 2289,2295 **** --- 2300,2310 ---- kfree (qual); } + #ifdef CONFIG_USB_HUB_ENHANCEMENT + static signed + #else static unsigned + #endif hub_power_remaining (struct usb_hub *hub) { struct usb_device *hdev = hub->hdev; *************** *** 2327,2333 **** --- 2342,2350 ---- dev_warn(&hub->intf->dev, "%dmA over power budget!\n", -2 * remaining); + #ifndef CONFIG_USB_HUB_ENHANCEMENT remaining = 0; + #endif } return remaining; } *************** *** 2456,2461 **** --- 2473,2482 ---- schedule_work (&hub->leds); } status = -ENOTCONN; /* Don't retry */ + #ifdef CONFIG_USB_HUB_ENHANCEMENT + // Call hotplug. + hub_call_helper(HELPER_APPS_MAXPOWER); + #endif goto loop; } } *************** *** 2499,2508 **** --- 2520,2543 ---- goto loop; status = hub_power_remaining(hub); + #ifdef CONFIG_USB_HUB_ENHANCEMENT + if (status > 0) + #else if (status) + #endif dev_dbg(hub_dev, "%dmA power budget left\n", 2 * status); + #ifdef CONFIG_USB_HUB_ENHANCEMENT + else if (status < 0) { + dev_err(&udev->dev, + "doesn't have enough power to connect this port\n"); + status = -ENOTCONN; /* Don't retry */ + // Call hotplug. + hub_call_helper(HELPER_APPS_MAXPOWER); + goto loop; + } + #endif return; *************** *** 2658,2664 **** --- 2693,2710 ---- i + 1); clear_port_feature(hdev, i + 1, USB_PORT_FEAT_C_OVER_CURRENT); + #ifdef CONFIG_USB_HUB_ENHANCEMENT + // This feature is only for root hub. + if (!hdev->parent) + // Call hotplug. + // And, should turn the port power on again after + // getting the command from the application. + hub_overcurrent(hub); + else + hub_power_on(hub); + #else hub_power_on(hub); + #endif } if (portchange & USB_PORT_STAT_C_RESET) { *************** *** 2753,2758 **** --- 2799,2815 ---- } pid = kernel_thread(hub_thread, NULL, CLONE_KERNEL); + + #ifdef CONFIG_USB_RTSCHED + { + struct sched_param hubd_sched_param = { sched_priority: CONFIG_USB_RTSCHED_PRIO }; + mm_segment_t old_fs = get_fs(); + set_fs(get_ds()); + sched_setscheduler(pid, SCHED_FIFO, &hubd_sched_param); + set_fs(old_fs); + } + #endif + if (pid >= 0) { khubd_pid = pid; *************** *** 2954,2956 **** --- 3011,3102 ---- hub_port_logical_disconnect(parent, port); return -ENODEV; } + + #ifdef CONFIG_USB_HUB_ENHANCEMENT + // Launch Helper Application (/sbin/hotplug). + void + hub_call_helper( + int id) + { + #ifdef CONFIG_HOTPLUG + char *argv [3], **envp; + int value; + + if (!hotplug_path [0]) + return; + if (in_interrupt ()) { + printk("Unable to call hotplug because of In_interrupt.\n"); + return; + } + if (!current->fs->root) { + return; + } + if (!(envp = (char **) kmalloc (1 * sizeof (char *), GFP_KERNEL))) { + return; + } + + /* only one standardized param to hotplug command: type */ + argv [0] = hotplug_path; + if (id == HELPER_APPS_MAXPOWER) { + argv [1] = "hub_pwr_err"; + } + else { + argv [1] = "hub_oc_err"; + } + argv [2] = 0; + + envp [0] = 0; + + /* NOTE: user mode daemons can call the agents too */ + value = call_usermodehelper (argv [0], argv, envp, 0); + kfree (envp); + if (value != 0) + warn ("Unable to call hotplug. returned 0x%x", value); + #endif + } + + // Send the event to recover from over-current condition. + void + hub_overcurrent_recover( + void) + { + wake_up(&recover_wait); + } + + // Recover from OverCurrent condition. + static void + hub_recover_oc_thread( + void* data) + { + struct usb_hub *hub = (struct usb_hub *)data; + + /* + * This thread doesn't need any user-level access, + * so get rid of all our resources + */ + daemonize("khub_oc"); + reparent_to_init(); + + // Wait for event to recover the over-current condition. + sleep_on(&recover_wait); + + hub_power_on(hub); + + usb_remove_sysfs_overcurrent_files(&hub->hdev->dev); + } + + // This function is called when OverCurrent is detected on root hub. + void + hub_overcurrent( + struct usb_hub *hub) + { + usb_create_sysfs_overcurrent_files(&hub->hdev->dev); + + // create the recovery process. + kernel_thread((int (*)(void *)) hub_recover_oc_thread, (void *)hub, 0); + + // call helper application. + hub_call_helper(HELPER_APPS_OVERCURRENT); + } + + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/core/message.c linux-current/drivers/usb/core/message.c *** linux-2.6.10/drivers/usb/core/message.c Sat Dec 25 06:34:26 2004 --- linux-current/drivers/usb/core/message.c Wed Jun 14 21:12:59 2006 *************** *** 136,144 **** --- 136,159 ---- { struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); int ret; + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) /* BUG??? */ + void *tmpdata = NULL; + #endif if (!dr) return -ENOMEM; + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) /* BUG??? */ + if (size) { + tmpdata = kmalloc(size, GFP_NOIO); + if (!data) { + kfree(dr); + return -ENOMEM; + } + memcpy(tmpdata, data, size); + } else { + tmpdata = data; + } + #endif dr->bRequestType= requesttype; dr->bRequest = request; *************** *** 148,154 **** --- 163,177 ---- //dbg("usb_control_msg"); + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) /* BUG??? */ + ret = usb_internal_control_msg(dev, pipe, dr, tmpdata, size, timeout); + if (size) { + memcpy(data, tmpdata, size); + kfree(tmpdata); + } + #else ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); + #endif kfree(dr); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/core/sysfs.c linux-current/drivers/usb/core/sysfs.c *** linux-2.6.10/drivers/usb/core/sysfs.c Sat Dec 25 06:34:27 2004 --- linux-current/drivers/usb/core/sysfs.c Wed Jun 14 21:12:59 2006 *************** *** 308,310 **** --- 308,347 ---- device_remove_file(&intf->dev, &dev_attr_interface); } + + #ifdef CONFIG_USB_HUB_ENHANCEMENT + static ssize_t + store_overcurret_field(struct device *dev, const char *buf, size_t count) + { + const char recover_cmd[] = "recover"; + const int len = strlen(recover_cmd); + + if (strncmp(recover_cmd, buf, len) == 0) { + // Let's recover the overcurrent condition. + hub_overcurrent_recover(); + } + return count; + } + + DEVICE_ATTR(recover_oc_condition, S_IWUSR, NULL, store_overcurret_field); + + static struct attribute *overcurrent_attrs[] = { + &dev_attr_recover_oc_condition.attr, + NULL, + }; + static struct attribute_group overcurrent_attr_grp = { + .attrs = overcurrent_attrs, + }; + void usb_create_sysfs_overcurrent_files (struct device *dev) + { + sysfs_create_group(&dev->kobj, &overcurrent_attr_grp); + device_create_file(dev, &dev_attr_recover_oc_condition); + } + + void usb_remove_sysfs_overcurrent_files (struct device *dev) + { + sysfs_remove_group(&dev->kobj, &overcurrent_attr_grp); + device_remove_file(dev, &dev_attr_recover_oc_condition); + + } + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/core/usb.h linux-current/drivers/usb/core/usb.h *** linux-2.6.10/drivers/usb/core/usb.h Sat Dec 25 06:34:26 2004 --- linux-current/drivers/usb/core/usb.h Wed Jun 14 21:12:59 2006 *************** *** 48,50 **** --- 48,55 ---- unsigned long ifclaimed; }; + #ifdef CONFIG_USB_HUB_ENHANCEMENT + extern void hub_overcurrent_recover(void); + extern void usb_create_sysfs_overcurrent_files (struct device *dev); + extern void usb_remove_sysfs_overcurrent_files (struct device *dev); + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ehci-hcd.c linux-current/drivers/usb/host/ehci-hcd.c *** linux-2.6.10/drivers/usb/host/ehci-hcd.c Sat Dec 25 06:35:01 2004 --- linux-current/drivers/usb/host/ehci-hcd.c Wed Jun 14 21:12:59 2006 *************** *** 112,118 **** --- 112,122 ---- #endif /* magic numbers that can affect system performance */ + #ifdef CHIP1S_EHCI_WORKAROUND + #define EHCI_TUNE_CERR 0 /* 0-3 qtd retries; 0 == don't stop */ + #else #define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ + #endif #define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ #define EHCI_TUNE_RL_TT 0 #define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ *************** *** 136,141 **** --- 140,163 ---- #include "ehci.h" #include "ehci-dbg.c" + #ifdef CHIP1S_EHCI_INTR_WORKAROUND /* WORKAROUND USBCMD and USBSTS BUG */ + static void chip1s_sts_cmd_check(struct ehci_hcd *ehci) + { + if (ehci->iaad_set) { + u32 cmd; + cmd = readl (&ehci->regs->command); + if (!(cmd & CMD_IAAD)) { + u32 sts; + sts = readl (&ehci->regs->status); + if (!(sts & STS_IAA)) { + cmd |= CMD_IAAD; + writel (cmd, &ehci->regs->command); + (void) readl (&ehci->regs->command); + } + } + } + } + #endif /*-------------------------------------------------------------------------*/ /* *************** *** 222,227 **** --- 244,252 ---- temp = readl (&ehci->regs->command); temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); writel (temp, &ehci->regs->command); + #ifdef CHIP1S_EHCI_INTR_WORKAROUND /* WORKAROUND USBCMD and USBSTS BUG */ + ehci->iaad_set = 0; + #endif /* hardware can take 16 microframes to turn off ... */ if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, *************** *** 256,264 **** --- 281,296 ---- if (status & STS_IAA) { ehci_vdbg (ehci, "lost IAA\n"); COUNT (ehci->stats.lost_iaa); + #ifdef CHIP1S_EHCI_INTR_WORKAROUND /* WORKAROUND USBCMD and USBSTS BUG */ + ehci->iaad_set = 0; + #endif writel (STS_IAA, &ehci->regs->status); ehci->reclaim_ready = 1; } + #ifdef CHIP1S_EHCI_INTR_WORKAROUND /* WORKAROUND USBCMD and USBSTS BUG */ + else + chip1s_sts_cmd_check(ehci); + #endif } /* stop async processing after it's idled a bit */ *************** *** 461,466 **** --- 493,510 ---- if (pdev->device == PCI_DEVICE_ID_ARC_EHCI) ehci->is_arc_rh_tt = 1; break; + #ifdef CHIP1S_EHCI_WORKAROUND /* WORKAROUND USB FIFO SETTING */ + /* Please note that you must enable PCI prefetch setting if you + * want to use Linux EHCI driver. + * Because qTD have to be read by Host Controller atomically. + */ + case PCI_VENDOR_ID_TOSHIBA_2: + if (pdev->device == PCI_DEVICE_ID_TOSHIBA_CHIP1S_USB2) { + writel (EXTREG_03_64, &ehci->regs->extreg_03); + writel (EXTREG_01_64, &ehci->regs->extreg_01); + } + break; + #endif } } *************** *** 805,815 **** --- 849,867 ---- spin_unlock(&ehci->lock); return IRQ_NONE; } + #ifdef CHIP1S_EHCI_INTR_WORKAROUND /* WORKAROUND USBCMD and USBSTS BUG */ + if (status & STS_IAA) + ehci->iaad_set = 0; + #endif /* clear (just) interrupts */ writel (status, &ehci->regs->status); readl (&ehci->regs->command); /* unblock posted write */ bh = 0; + #ifdef CHIP1S_EHCI_INTR_WORKAROUND /* WORKAROUND USBCMD and USBSTS BUG */ + if (!(status & STS_IAA)) + chip1s_sts_cmd_check(ehci); + #endif #ifdef EHCI_VERBOSE_DEBUG /* unrequested/ignored: Frame List Rollover */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ehci-hub.c linux-current/drivers/usb/host/ehci-hub.c *** linux-2.6.10/drivers/usb/host/ehci-hub.c Sat Dec 25 06:35:39 2004 --- linux-current/drivers/usb/host/ehci-hub.c Wed Jun 14 21:12:59 2006 *************** *** 188,193 **** --- 188,214 ---- ehci_dbg (ehci, "port %d full speed --> companion\n", index + 1); + #ifdef CHIP1S_EHCI_CHIRP_WORKAROUND /* WORKAROUND CHIRP BUG */ + printk("port %d CHIRP BUG! full speed --> companion \n", + index + 1); + if (port_status & PORT_POWER) { + /* POWER OFF */ + port_status &= ~PORT_POWER; + writel (port_status, &ehci->regs->port_status [index]); + mdelay(10); + // printk("portsc[POWEROFF] = 0x%08x\n",readl(&ehci->regs->port_status [index])); + + /* POWER ON */ + port_status = readl(&ehci->regs->port_status [index]); + port_status |= PORT_POWER; + writel (port_status, &ehci->regs->port_status [index]); + mdelay(1); /* FIXME!! I don't know best delay-time */ + // printk("portsc[POWERON] = 0x%08x\n",readl(&ehci->regs->port_status [index])); + + port_status = readl(&ehci->regs->port_status [index]); + } + #endif + // what happens if HCS_N_CC(params) == 0 ? port_status |= PORT_OWNER; writel (port_status, &ehci->regs->port_status [index]); *************** *** 442,450 **** --- 463,488 ---- if (retval != 0) { ehci_err (ehci, "port %d reset error %d\n", wIndex + 1, retval); + #ifdef CHIP1S_EHCI_CHIRP_WORKAROUND /* WORKAROUND CHIRP BUG */ + { + struct pci_dev *pdev; + pdev = to_pci_dev(hcd->self.controller); + if ((pdev->vendor == PCI_VENDOR_ID_TOSHIBA_2) && + (pdev->device == PCI_DEVICE_ID_TOSHIBA_CHIP1S_USB2)) + printk("USB CHIRP BUG \n"); + else + goto error; + } + #else goto error; + #endif } + #ifdef CHIP1S_EHCI_CHIRP_WORKAROUND /* WORKAROUND CHIRP BUG */ + // Need to wait to detect CHIRP BUG. + // But I don't know the best delay-time. + // udelay(100000); + #endif /* see what we found out */ temp = check_reset_complete (ehci, wIndex, readl (&ehci->regs->port_status [wIndex])); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ehci-mem.c linux-current/drivers/usb/host/ehci-mem.c *** linux-2.6.10/drivers/usb/host/ehci-mem.c Sat Dec 25 06:35:28 2004 --- linux-current/drivers/usb/host/ehci-mem.c Wed Jun 14 21:12:59 2006 *************** *** 189,195 **** --- 189,199 ---- ehci->qtd_pool = dma_pool_create ("ehci_qtd", ehci->hcd.self.controller, sizeof (struct ehci_qtd), + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + 64 /* byte alignment (for hw parts) */, + #else 32 /* byte alignment (for hw parts) */, + #endif 4096 /* can't cross 4K */); if (!ehci->qtd_pool) { goto fail; *************** *** 199,205 **** --- 203,213 ---- ehci->qh_pool = dma_pool_create ("ehci_qh", ehci->hcd.self.controller, sizeof (struct ehci_qh), + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + 64 /* byte alignment (for hw parts) */, + #else 32 /* byte alignment (for hw parts) */, + #endif 4096 /* can't cross 4K */); if (!ehci->qh_pool) { goto fail; *************** *** 213,219 **** --- 221,231 ---- ehci->itd_pool = dma_pool_create ("ehci_itd", ehci->hcd.self.controller, sizeof (struct ehci_itd), + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + 64 /* byte alignment (for hw parts) */, + #else 32 /* byte alignment (for hw parts) */, + #endif 4096 /* can't cross 4K */); if (!ehci->itd_pool) { goto fail; *************** *** 223,229 **** --- 235,245 ---- ehci->sitd_pool = dma_pool_create ("ehci_sitd", ehci->hcd.self.controller, sizeof (struct ehci_sitd), + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + 64 /* byte alignment (for hw parts) */, + #else 32 /* byte alignment (for hw parts) */, + #endif 4096 /* can't cross 4K */); if (!ehci->sitd_pool) { goto fail; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ehci-q.c linux-current/drivers/usb/host/ehci-q.c *** linux-2.6.10/drivers/usb/host/ehci-q.c Sat Dec 25 06:35:24 2004 --- linux-current/drivers/usb/host/ehci-q.c Wed Jun 14 21:12:59 2006 *************** *** 1050,1055 **** --- 1050,1058 ---- cmd |= CMD_IAAD; writel (cmd, &ehci->regs->command); (void) readl (&ehci->regs->command); + #ifdef CHIP1S_EHCI_INTR_WORKAROUND /* WORKAROUND USBCMD and USBSTS BUG */ + ehci->iaad_set = 1; + #endif timer_action (ehci, TIMER_IAA_WATCHDOG); } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ehci.h linux-current/drivers/usb/host/ehci.h *** linux-2.6.10/drivers/usb/host/ehci.h Sat Dec 25 06:35:25 2004 --- linux-current/drivers/usb/host/ehci.h Wed Jun 14 21:12:59 2006 *************** *** 19,24 **** --- 19,29 ---- #ifndef __LINUX_EHCI_HCD_H #define __LINUX_EHCI_HCD_H + #ifdef CONFIG_TOSHIBA_CHIP1S_SHARP1 + #define CHIP1S_PCIC_WORKAROUND + #define CHIP1S_EHCI_INTR_WORKAROUND + #endif + /* definitions used for the EHCI driver */ /* statistics can be kept for for tuning/monitoring */ *************** *** 61,66 **** --- 66,74 ---- struct ehci_qh *reclaim; unsigned reclaim_ready : 1; unsigned scanning : 1; + #ifdef CHIP1S_EHCI_INTR_WORKAROUND /* WORKAROUND USBCMD and USBSTS BUG */ + unsigned iaad_set : 1; + #endif /* periodic schedule support */ #define DEFAULT_I_TDPS 1024 /* some HCs can do less */ *************** *** 233,239 **** --- 241,251 ---- #define FLAG_CF (1<<0) /* true: we'll support "high speed" */ /* PORTSC: offset 0x44 */ + #ifdef CHIP1S_EHCI_WORKAROUND /* WORKAROUND fix FIFO issue */ + u32 port_status [15]; /* up to N_PORTS */ + #else u32 port_status [0]; /* up to N_PORTS */ + #endif /* 31:23 reserved */ #define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */ #define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */ *************** *** 257,262 **** --- 269,285 ---- #define PORT_PE (1<<2) /* port enable */ #define PORT_CSC (1<<1) /* connect status change */ #define PORT_CONNECT (1<<0) /* device connected */ + #ifdef CHIP1S_EHCI_WORKAROUND /* WORKAROUND fix FIFO issue */ + u32 reserved1; + u32 extreg_01; + //#define EXTREG_01_64 0x00800010 + #define EXTREG_01_64 0x00FF0010 + u32 reserved2; + u32 extreg_03; + #define EXTREG_03_64 0x00000001 + u32 reserved3; + u32 reserved4; + #endif } __attribute__ ((packed)); *************** *** 298,304 **** --- 321,331 ---- struct list_head qtd_list; /* sw qtd list */ struct urb *urb; /* qtd's urb */ size_t length; /* length of buffer */ + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + } __attribute__ ((aligned (64))); + #else } __attribute__ ((aligned (32))); + #endif /* mask NakCnt+T in qh->hw_alt_next */ #define QTD_MASK __constant_cpu_to_le32 (~0x1f) *************** *** 390,396 **** --- 417,427 ---- unsigned short start; /* where polling starts */ #define NO_FRAME ((unsigned short)~0) /* pick new start */ struct usb_device *dev; /* access to TT */ + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + } __attribute__ ((aligned (64))); + #else } __attribute__ ((aligned (32))); + #endif /*-------------------------------------------------------------------------*/ *************** *** 493,499 **** --- 524,534 ---- unsigned pg; unsigned index[8]; /* in urb->iso_frame_desc */ u8 usecs[8]; + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + } __attribute__ ((aligned (64))); + #else } __attribute__ ((aligned (32))); + #endif /*-------------------------------------------------------------------------*/ *************** *** 536,542 **** --- 571,581 ---- struct list_head sitd_list; /* list of stream's sitds */ unsigned frame; unsigned index; + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + } __attribute__ ((aligned (64))); + #else } __attribute__ ((aligned (32))); + #endif /*-------------------------------------------------------------------------*/ *************** *** 556,562 **** --- 595,605 ---- /* the rest is HCD-private */ dma_addr_t fstn_dma; union ehci_shadow fstn_next; /* ptr to periodic q entry */ + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + } __attribute__ ((aligned (64))); + #else } __attribute__ ((aligned (32))); + #endif /*-------------------------------------------------------------------------*/ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ohci-hcd.c linux-current/drivers/usb/host/ohci-hcd.c *** linux-2.6.10/drivers/usb/host/ohci-hcd.c Sat Dec 25 06:33:52 2004 --- linux-current/drivers/usb/host/ohci-hcd.c Wed Jun 14 21:12:59 2006 *************** *** 578,583 **** --- 578,587 ---- (void) ohci_readl (ohci, &ohci->regs->control); } ohci_writel (ohci, ohci->fminterval, &ohci->regs->fminterval); + if (ohci->flags & OHCI_QUIRK_NEC) { + while (ohci_readl (ohci, &ohci->regs->fminterval) != ohci->fminterval) + ohci_writel (ohci, ohci->fminterval, &ohci->regs->fminterval); + } /* Tell the controller where the control and bulk lists are * The lists are empty now. */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ohci-hub.c linux-current/drivers/usb/host/ohci-hub.c *** linux-2.6.10/drivers/usb/host/ohci-hub.c Sat Dec 25 06:34:00 2004 --- linux-current/drivers/usb/host/ohci-hub.c Wed Jun 14 21:12:59 2006 *************** *** 624,629 **** --- 624,634 ---- case USB_PORT_FEAT_POWER: ohci_writel (ohci, RH_PS_PPS, &ohci->regs->roothub.portstatus [wIndex]); + if (ohci->flags & OHCI_QUIRK_NEC) { + while (!(ohci_readl(ohci, &ohci->regs->roothub.portstatus [wIndex]) & RH_PS_PPS)) + ohci_writel (ohci, RH_PS_PPS, + &ohci->regs->roothub.portstatus [wIndex]); + } break; case USB_PORT_FEAT_RESET: root_port_reset (ohci, wIndex); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ohci-mem.c linux-current/drivers/usb/host/ohci-mem.c *** linux-2.6.10/drivers/usb/host/ohci-mem.c Sat Dec 25 06:35:01 2004 --- linux-current/drivers/usb/host/ohci-mem.c Wed Jun 14 21:12:59 2006 *************** *** 46,58 **** --- 46,66 ---- { ohci->td_cache = dma_pool_create ("ohci_td", ohci->hcd.self.controller, sizeof (struct td), + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + 64 /* byte alignment */, + #else 32 /* byte alignment */, + #endif 0 /* no page-crossing issues */); if (!ohci->td_cache) return -ENOMEM; ohci->ed_cache = dma_pool_create ("ohci_ed", ohci->hcd.self.controller, sizeof (struct ed), + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + 64 /* byte alignment */, + #else 16 /* byte alignment */, + #endif 0 /* no page-crossing issues */); if (!ohci->ed_cache) { dma_pool_destroy (ohci->td_cache); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ohci-pci.c linux-current/drivers/usb/host/ohci-pci.c *** linux-2.6.10/drivers/usb/host/ohci-pci.c Sat Dec 25 06:35:23 2004 --- linux-current/drivers/usb/host/ohci-pci.c Wed Jun 14 21:12:59 2006 *************** *** 86,91 **** --- 86,100 ---- ohci_info (ohci, "Using NSC SuperIO setup\n"); } } + + /* NEC uPD720100A/uPD720101 sometimes fail the register write... + * so enable the vendor specific workaround. + */ + else if (pdev->vendor == PCI_VENDOR_ID_NEC + && pdev->device == PCI_DEVICE_ID_NEC_USB) { + ohci->flags = OHCI_QUIRK_NEC; + ohci_info (ohci, "NEC uPD720100A/uPD720101 workarounds are enabled.\n"); + } } /* NOTE: there may have already been a first reset, to diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/host/ohci.h linux-current/drivers/usb/host/ohci.h *** linux-2.6.10/drivers/usb/host/ohci.h Sat Dec 25 06:35:40 2004 --- linux-current/drivers/usb/host/ohci.h Wed Jun 14 21:12:59 2006 *************** *** 7,12 **** --- 7,16 ---- * This file is licenced under the GPL. */ + #ifdef CONFIG_TOSHIBA_CHIP1S_SHARP1 + #define CHIP1S_PCIC_WORKAROUND + #endif + /* * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to * __leXX (normally) or __beXX (given OHCI_BIG_ENDIAN), depending on the *************** *** 66,72 **** --- 70,80 ---- /* HC may see EDs on rm_list until next frame (frame_no == tick) */ u16 tick; + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + } __attribute__ ((aligned(64))); + #else } __attribute__ ((aligned(16))); + #endif #define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */ *************** *** 126,132 **** --- 134,144 ---- dma_addr_t data_dma; /* addr of data it points to */ struct list_head td_list; /* "shadow list", TDs on same ED */ + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + } __attribute__ ((aligned(64))); + #else } __attribute__ ((aligned(32))); /* c/b/i need 16; only iso needs 32 */ + #endif #define TD_MASK ((u32)~0x1f) /* strip hw status in low addr bits */ *************** *** 401,406 **** --- 413,419 ---- #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ #define OHCI_BIG_ENDIAN 0x08 /* big endian HC */ + #define OHCI_QUIRK_NEC 0x10 /* NEC */ // there are also chip quirks/bugs in init logic }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/input/hid-core.c linux-current/drivers/usb/input/hid-core.c *** linux-2.6.10/drivers/usb/input/hid-core.c Sat Dec 25 06:34:58 2004 --- linux-current/drivers/usb/input/hid-core.c Wed Jun 14 21:12:59 2006 *************** *** 28,33 **** --- 28,35 ---- #undef DEBUG #undef DEBUG_DATA + #define IMPROVE_REPORTS_INIT + #include #include "hid.h" *************** *** 1183,1190 **** --- 1185,1199 ---- case -ECONNRESET: /* unlink */ case -ENOENT: case -ESHUTDOWN: + #ifdef IMPROVE_REPORTS_INIT + break; + case -EPIPE: /* report not available */ + hid->quirks |= HID_QUIRK_NOGET; + break; + #else case -EPIPE: /* report not available */ break; + #endif default: /* error */ warn("ctrl urb status %d received", urb->status); } *************** *** 1338,1343 **** --- 1347,1357 ---- while (list != &report_enum->report_list) { report = (struct hid_report *) list; hid_submit_report(hid, report, USB_DIR_IN); + #ifdef IMPROVE_REPORTS_INIT + hid_wait_io(hid); + if (hid->quirks & HID_QUIRK_NOGET); + break; + #endif list = list->next; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/storage/Kconfig linux-current/drivers/usb/storage/Kconfig *** linux-2.6.10/drivers/usb/storage/Kconfig Sat Dec 25 06:35:29 2004 --- linux-current/drivers/usb/storage/Kconfig Wed Jun 14 21:12:59 2006 *************** *** 118,120 **** --- 118,126 ---- Say Y here to include additional code to support the Lexar Jumpshot USB CompactFlash reader. + config USB_STORAGE_REMOVABLE_ENHANCEMENT + bool "Enable removable media handling enhancement" + depends on USB_STORAGE + help + This enables removable media handling enhancement. + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/storage/scsiglue.c linux-current/drivers/usb/storage/scsiglue.c *** linux-2.6.10/drivers/usb/storage/scsiglue.c Sat Dec 25 06:34:45 2004 --- linux-current/drivers/usb/storage/scsiglue.c Wed Jun 14 21:12:59 2006 *************** *** 342,347 **** --- 342,355 ---- us = (struct us_data*)hostptr->hostdata[0]; + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + down(&us->dev_semaphore); + if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + up(&us->dev_semaphore); + return 0; + } + #endif + /* print the controller name */ SPRINTF(" Host scsi%d: usb-storage\n", hostptr->host_no); *************** *** 366,371 **** --- 374,383 ---- *(pos++) = '\n'; } + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + up(&us->dev_semaphore); + #endif + /* * Calculate start of next buffer, and return value. */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/storage/transport.c linux-current/drivers/usb/storage/transport.c *** linux-2.6.10/drivers/usb/storage/transport.c Sat Dec 25 06:34:31 2004 --- linux-current/drivers/usb/storage/transport.c Wed Jun 14 21:12:59 2006 *************** *** 529,534 **** --- 529,537 ---- { int need_auto_sense; int result; + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) /* BUG??? */ + unsigned char *tmpdata = NULL; + #endif /* send the command to the transport layer */ srb->resid = 0; *************** *** 636,642 **** --- 639,653 ---- /* use the new buffer we have */ old_request_buffer = srb->request_buffer; + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) /* BUG??? */ + tmpdata = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_NOIO); + if (!tmpdata) + srb->request_buffer = srb->sense_buffer; + else + srb->request_buffer = tmpdata; + #else srb->request_buffer = srb->sense_buffer; + #endif /* set the buffer length for transfer */ old_request_bufflen = srb->request_bufflen; *************** *** 654,659 **** --- 665,677 ---- old_resid = srb->resid; srb->resid = 0; temp_result = us->transport(us->srb, us); + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) /* BUG??? */ + if (tmpdata) { + memcpy(srb->sense_buffer, tmpdata, + SCSI_SENSE_BUFFERSIZE); + kfree(tmpdata); + } + #endif /* let's clean up right away */ srb->resid = old_resid; *************** *** 1114,1119 **** --- 1132,1145 ---- int result2; int rc = FAILED; + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + int timeout = 20*HZ; + + if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) { + timeout = 5*HZ; + } + #endif + /* Let the SCSI layer know we are doing a reset, set the * RESETTING bit, and clear the ABORTING bit so that the reset * may proceed. *************** *** 1130,1136 **** --- 1156,1166 ---- */ result = usb_stor_control_msg(us, us->send_ctrl_pipe, request, requesttype, value, index, data, size, + #ifdef CONFIG_USB_STORAGE_REMOVABLE_ENHANCEMENT + timeout); + #else 20*HZ); + #endif if (result < 0) { US_DEBUGP("Soft reset failed: %d\n", result); goto Done; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/storage/unusual_devs.h linux-current/drivers/usb/storage/unusual_devs.h *** linux-2.6.10/drivers/usb/storage/unusual_devs.h Sat Dec 25 06:35:24 2004 --- linux-current/drivers/usb/storage/unusual_devs.h Tue Sep 5 14:52:52 2006 *************** *** 313,321 **** US_FL_SINGLE_LUN | US_FL_MODE_XLATE ), /* This entry is needed because the device reports Sub=ff */ ! UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0500, "Sony", ! "DSC-T1", US_SC_8070, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN | US_FL_MODE_XLATE ), --- 313,321 ---- US_FL_SINGLE_LUN | US_FL_MODE_XLATE ), /* This entry is needed because the device reports Sub=ff */ ! UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0600, "Sony", ! "DSC-T1/T5", US_SC_8070, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN | US_FL_MODE_XLATE ), *************** *** 884,886 **** --- 884,906 ---- US_SC_SCSI, US_PR_SDDR55, NULL, US_FL_SINGLE_LUN), #endif + + /* Patch for NEC FOMA N900i */ + UNUSUAL_DEV( 0x0409, 0x0113, 0x0100, 0x0100, + "NEC", + "FOMA N900i", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY), + + /* Patch for NEC FOMA N900iS */ + UNUSUAL_DEV( 0x0409, 0x0122, 0x0100, 0x0100, + "NEC", + "FOMA N900iS", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY), + + UNUSUAL_DEV( 0x0411, 0x0043, 0x0000, 0x0000, + "WDC WD16", + "00JB-00GVA0", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_INQUIRY ), diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/drivers/usb/storage/usb.c linux-current/drivers/usb/storage/usb.c *** linux-2.6.10/drivers/usb/storage/usb.c Sat Dec 25 06:34:27 2004 --- linux-current/drivers/usb/storage/usb.c Wed Jun 14 21:12:59 2006 *************** *** 804,809 **** --- 804,818 ---- "Unable to start control thread\n"); return p; } + #ifdef CONFIG_USB_RTSCHED + { + struct sched_param stor_control_sched_param = { sched_priority: CONFIG_USB_RTSCHED_PRIO }; + mm_segment_t old_fs = get_fs(); + set_fs(get_ds()); + sched_setscheduler(p, SCHED_FIFO, &stor_control_sched_param); + set_fs(old_fs); + } + #endif us->pid = p; /* Wait for the thread to start */ *************** *** 1014,1019 **** --- 1023,1038 ---- goto BadDevice; } + #ifdef CONFIG_USB_RTSCHED + { + struct sched_param stor_scan_sched_param = { sched_priority: CONFIG_USB_RTSCHED_PRIO }; + mm_segment_t old_fs = get_fs(); + set_fs(get_ds()); + sched_setscheduler(result, SCHED_FIFO, &stor_scan_sched_param); + set_fs(old_fs); + } + #endif + return 0; /* We come here if there are any problems */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/Kconfig linux-current/fs/Kconfig *** linux-2.6.10/fs/Kconfig Sat Dec 25 06:34:58 2004 --- linux-current/fs/Kconfig Wed Jun 14 21:12:59 2006 *************** *** 972,977 **** --- 972,1062 ---- To compile this as a module, choose M here: the module will be called ramfs. + config PRAMFS + tristate "Persistent and Protected RAM file system support" + help + If your system has a block of fast (comparable in access speed to + system memory) and non-volatile RAM and you wish to mount a + light-weight, full-featured, and space-efficient filesystem over it, + say Y here, and read . + + To compile this as a module, choose M here: the module will be + called pramfs. + + config PRAMFS_NOWP + bool "Disable write protection (default is enabled)" + depends on PRAMFS + help + Say Y here to disable the write protect feature of PRAMFS. + + config ROOT_PRAMFS + bool "Root file system on pramfs" + depends on PRAMFS + help + Say Y if you have enabled PRAMFS, and you want to be + able to use PRAMFS as the root filesystem. To actually + have the kernel mount PRAMFS as a root file system, you + must also pass the command line parameter + "root=/dev/null rootflags=physaddr=0x********" to the kernel + (replace 0x******** with the physical address location of the + previously initialized PRAMFS memory to boot with). + + config EMMA2RH_PRAMFS_PCIMB_DMA + bool " use DMA on pramfs in PCIMB" + depends on PRAMFS + depends EMMA2RH || EMMA + + config RELAYFS_FS + tristate "Relayfs file system support" + ---help--- + Relayfs is a high-speed data relay filesystem designed to provide + an efficient mechanism for tools and facilities to relay large + amounts of data from kernel space to user space. It's not useful + on its own, and should only be enabled if other facilities that + need it are enabled, such as for example klog or the Linux Trace + Toolkit. + + See for further + information. + + This file system is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module is called relayfs. If you want to compile it as a + module, say M here and read . + + If unsure, say N. + + config KLOG_CHANNEL + bool "Enable klog debugging support" + depends on RELAYFS_FS + default n + help + If you say Y to this, a relayfs channel named klog will be created + in the root of the relayfs file system. You can write to the klog + channel using klog() or klog_raw() from within the kernel or + kernel modules, and read from the klog channel by mounting relayfs + and using read(2) to read from it (or using cat). If you're not + sure, say N. + + config KLOG_CHANNEL_AUTOENABLE + bool "Enable klog logging on startup" + depends on KLOG_CHANNEL + default y + help + If you say Y to this, the klog channel will be automatically enabled + on startup. Otherwise, to turn klog logging on, you need use + sysctl (fs.relayfs.klog_enabled). This option is used in cases where + you don't actually want the channel to be written to until it's + enabled. If you're not sure, say Y. + + config KLOG_CHANNEL_SHIFT + depends on KLOG_CHANNEL + int "klog debugging channel size (14 => 16KB, 22 => 4MB)" + range 14 22 + default 21 + help + Select klog debugging channel size as a power of 2. + endmenu menu "Miscellaneous filesystems" *************** *** 1266,1271 **** --- 1351,1414 ---- If unsure, say N. + config CRAMFS_EXPAND_SIZE + bool "Use Expand size" + depends on CRAMFS + help + If unsure, say N. + + config CRAMFS_SIZE_WIDTH + int "CramFs size width" + depends on CRAMFS && CRAMFS_EXPAND_SIZE + default "24" + help + If unsure, say 24. + + config CRAMFS_LINEAR + bool "Use linear addressing for CramFs" + depends on CRAMFS + help + This option tells the CramFs driver to load data directly from + a linear adressed memory range (usually non volatile memory + like flash) instead of going through the block device layer. + This saves some memory since no intermediate buffering is + necessary. + + This is also a prerequisite for XIP of binaries stored on the + filesystem. + + The location of the CramFs image in memory is board + dependent. Therefore, if you say Y, you must know the proper + physical address where to store the CramFs image and specify + it using the physaddr=0x******** mount option (for example: + "mount -t cramfs -o physaddr=0x100000 none /mnt"). + + If unsure, say N. + + config CRAMFS_LINEAR_XIP + bool "Support XIP on linear CramFs" + depends on CRAMFS_LINEAR + help + You must say Y to this option if you want to be able to run + applications directly from non-volatile memory. XIP + applications are marked by setting the sticky bit (ie, "chmod + +t "). A cramfs file system then needs to be + created using mkcramfs (with XIP cramfs support in + it). Applications marked for XIP execution will not be + compressed since they have to run directly from flash. + + config ROOT_CRAMFS_LINEAR + bool "Root file system on linear CramFs" + depends on CRAMFS_LINEAR + help + Say Y if you have enabled linear CramFs, and you want to be + able to use the linear CramFs image as a root file system. To + actually have the kernel mount this CramFs image as a root + file system, you must also pass the command line parameter + "root=/dev/null rootflags=physaddr=0x********" to the kernel + (replace 0x******** with the physical address location of the + linear CramFs image to boot with). + config VXFS_FS tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" help *************** *** 1297,1304 **** To compile this file system support as a module, choose M here: the module will be called hpfs. If unsure, say N. - - config QNX4FS_FS tristate "QNX4 file system support (read only)" help --- 1440,1445 ---- *************** *** 1324,1331 **** It's currently broken, so for now: answer N. - - config SYSV_FS tristate "System V/Xenix/V7/Coherent file system support" help --- 1465,1470 ---- *************** *** 1362,1369 **** If you haven't heard about all of this before, it's safe to say N. - - config UFS_FS tristate "UFS file system support (read only)" help --- 1501,1506 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/Makefile linux-current/fs/Makefile *** linux-2.6.10/fs/Makefile Sat Dec 25 06:34:58 2004 --- linux-current/fs/Makefile Wed Jun 14 21:12:59 2006 *************** *** 52,58 **** --- 52,60 ---- obj-$(CONFIG_EXT2_FS) += ext2/ obj-$(CONFIG_CRAMFS) += cramfs/ obj-$(CONFIG_RAMFS) += ramfs/ + obj-$(CONFIG_PRAMFS) += pramfs/ obj-$(CONFIG_HUGETLBFS) += hugetlbfs/ + obj-$(CONFIG_RELAYFS_FS) += relayfs/ obj-$(CONFIG_CODA_FS) += coda/ obj-$(CONFIG_MINIX_FS) += minix/ obj-$(CONFIG_FAT_FS) += fat/ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/binfmt_elf.c linux-current/fs/binfmt_elf.c *** linux-2.6.10/fs/binfmt_elf.c Sat Dec 25 06:34:33 2004 --- linux-current/fs/binfmt_elf.c Thu Aug 17 19:01:37 2006 *************** *** 1139,1144 **** --- 1139,1154 ---- if (!dump_seek(file, (off))) \ goto end_coredump; + #ifdef CONFIG_DUMP_DEFLATE_CORE + #define DUMP_SEEK_DEFLATE(x) elf_core_dump_zlib(file, obuf, zbuf); + #define DUMP_WRITE_DEFLATE(_f,_addr,_size) elf_core_dump_zlib(_f, obuf, _addr) + #define OFFSET_DEFLATE ( dataoff + def_core.total_out ) + #else + #define DUMP_SEEK_DEFLATE(x) DUMP_SEEK(x) + #define DUMP_WRITE_DEFLATE(_f,_addr,_size) dump_write(_f,_addr,_size) + #define OFFSET_DEFLATE offset + #endif + static inline void fill_elf_header(struct elfhdr *elf, int segs) { memcpy(elf->e_ident, ELFMAG, SELFMAG); *************** *** 1315,1320 **** --- 1325,1392 ---- * and then they are actually written out. If we run out of core limit * we just truncate. */ + + #ifdef CONFIG_DUMP_DEFLATE_CORE + #include + #include + #include + static z_stream def_core; + + static int elf_core_dump_zlib(struct file * file, unsigned char *ob, unsigned char *ib) + { + int zlibout = def_core.total_out; + def_core.next_in = ib; + def_core.next_out = ob; + def_core.avail_in = PAGE_SIZE; + def_core.avail_out = PAGE_SIZE; + zlib_deflate(&def_core, Z_PARTIAL_FLUSH); + return dump_write(file, ob, def_core.total_out - zlibout); + } + + static int start_zlib_dump(unsigned char **zbuf, unsigned char **obuf) + { + def_core.workspace = vmalloc(zlib_deflate_workspacesize()); + if (!def_core.workspace) { + printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize()); + return -ENOMEM; + } + + if (Z_OK != zlib_deflateInit(&def_core, 3)) { + printk(KERN_WARNING "deflateInit failed\n"); + vfree(def_core.workspace); + return -1; + } + + def_core.total_in = 0; + def_core.total_out = 0; + + *zbuf = (unsigned char *)vmalloc(PAGE_SIZE); + if( !*zbuf ) { + printk(KERN_WARNING "Failed to allocate for zero buffer\n"); + return 1; + } + + *obuf = (unsigned char *)vmalloc(PAGE_SIZE); + if( !*obuf ) { + printk(KERN_WARNING "Failed to allocate for out buffer\n"); + vfree(*zbuf); + return 1; + } + memset( *zbuf, 0, PAGE_SIZE); + + return 0; + } + + static void end_zlib_dump(unsigned char **zbuf, unsigned char **obuf) + { + zlib_deflateEnd(&def_core); + vfree(*zbuf); + vfree(*obuf); + vfree(def_core.workspace); + return; + } + #endif + static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file) { #define NUM_NOTES 6 *************** *** 1340,1345 **** --- 1412,1420 ---- #endif int thread_status_size = 0; elf_addr_t *auxv; + #ifdef CONFIG_DUMP_DEFLATE_CORE + unsigned char *obuf,*zbuf; + #endif /* * We no longer stop all VM operations. *************** *** 1516,1521 **** --- 1591,1603 ---- DUMP_SEEK(dataoff); + #ifdef CONFIG_DUMP_DEFLATE_CORE + if ( start_zlib_dump(&zbuf, &obuf) != 0 ) { + printk(KERN_WARNING "setup zlib is failed\n"); + return 1; + } + #endif + for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) { unsigned long addr; *************** *** 1530,1545 **** if (get_user_pages(current, current->mm, addr, 1, 0, 1, &page, &vma) <= 0) { ! DUMP_SEEK (file->f_pos + PAGE_SIZE); } else { if (page == ZERO_PAGE(addr)) { ! DUMP_SEEK (file->f_pos + PAGE_SIZE); } else { void *kaddr; flush_cache_page(vma, addr); kaddr = kmap(page); if ((size += PAGE_SIZE) > limit || ! !dump_write(file, kaddr, PAGE_SIZE)) { kunmap(page); page_cache_release(page); --- 1612,1627 ---- if (get_user_pages(current, current->mm, addr, 1, 0, 1, &page, &vma) <= 0) { ! DUMP_SEEK_DEFLATE (file->f_pos + PAGE_SIZE); } else { if (page == ZERO_PAGE(addr)) { ! DUMP_SEEK_DEFLATE (file->f_pos + PAGE_SIZE); } else { void *kaddr; flush_cache_page(vma, addr); kaddr = kmap(page); if ((size += PAGE_SIZE) > limit || ! !DUMP_WRITE_DEFLATE(file, kaddr, PAGE_SIZE)) { kunmap(page); page_cache_release(page); *************** *** 1556,1569 **** ELF_CORE_WRITE_EXTRA_DATA; #endif ! if ((off_t) file->f_pos != offset) { /* Sanity check */ printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", ! (off_t) file->f_pos, offset); } end_coredump: set_fs(fs); cleanup: while(!list_empty(&thread_list)) { --- 1638,1654 ---- ELF_CORE_WRITE_EXTRA_DATA; #endif ! if ((off_t) file->f_pos != OFFSET_DEFLATE) { /* Sanity check */ printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n", ! (off_t) file->f_pos, OFFSET_DEFLATE); } end_coredump: set_fs(fs); + #ifdef CONFIG_DUMP_DEFLATE_CORE + end_zlib_dump(&zbuf, &obuf); + #endif cleanup: while(!list_empty(&thread_list)) { diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/buffer.c linux-current/fs/buffer.c *** linux-2.6.10/fs/buffer.c Sat Dec 25 06:34:58 2004 --- linux-current/fs/buffer.c Thu Oct 12 22:18:40 2006 *************** *** 39,44 **** --- 39,45 ---- #include #include #include + #include static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); static void invalidate_bh_lrus(void); *************** *** 87,93 **** --- 88,96 ---- */ void __wait_on_buffer(struct buffer_head * bh) { + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_BUF_WAIT_START, 0, 0, NULL); wait_on_bit(&bh->b_state, BH_Lock, sync_buffer, TASK_UNINTERRUPTIBLE); + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_BUF_WAIT_END, 0, 0, NULL); } static void *************** *** 1790,1796 **** } while (bh != head); do { - get_bh(bh); if (!buffer_mapped(bh)) continue; /* --- 1793,1798 ---- *************** *** 1819,1825 **** */ BUG_ON(PageWriteback(page)); set_page_writeback(page); - unlock_page(page); do { struct buffer_head *next = bh->b_this_page; --- 1821,1826 ---- *************** *** 1827,1835 **** submit_bh(WRITE, bh); nr_underway++; } - put_bh(bh); bh = next; } while (bh != head); err = 0; done: --- 1828,1836 ---- submit_bh(WRITE, bh); nr_underway++; } bh = next; } while (bh != head); + unlock_page(page); err = 0; done: *************** *** 1868,1874 **** bh = head; /* Recovery: lock and submit the mapped buffers */ do { - get_bh(bh); if (buffer_mapped(bh) && buffer_dirty(bh)) { lock_buffer(bh); mark_buffer_async_write(bh); --- 1869,1874 ---- *************** *** 1891,1897 **** submit_bh(WRITE, bh); nr_underway++; } - put_bh(bh); bh = next; } while (bh != head); goto done; --- 1891,1896 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/cramfs/inode.c linux-current/fs/cramfs/inode.c *** linux-2.6.10/fs/cramfs/inode.c Sat Dec 25 06:33:50 2004 --- linux-current/fs/cramfs/inode.c Wed Jun 14 21:12:59 2006 *************** *** 11,16 **** --- 11,49 ---- * The actual compression is based on zlib, see the other files. */ + /* Linear Addressing code + * + * Copyright (C) 2000 Shane Nay. + * + * Allows you to have a linearly addressed cramfs filesystem. + * Saves the need for buffer, and the munging of the buffer. + * Savings a bit over 32k with default PAGE_SIZE, BUFFER_SIZE + * etc. Usefull on embedded platform with ROM :-). + * + * Downsides- Currently linear addressed cramfs partitions + * don't co-exist with block cramfs partitions. + * + */ + + /* + * 28-Dec-2000: XIP mode for linear cramfs + * Copyright (C) 2000 Robert Leslie + * + * 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 *************** *** 25,30 **** --- 58,64 ---- #include #include + #include static struct super_operations cramfs_ops; static struct inode_operations cramfs_dir_inode_operations; *************** *** 39,44 **** --- 73,138 ---- #define CRAMINO(x) ((x)->offset?(x)->offset<<2:1) #define OFFSET(x) ((x)->i_ino) + #ifdef CONFIG_CRAMFS_LINEAR_XIP + static int cramfs_mmap(struct file *file, struct vm_area_struct *vma) + { + unsigned long address, length; + struct inode *inode = file->f_dentry->d_inode; + struct super_block *sb = inode->i_sb; + struct cramfs_sb_info *sbi = CRAMFS_SB(sb); + + /* this is only used in the case of read-only maps for XIP */ + + if (vma->vm_flags & VM_WRITE) + return generic_file_mmap(file, vma); + + if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) + return -EINVAL; + + address = PAGE_ALIGN(sbi->linear_phys_addr + OFFSET(inode)); + address += vma->vm_pgoff << PAGE_SHIFT; + + length = vma->vm_end - vma->vm_start; + + if (length > inode->i_size) + length = inode->i_size; + + length = PAGE_ALIGN(length); + + /* + * Don't dump addresses that are not real memory to a core file. + */ + vma->vm_flags |= (VM_IO | VM_XIP); + flush_tlb_page(vma, address); + if (remap_page_range(vma, vma->vm_start, address, length, + vma->vm_page_prot)) + return -EAGAIN; + + #ifdef DEBUG_CRAMFS_XIP + printk("cramfs_mmap: mapped %s at 0x%08lx, length %lu to vma 0x%08lx" + ", page_prot 0x%08lx\n", + file->f_dentry->d_name.name, address, length, + vma->vm_start, pgprot_val(vma->vm_page_prot)); + #endif + + return 0; + } + + static struct file_operations cramfs_linear_xip_fops = { + read: generic_file_read, + mmap: cramfs_mmap, + }; + + #define CRAMFS_INODE_IS_XIP(x) ((x)->i_mode & S_ISVTX) + + #endif + + #ifdef CONFIG_CRAMFS_LINEAR + static struct backing_dev_info cramfs_backing_dev_info = { + .ra_pages = 0, /* No readahead */ + }; + #endif + static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode) { struct inode * inode = new_inode(sb); *************** *** 51,56 **** --- 145,153 ---- inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_gid = cramfs_inode->gid; + #ifdef CONFIG_CRAMFS_LINEAR + inode->i_mapping->backing_dev_info = &cramfs_backing_dev_info; + #endif /* Struct copy intentional */ inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime; inode->i_ino = CRAMINO(cramfs_inode); *************** *** 60,66 **** --- 157,167 ---- without -noleaf option. */ insert_inode_hash(inode); if (S_ISREG(inode->i_mode)) { + #ifdef CONFIG_CRAMFS_LINEAR_XIP + inode->i_fop = CRAMFS_INODE_IS_XIP(inode) ? &cramfs_linear_xip_fops : &generic_ro_fops; + #else inode->i_fop = &generic_ro_fops; + #endif inode->i_data.a_ops = &cramfs_aops; } else if (S_ISDIR(inode->i_mode)) { inode->i_op = &cramfs_dir_inode_operations; *************** *** 77,82 **** --- 178,196 ---- return inode; } + #ifdef CONFIG_CRAMFS_LINEAR + /* + * Return a pointer to the block in the linearly addressed cramfs image. + */ + static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len) + { + struct cramfs_sb_info *sbi = CRAMFS_SB(sb); + + if (!len) + return NULL; + return (void*)(sbi->linear_virt_addr + offset); + } + #else /* Not linear addressing - aka regular block mode. */ /* * We have our own block cache: don't fill up the buffer cache * with the rom-image, because the way the filesystem is set *************** *** 186,191 **** --- 300,306 ---- } return read_buffers[buffer] + offset; } + #endif /* CONFIG_CRAMFS_LINEAR */ static void cramfs_put_super(struct super_block *sb) { *************** *** 201,207 **** --- 316,326 ---- static int cramfs_fill_super(struct super_block *sb, void *data, int silent) { + #ifndef CONFIG_CRAMFS_LINEAR int i; + #else + char *p; + #endif struct cramfs_super super; unsigned long root_offset; struct cramfs_sb_info *sbi; *************** *** 215,225 **** --- 334,382 ---- sb->s_fs_info = sbi; memset(sbi, 0, sizeof(struct cramfs_sb_info)); + #ifndef CONFIG_CRAMFS_LINEAR /* Invalidate the read buffers on mount: think disk change.. */ down(&read_mutex); for (i = 0; i < READ_BUFFERS; i++) buffer_blocknr[i] = -1; + #else /* CONFIG_CRAMFS_LINEAR */ + /* + * The physical location of the cramfs image is specified as + * a mount parameter. This parameter is mandatory for obvious + * reasons. Some validation is made on the phys address but this + * is not exhaustive and we count on the fact that someone using + * this feature is supposed to know what he/she's doing. + */ + if (!data || !(p = strstr((char *)data, "physaddr="))) { + printk(KERN_ERR "cramfs: unknown physical address for linear cramfs image\n"); + goto out; + } + sbi->linear_phys_addr = simple_strtoul(p + 9, NULL, 0); + if (sbi->linear_phys_addr & (PAGE_SIZE-1)) { + printk(KERN_ERR "cramfs: physical address 0x%lx for linear cramfs isn't aligned to a page boundary\n", + sbi->linear_phys_addr); + goto out; + } + if (sbi->linear_phys_addr == 0) { + printk(KERN_ERR "cramfs: physical address for linear cramfs image can't be 0\n"); + goto out; + } + printk(KERN_INFO "cramfs: checking physical address 0x%lx for linear cramfs image\n", + sbi->linear_phys_addr); + + /* Map only one page for now. Will remap it when fs size is known. */ + sbi->linear_virt_addr = + ioremap(sbi->linear_phys_addr, PAGE_SIZE); + + if (!sbi->linear_virt_addr) { + printk(KERN_ERR "cramfs: ioremap of the linear cramfs image failed\n"); + goto out; + } + + down(&read_mutex); + #endif /* CONFIG_CRAMFS_LINEAR */ + /* Read the first block and get the superblock from it */ memcpy(&super, cramfs_read(sb, 0, sizeof(super)), sizeof(super)); up(&read_mutex); *************** *** 280,287 **** --- 437,470 ---- iput(root); goto out; } + + #ifdef CONFIG_CRAMFS_LINEAR + /* Remap the whole filesystem now */ + iounmap(sbi->linear_virt_addr); + printk(KERN_INFO "cramfs: linear cramfs image appears to be %lu KB in size\n", + sbi->size/1024); + #ifdef CONFIG_ARM + sbi->linear_virt_addr = + __ioremap(sbi->linear_phys_addr, sbi->size, L_PTE_CACHEABLE, + 1); + #elif defined(CONFIG_MIPS) /* CONFIG_ARM */ + sbi->linear_virt_addr = + __ioremap(sbi->linear_phys_addr, sbi->size, PAGE_CACHABLE_DEFAULT); + #else /* CONFIG_ARM */ + sbi->linear_virt_addr = + ioremap(sbi->linear_phys_addr, sbi->size); + #endif /* CONFIG_ARM */ + if (!sbi->linear_virt_addr) { + printk(KERN_ERR "cramfs: ioremap of the linear cramfs image failed\n"); + goto out; + } + #endif /* CONFIG_CRAMFS_LINEAR */ return 0; out: + #ifdef CONFIG_CRAMFS_LINEAR + if (sbi->linear_virt_addr) + iounmap(sbi->linear_virt_addr); + #endif /* CONFIG_CRAMFS_LINEAR */ kfree(sbi); sb->s_fs_info = NULL; return -EINVAL; *************** *** 439,444 **** --- 622,641 ---- u32 blkptr_offset = OFFSET(inode) + page->index*4; u32 start_offset, compr_len; + #ifdef CONFIG_CRAMFS_LINEAR_XIP + if(CRAMFS_INODE_IS_XIP(inode)) { + blkptr_offset = + PAGE_ALIGN(OFFSET(inode)) + + page->index * PAGE_CACHE_SIZE; + down(&read_mutex); + memcpy(page_address(page), + cramfs_read(sb, blkptr_offset, PAGE_CACHE_SIZE), + PAGE_CACHE_SIZE); + up(&read_mutex); + bytes_filled = PAGE_CACHE_SIZE; + pgdata = kmap(page); + } else { + #endif /* CONFIG_CRAMFS_LINEAR_XIP */ start_offset = OFFSET(inode) + maxblock*4; down(&read_mutex); if (page->index) *************** *** 456,461 **** --- 653,661 ---- compr_len); up(&read_mutex); } + #ifdef CONFIG_CRAMFS_LINEAR_XIP + } + #endif /* CONFIG_CRAMFS_LINEAR_XIP */ } else pgdata = kmap(page); memset(pgdata + bytes_filled, 0, PAGE_CACHE_SIZE - bytes_filled); *************** *** 496,510 **** --- 696,718 ---- static struct super_block *cramfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { + #ifdef CONFIG_CRAMFS_LINEAR + return get_sb_nodev(fs_type, flags, data, cramfs_fill_super); + #else return get_sb_bdev(fs_type, flags, dev_name, data, cramfs_fill_super); + #endif } static struct file_system_type cramfs_fs_type = { .owner = THIS_MODULE, .name = "cramfs", .get_sb = cramfs_get_sb, + #ifdef CONFIG_CRAMFS_LINEAR + .kill_sb = kill_anon_super, + #else .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, + #endif /* CONFIG_CRAMFS_LINEAR */ }; static int __init init_cramfs_fs(void) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/exec.c linux-current/fs/exec.c *** linux-2.6.10/fs/exec.c Sat Dec 25 06:34:31 2004 --- linux-current/fs/exec.c Wed Jun 14 21:12:59 2006 *************** *** 47,52 **** --- 47,53 ---- #include #include #include + #include #include #include *************** *** 1105,1110 **** --- 1106,1114 ---- if (IS_ERR(file)) goto out_kfree; + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_EXEC, 0, + file->f_dentry->d_name.len, file->f_dentry->d_name.name); + sched_exec(); bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/inode.c linux-current/fs/inode.c *** linux-2.6.10/fs/inode.c Sat Dec 25 06:35:40 2004 --- linux-current/fs/inode.c Wed Jun 14 21:12:59 2006 *************** *** 285,290 **** --- 285,295 ---- if (inode->i_data.nrpages) truncate_inode_pages(&inode->i_data, 0); clear_inode(inode); + + spin_lock(&inode_lock); + hlist_del_init(&inode->i_hash); + spin_unlock(&inode_lock); + destroy_inode(inode); nr_disposed++; } *************** *** 314,320 **** continue; invalidate_inode_buffers(inode); if (!atomic_read(&inode->i_count)) { - hlist_del_init(&inode->i_hash); list_move(&inode->i_list, dispose); inode->i_state |= I_FREEING; count++; --- 319,324 ---- *************** *** 452,458 **** if (!can_unuse(inode)) continue; } - hlist_del_init(&inode->i_hash); list_move(&inode->i_list, &freeable); inode->i_state |= I_FREEING; nr_pruned++; --- 456,461 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/ioctl.c linux-current/fs/ioctl.c *** linux-2.6.10/fs/ioctl.c Sat Dec 25 06:34:26 2004 --- linux-current/fs/ioctl.c Wed Jun 14 21:12:59 2006 *************** *** 11,16 **** --- 11,17 ---- #include #include #include + #include #include #include *************** *** 68,73 **** --- 69,76 ---- goto out; } + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_IOCTL, fd, cmd, NULL); + lock_kernel(); switch (cmd) { case FIOCLEX: diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/jffs2/fs.c linux-current/fs/jffs2/fs.c *** linux-2.6.10/fs/jffs2/fs.c Sat Dec 25 06:34:32 2004 --- linux-current/fs/jffs2/fs.c Wed Jun 14 21:12:59 2006 *************** *** 236,241 **** --- 236,243 ---- c = JFFS2_SB_INFO(inode->i_sb); jffs2_init_inode_info(f); + + down(&f->sem); ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); *************** *** 403,408 **** --- 405,412 ---- f = JFFS2_INODE_INFO(inode); jffs2_init_inode_info(f); + down(&f->sem); + memset(ri, 0, sizeof(*ri)); /* Set OS-specific defaults for new inodes */ ri->uid = cpu_to_je16(current->fsuid); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/jffs2/gc.c linux-current/fs/jffs2/gc.c *** linux-2.6.10/fs/jffs2/gc.c Sat Dec 25 06:34:29 2004 --- linux-current/fs/jffs2/gc.c Wed Jun 14 21:12:59 2006 *************** *** 602,608 **** printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset); jffs2_free_raw_node_ref(nraw); } ! if (!retried && (nraw == jffs2_alloc_raw_node_ref())) { /* Try to reallocate space and retry */ uint32_t dummy; struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size]; --- 602,608 ---- printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset); jffs2_free_raw_node_ref(nraw); } ! if (!retried && (nraw = jffs2_alloc_raw_node_ref())) { /* Try to reallocate space and retry */ uint32_t dummy; struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size]; *************** *** 661,669 **** { struct jffs2_full_dnode *new_fn; struct jffs2_raw_inode ri; jint16_t dev; char *mdata = NULL, mdatalen = 0; ! uint32_t alloclen, phys_ofs; int ret; if (S_ISBLK(JFFS2_F_I_MODE(f)) || --- 661,670 ---- { struct jffs2_full_dnode *new_fn; struct jffs2_raw_inode ri; + struct jffs2_node_frag *last_frag; jint16_t dev; char *mdata = NULL, mdatalen = 0; ! uint32_t alloclen, phys_ofs, ilen; int ret; if (S_ISBLK(JFFS2_F_I_MODE(f)) || *************** *** 699,704 **** --- 700,713 ---- goto out; } + last_frag = frag_last(&f->fragtree); + if (last_frag) + /* Fetch the inode length from the fragtree rather then + * from i_size since i_size may have not been updated yet */ + ilen = last_frag->ofs + last_frag->size; + else + ilen = JFFS2_F_I_SIZE(f); + memset(&ri, 0, sizeof(ri)); ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); *************** *** 710,716 **** ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); ! ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); --- 719,725 ---- ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); ! ri.isize = cpu_to_je32(ilen); ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); *************** *** 891,897 **** struct jffs2_raw_inode ri; struct jffs2_node_frag *frag; struct jffs2_full_dnode *new_fn; ! uint32_t alloclen, phys_ofs; int ret; D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", --- 900,906 ---- struct jffs2_raw_inode ri; struct jffs2_node_frag *frag; struct jffs2_full_dnode *new_fn; ! uint32_t alloclen, phys_ofs, ilen; int ret; D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", *************** *** 951,960 **** ri.csize = cpu_to_je32(0); ri.compr = JFFS2_COMPR_ZERO; } ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); ! ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); --- 960,978 ---- ri.csize = cpu_to_je32(0); ri.compr = JFFS2_COMPR_ZERO; } + + frag = frag_last(&f->fragtree); + if (frag) + /* Fetch the inode length from the fragtree rather then + * from i_size since i_size may have not been updated yet */ + ilen = frag->ofs + frag->size; + else + ilen = JFFS2_F_I_SIZE(f); + ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); ! ri.isize = cpu_to_je32(ilen); ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); *************** *** 1161,1167 **** D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", orig_start, orig_end, start, end)); ! BUG_ON(end > JFFS2_F_I_SIZE(f)); BUG_ON(end < orig_end); BUG_ON(start > orig_start); } --- 1179,1185 ---- D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", orig_start, orig_end, start, end)); ! D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size)); BUG_ON(end < orig_end); BUG_ON(start > orig_start); } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/jffs2/nodelist.h linux-current/fs/jffs2/nodelist.h *** linux-2.6.10/fs/jffs2/nodelist.h Sat Dec 25 06:35:50 2004 --- linux-current/fs/jffs2/nodelist.h Wed Jun 14 21:12:59 2006 *************** *** 387,392 **** --- 387,404 ---- node = node->rb_left; return rb_entry(node, struct jffs2_node_frag, rb); } + + static inline struct jffs2_node_frag *frag_last(struct rb_root *root) + { + struct rb_node *node = root->rb_node; + + if (!node) + return NULL; + while(node->rb_right) + node = node->rb_right; + return rb_entry(node, struct jffs2_node_frag, rb); + } + #define rb_parent(rb) ((rb)->rb_parent) #define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb) #define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/jffs2/super.c linux-current/fs/jffs2/super.c *** linux-2.6.10/fs/jffs2/super.c Sat Dec 25 06:34:30 2004 --- linux-current/fs/jffs2/super.c Wed Jun 14 21:12:59 2006 *************** *** 51,57 **** if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) { ! init_MUTEX_LOCKED(&ei->sem); inode_init_once(&ei->vfs_inode); } } --- 51,57 ---- if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) { ! init_MUTEX(&ei->sem); inode_init_once(&ei->vfs_inode); } } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/nfs/file.c linux-current/fs/nfs/file.c *** linux-2.6.10/fs/nfs/file.c Sat Dec 25 06:35:01 2004 --- linux-current/fs/nfs/file.c Thu Dec 7 20:41:02 2006 *************** *** 105,110 **** --- 105,113 ---- static int nfs_file_release(struct inode *inode, struct file *filp) { + /* Ensure that dirty pages are flushed out with the right creds */ + if (filp->f_mode & FMODE_WRITE) + filemap_fdatawrite(filp->f_mapping); return NFS_PROTO(inode)->file_release(inode, filp); } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/open.c linux-current/fs/open.c *** linux-2.6.10/fs/open.c Sat Dec 25 06:33:50 2004 --- linux-current/fs/open.c Wed Jun 14 21:12:59 2006 *************** *** 19,24 **** --- 19,26 ---- #include #include #include + #include + #include #include #include *************** *** 956,961 **** --- 958,965 ---- error = PTR_ERR(f); if (IS_ERR(f)) goto out_error; + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_OPEN, fd, + f->f_dentry->d_name.len, f->f_dentry->d_name.name); fd_install(fd, f); } out: *************** *** 1031,1036 **** --- 1035,1041 ---- filp = files->fd[fd]; if (!filp) goto out_unlock; + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_CLOSE, fd, 0, NULL); files->fd[fd] = NULL; FD_CLR(fd, files->close_on_exec); __put_unused_fd(files, fd); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/partitions/Kconfig linux-current/fs/partitions/Kconfig *** linux-2.6.10/fs/partitions/Kconfig Sat Dec 25 06:35:27 2004 --- linux-current/fs/partitions/Kconfig Wed Jun 14 21:12:59 2006 *************** *** 155,160 **** --- 155,164 ---- If you don't know what all this is about, say N. + config NOMBR_PARTITION + bool "No MBR partition support" + depends on PARTITION_ADVANCED && MSDOS_PARTITION + config LDM_PARTITION bool "Windows Logical Disk Manager (Dynamic Disk) support" depends on PARTITION_ADVANCED diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/partitions/msdos.c linux-current/fs/partitions/msdos.c *** linux-2.6.10/fs/partitions/msdos.c Sat Dec 25 06:35:00 2004 --- linux-current/fs/partitions/msdos.c Wed Jun 14 21:12:59 2006 *************** *** 378,383 **** --- 378,443 ---- {0, NULL}, }; + #ifdef CONFIG_NOMBR_PARTITION + #include + int check_fat(struct block_device *bdev, unsigned char* data) + { + int bpb_RootEntCnt,rootDirSectors,fatsz,bpb_RsvdSecCnt,dataSec,countOfClusters; + int totSec; + int hard_blksize = bdev_hardsect_size(bdev); + struct fat_boot_sector *b = (struct fat_boot_sector *) data; + int logical_sector_size = + CF_LE_W(get_unaligned((unsigned short *) &b->sector_size)); + if (!logical_sector_size + || (logical_sector_size & (logical_sector_size - 1))) { + printk("FAT: bogus logical sector size %d\n", + logical_sector_size); + goto out_invalid; + } + + if (!b->sec_per_clus + || (b->sec_per_clus & (b->sec_per_clus - 1))) { + printk("FAT: bogus cluster size %d\n", b->sec_per_clus); + goto out_invalid; + } + + if (logical_sector_size < hard_blksize) { + printk("FAT: logical sector size too small for device" + " (logical sector size = %d)\n", logical_sector_size); + goto out_invalid; + } + + totSec = CF_LE_W(get_unaligned((unsigned short *) &b->sectors)); + if( totSec == 0 ){ + totSec = CF_LE_L(b->total_sect); + } + bpb_RootEntCnt = CF_LE_W(get_unaligned((unsigned short *) &b->dir_entries)); + rootDirSectors = ((bpb_RootEntCnt * 32) + (logical_sector_size-1)) / logical_sector_size; + fatsz = CF_LE_W(b->fat_length); + if(fatsz==0){ + fatsz = CF_LE_L(b->fat32_length); + } + bpb_RsvdSecCnt = CF_LE_W(b->reserved); + dataSec = totSec - (bpb_RsvdSecCnt + (b->fats * fatsz) + rootDirSectors); + countOfClusters = dataSec / b->sec_per_clus; + #if 0 + printk("bpb_RootEntCnt=%d\n",bpb_RootEntCnt); + printk("rootDirSectors=%d\n",rootDirSectors); + printk("fatsz=%d\n",fatsz); + printk("bpb_RsvdSecCnt=%d\n",bpb_RsvdSecCnt); + printk("dataSec=%d\n",dataSec); + printk("countOfClusters=%d\n",countOfClusters); + #endif + if( countOfClusters == 0 ){ + printk("FAT: FileFormat is illegal\n"); + goto out_invalid; + } + return totSec; + out_invalid: + return 0; + } + #endif + int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) { int sector_size = bdev_hardsect_size(bdev) / 512; *************** *** 394,399 **** --- 454,469 ---- return 0; } + #ifdef CONFIG_NOMBR_PARTITION + /* FAT exist here if no MBR partition */ + if(data[0]==0xe9 || data[0]==0xeb){ + int totSec = check_fat(bdev,data); + if(totSec){ + put_partition(state, 1, 0, totSec); + return 1; + } + } + #endif /* * Now that the 55aa signature is present, this is probably * either the boot sector of a FAT filesystem or a DOS-type diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/Makefile linux-current/fs/pramfs/Makefile *** linux-2.6.10/fs/pramfs/Makefile Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/Makefile Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,11 ---- + # + # Makefile for the linux pram-filesystem routines. + # + + obj-$(CONFIG_PRAMFS) += pramfs.o + + pramfs-objs := balloc.o dir.o file.o fsync.o inode.o ioctl.o namei.o \ + super.o symlink.o + ifndef CONFIG_PRAMFS_NOWP + pramfs-objs += wprotect.o + endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/balloc.c linux-current/fs/pramfs/balloc.c *** linux-2.6.10/fs/pramfs/balloc.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/balloc.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,157 ---- + /* + * FILE NAME fs/pramfs/balloc.c + * + * BRIEF MODULE DESCRIPTION + * + * The blocks allocation and deallocation routines. + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + + + /* + * This just marks in-use the blocks that make up the bitmap. + * The bitmap must be writeable before calling. + */ + void pram_init_bitmap(struct super_block * sb) + { + struct pram_super_block * ps = pram_get_super(sb); + u32* bitmap = pram_get_bitmap(sb); + int blocks = ps->s_bitmap_blocks; + + memset(bitmap, 0, blocks<s_blocksize_bits); + + while (blocks >= 32) { + *bitmap++ = 0xffffffff; + blocks -= 32; + } + + if (blocks) + *bitmap = (1<> (3 + sb->s_blocksize_bits); + bitmap_block = pram_get_block_off(sb, bitmap_bnr); + bp = pram_get_block(sb, bitmap_block); + + pram_lock_block(sb, bp); + clear_bit(blocknr, bitmap); // mark the block free + pram_unlock_block(sb, bp); + + ps = pram_get_super(sb); + pram_lock_super(ps); + if (blocknr < ps->s_free_blocknr_hint) + ps->s_free_blocknr_hint = blocknr; + ps->s_free_blocks_count++; + pram_unlock_super(ps); + + unlock_super (sb); + } + + + /* + * allocate a block and return it's absolute blocknr. Zeroes out the + * block if zero set. + */ + int pram_new_block (struct super_block * sb, int* blocknr, int zero) + { + struct pram_super_block * ps; + pram_off_t bitmap_block; + unsigned long flags; + int bnr, bitmap_bnr, errval; + void* bitmap; + void* bp; + + lock_super (sb); + ps = pram_get_super(sb); + bitmap = pram_get_bitmap(sb); + + if (ps->s_free_blocks_count) { + /* find the oldest unused block */ + bnr = find_next_zero_bit(bitmap, + ps->s_blocks_count, + ps->s_free_blocknr_hint); + + if (bnr < ps->s_bitmap_blocks || bnr >= ps->s_blocks_count) { + pram_err("no free blocks found!\n"); + errval = -ENOSPC; + goto fail; + } + + pram_dbg ("allocating blocknr %d\n", bnr); + pram_lock_super(ps); + ps->s_free_blocks_count--; + ps->s_free_blocknr_hint = + (bnr < ps->s_blocks_count-1) ? bnr+1 : 0; + pram_unlock_super(ps); + } else { + pram_err("all blocks allocated\n"); + errval = -ENOSPC; + goto fail; + } + + /* + * find the block within the bitmap that contains the inuse bit + * for the unused block we just found. We need to unlock it to + * set the inuse bit. + */ + bitmap_bnr = bnr >> (3 + sb->s_blocksize_bits); + bitmap_block = pram_get_block_off(sb, bitmap_bnr); + bp = pram_get_block(sb, bitmap_block); + + pram_lock_block(sb, bp); + set_bit(bnr, bitmap); // mark the new block in use + pram_unlock_block(sb, bp); + + if (zero) { + bp = pram_get_block(sb, pram_get_block_off(sb, bnr)); + pram_lock_block(sb, bp); + memset(bp, 0, sb->s_blocksize); + pram_unlock_block(sb, bp); + } + + *blocknr = bnr; + errval = 0; + fail: + unlock_super (sb); + return errval; + } + + + unsigned long pram_count_free_blocks (struct super_block * sb) + { + struct pram_super_block * ps = pram_get_super(sb); + return ps->s_free_blocks_count; + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/dir.c linux-current/fs/pramfs/dir.c *** linux-2.6.10/fs/pramfs/dir.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/dir.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,218 ---- + /* + * FILE NAME fs/pramfs/dir.c + * + * BRIEF DESCRIPTION + * + * File operations for directories. + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + + + /* + * Parent is locked. + */ + int pram_add_link (struct dentry * dentry, struct inode * inode) + { + struct inode * dir = dentry->d_parent->d_inode; + struct pram_inode * pidir, * pi, * pitail = NULL; + unsigned long flags; + pram_off_t tail_ino, prev_ino; + const char *name = dentry->d_name.name; + int namelen = dentry->d_name.len > PRAM_NAME_LEN ? + PRAM_NAME_LEN : dentry->d_name.len; + + pidir = pram_get_inode(dir->i_sb, dir->i_ino); + pi = pram_get_inode(dir->i_sb, inode->i_ino); + + dir->i_mtime = dir->i_ctime = CURRENT_TIME; + + tail_ino = pidir->i_type.dir.tail; + if (tail_ino != 0) { + pitail = pram_get_inode(dir->i_sb, tail_ino); + pram_lock_inode(pitail); + pitail->i_d.d_next = inode->i_ino; + pram_unlock_inode(pitail); + + prev_ino = tail_ino; + + pram_lock_inode(pidir); + pidir->i_type.dir.tail = inode->i_ino; + pidir->i_mtime = dir->i_mtime.tv_sec; + pidir->i_ctime = dir->i_ctime.tv_sec; + pram_unlock_inode(pidir); + } else { + // the directory is empty + prev_ino = 0; + + pram_lock_inode(pidir); + pidir->i_type.dir.head = pidir->i_type.dir.tail = inode->i_ino; + pidir->i_mtime = dir->i_mtime.tv_sec; + pidir->i_ctime = dir->i_ctime.tv_sec; + pram_unlock_inode(pidir); + } + + + pram_lock_inode(pi); + pi->i_d.d_prev = prev_ino; + pi->i_d.d_parent = dir->i_ino; + memcpy(pi->i_d.d_name, name, namelen); + pi->i_d.d_name[namelen] = '\0'; + pram_unlock_inode(pi); + return 0; + } + + int pram_remove_link(struct inode * inode) + { + struct super_block * sb = inode->i_sb; + struct pram_inode * prev = NULL; + struct pram_inode * next = NULL; + struct pram_inode * pidir, * pi; + unsigned long flags; + + pi = pram_get_inode(sb, inode->i_ino); + pidir = pram_get_inode(sb, pi->i_d.d_parent); + if (!pidir) + return -EACCES; + + if (inode->i_ino == pidir->i_type.dir.head) { + // first inode in directory + next = pram_get_inode(sb, pi->i_d.d_next); + + if (next) { + pram_lock_inode(next); + next->i_d.d_prev = 0; + pram_unlock_inode(next); + + pram_lock_inode(pidir); + pidir->i_type.dir.head = pi->i_d.d_next; + } else { + pram_lock_inode(pidir); + pidir->i_type.dir.head = pidir->i_type.dir.tail = 0; + } + pram_unlock_inode(pidir); + } else if (inode->i_ino == pidir->i_type.dir.tail) { + // last inode in directory + prev = pram_get_inode(sb, pi->i_d.d_prev); + + pram_lock_inode(prev); + prev->i_d.d_next = 0; + pram_unlock_inode(prev); + + pram_lock_inode(pidir); + pidir->i_type.dir.tail = pi->i_d.d_prev; + pram_unlock_inode(pidir); + } else { + // somewhere in the middle + prev = pram_get_inode(sb, pi->i_d.d_prev); + next = pram_get_inode(sb, pi->i_d.d_next); + + if (prev && next) { + pram_lock_inode(prev); + prev->i_d.d_next = pi->i_d.d_next; + pram_unlock_inode(prev); + + pram_lock_inode(next); + next->i_d.d_prev = pi->i_d.d_prev; + pram_unlock_inode(next); + } + } + + pram_lock_inode(pi); + pi->i_d.d_next = pi->i_d.d_prev = pi->i_d.d_parent = 0; + pram_unlock_inode(pi); + + return 0; + } + + #define S_SHIFT 12 + static unsigned int dtype_by_mode[S_IFMT >> S_SHIFT] = { + [S_IFREG >> S_SHIFT] DT_REG, + [S_IFDIR >> S_SHIFT] DT_DIR, + [S_IFCHR >> S_SHIFT] DT_CHR, + [S_IFBLK >> S_SHIFT] DT_BLK, + [S_IFIFO >> S_SHIFT] DT_FIFO, + [S_IFSOCK >> S_SHIFT] DT_SOCK, + [S_IFLNK >> S_SHIFT] DT_LNK, + }; + + static int + pram_readdir (struct file * filp, void * dirent, filldir_t filldir) + { + struct inode *inode = filp->f_dentry->d_inode; + struct super_block * sb = inode->i_sb; + struct pram_inode * pi; + int namelen, ret=0; + char *name; + ino_t ino; + + if (filp->f_pos >> 32) + return 0; + + pi = pram_get_inode(sb, inode->i_ino); + + switch ((unsigned long)filp->f_pos) { + case 0: + ret = filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR); + filp->f_pos++; + return ret; + case 1: + ret = filldir(dirent, "..", 2, 1, pi->i_d.d_parent, DT_DIR); + ino = pi->i_type.dir.head; + filp->f_pos = ino ? ino : 2; + return ret; + case 2: + ino = pi->i_type.dir.head; + if (ino) { + filp->f_pos = ino; + pi = pram_get_inode(sb, ino); + break; + } else { + /* the directory is empty */ + filp->f_pos = 2; + return 0; + } + case 3: + return 0; + default: + ino = filp->f_pos; + pi = pram_get_inode(sb, ino); + break; + } + + while (pi && !pi->i_links_count) { + ino = filp->f_pos = pi->i_d.d_next; + pi = pram_get_inode(sb, ino); + } + + if (pi) { + name = pi->i_d.d_name; + namelen = strlen(name); + + ret = filldir(dirent, name, namelen, + filp->f_pos, ino, + dtype_by_mode[(pi->i_mode & S_IFMT)>>S_SHIFT]); + filp->f_pos = pi->i_d.d_next ? pi->i_d.d_next : 3; + } else + filp->f_pos = 3; + + return ret; + } + + struct file_operations pram_dir_operations = { + read: generic_read_dir, + readdir: pram_readdir, + ioctl: pram_ioctl, + fsync: pram_sync_file, + }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/file.c linux-current/fs/pramfs/file.c *** linux-2.6.10/fs/pramfs/file.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/file.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,228 ---- + /* + * FILE NAME fs/pramfs/file.c + * + * BRIEF DESCRIPTION + * + * File operations for files. + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + #include + + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + #include + #include + + extern struct semaphore pramfs_pcimb_lock; + extern unsigned long pcimem_phys_offset; + #endif + + static int pram_open_file(struct inode * inode, struct file * filp) + { + filp->f_flags |= O_DIRECT; + return generic_file_open(inode, filp); + } + + /* + * Called when an inode is released. Note that this is different + * from pram_open_file: open gets called at every open, but release + * gets called only when /all/ the files are closed. + */ + static int pram_release_file (struct inode * inode, struct file * filp) + { + return 0; + } + + int pram_direct_IO(int rw, struct kiocb *iocb, + const struct iovec *iov, + loff_t offset, unsigned long nr_segs) + { + struct file *file = iocb->ki_filp; + struct inode *inode = file->f_mapping->host; + struct super_block * sb = inode->i_sb; + int progress = 0, retval = 0; + struct pram_inode * pi; + void * tmp = NULL; + unsigned long blocknr, blockoff, flags; + int num_blocks, blocksize_mask, blocksize, blocksize_bits; + char __user *buf = iov->iov_base; + size_t length = iov->iov_len; + + if (length < 0) + return -EINVAL; + if ((rw == READ) && (offset + length > inode->i_size)) + length = inode->i_size - offset; + if (!length) + goto out; + + blocksize_bits = inode->i_sb->s_blocksize_bits; + blocksize = 1 << blocksize_bits; + blocksize_mask = blocksize - 1; + + /* find starting block number to access */ + blocknr = offset >> blocksize_bits; + /* find starting offset within starting block */ + blockoff = offset & blocksize_mask; + /* find number of blocks to access */ + num_blocks = (blockoff + length + blocksize_mask) >> blocksize_bits; + + if (rw == WRITE) { + // prepare a temporary buffer to hold a user data block + // for writing. + #ifndef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + tmp = kmalloc(blocksize, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + #endif + /* now allocate the data blocks we'll need */ + retval = pram_alloc_blocks(inode, blocknr, num_blocks); + if (retval) + goto fail; + } + + pi = pram_get_inode(inode->i_sb, inode->i_ino); + + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + tmp = kmalloc(blocksize+DMAADDROFFSET, GFP_KERNEL | GFP_DMA); + if (!tmp) + return -ENOMEM; + #endif + + while (length) { + int count; + pram_off_t block = pram_find_data_block(inode, blocknr++); + u8* bp = (u8*)pram_get_block(sb, block); + if (!bp) + goto fail; + + count = blockoff + length > blocksize ? + blocksize - blockoff : length; + + if (rw == READ) { + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + unsigned long pciaddr = (unsigned long)&bp[blockoff]; + unsigned long memaddr = (unsigned long)tmp + DMAADDROFFSET; + unsigned long pcioffset; + unsigned int dmacount = count; + + if ( CHECK_PCIMB_ADDR ( pciaddr ) ) { + down(&pramfs_pcimb_lock); + pcioffset = (pciaddr & 0x3); + if ( pcioffset > 0 ) { + unsigned long copysize; + pcioffset = DMAADDROFFSET - pcioffset; + copysize = ( dmacount < pcioffset ) ? + dmacount : pcioffset; + memcpy((void *)(memaddr-pcioffset), + (void *)(pciaddr), + copysize); + dmacount -= copysize; + pciaddr += copysize;; + } + dmacount &= DMAADDRMASK; + if ( dmacount ) { + dma_cache_wback_inv(memaddr,dmacount); + SET_DMA_ADDR(pciaddr,memaddr,dmacount); + START_DMA(0); + CHECK_DMA(100000); + } + if ( (dmacount + pcioffset) < count ) { + memcpy((void *)(memaddr+dmacount), + (void *)(pciaddr+dmacount), + count - (dmacount + pcioffset)); + } + up(&pramfs_pcimb_lock); + copy_to_user(buf, (void *)(memaddr-pcioffset), count); + } else + #endif + copy_to_user(buf, &bp[blockoff], count); + } else { + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + unsigned long pciaddr = (unsigned long)&bp[blockoff]; + unsigned long memaddr = (unsigned long)tmp + DMAADDROFFSET; + unsigned long pcioffset; + unsigned int dmacount = count; + if ( CHECK_PCIMB_ADDR ( pciaddr ) ) { + pram_lock_block(inode->i_sb, bp); + down(&pramfs_pcimb_lock); + pcioffset = (pciaddr & 0x3); + pcioffset = DMAADDROFFSET - pcioffset; + copy_from_user((void *)(memaddr-pcioffset), buf, count); + if ( pcioffset > 0 ) { + unsigned long copysize; + copysize = ( dmacount < pcioffset ) ? + dmacount : pcioffset; + memcpy((void *)(pciaddr), + (void *)(memaddr - pcioffset), + copysize); + dmacount -= copysize; + pciaddr += copysize;; + } + dmacount &= DMAADDRMASK; + if ( dmacount ) { + dma_cache_wback_inv(memaddr,dmacount); + SET_DMA_ADDR(pciaddr,memaddr,dmacount); + START_DMA(1); + CHECK_DMA(100000); + } + if ( (dmacount + pcioffset) < count ) { + memcpy((void *)(pciaddr+dmacount), + (void *)(memaddr+dmacount), + count - (dmacount + pcioffset)); + } + up(&pramfs_pcimb_lock); + pram_unlock_block(inode->i_sb, bp); + } else { + #endif + copy_from_user(tmp, buf, count); + + pram_lock_block(inode->i_sb, bp); + memcpy(&bp[blockoff], tmp, count); + pram_unlock_block(inode->i_sb, bp); + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + } + #endif + } + + progress += count; + buf += count; + length -= count; + blockoff = 0; + } + + retval = progress; + fail: + if (tmp) + kfree(tmp); + out: + return retval; + } + + + + struct file_operations pram_file_operations = { + llseek: generic_file_llseek, + read: generic_file_read, + write: generic_file_write, + ioctl: pram_ioctl, + mmap: generic_file_mmap, + open: pram_open_file, + release: pram_release_file, + fsync: pram_sync_file, + }; + + struct inode_operations pram_file_inode_operations = { + truncate: pram_truncate, + }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/fsync.c linux-current/fs/pramfs/fsync.c *** linux-2.6.10/fs/pramfs/fsync.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/fsync.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,30 ---- + /* + * FILE NAME fs/pramfs/fsync.c + * + * BRIEF DESCRIPTION + * + * fsync operation for directory and regular files. + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + + /* + * File may be NULL when we are called. Perhaps we shouldn't + * even pass file to fsync ? + */ + + int pram_sync_file(struct file * file, struct dentry *dentry, int datasync) + { + // FIXME: check + return 0; + } + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/inode.c linux-current/fs/pramfs/inode.c *** linux-2.6.10/fs/pramfs/inode.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/inode.c Mon Jul 31 14:42:32 2006 *************** *** 0 **** --- 1,739 ---- + /* + * FILE NAME fs/pramfs/inode.c + * + * BRIEF DESCRIPTION + * + * Inode methods (allocate/free/read/write). + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + #include + #include + #include + #include + #include + + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + #include + #include + + extern struct semaphore pramfs_pcimb_lock; + extern unsigned long pcimem_phys_offset; + #endif + + static struct backing_dev_info pram_backing_dev_info = { + .ra_pages = 0, /* No readahead */ + .memory_backed = 1, /* Does not contribute to dirty memory */ + }; + + /* + * allocate a data block for inode and return it's absolute blocknr. + * Zeroes out the block if zero set. Increments inode->i_blocks. + */ + static int + pram_new_data_block (struct inode * inode, int* blocknr, int zero) + { + unsigned long flags; + int errval = pram_new_block(inode->i_sb, blocknr, zero); + + if (!errval) { + struct pram_inode * pi = pram_get_inode(inode->i_sb, + inode->i_ino); + inode->i_blocks++; + pram_lock_inode(pi); + pi->i_blocks = inode->i_blocks; + pram_unlock_inode(pi); + } + + return errval; + } + + /* + * find the offset to the block represented by the given inode's file + * relative block number. + */ + pram_off_t pram_find_data_block(struct inode * inode, int file_blocknr) + { + struct super_block * sb = inode->i_sb; + struct pram_inode * pi; + pram_off_t * row; /* ptr to row block */ + pram_off_t * col; /* ptr to column blocks */ + pram_off_t bp = 0; + int i_row, i_col; + int N = sb->s_blocksize >> 2; // num block ptrs per block + int Nbits = sb->s_blocksize_bits - 2; + + pi = pram_get_inode(sb, inode->i_ino); + + i_row = file_blocknr >> Nbits; + i_col = file_blocknr & (N-1); + + row = pram_get_block(sb, pi->i_type.reg.row_block); + if (row) { + col = pram_get_block(sb, row[i_row]); + if (col) + bp = col[i_col]; + } + + return bp; + } + + + /* + * Free data blocks from inode starting at first_trunc_block. + */ + static void + pram_truncate_blocks(struct inode * inode, int first_trunc_block) + { + struct super_block * sb = inode->i_sb; + struct pram_inode * pi = pram_get_inode(sb, inode->i_ino); + int N = sb->s_blocksize >> 2; // num block ptrs per block + int Nbits = sb->s_blocksize_bits - 2; + int first_row_index, last_row_index; + int i, j, first_blocknr, last_blocknr, blocknr; + unsigned long flags; + pram_off_t * row; /* ptr to row block */ + pram_off_t * col; /* ptr to column blocks */ + + if (first_trunc_block >= inode->i_blocks || + !inode->i_blocks || !pi->i_type.reg.row_block) { + return; + } + + first_blocknr = first_trunc_block; + last_blocknr = inode->i_blocks - 1; + first_row_index = first_blocknr >> Nbits; + last_row_index = last_blocknr >> Nbits; + + row = pram_get_block(sb, pi->i_type.reg.row_block); + + for (i=first_row_index; i <= last_row_index; i++) { + int first_col_index = (i == first_row_index) ? + first_blocknr & (N-1) : 0; + int last_col_index = (i == last_row_index) ? + last_blocknr & (N-1) : N-1; + + col = pram_get_block(sb, row[i]); + for (j=first_col_index; j <= last_col_index; j++) { + blocknr = pram_get_blocknr(sb, col[j]); + pram_free_block(sb, blocknr); + pram_lock_block(sb, col); + col[j] = 0; + pram_unlock_block(sb, col); + } + + if (first_col_index == 0) { + blocknr = pram_get_blocknr(sb, row[i]); + pram_free_block(sb, blocknr); + pram_lock_block(sb, row); + row[i] = 0; + pram_unlock_block(sb, row); + } + } + + inode->i_blocks -= (last_blocknr - first_blocknr + 1); + + if (first_blocknr == 0) { + blocknr = pram_get_blocknr(sb, pi->i_type.reg.row_block); + pram_free_block(sb, blocknr); + pram_lock_inode(pi); + pi->i_type.reg.row_block = 0; + pram_unlock_inode(pi); + }else if((inode->i_size & (sb->s_blocksize-1)) != 0) { + int offset; + pram_off_t block; + void *bp; + + block = pram_find_data_block(inode, first_blocknr - 1); + bp = pram_get_block(sb, block); + if(bp){ + offset = (inode->i_size & (sb->s_blocksize-1)); + memset((char *)bp + offset, 0, sb->s_blocksize - offset); + } + } + pram_lock_inode(pi); + pi->i_blocks = inode->i_blocks; + pram_unlock_inode(pi); + } + + /* + * Allocate num data blocks for inode, starting at given file-relative + * block number. Any unallocated file blocks before file_blocknr + * are allocated. All blocks except the last are zeroed out. + */ + int pram_alloc_blocks(struct inode * inode, int file_blocknr, int num) + { + struct super_block * sb = inode->i_sb; + struct pram_inode * pi = pram_get_inode(sb, inode->i_ino); + int N = sb->s_blocksize >> 2; // num block ptrs per block + int Nbits = sb->s_blocksize_bits - 2; + int first_file_blocknr; + int last_file_blocknr; + int first_row_index, last_row_index; + int i, j, blocknr, errval; + unsigned long flags; + pram_off_t * row; + pram_off_t * col; + + if ((file_blocknr + num - 1)>= (N * N)) { + errval = -EINVAL; + goto fail; + } + + if (!pi->i_type.reg.row_block) { + /* alloc the 2nd order array block */ + errval = pram_new_block(sb, &blocknr, 1); + if (errval) { + pram_err("failed to alloc 2nd order array block\n"); + goto fail; + } + pram_lock_inode(pi); + pi->i_type.reg.row_block = pram_get_block_off(sb, blocknr); + pram_unlock_inode(pi); + } + + row = pram_get_block(sb, pi->i_type.reg.row_block); + + first_file_blocknr = (file_blocknr > inode->i_blocks) ? + inode->i_blocks : file_blocknr; + last_file_blocknr = file_blocknr + num - 1; + + first_row_index = first_file_blocknr >> Nbits; + last_row_index = last_file_blocknr >> Nbits; + + for (i=first_row_index; i<=last_row_index; i++) { + int first_col_index, last_col_index; + /* + * we are starting a new row, so make sure + * there is a block allocated for the row. + */ + if (!row[i]) { + /* allocate the row block */ + errval = pram_new_block(sb, &blocknr, 1); + if (errval) { + pram_err("failed to alloc row block\n"); + goto fail; + } + pram_lock_block(sb, row); + row[i] = pram_get_block_off(sb, blocknr); + pram_unlock_block(sb, row); + } + col = pram_get_block(sb, row[i]); + + first_col_index = (i == first_row_index) ? + first_file_blocknr & (N-1) : 0; + + last_col_index = (i == last_row_index) ? + last_file_blocknr & (N-1) : N-1; + + for (j=first_col_index; j<=last_col_index; j++) { + if (!col[j]) { + errval = pram_new_data_block(inode, + &blocknr, + 1); + if (errval) { + pram_err("failed to alloc " + "data block\n"); + goto fail; + } + pram_lock_block(sb, col); + col[j] = pram_get_block_off(sb, blocknr); + pram_unlock_block(sb, col); + } + } + } + + errval = 0; + fail: + return errval; + } + + + static int + pram_fill_inode(struct inode * inode, struct pram_inode * pi) + { + int ret = -EIO; + + if (pram_calc_checksum((u32*)pi, PRAM_INODE_SIZE>>2)) { + pram_err("checksum error in inode %08x\n", + (u32)inode->i_ino); + goto bad_inode; + } + + inode->i_mode = pi->i_mode; + inode->i_uid = pi->i_uid; + inode->i_gid = pi->i_gid; + inode->i_nlink = pi->i_links_count; + inode->i_size = pi->i_size; + inode->i_atime.tv_sec = pi->i_atime; + inode->i_ctime.tv_sec = pi->i_ctime; + inode->i_mtime.tv_sec = pi->i_mtime; + inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = + inode->i_ctime.tv_nsec = 0; + + /* check if the inode is active. */ + if (inode->i_nlink == 0 && (inode->i_mode == 0 || pi->i_dtime)) { + /* this inode is deleted */ + ret = -EINVAL; + goto bad_inode; + } + + inode->i_blocks = pi->i_blocks; + inode->i_blksize = inode->i_sb->s_blocksize; + inode->i_ino = pram_get_inodenr(inode->i_sb, pi); + inode->i_mapping->a_ops = &pram_aops; + inode->i_mapping->backing_dev_info = &pram_backing_dev_info; + + switch (inode->i_mode & S_IFMT) { + case S_IFREG: + inode->i_op = &pram_file_inode_operations; + inode->i_fop = &pram_file_operations; + break; + case S_IFDIR: + inode->i_op = &pram_dir_inode_operations; + inode->i_fop = &pram_dir_operations; + break; + case S_IFLNK: + inode->i_op = &pram_symlink_inode_operations; + break; + default: + inode->i_size = 0; + init_special_inode(inode, inode->i_mode, + pi->i_type.dev.rdev); + break; + } + + return 0; + + bad_inode: + make_bad_inode(inode); + return ret; + } + + static int pram_update_inode(struct inode * inode) + { + struct pram_inode * pi; + unsigned long flags; + int retval = 0; + + pi = pram_get_inode(inode->i_sb, inode->i_ino); + + pram_lock_inode(pi); + pi->i_mode = inode->i_mode; + pi->i_uid = inode->i_uid; + pi->i_gid = inode->i_gid; + pi->i_links_count = inode->i_nlink; + pi->i_size = inode->i_size; + pi->i_blocks = inode->i_blocks; + pi->i_atime = inode->i_atime.tv_sec; + pi->i_ctime = inode->i_ctime.tv_sec; + pi->i_mtime = inode->i_mtime.tv_sec; + + if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) + pi->i_type.dev.rdev = inode->i_rdev; + + pram_unlock_inode(pi); + return retval; + } + + /* + * NOTE! When we get the inode, we're the only people + * that have access to it, and as such there are no + * race conditions we have to worry about. The inode + * is not on the hash-lists, and it cannot be reached + * through the filesystem because the directory entry + * has been deleted earlier. + */ + static void pram_free_inode (struct inode * inode) + { + struct super_block * sb = inode->i_sb; + struct pram_super_block * ps; + struct pram_inode * pi; + unsigned long flags, inode_nr; + + /* + * Note: we must free any quota before locking the superblock, + * as writing the quota to disk may need the lock as well. + */ + if (!is_bad_inode(inode)) { + /* Quota is already initialized in iput() */ + DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); + } + + lock_super (sb); + clear_inode (inode); + + inode_nr = (inode->i_ino - PRAM_ROOT_INO) >> PRAM_INODE_BITS; + + pi = pram_get_inode(sb, inode->i_ino); + pram_lock_inode(pi); + pi->i_dtime = get_seconds(); + pi->i_type.reg.row_block = 0; + pram_unlock_inode(pi); + + // increment s_free_inodes_count + ps = pram_get_super(sb); + pram_lock_super(ps); + if (inode_nr < ps->s_free_inode_hint) + ps->s_free_inode_hint = inode_nr; + ps->s_free_inodes_count++; + if (ps->s_free_inodes_count == ps->s_inodes_count - 1) { + // filesystem is empty + pram_dbg ("fs is empty!\n"); + ps->s_free_inode_hint = 1; + } + pram_unlock_super(ps); + + unlock_super (sb); + } + + + struct inode * + pram_fill_new_inode(struct super_block *sb, + struct pram_inode * pi) + { + struct inode * inode = new_inode(sb); + + if (inode) { + pram_fill_inode(inode, pi); + insert_inode_hash(inode); + } + + return inode; + } + + + /* + * Called at each iput() + */ + void pram_put_inode (struct inode * inode) + { + // nothing to do + } + + /* + * Called at the last iput() if i_nlink is zero. + */ + void pram_delete_inode (struct inode * inode) + { + lock_kernel(); + + if (is_bad_inode(inode)) + goto no_delete; + + // unlink from chain in the inode's directory + pram_remove_link(inode); + inode->i_size = 0; + if (inode->i_blocks) + pram_truncate(inode); + pram_free_inode(inode); + + unlock_kernel(); + return; + no_delete: + unlock_kernel(); + clear_inode(inode); /* We must guarantee clearing of inode... */ + } + + + struct inode * pram_new_inode (const struct inode * dir, int mode) + { + struct super_block * sb; + struct pram_super_block * ps; + struct inode * inode; + struct pram_inode * pi = NULL; + unsigned long flags; + int i, errval; + ino_t ino=0; + + sb = dir->i_sb; + inode = new_inode(sb); + if (!inode) + return ERR_PTR(-ENOMEM); + + lock_super (sb); + ps = pram_get_super(sb); + + if (ps->s_free_inodes_count) { + /* find the oldest unused pram inode */ + for (i=ps->s_free_inode_hint; i < ps->s_inodes_count; i++) { + ino = PRAM_ROOT_INO + (i << PRAM_INODE_BITS); + pi = pram_get_inode(sb, ino); + /* check if the inode is active. */ + if (pi->i_links_count == 0 && (pi->i_mode == 0 || + pi->i_dtime)) { + /* this inode is deleted */ + break; + } + } + + if (i >= ps->s_inodes_count) { + pram_err("s_free_inodes_count!=0 but none free!?\n"); + errval = -ENOSPC; + goto fail; + } + + pram_dbg ("allocating inode %lu\n", ino); + pram_lock_super(ps); + ps->s_free_inodes_count--; + ps->s_free_inode_hint = (i < ps->s_inodes_count-1) ? i+1 : 0; + pram_unlock_super(ps); + } else { + pram_err("no space left to create new inode!\n"); + errval = -ENOSPC; + goto fail; + } + + // chosen inode is in ino + + inode->i_ino = ino; + inode->i_uid = current->fsuid; + + if (dir->i_mode & S_ISGID) { + inode->i_gid = dir->i_gid; + if (S_ISDIR(mode)) + mode |= S_ISGID; + } else + inode->i_gid = current->fsgid; + inode->i_mode = mode; + + inode->i_blksize = sb->s_blocksize; + inode->i_blocks = inode->i_size = 0; + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + + pram_lock_inode(pi); + pi->i_d.d_next = 0; + pi->i_d.d_prev = 0; + pi->i_dtime = 0; + pram_unlock_inode(pi); + + insert_inode_hash(inode); + pram_write_inode(inode, 0); + + unlock_super (sb); + + if(DQUOT_ALLOC_INODE(inode)) { + DQUOT_DROP(inode); + inode->i_flags |= S_NOQUOTA; + inode->i_nlink = 0; + iput(inode); + return ERR_PTR(-EDQUOT); + } + return inode; + + fail: + unlock_super(sb); + make_bad_inode(inode); + iput(inode); + return ERR_PTR(errval); + } + + + void pram_read_inode (struct inode * inode) + { + struct pram_inode * pi; + + pi = pram_get_inode(inode->i_sb, inode->i_ino); + pram_fill_inode(inode, pi); + } + + void pram_truncate (struct inode * inode) + { + int blocksize, blocksize_bits; + int blocknr; + + if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || + S_ISLNK(inode->i_mode))) + return; + if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) + return; + + blocksize_bits = inode->i_sb->s_blocksize_bits; + blocksize = 1 << blocksize_bits; + blocknr = (inode->i_size + blocksize-1) >> blocksize_bits; + + lock_kernel(); + pram_truncate_blocks(inode, blocknr); + inode->i_mtime = inode->i_ctime = CURRENT_TIME; + pram_update_inode(inode); + unlock_kernel(); + } + + + void pram_write_inode (struct inode * inode, int wait) + { + lock_kernel(); + pram_update_inode(inode); + unlock_kernel(); + } + + /* + * dirty_inode() is called from __mark_inode_dirty() + */ + void pram_dirty_inode(struct inode * inode) + { + pram_write_inode(inode, 0); + } + + + static int pram_get_and_update_block(struct inode *inode, sector_t iblock, + struct buffer_head *bh, int create) + { + struct super_block * sb = inode->i_sb; + unsigned int blocksize = 1 << inode->i_blkbits; + int err = -EIO; + unsigned long flags; + pram_off_t block; + void* bp; + + lock_kernel(); + + block = pram_find_data_block(inode, iblock); + + if (!block) { + if (!create) + goto out; + + err = pram_alloc_blocks(inode, iblock, 1); + if (err) + goto out; + block = pram_find_data_block(inode, iblock); + if (!block) { + err = -EIO; + goto out; + } + set_buffer_new(bh); + } + + bh->b_blocknr = block; + set_buffer_mapped(bh); + + /* now update the buffer synchronously */ + bp = pram_get_block(sb, block); + if (buffer_new(bh)) { + pram_lock_block(sb, bp); + memset(bp, 0, blocksize); + pram_unlock_block(sb, bp); + memset(bh->b_data, 0, blocksize); + } else { + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + if ( CHECK_PCIMB_ADDR ( (unsigned long)bp ) && + ( blocksize > 0x3 ) && + ( ( (unsigned long)bp & 0x3) > 0) ) { + down(&pramfs_pcimb_lock); + dma_cache_wback_inv((unsigned long)bh->b_data,blocksize); + SET_DMA_ADDR((unsigned long)bp, + (unsigned long)bh->b_data, + blocksize); + START_DMA(0); + CHECK_DMA(100000); + up(&pramfs_pcimb_lock); + } else + #endif + memcpy(bh->b_data, bp, blocksize); + } + flush_dcache_page(bh->b_page); + + set_buffer_uptodate(bh); + err = 0; + + out: + unlock_kernel(); + return err; + } + + static int pram_writepage(struct page *page, struct writeback_control *wbc) + { + struct inode * const inode = page->mapping->host; + struct super_block * sb = inode->i_sb; + struct buffer_head *bh, *head; + unsigned int blocksize = 1 << inode->i_blkbits; + sector_t iblock, lblock; + loff_t i_size = i_size_read(inode); + const pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; + + if (page->index > end_index) { + printk("try to write beyond end of the file.\n"); + return -EIO; + } + + BUG_ON(!PageLocked(page)); + if (!page_has_buffers(page)) + create_empty_buffers(page, blocksize, 0); + head = page_buffers(page); + + iblock = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits); + lblock = (i_size_read(inode)+blocksize-1) >> inode->i_blkbits; + bh = head; + + do { + if (!buffer_mapped(bh)) + continue; + lock_buffer(bh); + if (test_clear_buffer_dirty(bh)) { + pram_off_t block; + void* bp; + lock_kernel(); + block = pram_find_data_block(inode, iblock); + BUG_ON(bh->b_blocknr != block); + + bp = pram_get_block(sb, block); + BUG_ON(buffer_new(bh)); + + flush_dcache_page(bh->b_page); + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + if ( CHECK_PCIMB_ADDR ( (unsigned long)bp ) && + ( blocksize > 0x3 ) && + ( ( (unsigned long)bp & 0x3) > 0) ) { + down(&pramfs_pcimb_lock); + dma_cache_wback_inv((unsigned long)bh->b_data,blocksize); + SET_DMA_ADDR((unsigned long)bp, + (unsigned long)bh->b_data, + blocksize); + START_DMA(1); + CHECK_DMA(100000); + up(&pramfs_pcimb_lock); + } else + #endif + memcpy(bp, bh->b_data, blocksize); + } + unlock_buffer(bh); + } while (iblock++, (bh = bh->b_this_page) != head); + + BUG_ON(PageWriteback(page)); + unlock_page(page); + + return 0; + } + + #if 0 + static int pram_bmap(struct address_space *mapping, long block) + { + return 0; + } + #endif + + static int pram_readpage(struct file *file, struct page *page) + { + return block_read_full_page(page, pram_get_and_update_block); + } + + struct address_space_operations pram_aops = { + readpage: pram_readpage, + writepage: pram_writepage, + // bmap: pram_bmap, + direct_IO: pram_direct_IO, + }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/ioctl.c linux-current/fs/pramfs/ioctl.c *** linux-2.6.10/fs/pramfs/ioctl.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/ioctl.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,28 ---- + /* + * FILE NAME fs/pramfs/ioctl.c + * + * BRIEF DESCRIPTION + * + * Ioctl method for directory and regular files. + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + + + int pram_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, + unsigned long arg) + { + // FIXME: need any special ioctl's? + return 0; + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/namei.c linux-current/fs/pramfs/namei.c *** linux-2.6.10/fs/pramfs/namei.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/namei.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,339 ---- + /* + * FILE NAME fs/pramfs/namei.c + * + * BRIEF DESCRIPTION + * + * Inode operations for directories. + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + + + /* + * Couple of helper functions - make the code slightly cleaner. + */ + + static inline void pram_inc_count(struct inode *inode) + { + inode->i_nlink++; + pram_write_inode(inode, 0); + } + + static inline void pram_dec_count(struct inode *inode) + { + if (inode->i_nlink) { + inode->i_nlink--; + pram_write_inode(inode, 0); + } + } + + static inline int pram_add_nondir(struct inode * dir, + struct dentry * dentry, + struct inode * inode) + { + int err; + + lock_kernel(); + err = pram_add_link(dentry, inode); + if (!err) { + d_instantiate(dentry, inode); + unlock_kernel(); + return 0; + } + pram_dec_count(inode); + iput(inode); + unlock_kernel(); + return err; + } + + /* + * Methods themselves. + */ + + static ino_t + pram_inode_by_name(struct inode * dir, + struct dentry * dentry) + { + struct pram_inode * pi; + ino_t ino; + int namelen; + + pi = pram_get_inode(dir->i_sb, dir->i_ino); + ino = pi->i_type.dir.head; + + while (ino) { + pi = pram_get_inode(dir->i_sb, ino); + + if (pi->i_links_count) { + namelen = strlen(pi->i_d.d_name); + + if (namelen == dentry->d_name.len && + !memcmp(dentry->d_name.name, + pi->i_d.d_name, namelen)) + break; + } + + ino = pi->i_d.d_next; + } + + return ino; + } + + static struct dentry * + pram_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) + { + struct inode * inode = NULL; + ino_t ino; + + if (dentry->d_name.len > PRAM_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + + ino = pram_inode_by_name(dir, dentry); + if (ino) { + inode = iget(dir->i_sb, ino); + if (!inode) + return ERR_PTR(-EACCES); + } + + d_add(dentry, inode); + return NULL; + } + + + /* + * By the time this is called, we already have created + * the directory cache entry for the new file, but it + * is so far negative - it has no inode. + * + * If the create succeeds, we fill in the inode information + * with d_instantiate(). + */ + static int pram_create (struct inode * dir, struct dentry * dentry, + int mode, struct nameidata *nd) + { + struct inode * inode = pram_new_inode (dir, mode); + int err = PTR_ERR(inode); + if (!IS_ERR(inode)) { + inode->i_op = &pram_file_inode_operations; + inode->i_fop = &pram_file_operations; + inode->i_mapping->a_ops = &pram_aops; + err = pram_add_nondir(dir, dentry, inode); + } + return err; + } + + static int pram_mknod (struct inode * dir, struct dentry *dentry, int mode, + dev_t rdev) + { + struct inode * inode = pram_new_inode (dir, mode); + int err = PTR_ERR(inode); + if (!IS_ERR(inode)) { + init_special_inode(inode, mode, rdev); + pram_write_inode(inode, 0); /* update rdev */ + err = pram_add_nondir(dir, dentry, inode); + } + return err; + } + + static int pram_symlink (struct inode * dir, + struct dentry * dentry, + const char * symname) + { + struct super_block * sb = dir->i_sb; + int err = -ENAMETOOLONG; + unsigned len = strlen(symname); + struct inode * inode; + + if (len+1 > sb->s_blocksize) + goto out; + + inode = pram_new_inode (dir, S_IFLNK | S_IRWXUGO); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out; + + inode->i_op = &pram_symlink_inode_operations; + inode->i_mapping->a_ops = &pram_aops; + err = pram_block_symlink(inode, symname, len); + if (err) + goto out_fail; + + inode->i_size = len; + pram_write_inode(inode, 0); + + err = pram_add_nondir(dir, dentry, inode); + out: + return err; + + out_fail: + pram_dec_count(inode); + iput (inode); + goto out; + } + + static int pram_link (struct dentry * dest_dentry, + struct inode * dir, + struct dentry * dentry) + { + pram_dbg ("hard links not supported\n"); + return -ENOSYS; + } + + static int pram_unlink(struct inode * dir, struct dentry *dentry) + { + struct inode * inode = dentry->d_inode; + inode->i_ctime = dir->i_ctime; + pram_dec_count(inode); + + return 0; + } + + static int pram_mkdir(struct inode * dir, struct dentry * dentry, int mode) + { + struct inode * inode; + struct pram_inode * pi; + unsigned long flags; + int err = -EMLINK; + + lock_kernel(); + + if (dir->i_nlink >= PRAM_LINK_MAX) + goto out; + + pram_inc_count(dir); + + inode = pram_new_inode (dir, S_IFDIR | mode); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out_dir; + + inode->i_op = &pram_dir_inode_operations; + inode->i_fop = &pram_dir_operations; + inode->i_mapping->a_ops = &pram_aops; + + pram_inc_count(inode); + + // make the new directory empty + pi = pram_get_inode(dir->i_sb, inode->i_ino); + pram_lock_inode(pi); + pi->i_type.dir.head = pi->i_type.dir.tail = 0; + pram_unlock_inode(pi); + + err = pram_add_link(dentry, inode); + if (err) + goto out_fail; + + d_instantiate(dentry, inode); + out: + unlock_kernel(); + return err; + + out_fail: + pram_dec_count(inode); + pram_dec_count(inode); + iput(inode); + out_dir: + pram_dec_count(dir); + goto out; + } + + static int pram_rmdir (struct inode * dir, struct dentry *dentry) + { + struct inode * inode = dentry->d_inode; + struct pram_inode * pi; + int err = -ENOTEMPTY; + + if (!d_unhashed(dentry)) { + return err; + } + + if (!inode) + return -ENOENT; + + pi = pram_get_inode(dir->i_sb, inode->i_ino); + + // directory to delete is empty? + if (pi->i_type.dir.tail == 0) { + inode->i_ctime = dir->i_ctime; + inode->i_size = 0; + inode->i_nlink = 0; + pram_write_inode(inode, 0); + pram_dec_count(dir); + err = 0; + } else { + pram_dbg("dir not empty\n"); + } + + return err; + } + + static int pram_rename (struct inode * old_dir, + struct dentry * old_dentry, + struct inode * new_dir, + struct dentry * new_dentry) + { + struct inode * old_inode = old_dentry->d_inode; + struct inode * new_inode = new_dentry->d_inode; + struct pram_inode * pi_new; + int err = -ENOENT; + + lock_kernel(); + if (new_inode) { + err = -ENOTEMPTY; + pi_new = pram_get_inode(new_dir->i_sb, new_inode->i_ino); + if (S_ISDIR(old_inode->i_mode)) { + if (pi_new->i_type.dir.tail != 0) + goto out; + if (new_inode->i_nlink) + new_inode->i_nlink--; + } + + new_inode->i_ctime = CURRENT_TIME; + pram_dec_count(new_inode); + } else { + if (S_ISDIR(old_inode->i_mode)) { + err = -EMLINK; + if (new_dir->i_nlink >= PRAM_LINK_MAX) + goto out; + pram_dec_count(old_dir); + pram_inc_count(new_dir); + } + } + + /* unlink the inode from the old directory ... */ + if ((err = pram_remove_link(old_inode))) { + goto out; + } + /* and link it into the new directory. */ + if ((err = pram_add_link(new_dentry, old_inode))) { + goto out; + } + + err = 0; + out: + unlock_kernel(); + return err; + } + + struct inode_operations pram_dir_inode_operations = { + create: pram_create, + lookup: pram_lookup, + link: pram_link, + unlink: pram_unlink, + symlink: pram_symlink, + mkdir: pram_mkdir, + rmdir: pram_rmdir, + mknod: pram_mknod, + rename: pram_rename, + }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/super.c linux-current/fs/pramfs/super.c *** linux-2.6.10/fs/pramfs/super.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/super.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,394 ---- + /* + * FILE NAME fs/pramfs/super.c + * + * BRIEF DESCRIPTION + * + * Super block operations. + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + #include + #include + #include + #include + #include + #include + + MODULE_AUTHOR("Steve Longerbeam, stevel@mvista.com"); + MODULE_DESCRIPTION("Protected/Persistent RAM Filesystem"); + MODULE_LICENSE("GPL"); + + static struct super_operations pram_sops; + + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + struct semaphore pramfs_pcimb_lock; + #endif + + #ifndef MODULE + extern struct list_head super_blocks; + + struct super_block * find_pramfs_super(void) + { + struct list_head *p; + list_for_each(p, &super_blocks) { + struct super_block * s = sb_entry(p); + if (s->s_magic == PRAM_SUPER_MAGIC) + return s; + } + return NULL; + } + EXPORT_SYMBOL(find_pramfs_super); + #endif + + static void pram_set_blocksize(struct super_block * sb, unsigned long size) + { + int bits; + for (bits = 9, size >>= 9; size >>= 1; bits++) + ; + if (bits > 12) + bits = 12; + sb->s_blocksize_bits = bits; + sb->s_blocksize = (1<s_fs_info = sbi; + memset(sbi, 0, sizeof(*sbi)); + + sbi->phys_addr = simple_strtoul(p + 9, NULL, 0); + if (sbi->phys_addr & (PAGE_SIZE-1)) { + pram_err("physical address 0x%lx for pramfs isn't " + "aligned to a page boundary\n", + sbi->phys_addr); + goto out; + } + + if (sbi->phys_addr == 0) { + pram_err("physical address for pramfs image can't be 0\n"); + goto out; + } + + if ((p = strstr((char *)data, "init="))) { + unsigned long bpi, num_inodes, bitmap_size; + unsigned long num_blocks; + pram_off_t bitmap_start; + + maxsize = simple_strtoul(p + 5, NULL, 0); + pram_info("creating an empty pramfs of size %lu\n", maxsize); + + sbi->virt_addr = pram_ioremap(sbi->phys_addr, maxsize); + if (!sbi->virt_addr) { + pram_err("ioremap of the pramfs image failed\n"); + goto out; + } + + if ((p = strstr((char *)data, "bs="))) + blocksize = simple_strtoul(p + 3, NULL, 0); + else + blocksize = PRAM_DEF_BLOCK_SIZE; + + pram_set_blocksize(sb, blocksize); + blocksize = sb->s_blocksize; + + if ((p = strstr((char *)data, "bpi="))) + bpi = simple_strtoul(p + 4, NULL, 0); + else { + /* default is that 5% of the filesystem is + devoted to the inode table */ + bpi = 20 * PRAM_INODE_SIZE; + } + + if ((p = strstr((char *)data, "N="))) + num_inodes = simple_strtoul(p + 2, NULL, 0); + else + num_inodes = maxsize / bpi; + + /* up num_inodes such that the end of the inode table + (and start of bitmap) is on a block boundary */ + bitmap_start = PRAM_SB_SIZE + (num_inodes<> PRAM_INODE_BITS; + + num_blocks = (maxsize - bitmap_start) >> sb->s_blocksize_bits; + + /* calc the data blocks in-use bitmap size in bytes */ + if (num_blocks & 7) + bitmap_size = ((num_blocks + 8) & ~7) >> 3; + else + bitmap_size = num_blocks >> 3; + /* round it up to the nearest blocksize boundary */ + if (bitmap_size & (blocksize - 1)) + bitmap_size = (bitmap_size + blocksize) & + ~(blocksize-1); + + pram_info("blocksize %lu, num inodes %lu, num blocks %lu\n", + blocksize, num_inodes, num_blocks); + pram_dbg("bitmap start 0x%08x, bitmap size %lu\n", + (unsigned long)bitmap_start, bitmap_size); + pram_dbg("max name length %d\n", PRAM_NAME_LEN); + + super = pram_get_super(sb); + pram_lock_range(super, bitmap_start + bitmap_size); + + /* clear out super-block and inode table */ + memset(super, 0, bitmap_start); + super->s_size = maxsize; + super->s_blocksize = blocksize; + super->s_inodes_count = num_inodes; + super->s_blocks_count = num_blocks; + super->s_free_inodes_count = num_inodes - 1; + super->s_bitmap_blocks = bitmap_size >> sb->s_blocksize_bits; + super->s_free_blocks_count = + num_blocks - super->s_bitmap_blocks; + super->s_free_inode_hint = 1; + super->s_bitmap_start = bitmap_start; + super->s_magic = PRAM_SUPER_MAGIC; + pram_sync_super(super); + + root_i = pram_get_inode(sb, PRAM_ROOT_INO); + root_i->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; + root_i->i_links_count = 2; + root_i->i_d.d_parent = PRAM_ROOT_INO; + pram_sync_inode(root_i); + + pram_init_bitmap(sb); + + pram_unlock_range(super, bitmap_start + bitmap_size); + + goto setup_sb; + } + + pram_info("checking physical address 0x%lx for pramfs image\n", + sbi->phys_addr); + + /* Map only one page for now. Will remap it when fs size is known. */ + sbi->virt_addr = pram_ioremap(sbi->phys_addr, PAGE_SIZE); + if (!sbi->virt_addr) { + pram_err("ioremap of the pramfs image failed\n"); + goto out; + } + + super = pram_get_super(sb); + + /* Do sanity checks on the superblock */ + if (super->s_magic != PRAM_SUPER_MAGIC) { + pram_err("wrong magic\n"); + goto out; + } + /* Read the superblock */ + if (pram_calc_checksum((u32*)super, PRAM_SB_SIZE>>2)) { + pram_err("checksum error in super block!\n"); + goto out; + } + + /* get feature flags first */ + // FIXME: implement fs features? + #if 0 + if (super->s_features & ~PRAM_SUPPORTED_FLAGS) { + pram_err("unsupported filesystem features\n"); + goto out; + } + #endif + + blocksize = super->s_blocksize; + pram_set_blocksize(sb, blocksize); + + maxsize = super->s_size; + pram_info("pramfs image appears to be %lu KB in size\n", maxsize>>10); + pram_info("blocksize %lu\n", blocksize); + + /* Read the root inode */ + root_i = pram_get_inode(sb, PRAM_ROOT_INO); + + if (pram_calc_checksum((u32*)root_i, PRAM_INODE_SIZE>>2)) { + pram_err("checksum error in root inode!\n"); + goto out; + } + + /* Check that the root inode is in a sane state */ + if (root_i->i_d.d_next) { + pram_err("root->next not NULL??!!\n"); + goto out; + } + + if (!S_ISDIR(root_i->i_mode)) { + pram_err("root is not a directory!\n"); + goto out; + } + + root_offset = root_i->i_type.dir.head; + if (root_offset == 0) + pram_info("empty filesystem\n"); + + /* Remap the whole filesystem now */ + iounmap(sbi->virt_addr); + sbi->virt_addr = pram_ioremap(sbi->phys_addr, maxsize); + if (!sbi->virt_addr) { + pram_err("ioremap of the pramfs image failed\n"); + goto out; + } + super = pram_get_super(sb); + root_i = pram_get_inode(sb, PRAM_ROOT_INO); + + /* Set it all up.. */ + setup_sb: + sbi->maxsize = maxsize; + sb->s_magic = sbi->magic = super->s_magic; + sbi->features = super->s_features; + + sb->s_op = &pram_sops; + sb->s_root = d_alloc_root(pram_fill_new_inode(sb, root_i)); + + retval = 0; + out: + if (retval && sbi->virt_addr) + iounmap(sbi->virt_addr); + + return retval; + } + + //static void pram_write_super (struct super_block * sb) + //{ + //} + + int pram_statfs (struct super_block * sb, struct kstatfs * buf) + { + struct pram_super_block * ps = pram_get_super(sb); + + buf->f_type = PRAM_SUPER_MAGIC; + buf->f_bsize = sb->s_blocksize; + buf->f_blocks = ps->s_blocks_count; + buf->f_bfree = buf->f_bavail = ps->s_free_blocks_count; + buf->f_files = ps->s_inodes_count; + buf->f_ffree = ps->s_free_inodes_count; + buf->f_namelen = PRAM_NAME_LEN; + return 0; + } + + int pram_remount (struct super_block * sb, int * mntflags, char * data) + { + struct pram_super_block * ps; + unsigned long flags; + + if ((*mntflags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) { + ps = pram_get_super(sb); + pram_lock_super(ps); + ps->s_mtime = get_seconds(); // update mount time + pram_unlock_super(ps); + } + return 0; + } + + void pram_put_super (struct super_block * sb) + { + struct pram_sb_info * sbi = (struct pram_sb_info *)sb->s_fs_info; + + /* It's unmount time, so unmap the pramfs memory */ + if (sbi->virt_addr) { + iounmap(sbi->virt_addr); + sbi->virt_addr = NULL; + } + + sb->s_fs_info = NULL; + kfree(sbi); + } + + /* + * the super block writes are all done "on the fly", so the + * super block is never in a "dirty" state, so there's no need + * for write_super. + */ + static struct super_operations pram_sops = { + read_inode: pram_read_inode, + write_inode: pram_write_inode, + dirty_inode: pram_dirty_inode, + put_inode: pram_put_inode, + delete_inode: pram_delete_inode, + put_super: pram_put_super, + //write_super: pram_write_super, + statfs: pram_statfs, + remount_fs: pram_remount, + }; + + static struct super_block *pram_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *data) + { + return get_sb_nodev(fs_type, flags, data, pram_fill_super); + } + + static struct file_system_type pram_fs_type = { + .owner = THIS_MODULE, + .name = "pramfs", + .get_sb = pram_get_sb, + .kill_sb = kill_anon_super, + }; + + static int __init init_pram_fs(void) + { + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + init_MUTEX(&pramfs_pcimb_lock); + #endif + return register_filesystem(&pram_fs_type); + } + + static void __exit exit_pram_fs(void) + { + unregister_filesystem(&pram_fs_type); + } + + module_init(init_pram_fs) + module_exit(exit_pram_fs) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/symlink.c linux-current/fs/pramfs/symlink.c *** linux-2.6.10/fs/pramfs/symlink.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/symlink.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,69 ---- + /* + * FILE NAME fs/pramfs/symlink.c + * + * BRIEF DESCRIPTION + * + * Symlink operations + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + + int pram_block_symlink(struct inode *inode, const char *symname, int len) + { + struct super_block * sb = inode->i_sb; + pram_off_t block; + char* blockp; + unsigned long flags; + int err; + + err = pram_alloc_blocks (inode, 0, 1); + if (err) + return err; + + block = pram_find_data_block(inode, 0); + blockp = pram_get_block(sb, block); + + pram_lock_block(sb, blockp); + memcpy(blockp, symname, len); + blockp[len] = '\0'; + pram_unlock_block(sb, blockp); + return 0; + } + + static int pram_readlink(struct dentry *dentry, char *buffer, int buflen) + { + struct inode * inode = dentry->d_inode; + struct super_block * sb = inode->i_sb; + pram_off_t block; + char* blockp; + + block = pram_find_data_block(inode, 0); + blockp = pram_get_block(sb, block); + return vfs_readlink(dentry, buffer, buflen, blockp); + } + + static int pram_follow_link(struct dentry *dentry, struct nameidata *nd) + { + struct inode * inode = dentry->d_inode; + struct super_block * sb = inode->i_sb; + pram_off_t block; + char* blockp; + + block = pram_find_data_block(inode, 0); + blockp = pram_get_block(sb, block); + return vfs_follow_link(nd, blockp); + } + + struct inode_operations pram_symlink_inode_operations = { + readlink: pram_readlink, + follow_link: pram_follow_link, + }; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/pramfs/wprotect.c linux-current/fs/pramfs/wprotect.c *** linux-2.6.10/fs/pramfs/wprotect.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/pramfs/wprotect.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,81 ---- + /* + * FILE NAME fs/pramfs/wprotect.c + * + * BRIEF DESCRIPTION + * + * Write protection for the filesystem pages. + * + * Author: Steve Longerbeam + * + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * 2003-2004 (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 + #include + #include + #include + + // init_mm.page_table_lock must be held before calling! + static void pram_page_writeable(unsigned long addr, int rw) + { + pgd_t *pgdp; + pmd_t *pmdp; + pte_t *ptep; + + pgdp = pgd_offset_k(addr); + if (!pgd_none(*pgdp)) { + pmdp = pmd_offset(pgdp, addr); + if (!pmd_none(*pmdp)) { + pte_t pte; + ptep = pte_offset_kernel(pmdp, addr); + pte = *ptep; + if (pte_present(pte)) { + pte = rw ? pte_mkwrite(pte) : + pte_wrprotect(pte); + set_pte(ptep, pte); + } + } + } + } + + + // init_mm.page_table_lock must be held before calling! + void pram_writeable(void * vaddr, unsigned long size, int rw) + { + unsigned long addr = (unsigned long)vaddr & PAGE_MASK; + unsigned long end = (unsigned long)vaddr + size; + unsigned long start = addr; + + do { + pram_page_writeable(addr, rw); + addr += PAGE_SIZE; + } while (addr && (addr < end)); + + + /* + * NOTE: we will always flush just one page (one TLB + * entry) except possibly in one case: when a new + * filesystem is initialized at mount time, when pram_read_super + * calls pram_lock_range to make the super block, inode + * table, and bitmap writeable. + */ + #if defined(__arm__) || defined(__mc68000__) || defined(CONFIG_H8300) + /* + * FIXME: so far only these archs have flush_tlb_kernel_page(), + * for the rest just use flush_tlb_kernel_range(). Not ideal + * to use _range() because many archs just flush the whole TLB. + */ + if (end <= start + PAGE_SIZE) + flush_tlb_kernel_page(start); + else + #endif + flush_tlb_kernel_range(start, end); + } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/read_write.c linux-current/fs/read_write.c *** linux-2.6.10/fs/read_write.c Sat Dec 25 06:35:00 2004 --- linux-current/fs/read_write.c Wed Jun 14 21:12:59 2006 *************** *** 14,19 **** --- 14,20 ---- #include #include #include + #include #include #include *************** *** 142,147 **** --- 143,151 ---- if (res != (loff_t)retval) retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ } + + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_SEEK, fd, offset, NULL); + fput_light(file, fput_needed); bad: return retval; *************** *** 169,174 **** --- 173,180 ---- offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low, origin); + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_SEEK, fd, offset, NULL); + retval = (int)offset; if (offset >= 0) { retval = -EFAULT; *************** *** 289,294 **** --- 295,301 ---- file = fget_light(fd, &fput_needed); if (file) { loff_t pos = file_pos_read(file); + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_READ, fd, count, NULL); ret = vfs_read(file, buf, count, &pos); file_pos_write(file, pos); fput_light(file, fput_needed); *************** *** 307,312 **** --- 314,320 ---- file = fget_light(fd, &fput_needed); if (file) { loff_t pos = file_pos_read(file); + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_WRITE, fd, count, NULL); ret = vfs_write(file, buf, count, &pos); file_pos_write(file, pos); fput_light(file, fput_needed); *************** *** 328,335 **** file = fget_light(fd, &fput_needed); if (file) { ret = -ESPIPE; ! if (file->f_mode & FMODE_PREAD) ret = vfs_read(file, buf, count, &pos); fput_light(file, fput_needed); } --- 336,347 ---- file = fget_light(fd, &fput_needed); if (file) { ret = -ESPIPE; ! if (file->f_mode & FMODE_PREAD) { ! ltt_ev_file_system(LTT_EV_FILE_SYSTEM_READ, fd, ! count, NULL); ret = vfs_read(file, buf, count, &pos); + } + fput_light(file, fput_needed); } *************** *** 349,356 **** file = fget_light(fd, &fput_needed); if (file) { ret = -ESPIPE; ! if (file->f_mode & FMODE_PWRITE) ret = vfs_write(file, buf, count, &pos); fput_light(file, fput_needed); } --- 361,371 ---- file = fget_light(fd, &fput_needed); if (file) { ret = -ESPIPE; ! if (file->f_mode & FMODE_PWRITE) { ! ltt_ev_file_system(LTT_EV_FILE_SYSTEM_WRITE, fd, ! count, NULL); ret = vfs_write(file, buf, count, &pos); + } fput_light(file, fput_needed); } *************** *** 535,540 **** --- 550,556 ---- file = fget_light(fd, &fput_needed); if (file) { loff_t pos = file_pos_read(file); + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_READ, fd, vlen, NULL); ret = vfs_readv(file, vec, vlen, &pos); file_pos_write(file, pos); fput_light(file, fput_needed); *************** *** 553,558 **** --- 569,575 ---- file = fget_light(fd, &fput_needed); if (file) { loff_t pos = file_pos_read(file); + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_WRITE, fd, vlen, NULL); ret = vfs_writev(file, vec, vlen, &pos); file_pos_write(file, pos); fput_light(file, fput_needed); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/Makefile linux-current/fs/relayfs/Makefile *** linux-2.6.10/fs/relayfs/Makefile Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/Makefile Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,8 ---- + # + # relayfs Makefile + # + + obj-$(CONFIG_RELAYFS_FS) += relayfs.o + + relayfs-y := relay.o relay_lockless.o relay_locking.o inode.o resize.o + relayfs-$(CONFIG_KLOG_CHANNEL) += klog.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/inode.c linux-current/fs/relayfs/inode.c *** linux-2.6.10/fs/relayfs/inode.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/inode.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,629 ---- + /* + * VFS-related code for RelayFS, a high-speed data relay filesystem. + * + * Copyright (C) 2003 - Tom Zanussi , IBM Corp + * Copyright (C) 2003 - Karim Yaghmour + * + * Based on ramfs, Copyright (C) 2002 - Linus Torvalds + * + * This file is released under the GPL. + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #define RELAYFS_MAGIC 0x26F82121 + + static struct super_operations relayfs_ops; + static struct address_space_operations relayfs_aops; + static struct inode_operations relayfs_file_inode_operations; + static struct file_operations relayfs_file_operations; + static struct inode_operations relayfs_dir_inode_operations; + + static struct vfsmount * relayfs_mount; + static int relayfs_mount_count; + + static struct backing_dev_info relayfs_backing_dev_info = { + .ra_pages = 0, /* No readahead */ + .memory_backed = 1, /* Does not contribute to dirty memory */ + }; + + static struct inode * + relayfs_get_inode(struct super_block *sb, int mode, dev_t dev) + { + struct inode * inode; + + inode = new_inode(sb); + + if (inode) { + inode->i_mode = mode; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; + inode->i_blksize = PAGE_CACHE_SIZE; + inode->i_blocks = 0; + inode->i_mapping->a_ops = &relayfs_aops; + inode->i_mapping->backing_dev_info = &relayfs_backing_dev_info; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + switch (mode & S_IFMT) { + default: + init_special_inode(inode, mode, dev); + break; + case S_IFREG: + inode->i_op = &relayfs_file_inode_operations; + inode->i_fop = &relayfs_file_operations; + break; + case S_IFDIR: + inode->i_op = &relayfs_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + + /* directory inodes start off with i_nlink == 2 (for "." entry) */ + inode->i_nlink++; + break; + case S_IFLNK: + inode->i_op = &page_symlink_inode_operations; + break; + } + } + return inode; + } + + /* + * File creation. Allocate an inode, and we're done.. + */ + /* SMP-safe */ + static int + relayfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) + { + struct inode * inode; + int error = -ENOSPC; + + inode = relayfs_get_inode(dir->i_sb, mode, dev); + + if (inode) { + d_instantiate(dentry, inode); + dget(dentry); /* Extra count - pin the dentry in core */ + error = 0; + } + return error; + } + + static int + relayfs_mkdir(struct inode * dir, struct dentry * dentry, int mode) + { + int retval; + + retval = relayfs_mknod(dir, dentry, mode | S_IFDIR, 0); + + if (!retval) + dir->i_nlink++; + return retval; + } + + static int + relayfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) + { + return relayfs_mknod(dir, dentry, mode | S_IFREG, 0); + } + + static int + relayfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) + { + struct inode *inode; + int error = -ENOSPC; + + inode = relayfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0); + + if (inode) { + int l = strlen(symname)+1; + error = page_symlink(inode, symname, l); + if (!error) { + d_instantiate(dentry, inode); + dget(dentry); + } else + iput(inode); + } + return error; + } + + /** + * relayfs_create_entry - create a relayfs directory or file + * @name: the name of the file to create + * @parent: parent directory + * @dentry: result dentry + * @entry_type: type of file to create (S_IFREG, S_IFDIR) + * @mode: mode + * @data: data to associate with the file + * + * Creates a file or directory with the specifed permissions. + */ + static int + relayfs_create_entry(const char * name, struct dentry * parent, struct dentry **dentry, int entry_type, int mode, void * data) + { + struct qstr qname; + struct dentry * d; + + int error = 0; + + error = simple_pin_fs("relayfs", &relayfs_mount, &relayfs_mount_count); + if (error) { + printk(KERN_ERR "Couldn't mount relayfs: errcode %d\n", error); + return error; + } + + qname.name = name; + qname.len = strlen(name); + qname.hash = full_name_hash(name, qname.len); + + if (parent == NULL) + if (relayfs_mount && relayfs_mount->mnt_sb) + parent = relayfs_mount->mnt_sb->s_root; + + if (parent == NULL) { + simple_release_fs(&relayfs_mount, &relayfs_mount_count); + return -EINVAL; + } + + parent = dget(parent); + down(&parent->d_inode->i_sem); + d = lookup_hash(&qname, parent); + if (IS_ERR(d)) { + error = PTR_ERR(d); + goto release_mount; + } + + if (d->d_inode) { + error = -EEXIST; + goto release_mount; + } + + if (entry_type == S_IFREG) + error = relayfs_create(parent->d_inode, d, entry_type | mode, NULL); + else + error = relayfs_mkdir(parent->d_inode, d, entry_type | mode); + if (error) + goto release_mount; + + if ((entry_type == S_IFREG) && data) { + d->d_inode->u.generic_ip = data; + goto exit; /* don't release mount for regular files */ + } + + release_mount: + simple_release_fs(&relayfs_mount, &relayfs_mount_count); + exit: + *dentry = d; + up(&parent->d_inode->i_sem); + dput(parent); + + return error; + } + + /** + * relayfs_create_file - create a file in the relay filesystem + * @name: the name of the file to create + * @parent: parent directory + * @dentry: result dentry + * @data: data to associate with the file + * @mode: mode, if not specied the default perms are used + * + * The file will be created user rw on behalf of current user. + */ + int + relayfs_create_file(const char * name, struct dentry * parent, struct dentry **dentry, void * data, int mode) + { + if (!mode) + mode = S_IRUSR | S_IWUSR; + + return relayfs_create_entry(name, parent, dentry, S_IFREG, + mode, data); + } + + /** + * relayfs_create_dir - create a directory in the relay filesystem + * @name: the name of the directory to create + * @parent: parent directory + * @dentry: result dentry + * + * The directory will be created world rwx on behalf of current user. + */ + int + relayfs_create_dir(const char * name, struct dentry * parent, struct dentry **dentry) + { + return relayfs_create_entry(name, parent, dentry, S_IFDIR, + S_IRWXU | S_IRUGO | S_IXUGO, NULL); + } + + /** + * relayfs_remove_file - remove a file in the relay filesystem + * @dentry: file dentry + * + * Remove a file previously created by relayfs_create_file. + */ + int + relayfs_remove_file(struct dentry *dentry) + { + struct dentry *parent; + int is_reg; + + parent = dentry->d_parent; + if (parent == NULL) + return -EINVAL; + + is_reg = S_ISREG(dentry->d_inode->i_mode); + + parent = dget(parent); + down(&parent->d_inode->i_sem); + if (dentry->d_inode) { + simple_unlink(parent->d_inode, dentry); + d_delete(dentry); + } + dput(dentry); + up(&parent->d_inode->i_sem); + dput(parent); + + if(is_reg) + simple_release_fs(&relayfs_mount, &relayfs_mount_count); + + return 0; + } + + /** + * relayfs_open - open file op for relayfs files + * @inode: the inode + * @filp: the file + * + * Associates the channel with the file, and increments the + * channel refcount. Reads will be 'auto-consuming'. + */ + int + relayfs_open(struct inode *inode, struct file *filp) + { + struct rchan *rchan; + struct rchan_reader *reader; + int retval = 0; + + if (inode->u.generic_ip) { + rchan = (struct rchan *)inode->u.generic_ip; + if (rchan == NULL) + return -EACCES; + reader = __add_rchan_reader(rchan, filp, 1, 0); + if (reader == NULL) + return -ENOMEM; + filp->private_data = reader; + retval = rchan->callbacks->fileop_notify(rchan->id, filp, + RELAY_FILE_OPEN); + if (retval == 0) + /* Inc relay channel refcount for file */ + rchan_get(rchan->id); + else { + __remove_rchan_reader(reader); + retval = -EPERM; + } + } + + return retval; + } + + /** + * relayfs_mmap - mmap file op for relayfs files + * @filp: the file + * @vma: the vma describing what to map + * + * Calls upon relay_mmap_buffer to map the file into user space. + */ + int + relayfs_mmap(struct file *filp, struct vm_area_struct *vma) + { + struct rchan *rchan; + + rchan = ((struct rchan_reader *)filp->private_data)->rchan; + + return __relay_mmap_buffer(rchan, vma); + } + + /** + * relayfs_file_read - read file op for relayfs files + * @filp: the file + * @buf: user buf to read into + * @count: bytes requested + * @offset: offset into file + * + * Reads count bytes from the channel, or as much as is available within + * the sub-buffer currently being read. Reads are 'auto-consuming'. + * See relay_read() for details. + * + * Returns bytes read on success, 0 or -EAGAIN if nothing available, + * negative otherwise. + */ + ssize_t + relayfs_file_read(struct file *filp, char * buf, size_t count, loff_t *offset) + { + size_t read_count; + struct rchan_reader *reader; + u32 dummy; /* all VFS readers are auto-consuming */ + + if (count == 0) + return 0; + + reader = (struct rchan_reader *)filp->private_data; + read_count = relay_read(reader, buf, count, + filp->f_flags & (O_NDELAY | O_NONBLOCK) ? 0 : 1, &dummy, (u32 *)offset); + + return read_count; + } + + /** + * relayfs_file_write - write file op for relayfs files + * @filp: the file + * @buf: user buf to write from + * @count: bytes to write + * @offset: offset into file + * + * Reserves a slot in the relay buffer and writes count bytes + * into it. The current limit for a single write is 2 pages + * worth. The user_deliver() channel callback will be invoked on + * + * Returns bytes written on success, 0 or -EAGAIN if nothing available, + * negative otherwise. + */ + ssize_t + relayfs_file_write(struct file *filp, const char *buf, size_t count, loff_t *offset) + { + int write_count; + char * write_buf; + struct rchan *rchan; + int err = 0; + void *wrote_pos; + struct rchan_reader *reader; + + reader = (struct rchan_reader *)filp->private_data; + if (reader == NULL) + return -EPERM; + + rchan = reader->rchan; + if (rchan == NULL) + return -EPERM; + + if (count == 0) + return 0; + + /* Change this if need to write more than 2 pages at once */ + if (count > 2 * PAGE_SIZE) + return -EINVAL; + + write_buf = (char *)__get_free_pages(GFP_KERNEL, 1); + if (write_buf == NULL) + return -ENOMEM; + + if (copy_from_user(write_buf, buf, count)) + return -EFAULT; + + if (filp->f_flags & (O_NDELAY | O_NONBLOCK)) { + write_count = relay_write(rchan->id, write_buf, count, -1, &wrote_pos); + if (write_count == 0) + return -EAGAIN; + } else { + err = wait_event_interruptible(rchan->write_wait, + (write_count = relay_write(rchan->id, write_buf, count, -1, &wrote_pos))); + if (err) + return err; + } + + free_pages((unsigned long)write_buf, 1); + + rchan->callbacks->user_deliver(rchan->id, wrote_pos, write_count); + + *offset += write_count; + + return write_count; + } + + /** + * relayfs_ioctl - ioctl file op for relayfs files + * @inode: the inode + * @filp: the file + * @cmd: the command + * @arg: command arg + * + * Passes the specified cmd/arg to the kernel client. arg may be a + * pointer to user-space data, in which case the kernel client is + * responsible for copying the data to/from user space appropriately. + * The kernel client is also responsible for returning a meaningful + * return value for ioctl calls. + * + * Returns result of relay channel callback, -EPERM if unsuccessful. + */ + int + relayfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) + { + struct rchan *rchan; + struct rchan_reader *reader; + + reader = (struct rchan_reader *)filp->private_data; + if (reader == NULL) + return -EPERM; + + rchan = reader->rchan; + if (rchan == NULL) + return -EPERM; + + return rchan->callbacks->ioctl(rchan->id, cmd, arg); + } + + /** + * relayfs_poll - poll file op for relayfs files + * @filp: the file + * @wait: poll table + * + * Poll implemention. + */ + static unsigned int + relayfs_poll(struct file *filp, poll_table *wait) + { + struct rchan_reader *reader; + unsigned int mask = 0; + + reader = (struct rchan_reader *)filp->private_data; + + if (reader->rchan->finalized) + return POLLERR; + + if (filp->f_mode & FMODE_READ) { + poll_wait(filp, &reader->rchan->read_wait, wait); + if (!rchan_empty(reader)) + mask |= POLLIN | POLLRDNORM; + } + + if (filp->f_mode & FMODE_WRITE) { + poll_wait(filp, &reader->rchan->write_wait, wait); + if (!rchan_full(reader)) + mask |= POLLOUT | POLLWRNORM; + } + + return mask; + } + + /** + * relayfs_release - release file op for relayfs files + * @inode: the inode + * @filp: the file + * + * Decrements the channel refcount, as the filesystem is + * no longer using it. + */ + int + relayfs_release(struct inode *inode, struct file *filp) + { + struct rchan_reader *reader; + struct rchan *rchan; + + reader = (struct rchan_reader *)filp->private_data; + if (reader == NULL || reader->rchan == NULL) + return 0; + rchan = reader->rchan; + + rchan->callbacks->fileop_notify(reader->rchan->id, filp, + RELAY_FILE_CLOSE); + __remove_rchan_reader(reader); + /* The channel is no longer in use as far as this file is concerned */ + rchan_put(rchan); + + return 0; + } + + static struct address_space_operations relayfs_aops = { + .readpage = simple_readpage, + .prepare_write = simple_prepare_write, + .commit_write = simple_commit_write + }; + + static struct file_operations relayfs_file_operations = { + .open = relayfs_open, + .llseek = no_llseek, + .read = relayfs_file_read, + .write = relayfs_file_write, + .ioctl = relayfs_ioctl, + .poll = relayfs_poll, + .mmap = relayfs_mmap, + .fsync = simple_sync_file, + .release = relayfs_release, + }; + + static struct inode_operations relayfs_file_inode_operations = { + .getattr = simple_getattr, + }; + + static struct inode_operations relayfs_dir_inode_operations = { + .create = relayfs_create, + .lookup = simple_lookup, + .link = simple_link, + .unlink = simple_unlink, + .symlink = relayfs_symlink, + .mkdir = relayfs_mkdir, + .rmdir = simple_rmdir, + .mknod = relayfs_mknod, + .rename = simple_rename, + }; + + static struct super_operations relayfs_ops = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, + }; + + static int + relayfs_fill_super(struct super_block * sb, void * data, int silent) + { + struct inode * inode; + struct dentry * root; + + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; + sb->s_magic = RELAYFS_MAGIC; + sb->s_op = &relayfs_ops; + inode = relayfs_get_inode(sb, S_IFDIR | 0755, 0); + + if (!inode) + return -ENOMEM; + + root = d_alloc_root(inode); + if (!root) { + iput(inode); + return -ENOMEM; + } + sb->s_root = root; + + return 0; + } + + static struct super_block * + relayfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data) + { + return get_sb_single(fs_type, flags, data, relayfs_fill_super); + } + + static struct file_system_type relayfs_fs_type = { + .owner = THIS_MODULE, + .name = "relayfs", + .get_sb = relayfs_get_sb, + .kill_sb = kill_litter_super, + }; + + static int __init + init_relayfs_fs(void) + { + int err = register_filesystem(&relayfs_fs_type); + #ifdef CONFIG_KLOG_CHANNEL + if (!err) + create_klog_channel(); + #endif + return err; + } + + static void __exit + exit_relayfs_fs(void) + { + #ifdef CONFIG_KLOG_CHANNEL + remove_klog_channel(); + #endif + unregister_filesystem(&relayfs_fs_type); + } + + module_init(init_relayfs_fs) + module_exit(exit_relayfs_fs) + + MODULE_AUTHOR("Tom Zanussi and Karim Yaghmour "); + MODULE_DESCRIPTION("Relay Filesystem"); + MODULE_LICENSE("GPL"); + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/klog.c linux-current/fs/relayfs/klog.c *** linux-2.6.10/fs/relayfs/klog.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/klog.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,206 ---- + /* + * KLOG Generic Logging facility built upon the relayfs infrastructure + * + * Authors: Hubertus Franke (frankeh@us.ibm.com) + * Tom Zanussi (zanussi@us.ibm.com) + * + * Please direct all questions/comments to zanussi@us.ibm.com + * + * Copyright (C) 2003, 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; either version + * 2 of the License, or (at your option) any later version. + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + /* klog channel id */ + static int klog_channel = -1; + + /* maximum size of klog formatting buffer beyond which truncation will occur */ + #define KLOG_BUF_SIZE (512) + /* per-cpu klog formatting buffer */ + static char buf[NR_CPUS][KLOG_BUF_SIZE]; + + /* + * klog_enabled determines whether klog()/klog_raw() actually do write + * to the klog channel at any given time. If klog_enabled == 1 they do, + * otherwise they don't. Settable using sysctl fs.relayfs.klog_enabled. + */ + #ifdef CONFIG_KLOG_CHANNEL_AUTOENABLE + static int klog_enabled = 1; + #else + static int klog_enabled = 0; + #endif + + /** + * klog - write a formatted string into the klog channel + * @fmt: format string + * + * Returns number of bytes written, negative number on failure. + */ + int klog(const char *fmt, ...) + { + va_list args; + int len, err; + char *cbuf; + unsigned long flags; + + if (!klog_enabled || klog_channel < 0) + return 0; + + local_irq_save(flags); + cbuf = buf[smp_processor_id()]; + + va_start(args, fmt); + len = vsnprintf(cbuf, KLOG_BUF_SIZE, fmt, args); + va_end(args); + + err = relay_write(klog_channel, cbuf, len, -1, NULL); + local_irq_restore(flags); + + return err; + } + + /** + * klog_raw - directly write into the klog channel + * @buf: buffer containing data to write + * @len: # bytes to write + * + * Returns number of bytes written, negative number on failure. + */ + int klog_raw(const char *buf,int len) + { + int err = 0; + + if (klog_enabled && klog_channel >= 0) + err = relay_write(klog_channel, buf, len, -1, NULL); + + return err; + } + + /** + * relayfs sysctl data + * + * Only sys/fs/relayfs/klog_enabled for now. + */ + #define CTL_ENABLE_KLOG 100 + #define CTL_RELAYFS 100 + + static struct ctl_table_header *relayfs_ctl_table_header; + + static struct ctl_table relayfs_table[] = + { + { + .ctl_name = CTL_ENABLE_KLOG, + .procname = "klog_enabled", + .data = &klog_enabled, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + 0 + } + }; + + static struct ctl_table relayfs_dir_table[] = + { + { + .ctl_name = CTL_RELAYFS, + .procname = "relayfs", + .data = NULL, + .maxlen = 0, + .mode = 0555, + .child = relayfs_table, + }, + { + 0 + } + }; + + static struct ctl_table relayfs_root_table[] = + { + { + .ctl_name = CTL_FS, + .procname = "fs", + .data = NULL, + .maxlen = 0, + .mode = 0555, + .child = relayfs_dir_table, + }, + { + 0 + } + }; + + /** + * create_klog_channel - creates channel /mnt/relay/klog + * + * Returns channel id on success, negative otherwise. + */ + int + create_klog_channel(void) + { + u32 bufsize, nbufs; + u32 channel_flags; + + channel_flags = RELAY_DELIVERY_PACKET | RELAY_USAGE_GLOBAL; + channel_flags |= RELAY_SCHEME_ANY | RELAY_TIMESTAMP_ANY; + + bufsize = 1 << (CONFIG_KLOG_CHANNEL_SHIFT - 2); + nbufs = 4; + + klog_channel = relay_open("klog", + bufsize, + nbufs, + channel_flags, + NULL, + 0, + 0, + 0, + 0, + 0, + 0, + NULL, + 0); + + if (klog_channel < 0) + printk("klog channel creation failed, errcode: %d\n", klog_channel); + else { + printk("klog channel created (%u bytes)\n", 1 << CONFIG_KLOG_CHANNEL_SHIFT); + relayfs_ctl_table_header = register_sysctl_table(relayfs_root_table, 1); + } + + return klog_channel; + } + + /** + * remove_klog_channel - destroys channel /mnt/relay/klog + * + * Returns 0, negative otherwise. + */ + int + remove_klog_channel(void) + { + if (relayfs_ctl_table_header) + unregister_sysctl_table(relayfs_ctl_table_header); + + return relay_close(klog_channel); + } + + EXPORT_SYMBOL(klog); + EXPORT_SYMBOL(klog_raw); + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/relay.c linux-current/fs/relayfs/relay.c *** linux-2.6.10/fs/relayfs/relay.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/relay.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,1961 ---- + /* + * Public API and common code for RelayFS. + * + * Please see Documentation/filesystems/relayfs.txt for API description. + * + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp + * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com) + * + * This file is released under the GPL. + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + #include "relay_lockless.h" + #include "relay_locking.h" + #include "resize.h" + + /* Relay channel table, indexed by channel id */ + static struct rchan * rchan_table[RELAY_MAX_CHANNELS]; + static rwlock_t rchan_table_lock = RW_LOCK_UNLOCKED; + + /* Relay operation structs, one per scheme */ + static struct relay_ops lockless_ops = { + .reserve = lockless_reserve, + .commit = lockless_commit, + .get_offset = lockless_get_offset, + .finalize = lockless_finalize, + .reset = lockless_reset, + .reset_index = lockless_reset_index + }; + + static struct relay_ops locking_ops = { + .reserve = locking_reserve, + .commit = locking_commit, + .get_offset = locking_get_offset, + .finalize = locking_finalize, + .reset = locking_reset, + .reset_index = locking_reset_index + }; + + /* + * Low-level relayfs kernel API. These functions should not normally be + * used by clients. See high-level kernel API below. + */ + + /** + * rchan_get - get channel associated with id, incrementing refcount + * @rchan_id: the channel id + * + * Returns channel if successful, NULL otherwise. + */ + struct rchan * + rchan_get(int rchan_id) + { + struct rchan *rchan; + + if ((rchan_id < 0) || (rchan_id >= RELAY_MAX_CHANNELS)) + return NULL; + + read_lock(&rchan_table_lock); + rchan = rchan_table[rchan_id]; + if (rchan) + atomic_inc(&rchan->refcount); + read_unlock(&rchan_table_lock); + + return rchan; + } + + /** + * clear_readers - clear non-VFS readers + * @rchan: the channel + * + * Clear the channel pointers of all non-VFS readers open on the channel. + */ + static inline void + clear_readers(struct rchan *rchan) + { + struct list_head *p; + struct rchan_reader *reader; + + read_lock(&rchan->open_readers_lock); + list_for_each(p, &rchan->open_readers) { + reader = list_entry(p, struct rchan_reader, list); + if (!reader->vfs_reader) + reader->rchan = NULL; + } + read_unlock(&rchan->open_readers_lock); + } + + /** + * rchan_alloc_id - reserve a channel id and store associated channel + * @rchan: the channel + * + * Returns channel id if successful, -1 otherwise. + */ + static inline int + rchan_alloc_id(struct rchan *rchan) + { + int i; + int rchan_id = -1; + + if (rchan == NULL) + return -1; + + write_lock(&rchan_table_lock); + for (i = 0; i < RELAY_MAX_CHANNELS; i++) { + if (rchan_table[i] == NULL) { + rchan_table[i] = rchan; + rchan_id = rchan->id = i; + break; + } + } + if (rchan_id != -1) + atomic_inc(&rchan->refcount); + write_unlock(&rchan_table_lock); + + return rchan_id; + } + + /** + * rchan_free_id - revoke a channel id and remove associated channel + * @rchan_id: the channel id + */ + static inline void + rchan_free_id(int rchan_id) + { + struct rchan *rchan; + + if ((rchan_id < 0) || (rchan_id >= RELAY_MAX_CHANNELS)) + return; + + write_lock(&rchan_table_lock); + rchan = rchan_table[rchan_id]; + rchan_table[rchan_id] = NULL; + write_unlock(&rchan_table_lock); + } + + /** + * rchan_destroy_buf - destroy the current channel buffer + * @rchan: the channel + */ + static inline int + rchan_destroy_buf(struct rchan *rchan) + { + int err = 0; + + if (rchan->buf && !rchan->init_buf) + err = free_rchan_buf(rchan->buf, + rchan->buf_page_array, + rchan->buf_page_count); + + return err; + } + + /** + * remove_rchan_file - remove the channel file + * @private: pointer to the channel struct + * + * Internal - manages the removal of old channel file + */ + static void + remove_rchan_file(void *private) + { + struct rchan *rchan = (struct rchan *)private; + + relayfs_remove_file(rchan->dentry); + } + + + /** + * relay_release - perform end-of-buffer processing for last buffer + * @rchan: the channel + * + * Returns 0 if successful, negative otherwise. + * + * Releases the channel buffer, destroys the channel, and removes the + * relay file from the relayfs filesystem. Should only be called from + * rchan_put(). If we're here, it means by definition refcount is 0. + */ + static int + relay_release(struct rchan *rchan) + { + int err = 0; + + if (rchan == NULL) { + err = -EBADF; + goto exit; + } + + err = rchan_destroy_buf(rchan); + if (err) + goto exit; + + rchan_free_id(rchan->id); + + INIT_WORK(&rchan->work, remove_rchan_file, rchan); + schedule_delayed_work(&rchan->work, 1); + + clear_readers(rchan); + kfree(rchan); + exit: + return err; + } + + /** + * rchan_get - decrement channel refcount, releasing it if 0 + * @rchan: the channel + * + * If the refcount reaches 0, the channel will be destroyed. + */ + void + rchan_put(struct rchan *rchan) + { + if (atomic_dec_and_test(&rchan->refcount)) + relay_release(rchan); + } + + /** + * relay_reserve - reserve a slot in the channel buffer + * @rchan: the channel + * @len: the length of the slot to reserve + * @td: the time delta between buffer start and current write, or TSC + * @err: receives the result flags + * @interrupting: 1 if interrupting previous, used only in locking scheme + * + * Returns pointer to the beginning of the reserved slot, NULL if error. + * + * The errcode value contains the result flags and is an ORed combination + * of the following: + * + * RELAY_BUFFER_SWITCH_NONE - no buffer switch occurred + * RELAY_EVENT_DISCARD_NONE - event should not be discarded + * RELAY_BUFFER_SWITCH - buffer switch occurred + * RELAY_EVENT_DISCARD - event should be discarded (all buffers are full) + * RELAY_EVENT_TOO_LONG - event won't fit into even an empty buffer + * + * buffer_start and buffer_end callbacks are triggered at this point + * if applicable. + */ + char * + relay_reserve(struct rchan *rchan, + u32 len, + struct timeval *ts, + u32 *td, + int *err, + int *interrupting) + { + if (rchan == NULL) + return NULL; + + *interrupting = 0; + + return rchan->relay_ops->reserve(rchan, len, ts, td, err, interrupting); + } + + + /** + * wakeup_readers - wake up VFS readers waiting on a channel + * @private: the channel + * + * This is the work function used to defer reader waking. The + * reason waking is deferred is that calling directly from commit + * causes problems if you're writing from say the scheduler. + */ + static void + wakeup_readers(void *private) + { + struct rchan *rchan = (struct rchan *)private; + + wake_up_interruptible(&rchan->read_wait); + } + + + /** + * relay_commit - commit a reserved slot in the buffer + * @rchan: the channel + * @from: commit the length starting here + * @len: length committed + * @interrupting: 1 if interrupting previous, used only in locking scheme + * + * After the write into the reserved buffer has been complted, this + * function must be called in order for the relay to determine whether + * buffers are complete and to wake up VFS readers. + * + * delivery callback is triggered at this point if applicable. + */ + void + relay_commit(struct rchan *rchan, + char *from, + u32 len, + int reserve_code, + int interrupting) + { + int deliver; + + if (rchan == NULL) + return; + + deliver = packet_delivery(rchan) || + (reserve_code & RELAY_BUFFER_SWITCH); + + rchan->relay_ops->commit(rchan, from, len, deliver, interrupting); + + /* The params are always the same, so no worry about re-queuing */ + if (deliver && waitqueue_active(&rchan->read_wait)) { + PREPARE_WORK(&rchan->wake_readers, wakeup_readers, rchan); + schedule_delayed_work(&rchan->wake_readers, 1); + } + } + + /** + * relay_get_offset - get current and max channel buffer offsets + * @rchan: the channel + * @max_offset: maximum channel offset + * + * Returns the current and maximum channel buffer offsets. + */ + u32 + relay_get_offset(struct rchan *rchan, u32 *max_offset) + { + return rchan->relay_ops->get_offset(rchan, max_offset); + } + + /** + * reset_index - try once to reset the current channel index + * @rchan: the channel + * @old_index: the index read before reset + * + * Attempts to reset the channel index to 0. It tries once, and + * if it fails, returns negative, 0 otherwise. + */ + int + reset_index(struct rchan *rchan, u32 old_index) + { + return rchan->relay_ops->reset_index(rchan, old_index); + } + + /* + * close() vm_op implementation for relayfs file mapping. + */ + static void + relay_file_mmap_close(struct vm_area_struct *vma) + { + struct file *filp = vma->vm_file; + struct rchan_reader *reader; + struct rchan *rchan; + + reader = (struct rchan_reader *)filp->private_data; + rchan = reader->rchan; + + atomic_dec(&rchan->mapped); + + rchan->callbacks->fileop_notify(reader->rchan->id, filp, + RELAY_FILE_UNMAP); + } + + /* + * vm_ops for relay file mappings. + */ + static struct vm_operations_struct relay_file_mmap_ops = { + .close = relay_file_mmap_close + }; + + /* \begin{Code inspired from BTTV driver} */ + static inline unsigned long + kvirt_to_pa(unsigned long adr) + { + unsigned long kva, ret; + + kva = (unsigned long) page_address(vmalloc_to_page((void *) adr)); + kva |= adr & (PAGE_SIZE - 1); + ret = __pa(kva); + return ret; + } + + static int + relay_mmap_region(struct vm_area_struct *vma, + const char *adr, + const char *start_pos, + unsigned long size) + { + unsigned long start = (unsigned long) adr; + unsigned long page, pos; + + pos = (unsigned long) start_pos; + + while (size > 0) { + page = kvirt_to_pa(pos); + #ifdef CONFIG_MIPS /* avoid d-cache aliasing */ + if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, + PAGE_SIZE, + pgprot_noncached(PAGE_SHARED))) + return -EAGAIN; + #else + if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, + PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; + #endif + start += PAGE_SIZE; + pos += PAGE_SIZE; + size -= PAGE_SIZE; + } + + return 0; + } + /* \end{Code inspired from BTTV driver} */ + + /** + * relay_mmap_buffer: - mmap buffer to process address space + * @rchan_id: relay channel id + * @vma: vm_area_struct describing memory to be mapped + * + * Returns: + * 0 if ok + * -EAGAIN, when remap failed + * -EINVAL, invalid requested length + * + * Caller should already have grabbed mmap_sem. + */ + int + __relay_mmap_buffer(struct rchan *rchan, + struct vm_area_struct *vma) + { + int err = 0; + unsigned long length = vma->vm_end - vma->vm_start; + struct file *filp = vma->vm_file; + + if (rchan == NULL) { + err = -EBADF; + goto exit; + } + + if (rchan->init_buf) { + err = -EPERM; + goto exit; + } + + if (length != (unsigned long)rchan->alloc_size) { + err = -EINVAL; + goto exit; + } + + err = relay_mmap_region(vma, + (char *)vma->vm_start, + rchan->buf, + rchan->alloc_size); + + if (err == 0) { + vma->vm_ops = &relay_file_mmap_ops; + err = rchan->callbacks->fileop_notify(rchan->id, filp, + RELAY_FILE_MAP); + if (err == 0) + atomic_inc(&rchan->mapped); + } + exit: + return err; + } + + /* + * High-level relayfs kernel API. See Documentation/filesystems/relafys.txt. + */ + + /* + * rchan_callback implementations defining default channel behavior. Used + * in place of corresponding NULL values in client callback struct. + */ + + /* + * buffer_end() default callback. Does nothing. + */ + static int + buffer_end_default_callback(int rchan_id, + char *current_write_pos, + char *end_of_buffer, + struct timeval end_time, + u32 end_tsc, + int using_tsc) + { + return 0; + } + + /* + * buffer_start() default callback. Does nothing. + */ + static int + buffer_start_default_callback(int rchan_id, + char *current_write_pos, + u32 buffer_id, + struct timeval start_time, + u32 start_tsc, + int using_tsc) + { + return 0; + } + + /* + * deliver() default callback. Does nothing. + */ + static void + deliver_default_callback(int rchan_id, char *from, u32 len) + { + } + + /* + * user_deliver() default callback. Does nothing. + */ + static void + user_deliver_default_callback(int rchan_id, char *from, u32 len) + { + } + + /* + * needs_resize() default callback. Does nothing. + */ + static void + needs_resize_default_callback(int rchan_id, + int resize_type, + u32 suggested_buf_size, + u32 suggested_n_bufs) + { + } + + /* + * fileop_notify() default callback. Does nothing. + */ + static int + fileop_notify_default_callback(int rchan_id, + struct file *filp, + enum relay_fileop fileop) + { + return 0; + } + + /* + * ioctl() default callback. Does nothing. + */ + static int + ioctl_default_callback(int rchan_id, + unsigned int cmd, + unsigned long arg) + { + return 0; + } + + /* relay channel default callbacks */ + static struct rchan_callbacks default_channel_callbacks = { + .buffer_start = buffer_start_default_callback, + .buffer_end = buffer_end_default_callback, + .deliver = deliver_default_callback, + .user_deliver = user_deliver_default_callback, + .needs_resize = needs_resize_default_callback, + .fileop_notify = fileop_notify_default_callback, + .ioctl = ioctl_default_callback, + }; + + /** + * check_attribute_flags - check sanity of channel attributes + * @flags: channel attributes + * @resizeable: 1 if true + * + * Returns 0 if successful, negative otherwise. + */ + static int + check_attribute_flags(u32 *attribute_flags, int resizeable) + { + u32 flags = *attribute_flags; + + if (!(flags & RELAY_DELIVERY_BULK) && !(flags & RELAY_DELIVERY_PACKET)) + return -EINVAL; /* Delivery mode must be specified */ + + if (!(flags & RELAY_USAGE_SMP) && !(flags & RELAY_USAGE_GLOBAL)) + return -EINVAL; /* Usage must be specified */ + + if (resizeable) { /* Resizeable can never be continuous */ + *attribute_flags &= ~RELAY_MODE_CONTINUOUS; + *attribute_flags |= RELAY_MODE_NO_OVERWRITE; + } + + if ((flags & RELAY_MODE_CONTINUOUS) && + (flags & RELAY_MODE_NO_OVERWRITE)) + return -EINVAL; /* Can't have it both ways */ + + if (!(flags & RELAY_MODE_CONTINUOUS) && + !(flags & RELAY_MODE_NO_OVERWRITE)) + *attribute_flags |= RELAY_MODE_CONTINUOUS; /* Default to continuous */ + + if (!(flags & RELAY_SCHEME_ANY)) + return -EINVAL; /* One or both must be specified */ + else if (flags & RELAY_SCHEME_LOCKLESS) { + if (have_cmpxchg()) + *attribute_flags &= ~RELAY_SCHEME_LOCKING; + else if (flags & RELAY_SCHEME_LOCKING) + *attribute_flags &= ~RELAY_SCHEME_LOCKLESS; + else + return -EINVAL; /* Locking scheme not an alternative */ + } + + if (!(flags & RELAY_TIMESTAMP_ANY)) + return -EINVAL; /* One or both must be specified */ + else if (flags & RELAY_TIMESTAMP_TSC) { + if (have_tsc()) + *attribute_flags &= ~RELAY_TIMESTAMP_GETTIMEOFDAY; + else if (flags & RELAY_TIMESTAMP_GETTIMEOFDAY) + *attribute_flags &= ~RELAY_TIMESTAMP_TSC; + else + return -EINVAL; /* gettimeofday not an alternative */ + } + + return 0; + } + + /* + * High-level API functions. + */ + + /** + * __relay_reset - internal reset function + * @rchan: the channel + * @init: 1 if this is a first-time channel initialization + * + * See relay_reset for description of effect. + */ + void + __relay_reset(struct rchan *rchan, int init) + { + int i; + + if (init) { + rchan->version = RELAYFS_CHANNEL_VERSION; + init_MUTEX(&rchan->resize_sem); + init_waitqueue_head(&rchan->read_wait); + init_waitqueue_head(&rchan->write_wait); + atomic_set(&rchan->refcount, 0); + INIT_LIST_HEAD(&rchan->open_readers); + rchan->open_readers_lock = RW_LOCK_UNLOCKED; + } + + rchan->buf_id = rchan->buf_idx = 0; + atomic_set(&rchan->suspended, 0); + atomic_set(&rchan->mapped, 0); + rchan->half_switch = 0; + rchan->bufs_produced = 0; + rchan->bufs_consumed = 0; + rchan->bytes_consumed = 0; + rchan->read_start = 0; + rchan->initialized = 0; + rchan->finalized = 0; + rchan->resize_min = rchan->resize_max = 0; + rchan->resizing = 0; + rchan->replace_buffer = 0; + rchan->resize_buf = NULL; + rchan->resize_buf_size = 0; + rchan->resize_alloc_size = 0; + rchan->resize_n_bufs = 0; + rchan->resize_err = 0; + rchan->resize_failures = 0; + rchan->resize_order = 0; + + rchan->expand_page_array = NULL; + rchan->expand_page_count = 0; + rchan->shrink_page_array = NULL; + rchan->shrink_page_count = 0; + rchan->resize_page_array = NULL; + rchan->resize_page_count = 0; + rchan->old_buf_page_array = NULL; + rchan->expand_buf_id = 0; + + INIT_WORK(&rchan->wake_readers, NULL, NULL); + INIT_WORK(&rchan->wake_writers, NULL, NULL); + + for (i = 0; i < RELAY_MAX_BUFS; i++) + rchan->unused_bytes[i] = 0; + + rchan->relay_ops->reset(rchan, init); + } + + /** + * relay_reset - reset the channel + * @rchan: the channel + * + * Returns 0 if successful, negative if not. + * + * This has the effect of erasing all data from the buffer and + * restarting the channel in its initial state. The buffer itself + * is not freed, so any mappings are still in effect. + * + * NOTE: Care should be taken that the channel isn't actually + * being used by anything when this call is made. + */ + int + relay_reset(int rchan_id) + { + struct rchan *rchan; + + rchan = rchan_get(rchan_id); + if (rchan == NULL) + return -EBADF; + + __relay_reset(rchan, 0); + update_readers_consumed(rchan, 0, 0); + + rchan_put(rchan); + + return 0; + } + + /** + * check_init_buf - check the sanity of init_buf, if present + * @init_buf: the initbuf + * @init_buf_size: the total initbuf size + * @bufsize: the channel's sub-buffer size + * @nbufs: the number of sub-buffers in the channel + * + * Returns 0 if ok, negative otherwise. + */ + static int + check_init_buf(char *init_buf, u32 init_buf_size, u32 bufsize, u32 nbufs) + { + int err = 0; + + if (init_buf && nbufs == 1) /* 1 sub-buffer makes no sense */ + err = -EINVAL; + + if (init_buf && (bufsize * nbufs != init_buf_size)) + err = -EINVAL; + + return err; + } + + /** + * rchan_create_buf - allocate the initial channel buffer + * @rchan: the channel + * @size_alloc: the total size of the channel buffer + * + * Returns 0 if successful, negative otherwise. + */ + static inline int + rchan_create_buf(struct rchan *rchan, int size_alloc) + { + struct page **page_array; + int page_count; + + if ((rchan->buf = (char *)alloc_rchan_buf(size_alloc, &page_array, &page_count)) == NULL) { + rchan->buf_page_array = NULL; + rchan->buf_page_count = 0; + return -ENOMEM; + } + + rchan->buf_page_array = page_array; + rchan->buf_page_count = page_count; + + return 0; + } + + /** + * rchan_create - allocate and initialize a channel, including buffer + * @chanpath: path specifying the relayfs channel file to create + * @bufsize: the size of the sub-buffers within the channel buffer + * @nbufs: the number of sub-buffers within the channel buffer + * @rchan_flags: flags specifying buffer attributes + * @err: err code + * + * Returns channel if successful, NULL otherwise, err receives errcode. + * + * Allocates a struct rchan representing a relay channel, according + * to the attributes passed in via rchan_flags. Does some basic sanity + * checking but doesn't try to do anything smart. In particular, the + * number of buffers must be a power of 2, and if the lockless scheme + * is being used, the sub-buffer size must also be a power of 2. The + * locking scheme can use buffers of any size. + */ + static struct rchan * + rchan_create(const char *chanpath, + int bufsize, + int nbufs, + u32 rchan_flags, + char *init_buf, + u32 init_buf_size, + int *err) + { + int size_alloc; + struct rchan *rchan = NULL; + + *err = 0; + + rchan = (struct rchan *)kmalloc(sizeof(struct rchan), GFP_KERNEL); + if (rchan == NULL) { + *err = -ENOMEM; + return NULL; + } + rchan->buf = rchan->init_buf = NULL; + + *err = check_init_buf(init_buf, init_buf_size, bufsize, nbufs); + if (*err) + goto exit; + + if (nbufs == 1 && bufsize) { + rchan->n_bufs = nbufs; + rchan->buf_size = bufsize; + size_alloc = bufsize; + goto alloc; + } + + if (bufsize <= 0 || + (rchan_flags & RELAY_SCHEME_LOCKLESS && hweight32(bufsize) != 1) || + hweight32(nbufs) != 1 || + nbufs < RELAY_MIN_BUFS || + nbufs > RELAY_MAX_BUFS) { + *err = -EINVAL; + goto exit; + } + + size_alloc = FIX_SIZE(bufsize * nbufs); + if (size_alloc > RELAY_MAX_BUF_SIZE) { + *err = -EINVAL; + goto exit; + } + rchan->n_bufs = nbufs; + rchan->buf_size = bufsize; + + if (rchan_flags & RELAY_SCHEME_LOCKLESS) { + offset_bits(rchan) = ffs(bufsize) - 1; + offset_mask(rchan) = RELAY_BUF_OFFSET_MASK(offset_bits(rchan)); + bufno_bits(rchan) = ffs(nbufs) - 1; + } + alloc: + if (rchan_alloc_id(rchan) == -1) { + *err = -ENOMEM; + goto exit; + } + + if (init_buf == NULL) { + *err = rchan_create_buf(rchan, size_alloc); + if (*err) { + rchan_free_id(rchan->id); + goto exit; + } + } else + rchan->buf = rchan->init_buf = init_buf; + + rchan->alloc_size = size_alloc; + + if (rchan_flags & RELAY_SCHEME_LOCKLESS) + rchan->relay_ops = &lockless_ops; + else + rchan->relay_ops = &locking_ops; + + exit: + if (*err) { + kfree(rchan); + rchan = NULL; + } + + return rchan; + } + + + static char tmpname[NAME_MAX]; + + /** + * rchan_create_dir - create directory for file + * @chanpath: path to file, including filename + * @residual: filename remaining after parse + * @topdir: the directory filename should be created in + * + * Returns 0 if successful, negative otherwise. + * + * Inspired by xlate_proc_name() in procfs. Given a file path which + * includes the filename, creates any and all directories necessary + * to create the file. + */ + static int + rchan_create_dir(const char * chanpath, + const char **residual, + struct dentry **topdir) + { + const char *cp = chanpath, *next; + struct dentry *parent = NULL; + int len, err = 0; + + while (1) { + next = strchr(cp, '/'); + if (!next) + break; + + len = next - cp; + + strncpy(tmpname, cp, len); + tmpname[len] = '\0'; + err = relayfs_create_dir(tmpname, parent, &parent); + if (err && (err != -EEXIST)) + return err; + cp += len + 1; + } + + *residual = cp; + *topdir = parent; + + return err; + } + + /** + * rchan_create_file - create file, including parent directories + * @chanpath: path to file, including filename + * @dentry: result dentry + * @data: data to associate with the file + * + * Returns 0 if successful, negative otherwise. + */ + static int + rchan_create_file(const char * chanpath, + struct dentry **dentry, + struct rchan * data, + int mode) + { + int err; + const char * fname; + struct dentry *topdir; + + err = rchan_create_dir(chanpath, &fname, &topdir); + if (err && (err != -EEXIST)) + return err; + + err = relayfs_create_file(fname, topdir, dentry, (void *)data, mode); + + return err; + } + + /** + * relay_open - create a new file/channel buffer in relayfs + * @chanpath: name of file to create, including path + * @bufsize: size of sub-buffers + * @nbufs: number of sub-buffers + * @flags: channel attributes + * @callbacks: client callback functions + * @start_reserve: number of bytes to reserve at start of each sub-buffer + * @end_reserve: number of bytes to reserve at end of each sub-buffer + * @rchan_start_reserve: additional reserve at start of first sub-buffer + * @resize_min: minimum total buffer size, if set + * @resize_max: maximum total buffer size, if set + * @mode: the perms to be given to the relayfs file, 0 to accept defaults + * @init_buf: initial memory buffer to start out with, NULL if N/A + * @init_buf_size: initial memory buffer size to start out with, 0 if N/A + * + * Returns channel id if successful, negative otherwise. + * + * Creates a relay channel using the sizes and attributes specified. + * The default permissions, used if mode == 0 are S_IRUSR | S_IWUSR. See + * Documentation/filesystems/relayfs.txt for details. + */ + int + relay_open(const char *chanpath, + int bufsize, + int nbufs, + u32 flags, + struct rchan_callbacks *channel_callbacks, + u32 start_reserve, + u32 end_reserve, + u32 rchan_start_reserve, + u32 resize_min, + u32 resize_max, + int mode, + char *init_buf, + u32 init_buf_size) + { + int err; + struct rchan *rchan; + struct dentry *dentry; + struct rchan_callbacks *callbacks = NULL; + + if (chanpath == NULL) + return -EINVAL; + + if (nbufs != 1) { + err = check_attribute_flags(&flags, resize_min ? 1 : 0); + if (err) + return err; + } + + rchan = rchan_create(chanpath, bufsize, nbufs, flags, init_buf, init_buf_size, &err); + + if (err < 0) + return err; + + /* Create file in fs */ + if ((err = rchan_create_file(chanpath, &dentry, rchan, mode)) < 0) { + rchan_destroy_buf(rchan); + rchan_free_id(rchan->id); + kfree(rchan); + return err; + } + + rchan->dentry = dentry; + + if (channel_callbacks == NULL) + callbacks = &default_channel_callbacks; + else + callbacks = channel_callbacks; + + if (callbacks->buffer_end == NULL) + callbacks->buffer_end = buffer_end_default_callback; + if (callbacks->buffer_start == NULL) + callbacks->buffer_start = buffer_start_default_callback; + if (callbacks->deliver == NULL) + callbacks->deliver = deliver_default_callback; + if (callbacks->user_deliver == NULL) + callbacks->user_deliver = user_deliver_default_callback; + if (callbacks->needs_resize == NULL) + callbacks->needs_resize = needs_resize_default_callback; + if (callbacks->fileop_notify == NULL) + callbacks->fileop_notify = fileop_notify_default_callback; + if (callbacks->ioctl == NULL) + callbacks->ioctl = ioctl_default_callback; + rchan->callbacks = callbacks; + + /* Just to let the client know the sizes used */ + rchan->callbacks->needs_resize(rchan->id, + RELAY_RESIZE_REPLACED, + rchan->buf_size, + rchan->n_bufs); + + rchan->flags = flags; + rchan->start_reserve = start_reserve; + rchan->end_reserve = end_reserve; + rchan->rchan_start_reserve = rchan_start_reserve; + + __relay_reset(rchan, 1); + + if (resize_min > 0 && resize_max > 0 && + resize_max < RELAY_MAX_TOTAL_BUF_SIZE) { + rchan->resize_min = resize_min; + rchan->resize_max = resize_max; + init_shrink_timer(rchan); + } + + rchan_get(rchan->id); + + return rchan->id; + } + + /** + * relay_discard_init_buf - alloc channel buffer and copy init_buf into it + * @rchan_id: the channel id + * + * Returns 0 if successful, negative otherwise. + * + * NOTE: May sleep. Should also be called only when the channel isn't + * actively being written into. + */ + int + relay_discard_init_buf(int rchan_id) + { + struct rchan *rchan; + int err = 0; + + rchan = rchan_get(rchan_id); + if (rchan == NULL) + return -EBADF; + + if (rchan->init_buf == NULL) { + err = -EINVAL; + goto out; + } + + err = rchan_create_buf(rchan, rchan->alloc_size); + if (err) + goto out; + + memcpy(rchan->buf, rchan->init_buf, rchan->n_bufs * rchan->buf_size); + rchan->init_buf = NULL; + out: + rchan_put(rchan); + + return err; + } + + /** + * relay_finalize - perform end-of-buffer processing for last buffer + * @rchan_id: the channel id + * @releasing: true if called when releasing file + * + * Returns 0 if successful, negative otherwise. + */ + static int + relay_finalize(int rchan_id) + { + struct rchan *rchan = rchan_get(rchan_id); + if (rchan == NULL) + return -EBADF; + + if (rchan->finalized == 0) { + rchan->relay_ops->finalize(rchan); + rchan->finalized = 1; + } + + if (waitqueue_active(&rchan->read_wait)) { + PREPARE_WORK(&rchan->wake_readers, wakeup_readers, rchan); + schedule_delayed_work(&rchan->wake_readers, 1); + } + + rchan_put(rchan); + + return 0; + } + + /** + * restore_callbacks - restore default channel callbacks + * @rchan: the channel + * + * Restore callbacks to the default versions. + */ + static inline void + restore_callbacks(struct rchan *rchan) + { + if (rchan->callbacks != &default_channel_callbacks) + rchan->callbacks = &default_channel_callbacks; + } + + /** + * relay_close - close the channel + * @rchan_id: relay channel id + * + * Finalizes the last sub-buffer and marks the channel as finalized. + * The channel buffer and channel data structure are then freed + * automatically when the last reference to the channel is given up. + */ + int + relay_close(int rchan_id) + { + int err; + struct rchan *rchan; + + if ((rchan_id < 0) || (rchan_id >= RELAY_MAX_CHANNELS)) + return -EBADF; + + err = relay_finalize(rchan_id); + + if (!err) { + read_lock(&rchan_table_lock); + rchan = rchan_table[rchan_id]; + read_unlock(&rchan_table_lock); + + if (rchan) { + restore_callbacks(rchan); + if (rchan->resize_min) + del_timer(&rchan->shrink_timer); + rchan_put(rchan); + } + } + + return err; + } + + /** + * relay_write - reserve a slot in the channel and write data into it + * @rchan_id: relay channel id + * @data_ptr: data to be written into reserved slot + * @count: number of bytes to write + * @td_offset: optional offset where time delta should be written + * @wrote_pos: optional ptr returning buf pos written to, ignored if NULL + * + * Returns the number of bytes written, 0 or negative on failure. + * + * Reserves space in the channel and writes count bytes of data_ptr + * to it. Automatically performs any necessary locking, depending + * on the scheme and SMP usage in effect (no locking is done for the + * lockless scheme regardless of usage). + * + * If td_offset is >= 0, the internal time delta calculated when + * slot was reserved will be written at that offset. + * + * If wrote_pos is non-NULL, it will receive the location the data + * was written to, which may be needed for some applications but is not + * normally interesting. + */ + int + relay_write(int rchan_id, + const void *data_ptr, + size_t count, + int td_offset, + void **wrote_pos) + { + unsigned long flags; + char *reserved, *write_pos; + int bytes_written = 0; + int reserve_code, interrupting; + struct timeval ts; + u32 td; + struct rchan *rchan; + + rchan = rchan_get(rchan_id); + if (rchan == NULL) + return -EBADF; + + relay_lock_channel(rchan, flags); /* nop for lockless */ + + write_pos = reserved = relay_reserve(rchan, count, &ts, &td, + &reserve_code, &interrupting); + + if (reserved != NULL) { + relay_write_direct(write_pos, data_ptr, count); + if ((td_offset >= 0) && (td_offset < count - sizeof(td))) + *((u32 *)(reserved + td_offset)) = td; + bytes_written = count; + } else if (reserve_code == RELAY_WRITE_TOO_LONG) + bytes_written = -EINVAL; + + if (bytes_written > 0) + relay_commit(rchan, reserved, bytes_written, reserve_code, interrupting); + + relay_unlock_channel(rchan, flags); /* nop for lockless */ + + rchan_put(rchan); + + if (wrote_pos) + *wrote_pos = reserved; + + return bytes_written; + } + + /** + * wakeup_writers - wake up VFS writers waiting on a channel + * @private: the channel + * + * This is the work function used to defer writer waking. The + * reason waking is deferred is that calling directly from + * buffers_consumed causes problems if you're writing from say + * the scheduler. + */ + static void + wakeup_writers(void *private) + { + struct rchan *rchan = (struct rchan *)private; + + wake_up_interruptible(&rchan->write_wait); + } + + + /** + * __relay_buffers_consumed - internal version of relay_buffers_consumed + * @rchan: the relay channel + * @bufs_consumed: number of buffers to add to current count for channel + * + * Internal - updates the channel's consumed buffer count. + */ + static void + __relay_buffers_consumed(struct rchan *rchan, u32 bufs_consumed) + { + rchan->bufs_consumed += bufs_consumed; + + if (rchan->bufs_consumed > rchan->bufs_produced) + rchan->bufs_consumed = rchan->bufs_produced; + + atomic_set(&rchan->suspended, 0); + + PREPARE_WORK(&rchan->wake_writers, wakeup_writers, rchan); + schedule_delayed_work(&rchan->wake_writers, 1); + } + + /** + * __reader_buffers_consumed - update reader/channel consumed buffer count + * @reader: channel reader + * @bufs_consumed: number of buffers to add to current count for channel + * + * Internal - updates the reader's consumed buffer count. If the reader's + * resulting total is greater than the channel's, update the channel's. + */ + static void + __reader_buffers_consumed(struct rchan_reader *reader, u32 bufs_consumed) + { + reader->bufs_consumed += bufs_consumed; + + if (reader->bufs_consumed > reader->rchan->bufs_consumed) + __relay_buffers_consumed(reader->rchan, bufs_consumed); + } + + /** + * relay_buffers_consumed - add to the # buffers consumed for the channel + * @reader: channel reader + * @bufs_consumed: number of buffers to add to current count for channel + * + * Adds to the channel's consumed buffer count. buffers_consumed should + * be the number of buffers newly consumed, not the total number consumed. + * + * NOTE: kernel clients don't need to call this function if the reader + * is auto-consuming or the channel is MODE_CONTINUOUS. + */ + void + relay_buffers_consumed(struct rchan_reader *reader, u32 bufs_consumed) + { + if (reader && reader->rchan) + __reader_buffers_consumed(reader, bufs_consumed); + } + + /** + * __relay_bytes_consumed - internal version of relay_bytes_consumed + * @rchan: the relay channel + * @bytes_consumed: number of bytes to add to current count for channel + * @read_offset: where the bytes were consumed from + * + * Internal - updates the channel's consumed count. + */ + static void + __relay_bytes_consumed(struct rchan *rchan, u32 bytes_consumed, u32 read_offset) + { + u32 consuming_idx; + u32 unused; + + consuming_idx = read_offset / rchan->buf_size; + + if (consuming_idx >= rchan->n_bufs) + consuming_idx = rchan->n_bufs - 1; + rchan->bytes_consumed += bytes_consumed; + + unused = rchan->unused_bytes[consuming_idx]; + + if (rchan->bytes_consumed + unused >= rchan->buf_size) { + __relay_buffers_consumed(rchan, 1); + rchan->bytes_consumed = 0; + } + } + + /** + * __reader_bytes_consumed - update reader/channel consumed count + * @reader: channel reader + * @bytes_consumed: number of bytes to add to current count for channel + * @read_offset: where the bytes were consumed from + * + * Internal - updates the reader's consumed count. If the reader's + * resulting total is greater than the channel's, update the channel's. + */ + static void + __reader_bytes_consumed(struct rchan_reader *reader, u32 bytes_consumed, u32 read_offset) + { + u32 consuming_idx; + u32 unused; + + consuming_idx = read_offset / reader->rchan->buf_size; + + if (consuming_idx >= reader->rchan->n_bufs) + consuming_idx = reader->rchan->n_bufs - 1; + + reader->bytes_consumed += bytes_consumed; + + unused = reader->rchan->unused_bytes[consuming_idx]; + + if (reader->bytes_consumed + unused >= reader->rchan->buf_size) { + reader->bufs_consumed++; + reader->bytes_consumed = 0; + } + + if ((reader->bufs_consumed > reader->rchan->bufs_consumed) || + ((reader->bufs_consumed == reader->rchan->bufs_consumed) && + (reader->bytes_consumed > reader->rchan->bytes_consumed))) + __relay_bytes_consumed(reader->rchan, bytes_consumed, read_offset); + } + + /** + * relay_bytes_consumed - add to the # bytes consumed for the channel + * @reader: channel reader + * @bytes_consumed: number of bytes to add to current count for channel + * @read_offset: where the bytes were consumed from + * + * Adds to the channel's consumed count. bytes_consumed should be the + * number of bytes actually read e.g. return value of relay_read() and + * the read_offset should be the actual offset the bytes were read from + * e.g. the actual_read_offset set by relay_read(). See + * Documentation/filesystems/relayfs.txt for more details. + * + * NOTE: kernel clients don't need to call this function if the reader + * is auto-consuming or the channel is MODE_CONTINUOUS. + */ + void + relay_bytes_consumed(struct rchan_reader *reader, u32 bytes_consumed, u32 read_offset) + { + if (reader && reader->rchan) + __reader_bytes_consumed(reader, bytes_consumed, read_offset); + } + + /** + * update_readers_consumed - apply offset change to reader + * @rchan: the channel + * + * Apply the consumed counts to all readers open on the channel. + */ + void + update_readers_consumed(struct rchan *rchan, u32 bufs_consumed, u32 bytes_consumed) + { + struct list_head *p; + struct rchan_reader *reader; + + read_lock(&rchan->open_readers_lock); + list_for_each(p, &rchan->open_readers) { + reader = list_entry(p, struct rchan_reader, list); + reader->bufs_consumed = bufs_consumed; + reader->bytes_consumed = bytes_consumed; + if (reader->vfs_reader) + reader->pos.file->f_pos = 0; + else + reader->pos.f_pos = 0; + reader->offset_changed = 1; + } + read_unlock(&rchan->open_readers_lock); + rchan->read_start = 0; + } + + /** + * do_read - utility function to do the actual read to user + * @rchan: the channel + * @buf: user buf to read into, NULL if just getting info + * @count: bytes requested + * @read_offset: offset into channel + * @new_offset: new offset into channel after read + * @actual_read_offset: read offset actually used + * + * Returns the number of bytes read, 0 if none. + */ + static ssize_t + do_read(struct rchan *rchan, char *buf, size_t count, u32 read_offset, u32 *new_offset, u32 *actual_read_offset) + { + u32 read_bufno, cur_bufno; + u32 avail_offset, cur_idx, max_offset, buf_end_offset; + u32 avail_count, buf_size; + int unused_bytes = 0; + size_t read_count = 0; + u32 last_buf_byte_offset; + + *actual_read_offset = read_offset; + + buf_size = rchan->buf_size; + if (unlikely(!buf_size)) BUG(); + + read_bufno = read_offset / buf_size; + if (unlikely(read_bufno >= RELAY_MAX_BUFS)) BUG(); + unused_bytes = rchan->unused_bytes[read_bufno]; + + avail_offset = cur_idx = relay_get_offset(rchan, &max_offset); + + if (cur_idx == read_offset) { + if (atomic_read(&rchan->suspended) == 1) { + read_offset += 1; + if (read_offset >= max_offset) + read_offset = 0; + *actual_read_offset = read_offset; + } else { + *new_offset = read_offset; + return 0; + } + } else { + last_buf_byte_offset = (read_bufno + 1) * buf_size - 1; + if (read_offset == last_buf_byte_offset) { + if (unused_bytes != 1) { + read_offset += 1; + if (read_offset >= max_offset) + read_offset = 0; + *actual_read_offset = read_offset; + } + } + } + + read_bufno = read_offset / buf_size; + if (unlikely(read_bufno >= RELAY_MAX_BUFS)) BUG(); + unused_bytes = rchan->unused_bytes[read_bufno]; + + cur_bufno = cur_idx / buf_size; + + buf_end_offset = (read_bufno + 1) * buf_size - unused_bytes; + if (avail_offset > buf_end_offset) + avail_offset = buf_end_offset; + else if (avail_offset < read_offset) + avail_offset = buf_end_offset; + avail_count = avail_offset - read_offset; + read_count = avail_count >= count ? count : avail_count; + + if (read_count && buf != NULL) + if (copy_to_user(buf, rchan->buf + read_offset, read_count)) + return -EFAULT; + + if (read_bufno == cur_bufno) + if (read_count && (read_offset + read_count >= buf_end_offset) && (read_offset + read_count <= cur_idx)) { + *new_offset = cur_idx; + return read_count; + } + + if (read_offset + read_count + unused_bytes > max_offset) + *new_offset = 0; + else if (read_offset + read_count >= buf_end_offset) + *new_offset = read_offset + read_count + unused_bytes; + else + *new_offset = read_offset + read_count; + + return read_count; + } + + /** + * __relay_read - read bytes from channel, relative to current reader pos + * @reader: channel reader + * @buf: user buf to read into, NULL if just getting info + * @count: bytes requested + * @read_offset: offset into channel + * @new_offset: new offset into channel after read + * @actual_read_offset: read offset actually used + * @wait: if non-zero, wait for something to read + * + * Internal - see relay_read() for details. + * + * Returns the number of bytes read, 0 if none, negative on failure. + */ + static ssize_t + __relay_read(struct rchan_reader *reader, char *buf, size_t count, u32 read_offset, u32 *new_offset, u32 *actual_read_offset, int wait) + { + int err = 0; + size_t read_count = 0; + struct rchan *rchan = reader->rchan; + + if (!wait && !rchan->initialized) + return -EAGAIN; + + if (using_lockless(rchan)) + read_offset &= idx_mask(rchan); + + if (read_offset >= rchan->n_bufs * rchan->buf_size) { + *new_offset = 0; + if (!wait) + return -EAGAIN; + else + return -EINTR; + } + + if (buf != NULL && wait) { + err = wait_event_interruptible(rchan->read_wait, + ((rchan->finalized == 1) || + (atomic_read(&rchan->suspended) == 1) || + (relay_get_offset(rchan, NULL) != read_offset))); + + if (rchan->finalized) + return 0; + + if (reader->offset_changed) { + reader->offset_changed = 0; + return -EINTR; + } + + if (err) + return err; + } + + read_count = do_read(rchan, buf, count, read_offset, new_offset, actual_read_offset); + + if (read_count < 0) + err = read_count; + + if (err) + return err; + else + return read_count; + } + + /** + * relay_read - read bytes from channel, relative to current reader pos + * @reader: channel reader + * @buf: user buf to read into, NULL if just getting info + * @count: bytes requested + * @wait: if non-zero, wait for something to read + * @actual_read_offset: set read offset actually used, must not be NULL + * + * Reads count bytes from the channel, or as much as is available within + * the sub-buffer currently being read. The read offset that will be + * read from is the position contained within the reader object. If the + * wait flag is set, buf is non-NULL, and there is nothing available, + * it will wait until there is. If the wait flag is 0 and there is + * nothing available, -EAGAIN is returned. If buf is NULL, the value + * returned is the number of bytes that would have been read. + * actual_read_offset is the value that should be passed as the read + * offset to relay_bytes_consumed, needed only if the reader is not + * auto-consuming and the channel is MODE_NO_OVERWRITE, but in any case, + * it must not be NULL. See Documentation/filesystems/relayfs.txt for + * more details. + */ + ssize_t + relay_read(struct rchan_reader *reader, char *buf, size_t count, int wait, u32 *actual_read_offset, u32 *new_offset) + { + u32 read_offset; + ssize_t read_count; + + if (reader == NULL || reader->rchan == NULL) + return -EBADF; + + if (actual_read_offset == NULL) + return -EINVAL; + + if (reader->vfs_reader) + read_offset = (u32)(reader->pos.file->f_pos); + else + read_offset = reader->pos.f_pos; + *actual_read_offset = read_offset; + + read_count = __relay_read(reader, buf, count, read_offset, + new_offset, actual_read_offset, wait); + + if (read_count < 0) + return read_count; + + if (reader->vfs_reader) { + down(&reader->rchan->resize_sem); + if (!(reader->rchan->flags & RELAY_MODE_START_AT_ZERO)) + reader->rchan->read_start = *new_offset; + up(&reader->rchan->resize_sem); + } else + reader->pos.f_pos = *new_offset; + + if (reader->auto_consume && ((read_count) || (*new_offset != read_offset))) + __reader_bytes_consumed(reader, read_count, *actual_read_offset); + + if (read_count == 0 && !wait) + return -EAGAIN; + + return read_count; + } + + /** + * relay_bytes_avail - number of bytes available in current sub-buffer + * @reader: channel reader + * + * Returns the number of bytes available relative to the reader's + * current read position within the corresponding sub-buffer, 0 if + * there is nothing available. See Documentation/filesystems/relayfs.txt + * for more details. + */ + ssize_t + relay_bytes_avail(struct rchan_reader *reader) + { + u32 f_pos; + u32 new_offset; + u32 actual_read_offset; + ssize_t bytes_read; + + if (reader == NULL || reader->rchan == NULL) + return -EBADF; + + if (reader->vfs_reader) + f_pos = (u32)reader->pos.file->f_pos; + else + f_pos = reader->pos.f_pos; + new_offset = f_pos; + + bytes_read = __relay_read(reader, NULL, reader->rchan->buf_size, + f_pos, &new_offset, &actual_read_offset, 0); + + if ((new_offset != f_pos) && + ((bytes_read == -EINTR) || (bytes_read == 0))) + bytes_read = -EAGAIN; + else if ((bytes_read < 0) && (bytes_read != -EAGAIN)) + bytes_read = 0; + + return bytes_read; + } + + /** + * rchan_empty - boolean, is the channel empty wrt reader? + * @reader: channel reader + * + * Returns 1 if the channel is empty, 0 otherwise. + */ + int + rchan_empty(struct rchan_reader *reader) + { + ssize_t avail_count; + u32 buffers_ready; + struct rchan *rchan = reader->rchan; + u32 cur_idx, curbuf_bytes; + int mapped; + + if (atomic_read(&rchan->suspended) == 1) + return 0; + + mapped = atomic_read(&rchan->mapped); + + if (mapped && bulk_delivery(rchan)) { + buffers_ready = rchan->bufs_produced - rchan->bufs_consumed; + return buffers_ready ? 0 : 1; + } + + if (mapped && packet_delivery(rchan)) { + buffers_ready = rchan->bufs_produced - rchan->bufs_consumed; + if (buffers_ready) + return 0; + else { + cur_idx = relay_get_offset(rchan, NULL); + curbuf_bytes = cur_idx % rchan->buf_size; + return curbuf_bytes == rchan->bytes_consumed ? 1 : 0; + } + } + + avail_count = relay_bytes_avail(reader); + + return avail_count ? 0 : 1; + } + + /** + * rchan_full - boolean, is the channel full wrt consuming reader? + * @reader: channel reader + * + * Returns 1 if the channel is full, 0 otherwise. + */ + int + rchan_full(struct rchan_reader *reader) + { + u32 buffers_ready; + struct rchan *rchan = reader->rchan; + + if (mode_continuous(rchan)) + return 0; + + buffers_ready = rchan->bufs_produced - rchan->bufs_consumed; + + return buffers_ready > reader->rchan->n_bufs - 1 ? 1 : 0; + } + + /** + * relay_info - get status and other information about a relay channel + * @rchan_id: relay channel id + * @rchan_info: pointer to the rchan_info struct to be filled in + * + * Fills in an rchan_info struct with channel status and attribute + * information. See Documentation/filesystems/relayfs.txt for details. + * + * Returns 0 if successful, negative otherwise. + */ + int + relay_info(int rchan_id, struct rchan_info *rchan_info) + { + int i; + struct rchan *rchan; + + rchan = rchan_get(rchan_id); + if (rchan == NULL) + return -EBADF; + + rchan_info->flags = rchan->flags; + rchan_info->buf_size = rchan->buf_size; + rchan_info->buf_addr = rchan->buf; + rchan_info->alloc_size = rchan->alloc_size; + rchan_info->n_bufs = rchan->n_bufs; + rchan_info->cur_idx = relay_get_offset(rchan, NULL); + rchan_info->bufs_produced = rchan->bufs_produced; + rchan_info->bufs_consumed = rchan->bufs_consumed; + rchan_info->buf_id = rchan->buf_id; + + for (i = 0; i < rchan->n_bufs; i++) { + rchan_info->unused_bytes[i] = rchan->unused_bytes[i]; + if (using_lockless(rchan)) + rchan_info->buffer_complete[i] = (atomic_read(&fill_count(rchan, i)) == rchan->buf_size); + else + rchan_info->buffer_complete[i] = 0; + } + + rchan_put(rchan); + + return 0; + } + + /** + * __add_rchan_reader - creates and adds a reader to a channel + * @rchan: relay channel + * @filp: the file associated with rchan, if applicable + * @auto_consume: boolean, whether reader's reads automatically consume + * @map_reader: boolean, whether reader's reading via a channel mapping + * + * Returns a pointer to the reader object create, NULL if unsuccessful + * + * Creates and initializes an rchan_reader object for reading the channel. + * If filp is non-NULL, the reader is a VFS reader, otherwise not. + * + * If the reader is a map reader, it isn't considered a VFS reader for + * our purposes. Also, map_readers can't be auto-consuming. + */ + struct rchan_reader * + __add_rchan_reader(struct rchan *rchan, struct file *filp, int auto_consume, int map_reader) + { + struct rchan_reader *reader; + u32 will_read; + + reader = kmalloc(sizeof(struct rchan_reader), GFP_KERNEL); + + if (reader) { + reader->rchan = rchan; + if (filp) { + reader->vfs_reader = 1; + down(&rchan->resize_sem); + filp->f_pos = rchan->read_start; + up(&rchan->resize_sem); + reader->pos.file = filp; + } else { + reader->vfs_reader = 0; + reader->pos.f_pos = 0; + } + reader->map_reader = map_reader; + reader->auto_consume = auto_consume; + + if (!map_reader) { + will_read = rchan->bufs_produced % rchan->n_bufs; + if (!will_read && atomic_read(&rchan->suspended)) + will_read = rchan->n_bufs; + reader->bufs_consumed = rchan->bufs_produced - will_read; + rchan->bufs_consumed = reader->bufs_consumed; + rchan->bytes_consumed = reader->bytes_consumed = 0; + reader->offset_changed = 0; + } + + write_lock(&rchan->open_readers_lock); + list_add(&reader->list, &rchan->open_readers); + write_unlock(&rchan->open_readers_lock); + } + + return reader; + } + + /** + * add_rchan_reader - create a reader for a channel + * @rchan_id: relay channel handle + * @auto_consume: boolean, whether reader's reads automatically consume + * + * Returns a pointer to the reader object created, NULL if unsuccessful + * + * Creates and initializes an rchan_reader object for reading the channel. + * This function is useful only for non-VFS readers. + */ + struct rchan_reader * + add_rchan_reader(int rchan_id, int auto_consume) + { + struct rchan *rchan = rchan_get(rchan_id); + if (rchan == NULL) + return NULL; + + return __add_rchan_reader(rchan, NULL, auto_consume, 0); + } + + /** + * add_map_reader - create a map reader for a channel + * @rchan_id: relay channel handle + * + * Returns a pointer to the reader object created, NULL if unsuccessful + * + * Creates and initializes an rchan_reader object for reading the channel. + * This function is useful only for map readers. + */ + struct rchan_reader * + add_map_reader(int rchan_id) + { + struct rchan *rchan = rchan_get(rchan_id); + if (rchan == NULL) + return NULL; + + return __add_rchan_reader(rchan, NULL, 0, 1); + } + + /** + * __remove_rchan_reader - destroy a channel reader + * @reader: channel reader + * + * Internal - removes reader from the open readers list, and frees it. + */ + void + __remove_rchan_reader(struct rchan_reader *reader) + { + struct list_head *p; + struct rchan_reader *found_reader = NULL; + + write_lock(&reader->rchan->open_readers_lock); + list_for_each(p, &reader->rchan->open_readers) { + found_reader = list_entry(p, struct rchan_reader, list); + if (found_reader == reader) { + list_del(&found_reader->list); + break; + } + } + write_unlock(&reader->rchan->open_readers_lock); + + if (found_reader) + kfree(found_reader); + } + + /** + * remove_rchan_reader - destroy a channel reader + * @reader: channel reader + * + * Finds and removes the given reader from the channel. This function + * is useful only for non-VFS readers. + * + * Returns 0 if successful, negative otherwise. + */ + int + remove_rchan_reader(struct rchan_reader *reader) + { + int err = 0; + + if (reader) { + rchan_put(reader->rchan); + __remove_rchan_reader(reader); + } else + err = -EINVAL; + + return err; + } + + /** + * remove_map_reader - destroy a map reader + * @reader: channel reader + * + * Finds and removes the given map reader from the channel. This function + * is useful only for map readers. + * + * Returns 0 if successful, negative otherwise. + */ + int + remove_map_reader(struct rchan_reader *reader) + { + return remove_rchan_reader(reader); + } + + EXPORT_SYMBOL(relay_open); + EXPORT_SYMBOL(relay_close); + EXPORT_SYMBOL(relay_reset); + EXPORT_SYMBOL(relay_reserve); + EXPORT_SYMBOL(relay_commit); + EXPORT_SYMBOL(relay_read); + EXPORT_SYMBOL(relay_write); + EXPORT_SYMBOL(relay_bytes_avail); + EXPORT_SYMBOL(relay_buffers_consumed); + EXPORT_SYMBOL(relay_bytes_consumed); + EXPORT_SYMBOL(relay_info); + EXPORT_SYMBOL(relay_discard_init_buf); + EXPORT_SYMBOL(add_rchan_reader); + EXPORT_SYMBOL(remove_rchan_reader); + EXPORT_SYMBOL(add_map_reader); + EXPORT_SYMBOL(remove_map_reader); + EXPORT_SYMBOL(rchan_empty); + EXPORT_SYMBOL(rchan_full); + + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/relay_locking.c linux-current/fs/relayfs/relay_locking.c *** linux-2.6.10/fs/relayfs/relay_locking.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/relay_locking.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,322 ---- + /* + * RelayFS locking scheme implementation. + * + * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com) + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp + * + * This file is released under the GPL. + */ + + #include + #include "relay_locking.h" + #include "resize.h" + + /** + * switch_buffers - switches between read and write buffers. + * @cur_time: current time. + * @cur_tsc: the TSC associated with current_time, if applicable + * @rchan: the channel + * @finalizing: if true, don't start a new buffer + * @resetting: if true, + * + * This should be called from with interrupts disabled. + */ + static void + switch_buffers(struct timeval cur_time, + u32 cur_tsc, + struct rchan *rchan, + int finalizing, + int resetting, + int finalize_buffer_only) + { + char *chan_buf_end; + int bytes_written; + + if (!rchan->half_switch) { + bytes_written = rchan->callbacks->buffer_end(rchan->id, + cur_write_pos(rchan), write_buf_end(rchan), + cur_time, cur_tsc, using_tsc(rchan)); + if (bytes_written == 0) + rchan->unused_bytes[rchan->buf_idx % rchan->n_bufs] = + write_buf_end(rchan) - cur_write_pos(rchan); + } + + if (finalize_buffer_only) { + rchan->bufs_produced++; + return; + } + + chan_buf_end = rchan->buf + rchan->n_bufs * rchan->buf_size; + if((write_buf(rchan) + rchan->buf_size >= chan_buf_end) || resetting) + write_buf(rchan) = rchan->buf; + else + write_buf(rchan) += rchan->buf_size; + write_buf_end(rchan) = write_buf(rchan) + rchan->buf_size; + write_limit(rchan) = write_buf_end(rchan) - rchan->end_reserve; + cur_write_pos(rchan) = write_buf(rchan); + + rchan->buf_start_time = cur_time; + rchan->buf_start_tsc = cur_tsc; + + if (resetting) + rchan->buf_idx = 0; + else + rchan->buf_idx++; + rchan->buf_id++; + + if (!packet_delivery(rchan)) + rchan->unused_bytes[rchan->buf_idx % rchan->n_bufs] = 0; + + if (resetting) { + rchan->bufs_produced = rchan->bufs_produced + rchan->n_bufs; + rchan->bufs_produced -= rchan->bufs_produced % rchan->n_bufs; + rchan->bufs_consumed = rchan->bufs_produced; + rchan->bytes_consumed = 0; + update_readers_consumed(rchan, rchan->bufs_consumed, rchan->bytes_consumed); + } else if (!rchan->half_switch) + rchan->bufs_produced++; + + rchan->half_switch = 0; + + if (!finalizing) { + bytes_written = rchan->callbacks->buffer_start(rchan->id, cur_write_pos(rchan), rchan->buf_id, cur_time, cur_tsc, using_tsc(rchan)); + cur_write_pos(rchan) += bytes_written; + } + } + + /** + * locking_reserve - reserve a slot in the buffer for an event. + * @rchan: the channel + * @slot_len: the length of the slot to reserve + * @ts: variable that will receive the time the slot was reserved + * @tsc: the timestamp counter associated with time + * @err: receives the result flags + * @interrupting: if this write is interrupting another, set to non-zero + * + * Returns pointer to the beginning of the reserved slot, NULL if error. + * + * The err value contains the result flags and is an ORed combination + * of the following: + * + * RELAY_BUFFER_SWITCH_NONE - no buffer switch occurred + * RELAY_EVENT_DISCARD_NONE - event should not be discarded + * RELAY_BUFFER_SWITCH - buffer switch occurred + * RELAY_EVENT_DISCARD - event should be discarded (all buffers are full) + * RELAY_EVENT_TOO_LONG - event won't fit into even an empty buffer + */ + inline char * + locking_reserve(struct rchan *rchan, + u32 slot_len, + struct timeval *ts, + u32 *tsc, + int *err, + int *interrupting) + { + u32 buffers_ready; + int bytes_written; + + *err = RELAY_BUFFER_SWITCH_NONE; + + if (slot_len >= rchan->buf_size) { + *err = RELAY_WRITE_DISCARD | RELAY_WRITE_TOO_LONG; + return NULL; + } + + if (rchan->initialized == 0) { + rchan->initialized = 1; + get_timestamp(&rchan->buf_start_time, + &rchan->buf_start_tsc, rchan); + rchan->unused_bytes[0] = 0; + bytes_written = rchan->callbacks->buffer_start( + rchan->id, cur_write_pos(rchan), + rchan->buf_id, rchan->buf_start_time, + rchan->buf_start_tsc, using_tsc(rchan)); + cur_write_pos(rchan) += bytes_written; + *tsc = get_time_delta(ts, rchan); + return cur_write_pos(rchan); + } + + *tsc = get_time_delta(ts, rchan); + + if (in_progress_event_size(rchan)) { + interrupted_pos(rchan) = cur_write_pos(rchan); + cur_write_pos(rchan) = in_progress_event_pos(rchan) + + in_progress_event_size(rchan) + + interrupting_size(rchan); + *interrupting = 1; + } else { + in_progress_event_pos(rchan) = cur_write_pos(rchan); + in_progress_event_size(rchan) = slot_len; + interrupting_size(rchan) = 0; + } + + if (cur_write_pos(rchan) + slot_len > write_limit(rchan)) { + if (atomic_read(&rchan->suspended) == 1) { + in_progress_event_pos(rchan) = NULL; + in_progress_event_size(rchan) = 0; + interrupting_size(rchan) = 0; + *err = RELAY_WRITE_DISCARD; + return NULL; + } + + buffers_ready = rchan->bufs_produced - rchan->bufs_consumed; + if (buffers_ready == rchan->n_bufs - 1) { + if (!mode_continuous(rchan)) { + atomic_set(&rchan->suspended, 1); + in_progress_event_pos(rchan) = NULL; + in_progress_event_size(rchan) = 0; + interrupting_size(rchan) = 0; + get_timestamp(ts, tsc, rchan); + switch_buffers(*ts, *tsc, rchan, 0, 0, 1); + recalc_time_delta(ts, tsc, rchan); + rchan->half_switch = 1; + + cur_write_pos(rchan) = write_buf_end(rchan) - 1; + *err = RELAY_BUFFER_SWITCH | RELAY_WRITE_DISCARD; + return NULL; + } + } + + get_timestamp(ts, tsc, rchan); + switch_buffers(*ts, *tsc, rchan, 0, 0, 0); + recalc_time_delta(ts, tsc, rchan); + *err = RELAY_BUFFER_SWITCH; + } + + return cur_write_pos(rchan); + } + + /** + * locking_commit - commit a reserved slot in the buffer + * @rchan: the channel + * @from: commit the length starting here + * @len: length committed + * @deliver: length committed + * @interrupting: not used + * + * Commits len bytes and calls deliver callback if applicable. + */ + inline void + locking_commit(struct rchan *rchan, + char *from, + u32 len, + int deliver, + int interrupting) + { + cur_write_pos(rchan) += len; + + if (interrupting) { + cur_write_pos(rchan) = interrupted_pos(rchan); + interrupting_size(rchan) += len; + } else { + in_progress_event_size(rchan) = 0; + if (interrupting_size(rchan)) { + cur_write_pos(rchan) += interrupting_size(rchan); + interrupting_size(rchan) = 0; + } + } + + if (deliver) { + if (bulk_delivery(rchan)) { + u32 cur_idx = cur_write_pos(rchan) - rchan->buf; + u32 cur_bufno = cur_idx / rchan->buf_size; + from = rchan->buf + cur_bufno * rchan->buf_size; + len = cur_idx - cur_bufno * rchan->buf_size; + } + rchan->callbacks->deliver(rchan->id, from, len); + expand_check(rchan); + } + } + + /** + * locking_finalize: - finalize last buffer at end of channel use + * @rchan: the channel + */ + inline void + locking_finalize(struct rchan *rchan) + { + unsigned long int flags; + struct timeval time; + u32 tsc; + + local_irq_save(flags); + get_timestamp(&time, &tsc, rchan); + switch_buffers(time, tsc, rchan, 1, 0, 0); + local_irq_restore(flags); + } + + /** + * locking_get_offset - get current and max 'file' offsets for VFS + * @rchan: the channel + * @max_offset: maximum channel offset + * + * Returns the current and maximum buffer offsets in VFS terms. + */ + u32 + locking_get_offset(struct rchan *rchan, + u32 *max_offset) + { + if (max_offset) + *max_offset = rchan->buf_size * rchan->n_bufs - 1; + + return cur_write_pos(rchan) - rchan->buf; + } + + /** + * locking_reset - reset the channel + * @rchan: the channel + * @init: 1 if this is a first-time channel initialization + */ + void locking_reset(struct rchan *rchan, int init) + { + if (init) + channel_lock(rchan) = SPIN_LOCK_UNLOCKED; + write_buf(rchan) = rchan->buf; + write_buf_end(rchan) = write_buf(rchan) + rchan->buf_size; + cur_write_pos(rchan) = write_buf(rchan); + write_limit(rchan) = write_buf_end(rchan) - rchan->end_reserve; + in_progress_event_pos(rchan) = NULL; + in_progress_event_size(rchan) = 0; + interrupted_pos(rchan) = NULL; + interrupting_size(rchan) = 0; + } + + /** + * locking_reset_index - atomically set channel index to the beginning + * @rchan: the channel + * + * If this fails, it means that something else just logged something + * and therefore we probably no longer want to do this. It's up to the + * caller anyway... + * + * Returns 0 if the index was successfully set, negative otherwise + */ + int + locking_reset_index(struct rchan *rchan, u32 old_idx) + { + unsigned long flags; + struct timeval time; + u32 tsc; + u32 cur_idx; + + relay_lock_channel(rchan, flags); + cur_idx = locking_get_offset(rchan, NULL); + if (cur_idx != old_idx) { + relay_unlock_channel(rchan, flags); + return -1; + } + + get_timestamp(&time, &tsc, rchan); + switch_buffers(time, tsc, rchan, 0, 1, 0); + + relay_unlock_channel(rchan, flags); + + return 0; + } + + + + + + + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/relay_locking.h linux-current/fs/relayfs/relay_locking.h *** linux-2.6.10/fs/relayfs/relay_locking.h Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/relay_locking.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,34 ---- + #ifndef _RELAY_LOCKING_H + #define _RELAY_LOCKING_H + + extern char * + locking_reserve(struct rchan *rchan, + u32 slot_len, + struct timeval *time_stamp, + u32 *tsc, + int *err, + int *interrupting); + + extern void + locking_commit(struct rchan *rchan, + char *from, + u32 len, + int deliver, + int interrupting); + + extern void + locking_resume(struct rchan *rchan); + + extern void + locking_finalize(struct rchan *rchan); + + extern u32 + locking_get_offset(struct rchan *rchan, u32 *max_offset); + + extern void + locking_reset(struct rchan *rchan, int init); + + extern int + locking_reset_index(struct rchan *rchan, u32 old_idx); + + #endif /* _RELAY_LOCKING_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/relay_lockless.c linux-current/fs/relayfs/relay_lockless.c *** linux-2.6.10/fs/relayfs/relay_lockless.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/relay_lockless.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,545 ---- + /* + * RelayFS lockless scheme implementation. + * + * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com) + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp + * Copyright (C) 2002, 2003 - Bob Wisniewski (bob@watson.ibm.com), IBM Corp + * + * This file is released under the GPL. + */ + + #include + #include "relay_lockless.h" + #include "resize.h" + + /** + * compare_and_store_volatile - self-explicit + * @ptr: ptr to the word that will receive the new value + * @oval: the value we think is currently in *ptr + * @nval: the value *ptr will get if we were right + */ + inline int + compare_and_store_volatile(volatile u32 *ptr, + u32 oval, + u32 nval) + { + u32 prev; + + barrier(); + prev = cmpxchg(ptr, oval, nval); + barrier(); + + return (prev == oval); + } + + /** + * atomic_set_volatile - atomically set the value in ptr to nval. + * @ptr: ptr to the word that will receive the new value + * @nval: the new value + */ + inline void + atomic_set_volatile(atomic_t *ptr, + u32 nval) + { + barrier(); + atomic_set(ptr, (int)nval); + barrier(); + } + + /** + * atomic_add_volatile - atomically add val to the value at ptr. + * @ptr: ptr to the word that will receive the addition + * @val: the value to add to *ptr + */ + inline void + atomic_add_volatile(atomic_t *ptr, u32 val) + { + barrier(); + atomic_add((int)val, ptr); + barrier(); + } + + /** + * atomic_sub_volatile - atomically substract val from the value at ptr. + * @ptr: ptr to the word that will receive the subtraction + * @val: the value to subtract from *ptr + */ + inline void + atomic_sub_volatile(atomic_t *ptr, s32 val) + { + barrier(); + atomic_sub((int)val, ptr); + barrier(); + } + + /** + * lockless_commit - commit a reserved slot in the buffer + * @rchan: the channel + * @from: commit the length starting here + * @len: length committed + * @deliver: length committed + * @interrupting: not used + * + * Commits len bytes and calls deliver callback if applicable. + */ + inline void + lockless_commit(struct rchan *rchan, + char *from, + u32 len, + int deliver, + int interrupting) + { + u32 bufno, idx; + + idx = from - rchan->buf; + + if (len > 0) { + bufno = RELAY_BUFNO_GET(idx, offset_bits(rchan)); + atomic_add_volatile(&fill_count(rchan, bufno), len); + } + + if (deliver) { + u32 mask = offset_mask(rchan); + if (bulk_delivery(rchan)) { + from = rchan->buf + RELAY_BUF_OFFSET_CLEAR(idx, mask); + len += RELAY_BUF_OFFSET_GET(idx, mask); + } + rchan->callbacks->deliver(rchan->id, from, len); + expand_check(rchan); + } + } + + /** + * get_buffer_end - get the address of the end of buffer + * @rchan: the channel + * @buf_idx: index into channel corresponding to address + */ + static inline char * + get_buffer_end(struct rchan *rchan, u32 buf_idx) + { + return rchan->buf + + RELAY_BUF_OFFSET_CLEAR(buf_idx, offset_mask(rchan)) + + RELAY_BUF_SIZE(offset_bits(rchan)); + } + + + /** + * finalize_buffer - utility function consolidating end-of-buffer tasks. + * @rchan: the channel + * @end_idx: index into buffer to write the end-buffer event at + * @size_lost: number of unused bytes at the end of the buffer + * @time_stamp: the time of the end-buffer event + * @tsc: the timestamp counter associated with time + * @resetting: are we resetting the channel? + * + * This function must be called with local irqs disabled. + */ + static inline void + finalize_buffer(struct rchan *rchan, + u32 end_idx, + u32 size_lost, + struct timeval *time_stamp, + u32 *tsc, + int resetting) + { + char* cur_write_pos; + char* write_buf_end; + u32 bufno; + int bytes_written; + + cur_write_pos = rchan->buf + end_idx; + write_buf_end = get_buffer_end(rchan, end_idx - 1); + + bytes_written = rchan->callbacks->buffer_end(rchan->id, cur_write_pos, + write_buf_end, *time_stamp, *tsc, using_tsc(rchan)); + if (bytes_written == 0) + rchan->unused_bytes[rchan->buf_idx % rchan->n_bufs] = size_lost; + + bufno = RELAY_BUFNO_GET(end_idx, offset_bits(rchan)); + atomic_add_volatile(&fill_count(rchan, bufno), size_lost); + if (resetting) { + rchan->bufs_produced = rchan->bufs_produced + rchan->n_bufs; + rchan->bufs_produced -= rchan->bufs_produced % rchan->n_bufs; + rchan->bufs_consumed = rchan->bufs_produced; + rchan->bytes_consumed = 0; + update_readers_consumed(rchan, rchan->bufs_consumed, rchan->bytes_consumed); + } else + rchan->bufs_produced++; + } + + /** + * lockless_finalize: - finalize last buffer at end of channel use + * @rchan: the channel + */ + inline void + lockless_finalize(struct rchan *rchan) + { + u32 event_end_idx; + u32 size_lost; + unsigned long int flags; + struct timeval time; + u32 tsc; + + event_end_idx = RELAY_BUF_OFFSET_GET(idx(rchan), offset_mask(rchan)); + size_lost = RELAY_BUF_SIZE(offset_bits(rchan)) - event_end_idx; + + local_irq_save(flags); + get_timestamp(&time, &tsc, rchan); + finalize_buffer(rchan, idx(rchan) & idx_mask(rchan), size_lost, + &time, &tsc, 0); + local_irq_restore(flags); + } + + /** + * discard_check: - determine whether a write should be discarded + * @rchan: the channel + * @old_idx: index into buffer where check for space should begin + * @write_len: the length of the write to check + * @time_stamp: the time of the end-buffer event + * @tsc: the timestamp counter associated with time + * + * The return value contains the result flags and is an ORed combination + * of the following: + * + * RELAY_WRITE_DISCARD_NONE - write should not be discarded + * RELAY_BUFFER_SWITCH - buffer switch occurred + * RELAY_WRITE_DISCARD - write should be discarded (all buffers are full) + * RELAY_WRITE_TOO_LONG - write won't fit into even an empty buffer + */ + static inline int + discard_check(struct rchan *rchan, + u32 old_idx, + u32 write_len, + struct timeval *time_stamp, + u32 *tsc) + { + u32 buffers_ready; + u32 offset_mask = offset_mask(rchan); + u8 offset_bits = offset_bits(rchan); + u32 idx_mask = idx_mask(rchan); + u32 size_lost; + unsigned long int flags; + + if (write_len > RELAY_BUF_SIZE(offset_bits)) + return RELAY_WRITE_DISCARD | RELAY_WRITE_TOO_LONG; + + if (mode_continuous(rchan)) + return RELAY_WRITE_DISCARD_NONE; + + local_irq_save(flags); + if (atomic_read(&rchan->suspended) == 1) { + local_irq_restore(flags); + return RELAY_WRITE_DISCARD; + } + if (rchan->half_switch) { + local_irq_restore(flags); + return RELAY_WRITE_DISCARD_NONE; + } + buffers_ready = rchan->bufs_produced - rchan->bufs_consumed; + if (buffers_ready == rchan->n_bufs - 1) { + atomic_set(&rchan->suspended, 1); + size_lost = RELAY_BUF_SIZE(offset_bits) + - RELAY_BUF_OFFSET_GET(old_idx, offset_mask); + finalize_buffer(rchan, old_idx & idx_mask, size_lost, + time_stamp, tsc, 0); + rchan->half_switch = 1; + #if 1 // XXX BUG??? + idx(rchan) = RELAY_BUF_OFFSET_CLEAR((old_idx & idx_mask), offset_mask(rchan)) + RELAY_BUF_SIZE(offset_bits) - 1 - rchan->end_reserve; + #else + idx(rchan) = RELAY_BUF_OFFSET_CLEAR((old_idx & idx_mask), offset_mask(rchan)) + RELAY_BUF_SIZE(offset_bits) - 1; + #endif + local_irq_restore(flags); + + return RELAY_BUFFER_SWITCH | RELAY_WRITE_DISCARD; + } + local_irq_restore(flags); + + return RELAY_WRITE_DISCARD_NONE; + } + + /** + * switch_buffers - switch over to a new sub-buffer + * @rchan: the channel + * @slot_len: the length of the slot needed for the current write + * @offset: the offset calculated for the new index + * @ts: timestamp + * @tsc: the timestamp counter associated with time + * @old_idx: the value of the buffer control index when we were called + * @old_idx: the new calculated value of the buffer control index + * @resetting: are we resetting the channel? + */ + static inline void + switch_buffers(struct rchan *rchan, + u32 slot_len, + u32 offset, + struct timeval *ts, + u32 *tsc, + u32 new_idx, + u32 old_idx, + int resetting) + { + u32 size_lost = rchan->end_reserve; + unsigned long int flags; + u32 idx_mask = idx_mask(rchan); + u8 offset_bits = offset_bits(rchan); + char *cur_write_pos; + u32 new_buf_no; + u32 start_reserve = rchan->start_reserve; + + if (resetting) + size_lost = RELAY_BUF_SIZE(offset_bits(rchan)) - old_idx % rchan->buf_size; + + if (offset > 0) + size_lost += slot_len - offset; + else + old_idx += slot_len; + + local_irq_save(flags); + if (!rchan->half_switch) + finalize_buffer(rchan, old_idx & idx_mask, size_lost, + ts, tsc, resetting); + rchan->half_switch = 0; + rchan->buf_start_time = *ts; + rchan->buf_start_tsc = *tsc; + local_irq_restore(flags); + + cur_write_pos = rchan->buf + RELAY_BUF_OFFSET_CLEAR((new_idx + & idx_mask), offset_mask(rchan)); + if (resetting) + rchan->buf_idx = 0; + else + rchan->buf_idx++; + rchan->buf_id++; + + rchan->unused_bytes[rchan->buf_idx % rchan->n_bufs] = 0; + + rchan->callbacks->buffer_start(rchan->id, cur_write_pos, + rchan->buf_id, *ts, *tsc, using_tsc(rchan)); + new_buf_no = RELAY_BUFNO_GET(new_idx & idx_mask, offset_bits); + atomic_sub_volatile(&fill_count(rchan, new_buf_no), + RELAY_BUF_SIZE(offset_bits) - start_reserve); + if (atomic_read(&fill_count(rchan, new_buf_no)) < start_reserve) + atomic_set_volatile(&fill_count(rchan, new_buf_no), + start_reserve); + } + + /** + * lockless_reserve_slow - the slow reserve path in the lockless scheme + * @rchan: the channel + * @slot_len: the length of the slot to reserve + * @ts: variable that will receive the time the slot was reserved + * @tsc: the timestamp counter associated with time + * @old_idx: the value of the buffer control index when we were called + * @err: receives the result flags + * + * Returns pointer to the beginning of the reserved slot, NULL if error. + + * err values same as for lockless_reserve. + */ + static inline char * + lockless_reserve_slow(struct rchan *rchan, + u32 slot_len, + struct timeval *ts, + u32 *tsc, + u32 old_idx, + int *err) + { + u32 new_idx, offset; + unsigned long int flags; + u32 offset_mask = offset_mask(rchan); + u32 idx_mask = idx_mask(rchan); + u32 start_reserve = rchan->start_reserve; + u32 end_reserve = rchan->end_reserve; + int discard_event; + u32 reserved_idx; + char *cur_write_pos; + int initializing = 0; + + *err = RELAY_BUFFER_SWITCH_NONE; + + discard_event = discard_check(rchan, old_idx, slot_len, ts, tsc); + if (discard_event != RELAY_WRITE_DISCARD_NONE) { + *err = discard_event; + return NULL; + } + + local_irq_save(flags); + if (rchan->initialized == 0) { + rchan->initialized = initializing = 1; + idx(rchan) = rchan->start_reserve + rchan->rchan_start_reserve; + } + local_irq_restore(flags); + + do { + old_idx = idx(rchan); + new_idx = old_idx + slot_len; + + offset = RELAY_BUF_OFFSET_GET(new_idx + end_reserve, + offset_mask); + if ((offset < slot_len) && (offset > 0)) { + reserved_idx = RELAY_BUF_OFFSET_CLEAR(new_idx + + end_reserve, offset_mask) + start_reserve; + new_idx = reserved_idx + slot_len; + } else if (offset < slot_len) { + reserved_idx = old_idx; + new_idx = RELAY_BUF_OFFSET_CLEAR(new_idx + + end_reserve, offset_mask) + start_reserve; + } else + reserved_idx = old_idx; + get_timestamp(ts, tsc, rchan); + } while (!compare_and_store_volatile(&idx(rchan), old_idx, new_idx)); + + reserved_idx &= idx_mask; + + if (initializing == 1) { + cur_write_pos = rchan->buf + + RELAY_BUF_OFFSET_CLEAR((old_idx & idx_mask), + offset_mask(rchan)); + rchan->buf_start_time = *ts; + rchan->buf_start_tsc = *tsc; + rchan->unused_bytes[0] = 0; + + rchan->callbacks->buffer_start(rchan->id, cur_write_pos, + rchan->buf_id, *ts, *tsc, using_tsc(rchan)); + } + + if (offset < slot_len) { + switch_buffers(rchan, slot_len, offset, ts, tsc, new_idx, + old_idx, 0); + *err = RELAY_BUFFER_SWITCH; + } + + /* If not using TSC, need to calc time delta */ + recalc_time_delta(ts, tsc, rchan); + + return rchan->buf + reserved_idx; + } + + /** + * lockless_reserve - reserve a slot in the buffer for an event. + * @rchan: the channel + * @slot_len: the length of the slot to reserve + * @ts: variable that will receive the time the slot was reserved + * @tsc: the timestamp counter associated with time + * @err: receives the result flags + * @interrupting: not used + * + * Returns pointer to the beginning of the reserved slot, NULL if error. + * + * The err value contains the result flags and is an ORed combination + * of the following: + * + * RELAY_BUFFER_SWITCH_NONE - no buffer switch occurred + * RELAY_EVENT_DISCARD_NONE - event should not be discarded + * RELAY_BUFFER_SWITCH - buffer switch occurred + * RELAY_EVENT_DISCARD - event should be discarded (all buffers are full) + * RELAY_EVENT_TOO_LONG - event won't fit into even an empty buffer + */ + inline char * + lockless_reserve(struct rchan *rchan, + u32 slot_len, + struct timeval *ts, + u32 *tsc, + int *err, + int *interrupting) + { + u32 old_idx, new_idx, offset; + u32 offset_mask = offset_mask(rchan); + + do { + old_idx = idx(rchan); + new_idx = old_idx + slot_len; + + offset = RELAY_BUF_OFFSET_GET(new_idx + rchan->end_reserve, + offset_mask); + if (offset < slot_len) + return lockless_reserve_slow(rchan, slot_len, + ts, tsc, old_idx, err); + get_time_or_tsc(ts, tsc, rchan); + } while (!compare_and_store_volatile(&idx(rchan), old_idx, new_idx)); + + /* If not using TSC, need to calc time delta */ + recalc_time_delta(ts, tsc, rchan); + + *err = RELAY_BUFFER_SWITCH_NONE; + + return rchan->buf + (old_idx & idx_mask(rchan)); + } + + /** + * lockless_get_offset - get current and max channel offsets + * @rchan: the channel + * @max_offset: maximum channel offset + * + * Returns the current and maximum channel offsets. + */ + u32 + lockless_get_offset(struct rchan *rchan, + u32 *max_offset) + { + if (max_offset) + *max_offset = rchan->buf_size * rchan->n_bufs - 1; + + return rchan->initialized ? idx(rchan) & idx_mask(rchan) : 0; + } + + /** + * lockless_reset - reset the channel + * @rchan: the channel + * @init: 1 if this is a first-time channel initialization + */ + void lockless_reset(struct rchan *rchan, int init) + { + int i; + + /* Start first buffer at 0 - (end_reserve + 1) so that it + gets initialized via buffer_start callback as well. */ + idx(rchan) = 0UL - (rchan->end_reserve + 1); + idx_mask(rchan) = + (1UL << (bufno_bits(rchan) + offset_bits(rchan))) - 1; + atomic_set(&fill_count(rchan, 0), + (int)rchan->start_reserve + + (int)rchan->rchan_start_reserve); + for (i = 1; i < rchan->n_bufs; i++) + atomic_set(&fill_count(rchan, i), + (int)RELAY_BUF_SIZE(offset_bits(rchan))); + } + + /** + * lockless_reset_index - atomically set channel index to the beginning + * @rchan: the channel + * @old_idx: the current index + * + * If this fails, it means that something else just logged something + * and therefore we probably no longer want to do this. It's up to the + * caller anyway... + * + * Returns 0 if the index was successfully set, negative otherwise + */ + int + lockless_reset_index(struct rchan *rchan, u32 old_idx) + { + struct timeval ts; + u32 tsc; + u32 new_idx; + + if (compare_and_store_volatile(&idx(rchan), old_idx, 0)) { + new_idx = rchan->start_reserve; + switch_buffers(rchan, 0, 0, &ts, &tsc, new_idx, old_idx, 1); + return 0; + } else + return -1; + } + + + + + + + + + + + + + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/relay_lockless.h linux-current/fs/relayfs/relay_lockless.h *** linux-2.6.10/fs/relayfs/relay_lockless.h Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/relay_lockless.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,34 ---- + #ifndef _RELAY_LOCKLESS_H + #define _RELAY_LOCKLESS_H + + extern char * + lockless_reserve(struct rchan *rchan, + u32 slot_len, + struct timeval *time_stamp, + u32 *tsc, + int * interrupting, + int * errcode); + + extern void + lockless_commit(struct rchan *rchan, + char * from, + u32 len, + int deliver, + int interrupting); + + extern void + lockless_resume(struct rchan *rchan); + + extern void + lockless_finalize(struct rchan *rchan); + + extern u32 + lockless_get_offset(struct rchan *rchan, u32 *max_offset); + + extern void + lockless_reset(struct rchan *rchan, int init); + + extern int + lockless_reset_index(struct rchan *rchan, u32 old_idx); + + #endif/* _RELAY_LOCKLESS_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/resize.c linux-current/fs/relayfs/resize.c *** linux-2.6.10/fs/relayfs/resize.c Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/resize.c Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,1115 ---- + /* + * RelayFS buffer management and resizing code. + * + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp + * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com) + * + * This file is released under the GPL. + */ + + #include + #include + #include + #include + #ifdef CONFIG_MIPS /* avoid d-cache aliasing */ + #include + #endif + #include "resize.h" + + /** + * alloc_page_array - alloc array to hold pages, but not pages + * @size: the total size of the memory represented by the page array + * @page_count: the number of pages the array can hold + * @err: 0 on success, negative otherwise + * + * Returns a pointer to the page array if successful, NULL otherwise. + */ + static struct page ** + alloc_page_array(int size, int *page_count, int *err) + { + int n_pages; + struct page **page_array; + int page_array_size; + + *err = 0; + + size = PAGE_ALIGN(size); + n_pages = size >> PAGE_SHIFT; + page_array_size = n_pages * sizeof(struct page *); + page_array = kmalloc(page_array_size, GFP_KERNEL); + if (page_array == NULL) { + *err = -ENOMEM; + return NULL; + } + *page_count = n_pages; + memset(page_array, 0, page_array_size); + + return page_array; + } + + /** + * free_page_array - free array to hold pages, but not pages + * @page_array: pointer to the page array + */ + static inline void + free_page_array(struct page **page_array) + { + kfree(page_array); + } + + /** + * depopulate_page_array - free and unreserve all pages in the array + * @page_array: pointer to the page array + * @page_count: number of pages to free + */ + static void + depopulate_page_array(struct page **page_array, int page_count) + { + int i; + + for (i = 0; i < page_count; i++) { + ClearPageReserved(page_array[i]); + __free_page(page_array[i]); + } + } + + /** + * populate_page_array - allocate and reserve pages + * @page_array: pointer to the page array + * @page_count: number of pages to allocate + * + * Returns 0 if successful, negative otherwise. + */ + static int + populate_page_array(struct page **page_array, int page_count) + { + int i; + + for (i = 0; i < page_count; i++) { + page_array[i] = alloc_page(GFP_KERNEL); + if (unlikely(!page_array[i])) { + depopulate_page_array(page_array, i); + return -ENOMEM; + } + SetPageReserved(page_array[i]); + #ifdef CONFIG_MIPS /* avoid d-cache aliasing */ + flush_data_cache_page((unsigned long)page_address(page_array[i])); + #endif + } + return 0; + } + + /** + * alloc_rchan_buf - allocate the initial channel buffer + * @size: total size of the buffer + * @page_array: receives a pointer to the buffer's page array + * @page_count: receives the number of pages allocated + * + * Returns a pointer to the resulting buffer, NULL if unsuccessful + */ + void * + alloc_rchan_buf(unsigned long size, struct page ***page_array, int *page_count) + { + void *mem; + int err; + + *page_array = alloc_page_array(size, page_count, &err); + if (!*page_array) + return NULL; + + err = populate_page_array(*page_array, *page_count); + if (err) { + free_page_array(*page_array); + *page_array = NULL; + return NULL; + } + + #ifdef CONFIG_MIPS + mem = vmap(*page_array, *page_count, GFP_KERNEL, PAGE_KERNEL_UNCACHED); + #else + mem = vmap(*page_array, *page_count, GFP_KERNEL, PAGE_KERNEL); + #endif + if (!mem) { + depopulate_page_array(*page_array, *page_count); + free_page_array(*page_array); + *page_array = NULL; + return NULL; + } + memset(mem, 0, size); + + return mem; + } + + /** + * expand_check - check whether the channel needs expanding + * @rchan: the channel + * + * If the channel needs expanding, the needs_resize callback is + * called with RELAY_RESIZE_EXPAND. + * + * Returns the suggested number of sub-buffers for the new + * buffer. + */ + void + expand_check(struct rchan *rchan) + { + u32 active_bufs; + u32 new_n_bufs = 0; + u32 threshold = rchan->n_bufs * RESIZE_THRESHOLD; + + if (rchan->init_buf) + return; + + if (rchan->resize_min == 0) + return; + + if (rchan->resizing || rchan->replace_buffer) + return; + + active_bufs = rchan->bufs_produced - rchan->bufs_consumed + 1; + + if (rchan->resize_max && active_bufs == threshold) { + new_n_bufs = rchan->n_bufs * 2; + } + + if (new_n_bufs && (new_n_bufs * rchan->buf_size <= rchan->resize_max)) + rchan->callbacks->needs_resize(rchan->id, + RELAY_RESIZE_EXPAND, + rchan->buf_size, + new_n_bufs); + } + + /** + * can_shrink - check whether the channel can shrink + * @rchan: the channel + * @cur_idx: the current channel index + * + * Returns the suggested number of sub-buffers for the new + * buffer, 0 if the buffer is not shrinkable. + */ + static inline u32 + can_shrink(struct rchan *rchan, u32 cur_idx) + { + u32 active_bufs = rchan->bufs_produced - rchan->bufs_consumed + 1; + u32 new_n_bufs = 0; + u32 cur_bufno_bytes = cur_idx % rchan->buf_size; + + if (rchan->resize_min == 0 || + rchan->resize_min >= rchan->n_bufs * rchan->buf_size) + goto out; + + if (active_bufs > 1) + goto out; + + if (cur_bufno_bytes != rchan->bytes_consumed) + goto out; + + new_n_bufs = rchan->resize_min / rchan->buf_size; + out: + return new_n_bufs; + } + + /** + * shrink_check: - timer function checking whether the channel can shrink + * @data: unused + * + * Every SHRINK_TIMER_SECS, check whether the channel is shrinkable. + * If so, we attempt to atomically reset the channel to the beginning. + * The needs_resize callback is then called with RELAY_RESIZE_SHRINK. + * If the reset fails, it means we really shouldn't be shrinking now + * and need to wait until the next time around. + */ + static void + shrink_check(unsigned long data) + { + struct rchan *rchan = (struct rchan *)data; + u32 shrink_to_nbufs, cur_idx; + + del_timer(&rchan->shrink_timer); + rchan->shrink_timer.expires = jiffies + SHRINK_TIMER_SECS * HZ; + add_timer(&rchan->shrink_timer); + + if (rchan->init_buf) + return; + + if (rchan->resizing || rchan->replace_buffer) + return; + + if (using_lockless(rchan)) + cur_idx = idx(rchan); + else + cur_idx = relay_get_offset(rchan, NULL); + + shrink_to_nbufs = can_shrink(rchan, cur_idx); + if (shrink_to_nbufs != 0 && reset_index(rchan, cur_idx) == 0) { + update_readers_consumed(rchan, rchan->bufs_consumed, 0); + rchan->callbacks->needs_resize(rchan->id, + RELAY_RESIZE_SHRINK, + rchan->buf_size, + shrink_to_nbufs); + } + } + + /** + * init_shrink_timer: - Start timer used to check shrinkability. + * @rchan: the channel + */ + void + init_shrink_timer(struct rchan *rchan) + { + if (rchan->resize_min) { + init_timer(&rchan->shrink_timer); + rchan->shrink_timer.function = shrink_check; + rchan->shrink_timer.data = (unsigned long)rchan; + rchan->shrink_timer.expires = jiffies + SHRINK_TIMER_SECS * HZ; + add_timer(&rchan->shrink_timer); + } + } + + + /** + * alloc_new_pages - allocate new pages for expanding buffer + * @rchan: the channel + * + * Returns 0 on success, negative otherwise. + */ + static int + alloc_new_pages(struct rchan *rchan) + { + int new_pages_size, err; + + if (unlikely(rchan->expand_page_array)) BUG(); + + new_pages_size = rchan->resize_alloc_size - rchan->alloc_size; + rchan->expand_page_array = alloc_page_array(new_pages_size, + &rchan->expand_page_count, &err); + if (rchan->expand_page_array == NULL) { + rchan->resize_err = -ENOMEM; + return -ENOMEM; + } + + err = populate_page_array(rchan->expand_page_array, + rchan->expand_page_count); + if (err) { + rchan->resize_err = -ENOMEM; + free_page_array(rchan->expand_page_array); + rchan->expand_page_array = NULL; + } + + return err; + } + + /** + * clear_resize_offset - helper function for buffer resizing + * @rchan: the channel + * + * Clear the saved offset change. + */ + static inline void + clear_resize_offset(struct rchan *rchan) + { + rchan->resize_offset.ge = 0UL; + rchan->resize_offset.le = 0UL; + rchan->resize_offset.delta = 0; + } + + /** + * save_resize_offset - helper function for buffer resizing + * @rchan: the channel + * @ge: affected region ge this + * @le: affected region le this + * @delta: apply this delta + * + * Save a resize offset. + */ + static inline void + save_resize_offset(struct rchan *rchan, u32 ge, u32 le, int delta) + { + rchan->resize_offset.ge = ge; + rchan->resize_offset.le = le; + rchan->resize_offset.delta = delta; + } + + /** + * update_file_offset - apply offset change to reader + * @reader: the channel reader + * @change_idx: the offset index into the offsets array + * + * Returns non-zero if the offset was applied. + * + * Apply the offset delta saved in change_idx to the reader's + * current read position. + */ + static inline int + update_file_offset(struct rchan_reader *reader) + { + int applied = 0; + struct rchan *rchan = reader->rchan; + u32 f_pos; + int delta = reader->rchan->resize_offset.delta; + + if (reader->vfs_reader) + f_pos = (u32)reader->pos.file->f_pos; + else + f_pos = reader->pos.f_pos; + + if (f_pos == relay_get_offset(rchan, NULL)) + return 0; + + if ((f_pos >= rchan->resize_offset.ge - 1) && + (f_pos <= rchan->resize_offset.le)) { + if (reader->vfs_reader) { + if (reader->rchan->read_start == f_pos) + if (!(rchan->flags & RELAY_MODE_START_AT_ZERO)) + reader->rchan->read_start += delta; + reader->pos.file->f_pos += delta; + } else + reader->pos.f_pos += delta; + applied = 1; + } + + return applied; + } + + /** + * update_file_offsets - apply offset change to readers + * @rchan: the channel + * + * Apply the saved offset deltas to all files open on the channel. + */ + static inline void + update_file_offsets(struct rchan *rchan) + { + struct list_head *p; + struct rchan_reader *reader; + + read_lock(&rchan->open_readers_lock); + list_for_each(p, &rchan->open_readers) { + reader = list_entry(p, struct rchan_reader, list); + if (update_file_offset(reader)) + reader->offset_changed = 1; + } + read_unlock(&rchan->open_readers_lock); + } + + /** + * setup_expand_buf - setup expand buffer for replacement + * @rchan: the channel + * @newsize: the size of the new buffer + * @oldsize: the size of the old buffer + * @old_n_bufs: the number of sub-buffers in the old buffer + * + * Inserts new pages into the old buffer to create a larger + * new channel buffer, splitting them at old_cur_idx, the bottom + * half of the old buffer going to the bottom of the new, likewise + * for the top half. + */ + static void + setup_expand_buf(struct rchan *rchan, int newsize, int oldsize, u32 old_n_bufs) + { + u32 cur_idx; + int cur_bufno, delta, i, j; + u32 ge, le; + int cur_pageno; + u32 free_bufs, free_pages; + u32 free_pages_in_cur_buf; + u32 free_bufs_to_end; + u32 cur_pages = rchan->alloc_size >> PAGE_SHIFT; + u32 pages_per_buf = cur_pages / rchan->n_bufs; + u32 bufs_ready = rchan->bufs_produced - rchan->bufs_consumed; + + if (!rchan->resize_page_array || !rchan->expand_page_array || + !rchan->buf_page_array) + return; + + if (bufs_ready >= rchan->n_bufs) { + bufs_ready = rchan->n_bufs; + free_bufs = 0; + } else + free_bufs = rchan->n_bufs - bufs_ready - 1; + + cur_idx = relay_get_offset(rchan, NULL); + cur_pageno = cur_idx / PAGE_SIZE; + cur_bufno = cur_idx / rchan->buf_size; + + free_pages_in_cur_buf = (pages_per_buf - 1) - (cur_pageno % pages_per_buf); + free_pages = free_bufs * pages_per_buf + free_pages_in_cur_buf; + free_bufs_to_end = (rchan->n_bufs - 1) - cur_bufno; + if (free_bufs >= free_bufs_to_end) { + free_pages = free_bufs_to_end * pages_per_buf + free_pages_in_cur_buf; + free_bufs = free_bufs_to_end; + } + + for (i = 0, j = 0; i <= cur_pageno + free_pages; i++, j++) + rchan->resize_page_array[j] = rchan->buf_page_array[i]; + for (i = 0; i < rchan->expand_page_count; i++, j++) + rchan->resize_page_array[j] = rchan->expand_page_array[i]; + for (i = cur_pageno + free_pages + 1; i < rchan->buf_page_count; i++, j++) + rchan->resize_page_array[j] = rchan->buf_page_array[i]; + + delta = newsize - oldsize; + ge = (cur_pageno + 1 + free_pages) * PAGE_SIZE; + le = oldsize; + save_resize_offset(rchan, ge, le, delta); + + rchan->expand_buf_id = rchan->buf_id + 1 + free_bufs; + } + + /** + * setup_shrink_buf - setup shrink buffer for replacement + * @rchan: the channel + * + * Removes pages from the old buffer to create a smaller + * new channel buffer. + */ + static void + setup_shrink_buf(struct rchan *rchan) + { + int i; + int copy_end_page; + + if (!rchan->resize_page_array || !rchan->shrink_page_array || + !rchan->buf_page_array) + return; + + copy_end_page = rchan->resize_alloc_size / PAGE_SIZE; + + for (i = 0; i < copy_end_page; i++) + rchan->resize_page_array[i] = rchan->buf_page_array[i]; + } + + /** + * cleanup_failed_alloc - relaybuf_alloc helper + */ + static void + cleanup_failed_alloc(struct rchan *rchan) + { + if (rchan->expand_page_array) { + depopulate_page_array(rchan->expand_page_array, + rchan->expand_page_count); + free_page_array(rchan->expand_page_array); + rchan->expand_page_array = NULL; + rchan->expand_page_count = 0; + } else if (rchan->shrink_page_array) { + free_page_array(rchan->shrink_page_array); + rchan->shrink_page_array = NULL; + rchan->shrink_page_count = 0; + } + + if (rchan->resize_page_array) { + free_page_array(rchan->resize_page_array); + rchan->resize_page_array = NULL; + rchan->resize_page_count = 0; + } + } + + /** + * relaybuf_alloc - allocate a new resized channel buffer + * @private: pointer to the channel struct + * + * Internal - manages the allocation and remapping of new channel + * buffers. + */ + static void + relaybuf_alloc(void *private) + { + struct rchan *rchan = (struct rchan *)private; + int i, j, err; + u32 old_cur_idx; + int free_size; + int free_start_page, free_end_page; + u32 newsize, oldsize; + + if (rchan->resize_alloc_size > rchan->alloc_size) { + err = alloc_new_pages(rchan); + if (err) goto cleanup; + } else { + free_size = rchan->alloc_size - rchan->resize_alloc_size; + BUG_ON(free_size <= 0); + rchan->shrink_page_array = alloc_page_array(free_size, + &rchan->shrink_page_count, &err); + if (rchan->shrink_page_array == NULL) + goto cleanup; + free_start_page = rchan->resize_alloc_size / PAGE_SIZE; + free_end_page = rchan->alloc_size / PAGE_SIZE; + for (i = 0, j = free_start_page; j < free_end_page; i++, j++) + rchan->shrink_page_array[i] = rchan->buf_page_array[j]; + } + + rchan->resize_page_array = alloc_page_array(rchan->resize_alloc_size, + &rchan->resize_page_count, &err); + if (rchan->resize_page_array == NULL) + goto cleanup; + + old_cur_idx = relay_get_offset(rchan, NULL); + clear_resize_offset(rchan); + newsize = rchan->resize_alloc_size; + oldsize = rchan->alloc_size; + if (newsize > oldsize) + setup_expand_buf(rchan, newsize, oldsize, rchan->n_bufs); + else + setup_shrink_buf(rchan); + + rchan->resize_buf = vmap(rchan->resize_page_array, rchan->resize_page_count, GFP_KERNEL, PAGE_KERNEL); + + if (rchan->resize_buf == NULL) + goto cleanup; + + rchan->replace_buffer = 1; + rchan->resizing = 0; + + rchan->callbacks->needs_resize(rchan->id, RELAY_RESIZE_REPLACE, 0, 0); + return; + + cleanup: + cleanup_failed_alloc(rchan); + rchan->resize_err = -ENOMEM; + return; + } + + /** + * relaybuf_free - free a resized channel buffer + * @private: pointer to the channel struct + * + * Internal - manages the de-allocation and unmapping of old channel + * buffers. + */ + static void + relaybuf_free(void *private) + { + struct free_rchan_buf *free_buf = (struct free_rchan_buf *)private; + int i; + + if (free_buf->unmap_buf) + vunmap(free_buf->unmap_buf); + + for (i = 0; i < 3; i++) { + if (!free_buf->page_array[i].array) + continue; + if (free_buf->page_array[i].count) + depopulate_page_array(free_buf->page_array[i].array, + free_buf->page_array[i].count); + free_page_array(free_buf->page_array[i].array); + } + + kfree(free_buf); + } + + /** + * calc_order - determine the power-of-2 order of a resize + * @high: the larger size + * @low: the smaller size + * + * Returns order + */ + static inline int + calc_order(u32 high, u32 low) + { + int order = 0; + + if (!high || !low || high <= low) + return 0; + + while (high > low) { + order++; + high /= 2; + } + + return order; + } + + /** + * check_size - check the sanity of the requested channel size + * @rchan: the channel + * @nbufs: the new number of sub-buffers + * @err: return code + * + * Returns the non-zero total buffer size if ok, otherwise 0 and + * sets errcode if not. + */ + static inline u32 + check_size(struct rchan *rchan, u32 nbufs, int *err) + { + u32 new_channel_size = 0; + + *err = 0; + + if (nbufs > rchan->n_bufs) { + rchan->resize_order = calc_order(nbufs, rchan->n_bufs); + if (!rchan->resize_order) { + *err = -EINVAL; + goto out; + } + + new_channel_size = rchan->buf_size * nbufs; + if (new_channel_size > rchan->resize_max) { + *err = -EINVAL; + goto out; + } + } else if (nbufs < rchan->n_bufs) { + if (rchan->n_bufs < 2) { + *err = -EINVAL; + goto out; + } + rchan->resize_order = -calc_order(rchan->n_bufs, nbufs); + if (!rchan->resize_order) { + *err = -EINVAL; + goto out; + } + + new_channel_size = rchan->buf_size * nbufs; + if (new_channel_size < rchan->resize_min) { + *err = -EINVAL; + goto out; + } + } else + *err = -EINVAL; + out: + return new_channel_size; + } + + /** + * __relay_realloc_buffer - allocate a new channel buffer + * @rchan: the channel + * @new_nbufs: the new number of sub-buffers + * @async: do the allocation using a work queue + * + * Internal - see relay_realloc_buffer() for details. + */ + static int + __relay_realloc_buffer(struct rchan *rchan, u32 new_nbufs, int async) + { + u32 new_channel_size; + int err = 0; + + if (new_nbufs == rchan->n_bufs) + return -EINVAL; + + if (down_trylock(&rchan->resize_sem)) + return -EBUSY; + + if (rchan->init_buf) { + err = -EPERM; + goto out; + } + + if (rchan->replace_buffer) { + err = -EBUSY; + goto out; + } + + if (rchan->resizing) { + err = -EBUSY; + goto out; + } else + rchan->resizing = 1; + + if (rchan->resize_failures > MAX_RESIZE_FAILURES) { + err = -ENOMEM; + goto out; + } + + new_channel_size = check_size(rchan, new_nbufs, &err); + if (err) + goto out; + + rchan->resize_n_bufs = new_nbufs; + rchan->resize_buf_size = rchan->buf_size; + rchan->resize_alloc_size = FIX_SIZE(new_channel_size); + + if (async) { + INIT_WORK(&rchan->work, relaybuf_alloc, rchan); + schedule_delayed_work(&rchan->work, 1); + } else + relaybuf_alloc((void *)rchan); + out: + up(&rchan->resize_sem); + + return err; + } + + /** + * relay_realloc_buffer - allocate a new channel buffer + * @rchan_id: the channel id + * @bufsize: the new sub-buffer size + * @nbufs: the new number of sub-buffers + * + * Allocates a new channel buffer using the specified sub-buffer size + * and count. If async is non-zero, the allocation is done in the + * background using a work queue. When the allocation has completed, + * the needs_resize() callback is called with a resize_type of + * RELAY_RESIZE_REPLACE. This function doesn't replace the old buffer + * with the new - see relay_replace_buffer(). See + * Documentation/filesystems/relayfs.txt for more details. + * + * Returns 0 on success, or errcode if the channel is busy or if + * the allocation couldn't happen for some reason. + */ + int + relay_realloc_buffer(int rchan_id, u32 new_nbufs, int async) + { + int err; + + struct rchan *rchan; + + rchan = rchan_get(rchan_id); + if (rchan == NULL) + return -EBADF; + + err = __relay_realloc_buffer(rchan, new_nbufs, async); + + rchan_put(rchan); + + return err; + } + + /** + * expand_cancel_check - check whether the current expand needs canceling + * @rchan: the channel + * + * Returns 1 if the expand should be canceled, 0 otherwise. + */ + static int + expand_cancel_check(struct rchan *rchan) + { + if (rchan->buf_id >= rchan->expand_buf_id) + return 1; + else + return 0; + } + + /** + * shrink_cancel_check - check whether the current shrink needs canceling + * @rchan: the channel + * + * Returns 1 if the shrink should be canceled, 0 otherwise. + */ + static int + shrink_cancel_check(struct rchan *rchan, u32 newsize) + { + u32 active_bufs = rchan->bufs_produced - rchan->bufs_consumed + 1; + u32 cur_idx = relay_get_offset(rchan, NULL); + + if (cur_idx >= newsize) + return 1; + + if (active_bufs > 1) + return 1; + + return 0; + } + + /** + * switch_rchan_buf - do_replace_buffer helper + */ + static void + switch_rchan_buf(struct rchan *rchan, + int newsize, + int oldsize, + u32 old_nbufs, + u32 cur_idx) + { + u32 newbufs, cur_bufno; + int i; + + cur_bufno = cur_idx / rchan->buf_size; + + rchan->buf = rchan->resize_buf; + rchan->alloc_size = rchan->resize_alloc_size; + rchan->n_bufs = rchan->resize_n_bufs; + + if (newsize > oldsize) { + u32 ge = rchan->resize_offset.ge; + u32 moved_buf = ge / rchan->buf_size; + + newbufs = (newsize - oldsize) / rchan->buf_size; + for (i = moved_buf; i < old_nbufs; i++) { + if (using_lockless(rchan)) + atomic_set(&fill_count(rchan, i + newbufs), + atomic_read(&fill_count(rchan, i))); + rchan->unused_bytes[i + newbufs] = rchan->unused_bytes[i]; + } + for (i = moved_buf; i < moved_buf + newbufs; i++) { + if (using_lockless(rchan)) + atomic_set(&fill_count(rchan, i), + (int)RELAY_BUF_SIZE(offset_bits(rchan))); + rchan->unused_bytes[i] = 0; + } + } + + rchan->buf_idx = cur_bufno; + + if (!using_lockless(rchan)) { + cur_write_pos(rchan) = rchan->buf + cur_idx; + write_buf(rchan) = rchan->buf + cur_bufno * rchan->buf_size; + write_buf_end(rchan) = write_buf(rchan) + rchan->buf_size; + write_limit(rchan) = write_buf_end(rchan) - rchan->end_reserve; + } else { + idx(rchan) &= idx_mask(rchan); + bufno_bits(rchan) += rchan->resize_order; + idx_mask(rchan) = + (1UL << (bufno_bits(rchan) + offset_bits(rchan))) - 1; + } + } + + /** + * do_replace_buffer - does the work of channel buffer replacement + * @rchan: the channel + * @newsize: new channel buffer size + * @oldsize: old channel buffer size + * @old_n_bufs: old channel sub-buffer count + * + * Returns 0 if replacement happened, 1 if canceled + * + * Does the work of switching buffers and fixing everything up + * so the channel can continue with a new size. + */ + static int + do_replace_buffer(struct rchan *rchan, + int newsize, + int oldsize, + u32 old_nbufs) + { + u32 cur_idx; + int err = 0; + int canceled; + + cur_idx = relay_get_offset(rchan, NULL); + + if (newsize > oldsize) + canceled = expand_cancel_check(rchan); + else + canceled = shrink_cancel_check(rchan, newsize); + + if (canceled) { + err = -EAGAIN; + goto out; + } + + switch_rchan_buf(rchan, newsize, oldsize, old_nbufs, cur_idx); + + if (rchan->resize_offset.delta) + update_file_offsets(rchan); + + atomic_set(&rchan->suspended, 0); + + rchan->old_buf_page_array = rchan->buf_page_array; + rchan->buf_page_array = rchan->resize_page_array; + rchan->buf_page_count = rchan->resize_page_count; + rchan->resize_page_array = NULL; + rchan->resize_page_count = 0; + rchan->resize_buf = NULL; + rchan->resize_buf_size = 0; + rchan->resize_alloc_size = 0; + rchan->resize_n_bufs = 0; + rchan->resize_err = 0; + rchan->resize_order = 0; + out: + rchan->callbacks->needs_resize(rchan->id, + RELAY_RESIZE_REPLACED, + rchan->buf_size, + rchan->n_bufs); + return err; + } + + /** + * add_free_page_array - add a page_array to be freed + * @free_rchan_buf: the free_rchan_buf struct + * @page_array: the page array to free + * @page_count: the number of pages to free, 0 to free the array only + * + * Internal - Used add page_arrays to be freed asynchronously. + */ + static inline void + add_free_page_array(struct free_rchan_buf *free_rchan_buf, + struct page **page_array, int page_count) + { + int cur = free_rchan_buf->cur++; + + free_rchan_buf->page_array[cur].array = page_array; + free_rchan_buf->page_array[cur].count = page_count; + } + + /** + * free_rchan_buf - free a channel buffer + * @buf: pointer to the buffer to free + * @page_array: pointer to the buffer's page array + * @page_count: number of pages in page array + */ + int + free_rchan_buf(void *buf, struct page **page_array, int page_count) + { + struct free_rchan_buf *free_buf; + + free_buf = kmalloc(sizeof(struct free_rchan_buf), GFP_ATOMIC); + if (!free_buf) + return -ENOMEM; + memset(free_buf, 0, sizeof(struct free_rchan_buf)); + + free_buf->unmap_buf = buf; + add_free_page_array(free_buf, page_array, page_count); + + INIT_WORK(&free_buf->work, relaybuf_free, free_buf); + schedule_delayed_work(&free_buf->work, 1); + + return 0; + } + + /** + * free_replaced_buffer - free a channel's old buffer + * @rchan: the channel + * @oldbuf: the old buffer + * @oldsize: old buffer size + * + * Frees a channel buffer via work queue. + */ + static int + free_replaced_buffer(struct rchan *rchan, char *oldbuf, int oldsize) + { + struct free_rchan_buf *free_buf; + + free_buf = kmalloc(sizeof(struct free_rchan_buf), GFP_ATOMIC); + if (!free_buf) + return -ENOMEM; + memset(free_buf, 0, sizeof(struct free_rchan_buf)); + + free_buf->unmap_buf = oldbuf; + add_free_page_array(free_buf, rchan->old_buf_page_array, 0); + rchan->old_buf_page_array = NULL; + add_free_page_array(free_buf, rchan->expand_page_array, 0); + add_free_page_array(free_buf, rchan->shrink_page_array, rchan->shrink_page_count); + + rchan->expand_page_array = NULL; + rchan->expand_page_count = 0; + rchan->shrink_page_array = NULL; + rchan->shrink_page_count = 0; + + INIT_WORK(&free_buf->work, relaybuf_free, free_buf); + schedule_delayed_work(&free_buf->work, 1); + + return 0; + } + + /** + * free_canceled_resize - free buffers allocated for a canceled resize + * @rchan: the channel + * + * Frees canceled buffers via work queue. + */ + static int + free_canceled_resize(struct rchan *rchan) + { + struct free_rchan_buf *free_buf; + + free_buf = kmalloc(sizeof(struct free_rchan_buf), GFP_ATOMIC); + if (!free_buf) + return -ENOMEM; + memset(free_buf, 0, sizeof(struct free_rchan_buf)); + + if (rchan->resize_alloc_size > rchan->alloc_size) + add_free_page_array(free_buf, rchan->expand_page_array, rchan->expand_page_count); + else + add_free_page_array(free_buf, rchan->shrink_page_array, 0); + + add_free_page_array(free_buf, rchan->resize_page_array, 0); + free_buf->unmap_buf = rchan->resize_buf; + + rchan->expand_page_array = NULL; + rchan->expand_page_count = 0; + rchan->shrink_page_array = NULL; + rchan->shrink_page_count = 0; + rchan->resize_page_array = NULL; + rchan->resize_page_count = 0; + rchan->resize_buf = NULL; + + INIT_WORK(&free_buf->work, relaybuf_free, free_buf); + schedule_delayed_work(&free_buf->work, 1); + + return 0; + } + + /** + * __relay_replace_buffer - replace channel buffer with new buffer + * @rchan: the channel + * + * Internal - see relay_replace_buffer() for details. + * + * Returns 0 if successful, negative otherwise. + */ + static int + __relay_replace_buffer(struct rchan *rchan) + { + int oldsize; + int err = 0; + char *oldbuf; + + if (down_trylock(&rchan->resize_sem)) + return -EBUSY; + + if (rchan->init_buf) { + err = -EPERM; + goto out; + } + + if (!rchan->replace_buffer) + goto out; + + if (rchan->resizing) { + err = -EBUSY; + goto out; + } + + if (rchan->resize_buf == NULL) { + err = -EINVAL; + goto out; + } + + oldbuf = rchan->buf; + oldsize = rchan->alloc_size; + + err = do_replace_buffer(rchan, rchan->resize_alloc_size, + oldsize, rchan->n_bufs); + if (err == 0) + err = free_replaced_buffer(rchan, oldbuf, oldsize); + else + err = free_canceled_resize(rchan); + out: + rchan->replace_buffer = 0; + up(&rchan->resize_sem); + + return err; + } + + /** + * relay_replace_buffer - replace channel buffer with new buffer + * @rchan_id: the channel id + * + * Replaces the current channel buffer with the new buffer allocated + * by relay_alloc_buffer and contained in the channel struct. When the + * replacement is complete, the needs_resize() callback is called with + * RELAY_RESIZE_REPLACED. + * + * Returns 0 on success, or errcode if the channel is busy or if + * the replacement or previous allocation didn't happen for some reason. + */ + int + relay_replace_buffer(int rchan_id) + { + int err; + + struct rchan *rchan; + + rchan = rchan_get(rchan_id); + if (rchan == NULL) + return -EBADF; + + err = __relay_replace_buffer(rchan); + + rchan_put(rchan); + + return err; + } + + EXPORT_SYMBOL(relay_realloc_buffer); + EXPORT_SYMBOL(relay_replace_buffer); + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/relayfs/resize.h linux-current/fs/relayfs/resize.h *** linux-2.6.10/fs/relayfs/resize.h Thu Jan 1 09:00:00 1970 --- linux-current/fs/relayfs/resize.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,51 ---- + #ifndef _RELAY_RESIZE_H + #define _RELAY_RESIZE_H + + /* + * If the channel usage has been below the low water mark for more than + * this amount of time, we can shrink the buffer if necessary. + */ + #define SHRINK_TIMER_SECS 60 + + /* This inspired by rtai/shmem */ + #define FIX_SIZE(x) (((x) - 1) & PAGE_MASK) + PAGE_SIZE + + /* Don't attempt resizing again after this many failures */ + #define MAX_RESIZE_FAILURES 1 + + /* Trigger resizing if a resizable channel is this full */ + #define RESIZE_THRESHOLD 3 / 4 + + /* + * Used for deferring resized channel free + */ + struct free_rchan_buf + { + char *unmap_buf; + struct + { + struct page **array; + int count; + } page_array[3]; + + int cur; + struct work_struct work; /* resize de-allocation work struct */ + }; + + extern void * + alloc_rchan_buf(unsigned long size, + struct page ***page_array, + int *page_count); + + extern int + free_rchan_buf(void *buf, + struct page **page_array, + int page_count); + + extern void + expand_check(struct rchan *rchan); + + extern void + init_shrink_timer(struct rchan *rchan); + + #endif/* _RELAY_RESIZE_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/fs/select.c linux-current/fs/select.c *** linux-2.6.10/fs/select.c Sat Dec 25 06:33:49 2004 --- linux-current/fs/select.c Wed Jun 14 21:12:59 2006 *************** *** 22,27 **** --- 22,28 ---- #include /* for STICKY_TIMEOUTS */ #include #include + #include #include *************** *** 223,228 **** --- 224,233 ---- file = fget(i); if (file) { f_op = file->f_op; + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_SELECT, + i /* The fd*/, + __timeout, + NULL); mask = DEFAULT_POLLMASK; if (f_op && f_op->poll) mask = (*f_op->poll)(file, retval ? NULL : wait); *************** *** 408,413 **** --- 413,420 ---- struct file * file = fget(fd); mask = POLLNVAL; if (file != NULL) { + ltt_ev_file_system(LTT_EV_FILE_SYSTEM_POLL, fd, + 0, NULL); mask = DEFAULT_POLLMASK; if (file->f_op && file->f_op->poll) mask = file->f_op->poll(file, *pwait); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-arm26/relay.h linux-current/include/asm-arm26/relay.h *** linux-2.6.10/include/asm-arm26/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-arm26/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_ARM_RELAY_H + #define _ASM_ARM_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-cris/relay.h linux-current/include/asm-cris/relay.h *** linux-2.6.10/include/asm-cris/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-cris/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_CRIS_RELAY_H + #define _ASM_CRIS_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-generic/relay.h linux-current/include/asm-generic/relay.h *** linux-2.6.10/include/asm-generic/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-generic/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,76 ---- + #ifndef _ASM_GENERIC_RELAY_H + #define _ASM_GENERIC_RELAY_H + /* + * linux/include/asm-generic/relay.h + * + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp + * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com) + * + * Architecture-independent definitions for relayfs + */ + + #include + + /** + * get_time_delta - utility function for getting time delta + * @now: pointer to a timeval struct that may be given current time + * @rchan: the channel + * + * Returns the time difference between the current time and the buffer + * start time. + */ + static inline u32 + get_time_delta(struct timeval *now, struct rchan *rchan) + { + u32 time_delta; + + do_gettimeofday(now); + time_delta = calc_time_delta(now, &rchan->buf_start_time); + + return time_delta; + } + + /** + * get_timestamp - utility function for getting a time and TSC pair + * @now: current time + * @tsc: the TSC associated with now + * @rchan: the channel + * + * Sets the value pointed to by now to the current time. Value pointed to + * by tsc is not set since there is no generic TSC support. + */ + static inline void + get_timestamp(struct timeval *now, + u32 *tsc, + struct rchan *rchan) + { + do_gettimeofday(now); + } + + /** + * get_time_or_tsc: - Utility function for getting a time or a TSC. + * @now: current time + * @tsc: current TSC + * @rchan: the channel + * + * Sets the value pointed to by now to the current time. + */ + static inline void + get_time_or_tsc(struct timeval *now, + u32 *tsc, + struct rchan *rchan) + { + do_gettimeofday(now); + } + + /** + * have_tsc - does this platform have a useable TSC? + * + * Returns 0. + */ + static inline int + have_tsc(void) + { + return 0; + } + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-h8300/relay.h linux-current/include/asm-h8300/relay.h *** linux-2.6.10/include/asm-h8300/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-h8300/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_H8300_RELAY_H + #define _ASM_H8300_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-i386/ltt.h linux-current/include/asm-i386/ltt.h *** linux-2.6.10/include/asm-i386/ltt.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-i386/ltt.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,15 ---- + /* + * linux/include/asm-i386/ltt.h + * + * Copyright (C) 2002, Karim Yaghmour + * + * i386 definitions for tracing system + */ + + #include + + /* Current arch type */ + #define LTT_ARCH_TYPE LTT_ARCH_TYPE_I386 + + /* Current variant type */ + #define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-i386/relay.h linux-current/include/asm-i386/relay.h *** linux-2.6.10/include/asm-i386/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-i386/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,101 ---- + #ifndef _ASM_I386_RELAY_H + #define _ASM_I386_RELAY_H + /* + * linux/include/asm-i386/relay.h + * + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp + * Copyright (C) 2002 - Karim Yaghmour (karim@opersys.com) + * + * i386 definitions for relayfs + */ + + #include + + #ifdef CONFIG_X86_TSC + #include + + /** + * get_time_delta - utility function for getting time delta + * @now: pointer to a timeval struct that may be given current time + * @rchan: the channel + * + * Returns either the TSC if TSCs are being used, or the time and the + * time difference between the current time and the buffer start time + * if TSCs are not being used. + */ + static inline u32 + get_time_delta(struct timeval *now, struct rchan *rchan) + { + u32 time_delta; + + if ((using_tsc(rchan) == 1) && cpu_has_tsc) + rdtscl(time_delta); + else { + do_gettimeofday(now); + time_delta = calc_time_delta(now, &rchan->buf_start_time); + } + + return time_delta; + } + + /** + * get_timestamp - utility function for getting a time and TSC pair + * @now: current time + * @tsc: the TSC associated with now + * @rchan: the channel + * + * Sets the value pointed to by now to the current time and the value + * pointed to by tsc to the tsc associated with that time, if the + * platform supports TSC. + */ + static inline void + get_timestamp(struct timeval *now, + u32 *tsc, + struct rchan *rchan) + { + do_gettimeofday(now); + + if ((using_tsc(rchan) == 1) && cpu_has_tsc) + rdtscl(*tsc); + } + + /** + * get_time_or_tsc - utility function for getting a time or a TSC + * @now: current time + * @tsc: current TSC + * @rchan: the channel + * + * Sets the value pointed to by now to the current time or the value + * pointed to by tsc to the current tsc, depending on whether we're + * using TSCs or not. + */ + static inline void + get_time_or_tsc(struct timeval *now, + u32 *tsc, + struct rchan *rchan) + { + if ((using_tsc(rchan) == 1) && cpu_has_tsc) + rdtscl(*tsc); + else + do_gettimeofday(now); + } + + /** + * have_tsc - does this platform have a useable TSC? + * + * Returns 1 if this platform has a useable TSC counter for + * timestamping purposes, 0 otherwise. + */ + static inline int + have_tsc(void) + { + if (cpu_has_tsc) + return 1; + else + return 0; + } + + #else /* No TSC support (#ifdef CONFIG_X86_TSC) */ + #include + #endif /* #ifdef CONFIG_X86_TSC */ + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-ia64/relay.h linux-current/include/asm-ia64/relay.h *** linux-2.6.10/include/asm-ia64/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-ia64/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_IA64_RELAY_H + #define _ASM_IA64_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-m68knommu/relay.h linux-current/include/asm-m68knommu/relay.h *** linux-2.6.10/include/asm-m68knommu/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-m68knommu/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_M68KNOMMU_RELAY_H + #define _ASM_M68KNOMMU_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/asmmacro.h linux-current/include/asm-mips/asmmacro.h *** linux-2.6.10/include/asm-mips/asmmacro.h Sat Dec 25 06:35:24 2004 --- linux-current/include/asm-mips/asmmacro.h Wed Jun 14 21:12:59 2006 *************** *** 10,15 **** --- 10,16 ---- #include #include + #include #ifdef CONFIG_MIPS32 #include *************** *** 20,34 **** --- 21,45 ---- .macro local_irq_enable reg=t0 mfc0 \reg, CP0_STATUS + #if TX49XX_MFC0_WAR && defined(MODULE) + ori \reg, \reg, 3 + xori \reg, \reg, 2 + #else ori \reg, \reg, 1 + #endif mtc0 \reg, CP0_STATUS irq_enable_hazard .endm .macro local_irq_disable reg=t0 mfc0 \reg, CP0_STATUS + #if TX49XX_MFC0_WAR && defined(MODULE) + ori \reg, \reg, 3 + xori \reg, \reg, 3 + #else ori \reg, \reg, 1 xori \reg, \reg, 1 + #endif mtc0 \reg, CP0_STATUS irq_disable_hazard .endm diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/bootinfo.h linux-current/include/asm-mips/bootinfo.h *** linux-2.6.10/include/asm-mips/bootinfo.h Sat Dec 25 06:34:26 2004 --- linux-current/include/asm-mips/bootinfo.h Thu Dec 14 11:17:26 2006 *************** *** 212,217 **** --- 212,266 ---- #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ + /* + * Valid machtype for group TX + */ + #define MACH_GROUP_TX 23 /* TX-RISC */ + #define MACH_TX_RBTX4927 3 + #define MACH_TX_RBTX4938 6 + #define MACH_TX_BOARD3A 10 + #define MACH_TX_BOARD1W 11 + + /* + * Valid machtype for group CHIP0S + */ + #define MACH_GROUP_CHIP0S 24 /* Toshiba Chip0s */ + #define MACH_CHIP0S_3000 0 + #define MACH_CHIP0S_4000 1 + #define MACH_CHIP0S_BOARD8L 2 + #define MACH_CHIP0S_BOARD7L 3 + #define MACH_CHIP0S_BOARD13L 4 + #define MACH_CHIP0S_BOARD14L 5 + #define MACH_CHIP0S_BOARD10R 6 + #define MACH_CHIP0S_BOARD11U 7 + #define MACH_CHIP0S_BOARD12U 8 + + /* + * Valid machtype for group CHIP1S + */ + #define MACH_GROUP_CHIP1S 25 /* Toshiba Chip1s */ + #define MACH_CHIP1S_PROTO1 0 + #define MACH_CHIP1S_BOARD15Z 1 + #define MACH_CHIP1S_BOARD19U 2 + #define MACH_CHIP1S_BOARD15C 3 + #define MACH_CHIP1S_BOARD15H 4 + #define MACH_CHIP1S_Z2000 5 + + /* + * Valid machtype for group NEC_EMMA + */ + #define MACH_GROUP_EMMA2RH 26 + #define MACH_EMMA2RH_GENERIC 0 + + /* + * Valid machtype for group NEC_EMMA3 + */ + #define MACH_GROUP_EMMA3 27 + #define MACH_EMMA3_TYPE0 0 + #define MACH_EMMA3_TYPE1 1 + #define MACH_EMMA3_TYPE2 2 + #define MACH_EMMA3_TYPE3 3 + #define CL_SIZE COMMAND_LINE_SIZE const char *get_system_type(void); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/cache.h linux-current/include/asm-mips/cache.h *** linux-2.6.10/include/asm-mips/cache.h Sat Dec 25 06:34:30 2004 --- linux-current/include/asm-mips/cache.h Wed Jun 14 21:12:59 2006 *************** *** 9,14 **** --- 9,18 ---- #ifndef _ASM_CACHE_H #define _ASM_CACHE_H + #ifdef CONFIG_TOSHIBA_CHIP1S_SHARP1 + #define CHIP1S_PCIC_WORKAROUND + #endif + #include #define L1_CACHE_SHIFT CONFIG_MIPS_L1_CACHE_SHIFT *************** *** 18,23 **** --- 22,38 ---- #define SMP_CACHE_SHIFT L1_CACHE_SHIFT #define SMP_CACHE_BYTES L1_CACHE_BYTES + #ifdef CONFIG_DMA_NONCOHERENT + /* Now we have dma_get_cache_alignment, but it is rarely used for now :-< */ + /* + * Default alignment (cache_line_size()) is used if both + * ARCH_KMALLOC_MINALIGN and ARCH_KMALLOC_FLAGS are not defined. + */ + #ifdef CHIP1S_PCIC_WORKAROUND /* WORKAROUND USB 64byte alignment BUG */ + #define ARCH_KMALLOC_MINALIGN 64 + #endif + #else #define ARCH_KMALLOC_MINALIGN 8 + #endif #endif /* _ASM_CACHE_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/cacheflush.h linux-current/include/asm-mips/cacheflush.h *** linux-2.6.10/include/asm-mips/cacheflush.h Sat Dec 25 06:35:24 2004 --- linux-current/include/asm-mips/cacheflush.h Wed Jun 14 21:12:59 2006 *************** *** 56,66 **** #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ memcpy(dst, (void *) src, len); \ flush_icache_page(vma, page); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ ! memcpy(dst, src, len) extern void (*flush_cache_sigtramp)(unsigned long addr); extern void (*flush_icache_all)(void); --- 56,72 ---- #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ + if (cpu_has_dc_aliases) \ + flush_cache_page(vma, vaddr); \ memcpy(dst, (void *) src, len); \ flush_icache_page(vma, page); \ } while (0) #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ ! do { \ ! if (cpu_has_dc_aliases) \ ! flush_cache_page(vma, vaddr); \ ! memcpy(dst, src, len); \ ! } while (0) extern void (*flush_cache_sigtramp)(unsigned long addr); extern void (*flush_icache_all)(void); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/cpu.h linux-current/include/asm-mips/cpu.h *** linux-2.6.10/include/asm-mips/cpu.h Sat Dec 25 06:34:00 2004 --- linux-current/include/asm-mips/cpu.h Wed Jun 14 21:12:59 2006 *************** *** 60,65 **** --- 60,66 ---- #define PRID_IMP_RM9000 0x3400 #define PRID_IMP_R5432 0x5400 #define PRID_IMP_R5500 0x5500 + #define PRID_IMP_VR5600 0x5600 #define PRID_IMP_4KC 0x8000 #define PRID_IMP_5KC 0x8100 #define PRID_IMP_20KC 0x8200 *************** *** 177,183 **** #define CPU_VR4133 56 #define CPU_AU1550 57 #define CPU_24K 58 ! #define CPU_LAST 58 /* * ISA Level encodings --- 178,185 ---- #define CPU_VR4133 56 #define CPU_AU1550 57 #define CPU_24K 58 ! #define CPU_VR5600 59 ! #define CPU_LAST 59 /* * ISA Level encodings diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/delay.h linux-current/include/asm-mips/delay.h *** linux-2.6.10/include/asm-mips/delay.h Sat Dec 25 06:35:29 2004 --- linux-current/include/asm-mips/delay.h Wed Jun 14 21:12:59 2006 *************** *** 57,62 **** --- 57,63 ---- * The common rates of 1000 and 128 are rounded wrongly by the * catchall case for 64-bit. Excessive precission? Probably ... */ + #if (HZ < 1000000 / (1000 * 5)) /* assume MAX_UDELAY_MS is default (5) */ #if defined(CONFIG_MIPS64) && (HZ == 128) usecs *= 0x0008637bd05af6c7UL; /* 2**64 / (1000000 / HZ) */ #elif defined(CONFIG_MIPS64) && (HZ == 1000) *************** *** 67,72 **** --- 68,83 ---- usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) + 0x80000000ULL) >> 32); #endif + #else + #if defined(CONFIG_MIPS64) + usecs *= (0x8000000000000000UL / (500000 / HZ)) >> 3; + #else + /* make sure this multiplication does not cause overflow */ + usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) + + 0x80000000ULL) >> (32 + 3)); + #endif + lpj <<=3; + #endif if (sizeof(long) == 4) __asm__("multu\t%2, %3" diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/elf.h linux-current/include/asm-mips/elf.h *** linux-2.6.10/include/asm-mips/elf.h Sat Dec 25 06:34:32 2004 --- linux-current/include/asm-mips/elf.h Wed Jun 14 21:12:59 2006 *************** *** 23,29 **** #define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */ #define PT_MIPS_REGINFO 0x70000000 ! #define PT_MIPS_OPTIONS 0x70000001 /* Flags in the e_flags field of the header */ #define EF_MIPS_NOREORDER 0x00000001 --- 23,30 ---- #define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */ #define PT_MIPS_REGINFO 0x70000000 ! #define PT_MIPS_RTPROC 0x70000001 ! #define PT_MIPS_OPTIONS 0x70000002 /* Flags in the e_flags field of the header */ #define EF_MIPS_NOREORDER 0x00000001 *************** *** 40,48 **** #define DT_MIPS_ICHECKSUM 0x70000003 #define DT_MIPS_IVERSION 0x70000004 #define DT_MIPS_FLAGS 0x70000005 ! #define RHF_NONE 0 ! #define RHF_HARDWAY 1 ! #define RHF_NOTPOT 2 #define DT_MIPS_BASE_ADDRESS 0x70000006 #define DT_MIPS_CONFLICT 0x70000008 #define DT_MIPS_LIBLIST 0x70000009 --- 41,50 ---- #define DT_MIPS_ICHECKSUM 0x70000003 #define DT_MIPS_IVERSION 0x70000004 #define DT_MIPS_FLAGS 0x70000005 ! #define RHF_NONE 0x00000000 ! #define RHF_HARDWAY 0x00000001 ! #define RHF_NOTPOT 0x00000002 ! #define RHF_SGI_ONLY 0x00000010 #define DT_MIPS_BASE_ADDRESS 0x70000006 #define DT_MIPS_CONFLICT 0x70000008 #define DT_MIPS_LIBLIST 0x70000009 *************** *** 222,239 **** #endif /* CONFIG_MIPS64 */ #endif /* __KERNEL__ */ /* This one accepts IRIX binaries. */ ! #define irix_elf_check_arch(hdr) ((hdr)->e_machine == EM_MIPS) #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE PAGE_SIZE - #define ELF_CORE_COPY_REGS(_dest,_regs) \ - memcpy((char *) &_dest, (char *) _regs, \ - sizeof(struct pt_regs)); - /* This yields a mask that user programs can use to figure out what instruction set this cpu supports. This could be done in userspace, but it's not easy, and we've already done it here. */ --- 224,263 ---- #endif /* CONFIG_MIPS64 */ + extern void dump_regs(elf_greg_t *, struct pt_regs *regs); + extern int dump_task_regs (struct task_struct *, elf_gregset_t *); + extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); + + #define ELF_CORE_COPY_REGS(elf_regs, regs) \ + dump_regs((elf_greg_t *)&(elf_regs), regs); + #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) + #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \ + dump_task_fpu(tsk, elf_fpregs) + + extern void dump_regs(elf_greg_t *, struct pt_regs *regs); + extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); + + #define ELF_CORE_COPY_REGS(elf_regs, regs) \ + dump_regs((elf_greg_t *)&(elf_regs), regs); + #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \ + dump_task_fpu(tsk, elf_fpregs) + + extern void dump_regs(elf_greg_t *, struct pt_regs *regs); + extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); + + #define ELF_CORE_COPY_REGS(elf_regs, regs) \ + dump_regs((elf_greg_t *)&(elf_regs), regs); + #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \ + dump_task_fpu(tsk, elf_fpregs) + #endif /* __KERNEL__ */ /* This one accepts IRIX binaries. */ ! #define irix_elf_check_arch(hdr) ((hdr)->e_flags & RHF_SGI_ONLY) #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE PAGE_SIZE /* This yields a mask that user programs can use to figure out what instruction set this cpu supports. This could be done in userspace, but it's not easy, and we've already done it here. */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/emma/pmon.h linux-current/include/asm-mips/emma/pmon.h *** linux-2.6.10/include/asm-mips/emma/pmon.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/emma/pmon.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,62 ---- + /* + * 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. + * + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + * + */ + #ifndef _EMMA3_PMON_H_ + #define _EMMA3_PMON_H_ + + #include + + struct pmon_vector { + int (*read)(int fd, char *buf, int size); + int (*write)(int fd, char *buf, int size); + int (*open)(char *name, int mode); + int (*close)(int fd); + int (*ioctl)(int fd, int request, void* arg); + int (*printf)(char *fmstr, ...); + int (*vsprintf)(char *dst, char *fmtstr, ...); + int (*ttctl)(int fd, int op, int ap1, int ap2); + void (*exit)(int status); + char *(*getenv)(char *name); + void (*onintr)(int code, int *dat); + void (*flush_cache)(int cache); + void (*_exception)(void); + int (*_fpstatesz)(void); + void (*_fpinit)(void); + void *(*_fpstate)(void); + void (*cop1)(void); + int (*adr2symoff)(char *dst, int value, int width); + int (*sym2adr)(int *v, char *label); + int (*getclkfreq)(void); + void (*_clkinit)(void); + int (*interpret)(const char *cmd, char *outbuf, int len); + }; + + extern struct pmon_vector *pmon_vector; + + /* from pmonlib.c */ + extern void prom_printf(char *fmt, ...); + /* pmonlib support routine */ + extern void prom_putchar(char c); + + #define pmon_printf prom_printf + + extern void pmon_halt(void) __attribute__((noreturn)); + extern void set_pmon_debug_traps(void) __init; + extern void pmon_breakpoint(void); + + extern char *pmon_getenv(const char *name) __init; + extern int pmon_interpret(const char *cmd, char *outbuf, int len); + + extern unsigned int get_pmon_clkfreq(void) __init; + + + #define PMON_VECTOR_BASE 0x9e000000 + #define PMON_VECTOR (PMON_VECTOR_BASE + 0x500) + + #endif /* _EMMA3_PMON_H_ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/emma2/emma2rh.h linux-current/include/asm-mips/emma2/emma2rh.h *** linux-2.6.10/include/asm-mips/emma2/emma2rh.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/emma2/emma2rh.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,180 ---- + /* + * (C) Copyright TOSHIBA CORPORATION 2005 + * All Rights Reserved. + */ + + #include + + #ifndef _EMMA2RH_H_ + #define _EMMA2RH_H_ + /* + * Memory MAP + */ + #define EMMA2RH_SDRAM_BASE 0x00000000 + #define EMMA2RH_SDRAM_SIZE 0x08000000 /* less than 128MB */ + + #define EMMA2RH_PCI_MEM_PCIBASE 0xa0000000 + #define EMMA2RH_PCI_MEM_BASE 0x12000000 + #define EMMA2RH_PCI_MEM_SIZE 0x01f00000 /* 32 MB - 1MB */ + + #define EMMA2RH_PCI_CONFIG_BASE EMMA2RH_PCI_MEM_BASE + #define EMMA2RH_PCI_CONFIG_SIZE EMMA2RH_PCI_MEM_SIZE + + #define EMMA2RH_PCI_IO_PCIBASE 0x00000000 + #define EMMA2RH_PCI_IO_BASE 0x00000000 + #define EMMA2RH_PCI_IO_SIZE 0x00000000 /* I/O Space does not exist. */ + + #define EMMA2RH_PCI1_MEM_PCIBASE 0xb0000000 + #define EMMA2RH_PCI1_MEM_BASE 0x14000000 + #define EMMA2RH_PCI1_MEM_SIZE 0x08000000 /* 128 MB for PCIMB */ + + #define EMMA2RH_BOARDSTR_BASE 0xa8202000 + #define INITPARAM_ADR 0xa8202020 /* Parameter from psos boot */ + #define INITPARAM_NOPCIC (1<<0) /* not initialize pcic */ + #define INITPARAM_A1INT (1<<1) /* A1 Interrupt Type */ + + /* + * PCI BUS Memory + */ + #define PCIMB_SLOT 2 + #define PCIMB_FUNC 0 + #define PCIBM_ID 0x01071179 + #define PCIMB_CONF_ADDR04_TYPE0 0x02000002 + #define PCIMB_CONF_ADDR10_TYPE0 0xa1f00000 + #define PCIMB_CONF_ADDR14_TYPE0 0xd0000000 + #define PCIMB_CONF_ADDR18_TYPE0 0xb0000000 + #define PCIMB_CONF_ADDR1c_TYPE0 0xc0000000 + #define PCIMB_CONF_ADDR44_TYPE0 0x201 + #define PCIMB_CONF_ADDR4c_TYPE0 0x0 + #define PCIMB_CONF_ADDR48_TYPE0 0x80ff3307 + + /* + * ISA LAN address + */ + #define EMMA2RH_ISA_LAN_ADDRESS 0x11800300 + + /* + * INTERRUPT + */ + + #define NUM_CPU_IRQ 8 + #define NUM_EMMA2RH_IRQ 96 + #define NUM_EMMA2RH_SWINT_IRQ 32 + #define NUM_EMMA2RH_GPIO_IRQ 32 + + #define CPU_IRQ_BASE 0 + #define EMMA2RH_IRQ_BASE (NUM_CPU_IRQ) + #define EMMA2RH_SWINT_IRQ_BASE (EMMA2RH_IRQ_BASE + NUM_EMMA2RH_IRQ) + #define EMMA2RH_GPIO_IRQ_BASE (EMMA2RH_SWINT_IRQ_BASE + NUM_EMMA2RH_SWINT_IRQ) + + #define EMMA2RH_CPU_CASCADE (CPU_IRQ_BASE + 2) + #define EMMA2RH_CPU_TIMER (CPU_IRQ_BASE + 7) + #define EMMA2RH_SWINT_CASCADE (EMMA2RH_IRQ_BASE + 7) + #define EMMA2RH_GPIO_CASCADE (EMMA2RH_IRQ_BASE + 32 + 15) + #define EMMA2RH_PFUR1_IRQ (EMMA2RH_IRQ_BASE + 32 + 18) + #define EMMA2RH_PFUR2_IRQ (EMMA2RH_IRQ_BASE + 32 + 19) + #define EMMA2RH_IRQ_PIIC0 (EMMA2RH_IRQ_BASE + 32 + 24) + #define EMMA2RH_IRQ_PIIC1 (EMMA2RH_IRQ_BASE + 32 + 25) + #define EMMA2RH_IRQ_PIIC2 (EMMA2RH_IRQ_BASE + 32 + 26) + + #define EMMA2RH_ISA_LAN_IRQ (EMMA2RH_GPIO_IRQ_BASE + 7) + #define EMMA2RH_PCI_USB_IRQ (EMMA2RH_GPIO_IRQ_BASE + 16) + #define EMMA2RH_PCI_ETHER_IRQ (EMMA2RH_GPIO_IRQ_BASE + 17) + + #define EMMA2RH_PCI_USB_IRQ_A1 (EMMA2RH_GPIO_IRQ_BASE + 0) + #define EMMA2RH_PCI_ETHER_IRQ_A1 (EMMA2RH_GPIO_IRQ_BASE + 3) + + #ifndef __ASSEMBLY__ + /* + * Other + */ + extern unsigned char emma2rh_rev; + #define IS_EMMA2RH_S10() (emma2rh_rev == 0x10) + + static inline void emma2rh_sync(void) + { + volatile u32 *p = (volatile u32 *)0xbfc00000; + (void)(*p); + } + + static inline void emma2rh_out32(u32 addr, u32 val) + { + *(volatile u32 *)(addr) = val; + emma2rh_sync(); + } + + static inline u32 emma2rh_in32(u32 addr) + { + u32 val = *(volatile u32 *)(addr); + emma2rh_sync(); + return val; + } + + static inline void emma2rh_out16(u32 addr, u16 val) + { + *(volatile u16 *)(addr) = val; + emma2rh_sync(); + } + + static inline u16 emma2rh_in16(u32 addr) + { + u16 val = *(volatile u16 *)(addr); + emma2rh_sync(); + return val; + } + + static inline void emma2rh_out8(u32 addr, u8 val) + { + *(volatile u8 *)(addr) = val; + emma2rh_sync(); + } + + static inline u8 emma2rh_in8(u32 addr) + { + u8 val = *(volatile u8 *)(addr); + emma2rh_sync(); + return val; + } + #endif + + #ifdef CONFIG_EMMA2RH_PRAMFS_PCIMB_DMA + #define DMADIR_BIT 4 /* PCI_DMAn_CTR DMADIR bit 0:PCI->MEM 1:MEM->PCI */ + #define DMASWAP 0x1000 /* byte swap in word (32bit) */ + #define PCICMD 0x60 /* Memory Read/Write */ + #define DMASTART_COMMAND ( ( PCICMD | DMASWAP ) | 0x1 ) + #define DMAADDRMASK 0xfffffffc + #define DMAADDROFFSET 0x4 + + #define SET_DMA_ADDR(pci,mem,size) do { \ + unsigned long pciaddr_,memaddr_; \ + pciaddr_ = CPHYSADDR( pci ) - EMMA2RH_PCI1_MEM_BASE; \ + memaddr_ = CPHYSADDR( mem ); \ + *(volatile unsigned long *)EMMA2RH_PCI_DMA1_PSADR = \ + pciaddr_ + EMMA2RH_PCI1_MEM_PCIBASE; \ + *(volatile unsigned long *)EMMA2RH_PCI_DMA1_MSADR = \ + memaddr_ + pcimem_phys_offset; \ + *(volatile unsigned long *)EMMA2RH_PCI_DMA1_MEADR = \ + memaddr_ + pcimem_phys_offset + size - DMAADDROFFSET; \ + } while (0) + + #define START_DMA(x) do { \ + *(volatile unsigned long *)EMMA2RH_PCI_DMA1_CTR = \ + ( DMASTART_COMMAND |( x << DMADIR_BIT ) ); \ + } while (0) + #define CHECK_DMA_STATUS ((*(volatile unsigned long *)EMMA2RH_PCI_DMA1_CTR) & 0x1 ) + #define CHECK_DMA(maxcount) do { \ + int dmacheckcount = 0; \ + do { \ + dmacheckcount++; \ + if (dmacheckcount > maxcount ) { \ + printk("PCIMB DMA timeout\n"); \ + break; \ + } \ + } while ( CHECK_DMA_STATUS == 1 ); \ + } while (0); + #define CHECK_PCIMB_ADDR(checkaddr) \ + (((CPHYSADDR(checkaddr) >= (EMMA2RH_PCI1_MEM_BASE)) & \ + (CPHYSADDR(checkaddr) <= (EMMA2RH_PCI1_MEM_BASE+EMMA2RH_PCI1_MEM_SIZE)) )) + #endif + + #endif /* _EMMA2RH_H_ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/emma2/emma2rh_reg.h linux-current/include/asm-mips/emma2/emma2rh_reg.h *** linux-2.6.10/include/asm-mips/emma2/emma2rh_reg.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/emma2/emma2rh_reg.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,415 ---- + /* emma2rh.h + * Definition for EMMA2RH Board Configuration + * + * (C) Copyright TOSHIBA CORPORATION 2005 + * All Rights Reserved. + */ + + #ifndef _EMMA2RH_REG_H_ + #define _EMMA2RH_REG_H_ + + #define EMMA2RH_REG_PBASE 0x10000000 + #define EMMA2RH_REG_SIZE 0x01000000 + + #define EMMA2RH_BHIF_BASE 0xb0000000 + #define EMMA2RH_ROMIF_BASE 0xb0000400 + #define EMMA2RH_PCI_CONF_BASE 0xb2000000 + #define EMMA2RH_PCI_COMM_BASE 0xb0200000 + + #define EMMA2RH_PFUR0_BASE 0xb0101000 + #define EMMA2RH_PFUR1_BASE 0xb0102000 + #define EMMA2RH_PFUR2_BASE 0xb0103000 + + #define EMMA2RH_PIIC0_BASE 0xb0107000 + #define EMMA2RH_PIIC1_BASE 0xb0108000 + #define EMMA2RH_PIIC2_BASE 0xb0109000 + + #define EMMA2RH_GPIO_BASE 0xb0110d00 + + #define EMMA2RH_PCI0_BASE 0xb2000000 /* 32MB PCI IO */ + #define EMMA2RH_PCI1_BASE 0xb4000000 /* 128MB PCI MEM */ + + /* + * GIO_CS + */ + #define EMMA2RH_GIO_CS0_PHYS_BASE 0x11000000 /* 4MB */ + #define EMMA2RH_GIO_CS1_PHYS_BASE 0x11400000 /* 4MB */ + #define EMMA2RH_GIO_CS2_PHYS_BASE 0x11800000 /* 4MB */ + #define EMMA2RH_GIO_CS3_PHYS_BASE 0x11c00000 /* 4MB */ + + /* + * BHIF + */ + #define EMMA2RH_BHIF_VERSION_OFF 0x0000 + #define EMMA2RH_BHIF_VERSION (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_VERSION_OFF) + #define EMMA2RH_BHIF_STRAP0_OFF 0x0010 + #define EMMA2RH_BHIF_STRAP0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_STRAP0_OFF) + #define EMMA2RH_BHIF_STRAP1_OFF 0x0014 + #define EMMA2RH_BHIF_STRAP1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_STRAP1_OFF) + #define EMMA2RH_BHIF_STRAP_WRITE0_OFF 0x0020 + #define EMMA2RH_BHIF_STRAP_WRITE0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_STRAP_WRITE0_OFF) + #define EMMA2RH_BHIF_ALTERNATE_OFF 0x0028 + #define EMMA2RH_BHIF_ALTERNATE (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_ALTERNATE_OFF) + #define EMMA2RH_BHIF_AVSWITCH_OFF 0x002c + #define EMMA2RH_BHIF_AVSWITCH (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_AVSWITCH_OFF) + + #define EMMA2RH_BHIF_MAIN_INT_ST0_OFF 0x0030 + #define EMMA2RH_BHIF_MAIN_INT_ST0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT_ST0_OFF) + #define EMMA2RH_BHIF_MAIN_INT_ST1_OFF 0x0034 + #define EMMA2RH_BHIF_MAIN_INT_ST1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT_ST1_OFF) + #define EMMA2RH_BHIF_MAIN_INT_ST2_OFF 0x0038 + #define EMMA2RH_BHIF_MAIN_INT_ST2 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT_ST2_OFF) + #define EMMA2RH_BHIF_MAIN_INT0_EN0_OFF 0x0040 + #define EMMA2RH_BHIF_MAIN_INT0_EN0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT0_EN0_OFF) + #define EMMA2RH_BHIF_MAIN_INT0_EN1_OFF 0x0044 + #define EMMA2RH_BHIF_MAIN_INT0_EN1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT0_EN1_OFF) + #define EMMA2RH_BHIF_MAIN_INT0_EN2_OFF 0x0048 + #define EMMA2RH_BHIF_MAIN_INT0_EN2 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT0_EN2_OFF) + #define EMMA2RH_BHIF_MAIN_INT1_EN0_OFF 0x0050 + #define EMMA2RH_BHIF_MAIN_INT1_EN0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT1_EN0_OFF) + #define EMMA2RH_BHIF_MAIN_INT1_EN1_OFF 0x0054 + #define EMMA2RH_BHIF_MAIN_INT1_EN1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT1_EN1_OFF) + #define EMMA2RH_BHIF_MAIN_INT1_EN2_OFF 0x0058 + #define EMMA2RH_BHIF_MAIN_INT1_EN2 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_INT1_EN2_OFF) + #define EMMA2RH_BHIF_NMI_ST_OFF 0x0060 + #define EMMA2RH_BHIF_NMI_ST (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_NMI_ST_OFF) + #define EMMA2RH_BHIF_NMI_EN_OFF 0x0064 + #define EMMA2RH_BHIF_NMI_EN (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_NMI_EN_OFF) + + #define EMMA2RH_BHIF_SW_INT0_OFF 0x0070 + #define EMMA2RH_BHIF_SW_INT0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT0_OFF) + #define EMMA2RH_BHIF_SW_INT0_EN_OFF 0x0080 + #define EMMA2RH_BHIF_SW_INT0_EN (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT0_EN_OFF) + #define EMMA2RH_BHIF_SW_INT0_CLR_OFF 0x0090 + #define EMMA2RH_BHIF_SW_INT0_CLR (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT0_CLR_OFF) + #define EMMA2RH_BHIF_SW_INT0_MSG_OFF 0x00a0 + #define EMMA2RH_BHIF_SW_INT0_MSG (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT0_MSG_OFF) + + #define EMMA2RH_BHIF_SW_INT1_OFF 0x0140 + #define EMMA2RH_BHIF_SW_INT1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT1_OFF) + #define EMMA2RH_BHIF_SW_INT1_EN_OFF 0x0150 + #define EMMA2RH_BHIF_SW_INT1_EN (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT1_EN_OFF) + #define EMMA2RH_BHIF_SW_INT1_CLR_OFF 0x0160 + #define EMMA2RH_BHIF_SW_INT1_CLR (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT1_CLR_OFF) + #define EMMA2RH_BHIF_SW_INT1_MSG_OFF 0x0170 + #define EMMA2RH_BHIF_SW_INT1_MSG (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT1_MSG_OFF) + + #define EMMA2RH_BHIF_SW_INT2_OFF 0x0240 + #define EMMA2RH_BHIF_SW_INT2 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT2_OFF) + #define EMMA2RH_BHIF_SW_INT2_EN_OFF 0x0250 + #define EMMA2RH_BHIF_SW_INT2_EN (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT2_EN_OFF) + #define EMMA2RH_BHIF_SW_INT2_CLR_OFF 0x0260 + #define EMMA2RH_BHIF_SW_INT2_CLR (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT2_CLR_OFF) + #define EMMA2RH_BHIF_SW_INT2_MSG_OFF 0x0270 + #define EMMA2RH_BHIF_SW_INT2_MSG (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SW_INT2_MSG_OFF) + + #define EMMA2RH_BHIF_MAIN_RESET_OFF 0x00b0 + #define EMMA2RH_BHIF_MAIN_RESET (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_RESET_OFF) + #define EMMA2RH_BHIF_MAIN_STATUS_OFF 0x00b8 + #define EMMA2RH_BHIF_MAIN_STATUS (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_STATUS_OFF) + #define EMMA2RH_BHIF_MAIN_EXPVEC_BADDR_OFF 0x00c0 + #define EMMA2RH_BHIF_MAIN_EXPVEC_BADDR (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_EXPVEC_BADDR_OFF) + #define EMMA2RH_BHIF_MAIN_OFFSET_ADDRESS_OFF 0x00c4 + #define EMMA2RH_BHIF_MAIN_OFFSET_ADDRESS (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_MAIN_OFFSET_ADDRESS_OFF) + + #define EMMA2RH_BHIF_SUB_INT_ST0_OFF 0x0100 + #define EMMA2RH_BHIF_SUB_INT_ST0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT_ST0_OFF) + #define EMMA2RH_BHIF_SUB_INT_ST1_OFF 0x0104 + #define EMMA2RH_BHIF_SUB_INT_ST1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT_ST1_OFF) + #define EMMA2RH_BHIF_SUB_INT_ST2_OFF 0x0108 + #define EMMA2RH_BHIF_SUB_INT_ST2 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT_ST2_OFF) + #define EMMA2RH_BHIF_SUB_INT0_EN0_OFF 0x0100 + #define EMMA2RH_BHIF_SUB_INT0_EN0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT0_EN0_OFF) + #define EMMA2RH_BHIF_SUB_INT0_EN1_OFF 0x0114 + #define EMMA2RH_BHIF_SUB_INT0_EN1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT0_EN1_OFF) + #define EMMA2RH_BHIF_SUB_INT0_EN2_OFF 0x0118 + #define EMMA2RH_BHIF_SUB_INT0_EN2 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT0_EN2_OFF) + #define EMMA2RH_BHIF_SUB_INT1_EN0_OFF 0x0120 + #define EMMA2RH_BHIF_SUB_INT1_EN0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT1_EN0_OFF) + #define EMMA2RH_BHIF_SUB_INT1_EN1_OFF 0x0124 + #define EMMA2RH_BHIF_SUB_INT1_EN1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT1_EN1_OFF) + #define EMMA2RH_BHIF_SUB_INT1_EN2_OFF 0x0128 + #define EMMA2RH_BHIF_SUB_INT1_EN2 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_INT1_EN2_OFF) + + #define EMMA2RH_BHIF_SUB_NMI_EN_OFF 0x0134 + #define EMMA2RH_BHIF_SUB_NMI_EN (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_NMI_EN_OFF) + #define EMMA2RH_BHIF_SUB_SW_INT_OFF 0x0140 + #define EMMA2RH_BHIF_SUB_SW_INT (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_SW_INT_OFF) + #define EMMA2RH_BHIF_SUB_SW_INT_EN_OFF 0x0150 + #define EMMA2RH_BHIF_SUB_SW_INT_EN (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_SW_INT_EN_OFF) + #define EMMA2RH_BHIF_SUB_SW_INT_CLR_OFF 0x0160 + #define EMMA2RH_BHIF_SUB_SW_INT_CLR (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_SW_INT_CLR_OFF) + #define EMMA2RH_BHIF_SUB_SW_INT_MSG_OFF 0x0170 + #define EMMA2RH_BHIF_SUB_SW_INT_MSG (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_SW_INT_MSG_OFF) + #define EMMA2RH_BHIF_SUB_RESET_OFF 0x0180 + #define EMMA2RH_BHIF_SUB_RESET (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_RESET_OFF) + #define EMMA2RH_BHIF_SUB_CTRL_OFF 0x0184 + #define EMMA2RH_BHIF_SUB_CTRL (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_CTRL_OFF) + #define EMMA2RH_BHIF_SUB_EXPVEC_BADDR_OFF 0x0190 + #define EMMA2RH_BHIF_SUB_EXPVEC_BADDR (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SUB_EXPVEC_BADDR_OFF) + + #define EMMA2RH_BHIF_SDC_RESET_OFF 0x01a0 + #define EMMA2RH_BHIF_SDC_RESET (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_RESET_OFF) + #define EMMA2RH_BHIF_SDC_CONFIG_OFF 0x01a4 + #define EMMA2RH_BHIF_SDC_CONFIG (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_CONFIG_OFF) + #define EMMA2RH_BHIF_SDC_INIT_OFF 0x01a8 + #define EMMA2RH_BHIF_SDC_INIT (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_INIT_OFF) + #define EMMA2RH_BHIF_SDC_REFCNT_OFF 0x01ac + #define EMMA2RH_BHIF_SDC_REFCNT (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_REFCNT_OFF) + #define EMMA2RH_BHIF_SDC_INT_OFF 0x01b0 + #define EMMA2RH_BHIF_SDC_INT (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_INT_OFF) + #define EMMA2RH_BHIF_SDC_ASYNC_CFG_OFF 0x01b4 + #define EMMA2RH_BHIF_SDC_ASYNC_CFG (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_ASYNC_CFG_OFF) + #define EMMA2RH_BHIF_SDC_CLOCK_DELAY_OFF 0x01b8 + #define EMMA2RH_BHIF_SDC_CLOCK_DELAY (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_CLOCK_DELAY_OFF) + #define EMMA2RH_BHIF_SDC_PRIO_CFG0_OFF 0x01c0 + #define EMMA2RH_BHIF_SDC_PRIO_CFG0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_PRIO_CFG0_OFF) + #define EMMA2RH_BHIF_SDC_PRIO_CFG1_OFF 0x01c4 + #define EMMA2RH_BHIF_SDC_PRIO_CFG1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_PRIO_CFG1_OFF) + #define EMMA2RH_BHIF_SDC_OPENPAGE_CTRL_OFF 0x01c8 + #define EMMA2RH_BHIF_SDC_OPENPAGE_CTRL (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_OPENPAGE_CTRL_OFF) + #define EMMA2RH_BHIF_SDC_MONITOR0_OFF 0x01d0 + #define EMMA2RH_BHIF_SDC_MONITOR0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_MONITOR0_OFF) + #define EMMA2RH_BHIF_SDC_MONITOR1_OFF 0x01d4 + #define EMMA2RH_BHIF_SDC_MONITOR1 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_MONITOR1_OFF) + #define EMMA2RH_BHIF_SDC_MONITOR2_OFF 0x01d8 + #define EMMA2RH_BHIF_SDC_MONITOR2 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_MONITOR2_OFF) + #define EMMA2RH_BHIF_SDC_MONITOR3_OFF 0x01dc + #define EMMA2RH_BHIF_SDC_MONITOR3 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_SDC_MONITOR3_OFF) + + #define EMMA2RH_BHIF_BERR_CTRL_OFF 0x0310 + #define EMMA2RH_BHIF_BERR_CTRL (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_BERR_CTRL_OFF) + #define EMMA2RH_BHIF_BERR_STATUS_OFF 0x0314 + #define EMMA2RH_BHIF_BERR_STATUS (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_BERR_STATUS_OFF) + #define EMMA2RH_BHIF_BERR_TARGET0_OFF 0x0318 + #define EMMA2RH_BHIF_BERR_TARGET0 (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_BERR_TARGET0_OFF) + #define EMMA2RH_BHIF_BERR_ADDR_OFF 0x0320 + #define EMMA2RH_BHIF_BERR_ADDR (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_BERR_ADDR_OFF) + #define EMMA2RH_BHIF_BERR_OCPY_TIME_OFF 0x0328 + #define EMMA2RH_BHIF_BERR_OCPY_TIME (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_BERR_OCPY_TIME_OFF) + #define EMMA2RH_BHIF_BERR_OCPY_EN_OFF 0x032c + #define EMMA2RH_BHIF_BERR_OCPY_EN (EMMA2RH_BHIF_BASE + EMMA2RH_BHIF_BERR_OCPY_EN_OFF) + + #define EMMA2RH_MONITOR_CTRL_MAIN_CPU_OFF 0x0330 + #define EMMA2RH_MONITOR_CTRL_MAIN_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_MONITOR_CTRL_MAIN_CPU_OFF) + #define EMMA2RH_MONITOR_STS0_MAIN_CPU_OFF 0x0334 + #define EMMA2RH_MONITOR_STS0_MAIN_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_MONITOR_STS0_MAIN_CPU_OFF) + #define EMMA2RH_MONITOR_STS1_MAIN_CPU_OFF 0x0330 + #define EMMA2RH_MONITOR_STS1_MAIN_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_MONITOR_STS1_MAIN_CPU_OFF) + #define EMMA2RH_MONITOR_CTRL_SUB_CPU_OFF 0x0340 + #define EMMA2RH_MONITOR_CTRL_SUB_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_MONITOR_CTRL_SUB_CPU_OFF) + #define EMMA2RH_MONITOR_STS0_SUB_CPU_OFF 0x0344 + #define EMMA2RH_MONITOR_STS0_SUB_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_MONITOR_STS0_SUB_CPU_OFF) + #define EMMA2RH_MONITOR_STS1_SUB_CPU_OFF 0x0348 + #define EMMA2RH_MONITOR_STS1_SUB_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_MONITOR_STS1_SUB_CPU_OFF) + + #define EMMA2RH_PREFETCH_CTRL_MAIN_CPU_OFF 0x0360 + #define EMMA2RH_PREFETCH_CTRL_MAIN_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_PREFETCH_CTRL_MAIN_CPU_OFF) + #define EMMA2RH_PREFETCH_ADDR_MAIN_CPU_OFF 0x0364 + #define EMMA2RH_PREFETCH_ADDR_MAIN_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_PREFETCH_ADDR_MAIN_CPU_OFF) + #define EMMA2RH_SWAP_CTRL_MAIN_CPU_OFF 0x0348 + #define EMMA2RH_SWAP_CTRL_MAIN_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_SWAP_CTRL_MAIN_CPU_OFF) + #define EMMA2RH_PREFETCH_CTRL_SUB_CPU_OFF 0x0370 + #define EMMA2RH_PREFETCH_CTRL_SUB_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_PREFETCH_CTRL_SUB_CPU_OFF) + #define EMMA2RH_PREFETCH_ADDR_SUB_CPU_OFF 0x0374 + #define EMMA2RH_PREFETCH_ADDR_SUB_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_PREFETCH_ADDR_SUB_CPU_OFF) + #define EMMA2RH_SWAP_CTRL_SUB_CPU_OFF 0x0378 + #define EMMA2RH_SWAP_CTRL_SUB_CPU (EMMA2RH_BHIF_BASE + EMMA2RH_SWAP_CTRL_SUB_CPU_OFF) + + /* + * Interrupt + */ + #define EMMA2RH_INT0_DMA (1<<0) + #define EMMA2RH_INT0_MIF (1<<1) + #define EMMA2RH_INT0_AUDIOM0 (1<<2) + #define EMMA2RH_INT0_AUDIOM1 (1<<3) + #define EMMA2RH_INT0_AUDIOS0 (1<<4) + #define EMMA2RH_INT0_AUDIOS1 (1<<5) + #define EMMA2RH_INT0_VIDEO (1<<6) + #define EMMA2RH_INT0_SW0 (1<<7) + #define EMMA2RH_INT0_SW1 (1<<8) + #define EMMA2RH_INT0_SW2 (1<<9) + #define EMMA2RH_INT0_VENC0 (1<<10) + #define EMMA2RH_INT0_VENC1 (1<<11) + #define EMMA2RH_INT0_DISP00 (1<<12) + #define EMMA2RH_INT0_DISP01 (1<<13) + #define EMMA2RH_INT0_DISP10 (1<<14) + #define EMMA2RH_INT0_DISP11 (1<<15) + #define EMMA2RH_INT0_BLT0 (1<<16) + #define EMMA2RH_INT0_BLT1 (1<<17) + #define EMMA2RH_INT0_AVENC (1<<18) + #define EMMA2RH_INT0_GIO (1<<19) + #define EMMA2RH_INT0_JTAG (1<<20) + + #define EMMA2RH_INT1_PCI (1<<0) + #define EMMA2RH_INT1_IDE (1<<1) + #define EMMA2RH_INT1_IPIO (1<<3) + #define EMMA2RH_INT1_SATA0 (1<<4) + #define EMMA2RH_INT1_SATA1 (1<<5) + #define EMMA2RH_INT1_SATA2 (1<<6) + #define EMMA2RH_INT1_ZTMR0 (1<<7) + #define EMMA2RH_INT1_ZTMR1 (1<<8) + #define EMMA2RH_INT1_TRTC (1<<9) + #define EMMA2RH_INT1_ZIRB (1<<13) + #define EMMA2RH_INT1_GPIO0 (1<<14) + #define EMMA2RH_INT1_GPIO1 (1<<15) + #define EMMA2RH_INT1_PRRD (1<<16) + #define EMMA2RH_INT1_PFUR0 (1<<17) + #define EMMA2RH_INT1_PFUR1 (1<<18) + #define EMMA2RH_INT1_PFUR2 (1<<19) + #define EMMA2RH_INT1_PSCI00 (1<<20) + #define EMMA2RH_INT1_PSCI01 (1<<21) + #define EMMA2RH_INT1_PSCI10 (1<<22) + #define EMMA2RH_INT1_PSCI11 (1<<23) + #define EMMA2RH_INT1_PIIC0 (1<<24) + #define EMMA2RH_INT1_PIIC1 (1<<25) + #define EMMA2RH_INT1_PIIC2 (1<<26) + #define EMMA2RH_INT1_PCIF (1<<27) + #define EMMA2RH_INT1_PCSI0 (1<<28) + #define EMMA2RH_INT1_PCSI1 (1<<29) + #define EMMA2RH_INT1_PCSI2 (1<<30) + #define EMMA2RH_INT1_PMM (1<<31) + + #define EMMA2RH_INIT2_SP000 (1<<0) + #define EMMA2RH_INIT2_SP001 (1<<1) + #define EMMA2RH_INIT2_SP002 (1<<2) + #define EMMA2RH_INIT2_SP003 (1<<3) + #define EMMA2RH_INIT2_SP004 (1<<4) + #define EMMA2RH_INIT2_SP005 (1<<5) + #define EMMA2RH_INIT2_SP006 (1<<6) + #define EMMA2RH_INIT2_SP007 (1<<7) + #define EMMA2RH_INIT2_SP008 (1<<8) + #define EMMA2RH_INIT2_SP009 (1<<9) + #define EMMA2RH_INIT2_SP010 (1<<10) + #define EMMA2RH_INIT2_SP011 (1<<11) + #define EMMA2RH_INIT2_SP012 (1<<12) + #define EMMA2RH_INIT2_SP013 (1<<13) + #define EMMA2RH_INIT2_SP014 (1<<14) + #define EMMA2RH_INIT2_SP015 (1<<15) + #define EMMA2RH_INIT2_SP100 (1<<16) + #define EMMA2RH_INIT2_SP101 (1<<17) + #define EMMA2RH_INIT2_SP102 (1<<18) + #define EMMA2RH_INIT2_SP103 (1<<19) + #define EMMA2RH_INIT2_SP104 (1<<20) + #define EMMA2RH_INIT2_SP105 (1<<21) + #define EMMA2RH_INIT2_SP106 (1<<22) + #define EMMA2RH_INIT2_SP107 (1<<23) + #define EMMA2RH_INIT2_SP108 (1<<24) + #define EMMA2RH_INIT2_SP109 (1<<25) + #define EMMA2RH_INIT2_SP110 (1<<26) + #define EMMA2RH_INIT2_SP111 (1<<27) + #define EMMA2RH_INIT2_SP112 (1<<28) + #define EMMA2RH_INIT2_SP113 (1<<29) + #define EMMA2RH_INIT2_SP114 (1<<30) + #define EMMA2RH_INIT2_SP115 (1<<31) + + /* + * PCI Configuration + */ + #define EMMA2RH_PCI_DEVICE_ID_OFF 0x0000 + #define EMMA2RH_PCI_COM_STAT_OFF 0x0004 + #define EMMA2RH_PCI_REV_CLASS_OFF 0x0008 + #define EMMA2RH_PCI_MISC0_OFF 0x000c + #define EMMA2RH_PCI_BASE1_ADR_OFF 0x0010 + #define EMMA2RH_PCI_BASE2_ADR_OFF 0x0014 + #define EMMA2RH_PCI_SUBSYS_ID_OFF 0x002c + #define EMMA2RH_PCI_EXROMADR_ID_OFF 0x0030 + #define EMMA2RH_PCI_EXT0_OFF 0x0034 + #define EMMA2RH_PCI_MISC1_OFF 0x003c + #define EMMA2RH_PCI_PM0_OFF 0x0040 + #define EMMA2RH_PCI_PM1_OFF 0x0044 + + /* + * PCI Communication + */ + #define EMMA2RH_PCI_CONTROL_OFF 0x0000 + #define EMMA2RH_PCI_CONTROL (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_CONTROL_OFF) + #define EMMA2RH_PCI_ARBIT_CTR_OFF 0x0004 + #define EMMA2RH_PCI_ARBIT_CTR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_ARBIT_CTR_OFF) + #define EMMA2RH_PCI_ERROR_OFF 0x0008 + #define EMMA2RH_PCI_ERROR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_ERROR_OFF) + #define EMMA2RH_PCI_BUS_STA_OFF 0x000c + #define EMMA2RH_PCI_BUS_STA (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_BUS_STA_OFF) + #define EMMA2RH_PCI_IWIN0_CTR_OFF 0x0010 + #define EMMA2RH_PCI_IWIN0_CTR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_IWIN0_CTR_OFF) + #define EMMA2RH_PCI_IWIN1_CTR_OFF 0x0014 + #define EMMA2RH_PCI_IWIN1_CTR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_IWIN1_CTR_OFF) + #define EMMA2RH_PCI_INIT_ESWP_OFF 0x0018 + #define EMMA2RH_PCI_INIT_ESWP (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_INIT_ESWP_OFF) + + #define EMMA2RH_PCI_INT_OFF 0x0020 + #define EMMA2RH_PCI_INT (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_INT_OFF) + #define EMMA2RH_PCI_INT_EN_OFF 0x0024 + #define EMMA2RH_PCI_INT_EN (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_INT_EN_OFF) + #define EMMA2RH_PCI_INT_PCIDMA1 (1 << 0) + #define EMMA2RH_PCI_INT_PCIDMA2 (1 << 1) + #define EMMA2RH_PCI_INT_SIGTABORT (1 << 8) + #define EMMA2RH_PCI_INT_RTABORT (1 << 9) + #define EMMA2RH_PCI_INT_RMABORT (1 << 10) + #define EMMA2RH_PCI_INT_MDPERR (1 << 12) + #define EMMA2RH_PCI_INT_DETPERR (1 << 13) + #define EMMA2RH_PCI_INT_SIGSERR (1 << 14) + #define EMMA2RH_PCI_INT_RSERR (1 << 15) + #define EMMA2RH_PCI_INT_PSCHG (1 << 20) + + #define EMMA2RH_PCI_TWIN_CTR_OFF 0x0030 + #define EMMA2RH_PCI_TWIN_CTR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_TWIN_CTR_OFF) + #define EMMA2RH_PCI_TWIN_BADR_OFF 0x0034 + #define EMMA2RH_PCI_TWIN_BADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_TWIN_BADR_OFF) + #define EMMA2RH_PCI_TWIN0_DADDR_OFF 0x0038 + #define EMMA2RH_PCI_TWIN0_DADDR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_TWIN0_DADDR_OFF) + #define EMMA2RH_PCI_TWIN1_DADDR_OFF 0x003c + #define EMMA2RH_PCI_TWIN1_DADDR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_TWIN1_DADDR_OFF) + #define EMMA2RH_PCI_DMA1_PSADR_OFF 0x0040 + #define EMMA2RH_PCI_DMA1_PSADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA1_PSADR_OFF) + #define EMMA2RH_PCI_DMA1_MSADR_OFF 0x0044 + #define EMMA2RH_PCI_DMA1_MSADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA1_MSADR_OFF) + #define EMMA2RH_PCI_DMA1_MEADR_OFF 0x0048 + #define EMMA2RH_PCI_DMA1_MEADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA1_MEADR_OFF) + #define EMMA2RH_PCI_DMA1_LPADR_OFF 0x004c + #define EMMA2RH_PCI_DMA1_LPADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA1_LPADR_OFF) + #define EMMA2RH_PCI_DMA1_CTR_OFF 0x0050 + #define EMMA2RH_PCI_DMA1_CTR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA1_CTR_OFF) + #define EMMA2RH_PCI_DMA1_STA_OFF 0x0054 + #define EMMA2RH_PCI_DMA1_STA (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA1_STA_OFF) + #define EMMA2RH_PCI_DMA2_PSADR_OFF 0x0060 + #define EMMA2RH_PCI_DMA2_PSADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA2_PSADR_OFF) + #define EMMA2RH_PCI_DMA2_MSADR_OFF 0x0064 + #define EMMA2RH_PCI_DMA2_MSADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA2_MSADR_OFF) + #define EMMA2RH_PCI_DMA2_MEADR_OFF 0x0068 + #define EMMA2RH_PCI_DMA2_MEADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA2_MEADR_OFF) + #define EMMA2RH_PCI_DMA2_LPADR_OFF 0x006c + #define EMMA2RH_PCI_DMA2_LPADR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA2_LPADR_OFF) + #define EMMA2RH_PCI_DMA2_CTR_OFF 0x0070 + #define EMMA2RH_PCI_DMA2_CTR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA2_CTR_OFF) + #define EMMA2RH_PCI_DMA2_STA_OFF 0x0074 + #define EMMA2RH_PCI_DMA2_STA (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_DMA2_STA_OFF) + #define EMMA2RH_PCI_PWR_STA_OFF 0x0080 + #define EMMA2RH_PCI_PWR_STA (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_PWR_STA_OFF) + #define EMMA2RH_PCI_PME_CTR_OFF 0x0084 + #define EMMA2RH_PCI_PME_CTR (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_PME_CTR_OFF) + #define EMMA2RH_PCI_SUBSYSID_OFF 0x0088 + #define EMMA2RH_PCI_SUBSYSID (EMMA2RH_PCI_COMM_BASE + EMMA2RH_PCI_SUBSYSID_OFF) + + /* + * GPIO + */ + #define EMMA2RH_ZPIO_DATA_OFF 0x0010 + #define EMMA2RH_ZPIO_DATA (EMMA2RH_GPIO_BASE + EMMA2RH_ZPIO_DATA_OFF) + #define EMMA2RH_ZPIO_MASK_OFF 0x0014 + #define EMMA2RH_ZPIO_MASK (EMMA2RH_GPIO_BASE + EMMA2RH_ZPIO_MASK_OFF) + #define EMMA2RH_ZPIO_DIR_OFF 0x0020 + #define EMMA2RH_ZPIO_DIR (EMMA2RH_GPIO_BASE + EMMA2RH_ZPIO_DIR_OFF) + #define EMMA2RH_ZPIO_INT_ST_OFF 0x0030 + #define EMMA2RH_ZPIO_INT_ST (EMMA2RH_GPIO_BASE + EMMA2RH_ZPIO_INT_ST_OFF) + #define EMMA2RH_ZPIO_INT_MASK_OFF 0x003c + #define EMMA2RH_ZPIO_INT_MASK (EMMA2RH_GPIO_BASE + EMMA2RH_ZPIO_INT_MASK_OFF) + #define EMMA2RH_ZPIO_INT_MASK_MAIN (0xb0111078) + #define EMMA2RH_ZPIO_INT_MOD_OFF 0x0048 + #define EMMA2RH_ZPIO_INT_MOD (EMMA2RH_GPIO_BASE + EMMA2RH_ZPIO_INT_MOD_OFF) + #define EMMA2RH_ZPIO_INT_CNDA_OFF 0x0054 + #define EMMA2RH_ZPIO_INT_CNDA (EMMA2RH_GPIO_BASE + EMMA2RH_ZPIO_INT_CNDA_OFF) + #define EMMA2RH_ZPIO_INT_CNDB_OFF 0x0060 + #define EMMA2RH_ZPIO_INT_CNDB (EMMA2RH_GPIO_BASE + EMMA2RH_ZPIO_INT_CNDB_OFF) + + #endif /* _EMMA2RH_REG_H_ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/emma2/i2c-emma.h linux-current/include/asm-mips/emma2/i2c-emma.h *** linux-2.6.10/include/asm-mips/emma2/i2c-emma.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/emma2/i2c-emma.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,212 ---- + /* -------------------------------------------------------------------- */ + /* i2c-emma.h: NEC EMMA2HL global defines */ + /* -------------------------------------------------------------------- */ + /* + Shinya Kuribayashi, NEC Electronics Corporation + s-kuribayashi@ap.jp.nec.com + Takamitsu Honda, NEC Electronics Corporation + takamitsu.honda@necel.com + + Copyright (C) NEC Electronics Corporation 2002, 2003, 2004, 2005 + + 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*/ + /* -------------------------------------------------------------------- */ + + #ifndef I2C_EMMA_H + #define I2C_EMMA_H + + /*---------------------------------------------------------------------------*/ + /* CNT - Control register (00H R/W) */ + /*---------------------------------------------------------------------------*/ + #define SPT 0x00000001 + #define STT 0x00000002 + #define ACKE 0x00000004 + #define WTIM 0x00000008 + #define SPIE 0x00000010 + #define WREL 0x00000020 + #define LREL 0x00000040 + #define IICE 0x00000080 + #define CNT_RESERVED 0x000000ff /* reserved bit 0 */ + + #define I2C_EMMA_START (IICE | STT) + #define I2C_EMMA_STOP (IICE | SPT) + #define I2C_EMMA_REPSTART I2C_EMMA_START + + /*---------------------------------------------------------------------------*/ + /* STA - Status register (04H Read) */ + /*---------------------------------------------------------------------------*/ + #define MSTS 0x00000080 + #define ALD 0x00000040 + #define EXC 0x00000020 + #define COI 0x00000010 + #define TRC 0x00000008 + #define ACKD 0x00000004 + #define STD 0x00000002 + #define SPD 0x00000001 + + /*---------------------------------------------------------------------------*/ + /* CSEL - Clock select register (08H R/W) */ + /*---------------------------------------------------------------------------*/ + #define SLEN 0x00000080 /* for test use, set "0" */ + #define OLSI 0x00000040 /* for test use, set "0" */ + #define CLD 0x00000020 + #define DAD 0x00000010 + #define SMC 0x00000008 + #define DFC 0x00000004 + #define CL 0x00000003 + #define CSEL_RESERVED 0x000000ff /* reserved bit 0 */ + + #define FAST375 0x0000000b + #define FAST281 0x0000000a + #define FAST140 0x00000009 + #define STANDARD102 0x00000003 + #define STANDARD78 0x00000002 + #define STANDARD40 0x00000001 + + /*---------------------------------------------------------------------------*/ + /* SVA - Slave address register (0CH R/W) */ + /*---------------------------------------------------------------------------*/ + #define SVA 0x000000fe + + /*---------------------------------------------------------------------------*/ + /* SHR - Shift register (10H R/W) */ + /*---------------------------------------------------------------------------*/ + #define SR 0x000000ff + + /*---------------------------------------------------------------------------*/ + /* FCNT - FIFO control register (20H R/W) */ + /*---------------------------------------------------------------------------*/ + #define FRST 0x00000001 + #define FENA 0x00000002 + #define FSTOP 0x00000004 + #define TCSEL 0x00000100 + #define RXT_ENA 0x00000200 + #define TXT_ENA 0x00000400 + #define SVA_REN 0x00010000 + #define ACKSTOP 0x00020000 + #define REINC 0x00040000 + #define FORCE 0x00080000 + #define RESERVED20 0x00100000 + #define RESERVED21 0x00200000 + #define FCNT_RESERVED 0x003f0707 /* reserved bit 0 */ + + /*---------------------------------------------------------------------------*/ + /* FSTA - FIFO status register (24H Read) */ + /*---------------------------------------------------------------------------*/ + #define WPOS 0x3f000000 + #define RPOS 0x003f0000 + #define RWSTA 0x00008000 + #define WAIT 0x00004000 + #define POOL 0x00003f00 + #define INTTXTO 0x00000080 + #define INTRXTO 0x00000040 + #define INTTXLV 0x00000020 + #define INTRXLV 0x00000010 + #define EMPTY 0x00000004 + #define FULL 0x00000001 + + /*---------------------------------------------------------------------------*/ + /* FTH - FIFO threshold register (28H R/W) */ + /*---------------------------------------------------------------------------*/ + #define TXLV 0x003f0000 + #define RX_STATUS 0x00001000 + #define RX_STOP_EN 0x00000100 + #define RXLV 0x0000003f + #define FTH_RESERVED 0x003f113f /* reserved bit 0 */ + + /*---------------------------------------------------------------------------*/ + /* FRXTO - Rx FIFO timeout level register (2CH R/W) */ + /*---------------------------------------------------------------------------*/ + #define RXTO 0x03ffffff + + /*---------------------------------------------------------------------------*/ + /* FTXTO - Tx FIFO timeout level register (30H R/W) */ + /*---------------------------------------------------------------------------*/ + #define TXTO 0x03ffffff + + /*---------------------------------------------------------------------------*/ + /* FRDAT - FIFO read data register (34H Read) */ + /*---------------------------------------------------------------------------*/ + #define R_DATA 0x000000ff + + /*---------------------------------------------------------------------------*/ + /* FWDAT - FIFO write data register (38H Write) */ + /*---------------------------------------------------------------------------*/ + #define W_DATA 0x000000ff + + /*---------------------------------------------------------------------------*/ + /* FDBG - Timeout counter data (3CH R/W) */ + /*---------------------------------------------------------------------------*/ + #define TCOUNT 0x03ffffff + + /*---------------------------------------------------------------------------*/ + /* INT - Interrupt register (40H R/W) */ + /* INTM - Interrupt mask register (44H R/W) */ + /*---------------------------------------------------------------------------*/ + #define INT_WCLK 0x00200000 + #define INT_WSVA 0x00100000 + #define INT_WFDAT 0x00080000 + #define INT_WSHIFT 0x00040000 + #define INT_WDWAIT 0x00020000 /* ? */ + #define INT_WCONT 0x00010000 + #define INT_TXTO 0x00004000 + #define INT_RXTO 0x00002000 + #define INT_TXTH 0x00001000 + #define INT_RXTH 0x00000800 + #define INT_EMPTY 0x00000400 + #define INT_FULL 0x00000200 + #define INT_CHANGE 0x00000100 + #define INT_TEST 0x00000040 + #define INT_NOP 0x00000020 + #define INT_ALD9 0x00000010 + #define INT_ALD8 0x00000008 + #define INT_WAIT9 0x00000004 + #define INT_WAIT8 0x00000002 + #define INT_STOP 0x00000001 + #define INT_RESERVED 0x003f7f7f /* reserved bit 0 */ + + #define INT_USUAL (INT_NOP|INT_ALD9|INT_ALD8|INT_WAIT9|INT_WAIT8|INT_STOP) + + /*********************************************************************** + * I2C registers + *********************************************************************** + */ + #if defined(CONFIG_EMMA2HL) + #define I2C_EMMA_CNT 0x00 + #define I2C_EMMA_STA 0x04 + #define I2C_EMMA_CSEL 0x08 + #define I2C_EMMA_SVA 0x0c + #define I2C_EMMA_SHR 0x10 + #define I2C_EMMA_FCNT 0x20 + #define I2C_EMMA_FSTA 0x24 + #define I2C_EMMA_FTH 0x28 + #define I2C_EMMA_FRXTO 0x2c + #define I2C_EMMA_FTXTO 0x30 + #define I2C_EMMA_FRDAT 0x34 + #define I2C_EMMA_FWDAT 0x38 + #define I2C_EMMA_FDBG 0x3c + #define I2C_EMMA_INT 0x40 + #define I2C_EMMA_INTM 0x44 + #elif defined(CONFIG_EMMA) + #define I2C_EMMA_CNT 0x00 + #define I2C_EMMA_STA 0x10 + #define I2C_EMMA_CSEL 0x20 + #define I2C_EMMA_SVA 0x30 + #define I2C_EMMA_SHR 0x40 + #define I2C_EMMA_INT 0x50 + #define I2C_EMMA_INTM 0x60 + #endif + + #endif /* I2C_EMMA_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/emma2/pmon.h linux-current/include/asm-mips/emma2/pmon.h *** linux-2.6.10/include/asm-mips/emma2/pmon.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/emma2/pmon.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,62 ---- + /* + * 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. + * + * (C) Copyright TOSHIBA CORPORATION 2005 + * All Rights Reserved. + * + */ + #ifndef _EMMA2_PMON_H_ + #define _EMMA2_PMON_H_ + + #include + + struct pmon_vector { + int (*read)(int fd, char *buf, int size); + int (*write)(int fd, char *buf, int size); + int (*open)(char *name, int mode); + int (*close)(int fd); + int (*ioctl)(int fd, int request, void* arg); + int (*printf)(char *fmstr, ...); + int (*vsprintf)(char *dst, char *fmtstr, ...); + int (*ttctl)(int fd, int op, int ap1, int ap2); + void (*exit)(int status); + char *(*getenv)(char *name); + void (*onintr)(int code, int *dat); + void (*flush_cache)(int cache); + void (*_exception)(void); + int (*_fpstatesz)(void); + void (*_fpinit)(void); + void *(*_fpstate)(void); + void (*cop1)(void); + int (*adr2symoff)(char *dst, int value, int width); + int (*sym2adr)(int *v, char *label); + int (*getclkfreq)(void); + void (*_clkinit)(void); + int (*interpret)(const char *cmd, char *outbuf, int len); + }; + + extern struct pmon_vector *pmon_vector; + + /* from pmonlib.c */ + extern void prom_printf(char *fmt, ...); + /* pmonlib support routine */ + extern void prom_putchar(char c); + + #define pmon_printf prom_printf + + extern void pmon_halt(void) __attribute__((noreturn)); + extern void set_pmon_debug_traps(void) __init; + extern void pmon_breakpoint(void); + + extern char *pmon_getenv(const char *name) __init; + extern int pmon_interpret(const char *cmd, char *outbuf, int len); + + extern unsigned int get_pmon_clkfreq(void) __init; + + + #define PMON_VECTOR_BASE 0x80000800 + #define PMON_VECTOR (PMON_VECTOR_BASE + 0x500) + + #endif /* _EMMA2_PMON_H_ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/emma3/emma3.h linux-current/include/asm-mips/emma3/emma3.h *** linux-2.6.10/include/asm-mips/emma3/emma3.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/emma3/emma3.h Wed Apr 18 16:46:33 2007 *************** *** 0 **** --- 1,129 ---- + /* + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + */ + + #include + + #ifndef _EMMA3_H_ + #define _EMMA3_H_ + /* + * Memory MAP + */ + #define EMMA3_SDRAM_BASE 0x00000000 + #define EMMA3_SDRAM_SIZE 0x10000000 /* less than 256MB */ + + #define EMMA3_PCI_MEM_PCIBASE 0xfe000000 + #define EMMA3_PCI_MEM_BASE 0x12000000 + #define EMMA3_PCI_MEM_SIZE 0x02000000 /* 32 MB */ + + #define EMMA3_PCI_CONFIG_BASE EMMA3_PCI_MEM_BASE + #define EMMA3_PCI_CONFIG_SIZE EMMA3_PCI_MEM_SIZE + + #define EMMA3_PCI_IO_PCIBASE 0x00000000 + #define EMMA3_PCI_IO_BASE 0x00000000 + #define EMMA3_PCI_IO_SIZE 0x00000000 /* I/O Space does not exist. */ + + #define EMMA3_PCI1_MEM_PCIBASE 0xb0000000 + #define EMMA3_PCI1_MEM_BASE 0x14000000 + #define EMMA3_PCI1_MEM_SIZE 0x04000000 /* 128 MB for PCIMB */ + + /* + * ISA LAN address + */ + #define EMMA3_ISA_LAN_ADDRESS 0x11800300 + + /* + * PCI SLOT NUM + */ + #define EMMA3_PCI_USB_SLOT 3 + #define EMMA3_PCI_LAN_SLOT 4 + #define EMMA3_PCI_EMMA3_SLOT 5 + + /* + * INTERRUPT + */ + + #define NUM_CPU_IRQ 8 + #define NUM_EMMA3_IRQ 96 + #define NUM_EMMA3_SWINT_IRQ 32 + #define NUM_EMMA3_GPIO0_IRQ 32 + #define NUM_EMMA3_GPIO1_IRQ 32 + #define NUM_EMMA3_GPIO_IRQ (NUM_EMMA3_GPIO0_IRQ + NUM_EMMA3_GPIO1_IRQ) + + + #define CPU_IRQ_BASE 0 + #define EMMA3_IRQ_BASE (NUM_CPU_IRQ) + #define EMMA3_SWINT_IRQ_BASE (EMMA3_IRQ_BASE + NUM_EMMA3_IRQ) + #define EMMA3_GPIO0_IRQ_BASE (EMMA3_SWINT_IRQ_BASE + NUM_EMMA3_SWINT_IRQ) + #define EMMA3_GPIO1_IRQ_BASE (EMMA3_GPIO0_IRQ_BASE + NUM_EMMA3_GPIO0_IRQ) + + #define EMMA3_CPU_CASCADE (CPU_IRQ_BASE + 2) + #define EMMA3_CPU_TIMER (CPU_IRQ_BASE + 7) + #define EMMA3_SWINT_CASCADE (EMMA3_IRQ_BASE + 6) + + #define EMMA3_USB_IRQ (EMMA3_IRQ_BASE + 32 + 4) + #define EMMA3_GPIO_CASCADE (EMMA3_IRQ_BASE + 32 + 14) + + #define EMMA3_PFUR0_IRQ (EMMA3_IRQ_BASE + 32 + 16) + #define EMMA3_PFUR1_IRQ (EMMA3_IRQ_BASE + 32 + 17) + #define EMMA3_PFUR2_IRQ (EMMA3_IRQ_BASE + 32 + 18) + + #define EMMA3_IRQ_PIIC0 (EMMA3_IRQ_BASE + 32 + 19) + #define EMMA3_IRQ_PIIC1 (EMMA3_IRQ_BASE + 32 + 20) + #define EMMA3_IRQ_PIIC2 (EMMA3_IRQ_BASE + 32 + 21) + + #define EMMA3_ISA_LAN_IRQ (EMMA3_GPIO0_IRQ_BASE + 9) + #define EMMA3_PCI_ETHER_IRQ (EMMA3_GPIO0_IRQ_BASE + 18) + #define EMMA3_PCI_USB_IRQ (EMMA3_GPIO0_IRQ_BASE + 35) + #define EMMA3_PCI_ETHER_IRQ_A2 (EMMA3_GPIO0_IRQ_BASE + 6) + #define EMMA3_PCI_USB_IRQ_A2 (EMMA3_GPIO0_IRQ_BASE + 7) + + #ifndef __ASSEMBLY__ + static inline void emma3_sync(void) + { + volatile u32 *p = (volatile u32 *)0xbfc00800; + (void)(*p); + } + + static inline void emma3_out32(u32 addr, u32 val) + { + *(volatile u32 *)(addr) = val; + emma3_sync(); + } + + static inline u32 emma3_in32(u32 addr) + { + u32 val = *(volatile u32 *)(addr); + emma3_sync(); + return val; + } + + static inline void emma3_out16(u32 addr, u16 val) + { + *(volatile u16 *)(addr) = val; + emma3_sync(); + } + + static inline u16 emma3_in16(u32 addr) + { + u16 val = *(volatile u16 *)(addr); + emma3_sync(); + return val; + } + + static inline void emma3_out8(u32 addr, u8 val) + { + *(volatile u8 *)(addr) = val; + emma3_sync(); + } + + static inline u8 emma3_in8(u32 addr) + { + u8 val = *(volatile u8 *)(addr); + emma3_sync(); + return val; + } + #endif + + #endif /* _EMMA3_H_ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/emma3/emma3_reg.h linux-current/include/asm-mips/emma3/emma3_reg.h *** linux-2.6.10/include/asm-mips/emma3/emma3_reg.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/emma3/emma3_reg.h Fri Jul 28 20:30:59 2006 *************** *** 0 **** --- 1,534 ---- + /* emma3.h + * Definition for EMMA3 Board Configuration + * + * (C) Copyright TOSHIBA CORPORATION 2006 + * All Rights Reserved. + */ + + #ifndef _EMMA3_REG_H_ + #define _EMMA3_REG_H_ + + #define EMMA3_REG_PBASE 0x10000000 + #define EMMA3_REG_SIZE 0x01000000 + + #define EMMA3_BHIF_BASE 0xb0000000 + #define EMMA3_PCI_CONF_BASE 0xb2000000 + #define EMMA3_PCI_COMM_BASE 0xb0200000 + #define EMMA3_PERIPH_BUS_BRIDGE_BASE 0xb0100000 + #define EMMA3_UART0_BASE 0xb0101000 + #define EMMA3_UART1_BASE 0xb0102000 + #define EMMA3_UART2_BASE 0xb0103000 + #define EMMA3_I2C0_BASE 0xb0104000 + #define EMMA3_I2C1_BASE 0xb0105000 + #define EMMA3_I2C2_BASE 0xb0106000 + + #define EMMA3_GPIO0_BASE 0xb0110d00 + #define EMMA3_GPIO1_BASE 0xb0110e00 + + #define EMMA3_GIO_BASE 0xb0000800 + + /* + * BHIF + */ + #define EMMA3_BHIF_VERSION_OFF 0x0000 + #define EMMA3_BHIF_VERSION (EMMA3_BHIF_BASE + EMMA3_BHIF_VERSION_OFF) + #define EMMA3_BHIF_GENERATION_OFF 0x0004 + #define EMMA3_BHIF_GENERATION (EMMA3_BHIF_BASE + EMMA3_BHIF_GENERATION_OFF) + #define EMMA3_BHIF_STRAP0_OFF 0x0010 + #define EMMA3_BHIF_STRAP0 (EMMA3_BHIF_BASE + EMMA3_BHIF_STRAP0_OFF) + #define EMMA3_BHIF_STRAP_WRITE0_OFF 0x0020 + #define EMMA3_BHIF_STRAP_WRITE0 (EMMA3_BHIF_BASE + EMMA3_BHIF_STRAP_WRITE0_OFF) + #define EMMA3_BHIF_ALTERNATE0_OFF 0x0028 + #define EMMA3_BHIF_ALTERNATE0 (EMMA3_BHIF_BASE + EMMA3_BHIF_ALTERNATE0_OFF) + #define EMMA3_BHIF_ALTERNATE1_OFF 0x0018 + #define EMMA3_BHIF_ALTERNATE1 (EMMA3_BHIF_BASE + EMMA3_BHIF_ALTERNATE0_OFF) + #define EMMA3_BHIF_AVSWITCH_OFF 0x002c + #define EMMA3_BHIF_AVSWITCH (EMMA3_BHIF_BASE + EMMA3_BHIF_AVSWITCH_OFF) + + #define EMMA3_BHIF_MAIN_INT_ST0_OFF 0x0030 + #define EMMA3_BHIF_MAIN_INT_ST0 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT_ST0_OFF) + #define EMMA3_BHIF_MAIN_INT_ST1_OFF 0x0034 + #define EMMA3_BHIF_MAIN_INT_ST1 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT_ST1_OFF) + #define EMMA3_BHIF_MAIN_INT_ST2_OFF 0x0038 + #define EMMA3_BHIF_MAIN_INT_ST2 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT_ST2_OFF) + #define EMMA3_BHIF_MAIN_INT0_EN0_OFF 0x0040 + #define EMMA3_BHIF_MAIN_INT0_EN0 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT0_EN0_OFF) + #define EMMA3_BHIF_MAIN_INT0_EN1_OFF 0x0044 + #define EMMA3_BHIF_MAIN_INT0_EN1 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT0_EN1_OFF) + #define EMMA3_BHIF_MAIN_INT0_EN2_OFF 0x0048 + #define EMMA3_BHIF_MAIN_INT0_EN2 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT0_EN2_OFF) + #define EMMA3_BHIF_MAIN_INT1_EN0_OFF 0x0050 + #define EMMA3_BHIF_MAIN_INT1_EN0 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT1_EN0_OFF) + #define EMMA3_BHIF_MAIN_INT1_EN1_OFF 0x0054 + #define EMMA3_BHIF_MAIN_INT1_EN1 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT1_EN1_OFF) + #define EMMA3_BHIF_MAIN_INT1_EN2_OFF 0x0058 + #define EMMA3_BHIF_MAIN_INT1_EN2 (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_INT1_EN2_OFF) + #define EMMA3_BHIF_NMI_ST_OFF 0x0060 + #define EMMA3_BHIF_NMI_ST (EMMA3_BHIF_BASE + EMMA3_BHIF_NMI_ST_OFF) + #define EMMA3_BHIF_NMI_EN_OFF 0x0064 + #define EMMA3_BHIF_NMI_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_NMI_EN_OFF) + + #define EMMA3_BHIF_MAIN_RESET_OFF 0x00b0 + #define EMMA3_BHIF_MAIN_RESET (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_RESET_OFF) + #define EMMA3_BHIF_MAIN_CTRL_OFF 0x00b4 + #define EMMA3_BHIF_MAIN_CTRL (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_CTRL_OFF) + #define EMMA3_BHIF_MAIN_EXPVEC_BADDR_OFF 0x00c0 + #define EMMA3_BHIF_MAIN_EXPVEC_BADDR (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_EXPVEC_BADDR_OFF) + #define EMMA3_BHIF_MAIN_OFFSET_ADDRESS_OFF 0x00c4 + #define EMMA3_BHIF_MAIN_OFFSET_ADDRESS (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_OFFSET_ADDRESS_OFF) + + #define EMMA3_BHIF_SUB_INT_ST0_OFF 0x0100 + #define EMMA3_BHIF_SUB_INT_ST0 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT_ST0_OFF) + #define EMMA3_BHIF_SUB_INT_ST1_OFF 0x0104 + #define EMMA3_BHIF_SUB_INT_ST1 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT_ST1_OFF) + #define EMMA3_BHIF_SUB_INT_ST2_OFF 0x0108 + #define EMMA3_BHIF_SUB_INT_ST2 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT_ST2_OFF) + #define EMMA3_BHIF_SUB_INT0_EN0_OFF 0x0110 + #define EMMA3_BHIF_SUB_INT0_EN0 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT0_EN0_OFF) + #define EMMA3_BHIF_SUB_INT0_EN1_OFF 0x0114 + #define EMMA3_BHIF_SUB_INT0_EN1 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT0_EN1_OFF) + #define EMMA3_BHIF_SUB_INT0_EN2_OFF 0x0118 + #define EMMA3_BHIF_SUB_INT0_EN2 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT0_EN2_OFF) + #define EMMA3_BHIF_SUB_INT1_EN0_OFF 0x0120 + #define EMMA3_BHIF_SUB_INT1_EN0 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT1_EN0_OFF) + #define EMMA3_BHIF_SUB_INT1_EN1_OFF 0x0124 + #define EMMA3_BHIF_SUB_INT1_EN1 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT1_EN1_OFF) + #define EMMA3_BHIF_SUB_INT1_EN2_OFF 0x0128 + #define EMMA3_BHIF_SUB_INT1_EN2 (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_INT1_EN2_OFF) + #define EMMA3_BHIF_SUB_NMI_ST_OFF 0x0130 + #define EMMA3_BHIF_SUB_NMI_ST (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_NMI_ST_OFF) + #define EMMA3_BHIF_SUB_NMI_EN_OFF 0x0134 + #define EMMA3_BHIF_SUB_NMI_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_NMI_EN_OFF) + #define EMMA3_BHIF_SUB_RESET_OFF 0x0180 + #define EMMA3_BHIF_SUB_RESET (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_RESET_OFF) + #define EMMA3_BHIF_SUB_CTRL_OFF 0x0184 + #define EMMA3_BHIF_SUB_CTRL (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_CTRL_OFF) + #define EMMA3_BHIF_SUB_EXPVEC_BADDR_OFF 0x0190 + #define EMMA3_BHIF_SUB_EXPVEC_BADDR (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_EXPVEC_BADDR_OFF) + + #define EMMA3_BHIF_AUD0_INT_ST_0_OFF 0x200 + #define EMMA3_BHIF_AUD0_INT_ST_0 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_INT_ST_0_OFF) + #define EMMA3_BHIF_AUD0_INT_ST_1_OFF 0x204 + #define EMMA3_BHIF_AUD0_INT_ST_1 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_INT_ST_1_OFF) + #define EMMA3_BHIF_AUD0_INT_ST_2_OFF 0x208 + #define EMMA3_BHIF_AUD0_INT_ST_2 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_INT_ST_2_OFF) + #define EMMA3_BHIF_AUD0_INT0_EN_0_OFF 0x210 + #define EMMA3_BHIF_AUD0_INT0_EN_0 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_INT0_EN_0_OFF) + #define EMMA3_BHIF_AUD0_INT0_EN_1_OFF 0x214 + #define EMMA3_BHIF_AUD0_INT0_EN_1 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_INT0_EN_1_OFF) + #define EMMA3_BHIF_AUD0_INT0_EN_2_OFF 0x218 + #define EMMA3_BHIF_AUD0_INT0_EN_2 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_INT0_EN_2_OFF) + #define EMMA3_BHIF_AUD0_RESET_OFF 0x280 + #define EMMA3_BHIF_AUD0_RESET (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_RESET_OFF) + #define EMMA3_BHIF_AUD0_CTRL_OFF 0x284 + #define EMMA3_BHIF_AUD0_CTRL (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_CTRL_OFF) + #define EMMA3_BHIF_AUD0_EXCEPT_VECT_BADDR_OFF 0x290 + #define EMMA3_BHIF_AUD0_EXCEPT_VECT_BADDR (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_EXCEPT_VECT_BASE_ADDRESS_OFF) + #define EMMA3_BHIF_AUD1_INT_ST_0_OFF 0x2a0 + #define EMMA3_BHIF_AUD1_INT_ST_0 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_INT_ST_0_OFF) + #define EMMA3_BHIF_AUD1_INT_ST_1_OFF 0x2a4 + #define EMMA3_BHIF_AUD1_INT_ST_1 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_INT_ST_1_OFF) + #define EMMA3_BHIF_AUD1_INT_ST_2_OFF 0x2a8 + #define EMMA3_BHIF_AUD1_INT_ST_2 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_INT_ST_2_OFF) + #define EMMA3_BHIF_AUD1_INT0_EN_0_OFF 0x2c0 + #define EMMA3_BHIF_AUD1_INT0_EN_0 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_INT0_EN_0_OFF) + #define EMMA3_BHIF_AUD1_INT0_EN_1_OFF 0x2c4 + #define EMMA3_BHIF_AUD1_INT0_EN_1 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_INT0_EN_1_OFF) + #define EMMA3_BHIF_AUD1_INT0_EN_2_OFF 0x2c8 + #define EMMA3_BHIF_AUD1_INT0_EN_2 (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_INT0_EN_2_OFF) + #define EMMA3_BHIF_AUD1_RESET_OFF 0x2f0 + #define EMMA3_BHIF_AUD1_RESET (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_RESET_OFF) + #define EMMA3_BHIF_AUD1_CTRL_OFF 0x2f4 + #define EMMA3_BHIF_AUD1_CTRL (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_CTRL_OFF) + #define EMMA3_BHIF_AUD1_EXCEPT_VECT_BADDR_OFF 0x2f8 + #define EMMA3_BHIF_AUD1_EXCEPT_VECT_BADDRESS (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_EXCEPT_VECT_BASE_ADDRESS_OFF) + #define EMMA3_BHIF_EXT_INT_EN_0_OFF 0x2b0 + #define EMMA3_BHIF_EXT_INT_EN_0 (EMMA3_BHIF_BASE + EMMA3_BHIF_EXT_INT_EN_0_OFF) + #define EMMA3_BHIF_EXT_INT_EN_1_OFF 0x2b4 + #define EMMA3_BHIF_EXT_INT_EN_1 (EMMA3_BHIF_BASE + EMMA3_BHIF_EXT_INT_EN_1_OFF) + #define EMMA3_BHIF_EXT_INT_EN_2_OFF 0x2b8 + #define EMMA3_BHIF_EXT_INT_EN_2 (EMMA3_BHIF_BASE + EMMA3_BHIF_EXT_INT_EN_2_OFF) + + #define EMMA3_BHIF_SW_INT0_OFF 0x0070 + #define EMMA3_BHIF_SW_INT0 (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT0_OFF) + #define EMMA3_BHIF_SW_INT0_EN_OFF 0x0080 + #define EMMA3_BHIF_SW_INT0_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT0_EN_OFF) + #define EMMA3_BHIF_SW_INT0_CLR_OFF 0x0090 + #define EMMA3_BHIF_SW_INT0_CLR (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT0_CLR_OFF) + #define EMMA3_BHIF_SW_INT0_MSG_OFF 0x00a0 + #define EMMA3_BHIF_SW_INT0_MSG (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT0_MSG_OFF) + + #define EMMA3_BHIF_SW_INT1_OFF 0x0140 + #define EMMA3_BHIF_SW_INT1 (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT1_OFF) + #define EMMA3_BHIF_SW_INT1_EN_OFF 0x0150 + #define EMMA3_BHIF_SW_INT1_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT1_EN_OFF) + #define EMMA3_BHIF_SW_INT1_CLR_OFF 0x0160 + #define EMMA3_BHIF_SW_INT1_CLR (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT1_CLR_OFF) + #define EMMA3_BHIF_SW_INT1_MSG_OFF 0x0170 + #define EMMA3_BHIF_SW_INT1_MSG (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT1_MSG_OFF) + + #define EMMA3_BHIF_SW_INT2_OFF 0x0240 + #define EMMA3_BHIF_SW_INT2 (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT2_OFF) + #define EMMA3_BHIF_SW_INT2_EN_OFF 0x0250 + #define EMMA3_BHIF_SW_INT2_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT2_EN_OFF) + #define EMMA3_BHIF_SW_INT2_CLR_OFF 0x0260 + #define EMMA3_BHIF_SW_INT2_CLR (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT2_CLR_OFF) + #define EMMA3_BHIF_SW_INT2_MSG_OFF 0x0270 + #define EMMA3_BHIF_SW_INT2_MSG (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT2_MSG_OFF) + + #define EMMA3_BHIF_SW_INT3_OFF 0x03c0 + #define EMMA3_BHIF_SW_INT3 (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT3_OFF) + #define EMMA3_BHIF_SW_INT3_EN_OFF 0x03c4 + #define EMMA3_BHIF_SW_INT3_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT3_EN_OFF) + #define EMMA3_BHIF_SW_INT3_CLR_OFF 0x03c8 + #define EMMA3_BHIF_SW_INT3_CLR (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT3_CLR_OFF) + #define EMMA3_BHIF_SW_INT3_MSG_OFF 0x03cc + #define EMMA3_BHIF_SW_INT3_MSG (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT3_MSG_OFF) + + #define EMMA3_BHIF_SW_INT4_OFF 0x03d0 + #define EMMA3_BHIF_SW_INT4 (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT4_OFF) + #define EMMA3_BHIF_SW_INT4_EN_OFF 0x03d4 + #define EMMA3_BHIF_SW_INT4_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT4_EN_OFF) + #define EMMA3_BHIF_SW_INT4_CLR_OFF 0x03d8 + #define EMMA3_BHIF_SW_INT4_CLR (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT4_CLR_OFF) + #define EMMA3_BHIF_SW_INT4_MSG_OFF 0x03dc + #define EMMA3_BHIF_SW_INT4_MSG (EMMA3_BHIF_BASE + EMMA3_BHIF_SW_INT4_MSG_OFF) + + #define EMMA3_BHIF_BERR_CTRL_OFF 0x0310 + #define EMMA3_BHIF_BERR_CTRL (EMMA3_BHIF_BASE + EMMA3_BHIF_BERR_CTRL_OFF) + #define EMMA3_BHIF_BERR_STATUS_OFF 0x0314 + #define EMMA3_BHIF_BERR_STATUS (EMMA3_BHIF_BASE + EMMA3_BHIF_BERR_STATUS_OFF) + #define EMMA3_BHIF_BERR_TARGET0_OFF 0x0318 + #define EMMA3_BHIF_BERR_TARGET0 (EMMA3_BHIF_BASE + EMMA3_BHIF_BERR_TARGET0_OFF) + #define EMMA3_BHIF_BERR_TARGET1_OFF 0x031c + #define EMMA3_BHIF_BERR_TARGET1 (EMMA3_BHIF_BASE + EMMA3_BHIF_BERR_TARGET1_OFF) + #define EMMA3_BHIF_BERR_ADDR0_OFF 0x0320 + #define EMMA3_BHIF_BERR_ADDR0 (EMMA3_BHIF_BASE + EMMA3_BHIF_BERR_ADDR0_OFF) + #define EMMA3_BHIF_BERR_ADDR1_OFF 0x0324 + #define EMMA3_BHIF_BERR_ADDR1 (EMMA3_BHIF_BASE + EMMA3_BHIF_BERR_ADDR1_OFF) + #define EMMA3_BHIF_BERR_OCPY_TIME_OFF 0x0328 + #define EMMA3_BHIF_BERR_OCPY_TIME (EMMA3_BHIF_BASE + EMMA3_BHIF_BERR_OCPY_TIME_OFF) + #define EMMA3_BHIF_BERR_OCPY_EN_OFF 0x032c + #define EMMA3_BHIF_BERR_OCPY_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_BERR_OCPY_EN_OFF) + + #define EMMA3_PREFETCH_CTRL_MAIN_CPU_OFF 0x0360 + #define EMMA3_PREFETCH_CTRL_MAIN_CPU (EMMA3_BHIF_BASE + EMMA3_PREFETCH_CTRL_MAIN_CPU_OFF) + #define EMMA3_PREFETCH_ADDR_MAIN_CPU_OFF 0x0364 + #define EMMA3_PREFETCH_ADDR_MAIN_CPU (EMMA3_BHIF_BASE + EMMA3_PREFETCH_ADDR_MAIN_CPU_OFF) + #define EMMA3_SWAP_CTRL_MAIN_CPU_OFF 0x0348 + #define EMMA3_SWAP_CTRL_MAIN_CPU (EMMA3_BHIF_BASE + EMMA3_SWAP_CTRL_MAIN_CPU_OFF) + #define EMMA3_PREFETCH_CTRL_SUB_CPU_OFF 0x0370 + #define EMMA3_PREFETCH_CTRL_SUB_CPU (EMMA3_BHIF_BASE + EMMA3_PREFETCH_CTRL_SUB_CPU_OFF) + #define EMMA3_PREFETCH_ADDR_SUB_CPU_OFF 0x0374 + #define EMMA3_PREFETCH_ADDR_SUB_CPU (EMMA3_BHIF_BASE + EMMA3_PREFETCH_ADDR_SUB_CPU_OFF) + #define EMMA3_SWAP_CTRL_SUB_CPU_OFF 0x0378 + #define EMMA3_SWAP_CTRL_SUB_CPU (EMMA3_BHIF_BASE + EMMA3_SWAP_CTRL_SUB_CPU_OFF) + #define EMMA3_PREFETCH_CTRL_AUD0_CPU_OFF 0x0380 + #define EMMA3_PREFETCH_CTRL_AUD0_CPU (EMMA3_BHIF_BASE + EMMA3_PREFETCH_CTRL_AUD0_CPU_OFF) + #define EMMA3_PREFETCH_ADDR_AUD0_CPU_OFF 0x0384 + #define EMMA3_PREFETCH_ADDR_AUD0_CPU (EMMA3_BHIF_BASE + EMMA3_PREFETCH_ADDR_AUD0_CPU_OFF) + #define EMMA3_SWAP_CTRL_AUD0_CPU_OFF 0x0388 + #define EMMA3_SWAP_CTRL_AUD0_CPU (EMMA3_BHIF_BASE + EMMA3_SWAP_CTRL_AUD0_CPU_OFF) + #define EMMA3_PREFETCH_CTRL_AUD1_CPU_OFF 0x0390 + #define EMMA3_PREFETCH_CTRL_AUD1_CPU (EMMA3_BHIF_BASE + EMMA3_PREFETCH_CTRL_AUD1_CPU_OFF) + #define EMMA3_PREFETCH_ADDR_AUD1_CPU_OFF 0x0394 + #define EMMA3_PREFETCH_ADDR_AUD1_CPU (EMMA3_BHIF_BASE + EMMA3_PREFETCH_ADDR_AUD1_CPU_OFF) + #define EMMA3_SWAP_CTRL_AUD1_CPU_OFF 0x0398 + #define EMMA3_SWAP_CTRL_AUD1_CPU (EMMA3_BHIF_BASE + EMMA3_SWAP_CTRL_AUD1_CPU_OFF) + + #define EMMA3_BHIF_MAIN_PADR_EN_OFF 0x0d0 + #define EMMA3_BHIF_MAIN_PADR_EN (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR_EN_OFF) + #define EMMA3_BHIF_MAIN_PADR0_MASK_OFF 0x0d4 + #define EMMA3_BHIF_MAIN_PADR0_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR0_MASK_OFF) + #define EMMA3_BHIF_MAIN_PADR0_TARGET_OFF 0x0d8 + #define EMMA3_BHIF_MAIN_PADR0_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR0_TARGET_OFF) + #define EMMA3_BHIF_MAIN_PADR1_BASE_OFF 0x0e0 + #define EMMA3_BHIF_MAIN_PADR1_BASE (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR1_BASE_OFF) + #define EMMA3_BHIF_MAIN_PADR1_MASK_OFF 0x0e4 + #define EMMA3_BHIF_MAIN_PADR1_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR1_MASK_OFF) + #define EMMA3_BHIF_MAIN_PADR1_TARGET_OFF 0x0e8 + #define EMMA3_BHIF_MAIN_PADR1_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR1_TARGET_OFF) + #define EMMA3_BHIF_MAIN_PADR2_BASE_OFF 0x0f0 + #define EMMA3_BHIF_MAIN_PADR2_BASE (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR2_BASE_OFF) + #define EMMA3_BHIF_MAIN_PADR2_MASK_OFF 0x0f4 + #define EMMA3_BHIF_MAIN_PADR2_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR2_MASK_OFF) + #define EMMA3_BHIF_MAIN_PADR2_TARGET_OFF 0x0f8 + #define EMMA3_BHIF_MAIN_PADR2_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_MAIN_PADR2_TARGET_OFF) + + #define EMMA3_BHIF_SUB_PADR_ENABLE_OFF 0x1a0 + #define EMMA3_BHIF_SUB_PADR_ENABLE (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR_ENABLE_OFF) + #define EMMA3_BHIF_SUB_PADR0_MASK_OFF 0x1a4 + #define EMMA3_BHIF_SUB_PADR0_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR0_MASK_OFF) + #define EMMA3_BHIF_SUB_PADR0_TARGET_OFF 0x1a8 + #define EMMA3_BHIF_SUB_PADR0_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR0_TARGET_OFF) + #define EMMA3_BHIF_SUB_PADR1_BASE_OFF 0x1b0 + #define EMMA3_BHIF_SUB_PADR1_BASE (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR1_BASE_OFF) + #define EMMA3_BHIF_SUB_PADR1_MASK_OFF 0x1b4 + #define EMMA3_BHIF_SUB_PADR1_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR1_MASK_OFF) + #define EMMA3_BHIF_SUB_PADR1_TARGET_OFF 0x1b8 + #define EMMA3_BHIF_SUB_PADR1_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR1_TARGET_OFF) + #define EMMA3_BHIF_SUB_PADR2_BASE_OFF 0x300 + #define EMMA3_BHIF_SUB_PADR2_BASE (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR2_BASE_OFF) + #define EMMA3_BHIF_SUB_PADR2_MASK_OFF 0x304 + #define EMMA3_BHIF_SUB_PADR2_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR2_MASK_OFF) + #define EMMA3_BHIF_SUB_PADR2_TARGET_OFF 0x308 + #define EMMA3_BHIF_SUB_PADR2_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_SUB_PADR2_TARGET_OFF) + + #define EMMA3_BHIF_AUD0_PADR_ENABLE_OFF 0x1c0 + #define EMMA3_BHIF_AUD0_PADR_ENABLE (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_PADR_ENABLE_OFF) + #define EMMA3_BHIF_AUD0_PADR0_MASK_OFF 0x1c4 + #define EMMA3_BHIF_AUD0_PADR0_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_PADR0_MASK_OFF) + #define EMMA3_BHIF_AUD0_PADR0_TARGET_OFF 0x1c8 + #define EMMA3_BHIF_AUD0_PADR0_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_PADR0_TARGET_OFF) + #define EMMA3_BHIF_AUD0_PADR1_BASE_OFF 0x1d0 + #define EMMA3_BHIF_AUD0_PADR1_BASE (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_PADR1_BASE_OFF) + #define EMMA3_BHIF_AUD0_PADR1_MASK_OFF 0x1d4 + #define EMMA3_BHIF_AUD0_PADR1_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_PADR1_MASK_OFF) + #define EMMA3_BHIF_AUD0_PADR1_TARGET_OFF 0x1d8 + #define EMMA3_BHIF_AUD0_PADR1_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD0_PADR1_TARGET_OFF) + + #define EMMA3_BHIF_AUD1_PADR_ENABLE_OFF 0x1e0 + #define EMMA3_BHIF_AUD1_PADR_ENABLE (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_PADR_ENABLE_OFF) + #define EMMA3_BHIF_AUD1_PADR0_MASK_OFF 0x1e4 + #define EMMA3_BHIF_AUD1_PADR0_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_PADR0_MASK_OFF) + #define EMMA3_BHIF_AUD1_PADR0_TARGET_OFF 0x1e8 + #define EMMA3_BHIF_AUD1_PADR0_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_PADR0_TARGET_OFF) + #define EMMA3_BHIF_AUD1_PADR1_BASE_OFF 0x1f0 + #define EMMA3_BHIF_AUD1_PADR1_BASE (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_PADR1_BASE_OFF) + #define EMMA3_BHIF_AUD1_PADR1_MASK_OFF 0x1f4 + #define EMMA3_BHIF_AUD1_PADR1_MASK (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_PADR1_MASK_OFF) + #define EMMA3_BHIF_AUD1_PADR1_TARGET_OFF 0x1f8 + #define EMMA3_BHIF_AUD1_PADR1_TARGET (EMMA3_BHIF_BASE + EMMA3_BHIF_AUD1_PADR1_TARGET_OFF) + + #define EMMA3_BHIF_AREA_CTRL_MAIN_CPU_OFF 0x220 + #define EMMA3_BHIF_AREA_CTRL_MAIN_CPU (EMMA3_BHIF_BASE + EMMA3_BHIF_AREA_CTRL_MAIN_CPU_OFF) + #define EMMA3_BHIF_AREA_CTRL_SUB_CPU_OFF 0x224 + #define EMMA3_BHIF_AREA_CTRL_SUB_CPU (EMMA3_BHIF_BASE + EMMA3_BHIF_AREA_CTRL_SUB_CPU_OFF) + #define EMMA3_BHIF_AREA_CTRL_AUD0_CPU_OFF 0x228 + #define EMMA3_BHIF_AREA_CTRL_AUD0_CPU (EMMA3_BHIF_BASE + EMMA3_BHIF_AREA_CTRL_AUD0_CPU_OFF) + #define EMMA3_BHIF_AREA_CTRL_AUD1_CPU_OFF 0x22c + #define EMMA3_BHIF_AREA_CTRL_AUD1_CPU (EMMA3_BHIF_BASE + EMMA3_BHIF_AREA_CTRL_AUD1_CPU_OFF) + + + /* + * Interrupt + */ + #define EMMA3_INT0_DMA (1<<0) + #define EMMA3_INT0_BROI (1<<1) + #define EMMA3_INT0_AUDIO0 (1<<2) + #define EMMA3_INT0_AUDIO1 (1<<3) + #define EMMA3_INT0_VIDEO (1<<4) + #define EMMA3_INT0_NAVC (1<<5) + #define EMMA3_INT0_SW0 (1<<6) + #define EMMA3_INT0_SW1 (1<<7) + #define EMMA3_INT0_SW2 (1<<8) + #define EMMA3_INT0_SW3 (1<<9) + #define EMMA3_INT0_SW4 (1<<10) + /* #define EMMA3_INT0_XXXXX (1<<11) */ + #define EMMA3_INT0_DISP0 (1<<12) + #define EMMA3_INT0_DISP1 (1<<13) + #define EMMA3_INT0_DISP2 (1<<14) + #define EMMA3_INT0_BLT0 (1<<15) + #define EMMA3_INT0_BLT1 (1<<16) + #define EMMA3_INT0_MIF0 (1<<17) + #define EMMA3_INT0_MIF1 (1<<18) + #define EMMA3_INT0_FGT00 (1<<19) + #define EMMA3_INT0_FGT01 (1<<20) + #define EMMA3_INT0_FGT10 (1<<21) + #define EMMA3_INT0_FGT11 (1<<22) + + #define EMMA3_INT1_PCI (1<<0) + #define EMMA3_INT1_IDE0 (1<<1) + #define EMMA3_INT1_IDE1 (1<<2) + #define EMMA3_INT1_IPIO (1<<3) + #define EMMA3_INT1_USB (1<<4) + /* #define EMMA3_INT1_XXX (1<<5) */ + #define EMMA3_INT1_VENC (1<<6) + #define EMMA3_INT1_ZTMR0 (1<<7) + #define EMMA3_INT1_ZTMR1 (1<<8) + #define EMMA3_INT1_TRTC (1<<9) + /* #define EMMA3_INT1_XXX (1<<10) */ + /* #define EMMA3_INT1_XXX (1<<11) */ + /* #define EMMA3_INT1_XXX (1<<12) */ + #define EMMA3_INT1_ZIRB (1<<13) + #define EMMA3_INT1_GPIO (1<<14) + /* #define EMMA3_INT1_XXX (1<<15) */ + #define EMMA3_INT1_PFUR0 (1<<16) + #define EMMA3_INT1_PFUR1 (1<<17) + #define EMMA3_INT1_PFUR2 (1<<18) + #define EMMA3_INT1_PIIC0 (1<<19) + #define EMMA3_INT1_PIIC1 (1<<20) + #define EMMA3_INT1_PIIC2 (1<<21) + #define EMMA3_INT1_PSSI0 (1<<22) + #define EMMA3_INT1_PSSI1 (1<<23) + #define EMMA3_INT1_PSSI2 (1<<24) + #define EMMA3_INT1_PSCI00 (1<<25) + #define EMMA3_INT1_PSCI11 (1<<26) + /* #define EMMA3_INT1_XXX (1<<27) */ + /* #define EMMA3_INT1_XXX (1<<28) */ + #define EMMA3_INT1_PPOD (1<<29) + #define EMMA3_INT1_GIO (1<<30) + #define EMMA3_INT1_JTAG (1<<31) + + #define EMMA3_INIT2_SP000 (1<<0) + #define EMMA3_INIT2_SP001 (1<<1) + #define EMMA3_INIT2_SP002 (1<<2) + #define EMMA3_INIT2_SP003 (1<<3) + #define EMMA3_INIT2_SP004 (1<<4) + #define EMMA3_INIT2_SP005 (1<<5) + #define EMMA3_INIT2_SP006 (1<<6) + #define EMMA3_INIT2_SP007 (1<<7) + #define EMMA3_INIT2_SP008 (1<<8) + #define EMMA3_INIT2_SP009 (1<<9) + #define EMMA3_INIT2_SP010 (1<<10) + #define EMMA3_INIT2_SP011 (1<<11) + #define EMMA3_INIT2_SP012 (1<<12) + #define EMMA3_INIT2_SP013 (1<<13) + #define EMMA3_INIT2_SP014 (1<<14) + #define EMMA3_INIT2_SP015 (1<<15) + #define EMMA3_INIT2_SP100 (1<<16) + #define EMMA3_INIT2_SP101 (1<<17) + #define EMMA3_INIT2_SP102 (1<<18) + #define EMMA3_INIT2_SP103 (1<<19) + #define EMMA3_INIT2_SP104 (1<<20) + #define EMMA3_INIT2_SP105 (1<<21) + #define EMMA3_INIT2_SP106 (1<<22) + #define EMMA3_INIT2_SP107 (1<<23) + #define EMMA3_INIT2_SP108 (1<<24) + #define EMMA3_INIT2_SP109 (1<<25) + #define EMMA3_INIT2_SP110 (1<<26) + #define EMMA3_INIT2_SP111 (1<<27) + #define EMMA3_INIT2_SP112 (1<<28) + #define EMMA3_INIT2_SP113 (1<<29) + #define EMMA3_INIT2_SP114 (1<<30) + #define EMMA3_INIT2_SP115 (1<<31) + + /* + * PCI Configuration + */ + #define EMMA3_PCI_DEVICE_ID_OFF 0x0000 + #define EMMA3_PCI_COM_STAT_OFF 0x0004 + #define EMMA3_PCI_REV_CLASS_OFF 0x0008 + #define EMMA3_PCI_MISC0_OFF 0x000c + #define EMMA3_PCI_BASE1_ADR_OFF 0x0010 + #define EMMA3_PCI_BASE2_ADR_OFF 0x0014 + #define EMMA3_PCI_SUBSYS_ID_OFF 0x002c + #define EMMA3_PCI_EXROMADR_ID_OFF 0x0030 + #define EMMA3_PCI_EXT0_OFF 0x0034 + #define EMMA3_PCI_MISC1_OFF 0x003c + #define EMMA3_PCI_PM0_OFF 0x0040 + #define EMMA3_PCI_PM1_OFF 0x0044 + + /* + * PCI Communication + */ + #define EMMA3_PCI_CONTROL_OFF 0x0000 + #define EMMA3_PCI_CONTROL (EMMA3_PCI_COMM_BASE + EMMA3_PCI_CONTROL_OFF) + #define EMMA3_PCI_ARBIT_CTR_OFF 0x0004 + #define EMMA3_PCI_ARBIT_CTR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_ARBIT_CTR_OFF) + #define EMMA3_PCI_ERROR_OFF 0x0008 + #define EMMA3_PCI_ERROR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_ERROR_OFF) + #define EMMA3_PCI_BUS_STA_OFF 0x000c + #define EMMA3_PCI_BUS_STA (EMMA3_PCI_COMM_BASE + EMMA3_PCI_BUS_STA_OFF) + #define EMMA3_PCI_IWIN0_CTR_OFF 0x0010 + #define EMMA3_PCI_IWIN0_CTR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_IWIN0_CTR_OFF) + #define EMMA3_PCI_IWIN1_CTR_OFF 0x0014 + #define EMMA3_PCI_IWIN1_CTR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_IWIN1_CTR_OFF) + #define EMMA3_PCI_INIT_ESWP_OFF 0x0018 + #define EMMA3_PCI_INIT_ESWP (EMMA3_PCI_COMM_BASE + EMMA3_PCI_INIT_ESWP_OFF) + + #define EMMA3_PCI_INT_OFF 0x0020 + #define EMMA3_PCI_INT (EMMA3_PCI_COMM_BASE + EMMA3_PCI_INT_OFF) + #define EMMA3_PCI_INT_EN_OFF 0x0024 + #define EMMA3_PCI_INT_EN (EMMA3_PCI_COMM_BASE + EMMA3_PCI_INT_EN_OFF) + #define EMMA3_PCI_INT_PCIDMA1 (1 << 0) + #define EMMA3_PCI_INT_PCIDMA2 (1 << 1) + #define EMMA3_PCI_INT_SIGTABORT (1 << 8) + #define EMMA3_PCI_INT_RTABORT (1 << 9) + #define EMMA3_PCI_INT_RMABORT (1 << 10) + #define EMMA3_PCI_INT_MDPERR (1 << 12) + #define EMMA3_PCI_INT_DETPERR (1 << 13) + #define EMMA3_PCI_INT_SIGSERR (1 << 14) + #define EMMA3_PCI_INT_RSERR (1 << 15) + #define EMMA3_PCI_INT_PSCHG (1 << 20) + + #define EMMA3_PCI_TWIN_CTR_OFF 0x0030 + #define EMMA3_PCI_TWIN_CTR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_TWIN_CTR_OFF) + #define EMMA3_PCI_TWIN_BADR_OFF 0x0034 + #define EMMA3_PCI_TWIN_BADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_TWIN_BADR_OFF) + #define EMMA3_PCI_TWIN0_DADDR_OFF 0x0038 + #define EMMA3_PCI_TWIN0_DADDR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_TWIN0_DADDR_OFF) + #define EMMA3_PCI_TWIN1_DADDR_OFF 0x003c + #define EMMA3_PCI_TWIN1_DADDR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_TWIN1_DADDR_OFF) + #define EMMA3_PCI_DMA1_PSADR_OFF 0x0040 + #define EMMA3_PCI_DMA1_PSADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA1_PSADR_OFF) + #define EMMA3_PCI_DMA1_MSADR_OFF 0x0044 + #define EMMA3_PCI_DMA1_MSADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA1_MSADR_OFF) + #define EMMA3_PCI_DMA1_MEADR_OFF 0x0048 + #define EMMA3_PCI_DMA1_MEADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA1_MEADR_OFF) + #define EMMA3_PCI_DMA1_LPADR_OFF 0x004c + #define EMMA3_PCI_DMA1_LPADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA1_LPADR_OFF) + #define EMMA3_PCI_DMA1_CTR_OFF 0x0050 + #define EMMA3_PCI_DMA1_CTR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA1_CTR_OFF) + #define EMMA3_PCI_DMA1_STA_OFF 0x0054 + #define EMMA3_PCI_DMA1_STA (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA1_STA_OFF) + #define EMMA3_PCI_DMA2_PSADR_OFF 0x0060 + #define EMMA3_PCI_DMA2_PSADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA2_PSADR_OFF) + #define EMMA3_PCI_DMA2_MSADR_OFF 0x0064 + #define EMMA3_PCI_DMA2_MSADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA2_MSADR_OFF) + #define EMMA3_PCI_DMA2_MEADR_OFF 0x0068 + #define EMMA3_PCI_DMA2_MEADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA2_MEADR_OFF) + #define EMMA3_PCI_DMA2_LPADR_OFF 0x006c + #define EMMA3_PCI_DMA2_LPADR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA2_LPADR_OFF) + #define EMMA3_PCI_DMA2_CTR_OFF 0x0070 + #define EMMA3_PCI_DMA2_CTR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA2_CTR_OFF) + #define EMMA3_PCI_DMA2_STA_OFF 0x0074 + #define EMMA3_PCI_DMA2_STA (EMMA3_PCI_COMM_BASE + EMMA3_PCI_DMA2_STA_OFF) + #define EMMA3_PCI_PWR_STA_OFF 0x0080 + #define EMMA3_PCI_PWR_STA (EMMA3_PCI_COMM_BASE + EMMA3_PCI_PWR_STA_OFF) + #define EMMA3_PCI_PME_CTR_OFF 0x0084 + #define EMMA3_PCI_PME_CTR (EMMA3_PCI_COMM_BASE + EMMA3_PCI_PME_CTR_OFF) + #define EMMA3_PCI_SUBSYSID_OFF 0x0088 + #define EMMA3_PCI_SUBSYSID (EMMA3_PCI_COMM_BASE + EMMA3_PCI_SUBSYSID_OFF) + + /* + * GPIO 0 + */ + #define EMMA3_ZPIO0_DIR_OFF 0x00c0 + #define EMMA3_ZPIO0_DIR (EMMA3_GPIO0_BASE + EMMA3_ZPIO0_DIR_OFF) + #define EMMA3_ZPIO0_INT_OFF 0x00c8 + #define EMMA3_ZPIO0_INT (EMMA3_GPIO0_BASE + EMMA3_ZPIO0_INT_OFF) + #define EMMA3_ZPIO0_INT_CPUMEN_OFF 0x00d0 + #define EMMA3_ZPIO0_INT_CPUMEN (EMMA3_GPIO0_BASE + EMMA3_ZPIO0_INT_CPUMEN_OFF) + #define EMMA3_ZPIO0_INT_CPUSEN_OFF 0x00d8 + #define EMMA3_ZPIO0_INT_CPUSEN (EMMA3_GPIO0_BASE + EMMA3_ZPIO0_INT_CPUSEN_OFF) + #define EMMA3_ZPIO0_INT_MODE_OFF 0x00e0 + #define EMMA3_ZPIO0_INT_MODE (EMMA3_GPIO0_BASE + EMMA3_ZPIO0_INT_MODE_OFF) + #define EMMA3_ZPIO0_INT_CNDA_OFF 0x00e8 + #define EMMA3_ZPIO0_INT_CNDA (EMMA3_GPIO0_BASE + EMMA3_ZPIO0_INT_CNDA_OFF) + #define EMMA3_ZPIO0_INT_CNDB_OFF 0x00f0 + #define EMMA3_ZPIO0_INT_CNDB (EMMA3_GPIO0_BASE + EMMA3_ZPIO0_INT_CNDB_OFF) + + #define EMMA3_GPIO0_DATAn(n) (EMMA3_GPIO0_BASE + (n << 2)) + + /* + * GPIO 1 + */ + #define EMMA3_ZPIO1_DIR_OFF 0x00c0 + #define EMMA3_ZPIO1_DIR (EMMA3_GPIO1_BASE + EMMA3_ZPIO1_DIR_OFF) + #define EMMA3_ZPIO1_INT_OFF 0x00c8 + #define EMMA3_ZPIO1_INT (EMMA3_GPIO1_BASE + EMMA3_ZPIO1_INT_OFF) + #define EMMA3_ZPIO1_INT_CPUMEN_OFF 0x00d0 + #define EMMA3_ZPIO1_INT_CPUMEN (EMMA3_GPIO1_BASE + EMMA3_ZPIO1_INT_CPUMEN_OFF) + #define EMMA3_ZPIO1_INT_CPUSEN_OFF 0x00d8 + #define EMMA3_ZPIO1_INT_CPUSEN (EMMA3_GPIO1_BASE + EMMA3_ZPIO1_INT_CPUSEN_OFF) + #define EMMA3_ZPIO1_INT_MODE_OFF 0x00e0 + #define EMMA3_ZPIO1_INT_MODE (EMMA3_GPIO1_BASE + EMMA3_ZPIO1_INT_MODE_OFF) + #define EMMA3_ZPIO1_INT_CNDA_OFF 0x00e8 + #define EMMA3_ZPIO1_INT_CNDA (EMMA3_GPIO1_BASE + EMMA3_ZPIO1_INT_CNDA_OFF) + #define EMMA3_ZPIO1_INT_CNDB_OFF 0x00f0 + #define EMMA3_ZPIO1_INT_CNDB (EMMA3_GPIO1_BASE + EMMA3_ZPIO1_INT_CNDB_OFF) + + #define EMMA3_GPIO1_DATAn(n) (EMMA3_GPIO1_BASE + (n << 2)) + + #endif /* _EMMA3_REG_H_ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/emma3/pmon.h linux-current/include/asm-mips/emma3/pmon.h *** linux-2.6.10/include/asm-mips/emma3/pmon.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/emma3/pmon.h Mon May 28 16:30:55 2007 *************** *** 0 **** --- 1,62 ---- + /* + * 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. + * + * (C) Copyright TOSHIBA CORPORATION 2005, 2006 + * All Rights Reserved. + * + */ + #ifndef _EMMA3_PMON_H_ + #define _EMMA3_PMON_H_ + + #include + + struct pmon_vector { + int (*read)(int fd, char *buf, int size); + int (*write)(int fd, char *buf, int size); + int (*open)(char *name, int mode); + int (*close)(int fd); + int (*ioctl)(int fd, int request, void* arg); + int (*printf)(char *fmstr, ...); + int (*vsprintf)(char *dst, char *fmtstr, ...); + int (*ttctl)(int fd, int op, int ap1, int ap2); + void (*exit)(int status); + char *(*getenv)(char *name); + void (*onintr)(int code, int *dat); + void (*flush_cache)(int cache); + void (*_exception)(void); + int (*_fpstatesz)(void); + void (*_fpinit)(void); + void *(*_fpstate)(void); + void (*cop1)(void); + int (*adr2symoff)(char *dst, int value, int width); + int (*sym2adr)(int *v, char *label); + int (*getclkfreq)(void); + void (*_clkinit)(void); + int (*interpret)(const char *cmd, char *outbuf, int len); + }; + + extern struct pmon_vector *pmon_vector; + + /* from pmonlib.c */ + extern void prom_printf(char *fmt, ...); + /* pmonlib support routine */ + extern void prom_putchar(char c); + + #define pmon_printf prom_printf + + extern void pmon_halt(void) __attribute__((noreturn)); + extern void set_pmon_debug_traps(void) __init; + extern void pmon_breakpoint(void); + + extern char *pmon_getenv(const char *name) __init; + extern int pmon_interpret(const char *cmd, char *outbuf, int len); + + extern unsigned int get_pmon_clkfreq(void) __init; + + + #define PMON_VECTOR_BASE 0x9fc00000 + #define PMON_VECTOR (PMON_VECTOR_BASE + 0x500) + + #endif /* _EMMA3_PMON_H_ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/fixmap.h linux-current/include/asm-mips/fixmap.h *** linux-2.6.10/include/asm-mips/fixmap.h Sat Dec 25 06:34:30 2004 --- linux-current/include/asm-mips/fixmap.h Wed Jun 14 21:12:59 2006 *************** *** 50,55 **** --- 50,60 ---- FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, #endif + #define FIX_N_COLOURS 8 + FIX_CMAP_BEGIN, + FIX_COLOUR_0 = (FIX_CMAP_BEGIN + FIX_N_COLOURS - 1) & ~(FIX_N_COLOURS - 1), + FIX_COLOUR_1 = FIX_COLOUR_0 + (FIX_N_COLOURS * NR_CPUS), + FIX_CMAP_END = FIX_COLOUR_1 + (FIX_N_COLOURS * NR_CPUS) - 1, __end_of_fixed_addresses }; *************** *** 70,76 **** * the start of the fixmap, and leave one page empty * at the top of mem.. */ ! #define FIXADDR_TOP (0xffffe000UL) #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) --- 75,85 ---- * the start of the fixmap, and leave one page empty * at the top of mem.. */ ! #if defined(CONFIG_CPU_TX39XX) || defined(CONFIG_CPU_TX49XX) ! #define FIXADDR_TOP (0xff000000UL - 0x8000) ! #else ! #define FIXADDR_TOP (0xffff8000UL) ! #endif #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) *************** *** 107,110 **** --- 116,126 ---- return __virt_to_fix(vaddr); } + /* + * Called from pgtable_init() + */ + extern void fixrange_init(unsigned long start, unsigned long end, + pgd_t *pgd_base); + + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/fpu.h linux-current/include/asm-mips/fpu.h *** linux-2.6.10/include/asm-mips/fpu.h Sat Dec 25 06:34:31 2004 --- linux-current/include/asm-mips/fpu.h Wed Jun 14 21:12:59 2006 *************** *** 127,134 **** --- 127,136 ---- static inline fpureg_t *get_fpu_regs(struct task_struct *tsk) { if (cpu_has_fpu) { + preempt_disable(); if ((tsk == current) && is_fpu_owner()) _save_fp(current); + preempt_enable(); return tsk->thread.fpu.hard.fpr; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/hazards.h linux-current/include/asm-mips/hazards.h *** linux-2.6.10/include/asm-mips/hazards.h Sat Dec 25 06:35:23 2004 --- linux-current/include/asm-mips/hazards.h Wed Jun 14 21:12:59 2006 *************** *** 16,21 **** --- 16,25 ---- sll $0, $0, 1 .endm + .macro _ehb + sll $0, $0, 3 + .endm + /* * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent * use of the JTLB for instructions should not occur for 4 cpu cycles and use *************** *** 23,39 **** */ #ifdef CONFIG_CPU_RM9000 ! #define mtc0_tlbw_hazard \ ! .set push; \ ! .set mips32; \ ! _ssnop; _ssnop; _ssnop; _ssnop; \ .set pop ! #define tlbw_eret_hazard \ ! .set push; \ ! .set mips32; \ ! _ssnop; _ssnop; _ssnop; _ssnop; \ .set pop #else --- 27,45 ---- */ #ifdef CONFIG_CPU_RM9000 ! .macro mtc0_tlbw_hazard ! .set push ! .set mips32 ! _ssnop; _ssnop; _ssnop; _ssnop .set pop + .endm ! .macro tlbw_eret_hazard ! .set push ! .set mips32 ! _ssnop; _ssnop; _ssnop; _ssnop .set pop + .endm #else *************** *** 43,51 **** * hazard so this is nice trick to have an optimal code for a range of * processors. */ ! #define mtc0_tlbw_hazard \ b . + 8 ! #define tlbw_eret_hazard #endif /* --- 49,60 ---- * hazard so this is nice trick to have an optimal code for a range of * processors. */ ! .macro mtc0_tlbw_hazard b . + 8 ! .endm ! ! .macro tlbw_eret_hazard ! .endm #endif /* *************** *** 58,88 **** /* * Use a macro for ehb unless explicit support for MIPSR2 is enabled */ - .macro ehb - sll $0, $0, 3 - .endm ! #define irq_enable_hazard \ ! ehb # irq_enable_hazard ! #define irq_disable_hazard \ ! ehb # irq_disable_hazard ! #else #define irq_enable_hazard #define irq_disable_hazard #endif #else /* __ASSEMBLY__ */ /* * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent * use of the JTLB for instructions should not occur for 4 cpu cycles and use * for data translations should not occur for 3 cpu cycles. */ - #ifdef CONFIG_CPU_RM9000 #define mtc0_tlbw_hazard() \ __asm__ __volatile__( \ --- 67,117 ---- /* * Use a macro for ehb unless explicit support for MIPSR2 is enabled */ ! #define irq_enable_hazard ! _ehb ! #define irq_disable_hazard ! _ehb ! #elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) ! ! /* ! * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. ! */ #define irq_enable_hazard + #define irq_disable_hazard + #else + + /* + * Classic MIPS needs 1 - 3 nops or ssnops + */ + #define irq_enable_hazard + #define irq_disable_hazard \ + _ssnop; _ssnop; _ssnop + #endif #else /* __ASSEMBLY__ */ + __asm__( + " .macro _ssnop \n\t" + " sll $0, $2, 1 \n\t" + " .endm \n\t" + " \n\t" + " .macro _ehb \n\t" + " sll $0, $0, 3 \n\t" + " .endm \n\t"); + + #ifdef CONFIG_CPU_RM9000 /* * RM9000 hazards. When the JTLB is updated by tlbwi or tlbwr, a subsequent * use of the JTLB for instructions should not occur for 4 cpu cycles and use * for data translations should not occur for 3 cpu cycles. */ #define mtc0_tlbw_hazard() \ __asm__ __volatile__( \ *************** *** 125,151 **** * Use a macro for ehb unless explicit support for MIPSR2 is enabled */ __asm__( - " .macro ehb \n\t" - " sll $0, $0, 3 \n\t" - " .endm \n\t" - " \n\t" " .macro\tirq_enable_hazard \n\t" ! " ehb \n\t" " .endm \n\t" " \n\t" " .macro\tirq_disable_hazard \n\t" ! " ehb \n\t" " .endm"); #define irq_enable_hazard() \ __asm__ __volatile__( \ ! "ehb\t\t\t\t# irq_enable_hazard") #define irq_disable_hazard() \ __asm__ __volatile__( \ ! "ehb\t\t\t\t# irq_disable_hazard") ! #elif defined(CONFIG_CPU_R10000) /* * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. --- 154,176 ---- * Use a macro for ehb unless explicit support for MIPSR2 is enabled */ __asm__( " .macro\tirq_enable_hazard \n\t" ! " _ehb \n\t" " .endm \n\t" " \n\t" " .macro\tirq_disable_hazard \n\t" ! " _ehb \n\t" " .endm"); #define irq_enable_hazard() \ __asm__ __volatile__( \ ! "_ehb\t\t\t\t# irq_enable_hazard") #define irq_disable_hazard() \ __asm__ __volatile__( \ ! "_ehb\t\t\t\t# irq_disable_hazard") ! #elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_RM9000) /* * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. *************** *** 170,179 **** */ __asm__( - " .macro _ssnop \n\t" - " sll $0, $2, 1 \n\t" - " .endm \n\t" - " \n\t" " # \n\t" " # There is a hazard but we do not care \n\t" " # \n\t" --- 195,200 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/interrupt.h linux-current/include/asm-mips/interrupt.h *** linux-2.6.10/include/asm-mips/interrupt.h Sat Dec 25 06:35:40 2004 --- linux-current/include/asm-mips/interrupt.h Wed Jun 14 21:12:59 2006 *************** *** 12,17 **** --- 12,18 ---- #define _ASM_INTERRUPT_H #include + #include __asm__ ( ".macro\tlocal_irq_enable\n\t" *************** *** 47,54 **** --- 48,60 ---- ".set\tpush\n\t" ".set\tnoat\n\t" "mfc0\t$1,$12\n\t" + #if TX49XX_MFC0_WAR && defined(MODULE) + "ori\t$1,3\n\t" + "xori\t$1,3\n\t" + #else "ori\t$1,1\n\t" "xori\t$1,1\n\t" + #endif ".set\tnoreorder\n\t" "mtc0\t$1,$12\n\t" "irq_disable_hazard\n\t" *************** *** 83,90 **** --- 89,101 ---- ".set\treorder\n\t" ".set\tnoat\n\t" "mfc0\t\\result, $12\n\t" + #if TX49XX_MFC0_WAR && defined(MODULE) + "ori\t$1, \\result, 3\n\t" + "xori\t$1, 3\n\t" + #else "ori\t$1, \\result, 1\n\t" "xori\t$1, 1\n\t" + #endif ".set\tnoreorder\n\t" "mtc0\t$1, $12\n\t" "irq_disable_hazard\n\t" *************** *** 104,111 **** --- 115,127 ---- ".set\tnoat\n\t" "mfc0\t$1, $12\n\t" "andi\t\\flags, 1\n\t" + #if TX49XX_MFC0_WAR && defined(MODULE) + "ori\t$1, 3\n\t" + "xori\t$1, 3\n\t" + #else "ori\t$1, 1\n\t" "xori\t$1, 1\n\t" + #endif "or\t\\flags, $1\n\t" "mtc0\t\\flags, $12\n\t" "irq_disable_hazard\n\t" diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/io.h linux-current/include/asm-mips/io.h *** linux-2.6.10/include/asm-mips/io.h Sat Dec 25 06:34:31 2004 --- linux-current/include/asm-mips/io.h Wed Jun 14 21:12:59 2006 *************** *** 6,26 **** * Copyright (C) 1994, 1995 Waldorf GmbH * Copyright (C) 1994 - 2000 Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. */ #ifndef _ASM_IO_H #define _ASM_IO_H #include #include #include #include #include #include #include #include #include ! #include #include /* --- 6,31 ---- * Copyright (C) 1994, 1995 Waldorf GmbH * Copyright (C) 1994 - 2000 Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. + * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved. + * Author: Maciej W. Rozycki */ #ifndef _ASM_IO_H #define _ASM_IO_H #include #include + #include #include #include + #include + #include #include #include #include #include #include ! #include /* *************** *** 29,62 **** #undef CONF_SLOWDOWN_IO /* ! * Sane hardware offers swapping of I/O space accesses in hardware; less ! * sane hardware forces software to fiddle with this ... */ - #if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__) - - #define __ioswab8(x) (x) - #ifdef CONFIG_SGI_IP22 /* * IP22 seems braindead enough to swap 16bits values in hardware, but * not 32bits. Go figure... Can't tell without documentation. */ ! #define __ioswab16(x) (x) ! #else ! #define __ioswab16(x) swab16(x) #endif ! #define __ioswab32(x) swab32(x) ! #define __ioswab64(x) swab64(x) #else ! #define __ioswab8(x) (x) ! #define __ioswab16(x) (x) ! #define __ioswab32(x) (x) ! #define __ioswab64(x) (x) #endif #define IO_SPACE_LIMIT 0xffff /* --- 34,118 ---- #undef CONF_SLOWDOWN_IO /* ! * Sane hardware offers swapping of PCI/ISA I/O space accesses in hardware; ! * less sane hardware forces software to fiddle with this... */ #ifdef CONFIG_SGI_IP22 /* * IP22 seems braindead enough to swap 16bits values in hardware, but * not 32bits. Go figure... Can't tell without documentation. */ ! # define ioswabw(a,x) (x) ! # define __raw_ioswabw(a,x) le16_to_cpu(x) ! #endif ! ! #ifndef ioswabb ! # define ioswabb(a,x) (x) #endif ! #ifndef __raw_ioswabb ! # define __raw_ioswabb(a,x) (x) ! #endif ! ! #if defined(CONFIG_SWAP_IO_SPACE) ! ! # ifndef ioswabw ! # define ioswabw(a,x) le16_to_cpu(x) ! # endif ! # ifndef __raw_ioswabw ! # define __raw_ioswabw(a,x) (x) ! # endif ! # ifndef ioswabl ! # define ioswabl(a,x) le32_to_cpu(x) ! # endif ! # ifndef __raw_ioswabl ! # define __raw_ioswabl(a,x) (x) ! # endif ! # ifndef ioswabq ! # define ioswabq(a,x) le64_to_cpu(x) ! # endif ! # ifndef __raw_ioswabq ! # define __raw_ioswabq(a,x) (x) ! # endif #else ! # ifndef ioswabb ! # define ioswabb(a,x) (x) ! # endif ! # ifndef __raw_ioswabb ! # define __raw_ioswabb(a,x) (x) ! # endif ! # ifndef ioswabw ! # define ioswabw(a,x) (x) ! # endif ! # ifndef __raw_ioswabw ! # define __raw_ioswabw(a,x) cpu_to_le16(x) ! # endif ! # ifndef ioswabl ! # define ioswabl(a,x) (x) ! # endif ! # ifndef __raw_ioswabl ! # define __raw_ioswabl(a,x) cpu_to_le32(x) ! # endif ! # ifndef ioswabq ! # define ioswabq(a,x) (x) ! # endif ! # ifndef __raw_ioswabq ! # define __raw_ioswabq(a,x) cpu_to_le64(x) ! # endif #endif + /* + * Native bus accesses never swapped. + */ + #define bus_ioswabb(a,x) (x) + #define bus_ioswabw(a,x) (x) + #define bus_ioswabl(a,x) (x) + #define bus_ioswabq(a,x) (x) + + #define __bus_ioswabq bus_ioswabq + #define IO_SPACE_LIMIT 0xffff /* *************** *** 67,73 **** --- 123,133 ---- * instruction, so the lower 16 bits must be zero. Should be true on * on any sane architecture; generic code does not use this assumption. */ + #ifdef CONFIG_XIP_KERNEL + extern unsigned long mips_io_port_base; + #else extern const unsigned long mips_io_port_base; + #endif #define set_io_port_base(base) \ do { * (unsigned long *) &mips_io_port_base = (base); } while (0) *************** *** 239,352 **** static inline void iounmap(volatile void __iomem *addr) { ! if (cpu_has_64bits) return; __iounmap(addr); } - #define __raw_readb(addr) \ - (*(volatile unsigned char *) __swizzle_addr_b((unsigned long)(addr))) - #define __raw_readw(addr) \ - (*(volatile unsigned short *) __swizzle_addr_w((unsigned long)(addr))) - #define __raw_readl(addr) \ - (*(volatile unsigned int *) __swizzle_addr_l((unsigned long)(addr))) - #ifdef CONFIG_MIPS32 - #define ____raw_readq(addr) \ - ({ \ - u64 __res; \ - \ - __asm__ __volatile__ ( \ - " .set mips3 # ____raw_readq \n" \ - " ld %L0, (%1) \n" \ - " dsra32 %M0, %L0, 0 \n" \ - " sll %L0, %L0, 0 \n" \ - " .set mips0 \n" \ - : "=r" (__res) \ - : "r" (__swizzle_addr_q((unsigned long)(addr)))); \ - __res; \ - }) - #define __raw_readq(addr) \ - ({ \ - unsigned long __flags; \ - u64 __res; \ - \ - local_irq_save(__flags); \ - __res = ____raw_readq(addr); \ - local_irq_restore(__flags); \ - __res; \ - }) - #endif - #ifdef CONFIG_MIPS64 - #define ____raw_readq(addr) \ - (*(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr))) - #define __raw_readq(addr) ____raw_readq(addr) - #endif ! #define readb(addr) __ioswab8(__raw_readb(addr)) ! #define readw(addr) __ioswab16(__raw_readw(addr)) ! #define readl(addr) __ioswab32(__raw_readl(addr)) ! #define readq(addr) __ioswab64(__raw_readq(addr)) ! #define readb_relaxed(addr) readb(addr) ! #define readw_relaxed(addr) readw(addr) ! #define readl_relaxed(addr) readl(addr) ! #define readq_relaxed(addr) readq(addr) ! ! #define __raw_writeb(b,addr) \ ! do { \ ! ((*(volatile unsigned char *)__swizzle_addr_b((unsigned long)(addr))) = (b)); \ ! } while (0) ! ! #define __raw_writew(w,addr) \ ! do { \ ! ((*(volatile unsigned short *)__swizzle_addr_w((unsigned long)(addr))) = (w)); \ ! } while (0) ! ! #define __raw_writel(l,addr) \ ! do { \ ! ((*(volatile unsigned int *)__swizzle_addr_l((unsigned long)(addr))) = (l)); \ ! } while (0) ! ! #ifdef CONFIG_MIPS32 ! #define ____raw_writeq(val,addr) \ ! do { \ ! u64 __tmp; \ ! \ ! __asm__ __volatile__ ( \ ! " .set mips3 \n" \ ! " dsll32 %L0, %L0, 0 # ____raw_writeq\n" \ ! " dsrl32 %L0, %L0, 0 \n" \ ! " dsll32 %M0, %M0, 0 \n" \ ! " or %L0, %L0, %M0 \n" \ ! " sd %L0, (%2) \n" \ ! " .set mips0 \n" \ ! : "=r" (__tmp) \ ! : "0" ((unsigned long long)val), \ ! "r" (__swizzle_addr_q((unsigned long)(addr)))); \ ! } while (0) ! ! #define __raw_writeq(val,addr) \ ! do { \ ! unsigned long __flags; \ ! \ ! local_irq_save(__flags); \ ! ____raw_writeq(val, addr); \ ! local_irq_restore(__flags); \ ! } while (0) ! #endif ! #ifdef CONFIG_MIPS64 ! #define ____raw_writeq(q,addr) \ ! do { \ ! *(volatile unsigned long *)__swizzle_addr_q((unsigned long)(addr)) = (q); \ ! } while (0) ! #define __raw_writeq(q,addr) ____raw_writeq(q, addr) ! #endif - #define writeb(b,addr) __raw_writeb(__ioswab8(b),(addr)) - #define writew(w,addr) __raw_writew(__ioswab16(w),(addr)) - #define writel(l,addr) __raw_writel(__ioswab32(l),(addr)) - #define writeq(q,addr) __raw_writeq(__ioswab64(q),(addr)) /* Depends on MIPS II instruction set */ #define mmiowb() asm volatile ("sync" ::: "memory") --- 299,512 ---- static inline void iounmap(volatile void __iomem *addr) { ! if (cpu_has_64bit_addresses) return; __iounmap(addr); } ! #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ ! \ ! static inline void pfx##write##bwlq(type val, \ ! volatile void __iomem *mem) \ ! { \ ! volatile type *__mem; \ ! type __val; \ ! \ ! __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \ ! \ ! __val = pfx##ioswab##bwlq(__mem, val); \ ! \ ! if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \ ! *__mem = __val; \ ! else if (cpu_has_64bits) { \ ! unsigned long __flags; \ ! type __tmp; \ ! \ ! if (irq) \ ! local_irq_save(__flags); \ ! __asm__ __volatile__( \ ! ".set mips3" "\t\t# __writeq""\n\t" \ ! "dsll32 %L0, %L0, 0" "\n\t" \ ! "dsrl32 %L0, %L0, 0" "\n\t" \ ! "dsll32 %M0, %M0, 0" "\n\t" \ ! "or %L0, %L0, %M0" "\n\t" \ ! "sd %L0, %2" "\n\t" \ ! ".set mips0" "\n" \ ! : "=r" (__tmp) \ ! : "0" (__val), "m" (*__mem)); \ ! if (irq) \ ! local_irq_restore(__flags); \ ! } else \ ! BUG(); \ ! } \ ! \ ! static inline type pfx##read##bwlq(volatile void __iomem *mem) \ ! { \ ! volatile type *__mem; \ ! type __val; \ ! \ ! __mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \ ! \ ! if (sizeof(type) != sizeof(u64) || sizeof(u64) == sizeof(long)) \ ! __val = *__mem; \ ! else if (cpu_has_64bits) { \ ! unsigned long __flags; \ ! \ ! local_irq_save(__flags); \ ! __asm__ __volatile__( \ ! ".set mips3" "\t\t# __readq" "\n\t" \ ! "ld %L0, %1" "\n\t" \ ! "dsra32 %M0, %L0, 0" "\n\t" \ ! "sll %L0, %L0, 0" "\n\t" \ ! ".set mips0" "\n" \ ! : "=r" (__val) \ ! : "m" (*__mem)); \ ! local_irq_restore(__flags); \ ! } else { \ ! __val = 0; \ ! BUG(); \ ! } \ ! \ ! return pfx##ioswab##bwlq(__mem, __val); \ ! } ! #define __BUILD_IOPORT_SINGLE(pfx, bwlq, type, p, slow) \ ! \ ! static inline void pfx##out##bwlq##p(type val, unsigned long port) \ ! { \ ! volatile type *__addr; \ ! type __val; \ ! \ ! __addr = (void *)(mips_io_port_base + port); \ ! __addr = (void *)__swizzle_addr_##bwlq((unsigned long)__addr); \ ! \ ! __val = pfx##ioswab##bwlq(__addr, val); \ ! \ ! if (sizeof(type) != sizeof(u64)) { \ ! *__addr = __val; \ ! slow; \ ! } else \ ! BUILD_BUG(); \ ! } \ ! \ ! static inline type pfx##in##bwlq##p(unsigned long port) \ ! { \ ! volatile type *__addr; \ ! type __val; \ ! \ ! __addr = (void *)(mips_io_port_base + port); \ ! __addr = (void *)__swizzle_addr_##bwlq((unsigned long)__addr); \ ! \ ! if (sizeof(type) != sizeof(u64)) { \ ! __val = *__addr; \ ! slow; \ ! } else { \ ! __val = 0; \ ! BUILD_BUG(); \ ! } \ ! \ ! return pfx##ioswab##bwlq(__addr, __val); \ ! } ! ! #define __BUILD_MEMORY_PFX(bus, bwlq, type) \ ! \ ! __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1) ! ! #define __BUILD_IOPORT_PFX(bus, bwlq, type) \ ! \ ! __BUILD_IOPORT_SINGLE(bus, bwlq, type, ,) \ ! __BUILD_IOPORT_SINGLE(bus, bwlq, type, _p, SLOW_DOWN_IO) ! ! #define BUILDIO(bwlq, type) \ ! \ ! __BUILD_MEMORY_PFX(, bwlq, type) \ ! __BUILD_MEMORY_PFX(__raw_, bwlq, type) \ ! __BUILD_MEMORY_PFX(bus_, bwlq, type) \ ! __BUILD_IOPORT_PFX(, bwlq, type) \ ! __BUILD_IOPORT_PFX(__raw_, bwlq, type) ! ! #define __BUILDIO(bwlq, type) \ ! \ ! __BUILD_MEMORY_SINGLE(__bus_, bwlq, type, 0) ! ! BUILDIO(b, u8) ! BUILDIO(w, u16) ! BUILDIO(l, u32) ! BUILDIO(q, u64) ! ! __BUILDIO(q, u64) ! ! #define readb_relaxed readb ! #define readw_relaxed readw ! #define readl_relaxed readl ! #define readq_relaxed readq ! ! /* ! * Some code tests for these symbols ! */ ! #define readq readq ! #define writeq writeq ! ! #define __BUILD_MEMORY_STRING(bwlq, type) \ ! \ ! static inline void writes##bwlq(volatile void __iomem *mem, void *addr, \ ! unsigned int count) \ ! { \ ! volatile type *__addr = addr; \ ! \ ! while (count--) { \ ! __raw_write##bwlq(*__addr, mem); \ ! __addr++; \ ! } \ ! } \ ! \ ! static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \ ! unsigned int count) \ ! { \ ! volatile type *__addr = addr; \ ! \ ! while (count--) { \ ! *__addr = __raw_read##bwlq(mem); \ ! __addr++; \ ! } \ ! } ! ! #define __BUILD_IOPORT_STRING(bwlq, type) \ ! \ ! static inline void outs##bwlq(unsigned long port, void *addr, \ ! unsigned int count) \ ! { \ ! volatile type *__addr = addr; \ ! \ ! while (count--) { \ ! __raw_out##bwlq(*__addr, port); \ ! __addr++; \ ! } \ ! } \ ! \ ! static inline void ins##bwlq(unsigned long port, void *addr, \ ! unsigned int count) \ ! { \ ! volatile type *__addr = addr; \ ! \ ! while (count--) { \ ! *__addr = __raw_in##bwlq(port); \ ! __addr++; \ ! } \ ! } ! ! #define BUILDSTRING(bwlq, type) \ ! \ ! __BUILD_MEMORY_STRING(bwlq, type) \ ! __BUILD_IOPORT_STRING(bwlq, type) ! ! BUILDSTRING(b, u8) ! BUILDSTRING(w, u16) ! BUILDSTRING(l, u32) ! BUILDSTRING(q, u64) /* Depends on MIPS II instruction set */ #define mmiowb() asm volatile ("sync" ::: "memory") *************** *** 394,400 **** * address should have been obtained by ioremap. * Returns 1 on a match. */ ! static inline int check_signature(unsigned long io_addr, const unsigned char *signature, int length) { int retval = 0; --- 554,560 ---- * address should have been obtained by ioremap. * Returns 1 on a match. */ ! static inline int check_signature(char __iomem *io_addr, const unsigned char *signature, int length) { int retval = 0; *************** *** 410,586 **** return retval; } - static inline void __outb(unsigned char val, unsigned long port) - { - port = __swizzle_addr_b(port); - - *(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val); - } - - static inline void __outw(unsigned short val, unsigned long port) - { - port = __swizzle_addr_w(port); - - *(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val); - } - - static inline void __outl(unsigned int val, unsigned long port) - { - port = __swizzle_addr_l(port); - - *(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val); - } - - static inline void __outb_p(unsigned char val, unsigned long port) - { - port = __swizzle_addr_b(port); - - *(volatile u8 *)(mips_io_port_base + port) = __ioswab8(val); - SLOW_DOWN_IO; - } - - static inline void __outw_p(unsigned short val, unsigned long port) - { - port = __swizzle_addr_w(port); - - *(volatile u16 *)(mips_io_port_base + port) = __ioswab16(val); - SLOW_DOWN_IO; - } - - static inline void __outl_p(unsigned int val, unsigned long port) - { - port = __swizzle_addr_l(port); - - *(volatile u32 *)(mips_io_port_base + port) = __ioswab32(val); - SLOW_DOWN_IO; - } - - #define outb(val, port) __outb(val, port) - #define outw(val, port) __outw(val, port) - #define outl(val, port) __outl(val, port) - #define outb_p(val, port) __outb_p(val, port) - #define outw_p(val, port) __outw_p(val, port) - #define outl_p(val, port) __outl_p(val, port) - - static inline unsigned char __inb(unsigned long port) - { - port = __swizzle_addr_b(port); - - return __ioswab8(*(volatile u8 *)(mips_io_port_base + port)); - } - - static inline unsigned short __inw(unsigned long port) - { - port = __swizzle_addr_w(port); - - return __ioswab16(*(volatile u16 *)(mips_io_port_base + port)); - } - - static inline unsigned int __inl(unsigned long port) - { - port = __swizzle_addr_l(port); - - return __ioswab32(*(volatile u32 *)(mips_io_port_base + port)); - } - - static inline unsigned char __inb_p(unsigned long port) - { - u8 __val; - - port = __swizzle_addr_b(port); - - __val = *(volatile u8 *)(mips_io_port_base + port); - SLOW_DOWN_IO; - - return __ioswab8(__val); - } - - static inline unsigned short __inw_p(unsigned long port) - { - u16 __val; - - port = __swizzle_addr_w(port); - - __val = *(volatile u16 *)(mips_io_port_base + port); - SLOW_DOWN_IO; - - return __ioswab16(__val); - } - - static inline unsigned int __inl_p(unsigned long port) - { - u32 __val; - - port = __swizzle_addr_l(port); - - __val = *(volatile u32 *)(mips_io_port_base + port); - SLOW_DOWN_IO; - - return __ioswab32(__val); - } - - #define inb(port) __inb(port) - #define inw(port) __inw(port) - #define inl(port) __inl(port) - #define inb_p(port) __inb_p(port) - #define inw_p(port) __inw_p(port) - #define inl_p(port) __inl_p(port) - - static inline void __outsb(unsigned long port, void *addr, unsigned int count) - { - while (count--) { - outb(*(u8 *)addr, port); - addr++; - } - } - - static inline void __insb(unsigned long port, void *addr, unsigned int count) - { - while (count--) { - *(u8 *)addr = inb(port); - addr++; - } - } - - static inline void __outsw(unsigned long port, void *addr, unsigned int count) - { - while (count--) { - outw(*(u16 *)addr, port); - addr += 2; - } - } - - static inline void __insw(unsigned long port, void *addr, unsigned int count) - { - while (count--) { - *(u16 *)addr = inw(port); - addr += 2; - } - } - - static inline void __outsl(unsigned long port, void *addr, unsigned int count) - { - while (count--) { - outl(*(u32 *)addr, port); - addr += 4; - } - } - - static inline void __insl(unsigned long port, void *addr, unsigned int count) - { - while (count--) { - *(u32 *)addr = inl(port); - addr += 4; - } - } - - #define outsb(port, addr, count) __outsb(port, addr, count) - #define insb(port, addr, count) __insb(port, addr, count) - #define outsw(port, addr, count) __outsw(port, addr, count) - #define insw(port, addr, count) __insw(port, addr, count) - #define outsl(port, addr, count) __outsl(port, addr, count) - #define insl(port, addr, count) __insl(port, addr, count) - /* * The caches on some architectures aren't dma-coherent and have need to * handle this in software. There are three types of operations that --- 570,575 ---- diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/ltt.h linux-current/include/asm-mips/ltt.h *** linux-2.6.10/include/asm-mips/ltt.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/ltt.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,15 ---- + /* + * linux/include/asm-mips/ltt.h + * + * Copyright (C) 2002, Karim Yaghmour + * + * MIPS definitions for tracing system + */ + + #include + + /* Current arch type */ + #define LTT_ARCH_TYPE LTT_ARCH_TYPE_MIPS + + /* Current variant type */ + #define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/mach-emma/cpu-feature-overrides.h linux-current/include/asm-mips/mach-emma/cpu-feature-overrides.h *** linux-2.6.10/include/asm-mips/mach-emma/cpu-feature-overrides.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/mach-emma/cpu-feature-overrides.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,20 ---- + /* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Ralf Baechle + * + * (C) Copyright TOSHIBA CORPORATION 2004-2005 + * All Rights Reserved. + * + */ + #ifndef __ASM_MACH_EMMA_CPU_FEATURE_OVERRIDES_H + #define __ASM_MACH_EMMA_CPU_FEATURE_OVERRIDES_H + + #include + + /* not necessary, but good for faster/smaller code */ + #define cpu_has_llsc 1 + + #endif /* __ASM_MACH_EMMA_GENERIC_CPU_FEATURE_OVERRIDES_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/mach-emma/irq.h linux-current/include/asm-mips/mach-emma/irq.h *** linux-2.6.10/include/asm-mips/mach-emma/irq.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/mach-emma/irq.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,13 ---- + /* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 by Ralf Baechle + */ + #ifndef __ASM_MACH_EMMA_IRQ_H + #define __ASM_MACH_EMMA_IRQ_H + + #define NR_IRQS 256 + + #endif /* __ASM_MACH_EMMA_IRQ_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/mach-generic/ide.h linux-current/include/asm-mips/mach-generic/ide.h *** linux-2.6.10/include/asm-mips/mach-generic/ide.h Sat Dec 25 06:35:00 2004 --- linux-current/include/asm-mips/mach-generic/ide.h Wed Jun 14 21:12:59 2006 *************** *** 16,21 **** --- 16,23 ---- #ifdef __KERNEL__ #include + #include + #include #ifndef MAX_HWIFS # ifdef CONFIG_BLK_DEV_IDEPCI *************** *** 27,58 **** #define IDE_ARCH_OBSOLETE_DEFAULTS static __inline__ int ide_default_irq(unsigned long base) { ! switch (base) { ! case 0x1f0: return 14; ! case 0x170: return 15; ! case 0x1e8: return 11; ! case 0x168: return 10; ! case 0x1e0: return 8; ! case 0x160: return 12; default: return 0; ! } } static __inline__ unsigned long ide_default_io_base(int index) { ! switch (index) { ! case 0: return 0x1f0; ! case 1: return 0x170; ! case 2: return 0x1e8; ! case 3: return 0x168; ! case 4: return 0x1e0; ! case 5: return 0x160; default: return 0; ! } } #define IDE_ARCH_OBSOLETE_INIT --- 29,96 ---- #define IDE_ARCH_OBSOLETE_DEFAULTS + static __inline__ int ide_probe_legacy(void) + { + #ifdef CONFIG_PCI + struct pci_dev *dev; + if ((dev = pci_get_class(PCI_CLASS_BRIDGE_EISA << 8, NULL)) != NULL || + (dev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL)) != NULL) { + pci_dev_put(dev); + + return 1; + } + return 0; + #elif defined(CONFIG_EISA) || defined(CONFIG_ISA) + return 1; + #else + return 0; + #endif + } + static __inline__ int ide_default_irq(unsigned long base) { ! if (ide_probe_legacy()) ! switch (base) { ! case 0x1f0: ! return 14; ! case 0x170: ! return 15; ! case 0x1e8: ! return 11; ! case 0x168: ! return 10; ! case 0x1e0: ! return 8; ! case 0x160: ! return 12; default: return 0; ! } ! else ! return 0; } static __inline__ unsigned long ide_default_io_base(int index) { ! if (ide_probe_legacy()) ! switch (index) { ! case 0: ! return 0x1f0; ! case 1: ! return 0x170; ! case 2: ! return 0x1e8; ! case 3: ! return 0x168; ! case 4: ! return 0x1e0; ! case 5: ! return 0x160; default: return 0; ! } ! else ! return 0; } #define IDE_ARCH_OBSOLETE_INIT *************** *** 64,70 **** #define ide_init_default_irq(base) ide_default_irq(base) #endif ! #include #endif /* __KERNEL__ */ --- 102,118 ---- #define ide_init_default_irq(base) ide_default_irq(base) #endif ! /* MIPS port and memory-mapped I/O string operations. */ ! ! #define __ide_insw insw ! #define __ide_insl insl ! #define __ide_outsw outsw ! #define __ide_outsl outsl ! ! #define __ide_mm_insw readsw ! #define __ide_mm_insl readsl ! #define __ide_mm_outsw writesw ! #define __ide_mm_outsl writesl #endif /* __KERNEL__ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/mipsregs.h linux-current/include/asm-mips/mipsregs.h *** linux-2.6.10/include/asm-mips/mipsregs.h Sat Dec 25 06:34:45 2004 --- linux-current/include/asm-mips/mipsregs.h Wed Jun 14 21:12:59 2006 *************** *** 532,537 **** --- 532,540 ---- #ifndef __ASSEMBLY__ + #define CAUSE_EXCCODE(x) ((CAUSEF_EXCCODE & (x->cp0_cause)) >> CAUSEB_EXCCODE) + #define CAUSE_EPC(x) (x->cp0_epc + (((x->cp0_cause & CAUSEF_BD) >> CAUSEB_BD) << 2)) + /* * Functions to access the r10k performance counter and control registers */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/mmu_context.h linux-current/include/asm-mips/mmu_context.h *** linux-2.6.10/include/asm-mips/mmu_context.h Sat Dec 25 06:34:44 2004 --- linux-current/include/asm-mips/mmu_context.h Wed Jun 14 21:12:59 2006 *************** *** 19,44 **** #include /* ! * For the fast tlb miss handlers, we currently keep a per cpu array ! * of pointers to the current pgd for each processor. Also, the proc. ! * id is stuffed into the context register. This should be changed to ! * use the processor id via current->processor, where current is stored ! * in watchhi/lo. The context register should be used to contiguously ! * map the page tables. */ #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ pgd_current[smp_processor_id()] = (unsigned long)(pgd) #ifdef CONFIG_MIPS32 ! #define TLBMISS_HANDLER_SETUP() \ ! write_c0_context((unsigned long) smp_processor_id() << 23); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif ! #ifdef CONFIG_MIPS64 ! #define TLBMISS_HANDLER_SETUP() \ write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif ! extern unsigned long pgd_current[]; #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) --- 19,48 ---- #include /* ! * For the fast tlb miss handlers, we keep a per cpu array of pointers ! * to the current pgd for each processor. Also, the proc. id is stuffed ! * into the context register. */ + extern unsigned long pgd_current[]; + #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ pgd_current[smp_processor_id()] = (unsigned long)(pgd) + #ifdef CONFIG_MIPS32 ! #define TLBMISS_HANDLER_SETUP() \ ! write_c0_context((unsigned long) smp_processor_id() << 23); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif ! #if defined(CONFIG_MIPS64) && !defined(CONFIG_BUILD_ELF64) ! #define TLBMISS_HANDLER_SETUP() \ write_c0_context((unsigned long) &pgd_current[smp_processor_id()] << 23); \ TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif ! #if defined(CONFIG_MIPS64) && defined(CONFIG_BUILD_ELF64) ! #define TLBMISS_HANDLER_SETUP() \ ! write_c0_context((unsigned long) smp_processor_id() << 23); \ ! TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) ! #endif #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) *************** *** 150,156 **** activate_mm(struct mm_struct *prev, struct mm_struct *next) { unsigned long flags; ! int cpu = smp_processor_id(); local_irq_save(flags); --- 154,160 ---- activate_mm(struct mm_struct *prev, struct mm_struct *next) { unsigned long flags; ! unsigned int cpu = smp_processor_id(); local_irq_save(flags); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/page.h linux-current/include/asm-mips/page.h *** linux-2.6.10/include/asm-mips/page.h Sat Dec 25 06:34:31 2004 --- linux-current/include/asm-mips/page.h Wed Jun 14 21:12:59 2006 *************** *** 52,76 **** struct page; ! static inline void clear_user_page(void *addr, unsigned long vaddr, ! struct page *page) ! { ! extern void (*flush_data_cache_page)(unsigned long addr); ! ! clear_page(addr); ! if (pages_do_alias((unsigned long) addr, vaddr)) ! flush_data_cache_page((unsigned long)addr); ! } ! ! static inline void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, ! struct page *to) ! { ! extern void (*flush_data_cache_page)(unsigned long addr); ! ! copy_page(vto, vfrom); ! if (pages_do_alias((unsigned long)vto, vaddr)) ! flush_data_cache_page((unsigned long)vto); ! } /* * These are used to make use of C type-checking.. --- 52,60 ---- struct page; ! extern void clear_user_page(void *addr, unsigned long vaddr, struct page *page); ! extern void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, ! struct page *to); /* * These are used to make use of C type-checking.. diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/pci.h linux-current/include/asm-mips/pci.h *** linux-2.6.10/include/asm-mips/pci.h Sat Dec 25 06:35:23 2004 --- linux-current/include/asm-mips/pci.h Wed Jun 14 21:12:59 2006 *************** *** 94,100 **** */ extern unsigned int PCI_DMA_BUS_IS_PHYS; ! #ifdef CONFIG_MAPPED_DMA_IO /* pci_unmap_{single,page} is not a nop, thus... */ #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; --- 94,100 ---- */ extern unsigned int PCI_DMA_BUS_IS_PHYS; ! #ifdef CONFIG_DMA_NEED_PCI_MAP_STATE /* pci_unmap_{single,page} is not a nop, thus... */ #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; *************** *** 104,110 **** #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) ! #else /* CONFIG_MAPPED_DMA_IO */ /* pci_unmap_{page,single} is a nop so... */ #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) --- 104,110 ---- #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) ! #else /* CONFIG_DMA_NEED_PCI_MAP_STATE */ /* pci_unmap_{page,single} is a nop so... */ #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) *************** *** 114,120 **** #define pci_unmap_len(PTR, LEN_NAME) (0) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) ! #endif /* CONFIG_MAPPED_DMA_IO */ /* This is always fine. */ #define pci_dac_dma_supported(pci_dev, mask) (1) --- 114,120 ---- #define pci_unmap_len(PTR, LEN_NAME) (0) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) ! #endif /* CONFIG_DMA_NEED_PCI_MAP_STATE */ /* This is always fine. */ #define pci_dac_dma_supported(pci_dev, mask) (1) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/pgtable-32.h linux-current/include/asm-mips/pgtable-32.h *** linux-2.6.10/include/asm-mips/pgtable-32.h Sat Dec 25 06:34:57 2004 --- linux-current/include/asm-mips/pgtable-32.h Wed Jun 14 21:12:59 2006 *************** *** 98,104 **** extern void load_pgd(unsigned long pg_dir); ! extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)]; /* * Empty pgd/pmd entries point to the invalid_pte_table. --- 98,104 ---- extern void load_pgd(unsigned long pg_dir); ! extern pte_t invalid_pte_table[PAGE_SIZE/sizeof(pte_t)]; /* * Empty pgd/pmd entries point to the invalid_pte_table. diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/reg.h linux-current/include/asm-mips/reg.h *** linux-2.6.10/include/asm-mips/reg.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/reg.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,129 ---- + /* + * Various register offset definitions for debuggers, core file + * examiners and whatnot. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1999 Ralf Baechle + * Copyright (C) 1995, 1999 Silicon Graphics + */ + #ifndef __ASM_MIPS_REG_H + #define __ASM_MIPS_REG_H + + #include + + #if defined(CONFIG_MIPS32) || defined(WANT_COMPAT_REG_H) + + #define EF_R0 6 + #define EF_R1 7 + #define EF_R2 8 + #define EF_R3 9 + #define EF_R4 10 + #define EF_R5 11 + #define EF_R6 12 + #define EF_R7 13 + #define EF_R8 14 + #define EF_R9 15 + #define EF_R10 16 + #define EF_R11 17 + #define EF_R12 18 + #define EF_R13 19 + #define EF_R14 20 + #define EF_R15 21 + #define EF_R16 22 + #define EF_R17 23 + #define EF_R18 24 + #define EF_R19 25 + #define EF_R20 26 + #define EF_R21 27 + #define EF_R22 28 + #define EF_R23 29 + #define EF_R24 30 + #define EF_R25 31 + + /* + * k0/k1 unsaved + */ + #define EF_R26 32 + #define EF_R27 33 + + #define EF_R28 34 + #define EF_R29 35 + #define EF_R30 36 + #define EF_R31 37 + + /* + * Saved special registers + */ + #define EF_LO 38 + #define EF_HI 39 + + #define EF_CP0_EPC 40 + #define EF_CP0_BADVADDR 41 + #define EF_CP0_STATUS 42 + #define EF_CP0_CAUSE 43 + #define EF_UNUSED0 44 + + #define EF_SIZE 180 + + #endif + + #if CONFIG_MIPS64 + + #define EF_R0 0 + #define EF_R1 1 + #define EF_R2 2 + #define EF_R3 3 + #define EF_R4 4 + #define EF_R5 5 + #define EF_R6 6 + #define EF_R7 7 + #define EF_R8 8 + #define EF_R9 9 + #define EF_R10 10 + #define EF_R11 11 + #define EF_R12 12 + #define EF_R13 13 + #define EF_R14 14 + #define EF_R15 15 + #define EF_R16 16 + #define EF_R17 17 + #define EF_R18 18 + #define EF_R19 19 + #define EF_R20 20 + #define EF_R21 21 + #define EF_R22 22 + #define EF_R23 23 + #define EF_R24 24 + #define EF_R25 25 + + /* + * k0/k1 unsaved + */ + #define EF_R26 26 + #define EF_R27 27 + + + #define EF_R28 28 + #define EF_R29 29 + #define EF_R30 30 + #define EF_R31 31 + + /* + * Saved special registers + */ + #define EF_LO 32 + #define EF_HI 33 + + #define EF_CP0_EPC 34 + #define EF_CP0_BADVADDR 35 + #define EF_CP0_STATUS 36 + #define EF_CP0_CAUSE 37 + + #define EF_SIZE 304 /* size in bytes */ + + #endif /* CONFIG_MIPS64 */ + + #endif /* __ASM_MIPS_REG_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/relay.h linux-current/include/asm-mips/relay.h *** linux-2.6.10/include/asm-mips/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-mips/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_RELAY_H + #define _ASM_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/stackframe.h linux-current/include/asm-mips/stackframe.h *** linux-2.6.10/include/asm-mips/stackframe.h Sat Dec 25 06:33:49 2004 --- linux-current/include/asm-mips/stackframe.h Wed Jun 14 21:12:59 2006 *************** *** 104,109 **** --- 104,110 ---- .macro SAVE_SOME .set push + .set noat .set reorder mfc0 k0, CP0_STATUS sll k0, 3 /* extract cu0 bit */ *************** *** 278,293 **** .macro RESTORE_ALL RESTORE_TEMP - RESTORE_AT RESTORE_STATIC RESTORE_SOME RESTORE_SP .endm .macro RESTORE_ALL_AND_RET RESTORE_TEMP - RESTORE_AT RESTORE_STATIC RESTORE_SOME RESTORE_SP_AND_RET .endm --- 279,294 ---- .macro RESTORE_ALL RESTORE_TEMP RESTORE_STATIC + RESTORE_AT RESTORE_SOME RESTORE_SP .endm .macro RESTORE_ALL_AND_RET RESTORE_TEMP RESTORE_STATIC + RESTORE_AT RESTORE_SOME RESTORE_SP_AND_RET .endm diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/uaccess.h linux-current/include/asm-mips/uaccess.h *** linux-2.6.10/include/asm-mips/uaccess.h Sat Dec 25 06:33:49 2004 --- linux-current/include/asm-mips/uaccess.h Wed Jun 14 21:12:59 2006 *************** *** 106,112 **** #define __access_mask get_fs().seg #define __access_ok(addr, size, mask) \ ! (((signed long)((mask) & ((addr) | ((addr) + (size)) | __ua_size(size)))) == 0) #define access_ok(type, addr, size) \ likely(__access_ok((unsigned long)(addr), (size),__access_mask)) --- 106,112 ---- #define __access_mask get_fs().seg #define __access_ok(addr, size, mask) \ ! (((signed long)((mask) & ((addr) | ((addr) + (size) - 1) | __ua_size(size)))) == 0) #define access_ok(type, addr, size) \ likely(__access_ok((unsigned long)(addr), (size),__access_mask)) *************** *** 150,156 **** * Returns zero on success, or -EFAULT on error. */ #define put_user(x,ptr) \ ! __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) /* * get_user: - Get a simple variable from user space. --- 150,156 ---- * Returns zero on success, or -EFAULT on error. */ #define put_user(x,ptr) \ ! __put_user_check((x),(ptr),sizeof(*(ptr))) /* * get_user: - Get a simple variable from user space. *************** *** 170,176 **** * On error, the variable @x is set to zero. */ #define get_user(x,ptr) \ ! __get_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) /* * __put_user: - Write a simple value into user space, with less checking. --- 170,176 ---- * On error, the variable @x is set to zero. */ #define get_user(x,ptr) \ ! __get_user_check((x),(ptr),sizeof(*(ptr))) /* * __put_user: - Write a simple value into user space, with less checking. *************** *** 192,198 **** * Returns zero on success, or -EFAULT on error. */ #define __put_user(x,ptr) \ ! __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) /* * __get_user: - Get a simple variable from user space, with less checking. --- 192,198 ---- * Returns zero on success, or -EFAULT on error. */ #define __put_user(x,ptr) \ ! __put_user_nocheck((x),(ptr),sizeof(*(ptr))) /* * __get_user: - Get a simple variable from user space, with less checking. *************** *** 215,221 **** * On error, the variable @x is set to zero. */ #define __get_user(x,ptr) \ ! __get_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct *)(x)) --- 215,221 ---- * On error, the variable @x is set to zero. */ #define __get_user(x,ptr) \ ! __get_user_nocheck((x),(ptr),sizeof(*(ptr))) struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct *)(x)) *************** *** 232,240 **** #define __get_user_nocheck(x,ptr,size) \ ({ \ - long __gu_err = 0; \ __typeof(*(ptr)) __gu_val = 0; \ long __gu_addr; \ might_sleep(); \ __gu_addr = (long) (ptr); \ switch (size) { \ --- 232,241 ---- #define __get_user_nocheck(x,ptr,size) \ ({ \ __typeof(*(ptr)) __gu_val = 0; \ long __gu_addr; \ + long __gu_err = 0; \ + \ might_sleep(); \ __gu_addr = (long) (ptr); \ switch (size) { \ *************** *** 244,260 **** case 8: __GET_USER_DW(__gu_err); break; \ default: __get_user_unknown(); break; \ } \ ! x = (__typeof__(*(ptr))) __gu_val; \ __gu_err; \ }) #define __get_user_check(x,ptr,size) \ ({ \ __typeof__(*(ptr)) __gu_val = 0; \ ! long __gu_addr = (long) (ptr); \ long __gu_err; \ \ might_sleep(); \ __gu_err = verify_area(VERIFY_READ, (void *) __gu_addr, size); \ \ if (likely(!__gu_err)) { \ --- 245,262 ---- case 8: __GET_USER_DW(__gu_err); break; \ default: __get_user_unknown(); break; \ } \ ! x = (__typeof__(*(ptr))) __gu_val; \ __gu_err; \ }) #define __get_user_check(x,ptr,size) \ ({ \ __typeof__(*(ptr)) __gu_val = 0; \ ! long __gu_addr; \ long __gu_err; \ \ might_sleep(); \ + __gu_addr = (long) (ptr); \ __gu_err = verify_area(VERIFY_READ, (void *) __gu_addr, size); \ \ if (likely(!__gu_err)) { \ *************** *** 267,273 **** } \ } \ x = (__typeof__(*(ptr))) __gu_val; \ ! __gu_err; \ }) #define __get_user_asm(insn,__gu_err) \ --- 269,275 ---- } \ } \ x = (__typeof__(*(ptr))) __gu_val; \ ! __gu_err; \ }) #define __get_user_asm(insn,__gu_err) \ *************** *** 324,332 **** #define __put_user_nocheck(x,ptr,size) \ ({ \ - long __pu_err = 0; \ __typeof__(*(ptr)) __pu_val; \ long __pu_addr; \ might_sleep(); \ __pu_val = (x); \ __pu_addr = (long) (ptr); \ --- 326,335 ---- #define __put_user_nocheck(x,ptr,size) \ ({ \ __typeof__(*(ptr)) __pu_val; \ long __pu_addr; \ + long __pu_err = 0; \ + \ might_sleep(); \ __pu_val = (x); \ __pu_addr = (long) (ptr); \ *************** *** 342,352 **** #define __put_user_check(x,ptr,size) \ ({ \ ! __typeof__(*(ptr)) __pu_val = (x); \ ! long __pu_addr = (long) (ptr); \ long __pu_err; \ \ might_sleep(); \ __pu_err = verify_area(VERIFY_WRITE, (void *) __pu_addr, size); \ \ if (likely(!__pu_err)) { \ --- 345,357 ---- #define __put_user_check(x,ptr,size) \ ({ \ ! __typeof__(*(ptr)) __pu_val; \ ! long __pu_addr; \ long __pu_err; \ \ might_sleep(); \ + __pu_val = (x); \ + __pu_addr = (long) (ptr); \ __pu_err = verify_area(VERIFY_WRITE, (void *) __pu_addr, size); \ \ if (likely(!__pu_err)) { \ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-mips/war.h linux-current/include/asm-mips/war.h *** linux-2.6.10/include/asm-mips/war.h Sat Dec 25 06:35:40 2004 --- linux-current/include/asm-mips/war.h Wed Jun 14 21:12:59 2006 *************** *** 169,174 **** --- 169,186 ---- #endif /* + * TX49 errata: + * If mfc0 $12 follows store and the mfc0 is last instruction of a + * page and fetching the next instruction causes TLB miss, the result + * of the mfc0 might wrongly contain EXL bit. + * + * Workaround: mask EXL bit of the result or place a nop before mfc0. + */ + #if defined(CONFIG_CPU_TX49XX) + #define TX49XX_MFC0_WAR 1 + #endif + + /* * On the RM9000 there is a problem which makes the CreateDirtyExclusive * cache operation unusable on SMP systems. */ *************** *** 214,219 **** --- 226,234 ---- #ifndef TX49XX_ICACHE_INDEX_INV_WAR #define TX49XX_ICACHE_INDEX_INV_WAR 0 #endif + #ifndef TX49XX_MFC0_WAR + #define TX49XX_MFC0_WAR 0 + #endif #ifndef RM9000_CDEX_SMP_WAR #define RM9000_CDEX_SMP_WAR 0 #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-parisc/relay.h linux-current/include/asm-parisc/relay.h *** linux-2.6.10/include/asm-parisc/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-parisc/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_PARISC_RELAY_H + #define _ASM_PARISC_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-ppc64/relay.h linux-current/include/asm-ppc64/relay.h *** linux-2.6.10/include/asm-ppc64/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-ppc64/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_PPC64_RELAY_H + #define _ASM_PPC64_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-s390/ltt.h linux-current/include/asm-s390/ltt.h *** linux-2.6.10/include/asm-s390/ltt.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-s390/ltt.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,15 ---- + /* + * linux/include/asm-s390/ltt.h + * + * Copyright (C) 2002, Karim Yaghmour + * + * S/390 definitions for tracing system + */ + + #include + + /* Current arch type */ + #define LTT_ARCH_TYPE LTT_ARCH_TYPE_S390 + + /* Current variant type */ + #define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-s390/relay.h linux-current/include/asm-s390/relay.h *** linux-2.6.10/include/asm-s390/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-s390/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_S390_RELAY_H + #define _ASM_S390_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-sh/ltt.h linux-current/include/asm-sh/ltt.h *** linux-2.6.10/include/asm-sh/ltt.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-sh/ltt.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,15 ---- + /* + * linux/include/asm-sh/ltt.h + * + * Copyright (C) 2002, Karim Yaghmour + * + * SuperH definitions for tracing system + */ + + #include + + /* Current arch type */ + #define LTT_ARCH_TYPE LTT_ARCH_TYPE_SH + + /* Current variant type */ + #define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-sh/relay.h linux-current/include/asm-sh/relay.h *** linux-2.6.10/include/asm-sh/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-sh/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_SH_RELAY_H + #define _ASM_SH_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-v850/relay.h linux-current/include/asm-v850/relay.h *** linux-2.6.10/include/asm-v850/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-v850/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef __V850_RELAY_H + #define __V850_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/asm-x86_64/relay.h linux-current/include/asm-x86_64/relay.h *** linux-2.6.10/include/asm-x86_64/relay.h Thu Jan 1 09:00:00 1970 --- linux-current/include/asm-x86_64/relay.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,5 ---- + #ifndef _ASM_X86_64_RELAY_H + #define _ASM_X86_64_RELAY_H + + #include + #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/cramfs_fs.h linux-current/include/linux/cramfs_fs.h *** linux-2.6.10/include/linux/cramfs_fs.h Sat Dec 25 06:35:24 2004 --- linux-current/include/linux/cramfs_fs.h Wed Jun 14 21:12:59 2006 *************** *** 18,28 **** */ #define CRAMFS_MODE_WIDTH 16 #define CRAMFS_UID_WIDTH 16 #define CRAMFS_SIZE_WIDTH 24 #define CRAMFS_GID_WIDTH 8 #define CRAMFS_NAMELEN_WIDTH 6 #define CRAMFS_OFFSET_WIDTH 26 - /* * Since inode.namelen is a unsigned 6-bit number, the maximum cramfs * path length is 63 << 2 = 252. --- 18,33 ---- */ #define CRAMFS_MODE_WIDTH 16 #define CRAMFS_UID_WIDTH 16 + + #if defined(CONFIG_CRAMFS_EXPAND_SIZE) && defined(CONFIG_CRAMFS_SIZE_WIDTH) && CONFIG_CRAMFS_SIZE_WIDTH>24 + #define CRAMFS_SIZE_WIDTH CONFIG_CRAMFS_SIZE_WIDTH + #endif + #ifndef CRAMFS_SIZE_WIDTH #define CRAMFS_SIZE_WIDTH 24 + #endif #define CRAMFS_GID_WIDTH 8 #define CRAMFS_NAMELEN_WIDTH 6 #define CRAMFS_OFFSET_WIDTH 26 /* * Since inode.namelen is a unsigned 6-bit number, the maximum cramfs * path length is 63 << 2 = 252. *************** *** 35,41 **** --- 40,51 ---- struct cramfs_inode { u32 mode:CRAMFS_MODE_WIDTH, uid:CRAMFS_UID_WIDTH; /* SIZE for device files is i_rdev */ + #ifdef CONFIG_CRAMFS_EXPAND_SIZE + u32 size; + u32 gid; + #else u32 size:CRAMFS_SIZE_WIDTH, gid:CRAMFS_GID_WIDTH; + #endif /* NAMELEN is the length of the file name, divided by 4 and rounded up. (cramfs doesn't support hard links.) */ /* OFFSET: For symlinks and non-empty regular files, this diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/cramfs_fs_sb.h linux-current/include/linux/cramfs_fs_sb.h *** linux-2.6.10/include/linux/cramfs_fs_sb.h Sat Dec 25 06:35:25 2004 --- linux-current/include/linux/cramfs_fs_sb.h Wed Jun 14 21:12:59 2006 *************** *** 10,15 **** --- 10,19 ---- unsigned long blocks; unsigned long files; unsigned long flags; + #ifdef CONFIG_CRAMFS_LINEAR + unsigned long linear_phys_addr; + char * linear_virt_addr; + #endif /* CONFIG_CRAMFS_LINEAR */ }; static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/elf.h linux-current/include/linux/elf.h *** linux-2.6.10/include/linux/elf.h Sat Dec 25 06:34:01 2004 --- linux-current/include/linux/elf.h Wed Jun 14 21:12:59 2006 *************** *** 65,71 **** #define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ ! #define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ #define EM_PARISC 15 /* HPPA */ --- 65,71 ---- #define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ ! #define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ #define EM_PARISC 15 /* HPPA */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/i2c-algo-emma.h linux-current/include/linux/i2c-algo-emma.h *** linux-2.6.10/include/linux/i2c-algo-emma.h Thu Jan 1 09:00:00 1970 --- linux-current/include/linux/i2c-algo-emma.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,64 ---- + /* ------------------------------------------------------------------------- */ + /* i2c-algo-emma.h i2c driver algorithms for NEC EMMA2HL I2C adapters */ + /* ------------------------------------------------------------------------- */ + /* Copyright (C) 1995-97 Simon G. Vogl + 1998-99 Hans Berglund + + 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. */ + /* ------------------------------------------------------------------------- */ + + /* With some changes from Kyösti Mälkki and even + Frodo Looijaard */ + + /* Modifications by NEC Electronics Corporation, May 2003 + Changes made to support the I2C peripheral on the NEC EMMA2HL */ + + + #ifndef I2C_ALGO_EMMA_H + #define I2C_ALGO_EMMA_H + + /* --- Defines for pcf-adapters --------------------------------------- */ + #include + + struct i2c_algo_emma_data { + void *data; /* private data for lolevel routines */ + void (*setemma) (void *data, int ctl, int val); + int (*getemma) (void *data, int ctl); + int (*getown) (void *data); + int (*getclock) (void *data); + void (*waitforpin) (void *data); + #ifdef CONFIG_I2C_EMMA_EXIOCTL + void (*setbusy) (void *data, int busy); + int (*getbusy) (void *data); + #endif + + /* local settings */ + int udelay; + int mdelay; + int timeout; + }; + + #define I2C_EMMA_ADAP_MAX 16 + + int i2c_emma_add_bus(struct i2c_adapter *); + int i2c_emma_del_bus(struct i2c_adapter *); + + #ifdef CONFIG_I2C_EMMA_EXIOCTL + #define I2C_EMMA_RESET 730 + #define I2C_EMMA_CHECK_BUSY 731 + #define I2C_EMMA_SET_CLOCK 733 + #define I2C_EMMA_GET_CLOCK 734 + #endif + #endif /* I2C_ALGO_EMMA_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/init.h linux-current/include/linux/init.h *** linux-2.6.10/include/linux/init.h Sat Dec 25 06:33:50 2004 --- linux-current/include/linux/init.h Wed Jun 14 21:12:59 2006 *************** *** 86,91 **** --- 86,93 ---- static initcall_t __initcall_##fn __attribute_used__ \ __attribute__((__section__(".initcall" level ".init"))) = fn + #define early_initcall(fn) __define_initcall(".early1",fn) + #define core_initcall(fn) __define_initcall("1",fn) #define postcore_initcall(fn) __define_initcall("2",fn) #define arch_initcall(fn) __define_initcall("3",fn) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/init_task.h linux-current/include/linux/init_task.h *** linux-2.6.10/include/linux/init_task.h Sat Dec 25 06:33:52 2004 --- linux-current/include/linux/init_task.h Wed Jun 14 21:12:59 2006 *************** *** 55,61 **** #define INIT_SIGHAND(sighand) { \ .count = ATOMIC_INIT(1), \ ! .action = { {{NULL,}}, }, \ .siglock = SPIN_LOCK_UNLOCKED, \ } --- 55,61 ---- #define INIT_SIGHAND(sighand) { \ .count = ATOMIC_INIT(1), \ ! .action = { {{ .sa_handler = NULL,}}, }, \ .siglock = SPIN_LOCK_UNLOCKED, \ } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/klog.h linux-current/include/linux/klog.h *** linux-2.6.10/include/linux/klog.h Thu Jan 1 09:00:00 1970 --- linux-current/include/linux/klog.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,24 ---- + /* + * KLOG Generic Logging facility built upon the relayfs infrastructure + * + * Authors: Hubertus Frankeh (frankeh@us.ibm.com) + * Tom Zanussi (zanussi@us.ibm.com) + * + * Please direct all questions/comments to zanussi@us.ibm.com + * + * Copyright (C) 2003, 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; either version + * 2 of the License, or (at your option) any later version. + */ + + #ifndef _LINUX_KLOG_H + #define _LINUX_KLOG_H + + extern int klog(const char *fmt, ...); + extern int klog_raw(const char *buf,int len); + + #endif /* _LINUX_KLOG_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/ltt-core.h linux-current/include/linux/ltt-core.h *** linux-2.6.10/include/linux/ltt-core.h Thu Jan 1 09:00:00 1970 --- linux-current/include/linux/ltt-core.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,430 ---- + /* + * linux/include/linux/ltt-core.h + * + * Copyright (C) 1999-2004 Karim Yaghmour (karim@opersys.com) + * + * This contains the core definitions for the Linux Trace Toolkit. + */ + + #ifndef _LTT_CORE_H + #define _LTT_CORE_H + + #include + #include + + #include + + /* Is kernel tracing enabled */ + #if defined(CONFIG_LTT) + + #define LTT_CUSTOM_EV_MAX_SIZE 8192 + #define LTT_CUSTOM_EV_TYPE_STR_LEN 20 + #define LTT_CUSTOM_EV_DESC_STR_LEN 100 + #define LTT_CUSTOM_EV_FORM_STR_LEN 256 + #define LTT_CUSTOM_EV_FINAL_STR_LEN 200 + + #define LTT_CUSTOM_EV_FORMAT_TYPE_NONE 0 + #define LTT_CUSTOM_EV_FORMAT_TYPE_STR 1 + #define LTT_CUSTOM_EV_FORMAT_TYPE_HEX 2 + #define LTT_CUSTOM_EV_FORMAT_TYPE_XML 3 + #define LTT_CUSTOM_EV_FORMAT_TYPE_IBM 4 + + #define LTT_MAX_HANDLES 256 + + /* In the ltt root directory lives the trace control file, used for + kernel-user communication. */ + #define LTT_RELAYFS_ROOT "ltt" + #define LTT_CONTROL_FILE "control" + + /* We currently support 2 traces, normal trace and flight recorder */ + #define NR_TRACES 2 + #define TRACE_HANDLE 0 + #define FLIGHT_HANDLE 1 + + /* System types */ + #define LTT_SYS_TYPE_VANILLA_LINUX 1 + + /* Architecture types */ + #define LTT_ARCH_TYPE_I386 1 + #define LTT_ARCH_TYPE_PPC 2 + #define LTT_ARCH_TYPE_SH 3 + #define LTT_ARCH_TYPE_S390 4 + #define LTT_ARCH_TYPE_MIPS 5 + #define LTT_ARCH_TYPE_ARM 6 + + /* Standard definitions for variants */ + #define LTT_ARCH_VARIANT_NONE 0 /* Main architecture implementation */ + + typedef u64 ltt_event_mask; + + /* Per-CPU channel information */ + struct ltt_channel_data + { + int channel_handle; + struct rchan_reader *reader; + atomic_t waiting_for_cpu_async; + u32 events_lost; + }; + + /* Per-trace status info */ + struct ltt_trace_info + { + int active; + unsigned int trace_handle; + int paused; + int flight_recorder; + int use_locking; + int using_tsc; + u32 n_buffers; + u32 buf_size; + ltt_event_mask traced_events; + ltt_event_mask log_event_details_mask; + u32 buffers_produced[NR_CPUS]; + }; + + /* Status info for all traces */ + struct ltt_tracer_status + { + int num_cpus; + struct ltt_trace_info traces[NR_TRACES]; + }; + + /* Per-trace information - each trace/flight recorder represented by one */ + struct ltt_trace_struct + { + unsigned int trace_handle; /* For convenience */ + struct ltt_trace_struct *active; /* 'this' if active, or NULL */ + int paused; /* Not currently logging */ + struct ltt_channel_data relay_data[NR_CPUS];/* Relayfs handles, by CPU */ + int flight_recorder;/* i.e. this is not a trace */ + struct task_struct *daemon_task_struct;/* Daemon associated with trace */ + struct _ltt_trace_start *trace_start_data; /* Trace start event data, for flight recorder */ + int tracer_started; + int tracer_stopping; + struct proc_dir_entry *proc_dir_entry; /* proc/ltt/0..1 */ + ltt_event_mask traced_events; + ltt_event_mask log_event_details_mask; + u32 n_buffers; /* Number of sub-buffers */ + u32 buf_size; /* Size of sub-buffer */ + int use_locking; + int using_tsc; + int log_cpuid; + int tracing_pid; + int tracing_pgrp; + int tracing_gid; + int tracing_uid; + pid_t traced_pid; + pid_t traced_pgrp; + gid_t traced_gid; + uid_t traced_uid; + unsigned long buffer_switches_pending;/* For trace */ + struct work_struct work; /* stop work struct */ + }; + + extern int ltt_set_trace_config( + int do_syscall_depth, + int do_syscall_bounds, + int eip_depth, + void *eip_lower_bound, + void *eip_upper_bound); + extern void ltt_set_flight_recorder_config( + struct ltt_trace_struct *trace); + extern int ltt_get_trace_config( + int *do_syscall_depth, + int *do_syscall_bounds, + int *eip_depth, + void **eip_lower_bound, + void **eip_upper_bound); + extern int ltt_get_status( + struct ltt_tracer_status *tracer_status); + extern int ltt_create_event( + char *event_type, + char *event_desc, + int format_type, + char *format_data); + extern int ltt_create_owned_event( + char *event_type, + char *event_desc, + int format_type, + char *format_data, + pid_t owner_pid); + extern void ltt_destroy_event( + int event_id); + extern void ltt_destroy_owners_events( + pid_t owner_pid); + extern void ltt_reregister_custom_events(void); + extern int ltt_log_std_formatted_event( + int event_id, + ...); + extern int ltt_log_raw_event( + int event_id, + int event_size, + void *event_data); + extern int _ltt_log_event( + struct ltt_trace_struct *trace, + u8 event_id, + void *event_struct, + u8 cpu_id); + extern int ltt_log_event( + u8 event_id, + void *event_struct); + extern int ltt_valid_trace_handle( + unsigned int tracer_handle); + extern int ltt_alloc_trace_handle( + unsigned int tracer_handle); + extern int ltt_free_trace_handle( + unsigned int tracer_handle); + extern int ltt_free_daemon_handle( + struct ltt_trace_struct *trace); + extern void ltt_free_all_handles( + struct task_struct* task_ptr); + extern int ltt_set_buffer_size( + struct ltt_trace_struct *trace, + int buffers_size, + char *dirname); + extern int ltt_set_n_buffers( + struct ltt_trace_struct *trace, + int no_buffers); + extern int ltt_set_default_config( + struct ltt_trace_struct *trace); + extern int ltt_syscall_active( + int syscall_type); + extern void ltt_flight_pause( + void); + extern void ltt_flight_unpause( + void); + + /* Tracer properties */ + #define LTT_TRACER_DEFAULT_BUF_SIZE 50000 + #define LTT_TRACER_MIN_BUF_SIZE 1000 + #define LTT_TRACER_MAX_BUF_SIZE 500000 + #define LTT_TRACER_MIN_BUFFERS 2 + #define LTT_TRACER_MAX_BUFFERS 256 + #define LTT_TRACER_MAGIC_NUMBER 0x00D6B7ED + #define LTT_TRACER_VERSION_MAJOR 2 + #define LTT_TRACER_VERSION_MINOR 2 + + #define LTT_TRACER_FIRST_EVENT_SIZE (sizeof(u8) + sizeof(u32) + sizeof(ltt_buffer_start) + sizeof(uint16_t)) + #define LTT_TRACER_START_TRACE_EVENT_SIZE (sizeof(u8) + sizeof(u32) + sizeof(ltt_trace_start) + sizeof(uint16_t)) + #define LTT_TRACER_LAST_EVENT_SIZE (sizeof(u8) \ + + sizeof(u8) \ + + sizeof(u32) \ + + sizeof(ltt_buffer_end) \ + + sizeof(uint16_t) \ + + sizeof(u32)) + + /* The configurations possible */ + enum { + LTT_TRACER_START = LTT_TRACER_MAGIC_NUMBER, /* Start tracing events using the current configuration */ + LTT_TRACER_STOP, /* Stop tracing */ + LTT_TRACER_CONFIG_DEFAULT, /* Set the tracer to the default configuration */ + LTT_TRACER_CONFIG_MEMORY_BUFFERS, /* Set the memory buffers the daemon wants us to use */ + LTT_TRACER_CONFIG_EVENTS, /* Trace the given events */ + LTT_TRACER_CONFIG_DETAILS, /* Record the details of the event, or not */ + LTT_TRACER_CONFIG_CPUID, /* Record the CPUID associated with the event */ + LTT_TRACER_CONFIG_PID, /* Trace only one process */ + LTT_TRACER_CONFIG_PGRP, /* Trace only the given process group */ + LTT_TRACER_CONFIG_GID, /* Trace the processes of a given group of users */ + LTT_TRACER_CONFIG_UID, /* Trace the processes of a given user */ + LTT_TRACER_CONFIG_SYSCALL_EIP_DEPTH, /* Set the call depth at which the EIP should be fetched on syscall */ + LTT_TRACER_CONFIG_SYSCALL_EIP_LOWER, /* Set the lowerbound address from which EIP is recorded on syscall */ + LTT_TRACER_CONFIG_SYSCALL_EIP_UPPER, /* Set the upperbound address from which EIP is recorded on syscall */ + LTT_TRACER_DATA_COMITTED, /* The daemon has comitted the last trace */ + LTT_TRACER_GET_EVENTS_LOST, /* Get the number of events lost */ + LTT_TRACER_CREATE_USER_EVENT, /* Create a user tracable event */ + LTT_TRACER_DESTROY_USER_EVENT, /* Destroy a user tracable event */ + LTT_TRACER_TRACE_USER_EVENT, /* Trace a user event */ + LTT_TRACER_SET_EVENT_MASK, /* Set the trace event mask */ + LTT_TRACER_GET_EVENT_MASK, /* Get the trace event mask */ + LTT_TRACER_GET_BUFFER_CONTROL, /* Get the buffer control data for the lockless schem*/ + LTT_TRACER_CONFIG_N_MEMORY_BUFFERS, /* Set the number of memory buffers the daemon wants us to use */ + LTT_TRACER_CONFIG_USE_LOCKING, /* Set the locking scheme to use */ + LTT_TRACER_CONFIG_TIMESTAMP, /* Set the timestamping method to use */ + LTT_TRACER_GET_ARCH_INFO, /* Get information about the CPU configuration */ + LTT_TRACER_ALLOC_HANDLE, /* Allocate a tracer handle */ + LTT_TRACER_FREE_HANDLE, /* Free a single handle */ + LTT_TRACER_FREE_DAEMON_HANDLE, /* Free the daemon's handle */ + LTT_TRACER_FREE_ALL_HANDLES, /* Free all handles */ + LTT_TRACER_MAP_BUFFER, /* Map buffer to process-space */ + LTT_TRACER_PAUSE, /* Pause tracing */ + LTT_TRACER_UNPAUSE, /* Unpause tracing */ + LTT_TRACER_GET_START_INFO, /* trace start data */ + LTT_TRACER_GET_STATUS /* status of traces */ + }; + + /* Lockless scheme definitions */ + #define LTT_TRACER_LOCKLESS_MIN_BUF_SIZE LTT_CUSTOM_EV_MAX_SIZE + 8192 + #define LTT_TRACER_LOCKLESS_MAX_BUF_SIZE 0x1000000 + + /* Flags used for per-CPU tasks */ + #define LTT_NOTHING_TO_DO 0x00 + #define LTT_FINALIZE_TRACE 0x02 + #define LTT_TRACE_HEARTBEAT 0x08 + + /* How often the LTT per-CPU timers fire */ + #define LTT_PERCPU_TIMER_FREQ (HZ/10); + + /* Convenience accessors */ + #define waiting_for_cpu_async(trace_handle, cpu) (current_traces[trace_handle].relay_data[cpu].waiting_for_cpu_async) + #define trace_channel_handle(trace_handle, cpu) (current_traces[trace_handle].relay_data[cpu].channel_handle) + #define trace_channel_reader(trace_handle, cpu) (current_traces[trace_handle].relay_data[cpu].reader) + #define trace_buffers_full(cpu) (daemon_relay_data[cpu].buffers_full) + #define events_lost(trace_handle, cpu) (current_traces[trace_handle].relay_data[cpu].events_lost) + + /* Used for sharing per-buffer information between driver and daemon */ + struct ltt_buf_control_info + { + s16 cpu_id; + u32 buffer_switches_pending; + u32 buffer_control_valid; + + u32 buf_size; + u32 n_buffers; + u32 cur_idx; + u32 buffers_produced; + u32 buffers_consumed; + int buffer_complete[LTT_TRACER_MAX_BUFFERS]; + }; + + /* Used for sharing buffer-commit information between driver and daemon */ + struct ltt_buffers_committed + { + u8 cpu_id; + u32 buffers_consumed; + }; + + /* Used for specifying size/cpu id pair between driver and daemon */ + struct ltt_cpu_mmap_data + { + u8 cpu_id; + unsigned long map_size; + }; + + /* Used for sharing architecture-specific info between driver and daemon */ + struct ltt_arch_info + { + int n_cpus; + int page_shift; + }; + + extern __inline__ int ltt_set_bit(int nr, void *addr) + { + unsigned char *p = addr; + unsigned char mask = 1 << (nr & 7); + unsigned char old; + + p += nr >> 3; + old = *p; + *p |= mask; + + return ((old & mask) != 0); + } + + extern __inline__ int ltt_clear_bit(int nr, void *addr) + { + unsigned char *p = addr; + unsigned char mask = 1 << (nr & 7); + unsigned char old; + + p += nr >> 3; + old = *p; + *p &= ~mask; + + return ((old & mask) != 0); + } + + extern __inline__ int ltt_test_bit(int nr, void *addr) + { + unsigned char *p = addr; + unsigned char mask = 1 << (nr & 7); + + p += nr >> 3; + + return ((*p & mask) != 0); + } + + #if !defined(CONFIG_X86) + # define cpu_has_tsc 0 /* FIXME: cpu_has_tsc isn't set except on x86 */ + #endif + + /** + * switch_time_delta: - Utility function getting buffer switch time delta. + * @time_delta: previously calculated or retrieved time delta + * + * Returns the time_delta passed in if we're using TSC or 0 otherwise. + */ + static inline u32 switch_time_delta(u32 time_delta, + int using_tsc) + { + if((using_tsc == 1) && cpu_has_tsc) + return time_delta; + else + return 0; + } + + #else /* defined(CONFIG_LTT) */ + static inline int ltt_create_event(char *event_type, + char *event_desc, + int format_type, + char *format_data) + { + return 0; + } + + static inline int ltt_create_owned_event(char *event_type, + char *event_desc, + int format_type, + char *format_data, + pid_t owner_pid) + { + return 0; + } + + static inline void ltt_destroy_event(int event_id) + { + } + + static inline void ltt_destroy_owners_events(pid_t owner_pid) + { + } + + static inline void ltt_reregister_custom_events(void) + { + } + + static inline int ltt_log_std_formatted_event(int event_id, ...) + { + return 0; + } + + + static inline int ltt_log_raw_event(int event_id, + int event_size, + void *event_data) + { + return 0; + } + + static inline int _ltt_log_event(u8 event_id, + void *event_struct, + u8 cpu_id) + { + return 0; + } + + static inline int ltt_log_event(u8 event_id, + void *event_struct) + { + return 0; + } + + static inline void ltt_flight_pause(void) + { + } + + static inline void ltt_flight_unpause(void) + { + } + + #endif /* defined(CONFIG_LTT) */ + #endif /* _LTT_CORE_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/ltt-events.h linux-current/include/linux/ltt-events.h *** linux-2.6.10/include/linux/ltt-events.h Thu Jan 1 09:00:00 1970 --- linux-current/include/linux/ltt-events.h Wed Jun 14 21:12:59 2006 *************** *** 0 **** --- 1,428 ---- + /* + * linux/include/linux/ltt-events.h + * + * Copyright (C) 1999-2004 Karim Yaghmour (karim@opersys.com) + * + * This contains the event definitions for the Linux Trace Toolkit. + */ + + #ifndef _LTT_EVENTS_H + #define _LTT_EVENTS_H + + #include + #include + + /* Is kernel tracing enabled */ + #if defined(CONFIG_LTT) + + /* Don't set this to "1" unless you really know what you're doing */ + #define LTT_UNPACKED_STRUCTS 0 + + /* Structure packing within the trace */ + #if LTT_UNPACKED_STRUCTS + #define LTT_PACKED_STRUCT + #else + #define LTT_PACKED_STRUCT __attribute__ ((packed)) + #endif + + extern unsigned int ltt_syscall_entry_trace_active; + extern unsigned int ltt_syscall_exit_trace_active; + + static inline void ltt_ev(u8 event_id, void* data) + { + ltt_log_event(event_id, data); + } + + /* Traced events */ + enum { + LTT_EV_START = 0, /* This is to mark the trace's start */ + LTT_EV_SYSCALL_ENTRY, /* Entry in a given system call */ + LTT_EV_SYSCALL_EXIT, /* Exit from a given system call */ + LTT_EV_TRAP_ENTRY, /* Entry in a trap */ + LTT_EV_TRAP_EXIT, /* Exit from a trap */ + LTT_EV_IRQ_ENTRY, /* Entry in an irq */ + LTT_EV_IRQ_EXIT, /* Exit from an irq */ + LTT_EV_SCHEDCHANGE, /* Scheduling change */ + LTT_EV_KERNEL_TIMER, /* The kernel timer routine has been called */ + LTT_EV_SOFT_IRQ, /* Hit key part of soft-irq management */ + LTT_EV_PROCESS, /* Hit key part of process management */ + LTT_EV_FILE_SYSTEM, /* Hit key part of file system */ + LTT_EV_TIMER, /* Hit key part of timer management */ + LTT_EV_MEMORY, /* Hit key part of memory management */ + LTT_EV_SOCKET, /* Hit key part of socket communication */ + LTT_EV_IPC, /* Hit key part of System V IPC */ + LTT_EV_NETWORK, /* Hit key part of network communication */ + LTT_EV_BUFFER_START, /* Mark the begining of a trace buffer */ + LTT_EV_BUFFER_END, /* Mark the ending of a trace buffer */ + LTT_EV_NEW_EVENT, /* New event type */ + LTT_EV_CUSTOM, /* Custom event */ + LTT_EV_CHANGE_MASK, /* Change in event mask */ + LTT_EV_HEARTBEAT /* Heartbeat event */ + }; + + /* Number of traced events */ + #define LTT_EV_MAX LTT_EV_HEARTBEAT + + /* Information logged when a trace is started */ + typedef struct _ltt_trace_start { + u32 magic_number; + u32 arch_type; + u32 arch_variant; + u32 system_type; + u8 major_version; + u8 minor_version; + + u32 buffer_size; + ltt_event_mask event_mask; + ltt_event_mask details_mask; + u8 log_cpuid; + u8 use_tsc; + u8 flight_recorder; + } LTT_PACKED_STRUCT ltt_trace_start; + + /* LTT_SYSCALL_ENTRY */ + typedef struct _ltt_syscall_entry { + #ifdef __mips__ + u32 syscall_id; /* Syscall entry number in entry.S */ + #else + u8 syscall_id; /* Syscall entry number in entry.S */ + #endif + u32 address; /* Address from which call was made */ + } LTT_PACKED_STRUCT ltt_syscall_entry; + + /* LTT_TRAP_ENTRY */ + #ifndef __s390__ + typedef struct _ltt_trap_entry { + u16 trap_id; /* Trap number */ + u32 address; /* Address where trap occured */ + } LTT_PACKED_STRUCT ltt_trap_entry; + static inline void ltt_ev_trap_entry(u16 trap_id, u32 address) + #else + typedef u64 trapid_t; + typedef struct _ltt_trap_entry { + trapid_t trap_id; /* Trap number */ + u32 address; /* Address where trap occured */ + } LTT_PACKED_STRUCT ltt_trap_entry; + static inline void ltt_ev_trap_entry(trapid_t trap_id, u32 address) + #endif + { + ltt_trap_entry trap_event; + + trap_event.trap_id = trap_id; + trap_event.address = address; + + ltt_log_event(LTT_EV_TRAP_ENTRY, &trap_event); + } + + /* LTT_TRAP_EXIT */ + static inline void ltt_ev_trap_exit(void) + { + ltt_log_event(LTT_EV_TRAP_EXIT, NULL); + } + + /* LTT_IRQ_ENTRY */ + typedef struct _ltt_irq_entry { + u8 irq_id; /* IRQ number */ + u8 kernel; /* Are we executing kernel code */ + } LTT_PACKED_STRUCT ltt_irq_entry; + static inline void ltt_ev_irq_entry(u8 irq_id, u8 in_kernel) + { + ltt_irq_entry irq_entry; + + irq_entry.irq_id = irq_id; + irq_entry.kernel = in_kernel; + + ltt_log_event(LTT_EV_IRQ_ENTRY, &irq_entry); + } + + /* LTT_IRQ_EXIT */ + static inline void ltt_ev_irq_exit(void) + { + ltt_log_event(LTT_EV_IRQ_EXIT, NULL); + } + + /* LTT_SCHEDCHANGE */ + typedef struct _ltt_schedchange { + u32 out; /* Outgoing process */ + u32 in; /* Incoming process */ + u32 out_state; /* Outgoing process' state */ + } LTT_PACKED_STRUCT ltt_schedchange; + static inline void ltt_ev_schedchange(task_t * task_out, task_t * task_in) + { + ltt_schedchange sched_event; + + sched_event.out = (u32) task_out->pid; + sched_event.in = (u32) task_in; + sched_event.out_state = (u32) task_out->state; + + ltt_log_event(LTT_EV_SCHEDCHANGE, &sched_event); + } + + /* LTT_SOFT_IRQ */ + enum { + LTT_EV_SOFT_IRQ_BOTTOM_HALF = 1, /* Conventional bottom-half */ + LTT_EV_SOFT_IRQ_SOFT_IRQ, /* Real soft-irq */ + LTT_EV_SOFT_IRQ_TASKLET_ACTION, /* Tasklet action */ + LTT_EV_SOFT_IRQ_TASKLET_HI_ACTION /* Tasklet hi-action */ + }; + typedef struct _ltt_soft_irq { + u8 event_sub_id; /* Soft-irq event Id */ + u32 event_data; + } LTT_PACKED_STRUCT ltt_soft_irq; + static inline void ltt_ev_soft_irq(u8 ev_id, u32 data) + { + ltt_soft_irq soft_irq_event; + + soft_irq_event.event_sub_id = ev_id; + soft_irq_event.event_data = data; + + ltt_log_event(LTT_EV_SOFT_IRQ, &soft_irq_event); + } + + /* LTT_PROCESS */ + enum { + LTT_EV_PROCESS_KTHREAD = 1, /* Creation of a kernel thread */ + LTT_EV_PROCESS_FORK, /* A fork or clone occured */ + LTT_EV_PROCESS_EXIT, /* An exit occured */ + LTT_EV_PROCESS_WAIT, /* A wait occured */ + LTT_EV_PROCESS_SIGNAL, /* A signal has been sent */ + LTT_EV_PROCESS_WAKEUP /* Wake up a process */ + }; + typedef struct _ltt_process { + u8 event_sub_id; /* Process event ID */ + u32 event_data1; + u32 event_data2; + } LTT_PACKED_STRUCT ltt_process; + static inline void ltt_ev_process(u8 ev_id, u32 data1, u32 data2) + { + ltt_process proc_event; + + proc_event.event_sub_id = ev_id; + proc_event.event_data1 = data1; + proc_event.event_data2 = data2; + + ltt_log_event(LTT_EV_PROCESS, &proc_event); + } + static inline void ltt_ev_process_exit(u32 data1, u32 data2) + { + ltt_process proc_event; + + proc_event.event_sub_id = LTT_EV_PROCESS_EXIT; + + /**** WARNING ****/ + /* Regardless of whether this trace statement is active or not, these + two function must be called, otherwise there will be inconsistencies + in the kernel's structures. */ + ltt_destroy_owners_events(current->pid); + ltt_free_all_handles(current); + + ltt_log_event(LTT_EV_PROCESS, &proc_event); + } + + /* LTT_FILE_SYSTEM */ + enum { + LTT_EV_FILE_SYSTEM_BUF_WAIT_START = 1, /* Starting to wait for a data buffer */ + LTT_EV_FILE_SYSTEM_BUF_WAIT_END, /* End to wait for a data buffer */ + LTT_EV_FILE_SYSTEM_EXEC, /* An exec occured */ + LTT_EV_FILE_SYSTEM_OPEN, /* An open occured */ + LTT_EV_FILE_SYSTEM_CLOSE, /* A close occured */ + LTT_EV_FILE_SYSTEM_READ, /* A read occured */ + LTT_EV_FILE_SYSTEM_WRITE, /* A write occured */ + LTT_EV_FILE_SYSTEM_SEEK, /* A seek occured */ + LTT_EV_FILE_SYSTEM_IOCTL, /* An ioctl occured */ + LTT_EV_FILE_SYSTEM_SELECT, /* A select occured */ + LTT_EV_FILE_SYSTEM_POLL /* A poll occured */ + }; + typedef struct _ltt_file_system { + u8 event_sub_id; /* File system event ID */ + u32 event_data1; + u32 event_data2; + char *file_name; /* Name of file operated on */ + } LTT_PACKED_STRUCT ltt_file_system; + static inline void ltt_ev_file_system(u8 ev_id, u32 data1, u32 data2, const unsigned char *file_name) + { + ltt_file_system fs_event; + + fs_event.event_sub_id = ev_id; + fs_event.event_data1 = data1; + fs_event.event_data2 = data2; + fs_event.file_name = (char*) file_name; + + ltt_log_event(LTT_EV_FILE_SYSTEM, &fs_event); + } + + /* LTT_TIMER */ + enum { + LTT_EV_TIMER_EXPIRED = 1, /* Timer expired */ + LTT_EV_TIMER_SETITIMER, /* Setting itimer occurred */ + LTT_EV_TIMER_SETTIMEOUT /* Setting sched timeout occurred */ + }; + typedef struct _ltt_timer { + u8 event_sub_id; /* Timer event ID */ + u8 event_sdata; /* Short data */ + u32 event_data1; + u32 event_data2; + } LTT_PACKED_STRUCT ltt_timer; + static inline void ltt_ev_timer(u8 ev_id, u8 sdata, u32 data1, u32 data2) + { + ltt_timer timer_event; + + timer_event.event_sub_id = ev_id; + timer_event.event_sdata = sdata; + timer_event.event_data1 = data1; + timer_event.event_data2 = data2; + + ltt_log_event(LTT_EV_TIMER, &timer_event); + } + + /* LTT_MEMORY */ + enum { + LTT_EV_MEMORY_PAGE_ALLOC = 1, /* Allocating pages */ + LTT_EV_MEMORY_PAGE_FREE, /* Freing pages */ + LTT_EV_MEMORY_SWAP_IN, /* Swaping pages in */ + LTT_EV_MEMORY_SWAP_OUT, /* Swaping pages out */ + LTT_EV_MEMORY_PAGE_WAIT_START, /* Start to wait for page */ + LTT_EV_MEMORY_PAGE_WAIT_END /* End to wait for page */ + }; + typedef struct _ltt_memory { + u8 event_sub_id; /* Memory event ID */ + u32 event_data; + } LTT_PACKED_STRUCT ltt_memory; + static inline void ltt_ev_memory(u8 ev_id, u32 data) + { + ltt_memory memory_event; + + memory_event.event_sub_id = ev_id; + memory_event.event_data = data; + + ltt_log_event(LTT_EV_MEMORY, &memory_event); + } + + /* LTT_SOCKET */ + enum { + LTT_EV_SOCKET_CALL = 1, /* A socket call occured */ + LTT_EV_SOCKET_CREATE, /* A socket has been created */ + LTT_EV_SOCKET_SEND, /* Data was sent to a socket */ + LTT_EV_SOCKET_RECEIVE /* Data was read from a socket */ + }; + typedef struct _ltt_socket { + u8 event_sub_id; /* Socket event ID */ + u32 event_data1; + u32 event_data2; + } LTT_PACKED_STRUCT ltt_socket; + static inline void ltt_ev_socket(u8 ev_id, u32 data1, u32 data2) + { + ltt_socket socket_event; + + socket_event.event_sub_id = ev_id; + socket_event.event_data1 = data1; + socket_event.event_data2 = data2; + + ltt_log_event(LTT_EV_SOCKET, &socket_event); + } + + /* LTT_IPC */ + enum { + LTT_EV_IPC_CALL = 1, /* A System V IPC call occured */ + LTT_EV_IPC_MSG_CREATE, /* A message queue has been created */ + LTT_EV_IPC_SEM_CREATE, /* A semaphore was created */ + LTT_EV_IPC_SHM_CREATE /* A shared memory segment has been created */ + }; + typedef struct _ltt_ipc { + u8 event_sub_id; /* IPC event ID */ + u32 event_data1; + u32 event_data2; + } LTT_PACKED_STRUCT ltt_ipc; + static inline void ltt_ev_ipc(u8 ev_id, u32 data1, u32 data2) + { + ltt_ipc ipc_event; + + ipc_event.event_sub_id = ev_id; + ipc_event.event_data1 = data1; + ipc_event.event_data2 = data2; + + ltt_log_event(LTT_EV_IPC, &ipc_event); + } + + /* LTT_NETWORK */ + enum { + LTT_EV_NETWORK_PACKET_IN = 1, /* A packet came in */ + LTT_EV_NETWORK_PACKET_OUT /* A packet was sent */ + }; + typedef struct _ltt_network { + u8 event_sub_id; /* Network event ID */ + u32 event_data; + } LTT_PACKED_STRUCT ltt_network; + static inline void ltt_ev_network(u8 ev_id, u32 data) + { + ltt_network net_event; + + net_event.event_sub_id = ev_id; + net_event.event_data = data; + + ltt_log_event(LTT_EV_NETWORK, &net_event); + } + + /* Start of trace buffer information */ + typedef struct _ltt_buffer_start { + struct timeval time; /* Time stamp of this buffer */ + u32 tsc; /* TSC of this buffer, if applicable */ + u32 id; /* Unique buffer ID */ + } LTT_PACKED_STRUCT ltt_buffer_start; + + /* End of trace buffer information */ + typedef struct _ltt_buffer_end { + struct timeval time; /* Time stamp of this buffer */ + u32 tsc; /* TSC of this buffer, if applicable */ + } LTT_PACKED_STRUCT ltt_buffer_end; + + /* Custom declared events */ + /* ***WARNING*** These structures should never be used as is, use the + provided custom event creation and logging functions. */ + typedef struct _ltt_new_event { + /* Basics */ + u32 id; /* Custom event ID */ + char type[LTT_CUSTOM_EV_TYPE_STR_LEN]; /* Event type description */ + char desc[LTT_CUSTOM_EV_DESC_STR_LEN]; /* Detailed event description */ + + /* Custom formatting */ + u32 format_type; /* Type of formatting */ + char form[LTT_CUSTOM_EV_FORM_STR_LEN]; /* Data specific to format */ + } LTT_PACKED_STRUCT ltt_new_event; + typedef struct _ltt_custom { + u32 id; /* Event ID */ + u32 data_size; /* Size of data recorded by event */ + void *data; /* Data recorded by event */ + } LTT_PACKED_STRUCT ltt_custom; + + /* LTT_CHANGE_MASK */ + typedef struct _ltt_change_mask { + ltt_event_mask mask; /* Event mask */ + } LTT_PACKED_STRUCT ltt_change_mask; + + + /* LTT_HEARTBEAT */ + static inline void ltt_ev_heartbeat(void) + { + ltt_log_event(LTT_EV_HEARTBEAT, NULL); + } + + #else /* defined(CONFIG_LTT) */ + #define ltt_ev(ID, DATA) + #define ltt_ev_trap_entry(ID, EIP) + #define ltt_ev_trap_exit() + #define ltt_ev_irq_entry(ID, KERNEL) + #define ltt_ev_irq_exit() + #define ltt_ev_schedchange(OUT, IN) + #define ltt_ev_soft_irq(ID, DATA) + #define ltt_ev_process(ID, DATA1, DATA2) + #define ltt_ev_process_exit(DATA1, DATA2) + #define ltt_ev_file_system(ID, DATA1, DATA2, FILE_NAME) + #define ltt_ev_timer(ID, SDATA, DATA1, DATA2) + #define ltt_ev_memory(ID, DATA) + #define ltt_ev_socket(ID, DATA1, DATA2) + #define ltt_ev_ipc(ID, DATA1, DATA2) + #define ltt_ev_network(ID, DATA) + #define ltt_ev_heartbeat() + #endif /* defined(CONFIG_LTT) */ + #endif /* _LTT_EVENTS_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/mm.h linux-current/include/linux/mm.h *** linux-2.6.10/include/linux/mm.h Sat Dec 25 06:33:50 2004 --- linux-current/include/linux/mm.h Wed Jun 14 21:12:59 2006 *************** *** 140,145 **** --- 140,146 ---- #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */ #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */ #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */ + #define VM_XIP 0x00200000 /* Execute In Place from ROM/flash */ #define VM_ACCOUNT 0x00100000 /* Is a VM accounted object */ #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/mtd/map.h linux-current/include/linux/mtd/map.h *** linux-2.6.10/include/linux/mtd/map.h Sat Dec 25 06:34:31 2004 --- linux-current/include/linux/mtd/map.h Wed Jun 14 21:13:00 2006 *************** *** 322,328 **** bitpos = (map_bankwidth(map)-1-i)*8; #endif orig.x[0] &= ~(0xff << bitpos); ! orig.x[0] |= buf[i] << bitpos; } } return orig; --- 322,328 ---- bitpos = (map_bankwidth(map)-1-i)*8; #endif orig.x[0] &= ~(0xff << bitpos); ! orig.x[0] |= buf[i-start] << bitpos; } } return orig; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/pci_ids.h linux-current/include/linux/pci_ids.h *** linux-2.6.10/include/linux/pci_ids.h Sat Dec 25 06:35:50 2004 --- linux-current/include/linux/pci_ids.h Wed Jun 14 21:12:59 2006 *************** *** 1450,1456 **** --- 1450,1463 ---- #define PCI_VENDOR_ID_TOSHIBA_2 0x102f #define PCI_DEVICE_ID_TOSHIBA_TX3927 0x000a #define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030 + #define PCI_DEVICE_ID_TOSHIBA_TC35815_NWU 0x0031 + #define PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE 0x0105 + #define PCI_DEVICE_ID_TOSHIBA_TC86C001_USB 0x0106 + #define PCI_DEVICE_ID_TOSHIBA_TC86C001_USBD 0x0107 + #define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 #define PCI_DEVICE_ID_TOSHIBA_TX4927 0x0180 + #define PCI_DEVICE_ID_TOSHIBA_CHIP1S_USB 0x0192 + #define PCI_DEVICE_ID_TOSHIBA_CHIP1S_USB2 0x0193 #define PCI_VENDOR_ID_RICOH 0x1180 #define PCI_DEVICE_ID_RICOH_RL5C465 0x0465 diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/pram_fs.h linux-current/include/linux/pram_fs.h *** linux-2.6.10/include/linux/pram_fs.h Thu Jan 1 09:00:00 1970 --- linux-current/include/linux/pram_fs.h Wed Jun 14 21:13:00 2006 *************** *** 0 **** --- 1,378 ---- + /* + * pram_fs.h + * + * Definitions for the PRAMFS filesystem. + * + * Author: Steve Longerbeam + * + * 2003 (c) MontaVista Software, Inc. + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * + * This software is being distributed under the terms of the GNU General Public + * License version 2. Some or all of the technology encompassed by this + * software may be subject to one or more patents pending as of the date of + * this notice. No additional patent license will be required for GPL + * implementations of the technology. If you want to create a non-GPL + * implementation of the technology encompassed by this software, please + * contact legal@mvista.com for details including licensing terms and fees. + * + * 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 _LINUX_PRAM_FS_H + #define _LINUX_PRAM_FS_H + + #include + #include + + #ifdef __KERNEL__ + #include + #endif + + /* + * The PRAM filesystem constants/structures + */ + + /* + * Define PRAMFS_DEBUG to produce debug messages + */ + #undef PRAMFS_DEBUG + + /* + * The PRAM filesystem version + */ + #define PRAMFS_DATE "2003/06/15" + #define PRAMFS_VERSION "0.1b" + + /* + * Debug code + */ + #ifdef __KERNEL__ + #define PFX "pramfs" + #ifdef PRAMFS_DEBUG + #define pram_dbg(format, arg...) \ + printk(KERN_DEBUG PFX ": " format , ## arg) + #else + #define pram_dbg(format, arg...) do {} while (0) + #endif + #define pram_err(format, arg...) \ + printk(KERN_ERR PFX ": " format , ## arg) + #define pram_info(format, arg...) \ + printk(KERN_INFO PFX ": " format , ## arg) + #define pram_warn(format, arg...) \ + printk(KERN_WARNING PFX ": " format , ## arg) + #endif + + /* + * The PRAM file system magic number + */ + #define PRAM_SUPER_MAGIC 0xEFFA + + /* + * Maximal count of links to a file + */ + #define PRAM_LINK_MAX 32000 + + typedef unsigned long pram_off_t; + + #define PRAM_MIN_BLOCK_SIZE 512 + #define PRAM_MAX_BLOCK_SIZE 4096 + #define PRAM_DEF_BLOCK_SIZE 2048 + + #define PRAM_INODE_SIZE 128 // must be power of two + #define PRAM_INODE_BITS 7 + + /* + * Structure of a directory entry in PRAMFS. + * Offsets are to the inode that holds the referenced dentry. + */ + struct pram_dentry { + pram_off_t d_next; /* next dentry in this directory */ + pram_off_t d_prev; /* previous dentry in this directory */ + pram_off_t d_parent; /* parent directory */ + char d_name[0]; + }; + + + /* + * Structure of an inode in PRAMFS + */ + struct pram_inode { + __u32 i_sum; /* checksum of this inode */ + __u32 i_uid; /* Owner Uid */ + __u32 i_gid; /* Group Id */ + __u16 i_mode; /* File mode */ + __u16 i_links_count; /* Links count */ + __u32 i_blocks; /* Blocks count */ + __u32 i_size; /* Size of data in bytes */ + __u32 i_atime; /* Access time */ + __u32 i_ctime; /* Creation time */ + __u32 i_mtime; /* Modification time */ + __u32 i_dtime; /* Deletion Time */ + + union { + struct { + /* + * ptr to row block of 2D block pointer array, + * file block #'s 0 to (blocksize/4)^2 - 1. + */ + pram_off_t row_block; + } reg; // regular file or symlink inode + struct { + pram_off_t head; /* first entry in this directory */ + pram_off_t tail; /* last entry in this directory */ + } dir; + struct { + __u32 rdev; /* major/minor # */ + } dev; // device inode + } i_type; + + struct pram_dentry i_d; + }; + + #define PRAM_NAME_LEN \ + (PRAM_INODE_SIZE - offsetof(struct pram_inode, i_d.d_name) - 1) + + + /* + * Behaviour when detecting errors + */ + #define PRAM_ERRORS_CONTINUE 1 /* Continue execution */ + #define PRAM_ERRORS_RO 2 /* Remount fs read-only */ + #define PRAM_ERRORS_PANIC 3 /* Panic */ + #define PRAM_ERRORS_DEFAULT PRAM_ERRORS_CONTINUE + + #define PRAM_SB_SIZE 128 // must be power of two + #define PRAM_SB_BITS 7 + + /* + * Structure of the super block in PRAMFS + */ + struct pram_super_block { + __u32 s_size; /* total size of fs in bytes */ + __u32 s_blocksize; /* blocksize in bytes */ + __u32 s_features; /* feature flags */ + __u32 s_inodes_count; /* total inodes count (used or free) */ + __u32 s_free_inodes_count;/* free inodes count */ + __u32 s_free_inode_hint; /* start hint for locating free inodes */ + __u32 s_blocks_count; /* total data blocks count (used or free) */ + __u32 s_free_blocks_count;/* free data blocks count */ + __u32 s_free_blocknr_hint;/* free data blocks count */ + pram_off_t s_bitmap_start; /* data block in-use bitmap location */ + __u32 s_bitmap_blocks;/* size of bitmap in number of blocks */ + __u32 s_mtime; /* Mount time */ + __u32 s_wtime; /* Write time */ + __u32 s_rev_level; /* Revision level */ + __u16 s_magic; /* Magic signature */ + __u16 s_state; /* File system state */ + __u16 s_errors; /* Behaviour when detecting errors */ + char s_volume_name[16]; /* volume name */ + __u32 s_sum; /* checksum of this sb, including padding */ + }; + + /* The root inode follows immediately after the super block */ + #define PRAM_ROOT_INO PRAM_SB_SIZE + + #ifdef __KERNEL__ + + /* Function Prototypes */ + + /* balloc.c */ + extern void pram_init_bitmap(struct super_block * sb); + extern void pram_free_block (struct super_block * sb, int blocknr); + extern int pram_new_block (struct super_block * sb, int* blocknr, int zero); + extern unsigned long pram_count_free_blocks (struct super_block * sb); + + /* dir.c */ + extern int pram_add_link (struct dentry * dentry, struct inode *inode); + extern int pram_remove_link(struct inode * inode); + + /* file.c */ + extern int pram_direct_IO(int rw, struct kiocb *iocb, + const struct iovec *iov, + loff_t offset, unsigned long nr_segs); + + /* fsync.c */ + extern int pram_sync_file (struct file *, struct dentry *, int); + extern int pram_fsync_inode (struct inode *, int); + + /* inode.c */ + extern int pram_alloc_blocks(struct inode * inode, int file_blocknr, int num); + extern pram_off_t pram_find_data_block(struct inode * inode, + int file_blocknr); + extern struct inode * pram_fill_new_inode(struct super_block *sb, + struct pram_inode * raw_inode); + extern void pram_put_inode (struct inode * inode); + extern void pram_delete_inode (struct inode * inode); + extern struct inode * pram_new_inode (const struct inode * dir, int mode); + extern void pram_read_inode (struct inode * inode); + extern void pram_truncate (struct inode * inode); + extern void pram_write_inode (struct inode * inode, int wait); + extern void pram_dirty_inode(struct inode * inode); + + /* ioctl.c */ + extern int pram_ioctl (struct inode *, struct file *, unsigned int, + unsigned long); + + /* super.c */ + extern struct super_block * find_pramfs_super(void); + extern struct super_block * pram_read_super (struct super_block * sb, + void * data, + int silent); + extern int pram_statfs (struct super_block * sb, struct kstatfs * buf); + extern int pram_remount (struct super_block * sb, int * flags, char * data); + + /* symlink.c */ + extern int pram_block_symlink(struct inode *inode, + const char *symname, int len); + + /* wprotect.c */ + #ifndef CONFIG_PRAMFS_NOWP + extern void pram_writeable (void * vaddr, unsigned long size, int rw); + #endif + + /* Inline functions start here */ + + static inline u32 pram_calc_checksum(u32* buf, int n) + { + u32 sum = 0; + while (n--) + sum += *buf++; + return sum; + } + + // If this is part of a read-modify-write of the super block, + // pram_lock_super() before calling! + static inline struct pram_super_block * + pram_get_super(struct super_block * sb) + { + struct pram_sb_info * sbi = (struct pram_sb_info *)sb->s_fs_info; + return (struct pram_super_block *)sbi->virt_addr; + } + + // pram_lock_super() before calling! + static inline void pram_sync_super(struct pram_super_block * ps) + { + ps->s_wtime = get_seconds(); + ps->s_sum = 0; + ps->s_sum = - pram_calc_checksum((u32*)ps, PRAM_SB_SIZE>>2); + } + + // pram_lock_inode() before calling! + static inline void pram_sync_inode(struct pram_inode * pi) + { + //pi->i_mtime = CURRENT_TIME; + pi->i_sum = 0; + pi->i_sum = - pram_calc_checksum((u32*)pi, PRAM_INODE_SIZE>>2); + } + + #ifndef CONFIG_PRAMFS_NOWP + #define pram_lock_range(p, len) {\ + spin_lock_irqsave(&init_mm.page_table_lock, flags);\ + pram_writeable((p), (len), 1);\ + } + + #define pram_unlock_range(p, len) {\ + pram_writeable((p), (len), 0);\ + spin_unlock_irqrestore(&init_mm.page_table_lock, flags);\ + } + #else + #define pram_lock_range(p, len) do {} while (0) + #define pram_unlock_range(p, len) do {} while (0) + #endif + + // write protection for super block + #define pram_lock_super(ps) \ + pram_lock_range((ps), PRAM_SB_SIZE) + #define pram_unlock_super(ps) {\ + pram_sync_super(ps);\ + pram_unlock_range((ps), PRAM_SB_SIZE);\ + } + + // write protection for inode metadata + #define pram_lock_inode(pi) \ + pram_lock_range((pi), PRAM_INODE_SIZE) + #define pram_unlock_inode(pi) {\ + pram_sync_inode(pi);\ + pram_unlock_range((pi), PRAM_SB_SIZE);\ + } + + // write protection for a data block + #define pram_lock_block(sb, bp) \ + pram_lock_range((bp), (sb)->s_blocksize) + #define pram_unlock_block(sb, bp) \ + pram_unlock_range((bp), (sb)->s_blocksize) + + static inline void * + pram_get_bitmap(struct super_block * sb) + { + struct pram_super_block * ps = pram_get_super(sb); + return ((void*)ps + ps->s_bitmap_start); + } + + // If this is part of a read-modify-write of the inode metadata, + // pram_lock_inode() before calling! + static inline struct pram_inode * + pram_get_inode(struct super_block * sb, pram_off_t ino) + { + struct pram_super_block * ps = pram_get_super(sb); + return ino ? (struct pram_inode *)((void*)ps + ino) : NULL; + } + + static inline ino_t + pram_get_inodenr(struct super_block * sb, struct pram_inode * pi) + { + struct pram_super_block * ps = pram_get_super(sb); + return (ino_t)((unsigned long)pi - (unsigned long)ps); + } + + static inline pram_off_t + pram_get_block_off(struct super_block * sb, unsigned long blocknr) + { + struct pram_super_block * ps = pram_get_super(sb); + return (pram_off_t)(ps->s_bitmap_start + + (blocknr << sb->s_blocksize_bits)); + } + + static inline unsigned long + pram_get_blocknr(struct super_block * sb, pram_off_t block) + { + struct pram_super_block * ps = pram_get_super(sb); + return (block - ps->s_bitmap_start) >> sb->s_blocksize_bits; + } + + // If this is part of a read-modify-write of the block, + // pram_lock_block() before calling! + static inline void * + pram_get_block(struct super_block * sb, pram_off_t block) + { + struct pram_super_block * ps = pram_get_super(sb); + return block ? ((void*)ps + block) : NULL; + } + + + /* + * Inodes and files operations + */ + + /* dir.c */ + extern struct file_operations pram_dir_operations; + + /* file.c */ + extern struct inode_operations pram_file_inode_operations; + extern struct file_operations pram_file_operations; + + /* inode.c */ + extern struct address_space_operations pram_aops; + + /* namei.c */ + extern struct inode_operations pram_dir_inode_operations; + + /* symlink.c */ + extern struct inode_operations pram_symlink_inode_operations; + + #endif /* __KERNEL__ */ + + #endif /* _LINUX_PRAM_FS_H */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/pram_fs_sb.h linux-current/include/linux/pram_fs_sb.h *** linux-2.6.10/include/linux/pram_fs_sb.h Thu Jan 1 09:00:00 1970 --- linux-current/include/linux/pram_fs_sb.h Wed Jun 14 21:13:00 2006 *************** *** 0 **** --- 1,43 ---- + /* + * pram_fs_sb.h + * + * Definitions for the PRAM filesystem. + * + * Author: Steve Longerbeam + * + * 2003 (c) MontaVista Software, Inc. + * Copyright 2003 Sony Corporation + * Copyright 2003 Matsushita Electric Industrial Co., Ltd. + * + * This software is being distributed under the terms of the GNU General Public + * License version 2. Some or all of the technology encompassed by this + * software may be subject to one or more patents pending as of the date of + * this notice. No additional patent license will be required for GPL + * implementations of the technology. If you want to create a non-GPL + * implementation of the technology encompassed by this software, please + * contact legal@mvista.com for details including licensing terms and fees. + * + * 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 _LINUX_PRAM_FS_SB + #define _LINUX_PRAM_FS_SB + + /* + * PRAM filesystem super-block data in memory + */ + struct pram_sb_info { + /* + * base physical and virtual address of PRAMFS (which is also + * the pointer to the super block) + */ + unsigned long phys_addr; + void * virt_addr; + + u32 maxsize; + u32 features; + u16 magic; + }; + + #endif /* _LINUX_PRAM_FS_SB */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/relayfs_fs.h linux-current/include/linux/relayfs_fs.h *** linux-2.6.10/include/linux/relayfs_fs.h Thu Jan 1 09:00:00 1970 --- linux-current/include/linux/relayfs_fs.h Wed Jun 14 21:13:00 2006 *************** *** 0 **** --- 1,689 ---- + /* + * linux/include/linux/relayfs_fs.h + * + * Copyright (C) 2002, 2003 - Tom Zanussi (zanussi@us.ibm.com), IBM Corp + * Copyright (C) 1999, 2000, 2001, 2002 - Karim Yaghmour (karim@opersys.com) + * + * RelayFS definitions and declarations + * + * Please see Documentation/filesystems/relayfs.txt for more info. + */ + + #ifndef _LINUX_RELAYFS_FS_H + #define _LINUX_RELAYFS_FS_H + + #include + #include + #include + #include + #include + #include + + /* + * Tracks changes to rchan struct + */ + #define RELAYFS_CHANNEL_VERSION 1 + + /* + * Maximum number of simultaneously open channels + */ + #define RELAY_MAX_CHANNELS 256 + + /* + * Relay properties + */ + #define RELAY_MIN_BUFS 2 + #define RELAY_MIN_BUFSIZE 4096 + #define RELAY_MAX_BUFS 256 + #define RELAY_MAX_BUF_SIZE 0x1000000 + #define RELAY_MAX_TOTAL_BUF_SIZE 0x8000000 + + /* + * Lockless scheme utility macros + */ + #define RELAY_MAX_BUFNO(bufno_bits) (1UL << (bufno_bits)) + #define RELAY_BUF_SIZE(offset_bits) (1UL << (offset_bits)) + #define RELAY_BUF_OFFSET_MASK(offset_bits) (RELAY_BUF_SIZE(offset_bits) - 1) + #define RELAY_BUFNO_GET(index, offset_bits) ((index) >> (offset_bits)) + #define RELAY_BUF_OFFSET_GET(index, mask) ((index) & (mask)) + #define RELAY_BUF_OFFSET_CLEAR(index, mask) ((index) & ~(mask)) + + /* + * Flags returned by relay_reserve() + */ + #define RELAY_BUFFER_SWITCH_NONE 0x0 + #define RELAY_WRITE_DISCARD_NONE 0x0 + #define RELAY_BUFFER_SWITCH 0x1 + #define RELAY_WRITE_DISCARD 0x2 + #define RELAY_WRITE_TOO_LONG 0x4 + + /* + * Relay attribute flags + */ + #define RELAY_DELIVERY_BULK 0x1 + #define RELAY_DELIVERY_PACKET 0x2 + #define RELAY_SCHEME_LOCKLESS 0x4 + #define RELAY_SCHEME_LOCKING 0x8 + #define RELAY_SCHEME_ANY 0xC + #define RELAY_TIMESTAMP_TSC 0x10 + #define RELAY_TIMESTAMP_GETTIMEOFDAY 0x20 + #define RELAY_TIMESTAMP_ANY 0x30 + #define RELAY_USAGE_SMP 0x40 + #define RELAY_USAGE_GLOBAL 0x80 + #define RELAY_MODE_CONTINUOUS 0x100 + #define RELAY_MODE_NO_OVERWRITE 0x200 + #define RELAY_MODE_START_AT_ZERO 0x400 + + /* + * Flags for needs_resize() callback + */ + #define RELAY_RESIZE_NONE 0x0 + #define RELAY_RESIZE_EXPAND 0x1 + #define RELAY_RESIZE_SHRINK 0x2 + #define RELAY_RESIZE_REPLACE 0x4 + #define RELAY_RESIZE_REPLACED 0x8 + + /* + * Values for fileop_notify() callback + */ + enum relay_fileop + { + RELAY_FILE_OPEN, + RELAY_FILE_CLOSE, + RELAY_FILE_MAP, + RELAY_FILE_UNMAP + }; + + /* + * Data structure returned by relay_info() + */ + struct rchan_info + { + u32 flags; /* relay attribute flags for channel */ + u32 buf_size; /* channel's sub-buffer size */ + char *buf_addr; /* address of channel start */ + u32 alloc_size; /* total buffer size actually allocated */ + u32 n_bufs; /* number of sub-buffers in channel */ + u32 cur_idx; /* current write index into channel */ + u32 bufs_produced; /* current count of sub-buffers produced */ + u32 bufs_consumed; /* current count of sub-buffers consumed */ + u32 buf_id; /* buf_id of current sub-buffer */ + int buffer_complete[RELAY_MAX_BUFS]; /* boolean per sub-buffer */ + int unused_bytes[RELAY_MAX_BUFS]; /* count per sub-buffer */ + }; + + /* + * Relay channel client callbacks + */ + struct rchan_callbacks + { + /* + * buffer_start - called at the beginning of a new sub-buffer + * @rchan_id: the channel id + * @current_write_pos: position in sub-buffer client should write to + * @buffer_id: the id of the new sub-buffer + * @start_time: the timestamp associated with the start of sub-buffer + * @start_tsc: the TSC associated with the timestamp, if using_tsc + * @using_tsc: boolean, indicates whether start_tsc is valid + * + * Return value should be the number of bytes written by the client. + * + * See Documentation/filesystems/relayfs.txt for details. + */ + int (*buffer_start) (int rchan_id, + char *current_write_pos, + u32 buffer_id, + struct timeval start_time, + u32 start_tsc, + int using_tsc); + + /* + * buffer_end - called at the end of a sub-buffer + * @rchan_id: the channel id + * @current_write_pos: position in sub-buffer of end of data + * @end_of_buffer: the position of the end of the sub-buffer + * @end_time: the timestamp associated with the end of the sub-buffer + * @end_tsc: the TSC associated with the end_time, if using_tsc + * @using_tsc: boolean, indicates whether end_tsc is valid + * + * Return value should be the number of bytes written by the client. + * + * See Documentation/filesystems/relayfs.txt for details. + */ + int (*buffer_end) (int rchan_id, + char *current_write_pos, + char *end_of_buffer, + struct timeval end_time, + u32 end_tsc, + int using_tsc); + + /* + * deliver - called when data is ready for the client + * @rchan_id: the channel id + * @from: the start of the delivered data + * @len: the length of the delivered data + * + * See Documentation/filesystems/relayfs.txt for details. + */ + void (*deliver) (int rchan_id, char *from, u32 len); + + /* + * user_deliver - called when data has been written from userspace + * @rchan_id: the channel id + * @from: the start of the delivered data + * @len: the length of the delivered data + * + * See Documentation/filesystems/relayfs.txt for details. + */ + void (*user_deliver) (int rchan_id, char *from, u32 len); + + /* + * needs_resize - called when a resizing event occurs + * @rchan_id: the channel id + * @resize_type: the type of resizing event + * @suggested_buf_size: the suggested new sub-buffer size + * @suggested_buf_size: the suggested new number of sub-buffers + * + * See Documentation/filesystems/relayfs.txt for details. + */ + void (*needs_resize)(int rchan_id, + int resize_type, + u32 suggested_buf_size, + u32 suggested_n_bufs); + + /* + * fileop_notify - called on open/close/mmap/munmap of a relayfs file + * @rchan_id: the channel id + * @filp: relayfs file pointer + * @fileop: which file operation is in progress + * + * The return value can direct the outcome of the operation. + * + * See Documentation/filesystems/relayfs.txt for details. + */ + int (*fileop_notify)(int rchan_id, + struct file *filp, + enum relay_fileop fileop); + + /* + * ioctl - called in ioctl context from userspace + * @rchan_id: the channel id + * @cmd: ioctl cmd + * @arg: ioctl cmd arg + * + * The return value is returned as the value from the ioctl call. + * + * See Documentation/filesystems/relayfs.txt for details. + */ + int (*ioctl) (int rchan_id, unsigned int cmd, unsigned long arg); + }; + + /* + * Lockless scheme-specific data + */ + struct lockless_rchan + { + u8 bufno_bits; /* # bits used for sub-buffer id */ + u8 offset_bits; /* # bits used for offset within sub-buffer */ + u32 index; /* current index = sub-buffer id and offset */ + u32 offset_mask; /* used to obtain offset portion of index */ + u32 index_mask; /* used to mask off unused bits index */ + atomic_t fill_count[RELAY_MAX_BUFS]; /* fill count per sub-buffer */ + }; + + /* + * Locking scheme-specific data + */ + struct locking_rchan + { + char *write_buf; /* start of write sub-buffer */ + char *write_buf_end; /* end of write sub-buffer */ + char *current_write_pos; /* current write pointer */ + char *write_limit; /* takes reserves into account */ + char *in_progress_event_pos; /* used for interrupted writes */ + u16 in_progress_event_size; /* used for interrupted writes */ + char *interrupted_pos; /* used for interrupted writes */ + u16 interrupting_size; /* used for interrupted writes */ + spinlock_t lock; /* channel lock for locking scheme */ + }; + + struct relay_ops; + + /* + * Offset resizing data structure + */ + struct resize_offset + { + u32 ge; + u32 le; + int delta; + }; + + /* + * Relay channel data structure + */ + struct rchan + { + u32 version; /* the version of this struct */ + char *buf; /* the channel buffer */ + union + { + struct lockless_rchan lockless; + struct locking_rchan locking; + } scheme; /* scheme-specific channel data */ + + int id; /* the channel id */ + struct rchan_callbacks *callbacks; /* client callbacks */ + u32 flags; /* relay channel attributes */ + u32 buf_id; /* current sub-buffer id */ + u32 buf_idx; /* current sub-buffer index */ + + atomic_t mapped; /* map count */ + + atomic_t suspended; /* channel suspended i.e full? */ + int half_switch; /* used internally for suspend */ + + struct timeval buf_start_time; /* current sub-buffer start time */ + u32 buf_start_tsc; /* current sub-buffer start TSC */ + + u32 buf_size; /* sub-buffer size */ + u32 alloc_size; /* total buffer size allocated */ + u32 n_bufs; /* number of sub-buffers */ + + u32 bufs_produced; /* count of sub-buffers produced */ + u32 bufs_consumed; /* count of sub-buffers consumed */ + u32 bytes_consumed; /* bytes consumed in cur sub-buffer */ + u32 read_start; /* start VFS readers here */ + + int initialized; /* first buffer initialized? */ + int finalized; /* channel finalized? */ + + u32 start_reserve; /* reserve at start of sub-buffers */ + u32 end_reserve; /* reserve at end of sub-buffers */ + u32 rchan_start_reserve; /* additional reserve sub-buffer 0 */ + + struct dentry *dentry; /* channel file dentry */ + + wait_queue_head_t read_wait; /* VFS read wait queue */ + wait_queue_head_t write_wait; /* VFS write wait queue */ + struct work_struct wake_readers; /* reader wake-up work struct */ + struct work_struct wake_writers; /* reader wake-up work struct */ + atomic_t refcount; /* channel refcount */ + + struct relay_ops *relay_ops; /* scheme-specific channel ops */ + + int unused_bytes[RELAY_MAX_BUFS]; /* unused count per sub-buffer */ + + struct semaphore resize_sem; /* serializes alloc/repace */ + struct work_struct work; /* resize allocation work struct */ + + struct list_head open_readers; /* open readers for this channel */ + rwlock_t open_readers_lock; /* protection for open_readers list */ + + char *init_buf; /* init channel buffer, if non-NULL */ + + u32 resize_min; /* minimum resized total buffer size */ + u32 resize_max; /* maximum resized total buffer size */ + char *resize_buf; /* for autosize alloc/free */ + u32 resize_buf_size; /* resized sub-buffer size */ + u32 resize_n_bufs; /* resized number of sub-buffers */ + u32 resize_alloc_size; /* resized actual total size */ + int resizing; /* is resizing in progress? */ + int resize_err; /* resizing err code */ + int resize_failures; /* number of resize failures */ + int replace_buffer; /* is the alloced buffer ready? */ + struct resize_offset resize_offset; /* offset change */ + struct timer_list shrink_timer; /* timer used for shrinking */ + int resize_order; /* size of last resize */ + u32 expand_buf_id; /* subbuf id expand will occur at */ + + struct page **buf_page_array; /* array of current buffer pages */ + int buf_page_count; /* number of current buffer pages */ + struct page **expand_page_array;/* new pages to be inserted */ + int expand_page_count; /* number of new pages */ + struct page **shrink_page_array;/* old pages to be freed */ + int shrink_page_count; /* number of old pages */ + struct page **resize_page_array;/* will become current pages */ + int resize_page_count; /* number of resize pages */ + struct page **old_buf_page_array; /* hold for freeing */ + } ____cacheline_aligned; + + /* + * Relay channel reader struct + */ + struct rchan_reader + { + struct list_head list; /* for list inclusion */ + struct rchan *rchan; /* the channel we're reading from */ + int auto_consume; /* does this reader auto-consume? */ + u32 bufs_consumed; /* buffers this reader has consumed */ + u32 bytes_consumed; /* bytes consumed in cur sub-buffer */ + int offset_changed; /* have channel offsets changed? */ + int vfs_reader; /* are we a VFS reader? */ + int map_reader; /* are we an mmap reader? */ + + union + { + struct file *file; + u32 f_pos; + } pos; /* current read offset */ + }; + + /* + * These help make union member access less tedious + */ + #define channel_buffer(rchan) ((rchan)->buf) + #define idx(rchan) ((rchan)->scheme.lockless.index) + #define bufno_bits(rchan) ((rchan)->scheme.lockless.bufno_bits) + #define offset_bits(rchan) ((rchan)->scheme.lockless.offset_bits) + #define offset_mask(rchan) ((rchan)->scheme.lockless.offset_mask) + #define idx_mask(rchan) ((rchan)->scheme.lockless.index_mask) + #define bulk_delivery(rchan) (((rchan)->flags & RELAY_DELIVERY_BULK) ? 1 : 0) + #define packet_delivery(rchan) (((rchan)->flags & RELAY_DELIVERY_PACKET) ? 1 : 0) + #define using_lockless(rchan) (((rchan)->flags & RELAY_SCHEME_LOCKLESS) ? 1 : 0) + #define using_locking(rchan) (((rchan)->flags & RELAY_SCHEME_LOCKING) ? 1 : 0) + #define using_tsc(rchan) (((rchan)->flags & RELAY_TIMESTAMP_TSC) ? 1 : 0) + #define using_gettimeofday(rchan) (((rchan)->flags & RELAY_TIMESTAMP_GETTIMEOFDAY) ? 1 : 0) + #define usage_smp(rchan) (((rchan)->flags & RELAY_USAGE_SMP) ? 1 : 0) + #define usage_global(rchan) (((rchan)->flags & RELAY_USAGE_GLOBAL) ? 1 : 0) + #define mode_continuous(rchan) (((rchan)->flags & RELAY_MODE_CONTINUOUS) ? 1 : 0) + #define fill_count(rchan, i) ((rchan)->scheme.lockless.fill_count[(i)]) + #define write_buf(rchan) ((rchan)->scheme.locking.write_buf) + #define read_buf(rchan) ((rchan)->scheme.locking.read_buf) + #define write_buf_end(rchan) ((rchan)->scheme.locking.write_buf_end) + #define read_buf_end(rchan) ((rchan)->scheme.locking.read_buf_end) + #define cur_write_pos(rchan) ((rchan)->scheme.locking.current_write_pos) + #define read_limit(rchan) ((rchan)->scheme.locking.read_limit) + #define write_limit(rchan) ((rchan)->scheme.locking.write_limit) + #define in_progress_event_pos(rchan) ((rchan)->scheme.locking.in_progress_event_pos) + #define in_progress_event_size(rchan) ((rchan)->scheme.locking.in_progress_event_size) + #define interrupted_pos(rchan) ((rchan)->scheme.locking.interrupted_pos) + #define interrupting_size(rchan) ((rchan)->scheme.locking.interrupting_size) + #define channel_lock(rchan) ((rchan)->scheme.locking.lock) + + + /** + * calc_time_delta - utility function for time delta calculation + * @now: current time + * @start: start time + * + * Returns the time delta produced by subtracting start time from now. + */ + static inline u32 + calc_time_delta(struct timeval *now, + struct timeval *start) + { + return (now->tv_sec - start->tv_sec) * 1000000 + + (now->tv_usec - start->tv_usec); + } + + /** + * recalc_time_delta - utility function for time delta recalculation + * @now: current time + * @new_delta: the new time delta calculated + * @cpu: the associated CPU id + */ + static inline void + recalc_time_delta(struct timeval *now, + u32 *new_delta, + struct rchan *rchan) + { + if (using_tsc(rchan) == 0) + *new_delta = calc_time_delta(now, &rchan->buf_start_time); + } + + /** + * have_cmpxchg - does this architecture have a cmpxchg? + * + * Returns 1 if this architecture has a cmpxchg useable by + * the lockless scheme, 0 otherwise. + */ + static inline int + have_cmpxchg(void) + { + #if defined(__HAVE_ARCH_CMPXCHG) + return 1; + #else + return 0; + #endif + } + + /** + * relay_write_direct - write data directly into destination buffer + */ + #define relay_write_direct(DEST, SRC, SIZE) \ + do\ + {\ + memcpy(DEST, SRC, SIZE);\ + DEST += SIZE;\ + } while (0); + + /** + * relay_lock_channel - lock the relay channel if applicable + * + * This macro only affects the locking scheme. If the locking scheme + * is in use and the channel usage is SMP, does a local_irq_save. If the + * locking sheme is in use and the channel usage is GLOBAL, uses + * spin_lock_irqsave. FLAGS is initialized to 0 since we know that + * it is being initialized prior to use and we avoid the compiler warning. + */ + #define relay_lock_channel(RCHAN, FLAGS) \ + do\ + {\ + FLAGS = 0;\ + if (using_locking(RCHAN)) {\ + if (usage_smp(RCHAN)) {\ + local_irq_save(FLAGS); \ + } else {\ + spin_lock_irqsave(&(RCHAN)->scheme.locking.lock, FLAGS); \ + }\ + }\ + } while (0); + + /** + * relay_unlock_channel - unlock the relay channel if applicable + * + * This macro only affects the locking scheme. See relay_lock_channel. + */ + #define relay_unlock_channel(RCHAN, FLAGS) \ + do\ + {\ + if (using_locking(RCHAN)) {\ + if (usage_smp(RCHAN)) {\ + local_irq_restore(FLAGS); \ + } else {\ + spin_unlock_irqrestore(&(RCHAN)->scheme.locking.lock, FLAGS); \ + }\ + }\ + } while (0); + + /* + * Define cmpxchg if we don't have it + */ + #ifndef __HAVE_ARCH_CMPXCHG + #define cmpxchg(p,o,n) 0 + #endif + + /* + * High-level relayfs kernel API, fs/relayfs/relay.c + */ + extern int + relay_open(const char *chanpath, + int bufsize, + int nbufs, + u32 flags, + struct rchan_callbacks *channel_callbacks, + u32 start_reserve, + u32 end_reserve, + u32 rchan_start_reserve, + u32 resize_min, + u32 resize_max, + int mode, + char *init_buf, + u32 init_buf_size); + + extern int + relay_close(int rchan_id); + + extern int + relay_write(int rchan_id, + const void *data_ptr, + size_t count, + int td_offset, + void **wrote_pos); + + extern ssize_t + relay_read(struct rchan_reader *reader, + char *buf, + size_t count, + int wait, + u32 *actual_read_offset, + u32 *new_offset); + + extern int + relay_discard_init_buf(int rchan_id); + + extern struct rchan_reader * + add_rchan_reader(int rchan_id, int autoconsume); + + extern int + remove_rchan_reader(struct rchan_reader *reader); + + extern struct rchan_reader * + add_map_reader(int rchan_id); + + extern int + remove_map_reader(struct rchan_reader *reader); + + extern int + relay_info(int rchan_id, struct rchan_info *rchan_info); + + extern void + relay_buffers_consumed(struct rchan_reader *reader, u32 buffers_consumed); + + extern void + relay_bytes_consumed(struct rchan_reader *reader, u32 bytes_consumed, u32 read_offset); + + extern ssize_t + relay_bytes_avail(struct rchan_reader *reader); + + extern int + relay_realloc_buffer(int rchan_id, u32 new_nbufs, int in_background); + + extern int + relay_replace_buffer(int rchan_id); + + extern int + rchan_empty(struct rchan_reader *reader); + + extern int + rchan_full(struct rchan_reader *reader); + + extern void + update_readers_consumed(struct rchan *rchan, u32 bufs_consumed, u32 bytes_consumed); + + extern int + __relay_mmap_buffer(struct rchan *rchan, struct vm_area_struct *vma); + + extern struct rchan_reader * + __add_rchan_reader(struct rchan *rchan, struct file *filp, int auto_consume, int map_reader); + + extern void + __remove_rchan_reader(struct rchan_reader *reader); + + /* + * Low-level relayfs kernel API, fs/relayfs/relay.c + */ + extern struct rchan * + rchan_get(int rchan_id); + + extern void + rchan_put(struct rchan *rchan); + + extern char * + relay_reserve(struct rchan *rchan, + u32 data_len, + struct timeval *time_stamp, + u32 *time_delta, + int *errcode, + int *interrupting); + + extern void + relay_commit(struct rchan *rchan, + char *from, + u32 len, + int reserve_code, + int interrupting); + + extern u32 + relay_get_offset(struct rchan *rchan, u32 *max_offset); + + extern int + relay_reset(int rchan_id); + + /* + * VFS functions, fs/relayfs/inode.c + */ + extern int + relayfs_create_dir(const char *name, + struct dentry *parent, + struct dentry **dentry); + + extern int + relayfs_create_file(const char * name, + struct dentry *parent, + struct dentry **dentry, + void * data, + int mode); + + extern int + relayfs_remove_file(struct dentry *dentry); + + extern int + reset_index(struct rchan *rchan, u32 old_index); + + + /* + * klog functions, fs/relayfs/klog.c + */ + extern int + create_klog_channel(void); + + extern int + remove_klog_channel(void); + + /* + * Scheme-specific channel ops + */ + struct relay_ops + { + char * (*reserve) (struct rchan *rchan, + u32 slot_len, + struct timeval *time_stamp, + u32 *tsc, + int * errcode, + int * interrupting); + + void (*commit) (struct rchan *rchan, + char *from, + u32 len, + int deliver, + int interrupting); + + u32 (*get_offset) (struct rchan *rchan, + u32 *max_offset); + + void (*resume) (struct rchan *rchan); + void (*finalize) (struct rchan *rchan); + void (*reset) (struct rchan *rchan, + int init); + int (*reset_index) (struct rchan *rchan, + u32 old_index); + }; + + #endif /* _LINUX_RELAYFS_FS_H */ + + + + + diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/sched.h linux-current/include/linux/sched.h *** linux-2.6.10/include/linux/sched.h Sat Dec 25 06:33:59 2004 --- linux-current/include/linux/sched.h Wed Jun 14 21:13:00 2006 *************** *** 740,745 **** --- 740,746 ---- extern int task_nice(const task_t *p); extern int task_curr(const task_t *p); extern int idle_cpu(int cpu); + extern int sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param); void yield(void); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/include/linux/serial_core.h linux-current/include/linux/serial_core.h *** linux-2.6.10/include/linux/serial_core.h Sat Dec 25 06:34:00 2004 --- linux-current/include/linux/serial_core.h Wed Jun 14 21:13:00 2006 *************** *** 39,45 **** --- 39,50 ---- #define PORT_RSA 13 #define PORT_NS16550A 14 #define PORT_XSCALE 15 + #ifdef CONFIG_EMMA + #define PORT_EMMA3 16 + #define PORT_MAX_8250 16 /* max port ID */ + #else #define PORT_MAX_8250 15 /* max port ID */ + #endif /* * ARM specific type numbers. These are not currently guaranteed *************** *** 100,105 **** --- 105,113 ---- /* Motorola i.MX SoC */ #define PORT_IMX 62 + /* TXX9 type number */ + #define PORT_TXX9 63 + #ifdef __KERNEL__ #include diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/init/Kconfig linux-current/init/Kconfig *** linux-2.6.10/init/Kconfig Sat Dec 25 06:35:24 2004 --- linux-current/init/Kconfig Wed Jun 14 21:13:00 2006 *************** *** 210,215 **** --- 210,221 ---- agent" (/sbin/hotplug) to load modules and set up software needed to use devices as you hotplug them. + config HOTPLUG_DEFAULT_PATH + string "hotplug path" + depends on HOTPLUG + default "/sbin/hotplug" + help + config KOBJECT_UEVENT bool "Kernel Userspace Events" depends on NET *************** *** 315,320 **** --- 321,358 ---- If unsure, say N. + config LTT + bool "Linux Trace Toolkit support" + depends on RELAYFS_FS=y + default n + ---help--- + It is possible for the kernel to log important events to a trace + facility. Doing so, enables the use of the generated traces in order + to reconstruct the dynamic behavior of the kernel, and hence the + whole system. + + The tracing process contains 4 parts : + 1) The logging of events by key parts of the kernel. + 2) The tracer that keeps the events in a data buffer (uses + relayfs). + 3) A trace daemon that interacts with the tracer and is + notified every time there is a certain quantity of data to + read from the tracer. + 4) A trace event data decoder that reads the accumulated data + and formats it in a human-readable format. + + If you say Y, the first two components will be built into the kernel. + Critical parts of the kernel will call upon the kernel tracing + function. The data is then recorded by the tracer if a trace daemon + is running in user-space and has issued a "start" command. + + In order to enable LTT support you must first select relayfs as + built-in. + + For more information on kernel tracing, the trace daemon or the event + decoder, please check the following address : + http://www.opersys.com/ltt + config SHMEM default y bool "Use full shmem filesystem" if EMBEDDED && MMU diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/init/do_mounts.c linux-current/init/do_mounts.c *** linux-2.6.10/init/do_mounts.c Sat Dec 25 06:34:31 2004 --- linux-current/init/do_mounts.c Wed Jun 14 21:13:00 2006 *************** *** 214,220 **** --- 214,224 ---- __setup("root=", root_dev_setup); + #if defined(CONFIG_ROOT_CRAMFS_LINEAR) + char * __initdata root_mount_data; + #else static char * __initdata root_mount_data; + #endif static int __init root_data_setup(char *str) { root_mount_data = str; *************** *** 321,326 **** --- 325,350 ---- } #endif + #ifdef CONFIG_ROOT_PRAMFS + static int __init mount_pramfs_root(void) + { + create_dev("/dev/root", ROOT_DEV, NULL); + if (do_mount_root("/dev/root", "pramfs", + root_mountflags, root_mount_data) == 0) + return 1; + return 0; + } + #endif + #ifdef CONFIG_ROOT_CRAMFS_LINEAR + static int __init mount_cramfs_linear_root(void) + { + create_dev("/dev/root", ROOT_DEV, root_device_name); + if (do_mount_root("/dev/root","cramfs",root_mountflags,root_mount_data) == 0) + return 1; + return 0; + } + #endif + #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD) void __init change_floppy(char *fmt, ...) { *************** *** 353,358 **** --- 377,389 ---- void __init mount_root(void) { + #ifdef CONFIG_ROOT_CRAMFS_LINEAR + if (ROOT_DEV == MKDEV(0, 0)) { + if (mount_cramfs_linear_root()) + return; + printk (KERN_ERR "VFS: Unable to mount linear cramfs root.\n"); + } + #endif #ifdef CONFIG_ROOT_NFS if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { if (mount_nfs_root()) *************** *** 362,367 **** --- 393,407 ---- ROOT_DEV = Root_FD0; } #endif + #ifdef CONFIG_ROOT_PRAMFS + if (ROOT_DEV == MKDEV(0, 0)) { + if (mount_pramfs_root()) + return; + + printk (KERN_ERR "VFS: Unable to mount PRAMFS root\n"); + ROOT_DEV = Root_FD0; + } + #endif #ifdef CONFIG_BLK_DEV_FD if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { /* rd_doload is 2 for a dual initrd/ramload setup */ *************** *** 403,408 **** --- 443,461 ---- if (is_floppy && rd_doload && rd_load_disk(0)) ROOT_DEV = Root_RAM0; + #if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO) + #ifndef MTD_BLOCK_MAJOR + #define MTD_BLOCK_MAJOR 31 + #endif + else if (MAJOR(ROOT_DEV) == MTD_BLOCK_MAJOR && rd_doload) { + #ifdef CONFIG_BLK_DEV_RAM + extern int rd_prompt; + rd_prompt = 0; + #endif + if (rd_load_disk(0)) + ROOT_DEV = Root_RAM0; + } + #endif mount_root(); out: diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/ipc/msg.c linux-current/ipc/msg.c *** linux-2.6.10/ipc/msg.c Sat Dec 25 06:33:48 2004 --- linux-current/ipc/msg.c Wed Jun 14 21:13:00 2006 *************** *** 25,30 **** --- 25,31 ---- #include #include #include + #include #include #include #include "util.h" *************** *** 229,234 **** --- 230,236 ---- msg_unlock(msq); } up(&msg_ids.sem); + ltt_ev_ipc(LTT_EV_IPC_MSG_CREATE, ret, msgflg); return ret; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/ipc/sem.c linux-current/ipc/sem.c *** linux-2.6.10/ipc/sem.c Sat Dec 25 06:34:31 2004 --- linux-current/ipc/sem.c Wed Jun 14 21:13:00 2006 *************** *** 72,77 **** --- 72,78 ---- #include #include #include + #include #include #include "util.h" *************** *** 239,244 **** --- 240,246 ---- } up(&sem_ids.sem); + ltt_ev_ipc(LTT_EV_IPC_SEM_CREATE, err, semflg); return err; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/ipc/shm.c linux-current/ipc/shm.c *** linux-2.6.10/ipc/shm.c Sat Dec 25 06:34:45 2004 --- linux-current/ipc/shm.c Wed Jun 14 21:13:00 2006 *************** *** 27,32 **** --- 27,33 ---- #include #include #include + #include #include #include "util.h" *************** *** 277,283 **** shm_unlock(shp); } up(&shm_ids.sem); ! return err; } --- 278,284 ---- shm_unlock(shp); } up(&shm_ids.sem); ! ltt_ev_ipc(LTT_EV_IPC_SHM_CREATE, err, shmflg); return err; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/Makefile linux-current/kernel/Makefile *** linux-2.6.10/kernel/Makefile Sat Dec 25 06:34:26 2004 --- linux-current/kernel/Makefile Wed Jun 14 21:13:00 2006 *************** *** 17,22 **** --- 17,23 ---- obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_PM) += power/ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o + obj-$(CONFIG_LTT) += ltt-core.o obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_IKCONFIG_PROC) += configs.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/exit.c linux-current/kernel/exit.c *** linux-2.6.10/kernel/exit.c Sat Dec 25 06:35:27 2004 --- linux-current/kernel/exit.c Wed Jun 14 21:13:00 2006 *************** *** 24,29 **** --- 24,30 ---- #include #include #include + #include #include #include *************** *** 811,816 **** --- 812,819 ---- acct_process(code); __exit_mm(tsk); + ltt_ev_process_exit(0, 0); + exit_sem(tsk); __exit_files(tsk); __exit_fs(tsk); *************** *** 1316,1321 **** --- 1319,1326 ---- struct task_struct *tsk; int flag, retval; + ltt_ev_process(LTT_EV_PROCESS_WAIT, pid, 0); + add_wait_queue(¤t->wait_chldexit,&wait); repeat: /* diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/fork.c linux-current/kernel/fork.c *** linux-2.6.10/kernel/fork.c Sat Dec 25 06:33:59 2004 --- linux-current/kernel/fork.c Wed Jun 14 21:13:00 2006 *************** *** 39,44 **** --- 39,45 ---- #include #include #include + #include #include #include *************** *** 1159,1164 **** --- 1160,1167 ---- ptrace_notify ((trace << 8) | SIGTRAP); } + ltt_ev_process(LTT_EV_PROCESS_FORK, p->pid, 0); + if (clone_flags & CLONE_VFORK) { wait_for_completion(&vfork); if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/irq/handle.c linux-current/kernel/irq/handle.c *** linux-2.6.10/kernel/irq/handle.c Sat Dec 25 06:35:50 2004 --- linux-current/kernel/irq/handle.c Wed Jun 14 21:13:00 2006 *************** *** 11,16 **** --- 11,17 ---- #include #include #include + #include #include "internals.h" *************** *** 91,96 **** --- 92,99 ---- { int ret, retval = 0, status = 0; + ltt_ev_irq_entry(irq, !(user_mode(regs))); + if (!(action->flags & SA_INTERRUPT)) local_irq_enable(); *************** *** 106,111 **** --- 109,116 ---- add_interrupt_randomness(irq); local_irq_disable(); + ltt_ev_irq_exit(); + return retval; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/itimer.c linux-current/kernel/itimer.c *** linux-2.6.10/kernel/itimer.c Sat Dec 25 06:34:32 2004 --- linux-current/kernel/itimer.c Wed Jun 14 21:13:00 2006 *************** *** 11,16 **** --- 11,17 ---- #include #include #include + #include #include *************** *** 69,74 **** --- 70,77 ---- struct task_struct * p = (struct task_struct *) __data; unsigned long interval; + ltt_ev_timer(LTT_EV_TIMER_EXPIRED, 0, 0, 0); + send_group_sig_info(SIGALRM, SEND_SIG_PRIV, p); interval = p->it_real_incr; if (interval) { *************** *** 88,93 **** --- 91,97 ---- j = timeval_to_jiffies(&value->it_value); if (ovalue && (k = do_getitimer(which, ovalue)) < 0) return k; + ltt_ev_timer(LTT_EV_TIMER_SETITIMER, which, i, j); switch (which) { case ITIMER_REAL: del_timer_sync(¤t->real_timer); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/sched.c linux-current/kernel/sched.c *** linux-2.6.10/kernel/sched.c Sat Dec 25 06:35:24 2004 --- linux-current/kernel/sched.c Wed Jun 14 21:13:00 2006 *************** *** 44,49 **** --- 44,50 ---- #include #include #include + #include #include #include *************** *** 317,322 **** --- 318,325 ---- { struct runqueue *rq; + ltt_ev_process(LTT_EV_PROCESS_WAKEUP, p->pid, p->state); + repeat_lock_task: local_irq_save(*flags); rq = task_rq(p); *************** *** 2685,2690 **** --- 2688,2694 ---- ++*switch_count; prepare_arch_switch(rq, next); + ltt_ev_schedchange(prev, next); prev = context_switch(rq, prev, next); barrier(); *************** *** 3186,3191 **** --- 3190,3208 ---- } /** + * sched_setscheduler - change the scheduling policy and/or RT priority of + * a thread. + * @pid: the pid in question. + * @policy: new policy + * @param: structure containing the new RT priority. + */ + int sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param) + { + return setscheduler(pid, policy, param); + } + EXPORT_SYMBOL_GPL(sched_setscheduler); + + /** * sys_sched_setscheduler - set/change the scheduler policy and RT priority * @pid: the pid in question. * @policy: new policy diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/signal.c linux-current/kernel/signal.c *** linux-2.6.10/kernel/signal.c Sat Dec 25 06:34:32 2004 --- linux-current/kernel/signal.c Wed Jun 14 21:13:00 2006 *************** *** 22,27 **** --- 22,28 ---- #include #include #include + #include #include #include #include *************** *** 833,838 **** --- 834,841 ---- if (sig_ignored(t, sig)) goto out; + ltt_ev_process(LTT_EV_PROCESS_SIGNAL, sig, t->pid); + /* Support queueing exactly one non-rt signal, so that we can get more detailed information about the cause of the signal. */ *************** *** 1912,1917 **** --- 1915,1924 ---- * first and our do_group_exit call below will use * that value and ignore the one we pass it. */ + #ifdef CONFIG_DEBUG_KERNEL + printk("EPC = 0x%08lx, SIG=%d\n", regs->cp0_epc, signr); + printk("PID = %d\n", current->pid); + #endif do_coredump((long)signr, signr, regs); } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/softirq.c linux-current/kernel/softirq.c *** linux-2.6.10/kernel/softirq.c Sat Dec 25 06:34:26 2004 --- linux-current/kernel/softirq.c Wed Jun 14 21:13:00 2006 *************** *** 16,21 **** --- 16,22 ---- #include #include #include + #include #include /* *************** *** 92,97 **** --- 93,99 ---- do { if (pending & 1) { + ltt_ev_soft_irq(LTT_EV_SOFT_IRQ_SOFT_IRQ, (h - softirq_vec)); h->action(h); rcu_bh_qsctr_inc(cpu); } *************** *** 246,251 **** --- 248,256 ---- if (!atomic_read(&t->count)) { if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) BUG(); + + ltt_ev_soft_irq(LTT_EV_SOFT_IRQ_TASKLET_ACTION, (unsigned long) (t->func)); + t->func(t->data); tasklet_unlock(t); continue; *************** *** 279,284 **** --- 284,292 ---- if (!atomic_read(&t->count)) { if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state)) BUG(); + + ltt_ev_soft_irq(LTT_EV_SOFT_IRQ_TASKLET_HI_ACTION, (unsigned long) (t->func)); + t->func(t->data); tasklet_unlock(t); continue; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/time.c linux-current/kernel/time.c *** linux-2.6.10/kernel/time.c Sat Dec 25 06:34:26 2004 --- linux-current/kernel/time.c Wed Jun 14 21:13:00 2006 *************** *** 33,38 **** --- 33,39 ---- #include #include #include + #include #include #include diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/kernel/timer.c linux-current/kernel/timer.c *** linux-2.6.10/kernel/timer.c Sat Dec 25 06:35:24 2004 --- linux-current/kernel/timer.c Wed Jun 14 21:13:00 2006 *************** *** 32,37 **** --- 32,38 ---- #include #include #include + #include #include #include *************** *** 923,928 **** --- 924,931 ---- { tvec_base_t *base = &__get_cpu_var(tvec_bases); + ltt_ev(LTT_EV_KERNEL_TIMER, NULL); + if (time_after_eq(jiffies, base->timer_jiffies)) __run_timers(base); } *************** *** 960,965 **** --- 963,970 ---- void do_timer(struct pt_regs *regs) { jiffies_64++; + /* prevent loading jiffies before storing new jiffies_64 value. */ + barrier(); update_times(); } *************** *** 1081,1086 **** --- 1086,1092 ---- static void process_timeout(unsigned long __data) { + ltt_ev_timer(LTT_EV_TIMER_EXPIRED, 0, 0, 0); wake_up_process((task_t *)__data); } *************** *** 1145,1150 **** --- 1151,1157 ---- } } + ltt_ev_timer(LTT_EV_TIMER_SETTIMEOUT, 0, timeout, 0); expire = timeout + jiffies; init_timer(&timer); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/lib/kobject_uevent.c linux-current/lib/kobject_uevent.c *** linux-2.6.10/lib/kobject_uevent.c Sat Dec 25 06:34:45 2004 --- linux-current/lib/kobject_uevent.c Wed Jun 14 21:13:00 2006 *************** *** 177,183 **** #ifdef CONFIG_HOTPLUG ! char hotplug_path[HOTPLUG_PATH_LEN] = "/sbin/hotplug"; u64 hotplug_seqnum; static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED; --- 177,183 ---- #ifdef CONFIG_HOTPLUG ! char hotplug_path[HOTPLUG_PATH_LEN] = CONFIG_HOTPLUG_DEFAULT_PATH; u64 hotplug_seqnum; static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/localversion.tx linux-current/localversion.tx *** linux-2.6.10/localversion.tx Thu Jan 1 09:00:00 1970 --- linux-current/localversion.tx Wed Jun 6 12:24:33 2007 *************** *** 0 **** --- 1 ---- + -TSB20070606N diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/mm/filemap.c linux-current/mm/filemap.c *** linux-2.6.10/mm/filemap.c Sat Dec 25 06:35:50 2004 --- linux-current/mm/filemap.c Wed Jun 14 21:13:00 2006 *************** *** 28,33 **** --- 28,34 ---- #include #include #include + #include /* * This is needed for the following functions: * - try_to_release_page *************** *** 402,410 **** --- 403,415 ---- { DEFINE_WAIT_BIT(wait, &page->flags, bit_nr); + ltt_ev_memory(LTT_EV_MEMORY_PAGE_WAIT_START, 0); + if (test_bit(bit_nr, &page->flags)) __wait_on_bit(page_waitqueue(page), &wait, sync_page, TASK_UNINTERRUPTIBLE); + + ltt_ev_memory(LTT_EV_MEMORY_PAGE_WAIT_END, 0); } EXPORT_SYMBOL(wait_on_page_bit); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/mm/memory.c linux-current/mm/memory.c *** linux-2.6.10/mm/memory.c Sat Dec 25 06:34:44 2004 --- linux-current/mm/memory.c Wed Jun 14 21:13:00 2006 *************** *** 47,52 **** --- 47,55 ---- #include #include + #include + #include + #include #include #include *************** *** 761,767 **** continue; } ! if (!vma || (vma->vm_flags & VM_IO) || !(flags & vma->vm_flags)) return i ? : -EFAULT; --- 764,771 ---- continue; } ! if (!vma || ((vma->vm_flags & VM_IO) ! && !(vma->vm_flags & VM_XIP)) || !(flags & vma->vm_flags)) return i ? : -EFAULT; *************** *** 1060,1065 **** --- 1064,1109 ---- pte_t entry; if (unlikely(!pfn_valid(pfn))) { + if ((vma->vm_flags & VM_XIP) && pte_present(pte) && + pte_read(pte)) { + /* + * Handle COW of XIP memory. + * Note that the source memory actually isn't a ram + * page so no struct page is associated to the source + * pte. + */ + char *dst; + int ret; + + spin_unlock(&mm->page_table_lock); + new_page = alloc_page(GFP_HIGHUSER); + if (!new_page) + return VM_FAULT_OOM; + + /* copy XIP data to memory */ + + dst = kmap_atomic(new_page, KM_USER0); + ret = copy_from_user(dst, (void*)address, PAGE_SIZE); + kunmap_atomic(dst, KM_USER0); + + /* make sure pte didn't change while we dropped the + lock */ + spin_lock(&mm->page_table_lock); + if (!ret && pte_same(*page_table, pte)) { + ++mm->rss; + break_cow(vma, new_page, address, page_table); + lru_cache_add(new_page); + page_add_file_rmap(new_page); + spin_unlock(&mm->page_table_lock); + return VM_FAULT_MINOR; /* Minor fault */ + } + + /* pte changed: back off */ + spin_unlock(&mm->page_table_lock); + page_cache_release(new_page); + return ret ? VM_FAULT_OOM : VM_FAULT_MINOR; + } + /* * This should really halt the system so it can be debugged or * at least the kernel stops what it's doing before it corrupts *************** *** 1346,1351 **** --- 1390,1396 ---- spin_unlock(&mm->page_table_lock); page = lookup_swap_cache(entry); if (!page) { + ltt_ev_memory(LTT_EV_MEMORY_SWAP_IN, address); swapin_readahead(entry, address, vma); page = read_swap_cache_async(entry, vma, address); if (!page) { diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/mm/page_alloc.c linux-current/mm/page_alloc.c *** linux-2.6.10/mm/page_alloc.c Sat Dec 25 06:33:51 2004 --- linux-current/mm/page_alloc.c Wed Jun 14 21:13:00 2006 *************** *** 32,37 **** --- 32,38 ---- #include #include #include + #include #include *************** *** 278,283 **** --- 279,286 ---- LIST_HEAD(list); int i; + ltt_ev_memory(LTT_EV_MEMORY_PAGE_FREE, order); + arch_free_page(page, order); mod_page_state(pgfree, 1 << order); *************** *** 752,757 **** --- 755,761 ---- page = alloc_pages(gfp_mask, order); if (!page) return 0; + ltt_ev_memory(LTT_EV_MEMORY_PAGE_ALLOC, order); return (unsigned long) page_address(page); } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/mm/page_io.c linux-current/mm/page_io.c *** linux-2.6.10/mm/page_io.c Sat Dec 25 06:33:59 2004 --- linux-current/mm/page_io.c Wed Jun 14 21:13:00 2006 *************** *** 17,22 **** --- 17,23 ---- #include #include #include + #include #include static struct bio *get_swap_bio(int gfp_flags, pgoff_t index, *************** *** 103,108 **** --- 104,110 ---- inc_page_state(pswpout); set_page_writeback(page); unlock_page(page); + ltt_ev_memory(LTT_EV_MEMORY_SWAP_OUT, (unsigned long) page); submit_bio(rw, bio); out: return ret; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/net/core/dev.c linux-current/net/core/dev.c *** linux-2.6.10/net/core/dev.c Sat Dec 25 06:34:45 2004 --- linux-current/net/core/dev.c Wed Jun 14 21:13:00 2006 *************** *** 107,112 **** --- 107,113 ---- #include #include #include + #include #include #ifdef CONFIG_NET_RADIO #include /* Note : will define WIRELESS_EXT */ *************** *** 1245,1250 **** --- 1246,1253 ---- if (skb_checksum_help(skb, 0)) goto out_kfree_skb; + ltt_ev_network(LTT_EV_NETWORK_PACKET_OUT, skb->protocol); + /* Disable soft irqs for various locks below. Also * stops preemption for RCU. */ *************** *** 1642,1647 **** --- 1645,1652 ---- __get_cpu_var(netdev_rx_stat).total++; + ltt_ev_network(LTT_EV_NETWORK_PACKET_IN, skb->protocol); + skb->h.raw = skb->nh.raw = skb->data; skb->mac_len = skb->nh.raw - skb->mac.raw; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-current/net/ipv4/netfilter/ip_conntrack_proto_tcp.c *** linux-2.6.10/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Sat Dec 25 06:35:40 2004 --- linux-current/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Wed Jun 14 21:13:00 2006 *************** *** 38,43 **** --- 38,45 ---- #include #include + #define TCPINWINDOW_ERROR_DROP_WORKAROUND + #if 0 #define DEBUGP printk #define DEBUGP_VARS *************** *** 352,368 **** http://www.nluug.nl/events/sane2000/papers.html http://www.iae.nl/users/guido/papers/tcp_filtering.ps.gz ! The boundaries and the conditions are slightly changed: td_maxend = max(sack + max(win,1)) seen in reply packets td_maxwin = max(max(win, 1)) + (sack - ack) seen in sent packets td_end = max(seq + len) seen in sent packets ! I. Upper bound for valid data: seq + len <= sender.td_maxend ! II. Lower bound for valid data: seq >= sender.td_end - receiver.td_maxwin III. Upper bound for valid ack: sack <= receiver.td_end IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW ! where sack is the highest right edge of sack block found in the packet. The upper bound limit for a valid ack is not ignored - --- 354,374 ---- http://www.nluug.nl/events/sane2000/papers.html http://www.iae.nl/users/guido/papers/tcp_filtering.ps.gz ! The boundaries and the conditions are changed to meet RFC793: ! the packet must intersect the window (i.e. segments may be ! after the right or before the left edge). td_maxend = max(sack + max(win,1)) seen in reply packets td_maxwin = max(max(win, 1)) + (sack - ack) seen in sent packets + td_maxwin += seq + len - sender.td_maxend + if seq + len > sender.td_maxend td_end = max(seq + len) seen in sent packets ! I. Upper bound for valid data: seq <= sender.td_maxend ! II. Lower bound for valid data: seq + len >= sender.td_end - receiver.td_maxwin III. Upper bound for valid ack: sack <= receiver.td_end IV. Lower bound for valid ack: ack >= receiver.td_end - MAXACKWINDOW ! where sack is the highest right edge of sack block found in the packet. The upper bound limit for a valid ack is not ignored - *************** *** 500,506 **** static int tcp_in_window(struct ip_ct_tcp *state, enum ip_conntrack_dir dir, ! unsigned int *index, const struct sk_buff *skb, struct iphdr *iph, struct tcphdr *tcph) --- 506,512 ---- static int tcp_in_window(struct ip_ct_tcp *state, enum ip_conntrack_dir dir, ! unsigned int index, const struct sk_buff *skb, struct iphdr *iph, struct tcphdr *tcph) *************** *** 606,642 **** seq = end = sender->td_end; DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " ! "seq=%u ack=%u sack =%u win=%u end=%u trim=%u\n", NIPQUAD(iph->saddr), ntohs(tcph->source), NIPQUAD(iph->daddr), ntohs(tcph->dest), ! seq, ack, sack, win, end, ! after(end, sender->td_maxend) && before(seq, sender->td_maxend) ! ? sender->td_maxend : end); DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale, receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale); ! ! /* Ignore data over the right edge of the receiver's window. */ ! if (after(end, sender->td_maxend) && ! before(seq, sender->td_maxend)) { ! end = sender->td_maxend; ! if (*index == TCP_FIN_SET) ! *index = TCP_ACK_SET; ! } DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n", ! before(end, sender->td_maxend + 1) ! || before(seq, sender->td_maxend + 1), ! after(seq, sender->td_end - receiver->td_maxwin - 1) ! || after(end, sender->td_end - receiver->td_maxwin - 1), before(sack, receiver->td_end + 1), after(ack, receiver->td_end - MAXACKWINDOW(sender))); if (sender->loose || receiver->loose || ! (before(end, sender->td_maxend + 1) && ! after(seq, sender->td_end - receiver->td_maxwin - 1) && before(sack, receiver->td_end + 1) && after(ack, receiver->td_end - MAXACKWINDOW(sender)))) { /* --- 612,637 ---- seq = end = sender->td_end; DEBUGP("tcp_in_window: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu " ! "seq=%u ack=%u sack =%u win=%u end=%u\n", NIPQUAD(iph->saddr), ntohs(tcph->source), NIPQUAD(iph->daddr), ntohs(tcph->dest), ! seq, ack, sack, win, end); DEBUGP("tcp_in_window: sender end=%u maxend=%u maxwin=%u scale=%i " "receiver end=%u maxend=%u maxwin=%u scale=%i\n", sender->td_end, sender->td_maxend, sender->td_maxwin, sender->td_scale, receiver->td_end, receiver->td_maxend, receiver->td_maxwin, receiver->td_scale); ! DEBUGP("tcp_in_window: I=%i II=%i III=%i IV=%i\n", ! before(end, sender->td_maxend + 1), ! after(seq, sender->td_end - receiver->td_maxwin - 1), before(sack, receiver->td_end + 1), after(ack, receiver->td_end - MAXACKWINDOW(sender))); if (sender->loose || receiver->loose || ! (before(seq, sender->td_maxend + 1) && ! after(end, sender->td_end - receiver->td_maxwin) && before(sack, receiver->td_end + 1) && after(ack, receiver->td_end - MAXACKWINDOW(sender)))) { /* *************** *** 653,658 **** --- 648,658 ---- sender->td_maxwin = swin; if (after(end, sender->td_end)) sender->td_end = end; + /* + * Update receiver data. + */ + if (after(end, sender->td_maxend)) + receiver->td_maxwin += end - sender->td_maxend; if (after(sack + win, receiver->td_maxend - 1)) { receiver->td_maxend = sack + win; if (win == 0) *************** *** 662,668 **** /* * Check retransmissions. */ ! if (*index == TCP_ACK_SET) { if (state->last_dir == dir && state->last_seq == seq && state->last_end == end) --- 662,668 ---- /* * Check retransmissions. */ ! if (index == TCP_ACK_SET) { if (state->last_dir == dir && state->last_seq == seq && state->last_end == end) *************** *** 689,697 **** after(seq, sender->td_end - receiver->td_maxwin - 1) ? before(sack, receiver->td_end + 1) ? after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG" ! : "ACK is under the lower bound (possibly overly delayed ACK)" ! : "ACK is over the upper bound (ACKed data has never seen yet)" ! : "SEQ is under the lower bound (retransmitted already ACKed data)" : "SEQ is over the upper bound (over the window of the receiver)"); res = ip_ct_tcp_be_liberal && !tcph->rst; --- 689,697 ---- after(seq, sender->td_end - receiver->td_maxwin - 1) ? before(sack, receiver->td_end + 1) ? after(ack, receiver->td_end - MAXACKWINDOW(sender)) ? "BUG" ! : "ACK is under the lower bound (possible overly delayed ACK)" ! : "ACK is over the upper bound (ACKed data not seen yet)" ! : "SEQ is under the lower bound (already ACKed data retransmitted)" : "SEQ is over the upper bound (over the window of the receiver)"); res = ip_ct_tcp_be_liberal && !tcph->rst; *************** *** 923,936 **** break; } ! if (!tcp_in_window(&conntrack->proto.tcp, dir, &index, skb, iph, th)) { WRITE_UNLOCK(&tcp_lock); return -NF_ACCEPT; } /* From now on we have got in-window packets */ - - /* If FIN was trimmed off, we don't change state. */ conntrack->proto.tcp.last_index = index; new_state = tcp_conntracks[dir][index][old_state]; --- 923,938 ---- break; } ! if (!tcp_in_window(&conntrack->proto.tcp, dir, index, skb, iph, th)) { WRITE_UNLOCK(&tcp_lock); + #ifdef TCPINWINDOW_ERROR_DROP_WORKAROUND + return -NF_DROP; + #else return -NF_ACCEPT; + #endif } /* From now on we have got in-window packets */ conntrack->proto.tcp.last_index = index; new_state = tcp_conntracks[dir][index][old_state]; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/net/socket.c linux-current/net/socket.c *** linux-2.6.10/net/socket.c Sat Dec 25 06:34:31 2004 --- linux-current/net/socket.c Wed Jun 14 21:13:00 2006 *************** *** 81,86 **** --- 81,87 ---- #include #include #include + #include #ifdef CONFIG_NET_RADIO #include /* Note : will define WIRELESS_EXT */ *************** *** 551,556 **** --- 552,559 ---- struct sock_iocb siocb; int ret; + ltt_ev_socket(LTT_EV_SOCKET_SEND, sock->type, size); + init_sync_kiocb(&iocb, NULL); iocb.private = &siocb; ret = __sock_sendmsg(&iocb, sock, msg, size); *************** *** 603,608 **** --- 606,613 ---- struct sock_iocb siocb; int ret; + ltt_ev_socket(LTT_EV_SOCKET_RECEIVE, sock->type, size); + init_sync_kiocb(&iocb, NULL); iocb.private = &siocb; ret = __sock_recvmsg(&iocb, sock, msg, size, flags); *************** *** 1197,1202 **** --- 1202,1209 ---- if (retval < 0) goto out_release; + ltt_ev_socket(LTT_EV_SOCKET_CREATE, retval, type); + out: /* It may be already another descriptor 8) Not kernel problem. */ return retval; *************** *** 1916,1921 **** --- 1923,1930 ---- a0=a[0]; a1=a[1]; + + ltt_ev_socket(LTT_EV_SOCKET_CALL, call, a0); switch(call) { diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/sound/core/memalloc.c linux-current/sound/core/memalloc.c *** linux-2.6.10/sound/core/memalloc.c Sat Dec 25 06:35:39 2004 --- linux-current/sound/core/memalloc.c Wed Jun 14 21:13:00 2006 *************** *** 150,156 **** #endif /* arch */ ! #if ! defined(__arm__) #define NEED_RESERVE_PAGES #endif --- 150,156 ---- #endif /* arch */ ! #if ! defined(__arm__) || ! defined(__mips__) #define NEED_RESERVE_PAGES #endif diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/sound/core/pcm_native.c linux-current/sound/core/pcm_native.c *** linux-2.6.10/sound/core/pcm_native.c Sat Dec 25 06:34:30 2004 --- linux-current/sound/core/pcm_native.c Wed Jun 14 21:13:00 2006 *************** *** 3052,3057 **** --- 3052,3061 ---- return NOPAGE_OOM; } else { vaddr = runtime->dma_area + offset; + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + /* dma_area is nocache addr */ + vaddr = CAC_ADDR(vaddr); + #endif page = virt_to_page(vaddr); } if (!PageReserved(page)) *************** *** 3073,3078 **** --- 3077,3086 ---- */ static int snd_pcm_default_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *area) { + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + /* use uncached access for dma_area */ + area->vm_page_prot = pgprot_noncached(area->vm_page_prot); + #endif area->vm_ops = &snd_pcm_vm_ops_data; area->vm_private_data = substream; area->vm_flags |= VM_RESERVED; diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/sound/core/sgbuf.c linux-current/sound/core/sgbuf.c *** linux-2.6.10/sound/core/sgbuf.c Sat Dec 25 06:35:15 2004 --- linux-current/sound/core/sgbuf.c Wed Jun 14 21:13:00 2006 *************** *** 97,103 **** --- 97,108 ---- } sgbuf->table[i].buf = tmpb.area; sgbuf->table[i].addr = tmpb.addr; + #if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT) + /* snd_dma_malloc_pages returns nocache addr */ + sgbuf->page_table[i] = virt_to_page(CAC_ADDR(tmpb.area)); + #else sgbuf->page_table[i] = virt_to_page(tmpb.area); + #endif sgbuf->pages++; } diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/tsb_modules/Kconfig linux-current/tsb_modules/Kconfig *** linux-2.6.10/tsb_modules/Kconfig Thu Jan 1 09:00:00 1970 --- linux-current/tsb_modules/Kconfig Fri Jul 7 22:07:31 2006 *************** *** 0 **** --- 1,11 ---- + # + # Toshiba Module Configuration + # + + menu "Toshiba Module" + + config TOSHIBA_SSFDC_DRV + tristate "Toshiba SmartMedia Card support" + depends on EMMA + + endmenu diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/tsb_modules/Makefile linux-current/tsb_modules/Makefile *** linux-2.6.10/tsb_modules/Makefile Thu Jan 1 09:00:00 1970 --- linux-current/tsb_modules/Makefile Fri Jul 7 22:07:31 2006 *************** *** 0 **** --- 1,4 ---- + # + # Makefile for Toshiba Modules + # + obj-y += block/ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/tsb_modules/block/Makefile linux-current/tsb_modules/block/Makefile *** linux-2.6.10/tsb_modules/block/Makefile Thu Jan 1 09:00:00 1970 --- linux-current/tsb_modules/block/Makefile Fri Jul 7 22:07:31 2006 *************** *** 0 **** --- 1,4 ---- + # + # Makefile for Toshiba Modules + # + obj-y += ssfdc/ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/tsb_modules/block/ssfdc/Makefile linux-current/tsb_modules/block/ssfdc/Makefile *** linux-2.6.10/tsb_modules/block/ssfdc/Makefile Thu Jan 1 09:00:00 1970 --- linux-current/tsb_modules/block/ssfdc/Makefile Fri Jul 7 22:07:31 2006 *************** *** 0 **** --- 1,5 ---- + # + # tsb_modules/block/ssfdc/Makefile + # + ssfdc-objs := ssfdcd.o + obj-$(CONFIG_TOSHIBA_SSFDC_DRV) := ssfdc.o diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/tsb_modules/block/ssfdc/ssfdc.h linux-current/tsb_modules/block/ssfdc/ssfdc.h *** linux-2.6.10/tsb_modules/block/ssfdc/ssfdc.h Thu Jan 1 09:00:00 1970 --- linux-current/tsb_modules/block/ssfdc/ssfdc.h Fri Jul 7 22:07:31 2006 *************** *** 0 **** --- 1,72 ---- + /* + * Copyright (C) 2004,2005 Toshiba Corporation + * + * + * SSFDC Driver Header + * all source codes include this header. + */ + + #ifndef _SSFDC_H_ + #define _SSFDC_H_ + + #define SSFDC_DEBUG_LEVEL 0 + + /* ioctl */ + #define SSFDCFMTMEDIA _IO(7, 0x47) + #define SSFDCSHOWBLOCK _IO(7, 0x48) + #define SSFDCDESTROYCIS _IO(7, 0x49) + #define SSFDCRECYCLEBADBLOCK _IO(7, 0x4a) + #define SSFDCERASEBLOCK _IO(7, 0x4b) + + /* Major Number */ + + #define SSFDC_MAJOR 241 + + #define SMIL_MODIFICATION + + #if defined(CONFIG_TOSHIBA_SSFDCCORE_DRV) + #define LINK_SSFDCCORE_DRV + #endif + + /* + * EMMA Definietions + */ + #ifdef CONFIG_EMMA + #include "asm/emma3/emma3_reg.h" + #undef HW_ECC_SUPPORTED /* Hardware ECC not Supported */ + #define NOUSE_INTERRUPT + #define USE_EMMAXBROI_SSFDC_CONTROLLER + #define INTV_SSFDC (0) /* no irq */ + #define SSFDC_VIRTBASE (0xb0000400) + #define SPR_VAL (0x25) + #define IDREAD_WAIT /* Current NULL */ + #define BUSYREAD_WAIT /* Current NULL */ + #define LARGE_PAGE_SUPPORT + #endif + + /*************************************************************************** + Hardware ECC Definition + ***************************************************************************/ + + #undef SSFDC_NOAUTOFORMAT /* define if no need auto format when w/o CIS */ + + #define VERIFY_AFTER_WRITE_CORE /* Enable verify in core driver */ + //#define VERIFY_AFTER_WRITE /* Enable verify in blockdev driver */ + #define VERIFY_RETRY_CNT 24 + #if defined(VERIFY_AFTER_WRITE) && defined(VERIFY_AFTER_WRITE_CORE) + #error "VERIFY_AFTER_WRITE and VERIFY_AFTER_WRITE_CORE are exclusive" + #endif + #define ENABLE_STAT_SSFDC /* Enable stats FreeBlock/BadBlock */ + #define RECYCLE_BADBLOCK /* Enable recycle bad block */ + #define WORKAROUND_ALL_ZERO_BLOCK /* Erase all zero block */ + //#define ENABLE_BLANK_CHECK /* Enable data blank check on init */ + //#define ACCESS_PHYS_SECTOR /* add PHYS access in ioctl */ + //#define ERROR_TEST_ENABLE /* for ERROR test */ + //#define IGNORE_READ_ERROR + //#define REMOVABLE_NAND_DEVICE + //#define ECC_ERROR_TEST 1 + //#define ECC_ERROR_TEST 2 + //#define ECC_ERROR_TEST_CNT 1 + //#define ECC_ERROR_PRINT /* Display ECC 1bit/2bit error */ + + #endif /* _SSFDC_H_ */ diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/tsb_modules/block/ssfdc/ssfdc_if.h linux-current/tsb_modules/block/ssfdc/ssfdc_if.h *** linux-2.6.10/tsb_modules/block/ssfdc/ssfdc_if.h Thu Jan 1 09:00:00 1970 --- linux-current/tsb_modules/block/ssfdc/ssfdc_if.h Fri Jul 7 22:07:31 2006 *************** *** 0 **** --- 1,77 ---- + /* + * Copyright (C) 2004 Toshiba Corporation + */ + + struct ssfdc_callback { + int (*Pwoff_SmartMedia)(void); + int (*Check_MediaPower)(void); + int (*Check_Parameter)(unsigned short *, unsigned char *, unsigned char *); + int (*Check_SmartMedia)(void); + int (*Erase_PhyOneBlock)(void); + int (*Init_SmartMedia)(void); + int (*Media_EraseAll)(void); + int (*Media_ReadSector)(unsigned long, unsigned short, unsigned char *); + int (*Media_WriteSector)(unsigned long, unsigned short, unsigned char *); + int (*Set_PhyFmtValue)(void); + int (*Write_PhyOneSect)(unsigned char *); + void (*Set_MediaInf)(unsigned char, unsigned char, unsigned short); + void (*Get_MediaInf)(unsigned char*, unsigned char*, unsigned short*, unsigned short*); + void (*Get_MediaSpec)(unsigned int*, unsigned int*, unsigned int*); + void (*Set_MediaSector)(unsigned char); + void (*Set_Redundant)(int); + void (*Set_sleep_time)(int); + unsigned char *(*Get_cis_id_info)(void); + unsigned short (*_Hw_Get_EJREQ)(void); + unsigned short (*_Hw_Get_IMASK)(void); + unsigned short (*_Hw_Get_ISTATUS)(void); + unsigned short (*_Hw_Get_STATUS)(void); + int (*Get_ERROR)(void); + int (*Get_NO_ERROR)(void); + int (*Get_ERR_ChangedMedia)(void); + int (*Get_INTV_SSFDC)(void); + unsigned long (*Get_VIRTADDR)(void); + unsigned char (*Get_CDIN)(void); + unsigned char (*Get_CDOUT)(void); + unsigned char (*Get_RDYREQ)(void); + void (*_Hw_Set_ImaskCi)(unsigned char); + void (*_Hw_Set_ImaskCo)(unsigned char); + void (*_Hw_Clr_ImaskCi)(void); + void (*_Hw_Clr_ImaskCo)(void); + void (*_Hw_Clr_ImaskCio)(unsigned char); + void (*_Hw_Clr_ImaskCioMrdy)(unsigned char); + void (*_Hw_Set_ImaskMi)(unsigned char); + void (*_Hw_Set_ImaskIMi)(unsigned char); + void (*_Hw_Set_ImaskMio)(unsigned char); + void (*_Hw_Set_ImaskDisRdyMo)(void); + void (*_Hw_Set_ImaskAll)(void); + void (*_Hw_Clr_ImaskAll)(void); + void (*_Hw_Set_ImaskOrg)(unsigned char); + void (*_Hw_Set_EJReq)(void); + unsigned char (*_Hw_inpb)(unsigned short); + unsigned char (*_Hw_ChkCardIn)(void); + void (*_Hw_Set_LED_0_2_Mask)(void); + int (*Read_PhyOneSect)(unsigned char *); + #ifdef ACCESS_PHYS_SECTOR + int (*Read_PhyOneSect_Plus)(unsigned char *, unsigned char *); + #endif + #ifdef ENABLE_STAT_SSFDC + int (*Media_ReadProcStats)(char *); + #endif + #ifdef RECYCLE_BADBLOCK + int (*Media_RecycleBadBlock)(unsigned char); + #endif + #ifdef ENABLE_ERASE_BLOCK + int (*Media_EraseBlock)(unsigned long,unsigned short); + #endif + }; + + int ssfdc_ddi_printf(const char *fmt, ...); + int ssfdc_ddi_init(struct ssfdc_callback *c); + void ssfdc_ddi_exit(void); + unsigned long ssfdc_ddi_getjiffies(void); + void ssfdc_ddi_udelay(unsigned int us); + void ssfdc_ddi_mdelay(unsigned int us); + unsigned long ssfdc_ddi_mask_intr(void); + void ssfdc_ddi_restore_intr(unsigned long flags); + void ssfdc_ddi_insw(unsigned int adr, unsigned short *buff, unsigned int count); + int ssfdc_ddi_getHZ(void); diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/tsb_modules/block/ssfdc/ssfdcd.c linux-current/tsb_modules/block/ssfdc/ssfdcd.c *** linux-2.6.10/tsb_modules/block/ssfdc/ssfdcd.c Thu Jan 1 09:00:00 1970 --- linux-current/tsb_modules/block/ssfdc/ssfdcd.c Fri Jul 28 20:30:59 2006 *************** *** 0 **** --- 1,1478 ---- + /* + * SSFDC Driver for Linux 2.6.x + * + * (C) Copyright TOSHIBA CORPORATION 2004-2005 + * All Rights Reserved. + * + * 2004-04-30 modified for TX4938 + * 2005-05-31 modified for EMMA2RH + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifdef CONFIG_PM + #include + #endif + + #include + #include + #include + #include + #include + + #include "ssfdc.h" + #include "ssfdc_if.h" + + #ifdef ENABLE_STAT_SSFDC + #include + #endif + + #ifdef CONFIG_PM + static struct pm_dev *ssfdc_pm_dev; /* registered PM device */ + #endif + + #ifndef KERNEL_SECTOR_SIZE + #define KERNEL_SECTOR_SIZE 512 + #endif + #define KS2HS ((sz_page)/KERNEL_SECTOR_SIZE) + + static struct ssfdc_callback *ssfdccallp; + + #ifdef LARGE_PAGE_SUPPORT + #define MAX_SECTSIZE 2048 + #define MAX_REDTSIZE 64 + #define MAX_PAGES 64 + #else + #define MAX_SECTSIZE 512 + #define MAX_REDTSIZE 16 + #define MAX_PAGES 32 + #endif + + /* NAND Flash ROM parameters */ + static unsigned int sz_page = MAX_SECTSIZE; + static unsigned int sz_redt = MAX_REDTSIZE; + static unsigned int sz_blocks = 1024; + + #define SSFDC_BUFSIZE (MAX_SECTSIZE * MAX_PAGES) + + static char rbuf[SSFDC_BUFSIZE], wbuf[SSFDC_BUFSIZE]; + #ifdef VERIFY_AFTER_WRITE + static char vbuf[SSFDC_BUFSIZE]; + #endif + + /* if #include "smil.h" READ,WRITE redefined */ + + #if SSFDC_DEBUG_LEVEL > 1 + #define DPRINT(x...) printk(x) + #else + #define DPRINT(x...) + #endif + + #if SSFDC_DEBUG_LEVEL > 2 + #define DPRINTK(x...) printk(x) + #else + #define DPRINTK(x...) + #endif + + #define SSFDCC_SIZE 0x100 /* the size of SSFDC Controller */ + + /* + * 35 has been officially registered as the RAMDISK major number, but + * so is the original MAJOR number of 1. We're using 1 in + * include/linux/major.h for now + */ + + #define DEVICE_ON(device) /* nothing */ + #define DEVICE_OFF(device) /* nothing */ + + #define MAJOR_NR SSFDC_MAJOR + + /* ssfdc */ + #undef DEVICE_NAME + #define DEVICE_NAME "ssfdc" + + struct semaphore sem; /* down before sleeping for media ready */ + #ifdef CONFIG_PM + struct semaphore power_sem; /* get before suspend */ + #endif + static int formatted = 0; /* check if media formatted or not */ + + /* Various static variables go here. Most are used only in the RAM disk code. + */ + + static unsigned short cyl; + static unsigned char head; + static unsigned char sect; + + /* Debug Information */ + static long interrupts_num; + static long readreq_num; + static long writereq_num; + static long real_wait_num; + + /* + * ssfdc device driver structure + */ + typedef struct ssfdc_dev + { + unsigned long phys_baseAddress; + unsigned long baseAddress; + int irq; + spinlock_t lock; + struct gendisk *gd; + } SSFDC_DEV, *PSSFDC_DEV; + static struct request_queue *ssfdc_queue; + + static struct ssfdc_dev *ssfdc_dev; + unsigned volatile char *ssfdc_base; + DECLARE_WAIT_QUEUE_HEAD(smreadyq); /* wait queue: RDYREQ */ + + /* + Added a queue for kernel thread and a variable to exit. + */ + #ifdef REMOVABLE_NAND_DEVICE + DECLARE_WAIT_QUEUE_HEAD(smhotplagq); /* wait queue for hotplug */ + static int running_kssfdc; /* kthread execute 1: stop 0 */ + static volatile int exit_kssfdc; + #endif + + /* + * forward declaration + */ + #ifndef NOUSE_INTERRUPT + static irqreturn_t ssfdc_interrupt(int, void *, struct pt_regs *); + #endif /* !NOUSE_INTERRUPT */ + static int ssfdc_phy_format(void); + static int ssfdc_destroy_CIS(void); + + #ifdef CONFIG_PM + static int ssfdc_pm_callback(struct pm_dev *, pm_request_t, void *); + #endif + + #ifdef ERROR_TEST_ENABLE + struct ssfdc_verify_test_struct { + int cmd; + int count; + int skip; + } ssfdc_verify_test_data; + EXPORT_SYMBOL(ssfdc_verify_test_data); + #define ERROR_TEST_SET(x1,x2,x3) do{ssfdc_verify_test_data.cmd=(x1);ssfdc_verify_test_data.count=(x2);ssfdc_verify_test_data.skip=(x3);}while(0) + #define ERROR_TEST_FUNC(x) \ + if(ssfdc_verify_test_data.cmd && ssfdc_verify_test_data.skip--<=0 && ssfdc_verify_test_data.count && (ssfdc_verify_test_data.cmd==(x))){ \ + switch(x){ \ + case 1: rv=-1; break; \ + case 2: rv=-1; break; \ + case 3: rv=-1; break; \ + case 4: rv=-1; break; \ + case 5: rv=-1; break; \ + } \ + ssfdc_verify_test_data.count--; } + #else + #define ERROR_TEST_FUNC(x) + #endif + + /* + * debug + */ + #if SSFDC_DEBUG_LEVEL > 0 + void sm_printk_buf(unsigned char *, int); + unsigned char bufbuf[SSFDC_BUFSIZE]; + #endif /* SSFDC_DEBUG_LEVEL > 0 */ + + /* + * function definition + */ + + static int + ssfdc_read_sector(char *data, int block, int size) + { + int rv; + + readreq_num++; + + #ifdef CONFIG_PM + down(&power_sem); + #endif + rv = ssfdccallp->Media_ReadSector(block, size, data); + + ERROR_TEST_FUNC(1); + #ifdef CONFIG_PM + up(&power_sem); + #endif + + if (rv) + printk("ssfdc_read_sector(blk=%d,size=%d): fail %x\n", block, size,rv); + return rv; + } + + static int + ssfdc_write_sector(char *data, int block, int size) + { + int rv; + #if defined(VERIFY_AFTER_WRITE) || defined(VERIFY_AFTER_WRITE_CORE) + int i; + #endif + + writereq_num++; + + #ifdef CONFIG_PM + down(&power_sem); + #endif + + #ifdef VERIFY_AFTER_WRITE + for(i=0; iMedia_WriteSector(block, size, data); + ERROR_TEST_FUNC(2); + if(rv){ + printk("%s write error %d, retry %d\n",__func__,rv,i); + continue; + } + rv = ssfdccallp->Media_ReadSector(block, size, vbuf); + ERROR_TEST_FUNC(3); + if(rv){ + printk("%s read error %d, retry %d\n",__func__,rv,i); + continue; + } + rv=memcmp(data,vbuf,size*sz_page); + ERROR_TEST_FUNC(4); + if(rv){ + rv = -1; + printk("%s verify error, retry %d\n",__func__,i); + }else{ + break; + } + }; + #elif defined(VERIFY_AFTER_WRITE_CORE) + for(i=0; iMedia_WriteSector(block, size, data); + if(rv==0) + ERROR_TEST_FUNC(5); + if(rv==0) + break; + printk("%s: error 0x%x,block=%d,size=%d,retry=%d/%d\n",__func__,rv,block,size,i,VERIFY_RETRY_CNT); + } + #else + rv = ssfdccallp->Media_WriteSector(block, size, data); + #endif + #ifdef CONFIG_PM + up(&power_sem); + #endif + + if (rv) + printk("ssfdc_write_sector(0x%x,0x%x,0x%x): fail %x\n", + (unsigned int)data,block,size,rv); + return rv; + } + + + /* custom end_request() to complete arbitrary number of sectors */ + static void end_request_sectors(struct request *req, int uptodate, int sectors) + { + if (!end_that_request_first(req, uptodate, sectors)) { + add_disk_randomness(req->rq_disk); + blkdev_dequeue_request(req); + end_that_request_last(req); + } + } + + #ifdef LARGE_PAGE_SUPPORT + static void + ssfdc_do_request_lp(request_queue_t *q) + { + unsigned int nr_hwpages, nr_kernelpages, nr_simplehwpages; + int adr_hwpage, adr_kernelpage, adr_simpehwpage; + int rc, rch, rct; + struct request *req; + int req_is_read; + int uas_head, uas_tail; + + while ((req = elv_next_request(q)) != NULL) { + if (!blk_fs_request(req)) { + end_request(req, 0); + continue; + } + + /* hard ware sector */ + adr_hwpage = req->sector / KS2HS; + + adr_kernelpage = req->sector; + + /* unaligned kernel sectors at head */ + uas_head = 0; + if(req->sector % KS2HS){ + uas_head = KS2HS - (req->sector % KS2HS); + } + + adr_simpehwpage = adr_hwpage; + if(uas_head){ + adr_simpehwpage++; + } + + #if SSFDC_DEBUG_LEVEL > 2 + if(!(ssfdccallp->_Hw_ChkCardIn())){ + printk("ssfdc: NoSmartMedia \n"); + end_request(req, 0); + continue; + } + + printk("\n* ssfdc_do_request *: nr_sectors=%x,sector=%x,dir=%d\n", + (unsigned int)req->nr_sectors,(unsigned int)req->sector,(int)rq_data_dir(req)); + #endif + if (req->sector + req->nr_sectors > (get_capacity(req->rq_disk)) ) { + printk("ssfdc: bad access: sector=%d, nr_sectors=%d (unit=512B)\n", + (unsigned int)req->sector, (unsigned int)req->nr_sectors); + end_request(req, 0); + continue; + } + + req_is_read = !rq_data_dir(req); + if (req_is_read) { + /* READ case */ + /* simple method. */ + + /* unaligned kernel sectors at tail */ + uas_tail = (req->sector + req->current_nr_sectors) % KS2HS; /* used in r */ + + nr_simplehwpages = ( (req->current_nr_sectors - uas_head - uas_tail ) / KS2HS ); + spin_unlock_irq(q->queue_lock); + + rc = rch = rct = 0; + + if(uas_head){ + /* handle only read request */ + rch = ssfdc_read_sector(rbuf, adr_hwpage, 1); + if(rch == 0){ + memcpy(req->buffer, + rbuf + (KS2HS - uas_head) * KERNEL_SECTOR_SIZE, + uas_head * KERNEL_SECTOR_SIZE); + } + } + + if(nr_simplehwpages){ + if (req_is_read) + rc = ssfdc_read_sector(req->buffer, adr_simpehwpage, nr_simplehwpages); + else + rc = ssfdc_write_sector(req->buffer, adr_simpehwpage, nr_simplehwpages); + } + + if(uas_tail){ + /* handle only read request */ + rct = ssfdc_read_sector(rbuf, adr_simpehwpage+nr_simplehwpages, 1); + if(rct == 0){ + memcpy(req->buffer + + uas_head * KERNEL_SECTOR_SIZE + + nr_simplehwpages * KS2HS, + rbuf, uas_tail * KERNEL_SECTOR_SIZE); + } + } + if(rch != 0 || rct != 0) + rc = 1; + spin_lock_irq(q->queue_lock); + end_request(req, rc == 0); + } else { + /* WRITE case */ + /* maximum (SSFDC_BUFSIZE/sz_page = 32@512B, 64@2kB) sectors */ + char *bufp = req_is_read ? rbuf : wbuf; + struct bio *bio; + struct bio_vec *bv; + int s, i; + int n_bufpages = SSFDC_BUFSIZE/sz_page; + int nr_actkernelpages = 0; + + /* unaligned kernel sectors at tail */ + uas_tail = (req->sector + req->nr_sectors) % KS2HS; + + nr_hwpages = ( (req->sector % KS2HS) + req->nr_sectors + (KS2HS - 1)) / KS2HS; + nr_kernelpages = req->nr_sectors; + + /* number of sectors to transfer in one time r/w to/from ssfdc */ + if (n_bufpages - (adr_hwpage % n_bufpages) < nr_hwpages){ + nr_hwpages = n_bufpages - (adr_hwpage % n_bufpages); + uas_tail = 0; + } + nr_actkernelpages = nr_hwpages * KS2HS; + s = adr_kernelpage; + if(uas_head){ + nr_actkernelpages -= KS2HS - uas_head; + } + if(uas_tail){ + nr_actkernelpages -= uas_tail; + } + + if (req_is_read) { + spin_unlock_irq(q->queue_lock); + rc = ssfdc_read_sector(rbuf, adr_hwpage, nr_hwpages); + spin_lock_irq(q->queue_lock); + } + + if (!req_is_read && uas_head){ + /* read modify write of head */ + rch = ssfdc_read_sector(rbuf, adr_hwpage, 1); + if(rch == 0){ + memcpy(bufp, rbuf, sz_page); + } + bufp += (KS2HS - uas_head) * KERNEL_SECTOR_SIZE; + s += (KS2HS - uas_head); + } + + if (!req_is_read && uas_tail && !uas_head){ + /* read modify write of tail */ + rch = ssfdc_read_sector(rbuf, adr_hwpage+nr_hwpages-1, 1); + if(rch == 0){ + memcpy(bufp+(nr_hwpages-1)*sz_page, rbuf, sz_page); + } + } + + rq_for_each_bio(bio, req) { + bio_for_each_segment(bv, bio, i) { + unsigned int n = bv->bv_len / KERNEL_SECTOR_SIZE, len; + void *buf_addr; + BUG_ON(bv->bv_len % KERNEL_SECTOR_SIZE); + if (s + n > adr_kernelpage + nr_kernelpages) + n = adr_kernelpage + nr_kernelpages - s; + len = n * KERNEL_SECTOR_SIZE; + buf_addr = page_address(bv->bv_page) + bv->bv_offset; + if (req_is_read) + memcpy(buf_addr, bufp, len); + else + memcpy(bufp, buf_addr, len); + bufp += len; + s += n; + if (s - adr_kernelpage >= nr_kernelpages) + goto copy_done; + } + } + copy_done: + if (!req_is_read) { + spin_unlock_irq(q->queue_lock); + rc = ssfdc_write_sector(wbuf, adr_hwpage, nr_hwpages); + spin_lock_irq(q->queue_lock); + } + + /* do end_request for the contiguous requests */ + end_request_sectors(req, rc == 0, nr_actkernelpages); + } + } + } + #endif /* LARGE_PAGE_SUPPORT */ + + static void + ssfdc_do_request(request_queue_t *q) + { + unsigned int nsect; + int block; + int rc; + int transfered_block; + struct request *req; + int req_is_read; + + DPRINTK("\n* ssfdc_do_request *: start \n"); + DPRINT("[m_req in][rbuf:%p][wbuf:%p]", rbuf, wbuf); + + if (down_trylock(&sem)) { + #if 0 + /* Even if failed to trylock, it is NOT error. OK to return. */ + /* Caution: Don't printk, it is enough heavy if many requests come */ + printk("lock error\n"); + #endif + return; + } + + #ifdef LARGE_PAGE_SUPPORT + if(sz_page > KERNEL_SECTOR_SIZE){ + ssfdc_do_request_lp(q); + up(&sem); + return; + } + #endif + + while ((req = elv_next_request(q)) != NULL) { + if (!blk_fs_request(req)) { + end_request(req, 0); + continue; + } + + nsect = req->nr_sectors; + block = req->sector; + + #if SSFDC_DEBUG_LEVEL > 2 + if(!(ssfdccallp->_Hw_ChkCardIn())){ + printk("ssfdc: NoSmartMedia \n"); + end_request(req, 0); + continue; + } + + printk("\n* ssfdc_do_request *: nsect=%x,block=%x\n", + (unsigned int)nsect,(unsigned int)block); + #endif + if (block + nsect > get_capacity(req->rq_disk)) { + printk("ssfdc: bad access: block=%d, count=%d\n", + block, nsect); + end_request(req, 0); + continue; + } + + req_is_read = !rq_data_dir(req); + if (req_is_read) { + /* READ case */ + /* simple method. */ + transfered_block = req->current_nr_sectors; + spin_unlock_irq(q->queue_lock); + if (req_is_read) + rc = ssfdc_read_sector(req->buffer, block, + transfered_block); + else + rc = ssfdc_write_sector(req->buffer, block, + transfered_block); + spin_lock_irq(q->queue_lock); + end_request(req, rc == 0); + } else { + /* WRITE case */ + /* maximum 32 sectors */ + char *bufp = req_is_read ? rbuf : wbuf; + struct bio *bio; + struct bio_vec *bv; + int s, i; + + /* number of sectors to transfer in one time r/w to/from ssfdc */ + if (32 - block % 32 < nsect) + nsect = 32 - block % 32; + + if (req_is_read) { + spin_unlock_irq(q->queue_lock); + rc = ssfdc_read_sector(rbuf, block, nsect); + spin_lock_irq(q->queue_lock); + } + + s = block; + rq_for_each_bio(bio, req) { + bio_for_each_segment(bv, bio, i) { + unsigned int n = bv->bv_len / 512, len; + void *buf_addr; + BUG_ON(bv->bv_len % 512); + if (s + n > block + nsect) + n = block + nsect - s; + len = n * 512; + buf_addr = page_address(bv->bv_page) + bv->bv_offset; + if (req_is_read) + memcpy(buf_addr, bufp, len); + else + memcpy(bufp, buf_addr, len); + bufp += len; + s += n; + if (s - block >= nsect) + goto copy_done; + } + } + copy_done: + if (!req_is_read) { + spin_unlock_irq(q->queue_lock); + rc = ssfdc_write_sector(wbuf, block, nsect); + spin_lock_irq(q->queue_lock); + } + + /* do end_request for the contiguous requests */ + end_request_sectors(req, rc == 0, nsect); + } + } + up(&sem); + } + + static int + ssfdc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) + { + struct hd_geometry g; + int rv; + + DPRINTK("\n* ssfdc_ioctl *: start \n"); + DPRINT("ssfdc: ioctl cmd=%d, arg=0x%x\n", cmd, (unsigned int) arg); + + switch (cmd) { + case HDIO_GETGEO: + g.heads = head; + g.sectors = sect; + g.cylinders = cyl; + g.start = ( get_start_sect(inode->i_bdev) / KS2HS ); + return copy_to_user((void __user *)arg, &g, sizeof g) ? -EFAULT : 0; + + case SSFDCFMTMEDIA: /* Format the media physically */ + printk("ssfdc ioctl: format media.\n"); + rv = ssfdc_phy_format(); + return rv; + + case SSFDCDESTROYCIS: /* destroy CIS for debug */ + printk("ssfdc ioctl: destroy CIS (debug).\n"); + rv = ssfdc_destroy_CIS(); + return rv; + #ifdef RECYCLE_BADBLOCK + case SSFDCRECYCLEBADBLOCK: + if(arg<0 || arg>8) + return -EINVAL; + down(&sem); + rv = ssfdccallp->Media_RecycleBadBlock(arg); + up(&sem); + return rv; + #endif + #ifdef ENABLE_ERASE_BLOCK + case SSFDCERASEBLOCK: + { + int start,count; + if(copy_from_user(&start,(void*)arg,sizeof(int))) + return -EFAULT; + if(copy_from_user(&count,(void*)(arg+sizeof(int)),sizeof(int))) + return -EFAULT; + down(&sem); + rv = ssfdccallp->Media_EraseBlock(start,count); + up(&sem); + if(rv) + return -EIO; + return 0; + } + #endif + #ifdef ERROR_TEST_ENABLE + case 0x9998: + { + int value[3]; + copy_from_user(value,(void*)arg,12); + ERROR_TEST_SET(value[0],value[1],value[2]); + return 0; + } + #endif + #ifdef ACCESS_PHYS_SECTOR + case 0x9999: + { + int *param=(int*)arg; + int c=param[0]; + int zone=param[2]; + int sector=param[3]; + int phyblock=param[4]; + char buf[MAX_SECTSIZE]; + char buf_redundant[MAX_REDTSIZE]; + + //printk("9999,0x%x,%d,%d,%d\n",param[0],zone,sector,phyblock); + switch(c){ + case 'e': + //printk("Erase_PhyOneBlock\n"); + ssfdccallp->Check_MediaPower(); + ssfdccallp->Set_MediaInf(zone,sector,phyblock); + ssfdccallp->Erase_PhyOneBlock(); + return 0; + case 'w': + //printk("Write_PhyOneSect\n"); + copy_from_user(buf,(void*)param[1],MAX_SECTSIZE); + ssfdccallp->Check_MediaPower(); + ssfdccallp->Set_MediaInf(zone,sector,phyblock); + ssfdccallp->Write_PhyOneSect(buf); + return 0; + case 'r': + //printk("Read_PhyOneSect\n"); + ssfdccallp->Check_MediaPower(); + ssfdccallp->Set_MediaInf(zone,sector,phyblock); + ssfdccallp->Read_PhyOneSect_Plus(buf, buf_redundant); + copy_to_user((void __user *)param[1],buf,MAX_SECTSIZE); + copy_to_user((void __user *)param[5],buf_redundant,MAX_REDTSIZE); + return 0; + } + } + #endif + } + return -EINVAL; + } + + static int + ssfdc_open(struct inode *inode, struct file *filp) + { + DPRINTK("* ssfdc_open *: start.\n"); + + #ifdef USE_EXTERNAL_SSFDC_CONTROLLER + ssfdccallp->Check_SmartMedia(); + #else + #ifdef REMOVABLE_NAND_DEVICE + ssfdccallp->Init_SmartMedia(); + #endif + #endif + + DPRINTK("* ssfdc_open *: end \n"); + return 0; + } + + static int + ssfdc_release(struct inode *inode, struct file *filp) + { + #ifdef USE_EXTERNAL_SSFDC_CONTROLLER + DPRINTK("* ssfdc_release *: end \n"); + #else + DPRINT("ssfdc: release\n"); + ssfdccallp->Pwoff_SmartMedia(); + #endif + return 0; + } + + static int + ssfdc_revalidate(struct gendisk *disk) + { + int rc = -EIO; + DPRINTK("* ssfdc_revalidate *: start \n"); + down(&sem); + if (ssfdccallp->Check_Parameter(&cyl, &head, §) == 0) { + set_capacity(ssfdc_dev->gd, (long) cyl * (long) head * (long) sect * KS2HS ); + rc = 0; + } + up(&sem); + + return rc; + } + + static struct block_device_operations ssfdc_fops = { + .open = ssfdc_open, + .release = ssfdc_release, + .ioctl = ssfdc_ioctl, + .revalidate_disk = ssfdc_revalidate, + }; + + static ssize_t + ssfdc_info_show(struct device *dev, char *page) + { + char *p; + p = page; + p += sprintf(p, "ssfdc: sysfs information\n"); + p += sprintf(p, " baseaddr = 0x%08x\n", (unsigned int) (ssfdc_dev->baseAddress)); + p += sprintf(p, " interrupts = %d\n", (int) interrupts_num); + p += sprintf(p, " readreq, writereq = %d, %d\n", (int) readreq_num, (int) writereq_num); + p += sprintf(p, " wait, rwait = %d, %d\n", 0, (int) real_wait_num); + + return p - page; + } + static DEVICE_ATTR(info, S_IRUGO, ssfdc_info_show, NULL); + + static int + find_ssfdc(struct ssfdc_dev *dev) + { + dev->baseAddress = ssfdccallp->Get_VIRTADDR(); + dev->irq = ssfdccallp->Get_INTV_SSFDC(); /*S1_READY_NINT */ + ssfdc_base = (unsigned char *)dev->baseAddress; + + DPRINTK("* find_ssfdc *:irq=%x\n",dev->irq); + return 0; + } + + #ifdef REMOVABLE_NAND_DEVICE + /* main loop of kssfdc thread */ + static void ssfdc_kthread_mainloop(struct ssfdc_dev *sdev) + { + unsigned char mask; + + long flags; + unsigned char status; + + /* enable interrupts by HotPlag */ + local_irq_save(flags); + + mask = ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK()); + ssfdccallp->_Hw_Set_ImaskMio(mask); + local_irq_restore(flags); + + for(;;){ + DPRINT("%s: ssfdc_kthread_mainloop sleep on \n", __FUNCTION__); + DPRINTK("mainloop : sleep \n"); + //real_wait_num++; + sleep_on(&smhotplagq); + + status = ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_ISTATUS()); + DPRINTK("mainloop : wakeup! ists=%x\n", status); + if(ssfdccallp->_Hw_ChkCardIn()){ + DPRINTK("mainloop : revalidate \n"); + ssfdc_revalidate(sdev->gd); + ssfdccallp->_Hw_Set_ImaskDisRdyMo(); + DPRINTK("mainloop: insert imask=%x sts=%x\n", + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK()), + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_ISTATUS())); + printk("--- SmartMeida in end ----\n\n"); + }else{ + mask = ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK()); + ssfdccallp->_Hw_Set_ImaskMi(mask); + DPRINTK("mainloop : out imask=%x ists=%x\n", + (unsigned int)ssfdccallp->_Hw_Get_IMASK(), + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_ISTATUS())); + printk("---- SmartMeida out end ----\n\n"); + } + } + } + + + /* kssfdc thread - initalize and clean up SmartMedia */ + static int ssfdc_kthread(void* dev_data) + { + struct ssfdc_dev *sdev = dev_data; + running_kssfdc = 1; + DPRINT("%s: ssfdc_kthread running\n", __FUNCTION__); + + /* This thread doesn't need any user-level access, + * so get rid of all our resources.. + */ + daemonize("kssfdc"); + + ssfdc_kthread_mainloop(sdev); + + running_kssfdc = 0; + DPRINT("kssfdc exit\n"); + return 0; + } + #endif + + #ifdef ENABLE_STAT_SSFDC + static int ssfdc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) + + { + int len = 0; + char* p = page; + p += ssfdccallp->Media_ReadProcStats(p); + len = p - page; + *eof = 1; + *start = page + off; + len -= off; + if (len<0) len = 0; + return len; + } + #endif + + static struct completion device_release; + static void ssfdc_device_release(struct device *dev) + { + complete(&device_release); + } + static struct platform_device ssfdc_device = { + .name = DEVICE_NAME, + .id = 0, + .dev = { + .release = ssfdc_device_release, + } + }; + + static int + ssfdc_init(void) + { + int rc; + + ssfdccallp->Set_sleep_time(0); /* debug */ + ssfdc_dev = kmalloc(sizeof(ssfdc_dev), GFP_KERNEL); + if (ssfdc_dev == NULL) { + printk("ssfdc: Cannot alloc memory.\n"); + return -ENOMEM; + } + + if (find_ssfdc(ssfdc_dev)) { + kfree(ssfdc_dev); + printk("ssfdc: Cannot find_ssfdc.\n"); + return -ENXIO; + } + + #ifdef USE_EXTERNAL_SSFDC_CONTROLLER + ssfdccallp->_Hw_Set_LED_0_2_Mask(); + #endif + + DPRINTK("* ssfdc_init *: Init_smartMedia \n"); + ssfdccallp->Init_SmartMedia(); + ssfdccallp->_Hw_Set_ImaskAll(); /* mask all ssfdc controller's interrupt */ + #ifndef USE_EXTERNAL_SSFDC_CONTROLLER + ssfdccallp->_Hw_Clr_ImaskAll(); /* clear all ssfdc controller's interrupts */ + #endif + + + #ifndef NOUSE_INTERRUPT + if (request_irq(ssfdc_dev->irq, ssfdc_interrupt, SA_SHIRQ, DEVICE_NAME, ssfdc_dev)) { + DPRINT("ssfdc: unable to get IRQ%d for the hard disk driver\n", ssfdc_dev->irq); + return -1; + } else { + DPRINT("request_irq()done for ssfdc. irq=%d\n", ssfdc_dev->irq); + } + #endif /* !NOUSE_INTERRUPT */ + + sema_init(&sem, 1); /* ssfdc ready-wait routine */ + DPRINTK("* ssfdc_init *: Check_smartMedia \n"); + + /* Check Media */ + if ((rc = ssfdccallp->Check_SmartMedia()) && rc != ssfdccallp->Get_ERR_ChangedMedia()) { + printk("ssfdc: Can't find media. (rc = %d)\n", rc); + #ifndef NOUSE_INTERRUPT + free_irq(ssfdc_dev->irq, ssfdc_dev); + #endif /* !NOUSE_INTERRUPT */ + kfree(ssfdc_dev); + return -ENXIO; + } + DPRINTK("* ssfdc_init *: Check_Parameter \n"); + + /* Get Media information */ + /* (Check_Parameter() will power on through Check_MediaPower() */ + if (ssfdccallp->Check_Parameter(&cyl, &head, §)) { + ssfdccallp->Get_MediaSpec(&sz_page, &sz_redt, &sz_blocks); + printk("ssfdc: Can't get media information.\n"); + #ifdef SSFDC_NOAUTOFORMAT + printk(" CAUTION: Media may not be physically formatted. Try physical format. 2\n"); + + formatted = 0; + #else + printk(" Start physical format...\n"); + if (ssfdc_phy_format()) + formatted = 0; + #endif + + } else { + ssfdccallp->Get_MediaSpec(&sz_page, &sz_redt, &sz_blocks); + formatted = 1; + DPRINT("SSFDC(C:H:S) (%u:%u:%u)\n", cyl, head, sect); + } + + DPRINTK("SSFDC(C:H:S) (%u:%u:%u)\n", cyl, head, sect); + DPRINTK("\n* ssfdc_init *: register_blkdev \n"); + + /* regist block device */ + if (register_blkdev(MAJOR_NR, DEVICE_NAME) < 0) { + printk("ssfdc: Could not get major number %d\n", MAJOR_NR); + #ifndef NOUSE_INTERRUPT + free_irq(ssfdc_dev->irq, ssfdc_dev); + #endif /* !NOUSE_INTERRUPT */ + kfree(ssfdc_dev); + return -EIO; + } + spin_lock_init(&ssfdc_dev->lock); + /* + * Setup for gendisk. + */ + ssfdc_dev->gd = alloc_disk(1 << 6); + if (!ssfdc_dev->gd) { + printk("ssfdc: Could not allocate gendisk!"); + unregister_blkdev(MAJOR_NR, DEVICE_NAME); + kfree(ssfdc_dev); + return -ENOMEM; + } + ssfdc_dev->gd->major = MAJOR_NR; + ssfdc_dev->gd->first_minor = 0; + ssfdc_dev->gd->fops = &ssfdc_fops; + ssfdc_dev->gd->private_data = ssfdc_dev; + sprintf(ssfdc_dev->gd->disk_name, DEVICE_NAME "%c", 0 + 'a'); + sprintf(ssfdc_dev->gd->devfs_name, DEVICE_NAME "/%c", 0 + 'a'); + + /* regist request function */ + ssfdc_queue = blk_init_queue(ssfdc_do_request, &ssfdc_dev->lock); + if (!ssfdc_queue) { + printk("ssfdc: Could not init queue!"); + del_gendisk(ssfdc_dev->gd); + put_disk(ssfdc_dev->gd); + unregister_blkdev(MAJOR_NR, DEVICE_NAME); + kfree(ssfdc_dev); + return -ENOMEM; + } + ssfdc_dev->gd->queue = ssfdc_queue; + + #ifdef LARGE_PAGE_SUPPORT + blk_queue_hardsect_size(ssfdc_queue, sz_page); + #endif + + devfs_mk_dir(DEVICE_NAME); + + #ifdef CONFIG_PM + sema_init(&power_sem, 1); /* ensure ssfdc atomic r/w */ + ssfdc_pm_dev = pm_register(PM_SYS_DEV, PM_SYS_SSFDC, ssfdc_pm_callback); + #endif + + DPRINTK("\n* ssfdc_init *: register_disk.. \n"); + + set_capacity(ssfdc_dev->gd, (long) cyl * (long) head * (long) sect * KS2HS ); + #if 0 /* ONBOARD only */ + ssfdc_dev->gd->flags |= GENHD_FL_REMOVABLE; + #endif + add_disk(ssfdc_dev->gd); + + /* create thread */ + #ifdef REMOVABLE_NAND_DEVICE + DPRINTK("\n* ssfdc_init *: create_thread \n"); + exit_kssfdc = 0; + kernel_thread(ssfdc_kthread, ssfdc_dev, + (CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD)); + #endif + + /* create sysfs */ + DPRINTK("\n* ssfdc_init *: device_create_file \n"); + platform_device_register(&ssfdc_device); + device_create_file(&ssfdc_device.dev, &dev_attr_info); + + #ifdef ENABLE_STAT_SSFDC + if (!create_proc_read_entry ("driver/ssfdc", 0, NULL, ssfdc_read_proc, NULL)) { + printk("ssfdc_init: Cannot create proc entry\n"); + } + #endif + + #ifndef NOUSE_INTERRUPT + DPRINTK("ssfdc imask=%x ists=%x\n", + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK()), + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_ISTATUS())); + #endif /* !NOUSE_INTERRUPT */ + DPRINTK("ssfdc: %uM(%u)byte\n", cyl * head * sect * sz_page / 1024 / 1000, sz_page * cyl * head * sect); + return 0; + } + + /* Before freeing the module, invalidate all of the protected buffers! */ + static void + ssfdc_cleanup(void) + { + DPRINTK("ssfdc: cleanup\n"); + + init_completion(&device_release); + device_remove_file(&ssfdc_device.dev, &dev_attr_info); + platform_device_unregister(&ssfdc_device); + + ssfdccallp->_Hw_Set_ImaskAll(); /* mask all interrupt */ + #ifndef NOUSE_INTERRUPT + free_irq(ssfdc_dev->irq, ssfdc_dev); + #endif /* !NOUSE_INTERRUPT */ + del_gendisk(ssfdc_dev->gd); + put_disk(ssfdc_dev->gd); + devfs_remove(DEVICE_NAME); + unregister_blkdev(MAJOR_NR, DEVICE_NAME); + blk_cleanup_queue(ssfdc_queue); + + #ifdef CONFIG_PM + if (ssfdc_pm_dev) + pm_unregister(ssfdc_pm_dev); + #endif + + kfree(ssfdc_dev); + wait_for_completion(&device_release); + DPRINTK("* ssfdc_cleanup *: end.\n"); + } + + #ifndef NOUSE_INTERRUPT + static irqreturn_t + ssfdc_interrupt(int irq, void *dev_id, struct pt_regs *regs) + { + unsigned char mask, status; + + /*printk("[+si SR:%x &:%x INTEN1:%x STCLR1:%x]",PCSR,PCSR & PCSR_S1_READY,INTEN1,INTSTATCLR1); */ + + mask = ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK()); + status = ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_ISTATUS()); + + DPRINTK("---interrup ISTS=%x sts=%x\n", + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_ISTATUS()), + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_STATUS())); + if (status & mask) { + DPRINT("ssfdc_interrupt():int=%d\n", irq); + DPRINT(" interrupt status=%x\n", + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_ISTATUS())); + DPRINT(" interrupt mask=%x\n", + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK())); + } else { + return IRQ_NONE; + } + + #ifdef USE_EXTERNAL_SSFDC_CONTROLLER + ssfdccallp->_Hw_Clr_ImaskCio(mask); + #endif + + interrupts_num++; + ssfdccallp->_Hw_Clr_ImaskAll(); /* clear all ssfdc controller's interrupts */ + + #ifdef REMOVABLE_NAND_DEVICE + if (status & ssfdccallp->Get_CDIN()) { + #ifdef USE_EXTERNAL_SSFDC_CONTROLLER + if(ssfdccallp->_Hw_ChkCardIn()){ + DPRINTK("---- ssfdc_interrupt/SmartMeida in ----mask=%x ists=%x\n", + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK()), status); + wake_up(&smhotplagq); + DPRINTK("---- SmartMeida in start ---- \n"); + } + #else + DPRINT(" Media In (CDIN)\n"); + ssfdccallp->_Hw_Clr_ImaskCi(); + #endif /* USE_EXTERNAL_SSFDC_CONTROLLER */ + } + + if (status & ssfdccallp->Get_CDOUT()) { + #ifdef USE_EXTERNAL_SSFDC_CONTROLLER + if( ~(ssfdccallp->_Hw_ChkCardIn()) ){ + + DPRINTK("---- ssfdc_interrupt/SmartMeida out ----mask=%x ists=%x\n", + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK()), status); + wake_up(&smhotplagq); + DPRINTK("---- SmartMeida out start ---- \n"); + } + #else + DPRINT(" Media Out (CDOUT)\n"); + ssfdccallp->_Hw_Clr_ImaskCo(); + #endif /* USE_EXTERNAL_SSFDC_CONTROLLER */ + } + if (status & ssfdccallp->_Hw_Get_EJREQ()) { + DPRINTK("---- ssfdc_interrupt/SmartMeida eject ----mask=%x sts=%x\n", + ssfdccallp->_Hw_inpb(ssfdccallp->_Hw_Get_IMASK()), status); + DPRINT(" Media Eject Requested (EJREQ)\n"); + ssfdccallp->_Hw_Set_EJReq(); + } + #endif /* REMOVABLE_NAND_DEVICE */ + + if (status & ssfdccallp->Get_RDYREQ()) { + DPRINT(" Media Ready (RDYREQ)\n"); + ssfdccallp->_Hw_Clr_ImaskCioMrdy(mask); + wake_up(&smreadyq); + /* interruptible_wake_up(&smreadyq); */ + + ssfdccallp->_Hw_Set_ImaskOrg(mask); + } + /* printk("[-si SR:%x &:%x INTEN1:%x STCLR1:%x]",PCSR,PCSR & PCSR_S1_READY,INTEN1,INTSTATCLR1); */ + return IRQ_HANDLED; + } + #endif /* !NOUSE_INTERRUPT */ + + #ifdef CONFIG_PM + static void + ssfdc_suspend(void) + { + /* down(&power_sem); */ + DPRINT("ssfdc: suspend...\n"); + } + + static void + ssfdc_resume(void) + { + DPRINT("ssfdc: resume...\n"); + /* up(&power_sem); */ + } + + static int + ssfdc_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data) + { + switch (req) { + case PM_SUSPEND: + ssfdc_suspend(); + break; + case PM_RESUME: + ssfdc_resume(); + break; + } + return 0; + } + #endif + + static int + ssfdc_phy_format(void) + { + int rc, b, i; + int fok = 0; + unsigned char sm_zone, sm_sector; + unsigned short sm_phyblock, sm_logblock; + + #ifdef SSFDC_NOAUTOFORMAT + printk("* ssfdc_phy_format *: start \n"); + #endif + + ssfdccallp->Init_SmartMedia(); + + /* Power on */ + if ((rc = ssfdccallp->Check_MediaPower())) { + printk("ssfdc: Can't power on. (rc = %d)\n", rc); + return rc; + } + + /* set physical format value on global Ssfdc */ + if ((rc = ssfdccallp->Set_PhyFmtValue())) { + printk("ssfdc: Can't set physical format value. (rc = %d)\n", rc); + return rc; + } + + /* if need to clear late-fail block, define FORCE_CLEAR_LF *//***/ + + for (b = 0; !(fok) && (b < sz_blocks); b++) { + ssfdccallp->Set_MediaInf(0, 0, (unsigned short)b); + printk("[b=%d]\n", b); + if (!ssfdccallp->Erase_PhyOneBlock()) { + for (i = 0; i < sz_redt; i++) { + ssfdccallp->Set_Redundant(i); + } + ssfdccallp->Get_MediaInf(&sm_zone, &sm_sector, + &sm_phyblock, &sm_logblock); + printk("block erase succeeded @[Z:%d,PB:%d]\n", + sm_zone, sm_phyblock); + #define SSFDC_CIS_SIZE 512 + for (i = 0; i < sz_page/SSFDC_CIS_SIZE ;i++){ + memcpy(wbuf + i*SSFDC_CIS_SIZE, ssfdccallp->Get_cis_id_info(), SSFDC_CIS_SIZE); + } + if (!ssfdccallp->Write_PhyOneSect(wbuf)) { + fok = 1; + ssfdccallp->Get_MediaInf(&sm_zone, &sm_sector, + &sm_phyblock, &sm_logblock); + printk("CIS write done @[Z:%d,PB:%d]\n", + sm_zone, sm_sector); + } else { + ssfdccallp->Get_MediaInf(&sm_zone, &sm_sector, + &sm_phyblock, &sm_logblock); + printk("CIS write failed @[Z:%d,PB:%d]\n", + sm_zone, sm_phyblock); + } + + } else { + ssfdccallp->Get_MediaInf(&sm_zone, &sm_sector, + &sm_phyblock, &sm_logblock); + printk("block erase failed @[Z:%d,PB:%d]\n", + sm_zone, sm_phyblock); + } + } + if (b == 1024) { + printk("Format failed. This media can't have CIS block.\n"); + return ssfdccallp->Get_ERROR(); + } + #if SSFDC_DEBUG_LEVEL > 0 + { + int rc; + + ssfdccallp->Set_MediaSector(0); + rc = ssfdccallp->Read_PhyOneSect(bufbuf); + ssfdccallp->Get_MediaInf(&sm_zone, &sm_sector, + &sm_phyblock, &sm_logblock); + printk("block read @[Z:%d,PB:%d,S:%d] rc:%x\n", + sm_sector, sm_phyblock, sm_sector, rc); + sm_printk_buf(bufbuf, sz_page); + } + #endif /* SSFDC_DEBUG_LEVEL > 0 */ + + printk("erase all blocks...\n"); + if (ssfdccallp->Media_EraseAll() != ssfdccallp->Get_NO_ERROR()) { + printk("format failed. some blocks may be remained late-failed or something illegal.\n"); + return ssfdccallp->Get_ERROR(); + } else { + printk("SmartMedia physical format done.\n"); + } + + if (ssfdccallp->Check_Parameter(&cyl, &head, §)) { + printk("ssfdc: Can't get media information after phyisical format.\n"); + return ssfdccallp->Get_ERROR(); + } else { + printk("ssfdc: Physical format succeeded.\n"); + formatted = 1; + + return 0; + } + } + + static int + ssfdc_destroy_CIS(void) + { + int rc, b; + int eok = 0; + unsigned char sm_zone, sm_sector; + unsigned short sm_phyblock, sm_logblock; + + #ifdef SSFDC_NOAUTOFORMAT + printk("* ssfdc_destroy_CIS *: start \n"); + #endif + + ssfdccallp->Init_SmartMedia(); + + /* Power on */ + if ((rc = ssfdccallp->Check_MediaPower())) { + printk("ssfdc: Can't power on. (rc = %d)\n", rc); + return rc; + } + + /* set physical format value on global Ssfdc */ + if ((rc = ssfdccallp->Set_PhyFmtValue())) { + printk("ssfdc: Can't set physical format value. (rc = %d)\n", rc); + return rc; + } + /* if need to clear late-fail block, define FORCE_CLEAR_LF *//***/ + + for (b = 0; !(eok) && (b < sz_blocks); b++) { + ssfdccallp->Set_MediaInf(0, 0, (unsigned short)b); + printk("[b=%d]\n", b); + if (!ssfdccallp->Erase_PhyOneBlock()) { + ssfdccallp->Get_MediaInf(&sm_zone, &sm_sector, + &sm_phyblock, &sm_logblock); + printk("block erase succeeded @[Z:%d,PB:%d]\n", + sm_zone, sm_phyblock); + eok = 1; + } else { + ssfdccallp->Get_MediaInf(&sm_zone, + &sm_sector, &sm_phyblock, &sm_logblock); + printk("block erase failed @[Z:%d,PB:%d]\n", + sm_zone, sm_phyblock); + } + } + if (b == 1024) { + printk("Erase failed. This media can't be accessed.\n"); + return ssfdccallp->Get_ERROR(); + } + #if SSFDC_DEBUG_LEVEL > 0 + { + int rc; + + ssfdccallp->Set_MediaSector(0); + rc = ssfdccallp->Read_PhyOneSect(bufbuf); + ssfdccallp->Get_MediaInf(&sm_zone, + &sm_sector, &sm_phyblock, &sm_logblock); + printk("block read @[Z:%d,PB:%d,S:%d] rc:%x\n", + sm_zone, sm_phyblock, sm_sector, rc); + sm_printk_buf(bufbuf, sz_page); + } + #endif /* SSFDC_DEBUG_LEVEL > 0 */ + + /* *** */ + if (ssfdccallp->Check_Parameter(&cyl, &head, §)) { + printk("ssfdc: Can't get media information after CIS is destroyed.\n"); + formatted = 0; + return 0; /* OK, CIS is successfully destroyed */ + } else { + printk("ssfdc: CIS isn't destroyed successfully.\n"); + formatted = 1; + return ssfdccallp->Get_ERROR(); + } + + } + + /* time(usec) sleep */ + long + wait_for_ready_on_timeout(long time) + { + int rc; + real_wait_num++; + /* spin_unlock_irq(&io_request_lock); */ + rc = sleep_on_timeout(&smreadyq, time); + /* spin_lock_irq(&io_request_lock); */ + return (rc); + } + + #if SSFDC_DEBUG_LEVEL > 0 + void + sm_printk_buf(unsigned char *buf, int size) + { + int i, j, lines; + + lines = size / 0x10; + printk(" "); + for (j = 0; j < 0x10; j++) { + printk("+%x ", j); + } + printk("\n"); + for (i = 0; i < lines; i++) { + printk("%.4xh ", i * 0x10); + for (j = 0; j < 0x10; j++) { + printk("%.2x ", buf[i * 0x10 + j]); + } + printk("\n"); + } + if (size % 0x10) { + printk("%.4xh ", i * 0x10); + for (j = 0; j < (size % 0x10); j++) + printk("%.2x ", buf[i * 0x10 + j]); + printk("\n"); + } + } + #endif /* SSFDC_DEBUG_LEVEL > 0 */ + + //================================================================== + + #ifndef LINK_SSFDCCORE_DRV + int __init ssfdc_init_dummy(void) { return 0; } + #else + extern int ssfdc_core_init (void); + int __init ssfdc_init_dummy(void) + { + if(ssfdc_core_init() == -1) + return -ENODEV; + return 0; + } + #endif + module_init(ssfdc_init_dummy); + #ifdef MODULE + static void __exit ssfdc_cleanup_dummy(void) {} + module_exit(ssfdc_cleanup_dummy); + MODULE_LICENSE("GPL"); + #endif /* MODULE */ + + + /* ddi entrypoints */ + int ssfdc_ddi_init(struct ssfdc_callback *c) + { + ssfdccallp = c; + + return ssfdc_init(); + } + + void ssfdc_ddi_exit(void) + { + ssfdc_cleanup(); + } + + unsigned long ssfdc_ddi_getjiffies(void) + { + return jiffies; + } + + void ssfdc_ddi_udelay(unsigned int us) + { + udelay(us); + } + + void ssfdc_ddi_mdelay(unsigned int ms) + { + mdelay(ms); + } + + unsigned long ssfdc_ddi_mask_intr(void) + { + unsigned long flags; + local_irq_save(flags); + return flags; + } + + void ssfdc_ddi_restore_intr(unsigned long flags) + { + local_irq_restore(flags); + } + + int ssfdc_ddi_printf(const char *fmt, ...) + { + va_list args; + static char buf[512]; + va_start(args, fmt); + vsprintf(buf, fmt, args); + va_end(args); + return printk("%s", buf); + } + + void ssfdc_ddi_insw(unsigned int adr, unsigned short *buff, unsigned int count) + { + insw(adr, buff, count); + } + + int ssfdc_ddi_getHZ(void) + { + return HZ; + } + + #ifndef LINK_SSFDCCORE_DRV + EXPORT_SYMBOL(ssfdc_ddi_init); + EXPORT_SYMBOL(ssfdc_ddi_exit); + EXPORT_SYMBOL(ssfdc_base); + EXPORT_SYMBOL(wait_for_ready_on_timeout); + EXPORT_SYMBOL(ssfdc_ddi_getjiffies); + EXPORT_SYMBOL(ssfdc_ddi_udelay); + EXPORT_SYMBOL(ssfdc_ddi_mdelay); + EXPORT_SYMBOL(ssfdc_ddi_mask_intr); + EXPORT_SYMBOL(ssfdc_ddi_restore_intr); + EXPORT_SYMBOL(ssfdc_ddi_printf); + EXPORT_SYMBOL(ssfdc_ddi_insw); + EXPORT_SYMBOL(ssfdc_ddi_getHZ); + #endif + //================================================================== diff -c -rN --exclude-from=/avlinux/iosub/local/lib/excludefile linux-2.6.10/tsb_modules/block/ssfdc/ssfdcfmt.c linux-current/tsb_modules/block/ssfdc/ssfdcfmt.c *** linux-2.6.10/tsb_modules/block/ssfdc/ssfdcfmt.c Thu Jan 1 09:00:00 1970 --- linux-current/tsb_modules/block/ssfdc/ssfdcfmt.c Fri Jul 7 22:07:32 2006 *************** *** 0 **** --- 1,49 ---- + /* + * Copyright (C) 2001,2004 TOSHIBA CORPORATION. + * + * This is the SSFDC physical format command. + * + * Compile: + * $ xx-gcc -static ssfdcfmt.c -o ssfdcfmt + */ + + #include + #include + #include + #include + #include + + #define SSFDCFMTMEDIA _IO(7, 0x47) + #define SSFDCSHOWBLOCK _IO(7, 0x48) + #define SSFDCDESTROYCIS _IO(7, 0x49) + + int main(int argc, char *argv[]) + { + int fd,ret; + char *file="/dev/ssfdca"; + char input; + int force_flag=0; + + if(argc>1 && strcmp(argv[1],"-f")==0) + force_flag=1; + + fd=open(file, O_RDWR); + if(fd==0){ + printf("Cannot open %s\n",file); + exit(1); + } + if(force_flag){ + input='y'; + }else{ + printf("Do you format SSFDC ? (y/n): "); + scanf("%c",&input); + } + if(input=='y'){ + ret = ioctl(fd, SSFDCFMTMEDIA, 0); + if(ret==0) + printf("SSFDC format is success.\n"); + }else{ + exit(1); + } + return 0; + }