提交 25da0974 编写于 作者: L Len Brown

Auto-update from upstream

要显示的变更太多。

To preserve performance only 1000 of 1000+ files are displayed.
...@@ -23,6 +23,7 @@ Module.symvers ...@@ -23,6 +23,7 @@ Module.symvers
# Generated include files # Generated include files
# #
include/asm include/asm
include/asm-*/asm-offsets.h
include/config include/config
include/linux/autoconf.h include/linux/autoconf.h
include/linux/compile.h include/linux/compile.h
......
...@@ -1883,6 +1883,7 @@ N: Jaya Kumar ...@@ -1883,6 +1883,7 @@ N: Jaya Kumar
E: jayalk@intworks.biz E: jayalk@intworks.biz
W: http://www.intworks.biz W: http://www.intworks.biz
D: Arc monochrome LCD framebuffer driver, x86 reboot fixups D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
D: pirq addr, CS5535 alsa audio driver
S: Gurgaon, India S: Gurgaon, India
S: Kuala Lumpur, Malaysia S: Kuala Lumpur, Malaysia
......
...@@ -253,6 +253,7 @@ ...@@ -253,6 +253,7 @@
!Edrivers/usb/core/urb.c !Edrivers/usb/core/urb.c
!Edrivers/usb/core/message.c !Edrivers/usb/core/message.c
!Edrivers/usb/core/file.c !Edrivers/usb/core/file.c
!Edrivers/usb/core/driver.c
!Edrivers/usb/core/usb.c !Edrivers/usb/core/usb.c
!Edrivers/usb/core/hub.c !Edrivers/usb/core/hub.c
</chapter> </chapter>
......
...@@ -158,7 +158,7 @@ Even if the maintainer did not respond in step #4, make sure to ALWAYS ...@@ -158,7 +158,7 @@ Even if the maintainer did not respond in step #4, make sure to ALWAYS
copy the maintainer when you change their code. copy the maintainer when you change their code.
For small patches you may want to CC the Trivial Patch Monkey For small patches you may want to CC the Trivial Patch Monkey
trivial@rustcorp.com.au set up by Rusty Russell; which collects "trivial" trivial@kernel.org managed by Adrian Bunk; which collects "trivial"
patches. Trivial patches must qualify for one of the following rules: patches. Trivial patches must qualify for one of the following rules:
Spelling fixes in documentation Spelling fixes in documentation
Spelling fixes which could break grep(1). Spelling fixes which could break grep(1).
...@@ -171,7 +171,7 @@ patches. Trivial patches must qualify for one of the following rules: ...@@ -171,7 +171,7 @@ patches. Trivial patches must qualify for one of the following rules:
since people copy, as long as it's trivial) since people copy, as long as it's trivial)
Any fix by the author/maintainer of the file. (ie. patch monkey Any fix by the author/maintainer of the file. (ie. patch monkey
in re-transmission mode) in re-transmission mode)
URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/> URL: <http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/>
......
...@@ -31,7 +31,7 @@ The following people helped with review comments and inputs for this ...@@ -31,7 +31,7 @@ The following people helped with review comments and inputs for this
document: document:
Christoph Hellwig <hch@infradead.org> Christoph Hellwig <hch@infradead.org>
Arjan van de Ven <arjanv@redhat.com> Arjan van de Ven <arjanv@redhat.com>
Randy Dunlap <rddunlap@osdl.org> Randy Dunlap <rdunlap@xenotime.net>
Andre Hedrick <andre@linux-ide.org> Andre Hedrick <andre@linux-ide.org>
The following people helped with fixes/contributions to the bio patches The following people helped with fixes/contributions to the bio patches
...@@ -263,14 +263,8 @@ A flag in the bio structure, BIO_BARRIER is used to identify a barrier i/o. ...@@ -263,14 +263,8 @@ A flag in the bio structure, BIO_BARRIER is used to identify a barrier i/o.
The generic i/o scheduler would make sure that it places the barrier request and The generic i/o scheduler would make sure that it places the barrier request and
all other requests coming after it after all the previous requests in the all other requests coming after it after all the previous requests in the
queue. Barriers may be implemented in different ways depending on the queue. Barriers may be implemented in different ways depending on the
driver. A SCSI driver for example could make use of ordered tags to driver. For more details regarding I/O barriers, please read barrier.txt
preserve the necessary ordering with a lower impact on throughput. For IDE in this directory.
this might be two sync cache flush: a pre and post flush when encountering
a barrier write.
There is a provision for queues to indicate what kind of barriers they
can provide. This is as of yet unmerged, details will be added here once it
is in the kernel.
1.2.2 Request Priority/Latency 1.2.2 Request Priority/Latency
......
...@@ -27,6 +27,7 @@ Contents: ...@@ -27,6 +27,7 @@ Contents:
2.2 Powersave 2.2 Powersave
2.3 Userspace 2.3 Userspace
2.4 Ondemand 2.4 Ondemand
2.5 Conservative
3. The Governor Interface in the CPUfreq Core 3. The Governor Interface in the CPUfreq Core
...@@ -110,9 +111,64 @@ directory. ...@@ -110,9 +111,64 @@ directory.
The CPUfreq govenor "ondemand" sets the CPU depending on the The CPUfreq govenor "ondemand" sets the CPU depending on the
current usage. To do this the CPU must have the capability to current usage. To do this the CPU must have the capability to
switch the frequency very fast. switch the frequency very quickly. There are a number of sysfs file
accessible parameters:
sampling_rate: measured in uS (10^-6 seconds), this is how often you
want the kernel to look at the CPU usage and to make decisions on
what to do about the frequency. Typically this is set to values of
around '10000' or more.
show_sampling_rate_(min|max): the minimum and maximum sampling rates
available that you may set 'sampling_rate' to.
up_threshold: defines what the average CPU usaged between the samplings
of 'sampling_rate' needs to be for the kernel to make a decision on
whether it should increase the frequency. For example when it is set
to its default value of '80' it means that between the checking
intervals the CPU needs to be on average more than 80% in use to then
decide that the CPU frequency needs to be increased.
sampling_down_factor: this parameter controls the rate that the CPU
makes a decision on when to decrease the frequency. When set to its
default value of '5' it means that at 1/5 the sampling_rate the kernel
makes a decision to lower the frequency. Five "lower rate" decisions
have to be made in a row before the CPU frequency is actually lower.
If set to '1' then the frequency decreases as quickly as it increases,
if set to '2' it decreases at half the rate of the increase.
ignore_nice_load: this parameter takes a value of '0' or '1', when set
to '0' (its default) then all processes are counted towards towards the
'cpu utilisation' value. When set to '1' then processes that are
run with a 'nice' value will not count (and thus be ignored) in the
overal usage calculation. This is useful if you are running a CPU
intensive calculation on your laptop that you do not care how long it
takes to complete as you can 'nice' it and prevent it from taking part
in the deciding process of whether to increase your CPU frequency.
2.5 Conservative
----------------
The CPUfreq governor "conservative", much like the "ondemand"
governor, sets the CPU depending on the current usage. It differs in
behaviour in that it gracefully increases and decreases the CPU speed
rather than jumping to max speed the moment there is any load on the
CPU. This behaviour more suitable in a battery powered environment.
The governor is tweaked in the same manner as the "ondemand" governor
through sysfs with the addition of:
freq_step: this describes what percentage steps the cpu freq should be
increased and decreased smoothly by. By default the cpu frequency will
increase in 5% chunks of your maximum cpu frequency. You can change this
value to anywhere between 0 and 100 where '0' will effectively lock your
CPU at a speed regardless of its load whilst '100' will, in theory, make
it behave identically to the "ondemand" governor.
down_threshold: same as the 'up_threshold' found for the "ondemand"
governor but for the opposite direction. For example when set to its
default value of '20' it means that if the CPU usage needs to be below
20% between samples to have the frequency decreased.
3. The Governor Interface in the CPUfreq Core 3. The Governor Interface in the CPUfreq Core
============================================= =============================================
......
...@@ -47,17 +47,6 @@ Who: Paul E. McKenney <paulmck@us.ibm.com> ...@@ -47,17 +47,6 @@ Who: Paul E. McKenney <paulmck@us.ibm.com>
--------------------------- ---------------------------
What: IEEE1394 Audio and Music Data Transmission Protocol driver,
Connection Management Procedures driver
When: November 2005
Files: drivers/ieee1394/{amdtp,cmp}*
Why: These are incomplete, have never worked, and are better implemented
in userland via raw1394 (see http://freebob.sourceforge.net/ for
example.)
Who: Jody McIntyre <scjody@steamballoon.com>
---------------------------
What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
When: November 2005 When: November 2005
Why: Deprecated in favour of the new ioctl-based rawiso interface, which is Why: Deprecated in favour of the new ioctl-based rawiso interface, which is
......
...@@ -12,14 +12,16 @@ cifs.txt ...@@ -12,14 +12,16 @@ cifs.txt
- description of the CIFS filesystem - description of the CIFS filesystem
coda.txt coda.txt
- description of the CODA filesystem. - description of the CODA filesystem.
configfs/
- directory containing configfs documentation and example code.
cramfs.txt cramfs.txt
- info on the cram filesystem for small storage (ROMs etc) - info on the cram filesystem for small storage (ROMs etc)
devfs/ devfs/
- directory containing devfs documentation. - directory containing devfs documentation.
dlmfs.txt
- info on the userspace interface to the OCFS2 DLM.
ext2.txt ext2.txt
- info, mount options and specifications for the Ext2 filesystem. - info, mount options and specifications for the Ext2 filesystem.
fat_cvf.txt
- info on the Compressed Volume Files extension to the FAT filesystem
hpfs.txt hpfs.txt
- info and mount options for the OS/2 HPFS. - info and mount options for the OS/2 HPFS.
isofs.txt isofs.txt
...@@ -32,6 +34,8 @@ ntfs.txt ...@@ -32,6 +34,8 @@ ntfs.txt
- info and mount options for the NTFS filesystem (Windows NT). - info and mount options for the NTFS filesystem (Windows NT).
proc.txt proc.txt
- info on Linux's /proc filesystem. - info on Linux's /proc filesystem.
ocfs2.txt
- info and mount options for the OCFS2 clustered filesystem.
romfs.txt romfs.txt
- Description of the ROMFS filesystem. - Description of the ROMFS filesystem.
smbfs.txt smbfs.txt
......
configfs - Userspace-driven kernel object configuation.
Joel Becker <joel.becker@oracle.com>
Updated: 31 March 2005
Copyright (c) 2005 Oracle Corporation,
Joel Becker <joel.becker@oracle.com>
[What is configfs?]
configfs is a ram-based filesystem that provides the converse of
sysfs's functionality. Where sysfs is a filesystem-based view of
kernel objects, configfs is a filesystem-based manager of kernel
objects, or config_items.
With sysfs, an object is created in kernel (for example, when a device
is discovered) and it is registered with sysfs. Its attributes then
appear in sysfs, allowing userspace to read the attributes via
readdir(3)/read(2). It may allow some attributes to be modified via
write(2). The important point is that the object is created and
destroyed in kernel, the kernel controls the lifecycle of the sysfs
representation, and sysfs is merely a window on all this.
A configfs config_item is created via an explicit userspace operation:
mkdir(2). It is destroyed via rmdir(2). The attributes appear at
mkdir(2) time, and can be read or modified via read(2) and write(2).
As with sysfs, readdir(3) queries the list of items and/or attributes.
symlink(2) can be used to group items together. Unlike sysfs, the
lifetime of the representation is completely driven by userspace. The
kernel modules backing the items must respond to this.
Both sysfs and configfs can and should exist together on the same
system. One is not a replacement for the other.
[Using configfs]
configfs can be compiled as a module or into the kernel. You can access
it by doing
mount -t configfs none /config
The configfs tree will be empty unless client modules are also loaded.
These are modules that register their item types with configfs as
subsystems. Once a client subsystem is loaded, it will appear as a
subdirectory (or more than one) under /config. Like sysfs, the
configfs tree is always there, whether mounted on /config or not.
An item is created via mkdir(2). The item's attributes will also
appear at this time. readdir(3) can determine what the attributes are,
read(2) can query their default values, and write(2) can store new
values. Like sysfs, attributes should be ASCII text files, preferably
with only one value per file. The same efficiency caveats from sysfs
apply. Don't mix more than one attribute in one attribute file.
Like sysfs, configfs expects write(2) to store the entire buffer at
once. When writing to configfs attributes, userspace processes should
first read the entire file, modify the portions they wish to change, and
then write the entire buffer back. Attribute files have a maximum size
of one page (PAGE_SIZE, 4096 on i386).
When an item needs to be destroyed, remove it with rmdir(2). An
item cannot be destroyed if any other item has a link to it (via
symlink(2)). Links can be removed via unlink(2).
[Configuring FakeNBD: an Example]
Imagine there's a Network Block Device (NBD) driver that allows you to
access remote block devices. Call it FakeNBD. FakeNBD uses configfs
for its configuration. Obviously, there will be a nice program that
sysadmins use to configure FakeNBD, but somehow that program has to tell
the driver about it. Here's where configfs comes in.
When the FakeNBD driver is loaded, it registers itself with configfs.
readdir(3) sees this just fine:
# ls /config
fakenbd
A fakenbd connection can be created with mkdir(2). The name is
arbitrary, but likely the tool will make some use of the name. Perhaps
it is a uuid or a disk name:
# mkdir /config/fakenbd/disk1
# ls /config/fakenbd/disk1
target device rw
The target attribute contains the IP address of the server FakeNBD will
connect to. The device attribute is the device on the server.
Predictably, the rw attribute determines whether the connection is
read-only or read-write.
# echo 10.0.0.1 > /config/fakenbd/disk1/target
# echo /dev/sda1 > /config/fakenbd/disk1/device
# echo 1 > /config/fakenbd/disk1/rw
That's it. That's all there is. Now the device is configured, via the
shell no less.
[Coding With configfs]
Every object in configfs is a config_item. A config_item reflects an
object in the subsystem. It has attributes that match values on that
object. configfs handles the filesystem representation of that object
and its attributes, allowing the subsystem to ignore all but the
basic show/store interaction.
Items are created and destroyed inside a config_group. A group is a
collection of items that share the same attributes and operations.
Items are created by mkdir(2) and removed by rmdir(2), but configfs
handles that. The group has a set of operations to perform these tasks
A subsystem is the top level of a client module. During initialization,
the client module registers the subsystem with configfs, the subsystem
appears as a directory at the top of the configfs filesystem. A
subsystem is also a config_group, and can do everything a config_group
can.
[struct config_item]
struct config_item {
char *ci_name;
char ci_namebuf[UOBJ_NAME_LEN];
struct kref ci_kref;
struct list_head ci_entry;
struct config_item *ci_parent;
struct config_group *ci_group;
struct config_item_type *ci_type;
struct dentry *ci_dentry;
};
void config_item_init(struct config_item *);
void config_item_init_type_name(struct config_item *,
const char *name,
struct config_item_type *type);
struct config_item *config_item_get(struct config_item *);
void config_item_put(struct config_item *);
Generally, struct config_item is embedded in a container structure, a
structure that actually represents what the subsystem is doing. The
config_item portion of that structure is how the object interacts with
configfs.
Whether statically defined in a source file or created by a parent
config_group, a config_item must have one of the _init() functions
called on it. This initializes the reference count and sets up the
appropriate fields.
All users of a config_item should have a reference on it via
config_item_get(), and drop the reference when they are done via
config_item_put().
By itself, a config_item cannot do much more than appear in configfs.
Usually a subsystem wants the item to display and/or store attributes,
among other things. For that, it needs a type.
[struct config_item_type]
struct configfs_item_operations {
void (*release)(struct config_item *);
ssize_t (*show_attribute)(struct config_item *,
struct configfs_attribute *,
char *);
ssize_t (*store_attribute)(struct config_item *,
struct configfs_attribute *,
const char *, size_t);
int (*allow_link)(struct config_item *src,
struct config_item *target);
int (*drop_link)(struct config_item *src,
struct config_item *target);
};
struct config_item_type {
struct module *ct_owner;
struct configfs_item_operations *ct_item_ops;
struct configfs_group_operations *ct_group_ops;
struct configfs_attribute **ct_attrs;
};
The most basic function of a config_item_type is to define what
operations can be performed on a config_item. All items that have been
allocated dynamically will need to provide the ct_item_ops->release()
method. This method is called when the config_item's reference count
reaches zero. Items that wish to display an attribute need to provide
the ct_item_ops->show_attribute() method. Similarly, storing a new
attribute value uses the store_attribute() method.
[struct configfs_attribute]
struct configfs_attribute {
char *ca_name;
struct module *ca_owner;
mode_t ca_mode;
};
When a config_item wants an attribute to appear as a file in the item's
configfs directory, it must define a configfs_attribute describing it.
It then adds the attribute to the NULL-terminated array
config_item_type->ct_attrs. When the item appears in configfs, the
attribute file will appear with the configfs_attribute->ca_name
filename. configfs_attribute->ca_mode specifies the file permissions.
If an attribute is readable and the config_item provides a
ct_item_ops->show_attribute() method, that method will be called
whenever userspace asks for a read(2) on the attribute. The converse
will happen for write(2).
[struct config_group]
A config_item cannot live in a vaccum. The only way one can be created
is via mkdir(2) on a config_group. This will trigger creation of a
child item.
struct config_group {
struct config_item cg_item;
struct list_head cg_children;
struct configfs_subsystem *cg_subsys;
struct config_group **default_groups;
};
void config_group_init(struct config_group *group);
void config_group_init_type_name(struct config_group *group,
const char *name,
struct config_item_type *type);
The config_group structure contains a config_item. Properly configuring
that item means that a group can behave as an item in its own right.
However, it can do more: it can create child items or groups. This is
accomplished via the group operations specified on the group's
config_item_type.
struct configfs_group_operations {
struct config_item *(*make_item)(struct config_group *group,
const char *name);
struct config_group *(*make_group)(struct config_group *group,
const char *name);
int (*commit_item)(struct config_item *item);
void (*drop_item)(struct config_group *group,
struct config_item *item);
};
A group creates child items by providing the
ct_group_ops->make_item() method. If provided, this method is called from mkdir(2) in the group's directory. The subsystem allocates a new
config_item (or more likely, its container structure), initializes it,
and returns it to configfs. Configfs will then populate the filesystem
tree to reflect the new item.
If the subsystem wants the child to be a group itself, the subsystem
provides ct_group_ops->make_group(). Everything else behaves the same,
using the group _init() functions on the group.
Finally, when userspace calls rmdir(2) on the item or group,
ct_group_ops->drop_item() is called. As a config_group is also a
config_item, it is not necessary for a seperate drop_group() method.
The subsystem must config_item_put() the reference that was initialized
upon item allocation. If a subsystem has no work to do, it may omit
the ct_group_ops->drop_item() method, and configfs will call
config_item_put() on the item on behalf of the subsystem.
IMPORTANT: drop_item() is void, and as such cannot fail. When rmdir(2)
is called, configfs WILL remove the item from the filesystem tree
(assuming that it has no children to keep it busy). The subsystem is
responsible for responding to this. If the subsystem has references to
the item in other threads, the memory is safe. It may take some time
for the item to actually disappear from the subsystem's usage. But it
is gone from configfs.
A config_group cannot be removed while it still has child items. This
is implemented in the configfs rmdir(2) code. ->drop_item() will not be
called, as the item has not been dropped. rmdir(2) will fail, as the
directory is not empty.
[struct configfs_subsystem]
A subsystem must register itself, ususally at module_init time. This
tells configfs to make the subsystem appear in the file tree.
struct configfs_subsystem {
struct config_group su_group;
struct semaphore su_sem;
};
int configfs_register_subsystem(struct configfs_subsystem *subsys);
void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
A subsystem consists of a toplevel config_group and a semaphore.
The group is where child config_items are created. For a subsystem,
this group is usually defined statically. Before calling
configfs_register_subsystem(), the subsystem must have initialized the
group via the usual group _init() functions, and it must also have
initialized the semaphore.
When the register call returns, the subsystem is live, and it
will be visible via configfs. At that point, mkdir(2) can be called and
the subsystem must be ready for it.
[An Example]
The best example of these basic concepts is the simple_children
subsystem/group and the simple_child item in configfs_example.c It
shows a trivial object displaying and storing an attribute, and a simple
group creating and destroying these children.
[Hierarchy Navigation and the Subsystem Semaphore]
There is an extra bonus that configfs provides. The config_groups and
config_items are arranged in a hierarchy due to the fact that they
appear in a filesystem. A subsystem is NEVER to touch the filesystem
parts, but the subsystem might be interested in this hierarchy. For
this reason, the hierarchy is mirrored via the config_group->cg_children
and config_item->ci_parent structure members.
A subsystem can navigate the cg_children list and the ci_parent pointer
to see the tree created by the subsystem. This can race with configfs'
management of the hierarchy, so configfs uses the subsystem semaphore to
protect modifications. Whenever a subsystem wants to navigate the
hierarchy, it must do so under the protection of the subsystem
semaphore.
A subsystem will be prevented from acquiring the semaphore while a newly
allocated item has not been linked into this hierarchy. Similarly, it
will not be able to acquire the semaphore while a dropping item has not
yet been unlinked. This means that an item's ci_parent pointer will
never be NULL while the item is in configfs, and that an item will only
be in its parent's cg_children list for the same duration. This allows
a subsystem to trust ci_parent and cg_children while they hold the
semaphore.
[Item Aggregation Via symlink(2)]
configfs provides a simple group via the group->item parent/child
relationship. Often, however, a larger environment requires aggregation
outside of the parent/child connection. This is implemented via
symlink(2).
A config_item may provide the ct_item_ops->allow_link() and
ct_item_ops->drop_link() methods. If the ->allow_link() method exists,
symlink(2) may be called with the config_item as the source of the link.
These links are only allowed between configfs config_items. Any
symlink(2) attempt outside the configfs filesystem will be denied.
When symlink(2) is called, the source config_item's ->allow_link()
method is called with itself and a target item. If the source item
allows linking to target item, it returns 0. A source item may wish to
reject a link if it only wants links to a certain type of object (say,
in its own subsystem).
When unlink(2) is called on the symbolic link, the source item is
notified via the ->drop_link() method. Like the ->drop_item() method,
this is a void function and cannot return failure. The subsystem is
responsible for responding to the change.
A config_item cannot be removed while it links to any other item, nor
can it be removed while an item links to it. Dangling symlinks are not
allowed in configfs.
[Automatically Created Subgroups]
A new config_group may want to have two types of child config_items.
While this could be codified by magic names in ->make_item(), it is much
more explicit to have a method whereby userspace sees this divergence.
Rather than have a group where some items behave differently than
others, configfs provides a method whereby one or many subgroups are
automatically created inside the parent at its creation. Thus,
mkdir("parent) results in "parent", "parent/subgroup1", up through
"parent/subgroupN". Items of type 1 can now be created in
"parent/subgroup1", and items of type N can be created in
"parent/subgroupN".
These automatic subgroups, or default groups, do not preclude other
children of the parent group. If ct_group_ops->make_group() exists,
other child groups can be created on the parent group directly.
A configfs subsystem specifies default groups by filling in the
NULL-terminated array default_groups on the config_group structure.
Each group in that array is populated in the configfs tree at the same
time as the parent group. Similarly, they are removed at the same time
as the parent. No extra notification is provided. When a ->drop_item()
method call notifies the subsystem the parent group is going away, it
also means every default group child associated with that parent group.
As a consequence of this, default_groups cannot be removed directly via
rmdir(2). They also are not considered when rmdir(2) on the parent
group is checking for children.
[Committable Items]
NOTE: Committable items are currently unimplemented.
Some config_items cannot have a valid initial state. That is, no
default values can be specified for the item's attributes such that the
item can do its work. Userspace must configure one or more attributes,
after which the subsystem can start whatever entity this item
represents.
Consider the FakeNBD device from above. Without a target address *and*
a target device, the subsystem has no idea what block device to import.
The simple example assumes that the subsystem merely waits until all the
appropriate attributes are configured, and then connects. This will,
indeed, work, but now every attribute store must check if the attributes
are initialized. Every attribute store must fire off the connection if
that condition is met.
Far better would be an explicit action notifying the subsystem that the
config_item is ready to go. More importantly, an explicit action allows
the subsystem to provide feedback as to whether the attibutes are
initialized in a way that makes sense. configfs provides this as
committable items.
configfs still uses only normal filesystem operations. An item is
committed via rename(2). The item is moved from a directory where it
can be modified to a directory where it cannot.
Any group that provides the ct_group_ops->commit_item() method has
committable items. When this group appears in configfs, mkdir(2) will
not work directly in the group. Instead, the group will have two
subdirectories: "live" and "pending". The "live" directory does not
support mkdir(2) or rmdir(2) either. It only allows rename(2). The
"pending" directory does allow mkdir(2) and rmdir(2). An item is
created in the "pending" directory. Its attributes can be modified at
will. Userspace commits the item by renaming it into the "live"
directory. At this point, the subsystem recieves the ->commit_item()
callback. If all required attributes are filled to satisfaction, the
method returns zero and the item is moved to the "live" directory.
As rmdir(2) does not work in the "live" directory, an item must be
shutdown, or "uncommitted". Again, this is done via rename(2), this
time from the "live" directory back to the "pending" one. The subsystem
is notified by the ct_group_ops->uncommit_object() method.
/*
* vim: noexpandtab ts=8 sts=0 sw=8:
*
* configfs_example.c - This file is a demonstration module containing
* a number of configfs subsystems.
*
* 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 021110-1307, USA.
*
* Based on sysfs:
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
*
* configfs Copyright (C) 2005 Oracle. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/configfs.h>
/*
* 01-childless
*
* This first example is a childless subsystem. It cannot create
* any config_items. It just has attributes.
*
* Note that we are enclosing the configfs_subsystem inside a container.
* This is not necessary if a subsystem has no attributes directly
* on the subsystem. See the next example, 02-simple-children, for
* such a subsystem.
*/
struct childless {
struct configfs_subsystem subsys;
int showme;
int storeme;
};
struct childless_attribute {
struct configfs_attribute attr;
ssize_t (*show)(struct childless *, char *);
ssize_t (*store)(struct childless *, const char *, size_t);
};
static inline struct childless *to_childless(struct config_item *item)
{
return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
}
static ssize_t childless_showme_read(struct childless *childless,
char *page)
{
ssize_t pos;
pos = sprintf(page, "%d\n", childless->showme);
childless->showme++;
return pos;
}
static ssize_t childless_storeme_read(struct childless *childless,
char *page)
{
return sprintf(page, "%d\n", childless->storeme);
}
static ssize_t childless_storeme_write(struct childless *childless,
const char *page,
size_t count)
{
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
childless->storeme = tmp;
return count;
}
static ssize_t childless_description_read(struct childless *childless,
char *page)
{
return sprintf(page,
"[01-childless]\n"
"\n"
"The childless subsystem is the simplest possible subsystem in\n"
"configfs. It does not support the creation of child config_items.\n"
"It only has a few attributes. In fact, it isn't much different\n"
"than a directory in /proc.\n");
}
static struct childless_attribute childless_attr_showme = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
.show = childless_showme_read,
};
static struct childless_attribute childless_attr_storeme = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
.show = childless_storeme_read,
.store = childless_storeme_write,
};
static struct childless_attribute childless_attr_description = {
.attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
.show = childless_description_read,
};
static struct configfs_attribute *childless_attrs[] = {
&childless_attr_showme.attr,
&childless_attr_storeme.attr,
&childless_attr_description.attr,
NULL,
};
static ssize_t childless_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
struct childless *childless = to_childless(item);
struct childless_attribute *childless_attr =
container_of(attr, struct childless_attribute, attr);
ssize_t ret = 0;
if (childless_attr->show)
ret = childless_attr->show(childless, page);
return ret;
}
static ssize_t childless_attr_store(struct config_item *item,
struct configfs_attribute *attr,
const char *page, size_t count)
{
struct childless *childless = to_childless(item);
struct childless_attribute *childless_attr =
container_of(attr, struct childless_attribute, attr);
ssize_t ret = -EINVAL;
if (childless_attr->store)
ret = childless_attr->store(childless, page, count);
return ret;
}
static struct configfs_item_operations childless_item_ops = {
.show_attribute = childless_attr_show,
.store_attribute = childless_attr_store,
};
static struct config_item_type childless_type = {
.ct_item_ops = &childless_item_ops,
.ct_attrs = childless_attrs,
.ct_owner = THIS_MODULE,
};
static struct childless childless_subsys = {
.subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "01-childless",
.ci_type = &childless_type,
},
},
},
};
/* ----------------------------------------------------------------- */
/*
* 02-simple-children
*
* This example merely has a simple one-attribute child. Note that
* there is no extra attribute structure, as the child's attribute is
* known from the get-go. Also, there is no container for the
* subsystem, as it has no attributes of its own.
*/
struct simple_child {
struct config_item item;
int storeme;
};
static inline struct simple_child *to_simple_child(struct config_item *item)
{
return item ? container_of(item, struct simple_child, item) : NULL;
}
static struct configfs_attribute simple_child_attr_storeme = {
.ca_owner = THIS_MODULE,
.ca_name = "storeme",
.ca_mode = S_IRUGO | S_IWUSR,
};
static struct configfs_attribute *simple_child_attrs[] = {
&simple_child_attr_storeme,
NULL,
};
static ssize_t simple_child_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
ssize_t count;
struct simple_child *simple_child = to_simple_child(item);
count = sprintf(page, "%d\n", simple_child->storeme);
return count;
}
static ssize_t simple_child_attr_store(struct config_item *item,
struct configfs_attribute *attr,
const char *page, size_t count)
{
struct simple_child *simple_child = to_simple_child(item);
unsigned long tmp;
char *p = (char *) page;
tmp = simple_strtoul(p, &p, 10);
if (!p || (*p && (*p != '\n')))
return -EINVAL;
if (tmp > INT_MAX)
return -ERANGE;
simple_child->storeme = tmp;
return count;
}
static void simple_child_release(struct config_item *item)
{
kfree(to_simple_child(item));
}
static struct configfs_item_operations simple_child_item_ops = {
.release = simple_child_release,
.show_attribute = simple_child_attr_show,
.store_attribute = simple_child_attr_store,
};
static struct config_item_type simple_child_type = {
.ct_item_ops = &simple_child_item_ops,
.ct_attrs = simple_child_attrs,
.ct_owner = THIS_MODULE,
};
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
{
struct simple_child *simple_child;
simple_child = kmalloc(sizeof(struct simple_child), GFP_KERNEL);
if (!simple_child)
return NULL;
memset(simple_child, 0, sizeof(struct simple_child));
config_item_init_type_name(&simple_child->item, name,
&simple_child_type);
simple_child->storeme = 0;
return &simple_child->item;
}
static struct configfs_attribute simple_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *simple_children_attrs[] = {
&simple_children_attr_description,
NULL,
};
static ssize_t simple_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[02-simple-children]\n"
"\n"
"This subsystem allows the creation of child config_items. These\n"
"items have only one attribute that is readable and writeable.\n");
}
static struct configfs_item_operations simple_children_item_ops = {
.show_attribute = simple_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations simple_children_group_ops = {
.make_item = simple_children_make_item,
};
static struct config_item_type simple_children_type = {
.ct_item_ops = &simple_children_item_ops,
.ct_group_ops = &simple_children_group_ops,
.ct_attrs = simple_children_attrs,
};
static struct configfs_subsystem simple_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "02-simple-children",
.ci_type = &simple_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* 03-group-children
*
* This example reuses the simple_children group from above. However,
* the simple_children group is not the subsystem itself, it is a
* child of the subsystem. Creation of a group in the subsystem creates
* a new simple_children group. That group can then have simple_child
* children of its own.
*/
struct simple_children {
struct config_group group;
};
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
{
struct simple_children *simple_children;
simple_children = kmalloc(sizeof(struct simple_children),
GFP_KERNEL);
if (!simple_children)
return NULL;
memset(simple_children, 0, sizeof(struct simple_children));
config_group_init_type_name(&simple_children->group, name,
&simple_children_type);
return &simple_children->group;
}
static struct configfs_attribute group_children_attr_description = {
.ca_owner = THIS_MODULE,
.ca_name = "description",
.ca_mode = S_IRUGO,
};
static struct configfs_attribute *group_children_attrs[] = {
&group_children_attr_description,
NULL,
};
static ssize_t group_children_attr_show(struct config_item *item,
struct configfs_attribute *attr,
char *page)
{
return sprintf(page,
"[03-group-children]\n"
"\n"
"This subsystem allows the creation of child config_groups. These\n"
"groups are like the subsystem simple-children.\n");
}
static struct configfs_item_operations group_children_item_ops = {
.show_attribute = group_children_attr_show,
};
/*
* Note that, since no extra work is required on ->drop_item(),
* no ->drop_item() is provided.
*/
static struct configfs_group_operations group_children_group_ops = {
.make_group = group_children_make_group,
};
static struct config_item_type group_children_type = {
.ct_item_ops = &group_children_item_ops,
.ct_group_ops = &group_children_group_ops,
.ct_attrs = group_children_attrs,
};
static struct configfs_subsystem group_children_subsys = {
.su_group = {
.cg_item = {
.ci_namebuf = "03-group-children",
.ci_type = &group_children_type,
},
},
};
/* ----------------------------------------------------------------- */
/*
* We're now done with our subsystem definitions.
* For convenience in this module, here's a list of them all. It
* allows the init function to easily register them. Most modules
* will only have one subsystem, and will only call register_subsystem
* on it directly.
*/
static struct configfs_subsystem *example_subsys[] = {
&childless_subsys.subsys,
&simple_children_subsys,
&group_children_subsys,
NULL,
};
static int __init configfs_example_init(void)
{
int ret;
int i;
struct configfs_subsystem *subsys;
for (i = 0; example_subsys[i]; i++) {
subsys = example_subsys[i];
config_group_init(&subsys->su_group);
init_MUTEX(&subsys->su_sem);
ret = configfs_register_subsystem(subsys);
if (ret) {
printk(KERN_ERR "Error %d while registering subsystem %s\n",
ret,
subsys->su_group.cg_item.ci_namebuf);
goto out_unregister;
}
}
return 0;
out_unregister:
for (; i >= 0; i--) {
configfs_unregister_subsystem(example_subsys[i]);
}
return ret;
}
static void __exit configfs_example_exit(void)
{
int i;
for (i = 0; example_subsys[i]; i++) {
configfs_unregister_subsystem(example_subsys[i]);
}
}
module_init(configfs_example_init);
module_exit(configfs_example_exit);
MODULE_LICENSE("GPL");
dlmfs
==================
A minimal DLM userspace interface implemented via a virtual file
system.
dlmfs is built with OCFS2 as it requires most of its infrastructure.
Project web page: http://oss.oracle.com/projects/ocfs2
Tools web page: http://oss.oracle.com/projects/ocfs2-tools
OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
All code copyright 2005 Oracle except when otherwise noted.
CREDITS
=======
Some code taken from ramfs which is Copyright (C) 2000 Linus Torvalds
and Transmeta Corp.
Mark Fasheh <mark.fasheh@oracle.com>
Caveats
=======
- Right now it only works with the OCFS2 DLM, though support for other
DLM implementations should not be a major issue.
Mount options
=============
None
Usage
=====
If you're just interested in OCFS2, then please see ocfs2.txt. The
rest of this document will be geared towards those who want to use
dlmfs for easy to setup and easy to use clustered locking in
userspace.
Setup
=====
dlmfs requires that the OCFS2 cluster infrastructure be in
place. Please download ocfs2-tools from the above url and configure a
cluster.
You'll want to start heartbeating on a volume which all the nodes in
your lockspace can access. The easiest way to do this is via
ocfs2_hb_ctl (distributed with ocfs2-tools). Right now it requires
that an OCFS2 file system be in place so that it can automatically
find it's heartbeat area, though it will eventually support heartbeat
against raw disks.
Please see the ocfs2_hb_ctl and mkfs.ocfs2 manual pages distributed
with ocfs2-tools.
Once you're heartbeating, DLM lock 'domains' can be easily created /
destroyed and locks within them accessed.
Locking
=======
Users may access dlmfs via standard file system calls, or they can use
'libo2dlm' (distributed with ocfs2-tools) which abstracts the file
system calls and presents a more traditional locking api.
dlmfs handles lock caching automatically for the user, so a lock
request for an already acquired lock will not generate another DLM
call. Userspace programs are assumed to handle their own local
locking.
Two levels of locks are supported - Shared Read, and Exlcusive.
Also supported is a Trylock operation.
For information on the libo2dlm interface, please see o2dlm.h,
distributed with ocfs2-tools.
Lock value blocks can be read and written to a resource via read(2)
and write(2) against the fd obtained via your open(2) call. The
maximum currently supported LVB length is 64 bytes (though that is an
OCFS2 DLM limitation). Through this mechanism, users of dlmfs can share
small amounts of data amongst their nodes.
mkdir(2) signals dlmfs to join a domain (which will have the same name
as the resulting directory)
rmdir(2) signals dlmfs to leave the domain
Locks for a given domain are represented by regular inodes inside the
domain directory. Locking against them is done via the open(2) system
call.
The open(2) call will not return until your lock has been granted or
an error has occurred, unless it has been instructed to do a trylock
operation. If the lock succeeds, you'll get an fd.
open(2) with O_CREAT to ensure the resource inode is created - dlmfs does
not automatically create inodes for existing lock resources.
Open Flag Lock Request Type
--------- -----------------
O_RDONLY Shared Read
O_RDWR Exclusive
Open Flag Resulting Locking Behavior
--------- --------------------------
O_NONBLOCK Trylock operation
You must provide exactly one of O_RDONLY or O_RDWR.
If O_NONBLOCK is also provided and the trylock operation was valid but
could not lock the resource then open(2) will return ETXTBUSY.
close(2) drops the lock associated with your fd.
Modes passed to mkdir(2) or open(2) are adhered to locally. Chown is
supported locally as well. This means you can use them to restrict
access to the resources via dlmfs on your local node only.
The resource LVB may be read from the fd in either Shared Read or
Exclusive modes via the read(2) system call. It can be written via
write(2) only when open in Exclusive mode.
Once written, an LVB will be visible to other nodes who obtain Read
Only or higher level locks on the resource.
See Also
========
http://opendlm.sourceforge.net/cvsmirror/opendlm/docs/dlmbook_final.pdf
For more information on the VMS distributed locking API.
OCFS2 filesystem
==================
OCFS2 is a general purpose extent based shared disk cluster file
system with many similarities to ext3. It supports 64 bit inode
numbers, and has automatically extending metadata groups which may
also make it attractive for non-clustered use.
You'll want to install the ocfs2-tools package in order to at least
get "mount.ocfs2" and "ocfs2_hb_ctl".
Project web page: http://oss.oracle.com/projects/ocfs2
Tools web page: http://oss.oracle.com/projects/ocfs2-tools
OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
All code copyright 2005 Oracle except when otherwise noted.
CREDITS:
Lots of code taken from ext3 and other projects.
Authors in alphabetical order:
Joel Becker <joel.becker@oracle.com>
Zach Brown <zach.brown@oracle.com>
Mark Fasheh <mark.fasheh@oracle.com>
Kurt Hackel <kurt.hackel@oracle.com>
Sunil Mushran <sunil.mushran@oracle.com>
Manish Singh <manish.singh@oracle.com>
Caveats
=======
Features which OCFS2 does not support yet:
- sparse files
- extended attributes
- shared writeable mmap
- loopback is supported, but data written will not
be cluster coherent.
- quotas
- cluster aware flock
- Directory change notification (F_NOTIFY)
- Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
- POSIX ACLs
- readpages / writepages (not user visible)
Mount options
=============
OCFS2 supports the following mount options:
(*) == default
barrier=1 This enables/disables barriers. barrier=0 disables it,
barrier=1 enables it.
errors=remount-ro(*) Remount the filesystem read-only on an error.
errors=panic Panic and halt the machine if an error occurs.
intr (*) Allow signals to interrupt cluster operations.
nointr Do not allow signals to interrupt cluster
operations.
...@@ -162,9 +162,8 @@ get_sb() method fills in is the "s_op" field. This is a pointer to ...@@ -162,9 +162,8 @@ get_sb() method fills in is the "s_op" field. This is a pointer to
a "struct super_operations" which describes the next level of the a "struct super_operations" which describes the next level of the
filesystem implementation. filesystem implementation.
Usually, a filesystem uses generic one of the generic get_sb() Usually, a filesystem uses one of the generic get_sb() implementations
implementations and provides a fill_super() method instead. The and provides a fill_super() method instead. The generic methods are:
generic methods are:
get_sb_bdev: mount a filesystem residing on a block device get_sb_bdev: mount a filesystem residing on a block device
......
...@@ -38,7 +38,7 @@ included in the kernel tree. ...@@ -38,7 +38,7 @@ included in the kernel tree.
What is covered within this file is mainly information to authors What is covered within this file is mainly information to authors
of modules. The author of an external modules should supply of modules. The author of an external modules should supply
a makefile that hides most of the complexity so one only has to type a makefile that hides most of the complexity so one only has to type
'make' to buld the module. A complete example will be present in 'make' to build the module. A complete example will be present in
chapter ¤. Creating a kbuild file for an external module". chapter ¤. Creating a kbuild file for an external module".
...@@ -69,7 +69,7 @@ when building an external module. ...@@ -69,7 +69,7 @@ when building an external module.
--- 2.2 Available targets --- 2.2 Available targets
$KDIR refers to path to kernel source top-level directory $KDIR refers to the path to the kernel source top-level directory
make -C $KDIR M=`pwd` make -C $KDIR M=`pwd`
Will build the module(s) located in current directory. Will build the module(s) located in current directory.
...@@ -87,11 +87,11 @@ when building an external module. ...@@ -87,11 +87,11 @@ when building an external module.
make -C $KDIR M=$PWD modules_install make -C $KDIR M=$PWD modules_install
Install the external module(s). Install the external module(s).
Installation default is in /lib/modules/<kernel-version>/extra, Installation default is in /lib/modules/<kernel-version>/extra,
but may be prefixed with INSTALL_MOD_PATH - see separate chater. but may be prefixed with INSTALL_MOD_PATH - see separate chapter.
make -C $KDIR M=$PWD clean make -C $KDIR M=$PWD clean
Remove all generated files for the module - the kernel Remove all generated files for the module - the kernel
source directory is not moddified. source directory is not modified.
make -C $KDIR M=`pwd` help make -C $KDIR M=`pwd` help
help will list the available target when building external help will list the available target when building external
...@@ -99,7 +99,7 @@ when building an external module. ...@@ -99,7 +99,7 @@ when building an external module.
--- 2.3 Available options: --- 2.3 Available options:
$KDIR refer to path to kernel src $KDIR refers to the path to the kernel source top-level directory
make -C $KDIR make -C $KDIR
Used to specify where to find the kernel source. Used to specify where to find the kernel source.
...@@ -206,11 +206,11 @@ following files: ...@@ -206,11 +206,11 @@ following files:
KERNELDIR := /lib/modules/`uname -r`/build KERNELDIR := /lib/modules/`uname -r`/build
all:: all::
$(MAKE) -C $KERNELDIR M=`pwd` $@ $(MAKE) -C $(KERNELDIR) M=`pwd` $@
# Module specific targets # Module specific targets
genbin: genbin:
echo "X" > 8123_bini.o_shipped echo "X" > 8123_bin.o_shipped
endif endif
...@@ -341,13 +341,13 @@ directory and therefore needs to deal with this in their kbuild file. ...@@ -341,13 +341,13 @@ directory and therefore needs to deal with this in their kbuild file.
EXTRA_CFLAGS := -Iinclude EXTRA_CFLAGS := -Iinclude
8123-y := 8123_if.o 8123_pci.o 8123_bin.o 8123-y := 8123_if.o 8123_pci.o 8123_bin.o
Note that in the assingment there is no space between -I and the path. Note that in the assignment there is no space between -I and the path.
This is a kbuild limitation and no space must be present. This is a kbuild limitation: there must be no space present.
=== 6. Module installation === 6. Module installation
Modules which are included in the kernel is installed in the directory: Modules which are included in the kernel are installed in the directory:
/lib/modules/$(KERNELRELEASE)/kernel /lib/modules/$(KERNELRELEASE)/kernel
...@@ -365,7 +365,7 @@ External modules are installed in the directory: ...@@ -365,7 +365,7 @@ External modules are installed in the directory:
=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
example above be specified on the commandline when calling make. example above be specified on the command line when calling make.
INSTALL_MOD_PATH has effect both when installing modules included in INSTALL_MOD_PATH has effect both when installing modules included in
the kernel as well as when installing external modules. the kernel as well as when installing external modules.
...@@ -384,7 +384,7 @@ External modules are installed in the directory: ...@@ -384,7 +384,7 @@ External modules are installed in the directory:
=== 7. Module versioning === 7. Module versioning
Module versioning are enabled by the CONFIG_MODVERSIONS tag. Module versioning is enabled by the CONFIG_MODVERSIONS tag.
Module versioning is used as a simple ABI consistency check. The Module Module versioning is used as a simple ABI consistency check. The Module
versioning creates a CRC value of the full prototype for an exported symbol and versioning creates a CRC value of the full prototype for an exported symbol and
......
...@@ -633,6 +633,14 @@ running once the system is up. ...@@ -633,6 +633,14 @@ running once the system is up.
inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver
Format: <irq> Format: <irq>
combined_mode= [HW] control which driver uses IDE ports in combined
mode: legacy IDE driver, libata, or both
(in the libata case, libata.atapi_enabled=1 may be
useful as well). Note that using the ide or libata
options may affect your device naming (e.g. by
changing hdc to sdb).
Format: combined (default), ide, or libata
inttest= [IA64] inttest= [IA64]
io7= [HW] IO7 for Marvel based alpha systems io7= [HW] IO7 for Marvel based alpha systems
......
...@@ -860,24 +860,6 @@ The structure has a number of fields, some of which are mandatory: ...@@ -860,24 +860,6 @@ The structure has a number of fields, some of which are mandatory:
It is safe to sleep in this method. It is safe to sleep in this method.
(*) int (*duplicate)(struct key *key, const struct key *source);
If this type of key can be duplicated, then this method should be
provided. It is called to copy the payload attached to the source into the
new key. The data length on the new key will have been updated and the
quota adjusted already.
This method will be called with the source key's semaphore read-locked to
prevent its payload from being changed, thus RCU constraints need not be
applied to the source key.
This method does not have to lock the destination key in order to attach a
payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags
prevents anything else from gaining access to the key.
It is safe to sleep in this method.
(*) int (*update)(struct key *key, const void *data, size_t datalen); (*) int (*update)(struct key *key, const void *data, size_t datalen);
If this type of key can be updated, then this method should be provided. If this type of key can be updated, then this method should be provided.
......
...@@ -51,6 +51,30 @@ superblock can be autodetected and run at boot time. ...@@ -51,6 +51,30 @@ superblock can be autodetected and run at boot time.
The kernel parameter "raid=partitionable" (or "raid=part") means The kernel parameter "raid=partitionable" (or "raid=part") means
that all auto-detected arrays are assembled as partitionable. that all auto-detected arrays are assembled as partitionable.
Boot time assembly of degraded/dirty arrays
-------------------------------------------
If a raid5 or raid6 array is both dirty and degraded, it could have
undetectable data corruption. This is because the fact that it is
'dirty' means that the parity cannot be trusted, and the fact that it
is degraded means that some datablocks are missing and cannot reliably
be reconstructed (due to no parity).
For this reason, md will normally refuse to start such an array. This
requires the sysadmin to take action to explicitly start the array
desipite possible corruption. This is normally done with
mdadm --assemble --force ....
This option is not really available if the array has the root
filesystem on it. In order to support this booting from such an
array, md supports a module parameter "start_dirty_degraded" which,
when set to 1, bypassed the checks and will allows dirty degraded
arrays to be started.
So, to boot with a root filesystem of a dirty degraded raid[56], use
md-mod.start_dirty_degraded=1
Superblock formats Superblock formats
------------------ ------------------
...@@ -141,6 +165,70 @@ All md devices contain: ...@@ -141,6 +165,70 @@ All md devices contain:
in a fully functional array. If this is not yet known, the file in a fully functional array. If this is not yet known, the file
will be empty. If an array is being resized (not currently will be empty. If an array is being resized (not currently
possible) this will contain the larger of the old and new sizes. possible) this will contain the larger of the old and new sizes.
Some raid level (RAID1) allow this value to be set while the
array is active. This will reconfigure the array. Otherwise
it can only be set while assembling an array.
chunk_size
This is the size if bytes for 'chunks' and is only relevant to
raid levels that involve striping (1,4,5,6,10). The address space
of the array is conceptually divided into chunks and consecutive
chunks are striped onto neighbouring devices.
The size should be atleast PAGE_SIZE (4k) and should be a power
of 2. This can only be set while assembling an array
component_size
For arrays with data redundancy (i.e. not raid0, linear, faulty,
multipath), all components must be the same size - or at least
there must a size that they all provide space for. This is a key
part or the geometry of the array. It is measured in sectors
and can be read from here. Writing to this value may resize
the array if the personality supports it (raid1, raid5, raid6),
and if the component drives are large enough.
metadata_version
This indicates the format that is being used to record metadata
about the array. It can be 0.90 (traditional format), 1.0, 1.1,
1.2 (newer format in varying locations) or "none" indicating that
the kernel isn't managing metadata at all.
level
The raid 'level' for this array. The name will often (but not
always) be the same as the name of the module that implements the
level. To be auto-loaded the module must have an alias
md-$LEVEL e.g. md-raid5
This can be written only while the array is being assembled, not
after it is started.
new_dev
This file can be written but not read. The value written should
be a block device number as major:minor. e.g. 8:0
This will cause that device to be attached to the array, if it is
available. It will then appear at md/dev-XXX (depending on the
name of the device) and further configuration is then possible.
sync_speed_min
sync_speed_max
This are similar to /proc/sys/dev/raid/speed_limit_{min,max}
however they only apply to the particular array.
If no value has been written to these, of if the word 'system'
is written, then the system-wide value is used. If a value,
in kibibytes-per-second is written, then it is used.
When the files are read, they show the currently active value
followed by "(local)" or "(system)" depending on whether it is
a locally set or system-wide value.
sync_completed
This shows the number of sectors that have been completed of
whatever the current sync_action is, followed by the number of
sectors in total that could need to be processed. The two
numbers are separated by a '/' thus effectively showing one
value, a fraction of the process that is complete.
sync_speed
This shows the current actual speed, in K/sec, of the current
sync_action. It is averaged over the last 30 seconds.
As component devices are added to an md array, they appear in the 'md' As component devices are added to an md array, they appear in the 'md'
directory as new directories named directory as new directories named
...@@ -167,6 +255,38 @@ Each directory contains: ...@@ -167,6 +255,38 @@ Each directory contains:
of being recoverred to of being recoverred to
This list make grow in future. This list make grow in future.
errors
An approximate count of read errors that have been detected on
this device but have not caused the device to be evicted from
the array (either because they were corrected or because they
happened while the array was read-only). When using version-1
metadata, this value persists across restarts of the array.
This value can be written while assembling an array thus
providing an ongoing count for arrays with metadata managed by
userspace.
slot
This gives the role that the device has in the array. It will
either be 'none' if the device is not active in the array
(i.e. is a spare or has failed) or an integer less than the
'raid_disks' number for the array indicating which possition
it currently fills. This can only be set while assembling an
array. A device for which this is set is assumed to be working.
offset
This gives the location in the device (in sectors from the
start) where data from the array will be stored. Any part of
the device before this offset us not touched, unless it is
used for storing metadata (Formats 1.1 and 1.2).
size
The amount of the device, after the offset, that can be used
for storage of data. This will normally be the same as the
component_size. This can be written while assembling an
array. If a value less than the current component_size is
written, component_size will be reduced to this value.
An active md device will also contain and entry for each active device An active md device will also contain and entry for each active device
in the array. These are named in the array. These are named
......
The Gianfar Ethernet Driver
Sysfs File description
Author: Andy Fleming <afleming@freescale.com>
Updated: 2005-07-28
SYSFS
Several of the features of the gianfar driver are controlled
through sysfs files. These are:
bd_stash:
To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
bd_stash, echo 'off' or '0' to disable
rx_stash_len:
To stash the first n bytes of the packet in L2, echo the number
of bytes to buf_stash_len. echo 0 to disable.
WARNING: You could really screw these up if you set them too low or high!
fifo_threshold:
To change the number of bytes the controller needs in the
fifo before it starts transmission, echo the number of bytes to
fifo_thresh. Range should be 0-511.
fifo_starve:
When the FIFO has less than this many bytes during a transmit, it
enters starve mode, and increases the priority of TX memory
transactions. To change, echo the number of bytes to
fifo_starve. Range should be 0-511.
fifo_starve_off:
Once in starve mode, the FIFO remains there until it has this
many bytes. To change, echo the number of bytes to
fifo_starve_off. Range should be 0-511.
CHECKSUM OFFLOADING
The eTSEC controller (first included in parts from late 2005 like
the 8548) has the ability to perform TCP, UDP, and IP checksums
in hardware. The Linux kernel only offloads the TCP and UDP
checksums (and always performs the pseudo header checksums), so
the driver only supports checksumming for TCP/IP and UDP/IP
packets. Use ethtool to enable or disable this feature for RX
and TX.
VLAN
In order to use VLAN, please consult Linux documentation on
configuring VLANs. The gianfar driver supports hardware insertion and
extraction of VLAN headers, but not filtering. Filtering will be
done by the kernel.
MULTICASTING
The gianfar driver supports using the group hash table on the
TSEC (and the extended hash table on the eTSEC) for multicast
filtering. On the eTSEC, the exact-match MAC registers are used
before the hash tables. See Linux documentation on how to join
multicast groups.
PADDING
The gianfar driver supports padding received frames with 2 bytes
to align the IP header to a 16-byte boundary, when supported by
hardware.
ETHTOOL
The gianfar driver supports the use of ethtool for many
configuration options. You must run ethtool only on currently
open interfaces. See ethtool documentation for details.
...@@ -46,6 +46,29 @@ ipfrag_secret_interval - INTEGER ...@@ -46,6 +46,29 @@ ipfrag_secret_interval - INTEGER
for the hash secret) for IP fragments. for the hash secret) for IP fragments.
Default: 600 Default: 600
ipfrag_max_dist - INTEGER
ipfrag_max_dist is a non-negative integer value which defines the
maximum "disorder" which is allowed among fragments which share a
common IP source address. Note that reordering of packets is
not unusual, but if a large number of fragments arrive from a source
IP address while a particular fragment queue remains incomplete, it
probably indicates that one or more fragments belonging to that queue
have been lost. When ipfrag_max_dist is positive, an additional check
is done on fragments before they are added to a reassembly queue - if
ipfrag_max_dist (or more) fragments have arrived from a particular IP
address between additions to any IP fragment queue using that source
address, it's presumed that one or more fragments in the queue are
lost. The existing fragment queue will be dropped, and a new one
started. An ipfrag_max_dist value of zero disables this check.
Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
result in unnecessarily dropping fragment queues when normal
reordering of packets occurs, which could lead to poor application
performance. Using a very large value, e.g. 50000, increases the
likelihood of incorrectly reassembling IP fragments that originate
from different IP datagrams, which could result in data corruption.
Default: 64
INET peer storage: INET peer storage:
inet_peer_threshold - INTEGER inet_peer_threshold - INTEGER
......
This file details changes in 2.6 which affect PCMCIA card driver authors: This file details changes in 2.6 which affect PCMCIA card driver authors:
* Unify detach and REMOVAL event code, as well as attach and INSERTION
code (as of 2.6.16)
void (*remove) (struct pcmcia_device *dev);
int (*probe) (struct pcmcia_device *dev);
* Move suspend, resume and reset out of event handler (as of 2.6.16)
int (*suspend) (struct pcmcia_device *dev);
int (*resume) (struct pcmcia_device *dev);
should be initialized in struct pcmcia_driver, and handle
(SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
* event handler initialization in struct pcmcia_driver (as of 2.6.13) * event handler initialization in struct pcmcia_driver (as of 2.6.13)
The event handler is notified of all events, and must be initialized The event handler is notified of all events, and must be initialized
as the event() callback in the driver's struct pcmcia_driver. as the event() callback in the driver's struct pcmcia_driver.
......
...@@ -41,3 +41,14 @@ to. Writing to this file will accept one of ...@@ -41,3 +41,14 @@ to. Writing to this file will accept one of
It will only change to 'firmware' or 'platform' if the system supports It will only change to 'firmware' or 'platform' if the system supports
it. it.
/sys/power/image_size controls the size of the image created by
the suspend-to-disk mechanism. It can be written a string
representing a non-negative integer that will be used as an upper
limit of the image size, in megabytes. The suspend-to-disk mechanism will
do its best to ensure the image size will not exceed that number. However,
if this turns out to be impossible, it will try to suspend anyway using the
smallest image possible. In particular, if "0" is written to this file, the
suspend image will be as small as possible.
Reading from this file will display the current image size limit, which
is set to 500 MB by default.
...@@ -27,6 +27,11 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state ...@@ -27,6 +27,11 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state
echo platform > /sys/power/disk; echo disk > /sys/power/state echo platform > /sys/power/disk; echo disk > /sys/power/state
If you want to limit the suspend image size to N megabytes, do
echo N > /sys/power/image_size
before suspend (it is limited to 500 MB by default).
Encrypted suspend image: Encrypted suspend image:
------------------------ ------------------------
......
...@@ -115,7 +115,7 @@ Current PPC64 Linux EEH Implementation ...@@ -115,7 +115,7 @@ Current PPC64 Linux EEH Implementation
At this time, a generic EEH recovery mechanism has been implemented, At this time, a generic EEH recovery mechanism has been implemented,
so that individual device drivers do not need to be modified to support so that individual device drivers do not need to be modified to support
EEH recovery. This generic mechanism piggy-backs on the PCI hotplug EEH recovery. This generic mechanism piggy-backs on the PCI hotplug
infrastructure, and percolates events up through the hotplug/udev infrastructure, and percolates events up through the userspace/udev
infrastructure. Followiing is a detailed description of how this is infrastructure. Followiing is a detailed description of how this is
accomplished. accomplished.
...@@ -172,7 +172,7 @@ A handler for the EEH notifier_block events is implemented in ...@@ -172,7 +172,7 @@ A handler for the EEH notifier_block events is implemented in
drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events(). drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter(). It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
This last call causes the device driver for the card to be stopped, This last call causes the device driver for the card to be stopped,
which causes hotplug events to go out to user space. This triggers which causes uevents to go out to user space. This triggers
user-space scripts that might issue commands such as "ifdown eth0" user-space scripts that might issue commands such as "ifdown eth0"
for ethernet cards, and so on. This handler then sleeps for 5 seconds, for ethernet cards, and so on. This handler then sleeps for 5 seconds,
hoping to give the user-space scripts enough time to complete. hoping to give the user-space scripts enough time to complete.
...@@ -258,29 +258,30 @@ rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c ...@@ -258,29 +258,30 @@ rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c
calls calls
pci_destroy_dev (struct pci_dev *) { pci_destroy_dev (struct pci_dev *) {
calls calls
device_unregister (&dev->dev) { // in /drivers/base/core.c device_unregister (&dev->dev) { // in /drivers/base/core.c
calls calls
device_del(struct device * dev) { // in /drivers/base/core.c device_del(struct device * dev) { // in /drivers/base/core.c
calls calls
kobject_del() { //in /libs/kobject.c kobject_del() { //in /libs/kobject.c
calls calls
kobject_hotplug() { // in /libs/kobject.c kobject_uevent() { // in /libs/kobject.c
calls calls
kset_hotplug() { // in /lib/kobject.c kset_uevent() { // in /lib/kobject.c
calls calls
kset->hotplug_ops->hotplug() which is really just kset->uevent_ops->uevent() // which is really just
a call to a call to
dev_hotplug() { // in /drivers/base/core.c dev_uevent() { // in /drivers/base/core.c
calls calls
dev->bus->hotplug() which is really just a call to dev->bus->uevent() which is really just a call to
pci_hotplug () { // in drivers/pci/hotplug.c pci_uevent () { // in drivers/pci/hotplug.c
which prints device name, etc.... which prints device name, etc....
} }
} }
then kset_hotplug() calls then kobject_uevent() sends a netlink uevent to userspace
call_usermodehelper () with --> userspace uevent
argv[0]=hotplug_path[] which is "/sbin/hotplug" (during early boot, nobody listens to netlink events and
--> event to userspace, kobject_uevent() executes uevent_helper[], which runs the
event process /sbin/hotplug)
} }
} }
kobject_del() then calls sysfs_remove_dir(), which would kobject_del() then calls sysfs_remove_dir(), which would
......
Release Date : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
1. Sorted out PCI IDs to remove megaraid support overlaps.
Based on the patch from Daniel, sorted out PCI IDs along with
charactor node name change from 'megadev' to 'megadev_legacy' to avoid
conflict.
---
Hopefully we'll be getting the build restriction zapped much sooner,
but we should also be thinking about totally removing the hardware
support overlap in the megaraid drivers.
This patch pencils in a date of Feb 06 for this, and performs some
printk abuse in hope that existing legacy users might pick up on what's
going on.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
---
2. Fixed a issue: megaraid always fails to reset handler.
---
I found that the megaraid driver always fails to reset the
adapter with the following message:
megaraid: resetting the host...
megaraid mbox: reset sequence completed successfully
megaraid: fast sync command timed out
megaraid: reservation reset failed
when the "Cluster mode" of the adapter BIOS is enabled.
So, whenever the reset occurs, the adapter goes to
offline and just become unavailable.
Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp]
---
Release Date : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com> Release Date : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module) Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module) Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
......
...@@ -150,7 +150,8 @@ scsi devices of which only the first 2 respond: ...@@ -150,7 +150,8 @@ scsi devices of which only the first 2 respond:
LLD mid level LLD LLD mid level LLD
===-------------------=========--------------------===------ ===-------------------=========--------------------===------
scsi_host_alloc() --> scsi_host_alloc() -->
scsi_add_host() --------+ scsi_add_host() ---->
scsi_scan_host() -------+
| |
slave_alloc() slave_alloc()
slave_configure() --> scsi_adjust_queue_depth() slave_configure() --> scsi_adjust_queue_depth()
...@@ -196,7 +197,7 @@ of the issues involved. See the section on reference counting below. ...@@ -196,7 +197,7 @@ of the issues involved. See the section on reference counting below.
The hotplug concept may be extended to SCSI devices. Currently, when an The hotplug concept may be extended to SCSI devices. Currently, when an
HBA is added, the scsi_add_host() function causes a scan for SCSI devices HBA is added, the scsi_scan_host() function causes a scan for SCSI devices
attached to the HBA's SCSI transport. On newer SCSI transports the HBA attached to the HBA's SCSI transport. On newer SCSI transports the HBA
may become aware of a new SCSI device _after_ the scan has completed. may become aware of a new SCSI device _after_ the scan has completed.
An LLD can use this sequence to make the mid level aware of a SCSI device: An LLD can use this sequence to make the mid level aware of a SCSI device:
...@@ -372,7 +373,7 @@ names all start with "scsi_". ...@@ -372,7 +373,7 @@ names all start with "scsi_".
Summary: Summary:
scsi_activate_tcq - turn on tag command queueing scsi_activate_tcq - turn on tag command queueing
scsi_add_device - creates new scsi device (lu) instance scsi_add_device - creates new scsi device (lu) instance
scsi_add_host - perform sysfs registration and SCSI bus scan. scsi_add_host - perform sysfs registration and set up transport class
scsi_adjust_queue_depth - change the queue depth on a SCSI device scsi_adjust_queue_depth - change the queue depth on a SCSI device
scsi_assign_lock - replace default host_lock with given lock scsi_assign_lock - replace default host_lock with given lock
scsi_bios_ptable - return copy of block device's partition table scsi_bios_ptable - return copy of block device's partition table
...@@ -386,6 +387,7 @@ Summary: ...@@ -386,6 +387,7 @@ Summary:
scsi_remove_device - detach and remove a SCSI device scsi_remove_device - detach and remove a SCSI device
scsi_remove_host - detach and remove all SCSI devices owned by host scsi_remove_host - detach and remove all SCSI devices owned by host
scsi_report_bus_reset - report scsi _bus_ reset observed scsi_report_bus_reset - report scsi _bus_ reset observed
scsi_scan_host - scan SCSI bus
scsi_track_queue_full - track successive QUEUE_FULL events scsi_track_queue_full - track successive QUEUE_FULL events
scsi_unblock_requests - allow further commands to be queued to given host scsi_unblock_requests - allow further commands to be queued to given host
scsi_unregister - [calls scsi_host_put()] scsi_unregister - [calls scsi_host_put()]
...@@ -425,10 +427,10 @@ void scsi_activate_tcq(struct scsi_device *sdev, int depth) ...@@ -425,10 +427,10 @@ void scsi_activate_tcq(struct scsi_device *sdev, int depth)
* Might block: yes * Might block: yes
* *
* Notes: This call is usually performed internally during a scsi * Notes: This call is usually performed internally during a scsi
* bus scan when an HBA is added (i.e. scsi_add_host()). So it * bus scan when an HBA is added (i.e. scsi_scan_host()). So it
* should only be called if the HBA becomes aware of a new scsi * should only be called if the HBA becomes aware of a new scsi
* device (lu) after scsi_add_host() has completed. If successful * device (lu) after scsi_scan_host() has completed. If successful
* this call we lead to slave_alloc() and slave_configure() callbacks * this call can lead to slave_alloc() and slave_configure() callbacks
* into the LLD. * into the LLD.
* *
* Defined in: drivers/scsi/scsi_scan.c * Defined in: drivers/scsi/scsi_scan.c
...@@ -439,7 +441,7 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost, ...@@ -439,7 +441,7 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
/** /**
* scsi_add_host - perform sysfs registration and SCSI bus scan. * scsi_add_host - perform sysfs registration and set up transport class
* @shost: pointer to scsi host instance * @shost: pointer to scsi host instance
* @dev: pointer to struct device of type scsi class * @dev: pointer to struct device of type scsi class
* *
...@@ -448,7 +450,11 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost, ...@@ -448,7 +450,11 @@ struct scsi_device * scsi_add_device(struct Scsi_Host *shost,
* Might block: no * Might block: no
* *
* Notes: Only required in "hotplug initialization model" after a * Notes: Only required in "hotplug initialization model" after a
* successful call to scsi_host_alloc(). * successful call to scsi_host_alloc(). This function does not
* scan the bus; this can be done by calling scsi_scan_host() or
* in some other transport-specific way. The LLD must set up
* the transport template before calling this function and may only
* access the transport class data after this function has been called.
* *
* Defined in: drivers/scsi/hosts.c * Defined in: drivers/scsi/hosts.c
**/ **/
...@@ -559,7 +565,7 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) ...@@ -559,7 +565,7 @@ void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
* area for the LLD's exclusive use. * area for the LLD's exclusive use.
* Both associated refcounting objects have their refcount set to 1. * Both associated refcounting objects have their refcount set to 1.
* Full registration (in sysfs) and a bus scan are performed later when * Full registration (in sysfs) and a bus scan are performed later when
* scsi_add_host() is called. * scsi_add_host() and scsi_scan_host() are called.
* *
* Defined in: drivers/scsi/hosts.c . * Defined in: drivers/scsi/hosts.c .
**/ **/
...@@ -698,6 +704,19 @@ int scsi_remove_host(struct Scsi_Host *shost) ...@@ -698,6 +704,19 @@ int scsi_remove_host(struct Scsi_Host *shost)
void scsi_report_bus_reset(struct Scsi_Host * shost, int channel) void scsi_report_bus_reset(struct Scsi_Host * shost, int channel)
/**
* scsi_scan_host - scan SCSI bus
* @shost: a pointer to a scsi host instance
*
* Might block: yes
*
* Notes: Should be called after scsi_add_host()
*
* Defined in: drivers/scsi/scsi_scan.c
**/
void scsi_scan_host(struct Scsi_Host *shost)
/** /**
* scsi_track_queue_full - track successive QUEUE_FULL events on given * scsi_track_queue_full - track successive QUEUE_FULL events on given
* device to determine if and when there is a need * device to determine if and when there is a need
...@@ -1433,7 +1452,7 @@ The following people have contributed to this document: ...@@ -1433,7 +1452,7 @@ The following people have contributed to this document:
Christoph Hellwig <hch at infradead dot org> Christoph Hellwig <hch at infradead dot org>
Doug Ledford <dledford at redhat dot com> Doug Ledford <dledford at redhat dot com>
Andries Brouwer <Andries dot Brouwer at cwi dot nl> Andries Brouwer <Andries dot Brouwer at cwi dot nl>
Randy Dunlap <rddunlap at osdl dot org> Randy Dunlap <rdunlap at xenotime dot net>
Alan Stern <stern at rowland dot harvard dot edu> Alan Stern <stern at rowland dot harvard dot edu>
......
...@@ -138,6 +138,22 @@ card*/codec97#0/ac97#?-?+regs ...@@ -138,6 +138,22 @@ card*/codec97#0/ac97#?-?+regs
# echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs # echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs
USB Audio Streams
-----------------
card*/stream*
Shows the assignment and the current status of each audio stream
of the given card. This information is very useful for debugging.
HD-Audio Codecs
---------------
card*/codec#*
Shows the general codec information and the attribute of each
widget node.
Sequencer Information Sequencer Information
--------------------- ---------------------
......
...@@ -63,7 +63,7 @@ The bus instance is created via snd_hda_bus_new(). You need to pass ...@@ -63,7 +63,7 @@ The bus instance is created via snd_hda_bus_new(). You need to pass
the card instance, the template, and the pointer to store the the card instance, the template, and the pointer to store the
resultant bus instance. resultant bus instance.
int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp, int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
struct hda_bus **busp); struct hda_bus **busp);
It returns zero if successful. A negative return value means any It returns zero if successful. A negative return value means any
...@@ -166,14 +166,14 @@ The ops field contains the following callback functions: ...@@ -166,14 +166,14 @@ The ops field contains the following callback functions:
struct hda_pcm_ops { struct hda_pcm_ops {
int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
snd_pcm_substream_t *substream); struct snd_pcm_substream *substream);
int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
snd_pcm_substream_t *substream); struct snd_pcm_substream *substream);
int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
unsigned int stream_tag, unsigned int format, unsigned int stream_tag, unsigned int format,
snd_pcm_substream_t *substream); struct snd_pcm_substream *substream);
int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec, int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
snd_pcm_substream_t *substream); struct snd_pcm_substream *substream);
}; };
All are non-NULL, so you can call them safely without NULL check. All are non-NULL, so you can call them safely without NULL check.
...@@ -284,7 +284,7 @@ parameter, and PCI subsystem IDs. If the matching entry is found, it ...@@ -284,7 +284,7 @@ parameter, and PCI subsystem IDs. If the matching entry is found, it
returns the config field value. returns the config field value.
snd_hda_add_new_ctls() can be used to create and add control entries. snd_hda_add_new_ctls() can be used to create and add control entries.
Pass the zero-terminated array of snd_kcontrol_new_t. The same array Pass the zero-terminated array of struct snd_kcontrol_new. The same array
can be passed to snd_hda_resume_ctls() for resume. can be passed to snd_hda_resume_ctls() for resume.
Note that this will call control->put callback of these entries. So, Note that this will call control->put callback of these entries. So,
put callback should check codec->in_resume and force to restore the put callback should check codec->in_resume and force to restore the
...@@ -292,7 +292,7 @@ given value if it's non-zero even if the value is identical with the ...@@ -292,7 +292,7 @@ given value if it's non-zero even if the value is identical with the
cached value. cached value.
Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
used for the entry of snd_kcontrol_new_t. used for the entry of struct snd_kcontrol_new.
The input MUX helper callbacks for such a control are provided, too: The input MUX helper callbacks for such a control are provided, too:
snd_hda_input_mux_info() and snd_hda_input_mux_put(). See snd_hda_input_mux_info() and snd_hda_input_mux_put(). See
......
...@@ -202,17 +202,13 @@ you must call __handle_sysrq_nolock instead. ...@@ -202,17 +202,13 @@ you must call __handle_sysrq_nolock instead.
* I have more questions, who can I ask? * I have more questions, who can I ask?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
You may feel free to send email to myrdraal@deathsdoor.com, and I will
respond as soon as possible.
-Myrdraal
And I'll answer any questions about the registration system you got, also And I'll answer any questions about the registration system you got, also
responding as soon as possible. responding as soon as possible.
-Crutcher -Crutcher
* Credits * Credits
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Written by Mydraal <myrdraal@deathsdoor.com> Written by Mydraal <vulpyne@vulpyne.net>
Updated by Adam Sulmicki <adam@cfar.umd.edu> Updated by Adam Sulmicki <adam@cfar.umd.edu>
Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59 Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59
Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com> Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com>
...@@ -258,6 +258,13 @@ P: Ivan Kokshaysky ...@@ -258,6 +258,13 @@ P: Ivan Kokshaysky
M: ink@jurassic.park.msu.ru M: ink@jurassic.park.msu.ru
S: Maintained for 2.4; PCI support for 2.6. S: Maintained for 2.4; PCI support for 2.6.
AMD GEODE PROCESSOR/CHIPSET SUPPORT
P: Jordan Crouse
M: info-linux@geode.amd.com
L: info-linux@geode.amd.com
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
S: Supported
APM DRIVER APM DRIVER
P: Stephen Rothwell P: Stephen Rothwell
M: sfr@canb.auug.org.au M: sfr@canb.auug.org.au
...@@ -554,6 +561,11 @@ W: http://us1.samba.org/samba/Linux_CIFS_client.html ...@@ -554,6 +561,11 @@ W: http://us1.samba.org/samba/Linux_CIFS_client.html
T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git T: git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
S: Supported S: Supported
CONFIGFS
P: Joel Becker
M: Joel Becker <joel.becker@oracle.com>
S: Supported
CIRRUS LOGIC GENERIC FBDEV DRIVER CIRRUS LOGIC GENERIC FBDEV DRIVER
P: Jeff Garzik P: Jeff Garzik
M: jgarzik@pobox.com M: jgarzik@pobox.com
...@@ -650,6 +662,11 @@ L: linux-crypto@vger.kernel.org ...@@ -650,6 +662,11 @@ L: linux-crypto@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git T: git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
S: Maintained S: Maintained
CS5535 Audio ALSA driver
P: Jaya Kumar
M: jayakumar.alsa@gmail.com
S: Maintained
CYBERPRO FB DRIVER CYBERPRO FB DRIVER
P: Russell King P: Russell King
M: rmk@arm.linux.org.uk M: rmk@arm.linux.org.uk
...@@ -1225,7 +1242,7 @@ IEEE 1394 SUBSYSTEM ...@@ -1225,7 +1242,7 @@ IEEE 1394 SUBSYSTEM
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Jody McIntyre P: Jody McIntyre
M: scjody@steamballoon.com M: scjody@modernduck.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
...@@ -1235,14 +1252,14 @@ IEEE 1394 OHCI DRIVER ...@@ -1235,14 +1252,14 @@ IEEE 1394 OHCI DRIVER
P: Ben Collins P: Ben Collins
M: bcollins@debian.org M: bcollins@debian.org
P: Jody McIntyre P: Jody McIntyre
M: scjody@steamballoon.com M: scjody@modernduck.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
IEEE 1394 PCILYNX DRIVER IEEE 1394 PCILYNX DRIVER
P: Jody McIntyre P: Jody McIntyre
M: scjody@steamballoon.com M: scjody@modernduck.com
L: linux1394-devel@lists.sourceforge.net L: linux1394-devel@lists.sourceforge.net
W: http://www.linux1394.org/ W: http://www.linux1394.org/
S: Maintained S: Maintained
...@@ -1465,7 +1482,6 @@ P: Several ...@@ -1465,7 +1482,6 @@ P: Several
L: kernel-janitors@osdl.org L: kernel-janitors@osdl.org
W: http://www.kerneljanitors.org/ W: http://www.kerneljanitors.org/
W: http://sf.net/projects/kernel-janitor/ W: http://sf.net/projects/kernel-janitor/
W: http://developer.osdl.org/rddunlap/kj-patches/
S: Maintained S: Maintained
KERNEL NFSD KERNEL NFSD
...@@ -1476,17 +1492,11 @@ W: http://nfs.sourceforge.net/ ...@@ -1476,17 +1492,11 @@ W: http://nfs.sourceforge.net/
W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/ W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
S: Maintained S: Maintained
KERNEL EVENT LAYER (KOBJECT_UEVENT)
P: Robert Love
M: rml@novell.com
L: linux-kernel@vger.kernel.org
S: Maintained
KEXEC KEXEC
P: Eric Biederman P: Eric Biederman
P: Randy Dunlap P: Randy Dunlap
M: ebiederm@xmission.com M: ebiederm@xmission.com
M: rddunlap@osdl.org M: rdunlap@xenotime.net
W: http://www.xmission.com/~ebiederm/files/kexec/ W: http://www.xmission.com/~ebiederm/files/kexec/
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
L: fastboot@osdl.org L: fastboot@osdl.org
...@@ -1900,6 +1910,15 @@ M: ajoshi@shell.unixbox.com ...@@ -1900,6 +1910,15 @@ M: ajoshi@shell.unixbox.com
L: linux-nvidia@lists.surfsouth.com L: linux-nvidia@lists.surfsouth.com
S: Maintained S: Maintained
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
P: Mark Fasheh
M: mark.fasheh@oracle.com
P: Kurt Hackel
M: kurt.hackel@oracle.com
L: ocfs2-devel@oss.oracle.com
W: http://oss.oracle.com/projects/ocfs2/
S: Supported
OLYMPIC NETWORK DRIVER OLYMPIC NETWORK DRIVER
P: Peter De Shrijver P: Peter De Shrijver
M: p2@ace.ulyssis.student.kuleuven.ac.be M: p2@ace.ulyssis.student.kuleuven.ac.be
...@@ -2587,7 +2606,6 @@ S: Maintained ...@@ -2587,7 +2606,6 @@ S: Maintained
UDF FILESYSTEM UDF FILESYSTEM
P: Ben Fennema P: Ben Fennema
M: bfennema@falcon.csc.calpoly.edu M: bfennema@falcon.csc.calpoly.edu
L: linux_udf@hpesjro.fc.hp.com
W: http://linux-udf.sourceforge.net W: http://linux-udf.sourceforge.net
S: Maintained S: Maintained
...@@ -2640,6 +2658,12 @@ L: linux-usb-users@lists.sourceforge.net ...@@ -2640,6 +2658,12 @@ L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net
S: Maintained S: Maintained
USB ISP116X DRIVER
P: Olav Kongas
M: ok@artecdesign.ee
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB KAWASAKI LSI DRIVER USB KAWASAKI LSI DRIVER
P: Oliver Neukum P: Oliver Neukum
M: oliver@neukum.name M: oliver@neukum.name
...@@ -2651,7 +2675,7 @@ USB MASS STORAGE DRIVER ...@@ -2651,7 +2675,7 @@ USB MASS STORAGE DRIVER
P: Matthew Dharm P: Matthew Dharm
M: mdharm-usb@one-eyed-alien.net M: mdharm-usb@one-eyed-alien.net
L: linux-usb-users@lists.sourceforge.net L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net L: usb-storage@lists.one-eyed-alien.net
S: Maintained S: Maintained
W: http://www.one-eyed-alien.net/~mdharm/linux-usb/ W: http://www.one-eyed-alien.net/~mdharm/linux-usb/
......
...@@ -286,10 +286,6 @@ export quiet Q KBUILD_VERBOSE ...@@ -286,10 +286,6 @@ export quiet Q KBUILD_VERBOSE
cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
> /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;) > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
# For backward compatibility
check_gcc = $(warning check_gcc is deprecated - use cc-option) \
$(call cc-option, $(1),$(2))
# cc-option-yn # cc-option-yn
# Usage: flag := $(call cc-option-yn, -march=winchip-c6) # Usage: flag := $(call cc-option-yn, -march=winchip-c6)
cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \ cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
...@@ -481,18 +477,20 @@ ifeq ($(dot-config),1) ...@@ -481,18 +477,20 @@ ifeq ($(dot-config),1)
# Read in dependencies to all Kconfig* files, make sure to run # Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected. # oldconfig if changes are detected.
-include .config.cmd -include .kconfig.d
include .config include .config
# If .config needs to be updated, it will be done via the dependency # If .config needs to be updated, it will be done via the dependency
# that autoconf has on .config. # that autoconf has on .config.
# To avoid any implicit rule to kick in, define an empty command # To avoid any implicit rule to kick in, define an empty command
.config: ; .config .kconfig.d: ;
# If .config is newer than include/linux/autoconf.h, someone tinkered # If .config is newer than include/linux/autoconf.h, someone tinkered
# with it and forgot to run make oldconfig # with it and forgot to run make oldconfig.
include/linux/autoconf.h: .config # If kconfig.d is missing then we are probarly in a cleaned tree so
# we execute the config step to be sure to catch updated Kconfig files
include/linux/autoconf.h: .kconfig.d .config
$(Q)mkdir -p include/linux $(Q)mkdir -p include/linux
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
else else
...@@ -1066,7 +1064,7 @@ help: ...@@ -1066,7 +1064,7 @@ help:
@echo ' all - Build all targets marked with [*]' @echo ' all - Build all targets marked with [*]'
@echo '* vmlinux - Build the bare kernel' @echo '* vmlinux - Build the bare kernel'
@echo '* modules - Build all modules' @echo '* modules - Build all modules'
@echo ' modules_install - Install all modules' @echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
@echo ' dir/ - Build all files in dir and below' @echo ' dir/ - Build all files in dir and below'
@echo ' dir/file.[ois] - Build specified target only' @echo ' dir/file.[ois] - Build specified target only'
@echo ' dir/file.ko - Build module including final link' @echo ' dir/file.ko - Build module including final link'
...@@ -1240,8 +1238,11 @@ cscope: FORCE ...@@ -1240,8 +1238,11 @@ cscope: FORCE
quiet_cmd_TAGS = MAKE $@ quiet_cmd_TAGS = MAKE $@
define cmd_TAGS define cmd_TAGS
rm -f $@; \ rm -f $@; \
ETAGSF=`etags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \ ETAGSF=`etags --version | grep -i exuberant >/dev/null && \
$(all-sources) | xargs etags $$ETAGSF -a echo "-I __initdata,__exitdata,__acquires,__releases \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
--extra=+f --c-kinds=+px"`; \
$(all-sources) | xargs etags $$ETAGSF -a
endef endef
TAGS: FORCE TAGS: FORCE
...@@ -1251,8 +1252,11 @@ TAGS: FORCE ...@@ -1251,8 +1252,11 @@ TAGS: FORCE
quiet_cmd_tags = MAKE $@ quiet_cmd_tags = MAKE $@
define cmd_tags define cmd_tags
rm -f $@; \ rm -f $@; \
CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \ CTAGSF=`ctags --version | grep -i exuberant >/dev/null && \
$(all-sources) | xargs ctags $$CTAGSF -a echo "-I __initdata,__exitdata,__acquires,__releases \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
--extra=+f --c-kinds=+px"`; \
$(all-sources) | xargs ctags $$CTAGSF -a
endef endef
tags: FORCE tags: FORCE
......
...@@ -40,6 +40,19 @@ config GENERIC_IOMAP ...@@ -40,6 +40,19 @@ config GENERIC_IOMAP
bool bool
default n default n
config GENERIC_HARDIRQS
bool
default y
config GENERIC_IRQ_PROBE
bool
default y
config AUTO_IRQ_AFFINITY
bool
depends on SMP
default y
source "init/Kconfig" source "init/Kconfig"
......
...@@ -175,7 +175,6 @@ EXPORT_SYMBOL(up); ...@@ -175,7 +175,6 @@ EXPORT_SYMBOL(up);
*/ */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
EXPORT_SYMBOL(synchronize_irq);
EXPORT_SYMBOL(flush_tlb_mm); EXPORT_SYMBOL(flush_tlb_mm);
EXPORT_SYMBOL(flush_tlb_range); EXPORT_SYMBOL(flush_tlb_range);
EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(flush_tlb_page);
......
此差异已折叠。
...@@ -45,7 +45,7 @@ static int amba_match(struct device *dev, struct device_driver *drv) ...@@ -45,7 +45,7 @@ static int amba_match(struct device *dev, struct device_driver *drv)
} }
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz) static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
{ {
struct amba_device *pcdev = to_amba_device(dev); struct amba_device *pcdev = to_amba_device(dev);
...@@ -58,7 +58,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, ...@@ -58,7 +58,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf,
return 0; return 0;
} }
#else #else
#define amba_hotplug NULL #define amba_uevent NULL
#endif #endif
static int amba_suspend(struct device *dev, pm_message_t state) static int amba_suspend(struct device *dev, pm_message_t state)
...@@ -88,7 +88,7 @@ static int amba_resume(struct device *dev) ...@@ -88,7 +88,7 @@ static int amba_resume(struct device *dev)
static struct bus_type amba_bustype = { static struct bus_type amba_bustype = {
.name = "amba", .name = "amba",
.match = amba_match, .match = amba_match,
.hotplug = amba_hotplug, .uevent = amba_uevent,
.suspend = amba_suspend, .suspend = amba_suspend,
.resume = amba_resume, .resume = amba_resume,
}; };
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#include <asm/arch/pxafb.h> #include <asm/arch/pxafb.h>
#include <asm/arch/mmc.h> #include <asm/arch/mmc.h>
#include <asm/arch/irda.h> #include <asm/arch/irda.h>
#include <asm/arch/ohci.h>
#include "generic.h" #include "generic.h"
...@@ -393,6 +394,25 @@ static struct platform_device *platform_devices[] __initdata = { ...@@ -393,6 +394,25 @@ static struct platform_device *platform_devices[] __initdata = {
&mst_flash_device[1], &mst_flash_device[1],
}; };
static int mainstone_ohci_init(struct device *dev)
{
/* setup Port1 GPIO pin. */
pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN); /* USBHPWR1 */
pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT); /* USBHPEN1 */
/* Set the Power Control Polarity Low and Power Sense
Polarity Low to active low. */
UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
return 0;
}
static struct pxaohci_platform_data mainstone_ohci_platform_data = {
.port_mode = PMM_PERPORT_MODE,
.init = mainstone_ohci_init,
};
static void __init mainstone_init(void) static void __init mainstone_init(void)
{ {
int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */ int SW7 = 0; /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
...@@ -424,6 +444,7 @@ static void __init mainstone_init(void) ...@@ -424,6 +444,7 @@ static void __init mainstone_init(void)
pxa_set_mci_info(&mainstone_mci_platform_data); pxa_set_mci_info(&mainstone_mci_platform_data);
pxa_set_ficp_info(&mainstone_ficp_platform_data); pxa_set_ficp_info(&mainstone_ficp_platform_data);
pxa_set_ohci_info(&mainstone_ohci_platform_data);
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/arch/pxa-regs.h> #include <asm/arch/pxa-regs.h>
#include <asm/arch/ohci.h>
#include "generic.h" #include "generic.h"
...@@ -194,6 +195,11 @@ static struct platform_device ohci_device = { ...@@ -194,6 +195,11 @@ static struct platform_device ohci_device = {
.resource = pxa27x_ohci_resources, .resource = pxa27x_ohci_resources,
}; };
void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
{
ohci_device.dev.platform_data = info;
}
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&ohci_device, &ohci_device,
}; };
......
...@@ -46,10 +46,9 @@ typedef struct task_struct* PTASK; ...@@ -46,10 +46,9 @@ typedef struct task_struct* PTASK;
#ifdef MODULE #ifdef MODULE
void fp_send_sig(unsigned long sig, PTASK p, int priv); void fp_send_sig(unsigned long sig, PTASK p, int priv);
#if LINUX_VERSION_CODE > 0x20115
MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>"); MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
MODULE_DESCRIPTION("NWFPE floating point emulator"); MODULE_DESCRIPTION("NWFPE floating point emulator");
#endif
#else #else
#define fp_send_sig send_sig #define fp_send_sig send_sig
......
...@@ -569,12 +569,6 @@ gdb_cris_strtol (const char *s, char **endptr, int base) ...@@ -569,12 +569,6 @@ gdb_cris_strtol (const char *s, char **endptr, int base)
return x; return x;
} }
int
double_this(int x)
{
return 2 * x;
}
/********************************* Register image ****************************/ /********************************* Register image ****************************/
/* Copy the content of a register image into another. The size n is /* Copy the content of a register image into another. The size n is
the size of the register image. Due to struct assignment generation of the size of the register image. Due to struct assignment generation of
......
...@@ -20,3 +20,4 @@ obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o ...@@ -20,3 +20,4 @@ obj-$(CONFIG_FUJITSU_MB93493) += irq-mb93493.o
obj-$(CONFIG_PM) += pm.o cmode.o obj-$(CONFIG_PM) += pm.o cmode.o
obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o
obj-$(CONFIG_SYSCTL) += sysctl.o obj-$(CONFIG_SYSCTL) += sysctl.o
obj-$(CONFIG_FUTEX) += futex.o
...@@ -1076,7 +1076,7 @@ __entry_work_notifysig: ...@@ -1076,7 +1076,7 @@ __entry_work_notifysig:
LEDS 0x6410 LEDS 0x6410
ori.p gr4,#0,gr8 ori.p gr4,#0,gr8
call do_notify_resume call do_notify_resume
bra __entry_return_direct bra __entry_resume_userspace
# perform syscall entry tracing # perform syscall entry tracing
__syscall_trace_entry: __syscall_trace_entry:
......
/* futex.c: futex operations
*
* Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/futex.h>
#include <asm/futex.h>
#include <asm/errno.h>
#include <asm/uaccess.h>
/*
* the various futex operations; MMU fault checking is ignored under no-MMU
* conditions
*/
static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_oldval)
{
int oldval, ret;
asm("0: \n"
" orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
" ckeq icc3,cc7 \n"
"1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
" orcr cc7,cc7,cc3 \n" /* set CC3 to true */
"2: cst.p %3,%M0 ,cc3,#1 \n"
" corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
" beq icc3,#0,0b \n"
" setlos 0,%2 \n"
"3: \n"
".subsection 2 \n"
"4: setlos %5,%2 \n"
" bra 3b \n"
".previous \n"
".section __ex_table,\"a\" \n"
" .balign 8 \n"
" .long 1b,4b \n"
" .long 2b,4b \n"
".previous"
: "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
: "3"(oparg), "i"(-EFAULT)
: "memory", "cc7", "cc3", "icc3"
);
*_oldval = oldval;
return ret;
}
static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_oldval)
{
int oldval, ret;
asm("0: \n"
" orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
" ckeq icc3,cc7 \n"
"1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
" orcr cc7,cc7,cc3 \n" /* set CC3 to true */
" add %1,%3,%3 \n"
"2: cst.p %3,%M0 ,cc3,#1 \n"
" corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
" beq icc3,#0,0b \n"
" setlos 0,%2 \n"
"3: \n"
".subsection 2 \n"
"4: setlos %5,%2 \n"
" bra 3b \n"
".previous \n"
".section __ex_table,\"a\" \n"
" .balign 8 \n"
" .long 1b,4b \n"
" .long 2b,4b \n"
".previous"
: "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
: "3"(oparg), "i"(-EFAULT)
: "memory", "cc7", "cc3", "icc3"
);
*_oldval = oldval;
return ret;
}
static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_oldval)
{
int oldval, ret;
asm("0: \n"
" orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
" ckeq icc3,cc7 \n"
"1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
" orcr cc7,cc7,cc3 \n" /* set CC3 to true */
" or %1,%3,%3 \n"
"2: cst.p %3,%M0 ,cc3,#1 \n"
" corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
" beq icc3,#0,0b \n"
" setlos 0,%2 \n"
"3: \n"
".subsection 2 \n"
"4: setlos %5,%2 \n"
" bra 3b \n"
".previous \n"
".section __ex_table,\"a\" \n"
" .balign 8 \n"
" .long 1b,4b \n"
" .long 2b,4b \n"
".previous"
: "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
: "3"(oparg), "i"(-EFAULT)
: "memory", "cc7", "cc3", "icc3"
);
*_oldval = oldval;
return ret;
}
static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_oldval)
{
int oldval, ret;
asm("0: \n"
" orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
" ckeq icc3,cc7 \n"
"1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
" orcr cc7,cc7,cc3 \n" /* set CC3 to true */
" and %1,%3,%3 \n"
"2: cst.p %3,%M0 ,cc3,#1 \n"
" corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
" beq icc3,#0,0b \n"
" setlos 0,%2 \n"
"3: \n"
".subsection 2 \n"
"4: setlos %5,%2 \n"
" bra 3b \n"
".previous \n"
".section __ex_table,\"a\" \n"
" .balign 8 \n"
" .long 1b,4b \n"
" .long 2b,4b \n"
".previous"
: "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
: "3"(oparg), "i"(-EFAULT)
: "memory", "cc7", "cc3", "icc3"
);
*_oldval = oldval;
return ret;
}
static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_oldval)
{
int oldval, ret;
asm("0: \n"
" orcc gr0,gr0,gr0,icc3 \n" /* set ICC3.Z */
" ckeq icc3,cc7 \n"
"1: ld.p %M0,%1 \n" /* LD.P/ORCR must be atomic */
" orcr cc7,cc7,cc3 \n" /* set CC3 to true */
" xor %1,%3,%3 \n"
"2: cst.p %3,%M0 ,cc3,#1 \n"
" corcc gr29,gr29,gr0 ,cc3,#1 \n" /* clear ICC3.Z if store happens */
" beq icc3,#0,0b \n"
" setlos 0,%2 \n"
"3: \n"
".subsection 2 \n"
"4: setlos %5,%2 \n"
" bra 3b \n"
".previous \n"
".section __ex_table,\"a\" \n"
" .balign 8 \n"
" .long 1b,4b \n"
" .long 2b,4b \n"
".previous"
: "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
: "3"(oparg), "i"(-EFAULT)
: "memory", "cc7", "cc3", "icc3"
);
*_oldval = oldval;
return ret;
}
/*****************************************************************************/
/*
* do the futex operations
*/
int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
inc_preempt_count();
switch (op) {
case FUTEX_OP_SET:
ret = atomic_futex_op_xchg_set(oparg, uaddr, &oldval);
break;
case FUTEX_OP_ADD:
ret = atomic_futex_op_xchg_add(oparg, uaddr, &oldval);
break;
case FUTEX_OP_OR:
ret = atomic_futex_op_xchg_or(oparg, uaddr, &oldval);
break;
case FUTEX_OP_ANDN:
ret = atomic_futex_op_xchg_and(~oparg, uaddr, &oldval);
break;
case FUTEX_OP_XOR:
ret = atomic_futex_op_xchg_xor(oparg, uaddr, &oldval);
break;
default:
ret = -ENOSYS;
break;
}
dec_preempt_count();
if (!ret) {
switch (cmp) {
case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
default: ret = -ENOSYS; break;
}
}
return ret;
} /* end futex_atomic_op_inuser() */
此差异已折叠。
...@@ -464,7 +464,6 @@ config NUMA ...@@ -464,7 +464,6 @@ config NUMA
depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI)) depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI))
default n if X86_PC default n if X86_PC
default y if (X86_NUMAQ || X86_SUMMIT) default y if (X86_NUMAQ || X86_SUMMIT)
select SPARSEMEM_STATIC
# Need comments to help the hapless user trying to turn on NUMA support # Need comments to help the hapless user trying to turn on NUMA support
comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
...@@ -493,6 +492,10 @@ config HAVE_ARCH_ALLOC_REMAP ...@@ -493,6 +492,10 @@ config HAVE_ARCH_ALLOC_REMAP
depends on NUMA depends on NUMA
default y default y
config ARCH_FLATMEM_ENABLE
def_bool y
depends on (ARCH_SELECT_MEMORY_MODEL && X86_PC)
config ARCH_DISCONTIGMEM_ENABLE config ARCH_DISCONTIGMEM_ENABLE
def_bool y def_bool y
depends on NUMA depends on NUMA
...@@ -503,7 +506,8 @@ config ARCH_DISCONTIGMEM_DEFAULT ...@@ -503,7 +506,8 @@ config ARCH_DISCONTIGMEM_DEFAULT
config ARCH_SPARSEMEM_ENABLE config ARCH_SPARSEMEM_ENABLE
def_bool y def_bool y
depends on NUMA depends on (NUMA || (X86_PC && EXPERIMENTAL))
select SPARSEMEM_STATIC
config ARCH_SELECT_MEMORY_MODEL config ARCH_SELECT_MEMORY_MODEL
def_bool y def_bool y
......
...@@ -39,6 +39,7 @@ config M386 ...@@ -39,6 +39,7 @@ config M386
- "Winchip-2" for IDT Winchip 2. - "Winchip-2" for IDT Winchip 2.
- "Winchip-2A" for IDT Winchips with 3dNow! capabilities. - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
- "GeodeGX1" for Geode GX1 (Cyrix MediaGX). - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
- "Geode GX/LX" For AMD Geode GX and LX processors.
- "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
- "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
...@@ -171,6 +172,11 @@ config MGEODEGX1 ...@@ -171,6 +172,11 @@ config MGEODEGX1
help help
Select this for a Geode GX1 (Cyrix MediaGX) chip. Select this for a Geode GX1 (Cyrix MediaGX) chip.
config MGEODE_LX
bool "Geode GX/LX"
help
Select this for AMD Geode GX and LX processors.
config MCYRIXIII config MCYRIXIII
bool "CyrixIII/VIA-C3" bool "CyrixIII/VIA-C3"
help help
...@@ -220,8 +226,8 @@ config X86_XADD ...@@ -220,8 +226,8 @@ config X86_XADD
config X86_L1_CACHE_SHIFT config X86_L1_CACHE_SHIFT
int int
default "7" if MPENTIUM4 || X86_GENERIC default "7" if MPENTIUM4 || X86_GENERIC
default "4" if X86_ELAN || M486 || M386 default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
default "6" if MK7 || MK8 || MPENTIUMM default "6" if MK7 || MK8 || MPENTIUMM
config RWSEM_GENERIC_SPINLOCK config RWSEM_GENERIC_SPINLOCK
...@@ -290,12 +296,12 @@ config X86_INTEL_USERCOPY ...@@ -290,12 +296,12 @@ config X86_INTEL_USERCOPY
config X86_USE_PPRO_CHECKSUM config X86_USE_PPRO_CHECKSUM
bool bool
depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX
default y default y
config X86_USE_3DNOW config X86_USE_3DNOW
bool bool
depends on MCYRIXIII || MK7 depends on MCYRIXIII || MK7 || MGEODE_LX
default y default y
config X86_OOSTORE config X86_OOSTORE
......
...@@ -42,6 +42,16 @@ config DEBUG_PAGEALLOC ...@@ -42,6 +42,16 @@ config DEBUG_PAGEALLOC
This results in a large slowdown, but helps to find certain types This results in a large slowdown, but helps to find certain types
of memory corruptions. of memory corruptions.
config DEBUG_RODATA
bool "Write protect kernel read-only data structures"
depends on DEBUG_KERNEL
help
Mark the kernel read-only data as write-protected in the pagetables,
in order to catch accidental (and incorrect) writes to such const
data. This option may have a slight performance impact because a
portion of the kernel code won't be covered by a 2MB TLB anymore.
If in doubt, say "N".
config 4KSTACKS config 4KSTACKS
bool "Use 4Kb for kernel stacks instead of 8Kb" bool "Use 4Kb for kernel stacks instead of 8Kb"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
......
...@@ -721,7 +721,7 @@ static int __init apic_set_verbosity(char *str) ...@@ -721,7 +721,7 @@ static int __init apic_set_verbosity(char *str)
apic_verbosity = APIC_VERBOSE; apic_verbosity = APIC_VERBOSE;
else else
printk(KERN_WARNING "APIC Verbosity level %s not recognised" printk(KERN_WARNING "APIC Verbosity level %s not recognised"
" use apic=verbose or apic=debug", str); " use apic=verbose or apic=debug\n", str);
return 0; return 0;
} }
......
...@@ -302,17 +302,6 @@ extern int (*console_blank_hook)(int); ...@@ -302,17 +302,6 @@ extern int (*console_blank_hook)(int);
#include "apm.h" #include "apm.h"
/*
* Define to make all _set_limit calls use 64k limits. The APM 1.1 BIOS is
* supposed to provide limit information that it recognizes. Many machines
* do this correctly, but many others do not restrict themselves to their
* claimed limit. When this happens, they will cause a segmentation
* violation in the kernel at boot time. Most BIOS's, however, will
* respect a 64k limit, so we use that. If you want to be pedantic and
* hold your BIOS to its claims, then undefine this.
*/
#define APM_RELAX_SEGMENTS
/* /*
* Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend. * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
* This patched by Chad Miller <cmiller@surfsouth.com>, original code by * This patched by Chad Miller <cmiller@surfsouth.com>, original code by
...@@ -1075,22 +1064,23 @@ static int apm_engage_power_management(u_short device, int enable) ...@@ -1075,22 +1064,23 @@ static int apm_engage_power_management(u_short device, int enable)
static int apm_console_blank(int blank) static int apm_console_blank(int blank)
{ {
int error; int error, i;
u_short state; u_short state;
static const u_short dev[3] = { 0x100, 0x1FF, 0x101 };
state = blank ? APM_STATE_STANDBY : APM_STATE_READY; state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
/* Blank the first display device */
error = set_power_state(0x100, state); for (i = 0; i < ARRAY_SIZE(dev); i++) {
if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) { error = set_power_state(dev[i], state);
/* try to blank them all instead */
error = set_power_state(0x1ff, state); if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) return 1;
/* try to blank device one instead */
error = set_power_state(0x101, state); if (error == APM_NOT_ENGAGED)
break;
} }
if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
return 1; if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) {
if (error == APM_NOT_ENGAGED) {
static int tried; static int tried;
int eng_error; int eng_error;
if (tried++ == 0) { if (tried++ == 0) {
...@@ -2233,8 +2223,8 @@ static struct dmi_system_id __initdata apm_dmi_table[] = { ...@@ -2233,8 +2223,8 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
static int __init apm_init(void) static int __init apm_init(void)
{ {
struct proc_dir_entry *apm_proc; struct proc_dir_entry *apm_proc;
struct desc_struct *gdt;
int ret; int ret;
int i;
dmi_check_system(apm_dmi_table); dmi_check_system(apm_dmi_table);
...@@ -2312,45 +2302,30 @@ static int __init apm_init(void) ...@@ -2312,45 +2302,30 @@ static int __init apm_init(void)
set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
/*
* Set up the long jump entry point to the APM BIOS, which is called
* from inline assembly.
*/
apm_bios_entry.offset = apm_info.bios.offset; apm_bios_entry.offset = apm_info.bios.offset;
apm_bios_entry.segment = APM_CS; apm_bios_entry.segment = APM_CS;
for (i = 0; i < NR_CPUS; i++) { /*
struct desc_struct *gdt = get_cpu_gdt_table(i); * The APM 1.1 BIOS is supposed to provide limit information that it
set_base(gdt[APM_CS >> 3], * recognizes. Many machines do this correctly, but many others do
__va((unsigned long)apm_info.bios.cseg << 4)); * not restrict themselves to their claimed limit. When this happens,
set_base(gdt[APM_CS_16 >> 3], * they will cause a segmentation violation in the kernel at boot time.
__va((unsigned long)apm_info.bios.cseg_16 << 4)); * Most BIOS's, however, will respect a 64k limit, so we use that.
set_base(gdt[APM_DS >> 3], *
__va((unsigned long)apm_info.bios.dseg << 4)); * Note we only set APM segments on CPU zero, since we pin the APM
#ifndef APM_RELAX_SEGMENTS * code to that CPU.
if (apm_info.bios.version == 0x100) { */
#endif gdt = get_cpu_gdt_table(0);
/* For ASUS motherboard, Award BIOS rev 110 (and others?) */ set_base(gdt[APM_CS >> 3],
_set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1); __va((unsigned long)apm_info.bios.cseg << 4));
/* For some unknown machine. */ set_base(gdt[APM_CS_16 >> 3],
_set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1); __va((unsigned long)apm_info.bios.cseg_16 << 4));
/* For the DEC Hinote Ultra CT475 (and others?) */ set_base(gdt[APM_DS >> 3],
_set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1); __va((unsigned long)apm_info.bios.dseg << 4));
#ifndef APM_RELAX_SEGMENTS
} else {
_set_limit((char *)&gdt[APM_CS >> 3],
(apm_info.bios.cseg_len - 1) & 0xffff);
_set_limit((char *)&gdt[APM_CS_16 >> 3],
(apm_info.bios.cseg_16_len - 1) & 0xffff);
_set_limit((char *)&gdt[APM_DS >> 3],
(apm_info.bios.dseg_len - 1) & 0xffff);
/* workaround for broken BIOSes */
if (apm_info.bios.cseg_len <= apm_info.bios.offset)
_set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
/* for the BIOS that assumes granularity = 1 */
gdt[APM_DS >> 3].b |= 0x800000;
printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
}
}
#endif
}
apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info); apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info);
if (apm_proc) if (apm_proc)
......
...@@ -161,8 +161,13 @@ static void __init init_amd(struct cpuinfo_x86 *c) ...@@ -161,8 +161,13 @@ static void __init init_amd(struct cpuinfo_x86 *c)
set_bit(X86_FEATURE_K6_MTRR, c->x86_capability); set_bit(X86_FEATURE_K6_MTRR, c->x86_capability);
break; break;
} }
break;
if (c->x86_model == 10) {
/* AMD Geode LX is model 10 */
/* placeholder for any needed mods */
break;
}
break;
case 6: /* An Athlon/Duron */ case 6: /* An Athlon/Duron */
/* Bit 15 of Athlon specific MSR 15, needs to be 0 /* Bit 15 of Athlon specific MSR 15, needs to be 0
......
...@@ -18,9 +18,6 @@ ...@@ -18,9 +18,6 @@
#include "cpu.h" #include "cpu.h"
DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
...@@ -598,11 +595,6 @@ void __devinit cpu_init(void) ...@@ -598,11 +595,6 @@ void __devinit cpu_init(void)
load_gdt(&cpu_gdt_descr[cpu]); load_gdt(&cpu_gdt_descr[cpu]);
load_idt(&idt_descr); load_idt(&idt_descr);
/*
* Delete NT
*/
__asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
/* /*
* Set up and load the per-CPU TSS and LDT * Set up and load the per-CPU TSS and LDT
*/ */
......
...@@ -177,9 +177,10 @@ static unsigned int nforce2_fsb_read(int bootfsb) ...@@ -177,9 +177,10 @@ static unsigned int nforce2_fsb_read(int bootfsb)
*/ */
static int nforce2_set_fsb(unsigned int fsb) static int nforce2_set_fsb(unsigned int fsb)
{ {
u32 pll, temp = 0; u32 temp = 0;
unsigned int tfsb; unsigned int tfsb;
int diff; int diff;
int pll = 0;
if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) { if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb); printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
......
...@@ -44,4 +44,5 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor); ...@@ -44,4 +44,5 @@ extern unsigned int speedstep_get_processor_frequency(unsigned int processor);
extern unsigned int speedstep_get_freqs(unsigned int processor, extern unsigned int speedstep_get_freqs(unsigned int processor,
unsigned int *low_speed, unsigned int *low_speed,
unsigned int *high_speed, unsigned int *high_speed,
unsigned int *transition_latency,
void (*set_state) (unsigned int state)); void (*set_state) (unsigned int state));
...@@ -269,6 +269,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) ...@@ -269,6 +269,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
result = speedstep_get_freqs(speedstep_processor, result = speedstep_get_freqs(speedstep_processor,
&speedstep_freqs[SPEEDSTEP_LOW].frequency, &speedstep_freqs[SPEEDSTEP_LOW].frequency,
&speedstep_freqs[SPEEDSTEP_HIGH].frequency, &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
NULL,
&speedstep_set_state); &speedstep_set_state);
if (result) { if (result) {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -657,6 +657,7 @@ ENTRY(spurious_interrupt_bug) ...@@ -657,6 +657,7 @@ ENTRY(spurious_interrupt_bug)
pushl $do_spurious_interrupt_bug pushl $do_spurious_interrupt_bug
jmp error_code jmp error_code
.section .rodata,"a"
#include "syscall_table.S" #include "syscall_table.S"
syscall_table_size=(.-sys_call_table) syscall_table_size=(.-sys_call_table)
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册