S: USA
N: Ian McDonald
-E: iam4@cs.waikato.ac.nz
+E: ian.mcdonald@jandi.co.nz
E: imcdnzl@gmail.com
W: http://wand.net.nz/~iam4
W: http://imcdnzl.blogspot.com
--- /dev/null
+/*
+ * ucon.c
+ *
+ * Copyright (c) 2004+ Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+ *
+ *
+ * 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 <asm/types.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include <linux/connector.h>
+
+#define DEBUG
+#define NETLINK_CONNECTOR 11
+
+#ifdef DEBUG
+#define ulog(f, a...) fprintf(stdout, f, ##a)
+#else
+#define ulog(f, a...) do {} while (0)
+#endif
+
+static int need_exit;
+static __u32 seq;
+
+static int netlink_send(int s, struct cn_msg *msg)
+{
+ struct nlmsghdr *nlh;
+ unsigned int size;
+ int err;
+ char buf[128];
+ struct cn_msg *m;
+
+ size = NLMSG_SPACE(sizeof(struct cn_msg) + msg->len);
+
+ nlh = (struct nlmsghdr *)buf;
+ nlh->nlmsg_seq = seq++;
+ nlh->nlmsg_pid = getpid();
+ nlh->nlmsg_type = NLMSG_DONE;
+ nlh->nlmsg_len = NLMSG_LENGTH(size - sizeof(*nlh));
+ nlh->nlmsg_flags = 0;
+
+ m = NLMSG_DATA(nlh);
+#if 0
+ ulog("%s: [%08x.%08x] len=%u, seq=%u, ack=%u.\n",
+ __func__, msg->id.idx, msg->id.val, msg->len, msg->seq, msg->ack);
+#endif
+ memcpy(m, msg, sizeof(*m) + msg->len);
+
+ err = send(s, nlh, size, 0);
+ if (err == -1)
+ ulog("Failed to send: %s [%d].\n",
+ strerror(errno), errno);
+
+ return err;
+}
+
+int main(int argc, char *argv[])
+{
+ int s;
+ char buf[1024];
+ int len;
+ struct nlmsghdr *reply;
+ struct sockaddr_nl l_local;
+ struct cn_msg *data;
+ FILE *out;
+ time_t tm;
+ struct pollfd pfd;
+
+ if (argc < 2)
+ out = stdout;
+ else {
+ out = fopen(argv[1], "a+");
+ if (!out) {
+ ulog("Unable to open %s for writing: %s\n",
+ argv[1], strerror(errno));
+ out = stdout;
+ }
+ }
+
+ memset(buf, 0, sizeof(buf));
+
+ s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+ if (s == -1) {
+ perror("socket");
+ return -1;
+ }
+
+ l_local.nl_family = AF_NETLINK;
+ l_local.nl_groups = 0x123; /* bitmask of requested groups */
+ l_local.nl_pid = 0;
+
+ if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
+ perror("bind");
+ close(s);
+ return -1;
+ }
+
+#if 0
+ {
+ int on = 0x57; /* Additional group number */
+ setsockopt(s, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &on, sizeof(on));
+ }
+#endif
+ if (0) {
+ int i, j;
+
+ memset(buf, 0, sizeof(buf));
+
+ data = (struct cn_msg *)buf;
+
+ data->id.idx = 0x123;
+ data->id.val = 0x456;
+ data->seq = seq++;
+ data->ack = 0;
+ data->len = 0;
+
+ for (j=0; j<10; ++j) {
+ for (i=0; i<1000; ++i) {
+ len = netlink_send(s, data);
+ }
+
+ ulog("%d messages have been sent to %08x.%08x.\n", i, data->id.idx, data->id.val);
+ }
+
+ return 0;
+ }
+
+
+ pfd.fd = s;
+
+ while (!need_exit) {
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ switch (poll(&pfd, 1, -1)) {
+ case 0:
+ need_exit = 1;
+ break;
+ case -1:
+ if (errno != EINTR) {
+ need_exit = 1;
+ break;
+ }
+ continue;
+ }
+ if (need_exit)
+ break;
+
+ memset(buf, 0, sizeof(buf));
+ len = recv(s, buf, sizeof(buf), 0);
+ if (len == -1) {
+ perror("recv buf");
+ close(s);
+ return -1;
+ }
+ reply = (struct nlmsghdr *)buf;
+
+ switch (reply->nlmsg_type) {
+ case NLMSG_ERROR:
+ fprintf(out, "Error message received.\n");
+ fflush(out);
+ break;
+ case NLMSG_DONE:
+ data = (struct cn_msg *)NLMSG_DATA(reply);
+
+ time(&tm);
+ fprintf(out, "%.24s : [%x.%x] [%08u.%08u].\n",
+ ctime(&tm), data->id.idx, data->id.val, data->seq, data->ack);
+ fflush(out);
+ break;
+ default:
+ break;
+ }
+ }
+
+ close(s);
+ return 0;
+}
to represent the cpuset hierarchy provides for a familiar permission
and name space for cpusets, with a minimum of additional kernel code.
+The cpus file in the root (top_cpuset) cpuset is read-only.
+It automatically tracks the value of cpu_online_map, using a CPU
+hotplug notifier. If and when memory nodes can be hotplugged,
+we expect to make the mems file in the root cpuset read-only
+as well, and have it track the value of node_online_map.
+
1.4 What are exclusive cpusets ?
--------------------------------
--- /dev/null
+
+What is imacfb?
+===============
+
+This is a generic EFI platform driver for Intel based Apple computers.
+Imacfb is only for EFI booted Intel Macs.
+
+Supported Hardware
+==================
+
+iMac 17"/20"
+Macbook
+Macbook Pro 15"/17"
+MacMini
+
+How to use it?
+==============
+
+Imacfb does not have any kind of autodetection of your machine.
+You have to add the fillowing kernel parameters in your elilo.conf:
+ Macbook :
+ video=imacfb:macbook
+ MacMini :
+ video=imacfb:mini
+ Macbook Pro 15", iMac 17" :
+ video=imacfb:i17
+ Macbook Pro 17", iMac 20" :
+ video=imacfb:i20
+
+--
+Edgar Hucek <gimli@dark-green.com>
- info on the 'in memory' filesystems ramfs, rootfs and initramfs.
reiser4.txt
- info on the Reiser4 filesystem based on dancing tree algorithms.
-relayfs.txt
- - info on relayfs, for efficient streaming from kernel to user space.
+relay.txt
+ - info on relay, for efficient streaming from kernel to user space.
romfs.txt
- description of the ROMFS filesystem.
smbfs.txt
--- /dev/null
+relay interface (formerly relayfs)
+==================================
+
+The relay interface provides a means for kernel applications to
+efficiently log and transfer large quantities of data from the kernel
+to userspace via user-defined 'relay channels'.
+
+A 'relay channel' is a kernel->user data relay mechanism implemented
+as a set of per-cpu kernel buffers ('channel buffers'), each
+represented as a regular file ('relay file') in user space. Kernel
+clients write into the channel buffers using efficient write
+functions; these automatically log into the current cpu's channel
+buffer. User space applications mmap() or read() from the relay files
+and retrieve the data as it becomes available. The relay files
+themselves are files created in a host filesystem, e.g. debugfs, and
+are associated with the channel buffers using the API described below.
+
+The format of the data logged into the channel buffers is completely
+up to the kernel client; the relay interface does however provide
+hooks which allow kernel clients to impose some structure on the
+buffer data. The relay interface doesn't implement any form of data
+filtering - this also is left to the kernel client. The purpose is to
+keep things as simple as possible.
+
+This document provides an overview of the relay interface API. The
+details of the function parameters are documented along with the
+functions in the relay interface code - please see that for details.
+
+Semantics
+=========
+
+Each relay channel has one buffer per CPU, each buffer has one or more
+sub-buffers. Messages are written to the first sub-buffer until it is
+too full to contain a new message, in which case it it is written to
+the next (if available). Messages are never split across sub-buffers.
+At this point, userspace can be notified so it empties the first
+sub-buffer, while the kernel continues writing to the next.
+
+When notified that a sub-buffer is full, the kernel knows how many
+bytes of it are padding i.e. unused space occurring because a complete
+message couldn't fit into a sub-buffer. Userspace can use this
+knowledge to copy only valid data.
+
+After copying it, userspace can notify the kernel that a sub-buffer
+has been consumed.
+
+A relay channel can operate in a mode where it will overwrite data not
+yet collected by userspace, and not wait for it to be consumed.
+
+The relay channel itself does not provide for communication of such
+data between userspace and kernel, allowing the kernel side to remain
+simple and not impose a single interface on userspace. It does
+provide a set of examples and a separate helper though, described
+below.
+
+The read() interface both removes padding and internally consumes the
+read sub-buffers; thus in cases where read(2) is being used to drain
+the channel buffers, special-purpose communication between kernel and
+user isn't necessary for basic operation.
+
+One of the major goals of the relay interface is to provide a low
+overhead mechanism for conveying kernel data to userspace. While the
+read() interface is easy to use, it's not as efficient as the mmap()
+approach; the example code attempts to make the tradeoff between the
+two approaches as small as possible.
+
+klog and relay-apps example code
+================================
+
+The relay interface itself is ready to use, but to make things easier,
+a couple simple utility functions and a set of examples are provided.
+
+The relay-apps example tarball, available on the relay sourceforge
+site, contains a set of self-contained examples, each consisting of a
+pair of .c files containing boilerplate code for each of the user and
+kernel sides of a relay application. When combined these two sets of
+boilerplate code provide glue to easily stream data to disk, without
+having to bother with mundane housekeeping chores.
+
+The 'klog debugging functions' patch (klog.patch in the relay-apps
+tarball) provides a couple of high-level logging functions to the
+kernel which allow writing formatted text or raw data to a channel,
+regardless of whether a channel to write into exists or not, or even
+whether the relay interface is compiled into the kernel or not. These
+functions allow you to put unconditional 'trace' statements anywhere
+in the kernel or kernel modules; only when there is a 'klog handler'
+registered will data actually be logged (see the klog and kleak
+examples for details).
+
+It is of course possible to use the relay interface from scratch,
+i.e. without using any of the relay-apps example code or klog, but
+you'll have to implement communication between userspace and kernel,
+allowing both to convey the state of buffers (full, empty, amount of
+padding). The read() interface both removes padding and internally
+consumes the read sub-buffers; thus in cases where read(2) is being
+used to drain the channel buffers, special-purpose communication
+between kernel and user isn't necessary for basic operation. Things
+such as buffer-full conditions would still need to be communicated via
+some channel though.
+
+klog and the relay-apps examples can be found in the relay-apps
+tarball on http://relayfs.sourceforge.net
+
+The relay interface user space API
+==================================
+
+The relay interface implements basic file operations for user space
+access to relay channel buffer data. Here are the file operations
+that are available and some comments regarding their behavior:
+
+open() enables user to open an _existing_ channel buffer.
+
+mmap() results in channel buffer being mapped into the caller's
+ memory space. Note that you can't do a partial mmap - you
+ must map the entire file, which is NRBUF * SUBBUFSIZE.
+
+read() read the contents of a channel buffer. The bytes read are
+ 'consumed' by the reader, i.e. they won't be available
+ again to subsequent reads. If the channel is being used
+ in no-overwrite mode (the default), it can be read at any
+ time even if there's an active kernel writer. If the
+ channel is being used in overwrite mode and there are
+ active channel writers, results may be unpredictable -
+ users should make sure that all logging to the channel has
+ ended before using read() with overwrite mode. Sub-buffer
+ padding is automatically removed and will not be seen by
+ the reader.
+
+sendfile() transfer data from a channel buffer to an output file
+ descriptor. Sub-buffer padding is automatically removed
+ and will not be seen by the reader.
+
+poll() POLLIN/POLLRDNORM/POLLERR supported. User applications are
+ notified when sub-buffer boundaries are crossed.
+
+close() decrements the channel buffer's refcount. When the refcount
+ reaches 0, i.e. when no process or kernel client has the
+ buffer open, the channel buffer is freed.
+
+In order for a user application to make use of relay files, the
+host filesystem must be mounted. For example,
+
+ mount -t debugfs debugfs /debug
+
+NOTE: the host filesystem doesn't need to be mounted for kernel
+ clients to create or use channels - it only needs to be
+ mounted when user space applications need access to the buffer
+ data.
+
+
+The relay interface kernel API
+==============================
+
+Here's a summary of the API the relay interface provides to in-kernel clients:
+
+TBD(curr. line MT:/API/)
+ channel management functions:
+
+ relay_open(base_filename, parent, subbuf_size, n_subbufs,
+ callbacks)
+ relay_close(chan)
+ relay_flush(chan)
+ relay_reset(chan)
+
+ channel management typically called on instigation of userspace:
+
+ relay_subbufs_consumed(chan, cpu, subbufs_consumed)
+
+ write functions:
+
+ relay_write(chan, data, length)
+ __relay_write(chan, data, length)
+ relay_reserve(chan, length)
+
+ callbacks:
+
+ subbuf_start(buf, subbuf, prev_subbuf, prev_padding)
+ buf_mapped(buf, filp)
+ buf_unmapped(buf, filp)
+ create_buf_file(filename, parent, mode, buf, is_global)
+ remove_buf_file(dentry)
+
+ helper functions:
+
+ relay_buf_full(buf)
+ subbuf_start_reserve(buf, length)
+
+
+Creating a channel
+------------------
+
+relay_open() is used to create a channel, along with its per-cpu
+channel buffers. Each channel buffer will have an associated file
+created for it in the host filesystem, which can be and mmapped or
+read from in user space. The files are named basename0...basenameN-1
+where N is the number of online cpus, and by default will be created
+in the root of the filesystem (if the parent param is NULL). If you
+want a directory structure to contain your relay files, you should
+create it using the host filesystem's directory creation function,
+e.g. debugfs_create_dir(), and pass the parent directory to
+relay_open(). Users are responsible for cleaning up any directory
+structure they create, when the channel is closed - again the host
+filesystem's directory removal functions should be used for that,
+e.g. debugfs_remove().
+
+In order for a channel to be created and the host filesystem's files
+associated with its channel buffers, the user must provide definitions
+for two callback functions, create_buf_file() and remove_buf_file().
+create_buf_file() is called once for each per-cpu buffer from
+relay_open() and allows the user to create the file which will be used
+to represent the corresponding channel buffer. The callback should
+return the dentry of the file created to represent the channel buffer.
+remove_buf_file() must also be defined; it's responsible for deleting
+the file(s) created in create_buf_file() and is called during
+relay_close().
+
+Here are some typical definitions for these callbacks, in this case
+using debugfs:
+
+/*
+ * create_buf_file() callback. Creates relay file in debugfs.
+ */
+static struct dentry *create_buf_file_handler(const char *filename,
+ struct dentry *parent,
+ int mode,
+ struct rchan_buf *buf,
+ int *is_global)
+{
+ return debugfs_create_file(filename, mode, parent, buf,
+ &relay_file_operations);
+}
+
+/*
+ * remove_buf_file() callback. Removes relay file from debugfs.
+ */
+static int remove_buf_file_handler(struct dentry *dentry)
+{
+ debugfs_remove(dentry);
+
+ return 0;
+}
+
+/*
+ * relay interface callbacks
+ */
+static struct rchan_callbacks relay_callbacks =
+{
+ .create_buf_file = create_buf_file_handler,
+ .remove_buf_file = remove_buf_file_handler,
+};
+
+And an example relay_open() invocation using them:
+
+ chan = relay_open("cpu", NULL, SUBBUF_SIZE, N_SUBBUFS, &relay_callbacks);
+
+If the create_buf_file() callback fails, or isn't defined, channel
+creation and thus relay_open() will fail.
+
+The total size of each per-cpu buffer is calculated by multiplying the
+number of sub-buffers by the sub-buffer size passed into relay_open().
+The idea behind sub-buffers is that they're basically an extension of
+double-buffering to N buffers, and they also allow applications to
+easily implement random-access-on-buffer-boundary schemes, which can
+be important for some high-volume applications. The number and size
+of sub-buffers is completely dependent on the application and even for
+the same application, different conditions will warrant different
+values for these parameters at different times. Typically, the right
+values to use are best decided after some experimentation; in general,
+though, it's safe to assume that having only 1 sub-buffer is a bad
+idea - you're guaranteed to either overwrite data or lose events
+depending on the channel mode being used.
+
+The create_buf_file() implementation can also be defined in such a way
+as to allow the creation of a single 'global' buffer instead of the
+default per-cpu set. This can be useful for applications interested
+mainly in seeing the relative ordering of system-wide events without
+the need to bother with saving explicit timestamps for the purpose of
+merging/sorting per-cpu files in a postprocessing step.
+
+To have relay_open() create a global buffer, the create_buf_file()
+implementation should set the value of the is_global outparam to a
+non-zero value in addition to creating the file that will be used to
+represent the single buffer. In the case of a global buffer,
+create_buf_file() and remove_buf_file() will be called only once. The
+normal channel-writing functions, e.g. relay_write(), can still be
+used - writes from any cpu will transparently end up in the global
+buffer - but since it is a global buffer, callers should make sure
+they use the proper locking for such a buffer, either by wrapping
+writes in a spinlock, or by copying a write function from relay.h and
+creating a local version that internally does the proper locking.
+
+Channel 'modes'
+---------------
+
+relay channels can be used in either of two modes - 'overwrite' or
+'no-overwrite'. The mode is entirely determined by the implementation
+of the subbuf_start() callback, as described below. The default if no
+subbuf_start() callback is defined is 'no-overwrite' mode. If the
+default mode suits your needs, and you plan to use the read()
+interface to retrieve channel data, you can ignore the details of this
+section, as it pertains mainly to mmap() implementations.
+
+In 'overwrite' mode, also known as 'flight recorder' mode, writes
+continuously cycle around the buffer and will never fail, but will
+unconditionally overwrite old data regardless of whether it's actually
+been consumed. In no-overwrite mode, writes will fail, i.e. data will
+be lost, if the number of unconsumed sub-buffers equals the total
+number of sub-buffers in the channel. It should be clear that if
+there is no consumer or if the consumer can't consume sub-buffers fast
+enough, data will be lost in either case; the only difference is
+whether data is lost from the beginning or the end of a buffer.
+
+As explained above, a relay channel is made of up one or more
+per-cpu channel buffers, each implemented as a circular buffer
+subdivided into one or more sub-buffers. Messages are written into
+the current sub-buffer of the channel's current per-cpu buffer via the
+write functions described below. Whenever a message can't fit into
+the current sub-buffer, because there's no room left for it, the
+client is notified via the subbuf_start() callback that a switch to a
+new sub-buffer is about to occur. The client uses this callback to 1)
+initialize the next sub-buffer if appropriate 2) finalize the previous
+sub-buffer if appropriate and 3) return a boolean value indicating
+whether or not to actually move on to the next sub-buffer.
+
+To implement 'no-overwrite' mode, the userspace client would provide
+an implementation of the subbuf_start() callback something like the
+following:
+
+static int subbuf_start(struct rchan_buf *buf,
+ void *subbuf,
+ void *prev_subbuf,
+ unsigned int prev_padding)
+{
+ if (prev_subbuf)
+ *((unsigned *)prev_subbuf) = prev_padding;
+
+ if (relay_buf_full(buf))
+ return 0;
+
+ subbuf_start_reserve(buf, sizeof(unsigned int));
+
+ return 1;
+}
+
+If the current buffer is full, i.e. all sub-buffers remain unconsumed,
+the callback returns 0 to indicate that the buffer switch should not
+occur yet, i.e. until the consumer has had a chance to read the
+current set of ready sub-buffers. For the relay_buf_full() function
+to make sense, the consumer is reponsible for notifying the relay
+interface when sub-buffers have been consumed via
+relay_subbufs_consumed(). Any subsequent attempts to write into the
+buffer will again invoke the subbuf_start() callback with the same
+parameters; only when the consumer has consumed one or more of the
+ready sub-buffers will relay_buf_full() return 0, in which case the
+buffer switch can continue.
+
+The implementation of the subbuf_start() callback for 'overwrite' mode
+would be very similar:
+
+static int subbuf_start(struct rchan_buf *buf,
+ void *subbuf,
+ void *prev_subbuf,
+ unsigned int prev_padding)
+{
+ if (prev_subbuf)
+ *((unsigned *)prev_subbuf) = prev_padding;
+
+ subbuf_start_reserve(buf, sizeof(unsigned int));
+
+ return 1;
+}
+
+In this case, the relay_buf_full() check is meaningless and the
+callback always returns 1, causing the buffer switch to occur
+unconditionally. It's also meaningless for the client to use the
+relay_subbufs_consumed() function in this mode, as it's never
+consulted.
+
+The default subbuf_start() implementation, used if the client doesn't
+define any callbacks, or doesn't define the subbuf_start() callback,
+implements the simplest possible 'no-overwrite' mode, i.e. it does
+nothing but return 0.
+
+Header information can be reserved at the beginning of each sub-buffer
+by calling the subbuf_start_reserve() helper function from within the
+subbuf_start() callback. This reserved area can be used to store
+whatever information the client wants. In the example above, room is
+reserved in each sub-buffer to store the padding count for that
+sub-buffer. This is filled in for the previous sub-buffer in the
+subbuf_start() implementation; the padding value for the previous
+sub-buffer is passed into the subbuf_start() callback along with a
+pointer to the previous sub-buffer, since the padding value isn't
+known until a sub-buffer is filled. The subbuf_start() callback is
+also called for the first sub-buffer when the channel is opened, to
+give the client a chance to reserve space in it. In this case the
+previous sub-buffer pointer passed into the callback will be NULL, so
+the client should check the value of the prev_subbuf pointer before
+writing into the previous sub-buffer.
+
+Writing to a channel
+--------------------
+
+Kernel clients write data into the current cpu's channel buffer using
+relay_write() or __relay_write(). relay_write() is the main logging
+function - it uses local_irqsave() to protect the buffer and should be
+used if you might be logging from interrupt context. If you know
+you'll never be logging from interrupt context, you can use
+__relay_write(), which only disables preemption. These functions
+don't return a value, so you can't determine whether or not they
+failed - the assumption is that you wouldn't want to check a return
+value in the fast logging path anyway, and that they'll always succeed
+unless the buffer is full and no-overwrite mode is being used, in
+which case you can detect a failed write in the subbuf_start()
+callback by calling the relay_buf_full() helper function.
+
+relay_reserve() is used to reserve a slot in a channel buffer which
+can be written to later. This would typically be used in applications
+that need to write directly into a channel buffer without having to
+stage data in a temporary buffer beforehand. Because the actual write
+may not happen immediately after the slot is reserved, applications
+using relay_reserve() can keep a count of the number of bytes actually
+written, either in space reserved in the sub-buffers themselves or as
+a separate array. See the 'reserve' example in the relay-apps tarball
+at http://relayfs.sourceforge.net for an example of how this can be
+done. Because the write is under control of the client and is
+separated from the reserve, relay_reserve() doesn't protect the buffer
+at all - it's up to the client to provide the appropriate
+synchronization when using relay_reserve().
+
+Closing a channel
+-----------------
+
+The client calls relay_close() when it's finished using the channel.
+The channel and its associated buffers are destroyed when there are no
+longer any references to any of the channel buffers. relay_flush()
+forces a sub-buffer switch on all the channel buffers, and can be used
+to finalize and process the last sub-buffers before the channel is
+closed.
+
+Misc
+----
+
+Some applications may want to keep a channel around and re-use it
+rather than open and close a new channel for each use. relay_reset()
+can be used for this purpose - it resets a channel to its initial
+state without reallocating channel buffer memory or destroying
+existing mappings. It should however only be called when it's safe to
+do so, i.e. when the channel isn't currently being written to.
+
+Finally, there are a couple of utility callbacks that can be used for
+different purposes. buf_mapped() is called whenever a channel buffer
+is mmapped from user space and buf_unmapped() is called when it's
+unmapped. The client can use this notification to trigger actions
+within the kernel application, such as enabling/disabling logging to
+the channel.
+
+
+Resources
+=========
+
+For news, example code, mailing list, etc. see the relay interface homepage:
+
+ http://relayfs.sourceforge.net
+
+
+Credits
+=======
+
+The ideas and specs for the relay interface came about as a result of
+discussions on tracing involving the following:
+
+Michel Dagenais <michel.dagenais@polymtl.ca>
+Richard Moore <richardj_moore@uk.ibm.com>
+Bob Wisniewski <bob@watson.ibm.com>
+Karim Yaghmour <karim@opersys.com>
+Tom Zanussi <zanussi@us.ibm.com>
+
+Also thanks to Hubertus Franke for a lot of useful suggestions and bug
+reports.
+++ /dev/null
-
-relayfs - a high-speed data relay filesystem
-============================================
-
-relayfs is a filesystem designed to provide an efficient mechanism for
-tools and facilities to relay large and potentially sustained streams
-of data from kernel space to user space.
-
-The main abstraction of relayfs is the 'channel'. A channel consists
-of a set of per-cpu kernel buffers each represented by a file in the
-relayfs filesystem. Kernel clients write into a channel using
-efficient write functions which automatically log to the current cpu's
-channel buffer. User space applications mmap() the per-cpu files and
-retrieve the data as it becomes available.
-
-The format of the data logged into the channel buffers is completely
-up to the relayfs client; relayfs does however provide hooks which
-allow clients to impose some structure on the buffer data. Nor does
-relayfs implement any form of data filtering - this also is left to
-the client. The purpose is to keep relayfs as simple as possible.
-
-This document provides an overview of the relayfs API. The details of
-the function parameters are documented along with the functions in the
-filesystem code - please see that for details.
-
-Semantics
-=========
-
-Each relayfs channel has one buffer per CPU, each buffer has one or
-more sub-buffers. Messages are written to the first sub-buffer until
-it is too full to contain a new message, in which case it it is
-written to the next (if available). Messages are never split across
-sub-buffers. At this point, userspace can be notified so it empties
-the first sub-buffer, while the kernel continues writing to the next.
-
-When notified that a sub-buffer is full, the kernel knows how many
-bytes of it are padding i.e. unused. Userspace can use this knowledge
-to copy only valid data.
-
-After copying it, userspace can notify the kernel that a sub-buffer
-has been consumed.
-
-relayfs can operate in a mode where it will overwrite data not yet
-collected by userspace, and not wait for it to consume it.
-
-relayfs itself does not provide for communication of such data between
-userspace and kernel, allowing the kernel side to remain simple and
-not impose a single interface on userspace. It does provide a set of
-examples and a separate helper though, described below.
-
-klog and relay-apps example code
-================================
-
-relayfs itself is ready to use, but to make things easier, a couple
-simple utility functions and a set of examples are provided.
-
-The relay-apps example tarball, available on the relayfs sourceforge
-site, contains a set of self-contained examples, each consisting of a
-pair of .c files containing boilerplate code for each of the user and
-kernel sides of a relayfs application; combined these two sets of
-boilerplate code provide glue to easily stream data to disk, without
-having to bother with mundane housekeeping chores.
-
-The 'klog debugging functions' patch (klog.patch in the relay-apps
-tarball) provides a couple of high-level logging functions to the
-kernel which allow writing formatted text or raw data to a channel,
-regardless of whether a channel to write into exists or not, or
-whether relayfs is compiled into the kernel or is configured as a
-module. These functions allow you to put unconditional 'trace'
-statements anywhere in the kernel or kernel modules; only when there
-is a 'klog handler' registered will data actually be logged (see the
-klog and kleak examples for details).
-
-It is of course possible to use relayfs from scratch i.e. without
-using any of the relay-apps example code or klog, but you'll have to
-implement communication between userspace and kernel, allowing both to
-convey the state of buffers (full, empty, amount of padding).
-
-klog and the relay-apps examples can be found in the relay-apps
-tarball on http://relayfs.sourceforge.net
-
-
-The relayfs user space API
-==========================
-
-relayfs implements basic file operations for user space access to
-relayfs channel buffer data. Here are the file operations that are
-available and some comments regarding their behavior:
-
-open() enables user to open an _existing_ buffer.
-
-mmap() results in channel buffer being mapped into the caller's
- memory space. Note that you can't do a partial mmap - you must
- map the entire file, which is NRBUF * SUBBUFSIZE.
-
-read() read the contents of a channel buffer. The bytes read are
- 'consumed' by the reader i.e. they won't be available again
- to subsequent reads. If the channel is being used in
- no-overwrite mode (the default), it can be read at any time
- even if there's an active kernel writer. If the channel is
- being used in overwrite mode and there are active channel
- writers, results may be unpredictable - users should make
- sure that all logging to the channel has ended before using
- read() with overwrite mode.
-
-poll() POLLIN/POLLRDNORM/POLLERR supported. User applications are
- notified when sub-buffer boundaries are crossed.
-
-close() decrements the channel buffer's refcount. When the refcount
- reaches 0 i.e. when no process or kernel client has the buffer
- open, 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 /mnt/relay
-
-NOTE: relayfs doesn't need to be mounted for kernel clients to create
- or use channels - it only needs to be mounted when user space
- applications need access to the buffer data.
-
-
-The relayfs kernel API
-======================
-
-Here's a summary of the API relayfs provides to in-kernel clients:
-
-
- channel management functions:
-
- relay_open(base_filename, parent, subbuf_size, n_subbufs,
- callbacks)
- relay_close(chan)
- relay_flush(chan)
- relay_reset(chan)
- relayfs_create_dir(name, parent)
- relayfs_remove_dir(dentry)
- relayfs_create_file(name, parent, mode, fops, data)
- relayfs_remove_file(dentry)
-
- channel management typically called on instigation of userspace:
-
- relay_subbufs_consumed(chan, cpu, subbufs_consumed)
-
- write functions:
-
- relay_write(chan, data, length)
- __relay_write(chan, data, length)
- relay_reserve(chan, length)
-
- callbacks:
-
- subbuf_start(buf, subbuf, prev_subbuf, prev_padding)
- buf_mapped(buf, filp)
- buf_unmapped(buf, filp)
- create_buf_file(filename, parent, mode, buf, is_global)
- remove_buf_file(dentry)
-
- helper functions:
-
- relay_buf_full(buf)
- subbuf_start_reserve(buf, length)
-
-
-Creating a channel
-------------------
-
-relay_open() is used to create a channel, along with its per-cpu
-channel buffers. Each channel buffer will have an associated file
-created for it in the relayfs filesystem, which can be opened and
-mmapped from user space if desired. The files are named
-basename0...basenameN-1 where N is the number of online cpus, and by
-default will be created in the root of the filesystem. If you want a
-directory structure to contain your relayfs files, you can create it
-with relayfs_create_dir() and pass the parent directory to
-relay_open(). Clients are responsible for cleaning up any directory
-structure they create when the channel is closed - use
-relayfs_remove_dir() for that.
-
-The total size of each per-cpu buffer is calculated by multiplying the
-number of sub-buffers by the sub-buffer size passed into relay_open().
-The idea behind sub-buffers is that they're basically an extension of
-double-buffering to N buffers, and they also allow applications to
-easily implement random-access-on-buffer-boundary schemes, which can
-be important for some high-volume applications. The number and size
-of sub-buffers is completely dependent on the application and even for
-the same application, different conditions will warrant different
-values for these parameters at different times. Typically, the right
-values to use are best decided after some experimentation; in general,
-though, it's safe to assume that having only 1 sub-buffer is a bad
-idea - you're guaranteed to either overwrite data or lose events
-depending on the channel mode being used.
-
-Channel 'modes'
----------------
-
-relayfs channels can be used in either of two modes - 'overwrite' or
-'no-overwrite'. The mode is entirely determined by the implementation
-of the subbuf_start() callback, as described below. In 'overwrite'
-mode, also known as 'flight recorder' mode, writes continuously cycle
-around the buffer and will never fail, but will unconditionally
-overwrite old data regardless of whether it's actually been consumed.
-In no-overwrite mode, writes will fail i.e. data will be lost, if the
-number of unconsumed sub-buffers equals the total number of
-sub-buffers in the channel. It should be clear that if there is no
-consumer or if the consumer can't consume sub-buffers fast enought,
-data will be lost in either case; the only difference is whether data
-is lost from the beginning or the end of a buffer.
-
-As explained above, a relayfs channel is made of up one or more
-per-cpu channel buffers, each implemented as a circular buffer
-subdivided into one or more sub-buffers. Messages are written into
-the current sub-buffer of the channel's current per-cpu buffer via the
-write functions described below. Whenever a message can't fit into
-the current sub-buffer, because there's no room left for it, the
-client is notified via the subbuf_start() callback that a switch to a
-new sub-buffer is about to occur. The client uses this callback to 1)
-initialize the next sub-buffer if appropriate 2) finalize the previous
-sub-buffer if appropriate and 3) return a boolean value indicating
-whether or not to actually go ahead with the sub-buffer switch.
-
-To implement 'no-overwrite' mode, the userspace client would provide
-an implementation of the subbuf_start() callback something like the
-following:
-
-static int subbuf_start(struct rchan_buf *buf,
- void *subbuf,
- void *prev_subbuf,
- unsigned int prev_padding)
-{
- if (prev_subbuf)
- *((unsigned *)prev_subbuf) = prev_padding;
-
- if (relay_buf_full(buf))
- return 0;
-
- subbuf_start_reserve(buf, sizeof(unsigned int));
-
- return 1;
-}
-
-If the current buffer is full i.e. all sub-buffers remain unconsumed,
-the callback returns 0 to indicate that the buffer switch should not
-occur yet i.e. until the consumer has had a chance to read the current
-set of ready sub-buffers. For the relay_buf_full() function to make
-sense, the consumer is reponsible for notifying relayfs when
-sub-buffers have been consumed via relay_subbufs_consumed(). Any
-subsequent attempts to write into the buffer will again invoke the
-subbuf_start() callback with the same parameters; only when the
-consumer has consumed one or more of the ready sub-buffers will
-relay_buf_full() return 0, in which case the buffer switch can
-continue.
-
-The implementation of the subbuf_start() callback for 'overwrite' mode
-would be very similar:
-
-static int subbuf_start(struct rchan_buf *buf,
- void *subbuf,
- void *prev_subbuf,
- unsigned int prev_padding)
-{
- if (prev_subbuf)
- *((unsigned *)prev_subbuf) = prev_padding;
-
- subbuf_start_reserve(buf, sizeof(unsigned int));
-
- return 1;
-}
-
-In this case, the relay_buf_full() check is meaningless and the
-callback always returns 1, causing the buffer switch to occur
-unconditionally. It's also meaningless for the client to use the
-relay_subbufs_consumed() function in this mode, as it's never
-consulted.
-
-The default subbuf_start() implementation, used if the client doesn't
-define any callbacks, or doesn't define the subbuf_start() callback,
-implements the simplest possible 'no-overwrite' mode i.e. it does
-nothing but return 0.
-
-Header information can be reserved at the beginning of each sub-buffer
-by calling the subbuf_start_reserve() helper function from within the
-subbuf_start() callback. This reserved area can be used to store
-whatever information the client wants. In the example above, room is
-reserved in each sub-buffer to store the padding count for that
-sub-buffer. This is filled in for the previous sub-buffer in the
-subbuf_start() implementation; the padding value for the previous
-sub-buffer is passed into the subbuf_start() callback along with a
-pointer to the previous sub-buffer, since the padding value isn't
-known until a sub-buffer is filled. The subbuf_start() callback is
-also called for the first sub-buffer when the channel is opened, to
-give the client a chance to reserve space in it. In this case the
-previous sub-buffer pointer passed into the callback will be NULL, so
-the client should check the value of the prev_subbuf pointer before
-writing into the previous sub-buffer.
-
-Writing to a channel
---------------------
-
-kernel clients write data into the current cpu's channel buffer using
-relay_write() or __relay_write(). relay_write() is the main logging
-function - it uses local_irqsave() to protect the buffer and should be
-used if you might be logging from interrupt context. If you know
-you'll never be logging from interrupt context, you can use
-__relay_write(), which only disables preemption. These functions
-don't return a value, so you can't determine whether or not they
-failed - the assumption is that you wouldn't want to check a return
-value in the fast logging path anyway, and that they'll always succeed
-unless the buffer is full and no-overwrite mode is being used, in
-which case you can detect a failed write in the subbuf_start()
-callback by calling the relay_buf_full() helper function.
-
-relay_reserve() is used to reserve a slot in a channel buffer which
-can be written to later. This would typically be used in applications
-that need to write directly into a channel buffer without having to
-stage data in a temporary buffer beforehand. Because the actual write
-may not happen immediately after the slot is reserved, applications
-using relay_reserve() can keep a count of the number of bytes actually
-written, either in space reserved in the sub-buffers themselves or as
-a separate array. See the 'reserve' example in the relay-apps tarball
-at http://relayfs.sourceforge.net for an example of how this can be
-done. Because the write is under control of the client and is
-separated from the reserve, relay_reserve() doesn't protect the buffer
-at all - it's up to the client to provide the appropriate
-synchronization when using relay_reserve().
-
-Closing a channel
------------------
-
-The client calls relay_close() when it's finished using the channel.
-The channel and its associated buffers are destroyed when there are no
-longer any references to any of the channel buffers. relay_flush()
-forces a sub-buffer switch on all the channel buffers, and can be used
-to finalize and process the last sub-buffers before the channel is
-closed.
-
-Creating non-relay files
-------------------------
-
-relay_open() automatically creates files in the relayfs filesystem to
-represent the per-cpu kernel buffers; it's often useful for
-applications to be able to create their own files alongside the relay
-files in the relayfs filesystem as well e.g. 'control' files much like
-those created in /proc or debugfs for similar purposes, used to
-communicate control information between the kernel and user sides of a
-relayfs application. For this purpose the relayfs_create_file() and
-relayfs_remove_file() API functions exist. For relayfs_create_file(),
-the caller passes in a set of user-defined file operations to be used
-for the file and an optional void * to a user-specified data item,
-which will be accessible via inode->u.generic_ip (see the relay-apps
-tarball for examples). The file_operations are a required parameter
-to relayfs_create_file() and thus the semantics of these files are
-completely defined by the caller.
-
-See the relay-apps tarball at http://relayfs.sourceforge.net for
-examples of how these non-relay files are meant to be used.
-
-Creating relay files in other filesystems
------------------------------------------
-
-By default of course, relay_open() creates relay files in the relayfs
-filesystem. Because relay_file_operations is exported, however, it's
-also possible to create and use relay files in other pseudo-filesytems
-such as debugfs.
-
-For this purpose, two callback functions are provided,
-create_buf_file() and remove_buf_file(). create_buf_file() is called
-once for each per-cpu buffer from relay_open() to allow the client to
-create a file to be used to represent the corresponding buffer; if
-this callback is not defined, the default implementation will create
-and return a file in the relayfs filesystem to represent the buffer.
-The callback should return the dentry of the file created to represent
-the relay buffer. Note that the parent directory passed to
-relay_open() (and passed along to the callback), if specified, must
-exist in the same filesystem the new relay file is created in. If
-create_buf_file() is defined, remove_buf_file() must also be defined;
-it's responsible for deleting the file(s) created in create_buf_file()
-and is called during relay_close().
-
-The create_buf_file() implementation can also be defined in such a way
-as to allow the creation of a single 'global' buffer instead of the
-default per-cpu set. This can be useful for applications interested
-mainly in seeing the relative ordering of system-wide events without
-the need to bother with saving explicit timestamps for the purpose of
-merging/sorting per-cpu files in a postprocessing step.
-
-To have relay_open() create a global buffer, the create_buf_file()
-implementation should set the value of the is_global outparam to a
-non-zero value in addition to creating the file that will be used to
-represent the single buffer. In the case of a global buffer,
-create_buf_file() and remove_buf_file() will be called only once. The
-normal channel-writing functions e.g. relay_write() can still be used
-- writes from any cpu will transparently end up in the global buffer -
-but since it is a global buffer, callers should make sure they use the
-proper locking for such a buffer, either by wrapping writes in a
-spinlock, or by copying a write function from relayfs_fs.h and
-creating a local version that internally does the proper locking.
-
-See the 'exported-relayfile' examples in the relay-apps tarball for
-examples of creating and using relay files in debugfs.
-
-Misc
-----
-
-Some applications may want to keep a channel around and re-use it
-rather than open and close a new channel for each use. relay_reset()
-can be used for this purpose - it resets a channel to its initial
-state without reallocating channel buffer memory or destroying
-existing mappings. It should however only be called when it's safe to
-do so i.e. when the channel isn't currently being written to.
-
-Finally, there are a couple of utility callbacks that can be used for
-different purposes. buf_mapped() is called whenever a channel buffer
-is mmapped from user space and buf_unmapped() is called when it's
-unmapped. The client can use this notification to trigger actions
-within the kernel application, such as enabling/disabling logging to
-the channel.
-
-
-Resources
-=========
-
-For news, example code, mailing list, etc. see the relayfs homepage:
-
- http://relayfs.sourceforge.net
-
-
-Credits
-=======
-
-The ideas and specs for relayfs came about as a result of discussions
-on tracing involving the following:
-
-Michel Dagenais <michel.dagenais@polymtl.ca>
-Richard Moore <richardj_moore@uk.ibm.com>
-Bob Wisniewski <bob@watson.ibm.com>
-Karim Yaghmour <karim@opersys.com>
-Tom Zanussi <zanussi@us.ibm.com>
-
-Also thanks to Hubertus Franke for a lot of useful suggestions and bug
-reports.
The input project website is at:
- http://www.suse.cz/development/input/
http://atrey.karlin.mff.cuni.cz/~vojtech/input/
There is also a mailing list for the driver at:
Mechanism 2.
nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI
Configuration
+ mmconf [IA-32,X86_64] Force MMCONFIG. This is useful
+ to override the builtin blacklist.
nomsi [MSI] If the PCI_MSI kernel config parameter is
enabled, this kernel boot option can be used to
disable the use of MSI interrupts system-wide.
- default_attrs: Default attributes to be exported via sysfs when the
object is registered.Note that the last attribute has to be
initialized to NULL ! You can find a complete implementation
- in drivers/block/genhd.c
+ in block/genhd.c
Instances of struct kobj_type are not registered; only referenced by
Default: 87380*2 bytes.
tcp_mem - vector of 3 INTEGERs: min, pressure, max
- low: below this number of pages TCP is not bothered about its
+ min: below this number of pages TCP is not bothered about its
memory appetite.
pressure: when amount of memory allocated by TCP exceeds this number
of pages, TCP moderates its memory consumption and enters memory
pressure mode, which is exited when memory consumption falls
- under "low".
+ under "min".
- high: number of pages allowed for queueing by all TCP sockets.
+ max: number of pages allowed for queueing by all TCP sockets.
Defaults are calculated at boot time from amount of available
memory.
+Release Date : Fri May 19 09:31:45 EST 2006 - Seokmann Ju <sju@lsil.com>
+Current Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module)
+Older Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module)
+
+1. Fixed a bug in megaraid_init_mbox().
+ Customer reported "garbage in file on x86_64 platform".
+ Root Cause: the driver registered controllers as 64-bit DMA capable
+ for those which are not support it.
+ Fix: Made change in the function inserting identification machanism
+ identifying 64-bit DMA capable controllers.
+
+ > -----Original Message-----
+ > From: Vasily Averin [mailto:vvs@sw.ru]
+ > Sent: Thursday, May 04, 2006 2:49 PM
+ > To: linux-scsi@vger.kernel.org; Kolli, Neela; Mukker, Atul;
+ > Ju, Seokmann; Bagalkote, Sreenivas;
+ > James.Bottomley@SteelEye.com; devel@openvz.org
+ > Subject: megaraid_mbox: garbage in file
+ >
+ > Hello all,
+ >
+ > I've investigated customers claim on the unstable work of
+ > their node and found a
+ > strange effect: reading from some files leads to the
+ > "attempt to access beyond end of device" messages.
+ >
+ > I've checked filesystem, memory on the node, motherboard BIOS
+ > version, but it
+ > does not help and issue still has been reproduced by simple
+ > file reading.
+ >
+ > Reproducer is simple:
+ >
+ > echo 0xffffffff >/proc/sys/dev/scsi/logging_level ;
+ > cat /vz/private/101/root/etc/ld.so.cache >/tmp/ttt ;
+ > echo 0 >/proc/sys/dev/scsi/logging
+ >
+ > It leads to the following messages in dmesg
+ >
+ > sd_init_command: disk=sda, block=871769260, count=26
+ > sda : block=871769260
+ > sda : reading 26/26 512 byte blocks.
+ > scsi_add_timer: scmd: f79ed980, time: 7500, (c02b1420)
+ > sd 0:1:0:0: send 0xf79ed980 sd 0:1:0:0:
+ > command: Read (10): 28 00 33 f6 24 ac 00 00 1a 00
+ > buffer = 0xf7cfb540, bufflen = 13312, done = 0xc0366b40,
+ > queuecommand 0xc0344010
+ > leaving scsi_dispatch_cmnd()
+ > scsi_delete_timer: scmd: f79ed980, rtn: 1
+ > sd 0:1:0:0: done 0xf79ed980 SUCCESS 0 sd 0:1:0:0:
+ > command: Read (10): 28 00 33 f6 24 ac 00 00 1a 00
+ > scsi host busy 1 failed 0
+ > sd 0:1:0:0: Notifying upper driver of completion (result 0)
+ > sd_rw_intr: sda: res=0x0
+ > 26 sectors total, 13312 bytes done.
+ > use_sg is 4
+ > attempt to access beyond end of device
+ > sda6: rw=0, want=1044134458, limit=951401367
+ > Buffer I/O error on device sda6, logical block 522067228
+ > attempt to access beyond end of device
+
+2. When INQUIRY with EVPD bit set issued to the MegaRAID controller,
+ system memory gets corrupted.
+ Root Cause: MegaRAID F/W handle the INQUIRY with EVPD bit set
+ incorrectly.
+ Fix: MegaRAID F/W has fixed the problem and being process of release,
+ soon. Meanwhile, driver will filter out the request.
+
+3. One of member in the data structure of the driver leads unaligne
+ issue on 64-bit platform.
+ Customer reporeted "kernel unaligned access addrss" issue when
+ application communicates with MegaRAID HBA driver.
+ Root Cause: in uioc_t structure, one of member had misaligned and it
+ led system to display the error message.
+ Fix: A patch submitted to community from following folk.
+
+ > -----Original Message-----
+ > From: linux-scsi-owner@vger.kernel.org
+ > [mailto:linux-scsi-owner@vger.kernel.org] On Behalf Of Sakurai Hiroomi
+ > Sent: Wednesday, July 12, 2006 4:20 AM
+ > To: linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org
+ > Subject: Re: Help: strange messages from kernel on IA64 platform
+ >
+ > Hi,
+ >
+ > I saw same message.
+ >
+ > When GAM(Global Array Manager) is started, The following
+ > message output.
+ > kernel: kernel unaligned access to 0xe0000001fe1080d4,
+ > ip=0xa000000200053371
+ >
+ > The uioc structure used by ioctl is defined by packed,
+ > the allignment of each member are disturbed.
+ > In a 64 bit structure, the allignment of member doesn't fit 64 bit
+ > boundary. this causes this messages.
+ > In a 32 bit structure, we don't see the message because the allinment
+ > of member fit 32 bit boundary even if packed is specified.
+ >
+ > patch
+ > I Add 32 bit dummy member to fit 64 bit boundary. I tested.
+ > We confirmed this patch fix the problem by IA64 server.
+ >
+ > **************************************************************
+ > ****************
+ > --- linux-2.6.9/drivers/scsi/megaraid/megaraid_ioctl.h.orig
+ > 2006-04-03 17:13:03.000000000 +0900
+ > +++ linux-2.6.9/drivers/scsi/megaraid/megaraid_ioctl.h
+ > 2006-04-03 17:14:09.000000000 +0900
+ > @@ -132,6 +132,10 @@
+ > /* Driver Data: */
+ > void __user * user_data;
+ > uint32_t user_data_len;
+ > +
+ > + /* 64bit alignment */
+ > + uint32_t pad_0xBC;
+ > +
+ > mraid_passthru_t __user *user_pthru;
+ >
+ > mraid_passthru_t *pthru32;
+ > **************************************************************
+ > ****************
+
Release Date : Mon Apr 11 12:27:22 EST 2006 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
- inode-state
- overflowuid
- overflowgid
+- suid_dumpable
- super-max
- super-nr
==============================================================
+suid_dumpable:
+
+This value can be used to query and set the core dump mode for setuid
+or otherwise protected/tainted binaries. The modes are
+
+0 - (default) - traditional behaviour. Any process which has changed
+ privilege levels or is execute only will not be dumped
+1 - (debug) - all processes dump core when possible. The core dump is
+ owned by the current user and no security is applied. This is
+ intended for system debugging situations only. Ptrace is unchecked.
+2 - (suidsafe) - any binary which normally would not be dumped is dumped
+ readable by root only. This allows the end user to remove
+ such a dump but not access it directly. For security reasons
+ core dumps in this mode will not overwrite one another or
+ other files. This mode is appropriate when adminstrators are
+ attempting to debug problems in a normal environment.
+
+==============================================================
+
super-max & super-nr:
These numbers control the maximum number of superblocks, and
- shmmax [ sysv ipc ]
- shmmni
- stop-a [ SPARC only ]
-- suid_dumpable
- sysrq ==> Documentation/sysrq.txt
- tainted
- threads-max
==============================================================
-suid_dumpable:
-
-This value can be used to query and set the core dump mode for setuid
-or otherwise protected/tainted binaries. The modes are
-
-0 - (default) - traditional behaviour. Any process which has changed
- privilege levels or is execute only will not be dumped
-1 - (debug) - all processes dump core when possible. The core dump is
- owned by the current user and no security is applied. This is
- intended for system debugging situations only. Ptrace is unchecked.
-2 - (suidsafe) - any binary which normally would not be dumped is dumped
- readable by root only. This allows the end user to remove
- such a dump but not access it directly. For security reasons
- core dumps in this mode will not overwrite one another or
- other files. This mode is appropriate when adminstrators are
- attempting to debug problems in a normal environment.
-
-==============================================================
-
tainted:
Non-zero if the kernel has been tainted. Numeric values, which
T: git http://tali.admingilde.org/git/linux-docbook.git
S: Maintained
+DOCKING STATION DRIVER
+P: Kristen Carlson Accardi
+M: kristen.c.accardi@intel.com
+L: linux-acpi@vger.kernel.org
+S: Maintained
+
DOUBLETALK DRIVER
P: James R. Van Zandt
M: jrv@vanzandt.mv.com
L: stable@kernel.org
S: Maintained
+STABLE BRANCH:
+P: Greg Kroah-Hartman
+M: greg@kroah.com
+P: Chris Wright
+M: chrisw@sous-sol.org
+L: stable@kernel.org
+S: Maintained
+
TPM DEVICE DRIVER
P: Kylene Hall
M: kjhall@us.ibm.com
XFS FILESYSTEM
P: Silicon Graphics Inc
+P: Tim Shimmin, David Chatterton
M: xfs-masters@oss.sgi.com
-M: nathans@sgi.com
L: xfs@oss.sgi.com
W: http://oss.sgi.com/projects/xfs
+T: git git://oss.sgi.com:8090/xfs/xfs-2.6
S: Supported
X86 3-LEVEL PAGING (PAE) SUPPORT
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 18
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
NAME=Crazed Snow-Weasel
# *DOCUMENTATION*
CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common
-# Force gcc to behave correct even for buggy distributions
-CFLAGS += $(call cc-option, -fno-stack-protector)
-
AFLAGS := -D__ASSEMBLY__
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
endif # KBUILD_EXTMOD
ifeq ($(dot-config),1)
-# In this section, we need .config
+# Read in config
+-include include/config/auto.conf
+ifeq ($(KBUILD_EXTMOD),)
# Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected.
-include include/config/auto.conf.cmd
--include include/config/auto.conf
# To avoid any implicit rule to kick in, define an empty command
$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
# if auto.conf.cmd is missing then we are probably in a cleaned tree so
# we execute the config step to be sure to catch updated Kconfig files
include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
-ifeq ($(KBUILD_EXTMOD),)
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
else
- $(error kernel configuration not valid - run 'make prepare' in $(srctree) to update it)
-endif
+# external modules needs include/linux/autoconf.h and include/config/auto.conf
+# but do not care if they are up-to-date. Use auto.conf to trigger the test
+PHONY += include/config/auto.conf
+
+include/config/auto.conf:
+ $(Q)test -e include/linux/autoconf.h -a -e $@ || ( \
+ echo; \
+ echo " ERROR: Kernel configuration is invalid."; \
+ echo " include/linux/autoconf.h or $@ are missing."; \
+ echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
+ echo; \
+ /bin/false)
+
+endif # KBUILD_EXTMOD
else
# Dummy target needed, because used as prerequisite
include/config/auto.conf: ;
-endif
+endif # $(dot-config)
# The all: target is the default when no target is given on the
# command line.
CFLAGS += -O2
endif
+include $(srctree)/arch/$(ARCH)/Makefile
+
ifdef CONFIG_FRAME_POINTER
CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
else
CFLAGS += -g
endif
-include $(srctree)/arch/$(ARCH)/Makefile
+# Force gcc to behave correct even for buggy distributions
+CFLAGS += $(call cc-option, -fno-stack-protector)
# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
# testing for a specific architecture or later rather impossible.
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
-arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4)
+arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
+arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t
arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
static inline struct safe_buffer *
find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr)
{
- struct safe_buffer *b = NULL;
+ struct safe_buffer *b, *rb = NULL;
unsigned long flags;
read_lock_irqsave(&device_info->lock, flags);
list_for_each_entry(b, &device_info->safe_buffers, node)
- if (b->safe_dma_addr == safe_dma_addr)
+ if (b->safe_dma_addr == safe_dma_addr) {
+ rb = b;
break;
+ }
read_unlock_irqrestore(&device_info->lock, flags);
- return b;
+ return rb;
}
static inline void
rtc_time_to_tm(next_time, next);
}
}
+EXPORT_SYMBOL(rtc_next_alarm_time);
static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm)
{
{
struct sa1111 *sachip;
unsigned long id;
- unsigned int has_devs, val;
+ unsigned int has_devs;
int i, ret = -ENODEV;
sachip = kzalloc(sizeof(struct sa1111), GFP_KERNEL);
sa1111_wake(sachip);
#ifdef CONFIG_ARCH_SA1100
+ {
+ unsigned int val;
+
/*
* The SDRAM configuration of the SA1110 and the SA1111 must
* match. This is very important to ensure that SA1111 accesses
* Enable the SA1110 memory bus request and grant signals.
*/
sa1110_mb_enable();
+ }
#endif
/*
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_ISA_DMA_API) += dma.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o
-obj-$(CONFIG_FOOTBRIDGE) += isa.o
obj-$(CONFIG_FIQ) += fiq.o
obj-$(CONFIG_MODULES) += armksyms.o module.o
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
-obj-$(CONFIG_PCI) += bios32.o
+obj-$(CONFIG_PCI) += bios32.o isa.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
* purpose.
*/
+ .macro usr_ret, reg
+#ifdef CONFIG_ARM_THUMB
+ bx \reg
+#else
+ mov pc, \reg
+#endif
+ .endm
+
.align 5
.globl __kuser_helper_start
__kuser_helper_start:
#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP)
mcr p15, 0, r0, c7, c10, 5 @ dmb
#endif
- mov pc, lr
+ usr_ret lr
.align 5
mov r0, #-1
adds r0, r0, #0
#endif
- mov pc, lr
+ usr_ret lr
#else
#ifdef CONFIG_SMP
mcr p15, 0, r0, c7, c10, 5 @ dmb
#endif
- mov pc, lr
+ usr_ret lr
#endif
__kuser_get_tls: @ 0xffff0fe0
#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
-
ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
- mov pc, lr
-
#else
-
mrc p15, 0, r0, c13, c0, 3 @ read TLS register
- mov pc, lr
-
#endif
+ usr_ret lr
.rep 5
.word 0 @ pad up to __kuser_helper_version
sub r4, r4, r5 @ mmu has been enabled
ldr r4, [r7, r4] @ get secondary_data.pgdir
adr lr, __enable_mmu @ return address
- add pc, r10, #12 @ initialise processor
+ add pc, r10, #PROCINFO_INITFUNC @ initialise processor
@ (return control reg)
/*
*
* Copyright (C) 1999 Phil Blundell
*
- * ISA shared memory and I/O port support
- */
-
-/*
* 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.
+ *
+ * ISA shared memory and I/O port support, and is required to support
+ * iopl, inb, outb and friends in userspace via glibc emulation.
*/
-
-/*
- * Nothing about this is actually ARM specific. One day we could move
- * it into kernel/resource.c or some place like that.
- */
-
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/fs.h>
static unsigned int isa_membase, isa_portbase, isa_portshift;
static ctl_table ctl_isa_vars[4] = {
- {BUS_ISA_MEM_BASE, "membase", &isa_membase,
- sizeof(isa_membase), 0444, NULL, &proc_dointvec},
- {BUS_ISA_PORT_BASE, "portbase", &isa_portbase,
- sizeof(isa_portbase), 0444, NULL, &proc_dointvec},
- {BUS_ISA_PORT_SHIFT, "portshift", &isa_portshift,
- sizeof(isa_portshift), 0444, NULL, &proc_dointvec},
- {0}
+ {
+ .ctl_name = BUS_ISA_MEM_BASE,
+ .procname = "membase",
+ .data = &isa_membase,
+ .maxlen = sizeof(isa_membase),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ }, {
+ .ctl_name = BUS_ISA_PORT_BASE,
+ .procname = "portbase",
+ .data = &isa_portbase,
+ .maxlen = sizeof(isa_portbase),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ }, {
+ .ctl_name = BUS_ISA_PORT_SHIFT,
+ .procname = "portshift",
+ .data = &isa_portshift,
+ .maxlen = sizeof(isa_portshift),
+ .mode = 0444,
+ .proc_handler = &proc_dointvec,
+ }, {0}
};
static struct ctl_table_header *isa_sysctl_header;
-static ctl_table ctl_isa[2] = {{CTL_BUS_ISA, "isa", NULL, 0, 0555, ctl_isa_vars},
- {0}};
-static ctl_table ctl_bus[2] = {{CTL_BUS, "bus", NULL, 0, 0555, ctl_isa},
- {0}};
+static ctl_table ctl_isa[2] = {
+ {
+ .ctl_name = CTL_BUS_ISA,
+ .procname = "isa",
+ .mode = 0555,
+ .child = ctl_isa_vars,
+ }, {0}
+};
+
+static ctl_table ctl_bus[2] = {
+ {
+ .ctl_name = CTL_BUS,
+ .procname = "bus",
+ .mode = 0555,
+ .child = ctl_isa,
+ }, {0}
+};
void __init
register_isa_ports(unsigned int membase, unsigned int portbase, unsigned int portshift)
spin_unlock_irq(&die_lock);
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
do_exit(SIGSEGV);
}
extern int setup_arm_irq(int, struct irqaction *);
extern void pcibios_report_status(u_int status_mask, int warn);
-extern void register_isa_ports(unsigned int, unsigned int, unsigned int);
static unsigned long
dc21285_base_address(struct pci_bus *bus, unsigned int devfn)
printk(KERN_ERR "PCI: unable to grab local bus timeout "
"interrupt: %d\n", ret);
#endif
+
+ register_isa_ports(PHYS_PCI_MEM_BASE, PHYS_PCI_IO_BASE, 0);
}
return -EIO;
}
-EXPORT_SYMBOL(pci_set_dma_mask);
-EXPORT_SYMBOL(pci_set_consistent_dma_mask);
EXPORT_SYMBOL(ixp4xx_pci_read);
EXPORT_SYMBOL(ixp4xx_pci_write);
.width = 2,
};
-static struct gtw5715_flash_resource = {
+static struct resource gtwx5715_flash_resource = {
.flags = IORESOURCE_MEM,
-}
+};
static struct platform_device gtwx5715_flash = {
.name = "IXP4XX-Flash",
{
ixp4xx_sys_init();
- if (!flash_resource)
- printk(KERN_ERR "Could not allocate flash resource\n");
-
gtwx5715_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
gtwx5715_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1;
*/
unsigned long corgi_ssp_ads7846_putget(ulong data)
{
- unsigned long ret,flag;
+ unsigned long flag;
+ u32 ret = 0;
spin_lock_irqsave(&corgi_ssp_lock, flag);
if (ssp_machinfo->cs_ads7846 >= 0)
GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
ssp_write_word(&corgi_ssp_dev,data);
- ret = ssp_read_word(&corgi_ssp_dev);
+ ssp_read_word(&corgi_ssp_dev, &ret);
if (ssp_machinfo->cs_ads7846 >= 0)
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
unsigned long corgi_ssp_ads7846_get(void)
{
- return ssp_read_word(&corgi_ssp_dev);
+ u32 ret = 0;
+ ssp_read_word(&corgi_ssp_dev, &ret);
+ return ret;
}
EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
unsigned long corgi_ssp_dac_put(ulong data)
{
unsigned long flag, sscr1 = SSCR1_SPH;
+ u32 tmp;
spin_lock_irqsave(&corgi_ssp_lock, flag);
GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
ssp_write_word(&corgi_ssp_dev,data);
/* Read null data back from device to prevent SSP overflow */
- ssp_read_word(&corgi_ssp_dev);
+ ssp_read_word(&corgi_ssp_dev, &tmp);
if (ssp_machinfo->cs_lcdcon >= 0)
GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
int corgi_ssp_max1111_get(ulong data)
{
unsigned long flag;
- int voltage,voltage1,voltage2;
+ long voltage = 0, voltage1 = 0, voltage2 = 0;
spin_lock_irqsave(&corgi_ssp_lock, flag);
if (ssp_machinfo->cs_max1111 >= 0)
/* TB1/RB1 */
ssp_write_word(&corgi_ssp_dev,data);
- ssp_read_word(&corgi_ssp_dev); /* null read */
+ ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
/* TB12/RB2 */
ssp_write_word(&corgi_ssp_dev,0);
- voltage1=ssp_read_word(&corgi_ssp_dev);
+ ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
/* TB13/RB3*/
ssp_write_word(&corgi_ssp_dev,0);
- voltage2=ssp_read_word(&corgi_ssp_dev);
+ ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
ssp_disable(&corgi_ssp_dev);
ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
#define PXA_SSP_PORTS 3
+#define TIMEOUT 100000
+
struct ssp_info_ {
int irq;
u32 clock;
* The caller is expected to perform the necessary locking.
*
* Returns:
- * %-ETIMEDOUT timeout occurred (for future)
+ * %-ETIMEDOUT timeout occurred
* 0 success
*/
int ssp_write_word(struct ssp_dev *dev, u32 data)
{
- while (!(SSSR_P(dev->port) & SSSR_TNF))
+ int timeout = TIMEOUT;
+
+ while (!(SSSR_P(dev->port) & SSSR_TNF)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
cpu_relax();
+ }
SSDR_P(dev->port) = data;
* The caller is expected to perform the necessary locking.
*
* Returns:
- * %-ETIMEDOUT timeout occurred (for future)
+ * %-ETIMEDOUT timeout occurred
* 32-bit data success
*/
-int ssp_read_word(struct ssp_dev *dev)
+int ssp_read_word(struct ssp_dev *dev, u32 *data)
{
- while (!(SSSR_P(dev->port) & SSSR_RNE))
+ int timeout = TIMEOUT;
+
+ while (!(SSSR_P(dev->port) & SSSR_RNE)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
cpu_relax();
+ }
- return SSDR_P(dev->port);
+ *data = SSDR_P(dev->port);
+ return 0;
}
/**
*
* The caller is expected to perform the necessary locking.
*/
-void ssp_flush(struct ssp_dev *dev)
+int ssp_flush(struct ssp_dev *dev)
{
+ int timeout = TIMEOUT * 2;
+
do {
while (SSSR_P(dev->port) & SSSR_RNE) {
+ if (!--timeout)
+ return -ETIMEDOUT;
(void) SSDR_P(dev->port);
}
+ if (!--timeout)
+ return -ETIMEDOUT;
} while (SSSR_P(dev->port) & SSSR_BSY);
+
+ return 0;
}
/**
obj-n :=
obj- :=
+# DMA
+obj-$(CONFIG_S3C2410_DMA) += dma.o
+
# S3C2400 support files
-obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o
+obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o
# S3C2410 support files
-obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
-obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o
-obj-$(CONFIG_S3C2410_DMA) += dma.o
+obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
+obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o
# Power Management support
-obj-$(CONFIG_PM) += pm.o sleep.o
-obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
+obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
# S3C2412 support
-obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
-obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o
+obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
+obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o
#
# S3C244X support
-obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
-obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
+obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
# Clock control
-obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
+obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
# S3C2440 support
-obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
-obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
-obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
-obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o
+obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
+obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
+obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
+obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o
# S3C2442 support
-obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
-obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o
+obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
+obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o
# bast extras
}
static void
-dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan,
+dmadbg_dumpregs(const char *fname, int line, s3c2410_dma_chan_t *chan,
struct s3c2410_dma_regstate *regs)
{
printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
chan->number, fname, line, chan->load_state,
chan->curr, chan->next, chan->end);
- dmadbg_showregs(fname, line, chan, &state);
+ dmadbg_dumpregs(fname, line, chan, &state);
+}
+
+static void
+dmadbg_showregs(const char *fname, int line, s3c2410_dma_chan_t *chan)
+{
+ struct s3c2410_dma_regstate state;
+
+ dmadbg_capture(chan, &state);
+ dmadbg_dumpregs(fname, line, chan, &state);
}
#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
buf->next);
reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
} else {
- pr_debug("load_state is %d => autoreload\n", chan->load_state);
+ //pr_debug("load_state is %d => autoreload\n", chan->load_state);
reload = S3C2410_DCON_AUTORELOAD;
}
+ if ((buf->data & 0xf0000000) != 0x30000000) {
+ dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
+ }
+
writel(buf->data, chan->addr_reg);
dma_wrreg(chan, S3C2410_DMA_DCON,
tmp |= S3C2410_DMASKTRIG_ON;
dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
- pr_debug("wrote %08lx to DMASKTRIG\n", tmp);
+ pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
#if 0
/* the dma buffer loads should take care of clearing the AUTO
dbg_showchan(chan);
+ /* if we've only loaded one buffer onto the channel, then chec
+ * to see if we have another, and if so, try and load it so when
+ * the first buffer is finished, the new one will be loaded onto
+ * the channel */
+
+ if (chan->next != NULL) {
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ pr_debug("%s: buff not yet loaded, no more todo\n",
+ __FUNCTION__);
+ } else {
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+
+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+ }
+
+
local_irq_restore(flags);
+
return 0;
}
buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
if (buf == NULL) {
pr_debug("%s: out of memory (%ld alloc)\n",
- __FUNCTION__, sizeof(*buf));
+ __FUNCTION__, (long)sizeof(*buf));
return -ENOMEM;
}
- pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
-
+ //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
//dbg_showchan(chan);
buf->next = NULL;
case S3C2410_DMALOAD_1LOADED:
if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
/* flag error? */
- printk(KERN_ERR "dma%d: timeout waiting for load\n",
- chan->number);
+ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+ chan->number, __FUNCTION__);
return;
}
break;
+ case S3C2410_DMALOAD_1LOADED_1RUNNING:
+ /* I belive in this case we do not have anything to do
+ * until the next buffer comes along, and we turn off the
+ * reload */
+ return;
+
default:
- pr_debug("dma%d: lastxfer: unhandled load_state %d with no next",
+ pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
chan->number, chan->load_state);
return;
} else {
}
- if (chan->next != NULL) {
+ /* only reload if the channel is still running... our buffer done
+ * routine may have altered the state by requesting the dma channel
+ * to stop or shutdown... */
+
+ /* todo: check that when the channel is shut-down from inside this
+ * function, we cope with unsetting reload, etc */
+
+ if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
unsigned long flags;
switch (chan->load_state) {
case S3C2410_DMALOAD_1LOADED:
if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
/* flag error? */
- printk(KERN_ERR "dma%d: timeout waiting for load\n",
- chan->number);
+ printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
+ chan->number, __FUNCTION__);
return IRQ_HANDLED;
}
return IRQ_HANDLED;
}
-
-
/* s3c2410_request_dma
*
* get control of an dma channel
pr_debug("dma%d: %s : requesting irq %d\n",
channel, __FUNCTION__, chan->irq);
+ chan->irq_claimed = 1;
+ local_irq_restore(flags);
+
err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
client->name, (void *)chan);
+ local_irq_save(flags);
+
if (err) {
chan->in_use = 0;
+ chan->irq_claimed = 0;
local_irq_restore(flags);
printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
return err;
}
- chan->irq_claimed = 1;
chan->irq_enabled = 1;
}
tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
tmp |= S3C2410_DMASKTRIG_STOP;
+ //tmp &= ~S3C2410_DMASKTRIG_ON;
dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
#if 0
dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
#endif
+ /* should stop do this, or should we wait for flush? */
chan->state = S3C2410_DMA_IDLE;
chan->load_state = S3C2410_DMALOAD_NONE;
return 0;
}
+void s3c2410_dma_waitforstop(s3c2410_dma_chan_t *chan)
+{
+ unsigned long tmp;
+ unsigned int timeout = 0x10000;
+
+ while (timeout-- > 0) {
+ tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
+
+ if (!(tmp & S3C2410_DMASKTRIG_ON))
+ return;
+ }
+
+ pr_debug("dma%d: failed to stop?\n", chan->number);
+}
+
+
/* s3c2410_dma_flush
*
* stop the channel, and remove all current and pending transfers
s3c2410_dma_buf_t *buf, *next;
unsigned long flags;
- pr_debug("%s:\n", __FUNCTION__);
+ pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
+
+ dbg_showchan(chan);
local_irq_save(flags);
}
}
+ dbg_showregs(chan);
+
+ s3c2410_dma_waitforstop(chan);
+
+#if 0
+ /* should also clear interrupts, according to WinCE BSP */
+ {
+ unsigned long tmp;
+
+ tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
+ tmp |= S3C2410_DCON_NORELOAD;
+ dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
+ }
+#endif
+
+ dbg_showregs(chan);
+
local_irq_restore(flags);
return 0;
}
+int
+s3c2410_dma_started(s3c2410_dma_chan_t *chan)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ dbg_showchan(chan);
+
+ /* if we've only loaded one buffer onto the channel, then chec
+ * to see if we have another, and if so, try and load it so when
+ * the first buffer is finished, the new one will be loaded onto
+ * the channel */
+
+ if (chan->next != NULL) {
+ if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
+
+ if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
+ pr_debug("%s: buff not yet loaded, no more todo\n",
+ __FUNCTION__);
+ } else {
+ chan->load_state = S3C2410_DMALOAD_1RUNNING;
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+
+ } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
+ s3c2410_dma_loadbuffer(chan, chan->next);
+ }
+ }
+
+
+ local_irq_restore(flags);
+
+ return 0;
+
+}
int
s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op)
return s3c2410_dma_dostop(chan);
case S3C2410_DMAOP_PAUSE:
- return -ENOENT;
-
case S3C2410_DMAOP_RESUME:
return -ENOENT;
case S3C2410_DMAOP_FLUSH:
return s3c2410_dma_flush(chan);
+ case S3C2410_DMAOP_STARTED:
+ return s3c2410_dma_started(chan);
+
case S3C2410_DMAOP_TIMEOUT:
return 0;
#include <asm/hardware.h>
#include <asm/hardware/ssp.h>
+#define TIMEOUT 100000
+
static irqreturn_t ssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned int status = Ser4SSSR;
* The caller is expected to perform the necessary locking.
*
* Returns:
- * %-ETIMEDOUT timeout occurred (for future)
+ * %-ETIMEDOUT timeout occurred
* 0 success
*/
int ssp_write_word(u16 data)
{
- while (!(Ser4SSSR & SSSR_TNF))
+ int timeout = TIMEOUT;
+
+ while (!(Ser4SSSR & SSSR_TNF)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
cpu_relax();
+ }
Ser4SSDR = data;
- while (!(Ser4SSSR & SSSR_BSY))
+ timeout = TIMEOUT;
+ while (!(Ser4SSSR & SSSR_BSY)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
cpu_relax();
+ }
return 0;
}
* The caller is expected to perform the necessary locking.
*
* Returns:
- * %-ETIMEDOUT timeout occurred (for future)
+ * %-ETIMEDOUT timeout occurred
* 16-bit data success
*/
-int ssp_read_word(void)
+int ssp_read_word(u16 *data)
{
- while (!(Ser4SSSR & SSSR_RNE))
+ int timeout = TIMEOUT;
+
+ while (!(Ser4SSSR & SSSR_RNE)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
cpu_relax();
+ }
+
+ *data = (u16)Ser4SSDR;
- return Ser4SSDR;
+ return 0;
}
/**
* is empty.
*
* The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ * %-ETIMEDOUT timeout occurred
+ * 0 success
*/
-void ssp_flush(void)
+int ssp_flush(void)
{
+ int timeout = TIMEOUT * 2;
+
do {
while (Ser4SSSR & SSSR_RNE) {
+ if (!--timeout)
+ return -ETIMEDOUT;
(void) Ser4SSDR;
}
+ if (!--timeout)
+ return -ETIMEDOUT;
} while (Ser4SSSR & SSSR_BSY);
+
+ return 0;
}
/**
static struct resource versatile_flash_resource = {
.start = VERSATILE_FLASH_BASE,
- .end = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE,
+ .end = VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1,
.flags = IORESOURCE_MEM,
};
config CPU_ARM720T
bool "Support ARM720T processor" if !ARCH_CLPS711X && !ARCH_L7200 && !ARCH_CDB89712 && ARCH_INTEGRATOR
default y if ARCH_CLPS711X || ARCH_L7200 || ARCH_CDB89712 || ARCH_H720X
- select CPU_32v4
+ select CPU_32v4T
select CPU_ABRT_LV4T
select CPU_CACHE_V4
select CPU_CACHE_VIVT
bool "Support ARM920T processor"
depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
- select CPU_32v4
+ select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
bool "Support ARM922T processor" if ARCH_INTEGRATOR
depends on ARCH_LH7A40X || ARCH_INTEGRATOR
default y if ARCH_LH7A40X
- select CPU_32v4
+ select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
bool "Support ARM925T processor" if ARCH_OMAP1
depends on ARCH_OMAP15XX
default y if ARCH_OMAP15XX
- select CPU_32v4
+ select CPU_32v4T
select CPU_ABRT_EV4T
select CPU_CACHE_V4WT
select CPU_CACHE_VIVT
select TLS_REG_EMUL if SMP || !MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+config CPU_32v4T
+ bool
+ select TLS_REG_EMUL if SMP || !MMU
+ select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+
config CPU_32v5
bool
select TLS_REG_EMUL if SMP || !MMU
* A special flag to tell the normalisation code not to normalise.
*/
#define VFP_NAN_FLAG 0x100
+
+/*
+ * A bit pattern used to indicate the initial (unset) value of the
+ * exception mask, in case nothing handles an instruction. This
+ * doesn't include the NAN flag, which get masked out before
+ * we check for an error.
+ */
+#define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG)
*/
if (tm & (VFP_INFINITY|VFP_NAN)) {
vsd.exponent = 255;
- if (tm & VFP_NAN)
+ if (tm == VFP_QNAN)
vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN;
goto pack_nan;
} else if (tm & VFP_ZERO)
{
u32 op = inst & FOP_MASK;
u32 exceptions = 0;
- unsigned int dd = vfp_get_dd(inst);
+ unsigned int dest;
unsigned int dn = vfp_get_dn(inst);
unsigned int dm = vfp_get_dm(inst);
unsigned int vecitr, veclen, vecstride;
veclen = fpscr & FPSCR_LENGTH_MASK;
vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2;
+ /*
+ * fcvtds takes an sN register number as destination, not dN.
+ * It also always operates on scalars.
+ */
+ if ((inst & FEXT_MASK) == FEXT_FCVT) {
+ veclen = 0;
+ dest = vfp_get_sd(inst);
+ } else
+ dest = vfp_get_dd(inst);
+
/*
* If destination bank is zero, vector length is always '1'.
* ARM DDI0100F C5.1.3, C5.3.2.
*/
- if (FREG_BANK(dd) == 0)
+ if (FREG_BANK(dest) == 0)
veclen = 0;
pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) {
u32 except;
- if (op == FOP_EXT)
+ if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
+ pr_debug("VFP: itr%d (s%u) = op[%u] (d%u)\n",
+ vecitr >> FPSCR_LENGTH_BIT,
+ dest, dn, dm);
+ else if (op == FOP_EXT)
pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n",
vecitr >> FPSCR_LENGTH_BIT,
- dd, dn, dm);
+ dest, dn, dm);
else
pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n",
vecitr >> FPSCR_LENGTH_BIT,
- dd, dn, FOP_TO_IDX(op), dm);
+ dest, dn, FOP_TO_IDX(op), dm);
- except = fop(dd, dn, dm, fpscr);
+ except = fop(dest, dn, dm, fpscr);
pr_debug("VFP: itr%d: exceptions=%08x\n",
vecitr >> FPSCR_LENGTH_BIT, except);
* we encounter an exception. We continue.
*/
- dd = FREG_BANK(dd) + ((FREG_IDX(dd) + vecstride) & 6);
+ dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6);
dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6);
if (FREG_BANK(dm) != 0)
dm = FREG_BANK(dm) + ((FREG_IDX(dm) + vecstride) & 6);
pr_debug("VFP: raising exceptions %08x\n", exceptions);
- if (exceptions == (u32)-1) {
+ if (exceptions == VFP_EXCEPTION_ERROR) {
vfp_panic("unhandled bounce");
vfp_raise_sigfpe(0, regs);
return;
*/
static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs)
{
- u32 exceptions = (u32)-1;
+ u32 exceptions = VFP_EXCEPTION_ERROR;
pr_debug("VFP: emulate: INST=0x%08x SCR=0x%08x\n", inst, fpscr);
*/
if (tm & (VFP_INFINITY|VFP_NAN)) {
vdd.exponent = 2047;
- if (tm & VFP_NAN)
+ if (tm == VFP_QNAN)
vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN;
goto pack_nan;
} else if (tm & VFP_ZERO)
else
vdd.exponent = vsm.exponent + (1023 - 127);
- /*
- * Technically, if bit 0 of dd is set, this is an invalid
- * instruction. However, we ignore this for efficiency.
- */
return vfp_double_normaliseround(dd, &vdd, fpscr, exceptions, "fcvtd");
pack_nan:
{
u32 op = inst & FOP_MASK;
u32 exceptions = 0;
- unsigned int sd = vfp_get_sd(inst);
+ unsigned int dest;
unsigned int sn = vfp_get_sn(inst);
unsigned int sm = vfp_get_sm(inst);
unsigned int vecitr, veclen, vecstride;
veclen = fpscr & FPSCR_LENGTH_MASK;
vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK);
+ /*
+ * fcvtsd takes a dN register number as destination, not sN.
+ * Technically, if bit 0 of dd is set, this is an invalid
+ * instruction. However, we ignore this for efficiency.
+ * It also only operates on scalars.
+ */
+ if ((inst & FEXT_MASK) == FEXT_FCVT) {
+ veclen = 0;
+ dest = vfp_get_dd(inst);
+ } else
+ dest = vfp_get_sd(inst);
+
/*
* If destination bank is zero, vector length is always '1'.
* ARM DDI0100F C5.1.3, C5.3.2.
*/
- if (FREG_BANK(sd) == 0)
+ if (FREG_BANK(dest) == 0)
veclen = 0;
pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride,
s32 m = vfp_get_float(sm);
u32 except;
- if (op == FOP_EXT)
+ if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT)
+ pr_debug("VFP: itr%d (d%u) = op[%u] (s%u=%08x)\n",
+ vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
+ else if (op == FOP_EXT)
pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n",
- vecitr >> FPSCR_LENGTH_BIT, sd, sn, sm, m);
+ vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m);
else
pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n",
- vecitr >> FPSCR_LENGTH_BIT, sd, sn,
+ vecitr >> FPSCR_LENGTH_BIT, dest, sn,
FOP_TO_IDX(op), sm, m);
- except = fop(sd, sn, m, fpscr);
+ except = fop(dest, sn, m, fpscr);
pr_debug("VFP: itr%d: exceptions=%08x\n",
vecitr >> FPSCR_LENGTH_BIT, except);
* we encounter an exception. We continue.
*/
- sd = FREG_BANK(sd) + ((FREG_IDX(sd) + vecstride) & 7);
+ dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7);
sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7);
if (FREG_BANK(sm) != 0)
sm = FREG_BANK(sm) + ((FREG_IDX(sm) + vecstride) & 7);
In particular, it is needed for the x440.
If you don't have one of these computers, you should say N here.
+ If you want to build a NUMA kernel, you must select ACPI.
config X86_BIGSMP
bool "Support for other sub-arch SMP systems with more than 8 CPUs"
help
This option compiles in the Summit, bigsmp, ES7000, default subarchitectures.
It is intended for a generic binary kernel.
+ If you want a NUMA kernel, select ACPI. We need SRAT for NUMA.
config X86_ES7000
bool "Support for Unisys ES7000 IA32 series"
# Common NUMA Features
config NUMA
bool "Numa Memory Allocation and Scheduler Support"
- depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI))
+ depends on SMP && HIGHMEM64G && (X86_NUMAQ || (X86_SUMMIT || X86_GENERICARCH) && ACPI)
default n if X86_PC
default y if (X86_NUMAQ || X86_SUMMIT)
#define BAD_MADT_ENTRY(entry, end) ( \
(!entry) || (unsigned long)entry + sizeof(*entry) > end || \
- ((acpi_table_entry_header *)entry)->length != sizeof(*entry))
+ ((acpi_table_entry_header *)entry)->length < sizeof(*entry))
#define PREFIX "ACPI: "
pushl $3
call acpi_enter_sleep_state
addl $4, %esp
- ret
+
+# In case of S3 failure, we'll emerge here. Jump
+# to ret_point to recover
+ jmp ret_point
.p2align 4,,7
ret_point:
call restore_registers
static int __init
acpi_cpufreq_init (void)
{
- int result = 0;
-
dprintk("acpi_cpufreq_init\n");
- result = acpi_cpufreq_early_init_acpi();
+ acpi_cpufreq_early_init_acpi();
- if (!result)
- result = cpufreq_register_driver(&acpi_cpufreq_driver);
-
- return (result);
+ return cpufreq_register_driver(&acpi_cpufreq_driver);
}
movl %eax,%gs
lldt %ax
cld # gcc2 wants the direction flag cleared at all times
+ pushl %eax # fake return address
#ifdef CONFIG_SMP
movb ready, %cl
movb $1, ready
- cmpb $0,%cl
- je 1f # the first CPU calls start_kernel
- # all other CPUs call initialize_secondary
- call initialize_secondary
- jmp L6
-1:
+ cmpb $0,%cl # the first CPU calls start_kernel
+ jne initialize_secondary # all other CPUs call initialize_secondary
#endif /* CONFIG_SMP */
- call start_kernel
-L6:
- jmp L6 # main should never return here, but
- # just in case, we know what happens.
+ jmp start_kernel
/*
* We depend on ET to be correct. This checks for 287/387.
}
#endif
- if (!irq_desc[irq].handle_irq) {
- __do_IRQ(irq, regs);
- goto out_exit;
- }
#ifdef CONFIG_4KSTACKS
curctx = (union irq_ctx *) current_thread_info();
#endif
__do_IRQ(irq, regs);
-out_exit:
irq_exit();
return 1;
return 0;
}
- /*
- * This function checks if the entire range <start,end> is mapped with type.
- *
- * Note: this function only works correct if the e820 table is sorted and
- * not-overlapping, which is the case
- */
-int __init
-e820_all_mapped(unsigned long s, unsigned long e, unsigned type)
-{
- u64 start = s;
- u64 end = e;
- int i;
- for (i = 0; i < e820.nr_map; i++) {
- struct e820entry *ei = &e820.map[i];
- if (type && ei->type != type)
- continue;
- /* is the region (part) in overlap with the current region ?*/
- if (ei->addr >= end || ei->addr + ei->size <= start)
- continue;
- /* if the region is at the beginning of <start,end> we move
- * start to the end of the region since it's ok until there
- */
- if (ei->addr <= start)
- start = ei->addr + ei->size;
- /* if start is now at or beyond end, we're done, full
- * coverage */
- if (start >= end)
- return 1; /* we're done */
- }
- return 0;
-}
-
/*
* Find the highest page frame number we have available
*/
asmlinkage void machine_check(void);
static int kstack_depth_to_print = 24;
+#ifdef CONFIG_STACK_UNWIND
static int call_trace = 1;
+#else
+#define call_trace (-1)
+#endif
ATOMIC_NOTIFIER_HEAD(i386die_chain);
int register_die_notifier(struct notifier_block *nb)
if (unwind_init_blocked(&info, task) == 0)
unw_ret = show_trace_unwind(&info, log_lvl);
}
- if (unw_ret > 0 && !arch_unw_user_mode(&info)) {
-#ifdef CONFIG_STACK_UNWIND
- print_symbol("DWARF2 unwinder stuck at %s\n",
- UNW_PC(&info));
- if (call_trace == 1) {
- printk("Leftover inexact backtrace:\n");
- if (UNW_SP(&info))
+ if (unw_ret > 0) {
+ if (call_trace == 1 && !arch_unw_user_mode(&info)) {
+ print_symbol("DWARF2 unwinder stuck at %s\n",
+ UNW_PC(&info));
+ if (UNW_SP(&info) >= PAGE_OFFSET) {
+ printk("Leftover inexact backtrace:\n");
stack = (void *)UNW_SP(&info);
- } else if (call_trace > 1)
+ } else
+ printk("Full inexact backtrace again:\n");
+ } else if (call_trace >= 1)
return;
else
printk("Full inexact backtrace again:\n");
-#else
+ } else
printk("Inexact backtrace:\n");
-#endif
- }
}
if (task == current) {
panic("Fatal exception in interrupt");
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
oops_exit();
do_exit(SIGSEGV);
}
__setup("kstack=", kstack_setup);
+#ifdef CONFIG_STACK_UNWIND
static int __init call_trace_setup(char *s)
{
if (strcmp(s, "old") == 0)
return 1;
}
__setup("call_trace=", call_trace_setup);
+#endif
pci_probe &= ~PCI_PROBE_MMCONF;
return NULL;
}
+ /* override DMI blacklist */
+ else if (!strcmp(str, "mmconf")) {
+ pci_probe |= PCI_PROBE_MMCONF_FORCE;
+ return NULL;
+ }
#endif
else if (!strcmp(str, "noacpi")) {
acpi_noirq_set();
#ifdef CONFIG_PCI_BIOS
pci_pcbios_init();
#endif
- if (raw_pci_ops)
- return 0;
+ /*
+ * don't check for raw_pci_ops here because we want pcbios as last
+ * fallback, yet it's needed to run first to set pcibios_last_bus
+ * in case legacy PCI probing is used. otherwise detecting peer busses
+ * fails.
+ */
#ifdef CONFIG_PCI_DIRECT
pci_direct_init();
#endif
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/acpi.h>
+#include <linux/dmi.h>
#include <asm/e820.h>
#include "pci.h"
pci_exp_set_dev_base(addr, k, PCI_DEVFN(i, 0));
if (addr == 0 ||
readl((u32 __iomem *)mmcfg_virt_addr) != val1) {
- set_bit(i, fallback_slots);
+ set_bit(i + 32*k, fallback_slots);
printk(KERN_NOTICE
"PCI: No mmconfig possible on %x:%x\n", k, i);
}
}
}
+static int disable_mcfg(struct dmi_system_id *d)
+{
+ printk("PCI: %s detected. Disabling MCFG.\n", d->ident);
+ pci_probe &= ~PCI_PROBE_MMCONF;
+ return 0;
+}
+
+static struct dmi_system_id __initdata dmi_bad_mcfg[] = {
+ /* Has broken MCFG table that makes the system hang when used */
+ {
+ .callback = disable_mcfg,
+ .ident = "Intel D3C5105 SDV",
+ .matches = {
+ DMI_MATCH(DMI_BIOS_VENDOR, "Intel"),
+ DMI_MATCH(DMI_BOARD_NAME, "D26928"),
+ },
+ },
+ {}
+};
+
void __init pci_mmcfg_init(void)
{
- if ((pci_probe & PCI_PROBE_MMCONF) == 0)
+ dmi_check_system(dmi_bad_mcfg);
+
+ if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0)
return;
acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg);
(pci_mmcfg_config[0].base_address == 0))
return;
- if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
- pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
- E820_RESERVED)) {
- printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
- pci_mmcfg_config[0].base_address);
- printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
- return;
- }
-
printk(KERN_INFO "PCI: Using MMCONFIG\n");
raw_pci_ops = &pci_mmcfg;
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
#define PCI_PROBE_CONF1 0x0002
#define PCI_PROBE_CONF2 0x0004
#define PCI_PROBE_MMCONF 0x0008
-#define PCI_PROBE_MASK 0x000f
+#define PCI_PROBE_MMCONF_FORCE 0x0010
+#define PCI_PROBE_MASK 0x00ff
#define PCI_NO_SORT 0x0100
#define PCI_BIOS_SORT 0x0200
int "Maximum number of CPUs (2-1024)"
range 2 1024
depends on SMP
- default "64"
+ default "1024"
help
You should set this to the number of CPUs in your system, but
keep in mind that a kernel compiled for, e.g., 2 CPUs will boot but
config NODES_SHIFT
int "Max num nodes shift(3-10)"
range 3 10
- default "8"
+ default "10"
depends on NEED_MULTIPLE_NODES
help
This option specifies the maximum number of nodes in your SSI system.
if (scatterlen == 0)
memcpy(sc->request_buffer, buf, len);
- else for (slp = (struct scatterlist *)sc->request_buffer; scatterlen-- > 0 && len > 0; slp++) {
+ else for (slp = (struct scatterlist *)sc->request_buffer;
+ scatterlen-- > 0 && len > 0; slp++) {
unsigned thislen = min(len, slp->length);
memcpy(page_address(slp->page) + slp->offset, buf, thislen);
#define BAD_MADT_ENTRY(entry, end) ( \
(!entry) || (unsigned long)entry + sizeof(*entry) > end || \
- ((acpi_table_entry_header *)entry)->length != sizeof(*entry))
+ ((acpi_table_entry_header *)entry)->length < sizeof(*entry))
#define PREFIX "ACPI: "
#endif
sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL);
- if (!sysfs_cpus) {
- err = -ENOMEM;
- goto out;
- }
+ if (!sysfs_cpus)
+ panic("kzalloc in topology_init failed - NR_CPUS too big?");
for_each_present_cpu(i) {
if((err = arch_register_cpu(i)))
spin_unlock_irq(&die.lock);
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
do_exit(SIGSEGV);
}
return part->reason;
}
- bte_ret = xp_bte_copy((u64) src, (u64) ia64_tpa((u64) dst),
- (u64) cnt, (BTE_NORMAL | BTE_WACQUIRE), NULL);
+ bte_ret = xp_bte_copy((u64) src, (u64) dst, (u64) cnt,
+ (BTE_NORMAL | BTE_WACQUIRE), NULL);
if (bte_ret == BTE_SUCCESS) {
return xpcSuccess;
}
if (xpc_sysctl) {
unregister_sysctl_table(xpc_sysctl);
}
+
+ kfree(xpc_remote_copy_buffer_base);
}
partid_t partid;
struct xpc_partition *part;
pid_t pid;
+ size_t buf_size;
if (!ia64_platform_is("sn2")) {
return -ENODEV;
}
- /*
- * xpc_remote_copy_buffer is used as a temporary buffer for bte_copy'ng
- * various portions of a partition's reserved page. Its size is based
- * on the size of the reserved page header and part_nasids mask. So we
- * need to ensure that the other items will fit as well.
- */
- if (XPC_RP_VARS_SIZE > XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES) {
- dev_err(xpc_part, "xpc_remote_copy_buffer is not big enough\n");
- return -EPERM;
- }
- DBUG_ON((u64) xpc_remote_copy_buffer !=
- L1_CACHE_ALIGN((u64) xpc_remote_copy_buffer));
+
+ buf_size = max(XPC_RP_VARS_SIZE,
+ XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES);
+ xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size,
+ GFP_KERNEL, &xpc_remote_copy_buffer_base);
+ if (xpc_remote_copy_buffer == NULL)
+ return -ENOMEM;
snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part");
snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan");
if (xpc_sysctl) {
unregister_sysctl_table(xpc_sysctl);
}
+
+ kfree(xpc_remote_copy_buffer_base);
return -EBUSY;
}
if (xpc_sysctl) {
unregister_sysctl_table(xpc_sysctl);
}
+
+ kfree(xpc_remote_copy_buffer_base);
return -EBUSY;
}
if (xpc_sysctl) {
unregister_sysctl_table(xpc_sysctl);
}
+
+ kfree(xpc_remote_copy_buffer_base);
return -EBUSY;
}
* Generic buffer used to store a local copy of portions of a remote
* partition's reserved page (either its header and part_nasids mask,
* or its vars).
- *
- * xpc_discovery runs only once and is a seperate thread that is
- * very likely going to be processing in parallel with receiving
- * interrupts.
*/
-char ____cacheline_aligned xpc_remote_copy_buffer[XPC_RP_HEADER_SIZE +
- XP_NASID_MASK_BYTES];
+char *xpc_remote_copy_buffer;
+void *xpc_remote_copy_buffer_base;
/*
* Guarantee that the kmalloc'd memory is cacheline aligned.
*/
-static void *
+void *
xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
{
/* see if kmalloc will give us cachline aligned memory by default */
}
}
- bte_res = xp_bte_copy(rp_pa, ia64_tpa(buf), buf_len,
+ bte_res = xp_bte_copy(rp_pa, buf, buf_len,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bte_res != BTE_SUCCESS) {
dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
/* pull the remote_hb cache line */
bres = xp_bte_copy(part->remote_vars_pa,
- ia64_tpa((u64) remote_vars),
+ (u64) remote_vars,
XPC_RP_VARS_SIZE,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bres != BTE_SUCCESS) {
/* pull over the reserved page header and part_nasids mask */
-
- bres = xp_bte_copy(*remote_rp_pa, ia64_tpa((u64) remote_rp),
+ bres = xp_bte_copy(*remote_rp_pa, (u64) remote_rp,
XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bres != BTE_SUCCESS) {
return xpcVarsNotSet;
}
-
/* pull over the cross partition variables */
-
- bres = xp_bte_copy(remote_vars_pa, ia64_tpa((u64) remote_vars),
- XPC_RP_VARS_SIZE,
+ bres = xp_bte_copy(remote_vars_pa, (u64) remote_vars, XPC_RP_VARS_SIZE,
(BTE_NOTIFY | BTE_WACQUIRE), NULL);
if (bres != BTE_SUCCESS) {
return xpc_map_bte_errors(bres);
part_nasid_pa = (u64) XPC_RP_PART_NASIDS(part->remote_rp_pa);
- bte_res = xp_bte_copy(part_nasid_pa, ia64_tpa((u64) nasid_mask),
+ bte_res = xp_bte_copy(part_nasid_pa, (u64) nasid_mask,
xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
return xpc_map_bte_errors(bte_res);
panic("Fatal exception in interrupt");
if (panic_on_oops)
- panic("Fatal exception: panic_on_oops");
+ panic("Fatal exception");
do_exit(err);
#include <linux/initrd.h>
#include <linux/module.h>
#include <linux/fsl_devices.h>
+#include <linux/fs_enet_pd.h>
#include <asm/system.h>
#include <asm/pgtable.h>
* Setup the architecture
*
*/
+static void init_fcc_ioports(void)
+{
+ struct immap *immap;
+ struct io_port *io;
+ u32 tempval;
+
+ immap = cpm2_immr;
+
+ io = &immap->im_ioport;
+ /* FCC2/3 are on the ports B/C. */
+ tempval = in_be32(&io->iop_pdirb);
+ tempval &= ~PB2_DIRB0;
+ tempval |= PB2_DIRB1;
+ out_be32(&io->iop_pdirb, tempval);
+
+ tempval = in_be32(&io->iop_psorb);
+ tempval &= ~PB2_PSORB0;
+ tempval |= PB2_PSORB1;
+ out_be32(&io->iop_psorb, tempval);
+
+ tempval = in_be32(&io->iop_pparb);
+ tempval |= (PB2_DIRB0 | PB2_DIRB1);
+ out_be32(&io->iop_pparb, tempval);
+
+ tempval = in_be32(&io->iop_pdirb);
+ tempval &= ~PB3_DIRB0;
+ tempval |= PB3_DIRB1;
+ out_be32(&io->iop_pdirb, tempval);
+
+ tempval = in_be32(&io->iop_psorb);
+ tempval &= ~PB3_PSORB0;
+ tempval |= PB3_PSORB1;
+ out_be32(&io->iop_psorb, tempval);
+
+ tempval = in_be32(&io->iop_pparb);
+ tempval |= (PB3_DIRB0 | PB3_DIRB1);
+ out_be32(&io->iop_pparb, tempval);
+
+ tempval = in_be32(&io->iop_pdirc);
+ tempval |= PC3_DIRC1;
+ out_be32(&io->iop_pdirc, tempval);
+
+ tempval = in_be32(&io->iop_pparc);
+ tempval |= PC3_DIRC1;
+ out_be32(&io->iop_pparc, tempval);
+
+ /* Port C has clocks...... */
+ tempval = in_be32(&io->iop_psorc);
+ tempval &= ~(CLK_TRX);
+ out_be32(&io->iop_psorc, tempval);
+
+ tempval = in_be32(&io->iop_pdirc);
+ tempval &= ~(CLK_TRX);
+ out_be32(&io->iop_pdirc, tempval);
+ tempval = in_be32(&io->iop_pparc);
+ tempval |= (CLK_TRX);
+ out_be32(&io->iop_pparc, tempval);
+
+ /* Configure Serial Interface clock routing.
+ * First, clear all FCC bits to zero,
+ * then set the ones we want.
+ */
+ immap->im_cpmux.cmx_fcr &= ~(CPMUX_CLK_MASK);
+ immap->im_cpmux.cmx_fcr |= CPMUX_CLK_ROUTE;
+}
static void __init
mpc8560ads_setup_arch(void)
unsigned int freq;
struct gianfar_platform_data *pdata;
struct gianfar_mdio_data *mdata;
+ struct fs_platform_info *fpi;
cpm2_reset();
memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
}
+ init_fcc_ioports();
+ ppc_sys_device_remove(MPC85xx_CPM_FCC1);
+
+ fpi = (struct fs_platform_info *) ppc_sys_get_pdata(MPC85xx_CPM_FCC2);
+ if (fpi) {
+ memcpy(fpi->macaddr, binfo->bi_enet2addr, 6);
+ fpi->bus_id = "0:02";
+ fpi->phy_addr = 2;
+ fpi->dpram_offset = (u32)cpm2_immr->im_dprambase;
+ fpi->fcc_regs_c = (u32)&cpm2_immr->im_fcc_c[1];
+ }
+
+ fpi = (struct fs_platform_info *) ppc_sys_get_pdata(MPC85xx_CPM_FCC3);
+ if (fpi) {
+ memcpy(fpi->macaddr, binfo->bi_enet2addr, 6);
+ fpi->macaddr[5] += 1;
+ fpi->bus_id = "0:03";
+ fpi->phy_addr = 3;
+ fpi->dpram_offset = (u32)cpm2_immr->im_dprambase;
+ fpi->fcc_regs_c = (u32)&cpm2_immr->im_fcc_c[2];
+ }
+
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start)
ROOT_DEV = Root_RAM0;
#define MPC85XX_PCI1_IO_SIZE 0x01000000
+/* FCC1 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK9-12 */
+#define F1_RXCLK 12
+#define F1_TXCLK 11
+
+/* FCC2 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK13-16 */
+#define F2_RXCLK 13
+#define F2_TXCLK 14
+
+/* FCC3 Clock Source Configuration. These can be
+ * redefined in the board specific file.
+ * Can only choose from CLK13-16 */
+#define F3_RXCLK 15
+#define F3_TXCLK 16
+
+
#endif /* __MACH_MPC85XX_ADS_H__ */
},
};
-static struct fs_mii_bus_info mii_bus_info = {
- .method = fsmii_bitbang,
- .id = 0,
- .i.bitbang = {
- .mdio_port = fsiop_portc,
- .mdio_bit = 18,
- .mdc_port = fsiop_portc,
- .mdc_bit = 19,
- .delay = 1,
- },
-};
-
-static struct fs_platform_info mpc82xx_fcc1_pdata = {
- .fs_no = fsid_fcc1,
- .cp_page = CPM_CR_FCC1_PAGE,
- .cp_block = CPM_CR_FCC1_SBLOCK,
- .clk_trx = (PC_F1RXCLK | PC_F1TXCLK),
- .clk_route = CMX1_CLK_ROUTE,
- .clk_mask = CMX1_CLK_MASK,
- .init_ioports = init_fcc1_ioports,
-
- .phy_addr = 0,
-#ifdef PHY_INTERRUPT
- .phy_irq = PHY_INTERRUPT,
-#else
- .phy_irq = -1;
-#endif
- .mem_offset = FCC1_MEM_OFFSET,
- .bus_info = &mii_bus_info,
- .rx_ring = 32,
- .tx_ring = 32,
- .rx_copybreak = 240,
- .use_napi = 0,
- .napi_weight = 17,
+static struct fs_mii_bb_platform_info m82xx_mii_bb_pdata = {
+ .mdio_dat.bit = 18,
+ .mdio_dir.bit = 18,
+ .mdc_dat.bit = 19,
+ .delay = 1,
};
-static struct fs_platform_info mpc82xx_fcc2_pdata = {
- .fs_no = fsid_fcc2,
- .cp_page = CPM_CR_FCC2_PAGE,
- .cp_block = CPM_CR_FCC2_SBLOCK,
- .clk_trx = (PC_F2RXCLK | PC_F2TXCLK),
- .clk_route = CMX2_CLK_ROUTE,
- .clk_mask = CMX2_CLK_MASK,
- .init_ioports = init_fcc2_ioports,
-
- .phy_addr = 3,
-#ifdef PHY_INTERRUPT
- .phy_irq = PHY_INTERRUPT,
-#else
- .phy_irq = -1;
-#endif
- .mem_offset = FCC2_MEM_OFFSET,
- .bus_info = &mii_bus_info,
- .rx_ring = 32,
- .tx_ring = 32,
- .rx_copybreak = 240,
- .use_napi = 0,
- .napi_weight = 17,
+static struct fs_platform_info mpc82xx_enet_pdata[] = {
+ [fsid_fcc1] = {
+ .fs_no = fsid_fcc1,
+ .cp_page = CPM_CR_FCC1_PAGE,
+ .cp_block = CPM_CR_FCC1_SBLOCK,
+
+ .clk_trx = (PC_F1RXCLK | PC_F1TXCLK),
+ .clk_route = CMX1_CLK_ROUTE,
+ .clk_mask = CMX1_CLK_MASK,
+ .init_ioports = init_fcc1_ioports,
+
+ .mem_offset = FCC1_MEM_OFFSET,
+
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+ .bus_id = "0:00",
+ },
+ [fsid_fcc2] = {
+ .fs_no = fsid_fcc2,
+ .cp_page = CPM_CR_FCC2_PAGE,
+ .cp_block = CPM_CR_FCC2_SBLOCK,
+ .clk_trx = (PC_F2RXCLK | PC_F2TXCLK),
+ .clk_route = CMX2_CLK_ROUTE,
+ .clk_mask = CMX2_CLK_MASK,
+ .init_ioports = init_fcc2_ioports,
+
+ .mem_offset = FCC2_MEM_OFFSET,
+
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+ .bus_id = "0:03",
+ },
};
static void init_fcc1_ioports(void)
bd_t* bi = (void*)__res;
int fs_no = fsid_fcc1+pdev->id-1;
- mpc82xx_fcc1_pdata.dpram_offset = mpc82xx_fcc2_pdata.dpram_offset = (u32)cpm2_immr->im_dprambase;
- mpc82xx_fcc1_pdata.fcc_regs_c = mpc82xx_fcc2_pdata.fcc_regs_c = (u32)cpm2_immr->im_fcc_c;
-
- switch(fs_no) {
- case fsid_fcc1:
- memcpy(&mpc82xx_fcc1_pdata.macaddr,bi->bi_enetaddr,6);
- pdev->dev.platform_data = &mpc82xx_fcc1_pdata;
- break;
- case fsid_fcc2:
- memcpy(&mpc82xx_fcc2_pdata.macaddr,bi->bi_enetaddr,6);
- mpc82xx_fcc2_pdata.macaddr[5] ^= 1;
- pdev->dev.platform_data = &mpc82xx_fcc2_pdata;
- break;
+ if(fs_no > ARRAY_SIZE(mpc82xx_enet_pdata)) {
+ return;
}
+
+ mpc82xx_enet_pdata[fs_no].dpram_offset=
+ (u32)cpm2_immr->im_dprambase;
+ mpc82xx_enet_pdata[fs_no].fcc_regs_c =
+ (u32)cpm2_immr->im_fcc_c;
+ memcpy(&mpc82xx_enet_pdata[fs_no].macaddr,bi->bi_enetaddr,6);
+
+ /* prevent dup mac */
+ if(fs_no == fsid_fcc2)
+ mpc82xx_enet_pdata[fs_no].macaddr[5] ^= 1;
+
+ pdev->dev.platform_data = &mpc82xx_enet_pdata[fs_no];
}
static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
iounmap(immap);
}
+static void __init mpc8272ads_fixup_mdio_pdata(struct platform_device *pdev,
+ int idx)
+{
+ m82xx_mii_bb_pdata.irq[0] = PHY_INTERRUPT;
+ m82xx_mii_bb_pdata.irq[1] = -1;
+ m82xx_mii_bb_pdata.irq[2] = -1;
+ m82xx_mii_bb_pdata.irq[3] = PHY_INTERRUPT;
+ m82xx_mii_bb_pdata.irq[31] = -1;
+
+
+ m82xx_mii_bb_pdata.mdio_dat.offset =
+ (u32)&cpm2_immr->im_ioport.iop_pdatc;
+
+ m82xx_mii_bb_pdata.mdio_dir.offset =
+ (u32)&cpm2_immr->im_ioport.iop_pdirc;
+
+ m82xx_mii_bb_pdata.mdc_dat.offset =
+ (u32)&cpm2_immr->im_ioport.iop_pdatc;
+
+
+ pdev->dev.platform_data = &m82xx_mii_bb_pdata;
+}
+
static int mpc8272ads_platform_notify(struct device *dev)
{
static const struct platform_notify_dev_map dev_map[] = {
.bus_id = "fsl-cpm-scc:uart",
.rtn = mpc8272ads_fixup_uart_pdata,
},
+ {
+ .bus_id = "fsl-bb-mdio",
+ .rtn = mpc8272ads_fixup_mdio_pdata,
+ },
{
.bus_id = NULL
}
ppc_sys_device_enable(MPC82xx_CPM_SCC4);
#endif
+ ppc_sys_device_enable(MPC82xx_MDIO_BB);
return 0;
}
-/*arch/ppc/platforms/mpc885ads-setup.c
+/*arch/ppc/platforms/mpc866ads-setup.c
*
- * Platform setup for the Freescale mpc885ads board
+ * Platform setup for the Freescale mpc866ads board
*
* Vitaly Bordug <vbordug@ru.mvista.com>
*
- * Copyright 2005 MontaVista Software Inc.
+ * Copyright 2005-2006 MontaVista Software Inc.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
static void setup_smc1_ioports(void);
static void setup_smc2_ioports(void);
-static struct fs_mii_bus_info fec_mii_bus_info = {
- .method = fsmii_fec,
- .id = 0,
-};
-
-static struct fs_mii_bus_info scc_mii_bus_info = {
- .method = fsmii_fixed,
- .id = 0,
- .i.fixed.speed = 10,
- .i.fixed.duplex = 0,
-};
+static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
-static struct fs_platform_info mpc8xx_fec_pdata[] = {
- {
- .rx_ring = 128,
- .tx_ring = 16,
- .rx_copybreak = 240,
+static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
- .use_napi = 1,
- .napi_weight = 17,
+static struct fs_platform_info mpc8xx_enet_pdata[] = {
+ [fsid_fec1] = {
+ .rx_ring = 128,
+ .tx_ring = 16,
+ .rx_copybreak = 240,
- .phy_addr = 15,
- .phy_irq = -1,
+ .use_napi = 1,
+ .napi_weight = 17,
- .use_rmii = 0,
+ .init_ioports = setup_fec1_ioports,
- .bus_info = &fec_mii_bus_info,
- }
-};
+ .bus_id = "0:0f",
+ .has_phy = 1,
+ },
+ [fsid_scc1] = {
+ .rx_ring = 64,
+ .tx_ring = 8,
+ .rx_copybreak = 240,
+ .use_napi = 1,
+ .napi_weight = 17,
-static struct fs_platform_info mpc8xx_scc_pdata = {
- .rx_ring = 64,
- .tx_ring = 8,
- .rx_copybreak = 240,
- .use_napi = 1,
- .napi_weight = 17,
-
- .phy_addr = -1,
- .phy_irq = -1,
-
- .bus_info = &scc_mii_bus_info,
+ .init_ioports = setup_scc1_ioports,
+ .bus_id = "fixed@100:1",
+ },
};
static struct fs_uart_platform_info mpc866_uart_pdata[] = {
}
-static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
-{
- struct fs_platform_info *fpi = pdev->dev.platform_data;
-
- volatile cpm8xx_t *cp;
- bd_t *bd = (bd_t *) __res;
- char *e;
- int i;
-
- /* Get pointer to Communication Processor */
- cp = cpmp;
- switch (fs_no) {
- case fsid_fec1:
- fpi = &mpc8xx_fec_pdata[0];
- fpi->init_ioports = &setup_fec1_ioports;
-
- break;
- case fsid_scc1:
- fpi = &mpc8xx_scc_pdata;
- fpi->init_ioports = &setup_scc1_ioports;
-
- break;
- default:
- printk(KERN_WARNING"Device %s is not supported!\n", pdev->name);
- return;
- }
-
- pdev->dev.platform_data = fpi;
- fpi->fs_no = fs_no;
-
- e = (unsigned char *)&bd->bi_enetaddr;
- for (i = 0; i < 6; i++)
- fpi->macaddr[i] = *e++;
-
- fpi->macaddr[5 - pdev->id]++;
-
-}
-
-static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev,
- int idx)
-{
- /* This is for FEC devices only */
- if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
- return;
- mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
-}
-
-static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
- int idx)
-{
- /* This is for SCC devices only */
- if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
- return;
-
- mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
-}
-
static void setup_smc1_ioports(void)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
}
+static int ma_count = 0;
+
+static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
+{
+ struct fs_platform_info *fpi;
+
+ volatile cpm8xx_t *cp;
+ bd_t *bd = (bd_t *) __res;
+ char *e;
+ int i;
+
+ /* Get pointer to Communication Processor */
+ cp = cpmp;
+
+ if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) {
+ printk(KERN_ERR"No network-suitable #%d device on bus", fs_no);
+ return;
+ }
+
+
+ fpi = &mpc8xx_enet_pdata[fs_no];
+ fpi->fs_no = fs_no;
+ pdev->dev.platform_data = fpi;
+
+ e = (unsigned char *)&bd->bi_enetaddr;
+ for (i = 0; i < 6; i++)
+ fpi->macaddr[i] = *e++;
+
+ fpi->macaddr[5] += ma_count++;
+}
+
+static void mpc866ads_fixup_fec_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for FEC devices only */
+ if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-fec")))
+ return;
+ mpc866ads_fixup_enet_pdata(pdev, fsid_fec1 + pdev->id - 1);
+}
+
+static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
+ int idx)
+{
+ /* This is for SCC devices only */
+ if (!pdev || !pdev->name || (!strstr(pdev->name, "fsl-cpm-scc")))
+ return;
+
+ mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
+}
+
static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev,
int idx)
{
int __init mpc866ads_init(void)
{
+ bd_t *bd = (bd_t *) __res;
+ struct fs_mii_fec_platform_info* fmpi;
+
printk(KERN_NOTICE "mpc866ads: Init\n");
platform_notify = mpc866ads_platform_notify;
ppc_sys_device_initfunc();
ppc_sys_device_disable_all();
-#ifdef MPC8xx_SECOND_ETH_SCC1
+#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC1
ppc_sys_device_enable(MPC8xx_CPM_SCC1);
#endif
ppc_sys_device_enable(MPC8xx_CPM_FEC1);
+ ppc_sys_device_enable(MPC8xx_MDIO_FEC);
+
+ fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data =
+ &mpc8xx_mdio_fec_pdata;
+
+ fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
+ /* No PHY interrupt line here */
+ fmpi->irq[0xf] = -1;
+
/* Since either of the uarts could be used as console, they need to ready */
#ifdef CONFIG_SERIAL_CPM_SMC1
ppc_sys_device_enable(MPC8xx_CPM_SMC1);
ppc_sys_device_enable(MPC8xx_CPM_SMC2);
ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
#endif
+ ppc_sys_device_enable(MPC8xx_MDIO_FEC);
+
+ fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data =
+ &mpc8xx_mdio_fec_pdata;
+
+ fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
+ /* No PHY interrupt line here */
+ fmpi->irq[0xf] = -1;
return 0;
}
static void setup_smc1_ioports(void);
static void setup_smc2_ioports(void);
-static void __init mpc885ads_scc_phy_init(char);
+static struct fs_mii_fec_platform_info mpc8xx_mdio_fec_pdata;
+static void setup_fec1_ioports(void);
+static void setup_fec2_ioports(void);
+static void setup_scc3_ioports(void);
static struct fs_uart_platform_info mpc885_uart_pdata[] = {
[fsid_smc1_uart] = {
},
};
-static struct fs_mii_bus_info fec_mii_bus_info = {
- .method = fsmii_fec,
- .id = 0,
-};
-
-static struct fs_mii_bus_info scc_mii_bus_info = {
-#ifdef CONFIG_SCC_ENET_8xx_FIXED
- .method = fsmii_fixed,
-#else
- .method = fsmii_fec,
-#endif
-
- .id = 0,
-};
-
-static struct fs_platform_info mpc8xx_fec_pdata[] = {
- {
+static struct fs_platform_info mpc8xx_enet_pdata[] = {
+ [fsid_fec1] = {
.rx_ring = 128,
.tx_ring = 16,
.rx_copybreak = 240,
.use_napi = 1,
.napi_weight = 17,
- .phy_addr = 0,
- .phy_irq = SIU_IRQ7,
+ .init_ioports = setup_fec1_ioports,
- .bus_info = &fec_mii_bus_info,
- }, {
+ .bus_id = "0:00",
+ .has_phy = 1,
+ },
+ [fsid_fec2] = {
.rx_ring = 128,
.tx_ring = 16,
.rx_copybreak = 240,
.use_napi = 1,
.napi_weight = 17,
- .phy_addr = 1,
- .phy_irq = SIU_IRQ7,
-
- .bus_info = &fec_mii_bus_info,
- }
-};
+ .init_ioports = setup_fec2_ioports,
-static struct fs_platform_info mpc8xx_scc_pdata = {
- .rx_ring = 64,
- .tx_ring = 8,
- .rx_copybreak = 240,
+ .bus_id = "0:01",
+ .has_phy = 1,
+ },
+ [fsid_scc3] = {
+ .rx_ring = 64,
+ .tx_ring = 8,
+ .rx_copybreak = 240,
- .use_napi = 1,
- .napi_weight = 17,
+ .use_napi = 1,
+ .napi_weight = 17,
- .phy_addr = 2,
-#ifdef CONFIG_MPC8xx_SCC_ENET_FIXED
- .phy_irq = -1,
+ .init_ioports = setup_scc3_ioports,
+#ifdef CONFIG_FIXED_MII_10_FDX
+ .bus_id = "fixed@100:1",
#else
- .phy_irq = SIU_IRQ7,
-#endif
-
- .bus_info = &scc_mii_bus_info,
+ .bus_id = "0:02",
+ #endif
+ },
};
void __init board_init(void)
{
- volatile cpm8xx_t *cp = cpmp;
- unsigned int *bcsr_io;
+ cpm8xx_t *cp = cpmp;
+ unsigned int *bcsr_io;
#ifdef CONFIG_FS_ENET
immap_t *immap = (immap_t *) IMAP_ADDR;
/* use MDC for MII (common) */
setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
+ bcsr_io = ioremap(BCSR5, sizeof(unsigned long));
+ clrbits32(bcsr_io,BCSR5_MII1_EN);
+ clrbits32(bcsr_io,BCSR5_MII1_RST);
+#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
+ clrbits32(bcsr_io,BCSR5_MII2_EN);
+ clrbits32(bcsr_io,BCSR5_MII2_RST);
+#endif
+ iounmap(bcsr_io);
#endif
}
/* configure FEC2 pins */
setbits32(&immap->im_cpm.cp_pepar, 0x0003fffc);
setbits32(&immap->im_cpm.cp_pedir, 0x0003fffc);
- setbits32(&immap->im_cpm.cp_peso, 0x00037800);
clrbits32(&immap->im_cpm.cp_peso, 0x000087fc);
+ setbits32(&immap->im_cpm.cp_peso, 0x00037800);
clrbits32(&immap->im_cpm.cp_cptr, 0x00000080);
}
/* Enable the PHY.
*/
+ clrbits32(bcsr_io+4, BCSR4_ETH10_RST);
+ udelay(1000);
setbits32(bcsr_io+4, BCSR4_ETH10_RST);
/* Configure port A pins for Txd and Rxd.
*/
clrbits32(&immap->im_cpm.cp_pedir, PE_ENET_TENA);
setbits32(&immap->im_cpm.cp_peso, PE_ENET_TENA);
- setbits32(bcsr_io+1, BCSR1_ETHEN);
+ setbits32(bcsr_io+4, BCSR1_ETHEN);
iounmap(bcsr_io);
}
+static int mac_count = 0;
+
static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no)
{
- struct fs_platform_info *fpi = pdev->dev.platform_data;
-
- volatile cpm8xx_t *cp;
+ struct fs_platform_info *fpi;
bd_t *bd = (bd_t *) __res;
char *e;
int i;
- /* Get pointer to Communication Processor */
- cp = cpmp;
+ if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) {
+ printk(KERN_ERR"No network-suitable #%d device on bus", fs_no);
+ return;
+ }
+
+ fpi = &mpc8xx_enet_pdata[fs_no];
+
switch (fs_no) {
case fsid_fec1:
- fpi = &mpc8xx_fec_pdata[0];
fpi->init_ioports = &setup_fec1_ioports;
break;
case fsid_fec2:
- fpi = &mpc8xx_fec_pdata[1];
fpi->init_ioports = &setup_fec2_ioports;
break;
case fsid_scc3:
- fpi = &mpc8xx_scc_pdata;
fpi->init_ioports = &setup_scc3_ioports;
- mpc885ads_scc_phy_init(fpi->phy_addr);
break;
default:
- printk(KERN_WARNING"Device %s is not supported!\n", pdev->name);
+ printk(KERN_WARNING "Device %s is not supported!\n", pdev->name);
return;
}
for (i = 0; i < 6; i++)
fpi->macaddr[i] = *e++;
- fpi->macaddr[5 - pdev->id]++;
+ fpi->macaddr[5] += mac_count++;
}
mpc885ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
}
-/* SCC ethernet controller does not have MII management channel. FEC1 MII
- * channel is used to communicate with the 10Mbit PHY.
- */
-
-#define MII_ECNTRL_PINMUX 0x4
-#define FEC_ECNTRL_PINMUX 0x00000004
-#define FEC_RCNTRL_MII_MODE 0x00000004
-
-/* Make MII read/write commands.
- */
-#define mk_mii_write(REG, VAL, PHY_ADDR) (0x50020000 | (((REG) & 0x1f) << 18) | \
- ((VAL) & 0xffff) | ((PHY_ADDR) << 23))
-
-static void mpc885ads_scc_phy_init(char phy_addr)
-{
- volatile immap_t *immap;
- volatile fec_t *fecp;
- bd_t *bd;
-
- bd = (bd_t *) __res;
- immap = (immap_t *) IMAP_ADDR; /* pointer to internal registers */
- fecp = &(immap->im_cpm.cp_fec);
-
- /* Enable MII pins of the FEC1
- */
- setbits16(&immap->im_ioport.iop_pdpar, 0x0080);
- clrbits16(&immap->im_ioport.iop_pddir, 0x0080);
- /* Set MII speed to 2.5 MHz
- */
- out_be32(&fecp->fec_mii_speed,
- ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1);
-
- /* Enable FEC pin MUX
- */
- setbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
- setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
-
- out_be32(&fecp->fec_mii_data,
- mk_mii_write(MII_BMCR, BMCR_ISOLATE, phy_addr));
- udelay(100);
- out_be32(&fecp->fec_mii_data,
- mk_mii_write(MII_ADVERTISE,
- ADVERTISE_10HALF | ADVERTISE_CSMA, phy_addr));
- udelay(100);
-
- /* Disable FEC MII settings
- */
- clrbits32(&fecp->fec_ecntrl, MII_ECNTRL_PINMUX);
- clrbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
- out_be32(&fecp->fec_mii_speed, 0);
-}
-
static void setup_smc1_ioports(void)
{
immap_t *immap = (immap_t *) IMAP_ADDR;
int __init mpc885ads_init(void)
{
+ struct fs_mii_fec_platform_info* fmpi;
+ bd_t *bd = (bd_t *) __res;
+
printk(KERN_NOTICE "mpc885ads: Init\n");
platform_notify = mpc885ads_platform_notify;
ppc_sys_device_enable(MPC8xx_CPM_FEC1);
+ ppc_sys_device_enable(MPC8xx_MDIO_FEC);
+ fmpi = ppc_sys_platform_devices[MPC8xx_MDIO_FEC].dev.platform_data =
+ &mpc8xx_mdio_fec_pdata;
+
+ fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
+
+ /* No PHY interrupt line here */
+ fmpi->irq[0xf] = SIU_IRQ7;
+
#ifdef CONFIG_MPC8xx_SECOND_ETH_SCC3
- ppc_sys_device_enable(MPC8xx_CPM_SCC1);
+ ppc_sys_device_enable(MPC8xx_CPM_SCC3);
#endif
#ifdef CONFIG_MPC8xx_SECOND_ETH_FEC2
#define F3_RXCLK 13
#define F3_TXCLK 14
-/* Automatically generates register configurations */
-#define PC_CLK(x) ((uint)(1<<(x-1))) /* FCC CLK I/O ports */
-
-#define CMXFCR_RF1CS(x) ((uint)((x-5)<<27)) /* FCC1 Receive Clock Source */
-#define CMXFCR_TF1CS(x) ((uint)((x-5)<<24)) /* FCC1 Transmit Clock Source */
-#define CMXFCR_RF2CS(x) ((uint)((x-9)<<19)) /* FCC2 Receive Clock Source */
-#define CMXFCR_TF2CS(x) ((uint)((x-9)<<16)) /* FCC2 Transmit Clock Source */
-#define CMXFCR_RF3CS(x) ((uint)((x-9)<<11)) /* FCC3 Receive Clock Source */
-#define CMXFCR_TF3CS(x) ((uint)((x-9)<<8)) /* FCC3 Transmit Clock Source */
-
-#define PC_F1RXCLK PC_CLK(F1_RXCLK)
-#define PC_F1TXCLK PC_CLK(F1_TXCLK)
-#define CMX1_CLK_ROUTE (CMXFCR_RF1CS(F1_RXCLK) | CMXFCR_TF1CS(F1_TXCLK))
-#define CMX1_CLK_MASK ((uint)0xff000000)
-
-#define PC_F2RXCLK PC_CLK(F2_RXCLK)
-#define PC_F2TXCLK PC_CLK(F2_TXCLK)
-#define CMX2_CLK_ROUTE (CMXFCR_RF2CS(F2_RXCLK) | CMXFCR_TF2CS(F2_TXCLK))
-#define CMX2_CLK_MASK ((uint)0x00ff0000)
-
-#define PC_F3RXCLK PC_CLK(F3_RXCLK)
-#define PC_F3TXCLK PC_CLK(F3_TXCLK)
-#define CMX3_CLK_ROUTE (CMXFCR_RF3CS(F3_RXCLK) | CMXFCR_TF3CS(F3_TXCLK))
-#define CMX3_CLK_MASK ((uint)0x0000ff00)
-
-/* I/O Pin assignment for FCC1. I don't yet know the best way to do this,
- * but there is little variation among the choices.
- */
-#define PA1_COL 0x00000001U
-#define PA1_CRS 0x00000002U
-#define PA1_TXER 0x00000004U
-#define PA1_TXEN 0x00000008U
-#define PA1_RXDV 0x00000010U
-#define PA1_RXER 0x00000020U
-#define PA1_TXDAT 0x00003c00U
-#define PA1_RXDAT 0x0003c000U
-#define PA1_PSORA0 (PA1_RXDAT | PA1_TXDAT)
-#define PA1_PSORA1 (PA1_COL | PA1_CRS | PA1_TXER | PA1_TXEN | \
- PA1_RXDV | PA1_RXER)
-#define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV)
-#define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER)
-
-
-/* I/O Pin assignment for FCC2. I don't yet know the best way to do this,
- * but there is little variation among the choices.
- */
-#define PB2_TXER 0x00000001U
-#define PB2_RXDV 0x00000002U
-#define PB2_TXEN 0x00000004U
-#define PB2_RXER 0x00000008U
-#define PB2_COL 0x00000010U
-#define PB2_CRS 0x00000020U
-#define PB2_TXDAT 0x000003c0U
-#define PB2_RXDAT 0x00003c00U
-#define PB2_PSORB0 (PB2_RXDAT | PB2_TXDAT | PB2_CRS | PB2_COL | \
- PB2_RXER | PB2_RXDV | PB2_TXER)
-#define PB2_PSORB1 (PB2_TXEN)
-#define PB2_DIRB0 (PB2_RXDAT | PB2_CRS | PB2_COL | PB2_RXER | PB2_RXDV)
-#define PB2_DIRB1 (PB2_TXDAT | PB2_TXEN | PB2_TXER)
-
-
-/* I/O Pin assignment for FCC3. I don't yet know the best way to do this,
- * but there is little variation among the choices.
- */
-#define PB3_RXDV 0x00004000U
-#define PB3_RXER 0x00008000U
-#define PB3_TXER 0x00010000U
-#define PB3_TXEN 0x00020000U
-#define PB3_COL 0x00040000U
-#define PB3_CRS 0x00080000U
-#define PB3_TXDAT 0x0f000000U
-#define PB3_RXDAT 0x00f00000U
-#define PB3_PSORB0 (PB3_RXDAT | PB3_TXDAT | PB3_CRS | PB3_COL | \
- PB3_RXER | PB3_RXDV | PB3_TXER | PB3_TXEN)
-#define PB3_PSORB1 0
-#define PB3_DIRB0 (PB3_RXDAT | PB3_CRS | PB3_COL | PB3_RXER | PB3_RXDV)
-#define PB3_DIRB1 (PB3_TXDAT | PB3_TXEN | PB3_TXER)
-
-#define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128))
-#define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0)
-#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1)
-
#endif
#include <linux/device.h>
#include <linux/serial_8250.h>
#include <linux/fsl_devices.h>
+#include <linux/fs_enet_pd.h>
#include <asm/mpc85xx.h>
#include <asm/irq.h>
#include <asm/ppc_sys.h>
+#include <asm/cpm2.h>
/* We use offsets for IORESOURCE_MEM since we do not know at compile time
* what CCSRBAR is, will get fixed up by mach_mpc85xx_fixup
.device_flags = FSL_I2C_DEV_SEPARATE_DFSRR,
};
+static struct fs_platform_info mpc85xx_fcc1_pdata = {
+ .fs_no = fsid_fcc1,
+ .cp_page = CPM_CR_FCC1_PAGE,
+ .cp_block = CPM_CR_FCC1_SBLOCK,
+
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+
+ .clk_mask = CMX1_CLK_MASK,
+ .clk_route = CMX1_CLK_ROUTE,
+ .clk_trx = (PC_F1RXCLK | PC_F1TXCLK),
+
+ .mem_offset = FCC1_MEM_OFFSET,
+};
+
+static struct fs_platform_info mpc85xx_fcc2_pdata = {
+ .fs_no = fsid_fcc2,
+ .cp_page = CPM_CR_FCC2_PAGE,
+ .cp_block = CPM_CR_FCC2_SBLOCK,
+
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+
+ .clk_mask = CMX2_CLK_MASK,
+ .clk_route = CMX2_CLK_ROUTE,
+ .clk_trx = (PC_F2RXCLK | PC_F2TXCLK),
+
+ .mem_offset = FCC2_MEM_OFFSET,
+};
+
+static struct fs_platform_info mpc85xx_fcc3_pdata = {
+ .fs_no = fsid_fcc3,
+ .cp_page = CPM_CR_FCC3_PAGE,
+ .cp_block = CPM_CR_FCC3_SBLOCK,
+
+ .rx_ring = 32,
+ .tx_ring = 32,
+ .rx_copybreak = 240,
+ .use_napi = 0,
+ .napi_weight = 17,
+
+ .clk_mask = CMX3_CLK_MASK,
+ .clk_route = CMX3_CLK_ROUTE,
+ .clk_trx = (PC_F3RXCLK | PC_F3TXCLK),
+
+ .mem_offset = FCC3_MEM_OFFSET,
+};
+
static struct plat_serial8250_port serial_platform_data[] = {
[0] = {
.mapbase = 0x4500,
[MPC85xx_CPM_FCC1] = {
.name = "fsl-cpm-fcc",
.id = 1,
- .num_resources = 3,
+ .num_resources = 4,
+ .dev.platform_data = &mpc85xx_fcc1_pdata,
.resource = (struct resource[]) {
{
+ .name = "fcc_regs",
.start = 0x91300,
.end = 0x9131F,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_regs_c",
.start = 0x91380,
.end = 0x9139F,
.flags = IORESOURCE_MEM,
},
+ {
+ .name = "fcc_pram",
+ .start = 0x88400,
+ .end = 0x884ff,
+ .flags = IORESOURCE_MEM,
+ },
{
.start = SIU_INT_FCC1,
.end = SIU_INT_FCC1,
[MPC85xx_CPM_FCC2] = {
.name = "fsl-cpm-fcc",
.id = 2,
- .num_resources = 3,
+ .num_resources = 4,
+ .dev.platform_data = &mpc85xx_fcc2_pdata,
.resource = (struct resource[]) {
{
+ .name = "fcc_regs",
.start = 0x91320,
.end = 0x9133F,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_regs_c",
.start = 0x913A0,
.end = 0x913CF,
.flags = IORESOURCE_MEM,
},
+ {
+ .name = "fcc_pram",
+ .start = 0x88500,
+ .end = 0x885ff,
+ .flags = IORESOURCE_MEM,
+ },
{
.start = SIU_INT_FCC2,
.end = SIU_INT_FCC2,
[MPC85xx_CPM_FCC3] = {
.name = "fsl-cpm-fcc",
.id = 3,
- .num_resources = 3,
+ .num_resources = 4,
+ .dev.platform_data = &mpc85xx_fcc3_pdata,
.resource = (struct resource[]) {
{
+ .name = "fcc_regs",
.start = 0x91340,
.end = 0x9135F,
.flags = IORESOURCE_MEM,
},
{
+ .name = "fcc_regs_c",
.start = 0x913D0,
.end = 0x913FF,
.flags = IORESOURCE_MEM,
},
+ {
+ .name = "fcc_pram",
+ .start = 0x88600,
+ .end = 0x886ff,
+ .flags = IORESOURCE_MEM,
+ },
{
.start = SIU_INT_FCC3,
.end = SIU_INT_FCC3,
},
},
},
+
+ [MPC8xx_MDIO_FEC] = {
+ .name = "fsl-cpm-fec-mdio",
+ .id = 0,
+ .num_resources = 0,
+
+ },
+
};
static int __init mach_mpc8xx_fixup(struct platform_device *pdev)
.ppc_sys_name = "MPC86X",
.mask = 0xFFFFFFFF,
.value = 0x00000000,
- .num_devices = 7,
+ .num_devices = 8,
.device_list = (enum ppc_sys_devices[])
{
MPC8xx_CPM_FEC1,
MPC8xx_CPM_SCC4,
MPC8xx_CPM_SMC1,
MPC8xx_CPM_SMC2,
+ MPC8xx_MDIO_FEC,
},
},
{
.ppc_sys_name = "MPC885",
.mask = 0xFFFFFFFF,
.value = 0x00000000,
- .num_devices = 8,
+ .num_devices = 9,
.device_list = (enum ppc_sys_devices[])
{
MPC8xx_CPM_FEC1,
MPC8xx_CPM_SCC4,
MPC8xx_CPM_SMC1,
MPC8xx_CPM_SMC2,
+ MPC8xx_MDIO_FEC,
},
},
{ /* default match */
},
},
},
+ [MPC82xx_MDIO_BB] = {
+ .name = "fsl-bb-mdio",
+ .id = 0,
+ .num_resources = 0,
+ },
};
static int __init mach_mpc82xx_fixup(struct platform_device *pdev)
.ppc_sys_name = "8272",
.mask = 0x0000ff00,
.value = 0x00000c00,
- .num_devices = 12,
+ .num_devices = 13,
.device_list = (enum ppc_sys_devices[])
{
MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1,
+ MPC82xx_MDIO_BB,
},
},
/* below is a list of the 8280 family of processors */
}
#ifdef CONFIG_HOTPLUG_CPU
-static int
+static int __cpuinit
appldata_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
/*
* pg_table is physical at this point
*/
- pg_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
pg_dir->pgd0 = (_PAGE_TABLE | __pa(pg_table));
pg_dir->pgd1 = (_PAGE_TABLE | (__pa(pg_table)+1024));
continue;
}
- pm_dir = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE*4);
+ pm_dir = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE * 4);
pgd_populate(&init_mm, pg_dir, pm_dir);
for (j = 0 ; j < PTRS_PER_PMD ; j++,pm_dir++) {
continue;
}
- pt_dir = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ pt_dir = (pte_t *) alloc_bootmem_pages(PAGE_SIZE);
pmd_populate_kernel(&init_mm, pm_dir, pt_dir);
for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) {
init_mm.context = (unsigned long) NO_CONTEXT;
init_task.thread.kregs = &fake_swapper_regs;
- smp_setup_cpu_possible_map();
-
paging_init();
+
+ smp_setup_cpu_possible_map();
}
static int __init set_preferred_console(void)